未验证 提交 c1aadec3 编写于 作者: O openharmony_ci 提交者: Gitee

!1201 console 服务配置为动态拉起

Merge pull request !1201 from cheng_jinsong/init_console
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
"sandbox" : 0, "sandbox" : 0,
"uid" : "root", "uid" : "root",
"gid" : ["shell", "log", "readproc"], "gid" : ["shell", "log", "readproc"],
"ondemand" : true,
"jobs" : { "jobs" : {
"on-start" : "services:console" "on-start" : "services:console"
}, },
......
...@@ -212,12 +212,6 @@ ...@@ -212,12 +212,6 @@
"cmds" : [ "cmds" : [
"write /proc/sys/kernel/perf_event_paranoid 3" "write /proc/sys/kernel/perf_event_paranoid 3"
] ]
}, {
"name" : "boot && param:const.debuggable=1",
"condition" : "boot && const.debuggable=1",
"cmds" : [
"start console"
]
}, { }, {
"name" : "services:console", "name" : "services:console",
"cmds" : [ "cmds" : [
......
...@@ -42,6 +42,7 @@ typedef struct { ...@@ -42,6 +42,7 @@ typedef struct {
#define WAIT_MAX_SECOND 5 #define WAIT_MAX_SECOND 5
#define MAX_BUFFER_LEN 256 #define MAX_BUFFER_LEN 256
#define CMDLINE_VALUE_LEN_MAX 512 #define CMDLINE_VALUE_LEN_MAX 512
#define STDERR_HANDLE 2
#define ARRAY_LENGTH(array) (sizeof((array)) / sizeof((array)[0])) #define ARRAY_LENGTH(array) (sizeof((array)) / sizeof((array)[0]))
#ifndef STARTUP_INIT_UT_PATH #ifndef STARTUP_INIT_UT_PATH
...@@ -83,7 +84,8 @@ char *TrimHead(char *str, char c); ...@@ -83,7 +84,8 @@ char *TrimHead(char *str, char c);
INIT_LOCAL_API int StringToULL(const char *str, unsigned long long int *out); INIT_LOCAL_API int StringToULL(const char *str, unsigned long long int *out);
INIT_LOCAL_API int StringToLL(const char *str, long long int *out); INIT_LOCAL_API int StringToLL(const char *str, long long int *out);
void CloseStdio(void);
void RedirectStdio(int fd);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
...@@ -29,7 +29,6 @@ extern "C" { ...@@ -29,7 +29,6 @@ extern "C" {
void MountBasicFs(void); void MountBasicFs(void);
void CreateDeviceNode(void); void CreateDeviceNode(void);
void CloseStdio(void);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
......
...@@ -67,6 +67,12 @@ extern "C" { ...@@ -67,6 +67,12 @@ extern "C" {
#define IsOnDemandService(service) \ #define IsOnDemandService(service) \
(((service)->attribute & SERVICE_ATTR_ONDEMAND) == SERVICE_ATTR_ONDEMAND) (((service)->attribute & SERVICE_ATTR_ONDEMAND) == SERVICE_ATTR_ONDEMAND)
#define MarkServiceAsOndemand(service) \
((service)->attribute |= SERVICE_ATTR_ONDEMAND)
#define UnMarkServiceAsOndemand(service) \
((service)->attribute &= ~SERVICE_ATTR_ONDEMAND)
#define IsServiceWithTimerEnabled(service) \ #define IsServiceWithTimerEnabled(service) \
(((service)->attribute & SERVICE_ATTR_TIMERSTART) == SERVICE_ATTR_TIMERSTART) (((service)->attribute & SERVICE_ATTR_TIMERSTART) == SERVICE_ATTR_TIMERSTART)
......
...@@ -64,6 +64,7 @@ Service *AddService(const char *name); ...@@ -64,6 +64,7 @@ Service *AddService(const char *name);
void DumpServiceHookExecute(const char *name, const char *info); void DumpServiceHookExecute(const char *name, const char *info);
void ProcessControlFd(uint16_t type, const char *serviceCmd, const void *context); void ProcessControlFd(uint16_t type, const char *serviceCmd, const void *context);
int GetKillServiceSig(const char *name); int GetKillServiceSig(const char *name);
int WatchConsoleDevice(Service *service);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
...@@ -308,8 +308,12 @@ static int InitServicePropertys(Service *service) ...@@ -308,8 +308,12 @@ static int InitServicePropertys(Service *service)
} }
CreateServiceFile(service->fileCfg); CreateServiceFile(service->fileCfg);
if (service->attribute & SERVICE_ATTR_CONSOLE) { if ((service->attribute & SERVICE_ATTR_CONSOLE)) {
OpenConsole(); if (strcmp(service->name, "console") != 0 || !IsOnDemandService(service)) {
OpenConsole();
} else {
setsid();
}
} }
PublishHoldFds(service); PublishHoldFds(service);
...@@ -317,7 +321,7 @@ static int InitServicePropertys(Service *service) ...@@ -317,7 +321,7 @@ static int InitServicePropertys(Service *service)
"binding core number failed for service %s", service->name); "binding core number failed for service %s", service->name);
SetSystemSeccompPolicy(service); SetSystemSeccompPolicy(service);
// permissions // permissions
INIT_ERROR_CHECK(SetPerms(service) == SERVICE_SUCCESS, return -1, INIT_ERROR_CHECK(SetPerms(service) == SERVICE_SUCCESS, return -1,
"service %s exit! set perms failed! err %d.", service->name, errno); "service %s exit! set perms failed! err %d.", service->name, errno);
...@@ -524,9 +528,15 @@ void ServiceReap(Service *service) ...@@ -524,9 +528,15 @@ void ServiceReap(Service *service)
return; return;
} }
} }
// service no need to restart which socket managed by init until socket message detected // service no need to restart if it is an ondemand service.
if (IsOnDemandService(service)) { if (IsOnDemandService(service)) {
CheckServiceSocket(service); CheckServiceSocket(service);
if (strcmp(service->name, "console") == 0) {
if (WatchConsoleDevice(service) < 0) {
INIT_LOGE("Failed to watch console service after it exit, mark console service invalid");
service->attribute |= SERVICE_ATTR_INVALID;
}
}
return; return;
} }
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h> #include <unistd.h>
#include <sys/ioctl.h>
#include "cJSON.h" #include "cJSON.h"
#include "init.h" #include "init.h"
#include "init_group_manager.h" #include "init_group_manager.h"
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "init_utils.h" #include "init_utils.h"
#include "securec.h" #include "securec.h"
#include "service_control.h" #include "service_control.h"
#include "sys_param.h"
#ifdef ASAN_DETECTOR #ifdef ASAN_DETECTOR
#include "init_param.h" #include "init_param.h"
#endif #endif
...@@ -872,6 +873,90 @@ static void ParseServiceHookExecute(const char *name, const cJSON *serviceNode) ...@@ -872,6 +873,90 @@ static void ParseServiceHookExecute(const char *name, const cJSON *serviceNode)
} }
#endif #endif
static void ProcessConsoleEvent(const WatcherHandle handler, int fd, uint32_t *events, const void *context)
{
Service *service = (Service *)context;
LE_RemoveWatcher(LE_GetDefaultLoop(), (WatcherHandle)handler);
if (fd < 0 || service == NULL) {
INIT_LOGE("Process console event with invalid arguments");
return;
}
if (strcmp(service->name, "console") != 0) {
INIT_LOGE("Process console event with invalid service %s, only console service should do this", service->name);
return;
}
// Check if debuggable
char value[MAX_BUFFER_LEN] = {0};
unsigned int len = MAX_BUFFER_LEN;
if (SystemReadParam("const.debuggable", value, &len) != 0) {
INIT_LOGE("Failed to read parameter \'const.debuggable\', prevent console service starting");
CloseStdio();
return;
}
int isDebug = StringToInt(value, 0);
if (isDebug != 1) {
INIT_LOGI("Non-debuggable system, prevent console service starting");
CloseStdio();
return;
}
ioctl(fd, TIOCSCTTY, 0);
RedirectStdio(fd);
close(fd);
if (ServiceStart(service) != SERVICE_SUCCESS) {
INIT_LOGE("Start console service failed");
}
return;
}
static int AddFileDescriptorToWatcher(int fd, Service *service)
{
if (fd < 0 || service == NULL) {
return -1;
}
WatcherHandle watcher = NULL;
LE_WatchInfo info = {};
info.fd = fd;
info.flags = 0; // WATCHER_ONCE;
info.events = Event_Read;
info.processEvent = ProcessConsoleEvent;
int ret = LE_StartWatcher(LE_GetDefaultLoop(), &watcher, &info, service);
if (ret != LE_SUCCESS) {
INIT_LOGE("Failed to watch console device for service \' %s \'", service->name);
return -1;
}
return 0;
}
int WatchConsoleDevice(Service *service)
{
if (service == NULL) {
return -1;
}
int fd = open("/dev/console", O_RDWR);
if (fd < 0) {
if (errno == ENOENT) {
INIT_LOGW("/dev/console is not exist, wait for it...");
WaitForFile("/dev/console", WAIT_MAX_SECOND);
fd = open("/dev/console", O_RDWR);
if (fd < 0) {
INIT_LOGW("Failed to open /dev/console after try 1 time");
return -1;
}
}
}
if (AddFileDescriptorToWatcher(fd, service) < 0) {
close(fd);
return -1;
}
return 0;
}
void ParseAllServices(const cJSON *fileRoot) void ParseAllServices(const cJSON *fileRoot)
{ {
int servArrSize = 0; int servArrSize = 0;
...@@ -916,6 +1001,14 @@ void ParseAllServices(const cJSON *fileRoot) ...@@ -916,6 +1001,14 @@ void ParseAllServices(const cJSON *fileRoot)
service->fileCfg = NULL; service->fileCfg = NULL;
} }
// Watch "/dev/console" node for starting console service ondemand.
if ((strcmp(service->name, "console") == 0) && IsOnDemandService(service)) {
if (WatchConsoleDevice(service) < 0) {
INIT_LOGW("Failed to watch \'/dev/console\' device");
INIT_LOGW("Remove service \' %s \' ondemand attribute", service->name);
UnMarkServiceAsOndemand(service);
}
}
#ifndef OHOS_LITE #ifndef OHOS_LITE
/* /*
* Execute service parsing hooks * Execute service parsing hooks
......
...@@ -25,19 +25,6 @@ ...@@ -25,19 +25,6 @@
#define DEFAULT_RW_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) #define DEFAULT_RW_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
#define DEFAULT_NO_AUTHORITY_MODE (S_IWUSR | S_IRUSR) #define DEFAULT_NO_AUTHORITY_MODE (S_IWUSR | S_IRUSR)
#define STDERR_HANDLE 2
void CloseStdio(void)
{
int fd = open("/dev/null", O_RDWR | O_CLOEXEC);
if (fd < 0) {
return;
}
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, STDERR_HANDLE);
close(fd);
}
void MountBasicFs(void) void MountBasicFs(void)
{ {
......
...@@ -160,6 +160,20 @@ char *ReadFileToBuf(const char *configFile) ...@@ -160,6 +160,20 @@ char *ReadFileToBuf(const char *configFile)
return buffer; return buffer;
} }
void CloseStdio(void)
{
#ifndef __LITEOS_M__
int fd = open("/dev/null", O_RDWR | O_CLOEXEC);
if (fd < 0) {
return;
}
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, STDERR_HANDLE);
close(fd);
#endif
}
char *ReadFileData(const char *fileName) char *ReadFileData(const char *fileName)
{ {
if (fileName == NULL) { if (fileName == NULL) {
...@@ -531,18 +545,25 @@ uint32_t GetRandom() ...@@ -531,18 +545,25 @@ uint32_t GetRandom()
return ulSeed; return ulSeed;
} }
void OpenConsole(void) void RedirectStdio(int fd)
{ {
#ifndef __LITEOS_M__ #ifndef __LITEOS_M__
const int stdError = 2; const int stdError = 2;
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, stdError); // Redirect fd to 0, 1, 2
#endif
}
void OpenConsole(void)
{
#ifndef __LITEOS_M__
setsid(); setsid();
WaitForFile("/dev/console", WAIT_MAX_SECOND); WaitForFile("/dev/console", WAIT_MAX_SECOND);
int fd = open("/dev/console", O_RDWR); int fd = open("/dev/console", O_RDWR);
if (fd >= 0) { if (fd >= 0) {
ioctl(fd, TIOCSCTTY, 0); ioctl(fd, TIOCSCTTY, 0);
dup2(fd, 0); RedirectStdio(fd);
dup2(fd, 1);
dup2(fd, stdError); // Redirect fd to 0, 1, 2
close(fd); close(fd);
} else { } else {
INIT_LOGE("Open /dev/console failed. err = %d", errno); INIT_LOGE("Open /dev/console failed. err = %d", errno);
......
...@@ -134,8 +134,10 @@ typedef struct { ...@@ -134,8 +134,10 @@ typedef struct {
#define DEV_NODE_PATH_PREFIX_LEN 5 #define DEV_NODE_PATH_PREFIX_LEN 5
static const DYNAMIC_DEVICE_NODE dynamicDevices[] = { static const DYNAMIC_DEVICE_NODE dynamicDevices[] = {
{ DEV_NODE_PATH_PREFIX"tty", S_IFCHR | DEFAULT_RW_MODE }, { DEV_NODE_PATH_PREFIX"tty", S_IFCHR | DEFAULT_RW_MODE },
{ DEV_NODE_PATH_PREFIX"binder", S_IFCHR | DEFAULT_RW_MODE } { DEV_NODE_PATH_PREFIX"binder", S_IFCHR | DEFAULT_RW_MODE },
{ DEV_NODE_PATH_PREFIX"console", S_IFCHR | DEFAULT_RW_MODE },
{ DEV_NODE_PATH_PREFIX"tty", S_IFCHR | DEFAULT_RW_MODE }
}; };
static void HandleRequiredDynamicDeviceNodes(const struct Uevent *uevent) static void HandleRequiredDynamicDeviceNodes(const struct Uevent *uevent)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册