From 7e703f4da0ad2dbb62e3e42ffd44b2a96edf2f27 Mon Sep 17 00:00:00 2001 From: boxi Date: Thu, 29 Apr 2021 14:31:46 +0800 Subject: [PATCH] feat: Add the init_stage module in startup_init_lite. Add the init_stage module to provide synchronous communication between user mode processes and init process. init stage0-------1fork----> key app |2 |3 (listen)<---------4--------- (notify) |5 init stage1-------6fork----> other app Close #I3OTSU Change-Id: Idec84e90f739475e98347a6a681a6953862b0928 --- initstage/BUILD.gn | 36 +++++++++++++ initstage/include/init_notify.h | 38 ++++++++++++++ initstage/include/init_stage.h | 92 +++++++++++++++++++++++++++++++++ initstage/src/init_stage.c | 67 ++++++++++++++++++++++++ 4 files changed, 233 insertions(+) create mode 100644 initstage/BUILD.gn create mode 100644 initstage/include/init_notify.h create mode 100644 initstage/include/init_stage.h create mode 100644 initstage/src/init_stage.c diff --git a/initstage/BUILD.gn b/initstage/BUILD.gn new file mode 100644 index 000000000..533dc7a9c --- /dev/null +++ b/initstage/BUILD.gn @@ -0,0 +1,36 @@ +# Copyright (c) 2021 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("//build/lite/config/component/lite_component.gni") + +lite_component("initstage") { + features = [ "//base/startup/init_lite/initstage:libinitstage_shared" ] +} + +shared_library("libinitstage_shared") { + sources = [ "src/init_stage.c" ] + cflags = [ "-Wall" ] + include_dirs = [ + "//base/startup/init_lite/initstage/include", + ] + public_deps = [ "//third_party/bounds_checking_function:libsec_shared" ] +} + +static_library("libinitstage_static") { + sources = [ "src/init_stage.c" ] + cflags = [ "-Wall" ] + include_dirs = [ + "//base/startup/init_lite/initstage/include", + ] + public_deps = [ "//third_party/bounds_checking_function:libsec_static" ] +} diff --git a/initstage/include/init_notify.h b/initstage/include/init_notify.h new file mode 100644 index 000000000..95032ad77 --- /dev/null +++ b/initstage/include/init_notify.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 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 BASE_STARTUP_INITLITE_NOTIFY_H +#define BASE_STARTUP_INITLITE_NOTIFY_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/* + * Notify the event to Init process. + * All processes can call. Usually called by the listened process. + * event: There needs to be a consensus between the listener(init process) and the notifier. + */ +extern int NotifyInit(unsigned short event); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif // BASE_STARTUP_INITLITE_NOTIFY_H diff --git a/initstage/include/init_stage.h b/initstage/include/init_stage.h new file mode 100644 index 000000000..09341dc3c --- /dev/null +++ b/initstage/include/init_stage.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2021 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 BASE_STARTUP_INITLITE_STAGE_H +#define BASE_STARTUP_INITLITE_STAGE_H + +#include +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +typedef enum { + QS_STAGE1 = 1, /* 1: start from stage1, 0 is already called in kernel process */ + QS_STAGE2, /* system init stage No 2 */ + QS_STAGE3, /* system init stage No 3 */ + QS_STAGE_LIMIT +} QuickstartStage; + +typedef enum { + QS_UNREGISTER = QS_STAGE_LIMIT, /* quickstart dev unregister */ + QS_NOTIFY, /* quickstart notify */ + QS_LISTEN, /* quickstart listen */ + QS_CTL_LIMIT +} QuickstartConctrl; + +typedef struct { + unsigned int pid; + unsigned int events; +} QuickstartMask; + +#define QUICKSTART_IOC_MAGIC 'T' +#define QUICKSTART_UNREGISTER _IO(QUICKSTART_IOC_MAGIC, QS_UNREGISTER) +#define QUICKSTART_NOTIFY _IO(QUICKSTART_IOC_MAGIC, QS_NOTIFY) +#define QUICKSTART_LISTEN _IOR(QUICKSTART_IOC_MAGIC, QS_LISTEN, QuickstartMask) +#define QUICKSTART_STAGE(x) _IO(QUICKSTART_IOC_MAGIC, (x)) + +#define QUICKSTART_NODE "/dev/quickstart" + +/* Simple sample Useage: + * INIT PROCESS + * SystemInitStage(QS_STAGE1)----(1)fork----> key APP + * |(2) |(3) + * InitListen<-------------------(4)---------- NotifyInit + * |(5) + * SystemInitStage(QS_STAGE2)----(6)fork---------------------> other APP + * |... + * InitStageFinished + */ + +/* + * Listen the events of a specific pid process by Init process. + * Only be called by Init process. + * eventMask: There needs to be a consensus between the listener and the notifier. + + */ +extern int InitListen(pid_t pid, unsigned short eventMask); + +/* + * Trigger the SystemInit stage. + * Only be called by Init process. + */ +extern int SystemInitStage(QuickstartStage stage); + +/* + * InitStage finished. + * Only be called by Init process. + */ +extern int InitStageFinished(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif // BASE_STARTUP_INITLITE_STAGE_H diff --git a/initstage/src/init_stage.c b/initstage/src/init_stage.c new file mode 100644 index 000000000..bffb2697f --- /dev/null +++ b/initstage/src/init_stage.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021 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 "init_stage.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int SendCmd(int cmd, unsigned long arg) +{ + int fd = open(QUICKSTART_NODE, O_RDONLY); + if (fd != -1) { + int ret = ioctl(fd, cmd, arg); + if (ret == -1) { + printf("[%s][%d]Err: %s!\n", __FUNCTION__, __LINE__, strerror(errno)); + } + close(fd); + return ret; + } + printf("[%s][%d]Err: %s!\n", __FUNCTION__, __LINE__, strerror(errno)); + return fd; +} + +int InitListen(pid_t pid, unsigned short eventMask) +{ + QuickstartMask listenMask; + listenMask.pid = pid; + listenMask.events = eventMask; + return SendCmd(QUICKSTART_LISTEN, (unsigned long)&listenMask); +} + +int NotifyInit(unsigned short event) +{ + return SendCmd(QUICKSTART_NOTIFY, event); +} + +int SystemInitStage(QuickstartStage stage) +{ + if (stage >= QS_STAGE_LIMIT || stage < QS_STAGE1) { + printf("[%s][%d]Err: the stage(%d) is Not expected!!\n", __FUNCTION__, __LINE__, stage); + return -1; + } + return SendCmd(QUICKSTART_STAGE(stage), 0); +} + +int InitStageFinished(void) +{ + return SendCmd(QUICKSTART_UNREGISTER, 0); +}