提交 db5614cc 编写于 作者: C cheng_jinsong

init: add console ondemand

Signed-off-by: Ncheng_jinsong <chengjinsong2@huawei.com>
上级 f7b45cf7
......@@ -8,6 +8,7 @@
"sandbox" : 0,
"uid" : "root",
"gid" : ["shell", "log", "readproc"],
"ondemand" : true,
"jobs" : {
"on-start" : "services:console"
},
......
......@@ -212,12 +212,6 @@
"cmds" : [
"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",
"cmds" : [
......
......@@ -42,6 +42,7 @@ typedef struct {
#define WAIT_MAX_SECOND 5
#define MAX_BUFFER_LEN 256
#define CMDLINE_VALUE_LEN_MAX 512
#define STDERR_HANDLE 2
#define ARRAY_LENGTH(array) (sizeof((array)) / sizeof((array)[0]))
#ifndef STARTUP_INIT_UT_PATH
......@@ -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 StringToLL(const char *str, long long int *out);
void CloseStdio(void);
void RedirectStdio(int fd);
#ifdef __cplusplus
#if __cplusplus
}
......
......@@ -29,7 +29,6 @@ extern "C" {
void MountBasicFs(void);
void CreateDeviceNode(void);
void CloseStdio(void);
#ifdef __cplusplus
#if __cplusplus
......
......@@ -67,6 +67,12 @@ extern "C" {
#define IsOnDemandService(service) \
(((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) \
(((service)->attribute & SERVICE_ATTR_TIMERSTART) == SERVICE_ATTR_TIMERSTART)
......
......@@ -64,6 +64,7 @@ Service *AddService(const char *name);
void DumpServiceHookExecute(const char *name, const char *info);
void ProcessControlFd(uint16_t type, const char *serviceCmd, const void *context);
int GetKillServiceSig(const char *name);
int WatchConsoleDevice(Service *service);
#ifdef __cplusplus
#if __cplusplus
}
......
......@@ -308,8 +308,12 @@ static int InitServicePropertys(Service *service)
}
CreateServiceFile(service->fileCfg);
if (service->attribute & SERVICE_ATTR_CONSOLE) {
OpenConsole();
if ((service->attribute & SERVICE_ATTR_CONSOLE)) {
if (strcmp(service->name, "console") != 0 || !IsOnDemandService(service)) {
OpenConsole();
} else {
setsid();
}
}
PublishHoldFds(service);
......@@ -317,7 +321,7 @@ static int InitServicePropertys(Service *service)
"binding core number failed for service %s", service->name);
SetSystemSeccompPolicy(service);
// permissions
INIT_ERROR_CHECK(SetPerms(service) == SERVICE_SUCCESS, return -1,
"service %s exit! set perms failed! err %d.", service->name, errno);
......@@ -524,9 +528,15 @@ void ServiceReap(Service *service)
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)) {
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;
}
......
......@@ -20,7 +20,7 @@
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include "cJSON.h"
#include "init.h"
#include "init_group_manager.h"
......@@ -31,6 +31,7 @@
#include "init_utils.h"
#include "securec.h"
#include "service_control.h"
#include "sys_param.h"
#ifdef ASAN_DETECTOR
#include "init_param.h"
#endif
......@@ -872,6 +873,90 @@ static void ParseServiceHookExecute(const char *name, const cJSON *serviceNode)
}
#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)
{
int servArrSize = 0;
......@@ -916,6 +1001,14 @@ void ParseAllServices(const cJSON *fileRoot)
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
/*
* Execute service parsing hooks
......
......@@ -25,19 +25,6 @@
#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 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)
{
......
......@@ -160,6 +160,20 @@ char *ReadFileToBuf(const char *configFile)
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)
{
if (fileName == NULL) {
......@@ -531,18 +545,25 @@ uint32_t GetRandom()
return ulSeed;
}
void OpenConsole(void)
void RedirectStdio(int fd)
{
#ifndef __LITEOS_M__
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();
WaitForFile("/dev/console", WAIT_MAX_SECOND);
int fd = open("/dev/console", O_RDWR);
if (fd >= 0) {
ioctl(fd, TIOCSCTTY, 0);
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, stdError); // Redirect fd to 0, 1, 2
RedirectStdio(fd);
close(fd);
} else {
INIT_LOGE("Open /dev/console failed. err = %d", errno);
......
......@@ -134,8 +134,10 @@ typedef struct {
#define DEV_NODE_PATH_PREFIX_LEN 5
static const DYNAMIC_DEVICE_NODE dynamicDevices[] = {
{ DEV_NODE_PATH_PREFIX"tty", S_IFCHR | DEFAULT_RW_MODE },
{ DEV_NODE_PATH_PREFIX"binder", 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"console", S_IFCHR | DEFAULT_RW_MODE },
{ DEV_NODE_PATH_PREFIX"tty", S_IFCHR | DEFAULT_RW_MODE }
};
static void HandleRequiredDynamicDeviceNodes(const struct Uevent *uevent)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册