提交 200377ec 编写于 作者: M Mupceet

init: add control_fd cmd

Signed-off-by: NMupceet <laiguizhong@huawei.com>
上级 dc00e1c8
...@@ -51,7 +51,8 @@ ...@@ -51,7 +51,8 @@
"//base/startup/init_lite/services/init/module_engine:libinit_stub_empty", "//base/startup/init_lite/services/init/module_engine:libinit_stub_empty",
"//base/startup/init_lite/device_info:device_info_group", "//base/startup/init_lite/device_info:device_info_group",
"//base/startup/init_lite/interfaces/innerkits/sandbox:libsandbox", "//base/startup/init_lite/interfaces/innerkits/sandbox:libsandbox",
"//base/startup/init_lite/test/exec_test:exectest" "//base/startup/init_lite/test/exec_test:exectest",
"//base/startup/init_lite/interfaces/innerkits/control_fd:libcontrolfd"
], ],
"inner_kits": [ "inner_kits": [
{ {
......
# Copyright (c) 2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//base/startup/init_lite/begetd.gni")
import("//build/ohos.gni")
ohos_shared_library("libcontrolfd") {
sources = [
"control_fd_client.c",
"control_fd_service.c",
]
include_dirs = [
".",
"//third_party/bounds_checking_function/include",
"//base/startup/init_lite/services/include",
"//base/startup/init_lite/interfaces/innerkits/include",
"//base/startup/init_lite/services/loopevent/include",
]
deps = [
"//base/startup/init_lite/services/loopevent:loopevent",
"//base/startup/init_lite/services/utils:libinit_tools",
"//base/startup/init_lite/services/utils:libinit_utils",
"//third_party/bounds_checking_function:libsec_shared",
]
deps += [ "//base/startup/init_lite/services/log:agent_log" ]
part_name = "init"
install_images = [ "system" ]
}
# For init only
ohos_static_library("libcontrolfd_static") {
sources = [
"control_fd_client.c",
"control_fd_service.c",
]
include_dirs = [
".",
"//third_party/bounds_checking_function/include",
"//base/startup/init_lite/services/include",
"//base/startup/init_lite/interfaces/innerkits/include",
"//base/startup/init_lite/services/loopevent/include",
]
deps = [
"//base/startup/init_lite/services/loopevent:loopevent",
"//base/startup/init_lite/services/utils:libinit_tools",
"//base/startup/init_lite/services/utils:libinit_utils",
]
part_name = "init"
}
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CONTROL_FD_
#define CONTROL_FD_
#include <stdint.h>
#include "loop_event.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#define INIT_CONTROL_FD_SOCKET_PATH "/dev/unix/socket/init_control_fd"
#define CONTROL_FD_FIFO_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
#define FIFO_BUF_SIZE 4096
#define FIFO_PATH_SIZE 128
typedef struct CmdService_ {
TaskHandle serverTask;
} CmdService;
typedef struct CmdAgent_ {
TaskHandle task;
WatcherHandle input; // watch stdin
WatcherHandle reader; // watch read pipe
} CmdAgent;
typedef void (* CallbackControlFdProcess)(uint16_t type, const char *serviceCmd, const void *context);
typedef enum {
ACTION_SANDBOX = 0,
ACTION_DUMP,
ACTION_PARAM_SHELL,
ACTION_MAX
} ActionType;
typedef struct {
uint16_t msgSize;
uint16_t type;
uint32_t pid;
char fifoName[FIFO_PATH_SIZE];
char cmd[0];
} CmdMessage;
void CmdServiceInit(const char *socketPath, CallbackControlFdProcess func);
void CmdClientInit(const char *socketPath, uint16_t type, const char *cmd, const char *fifoName);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif
\ No newline at end of file
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <limits.h>
#include "beget_ext.h"
#include "control_fd.h"
#include "init_utils.h"
#include "securec.h"
static char g_FifoReadPath[FIFO_PATH_SIZE] = {0};
static int g_FifoReadFd = -1;
static char g_FifoWritePath[FIFO_PATH_SIZE] = {0};
static int g_FifoWriteFd = -1;
static void ProcessFifoWrite(const WatcherHandle taskHandle, int fd, uint32_t *events, const void *context)
{
if ((fd < 0) || (events == NULL) || (context == NULL)) {
BEGET_LOGE("[control_fd] Invaild fifo write parameter");
return;
}
int fifow = *((int *)context);
if (fifow < 0) {
BEGET_LOGE("[control_fd] invaild fifo write fd");
return;
}
char rbuf[FIFO_BUF_SIZE] = {0};
int rlen = read(fd, rbuf, FIFO_BUF_SIZE - 1);
int ret = fflush(stdin);
BEGET_ERROR_CHECK(ret == 0, return, "[control_fd] Failed fflush err=%d", errno);
if (rlen > 0) {
int wlen = write(fifow, rbuf, rlen);
BEGET_ERROR_CHECK(wlen == rlen, return, "[control_fd] Failed write fifo err=%d", errno);
}
printf("#");
ret = fflush(stdout);
BEGET_ERROR_CHECK(ret == 0, return, "[control_fd] Failed fflush err=%d", errno);
*events = Event_Read;
}
static void ProcessFifoRead(const WatcherHandle taskHandle, int fd, uint32_t *events, const void *context)
{
if ((fd < 0) || (events == NULL)) {
BEGET_LOGE("[control_fd] Invaild fifo read parameter");
return;
}
char buf[FIFO_BUF_SIZE] = {0};
int readlen = read(fd, buf, FIFO_BUF_SIZE - 1);
if (readlen > 0) {
fprintf(stdout, "%s", buf);
}
int ret = fflush(stdout);
BEGET_ERROR_CHECK(ret == 0, return, "[control_fd] Failed fflush err=%d", errno);
printf("#");
ret = fflush(stdout);
BEGET_ERROR_CHECK(ret == 0, return, "[control_fd] Failed fflush err=%d", errno);
*events = Event_Read;
}
static void DestroyCmdFifo(void)
{
if (g_FifoReadFd >= 0) {
(void)close(g_FifoReadFd);
}
if (g_FifoWriteFd >= 0) {
(void)close(g_FifoWriteFd);
}
g_FifoReadFd = -1;
g_FifoWriteFd = -1;
int ret = unlink(g_FifoReadPath);
BEGET_CHECK_ONLY_ELOG(ret == 0, "Failed unlink fifo %s", g_FifoReadPath);
ret = unlink(g_FifoWritePath);
BEGET_CHECK_ONLY_ELOG(ret == 0, "Failed unlink fifo %s", g_FifoReadPath);
}
static void CmdOnRecvMessage(const TaskHandle task, const uint8_t *buffer, uint32_t buffLen)
{
BEGET_LOGI("[control_fd] CmdOnRecvMessage %s len %d.", (char *)buffer, buffLen);
}
static void CmdOnConntectComplete(const TaskHandle client)
{
BEGET_LOGI("[control_fd] CmdOnConntectComplete");
}
static void CmdOnClose(const TaskHandle task)
{
BEGET_LOGI("[control_fd] CmdOnClose");
DestroyCmdFifo();
}
static void CmdDisConnectComplete(const TaskHandle client)
{
BEGET_LOGI("[control_fd] CmdDisConnectComplete");
}
static void CmdAgentInit(WatcherHandle handle, const char *path, bool read, ProcessWatchEvent func)
{
BEGET_LOGI("[control_fd] client open %s", (read ? "read" : "write"));
if (read == true) {
g_FifoReadFd = open(path, O_RDONLY | O_TRUNC | O_NONBLOCK);
BEGET_ERROR_CHECK(g_FifoReadFd >= 0, return, "[control_fd] Failed to open fifo read");
BEGET_LOGI("[control_fd] g_FifoReadFd is %d", g_FifoReadFd);
} else {
g_FifoWriteFd = open(path, O_WRONLY | O_TRUNC);
BEGET_ERROR_CHECK(g_FifoWriteFd >= 0, return, "[control_fd] Failed to open fifo write");
BEGET_LOGI("[control_fd] g_FifoWriteFd is %d", g_FifoWriteFd);
}
// start watcher for stdin
LE_WatchInfo info = {};
info.flags = 0;
info.events = Event_Read;
info.processEvent = func;
if (read == true) {
info.fd = g_FifoReadFd; // read fifo0
BEGET_ERROR_CHECK(LE_StartWatcher(LE_GetDefaultLoop(), &handle, &info, NULL) == LE_SUCCESS,
return, "[control_fd] Failed le_loop start watcher fifo read");
} else {
info.fd = STDIN_FILENO; // read stdin and write fifo1
BEGET_ERROR_CHECK(LE_StartWatcher(LE_GetDefaultLoop(), &handle, &info, &g_FifoWriteFd) == LE_SUCCESS,
return, "[control_fd] Failed le_loop start watcher stdin");
}
return;
}
static void CmdOnSendMessageComplete(const TaskHandle task, const BufferHandle handle)
{
BEGET_LOGI("[control_fd] CmdOnSendMessageComplete");
CmdAgent *agent = (CmdAgent *)LE_GetUserData(task);
BEGET_ERROR_CHECK(agent != NULL, return, "[control_fd] Invalid agent");
CmdAgentInit(agent->input, g_FifoWritePath, false, ProcessFifoWrite);
printf("#");
int ret = fflush(stdout);
BEGET_ERROR_CHECK(ret == 0, return, "[control_fd] Failed fflush err=%d", errno);
}
static CmdAgent *CmdAgentCreate(const char *server)
{
if (server == NULL) {
BEGET_LOGE("[control_fd] Invaild parameter");
return NULL;
}
TaskHandle task = NULL;
LE_StreamInfo info = {};
info.baseInfo.flags = TASK_STREAM | TASK_PIPE | TASK_CONNECT;
info.server = (char *)server;
info.baseInfo.userDataSize = sizeof(CmdAgent);
info.baseInfo.close = CmdOnClose;
info.disConntectComplete = CmdDisConnectComplete;
info.connectComplete = CmdOnConntectComplete;
info.sendMessageComplete = CmdOnSendMessageComplete;
info.recvMessage = CmdOnRecvMessage;
LE_STATUS status = LE_CreateStreamClient(LE_GetDefaultLoop(), &task, &info);
BEGET_ERROR_CHECK(status == 0, return NULL, "[control_fd] Failed create client");
CmdAgent *agent = (CmdAgent *)LE_GetUserData(task);
BEGET_ERROR_CHECK(agent != NULL, return NULL, "[control_fd] Invalid agent");
agent->task = task;
return agent;
}
static int CreateFifo(const char *pipeName)
{
if (pipeName == NULL) {
BEGET_LOGE("[control_fd] Invaild parameter");
return -1;
}
// create fifo for cmd
CheckAndCreateDir(pipeName);
int ret = mkfifo(pipeName, CONTROL_FD_FIFO_MODE);
if (ret != 0) {
if (errno != EEXIST) {
return -1;
}
}
return 0;
}
static int SendCmdMessage(const CmdAgent *agent, uint16_t type, const char *cmd, const char *fifoName)
{
if ((agent == NULL) || (cmd == NULL) || (fifoName == NULL)) {
BEGET_LOGE("[control_fd] Invaild parameter");
return -1;
}
int ret = 0;
BufferHandle handle = NULL;
uint32_t bufferSize = sizeof(CmdMessage) + strlen(cmd) + FIFO_PATH_SIZE + 1;
handle = LE_CreateBuffer(LE_GetDefaultLoop(), bufferSize);
char *buff = (char *)LE_GetBufferInfo(handle, NULL, NULL);
BEGET_ERROR_CHECK(buff != NULL, return -1, "[control_fd] Failed get buffer info");
CmdMessage *message = (CmdMessage *)buff;
message->msgSize = bufferSize;
message->type = type;
message->pid = getpid();
ret = strcpy_s(message->fifoName, FIFO_PATH_SIZE - 1, fifoName);
BEGET_ERROR_CHECK(ret == 0, LE_FreeBuffer(LE_GetDefaultLoop(), agent->task, handle);
return -1, "[control_fd] Failed to copy fifo name %s", fifoName);
ret = strcpy_s(message->cmd, bufferSize - sizeof(CmdMessage) - FIFO_PATH_SIZE, cmd);
BEGET_ERROR_CHECK(ret == 0, LE_FreeBuffer(LE_GetDefaultLoop(), agent->task, handle);
return -1, "[control_fd] Failed to copy cmd %s", cmd);
ret = LE_Send(LE_GetDefaultLoop(), agent->task, handle, bufferSize);
BEGET_ERROR_CHECK(ret == 0, return -1, "[control_fd] Failed LE_Send msg type %d, pid %d, cmd %s",
message->type, message->pid, message->cmd);
return 0;
}
static int CmdMakeFifoInit(const char *fifoPath)
{
if (fifoPath == NULL) {
BEGET_LOGE("[control_fd] Invaild parameter");
return -1;
}
int ret = sprintf_s(g_FifoReadPath, sizeof(g_FifoReadPath) - 1, "/dev/fifo/%s0.%d", fifoPath, getpid());
BEGET_ERROR_CHECK(ret > 0, return -1, "[control_fd] Failed sprintf_s err=%d", errno);
ret = CreateFifo(g_FifoReadPath);
BEGET_ERROR_CHECK(ret == 0, return -1, "[control_fd] Failed create fifo err=%d", errno);
ret = sprintf_s(g_FifoWritePath, sizeof(g_FifoWritePath) - 1, "/dev/fifo/%s1.%d", fifoPath, getpid());
BEGET_ERROR_CHECK(ret > 0, return -1, "[control_fd] Failed sprintf_s err=%d", errno);
ret = CreateFifo(g_FifoWritePath);
BEGET_ERROR_CHECK(ret == 0, return -1, "[control_fd] Failed create fifo err=%d", errno);
return 0;
}
void CmdClientInit(const char *socketPath, uint16_t type, const char *cmd, const char *fifoName)
{
if ((socketPath == NULL) || (cmd == NULL)) {
BEGET_LOGE("[control_fd] Invaild parameter");
}
BEGET_LOGI("[control_fd] CmdAgentInit");
int ret = CmdMakeFifoInit(fifoName);
BEGET_ERROR_CHECK(ret == 0, return, "[control_fd] Failed init fifo");
CmdAgent *agent = CmdAgentCreate(socketPath);
BEGET_ERROR_CHECK(agent != NULL, return, "[control_fd] Failed to create agent");
CmdAgentInit(agent->reader, g_FifoReadPath, true, ProcessFifoRead);
ret = SendCmdMessage(agent, type, cmd, fifoName);
BEGET_ERROR_CHECK(ret == 0, return, "[control_fd] Failed send message");
LE_RunLoop(LE_GetDefaultLoop());
BEGET_LOGI("Cmd Client exit ");
LE_CloseStreamTask(LE_GetDefaultLoop(), agent->task);
free(agent);
DestroyCmdFifo();
}
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <fcntl.h>
#include <stdbool.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/wait.h>
#include "beget_ext.h"
#include "control_fd.h"
#include "init_utils.h"
#include "securec.h"
static CmdService g_cmdService;
CallbackControlFdProcess g_controlFdFunc = NULL;
static void CmdOnClose(const TaskHandle task)
{
BEGET_LOGI("[control_fd] CmdOnClose");
}
static void CmdDisConnectComplete(const TaskHandle client)
{
BEGET_LOGI("[control_fd] CmdDisConnectComplete");
}
static void CmdOnSendMessageComplete(const TaskHandle task, const BufferHandle handle)
{
BEGET_LOGI("[control_fd] CmdOnSendMessageComplete ");
}
static int OpenFifo(int pid, bool read, const char *pipeName)
{
// create pipe for cmd
if (pipeName == NULL) {
return -1;
}
char buffer[FIFO_PATH_SIZE] = {0};
int ret = 0;
if (read == true) {
ret = sprintf_s(buffer, sizeof(buffer) - 1, "/dev/fifo/%s1.%d", pipeName, pid);
BEGET_ERROR_CHECK(ret > 0, return -1, "[control_fd] Failed sprintf_s err=%d", errno);
} else {
ret = sprintf_s(buffer, sizeof(buffer) - 1, "/dev/fifo/%s0.%d", pipeName, pid);
BEGET_ERROR_CHECK(ret > 0, return -1, "[control_fd] Failed sprintf_s err=%d", errno);
}
int flags = read ? (O_RDONLY | O_TRUNC | O_NONBLOCK) : (O_WRONLY | O_TRUNC);
return open(buffer, flags);
}
static void CmdOnRecvMessage(const TaskHandle task, const uint8_t *buffer, uint32_t buffLen)
{
BEGET_LOGI("[control_fd] CmdOnRecvMessage");
if (buffer == NULL) {
return;
}
// parse msg to exec
CmdMessage *msg = (CmdMessage *)buffer;
if ((msg->type < 0) || (msg->type >= ACTION_MAX) || (msg->cmd[0] == '\0') || (msg->fifoName[0] == '\0')) {
BEGET_LOGE("[control_fd] Failed msg ");
return;
}
int reader = OpenFifo(msg->pid, true, msg->fifoName); // read
BEGET_ERROR_CHECK(reader > 0, return, "[control_fd] Failed to open filo");
int writer = OpenFifo(msg->pid, false, msg->fifoName); // write
BEGET_ERROR_CHECK(writer > 0, return, "[control_fd] Failed to open filo");
pid_t pid = fork();
if (pid == 0) {
(void)dup2(reader, STDIN_FILENO);
(void)dup2(writer, STDOUT_FILENO);
(void)dup2(writer, STDERR_FILENO); // Redirect fd to 0, 1, 2
g_controlFdFunc(msg->type, msg->cmd, NULL);
exit(0);
} else if (pid < 0) {
BEGET_LOGE("[control_fd] Failed fork service");
}
return;
}
static int SendMessage(LoopHandle loop, TaskHandle task, const char *message)
{
if (message == NULL) {
BEGET_LOGE("[control_fd] Invaild parameter");
return -1;
}
BufferHandle handle = NULL;
uint32_t bufferSize = strlen(message) + 1;
handle = LE_CreateBuffer(loop, bufferSize);
char *buff = (char *)LE_GetBufferInfo(handle, NULL, &bufferSize);
BEGET_ERROR_CHECK(buff != NULL, return -1, "[control_fd] Failed get buffer info");
int ret = memcpy_s(buff, bufferSize, message, strlen(message) + 1);
BEGET_ERROR_CHECK(ret == 0, LE_FreeBuffer(LE_GetDefaultLoop(), task, handle);
return -1, "[control_fd] Failed memcpy_s err=%d", errno);
LE_STATUS status = LE_Send(loop, task, handle, strlen(message) + 1);
BEGET_ERROR_CHECK(status == LE_SUCCESS, return -1, "[control_fd] Failed le send msg");
return 0;
}
static int CmdOnIncommingConntect(const LoopHandle loop, const TaskHandle server)
{
BEGET_LOGI("[control_fd] CmdOnIncommingConntect");
TaskHandle client = NULL;
LE_StreamInfo info = {};
info.baseInfo.flags = TASK_STREAM | TASK_PIPE | TASK_CONNECT;
info.baseInfo.close = CmdOnClose;
info.baseInfo.userDataSize = sizeof(CmdAgent);
info.disConntectComplete = CmdDisConnectComplete;
info.sendMessageComplete = CmdOnSendMessageComplete;
info.recvMessage = CmdOnRecvMessage;
int ret = LE_AcceptStreamClient(LE_GetDefaultLoop(), server, &client, &info);
BEGET_ERROR_CHECK(ret == 0, return -1, "[control_fd] Failed accept stream")
CmdAgent *agent = (CmdAgent *)LE_GetUserData(client);
BEGET_ERROR_CHECK(agent != NULL, return -1, "[control_fd] Invalid agent");
agent->task = client;
ret = SendMessage(LE_GetDefaultLoop(), agent->task, "connect success.");
BEGET_ERROR_CHECK(ret == 0, return -1, "[control_fd] Failed send msg");
return 0;
}
void CmdServiceInit(const char *socketPath, CallbackControlFdProcess func)
{
if ((socketPath == NULL) || (func == NULL)) {
BEGET_LOGE("[control_fd] Invaild parameter");
return;
}
LE_StreamServerInfo info = {};
info.baseInfo.flags = TASK_STREAM | TASK_SERVER | TASK_PIPE;
info.server = (char *)socketPath;
info.socketId = -1;
info.baseInfo.close = NULL;
info.disConntectComplete = NULL;
info.incommingConntect = CmdOnIncommingConntect;
info.sendMessageComplete = NULL;
info.recvMessage = NULL;
g_controlFdFunc = func;
(void)LE_CreateStreamServer(LE_GetDefaultLoop(), &g_cmdService.serverTask, &info);
}
...@@ -56,7 +56,6 @@ bool InitSandboxWithName(const char *name); ...@@ -56,7 +56,6 @@ bool InitSandboxWithName(const char *name);
int PrepareSandbox(const char *name); int PrepareSandbox(const char *name);
int EnterSandbox(const char *name); int EnterSandbox(const char *name);
void DestroySandbox(const char *name); void DestroySandbox(const char *name);
int CheckSupportSandbox(void);
void DumpSandboxByName(const char *name); void DumpSandboxByName(const char *name);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -23,7 +23,7 @@ extern "C" { ...@@ -23,7 +23,7 @@ extern "C" {
int GetNamespaceFd(const char *nsPath); int GetNamespaceFd(const char *nsPath);
int UnshareNamespace(int nsType); int UnshareNamespace(int nsType);
int SetNamespce(int nsFd, int nsType); int SetNamespace(int nsFd, int nsType);
void InitDefaultNamespace(void); void InitDefaultNamespace(void);
int EnterDefaultNamespace(void); int EnterDefaultNamespace(void);
void CloseDefaultNamespace(void); void CloseDefaultNamespace(void);
......
...@@ -220,7 +220,7 @@ static int GetSandboxInfo(sandbox_t *sandbox, cJSON *root, const char *itemName) ...@@ -220,7 +220,7 @@ static int GetSandboxInfo(sandbox_t *sandbox, cJSON *root, const char *itemName)
} else if (strcmp(itemName, SANDBOX_SYMLINK_TAG) == 0) { } else if (strcmp(itemName, SANDBOX_SYMLINK_TAG) == 0) {
func = AddSymbolLinksToSandbox; func = AddSymbolLinksToSandbox;
} else { } else {
BEGET_LOGE("Failed %s item name is not support.", itemName); BEGET_LOGE("%s item name is not support.", itemName);
return -1; return -1;
} }
for (int i = 0; i < counts; i++) { for (int i = 0; i < counts; i++) {
...@@ -279,7 +279,7 @@ static int ParseSandboxConfig(sandbox_t *sandbox, const char *sandboxConfig) ...@@ -279,7 +279,7 @@ static int ParseSandboxConfig(sandbox_t *sandbox, const char *sandboxConfig)
static const struct SandboxMap *GetSandboxMapByName(const char *name) static const struct SandboxMap *GetSandboxMapByName(const char *name)
{ {
if (name == NULL) { if (name == NULL) {
BEGET_LOGE("Failed get sandbox map name is NULL."); BEGET_LOGE("Sandbox map name is NULL.");
return NULL; return NULL;
} }
int len = ARRAY_LENGTH(g_map); int len = ARRAY_LENGTH(g_map);
...@@ -306,7 +306,7 @@ static void InitSandbox(sandbox_t *sandbox, const char *sandboxConfig, const cha ...@@ -306,7 +306,7 @@ static void InitSandbox(sandbox_t *sandbox, const char *sandboxConfig, const cha
} }
sandbox->ns = GetNamespaceFd("/proc/self/ns/mnt"); sandbox->ns = GetNamespaceFd("/proc/self/ns/mnt");
if (sandbox->ns < 0) { if (sandbox->ns < 0) {
BEGET_LOGE("Failed get sandbox namespace fd."); BEGET_LOGE("Get sandbox namespace fd is failed");
return; return;
} }
...@@ -446,7 +446,7 @@ int PrepareSandbox(const char *name) ...@@ -446,7 +446,7 @@ int PrepareSandbox(const char *name)
BEGET_ERROR_CHECK(name != NULL, return -1, "Prepare sandbox name is NULL."); BEGET_ERROR_CHECK(name != NULL, return -1, "Prepare sandbox name is NULL.");
BEGET_ERROR_CHECK(getuid() == 0, return -1, "Current process uid is not root, exit."); BEGET_ERROR_CHECK(getuid() == 0, return -1, "Current process uid is not root, exit.");
const struct SandboxMap *map = GetSandboxMapByName(name); const struct SandboxMap *map = GetSandboxMapByName(name);
BEGET_ERROR_CHECK(map != NULL, return -1, "Failed get sandbox map by name %s.", name); BEGET_ERROR_CHECK(map != NULL, return -1, "Cannot get sandbox map by name %s.", name);
sandbox_t *sandbox = map->sandbox; sandbox_t *sandbox = map->sandbox;
BEGET_CHECK(IsValidSandbox(sandbox) == true, return -1); BEGET_CHECK(IsValidSandbox(sandbox) == true, return -1);
BEGET_INFO_CHECK(sandbox->isCreated == false, return 0, "Sandbox %s already created", sandbox->name); BEGET_INFO_CHECK(sandbox->isCreated == false, return 0, "Sandbox %s already created", sandbox->name);
...@@ -569,7 +569,7 @@ void DestroySandbox(const char *name) ...@@ -569,7 +569,7 @@ void DestroySandbox(const char *name)
} }
const struct SandboxMap *map = GetSandboxMapByName(name); const struct SandboxMap *map = GetSandboxMapByName(name);
if (map == NULL) { if (map == NULL) {
BEGET_LOGE("Failed get sandbox map by name %s.", name); BEGET_LOGE("Cannot get sandbox map by name %s.", name);
return; return;
} }
sandbox_t *sandbox = map->sandbox; sandbox_t *sandbox = map->sandbox;
...@@ -599,7 +599,7 @@ int EnterSandbox(const char *name) ...@@ -599,7 +599,7 @@ int EnterSandbox(const char *name)
} }
const struct SandboxMap *map = GetSandboxMapByName(name); const struct SandboxMap *map = GetSandboxMapByName(name);
if (map == NULL) { if (map == NULL) {
BEGET_LOGE("Failed to get sandbox map by name %s.", name); BEGET_LOGE("Cannot get sandbox map by name %s.", name);
return -1; return -1;
} }
sandbox_t *sandbox = map->sandbox; sandbox_t *sandbox = map->sandbox;
...@@ -612,8 +612,8 @@ int EnterSandbox(const char *name) ...@@ -612,8 +612,8 @@ int EnterSandbox(const char *name)
return -1; return -1;
} }
if (sandbox->ns > 0) { if (sandbox->ns > 0) {
if (SetNamespce(sandbox->ns, CLONE_NEWNS) < 0) { if (SetNamespace(sandbox->ns, CLONE_NEWNS) < 0) {
BEGET_LOGE("Failed to enter mount namespace for sandbox \' %s \', err=%d.", name, errno); BEGET_LOGE("Cannot enter mount namespace for sandbox \' %s \', err=%d.", name, errno);
return -1; return -1;
} }
} else { } else {
......
...@@ -30,7 +30,7 @@ int GetNamespaceFd(const char *nsPath) ...@@ -30,7 +30,7 @@ int GetNamespaceFd(const char *nsPath)
} }
int ns = open(nsPath, O_RDONLY | O_CLOEXEC); int ns = open(nsPath, O_RDONLY | O_CLOEXEC);
if (ns < 0) { if (ns < 0) {
BEGET_LOGE("Failed unshare namespace, err=%d", errno); BEGET_LOGE("Open default namespace failed, err=%d", errno);
return -1; return -1;
} }
return ns; return ns;
...@@ -40,25 +40,25 @@ int UnshareNamespace(int nsType) ...@@ -40,25 +40,25 @@ int UnshareNamespace(int nsType)
{ {
if (nsType == CLONE_NEWNS) { if (nsType == CLONE_NEWNS) {
if (unshare(nsType) < 0) { if (unshare(nsType) < 0) {
BEGET_LOGE("Failed unshare namespace, err=%d", errno); BEGET_LOGE("Unshare namespace failed, err=%d", errno);
return -1; return -1;
} else { } else {
return 0; return 0;
} }
} else { } else {
BEGET_LOGE("Failed unshare, type is not support"); BEGET_LOGE("Namespace type is not support");
return -1; return -1;
} }
} }
int SetNamespce(int nsFd, int nsType) int SetNamespace(int nsFd, int nsType)
{ {
if (nsFd < 0) { if (nsFd < 0) {
BEGET_LOGE("Failed get namespace fd"); BEGET_LOGE("Namespace fd is invaild");
return -1; return -1;
} }
if (nsType != CLONE_NEWNS) { if (nsType != CLONE_NEWNS) {
BEGET_LOGE("Failed get namespace type"); BEGET_LOGE("Namespace type is not support");
return -1; return -1;
} }
return setns(nsFd, nsType); return setns(nsFd, nsType);
...@@ -78,7 +78,7 @@ int EnterDefaultNamespace(void) ...@@ -78,7 +78,7 @@ int EnterDefaultNamespace(void)
if (g_defaultNs < 0) { if (g_defaultNs < 0) {
return -1; return -1;
} }
return SetNamespce(g_defaultNs, CLONE_NEWNS); return SetNamespace(g_defaultNs, CLONE_NEWNS);
} }
void CloseDefaultNamespace(void) void CloseDefaultNamespace(void)
......
...@@ -124,6 +124,7 @@ if (defined(ohos_lite)) { ...@@ -124,6 +124,7 @@ if (defined(ohos_lite)) {
"init/standard/init.c", "init/standard/init.c",
"init/standard/init_cmdexecutor.c", "init/standard/init_cmdexecutor.c",
"init/standard/init_cmds.c", "init/standard/init_cmds.c",
"init/standard/init_control_fd_service.c",
"init/standard/init_jobs.c", "init/standard/init_jobs.c",
"init/standard/init_mount.c", "init/standard/init_mount.c",
"init/standard/init_reboot.c", "init/standard/init_reboot.c",
...@@ -158,12 +159,14 @@ if (defined(ohos_lite)) { ...@@ -158,12 +159,14 @@ if (defined(ohos_lite)) {
"//base/startup/init_lite/ueventd/include", "//base/startup/init_lite/ueventd/include",
"//third_party/cJSON", "//third_party/cJSON",
"//third_party/bounds_checking_function/include", "//third_party/bounds_checking_function/include",
"//base/startup/init_lite/interfaces/innerkits/control_fd",
] ]
deps = [ deps = [
"//base/customization/config_policy/frameworks/config_policy:configpolicy_util_for_init_static", "//base/customization/config_policy/frameworks/config_policy:configpolicy_util_for_init_static",
"//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken", "//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken",
"//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc", "//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc",
"//base/startup/init_lite/interfaces/innerkits:libfsmanager_static", "//base/startup/init_lite/interfaces/innerkits:libfsmanager_static",
"//base/startup/init_lite/interfaces/innerkits/control_fd:libcontrolfd_static",
"//base/startup/init_lite/interfaces/innerkits/sandbox:libsandbox_static", "//base/startup/init_lite/interfaces/innerkits/sandbox:libsandbox_static",
"//base/startup/init_lite/services/log:init_log", "//base/startup/init_lite/services/log:init_log",
"//base/startup/init_lite/services/loopevent:loopevent", "//base/startup/init_lite/services/loopevent:loopevent",
......
...@@ -87,9 +87,11 @@ if (defined(ohos_lite)) { ...@@ -87,9 +87,11 @@ if (defined(ohos_lite)) {
"//base/startup/init_lite/services/loopevent/include", "//base/startup/init_lite/services/loopevent/include",
"//third_party/bounds_checking_function/include", "//third_party/bounds_checking_function/include",
"//base/startup/init_lite/interfaces/innerkits/sandbox/include", "//base/startup/init_lite/interfaces/innerkits/sandbox/include",
"//base/startup/init_lite/interfaces/innerkits/control_fd",
] ]
deps = [ deps = [
"//base/startup/init_lite/interfaces/innerkits:libbegetutil", "//base/startup/init_lite/interfaces/innerkits:libbegetutil",
"//base/startup/init_lite/interfaces/innerkits/control_fd:libcontrolfd",
"//base/startup/init_lite/interfaces/innerkits/sandbox:libsandbox", "//base/startup/init_lite/interfaces/innerkits/sandbox:libsandbox",
"//third_party/bounds_checking_function:libsec_shared", "//third_party/bounds_checking_function:libsec_shared",
] ]
......
文件模式从 100755 更改为 100644
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <vector> #include <vector>
#include "begetctl.h" #include "begetctl.h"
#include "control_fd.h"
#include "init_utils.h" #include "init_utils.h"
#include "sandbox.h" #include "sandbox.h"
#include "sandbox_namespace.h" #include "sandbox_namespace.h"
...@@ -32,8 +33,8 @@ ...@@ -32,8 +33,8 @@
using namespace OHOS; using namespace OHOS;
struct option g_options[] = { struct option g_options[] = {
{ "config_file", required_argument, nullptr, 'c' }, { "service_name", required_argument, nullptr, 's' },
{ "sandbox_name", required_argument, nullptr, 's' }, { "namespace_name", required_argument, nullptr, 'n' },
{ "process_name", required_argument, nullptr, 'p' }, { "process_name", required_argument, nullptr, 'p' },
{ "help", no_argument, nullptr, 'h' }, { "help", no_argument, nullptr, 'h' },
{ nullptr, 0, nullptr, 0 }, { nullptr, 0, nullptr, 0 },
...@@ -41,43 +42,17 @@ struct option g_options[] = { ...@@ -41,43 +42,17 @@ struct option g_options[] = {
static void Usage() static void Usage()
{ {
std::cout << "sandbox -c, --config_file=sandbox config file \"config file with json format\"" << std::endl; std::cout << "sandbox -s | -n [-p] | -p | -h" << std::endl;
std::cout << "sandbox -s, --sandbox_name=sandbox name \"Sandbox name, system, chipset etc.\"" << std::endl; std::cout << "sandbox -s, --service_name=sandbox service \"enter service sandbox\"" << std::endl;
std::cout << "sandbox -n, --namespace_name=namespace name \"namespace name, system, chipset etc.\"" << std::endl;
std::cout << "sandbox -p, --process=process name \"sh, hdcd, hdf_devhost, etc.\"" << std::endl; std::cout << "sandbox -p, --process=process name \"sh, hdcd, hdf_devhost, etc.\"" << std::endl;
std::cout << "sandbox -h, --help \"Show help\"" << std::endl; std::cout << "sandbox -h, --help \"Show help\"" << std::endl;
exit(0); exit(0);
} }
static std::string SearchConfigBySandboxName(const std::string &sandboxName) static void RunSandbox(const std::string &sandboxName)
{ {
std::map<std::string, std::string> sandboxConfigMap = { if (sandboxName.empty()) {
{"system", "/system/etc/system-sandbox.json"},
{"chipset", "/system/etc/chipset-sandbox.json"},
{"priv-app", "/system/etc/priv-app-sandbox.json"},
{"app", "/system/etc/app-sandbox.json"},
};
auto it = sandboxConfigMap.find(sandboxName);
if (it == sandboxConfigMap.end()) {
return "";
} else {
return it->second;
}
}
static void RunSandbox(const std::string &configFile, const std::string &name)
{
std::string config {};
std::string sandboxName {};
if (!name.empty()) {
config = SearchConfigBySandboxName(name);
sandboxName = name;
} else {
// Without sandbox name, give one.
sandboxName = "sandbox_test";
}
if (config.empty()) {
std::cout << "No sandbox name " << sandboxName << "or config file specified!" << std::endl;
return; return;
} }
InitDefaultNamespace(); InitDefaultNamespace();
...@@ -139,18 +114,21 @@ static void EnterExec(const std::string &processName) ...@@ -139,18 +114,21 @@ static void EnterExec(const std::string &processName)
return; return;
} }
static void RunCmd(const std::string &configFile, const std::string &sandboxName, const std::string &processName) static void RunCmd(const std::string &serviceName, const std::string &namespaceName, const std::string &processName)
{ {
if (!sandboxName.empty() && processName.empty()) { if (!namespaceName.empty() && processName.empty() && serviceName.empty()) {
RunSandbox(configFile, sandboxName); RunSandbox(namespaceName);
EnterShell(); EnterShell();
} else if (!sandboxName.empty() && !processName.empty()) { } else if (!namespaceName.empty() && !processName.empty() && serviceName.empty()) {
RunSandbox(configFile, sandboxName); RunSandbox(namespaceName);
EnterExec(processName); EnterExec(processName);
} else if (sandboxName.empty() && !processName.empty()) { } else if (namespaceName.empty() && !processName.empty() && serviceName.empty()) {
std::cout << "process name:" << processName << std::endl; std::cout << "process name:" << processName << std::endl;
RunSandbox(configFile, std::string("system")); RunSandbox(std::string("system"));
EnterExec(processName); EnterExec(processName);
} else if (namespaceName.empty() && processName.empty() && !serviceName.empty()) {
std::cout << "enter sandbox service name " << serviceName << std::endl;
CmdClientInit(INIT_CONTROL_FD_SOCKET_PATH, ACTION_SANDBOX, serviceName.c_str(), "FIFO");
} else { } else {
Usage(); Usage();
} }
...@@ -160,35 +138,35 @@ static int main_cmd(BShellHandle shell, int argc, char **argv) ...@@ -160,35 +138,35 @@ static int main_cmd(BShellHandle shell, int argc, char **argv)
{ {
int rc = -1; int rc = -1;
int optIndex = -1; int optIndex = -1;
std::string configFile {}; std::string serviceName {};
std::string sandboxName {}; std::string namespaceName {};
std::string processName {}; std::string processName {};
while ((rc = getopt_long(argc, argv, "c:s:p:h", g_options, &optIndex)) != -1) { while ((rc = getopt_long(argc, argv, "s:n:p:h", g_options, &optIndex)) != -1) {
switch (rc) { switch (rc) {
case 0: { case 0: {
std::string optionName = g_options[optIndex].name; std::string optionName = g_options[optIndex].name;
if (optionName == "config_file") { if (optionName == "service_name") {
configFile = optarg; serviceName = optarg;
} else if (optionName == "help") { } else if (optionName == "help") {
Usage(); Usage();
} else if (optionName == "sandbox_name") { } else if (optionName == "namespace_name") {
sandboxName = optarg; namespaceName = optarg;
} else if (optionName == "process_name") { } else if (optionName == "process_name") {
processName = optarg; processName = optarg;
} }
break; break;
} }
case 'c': case 's':
configFile = optarg; serviceName = optarg;
break; break;
case 'h': case 'h':
Usage(); Usage();
break; break;
case 's': case 'n':
sandboxName = optarg; namespaceName = optarg;
break; break;
case 'p': case 'p':
std::cout << "1111 process name:" << optarg << std::endl; std::cout << "process name:" << optarg << std::endl;
processName = optarg; processName = optarg;
break; break;
case '?': case '?':
...@@ -199,7 +177,7 @@ static int main_cmd(BShellHandle shell, int argc, char **argv) ...@@ -199,7 +177,7 @@ static int main_cmd(BShellHandle shell, int argc, char **argv)
break; break;
} }
} }
RunCmd(configFile, sandboxName, processName); RunCmd(serviceName, namespaceName, processName);
return 0; return 0;
} }
...@@ -207,8 +185,18 @@ MODULE_CONSTRUCTOR(void) ...@@ -207,8 +185,18 @@ MODULE_CONSTRUCTOR(void)
{ {
CmdInfo infos[] = { CmdInfo infos[] = {
{ {
(char *)"sandbox", main_cmd, (char *)"sandbox debug tool", (char *)"sandbox", main_cmd, (char *)"enter service sandbox",
(char *)"sandbox -s, --sandbox=system, chipset, priv-app, or app", (char *)"sandbox -s service_name",
NULL
},
{
(char *)"sandbox", main_cmd, (char *)"enter namespace, system, chipset etc.",
(char *)"sandbox -n namespace_name [-p]",
NULL
},
{
(char *)"sandbox", main_cmd, (char *)"enter namespace and exec process",
(char *)"sandbox -p process_name",
NULL NULL
} }
}; };
......
文件模式从 100755 更改为 100644
...@@ -59,6 +59,7 @@ size_t WriteAll(int fd, const char *buffer, size_t size); ...@@ -59,6 +59,7 @@ size_t WriteAll(int fd, const char *buffer, size_t size);
char *GetRealPath(const char *source); char *GetRealPath(const char *source);
int StringToInt(const char *str, int defaultValue); int StringToInt(const char *str, int defaultValue);
int MakeDirRecursive(const char *dir, mode_t mode); int MakeDirRecursive(const char *dir, mode_t mode);
void CheckAndCreateDir(const char *fileName);
int MakeDir(const char *dir, mode_t mode); int MakeDir(const char *dir, mode_t mode);
int ReadFileInDir(const char *dirPath, const char *includeExt, int ReadFileInDir(const char *dirPath, const char *includeExt,
int (*processFile)(const char *fileName, void *context), void *context); int (*processFile)(const char *fileName, void *context), void *context);
......
文件模式从 100755 更改为 100644
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CONTROL_FD_SERVICE_H
#define CONTROL_FD_SERVICE_H
void InitControlFd(void);
#endif
\ No newline at end of file
文件模式从 100755 更改为 100644
...@@ -173,7 +173,7 @@ int SetAccessToken(const Service *service); ...@@ -173,7 +173,7 @@ int SetAccessToken(const Service *service);
void GetAccessToken(void); void GetAccessToken(void);
void ServiceStopTimer(Service *service); void ServiceStopTimer(Service *service);
void ServiceStartTimer(Service *service, uint64_t timeout); void ServiceStartTimer(Service *service, uint64_t timeout);
void EnterServiceSandbox(Service *service);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
...@@ -66,6 +66,7 @@ Service *AddService(const char *name); ...@@ -66,6 +66,7 @@ Service *AddService(const char *name);
#ifdef OHOS_SERVICE_DUMP #ifdef OHOS_SERVICE_DUMP
void DumpAllServices(); void DumpAllServices();
void DumpOneService(const Service *service);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
......
文件模式从 100755 更改为 100644
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <sys/capability.h> #include <sys/capability.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/resource.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
...@@ -278,38 +279,19 @@ static void ClearEnvironment(Service *service) ...@@ -278,38 +279,19 @@ static void ClearEnvironment(Service *service)
return; return;
} }
int ServiceStart(Service *service) static int InitServicePropertys(Service *service)
{ {
INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "start service failed! null ptr."); INIT_ERROR_CHECK(service != NULL, return -1, "Invaild parameter.");
INIT_ERROR_CHECK(service->pid <= 0, return SERVICE_SUCCESS, "service : %s had started already.", service->name);
INIT_ERROR_CHECK(service->pathArgs.count > 0,
return SERVICE_FAILURE, "start service %s pathArgs is NULL.", service->name);
if (service->attribute & SERVICE_ATTR_INVALID) {
INIT_LOGE("start service %s invalid.", service->name);
return SERVICE_FAILURE;
}
struct stat pathStat = { 0 };
service->attribute &= (~(SERVICE_ATTR_NEED_RESTART | SERVICE_ATTR_NEED_STOP));
if (stat(service->pathArgs.argv[0], &pathStat) != 0) {
service->attribute |= SERVICE_ATTR_INVALID;
INIT_LOGE("start service %s invalid, please check %s.", service->name, service->pathArgs.argv[0]);
return SERVICE_FAILURE;
}
int pid = fork();
if (pid == 0) {
SetServiceEnterSandbox(service->pathArgs.argv[0], service->attribute); SetServiceEnterSandbox(service->pathArgs.argv[0], service->attribute);
INIT_CHECK_ONLY_ELOG(SetAccessToken(service) == SERVICE_SUCCESS, "access token failed %s", service->name); INIT_CHECK_ONLY_ELOG(SetAccessToken(service) == SERVICE_SUCCESS, "access token failed %s", service->name);
// deal start job // deal start job
if (service->serviceJobs.jobsName[JOB_ON_START] != NULL) { if (service->serviceJobs.jobsName[JOB_ON_START] != NULL) {
DoJobNow(service->serviceJobs.jobsName[JOB_ON_START]); DoJobNow(service->serviceJobs.jobsName[JOB_ON_START]);
} }
ClearEnvironment(service); ClearEnvironment(service);
if (!IsOnDemandService(service)) { if (!IsOnDemandService(service)) {
INIT_ERROR_CHECK(CreateServiceSocket(service) >= 0, return SERVICE_FAILURE, INIT_ERROR_CHECK(CreateServiceSocket(service) >= 0, return -1,
"service %s exit! create socket failed!", service->name); "service %s exit! create socket failed!", service->name);
} }
...@@ -317,6 +299,7 @@ int ServiceStart(Service *service) ...@@ -317,6 +299,7 @@ int ServiceStart(Service *service)
if (service->attribute & SERVICE_ATTR_CONSOLE) { if (service->attribute & SERVICE_ATTR_CONSOLE) {
OpenConsole(); OpenConsole();
} }
PublishHoldFds(service); PublishHoldFds(service);
INIT_CHECK_ONLY_ELOG(BindCpuCore(service) == SERVICE_SUCCESS, INIT_CHECK_ONLY_ELOG(BindCpuCore(service) == SERVICE_SUCCESS,
"binding core number failed for service %s", service->name); "binding core number failed for service %s", service->name);
...@@ -327,6 +310,47 @@ int ServiceStart(Service *service) ...@@ -327,6 +310,47 @@ int ServiceStart(Service *service)
INIT_ERROR_CHECK(WritePid(service) == SERVICE_SUCCESS, _exit(PROCESS_EXIT_CODE), INIT_ERROR_CHECK(WritePid(service) == SERVICE_SUCCESS, _exit(PROCESS_EXIT_CODE),
"service %s exit! write pid failed!", service->name); "service %s exit! write pid failed!", service->name);
SetSecon(service); SetSecon(service);
return 0;
}
void EnterServiceSandbox(Service *service)
{
INIT_ERROR_CHECK(InitServicePropertys(service) == 0, return, "Failed init service property");
if (service->importance != 0) {
if (setpriority(PRIO_PROCESS, 0, service->importance) != 0) {
INIT_LOGE("setpriority failed for %s, importance = %d, err=%d",
service->name, service->importance, errno);
_exit(0x7f); // 0x7f: user specified
}
}
INIT_CHECK_ONLY_ELOG(unsetenv("UV_THREADPOOL_SIZE") == 0, "set UV_THREADPOOL_SIZE error : %d.", errno);
char *argv[] = { (char *)"/bin/sh", NULL };
INIT_CHECK_ONLY_ELOG(execv(argv[0], argv) == 0,
"service %s execv sh failed! err %d.", service->name, errno);
_exit(PROCESS_EXIT_CODE);
}
int ServiceStart(Service *service)
{
INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "start service failed! null ptr.");
INIT_ERROR_CHECK(service->pid <= 0, return SERVICE_SUCCESS, "service : %s had started already.", service->name);
INIT_ERROR_CHECK(service->pathArgs.count > 0,
return SERVICE_FAILURE, "start service %s pathArgs is NULL.", service->name);
if (service->attribute & SERVICE_ATTR_INVALID) {
INIT_LOGE("start service %s invalid.", service->name);
return SERVICE_FAILURE;
}
struct stat pathStat = { 0 };
service->attribute &= (~(SERVICE_ATTR_NEED_RESTART | SERVICE_ATTR_NEED_STOP));
if (stat(service->pathArgs.argv[0], &pathStat) != 0) {
service->attribute |= SERVICE_ATTR_INVALID;
INIT_LOGE("start service %s invalid, please check %s.", service->name, service->pathArgs.argv[0]);
return SERVICE_FAILURE;
}
int pid = fork();
if (pid == 0) {
INIT_ERROR_CHECK(InitServicePropertys(service) == 0, return SERVICE_FAILURE, "Failed init service property");
ServiceExec(service); ServiceExec(service);
_exit(PROCESS_EXIT_CODE); _exit(PROCESS_EXIT_CODE);
} else if (pid < 0) { } else if (pid < 0) {
......
...@@ -46,45 +46,45 @@ static const int CRITICAL_CONFIG_ARRAY_LEN = 3; ...@@ -46,45 +46,45 @@ static const int CRITICAL_CONFIG_ARRAY_LEN = 3;
#ifdef OHOS_SERVICE_DUMP #ifdef OHOS_SERVICE_DUMP
static void DumpServiceArgs(const char *info, const ServiceArgs *args) static void DumpServiceArgs(const char *info, const ServiceArgs *args)
{ {
INIT_LOGI("\tservice %s count %d", info, args->count); printf("\tservice %s count %d", info, args->count);
for (int j = 0; j < args->count; j++) { for (int j = 0; j < args->count; j++) {
if (args->argv[j] != NULL) { if (args->argv[j] != NULL) {
INIT_LOGI("\t\tinfo [%d] %s", j, args->argv[j]); printf("\t\tinfo [%d] %s", j, args->argv[j]);
} }
} }
} }
static void DumpServiceJobs(const Service *service) static void DumpServiceJobs(const Service *service)
{ {
INIT_LOGI("\tservice job info"); printf("\tservice job info");
if (service->serviceJobs.jobsName[JOB_ON_BOOT] != NULL) { if (service->serviceJobs.jobsName[JOB_ON_BOOT] != NULL) {
INIT_LOGI("\t\tservice boot job %s", service->serviceJobs.jobsName[JOB_ON_BOOT]); printf("\t\tservice boot job %s", service->serviceJobs.jobsName[JOB_ON_BOOT]);
} }
if (service->serviceJobs.jobsName[JOB_ON_START] != NULL) { if (service->serviceJobs.jobsName[JOB_ON_START] != NULL) {
INIT_LOGI("\t\tservice start job %s", service->serviceJobs.jobsName[JOB_ON_START]); printf("\t\tservice start job %s", service->serviceJobs.jobsName[JOB_ON_START]);
} }
if (service->serviceJobs.jobsName[JOB_ON_STOP] != NULL) { if (service->serviceJobs.jobsName[JOB_ON_STOP] != NULL) {
INIT_LOGI("\t\tservice stop job %s", service->serviceJobs.jobsName[JOB_ON_STOP]); printf("\t\tservice stop job %s", service->serviceJobs.jobsName[JOB_ON_STOP]);
} }
if (service->serviceJobs.jobsName[JOB_ON_RESTART] != NULL) { if (service->serviceJobs.jobsName[JOB_ON_RESTART] != NULL) {
INIT_LOGI("\t\tservice restart job %s", service->serviceJobs.jobsName[JOB_ON_RESTART]); printf("\t\tservice restart job %s", service->serviceJobs.jobsName[JOB_ON_RESTART]);
} }
} }
static void DumpServiceSocket(const Service *service) static void DumpServiceSocket(const Service *service)
{ {
INIT_LOGI("\tservice socket info"); printf("\tservice socket info");
ServiceSocket *sockopt = service->socketCfg; ServiceSocket *sockopt = service->socketCfg;
while (sockopt != NULL) { while (sockopt != NULL) {
INIT_LOGI("\t\tsocket name: %s", sockopt->name); printf("\t\tsocket name: %s", sockopt->name);
INIT_LOGI("\t\tsocket type: %d", sockopt->type); printf("\t\tsocket type: %d", sockopt->type);
INIT_LOGI("\t\tsocket uid: %d", sockopt->uid); printf("\t\tsocket uid: %d", sockopt->uid);
INIT_LOGI("\t\tsocket gid: %d", sockopt->gid); printf("\t\tsocket gid: %d", sockopt->gid);
sockopt = sockopt->next; sockopt = sockopt->next;
} }
} }
void DumpAllServices() void DumpOneService(const Service *service)
{ {
const InitArgInfo startModeMap[] = { const InitArgInfo startModeMap[] = {
{"condition", START_MODE_CONDITION}, {"condition", START_MODE_CONDITION},
...@@ -93,39 +93,44 @@ void DumpAllServices() ...@@ -93,39 +93,44 @@ void DumpAllServices()
}; };
int size = 0; int size = 0;
const InitArgInfo *statusMap = GetServieStatusMap(&size); const InitArgInfo *statusMap = GetServieStatusMap(&size);
INIT_LOGI("Ready to dump all services:"); printf("\tservice name: [%s]", service->name);
INIT_LOGI("total service number: %d", g_serviceSpace.serviceCount); printf("\tservice pid: [%d]", service->pid);
InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL); printf("\tservice crashCnt: [%d]", service->crashCnt);
while (node != NULL) { printf("\tservice attribute: [%d]", service->attribute);
if (node->data.service == NULL) { printf("\tservice importance: [%d]", service->importance);
node = GetNextGroupNode(NODE_TYPE_SERVICES, node); printf("\tservice startMode: [%s]", startModeMap[service->status].name);
continue; printf("\tservice status: [%s]", statusMap[service->status].name);
} printf("\tservice perms uID [%d]", service->servPerm.uID);
Service *service = node->data.service;
INIT_LOGI("\tservice name: [%s]", service->name);
INIT_LOGI("\tservice pid: [%d]", service->pid);
INIT_LOGI("\tservice crashCnt: [%d]", service->crashCnt);
INIT_LOGI("\tservice attribute: [%d]", service->attribute);
INIT_LOGI("\tservice importance: [%d]", service->importance);
INIT_LOGI("\tservice startMode: [%s]", startModeMap[service->status].name);
INIT_LOGI("\tservice status: [%s]", statusMap[service->status].name);
INIT_LOGI("\tservice perms uID [%d]", service->servPerm.uID);
DumpServiceArgs("path arg", &service->pathArgs); DumpServiceArgs("path arg", &service->pathArgs);
DumpServiceArgs("writepid file", &service->writePidArgs); DumpServiceArgs("writepid file", &service->writePidArgs);
DumpServiceJobs(service); DumpServiceJobs(service);
DumpServiceSocket(service); DumpServiceSocket(service);
INIT_LOGI("\tservice perms groupId %d", service->servPerm.gIDCnt); printf("\tservice perms groupId %d", service->servPerm.gIDCnt);
for (int i = 0; i < service->servPerm.gIDCnt; i++) { for (int i = 0; i < service->servPerm.gIDCnt; i++) {
INIT_LOGI("\t\tservice perms groupId %d", service->servPerm.gIDArray[i]); printf("\t\tservice perms groupId %d", service->servPerm.gIDArray[i]);
} }
INIT_LOGI("\tservice perms capability %d", service->servPerm.capsCnt); printf("\tservice perms capability %d", service->servPerm.capsCnt);
for (int i = 0; i < (int)service->servPerm.capsCnt; i++) { for (int i = 0; i < (int)service->servPerm.capsCnt; i++) {
INIT_LOGI("\t\tservice perms capability %d", service->servPerm.caps[i]); printf("\t\tservice perms capability %d", service->servPerm.caps[i]);
} }
}
void DumpAllServices()
{
printf("Ready to dump all services:");
printf("total service number: %d", g_serviceSpace.serviceCount);
InitGroupNode *node = GetNextGroupNode(NODE_TYPE_SERVICES, NULL);
while (node != NULL) {
if (node->data.service == NULL) {
node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
continue;
}
Service *service = node->data.service;
DumpOneService(service);
node = GetNextGroupNode(NODE_TYPE_SERVICES, node); node = GetNextGroupNode(NODE_TYPE_SERVICES, node);
} }
INIT_LOGI("Dump all services finished"); printf("Dump all services finished");
} }
#endif #endif
......
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "device.h" #include "device.h"
#include "fd_holder_service.h" #include "fd_holder_service.h"
#include "fs_manager/fs_manager.h" #include "fs_manager/fs_manager.h"
#include "init_control_fd_service.h"
#include "init_log.h" #include "init_log.h"
#include "init_mount.h" #include "init_mount.h"
#include "init_group_manager.h" #include "init_group_manager.h"
...@@ -106,6 +107,7 @@ void SystemInit(void) ...@@ -106,6 +107,7 @@ void SystemInit(void)
if (sock >= 0) { if (sock >= 0) {
RegisterFdHoldWatcher(sock); RegisterFdHoldWatcher(sock);
} }
InitControlFd();
} }
static void EnableDevKmsg(void) static void EnableDevKmsg(void)
...@@ -392,15 +394,15 @@ void SetServiceEnterSandbox(const char *execPath, unsigned int attribute) ...@@ -392,15 +394,15 @@ void SetServiceEnterSandbox(const char *execPath, unsigned int attribute)
} else if (strcmp(execPath, "/system/bin/hilogd") == 0) { } else if (strcmp(execPath, "/system/bin/hilogd") == 0) {
INIT_LOGI("Hilogd skip enter sandbox."); INIT_LOGI("Hilogd skip enter sandbox.");
} else { } else {
INIT_ERROR_CHECK(EnterSandbox("system") == 0, return, INIT_INFO_CHECK(EnterSandbox("system") == 0, return,
"Service %s failed enter sandbox system.", execPath); "Service %s skip enter sandbox system.", execPath);
} }
} else if (strncmp(execPath, "/vendor/bin/", strlen("/vendor/bin/")) == 0) { } else if (strncmp(execPath, "/vendor/bin/", strlen("/vendor/bin/")) == 0) {
// chipset sandbox will be implemented later. // chipset sandbox will be implemented later.
INIT_ERROR_CHECK(EnterSandbox("system") == 0, return, INIT_INFO_CHECK(EnterSandbox("system") == 0, return,
"Service %s failed enter sandbox system.", execPath); "Service %s skip enter sandbox system.", execPath);
} else { } else {
INIT_LOGE("Service %s does not enter sandbox", execPath); INIT_LOGI("Service %s does not enter sandbox", execPath);
} }
return; return;
} }
文件模式从 100755 更改为 100644
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "control_fd.h"
#include "init_service.h"
#include "init_service_manager.h"
#include "init_utils.h"
#include "init_log.h"
static void ProcessSandboxControlFd(uint16_t type, const char *serviceCmd)
{
if ((type != ACTION_SANDBOX) || (serviceCmd == NULL)) {
INIT_LOGE("Invaild parameter");
return;
}
Service *service = GetServiceByName(serviceCmd);
if (service == NULL) {
INIT_LOGE("Failed get service %s", serviceCmd);
return;
}
EnterServiceSandbox(service);
return;
}
static void ProcessDumpServiceControlFd(uint16_t type, const char *serviceCmd)
{
if ((type != ACTION_DUMP) || (serviceCmd == NULL)) {
return;
}
Service *service = GetServiceByName(serviceCmd);
if (service == NULL) {
#ifdef OHOS_SERVICE_DUMP
DumpAllServices();
} else {
DumpOneService(service);
#endif
}
return;
}
static void ProcessParamShellControlFd(uint16_t type, const char *serviceCmd)
{
if ((type != ACTION_PARAM_SHELL) || (serviceCmd == NULL)) {
return;
}
(void)setuid(2000); // 2000 shell group
(void)setgid(2000); // 2000 shell group
char *args[] = {(char *)serviceCmd, NULL};
int ret = execv(args[0], args);
if (ret < 0) {
INIT_LOGE("error on exec %d \n", errno);
exit(-1);
}
exit(0);
}
void ProcessControlFd(uint16_t type, const char *serviceCmd, const void *context)
{
if ((type >= ACTION_MAX) || (serviceCmd == NULL)) {
return;
}
switch (type) {
case ACTION_SANDBOX :
ProcessSandboxControlFd(type, serviceCmd);
break;
case ACTION_DUMP :
ProcessDumpServiceControlFd(type, serviceCmd);
break;
case ACTION_PARAM_SHELL :
ProcessParamShellControlFd(type, serviceCmd);
break;
default :
INIT_LOGW("Unknown control fd type.");
break;
}
}
void InitControlFd(void)
{
CmdServiceInit(INIT_CONTROL_FD_SOCKET_PATH, ProcessControlFd);
return;
}
...@@ -69,23 +69,10 @@ static int CreatePipeSocket_(const char *server) ...@@ -69,23 +69,10 @@ static int CreatePipeSocket_(const char *server)
LE_CHECK(ret == 0, close(fd); LE_CHECK(ret == 0, close(fd);
return ret, "Failed to memset_s serverAddr"); return ret, "Failed to memset_s serverAddr");
serverAddr.sun_family = AF_UNIX; serverAddr.sun_family = AF_UNIX;
// bind local
ret = sprintf_s(serverAddr.sun_path, sizeof(serverAddr.sun_path), "%s_%d", server, getpid());
LE_CHECK(ret > 0, close(fd);
return ret, "Failed to sprintf_s sun_path");
uint32_t size = offsetof(struct sockaddr_un, sun_path) + strlen(serverAddr.sun_path);
ret = bind(fd, (struct sockaddr *)&serverAddr, size);
LE_CHECK(ret >= 0, close(fd);
return ret, "Failed to bind socket");
ret = memset_s(&serverAddr, sizeof(serverAddr), 0, sizeof(serverAddr));
LE_CHECK(ret == 0, close(fd);
return ret, "Failed to memset_s serverAddr");
serverAddr.sun_family = AF_UNIX;
ret = strcpy_s(serverAddr.sun_path, sizeof(serverAddr.sun_path), server); ret = strcpy_s(serverAddr.sun_path, sizeof(serverAddr.sun_path), server);
LE_CHECK(ret == 0, close(fd); LE_CHECK(ret == 0, close(fd);
return ret, "Failed to strcpy_s sun_path"); return ret, "Failed to strcpy_s sun_path");
size = offsetof(struct sockaddr_un, sun_path) + strlen(serverAddr.sun_path); uint32_t size = offsetof(struct sockaddr_un, sun_path) + strlen(serverAddr.sun_path);
ret = connect(fd, (struct sockaddr *)&serverAddr, size); ret = connect(fd, (struct sockaddr *)&serverAddr, size);
LE_CHECK(ret >= 0, close(fd); LE_CHECK(ret >= 0, close(fd);
return ret, "Failed to connect socket"); return ret, "Failed to connect socket");
......
...@@ -349,6 +349,25 @@ int MakeDirRecursive(const char *dir, mode_t mode) ...@@ -349,6 +349,25 @@ int MakeDirRecursive(const char *dir, mode_t mode)
return MakeDir(dir, mode); return MakeDir(dir, mode);
} }
void CheckAndCreateDir(const char *fileName)
{
#ifndef __LITEOS_M__
if (fileName == NULL || *fileName == '\0') {
return;
}
char *path = strndup(fileName, strrchr(fileName, '/') - fileName);
if (path == NULL) {
return;
}
if (access(path, F_OK) == 0) {
free(path);
return;
}
MakeDirRecursive(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
free(path);
#endif
}
int StringToInt(const char *str, int defaultValue) int StringToInt(const char *str, int defaultValue)
{ {
if (str == NULL || *str == '\0') { if (str == NULL || *str == '\0') {
......
文件模式从 100755 更改为 100644
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册