From 38b56e03923f9678d58fe14f1761a761cca6ac04 Mon Sep 17 00:00:00 2001 From: sun_fan Date: Sat, 11 Sep 2021 14:59:45 +0800 Subject: [PATCH 01/14] init: add param, fix codedex and code style Signed-off-by: sun_fan --- initsync/src/init_sync.c | 3 +- interfaces/innerkits/dynamic_service/BUILD.gn | 29 + .../dynamic_service/dynamic_service.c | 110 ++- .../innerkits/include/dynamic_service.h | 27 +- interfaces/innerkits/reboot/BUILD.gn | 2 +- interfaces/innerkits/reboot/init_reboot.c | 2 +- interfaces/innerkits/socket/init_socket.c | 6 +- services/BUILD.gn | 24 +- services/cmds/reboot/init_cmd_reboot.c | 15 +- services/cmds/service_control/BUILD.gn | 2 +- services/etc/init.cfg | 55 +- services/etc/{ => param}/ohos.para | 0 services/etc/param/ohos.para.dac | 34 + services/include/init_cmds.h | 6 +- services/include/init_import.h | 12 +- services/include/init_service.h | 1 + services/include/init_service_manager.h | 2 +- services/include/init_service_socket.h | 6 +- services/include/init_utils.h | 6 +- {ueventd => services/include}/list.h | 0 services/include/param/init_param.h | 33 +- services/include/param/param.h | 61 ++ services/include/param/sys_param.h | 52 +- services/log/BUILD.gn | 9 + services/log/init_log.c | 36 + services/log/init_log.h | 27 + services/param/BUILD.gn | 150 +++- services/param/adapter/param_dac.c | 225 ++++++ services/param/adapter/param_libuvadp.c | 347 ++++++++ services/param/adapter/param_libuvadp.h | 76 ++ services/param/adapter/param_persistadp.c | 91 +++ services/param/adapter/param_selinux.c | 147 ++++ services/param/client/param_request.c | 332 +++++--- services/param/cmd/param_cmd.c | 172 ++++ services/param/include/param_manager.h | 137 +--- services/param/include/param_message.h | 138 ++++ services/param/include/param_persist.h | 52 ++ services/param/include/param_request.h | 46 +- services/param/include/param_security.h | 106 +++ services/param/include/param_service.h | 22 +- services/param/include/param_trie.h | 141 ++-- services/param/include/param_utils.h | 119 +++ services/param/include/trigger_checker.h | 21 +- services/param/include/trigger_manager.h | 161 ++-- services/param/manager/param_cache.c | 148 ---- services/param/manager/param_manager.c | 568 ++++--------- services/param/manager/param_message.c | 84 ++ services/param/manager/param_trie.c | 551 +++++-------- services/param/manager/param_utils.c | 158 ++++ services/param/service/param_persist.c | 208 ++--- services/param/service/param_service.c | 747 ++++++++++++++---- services/param/trigger/trigger_checker.c | 103 +-- services/param/trigger/trigger_manager.c | 603 +++++++------- services/param/trigger/trigger_processor.c | 358 ++++++--- services/param/watcher/agent/watcher.cpp | 29 + services/param/watcher/agent/watcher.h | 33 + .../watcher/agent/watcher_manager_kits.cpp | 162 ++++ .../watcher/agent/watcher_manager_kits.h | 89 +++ .../watcher/agent/watcher_manager_proxy.cpp | 54 ++ .../watcher/agent/watcher_manager_proxy.h | 35 + services/param/watcher/agent/watcher_stub.cpp | 39 + services/param/watcher/agent/watcher_stub.h | 32 + services/param/watcher/etc/param_watcher.cfg | 16 + services/param/watcher/etc/param_watcher.rc | 21 + services/param/watcher/include/iwatcher.h | 38 + .../param/watcher/include/iwatcher_manager.h | 40 + .../param/watcher/include/watcher_utils.h | 44 ++ .../param/watcher/proxy/watcher_manager.cpp | 295 +++++++ .../param/watcher/proxy/watcher_manager.h | 107 +++ .../watcher/proxy/watcher_manager_stub.cpp | 48 ++ .../watcher/proxy/watcher_manager_stub.h | 33 + .../param/watcher/proxy/watcher_proxy.cpp | 42 + services/param/watcher/proxy/watcher_proxy.h | 37 + services/param/watcher/sa_profile/3901.xml | 24 + services/param/watcher/sa_profile/BUILD.gn | 20 + services/src/init_capability.c | 8 +- services/src/init_cmds.c | 261 +++--- services/src/init_import.c | 4 +- services/src/init_jobs.c | 9 - services/src/init_read_cfg.c | 14 +- services/src/init_reboot.c | 133 ++-- services/src/init_service.c | 105 +-- services/src/init_service_manager.c | 208 +++-- services/src/init_service_socket.c | 13 +- services/src/init_signal_handler.c | 2 +- services/src/init_utils.c | 44 +- {ueventd => services/src}/list.c | 10 + services/src/main.c | 14 +- services/test/unittest/BUILD.gn | 236 ++++++ services/test/unittest/init_unittest_const.h | 26 + services/test/unittest/init_ut_entry.cpp | 28 + .../test/unittest/param/client_unittest.cpp | 267 +++++++ services/test/unittest/param/dac_unittest.cpp | 346 ++++++++ services/test/unittest/param/param_unittest.h | 72 ++ .../test/unittest/param/selinux_unittest.cpp | 236 ++++++ .../test/unittest/param/service_unittest.cpp | 646 +++++++++++++++ .../test/unittest/param/trigger_unittest.cpp | 536 +++++++++++++ .../unittest/param/watcher_agent_unittest.cpp | 87 ++ .../unittest/param/watcher_proxy_unittest.cpp | 129 +++ .../unittest/param_ut_entry.cpp} | 28 +- services/test/unittest/param_ut_server.cpp | 138 ++++ .../test/unittest/service/cmds_unittest.cpp | 39 + .../test/unittest/tools/prepare_testdata.sh | 123 +++ ueventd/BUILD.gn | 15 +- ueventd/ueventd.c | 8 +- ueventd/ueventd_device_handler.c | 24 +- ueventd/ueventd_read_cfg.c | 32 +- ueventd/ueventd_socket.c | 6 +- ueventd/ueventd_utils.c | 2 +- 109 files changed, 8955 insertions(+), 2703 deletions(-) create mode 100755 interfaces/innerkits/dynamic_service/BUILD.gn rename services/param/cmd/param_get.c => interfaces/innerkits/dynamic_service/dynamic_service.c (33%) mode change 100644 => 100755 rename services/param/include/trigger_processor.h => interfaces/innerkits/include/dynamic_service.h (61%) mode change 100644 => 100755 rename services/etc/{ => param}/ohos.para (100%) create mode 100755 services/etc/param/ohos.para.dac rename {ueventd => services/include}/list.h (100%) create mode 100755 services/include/param/param.h create mode 100755 services/param/adapter/param_dac.c create mode 100755 services/param/adapter/param_libuvadp.c create mode 100755 services/param/adapter/param_libuvadp.h create mode 100755 services/param/adapter/param_persistadp.c create mode 100755 services/param/adapter/param_selinux.c mode change 100644 => 100755 services/param/client/param_request.c create mode 100755 services/param/cmd/param_cmd.c mode change 100644 => 100755 services/param/include/param_manager.h create mode 100755 services/param/include/param_message.h create mode 100755 services/param/include/param_persist.h mode change 100644 => 100755 services/param/include/param_request.h create mode 100755 services/param/include/param_security.h mode change 100644 => 100755 services/param/include/param_service.h mode change 100644 => 100755 services/param/include/param_trie.h create mode 100755 services/param/include/param_utils.h mode change 100644 => 100755 services/param/include/trigger_checker.h mode change 100644 => 100755 services/param/include/trigger_manager.h delete mode 100644 services/param/manager/param_cache.c mode change 100644 => 100755 services/param/manager/param_manager.c create mode 100755 services/param/manager/param_message.c mode change 100644 => 100755 services/param/manager/param_trie.c create mode 100755 services/param/manager/param_utils.c mode change 100644 => 100755 services/param/service/param_persist.c mode change 100644 => 100755 services/param/service/param_service.c mode change 100644 => 100755 services/param/trigger/trigger_checker.c mode change 100644 => 100755 services/param/trigger/trigger_manager.c mode change 100644 => 100755 services/param/trigger/trigger_processor.c create mode 100755 services/param/watcher/agent/watcher.cpp create mode 100755 services/param/watcher/agent/watcher.h create mode 100755 services/param/watcher/agent/watcher_manager_kits.cpp create mode 100755 services/param/watcher/agent/watcher_manager_kits.h create mode 100755 services/param/watcher/agent/watcher_manager_proxy.cpp create mode 100755 services/param/watcher/agent/watcher_manager_proxy.h create mode 100755 services/param/watcher/agent/watcher_stub.cpp create mode 100755 services/param/watcher/agent/watcher_stub.h create mode 100755 services/param/watcher/etc/param_watcher.cfg create mode 100755 services/param/watcher/etc/param_watcher.rc create mode 100755 services/param/watcher/include/iwatcher.h create mode 100755 services/param/watcher/include/iwatcher_manager.h create mode 100755 services/param/watcher/include/watcher_utils.h create mode 100755 services/param/watcher/proxy/watcher_manager.cpp create mode 100755 services/param/watcher/proxy/watcher_manager.h create mode 100755 services/param/watcher/proxy/watcher_manager_stub.cpp create mode 100755 services/param/watcher/proxy/watcher_manager_stub.h create mode 100755 services/param/watcher/proxy/watcher_proxy.cpp create mode 100755 services/param/watcher/proxy/watcher_proxy.h create mode 100755 services/param/watcher/sa_profile/3901.xml create mode 100755 services/param/watcher/sa_profile/BUILD.gn rename {ueventd => services/src}/list.c (85%) create mode 100755 services/test/unittest/BUILD.gn create mode 100755 services/test/unittest/init_unittest_const.h create mode 100755 services/test/unittest/init_ut_entry.cpp create mode 100755 services/test/unittest/param/client_unittest.cpp create mode 100755 services/test/unittest/param/dac_unittest.cpp create mode 100755 services/test/unittest/param/param_unittest.h create mode 100755 services/test/unittest/param/selinux_unittest.cpp create mode 100755 services/test/unittest/param/service_unittest.cpp create mode 100755 services/test/unittest/param/trigger_unittest.cpp create mode 100755 services/test/unittest/param/watcher_agent_unittest.cpp create mode 100755 services/test/unittest/param/watcher_proxy_unittest.cpp rename services/{param/cmd/param_set.c => test/unittest/param_ut_entry.cpp} (51%) mode change 100644 => 100755 create mode 100755 services/test/unittest/param_ut_server.cpp create mode 100755 services/test/unittest/service/cmds_unittest.cpp create mode 100755 services/test/unittest/tools/prepare_testdata.sh diff --git a/initsync/src/init_sync.c b/initsync/src/init_sync.c index 73ba642b7..e58145b6c 100644 --- a/initsync/src/init_sync.c +++ b/initsync/src/init_sync.c @@ -18,14 +18,13 @@ #include #include #include -#include -#include #include #include #include #include #include #include "init_log.h" + static int SendCmd(int cmd, unsigned long arg) { int fd = open(QUICKSTART_NODE, O_RDONLY); diff --git a/interfaces/innerkits/dynamic_service/BUILD.gn b/interfaces/innerkits/dynamic_service/BUILD.gn new file mode 100755 index 000000000..460cd0637 --- /dev/null +++ b/interfaces/innerkits/dynamic_service/BUILD.gn @@ -0,0 +1,29 @@ +# 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/ohos.gni") +ohos_shared_library("dynamic_service") { + sources = [ "dynamic_service.c" ] + + include_dirs = [ + "//base/startup/syspara_lite/interfaces/innerkits/native/syspara/include", + "//base/startup/init_lite/interfaces/innerkits/include", + ] + + deps = [ + "//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara", + ] + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + install_images = [ "system" ] + part_name = "init" +} diff --git a/services/param/cmd/param_get.c b/interfaces/innerkits/dynamic_service/dynamic_service.c old mode 100644 new mode 100755 similarity index 33% rename from services/param/cmd/param_get.c rename to interfaces/innerkits/dynamic_service/dynamic_service.c index 1435dab09..c048bcf94 --- a/services/param/cmd/param_get.c +++ b/interfaces/innerkits/dynamic_service/dynamic_service.c @@ -1,59 +1,51 @@ -/* -* 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 -#include -#include "sys_param.h" - -#define HELP_PARAM "--help" -#define BUFFER_SIZE 256 - -static void ProcessParam(ParamHandle handle, void* cookie) -{ - if (cookie == NULL) { - printf("ProcessParam cookie is NULL\n"); - return; - } - SystemGetParameterName(handle, (char*)cookie, BUFFER_SIZE); - u_int32_t size = BUFFER_SIZE; - SystemGetParameterValue(handle, ((char*)cookie) + BUFFER_SIZE, &size); - printf("\t%s = %s \n", (char*)cookie, ((char*)cookie) + BUFFER_SIZE); -} - -int main(int argc, char* argv[]) -{ - if (argc == 1) { // 显示所有的记录 - char value[BUFFER_SIZE + BUFFER_SIZE] = {0}; - SystemTraversalParameter(ProcessParam, (void*)value); - return 0; - } - if (argc == 2 && strncmp(argv[1], HELP_PARAM, strlen(HELP_PARAM)) == 0) { // 显示帮助 - printf("usage: getparam NAME VALUE\n"); - return 0; - } - if (argc != 2) { - printf("usage: getparam NAME VALUE\n"); - return 0; - } - char value[BUFFER_SIZE] = {0}; - u_int32_t size = BUFFER_SIZE; - int ret = SystemGetParameter(argv[1], value, &size); - if (ret == 0) { - printf("%s \n", value); - } else { - printf("getparam %s %s fail\n", argv[1], value); - } - -} +/* +* 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 "dynamic_service.h" +#include +#include "hilog/log.h" +#include "parameter.h" + +#undef LOG_TAG +#undef LOG_DOMAIN +#define LOG_TAG "Init" +#define LOG_DOMAIN 0xD000719 + +int32_t StartDynamicProcess(const char *name) +{ + if (name == NULL) { + HILOG_ERROR(LOG_CORE, "Start dynamic service failed, service name is null."); + return -1; + } + if (SetParameter("ohos.ctl.start", name) != 0) { + HILOG_ERROR(LOG_CORE, "Set param for %{public}s failed.\n", name); + return -1; + } + return 0; +} + +int32_t StopDynamicProcess(const char *name) +{ + if (name == NULL) { + HILOG_ERROR(LOG_CORE, "Stop dynamic service failed, service is null.\n"); + return -1; + } + if (SetParameter("ohos.ctl.stop", name) != 0) { + HILOG_ERROR(LOG_CORE, "Set param for %{public}s failed.\n", name); + return -1; + } + return 0; +} + diff --git a/services/param/include/trigger_processor.h b/interfaces/innerkits/include/dynamic_service.h old mode 100644 new mode 100755 similarity index 61% rename from services/param/include/trigger_processor.h rename to interfaces/innerkits/include/dynamic_service.h index fc9a5e89e..61bf8bf82 --- a/services/param/include/trigger_processor.h +++ b/interfaces/innerkits/include/dynamic_service.h @@ -13,15 +13,10 @@ * limitations under the License. */ -#ifndef BASE_STARTUP_EVENT_MANAGER_H -#define BASE_STARTUP_EVENT_MANAGER_H +#ifndef DYNAMIC_SERVICE_API_H +#define DYNAMIC_SERVICE_API_H -#include - -#include "sys_param.h" -#include "init_param.h" -#include "trigger_manager.h" -#include "uv.h" +#include #ifdef __cplusplus #if __cplusplus @@ -29,21 +24,13 @@ extern "C" { #endif #endif -typedef struct TriggerEvent { - uv_work_t request; - EventType type; -} TriggerEvent; - -typedef struct { - uv_work_t request; - EventType type; - u_int32_t contentSize; - char content[0]; -} TriggerDataEvent; +int32_t StartDynamicProcess(const char *name); +int32_t StopDynamicProcess(const char *name); #ifdef __cplusplus #if __cplusplus } #endif #endif -#endif \ No newline at end of file + +#endif // DYNAMIC_SERVICE_API_H \ No newline at end of file diff --git a/interfaces/innerkits/reboot/BUILD.gn b/interfaces/innerkits/reboot/BUILD.gn index d603b712b..a34705e6c 100644 --- a/interfaces/innerkits/reboot/BUILD.gn +++ b/interfaces/innerkits/reboot/BUILD.gn @@ -25,7 +25,7 @@ ohos_static_library("libreboot") { deps = [ "//base/startup/init_lite/services/log:init_log", - "//base/startup/init_lite/services/param:paramclient", + "//base/startup/init_lite/services/param:param_client", "//third_party/bounds_checking_function:libsec_static", ] } diff --git a/interfaces/innerkits/reboot/init_reboot.c b/interfaces/innerkits/reboot/init_reboot.c index 51ac77497..e2e3fb4ba 100644 --- a/interfaces/innerkits/reboot/init_reboot.c +++ b/interfaces/innerkits/reboot/init_reboot.c @@ -46,7 +46,7 @@ int DoReboot(const char *cmdContent) } return 0; } - int length = strlen(cmdContent); + size_t length = strlen(cmdContent); if (length > MAX_REBOOT_VAUE_SIZE) { INIT_LOGE("DoReboot api error, cmdContent = %s, length = %d.", cmdContent, length); return -1; diff --git a/interfaces/innerkits/socket/init_socket.c b/interfaces/innerkits/socket/init_socket.c index f822a8340..ce28193de 100755 --- a/interfaces/innerkits/socket/init_socket.c +++ b/interfaces/innerkits/socket/init_socket.c @@ -18,11 +18,7 @@ #include #include #include -#include -#include #include -#include -#include #include #include #include @@ -34,7 +30,7 @@ #define MAX_SOCKET_ENV_PREFIX_LEN 64 #define MAX_SOCKET_DIR_LEN 128 -static int GetControlFromEnv(char *path, int length) +static int GetControlFromEnv(const char *path, int length) { if (path == NULL || length <= 0) { return -1; diff --git a/services/BUILD.gn b/services/BUILD.gn index 1994c2efa..9b8bb8603 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -112,7 +112,7 @@ if (defined(ohos_lite)) { ] deps = [ "//base/startup/init_lite/services/log:init_log", - "//base/startup/init_lite/services/param:paramservice", + "//base/startup/init_lite/services/param:param_service", "//third_party/bounds_checking_function:libsec_static", "//third_party/cJSON:cjson_static", ] @@ -134,13 +134,17 @@ if (defined(ohos_lite)) { deps = [ ":init", ":init_etc", + "//base/startup/init_lite/interfaces/innerkits/dynamic_service:dynamic_service", "//base/startup/init_lite/interfaces/innerkits/socket:libsocket", "//base/startup/init_lite/services/cmds/reboot:reboot", "//base/startup/init_lite/services/cmds/service_control:service_control", - "//base/startup/init_lite/services/param:getparam", - "//base/startup/init_lite/services/param:paramclient", - "//base/startup/init_lite/services/param:paramservice", - "//base/startup/init_lite/services/param:setparam", + "//base/startup/init_lite/services/param:param", + "//base/startup/init_lite/services/param:param_client", + "//base/startup/init_lite/services/param:param_service", + "//base/startup/init_lite/services/param:param_watcher", + "//base/startup/init_lite/services/param:param_watcher.rc", + "//base/startup/init_lite/services/param:param_watcheragent", + "//base/startup/init_lite/services/param/watcher/sa_profile:param_watcher_profile", ] } @@ -179,8 +183,15 @@ if (defined(ohos_lite)) { } ohos_prebuilt_etc("ohos.para") { - source = "//base/startup/init_lite/services/etc/ohos.para" + source = "//base/startup/init_lite/services/etc/param/ohos.para" part_name = "init" + module_install_dir = "etc/param" + } + + ohos_prebuilt_etc("ohos.para.dac") { + source = "//base/startup/init_lite/services/etc/param/ohos.para.dac" + part_name = "init" + module_install_dir = "etc/param" } group("init_etc") { @@ -190,6 +201,7 @@ if (defined(ohos_lite)) { ":init.usb.cfg", ":init.usb.configfs.cfg", ":ohos.para", + ":ohos.para.dac", ":passwd", ] } diff --git a/services/cmds/reboot/init_cmd_reboot.c b/services/cmds/reboot/init_cmd_reboot.c index 943021b1e..528a9d370 100644 --- a/services/cmds/reboot/init_cmd_reboot.c +++ b/services/cmds/reboot/init_cmd_reboot.c @@ -19,17 +19,26 @@ #include "init_reboot.h" #define REBOOT_CMD_NUMBER 2 +#define USAGE_INFO "usage: reboot shutdown\n"\ + " reboot updater\n"\ + " reboot updater[:options]\n" \ + " reboot flash\n" \ + " reboot flash[:options]\n" \ + " reboot\n" int main(int argc, char* argv[]) { if (argc > REBOOT_CMD_NUMBER) { - printf("usage: reboot shutdown\n reboot updater\n reboot updater[:options]\n reboot\n"); + printf("%s", USAGE_INFO); return 0; } + if (argc == REBOOT_CMD_NUMBER && strcmp(argv[1], "shutdown") != 0 && strcmp(argv[1], "updater") != 0 && - strncmp(argv[1], "updater:", strlen("updater:")) != 0) { - printf("usage: reboot shutdown\n reboot updater\n reboot updater[:options]\n reboot\n"); + strcmp(argv[1], "flash") != 0 && + strncmp(argv[1], "updater:", strlen("updater:")) != 0 && + strncmp(argv[1], "flash:", strlen("flash:")) != 0) { + printf("%s", USAGE_INFO); return 0; } int ret = 0; diff --git a/services/cmds/service_control/BUILD.gn b/services/cmds/service_control/BUILD.gn index 0e8f91315..682b137f5 100755 --- a/services/cmds/service_control/BUILD.gn +++ b/services/cmds/service_control/BUILD.gn @@ -19,7 +19,7 @@ ohos_executable("service_control") { "//base/startup/init_lite/services/include", ] deps = [ - "//base/startup/init_lite/services/param:paramclient", + "//base/startup/init_lite/services/param:param_client", "//third_party/bounds_checking_function:libsec_static", ] symlink_target_name = [ diff --git a/services/etc/init.cfg b/services/etc/init.cfg index f32a7bbb0..e0e54bea5 100755 --- a/services/etc/init.cfg +++ b/services/etc/init.cfg @@ -63,27 +63,7 @@ "mount configfs none /config nodev noexec nosuid", "chmod 0770 /config/sdcardfs", "chown system package_info /config/sdcardfs", - "mkdir /mnt/secure 0700 root root", - "mkdir /mnt/secure/asec 0700 root root", - "mkdir /mnt/asec 0755 root system", - "mkdir /mnt/obb 0755 root system", - "mkdir /mnt/media_rw 0750 root media_rw", - "mkdir /mnt/user 0755 root root", - "mkdir /mnt/user/0 0755 root root", - "mkdir /mnt/expand 0771 system system", - "mkdir /mnt/appfuse 0711 root root", - "mkdir /mnt/runtime 0700 root root", - "mkdir /mnt/runtime/default 0755 root root", - "mkdir /mnt/runtime/default/self 0755 root root", - "mkdir /mnt/runtime/read 0755 root root", - "mkdir /mnt/runtime/read/self 0755 root root", - "mkdir /mnt/runtime/write 0755 root root", - "mkdir /mnt/runtime/write/self 0755 root root", - "mkdir /mnt/runtime/full 0755 root root", - "mkdir /mnt/runtime/full/self 0755 root root", "symlink /storage/self/primary /sdcard", - "symlink /storage/self/primary /mnt/sdcard", - "symlink /mnt/user/0/primary /mnt/runtime/default/self/primary", "write /proc/sys/kernel/panic_on_oops 1", "write /proc/sys/kernel/hung_task_timeout_secs 0", "write /proc/cpu/alignment 4", @@ -153,25 +133,12 @@ "chmod 0600 /dev/cg2_bpf", "mount bpf bpf /sys/fs/bpf nodev noexec nosuid", "mkdir /dev/fscklogs 0770 root system", - "mount pstore pstore /sys/fs/pstore nodev noexec nosuid", - "chown system log /sys/fs/pstore", - "chmod 0550 /sys/fs/pstore", - "chown system log /sys/fs/pstore/console-ramoops", - "chmod 0440 /sys/fs/pstore/console-ramoops", - "chown system log /sys/fs/pstore/console-ramoops-0", - "chmod 0440 /sys/fs/pstore/console-ramoops-0", - "chown system log /sys/fs/pstore/pmsg-ramoops-0", - "chmod 0440 /sys/fs/pstore/pmsg-ramoops-0", "write /proc/sys/abi/swp 1", "symlink /proc/self/fd /dev/fd", "export DOWNLOAD_CACHE /data/cache", "setrlimit RLIMIT_NICE 40 40", "setrlimit RLIMIT_NOFILE 32768 32768", "write /sys/class/leds/vibrator/trigger transient", - "write /dev/cpu_variant:${ro.bionic.arch} ${ro.bionic.cpu_variant}", - "chmod 0444 /dev/cpu_variant:${ro.bionic.arch}", - "write /dev/cpu_variant:${ro.bionic.2nd_arch} ${ro.bionic.2nd_cpu_variant}", - "chmod 0444 /dev/cpu_variant:${ro.bionic.2nd_arch}", "chown system system /sys/power/state", "chown system system /sys/power/wakeup_count", "chmod 0660 /sys/power/state", @@ -182,6 +149,7 @@ }, { "name" : "load_persist_props_action", "cmds" : [ + "mkdir /data/parameters 0770 root root", "load_persist_params load_persist_params" ] }, { @@ -205,27 +173,14 @@ }, { "name" : "post-fs", "cmds" : [ - "exec - system system -- /system/bin/vdc checkpoint markBootAttempt", "mount rootfs rootfs / remount bind ro nodev", - "mount none /mnt/runtime/default /storage bind rec", - "mount none none /storage slave rec", - "chown system cache /cache", - "chmod 0770 /cache", - "mkdir /cache/recovery 0770 system cache", - "mkdir /cache/backup_stage 0700 system system", - "mkdir /cache/backup 0700 system system", "chown root log /proc/vmallocinfo", "chmod 0440 /proc/vmallocinfo", "chown root log /proc/slabinfo", "chmod 0440 /proc/slabinfo", "chown root system /proc/kmsg", "chmod 0440 /proc/kmsg", - "chown root system /proc/sysrq-trigger", - "chmod 0220 /proc/sysrq-trigger", - "chown system log /proc/last_kmsg", - "chmod 0440 /proc/last_kmsg", - "chmod 0444 /sys/fs/selinux/policy", - "mkdir /cache/lost+found 0770 root root" + "chmod 0444 /sys/fs/selinux/policy" ] }, { "name" : "late-fs", @@ -325,6 +280,7 @@ "mkdir /data/cache/recovery 0770 system cache", "mkdir /data/cache/backup_stage 0700 system system", "mkdir /data/cache/backup 0700 system system", + "mkdir /data/init_agent 0776 shell shell", "setparam sys.use_memfd false", "chown root system /dev/fscklogs/log", "chmod 0770 /dev/fscklogs/log" @@ -346,11 +302,6 @@ "write /proc/sys/vm/dirty_expire_centisecs 200", "write /proc/sys/vm/dirty_background_ratio 5", "write /sys/fs/f2fs/${dev.mnt.blk.data}/cp_interval 200", - "chown radio system /sys/android_power/state", - "chown radio system /sys/android_power/request_state", - "chown radio system /sys/android_power/acquire_full_wake_lock", - "chown radio system /sys/android_power/acquire_partial_wake_lock", - "chown radio system /sys/android_power/release_wake_lock", "chown system system /sys/power/autosleep", "chown radio wakelock /sys/power/wake_lock", "chown radio wakelock /sys/power/wake_unlock", diff --git a/services/etc/ohos.para b/services/etc/param/ohos.para similarity index 100% rename from services/etc/ohos.para rename to services/etc/param/ohos.para diff --git a/services/etc/param/ohos.para.dac b/services/etc/param/ohos.para.dac new file mode 100755 index 000000000..51473e979 --- /dev/null +++ b/services/etc/param/ohos.para.dac @@ -0,0 +1,34 @@ +# 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. + +build_version root:root:0777 +hw_sc.build.os.enable root:root:0777 +hw_sc.build.os.apiversion root:root:0777 +hw_sc.build.os.version root:root:0777 +hw_sc.build.os.releasetype root:root:0777 + +const.actionable_compatible_property.enabled root:root:0777 +const.postinstall.fstab.prefix root:root:0777 +const.secure root:root:0777 +security.perf_harden root:root:0777 +const.allow.mock.location root:root:0777 +const.debuggable root:root:0777 +persist.sys.usb.config root:root:0777 + +# default forbit other user to start service +ohos.servicectrl. root:root:0777 + +test.permission. root:root:0770 +test.permission.read. root:root:0774 +test.permission.write. root:root:0772 +test.permission.watcher. root:root:0771 \ No newline at end of file diff --git a/services/include/init_cmds.h b/services/include/init_cmds.h index 232f24a3d..343ec32d5 100644 --- a/services/include/init_cmds.h +++ b/services/include/init_cmds.h @@ -52,13 +52,15 @@ struct CmdArgs { int GetParamValue(const char *symValue, char *paramValue, unsigned int paramLen); struct CmdArgs* GetCmd(const char *cmdContent, const char *delim, int argsCount); -void FreeCmd(struct CmdArgs **cmd); +void FreeCmd(struct CmdArgs *cmd); void ParseCmdLine(const char* cmdStr, CmdLine* resCmd); void DoCmd(const CmdLine* curCmd); void DoCmdByName(const char *name, const char *cmdContent); -const char *GetMatchCmd(const char *cmdStr); +const char *GetMatchCmd(const char *cmdStr, unsigned int *index); +const char *GetCmdKey(unsigned int index); + #ifdef __cplusplus #if __cplusplus } diff --git a/services/include/init_import.h b/services/include/init_import.h index 48b6c01dd..5def1efa8 100644 --- a/services/include/init_import.h +++ b/services/include/init_import.h @@ -12,8 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #ifndef BASE_STARTUP_INITLITE_IMPORT_H - #define BASE_STARTUP_INITLITE_IMPORT_H - #include "cJSON.h" - void ParseAllImports(cJSON *root); - #endif \ No newline at end of file +#ifndef BASE_STARTUP_INITLITE_IMPORT_H +#define BASE_STARTUP_INITLITE_IMPORT_H + +#include "cJSON.h" +void ParseAllImports(const cJSON *root); + +#endif diff --git a/services/include/init_service.h b/services/include/init_service.h index fd269c238..69d5e643a 100644 --- a/services/include/init_service.h +++ b/services/include/init_service.h @@ -39,6 +39,7 @@ extern "C" { #define SERVICE_ATTR_CRITICAL 0x020 // critical, will reboot if it crash 4 times in 4 minutes #define SERVICE_ATTR_DISABLED 0x040 // disabled #define SERVICE_ATTR_CONSOLE 0x080 // console +#define SERVICE_ATTR_DYNAMIC 0x100 // dynamic service #define MAX_SERVICE_NAME 32 #define MAX_WRITEPID_FILES 100 diff --git a/services/include/init_service_manager.h b/services/include/init_service_manager.h index 3e680d3a9..16db1933d 100644 --- a/services/include/init_service_manager.h +++ b/services/include/init_service_manager.h @@ -37,7 +37,7 @@ extern "C" { #define MAX_SERVICES_CNT_IN_FILE 100 void RegisterServices(Service* services, int servicesCnt); -void StartServiceByName(const char* serviceName); +void StartServiceByName(const char* serviceName, bool checkDynamic); void StopServiceByName(const char* serviceName); void StopAllServices(); void StopAllServicesBeforeReboot(); diff --git a/services/include/init_service_socket.h b/services/include/init_service_socket.h index 326695085..6ff5ed563 100644 --- a/services/include/init_service_socket.h +++ b/services/include/init_service_socket.h @@ -23,8 +23,7 @@ #define MAX_SOCK_NAME_LEN 16 #define SOCK_OPT_NUMS 6 -enum SockOptionTab -{ +enum SockOptionTab { SERVICE_SOCK_NAME = 0, SERVICE_SOCK_TYPE, SERVICE_SOCK_PERM, @@ -34,8 +33,7 @@ enum SockOptionTab }; struct ServiceSocket; -struct ServiceSocket -{ +struct ServiceSocket { char *name; // service name int type; // socket type uid_t uid; // uid diff --git a/services/include/init_utils.h b/services/include/init_utils.h index 3dcdbcbda..00c69b67a 100644 --- a/services/include/init_utils.h +++ b/services/include/init_utils.h @@ -16,6 +16,8 @@ #ifndef INIT_UTILS_H #define INIT_UTILS_H +#include + #ifdef __cplusplus #if __cplusplus extern "C" { @@ -26,12 +28,10 @@ extern "C" { #define OCTAL_BASE 8 #define DECIMAL_BASE 10 -int DecodeUid(const char *name); -void CheckAndCreateDir(const char *fileName); +uid_t DecodeUid(const char *name); char* ReadFileToBuf(const char *configFile); int SplitString(char *srcPtr, char **dstPtr, int maxNum); void WaitForFile(const char *source, unsigned int maxCount); - #ifdef __cplusplus #if __cplusplus } diff --git a/ueventd/list.h b/services/include/list.h similarity index 100% rename from ueventd/list.h rename to services/include/list.h diff --git a/services/include/param/init_param.h b/services/include/param/init_param.h index dfdd52b0b..1526b41c5 100644 --- a/services/include/param/init_param.h +++ b/services/include/param/init_param.h @@ -15,21 +15,16 @@ #ifndef BASE_STARTUP_INIT_PARAM_H #define BASE_STARTUP_INIT_PARAM_H +#include #include -#include "cJSON.h" -#include "sys_param.h" +#include "cJSON.h" +#include "param.h" #ifdef __cplusplus #if __cplusplus extern "C" { #endif #endif - -typedef enum { - EVENT_PROPERTY, // 参数修改事件 - EVENT_BOOT -} EventType; - /** * Init 接口 * 初始化参数服务 @@ -56,14 +51,7 @@ void StopParamService(); * 加载默认的参数值 * */ -int LoadDefaultParams(const char *fileName); - -/** - * Init 接口 - * 安全使用,加载参数的信息,包括selinux label 等 - * - */ -int LoadParamInfos(const char *fileName); +int LoadDefaultParams(const char *fileName, int mode); /** * Init 接口 @@ -91,28 +79,21 @@ int SystemReadParam(const char *name, char *value, unsigned int *len); * 触发一个trigger操作。 * */ -void PostTrigger(EventType type, const char *content, u_int32_t contentLen); - -/** - * 对Init接口 - * 触发一个参数trigger操作。 - * - */ -void PostParamTrigger(const char *name, const char *value); +void PostTrigger(EventType type, const char *content, uint32_t contentLen); /** * 对Init接口 * 解析trigger文件。 * */ -int ParseTriggerConfig(cJSON *fileRoot); +int ParseTriggerConfig(const cJSON *fileRoot); /** * 对Init接口 * 按名字执行对应的trigger。 * */ -void DoTriggerExec(const char *content); +void DoTriggerExec(const char *triggerName); /** * 对Init接口 diff --git a/services/include/param/param.h b/services/include/param/param.h new file mode 100755 index 000000000..7a57bf000 --- /dev/null +++ b/services/include/param/param.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020 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_PARAM_H +#define BASE_STARTUP_PARAM_H +#include +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define PARAM_CONST_VALUE_LEN_MAX 4096 +#define PARAM_VALUE_LEN_MAX 96 +#define PARAM_NAME_LEN_MAX 96 +typedef uint32_t ParamHandle; + +typedef enum { + PARAM_CODE_ERROR = -1, + PARAM_CODE_SUCCESS = 0, + PARAM_CODE_INVALID_PARAM = 100, + PARAM_CODE_INVALID_NAME, + PARAM_CODE_INVALID_VALUE, + PARAM_CODE_REACHED_MAX, + PARAM_CODE_NOT_SUPPORT, + PARAM_CODE_TIMEOUT, + PARAM_CODE_NOT_FOUND, + PARAM_CODE_READ_ONLY, + PARAM_CODE_FAIL_CONNECT, + PARAM_CODE_MAX +} PARAM_CODE; + +typedef enum { + EVENT_TRIGGER_PARAM, + EVENT_TRIGGER_BOOT, + EVENT_TRIGGER_PARAM_WAIT, + EVENT_TRIGGER_PARAM_WATCH +} EventType; + +#define LOAD_PARAM_NORMAL 0x00 +#define LOAD_PARAM_ONLY_ADD 0x01 +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif +#endif \ No newline at end of file diff --git a/services/include/param/sys_param.h b/services/include/param/sys_param.h index f5b030bdb..970898197 100644 --- a/services/include/param/sys_param.h +++ b/services/include/param/sys_param.h @@ -16,34 +16,18 @@ #ifndef BASE_STARTUP_SYS_PARAM_H #define BASE_STARTUP_SYS_PARAM_H #include -#include +#include #include +#include "param.h" #ifdef __cplusplus #if __cplusplus extern "C" { #endif #endif -#define PARAM_VALUE_LEN_MAX 96 -#define PARAM_NAME_LEN_MAX 96 -typedef u_int32_t ParamHandle; - -typedef struct { - u_int32_t serial; - ParamHandle handle; - char value[PARAM_VALUE_LEN_MAX]; -} ParamCacheNode; - -typedef const char *(*ParamEvaluatePtr)(u_int32_t cacheCount, ParamCacheNode *node); - -typedef struct { - pthread_mutex_t lock; - u_int32_t serial; - u_int32_t cacheCount; - ParamEvaluatePtr evaluate; - ParamCacheNode *cacheNode; -} ParamCache; +#define DEFAULT_PARAM_WAIT_TIMEOUT 30 // 30s +#define DEFAULT_PARAM_SET_TIMEOUT 10 // 10s /** * 对外接口 @@ -61,6 +45,21 @@ int SystemSetParameter(const char *name, const char *value); */ int SystemGetParameter(const char *name, char *value, unsigned int *len); +/** + * 对外接口 + * 查询参数,主要用于其他进程使用,找到对应属性的handle。 + * + */ +int SystemFindParameter(const char *name, ParamHandle *handle); + +/** + * 对外接口 + * 根据handle获取对应数据的修改标识。 + * commitId 获取计数变化 + * + */ +int SystemGetParameterCommitId(ParamHandle handle, uint32_t *commitId); + /** * 外部接口 * 遍历参数。 @@ -83,6 +82,19 @@ int SystemGetParameterName(ParamHandle handle, char *name, unsigned int len); * */ int SystemGetParameterValue(ParamHandle handle, char *value, unsigned int *len); + +/** + * 外部接口 + * 等待某个参数值被修改,阻塞直到参数值被修改或超时 + * + */ +int SystemWaitParameter(const char *name, const char *value, int32_t timeout); + +typedef void (*ParameterChangePtr)(const char *key, const char *value, void *context); +int SystemWatchParameter(const char *keyprefix, ParameterChangePtr change, void *context); + +void SystemDumpParameters(int verbose); + #ifdef __cplusplus #if __cplusplus } diff --git a/services/log/BUILD.gn b/services/log/BUILD.gn index 0603b625d..adac11b5c 100644 --- a/services/log/BUILD.gn +++ b/services/log/BUILD.gn @@ -25,4 +25,13 @@ if (defined(ohos_lite)) { part_name = "startup" subsystem_name = "startup" } + + ohos_static_library("agent_log") { + sources = [ "init_log.c" ] + deps = [ "//third_party/bounds_checking_function:libsec_static" ] + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + defines = [ "INIT_AGENT" ] + part_name = "startup" + subsystem_name = "startup" + } } diff --git a/services/log/init_log.c b/services/log/init_log.c index 5c5719d9c..18e9e5559 100644 --- a/services/log/init_log.c +++ b/services/log/init_log.c @@ -65,6 +65,7 @@ void InitToHiLog(LogLevel logLevel, const char *fmt, ...) } #endif +#ifndef INIT_AGENT // for init static int g_fd = -1; void OpenLogDevice(void) { @@ -126,3 +127,38 @@ void InitLog(InitLogLevel logLevel, const char *fileName, int line, const char * } return; } +#else // for other process +static FILE *g_outfile = NULL; +void InitLog(InitLogLevel logLevel, const char *fileName, int line, const char *kLevel, + const char *fmt, ...) +{ + if (logLevel < g_logLevel) { + // return; + } + time_t second = time(0); + struct tm *t = localtime(&second); + if (t == NULL) { + return; + } + + if (g_outfile == NULL) { + chmod(PARAM_AGENT_LOG_PATH, S_IRWXU | S_IRWXG | S_IRWXO); + g_outfile = fopen(PARAM_AGENT_LOG_PATH, "w+"); + } + if (g_outfile == NULL) { + fprintf(stdout, "%s[%d-%d-%d %d:%d:%d][pid=%d][%s:%d][%s][%s] ", kLevel, (t->tm_year + BASE_YEAR), + (t->tm_mon + 1), t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, gettid(), fileName, + line, INIT_LOG_TAG, LOG_LEVEL_STR[logLevel]); + printf("output %s error: %s \n", fmt, strerror(errno)); + return; + } + fprintf(g_outfile, "%s[%d-%d-%d %d:%d:%d][pid=%d][%s:%d][%s][%s] ", kLevel, (t->tm_year + BASE_YEAR), + (t->tm_mon + 1), t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, getpid(), fileName, + line, INIT_LOG_TAG, LOG_LEVEL_STR[logLevel]); + va_list list; + va_start(list, fmt); + vfprintf(g_outfile, fmt, list); + va_end(list); + fflush(g_outfile); +} +#endif \ No newline at end of file diff --git a/services/log/init_log.h b/services/log/init_log.h index 37817237a..9960f0c2e 100644 --- a/services/log/init_log.h +++ b/services/log/init_log.h @@ -69,10 +69,30 @@ void SetHiLogLevel(LogLevel logLevel); #define INIT_LOGE(fmt, ...) InitLog(INIT_ERROR, (FILE_NAME), (__LINE__), "<3>", fmt"\n", ##__VA_ARGS__) #define INIT_LOGF(fmt, ...) InitLog(INIT_FATAL, (FILE_NAME), (__LINE__), "<3>", fmt"\n", ##__VA_ARGS__) +#ifndef INIT_AGENT #define STARTUP_LOGD(LABEL, fmt, ...) InitLog(INIT_DEBUG, (FILE_NAME), (__LINE__), "<7>", fmt "\n", ##__VA_ARGS__) #define STARTUP_LOGI(LABEL, fmt, ...) InitLog(INIT_INFO, (FILE_NAME), (__LINE__), "<6>", fmt "\n", ##__VA_ARGS__) #define STARTUP_LOGE(LABEL, fmt, ...) InitLog(INIT_ERROR, (FILE_NAME), (__LINE__), "<3>", fmt "\n", ##__VA_ARGS__) +#else +#include "hilog/log.h" +#define PARAM_AGENT_LOG_PATH "/data/init_agent/init_agent.log" + +#define STARTUP_LOGD(LABEL, fmt, ...) \ + InitLog(INIT_DEBUG, (FILE_NAME), (__LINE__), "", fmt "\n", ##__VA_ARGS__); \ + (void)HiLogPrint(LOG_APP, LOG_DEBUG, LOG_DOMAIN, LABEL, "[%{public}s(%{public}d)] " fmt, \ + (FILE_NAME), (__LINE__), ##__VA_ARGS__) + +#define STARTUP_LOGI(LABEL, fmt, ...) \ + InitLog(INIT_INFO, (FILE_NAME), (__LINE__), "", fmt "\n", ##__VA_ARGS__); \ + (void)HiLogPrint(LOG_APP, LOG_INFO, LOG_DOMAIN, LABEL, "[%{public}s(%{public}d)] " fmt, \ + FILE_NAME, __LINE__, ##__VA_ARGS__) +#define STARTUP_LOGE(LABEL, fmt, ...) \ + InitLog(INIT_ERROR, (FILE_NAME), (__LINE__), "", fmt "\n", ##__VA_ARGS__); \ + (void)HiLogPrint(LOG_APP, LOG_ERROR, LOG_DOMAIN, LABEL, "[%{public}s(%{public}d)] " fmt, \ + FILE_NAME, __LINE__, ##__VA_ARGS__) + +#endif void InitLog(InitLogLevel logLevel, const char *fileName, int line, const char *kLevel, const char *fmt, ...); void SetLogLevel(InitLogLevel logLevel); @@ -117,6 +137,13 @@ void EnableDevKmsg(void); } \ } while (0) +#define INIT_CHECK_ONLY_ELOG(ret, format, ...) \ + do { \ + if (!(ret)) { \ + INIT_LOGE(format, ##__VA_ARGS__); \ + } \ + } while(0) + #ifdef __cplusplus #if __cplusplus } diff --git a/services/param/BUILD.gn b/services/param/BUILD.gn index 07e1d2784..fff262b00 100644 --- a/services/param/BUILD.gn +++ b/services/param/BUILD.gn @@ -12,21 +12,37 @@ # limitations under the License. import("//build/ohos.gni") -ohos_static_library("paramservice") { +declare_args() { param_security = "dac" } + +ohos_prebuilt_etc("param_watcher.rc") { + if (use_musl) { + source = "watcher/etc/param_watcher.cfg" + } else { + source = "watcher/etc/param_watcher.rc" + } + relative_install_dir = "init" + part_name = "init" +} + +ohos_static_library("param_service") { sources = [ - "//base/startup/init_lite/services/src/init_utils.c", - "manager/param_cache.c", + "//base/startup/init_lite/services/src/list.c", + "manager/param_utils.c", "manager/param_manager.c", "manager/param_trie.c", + "manager/param_message.c", "service/param_persist.c", "service/param_service.c", "trigger/trigger_checker.c", "trigger/trigger_manager.c", "trigger/trigger_processor.c", + "adapter/param_libuvadp.c", + "adapter/param_persistadp.c", ] include_dirs = [ "include", + "adapter", "//base/startup/init_lite/services/include/param", "//base/startup/init_lite/services/include", "//base/startup/init_lite/services/log", @@ -34,6 +50,16 @@ ohos_static_library("paramservice") { "//third_party/cJSON", ] + defines = [ "PARAM_SUPPORT_SAVE_PERSIST"] + + if (param_security == "selinux") { + sources += [ "adapter/param_selinux.c"] + defines += [ "PARAM_SUPPORT_SELINUX" ] + } else { + sources += [ "adapter/param_dac.c"] + defines += [ "PARAM_SUPPORT_DAC" ] + } + deps = [ "//third_party/bounds_checking_function:libsec_static", "//third_party/libuv:uv_static", @@ -42,13 +68,13 @@ ohos_static_library("paramservice") { subsystem_name = "startup" } -ohos_static_library("paramclient") { +ohos_shared_library("param_client") { sources = [ - "//base/startup/init_lite/services/src/init_utils.c", "client/param_request.c", - "manager/param_cache.c", + "manager/param_message.c", "manager/param_manager.c", "manager/param_trie.c", + "manager/param_utils.c", ] include_dirs = [ @@ -56,48 +82,132 @@ ohos_static_library("paramclient") { "//base/startup/init_lite/services/include/param", "//base/startup/init_lite/services/include", "//base/startup/init_lite/services/log", - "//third_party/libuv/include", - "//third_party/cJSON", + "//base/hiviewdfx/hilog/interfaces/native/innerkits/include", + "//third_party/libuv/include" ] + defines = [ "INIT_AGENT" ] + + if (param_security == "selinux") { + sources += [ "adapter/param_selinux.c"] + defines += [ "PARAM_SUPPORT_SELINUX" ] + } else { + sources += [ "adapter/param_dac.c"] + defines += [ "PARAM_SUPPORT_DAC" ] + } + deps = [ - "//base/startup/init_lite/services/log:init_log", + "//base/startup/init_lite/services/log:agent_log", "//third_party/bounds_checking_function:libsec_static", - "//third_party/libuv:uv_static", + ] + external_deps = [ + "hiviewdfx_hilog_native:libhilog", ] part_name = "init" - subsystem_name = "startup" } -ohos_executable("getparam") { - sources = [ "cmd/param_get.c" ] +ohos_shared_library("param_watcheragent") { + sources = [ + "watcher/agent/watcher_manager_kits.cpp", + "watcher/agent/watcher_manager_proxy.cpp", + "watcher/agent/watcher_stub.cpp", + "watcher/agent/watcher.cpp" + ] + include_dirs = [ "include", "//base/startup/init_lite/services/include/param", + "//base/startup/init_lite/services/param/watcher/include", + "//base/startup/init_lite/services/param/watcher/agent", "//base/startup/init_lite/services/include", "//base/startup/init_lite/services/log", + "//base/update/updateservice/interfaces/innerkits/include", ] + + defines = [ "INIT_AGENT" ] + deps = [ - "//base/startup/init_lite/services/param:paramclient", + "//base/startup/init_lite/services/log:agent_log", + "//base/startup/init_lite/services/param:param_client", "//third_party/bounds_checking_function:libsec_static", - "//third_party/cJSON:cjson_static", + "//utils/native/base:utils", ] - install_enable = true + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", + ] + + part_name = "init" +} + +ohos_shared_library("param_watcher") { + sources = [ + "watcher/proxy/watcher_manager.cpp", + "watcher/proxy/watcher_manager_stub.cpp", + "watcher/proxy/watcher_proxy.cpp", + ] + + include_dirs = [ + "include", + "//base/startup/init_lite/services/include/param", + "//base/startup/init_lite/services/param/watcher/proxy", + "//base/startup/init_lite/services/param/watcher/include", + "//base/startup/init_lite/services/include", + "//base/startup/init_lite/services/log", + "//third_party/libuv/include", + "//third_party/cJSON", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include", + "//foundation/distributedschedule/safwk/services/safwk/include", + "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk", + "//foundation/distributedschedule/samgr/adapter/interfaces/innerkits/include", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include" + ] + + defines = [ "INIT_AGENT" ] + + deps = [ + "//base/startup/init_lite/services/log:agent_log", + "//base/startup/init_lite/services/param:param_client", + "//third_party/bounds_checking_function:libsec_static", + "//utils/native/base:utils", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", + ] + install_images = [ "system" ] part_name = "init" } -ohos_executable("setparam") { - sources = [ "cmd/param_set.c" ] +ohos_executable("param") { + sources = [ "cmd/param_cmd.c" ] include_dirs = [ "include", "//base/startup/init_lite/services/include/param", "//base/startup/init_lite/services/include", "//base/startup/init_lite/services/log", + "//base/update/updateservice/interfaces/innerkits/include", ] + + defines = [ "PARAM_TEST", "INIT_AGENT" ] + deps = [ - "//base/startup/init_lite/services/param:paramclient", + "//base/startup/init_lite/services/log:agent_log", + "//base/startup/init_lite/services/param:param_client", + "//base/startup/init_lite/services/param:param_watcheragent", "//third_party/bounds_checking_function:libsec_static", - "//third_party/cJSON:cjson_static", + "//base/update/updateservice/interfaces/innerkits/engine:updateservicekits", + ] + external_deps = [ + "hiviewdfx_hilog_native:libhilog", ] install_enable = true part_name = "init" diff --git a/services/param/adapter/param_dac.c b/services/param/adapter/param_dac.c new file mode 100755 index 000000000..c6b6fbbe8 --- /dev/null +++ b/services/param/adapter/param_dac.c @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2020 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 "param_security.h" +#include +#include +#include +#include + +#include "param_utils.h" +#define LABEL "PARAM_DAC" +static ParamSecurityLabel g_localSecurityLabel = {}; + +static void GetUserIdByName(FILE *fp, uid_t *uid, const char *name, uint32_t nameLen) +{ + *uid = -1; + fseek(fp, 0, SEEK_SET); + struct passwd *data = NULL; + while ((data = fgetpwent(fp)) != NULL) { + if (strlen(data->pw_name) == nameLen && strncmp(data->pw_name, name, nameLen) == 0) { + *uid = data->pw_uid; + return; + } + } +} + +static void GetGroupIdByName(FILE *fp, gid_t *gid, const char *name, uint32_t nameLen) +{ + *gid = -1; + fseek(fp, 0, SEEK_SET); + struct group *data = NULL; + while ((data = fgetgrent(fp)) != NULL) { + if (strlen(data->gr_name) == nameLen && strncmp(data->gr_name, name, nameLen) == 0) { + *gid = data->gr_gid; + break; + } + } +} + +// user:group:r|w +static int GetParamDacData(FILE *fpForGroup, FILE *fpForUser, ParamDacData *dacData, const char *value) +{ + char *groupName = strstr(value, ":"); + if (groupName == NULL) { + return -1; + } + char *mode = strstr(groupName + 1, ":"); + if (mode == NULL) { + return -1; + } + GetUserIdByName(fpForUser, &dacData->uid, value, groupName - value); + GetGroupIdByName(fpForGroup, &dacData->gid, groupName + 1, mode - groupName - 1); + dacData->mode = strtol(mode + 1, NULL, 8); + return 0; +} + +static int InitLocalSecurityLabel(ParamSecurityLabel **security, int isInit) +{ + PARAM_LOGD("InitLocalSecurityLabel uid:%d gid:%d euid: %d egid: %d ", getuid(), getgid(), geteuid(), getegid()); + g_localSecurityLabel.cred.pid = getpid(); + g_localSecurityLabel.cred.uid = geteuid(); + g_localSecurityLabel.cred.gid = getegid(); + *security = &g_localSecurityLabel; + // support check write permission in client + (*security)->flags |= LABEL_CHECK_FOR_ALL_PROCESS; + return 0; +} + +static int FreeLocalSecurityLabel(ParamSecurityLabel *srcLabel) +{ + return 0; +} + +static int EncodeSecurityLabel(const ParamSecurityLabel *srcLabel, char *buffer, uint32_t *bufferSize) +{ + PARAM_CHECK(bufferSize != NULL, return -1, "Invalid param"); + if (buffer == NULL) { + *bufferSize = sizeof(ParamSecurityLabel); + return 0; + } + PARAM_CHECK(*bufferSize >= sizeof(ParamSecurityLabel), return -1, "Invalid buffersize %u", *bufferSize); + *bufferSize = sizeof(ParamSecurityLabel); + return memcpy_s(buffer, *bufferSize, srcLabel, sizeof(ParamSecurityLabel)); +} + +static int DecodeSecurityLabel(ParamSecurityLabel **srcLabel, char *buffer, uint32_t bufferSize) +{ + PARAM_CHECK(bufferSize >= sizeof(ParamSecurityLabel), return -1, "Invalid buffersize %u", bufferSize); + PARAM_CHECK(srcLabel != NULL && buffer != NULL, return -1, "Invalid param"); + *srcLabel = (ParamSecurityLabel *)buffer; + return 0; +} + +static int LoadParamLabels(const char *fileName, SecurityLabelFunc label, void *context) +{ + FILE *fpForGroup = fopen(GROUP_FILE_PATH, "r"); + FILE *fpForUser = fopen(USER_FILE_PATH, "r"); + FILE *fp = fopen(fileName, "r"); + SubStringInfo *info = malloc(sizeof(SubStringInfo) * 2); + PARAM_CHECK(fpForGroup != NULL && fpForUser != NULL && fp != NULL && info != NULL, + goto exit, "Can not open file for load param labels"); + + uint32_t infoCount = 0; + char buff[PARAM_BUFFER_SIZE]; + ParamAuditData auditData = {}; + while (fgets(buff, PARAM_BUFFER_SIZE, fp) != NULL) { + int subStrNumber = GetSubStringInfo(buff, strlen(buff), ' ', info, SUBSTR_INFO_DAC + 1); + if (subStrNumber <= SUBSTR_INFO_DAC) { + continue; + } + auditData.name = info[SUBSTR_INFO_NAME].value; +#ifdef STARTUP_INIT_TEST + auditData.label = info[SUBSTR_INFO_NAME].value; +#endif + int ret = GetParamDacData(fpForGroup, fpForUser, &auditData.dacData, info[SUBSTR_INFO_DAC].value); + PARAM_CHECK(ret == 0, continue, "Failed to get param info %d %s", ret, buff); + ret = label(&auditData, context); + PARAM_CHECK(ret == 0, continue, "Failed to write param info %d %s", ret, buff); + infoCount++; + } + PARAM_LOGI("Load parameter label total %u success %s", infoCount, fileName); +exit: + if (fp) { + fclose(fp); + } + if (info) { + free(info); + } + if (fpForGroup) { + fclose(fpForGroup); + } + if (fpForUser) { + fclose(fpForUser); + } + return 0; +} + +static int ProcessParamFile(const char *fileName, void *context) +{ + LabelFuncContext *cxt = (LabelFuncContext *)context; + return LoadParamLabels(fileName, cxt->label, cxt->context); +} + +static int GetParamSecurityLabel(SecurityLabelFunc label, const char *path, void *context) +{ + PARAM_CHECK(label != NULL && path != NULL, return -1, "Invalid param"); + struct stat st; + LabelFuncContext cxt = {label, context}; + if ((stat(path, &st) == 0) && !S_ISDIR(st.st_mode)) { + return ProcessParamFile(path, &cxt); + } + return ReadFileInDir(path, ".para.dac", ProcessParamFile, &cxt); +} + +static int CheckFilePermission(const ParamSecurityLabel *localLabel, const char *fileName, int flags) +{ + PARAM_CHECK(localLabel != NULL && fileName != NULL, return -1, "Invalid param"); + return 0; +} + +static int CheckParamPermission(const ParamSecurityLabel *srcLabel, const ParamAuditData *auditData, int mode) +{ + int ret = DAC_RESULT_FORBIDED; + PARAM_CHECK(srcLabel != NULL && auditData != NULL && auditData->name != NULL, return ret, "Invalid param"); + PARAM_CHECK((mode & (DAC_READ | DAC_WRITE | DAC_WATCH)) != 0, return ret, "Invalid mode %x", mode); + + /** + * DAC group 实现的label的定义 + * user:group:read|write|watch + */ + uint32_t localMode = 0; + if (srcLabel->cred.uid == auditData->dacData.uid) { + localMode = mode & (DAC_READ | DAC_WRITE | DAC_WATCH); + } else if (srcLabel->cred.gid == auditData->dacData.gid) { + localMode = (mode & (DAC_READ | DAC_WRITE | DAC_WATCH)) >> 3; + } else { + localMode = (mode & (DAC_READ | DAC_WRITE | DAC_WATCH)) >> 6; + } + if ((auditData->dacData.mode & localMode) != 0) { + ret = DAC_RESULT_PERMISSION; + } + PARAM_LOGD("Src label %d %d ", srcLabel->cred.gid, srcLabel->cred.uid); + PARAM_LOGD("auditData label %d %d mode %o lable %s", + auditData->dacData.gid, auditData->dacData.uid, auditData->dacData.mode, auditData->label); + PARAM_LOGD("%s check %o localMode %o ret %d", auditData->name, mode, localMode, ret); + return ret; +} + +PARAM_STATIC int RegisterSecurityDacOps(ParamSecurityOps *ops, int isInit) +{ + PARAM_CHECK(ops != NULL, return -1, "Invalid param"); + PARAM_LOGI("RegisterSecurityDacOps %d", isInit); + ops->securityGetLabel = NULL; + ops->securityDecodeLabel = NULL; + ops->securityEncodeLabel = NULL; + ops->securityInitLabel = InitLocalSecurityLabel; + ops->securityCheckFilePermission = CheckFilePermission; + ops->securityCheckParamPermission = CheckParamPermission; + ops->securityFreeLabel = FreeLocalSecurityLabel; + if (isInit) { + ops->securityGetLabel = GetParamSecurityLabel; + ops->securityDecodeLabel = DecodeSecurityLabel; + } else { + ops->securityEncodeLabel = EncodeSecurityLabel; + } + return 0; +} + +#ifdef PARAM_SUPPORT_DAC +int RegisterSecurityOps(ParamSecurityOps *ops, int isInit) +{ + return RegisterSecurityDacOps(ops, isInit); +} +#endif \ No newline at end of file diff --git a/services/param/adapter/param_libuvadp.c b/services/param/adapter/param_libuvadp.c new file mode 100755 index 000000000..8c7b7b208 --- /dev/null +++ b/services/param/adapter/param_libuvadp.c @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2020 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 "param_libuvadp.h" +#include + +#define LABEL "Libuvadp" +static LibuvWorkSpace libuv = { NULL }; +static const uint32_t RECV_BUFFER_MAX = 5 * 1024; + +static LibuvBaseTask *CreateLibuvTask(uint32_t size, uint32_t flags, uint16_t userDataSize, TaskClose close) +{ + LibuvBaseTask *worker = (LibuvBaseTask *)malloc(size + userDataSize); + PARAM_CHECK(worker != NULL, return NULL, "Failed to create param woker"); + worker->worker.flags = flags; + worker->userDataSize = userDataSize; + worker->userDataOffset = size; + worker->close = close; + return worker; +} + +static void OnClientClose(uv_handle_t *handle) +{ + PARAM_LOGD("OnClientClose handle: %p", handle); + PARAM_CHECK(handle != NULL, return, "Invalid handle"); + LibuvStreamTask *worker = PARAM_ENTRY(handle, LibuvStreamTask, stream); + if (worker->base.close != NULL) { + worker->base.close((ParamTaskPtr)worker); + } + free(worker); +} + +static void OnServerClose(uv_handle_t *handle) +{ + PARAM_LOGD("OnServerClose handle: %p", handle); + PARAM_CHECK(handle != NULL, return, "Invalid handle"); + LibuvServerTask *worker = PARAM_ENTRY(handle, LibuvServerTask, server); + if (worker->base.close != NULL) { + worker->base.close((ParamTaskPtr)worker); + } + free(worker); +} + +static void OnTimerClose(uv_handle_t *handle) +{ + PARAM_CHECK(handle != NULL, return, "Invalid handle"); + LibuvTimerTask *worker = PARAM_ENTRY(handle, LibuvTimerTask, timer); + if (worker->base.close != NULL) { + worker->base.close((ParamTaskPtr)worker); + } + free(worker); +} + +static void OnReceiveAlloc(uv_handle_t *handle, size_t suggestedSize, uv_buf_t *buf) +{ + PARAM_CHECK(handle != NULL, return, "Invalid handle"); + buf->len = RECV_BUFFER_MAX; + buf->base = (char *)malloc(buf->len); +} + +static void OnWriteResponse(uv_write_t *req, int status) +{ + PARAM_CHECK(req != NULL, return, "Invalid req"); + PARAM_LOGD("OnWriteResponse handle: %p", req); +} + +static void OnReceiveRequest(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf) +{ + if (nread <= 0 || buf == NULL || buf->base == NULL) { + uv_close((uv_handle_t *)handle, OnClientClose); + if (buf != NULL) { + free(buf->base); + } + return; + } + LibuvStreamTask *client = PARAM_ENTRY(handle, LibuvStreamTask, stream); + if (client->recvMessage != NULL) { + client->recvMessage(&client->base.worker, (const ParamMessage *)buf->base); + } + free(buf->base); +} + +static void OnAsyncCloseCallback(uv_handle_t *handle) +{ + PARAM_CHECK(handle != NULL, return, "Invalid handle"); + free(handle); +} + +static void OnAsyncCallback(uv_async_t *handle) +{ + PARAM_CHECK(handle != NULL, return, "Invalid handle"); + LibuvAsyncEvent *event = (LibuvAsyncEvent *)handle; + if (event->task != NULL && event->task->process != NULL) { + event->task->process(event->eventId, event->content, event->contentSize); + } + uv_close((uv_handle_t *)handle, OnAsyncCloseCallback); +} + +static void OnConnection(uv_stream_t *server, int status) +{ + PARAM_CHECK(status >= 0, return, "Error status %d", status); + PARAM_CHECK(server != NULL, return, "Error server"); + LibuvServerTask *pipeServer = PARAM_ENTRY(server, LibuvServerTask, server); + PARAM_LOGD("OnConnection pipeServer: %p pip %p", pipeServer, server); + if (pipeServer->incomingConnect) { + pipeServer->incomingConnect((ParamTaskPtr)pipeServer, 0); + } +} + +static void LibuvFreeMsg(const ParamTaskPtr stream, const ParamMessage *msg) +{ + PARAM_CHECK(stream != NULL, return, "Invalid stream"); + PARAM_CHECK(msg != NULL, return, "Invalid msg"); + ParamMessage *message = (ParamMessage *)msg; + free(message); +} + +static int InitPipeSocket(uv_pipe_t *pipeServer) +{ + uv_fs_t req; + uv_fs_unlink(uv_default_loop(), &req, PIPE_NAME, NULL); + int ret = uv_pipe_init(uv_default_loop(), pipeServer, 0); + PARAM_CHECK(ret == 0, return ret, "Failed to uv_pipe_init %d", ret); + ret = uv_pipe_bind(pipeServer, PIPE_NAME); + PARAM_CHECK(ret == 0, return ret, "Failed to uv_pipe_bind %d %s", ret, uv_err_name(ret)); + ret = uv_listen((uv_stream_t *)pipeServer, SOMAXCONN, OnConnection); + PARAM_CHECK(ret == 0, return ret, "Failed to uv_listen %d %s", ret, uv_err_name(ret)); + PARAM_CHECK(chmod(PIPE_NAME, S_IRWXU | S_IRWXG | S_IRWXO) == 0, + return -1, "Open file %s error %s", PIPE_NAME, strerror(errno)); + return 0; +} + +static void LibuvTimerCallback(uv_timer_t *handle) +{ + PARAM_CHECK(handle != NULL, return, "Invalid handle"); + LibuvTimerTask *timer = PARAM_ENTRY(handle, LibuvTimerTask, timer); + timer->timerProcess(&timer->base.worker, timer->context); +} + +int ParamServerCreate(ParamTaskPtr *stream, const ParamStreamInfo *info) +{ + PARAM_CHECK(stream != NULL && info != NULL, return -1, "Invalid param"); + PARAM_CHECK(info->incomingConnect != NULL, return -1, "Invalid incomingConnect"); + + LibuvServerTask *worker = (LibuvServerTask *)CreateLibuvTask( + sizeof(LibuvServerTask), WORKER_TYPE_SERVER | info->flags, 0, info->close); + PARAM_CHECK(worker != NULL, return -1, "Failed to add param woker"); + InitPipeSocket(&worker->server.pipe); + PARAM_LOGD("OnConnection pipeServer: %p pipe %p", worker, &worker->server.pipe); + worker->incomingConnect = info->incomingConnect; + *stream = &worker->base.worker; + return 0; +} + +int ParamStreamCreate(ParamTaskPtr *stream, ParamTaskPtr server, const ParamStreamInfo *info, uint16_t userDataSize) +{ + PARAM_CHECK(stream != NULL && info != NULL, return -1, "Invalid stream"); + PARAM_CHECK(info->recvMessage != NULL, return -1, "Invalid recvMessage"); + PARAM_CHECK(info->close != NULL, return -1, "Invalid close"); + + LibuvServerTask *pipeServer = (LibuvServerTask *)server; + LibuvStreamTask *client = (LibuvStreamTask *)CreateLibuvTask(sizeof(LibuvStreamTask), + info->flags | WORKER_TYPE_MSG, userDataSize, info->close); + PARAM_CHECK(client != NULL, return -1, "Failed to add client"); + if (server != NULL) { + uv_pipe_t *pipe = &client->stream.pipe; + int ret = uv_pipe_init(uv_default_loop(), (uv_pipe_t *)pipe, 1); + PARAM_CHECK(ret == 0, free(client); return -1, "Failed to uv_pipe_init %d", ret); + pipe->data = &pipeServer->server; + PARAM_LOGD("OnConnection pipeServer: %p pipe %p", pipeServer, &pipeServer->server); + if ((info->flags & WORKER_TYPE_TEST) != WORKER_TYPE_TEST) { + ret = uv_accept((uv_stream_t *)&pipeServer->server.pipe, (uv_stream_t *)pipe); + PARAM_CHECK(ret == 0, uv_close((uv_handle_t *)pipe, NULL); free(client); + return -1, "Failed to uv_accept %d", ret); + ret = uv_read_start((uv_stream_t *)pipe, OnReceiveAlloc, OnReceiveRequest); + PARAM_CHECK(ret == 0, uv_close((uv_handle_t *)pipe, NULL); free(client); + return -1, "Failed to uv_read_start %d", ret); + } + } + client->recvMessage = info->recvMessage; + *stream = &client->base.worker; + return 0; +} + +void *ParamGetTaskUserData(ParamTaskPtr stream) +{ + PARAM_CHECK(stream != NULL, return NULL, "Invalid stream"); + if ((stream->flags & WORKER_TYPE_CLIENT) != WORKER_TYPE_CLIENT) { + return NULL; + } + LibuvStreamTask *client = (LibuvStreamTask *)stream; + if (client->base.userDataSize == 0) { + return NULL; + } + return (void *)(((char *)stream) + client->base.userDataOffset); +} + +int ParamTaskSendMsg(const ParamTaskPtr stream, const ParamMessage *msg) +{ + PARAM_CHECK(stream != NULL, LibuvFreeMsg(stream, msg); return -1, "Invalid stream"); + PARAM_CHECK(msg != NULL, LibuvFreeMsg(stream, msg); return -1, "Invalid msg"); + LibuvStreamTask *worker = (LibuvStreamTask *)stream; + if ((stream->flags & WORKER_TYPE_MSG) != WORKER_TYPE_MSG) { + LibuvFreeMsg(stream, msg); + return -1; + } + if ((stream->flags & WORKER_TYPE_TEST) != WORKER_TYPE_TEST) { + uv_buf_t buf = uv_buf_init((char *)msg, msg->msgSize); + int ret = uv_write(&worker->writer, (uv_stream_t *)&worker->stream.pipe, &buf, 1, OnWriteResponse); + PARAM_CHECK(ret >= 0, LibuvFreeMsg(stream, msg); return -1, "Failed to uv_write2 ret %s", uv_strerror(ret)); + } + LibuvFreeMsg(stream, msg); + return 0; +} + +int ParamEventTaskCreate(ParamTaskPtr *stream, EventProcess eventProcess, EventProcess eventBeforeProcess) +{ + PARAM_CHECK(stream != NULL && eventProcess != NULL, return -1, "Invalid info or stream"); + LibuvEventTask *worker = (LibuvEventTask *)CreateLibuvTask(sizeof(LibuvEventTask), + WORKER_TYPE_EVENT | WORKER_TYPE_ASYNC, 0, NULL); + PARAM_CHECK(worker != NULL, return -1, "Failed to alloc worker"); + worker->process = eventProcess; + worker->beforeProcess = eventBeforeProcess; + *stream = &worker->base.worker; + return 0; +} + +int ParamEventSend(ParamTaskPtr stream, uint64_t eventId, const char *content, uint32_t size) +{ + PARAM_CHECK(stream != NULL, return -1, "Invalid stream"); + PARAM_CHECK((stream->flags & WORKER_TYPE_EVENT) == WORKER_TYPE_EVENT, return -1, "Invalid stream type"); + int ret = PARAM_CODE_INVALID_PARAM; + if (stream->flags & WORKER_TYPE_ASYNC) { + LibuvEventTask *worker = (LibuvEventTask *)stream; + LibuvAsyncEvent *event = (LibuvAsyncEvent *)malloc(sizeof(LibuvAsyncEvent) + size + 1); + PARAM_CHECK(event != NULL, return -1, "Failed to alloc event"); + event->eventId = eventId; + event->contentSize = size + 1; + event->task = worker; + if (content != NULL) { + ret = memcpy_s(event->content, event->contentSize, content, size); + PARAM_CHECK(ret == 0, free(event); return -1, "Failed to memcpy content "); + event->content[size] = '\0'; + } + uv_async_init(uv_default_loop(), &event->async, OnAsyncCallback); + if (worker->beforeProcess != NULL) { + worker->beforeProcess(eventId, content, size); + } + uv_async_send(&event->async); + ret = 0; + } + return ret; +} + +int ParamTaskClose(ParamTaskPtr stream) +{ + PARAM_CHECK(stream != NULL, return -1, "Invalid param"); + if (stream->flags & WORKER_TYPE_TIMER) { + LibuvTimerTask *worker = (LibuvTimerTask *)stream; + uv_timer_stop(&worker->timer); + uv_close((uv_handle_t *)(&worker->timer), OnTimerClose); + } else if (stream->flags & WORKER_TYPE_SERVER) { + LibuvServerTask *worker = (LibuvServerTask *)stream; + uv_close((uv_handle_t *)(&worker->server.pipe), OnServerClose); + } else if (stream->flags & WORKER_TYPE_MSG) { + LibuvStreamTask *worker = (LibuvStreamTask *)stream; + uv_close((uv_handle_t *)(&worker->stream.pipe), OnClientClose); + } else if (stream->flags & WORKER_TYPE_EVENT) { + LibuvAsyncEvent *event = (LibuvAsyncEvent *)stream; + uv_close((uv_handle_t *)&event->async, OnAsyncCloseCallback); + } else { + free(stream); + } + return 0; +} + +int ParamTimerCreate(ParamTaskPtr *timer, TimerProcess process, void *context) +{ + PARAM_CHECK(timer != NULL && process != NULL, return -1, "Invalid timer"); + LibuvTimerTask *worker = (LibuvTimerTask *)CreateLibuvTask(sizeof(LibuvTimerTask), WORKER_TYPE_TIMER, 0, NULL); + PARAM_CHECK(worker != NULL, return -1, "Failed to alloc timer worker"); + worker->base.worker.flags = WORKER_TYPE_TIMER; + worker->timerProcess = process; + worker->context = context; + uv_timer_init(uv_default_loop(), &worker->timer); + *timer = &worker->base.worker; + return 0; +} + +int ParamTimerStart(ParamTaskPtr timer, uint64_t timeout, uint64_t repeat) +{ + PARAM_CHECK(timer != NULL, return -1, "Invalid timer"); + if (timer->flags & WORKER_TYPE_TIMER) { + LibuvTimerTask *worker = (LibuvTimerTask *)timer; + uv_timer_start(&worker->timer, LibuvTimerCallback, timeout, repeat); + return 0; + } + return -1; +} + +static void SignalHandler(uv_signal_t* handle, int signum) +{ + if (signum != SIGCHLD) { + return; + } + pid_t pid = 0; + int procStat = 0; + while (1) { + pid = waitpid(-1, &procStat, WNOHANG); + if (pid <= 0) { + break; + } + } + if (libuv.pidDeleteProcess != NULL) { + libuv.pidDeleteProcess(pid); + } +} + +int ParamServiceStart(ProcessPidDelete pidDelete) +{ + libuv.pidDeleteProcess = pidDelete; + uv_signal_t sigchldHandler; + int ret = uv_signal_init(uv_default_loop(), &sigchldHandler); + ret |= uv_signal_start(&sigchldHandler, SignalHandler, SIGCHLD); + PARAM_CHECK(ret == 0 , return -1, "Failed to process signal "); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + return 0; +} + +int ParamServiceStop() +{ + uv_fs_t req; + uv_fs_unlink(uv_default_loop(), &req, PIPE_NAME, NULL); + uv_stop(uv_default_loop()); + return 0; +} \ No newline at end of file diff --git a/services/param/adapter/param_libuvadp.h b/services/param/adapter/param_libuvadp.h new file mode 100755 index 000000000..81645b6ad --- /dev/null +++ b/services/param/adapter/param_libuvadp.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020 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_PARAM_LIBUVADP_H +#define BASE_STARTUP_PARAM_LIBUVADP_H +#include +#include +#include +#include + +#include "init_param.h" +#include "param_message.h" +#include "param_utils.h" +#include "uv.h" + +typedef struct { + ProcessPidDelete pidDeleteProcess; +} LibuvWorkSpace; + +typedef struct { + ParamTask worker; + TaskClose close; + uint16_t userDataSize; + uint16_t userDataOffset; +} LibuvBaseTask; + +typedef struct { + LibuvBaseTask base; + RecvMessage recvMessage; + union { + uv_pipe_t pipe; + } stream; + uv_write_t writer; +} LibuvStreamTask; + +typedef struct { + LibuvBaseTask base; + IncomingConnect incomingConnect; + union { + uv_pipe_t pipe; + } server; +} LibuvServerTask; + +typedef struct { + LibuvBaseTask base; + EventProcess process; + EventProcess beforeProcess; +} LibuvEventTask; + +typedef struct { + uv_async_t async; + LibuvEventTask *task; + uint64_t eventId; + uint32_t contentSize; + char content[0]; +} LibuvAsyncEvent; + +typedef struct { + LibuvBaseTask base; + uv_timer_t timer; + TimerProcess timerProcess; + void *context; +} LibuvTimerTask; + +#endif // BASE_STARTUP_PARAM_LIBUVADP_H \ No newline at end of file diff --git a/services/param/adapter/param_persistadp.c b/services/param/adapter/param_persistadp.c new file mode 100755 index 000000000..a38a39aa7 --- /dev/null +++ b/services/param/adapter/param_persistadp.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2020 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 "param_persist.h" +#include +#include +#include +#include + +#include "param_utils.h" + +#define LABEL "PERSIST_ADP" + +typedef struct { + void *context; + PersistParamGetPtr persistParamGet; +} PersistAdpContext; + +static int LoadPersistParam(PersistParamGetPtr persistParamGet, void *context) +{ + CheckAndCreateDir(PARAM_PERSIST_SAVE_PATH); + FILE *fp = fopen(PARAM_PERSIST_SAVE_TMP_PATH, "r"); + if (fp == NULL) { + fp = fopen(PARAM_PERSIST_SAVE_PATH, "r"); + PARAM_LOGI("LoadPersistParam open file %s", PARAM_PERSIST_SAVE_PATH); + } + PARAM_CHECK(fp != NULL, return -1, "No valid persist parameter file %s", PARAM_PERSIST_SAVE_PATH); + + char *buff = (char *)malloc(PARAM_BUFFER_SIZE); + SubStringInfo *info = malloc(sizeof(SubStringInfo) * (SUBSTR_INFO_VALUE + 1)); + while (info != NULL && buff != NULL && fgets(buff, PARAM_BUFFER_SIZE, fp) != NULL) { + int subStrNumber = GetSubStringInfo(buff, strlen(buff), '=', info, SUBSTR_INFO_VALUE + 1); + if (subStrNumber <= SUBSTR_INFO_VALUE) { + continue; + } + int ret = persistParamGet(info[0].value, info[1].value, context); + PARAM_CHECK(ret == 0, continue, "Failed to set param %d %s", ret, buff); + } + free(info); + free(buff); + fclose(fp); + return 0; +} + +static int BatchSavePersistParamBegin(PERSIST_SAVE_HANDLE *handle) +{ + FILE *fp = fopen(PARAM_PERSIST_SAVE_TMP_PATH, "w"); + PARAM_CHECK(fp != NULL, return -1, "Open file %s fail error %s", PARAM_PERSIST_SAVE_TMP_PATH, strerror(errno)); + *handle = (PERSIST_SAVE_HANDLE)fp; + return 0; +} + +static int BatchSavePersistParam(PERSIST_SAVE_HANDLE handle, const char *name, const char *value) +{ + FILE *fp = (FILE *)handle; + int ret = fprintf(fp, "%s=%s\n", name, value); + PARAM_CHECK(ret > 0, return -1, "Failed to write param"); + PARAM_LOGD("BatchSavePersistParam %s=%s", name, value); + return 0; +} + +static void BatchSavePersistParamEnd(PERSIST_SAVE_HANDLE handle) +{ + FILE *fp = (FILE *)handle; + fclose(fp); + unlink(PARAM_PERSIST_SAVE_PATH); + int ret = rename(PARAM_PERSIST_SAVE_TMP_PATH, PARAM_PERSIST_SAVE_PATH); + PARAM_CHECK(ret == 0, return, + "BatchSavePersistParamEnd %s fail error %s", PARAM_PERSIST_SAVE_TMP_PATH, strerror(errno)); +} + +int RegisterPersistParamOps(PersistParamOps *ops) +{ + ops->save = NULL; + ops->load = LoadPersistParam; + ops->batchSaveBegin = BatchSavePersistParamBegin; + ops->batchSave = BatchSavePersistParam; + ops->batchSaveEnd = BatchSavePersistParamEnd; + return 0; +} \ No newline at end of file diff --git a/services/param/adapter/param_selinux.c b/services/param/adapter/param_selinux.c new file mode 100755 index 000000000..7c51e4a98 --- /dev/null +++ b/services/param/adapter/param_selinux.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2020 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 "param_security.h" +#include + +#include "param_utils.h" + +#define LABEL "PARAM_SELINUX" +#define SELINUX_LABEL_LEN 128 + +typedef struct SELinuxSecurityLabel { + ParamSecurityLabel securityLabel; + char label[SELINUX_LABEL_LEN]; +} SELinuxSecurityLabel; + +static SELinuxSecurityLabel g_localSecurityLabel = {}; + +static int InitLocalSecurityLabel(ParamSecurityLabel **security, int isInit) +{ + PARAM_LOGI("TestDacGetLabel uid:%d gid:%d euid: %d egid: %d ", getuid(), getgid(), geteuid(), getegid()); + g_localSecurityLabel.securityLabel.cred.pid = getpid(); + g_localSecurityLabel.securityLabel.cred.uid = geteuid(); + g_localSecurityLabel.securityLabel.cred.gid = getegid(); + *security = &g_localSecurityLabel.securityLabel; + return 0; +} + +static int FreeLocalSecurityLabel(ParamSecurityLabel *srcLabel) +{ + return 0; +} + +static int EncodeSecurityLabel(const ParamSecurityLabel *srcLabel, char *buffer, uint32_t *bufferSize) +{ + PARAM_CHECK(bufferSize != NULL, return -1, "Invalid param"); + if (buffer == NULL) { + *bufferSize = sizeof(SELinuxSecurityLabel); + return 0; + } + PARAM_CHECK(*bufferSize >= sizeof(SELinuxSecurityLabel), return -1, "Invalid buffersize %u", *bufferSize); + *bufferSize = sizeof(SELinuxSecurityLabel); + return memcpy_s(buffer, *bufferSize, srcLabel, sizeof(SELinuxSecurityLabel)); +} + +static int DecodeSecurityLabel(ParamSecurityLabel **srcLabel, char *buffer, uint32_t bufferSize) +{ + PARAM_CHECK(bufferSize >= sizeof(SELinuxSecurityLabel), return -1, "Invalid buffersize %u", bufferSize); + PARAM_CHECK(srcLabel != NULL && buffer != NULL, return -1, "Invalid param"); + *srcLabel = &((SELinuxSecurityLabel *)buffer)->securityLabel; + return 0; +} + +static int LoadParamLabels(const char *fileName, SecurityLabelFunc label, void *context) +{ + int ret = 0; + FILE *fp = fopen(fileName, "r"); + PARAM_CHECK(fp != NULL, return -1, "Open file %s fail", fileName); + SubStringInfo *info = malloc(sizeof(SubStringInfo) * 2); + char buff[PARAM_BUFFER_SIZE]; + int infoCount = 0; + ParamAuditData auditData = {}; + while (fgets(buff, PARAM_BUFFER_SIZE, fp) != NULL) { + int subStrNumber = GetSubStringInfo(buff, strlen(buff), ' ', info, SUBSTR_INFO_DAC + 1); + if (subStrNumber <= SUBSTR_INFO_DAC) { + continue; + } + auditData.name = info[SUBSTR_INFO_NAME].value; + auditData.label = info[SUBSTR_INFO_LABEL].value; + ret = label(&auditData, context); + PARAM_CHECK(ret == 0, continue, "Failed to write param info %d %s", ret, buff); + infoCount++; + } + fclose(fp); + free(info); + PARAM_LOGI("Load parameter info %d success %s", infoCount, fileName); + return 0; +} + +static int ProcessParamFile(const char *fileName, void *context) +{ + LabelFuncContext *cxt = (LabelFuncContext *)context; + return LoadParamLabels(fileName, cxt->label, cxt->context); +} + +static int GetParamSecurityLabel(SecurityLabelFunc label, const char *path, void *context) +{ + PARAM_CHECK(label != NULL, return -1, "Invalid param"); + int ret = 0; + struct stat st; + LabelFuncContext cxt = { label, context }; + if ((stat(path, &st) == 0) && !S_ISDIR(st.st_mode)) { + ret = ProcessParamFile(path, &cxt); + } else { + ret = ReadFileInDir(path, ".para.selinux", ProcessParamFile, &cxt); + } + return ret; +} + +static int CheckFilePermission(const ParamSecurityLabel *localLabel, const char *fileName, int flags) +{ + PARAM_CHECK(localLabel != NULL && fileName != NULL, return -1, "Invalid param"); + return 0; +} + +static int CheckParamPermission(const ParamSecurityLabel *srcLabel, const ParamAuditData *auditData, int mode) +{ + PARAM_LOGI("CheckParamPermission "); + PARAM_CHECK(srcLabel != NULL && auditData != NULL && auditData->name != NULL, return -1, "Invalid param"); + return 0; +} + +PARAM_STATIC int RegisterSecuritySelinuxOps(ParamSecurityOps *ops, int isInit) +{ + PARAM_CHECK(ops != NULL, return -1, "Invalid param"); + ops->securityGetLabel = NULL; + ops->securityDecodeLabel = NULL; + ops->securityEncodeLabel = NULL; + ops->securityInitLabel = InitLocalSecurityLabel; + ops->securityCheckFilePermission = CheckFilePermission; + ops->securityCheckParamPermission = CheckParamPermission; + ops->securityFreeLabel = FreeLocalSecurityLabel; + if (isInit) { + ops->securityGetLabel = GetParamSecurityLabel; + ops->securityDecodeLabel = DecodeSecurityLabel; + } else { + ops->securityEncodeLabel = EncodeSecurityLabel; + } + return 0; +} +#ifdef PARAM_SUPPORT_SELINUX +int RegisterSecurityOps(ParamSecurityOps *ops, int isInit) +{ + return RegisterSecuritySelinuxOps(ops, isInit); +} +#endif \ No newline at end of file diff --git a/services/param/client/param_request.c b/services/param/client/param_request.c old mode 100644 new mode 100755 index ebed012fc..2490cf30f --- a/services/param/client/param_request.c +++ b/services/param/client/param_request.c @@ -12,151 +12,295 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "param_request.h" - +#include +#include +#include +#include #include +#include #include -#include #include "param_manager.h" -#include "uv.h" +#include "param_message.h" +#define INVALID_SOCKET -1 #define LABEL "Client" -#define BUFFER_SIZE 200 -#define ParamEntry(ptr, type, member) (type *)((char *)(ptr) - offsetof(type, member)) +static const uint32_t RECV_BUFFER_MAX = 5 * 1024; -static ParamWorkSpace g_paramWorkSpaceReadOnly = {ATOMIC_VAR_INIT(0), {}, {}, {}}; +static atomic_uint g_requestId = ATOMIC_VAR_INIT(1); +static ClientWorkSpace g_clientSpace = {{}, -1, {}}; -static void OnWrite(uv_write_t *req, int status) +__attribute__((constructor)) static void ClientInit(void); +__attribute__((destructor)) static void ClientDeinit(void); + +static int InitParamClient() { - PARAM_LOGD("OnWrite status %d", status); + if (PARAM_TEST_FLAG(g_clientSpace.paramSpace.flags, WORKSPACE_FLAGS_INIT)) { + return 0; + } + PARAM_LOGI("InitParamClient"); + pthread_mutex_init(&g_clientSpace.mutex, NULL); + g_clientSpace.clientFd = INVALID_SOCKET; + return InitParamWorkSpace(&g_clientSpace.paramSpace, 1); } -static void OnReceiveAlloc(uv_handle_t* handle, size_t suggestedSize, uv_buf_t* buf) +void ClientInit() { - // 这里需要按实际回复大小申请内存,不需要大内存 - buf->base = (char *)malloc(sizeof(ResponseMsg)); - PARAM_CHECK(buf->base != NULL, return, "OnReceiveAlloc malloc failed"); - buf->len = sizeof(ResponseMsg); - PARAM_LOGD("OnReceiveAlloc handle %p %zu", handle, suggestedSize); + PARAM_LOGI("ClientInit"); + (void)InitParamClient(); } -static void OnReceiveResponse(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf) +void ClientDeinit() { - RequestNode *req = ParamEntry(handle, RequestNode, handle); - PARAM_LOGD("OnReceiveResponse %p", handle); - if (nread <= 0 || buf == NULL || handle == NULL || buf->base == NULL) { - if (buf != NULL && buf->base != NULL) { - free(buf->base); - } - if (handle != NULL) { - uv_close((uv_handle_t*)handle, NULL); - uv_stop(req->loop); - } - return; + CloseParamWorkSpace(&g_clientSpace.paramSpace); +} + +static ParamSecurityOps *GetClientParamSecurityOps() +{ + return &g_clientSpace.paramSpace.paramSecurityOps; +} + +static int FillLabelContent(ParamMessage *request, uint32_t *start, uint32_t length) +{ + uint32_t bufferSize = request->msgSize - sizeof(ParamMessage); + uint32_t offset = *start; + PARAM_CHECK((offset + sizeof(ParamMsgContent) + length) <= bufferSize, + return -1, "Invalid msgSize %u offset %u", request->msgSize, offset); + ParamMsgContent *content = (ParamMsgContent *)(request->data + offset); + content->type = PARAM_LABEL; + content->contentSize = 0; + ParamSecurityOps *ops = GetClientParamSecurityOps(); + if (length != 0 && ops != NULL && ops->securityEncodeLabel != NULL) { + int ret = ops->securityEncodeLabel(g_clientSpace.paramSpace.securityLabel, content->content, &length); + PARAM_CHECK(ret == 0, return -1, "Failed to get label length"); + content->contentSize = length; } - ResponseMsg *response = (ResponseMsg *)(buf->base); - PARAM_CHECK(response != NULL, return, "The response is null"); - PARAM_LOGD("OnReceiveResponse %p cmd %d result: %d", handle, response->type, response->result); - switch (response->type) { - case SET_PARAM: - req->result = response->result; + offset += sizeof(ParamMsgContent) + PARAM_ALIGN(content->contentSize); + *start = offset; + return 0; +} + +static int ProcessRecvMsg(const ParamMessage *recvMsg) +{ + PARAM_LOGD("ProcessRecvMsg type: %u msgId: %u name %s", recvMsg->type, recvMsg->id.msgId, recvMsg->key); + int result = PARAM_CODE_INVALID_PARAM; + switch (recvMsg->type) { + case MSG_SET_PARAM: + result = ( (ParamResponseMessage *)recvMsg)->result; + break; + case MSG_NOTIFY_PARAM: + result = 0; break; default: - PARAM_LOGE("not supported the command: %d", response->type); break; } - PARAM_LOGD("Close handle %p", handle); - free(buf->base); - uv_close((uv_handle_t*)handle, NULL); - uv_stop(req->loop); -} - -static void OnConnection(uv_connect_t *connect, int status) -{ - PARAM_CHECK(status >= 0, return, "Failed to conntect status %s", uv_strerror(status)); - RequestNode *request = ParamEntry(connect, RequestNode, connect); - PARAM_LOGD("Connect to server handle %p", &(request->handle)); - uv_buf_t buf = uv_buf_init((char*)&request->msg, request->msg.contentSize + sizeof(request->msg)); - int ret = uv_write2(&request->wr, (uv_stream_t*)&(request->handle), &buf, 1, (uv_stream_t*)&(request->handle), OnWrite); - PARAM_CHECK(ret >= 0, return, "Failed to uv_write2 porperty"); - - // read result - ret = uv_read_start((uv_stream_t*)&(request->handle), OnReceiveAlloc, OnReceiveResponse); - PARAM_CHECK(ret >= 0, return, "Failed to uv_read_start response"); -} - -static int StartRequest(int cmd, RequestNode *request) -{ - PARAM_CHECK(request != NULL, return -1, "Invalid request"); - request->result = -1; - request->msg.type = cmd; - request->loop = uv_loop_new(); - PARAM_CHECK(request->loop != NULL, return -1, "StartRequest uv_loop_new failed"); - uv_pipe_init(request->loop, &request->handle, 1); - uv_pipe_connect(&request->connect, &request->handle, PIPE_NAME, OnConnection); - uv_run(request->loop, UV_RUN_DEFAULT); - uv_loop_delete(request->loop); - int result = request->result; - free(request); return result; } +static int StartRequest(int *fd, ParamMessage *request, int timeout) +{ + int ret = 0; + struct timeval time; + time.tv_sec = timeout; + time.tv_usec = 0; + do { + int clientFd = *fd; + if (clientFd == INVALID_SOCKET) { + clientFd = socket(AF_UNIX, SOCK_STREAM, 0); + PARAM_CHECK(clientFd >= 0, return PARAM_CODE_FAIL_CONNECT, "Failed to create socket"); + ret = ConntectServer(clientFd, PIPE_NAME); + PARAM_CHECK(ret == 0, close(clientFd); return PARAM_CODE_FAIL_CONNECT, "Failed to connect server"); + setsockopt(clientFd, SOL_SOCKET, SO_SNDTIMEO, (char *)&time, sizeof(struct timeval)); + setsockopt(clientFd, SOL_SOCKET, SO_RCVTIMEO, (char *)&time, sizeof(struct timeval)); + *fd = clientFd; + } + ssize_t recvLen = 0; + ssize_t sendLen = send(clientFd, (char *)request, request->msgSize, 0); + if (sendLen > 0) { + recvLen = recv(clientFd, (char *)request, RECV_BUFFER_MAX, 0); + if (recvLen > 0) { + break; + } + } + ret = errno; + close(clientFd); + *fd = INVALID_SOCKET; + if (errno == EAGAIN || recvLen == 0) { + ret = PARAM_CODE_TIMEOUT; + break; + } + PARAM_LOGE("Send or recv msg fail errno %d %zd %zd", errno, sendLen, recvLen); + } while (1); + + if (ret == 0) { // check result + ret = ProcessRecvMsg(request); + } + return ret; +} + int SystemSetParameter(const char *name, const char *value) { - PARAM_CHECK(name != NULL && value != NULL, return -1, "Invalid param"); + InitParamClient(); + PARAM_CHECK(name != NULL && value != NULL, return -1, "Invalid name or value"); int ret = CheckParamName(name, 0); - PARAM_CHECK(ret == 0, return ret, "Illegal param name"); + PARAM_CHECK(ret == 0, return ret, "Illegal param name %s", name); + uint32_t msgSize = sizeof(ParamMessage) + sizeof(ParamMsgContent) + PARAM_ALIGN(strlen(value) + 1); + uint32_t labelLen = 0; + ParamSecurityOps *ops = GetClientParamSecurityOps(); + if (LABEL_IS_CLIENT_CHECK_PERMITTED(g_clientSpace.paramSpace.securityLabel)) { + ret = CheckParamPermission(&g_clientSpace.paramSpace, g_clientSpace.paramSpace.securityLabel, name, DAC_WRITE); + PARAM_CHECK(ret == 0, return ret, "Forbit to set parameter %s", name); + } else if (!LABEL_IS_ALL_PERMITTED(g_clientSpace.paramSpace.securityLabel)) { // check local can check permissions + PARAM_CHECK(ops != NULL && ops->securityEncodeLabel != NULL, return -1, "Invalid securityEncodeLabel"); + ret = ops->securityEncodeLabel(g_clientSpace.paramSpace.securityLabel, NULL, &labelLen); + PARAM_CHECK(ret == 0, return -1, "Failed to get label length"); + } + msgSize += sizeof(ParamMsgContent) + labelLen; + msgSize = msgSize < RECV_BUFFER_MAX ? RECV_BUFFER_MAX : msgSize; - PARAM_LOGD("StartRequest %s", name); - u_int32_t msgSize = sizeof(RequestMsg) + strlen(name) + strlen(value) + 2; - RequestNode *request = (RequestNode *)malloc(sizeof(RequestNode) + msgSize); + ParamMessage *request = (ParamMessage *)CreateParamMessage(MSG_SET_PARAM, name, msgSize); PARAM_CHECK(request != NULL, return -1, "Failed to malloc for connect"); + uint32_t offset = 0; + ret = FillParamMsgContent(request, &offset, PARAM_VALUE, value, strlen(value)); + PARAM_CHECK(ret == 0, free(request); return -1, "Failed to fill value"); + ret = FillLabelContent(request, &offset, labelLen); + PARAM_CHECK(ret == 0, free(request); return -1, "Failed to fill label"); + request->msgSize = offset + sizeof(ParamMessage); + request->id.msgId = atomic_fetch_add(&g_requestId, 1); + + pthread_mutex_lock(&g_clientSpace.mutex); + ret = StartRequest(&g_clientSpace.clientFd, request, DEFAULT_PARAM_SET_TIMEOUT); + pthread_mutex_unlock(&g_clientSpace.mutex); + free(request); + return ret; +} + +int SystemWaitParameter(const char *name, const char *value, int32_t timeout) +{ + InitParamClient(); + PARAM_CHECK(name != NULL, return -1, "Invalid name"); + int ret = CheckParamName(name, 0); + PARAM_CHECK(ret == 0, return ret, "Illegal param name %s", name); + ParamHandle handle = 0; + ret = ReadParamWithCheck(&g_clientSpace.paramSpace, name, DAC_READ, &handle); + if (ret != PARAM_CODE_NOT_FOUND && ret != 0) { + PARAM_CHECK(ret == 0, return ret, "Forbid to wait parameter %s", name); + } + if (timeout == 0) { + timeout = DEFAULT_PARAM_WAIT_TIMEOUT; + } + uint32_t msgSize = sizeof(ParamMessage) + sizeof(ParamMsgContent) + sizeof(ParamMsgContent) + sizeof(uint32_t); + msgSize = msgSize < RECV_BUFFER_MAX ? RECV_BUFFER_MAX : msgSize; + uint32_t offset = 0; + ParamMessage *request = NULL; + if (value != NULL) { + msgSize += PARAM_ALIGN(strlen(value) + 1); + request = (ParamMessage *)CreateParamMessage(MSG_WAIT_PARAM, name, msgSize); + PARAM_CHECK(request != NULL, return -1, "Failed to malloc for wait"); + ret = FillParamMsgContent(request, &offset, PARAM_VALUE, value, strlen(value)); + } else { + msgSize += PARAM_ALIGN(1); + request = (ParamMessage *)CreateParamMessage(MSG_WAIT_PARAM, name, msgSize); + PARAM_CHECK(request != NULL, return -1, "Failed to malloc for wait"); + ret = FillParamMsgContent(request, &offset, PARAM_VALUE, "*", 1); + } + PARAM_CHECK(ret == 0, free(request); return -1, "Failed to fill value"); + ParamMsgContent *content = (ParamMsgContent *)(request->data + offset); + content->type = PARAM_WAIT_TIMEOUT; + content->contentSize = sizeof(uint32_t); + *((uint32_t *)(content->content)) = timeout; + offset += sizeof(ParamMsgContent) + sizeof(uint32_t); - memset_s(request, sizeof(RequestNode), 0, sizeof(RequestNode)); - // 带字符串结束符 - int contentSize = BuildParamContent(request->msg.content, msgSize - sizeof(RequestMsg), name, value); - PARAM_CHECK(contentSize > 0, free(request); return -1, "Failed to copy porperty"); - request->msg.contentSize = contentSize; - return StartRequest(SET_PARAM, request); + request->msgSize = offset + sizeof(ParamMessage); + request->id.waitId = atomic_fetch_add(&g_requestId, 1); + int fd = INVALID_SOCKET; + ret = StartRequest(&fd, request, timeout); + if (fd != INVALID_SOCKET) { + close(fd); + } + free(request); + PARAM_LOGI("SystemWaitParameter %s value %s result %d ", name, value, ret); + return ret; } int SystemGetParameter(const char *name, char *value, unsigned int *len) { + InitParamClient(); PARAM_CHECK(name != NULL && len != NULL, return -1, "The name or value is null"); - InitParamWorkSpace(&g_paramWorkSpaceReadOnly, 1, NULL); - ParamHandle handle = 0; - int ret = ReadParamWithCheck(&g_paramWorkSpaceReadOnly, name, &handle); - PARAM_CHECK(ret == 0, return ret, "Can not get param for %s", name); - return ReadParamValue(&g_paramWorkSpaceReadOnly, handle, value, len); + int ret = ReadParamWithCheck(&g_clientSpace.paramSpace, name, DAC_READ, &handle); + if (ret != PARAM_CODE_NOT_FOUND && ret != 0) { + PARAM_CHECK(ret == 0, return ret, "Forbid to get parameter %s", name); + } + return ReadParamValue(&g_clientSpace.paramSpace, handle, value, len); +} + +int SystemFindParameter(const char *name, ParamHandle *handle) +{ + InitParamClient(); + PARAM_CHECK(name != NULL && handle != NULL, return -1, "The name or handle is null"); + int ret = ReadParamWithCheck(&g_clientSpace.paramSpace, name, DAC_READ, handle); + if (ret != PARAM_CODE_NOT_FOUND && ret != 0) { + PARAM_CHECK(ret == 0, return ret, "Forbid to access parameter %s", name); + } + return 0; +} + +int SystemGetParameterCommitId(ParamHandle handle, uint32_t *commitId) +{ + PARAM_CHECK(handle != 0 || commitId != NULL, return -1, "The handle is null"); + return ReadParamCommitId(&g_clientSpace.paramSpace, handle, commitId); } int SystemGetParameterName(ParamHandle handle, char *name, unsigned int len) { PARAM_CHECK(name != NULL && handle != 0, return -1, "The name is null"); - InitParamWorkSpace(&g_paramWorkSpaceReadOnly, 1, NULL); - return ReadParamName(&g_paramWorkSpaceReadOnly, handle, name, len); + return ReadParamName(&g_clientSpace.paramSpace, handle, name, len); } int SystemGetParameterValue(ParamHandle handle, char *value, unsigned int *len) { PARAM_CHECK(len != NULL && handle != 0, return -1, "The value is null"); - InitParamWorkSpace(&g_paramWorkSpaceReadOnly, 1, NULL); - return ReadParamValue(&g_paramWorkSpaceReadOnly, handle, value, len); + return ReadParamValue(&g_clientSpace.paramSpace, handle, value, len); } -int SystemTraversalParameter(void (*traversalParameter)(ParamHandle handle, void* cookie), void* cookie) +int SystemTraversalParameter(void (*traversalParameter)(ParamHandle handle, void *cookie), void *cookie) { + InitParamClient(); PARAM_CHECK(traversalParameter != NULL, return -1, "The param is null"); - InitParamWorkSpace(&g_paramWorkSpaceReadOnly, 1, NULL); - return TraversalParam(&g_paramWorkSpaceReadOnly, traversalParameter, cookie); + ParamHandle handle = 0; + // check default dac + int ret = ReadParamWithCheck(&g_clientSpace.paramSpace, "#", DAC_READ, &handle); + if (ret != PARAM_CODE_NOT_FOUND && ret != 0) { + PARAM_CHECK(ret == 0, return ret, "Forbid to traversal parameters"); + } + return TraversalParam(&g_clientSpace.paramSpace, traversalParameter, cookie); +} + +void SystemDumpParameters(int verbose) +{ + InitParamClient(); + DumpParameters(&g_clientSpace.paramSpace, verbose); +} + +int WatchParamCheck(const char *keyprefix) +{ + InitParamClient(); + PARAM_CHECK(keyprefix != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid keyprefix"); + int ret = CheckParamName(keyprefix, 0); + PARAM_CHECK(ret == 0, return ret, "Illegal param name %s", keyprefix); + ParamHandle handle = 0; + ret = ReadParamWithCheck(&g_clientSpace.paramSpace, keyprefix, DAC_WATCH, &handle); + if (ret != PARAM_CODE_NOT_FOUND && ret != 0) { + PARAM_CHECK(ret == 0, return ret, "Forbid to watch parameter %s", keyprefix); + } + return 0; } -const char *SystemDetectParamChange(ParamCache *cache, - ParamEvaluatePtr evaluate, u_int32_t count, const char *parameters[][2]) +#ifdef STARTUP_INIT_TEST +ParamWorkSpace *GetClientParamWorkSpace() { - PARAM_CHECK(cache != NULL && evaluate != NULL && parameters != NULL, return NULL, "The param is null"); - return DetectParamChange(&g_paramWorkSpaceReadOnly, cache, evaluate, count, parameters); + return &g_clientSpace.paramSpace; } +#endif \ No newline at end of file diff --git a/services/param/cmd/param_cmd.c b/services/param/cmd/param_cmd.c new file mode 100755 index 000000000..08f609ed8 --- /dev/null +++ b/services/param/cmd/param_cmd.c @@ -0,0 +1,172 @@ +/* + * 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 +#include +#include + +#include "param_manager.h" +#include "param_utils.h" +#include "sys_param.h" + +#define USAGE_INFO_PARAM_GET "param get [key]" +#define USAGE_INFO_PARAM_SET "param set key value" +#define USAGE_INFO_PARAM_WAIT "param wait key value" +#define USAGE_INFO_PARAM_DUMP "param dump [verbose]" +#define USAGE_INFO_PARAM_READ "param read key" +#define USAGE_INFO_PARAM_WATCH "param watch key" + +static void ShowParam(ParamHandle handle, void *cookie) +{ + char *name = (char *)cookie; + char *value = ((char *)cookie) + PARAM_NAME_LEN_MAX; + SystemGetParameterName(handle, name, PARAM_NAME_LEN_MAX); + uint32_t size = PARAM_CONST_VALUE_LEN_MAX; + SystemGetParameterValue(handle, value, &size); + printf("\t%s = %s \n", name, value); +} + +static void ExeuteCmdParamGet(int argc, char *argv[], int start) +{ + uint32_t size = PARAM_CONST_VALUE_LEN_MAX + PARAM_NAME_LEN_MAX + 2; + char *buffer = (char *)malloc(size); + if (buffer == NULL) { + printf("Get parameterfail\n"); + return; + } + memset_s(buffer, size, 0, size); + if (argc == start) { + SystemTraversalParameter(ShowParam, (void *)buffer); + } else { + int ret = SystemGetParameter(argv[start], buffer, &size); + if (ret == 0) { + printf("%s \n", buffer); + } else { + printf("Get parameter \"%s\" fail\n", argv[start]); + } + } + free(buffer); +} + +static void ExeuteCmdParamSet(int argc, char *argv[], int start) +{ + int ret = SystemSetParameter(argv[start], argv[start + 1]); + if (ret == 0) { + printf("Set parameter %s %s success\n", argv[start], argv[start + 1]); + } else { + printf("Set parameter %s %s fail\n", argv[start], argv[start + 1]); + } + return; +} + +static void ExeuteCmdParamDump(int argc, char *argv[], int start) +{ + int verbose = 0; + if (argc > start && strcmp(argv[start], "verbose") == 0) { + verbose = 1; + } + SystemDumpParameters(verbose); +} + +static void ExeuteCmdParamWait(int argc, char *argv[], int start) +{ + char *value = NULL; + uint32_t timeout = DEFAULT_PARAM_WAIT_TIMEOUT; + if (argc > (start + 1)) { + value = argv[start + 1]; + } + if (argc > (start + 2)) { + timeout = atol(argv[start + 2]); + } + SystemWaitParameter(argv[start], value, timeout); +} + +#ifdef PARAM_TEST +static void ExeuteCmdParamRead(int argc, char *argv[], int start) +{ + srand((unsigned)time(NULL)); // srand()函数产生一个以当前时间开始的随机种子 + while (1) { + ExeuteCmdParamGet(argc, argv, start); + int wait = rand() / 100000 + 100000; // 100ms + usleep(wait); + } +} + +static void HandleParamChange(const char *key, const char *value, void *context) +{ + printf("Receive parameter change %s %s \n", key, value); +} + +static void ExeuteCmdParamWatch(int argc, char *argv[], int start) +{ + int ret = SystemWatchParameter(argv[start], HandleParamChange, NULL); + if (ret != 0) { + return; + } + while (1) { + (void)pause(); + } +} +#endif + +struct { + char name[8]; + int minArg; + void (*DoFuncion)(int argc, char *argv[], int start); + char help[128]; +} g_paramCmds[] = { + { "set", 4, ExeuteCmdParamSet, USAGE_INFO_PARAM_SET }, + { "get", 2, ExeuteCmdParamGet, USAGE_INFO_PARAM_GET }, + { "wait", 3, ExeuteCmdParamWait, USAGE_INFO_PARAM_WAIT }, + { "dump", 2, ExeuteCmdParamDump, USAGE_INFO_PARAM_DUMP }, +#ifdef PARAM_TEST + { "read", 2, ExeuteCmdParamRead, USAGE_INFO_PARAM_READ }, + { "watch", 2, ExeuteCmdParamWatch, USAGE_INFO_PARAM_WATCH }, +#endif +}; + +int RunParamCommand(int argc, char *argv[]) +{ + if (argc < 2) { + printf("usage: \n"); + for (size_t i = 0; i < sizeof(g_paramCmds) / sizeof(g_paramCmds[0]); i++) { + printf("\t %s\n", g_paramCmds[i].help); + } + return 0; + } + + for (size_t i = 0; i < sizeof(g_paramCmds) / sizeof(g_paramCmds[0]); i++) { + if (strncmp(argv[1], g_paramCmds[i].name, strlen(g_paramCmds[i].name)) == 0) { + if (argc < g_paramCmds[i].minArg) { + printf("usage: %s\n", g_paramCmds[i].help); + return 0; + } + g_paramCmds[i].DoFuncion(argc, argv, 2); + return 0; + } + } + printf("usage: \n"); + for (size_t i = 0; i < sizeof(g_paramCmds) / sizeof(g_paramCmds[0]); i++) { + printf("\t%s\n", g_paramCmds[i].help); + } + return 0; +} + +#ifndef STARTUP_INIT_TEST +int main(int argc, char *argv[]) +{ + return RunParamCommand(argc, argv); +} +#endif \ No newline at end of file diff --git a/services/param/include/param_manager.h b/services/param/include/param_manager.h old mode 100644 new mode 100755 index dc969651f..ff3a578d8 --- a/services/param/include/param_manager.h +++ b/services/param/include/param_manager.h @@ -18,140 +18,61 @@ #include #include -#include "init_log.h" -#include "sys_param.h" +#include "param_message.h" +#include "param_persist.h" +#include "param_security.h" #include "param_trie.h" -#include "securec.h" +#include "param_utils.h" +#include "sys_param.h" + #ifdef __cplusplus #if __cplusplus extern "C" { #endif #endif -typedef enum { - PARAM_CODE_INVALID_PARAM = 100, - PARAM_CODE_INVALID_NAME, - PARAM_CODE_INVALID_VALUE, - PARAM_CODE_REACHED_MAX, - PARAM_CODE_PERMISSION_DENIED, - PARAM_CODE_READ_ONLY_PROPERTY, - PARAM_CODE_NOT_SUPPORT, - PARAM_CODE_ERROR_MAP_FILE, - PARAM_CODE_NOT_FOUND_PROP, - PARAM_CODE_NOT_INIT -} PARAM_CODE; - -#define IS_READY_ONLY(name) strncmp((name), "ro.", strlen("ro.")) == 0 -#define LABEL_STRING_LEN 128 - -#ifdef STARTUP_LOCAL -#define PIPE_NAME "/tmp/paramservice" -#define PARAM_STORAGE_PATH "/media/sf_ubuntu/test/__parameters__/param_storage" -#define PARAM_PERSIST_PATH "/media/sf_ubuntu/test/param/persist_parameters" -#define PARAM_INFO_PATH "/media/sf_ubuntu/test/__parameters__/param_info" -#else -#define PIPE_NAME "/dev/unix/socket/paramservice" -#define PARAM_STORAGE_PATH "/dev/__parameters__/param_storage" -#define PARAM_PERSIST_PATH "/data/param/persist_parameters" -#define PARAM_INFO_PATH "/dev/__parameters__/param_info" -#endif - -#define SUBSTR_INFO_NAME 0 -#define SUBSTR_INFO_LABEL 1 -#define SUBSTR_INFO_TYPE 2 -#define SUBSTR_INFO_MAX 4 - -#define WORKSPACE_FLAGS_INIT 0x01 -#define WORKSPACE_FLAGS_LOADED 0x02 - -#define PARAM_LOGI(fmt, ...) STARTUP_LOGI(LABEL, fmt, ##__VA_ARGS__) -#define PARAM_LOGE(fmt, ...) STARTUP_LOGE(LABEL, fmt, ##__VA_ARGS__) -#define PARAM_LOGD(fmt, ...) STARTUP_LOGD(LABEL, fmt, ##__VA_ARGS__) - -#define PARAM_CHECK(retCode, exper, ...) \ - if (!(retCode)) { \ - PARAM_LOGE(__VA_ARGS__); \ - exper; \ - } - -#define futex(addr1, op, val, rel, addr2, val3) \ - syscall(SYS_futex, addr1, op, val, rel, addr2, val3) -#define futex_wait_always(addr1) \ - syscall(SYS_futex, addr1, FUTEX_WAIT, *(int*)(addr1), 0, 0, 0) -#define futex_wake_single(addr1) \ - syscall(SYS_futex, addr1, FUTEX_WAKE, 1, 0, 0, 0) - -typedef struct UserCred { - pid_t pid; - uid_t uid; - gid_t gid; -} UserCred; +#define futex(addr1, op, val, rel, addr2, val3) syscall(SYS_futex, addr1, op, val, rel, addr2, val3) +#define futex_wait_always(addr1) syscall(SYS_futex, addr1, FUTEX_WAIT, *(int *)(addr1), 0, 0, 0) +#define futex_wake_single(addr1) syscall(SYS_futex, addr1, FUTEX_WAKE, 1, 0, 0, 0) typedef struct { - char label[LABEL_STRING_LEN]; - UserCred cred; -} ParamSecurityLabel; - -typedef struct ParamAuditData { - const UserCred *cr; - const char *name; -} ParamAuditData; - -typedef struct { - atomic_uint_least32_t flags; - WorkSpace paramLabelSpace; + uint32_t flags; WorkSpace paramSpace; - ParamSecurityLabel label; + ParamSecurityLabel *securityLabel; + ParamSecurityOps paramSecurityOps; + ParamTaskPtr serverTask; + ParamTaskPtr timer; } ParamWorkSpace; typedef struct { - atomic_uint_least32_t flags; - WorkSpace persistWorkSpace; + uint32_t flags; + ParamTaskPtr saveTimer; + time_t lastSaveTimer; + PersistParamOps persistParamOps; } ParamPersistWorkSpace; -typedef struct { - char value[128]; -} SubStringInfo; - -int InitParamWorkSpace(ParamWorkSpace *workSpace, int onlyRead, const char *context); +int InitParamWorkSpace(ParamWorkSpace *workSpace, int onlyRead); void CloseParamWorkSpace(ParamWorkSpace *workSpace); -int ReadParamWithCheck(ParamWorkSpace *workSpace, const char *name, ParamHandle *handle); -int ReadParamValue(ParamWorkSpace *workSpace, ParamHandle handle, char *value, u_int32_t *len); -int ReadParamName(ParamWorkSpace *workSpace, ParamHandle handle, char *name, u_int32_t len); -u_int32_t ReadParamSerial(ParamWorkSpace *workSpace, ParamHandle handle); - -int AddParam(WorkSpace *workSpace, const char *name, const char *value); -int WriteParam(WorkSpace *workSpace, const char *name, const char *value); -int WriteParamWithCheck(ParamWorkSpace *workSpace, - const ParamSecurityLabel *srcLabel, const char *name, const char *value); -int WriteParamInfo(ParamWorkSpace *workSpace, SubStringInfo *info, int subStrNumber); +int ReadParamWithCheck(ParamWorkSpace *workSpace, const char *name, int op, ParamHandle *handle); +int ReadParamValue(ParamWorkSpace *workSpace, ParamHandle handle, char *value, uint32_t *len); +int ReadParamName(ParamWorkSpace *workSpace, ParamHandle handle, char *name, uint32_t len); +int ReadParamCommitId(ParamWorkSpace *workSpace, ParamHandle handle, uint32_t *commitId); -int CheckParamValue(WorkSpace *workSpace, const TrieDataNode *node, const char *name, const char *value); int CheckParamName(const char *name, int paramInfo); -int CanReadParam(ParamWorkSpace *workSpace, u_int32_t labelIndex, const char *name); -int CanWriteParam(ParamWorkSpace *workSpace, - const ParamSecurityLabel *srcLabel, const TrieDataNode *node, const char *name, const char *value); +int CheckParamPermission(ParamWorkSpace *workSpace, const ParamSecurityLabel *srcLabel, const char *name, int mode); -int CheckMacPerms(ParamWorkSpace *workSpace, - const ParamSecurityLabel *srcLabel, const char *name, u_int32_t labelIndex); -int CheckControlParamPerms(ParamWorkSpace *workSpace, - const ParamSecurityLabel *srcLabel, const char *name, const char *value); - -int GetSubStringInfo(const char *buff, u_int32_t buffLen, char delimiter, SubStringInfo *info, int subStrNumber); -int BuildParamContent(char *content, u_int32_t contentSize, const char *name, const char *value); -ParamWorkSpace *GetParamWorkSpace(); - -typedef void (*TraversalParamPtr)(ParamHandle handle, void* context); +typedef void (*TraversalParamPtr)(ParamHandle handle, void *context); typedef struct { TraversalParamPtr traversalParamPtr; void *context; } ParamTraversalContext; int TraversalParam(ParamWorkSpace *workSpace, TraversalParamPtr walkFunc, void *cookie); -const char *DetectParamChange(ParamWorkSpace *workSpace, ParamCache *cache, - ParamEvaluatePtr evaluate, u_int32_t count, const char *parameters[][2]); - +ParamPersistWorkSpace *GeParamPersistWorkSpace(); +ParamWorkSpace *GetParamWorkSpace(); +ParamWorkSpace *GetClientParamWorkSpace(); +void DumpParameters(ParamWorkSpace *workSpace, int verbose); #ifdef __cplusplus #if __cplusplus } diff --git a/services/param/include/param_message.h b/services/param/include/param_message.h new file mode 100755 index 000000000..c05f346e7 --- /dev/null +++ b/services/param/include/param_message.h @@ -0,0 +1,138 @@ +/* + * 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_PARAM_MESSAGE_H +#define BASE_STARTUP_PARAM_MESSAGE_H +#include +#include +#include +#include + +#include "list.h" +#include "param.h" +#include "param_utils.h" +#include "securec.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifndef PARAM_SUPPORT_LIBUV +#ifndef PARAM_SUPPORT_EVENT +#define PARAM_SUPPORT_LIBUV 1 +#endif +#endif + +#define WORKER_TYPE_MSG 0x01 +#define WORKER_TYPE_EVENT 0x02 +#define WORKER_TYPE_TIMER 0x08 + +#define WORKER_TYPE_ASYNC 0x10 +#define WORKER_TYPE_SERVER 0x20 +#define WORKER_TYPE_CLIENT 0x40 + +#define WORKER_TYPE_TEST 0x01000000 + +typedef enum { + MSG_SET_PARAM, + MSG_WAIT_PARAM, + MSG_ADD_WATCHER, + MSG_DEL_WATCHER, + MSG_NOTIFY_PARAM +} ParamMsgType; + +typedef enum ContentType { + PARAM_NAME, + PARAM_VALUE, + PARAM_LABEL, + PARAM_WAIT_TIMEOUT, + PARAM_NAME_VALUE, +} ContentType; + +typedef struct { + uint8_t type; + uint8_t rev; + uint16_t contentSize; + char content[0]; +} ParamMsgContent; + +typedef struct { + uint32_t type; + uint32_t msgSize; + union { + uint32_t msgId; + uint32_t watcherId; + uint32_t waitId; + } id; + char key[PARAM_NAME_LEN_MAX]; + char data[0]; +} ParamMessage; + +typedef struct { + ParamMessage msg; + uint32_t result; +} ParamResponseMessage; + +struct ParamTask_; +typedef struct ParamTask_ *ParamTaskPtr; +typedef int (*IncomingConnect)(const ParamTaskPtr stream, int flags); +typedef int (*RecvMessage)(const ParamTaskPtr stream, const ParamMessage *msg); +typedef void (*TimerProcess)(const ParamTaskPtr stream, void *context); +typedef void (*EventProcess)(uint64_t eventId, const char *context, uint32_t size); +typedef void (*TaskClose)(const ParamTaskPtr stream); +typedef void (*ProcessPidDelete)(pid_t pid); + +typedef struct ParamTask_ { + int32_t flags; +} ParamTask; + +typedef struct { + int flags; + char *server; + IncomingConnect incomingConnect; + RecvMessage recvMessage; + TaskClose close; +} ParamStreamInfo; + +int ParamServiceStop(); +int ParamServiceStart(ProcessPidDelete pidDelete); + +int ParamTaskClose(ParamTaskPtr stream); +int ParamServerCreate(ParamTaskPtr *server, const ParamStreamInfo *info); +int ParamStreamCreate(ParamTaskPtr *client, ParamTaskPtr server, const ParamStreamInfo *info, uint16_t userDataSize); +int ParamTaskSendMsg(const ParamTaskPtr stream, const ParamMessage *msg); + +int ParamEventTaskCreate(ParamTaskPtr *stream, EventProcess eventProcess, EventProcess eventBeforeProcess); +int ParamEventSend(ParamTaskPtr stream, uint64_t eventId, const char *content, uint32_t size); + +int ParamTimerCreate(ParamTaskPtr *timer, TimerProcess process, void *context); +int ParamTimerStart(ParamTaskPtr timer, uint64_t timeout, uint64_t repeat); + +void *ParamGetTaskUserData(ParamTaskPtr stream); + +int FillParamMsgContent(ParamMessage *request, uint32_t *start, int type, const char *value, uint32_t length); +ParamMsgContent *GetNextContent(const ParamMessage *reqest, uint32_t *offset); +ParamMessage *CreateParamMessage(int type, const char *name, uint32_t msgSize); + +int ConntectServer(int fd, const char *servername); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif +#endif // BASE_STARTUP_PARAM_MESSAGE_H \ No newline at end of file diff --git a/services/param/include/param_persist.h b/services/param/include/param_persist.h new file mode 100755 index 000000000..95b14f613 --- /dev/null +++ b/services/param/include/param_persist.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020 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_PARAM_PERSIST_H +#define BASE_STARTUP_PARAM_PERSIST_H +#include +#include +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +typedef int (*PersistParamGetPtr)(const char *name, const char *value, void *context); + +typedef void *PERSIST_SAVE_HANDLE; +typedef struct { + int (*load)(PersistParamGetPtr persistParamGet, void *context); + int (*save)(const char *name, const char *value); + int (*batchSaveBegin)(PERSIST_SAVE_HANDLE *handle); + int (*batchSave)(PERSIST_SAVE_HANDLE handle, const char *name, const char *value); + void (*batchSaveEnd)(PERSIST_SAVE_HANDLE handle); +} PersistParamOps; + +#ifndef PARAM_SUPPORT_SAVE_PERSIST +#define PARAM_SUPPORT_SAVE_PERSIST 1 // default +#endif + +#ifdef PARAM_SUPPORT_SAVE_PERSIST +int RegisterPersistParamOps(PersistParamOps *ops); +#define PARAM_MUST_SAVE_PARAM_DIFF 10 // 10s +#else +#define PARAM_MUST_SAVE_PARAM_DIFF UINT32_MAX +#endif +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif +#endif \ No newline at end of file diff --git a/services/param/include/param_request.h b/services/param/include/param_request.h old mode 100644 new mode 100755 index d2ed318d6..43452e5b8 --- a/services/param/include/param_request.h +++ b/services/param/include/param_request.h @@ -1,3 +1,4 @@ + /* * Copyright (c) 2020 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,54 +16,27 @@ #ifndef BASE_STARTUP_PARAM_REQUEST_H #define BASE_STARTUP_PARAM_REQUEST_H - +#include +#include #include -#include "sys_param.h" #include "param_manager.h" - -#include "uv.h" +#include "sys_param.h" #ifdef __cplusplus #if __cplusplus extern "C" { #endif #endif -typedef enum RequestType { - SET_PARAM, - GET_PARAM, -} RequestType; - typedef struct { - ParamSecurityLabel securitylabel; - RequestType type; - int contentSize; - char content[0]; -} RequestMsg; - -typedef struct { - RequestType type; - int result; - int contentSize; - char content[0]; -} ResponseMsg; - -typedef struct { - uv_loop_t *loop; - uv_connect_t connect; - uv_pipe_t handle; - uv_write_t wr; - int result; - RequestMsg msg; -} RequestNode; - -typedef struct { - uv_write_t writer; - ResponseMsg msg; -} ResponseNode; + ParamWorkSpace paramSpace; + int clientFd; + pthread_mutex_t mutex; +} ClientWorkSpace; +int WatchParamCheck(const char *keyprefix); #ifdef __cplusplus #if __cplusplus } #endif #endif -#endif \ No newline at end of file +#endif diff --git a/services/param/include/param_security.h b/services/param/include/param_security.h new file mode 100755 index 000000000..74149a250 --- /dev/null +++ b/services/param/include/param_security.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2020 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_PARAM_SECURITY_H +#define BASE_STARTUP_PARAM_SECURITY_H +#include +#include +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define DAC_READ 0x0100 +#define DAC_WRITE 0x0080 +#define DAC_WATCH 0x0040 + +#define LABEL_ALL_PERMISSION 0x04 +#define LABEL_CHECK_FOR_ALL_PROCESS 0x02 +#define LABEL_INIT_FOR_INIT 0x01 + +#define LABEL_IS_CLIENT_CHECK_PERMITTED(label) \ + ((label) != NULL) && ((((label)->flags & (LABEL_CHECK_FOR_ALL_PROCESS)) == (LABEL_CHECK_FOR_ALL_PROCESS)) && \ + (((label)->flags & (LABEL_ALL_PERMISSION)) != (LABEL_ALL_PERMISSION))) + +#define LABEL_IS_ALL_PERMITTED(label) \ + (((label) == NULL) || ((label)->flags & LABEL_ALL_PERMISSION) == (LABEL_ALL_PERMISSION)) + +typedef enum { + DAC_RESULT_PERMISSION = 0, + DAC_RESULT_INVALID_PARAM = 1000, + DAC_RESULT_FORBIDED, +} DAC_RESULT; + +typedef struct UserCred { + pid_t pid; + uid_t uid; + gid_t gid; +} UserCred; + +typedef struct { + uint32_t flags; + UserCred cred; +} ParamSecurityLabel; + +typedef struct { + pid_t pid; + uid_t uid; + gid_t gid; + uint32_t mode; // 访问权限 +} ParamDacData; + +typedef struct { + ParamDacData dacData; + const char *name; + const char *label; +} ParamAuditData; + +typedef int (*SecurityLabelFunc)(const ParamAuditData *auditData, void *context); + +typedef struct { + int (*securityInitLabel)(ParamSecurityLabel **label, int isInit); + int (*securityGetLabel)(SecurityLabelFunc label, const char *path, void *context); + int (*securityCheckFilePermission)(const ParamSecurityLabel *label, const char *fileName, int flags); + int (*securityCheckParamPermission)(const ParamSecurityLabel *srcLabel, const ParamAuditData *auditData, int mode); + int (*securityEncodeLabel)(const ParamSecurityLabel *srcLabel, char *buffer, uint32_t *bufferSize); + int (*securityDecodeLabel)(ParamSecurityLabel **srcLabel, char *buffer, uint32_t bufferSize); + int (*securityFreeLabel)(ParamSecurityLabel *srcLabel); +} ParamSecurityOps; + +typedef int (*RegisterSecurityOpsPtr)(ParamSecurityOps *ops, int isInit); + +int RegisterSecurityOps(ParamSecurityOps *ops, int isInit); + +typedef struct { + SecurityLabelFunc label; + void *context; +} LabelFuncContext; + + +#ifdef PARAM_SUPPORT_SELINUX +#ifdef PARAM_SUPPORT_DAC +#error param security only support one. +#endif +#else +#define PARAM_SUPPORT_DAC 1 // default support dac +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif +#endif // BASE_STARTUP_PARAM_SECURITY_H \ No newline at end of file diff --git a/services/param/include/param_service.h b/services/param/include/param_service.h old mode 100644 new mode 100755 index 8a0d85549..59444ab3c --- a/services/param/include/param_service.h +++ b/services/param/include/param_service.h @@ -15,20 +15,34 @@ #ifndef BASE_STARTUP_PARAM_SERVICE_H #define BASE_STARTUP_PARAM_SERVICE_H +#include #include -#include "sys_param.h" + #include "param_manager.h" +#include "sys_param.h" + #ifdef __cplusplus #if __cplusplus extern "C" { #endif #endif -int InitPersistParamWorkSpace(const char *context); -int RefreshPersistParams(ParamWorkSpace *workSpace, const char *context); +#define PARAM_WATCH_FLAGS_WAIT 0x01 + +int WriteParam(WorkSpace *workSpace, const char *name, const char *value, uint32_t *dataIndex, int onlyAdd); + +int InitPersistParamWorkSpace(ParamWorkSpace *workSpace); void ClosePersistParamWorkSpace(); -int WritePersistParam(const char *name, const char *value); +int LoadPersistParam(ParamWorkSpace *workSpace); +int WritePersistParam(ParamWorkSpace *workSpace, const char *name, const char *value); + +#ifdef STARTUP_INIT_TEST +int ProcessMessage(const ParamTaskPtr worker, const ParamMessage *msg); +int AddSecurityLabel(const ParamAuditData *auditData, void *context); +#endif +int ProcessParamWaitAdd(ParamWorkSpace *worksapce, const ParamTaskPtr worker, const ParamMessage *msg); +int ProcessParamWatchAdd(ParamWorkSpace *worksapce, const ParamTaskPtr worker, const ParamMessage *msg); #ifdef __cplusplus #if __cplusplus } diff --git a/services/param/include/param_trie.h b/services/param/include/param_trie.h old mode 100644 new mode 100755 index 8c3e3f984..e993e4d00 --- a/services/param/include/param_trie.h +++ b/services/param/include/param_trie.h @@ -15,15 +15,34 @@ #ifndef BASE_STARTUP_PARAM_TRIE_H #define BASE_STARTUP_PARAM_TRIE_H -#include #include #include #include #include #include "init_log.h" -#include "sys_param.h" +#include "param_security.h" #include "securec.h" +#include "sys_param.h" + + +#ifndef __NR_futex +#define __NR_futex 202 /* syscall number */ +#endif + +#if defined FUTEX_WAIT || defined FUTEX_WAKE +#include +#else +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 + +#define __futex(ftx, op, value, timeout, bitset) \ + struct timespec d_timeout = {0, 1000 * 1000 * (timeout)}; \ + syscall(__NR_futex, ftx, op, value, &d_timeout, NULL, bitset) + +#define futex_wake(ftx, count) __futex(ftx, FUTEX_WAKE, count, 0, 0) +#define futex_wait(ftx, value) __futex(ftx, FUTEX_WAIT, value, 100, 0) +#endif #ifdef __cplusplus #if __cplusplus @@ -31,105 +50,75 @@ extern "C" { #endif #endif -#define PARAM_WORKSPACE_MAX 64*1024 -#define TRIE_SERIAL_DIRTY_OFFSET 1 -#define TRIE_SERIAL_KEY_LEN_OFFSET 24 -#define TRIE_SERIAL_DATA_LEN_OFFSET 16 - -#define FILENAME_LEN_MAX 255 -#define TRIE_DATA_LEN_MAX 128 - -#define NODE_INDEX unsigned int +#define PARAM_WORKSPACE_MAX 80 * 1024 +#define FILENAME_LEN_MAX 255 #define TRIE_NODE_HEADER \ - atomic_uint_least32_t serial; \ - NODE_INDEX left; \ - NODE_INDEX right; - -#define DATA_ENTRY_KEY_LEN(entry) (entry)->dataLength >> TRIE_SERIAL_KEY_LEN_OFFSET -#define DATA_ENTRY_DATA_LEN(entry) (((entry)->dataLength >> TRIE_SERIAL_DATA_LEN_OFFSET) & 0x00FF) -#define DATA_ENTRY_DIRTY(serial) ((serial) & 1) - -#define FUTEX_WAIT 0 -#define FUTEX_WAKE 1 -#define __futex(ftx, op, value, timeout, bitset) \ - syscall(__NR_futex, ftx, op, value, timeout, NULL, bitset) -#define futex_wake(ftx, count) __futex(ftx, FUTEX_WAKE, count, NULL, 0) -#define futex_wait(ftx, value, timeout) __futex(ftx, FUTEX_WAIT, value, timeout, 0) + uint32_t left; \ + uint32_t right; typedef struct { TRIE_NODE_HEADER; + uint32_t child; + uint32_t labelIndex; + uint32_t dataIndex; + uint16_t length; char key[0]; -} TrieNode; +} ParamTrieNode; + +#define PARAM_FLAGS_MODIFY 0x80000000 +#define PARAM_FLAGS_TRIGGED 0x40000000 +#define PARAM_FLAGS_WAITED 0x20000000 +#define PARAM_FLAGS_COMMITID 0x0000ffff typedef struct { - TRIE_NODE_HEADER; - NODE_INDEX child; - NODE_INDEX labelIndex; - NODE_INDEX dataIndex; - char key[0]; -} TrieDataNode; + atomic_uint commitId; + uint16_t keyLength; + uint16_t valueLength; + char data[0]; +} ParamNode; typedef struct { - atomic_uint_least32_t serial; - atomic_uint_least32_t dataLength; + uid_t uid; + gid_t gid; + uint16_t mode; + uint16_t length; char data[0]; -} DataEntry; +} ParamSecruityNode; typedef struct { - atomic_uint_least32_t serial; - u_int32_t currOffset; - u_int32_t firstNode; - u_int32_t dataSize; - u_int32_t reserved_[28]; + uint32_t trieNodeCount; + uint32_t paramNodeCount; + uint32_t securityNodeCount; + uint32_t currOffset; + uint32_t firstNode; + uint32_t dataSize; + uint32_t reserved_[28]; char data[0]; -} WorkArea; +} ParamTrieHeader; struct WorkSpace_; -typedef u_int32_t (*AllocTrieNodePtr)(struct WorkSpace_ *workSpace, const char *key, u_int32_t keyLen); -typedef int (*CompareTrieNodePtr)(TrieNode *node, const char *key2, u_int32_t key2Len); - typedef struct WorkSpace_ { char fileName[FILENAME_LEN_MAX + 1]; - WorkArea *area; - TrieNode *rootNode; - AllocTrieNodePtr allocTrieNode; - CompareTrieNodePtr compareTrieNode; + uint32_t (*allocTrieNode)(struct WorkSpace_ *workSpace, const char *key, uint32_t keyLen); + int (*compareTrieNode)(ParamTrieNode *node, const char *key2, uint32_t key2Len); + ParamTrieHeader *area; } WorkSpace; -u_int32_t GetWorkSpaceSerial(WorkSpace *workSpace); -int CompareTrieNode(TrieNode *node, const char *key, u_int32_t keyLen); -u_int32_t AllocateTrieNode(WorkSpace *workSpace, const char *key, u_int32_t keyLen); -int CompareTrieDataNode(TrieNode *node, const char *key, u_int32_t keyLen); -u_int32_t AllocateTrieDataNode(WorkSpace *workSpace, const char *key, u_int32_t keyLen); - -u_int32_t GetTrieNodeOffset(WorkSpace *workSpace, const TrieNode *current); -TrieNode *GetTrieNode(WorkSpace *workSpace, NODE_INDEX *index); -u_int32_t GetTrieKeyLen(TrieNode *current); -void SaveIndex(NODE_INDEX *index, u_int32_t offset); -TrieDataNode *AddTrieDataNode(WorkSpace *workSpace, const char *key, u_int32_t keyLen); -TrieDataNode *AddToSubTrie(WorkSpace *workSpace, TrieDataNode *dataNode, const char *key, u_int32_t keyLen); -TrieDataNode *FindSubTrie(WorkSpace *workSpace, TrieDataNode *dataNode, const char *key, u_int32_t keyLen); -TrieDataNode *FindTrieDataNode(WorkSpace *workSpace, const char *key, u_int32_t keyLen, int matchPrefix); - -TrieNode *AddTrieNode(WorkSpace *workSpace, TrieNode *root, const char *key, u_int32_t keyLen); -TrieNode *FindTrieNode(WorkSpace *workSpace, TrieNode *tree, const char *key, u_int32_t keyLen); - -int InitWorkSpace_(WorkSpace *workSpace, int mode, int prot, u_int32_t spaceSize, int readOnly); -int InitPersistWorkSpace(const char *fileName, WorkSpace *workSpace); int InitWorkSpace(const char *fileName, WorkSpace *workSpace, int onlyRead); void CloseWorkSpace(WorkSpace *workSpace); -typedef int (*TraversalTrieNodePtr)(WorkSpace *workSpace, TrieNode *node, void *cookie); -int TraversalTrieNode(WorkSpace *workSpace, TrieNode *root, TraversalTrieNodePtr walkFunc, void *cookie); -int TraversalTrieDataNode(WorkSpace *workSpace, TrieDataNode *current, TraversalTrieNodePtr walkFunc, void *cookie); +ParamTrieNode *GetTrieNode(WorkSpace *workSpace, uint32_t offset); +void SaveIndex(uint32_t *index, uint32_t offset); + +ParamTrieNode *AddTrieNode(WorkSpace *workSpace, const char *key, uint32_t keyLen); +ParamTrieNode *FindTrieNode(WorkSpace *workSpace, const char *key, uint32_t keyLen, uint32_t *matchLabel); -u_int32_t AddData(WorkSpace *workSpace, const char *key, u_int32_t keyLen, const char *value, u_int32_t valueLen); -int UpdateDataValue(DataEntry *entry, const char *value); -int GetDataName(const DataEntry *entry, char *name, u_int32_t len); -int GetDataValue(const DataEntry *entry, char *value, u_int32_t len); -u_int32_t GetDataSerial(const DataEntry *entry); +typedef int (*TraversalTrieNodePtr)(WorkSpace *workSpace, ParamTrieNode *node, void *cookie); +int TraversalTrieNode(WorkSpace *workSpace, ParamTrieNode *subTrie, TraversalTrieNodePtr walkFunc, void *cookie); +uint32_t AddParamSecruityNode(WorkSpace *workSpace, const ParamAuditData *auditData); +uint32_t AddParamNode(WorkSpace *workSpace, const char *key, uint32_t keyLen, const char *value, uint32_t valueLen); #ifdef __cplusplus #if __cplusplus } diff --git a/services/param/include/param_utils.h b/services/param/include/param_utils.h new file mode 100755 index 000000000..5fa5ab93a --- /dev/null +++ b/services/param/include/param_utils.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2020 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_PARAM_UTILS_H +#define BASE_STARTUP_PARAM_UTILS_H +#include +#include + +#include "init_log.h" +#include "securec.h" +#include "sys_param.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +typedef enum { + PARAM_CODE_NOT_INIT = PARAM_CODE_MAX + 1, + PARAM_CODE_ERROR_MAP_FILE, +} PARAM_INNER_CODE; + +#define PARAM_ALIGN(len) (((len) + 0x03) & (~0x03)) +#define PARAM_ENTRY(ptr, type, member) (type *)((char *)(ptr)-offsetof(type, member)) + +#define IS_READY_ONLY(name) \ + ((strncmp((name), "const.", strlen("const.")) == 0) || (strncmp((name), "ro.", strlen("ro.")) == 0)) +#define PARAM_CONST_PREFIX "persist." + +#define SYS_POWER_CTRL "sys.powerctrl=" +#define OHOS_CTRL_START "ohos.ctl.start=" +#define OHOS_CTRL_STOP "ohos.ctl.stop=" +#define OHOS_SERVICE_CTRL_PREFIX "ohos.servicectrl." +#define OHOS_BOOT "ohos.boot." + +#ifdef STARTUP_INIT_TEST +#define PARAM_STATIC +#define PARAM_DEFAULT_PATH "/data/startup/test/test_data" +#define PIPE_NAME "/data/paramservice" +#define PARAM_STORAGE_PATH PARAM_DEFAULT_PATH"/__parameters__/param_storage" +#define PARAM_PERSIST_SAVE_PATH PARAM_DEFAULT_PATH"/param/persist_parameters" +#define PARAM_PERSIST_SAVE_TMP_PATH PARAM_DEFAULT_PATH"/param/tmp_persist_parameters" +#define PARAM_CMD_LINE PARAM_DEFAULT_PATH"/proc/cmdline" +#define GROUP_FILE_PATH PARAM_DEFAULT_PATH"/etc/group" +#define USER_FILE_PATH PARAM_DEFAULT_PATH"/etc/passwd" +#else +#define PARAM_DEFAULT_PATH "" +#define PARAM_STATIC static +#define PIPE_NAME "/dev/unix/socket/paramservice" +#define PARAM_STORAGE_PATH "/dev/__parameters__/param_storage" +#define PARAM_PERSIST_SAVE_PATH "/data/parameters/persist_parameters" +#define PARAM_PERSIST_SAVE_TMP_PATH "/data/parameters/tmp_persist_parameters" +#define PARAM_CMD_LINE "/proc/cmdline" +#define GROUP_FILE_PATH "/etc/group" +#define USER_FILE_PATH "/etc/passwd" +#endif + +#define WORKSPACE_FLAGS_INIT 0x01 +#define WORKSPACE_FLAGS_LOADED 0x02 +#define WORKSPACE_FLAGS_UPDATE 0x04 +#define WORKSPACE_FLAGS_LABEL_LOADED 0x08 + +#define PARAM_SET_FLAG(node, flag) ((node) |= (flag)) +#define PARAM_CLEAR_FLAG(node, flag) ((node) &= ~(flag)) +#define PARAM_TEST_FLAG(node, flag) (((node) & (flag)) == (flag)) + +#define PARAM_LOGI(fmt, ...) STARTUP_LOGI(LABEL, fmt, ##__VA_ARGS__) +#define PARAM_LOGE(fmt, ...) STARTUP_LOGE(LABEL, fmt, ##__VA_ARGS__) +#define PARAM_LOGD(fmt, ...) STARTUP_LOGD(LABEL, fmt, ##__VA_ARGS__) + +#define PARAM_CHECK(retCode, exper, ...) \ + if (!(retCode)) { \ + PARAM_LOGE(__VA_ARGS__); \ + exper; \ + } + +#define MAX_LABEL_LEN 256 +#define PARAM_BUFFER_SIZE 256 + +#define SUBSTR_INFO_NAME 0 +#define SUBSTR_INFO_VALUE 1 +#ifdef PARAM_SUPPORT_SELINUX +#define SUBSTR_INFO_LABEL 1 +#define SUBSTR_INFO_DAC 2 +#else +#define SUBSTR_INFO_LABEL 1 +#define SUBSTR_INFO_DAC 1 +#endif + +typedef struct { + int length; + char value[PARAM_BUFFER_SIZE]; +} SubStringInfo; + +#define MAX_DATA_BUFFER 2048 +char *ReadFileData(const char *fileName); +void CheckAndCreateDir(const char *fileName); +int ReadFileInDir(const char *dirPath, const char *includeExt, + int (*processFile)(const char *fileName, void *context), void *context); +int GetSubStringInfo(const char *buff, uint32_t buffLen, char delimiter, SubStringInfo *info, int subStrNumber); +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif +#endif \ No newline at end of file diff --git a/services/param/include/trigger_checker.h b/services/param/include/trigger_checker.h old mode 100644 new mode 100755 index 8bba9e1e4..19b004222 --- a/services/param/include/trigger_checker.h +++ b/services/param/include/trigger_checker.h @@ -15,8 +15,7 @@ #ifndef STARTUP_TRIGER_CHECKER_H #define STARTUP_TRIGER_CHECKER_H - -#include +#include #include #include @@ -41,16 +40,16 @@ extern "C" { #define LOGIC_DATA_CLEAR_FLAG(data, flag) (data)->flags &= ~(flag) typedef struct { - u_int32_t flags; - u_int32_t startIndex; - u_int32_t endIndex; + uint32_t flags; + uint32_t startIndex; + uint32_t endIndex; } LogicData; -struct tagTriggerNode; - +struct tagTriggerNode_; +typedef int (*PARAM_CHECK_DONE)(struct tagTriggerNode_ *trigger, const char *content, uint32_t size); typedef struct { char triggerContent[MAX_TRIGGER_NAME_LEN]; - int (*triggerExecuter)(struct tagTriggerNode *trigger, u_int32_t index); + PARAM_CHECK_DONE triggerExecuter; int dataNumber; int endIndex; int dataUnit; @@ -64,10 +63,10 @@ typedef struct { int CalculatorInit(LogicCalculator *calculator, int dataNumber, int dataUnit, int needCondition); void CalculatorFree(LogicCalculator *calculator); -int ConvertInfixToPrefix(const char *condition, char *prefix, u_int32_t prefixLen); +int ConvertInfixToPrefix(const char *condition, char *prefix, uint32_t prefixLen); int ComputeCondition(LogicCalculator *calculator, const char *condition); -int GetValueFromContent(const char *content, u_int32_t contentSize, u_int32_t start, char *value, u_int32_t valueSize); -char *GetMatchedSubCondition(const char *condition, const char *input, int length); +int GetValueFromContent(const char *content, uint32_t contentSize, uint32_t start, char *value, uint32_t valueSize); +int CheckMatchSubCondition(const char *condition, const char *input, int length); #ifdef __cplusplus #if __cplusplus diff --git a/services/param/include/trigger_manager.h b/services/param/include/trigger_manager.h old mode 100644 new mode 100755 index 6e32fa5d3..f0a604728 --- a/services/param/include/trigger_manager.h +++ b/services/param/include/trigger_manager.h @@ -15,16 +15,15 @@ #ifndef STARTUP_TRIGER_MANAGER_H #define STARTUP_TRIGER_MANAGER_H -#include -#include -#include +#include #include #include "cJSON.h" #include "init_log.h" -#include "param_manager.h" -#include "trigger_checker.h" +#include "param_message.h" +#include "param_utils.h" #include "securec.h" +#include "trigger_checker.h" #ifdef __cplusplus #if __cplusplus @@ -36,88 +35,130 @@ extern "C" { #define TRIGGER_ARR_NAME_IN_JSON "jobs" #define CMDS_ARR_NAME_IN_JSON "cmds" -#define TRIGGER_NODE_IN_QUEUE(trigger) \ - (atomic_load_explicit(&(trigger)->serial, memory_order_relaxed) & 0x01) -#define TRIGGER_NODE_SET_QUEUE_FLAG(trigger) \ - atomic_store_explicit(&(trigger)->serial, (trigger)->serial | 0x01, memory_order_relaxed) -#define TRIGGER_NODE_CLEAR_QUEUE_FLAG(trigger) \ - atomic_store_explicit(&(trigger)->serial, (trigger)->serial & ~0x01, memory_order_relaxed) +#define TRIGGER_EXECUTE_QUEUE 64 +#define MAX_CONDITION_NUMBER 64 + +#define TRIGGER_FLAGS_QUEUE 0x01 +#define TRIGGER_FLAGS_RELATED 0x02 +#define TRIGGER_FLAGS_ONCE 0x04 // 执行完成后释放 +#define TRIGGER_FLAGS_SUBTRIGGER 0x08 // 对init执行后,需要执行的init:xxx=aaa的trigger + +#define CMD_INDEX_FOR_PARA_WAIT 0xfffE +#define CMD_INDEX_FOR_PARA_WATCH 0xffff + +#define TRIGGER_IN_QUEUE(trigger) (((trigger)->flags & TRIGGER_FLAGS_QUEUE) == TRIGGER_FLAGS_QUEUE) +#define TRIGGER_SET_FLAG(trigger, flag) ((trigger)->flags |= (flag)) +#define TRIGGER_CLEAR_FLAG(trigger, flag) ((trigger)->flags &= ~(flag)) +#define TRIGGER_TEST_FLAG(trigger, flag) (((trigger)->flags & (flag)) == (flag)) +#define TRIGGER_GET_EXT_DATA(trigger, TYPE) \ + (trigger)->extDataSize == 0 ? NULL : (TYPE *)(((char *)(trigger)) + (trigger)->extDataOffset) typedef enum { TRIGGER_BOOT = 0, TRIGGER_PARAM, TRIGGER_UNKNOW, - TRIGGER_MAX -}TriggerType; + TRIGGER_MAX, + TRIGGER_PARAM_WAIT, + TRIGGER_PARAM_WATCH +} TriggerType; + +#define PARAM_TRIGGER_FOR_WAIT 0 +#define PARAM_TRIGGER_FOR_WATCH 1 + +typedef struct { + ListNode triggerList; + uint32_t triggerCount; + uint32_t cmdNodeCount; +} TriggerHeader; + +#define PARAM_TRIGGER_HEAD_INIT(head) \ + ListInit(&head.triggerList); \ + head.triggerCount = 0; \ + head.cmdNodeCount = 0; // Command对象列表,主要存储每个triger需要执行那些Command操作。 -typedef struct CommandNode { - atomic_uint_least32_t next; - char name[MAX_TRIGGER_CMD_NAME_LEN]; +typedef struct CommandNode_ { + struct CommandNode_ *next; + uint32_t cmdKeyIndex; char content[0]; } CommandNode; -typedef struct tagTriggerNode { - atomic_uint_least32_t serial; - atomic_uint_least32_t next; - atomic_uint_least32_t firstCmd; - atomic_uint_least32_t lastCmd; - int type; - char name[MAX_TRIGGER_NAME_LEN]; - char condition[0]; +typedef struct tagTriggerNode_ { + ListNode node; + uint32_t flags:24; + uint32_t type:8; + TriggerHeader *triggerHead; + CommandNode *firstCmd; + CommandNode *lastCmd; + uint16_t extDataOffset; + uint16_t extDataSize; + char *condition; + char name[0]; } TriggerNode; typedef struct { - atomic_uint_least32_t serial; - u_int32_t dataSize; - u_int32_t startSize; - u_int32_t currOffset; - char data[0]; -} TriggerArea; - -typedef struct { - atomic_uint_least32_t firstTrigger; - atomic_uint_least32_t lastTrigger; -} TriggerHeader; + uint32_t queueCount; + uint32_t startIndex; + uint32_t endIndex; + TriggerNode **executeQueue; +} TriggerExecuteQueue; typedef struct { - u_int32_t *executeQueue; - u_int32_t queueCount; - u_int32_t startIndex; - u_int32_t endIndex; - pthread_mutex_t mutex; -} TriggerExecuteQueue; + TriggerHeader triggerHead; + ListNode node; + uint32_t timeout; + ParamTaskPtr stream; +} ParamWatcher; + +typedef struct TriggerExtData_ { + int (*excuteCmd)(struct TriggerExtData_ *trigger, int cmd, const char *content); + uint32_t watcherId; + ParamWatcher *watcher; +} TriggerExtData; typedef struct TriggerWorkSpace { + void (*cmdExec)(TriggerNode *trigger, CommandNode *cmd, const char *content, uint32_t size); + ParamTaskPtr eventHandle; + char buffer[PARAM_NAME_LEN_MAX + PARAM_CONST_VALUE_LEN_MAX]; TriggerExecuteQueue executeQueue; - TriggerHeader header[TRIGGER_MAX]; - TriggerArea *area; + TriggerHeader triggerHead[TRIGGER_MAX]; + ParamWatcher watcher; + ListNode waitList; } TriggerWorkSpace; -int InitTriggerWorkSpace(TriggerWorkSpace *workSpace); -int ParseTrigger(TriggerWorkSpace *workSpace, cJSON *triggerItem); +int InitTriggerWorkSpace(); +void CloseTriggerWorkSpace(); -typedef int (*TRIGGER_MATCH)(LogicCalculator *calculator, TriggerNode *trigger, const char *content, u_int32_t contentSize); -typedef int (*PARAM_CHECK_DONE)(TriggerNode *trigger, u_int32_t index); -typedef int (*CMD_EXECUTE) (TriggerNode *trigger, const char *cmdName, const char *command); - -TriggerNode *GetTriggerByName(TriggerWorkSpace *workSpace, const char *triggerName, u_int32_t *triggerIndex); -int ExecuteTrigger(TriggerWorkSpace *workSpace, TriggerNode *trigger, CMD_EXECUTE cmdExecuter); -int CheckTrigger(const TriggerWorkSpace *workSpace, - int type, void *content, u_int32_t contentSize, PARAM_CHECK_DONE triggerExecuter); -int CheckParamTrigger(TriggerWorkSpace *workSpace, - const char *content, u_int32_t contentSize, PARAM_CHECK_DONE triggerExecuter); -int CheckAndExecuteTrigger(TriggerWorkSpace *workSpace, const char *content, PARAM_CHECK_DONE triggerExecuter); +typedef int (*TRIGGER_MATCH)(TriggerWorkSpace *workSpace, LogicCalculator *calculator, + TriggerNode *trigger, const char *content, uint32_t contentSize); +int CheckTrigger(TriggerWorkSpace *workSpace, int type, + const char *content, uint32_t contentSize, PARAM_CHECK_DONE triggerExecuter); +int MarkTriggerToParam(TriggerWorkSpace *workSpace, TriggerHeader *triggerHead, const char *name); +int CheckAndMarkTrigger(int type, const char *name); TriggerNode *ExecuteQueuePop(TriggerWorkSpace *workSpace); -int ExecuteQueuePush(TriggerWorkSpace *workSpace, TriggerNode *trigger, u_int32_t index); +int ExecuteQueuePush(TriggerWorkSpace *workSpace, TriggerNode *trigger); int ExecuteQueueSize(TriggerWorkSpace *workSpace); -u_int32_t AddTrigger(TriggerWorkSpace *workSpace, int type, const char *name, const char *condition); -u_int32_t AddCommand(TriggerWorkSpace *workSpace, TriggerNode *trigger, const char *cmdName, const char *content); +TriggerNode *AddTrigger(TriggerHeader *triggerHead, const char *name, const char *condition, uint16_t extDataSize); +TriggerNode *GetTriggerByName(TriggerWorkSpace *workSpace, const char *triggerName); +void FreeTrigger(TriggerNode *trigger); +void ClearTrigger(TriggerHeader *head); -TriggerWorkSpace *GetTriggerWorkSpace(); +int AddCommand(TriggerNode *trigger, uint32_t cmdIndex, const char *content); +CommandNode *GetNextCmdNode(TriggerNode *trigger, CommandNode *curr); + +void DumpTrigger(TriggerWorkSpace *workSpace); +void PostParamTrigger(int type, const char *name, const char *value); +ParamWatcher *GetParamWatcher(const ParamTaskPtr worker); +ParamWatcher *GetNextParamWatcher(TriggerWorkSpace *workSpace, ParamWatcher *curr); +TriggerNode *AddWatcherTrigger(ParamWatcher *watcher, + int triggerType, const char *name, const char *condition, const TriggerExtData *extData); +void DelWatcherTrigger(ParamWatcher *watcher, uint32_t watcherId); +void ClearWatcherTrigger(ParamWatcher *watcher); + +TriggerWorkSpace *GetTriggerWorkSpace(); #ifdef __cplusplus #if __cplusplus } diff --git a/services/param/manager/param_cache.c b/services/param/manager/param_cache.c deleted file mode 100644 index 690de37e8..000000000 --- a/services/param/manager/param_cache.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2020 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 "sys_param.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "param_manager.h" - -#define LABEL "Manager" -#define MAX_PROPERT_IN_WATCH 5 -#define NORMAL_MEMORY_FOR_PARAM_CACHE 4 * 1024 -static WorkSpace g_workSpace; -static pthread_mutex_t cacheLock = PTHREAD_MUTEX_INITIALIZER; - -static int InitNormalMemory(WorkSpace *workSpace, u_int32_t spaceSize) -{ - PARAM_CHECK(workSpace != NULL, return -1, "Invalid param"); - if (workSpace->area != NULL) { - return 0; - } - - void *areaAddr = (void *)mmap(NULL, spaceSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_POPULATE | MAP_ANON, -1, 0); - PARAM_CHECK(areaAddr != MAP_FAILED, return -1, "Failed to map memory error %s", strerror(errno)); - workSpace->area = (WorkArea*)areaAddr; - atomic_init(&workSpace->area->serial, 0); - workSpace->area->dataSize = spaceSize; - workSpace->area->currOffset = sizeof(WorkArea); - PARAM_LOGI("InitNormalMemory success, currOffset %u firstNode %u dataSize %u", - workSpace->area->currOffset, workSpace->area->firstNode, workSpace->area->dataSize); - return 0; -} - -static ParamCacheNode *AllocParamCacheNode(WorkSpace *workSpace, u_int32_t size) -{ - PARAM_CHECK(workSpace != NULL, return 0, "Invalid param"); - PARAM_CHECK((workSpace->area->currOffset + size) < workSpace->area->dataSize, return 0, - "Failed to allocate currOffset %d, dataSize %d", workSpace->area->currOffset, workSpace->area->dataSize); - ParamCacheNode *cache = (ParamCacheNode *)(workSpace->area->data + workSpace->area->currOffset); - workSpace->area->currOffset += size; - return cache; -} - -static int CreateParamCache(ParamCache *cache, ParamWorkSpace *workSpace, ParamEvaluatePtr evaluate) -{ - PARAM_CHECK(cache != NULL && evaluate != NULL, return -1, "Invalid param"); - if (cache->cacheNode != NULL) { - return 0; - } - int ret = InitNormalMemory(&g_workSpace, NORMAL_MEMORY_FOR_PARAM_CACHE); - PARAM_CHECK(ret == 0, return -1, "Failed to init normal memory"); - pthread_mutex_init(&cache->lock, NULL); - cache->serial = GetWorkSpaceSerial(&workSpace->paramSpace); - cache->cacheCount = 0; - cache->evaluate = evaluate; - cache->cacheNode = (ParamCacheNode *)AllocParamCacheNode(&g_workSpace, - sizeof(ParamCache) * MAX_PROPERT_IN_WATCH); - PARAM_CHECK(cache->cacheNode != NULL, return -1, "Failed to malloc memory"); - return 0; -} - -static int AddParamNode(ParamCache *cache, ParamWorkSpace *workSpace, const char *name, const char *defValue) -{ - PARAM_CHECK(cache != NULL && name != NULL, return -1, "Invalid param"); - PARAM_CHECK(cache->cacheCount < MAX_PROPERT_IN_WATCH, return -1, "Full param in cache"); - - ParamCacheNode *cacheNode = &cache->cacheNode[cache->cacheCount++]; - int ret = memcpy_s(cacheNode->value, sizeof(cacheNode->value), defValue, strlen(defValue)); - PARAM_CHECK(ret == 0, return -1, "Failed to copy default value"); - - ret = ReadParamWithCheck(workSpace, name, &cacheNode->handle); - PARAM_CHECK(ret == 0, return -1, "Failed to read param"); - cacheNode->serial = ReadParamSerial(workSpace, cacheNode->handle); - return ret; -} - -static int CheckCacheNode(ParamWorkSpace *workSpace, ParamCacheNode *cacheNode) -{ - return cacheNode && ReadParamSerial(workSpace, cacheNode->handle) != cacheNode->serial; -} - -static void RefreshCacheNode(ParamWorkSpace *workSpace, ParamCacheNode *cacheNode) -{ - cacheNode->serial = ReadParamSerial(workSpace, cacheNode->handle); - u_int32_t len = sizeof(cacheNode->value); - ReadParamValue(workSpace, cacheNode->handle, cacheNode->value, &len); -} - -static const char *TestParamCache(ParamCache *cache, ParamWorkSpace *workSpace) -{ - int changeDetected = 0; - if (pthread_mutex_trylock(&cache->lock)) { - return cache->evaluate(cache->cacheCount, cache->cacheNode); - } - if (GetWorkSpaceSerial(&workSpace->paramSpace) != cache->serial) { - changeDetected = 1; - } - for (u_int32_t i = 0; (i < cache->cacheCount) && changeDetected == 0; i++) { - changeDetected = CheckCacheNode(workSpace, &cache->cacheNode[i]); - } - if (changeDetected) { - for (u_int32_t i = 0; i < cache->cacheCount; i++) { - RefreshCacheNode(workSpace, &cache->cacheNode[i]); - } - cache->serial = GetWorkSpaceSerial(&workSpace->paramSpace); - } - pthread_mutex_unlock(&cache->lock); - - return cache->evaluate(cache->cacheCount, cache->cacheNode); -} - -const char *DetectParamChange(ParamWorkSpace *workSpace, ParamCache *cache, - ParamEvaluatePtr evaluate, u_int32_t count, const char *parameters[][2]) -{ - pthread_mutex_lock(&cacheLock); - while (cache->cacheCount == 0) { - int ret = CreateParamCache(cache, workSpace, evaluate); - PARAM_CHECK(ret == 0, break, "Failed to create cache"); - for (u_int32_t i = 0; i < count; i++) { - ret = AddParamNode(cache, workSpace, parameters[i][0], parameters[i][1]); - PARAM_CHECK(ret == 0, break, "Failed to add param cache"); - } - PARAM_CHECK(ret == 0, break, "Failed to add param cache"); - } - pthread_mutex_unlock(&cacheLock); - return TestParamCache(cache, workSpace); -} diff --git a/services/param/manager/param_manager.c b/services/param/manager/param_manager.c old mode 100644 new mode 100755 index d0a9b11bd..7d67d55dd --- a/services/param/manager/param_manager.c +++ b/services/param/manager/param_manager.c @@ -12,327 +12,145 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "param_manager.h" - #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #define LABEL "Manager" +#if !defined PARAM_SUPPORT_SELINUX && !defined PARAM_SUPPORT_DAC +static ParamSecurityLabel g_defaultSecurityLabel; +#endif -#ifdef PARAM_SUPPORT_SELINUX -static int SelinuxAuditCallback(void *data, - __attribute__((unused))security_class_t class, char *msgBuf, size_t msgSize) +static int GetParamSecurityOps(ParamWorkSpace *workSpace, int isInit) { - ParamAuditData *auditData = (ParamAuditData*)(data); - PARAM_CHECK(auditData != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); - PARAM_CHECK(auditData->name != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); - PARAM_CHECK(auditData->cr != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); - if (snprintf_s(msgBuf, msgSize, msgSize - 1, "param=%s pid=%d uid=%d gid=%d", - auditData->name, auditData->cr->pid, auditData->cr->uid, auditData->cr->gid) == -1) { - return PARAM_CODE_INVALID_PARAM; - } - return 0; -} + int ret = 0; +#if (defined PARAM_SUPPORT_SELINUX || defined PARAM_SUPPORT_DAC) + ret = RegisterSecurityOps(&workSpace->paramSecurityOps, isInit); + PARAM_CHECK(workSpace->paramSecurityOps.securityInitLabel != NULL, return -1, "Invalid securityInitLabel"); + ret = workSpace->paramSecurityOps.securityInitLabel(&workSpace->securityLabel, isInit); + PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_NAME, "Failed to init security"); +#else + workSpace->securityLabel = &g_defaultSecurityLabel; + workSpace->securityLabel->flags |= LABEL_ALL_PERMISSION; #endif + return ret; +} -int InitParamWorkSpace(ParamWorkSpace *workSpace, int onlyRead, const char *context) +int InitParamWorkSpace(ParamWorkSpace *workSpace, int onlyRead) { - u_int32_t flags = atomic_load_explicit(&workSpace->flags, memory_order_relaxed); - if ((flags & WORKSPACE_FLAGS_INIT) == WORKSPACE_FLAGS_INIT) { + PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_NAME, "Invalid param"); + if (PARAM_TEST_FLAG(workSpace->flags, WORKSPACE_FLAGS_INIT)) { return 0; } - -#ifdef PARAM_SUPPORT_SELINUX - union selinux_callback cb; - cb.func_audit = SelinuxAuditCallback; - selinux_set_callback(SELINUX_CB_AUDIT, cb); -#endif - -#ifdef PARAM_SUPPORT_SELINUX - if (context && fsetxattr(fd, XATTR_NAME_SELINUX, context, strlen(context) + 1, 0) != 0) { - PARAM_LOGI("fsetxattr context %s fail", context); + int isInit = 0; + int op = DAC_READ; + if (onlyRead == 0) { + isInit = LABEL_INIT_FOR_INIT; + op = DAC_WRITE; + } + int ret = GetParamSecurityOps(workSpace, isInit); + PARAM_CHECK(ret == 0, return -1, "Failed to get security operations"); + ParamSecurityOps *paramSecurityOps = &workSpace->paramSecurityOps; + if (!LABEL_IS_ALL_PERMITTED(workSpace->securityLabel)) { + PARAM_CHECK(paramSecurityOps->securityFreeLabel != NULL, return -1, "Invalid securityFreeLabel"); + PARAM_CHECK(paramSecurityOps->securityCheckFilePermission != NULL, return -1, "Invalid securityCheck"); + PARAM_CHECK(paramSecurityOps->securityCheckParamPermission != NULL, return -1, "Invalid securityCheck"); + if (isInit == LABEL_INIT_FOR_INIT) { + PARAM_CHECK(paramSecurityOps->securityGetLabel != NULL, return -1, "Invalid securityGetLabel"); + PARAM_CHECK(paramSecurityOps->securityDecodeLabel != NULL, return -1, "Invalid securityDecodeLabel"); + } else { + PARAM_CHECK(paramSecurityOps->securityEncodeLabel != NULL, return -1, "Invalid securityEncodeLabel"); + } + ret = paramSecurityOps->securityCheckFilePermission(workSpace->securityLabel, PARAM_STORAGE_PATH, op); + PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_NAME, "No permission to read file %s", PARAM_STORAGE_PATH); } -#endif - PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_NAME, "Invalid param"); - workSpace->paramSpace.compareTrieNode = CompareTrieDataNode; - workSpace->paramSpace.allocTrieNode = AllocateTrieDataNode; - int ret = InitWorkSpace(PARAM_STORAGE_PATH, &workSpace->paramSpace, onlyRead); - PARAM_CHECK(ret == 0, return ret, "InitWorkSpace failed."); - - workSpace->paramLabelSpace.compareTrieNode = CompareTrieNode; // 必须先设置 - workSpace->paramLabelSpace.allocTrieNode = AllocateTrieNode; - ret = InitWorkSpace(PARAM_INFO_PATH, &workSpace->paramLabelSpace, onlyRead); - PARAM_CHECK(ret == 0, return ret, "InitWorkSpace failed."); - - atomic_store_explicit(&workSpace->flags, WORKSPACE_FLAGS_INIT, memory_order_release); + ret = InitWorkSpace(PARAM_STORAGE_PATH, &workSpace->paramSpace, onlyRead); + PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_NAME, "Failed to init workspace"); + PARAM_SET_FLAG(workSpace->flags, WORKSPACE_FLAGS_INIT); return ret; } void CloseParamWorkSpace(ParamWorkSpace *workSpace) { CloseWorkSpace(&workSpace->paramSpace); - CloseWorkSpace(&workSpace->paramLabelSpace); - atomic_store_explicit(&workSpace->flags, 0, memory_order_release); + if (workSpace->paramSecurityOps.securityFreeLabel != NULL) { + workSpace->paramSecurityOps.securityFreeLabel(workSpace->securityLabel); + } + workSpace->flags = 0; } -int WriteParamInfo(ParamWorkSpace *workSpace, SubStringInfo *info, int subStrNumber) +static uint32_t ReadCommitId(ParamNode *entry) { - PARAM_CHECK(workSpace != NULL && info != NULL && subStrNumber > SUBSTR_INFO_NAME, - return PARAM_CODE_INVALID_PARAM, "Failed to check param"); - const char *name = info[SUBSTR_INFO_NAME].value; - char *label = NULL; - char *type = NULL; - if (subStrNumber >= SUBSTR_INFO_LABEL) { - label = info[SUBSTR_INFO_LABEL].value; - } else { - label = "u:object_r:default_prop:s0"; + uint32_t commitId = atomic_load_explicit(&entry->commitId, memory_order_acquire); + while (commitId & PARAM_FLAGS_MODIFY) { + futex_wait(&entry->commitId, commitId); + commitId = atomic_load_explicit(&entry->commitId, memory_order_acquire); } - if (subStrNumber >= SUBSTR_INFO_TYPE) { - type = info[SUBSTR_INFO_TYPE].value; - } else { - type = "string"; - } - - int ret = CheckParamName(name, 1); - PARAM_CHECK(ret == 0, return ret, "Illegal param name %s", name); - - // 先保存标签值 - TrieNode *node = AddTrieNode(&workSpace->paramLabelSpace, - workSpace->paramLabelSpace.rootNode, label, strlen(label)); - PARAM_CHECK(node != NULL, return PARAM_CODE_REACHED_MAX, "Failed to add label"); - u_int32_t offset = GetTrieNodeOffset(&workSpace->paramLabelSpace, node); - - TrieDataNode *dataNode = AddTrieDataNode(&workSpace->paramSpace, name, strlen(name)); - PARAM_CHECK(dataNode != NULL, return PARAM_CODE_REACHED_MAX, "Failed to add node %s", name); - TrieNode *entry = (TrieNode *)GetTrieNode(&workSpace->paramLabelSpace, &dataNode->labelIndex); - if (entry != 0) { // 已经存在label - PARAM_LOGE("Has been set label %s old label %s new label: %s", name, entry->key, label); - } - SaveIndex(&dataNode->labelIndex, offset); - return 0; + return commitId & PARAM_FLAGS_COMMITID; } -int AddParam(WorkSpace *workSpace, const char *name, const char *value) +int ReadParamCommitId(ParamWorkSpace *workSpace, ParamHandle handle, uint32_t *commitId) { - PARAM_CHECK(workSpace != NULL && name != NULL && value != NULL, - return PARAM_CODE_INVALID_PARAM, "Failed to check param"); - - TrieDataNode *node = AddTrieDataNode(workSpace, name, strlen(name)); - PARAM_CHECK(node != NULL, return PARAM_CODE_REACHED_MAX, "Failed to add node"); - DataEntry *entry = (DataEntry *)GetTrieNode(workSpace, &node->dataIndex); - //PARAM_LOGI("AddParam entry %p", entry); + PARAM_CHECK(workSpace != NULL && commitId != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid workSpace"); + ParamNode *entry = (ParamNode *)GetTrieNode(&workSpace->paramSpace, handle); if (entry == NULL) { - u_int32_t offset = AddData(workSpace, name, strlen(name), value, strlen(value)); - PARAM_CHECK(offset > 0, return PARAM_CODE_REACHED_MAX, "Failed to allocate name %s", name); - SaveIndex(&node->dataIndex, offset); - //PARAM_LOGI("AddParam entry %p %u", entry, offset); + return -1; } - atomic_store_explicit(&workSpace->area->serial, - atomic_load_explicit(&workSpace->area->serial, memory_order_relaxed) + 1, memory_order_release); - futex_wake(&workSpace->area->serial, INT_MAX); + *commitId = ReadCommitId(entry); return 0; } -int UpdateParam(WorkSpace *workSpace, u_int32_t *dataIndex, const char *name, const char *value) -{ - PARAM_CHECK(workSpace != NULL && name != NULL && value != NULL, - return PARAM_CODE_INVALID_PARAM, "Failed to check param"); - - DataEntry *entry = (DataEntry *)GetTrieNode(workSpace, dataIndex); - PARAM_CHECK(entry != NULL, return PARAM_CODE_REACHED_MAX, - "Failed to update param value %s %u", name, *dataIndex); - u_int32_t keyLen = DATA_ENTRY_KEY_LEN(entry); - PARAM_CHECK(keyLen == strlen(name), return PARAM_CODE_INVALID_NAME, "Failed to check name len %s", name); - - u_int32_t serial = atomic_load_explicit(&entry->serial, memory_order_relaxed); - serial |= 1; - atomic_store_explicit(&entry->serial, serial | 1, memory_order_release); - atomic_thread_fence(memory_order_release); - int ret = UpdateDataValue(entry, value); - if (ret != 0) { - PARAM_LOGE("Failed to update param value %s %s", name, value); - } - //PARAM_LOGI("UpdateParam entry %p", entry); - atomic_store_explicit(&entry->serial, serial + 1, memory_order_release); - futex_wake(&entry->serial, INT_MAX); - atomic_store_explicit(&workSpace->area->serial, - atomic_load_explicit(&workSpace->area->serial, memory_order_relaxed) + 1, memory_order_release); - futex_wake(&workSpace->area->serial, INT_MAX); - return ret; -} - -DataEntry *FindParam(WorkSpace *workSpace, const char *name) -{ - PARAM_CHECK(workSpace != NULL, return NULL, "Failed to check param"); - PARAM_CHECK(name != NULL, return NULL, "Invalid param size"); - - TrieDataNode *node = FindTrieDataNode(workSpace, name, strlen(name), 0); - if (node != NULL) { - return (DataEntry *)GetTrieNode(workSpace, &node->dataIndex); - } - return NULL; -} - -int WriteParamWithCheck(ParamWorkSpace *workSpace, - const ParamSecurityLabel *srcLabel, const char *name, const char *value) -{ - PARAM_CHECK(workSpace != NULL && srcLabel != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); - PARAM_CHECK(value != NULL && name != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); - u_int32_t flags = atomic_load_explicit(&workSpace->flags, memory_order_relaxed); - if ((flags & WORKSPACE_FLAGS_INIT) != WORKSPACE_FLAGS_INIT) { - return PARAM_CODE_NOT_INIT; - } - - int ret = CheckParamName(name, 0); - PARAM_CHECK(ret == 0, return ret, "Illegal param name %s", name); - TrieDataNode *info = FindTrieDataNode(&workSpace->paramSpace, name, strlen(name), 1); - ret = CanWriteParam(workSpace, srcLabel, info, name, value); - //PARAM_LOGI("WriteParamWithCheck info %p", info); - PARAM_CHECK(ret == 0, return ret, "Permission to write param %s", name); - return WriteParam(&workSpace->paramSpace, name, value); -} - -int WriteParam(WorkSpace *workSpace, const char *name, const char *value) +int ReadParamWithCheck(ParamWorkSpace *workSpace, const char *name, int op, ParamHandle *handle) { - PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); - PARAM_CHECK(value != NULL && name != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); - - TrieDataNode *node = FindTrieDataNode(workSpace, name, strlen(name), 0); - int ret = CheckParamValue(workSpace, node, name, value); - PARAM_CHECK(ret == 0, return ret, "Invalid value %s %s", name, value); - //PARAM_LOGI("WriteParamWithCheck node %p", node); - if (node != NULL && node->dataIndex != 0) { - return UpdateParam(workSpace, &node->dataIndex, name, value); - } - return AddParam(workSpace, name, value); -} - -int ReadParamWithCheck(ParamWorkSpace *workSpace, const char *name, ParamHandle *handle) -{ - PARAM_CHECK(handle != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); - PARAM_CHECK(workSpace != NULL && name != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); - u_int32_t flags = atomic_load_explicit(&workSpace->flags, memory_order_relaxed); - if ((flags & WORKSPACE_FLAGS_INIT) != WORKSPACE_FLAGS_INIT) { - return PARAM_CODE_NOT_INIT; - } - + PARAM_CHECK(handle != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param handle"); + PARAM_CHECK(workSpace != NULL && name != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param name"); *handle = 0; - // 取最长匹配 - TrieDataNode *paramInfo = FindTrieDataNode(&workSpace->paramSpace, name, strlen(name), 1); - int ret = CanReadParam(workSpace, paramInfo == NULL ? 0 : paramInfo->labelIndex, name); - PARAM_CHECK(ret == 0, return ret, "Permission to read param %s", name); + int ret = CheckParamPermission(workSpace, workSpace->securityLabel, name, op); + PARAM_CHECK(ret == 0, return ret, "Forbid to access parameter %s", name); - // 查找结点 - TrieDataNode *node = FindTrieDataNode(&workSpace->paramSpace, name, strlen(name), 0); + ParamTrieNode *node = FindTrieNode(&workSpace->paramSpace, name, strlen(name), NULL); if (node != NULL && node->dataIndex != 0) { - //PARAM_LOGI("ReadParamWithCheck trie %p dataIndex %u name %s", node, node->dataIndex, name); *handle = node->dataIndex; return 0; } - return PARAM_CODE_NOT_FOUND_PROP; + return PARAM_CODE_NOT_FOUND; } -int ReadParamValue(ParamWorkSpace *workSpace, ParamHandle handle, char *value, u_int32_t *len) +int ReadParamValue(ParamWorkSpace *workSpace, ParamHandle handle, char *value, uint32_t *length) { - PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); - u_int32_t flags = atomic_load_explicit(&workSpace->flags, memory_order_relaxed); - if ((flags & WORKSPACE_FLAGS_INIT) != WORKSPACE_FLAGS_INIT) { - return PARAM_CODE_NOT_INIT; - } - DataEntry *entry = (DataEntry *)GetTrieNode(&workSpace->paramSpace, &handle); + PARAM_CHECK(workSpace != NULL && length != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); + ParamNode *entry = (ParamNode *)GetTrieNode(&workSpace->paramSpace, handle); if (entry == NULL) { return -1; } - if (value == NULL) { - *len = DATA_ENTRY_DATA_LEN(entry) + 1; + *length = entry->valueLength + 1; return 0; } - - while (1) { - u_int32_t serial = GetDataSerial(entry); - int ret = GetDataValue(entry, value, *len); - PARAM_CHECK(ret == 0, return ret, "Failed to get value"); - atomic_thread_fence(memory_order_acquire); - if (serial == atomic_load_explicit(&(entry->serial), memory_order_relaxed)) { - return 0; - } - } + PARAM_CHECK(*length > entry->valueLength, return PARAM_CODE_INVALID_PARAM, + "Invalid value len %u %u", *length, entry->valueLength); + uint32_t commitId = ReadCommitId(entry); + do { + int ret = memcpy_s(value, *length, entry->data + entry->keyLength + 1, entry->valueLength); + PARAM_CHECK(ret == 0, return -1, "Failed to copy value"); + value[entry->valueLength] = '\0'; + *length = entry->valueLength; + } while (commitId != ReadCommitId(entry)); return 0; } -int ReadParamName(ParamWorkSpace *workSpace, ParamHandle handle, char *name, u_int32_t len) +int ReadParamName(ParamWorkSpace *workSpace, ParamHandle handle, char *name, uint32_t length) { PARAM_CHECK(workSpace != NULL && name != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); - DataEntry *entry = (DataEntry *)GetTrieNode(&workSpace->paramSpace, &handle); + ParamNode *entry = (ParamNode *)GetTrieNode(&workSpace->paramSpace, handle); if (entry == NULL) { return -1; } - return GetDataName(entry, name, len); -} - -u_int32_t ReadParamSerial(ParamWorkSpace *workSpace, ParamHandle handle) -{ - PARAM_CHECK(workSpace != NULL, return 0, "Invalid param"); - DataEntry *entry = (DataEntry *)GetTrieNode(&workSpace->paramSpace, &handle); - if (entry == NULL) { - return 0; - } - return GetDataSerial(entry); -} - -int CheckControlParamPerms(ParamWorkSpace *workSpace, - const ParamSecurityLabel *srcLabel, const char *name, const char *value) -{ - PARAM_CHECK(srcLabel != NULL && name != NULL && value != NULL, - return PARAM_CODE_INVALID_PARAM, "Invalid param"); - - char * ctrlName[] = { - "ctl.start", "ctl.stop", "ctl.restart" - }; - size_t size1 = strlen("ctl.") + strlen(value); - size_t size2 = strlen(name) + strlen(value) + 1; - size_t size = ((size1 > size2) ? size1 : size2) + 1; - char *legacyName = (char*)malloc(size); - PARAM_CHECK(legacyName != NULL, return PARAM_CODE_INVALID_PARAM, "Failed to alloc memory"); - - // We check the legacy method first but these parameters are dontaudit, so we only log an audit - // if the newer method fails as well. We only do this with the legacy ctl. parameters. - for (size_t i = 0; i < sizeof(ctrlName) / sizeof(char*); i++) { - if (strcmp(name, ctrlName[i]) == 0) { - // The legacy permissions model is that ctl. parameters have their name ctl. and - // their value is the name of the service to apply that action to. Permissions for these - // actions are based on the service, so we must create a fake name of ctl. to - // check permissions. - int n = snprintf_s(legacyName, size, strlen("ctl.") + strlen(value) + 1, "ctl.%s", value); - PARAM_CHECK(n > 0, free(legacyName); return PARAM_CODE_INVALID_PARAM, "Failed to snprintf value"); - legacyName[n] = '\0'; - - TrieDataNode *node = FindTrieDataNode(&workSpace->paramSpace, legacyName, strlen(legacyName), 1); - int ret = CheckMacPerms(workSpace, srcLabel, legacyName, node == NULL ? 0 : node->labelIndex); - if (ret == 0) { - free(legacyName); - return 0; - } - break; - } - } - int n = snprintf_s(legacyName, size, size, "%s$%s", name, value); - PARAM_CHECK(n > 0, free(legacyName); return PARAM_CODE_INVALID_PARAM, "Failed to snprintf value"); - - TrieDataNode *node = FindTrieDataNode(&workSpace->paramSpace, name, strlen(name), 1); - int ret = CheckMacPerms(workSpace, srcLabel, name, node == NULL ? 0 : node->labelIndex); - free(legacyName); - return ret; + PARAM_CHECK(length > entry->keyLength, return -1, "Invalid param size %u %u", entry->keyLength, length); + int ret = memcpy_s(name, length, entry->data, entry->keyLength); + PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_PARAM, "Failed to copy name"); + name[entry->keyLength] = '\0'; + return 0; } int CheckParamName(const char *name, int info) @@ -341,6 +159,9 @@ int CheckParamName(const char *name, int info) if (nameLen >= PARAM_NAME_LEN_MAX) { return PARAM_CODE_INVALID_NAME; } + if (strcmp(name, "#") == 0) { + return 0; + } if (nameLen < 1 || name[0] == '.' || (!info && name[nameLen - 1] == '.')) { PARAM_LOGE("CheckParamName %s %d", name, info); @@ -367,168 +188,105 @@ int CheckParamName(const char *name, int info) return 0; } -int CheckParamValue(WorkSpace *workSpace, const TrieDataNode *node, const char *name, const char *value) +static int ProcessParamTraversal(WorkSpace *workSpace, ParamTrieNode *node, void *cookie) { - if (IS_READY_ONLY(name)) { - if (node != NULL && node->dataIndex != 0) { - PARAM_LOGE("Read-only param was already set %s", name); - return PARAM_CODE_READ_ONLY_PROPERTY; - } - } else { - // 限制非read only的参数,防止参数值修改后,原空间不能保存 - PARAM_CHECK(strlen(value) < PARAM_VALUE_LEN_MAX, - return PARAM_CODE_INVALID_VALUE, "Illegal param value"); + ParamTraversalContext *context = (ParamTraversalContext *)cookie; + ParamTrieNode *current = (ParamTrieNode *)node; + if (current == NULL) { + return 0; + } + if (current->dataIndex == 0) { + return 0; } + context->traversalParamPtr(current->dataIndex, context->context); return 0; } -int CheckMacPerms(ParamWorkSpace *workSpace, - const ParamSecurityLabel *srcLabel, const char *name, u_int32_t labelIndex) +int TraversalParam(ParamWorkSpace *workSpace, TraversalParamPtr walkFunc, void *cookie) { -#ifdef PARAM_SUPPORT_SELINUX - ParamAuditData auditData; - auditData.name = name; - auditData.cr = &srcLabel->cred; - - int ret = 0; - TrieNode *node = (TrieNode *)GetTrieNode(&workSpace->paramLabelSpace, &labelIndex); - if (node != 0) { // 已经存在label - ret = selinux_check_access(srcLabel, node->key, "param_service", "set", &auditData); - } else { - ret = selinux_check_access(srcLabel, "u:object_r:default_prop:s0", "param_service", "set", &auditData); - } - return ret == 0 ? 0 : PARAM_CODE_PERMISSION_DENIED; -#else - return 0; -#endif + ParamTraversalContext context = { + walkFunc, cookie + }; + return TraversalTrieNode(&workSpace->paramSpace, NULL, ProcessParamTraversal, &context); } -int CanWriteParam(ParamWorkSpace *workSpace, - const ParamSecurityLabel *srcLabel, const TrieDataNode *node, const char *name, const char *value) +int CheckParamPermission(ParamWorkSpace *workSpace, + const ParamSecurityLabel *srcLabel, const char *name, int mode) { - PARAM_CHECK(workSpace != NULL && name != NULL && value != NULL && srcLabel != NULL, - return PARAM_CODE_INVALID_PARAM, "Invalid param"); - - if (strncmp(name, "ctl.", strlen("ctl.")) == 0) { // 处理ctrl TODO - return CheckControlParamPerms(workSpace, srcLabel, name, value); + if (LABEL_IS_ALL_PERMITTED(workSpace->securityLabel)) { + return 0; } + PARAM_CHECK(name != NULL && srcLabel != NULL, return -1, "Invalid param"); + if (workSpace->paramSecurityOps.securityCheckParamPermission == NULL) { + return DAC_RESULT_FORBIDED; + } + uint32_t labelIndex = 0; + FindTrieNode(&workSpace->paramSpace, name, strlen(name), &labelIndex); + ParamSecruityNode *node = (ParamSecruityNode *)GetTrieNode(&workSpace->paramSpace, labelIndex); + PARAM_CHECK(node != NULL, return DAC_RESULT_FORBIDED, "Can not get security label %d", labelIndex); - int ret = CheckMacPerms(workSpace, srcLabel, name, node == NULL ? 0 : node->labelIndex); - PARAM_CHECK(ret == 0, return ret, "SELinux permission check failed"); - return 0; -} - -int CanReadParam(ParamWorkSpace *workSpace, u_int32_t labelIndex, const char *name) -{ - PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); - PARAM_CHECK(name != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); -#ifdef PARAM_SUPPORT_SELINUX - ParamAuditData auditData; + ParamAuditData auditData = {}; auditData.name = name; - UserCred cr = {.pid = 0, .uid = 0, .gid = 0}; - auditData.cr = &cr; - - int ret = 0; - TrieNode *node = (TrieNode *)GetTrieNode(&workSpace->paramLabelSpace, &labelIndex); - if (node != 0) { // 已经存在label - ret = selinux_check_access(&workSpace->context, node->key, "param_service", "read", &auditData); - } else { - ret = selinux_check_access(&workSpace->context, "selinux_check_access", "file", "read", &auditData); - } - return ret == 0 ? 0 : PARAM_CODE_PERMISSION_DENIED; -#else - return 0; -#endif + auditData.dacData.uid = node->uid; + auditData.dacData.gid = node->gid; + auditData.dacData.mode = node->mode; + auditData.label = node->data; + return workSpace->paramSecurityOps.securityCheckParamPermission(srcLabel, &auditData, mode); } -int GetSubStringInfo(const char *buff, u_int32_t buffLen, char delimiter, SubStringInfo *info, int subStrNumber) +static int DumpTrieDataNodeTraversal(WorkSpace *workSpace, ParamTrieNode *node, void *cookie) { - size_t i = 0; - // 去掉开始的空格 - for (; i < strlen(buff); i++) { - if (!isspace(buff[i])) { - break; - } + int verbose = *(int *)cookie; + ParamTrieNode *current = (ParamTrieNode *)node; + if (current == NULL) { + return 0; } - // 过滤掉注释 - if (buff[i] == '#') { - return -1; + if (verbose) { + printf(" Trie node info [%5u,%5u,%5u] data [%5u,%5u] length:%-5d %s \n", + current->left, current->right, current->child, + current->dataIndex, current->labelIndex, current->length, current->key); } - // 分割字符串 - int spaceIsValid = 0; - int curr = 0; - int valueCurr = 0; - for (; i < buffLen; i++) { - if (buff[i] == '\n' || buff[i] == '\r') { - break; - } - if (buff[i] == delimiter && valueCurr != 0) { - info[curr].value[valueCurr] = '\0'; - valueCurr = 0; - curr++; - spaceIsValid = 1; - } else { - if (!spaceIsValid && isspace(buff[i])) { - continue; - } - if ((valueCurr + 1) >= (int)sizeof(info[curr].value)) { - continue; - } - info[curr].value[valueCurr++] = buff[i]; - } - if (curr >= subStrNumber) { - break; + if (current->dataIndex != 0) { + ParamNode *entry = (ParamNode *)GetTrieNode(workSpace, current->dataIndex); + if (entry != NULL) { + printf("\tparameter length [%5d,%5d] %s \n", + entry->keyLength, entry->valueLength, (entry != NULL) ? entry->data : "null"); } } - if (valueCurr > 0) { - info[curr].value[valueCurr] = '\0'; - valueCurr = 0; - curr++; + if (current->labelIndex != 0) { + ParamSecruityNode *label = (ParamSecruityNode *)GetTrieNode(workSpace, current->labelIndex); + if (label != NULL) { + printf("\tparameter label dac %d %d %o %s \n", + label->uid, label->gid, label->mode, (label->length > 0) ? label->data : "null"); + } } - return curr; + return 0; } -int BuildParamContent(char *content, u_int32_t contentSize, const char *name, const char *value) +static void DumpWorkSpace(ParamWorkSpace *workSpace, int verbose) { - PARAM_CHECK(name != NULL && value != NULL && content != NULL, return -1, "Invalid param"); - u_int32_t nameLen = (u_int32_t)strlen(name); - u_int32_t valueLen = (u_int32_t)strlen(value); - PARAM_CHECK(contentSize >= (nameLen + valueLen + 2), return -1, "Invalid content size %u", contentSize); - - int offset = 0; - int ret = memcpy_s(content + offset, contentSize - offset, name, nameLen); - PARAM_CHECK(ret == 0, return -1, "Failed to copy porperty"); - offset += nameLen; - ret = memcpy_s(content + offset, contentSize - offset, "=", 1); - PARAM_CHECK(ret == 0, return -1, "Failed to copy porperty"); - offset += 1; - ret = memcpy_s(content + offset, contentSize - offset, value, valueLen); - offset += valueLen; - content[offset] = '\0'; - PARAM_CHECK(ret == 0, return -1, "Failed to copy porperty"); - offset += 1; - return offset; + printf("workSpace information \n"); + printf(" map file: %s \n", workSpace->paramSpace.fileName); + printf(" total size: %d \n", workSpace->paramSpace.area->dataSize); + printf(" first offset: %d \n", workSpace->paramSpace.area->firstNode); + printf(" current offset: %d \n", workSpace->paramSpace.area->currOffset); + printf(" total node: %d \n", workSpace->paramSpace.area->trieNodeCount); + printf(" total param node: %d \n", workSpace->paramSpace.area->paramNodeCount); + printf(" total security node: %d\n", workSpace->paramSpace.area->securityNodeCount); + printf(" node info: \n"); + TraversalTrieNode(&workSpace->paramSpace, NULL, DumpTrieDataNodeTraversal, (void *)&verbose); } -int ProcessParamTraversal(WorkSpace *workSpace, TrieNode *node, void *cookie) +void DumpParameters(ParamWorkSpace *workSpace, int verbose) { - ParamTraversalContext *context = (ParamTraversalContext *)cookie; - TrieDataNode *current = (TrieDataNode *)node; - if (current == NULL) { - return 0; - } - if (current->dataIndex == 0) { - return 0; - } - context->traversalParamPtr(current->dataIndex, context->context); - return 0; + printf("Dump all paramters begin ...\n"); + DumpWorkSpace(workSpace, verbose); + if (verbose) { + printf("Local sercurity information\n"); + printf("\t pid: %d uid: %d gid: %d \n", + workSpace->securityLabel->cred.pid, + workSpace->securityLabel->cred.uid, + workSpace->securityLabel->cred.gid); + } + printf("Dump all paramters finish\n"); } - -int TraversalParam(ParamWorkSpace *workSpace, TraversalParamPtr walkFunc, void *cookie) -{ - ParamTraversalContext context = { - walkFunc, cookie - }; - return TraversalTrieDataNode(&workSpace->paramSpace, - (TrieDataNode *)workSpace->paramSpace.rootNode, ProcessParamTraversal, &context); -} \ No newline at end of file diff --git a/services/param/manager/param_message.c b/services/param/manager/param_message.c new file mode 100755 index 000000000..0a41d285c --- /dev/null +++ b/services/param/manager/param_message.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2020 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 "param_message.h" +#include +#include +#include +#include +#include +#include + +#define LABEL "PARAM_MSG" +int ConntectServer(int fd, const char *servername) +{ + PARAM_CHECK(fd >= 0, return -1, "Invalid fd %d", fd); + PARAM_CHECK(servername != NULL, return -1, "Invalid servername"); + struct sockaddr_un addr; + /* fill socket address structure with server's address */ + int ret = memset_s(&addr, sizeof(addr), 0, sizeof(addr)); + PARAM_CHECK(ret == 0, return -1, "Failed to memset server address"); + addr.sun_family = AF_UNIX; + ret = sprintf_s(addr.sun_path, sizeof(addr.sun_path) - 1, "%s", servername); + PARAM_CHECK(ret > 0, return -1, "Failed to sprintf_s server address"); + int len = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path); + ret = connect(fd, (struct sockaddr *)&addr, len); + PARAM_CHECK(ret != -1, return -1, "Failed to connect server %s %s", servername, strerror(errno)); + return 0; +} + +int FillParamMsgContent(ParamMessage *request, uint32_t *start, int type, const char *value, uint32_t length) +{ + PARAM_CHECK(request != NULL && start != NULL, return -1, "Invalid param"); + PARAM_CHECK(value != NULL && length > 0, return -1, "Invalid value"); + uint32_t bufferSize = request->msgSize - sizeof(ParamMessage); + uint32_t offset = *start; + PARAM_CHECK((offset + sizeof(ParamMsgContent) + length) <= bufferSize, + return -1, "Invalid msgSize %u offset %u %d", request->msgSize, offset, type); + ParamMsgContent *content = (ParamMsgContent *)(request->data + offset); + content->type = type; + content->contentSize = length + 1; + int ret = memcpy_s(content->content, content->contentSize - 1, value, length); + PARAM_CHECK(ret == 0, return -1, "Failed to copy value for %d", type); + content->content[length] = '\0'; + offset += sizeof(ParamMsgContent) + PARAM_ALIGN(content->contentSize); + *start = offset; + return 0; +} + +ParamMessage *CreateParamMessage(int type, const char *name, uint32_t msgSize) +{ + if (msgSize < sizeof(ParamMessage)) { + msgSize = sizeof(ParamMessage); + } + ParamMessage *msg = (ParamMessage *)malloc(msgSize); + PARAM_CHECK(msg != NULL, return NULL, "Failed to malloc message"); + msg->type = type; + msg->id.msgId = 0; + msg->msgSize = msgSize; + int ret = strcpy_s(msg->key, sizeof(msg->key) - 1, name); + PARAM_CHECK(ret == 0, free(msg); return NULL, "Failed to fill name"); + return msg; +} + +ParamMsgContent *GetNextContent(const ParamMessage *reqest, uint32_t *offset) +{ + ParamMessage *msg = (ParamMessage *)reqest; + if ((msg == NULL) || ((*offset + sizeof(ParamMessage) + sizeof(ParamMsgContent)) >= msg->msgSize)) { + return NULL; + } + ParamMsgContent *content = (ParamMsgContent *)(msg->data + *offset); + *offset += sizeof(ParamMsgContent) + PARAM_ALIGN(content->contentSize); + return content; +} diff --git a/services/param/manager/param_trie.c b/services/param/manager/param_trie.c old mode 100644 new mode 100755 index c380a8786..60a7c234e --- a/services/param/manager/param_trie.c +++ b/services/param/manager/param_trie.c @@ -19,8 +19,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -28,70 +28,27 @@ #include #include "init_utils.h" +#include "param_utils.h" #include "sys_param.h" -#include "param_manager.h" #define LABEL "Manager" -int InitWorkSpace(const char *fileName, WorkSpace *workSpace, int onlyRead) -{ - PARAM_CHECK(fileName != NULL, return PARAM_CODE_INVALID_NAME, "Invalid param"); - PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_NAME, "Invalid param"); - if (workSpace->area != NULL) { - return 0; - } - - int ret = memcpy_s(workSpace->fileName, FILENAME_LEN_MAX, fileName, strlen(fileName)); - PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_NAME, "Copy file %s fail ", fileName); - int openMode = 0; - int prot = PROT_READ; - if (onlyRead) { - openMode = O_RDONLY; - } else { - openMode = O_CREAT | O_RDWR | O_TRUNC; - prot = PROT_READ | PROT_WRITE; - } - ret = InitWorkSpace_(workSpace, openMode, prot, PARAM_WORKSPACE_MAX, onlyRead); - PARAM_CHECK(ret == 0, return ret, "Failed to init workspace %s", workSpace->fileName); - return ret; -} - -int InitPersistWorkSpace(const char *fileName, WorkSpace *workSpace) -{ - PARAM_CHECK(fileName != NULL, return PARAM_CODE_INVALID_NAME, "Invalid param"); - PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_NAME, "Invalid param"); - if (workSpace->area != NULL) { - return 0; - } - - int ret = memcpy_s(workSpace->fileName, FILENAME_LEN_MAX, fileName, strlen(fileName)); - PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_NAME, "Copy file %s fail ", fileName); - - int flag = (access(fileName, F_OK) == 0) ? 1 : 0; - int openMode = (flag == 0) ? (O_CREAT | O_RDWR | O_TRUNC) : O_RDWR; - int prot = PROT_READ | PROT_WRITE; - ret = InitWorkSpace_(workSpace, openMode, prot, PARAM_WORKSPACE_MAX, flag); - PARAM_CHECK(ret == 0, return ret, "Failed to init workspace %s", workSpace->fileName); - return ret; -} - -int InitWorkSpace_(WorkSpace *workSpace, int mode, int prot, u_int32_t spaceSize, int readOnly) +static int InitWorkSpace_(WorkSpace *workSpace, int mode, int prot, uint32_t spaceSize, int readOnly) { - PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid fileName"); + PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid workSpace"); PARAM_CHECK(workSpace->allocTrieNode != NULL, - return PARAM_CODE_INVALID_PARAM, "Invalid param %s", workSpace->fileName); + return PARAM_CODE_INVALID_PARAM, "Invalid allocTrieNode %s", workSpace->fileName); PARAM_CHECK(workSpace->compareTrieNode != NULL, - return PARAM_CODE_INVALID_PARAM, "Invalid param %s", workSpace->fileName); + return PARAM_CODE_INVALID_PARAM, "Invalid compareTrieNode %s", workSpace->fileName); PARAM_LOGD("InitWorkSpace %s ", workSpace->fileName); CheckAndCreateDir(workSpace->fileName); - int fd = open(workSpace->fileName, mode, 00777); //0444); + int fd = open(workSpace->fileName, mode, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); PARAM_CHECK(fd >= 0, return PARAM_CODE_INVALID_NAME, - "Open file %s fail error %s", workSpace->fileName, strerror(errno)); + "Open file %s mode %x fail error %s", workSpace->fileName, mode, strerror(errno)); if (!readOnly) { - lseek(fd, spaceSize - 1, SEEK_SET); - write(fd, "", 1); + ftruncate(fd, spaceSize); } void *areaAddr = (void *)mmap(NULL, spaceSize, prot, MAP_SHARED, fd, 0); PARAM_CHECK(areaAddr != MAP_FAILED, close(fd); return PARAM_CODE_ERROR_MAP_FILE, @@ -99,64 +56,30 @@ int InitWorkSpace_(WorkSpace *workSpace, int mode, int prot, u_int32_t spaceSize close(fd); if (!readOnly) { - workSpace->area = (WorkArea*)areaAddr; - atomic_init(&workSpace->area->serial, 0); - workSpace->area->dataSize = spaceSize; - workSpace->area->currOffset = sizeof(WorkArea); - // 创建一个key为#的节点 - u_int32_t offset = workSpace->allocTrieNode(workSpace, "#", 1); + workSpace->area = (ParamTrieHeader *)areaAddr; + workSpace->area->trieNodeCount = 0; + workSpace->area->paramNodeCount = 0; + workSpace->area->securityNodeCount = 0; + workSpace->area->dataSize = spaceSize - sizeof(ParamTrieHeader); + workSpace->area->currOffset = 0; + uint32_t offset = workSpace->allocTrieNode(workSpace, "#", 1); workSpace->area->firstNode = offset; - workSpace->rootNode = GetTrieNode(workSpace, &offset); } else { - workSpace->area = (WorkArea*)areaAddr; - workSpace->rootNode = GetTrieNode(workSpace, &workSpace->area->firstNode); + workSpace->area = (ParamTrieHeader *)areaAddr; } PARAM_LOGD("InitWorkSpace success, readOnly %d currOffset %u firstNode %u dataSize %u", readOnly, workSpace->area->currOffset, workSpace->area->firstNode, workSpace->area->dataSize); return 0; } -void CloseWorkSpace(WorkSpace *workSpace) -{ - PARAM_CHECK(workSpace != NULL && workSpace->area != NULL, return, "The workspace is null"); - munmap((char *)workSpace->area, workSpace->area->dataSize); - workSpace->area = NULL; -} - -u_int32_t GetWorkSpaceSerial(WorkSpace *workSpace) -{ - PARAM_CHECK(workSpace != NULL && workSpace->area != NULL, return 0, "The workspace is null"); - return (u_int32_t)workSpace->area->serial; -} - -u_int32_t AllocateTrieNode(WorkSpace *workSpace, const char *key, u_int32_t keyLen) -{ - u_int32_t len = keyLen + sizeof(TrieNode) + 1; - len = (len + 0x03) & (~0x03); - PARAM_CHECK((workSpace->area->currOffset + len) < workSpace->area->dataSize, return 0, - "Failed to allocate currOffset %d, dataSize %d", workSpace->area->currOffset, workSpace->area->dataSize); - TrieNode *node = (TrieNode*)(workSpace->area->data + workSpace->area->currOffset + len); - - atomic_init(&node->serial, ATOMIC_VAR_INIT(keyLen << TRIE_SERIAL_KEY_LEN_OFFSET)); - int ret = memcpy_s(node->key, keyLen, key, keyLen); - PARAM_CHECK(ret == 0, return 0, "Failed to copy key"); - node->key[keyLen] = '\0'; - node->left = 0; - node->right = 0; - u_int32_t offset = workSpace->area->currOffset; - workSpace->area->currOffset += len; - return offset; -} - -u_int32_t AllocateTrieDataNode(WorkSpace *workSpace, const char *key, u_int32_t keyLen) +static uint32_t AllocateParamTrieNode(WorkSpace *workSpace, const char *key, uint32_t keyLen) { - u_int32_t len = keyLen + sizeof(TrieDataNode) + 1; - len = (len + 0x03) & (~0x03); + uint32_t len = keyLen + sizeof(ParamTrieNode) + 1; + len = PARAM_ALIGN(len); PARAM_CHECK((workSpace->area->currOffset + len) < workSpace->area->dataSize, return 0, "Failed to allocate currOffset %d, dataSize %d", workSpace->area->currOffset, workSpace->area->dataSize); - TrieDataNode *node = (TrieDataNode*)(workSpace->area->data + workSpace->area->currOffset); - - atomic_init(&node->serial, ATOMIC_VAR_INIT(keyLen << TRIE_SERIAL_KEY_LEN_OFFSET)); + ParamTrieNode *node = (ParamTrieNode*)(workSpace->area->data + workSpace->area->currOffset); + node->length = keyLen; int ret = memcpy_s(node->key, keyLen, key, keyLen); PARAM_CHECK(ret == 0, return 0, "Failed to copy key"); node->key[keyLen] = '\0'; @@ -165,98 +88,122 @@ u_int32_t AllocateTrieDataNode(WorkSpace *workSpace, const char *key, u_int32_t node->child = 0; node->dataIndex = 0; node->labelIndex = 0; - u_int32_t offset = workSpace->area->currOffset; + uint32_t offset = workSpace->area->currOffset; workSpace->area->currOffset += len; + workSpace->area->trieNodeCount++; return offset; } -TrieNode *GetTrieNode(WorkSpace *workSpace, NODE_INDEX *index) +static int CompareParamTrieNode(ParamTrieNode *node, const char *key, uint32_t keyLen) { - if (index == NULL) { - return NULL; - } - u_int32_t offset = *index; // atomic_load_explicit(¤t->children, memory_order_relaxed); - if (offset == 0 || offset > workSpace->area->dataSize) { - return NULL; + if (node->length > keyLen) { + return -1; + } else if (node->length < keyLen) { + return 1; } - return (TrieNode*)(workSpace->area->data + offset); + return strncmp(node->key, key, keyLen); } -u_int32_t GetTrieKeyLen(TrieNode *current) +int InitWorkSpace(const char *fileName, WorkSpace *workSpace, int onlyRead) { - return (current)->serial >> TRIE_SERIAL_KEY_LEN_OFFSET; + PARAM_CHECK(fileName != NULL, return PARAM_CODE_INVALID_NAME, "Invalid fileName"); + PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_NAME, "Invalid workSpace"); + if (workSpace->area != NULL) { + return 0; + } + workSpace->compareTrieNode = CompareParamTrieNode; + workSpace->allocTrieNode = AllocateParamTrieNode; + int ret = memcpy_s(workSpace->fileName, FILENAME_LEN_MAX, fileName, strlen(fileName)); + PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_NAME, "Copy file %s fail ", fileName); + int openMode = 0; + int prot = PROT_READ; + if (onlyRead) { + openMode = O_RDONLY; + } else { + openMode = O_CREAT | O_RDWR | O_TRUNC; + prot = PROT_READ | PROT_WRITE; + } + ret = InitWorkSpace_(workSpace, openMode, prot, PARAM_WORKSPACE_MAX, onlyRead); + PARAM_CHECK(ret == 0, return ret, "Failed to init workspace %s", workSpace->fileName); + return ret; } -u_int32_t GetTrieNodeOffset(WorkSpace *workSpace, const TrieNode *current) +void CloseWorkSpace(WorkSpace *workSpace) { - return (((char *)current) - workSpace->area->data); + PARAM_CHECK(workSpace != NULL && workSpace->area != NULL, return, "The workspace is null"); + munmap((char *)workSpace->area, workSpace->area->dataSize); + workSpace->area = NULL; } -void SaveIndex(NODE_INDEX *index, u_int32_t offset) +static ParamTrieNode *GetTrieRoot(WorkSpace *workSpace) { - // atomic_store_explicit(¤t->children, new_offset, memory_order_release); - *index = offset; + return (ParamTrieNode *)(workSpace->area->data + workSpace->area->firstNode); } -int CompareTrieDataNode(TrieNode *node, const char *key, u_int32_t keyLen) +static void GetNextKey(const char **remainingKey, char **subKey, uint32_t *subKeyLen) { - TrieDataNode *data = (TrieDataNode *)node; - u_int32_t len = GetTrieKeyLen((TrieNode *)data); - if (len > keyLen) { - return -1; - } else if (len < keyLen) { - return 1; + *subKey = strchr(*remainingKey, '.'); + if (*subKey != NULL) { + *subKeyLen = *subKey - *remainingKey; + } else { + *subKeyLen = strlen(*remainingKey); } - return strncmp(data->key, key, keyLen); } -int CompareTrieNode(TrieNode *node, const char *key, u_int32_t keyLen) +static ParamTrieNode *AddToSubTrie(WorkSpace *workSpace, ParamTrieNode *current, const char *key, uint32_t keyLen) { - u_int32_t len = GetTrieKeyLen(node); - if (len > keyLen) { - return -1; - } else if (len < keyLen) { - return 1; + if (current == NULL) { + return NULL; } - return strncmp(node->key, key, keyLen); -} - -static void GetNextKey(const char **remainingKey, char **subKey, u_int32_t *subKeyLen) -{ - *subKey = strchr(*remainingKey, '.'); - if (*subKey != NULL) { - *subKeyLen = *subKey - *remainingKey; + ParamTrieNode *subTrie = NULL; + int ret = workSpace->compareTrieNode(current, key, keyLen); + if (ret == 0) { + return current; + } + if (ret < 0) { + subTrie = GetTrieNode(workSpace, current->left); + if (subTrie == NULL) { + uint32_t offset = workSpace->allocTrieNode(workSpace, key, keyLen); + PARAM_CHECK(offset != 0, return NULL, "Failed to allocate key %s", key); + SaveIndex(¤t->left, offset); + return GetTrieNode(workSpace, current->left); + } } else { - *subKeyLen = strlen(*remainingKey); + subTrie = GetTrieNode(workSpace, current->right); + if (subTrie == NULL) { + uint32_t offset = workSpace->allocTrieNode(workSpace, key, keyLen); + PARAM_CHECK(offset != 0, return NULL, "Failed to allocate key %s", key); + SaveIndex(¤t->right, offset); + return GetTrieNode(workSpace, current->right); + } } + return AddToSubTrie(workSpace, subTrie, key, keyLen); } -TrieDataNode *AddTrieDataNode(WorkSpace *workSpace, const char *key, u_int32_t keyLen) +ParamTrieNode *AddTrieNode(WorkSpace *workSpace, const char *key, uint32_t keyLen) { + PARAM_CHECK(key != NULL && keyLen > 0, return NULL, "Invalid param "); + PARAM_CHECK(workSpace != NULL, return NULL, "Invalid param %s", key); PARAM_CHECK(workSpace->allocTrieNode != NULL, return NULL, "Invalid param %s", key); PARAM_CHECK(workSpace->compareTrieNode != NULL, return NULL, "Invalid param %s", key); - const char *remainingKey = key; - TrieDataNode *current = (TrieDataNode *)workSpace->rootNode; + ParamTrieNode *current = GetTrieRoot(workSpace); PARAM_CHECK(current != NULL, return NULL, "Invalid current param %s", key); while (1) { - u_int32_t subKeyLen = 0; + uint32_t subKeyLen = 0; char *subKey = NULL; GetNextKey(&remainingKey, &subKey, &subKeyLen); if (!subKeyLen) { return NULL; } - u_int32_t offset = subKey == NULL ? strlen(key) : subKey - key; - if (current->child != 0) { // 如果child存在,则检查是否匹配 - TrieDataNode *next = (TrieDataNode*)GetTrieNode(workSpace, ¤t->child); - if (next != NULL && workSpace->compareTrieNode((TrieNode*)next, remainingKey, subKeyLen) == 0) { - current = next; - } else { // 不匹配,需要建立子树 - current = (TrieDataNode*)AddToSubTrie(workSpace, current, key, offset); - } + ParamTrieNode *next = GetTrieNode(workSpace, current->child); + current = AddToSubTrie(workSpace, next, remainingKey, subKeyLen); } else { - current = (TrieDataNode*)AddToSubTrie(workSpace, current, key, offset); + uint32_t dataOffset = workSpace->allocTrieNode(workSpace, remainingKey, subKeyLen); + PARAM_CHECK(dataOffset != 0, return NULL, "Failed to allocate key %s", key); + SaveIndex(¤t->child, dataOffset); + current = (ParamTrieNode *)GetTrieNode(workSpace, current->child); } if (current == NULL) { return NULL; @@ -269,265 +216,175 @@ TrieDataNode *AddTrieDataNode(WorkSpace *workSpace, const char *key, u_int32_t k return current; } -TrieDataNode *AddToSubTrie(WorkSpace *workSpace, TrieDataNode *dataNode, const char *key, u_int32_t keyLen) +static ParamTrieNode *FindSubTrie(WorkSpace *workSpace, + ParamTrieNode *current, const char *key, uint32_t keyLen, uint32_t *matchLabel) { - TrieDataNode *root = NULL; - int ret = workSpace->compareTrieNode((TrieNode *)dataNode, key, keyLen); - if (ret <= 0) { - root = (TrieDataNode *)GetTrieNode(workSpace, &dataNode->left); - if (root == NULL) { - u_int32_t offset = workSpace->allocTrieNode(workSpace, key, keyLen); - PARAM_CHECK(offset != 0, return NULL, "Failed to allocate key %s", key); - SaveIndex(&dataNode->left, offset); - return (TrieDataNode *)GetTrieNode(workSpace, &dataNode->left); - } - } else { - root = (TrieDataNode *)GetTrieNode(workSpace, &dataNode->right); - if (root == NULL) { - u_int32_t offset = workSpace->allocTrieNode(workSpace, key, keyLen); - PARAM_CHECK(offset != 0, return NULL, "Failed to allocate key %s", key); - SaveIndex(&dataNode->right, offset); - return (TrieDataNode *)GetTrieNode(workSpace, &dataNode->right); - } + if (current == NULL) { + return NULL; } - return (TrieDataNode*)AddTrieNode(workSpace, (TrieNode*)root, key, keyLen); -} -TrieNode *AddTrieNode(WorkSpace *workSpace, TrieNode *root, const char *key, u_int32_t keyLen) -{ - PARAM_CHECK(root != NULL, return NULL, "Invalid param %s", key); - TrieNode *current = root; - TrieNode *next = NULL; - while (1) { - if (current == NULL) { - return NULL; + ParamTrieNode *subTrie = NULL; + int ret = workSpace->compareTrieNode(current, key, keyLen); + if (ret == 0) { + if (matchLabel != NULL && current->labelIndex != 0) { // 有效前缀 + *matchLabel = current->labelIndex; } - int ret = workSpace->compareTrieNode(current, key, keyLen); - if (ret == 0) { - return current; + return current; + } + if (ret < 0) { + subTrie = (ParamTrieNode *)GetTrieNode(workSpace, current->left); + if (subTrie == NULL) { + return NULL; } - if (ret < 0) { - next = GetTrieNode(workSpace, ¤t->left); - if (next == NULL) { - u_int32_t offset = workSpace->allocTrieNode(workSpace, key, keyLen); - PARAM_CHECK(offset != 0, return NULL, "Failed to allocate key %s", key); - SaveIndex(¤t->left, offset); - return GetTrieNode(workSpace, ¤t->left); - } - } else { - next = GetTrieNode(workSpace, ¤t->right); - if (next == NULL) { - u_int32_t offset = workSpace->allocTrieNode(workSpace, key, keyLen); - PARAM_CHECK(offset != 0, return NULL, "Failed to allocate key %s", key); - SaveIndex(¤t->right, offset); - return GetTrieNode(workSpace, ¤t->right); - } + } else { + subTrie = (ParamTrieNode *)GetTrieNode(workSpace, current->right); + if (subTrie == NULL) { + return NULL; } - current = next; } - return current; + return FindSubTrie(workSpace, subTrie, key, keyLen, matchLabel); } -TrieDataNode *FindTrieDataNode(WorkSpace *workSpace, const char *key, u_int32_t keyLen, int matchPrefix) +ParamTrieNode *FindTrieNode(WorkSpace *workSpace, const char *key, uint32_t keyLen, uint32_t *matchLabel) { - PARAM_CHECK(workSpace->allocTrieNode != NULL, return NULL, "Invalid param %s", key); - PARAM_CHECK(workSpace->compareTrieNode != NULL, return NULL, "Invalid param %s", key); - + PARAM_CHECK(key != NULL && keyLen > 0, return NULL, "Invalid key "); + PARAM_CHECK(workSpace != NULL, return NULL, "Invalid workSpace %s", key); + PARAM_CHECK(workSpace->allocTrieNode != NULL, return NULL, "Invalid alloc function %s", key); + PARAM_CHECK(workSpace->compareTrieNode != NULL, return NULL, "Invalid compare function %s", key); const char *remainingKey = key; - TrieDataNode *matchNode = (TrieDataNode *)workSpace->rootNode; - TrieDataNode *current = (TrieDataNode *)workSpace->rootNode; + ParamTrieNode *current = GetTrieRoot(workSpace); PARAM_CHECK(current != NULL, return NULL, "Invalid current param %s", key); + if (matchLabel != NULL) { + *matchLabel = current->labelIndex; + } + int ret = workSpace->compareTrieNode(current, key, keyLen); + if (ret == 0) { + return current; + } while (1) { - u_int32_t subKeyLen = 0; + uint32_t subKeyLen = 0; char *subKey = NULL; GetNextKey(&remainingKey, &subKey, &subKeyLen); if (!subKeyLen) { - return matchPrefix ? matchNode : NULL; + return NULL; } - u_int32_t offset = subKey == NULL ? strlen(key) : subKey - key; - - if (current->child != 0) { // 如果child存在,则检查是否匹配 - TrieDataNode *next = (TrieDataNode*)GetTrieNode(workSpace, ¤t->child); - if (next != NULL && workSpace->compareTrieNode((TrieNode*)next, remainingKey, subKeyLen) == 0) { - current = next; - } else { // 不匹配,搜索子树 - current = (TrieDataNode*)FindSubTrie(workSpace, current, key, offset); - } + if (current->child != 0) { + ParamTrieNode *next = GetTrieNode(workSpace, current->child); + current = FindSubTrie(workSpace, next, remainingKey, subKeyLen, matchLabel); } else { - current = (TrieDataNode*)FindSubTrie(workSpace, current, key, offset); + current = FindSubTrie(workSpace, current, remainingKey, subKeyLen, matchLabel); } if (current == NULL) { - return matchPrefix ? matchNode : NULL; + return NULL; + } else if (matchLabel != NULL && current->labelIndex != 0) { + *matchLabel = current->labelIndex; } - matchNode = current; if (subKey == NULL || strcmp(subKey, ".") == 0) { break; } remainingKey = subKey + 1; } - return matchPrefix ? matchNode : current; -} - -TrieDataNode *FindSubTrie(WorkSpace *workSpace, TrieDataNode *dataNode, const char *key, u_int32_t keyLen) -{ - TrieDataNode *root = NULL; - int ret = workSpace->compareTrieNode((TrieNode*)dataNode, key, keyLen); - if (ret <= 0) { - root = (TrieDataNode *)GetTrieNode(workSpace, &dataNode->left); - if (root == NULL) { - return NULL; - } - } else { - root = (TrieDataNode *)GetTrieNode(workSpace, &dataNode->right); - if (root == NULL) { - return NULL; - } - } - return (TrieDataNode*)FindTrieNode(workSpace, (TrieNode*)root, key, keyLen); + return current; } -TrieNode *FindTrieNode(WorkSpace *workSpace, TrieNode *root, const char *key, u_int32_t keyLen) +static int TraversalSubTrieNode(WorkSpace *workSpace, + ParamTrieNode *current, TraversalTrieNodePtr walkFunc, void* cookie) { - PARAM_CHECK(root != NULL, return NULL, "Invalid param %s", key); - TrieNode *current = root; - TrieNode *next = NULL; - while (1) { - if (current == NULL) { - return NULL; - } - int ret = workSpace->compareTrieNode(current, key, keyLen); - if (ret == 0) { - return current; - } - if (ret < 0) { - next = GetTrieNode(workSpace, ¤t->left); - } else { - next = GetTrieNode(workSpace, ¤t->right); - } - if (next == NULL) { - return NULL; - } - current = next; + if (current == NULL) { + return 0; } - return current; + walkFunc(workSpace, (ParamTrieNode *)current, cookie); + TraversalSubTrieNode(workSpace, GetTrieNode(workSpace, current->child), walkFunc, cookie); + TraversalSubTrieNode(workSpace, GetTrieNode(workSpace, current->left), walkFunc, cookie); + TraversalSubTrieNode(workSpace, GetTrieNode(workSpace, current->right), walkFunc, cookie); + return 0; } -int TraversalTrieDataNode(WorkSpace *workSpace, TrieDataNode *current, TraversalTrieNodePtr walkFunc, void* cookie) +int TraversalTrieNode(WorkSpace *workSpace, ParamTrieNode *root, TraversalTrieNodePtr walkFunc, void *cookie) { PARAM_CHECK(walkFunc != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); + ParamTrieNode *current = root; + if (root == NULL) { + current = GetTrieRoot(workSpace); + } if (current == NULL) { return 0; } - - while (1) { - TrieDataNode *child = NULL; - // 显示子树 - TraversalTrieDataNode(workSpace, (TrieDataNode*)GetTrieNode(workSpace, ¤t->left), walkFunc, cookie); - TraversalTrieDataNode(workSpace, (TrieDataNode*)GetTrieNode(workSpace, ¤t->right), walkFunc, cookie); - walkFunc(workSpace, (TrieNode *)current, cookie); - - if (current->child != 0) { // 如果child存在,则检查是否匹配 - child = (TrieDataNode*)GetTrieNode(workSpace, ¤t->child); - } - if (child == NULL) { - return 0; - } - current = child; + walkFunc(workSpace, (ParamTrieNode *)current, cookie); + TraversalSubTrieNode(workSpace, GetTrieNode(workSpace, current->child), walkFunc, cookie); + if (root == NULL) { + TraversalSubTrieNode(workSpace, GetTrieNode(workSpace, current->left), walkFunc, cookie); + TraversalSubTrieNode(workSpace, GetTrieNode(workSpace, current->right), walkFunc, cookie); } return 0; } -int TraversalTrieNode(WorkSpace *workSpace, TrieNode *root, TraversalTrieNodePtr walkFunc, void* cookie) +uint32_t AddParamSecruityNode(WorkSpace *workSpace, const ParamAuditData *auditData) { - PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); - PARAM_CHECK(walkFunc != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); - if (root == NULL) { - return 0; + PARAM_CHECK(workSpace != NULL, return 0, "Invalid param"); + PARAM_CHECK(auditData != NULL && auditData->name != NULL, return 0, "Invalid auditData"); + uint32_t labelLen = ((auditData->label == NULL) || (strlen(auditData->label) == 0)) ? 0 : strlen(auditData->label); + uint32_t realLen = sizeof(ParamSecruityNode) + PARAM_ALIGN(labelLen + 1); + PARAM_CHECK((workSpace->area->currOffset + realLen) < workSpace->area->dataSize, return 0, + "Failed to allocate currOffset %u, dataSize %u datalen %u", + workSpace->area->currOffset, workSpace->area->dataSize, realLen); + + ParamSecruityNode *node = (ParamSecruityNode *)(workSpace->area->data + workSpace->area->currOffset); + node->uid = auditData->dacData.uid; + node->gid = auditData->dacData.gid; + node->mode = auditData->dacData.mode; + node->length = 0; + if (labelLen != 0) { + int ret = memcpy_s(node->data, labelLen, auditData->label, labelLen); + PARAM_CHECK(ret == 0, return 0, "Failed to copy key"); + node->data[labelLen] = '\0'; + node->length = labelLen; } - TraversalTrieNode(workSpace, GetTrieNode(workSpace, &root->left), walkFunc, cookie); - TraversalTrieNode(workSpace, GetTrieNode(workSpace, &root->right), walkFunc, cookie); - walkFunc(workSpace, (TrieNode *)root, cookie); - return 0; + uint32_t offset = workSpace->area->currOffset; + workSpace->area->currOffset += realLen; + workSpace->area->securityNodeCount++; + return offset; } -u_int32_t AddData(WorkSpace *workSpace, const char *key, u_int32_t keyLen, const char *value, u_int32_t valueLen) +uint32_t AddParamNode(WorkSpace *workSpace, const char *key, uint32_t keyLen, const char *value, uint32_t valueLen) { PARAM_CHECK(workSpace != NULL, return 0, "Invalid param"); PARAM_CHECK(key != NULL && value != NULL, return 0, "Invalid param"); - u_int32_t realLen = sizeof(DataEntry) + 1 + 1; + + uint32_t realLen = sizeof(ParamNode) + 1 + 1; if (valueLen > PARAM_VALUE_LEN_MAX) { realLen += keyLen + valueLen; } else { realLen += keyLen + PARAM_VALUE_LEN_MAX; } - realLen = (realLen + 0x03) & (~0x03); - //PARAM_LOGI("AddData realLen %u %u %u", realLen, keyLen, valueLen); + realLen = PARAM_ALIGN(realLen); PARAM_CHECK((workSpace->area->currOffset + realLen) < workSpace->area->dataSize, return 0, - "Failed to allocate currOffset %d, dataSize %d", workSpace->area->currOffset, workSpace->area->dataSize); + "Failed to allocate currOffset %u, dataSize %u datalen %u", + workSpace->area->currOffset, workSpace->area->dataSize, realLen); - DataEntry *node = (DataEntry*)(workSpace->area->data + workSpace->area->currOffset); - u_int32_t dataLength = keyLen << TRIE_SERIAL_KEY_LEN_OFFSET | valueLen << TRIE_SERIAL_DATA_LEN_OFFSET; - atomic_init(&node->serial, ATOMIC_VAR_INIT(0)); - atomic_init(&node->dataLength, ATOMIC_VAR_INIT(dataLength)); - int ret = memcpy_s(node->data, keyLen, key, keyLen); - PARAM_CHECK(ret == 0, return 0, "Failed to copy key"); - ret = memcpy_s(node->data + keyLen + 1, valueLen, value, valueLen); - PARAM_CHECK(ret == 0, return 0, "Failed to copy key"); - node->data[keyLen] = '='; - node->data[keyLen + 1 + valueLen] = '\0'; - u_int32_t offset = workSpace->area->currOffset; + ParamNode *node = (ParamNode *)(workSpace->area->data + workSpace->area->currOffset); + atomic_init(&node->commitId, 0); + + node->keyLength = keyLen; + node->valueLength = valueLen; + int ret = sprintf_s(node->data, realLen - 1, "%s=%s", key, value); + PARAM_CHECK(ret > 0, return 0, "Failed to sprint key and value"); + uint32_t offset = workSpace->area->currOffset; workSpace->area->currOffset += realLen; - //PARAM_LOGI("AddData node %p %u %d", node, offset, gettid()); + workSpace->area->paramNodeCount++; return offset; } -int UpdateDataValue(DataEntry *entry, const char *value) +ParamTrieNode *GetTrieNode(WorkSpace *workSpace, uint32_t offset) { - PARAM_CHECK(entry != NULL && value != NULL, return PARAM_CODE_INVALID_PARAM, "Failed to check param"); - int ret = PARAM_CODE_INVALID_VALUE; - u_int32_t keyLen = DATA_ENTRY_KEY_LEN(entry); - u_int32_t valueLen = strlen(value); - u_int32_t oldLen = DATA_ENTRY_DATA_LEN(entry); - if (oldLen < PARAM_VALUE_LEN_MAX && valueLen < PARAM_VALUE_LEN_MAX) { - PARAM_LOGD("Old value %s new value %s", entry->data + keyLen + 1, value); - ret = memcpy_s(entry->data + keyLen + 1, PARAM_VALUE_LEN_MAX, value, valueLen + 1); - PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_VALUE, "Failed to copy value"); - u_int32_t dataLength = keyLen << TRIE_SERIAL_KEY_LEN_OFFSET | valueLen << TRIE_SERIAL_DATA_LEN_OFFSET; - atomic_store_explicit(&entry->dataLength, dataLength, memory_order_release); - } - return ret; -} - -u_int32_t GetDataSerial(const DataEntry *entry) -{ - u_int32_t serial = atomic_load_explicit(&entry->serial, memory_order_acquire); - while (DATA_ENTRY_DIRTY(serial)) { - futex_wait(&entry->serial, serial, NULL); - serial = atomic_load_explicit(&entry->serial, memory_order_acquire); + if (offset == 0 || offset > workSpace->area->dataSize) { + return NULL; } - return serial; + return (ParamTrieNode *)(workSpace->area->data + offset); } -int GetDataName(const DataEntry *entry, char *name, u_int32_t len) +void SaveIndex(uint32_t *index, uint32_t offset) { - PARAM_CHECK(entry != NULL && name != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); - u_int32_t keyLen = DATA_ENTRY_KEY_LEN(entry); - PARAM_CHECK(len > keyLen, return -1, "Invalid param size"); - int ret = memcpy_s(name, len, entry->data, keyLen); - PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_PARAM, "Failed to copy name"); - name[keyLen] = '\0'; - return ret; -} - -int GetDataValue(const DataEntry *entry, char *value, u_int32_t len) -{ - PARAM_CHECK(entry != NULL && value != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); - u_int32_t keyLen = DATA_ENTRY_KEY_LEN(entry); - u_int32_t valueLen = DATA_ENTRY_DATA_LEN(entry); - PARAM_CHECK(len > valueLen, return PARAM_CODE_INVALID_PARAM, "Invalid value len %u %u", len, valueLen); - int ret = memcpy_s(value, len, entry->data + keyLen + 1, valueLen); - PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_PARAM, "Failed to copy value"); - value[valueLen] = '\0'; - return ret; + *index = offset; } diff --git a/services/param/manager/param_utils.c b/services/param/manager/param_utils.c new file mode 100755 index 000000000..4ecca7c8d --- /dev/null +++ b/services/param/manager/param_utils.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2020 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 "param_utils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LABEL "PARAM_UTILS" +void CheckAndCreateDir(const char *fileName) +{ + if (fileName == NULL || *fileName == '\0') { + return; + } + char *path = strndup(fileName, strrchr(fileName, '/') - fileName); + if (path != NULL && access(path, F_OK) != 0) { + mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + } + free(path); +} + +int ReadFileInDir(const char *dirPath, const char *includeExt, + int (*processFile)(const char *fileName, void *context), void *context) +{ + DIR *pDir = opendir(dirPath); + PARAM_CHECK(pDir != NULL, return -1, "Read dir :%s failed.%d", dirPath, errno); + char *fileName = malloc(PARAM_BUFFER_SIZE); + PARAM_CHECK(fileName != NULL, closedir(pDir); return -1, "Failed to malloc for %s", dirPath); + + struct dirent *dp; + while ((dp = readdir(pDir)) != NULL) { + if (dp->d_type == DT_DIR) { + continue; + } + PARAM_LOGD("ReadFileInDir %s", dp->d_name); + if (includeExt != NULL) { + char *tmp = strstr(dp->d_name, includeExt); + if (tmp == NULL) { + continue; + } + if (strcmp(tmp, includeExt) != 0) { + continue; + } + } + int ret = snprintf_s(fileName, PARAM_BUFFER_SIZE, PARAM_BUFFER_SIZE - 1, "%s/%s", dirPath, dp->d_name); + PARAM_CHECK(ret > 0, continue, "Failed to get file name for %s", dp->d_name); + struct stat st; + if (stat(fileName, &st) == 0) { + processFile(fileName, context); + } + } + closedir(pDir); + return 0; +} + +char *ReadFileData(const char *fileName) +{ + if (fileName == NULL) { + return NULL; + } + char *buffer = NULL; + int fd = -1; + do { + fd = open(fileName, O_RDONLY); + PARAM_CHECK(fd >= 0, break, "Failed to read file %s", fileName); + + buffer = (char *)malloc(MAX_DATA_BUFFER); + PARAM_CHECK(buffer != NULL, break, "Failed to allocate memory for %s", fileName); + ssize_t readLen = read(fd, buffer, MAX_DATA_BUFFER - 1); + PARAM_CHECK(readLen > 0, break, "Failed to read data for %s", fileName); + buffer[readLen] = '\0'; + } while (0); + if (fd != -1) { + close(fd); + } + return buffer; +} + +static void TrimString(char *string, uint32_t currLen) +{ + for (int i = currLen - 1; i >= 0; i--) { + if (string[i] == ' ' || string[i] == '\0') { + string[i] = '\0'; + } else { + break; + } + } +} + +int GetSubStringInfo(const char *buff, uint32_t buffLen, char delimiter, SubStringInfo *info, int subStrNumber) +{ + size_t i = 0; + // 去掉开始的空格 + for (; i < strlen(buff); i++) { + if (!isspace(buff[i])) { + break; + } + } + // 过滤掉注释 + if (buff[i] == '#') { + return -1; + } + // 分割字符串 + int spaceIsValid = 0; + int curr = 0; + int valueCurr = 0; + for (; i < buffLen; i++) { + if (buff[i] == '\n' || buff[i] == '\r' || buff[i] == '\0') { + break; + } + if (buff[i] == delimiter && valueCurr != 0) { + info[curr].value[valueCurr] = '\0'; + TrimString(info[curr].value, valueCurr); + valueCurr = 0; + curr++; + spaceIsValid = 0; + } else { + if (!spaceIsValid && isspace(buff[i])) { // 过滤开始前的无效字符 + continue; + } + spaceIsValid = 1; + if ((valueCurr + 1) >= (int)sizeof(info[curr].value)) { + continue; + } + info[curr].value[valueCurr++] = buff[i]; + } + if (curr >= subStrNumber) { + break; + } + } + if (valueCurr > 0) { + info[curr].value[valueCurr] = '\0'; + TrimString(info[curr].value, valueCurr); + valueCurr = 0; + curr++; + } + return curr; +} \ No newline at end of file diff --git a/services/param/service/param_persist.c b/services/param/service/param_persist.c old mode 100644 new mode 100755 index 7086357cb..6f5534b52 --- a/services/param/service/param_persist.c +++ b/services/param/service/param_persist.c @@ -12,145 +12,167 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "sys_param.h" - -#include +#include "param_persist.h" #include #include -#include -#include -#include -#include -#include -#include -#include +#include #include #include "param_manager.h" +#include "param_service.h" #include "param_trie.h" +#include "sys_param.h" #define LABEL "Manager" -#define MAX_BUFF 256 -typedef struct { - WorkSpace *workSpace; - WorkSpace *persistWorkSpace; - char *buffer; -} PersistContext; +static ParamPersistWorkSpace g_persistWorkSpace = { + 0, NULL, 0, {NULL, NULL, NULL, NULL, NULL} + }; -static ParamPersistWorkSpace g_persistWorkSpace = {ATOMIC_VAR_INIT(0), }; +static int AddPersistParam(const char *name, const char *value, void *context) +{ + PARAM_CHECK(value != NULL && name != NULL && context != NULL, + return PARAM_CODE_INVALID_PARAM, "Invalid name or context"); + WorkSpace *workSpace = (WorkSpace *)context; + uint32_t dataIndex = 0; + int ret = WriteParam(workSpace, name, value, &dataIndex, 0); + PARAM_CHECK(ret == 0, return ret, "Failed to write param %d name:%s %s", ret, name, value); + return 0; +} -static int ProcessParamTraversal(WorkSpace *workSpace, TrieNode *node, void *cookie) +static int SavePersistParam(WorkSpace *workSpace, ParamTrieNode *node, void *cookie) { - PARAM_CHECK(workSpace != 0 && node != NULL && cookie != NULL, return -1, "Invalid param"); - TrieDataNode *current = (TrieDataNode *)node; + ParamTrieNode *current = (ParamTrieNode *)node; if (current == NULL || current->dataIndex == 0) { return 0; } - DataEntry *entry = (DataEntry *)GetTrieNode(workSpace, ¤t->dataIndex); + ParamNode *entry = (ParamNode *)GetTrieNode(workSpace, current->dataIndex); if (entry == NULL) { - return -1; - } - PersistContext *persistContext = (PersistContext *)cookie; - int ret = GetDataName(entry, persistContext->buffer, MAX_BUFF); - PARAM_CHECK(ret == 0, return ret, "GetDataName failed"); - if (strncmp(persistContext->buffer, "persist.", strlen("persist.")) != 0) { return 0; } - ret = GetDataValue(entry, persistContext->buffer + MAX_BUFF, MAX_BUFF); - if (ret == 0) { // 只支持新建 - //PARAM_LOGI("Insert new persist param from normal param %s %s", - // persistContext->buffer, persistContext->buffer + MAX_BUFF); - ret = AddParam(persistContext->persistWorkSpace, persistContext->buffer, persistContext->buffer + MAX_BUFF); + PARAM_LOGD("SavePersistParam %s", entry->data); + if (strncmp(entry->data, PARAM_CONST_PREFIX, strlen(PARAM_CONST_PREFIX)) != 0) { + return 0; } - PARAM_CHECK(ret == 0, return ret, "Failed to add persist param"); + static char name[PARAM_NAME_LEN_MAX] = {0}; + int ret = memcpy_s(name, PARAM_NAME_LEN_MAX - 1, entry->data, entry->keyLength); + PARAM_CHECK(ret == 0, return -1, "Failed to read param name %s", entry->data); + name[entry->keyLength] = '\0'; + ret = g_persistWorkSpace.persistParamOps.batchSave(cookie, name, entry->data + entry->keyLength + 1); + PARAM_CHECK(ret == 0, return -1, "Failed to write param %s", current->key); return ret; } -static int ProcessPersistPropertTraversal(WorkSpace *workSpace, TrieNode *node, void *cookie) +static int BatchSavePersistParam(WorkSpace *workSpace) { - TrieDataNode *current = (TrieDataNode *)node; - if (current == NULL || current->dataIndex == 0) { + PARAM_LOGI("BatchSavePersistParam"); + if (g_persistWorkSpace.persistParamOps.batchSaveBegin == NULL || + g_persistWorkSpace.persistParamOps.batchSave == NULL || + g_persistWorkSpace.persistParamOps.batchSaveEnd == NULL) { return 0; } - DataEntry *entry = (DataEntry *)GetTrieNode(workSpace, ¤t->dataIndex); - if (entry == NULL) { - return -1; - } - PersistContext *persistContext = (PersistContext *)cookie; - int ret = GetDataName(entry, persistContext->buffer, MAX_BUFF); - PARAM_CHECK(ret == 0, return ret, "GetDataName failed"); - ret = GetDataValue(entry, persistContext->buffer + MAX_BUFF, MAX_BUFF); - if (ret == 0) { - //PARAM_LOGI("update normal param %s %s from persist param %u", - // persistContext->buffer, persistContext->buffer + MAX_BUFF, current->dataIndex); - ret = WriteParam(persistContext->workSpace, persistContext->buffer, persistContext->buffer + MAX_BUFF); - } - PARAM_CHECK(ret == 0, return ret, "Failed to add persist param"); + + PERSIST_SAVE_HANDLE handle; + int ret = g_persistWorkSpace.persistParamOps.batchSaveBegin(&handle); + PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_NAME, "Failed to save persist"); + ParamTrieNode *root = FindTrieNode(workSpace, PARAM_CONST_PREFIX, strlen(PARAM_CONST_PREFIX), NULL); + ret = TraversalTrieNode(workSpace, root, SavePersistParam, handle); + g_persistWorkSpace.persistParamOps.batchSaveEnd(handle); + PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_NAME, "Save persist param fail"); + + PARAM_CLEAR_FLAG(g_persistWorkSpace.flags, WORKSPACE_FLAGS_UPDATE); + time(&g_persistWorkSpace.lastSaveTimer); return ret; } -int InitPersistParamWorkSpace(const char *context) +int InitPersistParamWorkSpace(ParamWorkSpace *workSpace) { - u_int32_t flags = atomic_load_explicit(&g_persistWorkSpace.flags, memory_order_relaxed); - if ((flags & WORKSPACE_FLAGS_INIT) == WORKSPACE_FLAGS_INIT) { + if (PARAM_TEST_FLAG(g_persistWorkSpace.flags, WORKSPACE_FLAGS_INIT)) { return 0; } - g_persistWorkSpace.persistWorkSpace.compareTrieNode = CompareTrieDataNode; - g_persistWorkSpace.persistWorkSpace.allocTrieNode = AllocateTrieDataNode; - int ret = InitPersistWorkSpace(PARAM_PERSIST_PATH, &g_persistWorkSpace.persistWorkSpace); - PARAM_CHECK(ret == 0, return ret, "Failed to init persist param"); - atomic_store_explicit(&g_persistWorkSpace.flags, WORKSPACE_FLAGS_INIT, memory_order_release); - return ret; + time(&g_persistWorkSpace.lastSaveTimer); +#ifdef PARAM_SUPPORT_SAVE_PERSIST + RegisterPersistParamOps(&g_persistWorkSpace.persistParamOps); +#endif + PARAM_SET_FLAG(g_persistWorkSpace.flags, WORKSPACE_FLAGS_INIT); + return 0; } -int RefreshPersistParams(ParamWorkSpace *workSpace, const char *context) +void ClosePersistParamWorkSpace() { - int ret = InitPersistParamWorkSpace(context); + if (g_persistWorkSpace.saveTimer != NULL) { + ParamTaskClose(g_persistWorkSpace.saveTimer); + } + g_persistWorkSpace.flags = 0; +} + +int LoadPersistParam(ParamWorkSpace *workSpace) +{ + int ret = InitPersistParamWorkSpace(workSpace); PARAM_CHECK(ret == 0, return ret, "Failed to init persist param"); - u_int32_t flags = atomic_load_explicit(&g_persistWorkSpace.flags, memory_order_relaxed); - if ((flags & WORKSPACE_FLAGS_LOADED) == WORKSPACE_FLAGS_LOADED) { - PARAM_LOGE("RefreshPersistParams has been loaded"); + if (PARAM_TEST_FLAG(g_persistWorkSpace.flags, WORKSPACE_FLAGS_LOADED)) { + PARAM_LOGE("Persist param has been loaded"); return 0; } - - // 申请临时的缓存,用于数据读取 - char *buffer = (char *)malloc(MAX_BUFF + MAX_BUFF); - PARAM_CHECK(buffer != NULL, return -1, "Failed to malloc memory for param"); - PersistContext persistContext = { - &workSpace->paramSpace, &g_persistWorkSpace.persistWorkSpace, buffer - }; - - // 遍历当前的参数,并把persist的写入 - ret = TraversalTrieDataNode(&workSpace->paramSpace, - (TrieDataNode *)workSpace->paramSpace.rootNode, ProcessParamTraversal, &persistContext); - - // 修改默认参数值 - ret = TraversalTrieDataNode(&g_persistWorkSpace.persistWorkSpace, - (TrieDataNode *)g_persistWorkSpace.persistWorkSpace.rootNode, ProcessPersistPropertTraversal, &persistContext); - - atomic_store_explicit(&g_persistWorkSpace.flags, flags | WORKSPACE_FLAGS_LOADED, memory_order_release); - free(buffer); - return ret; + ret = -1; + if (g_persistWorkSpace.persistParamOps.load != NULL) { + ret = g_persistWorkSpace.persistParamOps.load(AddPersistParam, &workSpace->paramSpace); + } + if (ret == 0) { + PARAM_SET_FLAG(g_persistWorkSpace.flags, WORKSPACE_FLAGS_LOADED); + } else { + PARAM_LOGE("Failed to load persist param "); + } + // 刷新新增的常量到persist + BatchSavePersistParam(&workSpace->paramSpace); + return 0; } -void ClosePersistParamWorkSpace() +static void TimerCallbackForSave(ParamTaskPtr timer, void *context) { - CloseWorkSpace(&g_persistWorkSpace.persistWorkSpace); - atomic_store_explicit(&g_persistWorkSpace.flags, 0, memory_order_release); + ParamTaskClose(timer); + g_persistWorkSpace.saveTimer = NULL; + if (!PARAM_TEST_FLAG(g_persistWorkSpace.flags, WORKSPACE_FLAGS_UPDATE)) { + return; + } + BatchSavePersistParam((WorkSpace *)context); } -int WritePersistParam(const char *name, const char *value) +int WritePersistParam(ParamWorkSpace *workSpace, const char *name, const char *value) { PARAM_CHECK(value != NULL && name != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param"); - if (strncmp(name, "persist.", strlen("persist.")) != 0) { + if (strncmp(name, PARAM_CONST_PREFIX, strlen(PARAM_CONST_PREFIX)) != 0) { return 0; } - int ret = InitPersistParamWorkSpace(""); - PARAM_CHECK(ret == 0, return ret, "Failed to init persist param"); - u_int32_t flags = atomic_load_explicit(&g_persistWorkSpace.flags, memory_order_relaxed); - if ((flags & WORKSPACE_FLAGS_LOADED) != WORKSPACE_FLAGS_LOADED) { + if (!PARAM_TEST_FLAG(g_persistWorkSpace.flags, WORKSPACE_FLAGS_LOADED)) { + PARAM_LOGE("Can not save persist param before load %s ", name); + return 0; + } + PARAM_LOGD("WritePersistParam name %s ", name); + if (g_persistWorkSpace.persistParamOps.save != NULL) { + g_persistWorkSpace.persistParamOps.save(name, value); + } + + // 不需要批量保存 + if (g_persistWorkSpace.persistParamOps.batchSave == NULL) { return 0; } - return WriteParam(&g_persistWorkSpace.persistWorkSpace, name, value); + + // check timer for save all + time_t currTimer; + time(&currTimer); + uint32_t diff = (uint32_t)difftime(currTimer, g_persistWorkSpace.lastSaveTimer); + if (diff > PARAM_MUST_SAVE_PARAM_DIFF) { + if (g_persistWorkSpace.saveTimer != NULL) { + ParamTaskClose(g_persistWorkSpace.saveTimer); + g_persistWorkSpace.saveTimer = NULL; + } + return BatchSavePersistParam(&workSpace->paramSpace); + } + PARAM_SET_FLAG(g_persistWorkSpace.flags, WORKSPACE_FLAGS_UPDATE); + if (g_persistWorkSpace.saveTimer == NULL) { + ParamTimerCreate(&g_persistWorkSpace.saveTimer, TimerCallbackForSave, &workSpace->paramSpace); + ParamTimerStart(g_persistWorkSpace.saveTimer, PARAM_MUST_SAVE_PARAM_DIFF * 1000, 1000); + } + return 0; } diff --git a/services/param/service/param_service.c b/services/param/service/param_service.c old mode 100644 new mode 100755 index 58d6c8c3e..2ec4bdb06 --- a/services/param/service/param_service.c +++ b/services/param/service/param_service.c @@ -12,268 +12,669 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "param_service.h" - +#include +#include +#include #include #include #include +#include +#include +#include #include -#include "sys_param.h" +#include "init_param.h" +#include "param_message.h" #include "param_manager.h" #include "param_request.h" -#include "init_param.h" +#include "trigger_manager.h" -#include "uv.h" +#define LABEL "ParamServer" +static ParamWorkSpace g_paramWorkSpace = { + 0, {}, NULL, {}, NULL, NULL + }; -#define BUFFER_SIZE 256 -#define LABEL "Server" +static void OnClose(ParamTaskPtr client) +{ + ParamWatcher *watcher = (ParamWatcher *)ParamGetTaskUserData(client); + if (watcher == GetParamWatcher(NULL)) { + return; + } + ClearWatcherTrigger(watcher); + ListRemove(&watcher->node); +} -static char *g_initContext = ""; -static ParamWorkSpace g_paramWorkSpace = {ATOMIC_VAR_INIT(0), {}, {}, {}}; +static int AddParam(WorkSpace *workSpace, const char *name, const char *value, uint32_t *dataIndex) +{ + ParamTrieNode *node = AddTrieNode(workSpace, name, strlen(name)); + PARAM_CHECK(node != NULL, return PARAM_CODE_REACHED_MAX, "Failed to add node"); + ParamNode *entry = (ParamNode *)GetTrieNode(workSpace, node->dataIndex); + if (entry == NULL) { + uint32_t offset = AddParamNode(workSpace, name, strlen(name), value, strlen(value)); + PARAM_CHECK(offset > 0, return PARAM_CODE_REACHED_MAX, "Failed to allocate name %s", name); + SaveIndex(&node->dataIndex, offset); + } + *dataIndex = node->dataIndex; + return 0; +} -void InitParamService() +static int UpdateParam(WorkSpace *workSpace, uint32_t *dataIndex, const char *name, const char *value) { - int ret = InitParamWorkSpace(&g_paramWorkSpace, 0, g_initContext); - PARAM_CHECK(ret == 0, return, "Init parameter workspace fail"); + ParamNode *entry = (ParamNode *)GetTrieNode(workSpace, *dataIndex); + PARAM_CHECK(entry != NULL, return PARAM_CODE_REACHED_MAX, "Failed to update param value %s %u", name, *dataIndex); + PARAM_CHECK(entry->keyLength == strlen(name), return PARAM_CODE_INVALID_NAME, "Failed to check name len %s", name); + + uint32_t valueLen = strlen(value); + uint32_t commitId = atomic_load_explicit(&entry->commitId, memory_order_relaxed); + atomic_store_explicit(&entry->commitId, commitId | PARAM_FLAGS_MODIFY, memory_order_relaxed); + + if (entry->valueLength < PARAM_VALUE_LEN_MAX && valueLen < PARAM_VALUE_LEN_MAX) { + int ret = memcpy_s(entry->data + entry->keyLength + 1, PARAM_VALUE_LEN_MAX, value, valueLen + 1); + PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_VALUE, "Failed to copy value"); + entry->valueLength = valueLen; + } + uint32_t flags = commitId & ~PARAM_FLAGS_COMMITID; + atomic_store_explicit(&entry->commitId, (++commitId) | flags, memory_order_release); + futex_wake(&entry->commitId, INT_MAX); + return 0; } -int LoadDefaultParams(const char *fileName) +static int CheckParamValue(WorkSpace *workSpace, const ParamTrieNode *node, const char *name, const char *value) { - u_int32_t flags = atomic_load_explicit(&g_paramWorkSpace.flags, memory_order_relaxed); - if ((flags & WORKSPACE_FLAGS_INIT) != WORKSPACE_FLAGS_INIT) { - return PARAM_CODE_NOT_INIT; + if (IS_READY_ONLY(name)) { + PARAM_CHECK(strlen(value) < PARAM_CONST_VALUE_LEN_MAX, + return PARAM_CODE_INVALID_VALUE, "Illegal param value %s", value); + if (node != NULL && node->dataIndex != 0) { + PARAM_LOGE("Read-only param was already set %s", name); + return PARAM_CODE_READ_ONLY; + } + } else { + // 限制非read only的参数,防止参数值修改后,原空间不能保存 + PARAM_CHECK(strlen(value) < PARAM_VALUE_LEN_MAX, + return PARAM_CODE_INVALID_VALUE, "Illegal param value %s", value); } - FILE *fp = fopen(fileName, "r"); - PARAM_CHECK(fp != NULL, return -1, "Open file %s fail", fileName); - char buff[BUFFER_SIZE]; - SubStringInfo *info = malloc(sizeof(SubStringInfo) * (SUBSTR_INFO_LABEL + 1)); - PARAM_CHECK(info != NULL, return -1, "malloc failed"); + return 0; +} - while(fgets(buff, BUFFER_SIZE, fp) != NULL) { - int subStrNumber = GetSubStringInfo(buff, strlen(buff), '=', info, SUBSTR_INFO_LABEL + 1); - if (subStrNumber <= SUBSTR_INFO_LABEL) { - continue; +int WriteParam(WorkSpace *workSpace, const char *name, const char *value, uint32_t *dataIndex, int onlyAdd) +{ + PARAM_CHECK(workSpace != NULL && dataIndex != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid workSpace"); + PARAM_CHECK(value != NULL && name != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid name or value"); + ParamTrieNode *node = FindTrieNode(workSpace, name, strlen(name), NULL); + int ret = CheckParamValue(workSpace, node, name, value); + PARAM_CHECK(ret == 0, return ret, "Invalid param value param: %s=%s", name, value); + if (node != NULL && node->dataIndex != 0) { + *dataIndex = node->dataIndex; + if (onlyAdd) { + return 0; } + return UpdateParam(workSpace, &node->dataIndex, name, value); + } + return AddParam(workSpace, name, value, dataIndex); +} - if (strncmp(info[0].value, "ctl.", strlen("ctl.")) == 0) { - PARAM_LOGE("Do not set ctl. parameters from init %s", info[0].value); - continue; +PARAM_STATIC int AddSecurityLabel(const ParamAuditData *auditData, void *context) +{ + PARAM_CHECK(auditData != NULL && auditData->name != NULL, return -1, "Invalid auditData"); + PARAM_CHECK(context != NULL, return -1, "Invalid context"); + ParamWorkSpace *workSpace = (ParamWorkSpace *)context; + int ret = CheckParamName(auditData->name, 1); + PARAM_CHECK(ret == 0, return ret, "Illegal param name %s", auditData->name); + + ParamTrieNode *node = FindTrieNode(&workSpace->paramSpace, auditData->name, strlen(auditData->name), NULL); + if (node == NULL) { + node = AddTrieNode(&workSpace->paramSpace, auditData->name, strlen(auditData->name)); + } + PARAM_CHECK(node != NULL, return PARAM_CODE_REACHED_MAX, "Failed to add node %s", auditData->name); + if (node->labelIndex == 0) { // can not support update for label + uint32_t offset = AddParamSecruityNode(&workSpace->paramSpace, auditData); + PARAM_CHECK(offset != 0, return PARAM_CODE_REACHED_MAX, "Failed to add label"); + SaveIndex(&node->labelIndex, offset); + } else { +#ifdef STARTUP_INIT_TEST + ParamSecruityNode *label = (ParamSecruityNode *)GetTrieNode(&workSpace->paramSpace, node->labelIndex); + label->mode = auditData->dacData.mode; +#endif + PARAM_LOGE("Error, repeate to add label for name %s", auditData->name); + } + PARAM_LOGD("AddSecurityLabel label uid %d gid %d mode %o name: %s", auditData->dacData.gid, auditData->dacData.gid, + auditData->dacData.mode, auditData->name); + return 0; +} + +static char *GetServiceCtrlName(const char *name, const char *value) +{ + static char *ctrlParam[] = { + "ohos.ctl.start", + "ohos.ctl.stop" + }; + static char *powerCtrlArg[][2] = { + {"reboot,shutdown", "reboot.shutdown"}, + {"reboot,updater", "reboot.updater"}, + {"reboot,flash", "reboot.flash"}, + {"reboot", "reboot"}, + }; + char *key = NULL; + if (strcmp("sys.powerctrl", name) == 0) { + for (size_t i = 0; i < sizeof(powerCtrlArg) / sizeof(powerCtrlArg[0]); i++) { + if (strncmp(value, powerCtrlArg[i][0], strlen(powerCtrlArg[i][0])) == 0) { + uint32_t keySize = strlen(powerCtrlArg[i][1]) + strlen(OHOS_SERVICE_CTRL_PREFIX) + 1; + key = (char *)malloc(keySize + 1); + PARAM_CHECK(key != NULL, return NULL, "Failed to alloc memory for %s", name); + int ret = sprintf_s(key, keySize, "%s%s", OHOS_SERVICE_CTRL_PREFIX, powerCtrlArg[i][1]); + PARAM_CHECK(ret > 0, return NULL, "Failed to format key for %s", name); + return key; + } } - if (strcmp(info[0].value, "selinux.restorecon_recursive") == 0) { - PARAM_LOGE("Do not set selinux.restorecon_recursive from init %s", info[0].value); - continue; + } else { + for (size_t i = 0; i < sizeof(ctrlParam) / sizeof(ctrlParam[0]); i++) { + if (strcmp(name, ctrlParam[i]) == 0) { + uint32_t keySize = strlen(value) + strlen(OHOS_SERVICE_CTRL_PREFIX) + 1; + key = (char *)malloc(keySize + 1); + PARAM_CHECK(key != NULL, return NULL, "Failed to alloc memory for %s", name); + int ret = sprintf_s(key, keySize, "%s%s", OHOS_SERVICE_CTRL_PREFIX, value); + PARAM_CHECK(ret > 0, return NULL, "Failed to format key for %s", name); + return key; + } } - int ret = CheckParamName(info[0].value, 0); - PARAM_CHECK(ret == 0, continue, "Illegal param name %s", info[0].value); + } + return key; +} - ret = WriteParam(&g_paramWorkSpace.paramSpace, info[0].value, info[1].value); - PARAM_CHECK(ret == 0, continue, "Failed to set param %d %s", ret, buff); +static void CheckAndSendTrigger(ParamWorkSpace *workSpace, uint32_t dataIndex, const char *name, const char *value) +{ + ParamNode *entry = (ParamNode *)GetTrieNode(&workSpace->paramSpace, dataIndex); + PARAM_CHECK(entry != NULL, return, "Failed to get data %s ", name); + uint32_t trigger = 1; + if ((atomic_load_explicit(&entry->commitId, memory_order_relaxed) & PARAM_FLAGS_TRIGGED) != PARAM_FLAGS_TRIGGED) { + trigger = CheckAndMarkTrigger(TRIGGER_PARAM, name) != 0 ? 1 : 0; } - fclose(fp); - free(info); - PARAM_LOGI("LoadDefaultParams proterty success %s", fileName); - return 0; + if (trigger) { + atomic_store_explicit(&entry->commitId, + atomic_load_explicit(&entry->commitId, memory_order_relaxed) | PARAM_FLAGS_TRIGGED, memory_order_release); + // notify event to process trigger + PostParamTrigger(EVENT_TRIGGER_PARAM, name, value); + } + + int wait = 1; + if ((atomic_load_explicit(&entry->commitId, memory_order_relaxed) & PARAM_FLAGS_WAITED) != PARAM_FLAGS_WAITED) { + wait = CheckAndMarkTrigger(TRIGGER_PARAM_WAIT, name) != 0 ? 1 : 0; + } + if (wait) { + atomic_store_explicit(&entry->commitId, + atomic_load_explicit(&entry->commitId, memory_order_relaxed) | PARAM_FLAGS_WAITED, memory_order_release); + PostParamTrigger(EVENT_TRIGGER_PARAM_WAIT, name, value); + } + PostParamTrigger(EVENT_TRIGGER_PARAM_WATCH, name, value); } -int LoadParamInfos(const char *fileName) +static int SystemSetParam(const char *name, const char *value, const ParamSecurityLabel *srcLabel) { - u_int32_t flags = atomic_load_explicit(&g_paramWorkSpace.flags, memory_order_relaxed); - if ((flags & WORKSPACE_FLAGS_INIT) != WORKSPACE_FLAGS_INIT) { - return PARAM_CODE_NOT_INIT; + PARAM_LOGD("SystemSetParam name %s value: %s", name, value); + int ret = CheckParamName(name, 0); + PARAM_CHECK(ret == 0, return ret, "Illegal param name %s", name); + + int serviceCtrl = 0; + char *key = GetServiceCtrlName(name, value); + if (srcLabel != NULL) { + ret = CheckParamPermission(&g_paramWorkSpace, srcLabel, (key == NULL) ? name : key, DAC_WRITE); + PARAM_CHECK(ret == 0, return ret, "Forbit to set parameter %s", name); } - FILE *fp = fopen(fileName, "r"); - PARAM_CHECK(fp != NULL, return -1, "Open file %s fail", fileName); - SubStringInfo *info = malloc(sizeof(SubStringInfo) * SUBSTR_INFO_MAX); - PARAM_CHECK(info != NULL, return -1, "Load parameter malloc failed."); - char buff[BUFFER_SIZE]; - int infoCount = 0; - while(fgets(buff, BUFFER_SIZE, fp) != NULL) { - int subStrNumber = GetSubStringInfo(buff, strlen(buff), ' ', info, SUBSTR_INFO_MAX); - if (subStrNumber <= 0) { - continue; - } - int ret = WriteParamInfo(&g_paramWorkSpace, info, subStrNumber); - PARAM_CHECK(ret == 0, continue, "Failed to write param info %d %s", ret, buff); - infoCount++; + if (key != NULL) { + serviceCtrl = 1; + free(key); } - fclose(fp); - free(info); - PARAM_LOGI("Load parameter info %d success %s", infoCount, fileName); + uint32_t dataIndex = 0; + ret = WriteParam(&g_paramWorkSpace.paramSpace, name, value, &dataIndex, 0); + PARAM_CHECK(ret == 0, return ret, "Failed to set param %d name %s %s", ret, name, value); + ret = WritePersistParam(&g_paramWorkSpace, name, value); + PARAM_CHECK(ret == 0, return ret, "Failed to set persist param name %s", name); + if (serviceCtrl) { + PostParamTrigger(EVENT_TRIGGER_PARAM, name, value); + } else { + CheckAndSendTrigger(&g_paramWorkSpace, dataIndex, name, value); + } + return ret; +} + +static int SendResponseMsg(ParamTaskPtr worker, const ParamMessage *msg, int result) +{ + ParamResponseMessage *response = NULL; + response = (ParamResponseMessage *)CreateParamMessage(msg->type, msg->key, sizeof(ParamResponseMessage)); + PARAM_CHECK(response != NULL, return PARAM_CODE_ERROR, "Failed to alloc memory for response"); + response->msg.id.msgId = msg->id.msgId; + response->result = result; + response->msg.msgSize = sizeof(ParamResponseMessage); + ParamTaskSendMsg(worker, (ParamMessage *)response); return 0; } -static int ProcessParamSet(RequestMsg *msg) +static int SendWatcherNotifyMessage(TriggerExtData *extData, int cmd, const char *content) { - PARAM_CHECK(msg != NULL, return PARAM_CODE_INVALID_PARAM, "Failed to check param"); + PARAM_CHECK(content != NULL, return -1, "Invalid content"); + PARAM_CHECK(extData != NULL && extData->watcher != NULL, return -1, "Invalid extData"); + uint32_t msgSize = sizeof(ParamMessage) + PARAM_ALIGN(strlen(content) + 1); + ParamMessage *msg = (ParamMessage *)CreateParamMessage(MSG_NOTIFY_PARAM, "*", msgSize); + PARAM_CHECK(msg != NULL, return -1, "Failed to create msg "); - SubStringInfo info[3]; - int ret = GetSubStringInfo(msg->content, msg->contentSize, '=', info, sizeof(info)/sizeof(info[0])); - PARAM_CHECK(ret >= 2, return ret, "Failed to get name from content %s", msg->content); + uint32_t offset = 0; + int ret = 0; + char *tmp = strstr(content, "="); + if (tmp != NULL) { + ret = strncpy_s(msg->key, sizeof(msg->key) - 1, content, tmp - content); + PARAM_CHECK(ret == 0, free(msg); return -1, "Failed to fill value"); + tmp++; + ret = FillParamMsgContent(msg, &offset, PARAM_VALUE, tmp, strlen(tmp)); + PARAM_CHECK(ret == 0, free(msg); return -1, "Failed to fill value"); + } else { + ret = FillParamMsgContent(msg, &offset, PARAM_VALUE, tmp, strlen(content)); + PARAM_CHECK(ret == 0, free(msg); return -1, "Failed to fill value"); + } - PARAM_LOGD("ProcessParamSet name %s value: %s", info[0].value, info[1].value); - ret = WriteParamWithCheck(&g_paramWorkSpace, &msg->securitylabel, info[0].value, info[1].value); - PARAM_CHECK(ret == 0, return ret, "Failed to set param %d name %s %s", ret, info[0].value, info[1].value); - ret = WritePersistParam(info[0].value, info[1].value); - PARAM_CHECK(ret == 0, return ret, "Failed to set param"); - // notify event to process trigger - PostTrigger(EVENT_PROPERTY, msg->content, msg->contentSize); + msg->id.msgId = extData->watcherId; + msg->msgSize = sizeof(ParamMessage) + offset; + PARAM_LOGD("SendWatcherNotifyMessage watcherId %d msgSize %d para: %s", extData->watcherId, msg->msgSize, content); + ParamTaskSendMsg(extData->watcher->stream, msg); return 0; } -static void OnClose(uv_handle_t *handle) +static int HandleParamSet(const ParamTaskPtr worker, const ParamMessage *msg) { - free(handle); + uint32_t offset = 0; + ParamMsgContent *valueContent = GetNextContent(msg, &offset); + PARAM_CHECK(valueContent != NULL, return -1, "Invalid msg for %s", msg->key); + + ParamMsgContent *lableContent = GetNextContent(msg, &offset); + ParamSecurityLabel *srcLabel = NULL; + if (lableContent != NULL && lableContent->contentSize != 0) { + PARAM_CHECK(g_paramWorkSpace.paramSecurityOps.securityDecodeLabel != NULL, + return -1, "Can not get decode function"); + int ret = g_paramWorkSpace.paramSecurityOps.securityDecodeLabel(&srcLabel, + lableContent->content, lableContent->contentSize); + PARAM_CHECK(ret == 0, return ret, + "Failed to decode param %d name %s %s", ret, msg->key, valueContent->content); + } + + int ret = SystemSetParam(msg->key, valueContent->content, srcLabel); + if (srcLabel != NULL && g_paramWorkSpace.paramSecurityOps.securityFreeLabel != NULL) { + g_paramWorkSpace.paramSecurityOps.securityFreeLabel(srcLabel); + } + return SendResponseMsg(worker, msg, ret); } -static void OnReceiveAlloc(uv_handle_t *handle, size_t suggestedSize, uv_buf_t* buf) +static ParamNode *CheckMatchParamWait(ParamWorkSpace *worksapce, const char *name, const char *value) { - // 这里需要按实际消息的大小申请内存,取最大消息的长度 - buf->len = sizeof(RequestMsg) + BUFFER_SIZE * 2; - buf->base = (char *)malloc(buf->len); + uint32_t nameLength = strlen(name); + ParamTrieNode *node = FindTrieNode(&worksapce->paramSpace, name, nameLength, NULL); + if (node == NULL || node->dataIndex == 0) { + return NULL; + } + ParamNode *param = (ParamNode *)GetTrieNode(&worksapce->paramSpace, node->dataIndex); + if (param == NULL) { + return NULL; + } + if ((param->keyLength != nameLength) || (strncmp(param->data, name, nameLength) != 0)) { // compare name + return NULL; + } + atomic_store_explicit(¶m->commitId, + atomic_load_explicit(¶m->commitId, memory_order_relaxed) | PARAM_FLAGS_WAITED, memory_order_release); + if ((strncmp(value, "*", 1) == 0) || (strcmp(param->data + nameLength + 1, value) == 0)) { // compare value + return param; + } + char *tmp = strstr(value, "*"); + if (tmp != NULL && (strncmp(param->data + nameLength + 1, value, tmp - value) == 0)) { + return param; + } + return NULL; } -static void OnWriteResponse(uv_write_t *req, int status) +static int HandleParamWaitAdd(ParamWorkSpace *worksapce, const ParamTaskPtr worker, const ParamMessage *msg) { - // 发送成功,释放请求内存 - PARAM_LOGD("OnWriteResponse status %d", status); - ResponseNode *node = (ResponseNode*)req; - free(node); + PARAM_CHECK(msg != NULL, return -1, "Invalid message"); + uint32_t offset = 0; + uint32_t timeout = DEFAULT_PARAM_WAIT_TIMEOUT; + ParamMsgContent *valueContent = GetNextContent(msg, &offset); + PARAM_CHECK(valueContent != NULL, return -1, "Invalid msg"); + ParamMsgContent *timeoutContent = GetNextContent(msg, &offset); + if (timeoutContent != NULL) { + timeout = *((uint32_t *)(timeoutContent->content)); + } + + PARAM_LOGD("HandleParamWaitAdd name %s timeout %d", msg->key, timeout); + ParamWatcher *watcher = GetParamWatcher(worker); + PARAM_CHECK(watcher != NULL, return -1, "Failed to get param watcher data"); + watcher->timeout = timeout; + + TriggerExtData extData = {}; + extData.excuteCmd = SendWatcherNotifyMessage; + extData.watcherId = msg->id.watcherId; + extData.watcher = watcher; + // first check match, if match send response to client + ParamNode *param = CheckMatchParamWait(worksapce, msg->key, valueContent->content); + if (param != NULL) { + SendWatcherNotifyMessage(&extData, CMD_INDEX_FOR_PARA_WAIT, param->data); + return 0; + } + + uint32_t buffSize = strlen(msg->key) + valueContent->contentSize + 1 + 1; + char *condition = malloc(buffSize); + PARAM_CHECK(condition != NULL, return -1, "Failed to create condition for %s", msg->key); + int ret = sprintf_s(condition, buffSize - 1, "%s=%s", msg->key, valueContent->content); + PARAM_CHECK(ret > 0, free(condition); return -1, "Failed to copy name for %s", msg->key); + TriggerNode *trigger = AddWatcherTrigger(watcher, TRIGGER_PARAM_WAIT, msg->key, condition, &extData); + PARAM_CHECK(trigger != NULL, free(condition); return -1, "Failed to add trigger for %s", msg->key); + free(condition); + return 0; } -static void SendResponse(uv_stream_t *handle, RequestType type, int result, const void *content, int size) +static int HandleParamWatcherAdd(ParamWorkSpace *workSpace, const ParamTaskPtr worker, const ParamMessage *msg) { + PARAM_CHECK(msg != NULL, return -1, "Invalid message"); + TriggerExtData extData = {}; + extData.excuteCmd = SendWatcherNotifyMessage; + extData.watcherId = msg->id.watcherId; + int ret = 0; + do { + ParamWatcher *watcher = GetParamWatcher(NULL); + PARAM_CHECK(watcher != NULL, ret = -1; break, "Failed to get param watcher data"); + watcher->stream = worker; + TriggerNode *trigger = AddWatcherTrigger(watcher, TRIGGER_PARAM_WATCH, msg->key, NULL, &extData); + PARAM_CHECK(trigger != NULL, ret = -1; break, "Failed to add trigger for %s", msg->key); + } while (0); + PARAM_LOGD("HandleParamWatcherAdd name %s watcher: %d", msg->key, msg->id.watcherId); + return SendResponseMsg(worker, msg, ret); +} + +static int HandleParamWatcherDel(ParamWorkSpace *workSpace, const ParamTaskPtr worker, const ParamMessage *msg) +{ + PARAM_CHECK(msg != NULL, return -1, "Invalid message"); + ParamWatcher *watcher = GetParamWatcher(NULL); + PARAM_CHECK(watcher != NULL, return -1, "Failed to get param watcher data"); + PARAM_LOGD("HandleParamWatcherDel name %s watcher: %d", msg->key, msg->id.watcherId); + DelWatcherTrigger(watcher, msg->id.watcherId); + return SendResponseMsg(worker, msg, 0); +} + +PARAM_STATIC int ProcessMessage(const ParamTaskPtr worker, const ParamMessage *msg) +{ + PARAM_CHECK(msg != NULL, return -1, "Invalid msg"); + PARAM_CHECK(worker != NULL, return -1, "Invalid worker"); int ret = 0; - // 申请整块内存,用于回复数据和写请求 - ResponseNode *response = (ResponseNode *)malloc(sizeof(ResponseNode) + size); - PARAM_CHECK(response != NULL, return, "Failed to alloc memory for response"); - response->msg.type = type; - response->msg.contentSize = size; - response->msg.result = result; - if (content != NULL && size != 0) { - ret = memcpy_s(response->msg.content, size, content, size); - PARAM_CHECK(ret == 0, return, "Failed to copy content"); - } - uv_buf_t buf = uv_buf_init((char *)&response->msg, sizeof(response->msg) + size); - ret = uv_write2(&response->writer, handle, &buf, 1, handle, OnWriteResponse); - PARAM_CHECK(ret >= 0, return, "Failed to uv_write2 ret %s", uv_strerror(ret)); -} - -static void OnReceiveRequest(uv_stream_t *handle, ssize_t nread, uv_buf_t *buf) -{ - if (nread <= 0 || buf == NULL || buf->base == NULL) { - uv_close((uv_handle_t*)handle, OnClose); - if (buf != NULL && buf->base != NULL) { - free(buf->base); - } - return; - } - int freeHandle = 1; - RequestMsg *msg = (RequestMsg *)buf->base; switch (msg->type) { - case SET_PARAM: { - freeHandle = 0; - int ret = ProcessParamSet(msg); - SendResponse(handle, SET_PARAM, ret, NULL, 0); + case MSG_SET_PARAM: + ret = HandleParamSet(worker, msg); + break; + case MSG_WAIT_PARAM: + ret = HandleParamWaitAdd(&g_paramWorkSpace, worker, msg); + break; + case MSG_ADD_WATCHER: + ret = HandleParamWatcherAdd(&g_paramWorkSpace, worker, (const ParamMessage *)msg); + break; + case MSG_DEL_WATCHER: + ret = HandleParamWatcherDel(&g_paramWorkSpace, worker, (const ParamMessage *)msg); break; - } default: - PARAM_LOGE("not supported the command: %d", msg->type); break; } - free(buf->base); - buf->base = NULL; - uv_close((uv_handle_t*)handle, OnClose); + PARAM_CHECK(ret == 0, return -1, "Failed to process message ret %d", ret); + return 0; } -static void OnConnection(uv_stream_t *server, int status) +static int LoadDefaultParam_(const char *fileName, int mode, const char *exclude[], uint32_t count) { - PARAM_CHECK(status >= 0, return, "Error status %d", status); - PARAM_CHECK(server != NULL, return, "Error server"); - uv_pipe_t *stream = (uv_pipe_t*)malloc(sizeof(uv_pipe_t)); - PARAM_CHECK(stream != NULL, return, "Failed to alloc stream"); + uint32_t paramNum = 0; + FILE *fp = fopen(fileName, "r"); + PARAM_CHECK(fp != NULL, return -1, "Open file %s fail", fileName); + char *buff = malloc(sizeof(SubStringInfo) * (SUBSTR_INFO_VALUE + 1) + PARAM_BUFFER_SIZE); + PARAM_CHECK(buff != NULL, fclose(fp); return -1, "Failed to alloc memory for load %s", fileName); - int ret = uv_pipe_init(uv_default_loop(), (uv_pipe_t*)stream, 1); - PARAM_CHECK(ret == 0, free(stream); return, "Failed to uv_pipe_init %d", ret); + SubStringInfo *info = (SubStringInfo *)(buff + PARAM_BUFFER_SIZE); + while (fgets(buff, PARAM_BUFFER_SIZE, fp) != NULL) { + int subStrNumber = GetSubStringInfo(buff, strlen(buff), '=', info, SUBSTR_INFO_VALUE + 1); + if (subStrNumber <= SUBSTR_INFO_VALUE) { + continue; + } + // 过滤 + for (uint32_t i = 0; i < count; i++) { + if (strncmp(info[0].value, exclude[i], strlen(exclude[i])) == 0) { + PARAM_LOGI("Do not set %s parameters", info[0].value); + continue; + } + } + int ret = CheckParamName(info[0].value, 0); + PARAM_CHECK(ret == 0, continue, "Illegal param name %s", info[0].value); + PARAM_LOGI("Add default parameter %s %s", info[0].value, info[1].value); + uint32_t dataIndex = 0; + ret = WriteParam(&g_paramWorkSpace.paramSpace, + info[0].value, info[1].value, &dataIndex, mode & LOAD_PARAM_ONLY_ADD); + PARAM_CHECK(ret == 0, continue, "Failed to set param %d %s", ret, buff); + paramNum++; + } + fclose(fp); + free(buff); + PARAM_LOGI("Load parameters success %s total %u", fileName, paramNum); + return 0; +} - stream->data = server; - ret = uv_accept(server, (uv_stream_t *)stream); - PARAM_CHECK(ret == 0, uv_close((uv_handle_t*)stream, NULL); free(stream); - return, "Failed to uv_accept %d", ret); +static int OnIncomingConnect(const ParamTaskPtr server, int flags) +{ + PARAM_LOGD("OnIncomingConnect %p", server); + ParamStreamInfo info = {}; + info.flags = WORKER_TYPE_CLIENT | flags; + info.server = NULL; + info.close = OnClose; + info.recvMessage = ProcessMessage; + info.incomingConnect = NULL; + ParamTaskPtr client = NULL; + int ret = ParamStreamCreate(&client, server, &info, sizeof(ParamWatcher)); + PARAM_CHECK(ret == 0, return -1, "Failed to create client"); + + ParamWatcher *watcher = (ParamWatcher *)ParamGetTaskUserData(client); + ListInit(&watcher->node); + PARAM_TRIGGER_HEAD_INIT(watcher->triggerHead); + ListAddTail(&GetTriggerWorkSpace()->waitList, &watcher->node); + watcher->stream = client; + watcher->timeout = UINT32_MAX; + return 0; +} - ret = uv_read_start((uv_stream_t *)stream, OnReceiveAlloc, OnReceiveRequest); - PARAM_CHECK(ret == 0, uv_close((uv_handle_t*)stream, NULL); free(stream); - return, "Failed to uv_read_start %d", ret); +static void TimerCallback(ParamTaskPtr timer, void *context) +{ + ParamWatcher *watcher = GetNextParamWatcher(GetTriggerWorkSpace(), NULL); + while (watcher != NULL) { + ParamWatcher *next = GetNextParamWatcher(GetTriggerWorkSpace(), watcher); + if (watcher->timeout > 0) { + watcher->timeout--; + } else { + PARAM_LOGD("TimerCallback watcher->timeout %p ", watcher); + ParamTaskClose(watcher->stream); + } + watcher = next; + } } -void StopParamService() +static int CopyBootParam(char *buffer, const char *key, size_t keyLen) { - uv_fs_t req; - uv_fs_unlink(uv_default_loop(), &req, PIPE_NAME, NULL); - CloseParamWorkSpace(&g_paramWorkSpace); - ClosePersistParamWorkSpace(); - uv_stop(uv_default_loop()); - PARAM_LOGI("StopParamService."); + size_t bootLen = strlen(OHOS_BOOT); + int ret = strncpy_s(buffer, PARAM_NAME_LEN_MAX - 1, OHOS_BOOT, bootLen); + PARAM_CHECK(ret == 0, return -1, "Failed to cpy boot"); + size_t i = 0; + for (; (i < PARAM_NAME_LEN_MAX - 1 - bootLen) && (i <= keyLen); i++) { + buffer[i + bootLen] = key[i]; + } + if (i > (PARAM_NAME_LEN_MAX - 1 - bootLen)) { + return -1; + } + buffer[i + bootLen] = '\0'; + return 0; } -int StartParamService() +static int LoadParamFromCmdLine() { - PARAM_LOGI("StartParamService."); - uv_fs_t req; - uv_fs_unlink(uv_default_loop(), &req, PIPE_NAME, NULL); - - uv_pipe_t pipeServer; - int ret = uv_pipe_init(uv_default_loop(), &pipeServer, 0); - PARAM_CHECK(ret == 0, return ret, "Failed to uv_pipe_init %d", ret); - ret = uv_pipe_bind(&pipeServer, PIPE_NAME); - PARAM_CHECK(ret == 0, return ret, "Failed to uv_pipe_bind %d %s", ret, uv_err_name(ret)); - ret = chmod(PIPE_NAME, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); - PARAM_CHECK(ret == 0, return ret, "Failed to chmod %s, err %d. ", PIPE_NAME, errno); - ret = uv_listen((uv_stream_t*)&pipeServer, SOMAXCONN, OnConnection); - PARAM_CHECK(ret == 0, return ret, "Failed to uv_listen %d %s", ret, uv_err_name(ret)); - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - PARAM_LOGI("Start service exit."); + char *buffer = ReadFileData(PARAM_CMD_LINE); + PARAM_CHECK(buffer != NULL, return -1, "Failed to read file %s", PARAM_CMD_LINE); + char *data = malloc(PARAM_NAME_LEN_MAX + PARAM_CONST_VALUE_LEN_MAX); + PARAM_CHECK(data != NULL, free(buffer); return -1, "Failed to read file %s", PARAM_CMD_LINE); + + char *endBuffer = buffer + strlen(buffer); + char *key = data; + char *value = data + PARAM_NAME_LEN_MAX; + char *tmp = strchr(buffer, '='); + char *next = buffer; + while (tmp != 0) { + int ret = CopyBootParam(key, next, tmp - next - 1); + int ret1 = 0; + next = strchr(tmp + 1, '='); + if (next != NULL) { + while (!isspace(*next) && (next > buffer)) { // 直到属性值结束位置 + next--; + } + while (isspace(*next) && (next > buffer)) { // 去掉空格 + next--; + } + ret1 = strncpy_s(value, PARAM_CONST_VALUE_LEN_MAX - 1, tmp + 1, next - tmp); + next++; + while (isspace(*next) && (next < endBuffer)) { // 跳过空格 + next++; + } + } else { + ret1 = strncpy_s(value, PARAM_CONST_VALUE_LEN_MAX - 1, tmp + 1, endBuffer - tmp); + } + if ((ret == 0) && (ret1 == 0) && (CheckParamName(key, 0) == 0)) { + PARAM_LOGD("LoadParamFromCmdLine %s %s", key, value); + uint32_t dataIndex = 0; + (void)WriteParam(&g_paramWorkSpace.paramSpace, key, value, &dataIndex, 0); + } + if (next == NULL) { + break; + } + tmp = strchr(next, '='); + } + free(data); + free(buffer); return 0; } int SystemWriteParam(const char *name, const char *value) { PARAM_CHECK(name != NULL && value != NULL, return -1, "The name is null"); - PARAM_LOGI("SystemWriteParam name %s value: %s", name, value); - int ret = WriteParamWithCheck(&g_paramWorkSpace, &g_paramWorkSpace.label, name, value); - PARAM_CHECK(ret == 0, return ret, "Failed to set param %s", name); - ret = WritePersistParam(name, value); - PARAM_CHECK(ret == 0, return ret, "Failed to set persist param %s", name); - - // notify event to process trigger - PostParamTrigger(name, value); - return ret; + return SystemSetParam(name, value, g_paramWorkSpace.securityLabel); } int SystemReadParam(const char *name, char *value, unsigned int *len) { PARAM_CHECK(name != NULL && len != NULL, return -1, "The name is null"); ParamHandle handle = 0; - int ret = ReadParamWithCheck(&g_paramWorkSpace, name, &handle); + int ret = ReadParamWithCheck(&g_paramWorkSpace, name, DAC_READ, &handle); if (ret == 0) { ret = ReadParamValue(&g_paramWorkSpace, handle, value, len); } return ret; } -ParamWorkSpace *GetParamWorkSpace() +int SystemTraversalParam(void (*traversalParameter)(ParamHandle handle, void *cookie), void *cookie) { - return &g_paramWorkSpace; + PARAM_CHECK(traversalParameter != NULL, return -1, "The param is null"); + return TraversalParam(&g_paramWorkSpace, traversalParameter, cookie); } int LoadPersistParams() { - return RefreshPersistParams(&g_paramWorkSpace, g_initContext); + return LoadPersistParam(&g_paramWorkSpace); } -int SystemTraversalParam(void (*traversalParameter)(ParamHandle handle, void* cookie), void* cookie) +static int ProcessParamFile(const char *fileName, void *context) { - PARAM_CHECK(traversalParameter != NULL, return -1, "The param is null"); - return TraversalParam(&g_paramWorkSpace, traversalParameter, cookie); -} \ No newline at end of file + static const char *exclude[] = {"ctl.", "selinux.restorecon_recursive"}; + int mode = *(int *)context; + return LoadDefaultParam_(fileName, mode, exclude, sizeof(exclude) / sizeof(exclude[0])); +} + +int LoadDefaultParams(const char *fileName, int mode) +{ + PARAM_CHECK(fileName != NULL, return -1, "Invalid fielname for load"); + if (!PARAM_TEST_FLAG(g_paramWorkSpace.flags, WORKSPACE_FLAGS_INIT)) { + return PARAM_CODE_NOT_INIT; + } + PARAM_LOGI("load default parameters %s.", fileName); + int ret = 0; + struct stat st; + if ((stat(fileName, &st) == 0) && !S_ISDIR(st.st_mode)) { + ret = ProcessParamFile(fileName, &mode); + } else { + ret = ReadFileInDir(fileName, ".para", ProcessParamFile, &mode); + } + + // load security label + ParamSecurityOps *ops = &g_paramWorkSpace.paramSecurityOps; + if (ops->securityGetLabel != NULL) { + ret = ops->securityGetLabel(AddSecurityLabel, fileName, (void *)&g_paramWorkSpace); + } + return ret; +} + +void InitParamService() +{ + PARAM_LOGI("InitParamService pipe: %s.", PIPE_NAME); + CheckAndCreateDir(PIPE_NAME); + int ret = InitParamWorkSpace(&g_paramWorkSpace, 0); + PARAM_CHECK(ret == 0, return, "Init parameter workspace fail"); + ret = InitPersistParamWorkSpace(&g_paramWorkSpace); + PARAM_CHECK(ret == 0, return, "Init persist parameter workspace fail"); + if (g_paramWorkSpace.serverTask == NULL) { + ParamStreamInfo info = {}; + info.flags = WORKER_TYPE_SERVER; + info.server = PIPE_NAME; + info.close = NULL; + info.recvMessage = NULL; + info.incomingConnect = OnIncomingConnect; + int ret = ParamServerCreate(&g_paramWorkSpace.serverTask, &info); + PARAM_CHECK(ret == 0, return, "Failed to create server"); + PARAM_LOGD("OnIncomingConnect %p", g_paramWorkSpace.serverTask); + } + + if (g_paramWorkSpace.timer == NULL) { + ParamTimerCreate(&g_paramWorkSpace.timer, TimerCallback, &g_paramWorkSpace); + ParamTimerStart(g_paramWorkSpace.timer, 1, 1000); + PARAM_LOGD("Start timer %p", g_paramWorkSpace.timer); + } + ret = InitTriggerWorkSpace(); + PARAM_CHECK(ret == 0, return, "Failed to init trigger"); + + ParamAuditData auditData = {}; + auditData.name = "#"; + auditData.label = NULL; + auditData.dacData.gid = getegid(); + auditData.dacData.uid = geteuid(); + auditData.dacData.mode = 0777; + ret = AddSecurityLabel(&auditData, (void *)&g_paramWorkSpace); + PARAM_CHECK(ret == 0, return, "Failed to add default dac label"); + + // 读取cmdline的参数 + LoadParamFromCmdLine(); +} + +static void OnPidDelete(pid_t pid) +{ +} + +int StartParamService() +{ + return ParamServiceStart(OnPidDelete); +} + +void StopParamService() +{ + PARAM_LOGI("StopParamService."); + CloseParamWorkSpace(&g_paramWorkSpace); + CloseTriggerWorkSpace(); + // ParamTaskClose(g_paramWorkSpace.serverTask); + g_paramWorkSpace.serverTask = NULL; + ParamServiceStop(); +} + +ParamWorkSpace *GetParamWorkSpace() +{ + return &g_paramWorkSpace; +} diff --git a/services/param/trigger/trigger_checker.c b/services/param/trigger/trigger_checker.c old mode 100644 new mode 100755 index fff388e10..393eb891a --- a/services/param/trigger/trigger_checker.c +++ b/services/param/trigger/trigger_checker.c @@ -15,8 +15,9 @@ #include "trigger_checker.h" #include -#include "trigger_manager.h" + #include "init_param.h" +#include "trigger_manager.h" #define LABEL "Trigger" // 申请整块能存作为计算的节点 @@ -111,7 +112,7 @@ static int CalculatorLength(const LogicCalculator *calculator) return calculator->endIndex; } -static int PrefixAdd(char *prefix, u_int32_t *prefixIndex, u_int32_t prefixLen, char op) +static int PrefixAdd(char *prefix, uint32_t *prefixIndex, uint32_t prefixLen, char op) { if ((*prefixIndex + 3) >= prefixLen) { return -1; @@ -122,12 +123,12 @@ static int PrefixAdd(char *prefix, u_int32_t *prefixIndex, u_int32_t prefixLen, return 0; } -static int HandleOperationOr(LogicCalculator *calculator, char *prefix, u_int32_t *prefixIndex, u_int32_t prefixLen) +static int HandleOperationOr(LogicCalculator *calculator, char *prefix, uint32_t *prefixIndex, uint32_t prefixLen) { int ret = 0; char e; prefix[(*prefixIndex)++] = ' '; - if(CalculatorLength(calculator) == 0) { + if (CalculatorLength(calculator) == 0) { CalculatorPushChar(calculator, '|'); } else { do { @@ -144,48 +145,59 @@ static int HandleOperationOr(LogicCalculator *calculator, char *prefix, u_int32_ return 0; } +static int CompareValue(const char *condition, const char *value) +{ + if (strcmp(condition, "*") == 0) { + return 1; + } + if (strcmp(condition, value) == 0) { + return 1; + } + char *tmp = strstr(condition, "*"); + if (tmp != NULL && (strncmp(value, condition, tmp - condition) == 0)) { + return 1; + } + return 0; +} + static int ComputeSubCondition(LogicCalculator *calculator, LogicData *data, const char *condition) { if (!LOGIC_DATA_TEST_FLAG(data, LOGIC_DATA_FLAGS_ORIGINAL)) { return LOGIC_DATA_TEST_FLAG(data, LOGIC_DATA_FLAGS_TRUE); } - // 解析条件 + uint32_t triggerContentSize = strlen(calculator->triggerContent); + // 解析条件, aaaa && bbb=1 && ccc=1的场景 char *subStr = strstr(condition + data->startIndex, "="); - if (subStr != NULL && ((u_int32_t)(subStr - condition) > data->endIndex)) { - if (strncmp(condition + data->startIndex, calculator->triggerContent, strlen(calculator->triggerContent)) == 0) { + if (subStr != NULL && ((uint32_t)(subStr - condition) > data->endIndex)) { + if (strncmp(condition + data->startIndex, calculator->triggerContent, triggerContentSize) == 0) { return 1; } - } else { - int ret = GetValueFromContent(condition + data->startIndex, - data->endIndex - data->startIndex, 0, calculator->conditionName, SUPPORT_DATA_BUFFER_MAX); - PARAM_CHECK(ret == 0, return -1, "Failed parse content name"); - ret = GetValueFromContent(condition + data->startIndex, data->endIndex - data->startIndex, - strlen(calculator->conditionName) + 1, calculator->conditionContent, SUPPORT_DATA_BUFFER_MAX); - PARAM_CHECK(ret == 0, return -1, "Failed parse content value"); - // check name - if (calculator->inputName && strcmp(calculator->conditionName, calculator->inputName) == 0) { - if (strcmp(calculator->conditionContent, "*") == 0) { - return 1; - } - if (strcmp(calculator->conditionContent, calculator->inputContent) == 0) { - return 1; - } - } else { - u_int32_t len = SUPPORT_DATA_BUFFER_MAX; - ret = SystemReadParam(calculator->conditionName, calculator->readContent, &len); - if (ret == 0 && (strcmp(calculator->conditionContent, "*") == 0 || - strcmp(calculator->conditionContent, calculator->readContent) == 0)) { - return 1; - } + return 0; + } + int ret = GetValueFromContent(condition + data->startIndex, + data->endIndex - data->startIndex, 0, calculator->conditionName, SUPPORT_DATA_BUFFER_MAX); + PARAM_CHECK(ret == 0, return -1, "Failed parse content name"); + ret = GetValueFromContent(condition + data->startIndex, data->endIndex - data->startIndex, + strlen(calculator->conditionName) + 1, calculator->conditionContent, SUPPORT_DATA_BUFFER_MAX); + PARAM_CHECK(ret == 0, return -1, "Failed parse content value"); + // check name + if ((calculator->inputName != NULL) && (strcmp(calculator->conditionName, calculator->inputName) == 0)) { + return CompareValue(calculator->conditionContent, calculator->inputContent); + } else if (calculator->conditionName != NULL && strlen(calculator->conditionName) > 0) { + uint32_t len = SUPPORT_DATA_BUFFER_MAX; + ret = SystemReadParam(calculator->conditionName, calculator->readContent, &len); + if (ret != 0) { + return 0; } + return CompareValue(calculator->conditionContent, calculator->readContent); } return 0; } -int GetValueFromContent(const char *content, u_int32_t contentSize, u_int32_t start, char *value, u_int32_t valueSize) +int GetValueFromContent(const char *content, uint32_t contentSize, uint32_t start, char *value, uint32_t valueSize) { - u_int32_t contentIndex = start; - u_int32_t currIndex = 0; + uint32_t contentIndex = start; + uint32_t currIndex = 0; while (contentIndex < contentSize && currIndex < valueSize) { if (content[contentIndex] == '=') { value[currIndex++] = '\0'; @@ -202,8 +214,8 @@ int GetValueFromContent(const char *content, u_int32_t contentSize, u_int32_t st int ComputeCondition(LogicCalculator *calculator, const char *condition) { - u_int32_t currIndex = 0; - u_int32_t start = 0; + uint32_t currIndex = 0; + uint32_t start = 0; int noneOper = 1; CalculatorClear(calculator); LogicData data1 = {}; @@ -215,6 +227,7 @@ int ComputeCondition(LogicCalculator *calculator, const char *condition) int ret1 = CalculatorPop(calculator, (void*)&data1); PARAM_CHECK((ret == 0 && ret1 == 0), return -1, "Failed to pop data"); + ret = ComputeSubCondition(calculator, &data1, condition); data1.flags = 0; if (condition[currIndex] == '|' && ret == 1) { @@ -224,7 +237,7 @@ int ComputeCondition(LogicCalculator *calculator, const char *condition) LOGIC_DATA_SET_FLAG(&data1, LOGIC_DATA_FLAGS_TRUE); } } - ret = CalculatorPush(calculator, (void*)&data1); + ret = CalculatorPush(calculator, (void *)&data1); PARAM_CHECK(ret == 0, return -1, "Failed to push data"); start = currIndex + 1; // 跳过符号 } else if (isspace(condition[currIndex])) { @@ -235,7 +248,7 @@ int ComputeCondition(LogicCalculator *calculator, const char *condition) data1.flags = LOGIC_DATA_FLAGS_ORIGINAL; data1.startIndex = start; data1.endIndex = currIndex; - int ret = CalculatorPush(calculator, (void*)&data1); + int ret = CalculatorPush(calculator, (void *)&data1); PARAM_CHECK(ret == 0, return -1, "Failed to push data"); start = currIndex + 1; } @@ -252,12 +265,12 @@ int ComputeCondition(LogicCalculator *calculator, const char *condition) return ComputeSubCondition(calculator, &data1, condition); } -int ConvertInfixToPrefix(const char *condition, char *prefix, u_int32_t prefixLen) +int ConvertInfixToPrefix(const char *condition, char *prefix, uint32_t prefixLen) { char e = 0; int ret = 0; - u_int32_t curr = 0; - u_int32_t prefixIndex = 0; + uint32_t curr = 0; + uint32_t prefixIndex = 0; LogicCalculator calculator; CalculatorInit(&calculator, 100, 1, 0); @@ -300,13 +313,11 @@ int ConvertInfixToPrefix(const char *condition, char *prefix, u_int32_t prefixLe return 0; } -char *GetMatchedSubCondition(const char *condition, const char *input, int length) +int CheckMatchSubCondition(const char *condition, const char *input, int length) { - const char *p = condition; - for(;(p = strchr(p, *input)) != 0; p++) { - if(strncmp(p, input, length) == 0) { - return (char*)p; - } + char *tmp = strstr(condition, input); + if ((tmp != NULL) && (strlen(tmp) > length) && (tmp[length] == '=')) { + return 1; } - return NULL; + return 0; } diff --git a/services/param/trigger/trigger_manager.c b/services/param/trigger/trigger_manager.c old mode 100644 new mode 100755 index 7d2d104ba..c3182de77 --- a/services/param/trigger/trigger_manager.c +++ b/services/param/trigger/trigger_manager.c @@ -19,8 +19,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -28,270 +28,181 @@ #include "init_cmds.h" #include "init_utils.h" +#include "param_manager.h" #include "trigger_checker.h" #define LABEL "Trigger" -#define TRIGGER_AREA_SPACE 1024*128 -#define TRIGGER_EXECUTE_QUEUE 64 -#define BUFFER_SIZE 256 -#define CHECK_INDEX_VALID(workSpace, index) \ - (u_int32_t)(index) < sizeof((workSpace)->header) / sizeof((workSpace)->header[0]) - -#ifdef STARTUP_LOCAL -#define TRIGGER_PATH "/media/sf_ubuntu/test/__trigger__/trigger" -#else -#define TRIGGER_PATH "/dev/__trigger__/trigger" -#endif - -int InitTriggerWorkSpace(TriggerWorkSpace *workSpace) +int AddCommand(TriggerNode *trigger, uint32_t cmdKeyIndex, const char *content) { - PARAM_CHECK(workSpace != NULL, return -1, "Invalid parm"); - if (workSpace->area != NULL) { - return 0; + PARAM_CHECK(trigger != NULL, return -1, "trigger is null"); + uint32_t size = sizeof(CommandNode); + size += (content == NULL || strlen(content) == 0) ? 1 : strlen(content) + 1; + size = PARAM_ALIGN(size); + + CommandNode *node = (CommandNode *)malloc(size); + PARAM_CHECK(node != NULL, return -1, "Failed to alloc memory for command"); + node->cmdKeyIndex = cmdKeyIndex; + node->next = NULL; + node->content[0] = '\0'; + if (content != NULL && strlen(content) != 0) { + int ret = memcpy_s(node->content, size, content, strlen(content)); + node->content[strlen(content)] = '\0'; + PARAM_CHECK(ret == 0, return 0, "Failed to copy command"); } - CheckAndCreateDir(TRIGGER_PATH); - int fd = open(TRIGGER_PATH, O_CREAT | O_RDWR | O_TRUNC | O_CLOEXEC, 0444); - PARAM_CHECK(fd >= 0, return -1, "Open file fail error %s", strerror(errno)); - lseek(fd, TRIGGER_AREA_SPACE, SEEK_SET); - write(fd, "", 1); - - void *areaAddr = (void *)mmap(NULL, TRIGGER_AREA_SPACE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - PARAM_CHECK(areaAddr != MAP_FAILED, close(fd); return -1, - "Failed to map memory error %s", strerror(errno)); - close(fd); - - // 第一部分做执行队列 - workSpace->executeQueue.executeQueue = (u_int32_t *)areaAddr; - workSpace->executeQueue.queueCount = TRIGGER_EXECUTE_QUEUE; - workSpace->executeQueue.startIndex = 0; - workSpace->executeQueue.endIndex = 0; - pthread_mutex_init(&workSpace->executeQueue.mutex, NULL); - - // 动态数据保存 - workSpace->area = (TriggerArea *)(areaAddr + TRIGGER_EXECUTE_QUEUE * sizeof(u_int32_t)); - atomic_init(&workSpace->area->serial, ATOMIC_VAR_INIT(0)); - workSpace->area->dataSize = TRIGGER_AREA_SPACE - sizeof(TriggerArea) - TRIGGER_EXECUTE_QUEUE * sizeof(u_int32_t); - workSpace->area->currOffset = sizeof(TriggerArea) + TRIGGER_EXECUTE_QUEUE * sizeof(u_int32_t); - for (size_t i = 0; i < sizeof(workSpace->header) / sizeof(workSpace->header[0]); i++) { - atomic_init(&workSpace->header[i].firstTrigger, ATOMIC_VAR_INIT(0)); - atomic_init(&workSpace->header[i].lastTrigger, ATOMIC_VAR_INIT(0)); + // 插入队列 + if (trigger->firstCmd == NULL) { + trigger->firstCmd = node; + trigger->lastCmd = node; + } else { + trigger->lastCmd->next = node; + trigger->lastCmd = node; } + trigger->triggerHead->cmdNodeCount++; return 0; } -static CommandNode *GetCmdByIndex(TriggerWorkSpace *workSpace, TriggerNode *trigger, u_int32_t index) +CommandNode *GetNextCmdNode(TriggerNode *trigger, CommandNode *curr) { - if (index == 0 || index == (u_int32_t)-1) { - return NULL; + if (curr == NULL) { + return trigger->firstCmd; } - u_int32_t size = sizeof(CommandNode) + 2; - PARAM_CHECK((index + size) < workSpace->area->dataSize, - return NULL, "Invalid index for cmd %u", index); - return (CommandNode *)(workSpace->area->data + index); + return curr->next; } -u_int32_t AddCommand(TriggerWorkSpace *workSpace, TriggerNode *trigger, const char *cmdName, const char *content) +TriggerNode *AddTrigger(TriggerHeader *triggerHead, const char *name, const char *condition, uint16_t extDataSize) { - PARAM_CHECK(workSpace != NULL && trigger != NULL, return 0, "list is null"); - u_int32_t size = sizeof(CommandNode) + strlen(cmdName) + 1; - size += (content == NULL) ? 1 : strlen(content) + 1; - size = (size + 0x03) & (~0x03); - PARAM_CHECK((workSpace->area->currOffset + size) < workSpace->area->dataSize, - return 0, "Not enough memory for cmd %u %u", size, workSpace->area->currOffset); - - CommandNode *node = (CommandNode *)(workSpace->area->data + workSpace->area->currOffset); - PARAM_CHECK(node != NULL, return 0, "Failed to alloc memory for command"); - - int ret = memcpy_s(node->name, sizeof(node->name) - 1, cmdName, strlen(cmdName)); - PARAM_CHECK(ret == 0, return 0, "Failed to copy command"); - node->name[strlen(cmdName)] = '\0'; - if (content != NULL) { - ret = memcpy_s(node->content, size, content, strlen(content)); - node->content[strlen(content)] = '\0'; - PARAM_CHECK(ret == 0, return 0, "Failed to copy command"); - } else { - node->content[0] = '\0'; + PARAM_CHECK(triggerHead != NULL && name != NULL, return NULL, "triggerHead is null"); + uint32_t nameLen = strlen(name); + uint32_t triggerNodeLen = PARAM_ALIGN(nameLen + 1) + sizeof(TriggerNode); + uint32_t conditionLen = 0; + if (condition != NULL && strlen(condition) != 0) { + conditionLen = PARAM_ALIGN(strlen(condition) + 1) + CONDITION_EXTEND_LEN; } - u_int32_t offset = workSpace->area->currOffset; - atomic_init(&node->next, ATOMIC_VAR_INIT(0)); - // 插入队列 - if (trigger->firstCmd == 0) { - atomic_store_explicit(&trigger->firstCmd, offset, memory_order_release); - atomic_store_explicit(&trigger->lastCmd, offset, memory_order_release); - } else { - CommandNode *lastNode = GetCmdByIndex(workSpace, trigger, trigger->lastCmd); - if (lastNode != NULL) { - atomic_store_explicit(&lastNode->next, offset, memory_order_release); - } - atomic_store_explicit(&trigger->lastCmd, offset, memory_order_release); + TriggerNode *node = (TriggerNode *)malloc(triggerNodeLen + conditionLen + extDataSize); + PARAM_CHECK(node != NULL, return NULL, "Failed to alloc memory for trigger"); + int ret = memcpy_s(node->name, triggerNodeLen - sizeof(TriggerNode), name, nameLen); + PARAM_CHECK(ret == 0, free(node); return NULL, "Failed to memcpy_s for trigger"); + node->name[nameLen] = '\0'; + node->condition = NULL; + if (conditionLen != 0) { + char *cond = node->name + PARAM_ALIGN(nameLen + 1); + int ret = ConvertInfixToPrefix(condition, cond, conditionLen); + PARAM_CHECK(ret == 0, free(node); return NULL, "Failed to convert condition for trigger"); + node->condition = cond; } - workSpace->area->currOffset += size; - return offset; + node->flags = 0; + node->firstCmd = NULL; + node->lastCmd = NULL; + node->triggerHead = triggerHead; + ListInit(&node->node); + node->extDataSize = extDataSize; + node->extDataOffset = triggerNodeLen + conditionLen; + ListAddTail(&triggerHead->triggerList, &node->node); + triggerHead->triggerCount++; + return node; } -static TriggerNode *GetTriggerByIndex(TriggerWorkSpace *workSpace, u_int32_t index) +void ClearTrigger(TriggerHeader *head) { - if (index == 0 || index == (u_int32_t)-1) { - return NULL; + ListNode *node = head->triggerList.next; + while (node != &head->triggerList) { + ListRemove(node); + ListInit(node); + TriggerNode *trigger = ListEntry(node, TriggerNode, node); + FreeTrigger(trigger); + node = head->triggerList.next; } - u_int32_t size = sizeof(TriggerNode) + 1; - PARAM_CHECK((index + size) < workSpace->area->dataSize, - return NULL, "Invalid index for trigger %u", index); - return (TriggerNode *)(workSpace->area->data + index); + ListInit(&head->triggerList); } -u_int32_t AddTrigger(TriggerWorkSpace *workSpace, int type, const char *name, const char *condition) +void FreeTrigger(TriggerNode *trigger) { - PARAM_CHECK(workSpace != NULL && name != NULL, return 0, "list is null"); - const char *tmpCond = condition; - if (type == TRIGGER_BOOT && condition == NULL) { - tmpCond = name; + PARAM_CHECK(trigger != NULL, return, "trigger is null"); + PARAM_LOGD("FreeTrigger %s", trigger->name); + TriggerHeader *triggerHead = trigger->triggerHead; + CommandNode *cmd = trigger->firstCmd; + while (cmd != NULL) { + CommandNode *next = cmd->next; + free(cmd); + triggerHead->cmdNodeCount--; + cmd = next; } - u_int32_t conditionSize = (tmpCond == NULL) ? 1 : strlen(tmpCond) + 1 + CONDITION_EXTEND_LEN; - conditionSize = (conditionSize + 0x03) & (~0x03); - PARAM_CHECK((workSpace->area->currOffset + sizeof(TriggerNode) + conditionSize) < workSpace->area->dataSize, - return -1, "Not enough memory for cmd"); - - TriggerNode *node = (TriggerNode *)(workSpace->area->data + workSpace->area->currOffset); - PARAM_CHECK(node != NULL, return 0, "Failed to alloc memory for trigger"); - node->type = type; - int ret = memcpy_s(node->name, sizeof(node->name) - 1, name, strlen(name)); - PARAM_CHECK(ret == 0, return 0, "Failed to memcpy_s for trigger"); - node->name[strlen(name)] = '\0'; - - if (tmpCond != NULL) { - ret = ConvertInfixToPrefix(tmpCond, node->condition, conditionSize); - PARAM_CHECK(ret == 0, return 0, "Failed to memcpy_s for trigger"); - } else { - node->condition[0] = '\0'; + trigger->lastCmd = NULL; + trigger->firstCmd = NULL; + ListRemove(&trigger->node); + triggerHead->triggerCount--; + + // 如果在执行队列,从队列中移走 + if (!TRIGGER_IN_QUEUE(trigger)) { + free(trigger); + return; } - - u_int32_t offset = workSpace->area->currOffset; - atomic_init(&node->serial, ATOMIC_VAR_INIT(0)); - atomic_init(&node->next, ATOMIC_VAR_INIT(0)); - atomic_init(&node->firstCmd, ATOMIC_VAR_INIT(0)); - atomic_init(&node->lastCmd, ATOMIC_VAR_INIT(0)); - - // 插入到trigger队列中 - if (workSpace->header[type].firstTrigger == 0) { - atomic_store_explicit(&workSpace->header[type].firstTrigger, offset, memory_order_release); - atomic_store_explicit(&workSpace->header[type].lastTrigger, offset, memory_order_release); - } else { - TriggerNode *lastNode = GetTriggerByIndex(workSpace, workSpace->header[type].lastTrigger); - if (lastNode != NULL) { - atomic_store_explicit(&lastNode->next, offset, memory_order_release); + TriggerExecuteQueue *executeQueue = &GetTriggerWorkSpace()->executeQueue; + for (uint32_t i = executeQueue->startIndex; i < executeQueue->endIndex; i++) { + if (executeQueue->executeQueue[i] == trigger) { + executeQueue->executeQueue[i] = NULL; + break; } - atomic_store_explicit(&workSpace->header[type].lastTrigger, offset, memory_order_release); } - workSpace->area->currOffset += conditionSize + sizeof(TriggerNode); - return offset; + free(trigger); } -static int GetTriggerIndex(const char *type) +static TriggerNode *GetNextTrigger(TriggerHeader *triggerHead, TriggerNode *curr) { - if (strncmp("param:", type, strlen("param:")) == 0) { - return TRIGGER_PARAM; + ListNode *node = NULL; + if (curr != NULL) { + node = curr->node.next; + } else { + node = triggerHead->triggerList.next; } - static const char *triggerType[] = { - "pre-init", "boot", "early-init", "init", "late-init", "post-init", - "early-fs", "post-fs", "late-fs", "post-fs-data" - }; - for (size_t i = 0; i < sizeof(triggerType) / sizeof(char*); i++) { - if (strcmp(triggerType[i], type) == 0) { - return TRIGGER_BOOT; - } + if (node != &triggerHead->triggerList) { + return ListEntry(node, TriggerNode, node); } - return TRIGGER_UNKNOW; + return NULL; } -int ParseTrigger(TriggerWorkSpace *workSpace, cJSON *triggerItem) +static const char *GetTriggerCondition(TriggerWorkSpace *workSpace, TriggerNode *trigger) { - PARAM_CHECK(triggerItem != NULL, return -1, "Invalid file"); - PARAM_CHECK(workSpace != NULL, return -1, "Failed to create trigger list"); - - char *name = cJSON_GetStringValue(cJSON_GetObjectItem(triggerItem, "name")); - PARAM_CHECK(name != NULL, return -1, "Can not get name from cfg"); - char *condition = cJSON_GetStringValue(cJSON_GetObjectItem(triggerItem, "condition")); - - int index = GetTriggerIndex(name); - PARAM_CHECK(CHECK_INDEX_VALID(workSpace, index), return -1, "Failed to get trigger index"); - - u_int32_t offset = 0; - TriggerNode *trigger = GetTriggerByName(workSpace, name, &offset); - if (trigger == NULL) { - offset = AddTrigger(workSpace, index, name, condition); - PARAM_CHECK(offset > 0, return -1, "Failed to create trigger %s", name); - trigger = GetTriggerByIndex(workSpace, offset); - } else { - if (condition != NULL) { - PARAM_LOGE("Warning parseTrigger %s %s", name, condition); - } - } - PARAM_LOGD("ParseTrigger %s %u", name, offset); - - // 添加命令行 - cJSON* cmdItems = cJSON_GetObjectItem(triggerItem, CMDS_ARR_NAME_IN_JSON); - PARAM_CHECK(cJSON_IsArray(cmdItems), return -1, "Command item must be array"); - int cmdLinesCnt = cJSON_GetArraySize(cmdItems); - PARAM_CHECK(cmdLinesCnt > 0, return -1, "Command array size must positive %s", name); - - for (int i = 0; i < cmdLinesCnt; ++i) { - char *cmdLineStr = cJSON_GetStringValue(cJSON_GetArrayItem(cmdItems, i)); - PARAM_CHECK(cmdLineStr != NULL, continue, "Command is null"); - - size_t cmdLineLen = strlen(cmdLineStr); - const char *matchCmd = GetMatchCmd(cmdLineStr); - if (matchCmd == NULL && strncmp(cmdLineStr, TRIGGER_CMD, strlen(TRIGGER_CMD)) == 0) { - matchCmd = TRIGGER_CMD; - } - PARAM_CHECK(matchCmd != NULL, continue, "Command not support %s", cmdLineStr); - size_t matchLen = strlen(matchCmd); - if (matchLen == cmdLineLen) { - offset = AddCommand(workSpace, trigger, matchCmd, NULL); - } else { - offset = AddCommand(workSpace, trigger, matchCmd, cmdLineStr + matchLen); - } - //PARAM_LOGE("AddCommand %u %s %u", offset, cmdLineStr, workSpace->area->currOffset); - PARAM_CHECK(offset > 0, continue, "Failed to add command %s", cmdLineStr); - } - return 0; + return trigger->condition == NULL ? "" : trigger->condition; } -int ExecuteTrigger(TriggerWorkSpace *workSpace, TriggerNode *trigger, CMD_EXECUTE cmdExecuter) +TriggerNode *GetTriggerByName(TriggerWorkSpace *workSpace, const char *triggerName) { - PARAM_CHECK(workSpace != NULL && trigger != NULL && cmdExecuter != NULL, return -1, "Invalid param"); - PARAM_LOGI("ExecuteTrigger trigger %s", trigger->name); - CommandNode *cmd = GetCmdByIndex(workSpace, trigger, trigger->firstCmd); - while (cmd != NULL) { - cmdExecuter(trigger, cmd->name, cmd->content); - cmd = GetCmdByIndex(workSpace, trigger, cmd->next); + PARAM_CHECK(workSpace != NULL && triggerName != NULL, return NULL, "Invalid param"); + for (size_t i = 0; i < sizeof(workSpace->triggerHead) / sizeof(workSpace->triggerHead[0]); i++) { + TriggerNode *trigger = GetNextTrigger(&workSpace->triggerHead[i], NULL); + while (trigger != NULL) { + if (strcmp(triggerName, trigger->name) == 0) { + return trigger; + } + trigger = GetNextTrigger(&workSpace->triggerHead[i], trigger); + } } - return 0; + return NULL; } -int ExecuteQueuePush(TriggerWorkSpace *workSpace, TriggerNode *trigger, u_int32_t triggerIndex) +int ExecuteQueuePush(TriggerWorkSpace *workSpace, TriggerNode *trigger) { PARAM_CHECK(workSpace != NULL, return -1, "Invalid area"); - pthread_mutex_lock(&workSpace->executeQueue.mutex); - u_int32_t index = workSpace->executeQueue.endIndex++ % workSpace->executeQueue.queueCount; - workSpace->executeQueue.executeQueue[index] = triggerIndex; - pthread_mutex_unlock(&workSpace->executeQueue.mutex); + uint32_t index = workSpace->executeQueue.endIndex++ % workSpace->executeQueue.queueCount; + workSpace->executeQueue.executeQueue[index] = trigger; return 0; } TriggerNode *ExecuteQueuePop(TriggerWorkSpace *workSpace) { - if (workSpace->executeQueue.endIndex <= workSpace->executeQueue.startIndex) { - return NULL; - } - pthread_mutex_lock(&workSpace->executeQueue.mutex); - u_int32_t currIndex = workSpace->executeQueue.startIndex % workSpace->executeQueue.queueCount; - u_int32_t triggerIndex = workSpace->executeQueue.executeQueue[currIndex]; - workSpace->executeQueue.executeQueue[currIndex] = 0; - workSpace->executeQueue.startIndex++; - pthread_mutex_unlock(&workSpace->executeQueue.mutex); - return GetTriggerByIndex(workSpace, triggerIndex); + TriggerNode *trigger = NULL; + do { + if (workSpace->executeQueue.endIndex <= workSpace->executeQueue.startIndex) { + return NULL; + } + uint32_t currIndex = workSpace->executeQueue.startIndex % workSpace->executeQueue.queueCount; + trigger = workSpace->executeQueue.executeQueue[currIndex]; + workSpace->executeQueue.executeQueue[currIndex] = NULL; + workSpace->executeQueue.startIndex++; + } while (trigger == NULL); + return trigger; } int ExecuteQueueSize(TriggerWorkSpace *workSpace) @@ -300,8 +211,8 @@ int ExecuteQueueSize(TriggerWorkSpace *workSpace) return workSpace->executeQueue.endIndex - workSpace->executeQueue.startIndex; } -static int CheckBootTriggerMatch(LogicCalculator *calculator, - TriggerNode *trigger, const char *content, u_int32_t contentSize) +static int CheckBootTriggerMatch(TriggerWorkSpace *workSpace, LogicCalculator *calculator, + TriggerNode *trigger, const char *content, uint32_t contentSize) { if (strncmp(trigger->name, (char *)content, contentSize) == 0) { return 1; @@ -309,113 +220,239 @@ static int CheckBootTriggerMatch(LogicCalculator *calculator, return 0; } -static int CheckParamTriggerMatch(LogicCalculator *calculator, - TriggerNode *trigger, const char *content, u_int32_t contentSize) +static int CheckWatcherTriggerMatch(TriggerWorkSpace *workSpace, LogicCalculator *calculator, + TriggerNode *trigger, const char *content, uint32_t contentSize) +{ + if (strncmp(trigger->name, (char *)content, strlen(trigger->name)) == 0) { + return 1; + } + return 0; +} + +static int CheckParamTriggerMatch(TriggerWorkSpace *workSpace, LogicCalculator *calculator, + TriggerNode *trigger, const char *content, uint32_t contentSize) { + const char *condition = GetTriggerCondition(workSpace, trigger); if (calculator->inputName != NULL) { // 存在input数据时,先过滤非input的 - if (GetMatchedSubCondition(trigger->condition, content, strlen(calculator->inputName) + 1) == NULL) { + if (!CheckMatchSubCondition(condition, calculator->inputName, strlen(calculator->inputName))) { return 0; } } - return ComputeCondition(calculator, trigger->condition); + return ComputeCondition(calculator, condition); +} + +static int CheckOtherTriggerMatch(TriggerWorkSpace *workSpace, LogicCalculator *calculator, + TriggerNode *trigger, const char *content, uint32_t contentSize) +{ + const char *condition = GetTriggerCondition(workSpace, trigger); + return ComputeCondition(calculator, condition); +} + +static int CheckParamWaitMatch(TriggerWorkSpace *workSpace, int type, + LogicCalculator *calculator, const char *content, uint32_t contentSize) +{ + ParamWatcher *watcher = GetNextParamWatcher(workSpace, NULL); + while (watcher != NULL) { + TriggerNode *trigger = GetNextTrigger(&watcher->triggerHead, NULL); + while (trigger != NULL) { + TriggerNode *next = GetNextTrigger(&watcher->triggerHead, trigger); + if (CheckParamTriggerMatch(workSpace, calculator, trigger, content, contentSize) == 1) { + calculator->triggerExecuter(trigger, content, contentSize); + } + trigger = next; + } + watcher = GetNextParamWatcher(workSpace, watcher); + } + return 0; } -static int CheckOtherTriggerMatch(LogicCalculator *calculator, - TriggerNode *trigger, const char *content, u_int32_t contentSize) +static int CheckParamWatcherMatch(TriggerWorkSpace *workSpace, int type, + LogicCalculator *calculator, const char *content, uint32_t contentSize) { - return ComputeCondition(calculator, trigger->condition); + TriggerNode *trigger = GetNextTrigger(&workSpace->watcher.triggerHead, NULL); + while (trigger != NULL) { + TriggerNode *next = GetNextTrigger(&workSpace->watcher.triggerHead, trigger); + if (CheckWatcherTriggerMatch(workSpace, calculator, trigger, content, contentSize) == 1) { + calculator->triggerExecuter(trigger, content, contentSize); + } + trigger = next; + } + return 0; } static int CheckTrigger_(TriggerWorkSpace *workSpace, - LogicCalculator *calculator, int type, const char *content, u_int32_t contentSize) + LogicCalculator *calculator, int type, const char *content, uint32_t contentSize) { static TRIGGER_MATCH triggerCheckMatch[TRIGGER_MAX] = { CheckBootTriggerMatch, CheckParamTriggerMatch, CheckOtherTriggerMatch }; - PARAM_LOGD("CheckTrigger_ content %s ", content); PARAM_CHECK(calculator != NULL, return -1, "Failed to check calculator"); - PARAM_CHECK(CHECK_INDEX_VALID(workSpace, type), return -1, "Invalid type %d", type); - PARAM_CHECK((u_int32_t)type < sizeof(triggerCheckMatch) / sizeof(triggerCheckMatch[0]), + PARAM_CHECK(type < TRIGGER_MAX, return -1, "Invalid type %d", type); + PARAM_CHECK((uint32_t)type < sizeof(triggerCheckMatch) / sizeof(triggerCheckMatch[0]), return -1, "Failed to get check function"); PARAM_CHECK(triggerCheckMatch[type] != NULL, return -1, "Failed to get check function"); - u_int32_t index = workSpace->header[type].firstTrigger; - TriggerNode *trigger = GetTriggerByIndex(workSpace, workSpace->header[type].firstTrigger); + TriggerNode *trigger = GetNextTrigger(&workSpace->triggerHead[type], NULL); while (trigger != NULL) { - if (triggerCheckMatch[type](calculator, trigger, content, contentSize) == 1) { // 等于1 则认为匹配 - calculator->triggerExecuter(trigger, index); + if (triggerCheckMatch[type](workSpace, calculator, trigger, content, contentSize) == 1) { // 等于1 则认为匹配 + calculator->triggerExecuter(trigger, content, contentSize); } - index = trigger->next; - trigger = GetTriggerByIndex(workSpace, trigger->next); + trigger = GetNextTrigger(&workSpace->triggerHead[type], trigger); } return 0; } -int CheckTrigger(const TriggerWorkSpace *workSpace, - int type, void *content, u_int32_t contentSize, PARAM_CHECK_DONE triggerExecuter) +int CheckTrigger(TriggerWorkSpace *workSpace, int type, + const char *content, uint32_t contentSize, PARAM_CHECK_DONE triggerExecuter) { PARAM_CHECK(workSpace != NULL && content != NULL && triggerExecuter != NULL, return -1, "Failed arg for trigger"); - - LogicCalculator calculator = {}; + PARAM_LOGD("CheckTrigger type: %d content: %s ", type, content); + LogicCalculator calculator; + CalculatorInit(&calculator, MAX_CONDITION_NUMBER, sizeof(LogicData), 1); calculator.triggerExecuter = triggerExecuter; - return CheckTrigger_(workSpace, &calculator, type, (char *)content, contentSize); + if (type == TRIGGER_PARAM || type == TRIGGER_PARAM_WAIT) { + int ret = GetValueFromContent(content, contentSize, + 0, calculator.inputName, SUPPORT_DATA_BUFFER_MAX); + PARAM_CHECK(ret == 0, CalculatorFree(&calculator); return -1, "Failed parse content name"); + ret = GetValueFromContent(content, contentSize, + strlen(calculator.inputName) + 1, calculator.inputContent, SUPPORT_DATA_BUFFER_MAX); + PARAM_CHECK(ret == 0, CalculatorFree(&calculator); return -1, "Failed parse content value"); + } else if (type == TRIGGER_UNKNOW) { + int ret = memcpy_s(calculator.triggerContent, sizeof(calculator.triggerContent), content, contentSize); + PARAM_CHECK(ret == 0, CalculatorFree(&calculator); return -1, "Failed to memcpy"); + calculator.inputName = NULL; + calculator.inputContent = NULL; + } + if (type == TRIGGER_PARAM_WAIT) { + CheckParamWaitMatch(workSpace, PARAM_TRIGGER_FOR_WAIT, &calculator, content, contentSize); + } else if (type == TRIGGER_PARAM_WATCH) { + CheckParamWatcherMatch(workSpace, PARAM_TRIGGER_FOR_WATCH, &calculator, content, contentSize); + } else { + CheckTrigger_(workSpace, &calculator, type, content, contentSize); + } + CalculatorFree(&calculator); + return 0; } -int CheckParamTrigger(TriggerWorkSpace *workSpace, - const char *content, u_int32_t contentSize, PARAM_CHECK_DONE triggerExecuter) +int MarkTriggerToParam(TriggerWorkSpace *workSpace, TriggerHeader *triggerHead, const char *name) { - PARAM_CHECK(workSpace != NULL && content != NULL && triggerExecuter != NULL, - return -1, "Failed arg for param trigger"); - LogicCalculator calculator = {}; - CalculatorInit(&calculator, 100, sizeof(LogicData), 1); + int ret = 0; + TriggerNode *trigger = GetNextTrigger(triggerHead, NULL); + while (trigger != NULL) { + const char *tmp = strstr(GetTriggerCondition(workSpace, trigger), name); + if (tmp != NULL && strncmp(tmp + strlen(name), "=", 1) == 0) { + TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_RELATED); + ret = 1; + } + trigger = GetNextTrigger(triggerHead, trigger); + } + return ret; +} - // 先解析content - int ret = GetValueFromContent(content, contentSize, 0, calculator.inputName, SUPPORT_DATA_BUFFER_MAX); - PARAM_CHECK(ret == 0, CalculatorFree(&calculator); return -1, "Failed parse content name"); - ret = GetValueFromContent(content, contentSize, - strlen(calculator.inputName) + 1, calculator.inputContent, SUPPORT_DATA_BUFFER_MAX); - PARAM_CHECK(ret == 0, CalculatorFree(&calculator); return -1, "Failed parse content value"); - calculator.triggerExecuter = triggerExecuter; - CheckTrigger_(workSpace, &calculator, TRIGGER_PARAM, content, contentSize); - CalculatorFree(&calculator); - return 0; +ParamWatcher *GetNextParamWatcher(TriggerWorkSpace *workSpace, ParamWatcher *curr) +{ + ListNode *node = NULL; + if (curr != NULL) { + node = curr->node.next; + } else { + node = workSpace->waitList.next; + } + if (node == &workSpace->waitList) { + return NULL; + } + return ListEntry(node, ParamWatcher, node); } -int CheckAndExecuteTrigger(TriggerWorkSpace *workSpace, const char *content, PARAM_CHECK_DONE triggerExecuter) +TriggerNode *AddWatcherTrigger(ParamWatcher *watcher, + int triggerType, const char *name, const char *condition, const TriggerExtData *extData) { - PARAM_CHECK(workSpace != NULL && content != NULL && triggerExecuter != NULL, - return -1, "Failed arg for param trigger"); - LogicCalculator calculator = {}; - CalculatorInit(&calculator, 100, sizeof(LogicData), 1); + PARAM_CHECK(name != NULL, return NULL, "Invalid name"); + PARAM_CHECK(watcher != NULL && extData != NULL, return NULL, "Invalid watcher for %s", name); + + TriggerNode *trigger = AddTrigger(&watcher->triggerHead, name, condition, sizeof(TriggerExtData)); + PARAM_CHECK(trigger != NULL, return NULL, "Failed to create trigger for %s", name); + // add command and arg is "name" + int cmd = CMD_INDEX_FOR_PARA_WATCH; + if (triggerType == TRIGGER_PARAM_WAIT) { // wait 回复后立刻删除 + TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_ONCE); + cmd = CMD_INDEX_FOR_PARA_WAIT; + } + int ret = AddCommand(trigger, cmd, name); + PARAM_CHECK(ret == 0, FreeTrigger(trigger); return NULL, "Failed to add command for %s", name); + TriggerExtData *localData = TRIGGER_GET_EXT_DATA(trigger, TriggerExtData); + PARAM_CHECK(localData != NULL, return NULL, "Failed to get trigger ext data"); + localData->excuteCmd = extData->excuteCmd; + localData->watcherId = extData->watcherId; + localData->watcher = watcher; + return trigger; +} - int ret = memcpy_s(calculator.triggerContent, sizeof(calculator.triggerContent), content, strlen(content)); - PARAM_CHECK(ret == 0, CalculatorFree(&calculator); return -1, "Failed to memcpy"); +void DelWatcherTrigger(ParamWatcher *watcher, uint32_t watcherId) +{ + PARAM_CHECK(watcher != NULL, return, "Failed to add watcher "); + TriggerNode *trigger = GetNextTrigger(&watcher->triggerHead, NULL); + while (trigger != NULL) { + TriggerExtData *extData = TRIGGER_GET_EXT_DATA(trigger, TriggerExtData); + PARAM_CHECK(extData != NULL, continue, "Failed to get trigger ext data"); + TriggerNode *next = GetNextTrigger(&watcher->triggerHead, trigger); + if (extData->watcherId == watcherId) { + FreeTrigger(trigger); + break; + } + trigger = next; + } +} - calculator.triggerExecuter = triggerExecuter; - calculator.inputName = NULL; - calculator.inputContent = NULL; - // 执行完成后,对第三类trigger检查,执行必须是在本阶段执行的trigger - CheckTrigger_(workSpace, &calculator, TRIGGER_UNKNOW, content, 0); - CalculatorFree(&calculator); - return 0; +void ClearWatcherTrigger(ParamWatcher *watcher) +{ + PARAM_CHECK(watcher != NULL, return, "Invalid watcher "); + TriggerNode *trigger = GetNextTrigger(&watcher->triggerHead, NULL); + while (trigger != NULL) { + TriggerExtData *extData = TRIGGER_GET_EXT_DATA(trigger, TriggerExtData); + PARAM_CHECK(extData != NULL, continue, "Failed to get trigger ext data"); + FreeTrigger(trigger); + trigger = GetNextTrigger(&watcher->triggerHead, NULL); + } } -TriggerNode *GetTriggerByName(TriggerWorkSpace *workSpace, const char *triggerName, u_int32_t *triggerIndex) +#define DUMP_DEBUG PARAM_LOGD +static void DumpTriggerQueue(TriggerWorkSpace *workSpace, int index) { - PARAM_CHECK(workSpace != NULL && triggerName != NULL, return NULL, "Invalid param"); - for (size_t i = 0; i < sizeof(workSpace->header) / sizeof(workSpace->header[0]); i++) { - u_int32_t index = workSpace->header[i].firstTrigger; - TriggerNode *trigger = GetTriggerByIndex(workSpace, workSpace->header[i].firstTrigger); - while (trigger != NULL) { - if (strcmp(triggerName, trigger->name) == 0) { - *triggerIndex = index; - return trigger; - } - index = trigger->next; - trigger = GetTriggerByIndex(workSpace, trigger->next); + TriggerNode *trigger = GetNextTrigger(&workSpace->triggerHead[index], NULL); + while (trigger != NULL) { + DUMP_DEBUG("trigger 0x%08x", trigger->flags); + DUMP_DEBUG("trigger name %s ", trigger->name); + DUMP_DEBUG("trigger condition %s ", trigger->condition); + + CommandNode *cmd = GetNextCmdNode(trigger, NULL); + while (cmd != NULL) { + DUMP_DEBUG("\t command name %s", GetCmdKey(cmd->cmdKeyIndex)); + DUMP_DEBUG("\t command args %s", cmd->content); + cmd = GetNextCmdNode(trigger, cmd); + } + trigger = GetNextTrigger(&workSpace->triggerHead[index], trigger); + } +} + +void DumpTrigger(TriggerWorkSpace *workSpace) +{ + DUMP_DEBUG("Ready to dump all trigger memory"); + DUMP_DEBUG("workspace queue BOOT info:"); + DumpTriggerQueue(workSpace, TRIGGER_BOOT); + DUMP_DEBUG("workspace queue parameter info:"); + DumpTriggerQueue(workSpace, TRIGGER_PARAM); + DUMP_DEBUG("workspace queue other info:"); + DumpTriggerQueue(workSpace, TRIGGER_UNKNOW); + + DUMP_DEBUG("workspace queue execute info:"); + DUMP_DEBUG("queue info count: %u start: %u end: %u", + workSpace->executeQueue.queueCount, workSpace->executeQueue.startIndex, workSpace->executeQueue.endIndex); + for (uint32_t index = workSpace->executeQueue.startIndex; index < workSpace->executeQueue.endIndex; index++) { + TriggerNode *trigger = workSpace->executeQueue.executeQueue[index % workSpace->executeQueue.queueCount]; + if (trigger != 0) { + DUMP_DEBUG("queue node trigger name: %s ", trigger->name); } } - return NULL; } diff --git a/services/param/trigger/trigger_processor.c b/services/param/trigger/trigger_processor.c old mode 100644 new mode 100755 index 96d67fc46..8541f507f --- a/services/param/trigger/trigger_processor.c +++ b/services/param/trigger/trigger_processor.c @@ -12,178 +12,276 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#include "trigger_processor.h" #include #include #include "init_cmds.h" +#include "init_service_manager.h" #include "param_manager.h" +#include "param_utils.h" #include "trigger_checker.h" -#include "uv.h" +#include "trigger_manager.h" #define LABEL "Trigger" #define MAX_TRIGGER_COUNT_RUN_ONCE 20 -#define SYS_POWER_CTRL "sys.powerctrl=" -#define OHOS_CTL_START "ohos.ctl.start=" -#define OHOS_CTL_STOP "ohos.ctl.stop=" - static TriggerWorkSpace g_triggerWorkSpace = {}; -static int DoCmdExecute(TriggerNode *trigger, const char *cmdName, const char *command) +void DoTriggerExec(const char *triggerName) { - PARAM_CHECK(trigger != NULL && cmdName != NULL && command != NULL, return -1, "Invalid param"); - PARAM_LOGD("DoCmdExecute trigger %s cmd %s %s", trigger->name, cmdName, command); + PARAM_CHECK(triggerName != NULL, return, "Invalid param"); + TriggerNode *trigger = GetTriggerByName(&g_triggerWorkSpace, triggerName); + if (trigger != NULL && !TRIGGER_IN_QUEUE(trigger)) { // 不在队列中 + PARAM_LOGI("DoTriggerExec trigger %s", trigger->name); + TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_QUEUE); + ExecuteQueuePush(&g_triggerWorkSpace, trigger); + } +} + +static void DoCmdExec(TriggerNode *trigger, CommandNode *cmd, const char *content, uint32_t size) +{ + if (cmd->cmdKeyIndex == CMD_INDEX_FOR_PARA_WAIT || cmd->cmdKeyIndex == CMD_INDEX_FOR_PARA_WATCH) { + TriggerExtData *extData = TRIGGER_GET_EXT_DATA(trigger, TriggerExtData); + if (extData != NULL && extData->excuteCmd != NULL) { + extData->excuteCmd(extData, cmd->cmdKeyIndex, content); + } + return; + } + const char *cmdName = GetCmdKey(cmd->cmdKeyIndex); + if (cmdName == NULL) { + return; + } if (strncmp(cmdName, TRIGGER_CMD, strlen(TRIGGER_CMD)) == 0) { - DoTriggerExec(command); - return 0; + DoTriggerExec(cmd->content); + return; + } +#ifndef STARTUP_INIT_TEST + DoCmdByName(cmdName, cmd->content); +#endif +} + +static int ExecuteTrigger(TriggerWorkSpace *workSpace, TriggerNode *trigger) +{ + PARAM_CHECK(workSpace != NULL && trigger != NULL, return -1, "Invalid trigger"); + PARAM_CHECK(workSpace->cmdExec != NULL, return -1, "Invalid cmdExec"); + PARAM_LOGI("ExecuteTrigger trigger %s", trigger->name); + CommandNode *cmd = GetNextCmdNode(trigger, NULL); + while (cmd != NULL) { + workSpace->cmdExec(trigger, cmd, NULL, 0); + cmd = GetNextCmdNode(trigger, cmd); } - DoCmdByName(cmdName, command); return 0; } -static int DoTiggerCheckResult(TriggerNode *trigger, u_int32_t triggerIndex) +static int DoTiggerCheckResult(TriggerNode *trigger, const char *content, uint32_t size) { // 已经在队列中了,则不执行 TODO - if (TRIGGER_NODE_IN_QUEUE(trigger)) { + if (TRIGGER_IN_QUEUE(trigger)) { PARAM_LOGI("DoTiggerExecute trigger %s has been waiting execute", trigger->name); return 0; } - TRIGGER_NODE_SET_QUEUE_FLAG(trigger); - PARAM_LOGI("Waiting to exec trigger %s", trigger->name); - ExecuteQueuePush(&g_triggerWorkSpace, trigger, triggerIndex); + TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_QUEUE); + PARAM_LOGI("Add trigger %s to execute queue", trigger->name); + ExecuteQueuePush(&g_triggerWorkSpace, trigger); return 0; } -static int ExecuteTiggerImmediately(TriggerNode *trigger, u_int32_t triggerIndex) +static int ExecuteTiggerImmediately(TriggerNode *trigger, const char *content, uint32_t size) { - return ExecuteTrigger(&g_triggerWorkSpace, trigger, DoCmdExecute); + PARAM_CHECK(trigger != NULL, return -1, "Invalid trigger"); + PARAM_CHECK(g_triggerWorkSpace.cmdExec != NULL, return -1, "Invalid cmdExec"); + PARAM_LOGI("ExecuteTiggerImmediately trigger %s", trigger->name); + CommandNode *cmd = GetNextCmdNode(trigger, NULL); + while (cmd != NULL) { + g_triggerWorkSpace.cmdExec(trigger, cmd, content, size); + cmd = GetNextCmdNode(trigger, cmd); + } + if (TRIGGER_TEST_FLAG(trigger, TRIGGER_FLAGS_ONCE)) { + FreeTrigger(trigger); + } + return 0; } -void ExecuteQueueWork(u_int32_t maxCount) +static void ExecuteQueueWork(uint32_t maxCount) { - u_int32_t executeCount = 0; + uint32_t executeCount = 0; TriggerNode *trigger = ExecuteQueuePop(&g_triggerWorkSpace); while (trigger != NULL) { - ExecuteTrigger(&g_triggerWorkSpace, trigger, DoCmdExecute); - TRIGGER_NODE_CLEAR_QUEUE_FLAG(trigger); - CheckAndExecuteTrigger(&g_triggerWorkSpace, trigger->name, ExecuteTiggerImmediately); - + ExecuteTrigger(&g_triggerWorkSpace, trigger); + TRIGGER_CLEAR_FLAG(trigger, TRIGGER_FLAGS_QUEUE); + if (TRIGGER_TEST_FLAG(trigger, TRIGGER_FLAGS_SUBTRIGGER)) { // 检查boot:xxx=xxx 的trigger + CheckTrigger(&g_triggerWorkSpace, TRIGGER_UNKNOW, + trigger->name, strlen(trigger->name), ExecuteTiggerImmediately); + } + if (TRIGGER_TEST_FLAG(trigger, TRIGGER_FLAGS_ONCE)) { + FreeTrigger(trigger); + } executeCount++; if (executeCount > maxCount) { break; } - PARAM_LOGI("ExecuteQueueWork %u", executeCount); trigger = ExecuteQueuePop(&g_triggerWorkSpace); } } -static void CheckTriggers(int type, void *content, u_int32_t contentLen) +static void ProcessParamEvent(uint64_t eventId, const char *content, uint32_t size) +{ + ExecuteQueueWork(MAX_TRIGGER_COUNT_RUN_ONCE); +} + +static void ProcessBeforeEvent(uint64_t eventId, const char *content, uint32_t size) { - switch (type) { - case EVENT_PROPERTY: { - CheckParamTrigger(&g_triggerWorkSpace, content, contentLen, DoTiggerCheckResult); + switch (eventId) { + case EVENT_TRIGGER_PARAM: { + CheckTrigger(&g_triggerWorkSpace, TRIGGER_PARAM, content, size, DoTiggerCheckResult); break; } - case EVENT_BOOT: { - CheckTrigger(&g_triggerWorkSpace, TRIGGER_BOOT, content, contentLen, DoTiggerCheckResult); + case EVENT_TRIGGER_BOOT: { + CheckTrigger(&g_triggerWorkSpace, TRIGGER_BOOT, content, size, DoTiggerCheckResult); + break; + } + case EVENT_TRIGGER_PARAM_WAIT: { + CheckTrigger(&g_triggerWorkSpace, TRIGGER_PARAM_WAIT, content, size, ExecuteTiggerImmediately); + break; + } + case EVENT_TRIGGER_PARAM_WATCH: { + CheckTrigger(&g_triggerWorkSpace, TRIGGER_PARAM_WATCH, content, size, ExecuteTiggerImmediately); break; } default: - PARAM_LOGI("CheckTriggers: %d", type); + PARAM_LOGI("CheckTriggers: %lu", eventId); break; } } -static void ProcessAfterEvent(uv_work_t *req, int status) -{ - free(req); - ExecuteQueueWork(MAX_TRIGGER_COUNT_RUN_ONCE); -} - -static void ProcessEvent(uv_work_t *req) -{ - TriggerDataEvent *event = (TriggerDataEvent *)req; - CheckTriggers(event->type, event->content, event->contentSize); -} - -static const char *GetCmdInfo(const char *content, u_int32_t contentSize, char **cmdParam) +static const char *GetCmdInfo(const char *content, uint32_t contentSize, char **cmdParam) { static const char *ctrlCmds[][2] = { {"reboot", "reboot "} }; + uint32_t index = 0; for (size_t i = 0; i < sizeof(ctrlCmds) / sizeof(ctrlCmds[0]); i++) { if (strncmp(content, ctrlCmds[i][0], strlen(ctrlCmds[i][0])) == 0) { *cmdParam = (char *)content; - return GetMatchCmd(ctrlCmds[i][1]); + return GetMatchCmd(ctrlCmds[i][1], &index); } } return NULL; } -static void SendTriggerEvent(TriggerDataEvent *event) +static void SendTriggerEvent(int type, const char *content, uint32_t contentLen) { - if (event == NULL) { - return; - } - int ctrlSize = strlen(SYS_POWER_CTRL); - if (strncmp(event->content, SYS_POWER_CTRL, ctrlSize) == 0) { - char *cmdParam = NULL; - const char *matchCmd = GetCmdInfo(event->content + ctrlSize, event->contentSize - ctrlSize, &cmdParam); - if (matchCmd != NULL) { - DoCmdByName(matchCmd, cmdParam); + PARAM_CHECK(content != NULL, return, "Invalid param"); + PARAM_LOGD("SendTriggerEvent type %d content %s", type, content); + if (type == EVENT_TRIGGER_PARAM) { + int ctrlSize = strlen(SYS_POWER_CTRL); + if (strncmp(content, SYS_POWER_CTRL, ctrlSize) == 0) { + char *cmdParam = NULL; + const char *matchCmd = GetCmdInfo(content + ctrlSize, contentLen - ctrlSize, &cmdParam); + PARAM_LOGD("SendTriggerEvent matchCmd %s", matchCmd); + if (matchCmd != NULL) { +#ifndef STARTUP_INIT_TEST + DoCmdByName(matchCmd, cmdParam); +#endif + } else { + PARAM_LOGE("SendTriggerEvent cmd %s not found", content); + } + } else if (strncmp(content, OHOS_CTRL_START, strlen(OHOS_CTRL_START)) == 0) { + StartServiceByName(content + strlen(OHOS_CTRL_START), false); + } else if (strncmp(content, OHOS_CTRL_STOP, strlen(OHOS_CTRL_STOP)) == 0) { + StopServiceByName(content + strlen(OHOS_CTRL_STOP)); } else { - PARAM_LOGE("SendTriggerEvent cmd %s not found", event->content); + ParamEventSend(g_triggerWorkSpace.eventHandle, (uint64_t)type, content, contentLen); } - } else if (strncmp(event->content, OHOS_CTL_START, strlen(OHOS_CTL_START)) == 0) { - DoCmdByName("start ", event->content + strlen(OHOS_CTL_START)); - } else if (strncmp(event->content, OHOS_CTL_STOP, strlen(OHOS_CTL_STOP)) == 0) { - DoCmdByName("stop ", event->content + strlen(OHOS_CTL_STOP)); } else { - uv_queue_work(uv_default_loop(), &event->request, ProcessEvent, ProcessAfterEvent); - event = NULL; - } - if (event != NULL) { - free(event); + ParamEventSend(g_triggerWorkSpace.eventHandle, (uint64_t)type, content, contentLen); } } -void PostParamTrigger(const char *name, const char *value) +void PostParamTrigger(int type, const char *name, const char *value) { PARAM_CHECK(name != NULL && value != NULL, return, "Invalid param"); - PARAM_LOGD("PostParamTrigger %s ", name); - int contentLen = strlen(name) + strlen(value) + 2; - TriggerDataEvent *event = (TriggerDataEvent *)malloc(sizeof(TriggerDataEvent) + contentLen); - PARAM_CHECK(event != NULL, return, "Failed to alloc memory"); - event->type = EVENT_PROPERTY; - event->request.data = (char*)event + sizeof(uv_work_t); - event->contentSize = BuildParamContent(event->content, contentLen, name, value); - PARAM_CHECK(event->contentSize > 0, return, "Failed to copy porperty"); - SendTriggerEvent(event); - PARAM_LOGI("PostParamTrigger %s success", name); + uint32_t bufferSize = strlen(name) + strlen(value) + 1 + 1 + 1; + char *buffer = (char *)malloc(bufferSize); + PARAM_CHECK(buffer != NULL, return, "Failed to alloc memory for param %s", name); + int ret = sprintf_s(buffer, bufferSize - 1, "%s=%s", name, value); + PARAM_CHECK(ret > 0, free(buffer); return, "Failed to copy param"); + SendTriggerEvent(type, buffer, strlen(buffer)); + free(buffer); } -void PostTrigger(EventType type, const char *content, u_int32_t contentLen) +void PostTrigger(EventType type, const char *content, uint32_t contentLen) { - PARAM_LOGD("PostTrigger %d %s", type, content); PARAM_CHECK(content != NULL && contentLen > 0, return, "Invalid param"); - TriggerDataEvent *event = (TriggerDataEvent *)malloc(sizeof(TriggerDataEvent) + contentLen + 1); - PARAM_CHECK(event != NULL, return, "Failed to alloc memory"); - event->type = type; - event->request.data = (char*)event + sizeof(uv_work_t); - event->contentSize = contentLen; - PARAM_CHECK(memcpy_s(event->content, contentLen, content, contentLen) == 0, return, "Failed to copy content"); - event->content[contentLen] = '\0'; - SendTriggerEvent(event); - PARAM_LOGD("PostTrigger %d success", type); + SendTriggerEvent(type, content, contentLen); } -int ParseTriggerConfig(cJSON *fileRoot) +static int GetTriggerType(const char *type) { - PARAM_CHECK(fileRoot != NULL, return -1, "Invalid file"); - int ret = InitTriggerWorkSpace(&g_triggerWorkSpace); - PARAM_CHECK(ret == 0, return -1, "Failed to init trigger"); + if (strncmp("param:", type, strlen("param:")) == 0) { + return TRIGGER_PARAM; + } + static const char *triggerType[] = { + "pre-init", "boot", "early-init", "init", "early-init", "late-init", "post-init", + "early-fs", "post-fs", "late-fs", "post-fs-data" + }; + for (size_t i = 0; i < sizeof(triggerType) / sizeof(char *); i++) { + if (strcmp(triggerType[i], type) == 0) { + return TRIGGER_BOOT; + } + } + return TRIGGER_UNKNOW; +} + +static int ParseTrigger_(TriggerWorkSpace *workSpace, cJSON *triggerItem) +{ + PARAM_CHECK(triggerItem != NULL, return -1, "Invalid file"); + PARAM_CHECK(workSpace != NULL, return -1, "Failed to create trigger list"); + char *name = cJSON_GetStringValue(cJSON_GetObjectItem(triggerItem, "name")); + PARAM_CHECK(name != NULL, return -1, "Can not get name from cfg"); + char *condition = cJSON_GetStringValue(cJSON_GetObjectItem(triggerItem, "condition")); + int type = GetTriggerType(name); + PARAM_CHECK(type < TRIGGER_MAX, return -1, "Failed to get trigger index"); + + TriggerNode *trigger = GetTriggerByName(workSpace, name); + if (trigger == NULL) { + trigger = AddTrigger(&workSpace->triggerHead[type], name, condition, 0); + PARAM_CHECK(trigger != NULL, return -1, "Failed to create trigger %s", name); + } + if (type == TRIGGER_BOOT) { // 设置trigger立刻删除,如果是boot + TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_ONCE); + TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_SUBTRIGGER); + } + PARAM_LOGD("ParseTrigger %s type %d count %d", name, type, workSpace->triggerHead[type].triggerCount); + + // 添加命令行 + cJSON *cmdItems = cJSON_GetObjectItem(triggerItem, CMDS_ARR_NAME_IN_JSON); + PARAM_CHECK(cJSON_IsArray(cmdItems), return -1, "Command item must be array"); + int cmdLinesCnt = cJSON_GetArraySize(cmdItems); + PARAM_CHECK(cmdLinesCnt > 0, return -1, "Command array size must positive %s", name); + int ret = 0; + uint32_t cmdKeyIndex = 0; + for (int i = 0; i < cmdLinesCnt; ++i) { + char *cmdLineStr = cJSON_GetStringValue(cJSON_GetArrayItem(cmdItems, i)); + PARAM_CHECK(cmdLinesCnt > 0, continue, "Command is null"); + + size_t cmdLineLen = strlen(cmdLineStr); + const char *matchCmd = GetMatchCmd(cmdLineStr, &cmdKeyIndex); + PARAM_CHECK(matchCmd != NULL, continue, "Command not support %s", cmdLineStr); + size_t matchLen = strlen(matchCmd); + if (matchLen == cmdLineLen) { + ret = AddCommand(trigger, cmdKeyIndex, NULL); + } else { + ret = AddCommand(trigger, cmdKeyIndex, cmdLineStr + matchLen); + } + PARAM_CHECK(ret == 0, continue, "Failed to add command %s", cmdLineStr); + } + return 0; +} + +int ParseTriggerConfig(const cJSON *fileRoot) +{ + PARAM_CHECK(fileRoot != NULL, return -1, "Invalid file"); cJSON *triggers = cJSON_GetObjectItemCaseSensitive(fileRoot, TRIGGER_ARR_NAME_IN_JSON); PARAM_CHECK(cJSON_IsArray(triggers), return -1, "Trigger item must array"); @@ -192,24 +290,78 @@ int ParseTriggerConfig(cJSON *fileRoot) for (int i = 0; i < size; ++i) { cJSON *item = cJSON_GetArrayItem(triggers, i); - ParseTrigger(&g_triggerWorkSpace, item); + ParseTrigger_(&g_triggerWorkSpace, item); } return 0; } -void DoTriggerExec(const char *content) +int InitTriggerWorkSpace() { - PARAM_CHECK(content != NULL, return, "Invalid trigger content"); - u_int32_t triggerIndex = 0; - TriggerNode *trigger = GetTriggerByName(&g_triggerWorkSpace, content, &triggerIndex); - if (trigger != NULL && !TRIGGER_NODE_IN_QUEUE(trigger)) { // 不在队列中 - PARAM_LOGI("DoTriggerExec trigger %s", trigger->name); - TRIGGER_NODE_SET_QUEUE_FLAG(trigger); - ExecuteQueuePush(&g_triggerWorkSpace, trigger, triggerIndex); + if (g_triggerWorkSpace.eventHandle != NULL) { + return 0; } + g_triggerWorkSpace.cmdExec = DoCmdExec; + ParamEventTaskCreate(&g_triggerWorkSpace.eventHandle, ProcessParamEvent, ProcessBeforeEvent); + PARAM_CHECK(g_triggerWorkSpace.eventHandle != NULL, return -1, "Failed to event handle"); + + // executeQueue + g_triggerWorkSpace.executeQueue.executeQueue = malloc(TRIGGER_EXECUTE_QUEUE * sizeof(TriggerNode *)); + g_triggerWorkSpace.executeQueue.queueCount = TRIGGER_EXECUTE_QUEUE; + g_triggerWorkSpace.executeQueue.startIndex = 0; + g_triggerWorkSpace.executeQueue.endIndex = 0; + PARAM_CHECK(g_triggerWorkSpace.executeQueue.executeQueue != NULL, + return -1, "Failed to alloc memory for executeQueue"); + int ret = memset_s(g_triggerWorkSpace.executeQueue.executeQueue, + TRIGGER_EXECUTE_QUEUE * sizeof(TriggerNode *), 0, TRIGGER_EXECUTE_QUEUE * sizeof(TriggerNode *)); + PARAM_CHECK(ret == 0, return -1, "Failed to memset for executeQueue"); + + // normal trigger + for (size_t i = 0; i < sizeof(g_triggerWorkSpace.triggerHead) / sizeof(g_triggerWorkSpace.triggerHead[0]); i++) { + PARAM_TRIGGER_HEAD_INIT(g_triggerWorkSpace.triggerHead[i]); + } + // for watcher trigger + PARAM_TRIGGER_HEAD_INIT(g_triggerWorkSpace.watcher.triggerHead); + ListInit(&g_triggerWorkSpace.waitList); + return 0; +} + +void CloseTriggerWorkSpace() +{ + // 释放trigger + for (size_t i = 0; i < sizeof(g_triggerWorkSpace.triggerHead) / sizeof(g_triggerWorkSpace.triggerHead[0]); i++) { + ClearTrigger(&g_triggerWorkSpace.triggerHead[i]); + } + free(g_triggerWorkSpace.executeQueue.executeQueue); + ParamTaskClose(g_triggerWorkSpace.eventHandle); +} + +int CheckAndMarkTrigger(int type, const char *name) +{ + if (type == TRIGGER_PARAM) { + return MarkTriggerToParam(&g_triggerWorkSpace, &g_triggerWorkSpace.triggerHead[type], name); + } else if (type != TRIGGER_PARAM_WAIT) { + return 0; + } + + ParamWatcher *watcher = GetNextParamWatcher(&g_triggerWorkSpace, NULL); + while (watcher != NULL) { + if (MarkTriggerToParam(&g_triggerWorkSpace, &watcher->triggerHead, name)) { + return 1; + } + watcher = GetNextParamWatcher(&g_triggerWorkSpace, watcher); + } + return 0; } TriggerWorkSpace *GetTriggerWorkSpace() { return &g_triggerWorkSpace; } + +ParamWatcher *GetParamWatcher(const ParamTaskPtr worker) +{ + if (worker != NULL) { + return (ParamWatcher *)ParamGetTaskUserData(worker); + } + return &g_triggerWorkSpace.watcher; +} diff --git a/services/param/watcher/agent/watcher.cpp b/services/param/watcher/agent/watcher.cpp new file mode 100755 index 000000000..95240e1b8 --- /dev/null +++ b/services/param/watcher/agent/watcher.cpp @@ -0,0 +1,29 @@ +/* + * 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 "watcher.h" + +#include "iservice_registry.h" +#include "securec.h" +#include "system_ability_definition.h" +#include "watcher_utils.h" + +namespace OHOS { +namespace init_param { +void Watcher::OnParamerterChange(const std::string &name, const std::string &value) +{ +} +} // namespace init_param +} // namespace OHOS diff --git a/services/param/watcher/agent/watcher.h b/services/param/watcher/agent/watcher.h new file mode 100755 index 000000000..6c80f2503 --- /dev/null +++ b/services/param/watcher/agent/watcher.h @@ -0,0 +1,33 @@ +/* + * 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 START_WATCHER_H +#define START_WATCHER_H + +#include +#include "watcher_stub.h" + +namespace OHOS { +namespace init_param { +class Watcher : public WatcherStub { +public: + explicit Watcher() = default; + ~Watcher() = default; + + void OnParamerterChange(const std::string &name, const std::string &value) override; +}; +} // namespace init_param +} // namespace OHOS +#endif // START_WATCHER_H \ No newline at end of file diff --git a/services/param/watcher/agent/watcher_manager_kits.cpp b/services/param/watcher/agent/watcher_manager_kits.cpp new file mode 100755 index 000000000..0a60e7d08 --- /dev/null +++ b/services/param/watcher/agent/watcher_manager_kits.cpp @@ -0,0 +1,162 @@ +/* + * 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 "watcher_manager_kits.h" + +#include "if_system_ability_manager.h" +#include "iservice_registry.h" +#include "iwatcher.h" +#include "iwatcher_manager.h" +#include "param_request.h" +#include "system_ability_definition.h" +#include "watcher_utils.h" + +namespace OHOS { +namespace init_param { +WatcherManagerKits &WatcherManagerKits::GetInstance() +{ + return DelayedRefSingleton::GetInstance(); +} + +WatcherManagerKits::WatcherManagerKits() {} + +WatcherManagerKits::~WatcherManagerKits() {} + +void WatcherManagerKits::ResetService(const wptr &remote) +{ + WATCHER_LOGI("Remote is dead, reset service instance"); + std::lock_guard lock(lock_); + if (watcherManager_ != nullptr) { + sptr object = watcherManager_->AsObject(); + if ((object != nullptr) && (remote == object)) { + object->RemoveDeathRecipient(deathRecipient_); + watcherManager_ = nullptr; + } + } +} + +sptr WatcherManagerKits::GetService() +{ + std::lock_guard lock(lock_); + if (watcherManager_ != nullptr) { + return watcherManager_; + } + + sptr samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + WATCHER_CHECK(samgr != nullptr, return nullptr, "Get samgr failed"); + sptr object = samgr->GetSystemAbility(PARAM_WATCHER_DISTRIBUTED_SERVICE_ID); + WATCHER_CHECK(object != nullptr, return nullptr, "Get watcher manager object from samgr failed"); + if (deathRecipient_ == nullptr) { + deathRecipient_ = new DeathRecipient(); + } + + if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient_))) { + WATCHER_LOGE("Failed to add death recipient"); + } + watcherManager_ = iface_cast(object); + if (watcherManager_ == nullptr) { + WATCHER_LOGE("watcher manager iface_cast failed"); + } + return watcherManager_; +} + +void WatcherManagerKits::DeathRecipient::OnRemoteDied(const wptr &remote) +{ + DelayedRefSingleton::GetInstance().ResetService(remote); +} + +WatcherManagerKits::ParamWatcherKitPtr WatcherManagerKits::GetParamWatcher(const std::string &keyPrefix) +{ + std::lock_guard lock(mutex_); + if (watchers_.find(keyPrefix) == watchers_.end()) { + return nullptr; + } + return watchers_[keyPrefix]; +} + +void WatcherManagerKits::SetParamWatcher(const std::string &keyPrefix, ParamWatcherKitPtr watcher) +{ + std::lock_guard lock(mutex_); + if (watchers_.find(keyPrefix) != watchers_.end()) { + watchers_[keyPrefix] = watcher; + } +} + +int32_t WatcherManagerKits::AddWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context) +{ + WATCHER_LOGI("AddWatcher keyPrefix %s", keyPrefix.c_str()); + ParamWatcherKitPtr watcher = GetParamWatcher(keyPrefix); + if (watcher != nullptr) { + WATCHER_LOGE("Has been watched by keyPrefix %s", keyPrefix.c_str()); + return 0; + } + watcher = new ParamWatcher(keyPrefix, callback, context); + WATCHER_CHECK(watcher != nullptr, return -1, "Failed to create watcher for %s", keyPrefix.c_str()); + auto watcherManager = GetService(); + WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get watcher manager"); + uint32_t watcherId = watcherManager->AddWatcher(keyPrefix, watcher); + WATCHER_CHECK(watcherId != 0, return -1, "Failed to add watcher for %s", keyPrefix.c_str()); + watcher->SetWatcherId(watcherId); + SetParamWatcher(keyPrefix, watcher); + return watcher->GetWatcherId(); +} + +int32_t WatcherManagerKits::DelWatcher(const std::string &keyPrefix) +{ + ParamWatcherKitPtr watcher = GetParamWatcher(keyPrefix); + if (watcher == nullptr) { + WATCHER_LOGE("Has been watched by keyPrefix %s", keyPrefix.c_str()); + return 0; + } + auto watcherManager = GetService(); + WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get watcher manager"); + int ret = watcherManager->DelWatcher(keyPrefix, watcher->GetWatcherId()); + WATCHER_CHECK(ret == 0, return -1, "Failed to delete watcher for %s", keyPrefix.c_str()); + SetParamWatcher(keyPrefix, nullptr); + return 0; +} + +void WatcherManagerKits::ParamWatcher::OnParamerterChange(const std::string &name, const std::string &value) +{ + WATCHER_LOGD("OnParamerterChange name %s value %s", name.c_str(), value.c_str()); + if (callback_ != nullptr) { + callback_(name.c_str(), value.c_str(), context_); + } +} +} // namespace init_param +} // namespace OHOS + +int SystemWatchParameter(const char *keyPrefix, ParameterChangePtr callback, void *context) +{ + if (keyPrefix == nullptr) { + return PARAM_CODE_INVALID_PARAM; + } + int ret = 0; + std::string key(keyPrefix); + if (key.rfind("*") == key.length() - 1) { + ret = WatchParamCheck(key.substr(0, key.length() - 1).c_str()); + } else { + ret = WatchParamCheck(keyPrefix); + } + if (ret != 0) { + return ret; + } + OHOS::init_param::WatcherManagerKits &instance = OHOS::init_param::WatcherManagerKits::GetInstance(); + if (callback != nullptr) { + ret = (instance.AddWatcher(keyPrefix, callback, context) > 0) ? 0 : -1; + } else { + ret = instance.DelWatcher(keyPrefix); + } + return ret; +} diff --git a/services/param/watcher/agent/watcher_manager_kits.h b/services/param/watcher/agent/watcher_manager_kits.h new file mode 100755 index 000000000..fe7d59d0b --- /dev/null +++ b/services/param/watcher/agent/watcher_manager_kits.h @@ -0,0 +1,89 @@ +/* + * 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 WATCHER_MANAGER_KITS_H +#define WATCHER_MANAGER_KITS_H +#include +#include +#include + +#include "iwatcher.h" +#include "iwatcher_manager.h" +#include "singleton.h" +#include "sys_param.h" +#include "watcher.h" +#include "watcher_utils.h" + +namespace OHOS { +namespace init_param { + +class WatcherManagerKits final : public DelayedRefSingleton { + DECLARE_DELAYED_REF_SINGLETON(WatcherManagerKits); +public: + DISALLOW_COPY_AND_MOVE(WatcherManagerKits); + + static WatcherManagerKits &GetInstance(); + int32_t AddWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context); + int32_t DelWatcher(const std::string &keyPrefix); +private: + class ParamWatcher final : public Watcher { + public: + ParamWatcher(const std::string &key, ParameterChangePtr callback, void *context) + : keyPrefix_(key), callback_(callback), context_(context) {} + ~ParamWatcher() = default; + + void OnParamerterChange(const std::string &name, const std::string &value) override; + + void SetWatcherId(uint32_t watcherId) + { + watcherId_ = watcherId; + } + uint32_t GetWatcherId() + { + return watcherId_; + } + + private: + uint32_t watcherId_{ 0 }; + std::string keyPrefix_{}; + ParameterChangePtr callback_{ nullptr }; + void *context_ { nullptr }; + }; + + // For death event procession + class DeathRecipient final : public IRemoteObject::DeathRecipient { + public: + DeathRecipient() = default; + ~DeathRecipient() final = default; + DISALLOW_COPY_AND_MOVE(DeathRecipient); + void OnRemoteDied(const wptr &remote) final; + }; + +private: + using ParamWatcherKitPtr = sptr; + ParamWatcherKitPtr GetParamWatcher(const std::string &keyPrefix); + void SetParamWatcher(const std::string &keyPrefix, ParamWatcherKitPtr watcher); + void ResetService(const wptr &remote); + sptr GetService(); + std::mutex lock_; + sptr watcherManager_{}; + sptr deathRecipient_{}; + + std::mutex mutex_; + std::map watchers_; +}; +} // namespace init_param +} // namespace OHOS +#endif // WATCHER_MANAGER_KITS_H diff --git a/services/param/watcher/agent/watcher_manager_proxy.cpp b/services/param/watcher/agent/watcher_manager_proxy.cpp new file mode 100755 index 000000000..28dc1de29 --- /dev/null +++ b/services/param/watcher/agent/watcher_manager_proxy.cpp @@ -0,0 +1,54 @@ +/* + * 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 "watcher_manager_proxy.h" +#include "watcher_utils.h" + +namespace OHOS { +namespace init_param { +uint32_t WatcherManagerProxy::AddWatcher(const std::string &keyPrefix, const sptr &watcher) +{ + WATCHER_CHECK(watcher != nullptr, return ERR_INVALID_VALUE, "Invalid param"); + WATCHER_LOGD("WatcherManagerProxy::AddWatcher %s", keyPrefix.c_str()); + auto remote = Remote(); + WATCHER_CHECK(remote != nullptr, return 0, "Can not get remote"); + + MessageParcel data; + data.WriteString(keyPrefix); + bool ret = data.WriteRemoteObject(watcher->AsObject()); + WATCHER_CHECK(ret, return 0, "Can not get remote"); + + MessageParcel reply; + MessageOption option { MessageOption::TF_SYNC }; + int32_t res = remote->SendRequest(ADD_WATCHER, data, reply, option); + WATCHER_CHECK(res == ERR_OK, return 0, "Transact error"); + return reply.ReadUint32(); +} +int32_t WatcherManagerProxy::DelWatcher(const std::string &keyPrefix, uint32_t watcherId) +{ + WATCHER_LOGD("WatcherManagerProxy::DelWatcher %s", keyPrefix.c_str()); + auto remote = Remote(); + WATCHER_CHECK(remote != nullptr, return ERR_FLATTEN_OBJECT, "Can not get remote"); + + MessageParcel data; + data.WriteString(keyPrefix); + data.WriteUint32(watcherId); + MessageParcel reply; + MessageOption option { MessageOption::TF_SYNC }; + int32_t res = remote->SendRequest(DEL_WATCHER, data, reply, option); + WATCHER_CHECK(res == ERR_OK, return ERR_FLATTEN_OBJECT, "Transact error"); + return reply.ReadInt32(); +} +} +} // namespace OHOS diff --git a/services/param/watcher/agent/watcher_manager_proxy.h b/services/param/watcher/agent/watcher_manager_proxy.h new file mode 100755 index 000000000..b8b5961c0 --- /dev/null +++ b/services/param/watcher/agent/watcher_manager_proxy.h @@ -0,0 +1,35 @@ +/* + * 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 STARTUP_WATCH_MANAGER_PROXY_H +#define STARTUP_WATCH_MANAGER_PROXY_H + +#include "iremote_proxy.h" +#include "iwatcher_manager.h" + +namespace OHOS { +namespace init_param { +class WatcherManagerProxy : public IRemoteProxy { +public: + explicit WatcherManagerProxy(const sptr &impl) : IRemoteProxy(impl) {} + + uint32_t AddWatcher(const std::string &keyPrefix, const sptr &watcher) override; + int32_t DelWatcher(const std::string &keyPrefix, uint32_t watcherId) override; +private: + static inline BrokerDelegator delegator_; +}; +} // namespace init_param +} // namespace OHOS +#endif // STARTUP_WATCH_MANAGER_PROXY_H \ No newline at end of file diff --git a/services/param/watcher/agent/watcher_stub.cpp b/services/param/watcher/agent/watcher_stub.cpp new file mode 100755 index 000000000..3bc29a025 --- /dev/null +++ b/services/param/watcher/agent/watcher_stub.cpp @@ -0,0 +1,39 @@ +/* + * 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 "watcher_stub.h" + +#include "securec.h" +#include "watcher_utils.h" + +namespace OHOS { +namespace init_param { +int32_t WatcherStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + switch (code) { + case PARAM_CHANGE: { + std::string name = data.ReadString(); + std::string value = data.ReadString(); + OnParamerterChange(name, value); + break; + } + default: { + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + } + return 0; +} +} // namespace init_param +} // namespace OHOS diff --git a/services/param/watcher/agent/watcher_stub.h b/services/param/watcher/agent/watcher_stub.h new file mode 100755 index 000000000..64c06f3cb --- /dev/null +++ b/services/param/watcher/agent/watcher_stub.h @@ -0,0 +1,32 @@ +/* + * 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 STARTUP_WATCHER_STUB_H_ +#define STARTUP_WATCHER_STUB_H_ + +#include "iremote_stub.h" +#include "iwatcher.h" +#include "message_parcel.h" +#include "parcel.h" + +namespace OHOS { +namespace init_param { +class WatcherStub : public IRemoteStub { +public: + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; +}; +} // namespace init_param +} // namespace OHOS +#endif // !defined(STARTUP_WATCHER_STUB_H_) diff --git a/services/param/watcher/etc/param_watcher.cfg b/services/param/watcher/etc/param_watcher.cfg new file mode 100755 index 000000000..a6b3a15f4 --- /dev/null +++ b/services/param/watcher/etc/param_watcher.cfg @@ -0,0 +1,16 @@ +{ + "jobs" : [{ + "name" : "boot", + "cmds" : [ + "start param_watcher" + ] + } + ], + "services" : [{ + "name" : "param_watcher", + "path" : ["/system/bin/sa_main", "/system/profile/param_watcher.xml"], + "uid" : "system", + "gid" : ["system", "shell"] + } + ] +} diff --git a/services/param/watcher/etc/param_watcher.rc b/services/param/watcher/etc/param_watcher.rc new file mode 100755 index 000000000..fdfbd3b0b --- /dev/null +++ b/services/param/watcher/etc/param_watcher.rc @@ -0,0 +1,21 @@ +# 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. +service param_watcher /system/bin/sa_main /system/profile/param_watcher.xml +class z_core +user system +group system shell +seclabel u:r:param_watcher:s0 + +on boot + start param_watcher + diff --git a/services/param/watcher/include/iwatcher.h b/services/param/watcher/include/iwatcher.h new file mode 100755 index 000000000..957a0a0da --- /dev/null +++ b/services/param/watcher/include/iwatcher.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 ISTARTUP_WATCHER_H +#define ISTARTUP_WATCHER_H + +#include +#include "iremote_broker.h" +#include "iremote_proxy.h" + +namespace OHOS { +namespace init_param { +class IWatcher : public OHOS::IRemoteBroker { +public: + virtual ~IWatcher() = default; + enum { + PARAM_CHANGE = 1, + }; + + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.Startup.IWatcher"); +public: + virtual void OnParamerterChange(const std::string &name, const std::string &value) = 0; +}; +} // namespace init_param +} // namespace OHOS +#endif // ISTARTUP_WATCHER_H diff --git a/services/param/watcher/include/iwatcher_manager.h b/services/param/watcher/include/iwatcher_manager.h new file mode 100755 index 000000000..ac503463e --- /dev/null +++ b/services/param/watcher/include/iwatcher_manager.h @@ -0,0 +1,40 @@ +/* + * 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 ISTARTUP_WATCHER_MANAGER_H +#define ISTARTUP_WATCHER_MANAGER_H + +#include +#include "iremote_broker.h" +#include "iremote_proxy.h" +#include "iwatcher.h" + +namespace OHOS { +namespace init_param { +class IWatcherManager : public OHOS::IRemoteBroker { +public: + enum { + ADD_WATCHER, + DEL_WATCHER + }; + + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.Startup.IWatcherManager"); +public: + virtual uint32_t AddWatcher(const std::string &keyPrefix, const sptr &watcher) = 0; + virtual int32_t DelWatcher(const std::string &keyPrefix, uint32_t watcherId) = 0; +}; +} // namespace update_engine +} // namespace OHOS +#endif // ISTARTUP_WATCHER_MANAGER_H diff --git a/services/param/watcher/include/watcher_utils.h b/services/param/watcher/include/watcher_utils.h new file mode 100755 index 000000000..dd294d213 --- /dev/null +++ b/services/param/watcher/include/watcher_utils.h @@ -0,0 +1,44 @@ +/* + * 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 STARTUP_WATCHER_UTILS_H +#define STARTUP_WATCHER_UTILS_H +#include + +#include "init_log.h" +#include "iremote_broker.h" +#include "iremote_proxy.h" + +#include "securec.h" + +namespace OHOS { +namespace init_param { + +#ifndef LABEL +#define LABEL "Watcher" +#endif + +#define WATCHER_LOGI(fmt, ...) STARTUP_LOGI(LABEL, fmt, ##__VA_ARGS__) +#define WATCHER_LOGE(fmt, ...) STARTUP_LOGE(LABEL, fmt, ##__VA_ARGS__) +#define WATCHER_LOGD(fmt, ...) STARTUP_LOGD(LABEL, fmt, ##__VA_ARGS__) + +#define WATCHER_CHECK(retCode, exper, ...) \ + if (!(retCode)) { \ + WATCHER_LOGE(__VA_ARGS__); \ + exper; \ + } +} // namespace init_param +} // namespace OHOS +#endif // STARTUP_WATCHER_UTILS_H diff --git a/services/param/watcher/proxy/watcher_manager.cpp b/services/param/watcher/proxy/watcher_manager.cpp new file mode 100755 index 000000000..b386201a7 --- /dev/null +++ b/services/param/watcher/proxy/watcher_manager.cpp @@ -0,0 +1,295 @@ +/* + * 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 "watcher_manager.h" +#include +#include +#include +#include +#include + +#include "param_message.h" +#include "sys_param.h" +#include "system_ability_definition.h" +#include "watcher_utils.h" + +namespace OHOS { +namespace init_param { +REGISTER_SYSTEM_ABILITY_BY_ID(WatcherManager, PARAM_WATCHER_DISTRIBUTED_SERVICE_ID, true) + +const int32_t INVALID_SOCKET = -1; +const int32_t RECV_BUFFER_MAX = 5 * 1024; +uint32_t WatcherManager::AddWatcher(const std::string &keyPrefix, const sptr &watcher) +{ + WATCHER_CHECK(watcher != nullptr, return 0, "Invalid remove watcher for %s", keyPrefix.c_str()); + if (watcherId_ == 0) { + watcherId_++; + } + ParamWatcherPtr paramWather = std::make_shared(watcherId_, watcher); + WATCHER_CHECK(paramWather != nullptr, return 0, "Failed to create watcher for %s", keyPrefix.c_str()); + WatcherGroupPtr group = GetWatcherGroup(keyPrefix); + if (group == nullptr) { + group = std::make_shared(++groupId_, keyPrefix); + } + WATCHER_CHECK(group != nullptr, return 0, "Failed to create group for %s", keyPrefix.c_str()); + AddWatcherGroup(keyPrefix, group); + + if (group->Emptry()) { + StartLoop(); + SendMessage(group, MSG_ADD_WATCHER); + } + SendLocalChange(keyPrefix, paramWather); + group->AddWatcher(paramWather); + WATCHER_LOGD("AddWatcher %s watcherId: %u", keyPrefix.c_str(), paramWather->GetWatcherId()); + return paramWather->GetWatcherId(); +} + +int32_t WatcherManager::DelWatcher(const std::string &keyPrefix, uint32_t watcherId) +{ + auto group = GetWatcherGroup(keyPrefix); + if (group == nullptr) { + WATCHER_LOGE("DelWatcher can not find group %s", keyPrefix.c_str()); + return 0; + } + group->DelWatcher(watcherId); + if (group->Emptry()) { + SendMessage(group, MSG_DEL_WATCHER); + DelWatcherGroup(group); + } + return 0; +} + +int WatcherManager::SendMessage(WatcherGroupPtr group, int type) +{ + ParamMessage *request = nullptr; + request = (ParamMessage *)CreateParamMessage(type, group->GetKeyPrefix().c_str(), sizeof(ParamMessage)); + PARAM_CHECK(request != NULL, return PARAM_CODE_ERROR, "Failed to malloc for watch"); + request->id.watcherId = group->GetGroupId(); + request->msgSize = sizeof(ParamMessage); + do { + int fd = GetServerFd(false); + if (fd != INVALID_SOCKET) { + ssize_t sendLen = send(serverFd_, (char *)request, request->msgSize, 0); + if (sendLen > 0) { + PARAM_LOGD("SendMessage key: %s %d success", group->GetKeyPrefix().c_str(), type); + break; + } + } + // fail, try again + PARAM_LOGE("Failed to connect server %s, try again", PIPE_NAME); + fd = GetServerFd(true); + } while (1); + free(request); + return 0; +} + +void WatcherManager::ProcessWatcherMessage(const char *buffer, uint32_t dataSize) +{ + ParamMessage *msg = (ParamMessage *)buffer; + uint32_t offset = 0; + if (msg->type != MSG_NOTIFY_PARAM) { + return; + } + PARAM_CHECK(msg->msgSize <= dataSize, return, "Invalid msg size %d", msg->msgSize); + ParamMsgContent *valueContent = GetNextContent((const ParamMessage *)msg, &offset); + PARAM_CHECK(valueContent != NULL, return, "Invalid msg "); + PARAM_LOGI("ProcessWatcherMessage name %s watcherId %u ", msg->key, msg->id.watcherId); + + WatcherGroupPtr group = GetWatcherGroup(msg->id.watcherId); + if (group != nullptr) { + group->ProcessParameterChange(msg->key, valueContent->content); + } +} + +WatcherManager::WatcherGroupPtr WatcherManager::GetWatcherGroup(uint32_t groupId) +{ + std::lock_guard lock(watcherMutex_); + if (watcherGroups_.find(groupId) != watcherGroups_.end()) { + return watcherGroups_[groupId]; + } + return nullptr; +} + +WatcherManager::WatcherGroupPtr WatcherManager::GetWatcherGroup(const std::string &keyPrefix) +{ + if (groupMap_.find(keyPrefix) == groupMap_.end()) { + return nullptr; + } + return GetWatcherGroup(groupMap_[keyPrefix]); +} + +void WatcherManager::AddWatcherGroup(const std::string &keyPrefix, WatcherGroupPtr group) +{ + uint32_t groupId = group->GetGroupId(); + groupMap_[keyPrefix] = groupId; + + std::lock_guard lock(watcherMutex_); + if (watcherGroups_.find(groupId) != watcherGroups_.end()) { + return; + } + watcherGroups_[groupId] = group; +} + +void WatcherManager::DelWatcherGroup(WatcherGroupPtr group) +{ + groupMap_[group->GetKeyPrefix()] = 0; + std::lock_guard lock(watcherMutex_); + watcherGroups_[group->GetGroupId()] = nullptr; +} + +void WatcherManager::WatcherGroup::AddWatcher(const ParamWatcherPtr &watcher) +{ + watchers_[watcher->GetWatcherId()] = watcher; +} + +void WatcherManager::WatcherGroup::DelWatcher(uint32_t watcherId) +{ + if (watchers_.find(watcherId) != watchers_.end()) { + watchers_[watcherId] = nullptr; + } +} + +WatcherManager::ParamWatcherPtr WatcherManager::WatcherGroup::GetWatcher(uint32_t watcherId) +{ + if (watchers_.find(watcherId) != watchers_.end()) { + return watchers_[watcherId]; + } + return nullptr; +} + +void WatcherManager::WatcherGroup::ProcessParameterChange(const std::string &name, const std::string &value) +{ + // walk watcher + for (auto iter = watchers_.begin(); iter != watchers_.end(); iter++) { + iter->second->ProcessParameterChange(name, value); + } +} + +static int FilterParam(const char *name, const std::string &keyPrefix) +{ + if (keyPrefix.rfind("*") == keyPrefix.length() - 1) { + return strncmp(name, keyPrefix.c_str(), keyPrefix.length() - 1) == 0; + } + return strcmp(name, keyPrefix.c_str()) == 0; +} + +void WatcherManager::SendLocalChange(const std::string &keyPrefix, ParamWatcherPtr watcher) +{ + struct Context{ + char *buffer; + ParamWatcherPtr watcher; + std::string keyPrefix; + }; + std::vector buffer(PARAM_NAME_LEN_MAX + PARAM_CONST_VALUE_LEN_MAX); + struct Context context = {buffer.data(), watcher, keyPrefix}; + // walk watcher + SystemTraversalParameter( + [](ParamHandle handle, void *cookie) { + struct Context *context = (struct Context *)(cookie); + SystemGetParameterName(handle, context->buffer, PARAM_NAME_LEN_MAX); + if (!FilterParam(context->buffer, context->keyPrefix)) { + return; + } + uint32_t size = PARAM_CONST_VALUE_LEN_MAX; + SystemGetParameterValue(handle, context->buffer + PARAM_NAME_LEN_MAX, &size); + PARAM_LOGD("SendLocalChange key %s value: %s ", context->buffer, context->buffer + PARAM_NAME_LEN_MAX); + context->watcher->ProcessParameterChange(context->buffer, context->buffer + PARAM_NAME_LEN_MAX); + }, (void *)&context); +} + +void WatcherManager::RunLoop() +{ + char *buffer = (char *)malloc(RECV_BUFFER_MAX); + PARAM_CHECK(buffer != NULL, return, "Failed to create buffer for recv"); + while (!stop) { + int fd = GetServerFd(false); + ssize_t recvLen = recv(fd, buffer, RECV_BUFFER_MAX, 0); + if (recvLen <= 0) { + if (errno == EAGAIN) { // 超时,继续等待 + continue; + } + fd = GetServerFd(true); + PARAM_LOGE("Failed to recv msg from server %d errno %d", recvLen, errno); + } + PARAM_LOGD("Recv msg from server %d", recvLen); + if (recvLen >= (ssize_t)sizeof(ParamMessage)) { + ProcessWatcherMessage(buffer, recvLen); + } + } + PARAM_LOGI("Exit runLoop"); +} + +void WatcherManager::StartLoop() +{ + if (pRecvThread_ == nullptr) { + pRecvThread_ = new (std::nothrow)std::thread(&WatcherManager::RunLoop, this); + WATCHER_CHECK(pRecvThread_ != nullptr, return, "Failed to create thread"); + } +} + +int WatcherManager::GetServerFd(bool retry) +{ + std::lock_guard lock(mutex_); + if (retry && serverFd_ != INVALID_SOCKET) { + close(serverFd_); + serverFd_ = INVALID_SOCKET; + } + if (serverFd_ != INVALID_SOCKET) { + return serverFd_; + } + struct timeval time; + time.tv_sec = 1; + time.tv_usec = 0; + do { + serverFd_ = socket(AF_UNIX, SOCK_STREAM, 0); + int ret = ConntectServer(serverFd_, PIPE_NAME); + if (ret == 0) { + setsockopt(serverFd_, SOL_SOCKET, SO_RCVTIMEO, (char *)&time, sizeof(struct timeval)); + break; + } + if (ret != 0) { + close(serverFd_); + serverFd_ = INVALID_SOCKET; + usleep(2000); + } + } while (1); + return serverFd_; +} + +void WatcherManager::OnStart() +{ + PARAM_LOGI("WatcherManager OnStart"); + bool res = Publish(this); + if (res == false) { + PARAM_LOGI("WatcherManager OnStart failed"); + } + return; +} + +void WatcherManager::OnStop() +{ + PARAM_LOGI("WatcherManager OnStop"); + stop = true; + { + std::lock_guard lock(mutex_); + close(serverFd_); + } + if (pRecvThread_ != nullptr) { + pRecvThread_->join(); + delete pRecvThread_; + pRecvThread_ = nullptr; + } +} +} // namespace init_param +} // namespace OHOS diff --git a/services/param/watcher/proxy/watcher_manager.h b/services/param/watcher/proxy/watcher_manager.h new file mode 100755 index 000000000..1d76961d7 --- /dev/null +++ b/services/param/watcher/proxy/watcher_manager.h @@ -0,0 +1,107 @@ +/* + * 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 WATCHER_MANAGER_H_ +#define WATCHER_MANAGER_H_ +#include +#include +#include +#include +#include +#include + +#include "iremote_stub.h" +#include "iwatcher.h" +#include "message_parcel.h" +#include "parcel.h" +#include "system_ability.h" +#include "watcher_manager_stub.h" + +namespace OHOS { +namespace init_param { +class WatcherManager : public SystemAbility, public WatcherManagerStub { +public: + DECLARE_SYSTEM_ABILITY(WatcherManager); + DISALLOW_COPY_AND_MOVE(WatcherManager); + explicit WatcherManager(int32_t systemAbilityId, bool runOnCreate = true) + : SystemAbility(systemAbilityId, runOnCreate) {} + ~WatcherManager() override { + watcherGroups_.clear(); + groupMap_.clear(); + }; + + class ParamWatcher { + public: + ParamWatcher(uint32_t watcherId, const sptr &watcher) : watcherId_(watcherId), watcher_(watcher) {} + ~ParamWatcher() = default; + uint32_t GetWatcherId() { return watcherId_; } + void ProcessParameterChange(const std::string &name, const std::string &value) + { + watcher_->OnParamerterChange(name, value); + } + private: + uint32_t watcherId_ = { 0 }; + sptr watcher_; + }; + using ParamWatcherPtr = std::shared_ptr; + + class WatcherGroup { + public: + WatcherGroup(uint32_t groupId, const std::string &key) : groupId_(groupId), keyPrefix_(key) {} + ~WatcherGroup() = default; + void AddWatcher(const ParamWatcherPtr &watcher); + void DelWatcher(uint32_t watcherId); + void ProcessParameterChange(const std::string &name, const std::string &value); + ParamWatcherPtr GetWatcher(uint32_t watcherId); + + const std::string GetKeyPrefix() { return keyPrefix_; } + bool Emptry() { return watchers_.size() == 0; } + uint32_t GetGroupId() { return groupId_; } + private: + uint32_t groupId_; + std::string keyPrefix_ { }; + std::map watchers_; + }; + using WatcherGroupPtr = std::shared_ptr; + + uint32_t AddWatcher(const std::string &keyPrefix, const sptr &watcher) override; + int32_t DelWatcher(const std::string &keyPrefix, uint32_t watcherId) override; +protected: + void OnStart() override; + void OnStop() override; +private: + WatcherGroupPtr GetWatcherGroup(uint32_t groupId); + WatcherGroupPtr GetWatcherGroup(const std::string &keyPrefix); + void AddWatcherGroup(const std::string &keyPrefix, WatcherGroupPtr group); + void DelWatcherGroup(WatcherGroupPtr group); + void RunLoop(); + void StartLoop(); + void SendLocalChange(const std::string &keyPrefix, ParamWatcherPtr watcher); + void ProcessWatcherMessage(const char *buffer, uint32_t dataSize); + int SendMessage(WatcherGroupPtr group, int type); + int GetServerFd(bool retry); +private: + std::atomic watcherId_ { 0 }; + std::atomic groupId_ { 0 }; + std::mutex mutex_; + std::mutex watcherMutex_; + int serverFd_ { -1 }; + std::thread *pRecvThread_ { nullptr }; + std::atomic stop { false }; + std::map groupMap_ {}; + std::map watcherGroups_ {}; +}; +} // namespace init_param +} // namespace OHOS +#endif // WATCHER_MANAGER_H_ \ No newline at end of file diff --git a/services/param/watcher/proxy/watcher_manager_stub.cpp b/services/param/watcher/proxy/watcher_manager_stub.cpp new file mode 100755 index 000000000..209f6237b --- /dev/null +++ b/services/param/watcher/proxy/watcher_manager_stub.cpp @@ -0,0 +1,48 @@ +/* + * 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 "watcher_manager_stub.h" +#include "watcher_utils.h" + +namespace OHOS { +namespace init_param { +int32_t WatcherManagerStub::OnRemoteRequest(uint32_t code, + MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + switch (code) { + case ADD_WATCHER: { + std::string key = data.ReadString(); + auto remote = data.ReadRemoteObject(); + // 0 is invalid watcherId + WATCHER_CHECK(remote != nullptr, reply.WriteUint32(0); return 0, "Failed to read remote watcher"); + uint32_t watcherId = AddWatcher(key, iface_cast(remote)); + reply.WriteUint32(watcherId); + break; + } + case DEL_WATCHER: { + std::string key = data.ReadString(); + uint32_t watcherId = data.ReadUint32(); + int ret = DelWatcher(key, watcherId); + reply.WriteInt32(ret); + break; + } + default: { + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + } + return 0; +} +} +} diff --git a/services/param/watcher/proxy/watcher_manager_stub.h b/services/param/watcher/proxy/watcher_manager_stub.h new file mode 100755 index 000000000..1fbbba53a --- /dev/null +++ b/services/param/watcher/proxy/watcher_manager_stub.h @@ -0,0 +1,33 @@ +/* + * 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 WATCHER_MANAGER_STUB_H_ +#define WATCHER_MANAGER_STUB_H_ + +#include "iremote_stub.h" +#include "iwatcher_manager.h" +#include "message_parcel.h" +#include "parcel.h" + +namespace OHOS { +namespace init_param { +class WatcherManagerStub : public IRemoteStub { +public: + int32_t OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, + MessageOption &option) override; +}; +} +} +#endif // WATCHER_MANAGER_STUB_H_ \ No newline at end of file diff --git a/services/param/watcher/proxy/watcher_proxy.cpp b/services/param/watcher/proxy/watcher_proxy.cpp new file mode 100755 index 000000000..62e6aaeb5 --- /dev/null +++ b/services/param/watcher/proxy/watcher_proxy.cpp @@ -0,0 +1,42 @@ +/* + * 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 "watcher_proxy.h" + +#include +#include "parcel.h" +#include "message_parcel.h" +#include "watcher_utils.h" +#include "securec.h" + +namespace OHOS { +namespace init_param { +void WatcherProxy::OnParamerterChange(const std::string &name, const std::string &value) +{ + WATCHER_LOGD("WatcherProxy::OnParamerterChange %s %s", name.c_str(), value.c_str()); + MessageParcel data; + MessageParcel reply; + MessageOption option { MessageOption::TF_ASYNC }; + auto remote = Remote(); + WATCHER_CHECK(remote != nullptr, return, "Can not get remote"); + + data.WriteString(name); + data.WriteString(value); + int ret = remote->SendRequest(PARAM_CHANGE, data, reply, option); + WATCHER_CHECK(ret == ERR_OK, return, "Can not SendRequest for name %s", name.c_str()); + return; +} +} +} // namespace OHOS diff --git a/services/param/watcher/proxy/watcher_proxy.h b/services/param/watcher/proxy/watcher_proxy.h new file mode 100755 index 000000000..877d9f1b4 --- /dev/null +++ b/services/param/watcher/proxy/watcher_proxy.h @@ -0,0 +1,37 @@ +/* + * 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 STARTUP_WATCHER_PROXY_H +#define STARTUP_WATCHER_PROXY_H + +#include "iremote_proxy.h" +#include "iwatcher.h" + +namespace OHOS { +namespace init_param { +class WatcherProxy : public IRemoteProxy { +public: + explicit WatcherProxy(const sptr& impl) : IRemoteProxy(impl) {} + + virtual ~WatcherProxy() = default; + + void OnParamerterChange(const std::string &name, const std::string &value) override; + +private: + static inline BrokerDelegator delegator_; +}; +} +} // namespace OHOS +#endif // STARTUP_WATCHER_PROXY_H \ No newline at end of file diff --git a/services/param/watcher/sa_profile/3901.xml b/services/param/watcher/sa_profile/3901.xml new file mode 100755 index 000000000..2c45d21d9 --- /dev/null +++ b/services/param/watcher/sa_profile/3901.xml @@ -0,0 +1,24 @@ + + + + param_watcher + + 3901 + libparam_watcher.z.so + true + false + 1 + + diff --git a/services/param/watcher/sa_profile/BUILD.gn b/services/param/watcher/sa_profile/BUILD.gn new file mode 100755 index 000000000..7ca4643a1 --- /dev/null +++ b/services/param/watcher/sa_profile/BUILD.gn @@ -0,0 +1,20 @@ +# 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/ohos/sa_profile/sa_profile.gni") + +ohos_sa_profile("param_watcher_profile") { + sources = [ "3901.xml" ] + + part_name = "init" +} diff --git a/services/src/init_capability.c b/services/src/init_capability.c index 58884ef31..179c8ea2c 100644 --- a/services/src/init_capability.c +++ b/services/src/init_capability.c @@ -17,16 +17,12 @@ #include #include -#include -#include -#include #if defined OHOS_LITE && !defined __LINUX__ #include #else #include #endif #include -#include #include "init_log.h" #include "init_perms.h" @@ -112,7 +108,7 @@ static int GetServiceStringCaps(const cJSON* filedJ, Service* curServ) return SERVICE_FAILURE; } } - int ret = i == curServ->servPerm.capsCnt ? SERVICE_SUCCESS : SERVICE_FAILURE; + int ret = (i == curServ->servPerm.capsCnt ? SERVICE_SUCCESS : SERVICE_FAILURE); return ret; } @@ -156,7 +152,7 @@ int GetServiceCaps(const cJSON* curArrItem, Service* curServ) break; } curServ->servPerm.caps[i] = (unsigned int)cJSON_GetNumberValue(capJ); - if (curServ->servPerm.caps[i] > CAP_LAST_CAP && curServ->servPerm.caps[i] != FULL_CAP) { // CAP_LAST_CAP = 37 + if (curServ->servPerm.caps[i] > CAP_LAST_CAP && curServ->servPerm.caps[i] != FULL_CAP) { // resources will be released by function: ReleaseServiceMem INIT_LOGE("service=%s, caps = %d, error.", curServ->name, curServ->servPerm.caps[i]); return SERVICE_FAILURE; diff --git a/services/src/init_cmds.c b/services/src/init_cmds.c index d929e7976..40cdf8308 100644 --- a/services/src/init_cmds.c +++ b/services/src/init_cmds.c @@ -69,7 +69,6 @@ int GetParamValue(const char *symValue, char *paramValue, unsigned int paramLen) } char tmpName[MAX_PARAM_NAME_LEN] = {0}; char tmpValue[MAX_PARAM_VALUE_LEN] = {0}; - unsigned int tmpLen = 0; char *p = NULL; char *tmpptr = NULL; p = strchr(symValue, '$'); @@ -77,7 +76,7 @@ int GetParamValue(const char *symValue, char *paramValue, unsigned int paramLen) INIT_CHECK_RETURN_VALUE(strncpy_s(paramValue, paramLen, symValue, paramLen - 1) == EOK, -1); return 0; } - tmpLen = p - symValue; + unsigned int tmpLen = p - symValue; if (tmpLen > 0) { // copy '$' front string INIT_CHECK_RETURN_VALUE(strncpy_s(paramValue, paramLen, symValue, tmpLen) == EOK, -1); } @@ -94,7 +93,7 @@ int GetParamValue(const char *symValue, char *paramValue, unsigned int paramLen) INIT_LOGE("Parameter name longer than %d", MAX_PARAM_NAME_LEN); return -1; } - INIT_CHECK_RETURN_VALUE(strncpy_s(tmpName, MAX_PARAM_NAME_LEN, p, tmpLen) == EOK, -1); + INIT_CHECK_RETURN_VALUE(strncpy_s(tmpName, MAX_PARAM_NAME_LEN, p, tmpLen - 1) == EOK, -1); int ret = SystemReadParam(tmpName, tmpValue, &tmpLen); // get param if (ret != 0) { INIT_LOGE("Failed to read parameter \" %s \"", tmpName); @@ -133,22 +132,23 @@ struct CmdArgs* GetCmd(const char *cmdContent, const char *delim, int argsCount) argsCount = SPACES_CNT_IN_CMD_MAX; } ctx->argv = (char**)malloc(sizeof(char*) * (size_t)argsCount + 1); - INIT_CHECK(ctx->argv != NULL, FreeCmd(&ctx); return NULL); + INIT_CHECK(ctx->argv != NULL, FreeCmd(ctx); return NULL); char tmpCmd[MAX_BUFFER]; size_t cmdLength = strlen(cmdContent); if (cmdLength > MAX_BUFFER - 1) { INIT_LOGE("command line is too larget, should not bigger than %d. ignore...\n", MAX_BUFFER); - FreeCmd(&ctx); + FreeCmd(ctx); return NULL; } INIT_CHECK(strncpy_s(tmpCmd, MAX_BUFFER - 1, cmdContent, cmdLength) == EOK, - FreeCmd(&ctx); + FreeCmd(ctx); return NULL); tmpCmd[strlen(cmdContent)] = '\0'; char *p = tmpCmd; + INIT_CHECK_RETURN_VALUE(p != NULL, NULL); char *token = NULL; size_t allocSize = 0; @@ -162,9 +162,9 @@ struct CmdArgs* GetCmd(const char *cmdContent, const char *delim, int argsCount) // Make surce there is enough memory to store parameter value allocSize = (size_t)(cmdLength + MAX_PARAM_VALUE_LEN + 1); ctx->argv[ctx->argc] = calloc(sizeof(char), allocSize); - INIT_CHECK(ctx->argv[ctx->argc] != NULL, FreeCmd(&ctx); return NULL); + INIT_CHECK(ctx->argv[ctx->argc] != NULL, FreeCmd(ctx); return NULL); INIT_CHECK(GetParamValue(p, ctx->argv[ctx->argc], allocSize) == 0, - FreeCmd(&ctx); return NULL); + FreeCmd(ctx); return NULL); ctx->argc += 1; ctx->argv[ctx->argc] = NULL; return ctx; @@ -179,9 +179,9 @@ struct CmdArgs* GetCmd(const char *cmdContent, const char *delim, int argsCount) *token = '\0'; // replace it with '\0'; allocSize = (size_t)((token - p) + MAX_PARAM_VALUE_LEN + 1); ctx->argv[index] = calloc(sizeof(char), allocSize); - INIT_CHECK(ctx->argv[index] != NULL, FreeCmd(&ctx); return NULL); + INIT_CHECK(ctx->argv[index] != NULL, FreeCmd(ctx); return NULL); INIT_CHECK(GetParamValue(p, ctx->argv[index], allocSize) == 0, - FreeCmd(&ctx); return NULL); + FreeCmd(ctx); return NULL); p = token + 1; // skip '\0' // Skip lead whitespaces while (isspace(*p)) { @@ -197,9 +197,9 @@ struct CmdArgs* GetCmd(const char *cmdContent, const char *delim, int argsCount) size_t restSize = tmpCmd + cmdLength - p; allocSize = restSize + MAX_PARAM_VALUE_LEN + 1; ctx->argv[index] = calloc(sizeof(char), allocSize); - INIT_CHECK(ctx->argv[index] != NULL, FreeCmd(&ctx); return NULL); + INIT_CHECK(ctx->argv[index] != NULL, FreeCmd(ctx); return NULL); INIT_CHECK(GetParamValue(p, ctx->argv[index], allocSize) == 0, - FreeCmd(&ctx); return NULL); + FreeCmd(ctx); return NULL); ctx->argc = index + 1; } @@ -207,28 +207,25 @@ struct CmdArgs* GetCmd(const char *cmdContent, const char *delim, int argsCount) return ctx; } -void FreeCmd(struct CmdArgs **cmd) +void FreeCmd(struct CmdArgs *cmd) { - struct CmdArgs *tmpCmd = *cmd; - INIT_CHECK_ONLY_RETURN(tmpCmd != NULL); - for (int i = 0; i < tmpCmd->argc; ++i) { - INIT_CHECK(tmpCmd->argv[i] == NULL, free(tmpCmd->argv[i])); + INIT_CHECK_ONLY_RETURN(cmd != NULL); + for (int i = 0; i < cmd->argc; ++i) { + INIT_CHECK(cmd->argv[i] == NULL, free(cmd->argv[i])); } - INIT_CHECK(tmpCmd->argv == NULL, free(tmpCmd->argv)); - free(tmpCmd); + INIT_CHECK(cmd->argv == NULL, free(cmd->argv)); + free(cmd); return; } -#define EXTRACT_ARGS(cmdname, cmdContent, args) \ - struct CmdArgs *ctx = GetCmd(cmdContent, " ", args); \ - if ((ctx == NULL) || (ctx->argv == NULL) || (ctx->argc != args)) { \ - INIT_LOGE("Command \"%s\" with invalid arguments: %s", #cmdname, cmdContent); \ - goto out; \ - } \ - static void DoSetDomainname(const char *cmdContent, int maxArg) { - EXTRACT_ARGS(domainname, cmdContent, maxArg) + struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); + if ((ctx == NULL) || (ctx->argv == NULL) || (ctx->argc != maxArg)) { + INIT_LOGE("Command domainname with invalid arguments: %s", cmdContent); + goto out; + } + int fd = open("/proc/sys/kernel/domainname", O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, S_IRUSR | S_IWUSR); if (fd < 0) { @@ -239,19 +236,25 @@ static void DoSetDomainname(const char *cmdContent, int maxArg) size_t size = strlen(ctx->argv[0]); ssize_t n = write(fd, ctx->argv[0], size); if (n != (ssize_t)size) { - INIT_LOGE("DoSetHostname failed to write %s to \"/proc/sys/kernel/domainname\". err = %d", errno); + INIT_LOGE("DoSetHostname failed to write %s to \"/proc/sys/kernel/domainname\". err = %d", + ctx->argv[0], errno); } close(fd); out: - FreeCmd(&ctx); + FreeCmd(ctx); fd = -1; return; } static void DoSetHostname(const char *cmdContent, int maxArg) { - EXTRACT_ARGS(hostname, cmdContent, maxArg) + struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); + if ((ctx == NULL) || (ctx->argv == NULL) || (ctx->argc != maxArg)) { + INIT_LOGE("Command hostname with invalid arguments: %s", cmdContent); + goto out; + } + int fd = open("/proc/sys/kernel/hostname", O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, S_IRUSR | S_IWUSR); if (fd < 0) { @@ -262,12 +265,13 @@ static void DoSetHostname(const char *cmdContent, int maxArg) size_t size = strlen(ctx->argv[0]); ssize_t n = write(fd, ctx->argv[0], size); if (n != (ssize_t)size) { - INIT_LOGE("DoSetHostname failed to write %s to \"/proc/sys/kernel/hostname\". err = %d", errno); + INIT_LOGE("DoSetHostname failed to write %s to \"/proc/sys/kernel/hostname\". err = %d", + ctx->argv[0], errno); } close(fd); out: - FreeCmd(&ctx); + FreeCmd(ctx); fd = -1; return; } @@ -275,7 +279,12 @@ out: #ifndef OHOS_LITE static void DoIfup(const char *cmdContent, int maxArg) { - EXTRACT_ARGS(ifup, cmdContent, maxArg) + struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); + if ((ctx == NULL) || (ctx->argv == NULL) || (ctx->argc != maxArg)) { + INIT_LOGE("Command ifup with invalid arguments: %s", cmdContent); + goto out; + } + struct ifreq interface; if (strncpy_s(interface.ifr_name, IFNAMSIZ - 1, ctx->argv[0], strlen(ctx->argv[0])) != EOK) { INIT_LOGE("DoIfup failed to copy interface name"); @@ -303,7 +312,7 @@ static void DoIfup(const char *cmdContent, int maxArg) close(fd); out: - FreeCmd(&ctx); + FreeCmd(ctx); fd = -1; return; } @@ -332,11 +341,11 @@ static void DoSleep(const char *cmdContent, int maxArg) INIT_LOGI("Sleeping %d second(s)", sleepTime); sleep((unsigned int)sleepTime); out: - FreeCmd(&ctx); + FreeCmd(ctx); return; } -static void DoStart(const char* cmdContent, int maxArg) +static void DoStart(const char *cmdContent, int maxArg) { struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { @@ -344,9 +353,9 @@ static void DoStart(const char* cmdContent, int maxArg) goto out; } INIT_LOGD("DoStart %s", cmdContent); - StartServiceByName(cmdContent); + StartServiceByName(cmdContent, true); out: - FreeCmd(&ctx); + FreeCmd(ctx); return; } @@ -360,7 +369,7 @@ static void DoStop(const char* cmdContent, int maxArg) INIT_LOGD("DoStop %s", cmdContent); StopServiceByName(cmdContent); out: - FreeCmd(&ctx); + FreeCmd(ctx); return; } @@ -375,7 +384,7 @@ static void DoReset(const char* cmdContent, int maxArg) DoStop(cmdContent, maxArg); DoStart(cmdContent, maxArg); out: - FreeCmd(&ctx); + FreeCmd(ctx); return; } @@ -416,7 +425,7 @@ static void DoCopy(const char* cmdContent, int maxArg) } fsync(dstFd); out: - FreeCmd(&ctx); + FreeCmd(ctx); ctx = NULL; INIT_CHECK(srcFd < 0, close(srcFd); srcFd = -1); INIT_CHECK(dstFd < 0, close(dstFd); dstFd = -1); @@ -440,12 +449,12 @@ static void DoChown(const char* cmdContent, int maxArg) gid_t group = DecodeUid(ctx->argv[1]); INIT_ERROR_CHECK(group != (gid_t)-1, goto out, "DoChown invalid gid :%s.", ctx->argv[1]); - int pathPos = 2; + const int pathPos = 2; if (chown(ctx->argv[pathPos], owner, group) != 0) { INIT_LOGE("DoChown, failed for %s, err %d.", cmdContent, errno); } out: - FreeCmd(&ctx); + FreeCmd(ctx); return; } @@ -495,7 +504,7 @@ static void DoMkDir(const char* cmdContent, int maxArg) } } out: - FreeCmd(&ctx); + FreeCmd(ctx); return; } @@ -518,7 +527,7 @@ static void DoChmod(const char* cmdContent, int maxArg) INIT_LOGE("DoChmod, failed for %s, err %d.", cmdContent, errno); } out: - FreeCmd(&ctx); + FreeCmd(ctx); return; } @@ -675,7 +684,7 @@ static void DoMount(const char* cmdContent, int maxArg) #ifndef OHOS_LITE #define OPTIONS_SIZE 128u -static void DoInsmodInternal(const char *fileName, char *secondPtr, char *restPtr, int flags) +static void DoInsmodInternal(const char *fileName, const char *secondPtr, const char *restPtr, int flags) { char options[OPTIONS_SIZE] = {0}; if (flags == 0) { // '-f' option @@ -778,7 +787,54 @@ static void DoSetParam(const char* cmdContent, int maxArg) INIT_LOGE("param name: %s, value %s ", ctx->argv[0], ctx->argv[1]); SystemWriteParam(ctx->argv[0], ctx->argv[1]); out: - FreeCmd(&ctx); + FreeCmd(ctx); + return; +} + + +static void DoLoadPersistParams(const char *cmdContent, int maxArg) +{ + struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); + if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { + INIT_LOGE("DoLoadPersistParams invalid arguments :%s", cmdContent); + goto out; + } + INIT_LOGD("load persist params : %s", cmdContent); + LoadPersistParams(); +out: + FreeCmd(ctx); + return; +} + +static void DoTriggerCmd(const char *cmdContent, int maxArg) +{ + struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); + if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { + INIT_LOGE("DoTrigger invalid arguments :%s", cmdContent); + goto out; + } + INIT_LOGD("DoTrigger :%s", cmdContent); + DoTriggerExec(cmdContent); +out: + FreeCmd(ctx); + return; +} + +static void DoLoadDefaultParams(const char *cmdContent, int maxArg) +{ + struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); + if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { + INIT_LOGE("DoLoadDefaultParams invalid arguments :%s", cmdContent); + goto out; + } + int mode = 0; + if (strcmp(ctx->argv[1], "onlyadd") == 0) { + mode = LOAD_PARAM_ONLY_ADD; + } + INIT_LOGD("DoLoadDefaultParams args : %s %d", cmdContent, mode); + LoadDefaultParams(ctx->argv[0], mode); +out: + FreeCmd(ctx); return; } @@ -807,7 +863,7 @@ static void DoLoadCfg(const char *path, int maxArg) FILE *fp = NULL; size_t maxLoop = 0; CmdLine *cmdLine = NULL; - int len; + size_t len; INIT_CHECK_ONLY_RETURN(path != NULL); INIT_LOGI("DoLoadCfg cfg file %s", path); if (!CheckValidCfg(path)) { @@ -874,8 +930,8 @@ static void DoWrite(const char *cmdContent, int maxArg) goto out; } - size_t ret = write(fd, ctx->argv[1], strlen(ctx->argv[1])); - if (ret < 0) { + ssize_t ret = write(fd, ctx->argv[1], strlen(ctx->argv[1])); + if (ret < (ssize_t)0) { INIT_LOGE("DoWrite: write to file %s failed: %d", ctx->argv[0], errno); free(realPath); realPath = NULL; @@ -886,7 +942,7 @@ static void DoWrite(const char *cmdContent, int maxArg) realPath = NULL; close(fd); out: - FreeCmd(&ctx); + FreeCmd(ctx); return; } @@ -905,7 +961,7 @@ static void DoRmdir(const char *cmdContent, int maxArg) goto out; } out: - FreeCmd(&ctx); + FreeCmd(ctx); return; } @@ -918,49 +974,7 @@ static void DoRebootCmd(const char *cmdContent, int maxArg) } DoReboot(cmdContent); out: - FreeCmd(&ctx); - return; -} - -static void DoLoadPersistParams(const char *cmdContent, int maxArg) -{ - struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); - if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoLoadPersistParams invalid arguments :%s", cmdContent); - goto out; - } - INIT_LOGD("load persist params : %s", cmdContent); - LoadPersistParams(); -out: - FreeCmd(&ctx); - return; -} - -static void DoTriggerCmd(const char *cmdContent, int maxArg) -{ - struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); - if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoTrigger invalid arguments :%s", cmdContent); - goto out; - } - INIT_LOGD("DoTrigger :%s", cmdContent); - DoTriggerExec(cmdContent); -out: - FreeCmd(&ctx); - return; -} - -static void DoLoadDefaultParams(const char *cmdContent, int maxArg) -{ - struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); - if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoLoadDefaultParams invalid arguments :%s", cmdContent); - goto out; - } - INIT_LOGD("load persist params : %s", cmdContent); - LoadDefaultParams(cmdContent); -out: - FreeCmd(&ctx); + FreeCmd(ctx); return; } @@ -983,7 +997,7 @@ static void DoSetrlimit(const char *cmdContent, int maxArg) limit.rlim_cur = (rlim_t)atoi(ctx->argv[1]); limit.rlim_max = (rlim_t)atoi(ctx->argv[rlimMaxPos]); int rcs = -1; - for (unsigned int i = 0 ; i < sizeof(resource) / sizeof(char*); ++i) { + for (unsigned int i = 0; i < sizeof(resource) / sizeof(char*); ++i) { if (strcmp(ctx->argv[0], resource[i]) == 0) { rcs = (int)i; } @@ -998,7 +1012,7 @@ static void DoSetrlimit(const char *cmdContent, int maxArg) goto out; } out: - FreeCmd(&ctx); + FreeCmd(ctx); return; } @@ -1016,7 +1030,7 @@ static void DoRm(const char *cmdContent, int maxArg) goto out; } out: - FreeCmd(&ctx); + FreeCmd(ctx); return; } @@ -1034,7 +1048,7 @@ static void DoExport(const char *cmdContent, int maxArg) goto out; } out: - FreeCmd(&ctx); + FreeCmd(ctx); return; } @@ -1060,7 +1074,7 @@ static void DoExec(const char *cmdContent, int maxArg) if (ret == -1) { INIT_LOGE("DoExec: execute \"%s\" failed: %d.", cmdContent, errno); } - FreeCmd(&ctx); + FreeCmd(ctx); _exit(0x7f); } return; @@ -1082,7 +1096,7 @@ static void DoSymlink(const char *cmdContent, int maxArg) goto out; } out: - FreeCmd(&ctx); + FreeCmd(ctx); return; } @@ -1133,7 +1147,7 @@ static void DoMakeNode(const char *cmdContent, int maxArg) goto out; } out: - FreeCmd(&ctx); + FreeCmd(ctx); return; } @@ -1154,7 +1168,7 @@ static void DoMakeDevice(const char *cmdContent, int maxArg) goto out; } out: - FreeCmd(&ctx); + FreeCmd(ctx); return; } #endif // __LITEOS__ @@ -1194,7 +1208,7 @@ static const struct CmdTable CMD_TABLE[] = { { "insmod ", 10, DoInsmod }, { "setparam ", 2, DoSetParam }, { "load_persist_params ", 1, DoLoadPersistParams }, - { "load_param ", 1, DoLoadDefaultParams }, + { "load_param ", 2, DoLoadDefaultParams }, { "ifup ", 1, DoIfup }, #endif { "stop ", 1, DoStop }, @@ -1226,21 +1240,6 @@ void DoCmdByName(const char *name, const char *cmdContent) } } -const char *GetMatchCmd(const char *cmdStr) -{ - if (cmdStr == NULL) { - return NULL; - } - size_t supportCmdCnt = sizeof(CMD_TABLE) / sizeof(CMD_TABLE[0]); - for (size_t i = 0; i < supportCmdCnt; ++i) { - size_t curCmdNameLen = strlen(CMD_TABLE[i].name); - if (strncmp(CMD_TABLE[i].name, cmdStr, curCmdNameLen) == 0) { - return CMD_TABLE[i].name; - } - } - return NULL; -} - void ParseCmdLine(const char* cmdStr, CmdLine* resCmd) { size_t cmdLineLen = 0; @@ -1276,3 +1275,27 @@ void ParseCmdLine(const char* cmdStr, CmdLine* resCmd) } } +const char *GetMatchCmd(const char *cmdStr, unsigned int *index) +{ + if (cmdStr == NULL || index == NULL) { + return NULL; + } + size_t supportCmdCnt = sizeof(CMD_TABLE) / sizeof(CMD_TABLE[0]); + for (size_t i = 0; i < supportCmdCnt; ++i) { + size_t curCmdNameLen = strlen(CMD_TABLE[i].name); + if (strncmp(CMD_TABLE[i].name, cmdStr, curCmdNameLen) == 0) { + *index = (unsigned int)i; + return CMD_TABLE[i].name; + } + } + return NULL; +} + +const char *GetCmdKey(unsigned int index) +{ + size_t supportCmdCnt = sizeof(CMD_TABLE) / sizeof(CMD_TABLE[0]); + if (index >= supportCmdCnt) { + return NULL; + } + return CMD_TABLE[index].name; +} \ No newline at end of file diff --git a/services/src/init_import.c b/services/src/init_import.c index 36d031fd4..319c26516 100644 --- a/services/src/init_import.c +++ b/services/src/init_import.c @@ -40,7 +40,7 @@ static int ExtractCfgFile(char **cfgFile, const char *content) } #endif -void ParseAllImports(cJSON *root) +void ParseAllImports(const cJSON *root) { cJSON *importAttr = cJSON_GetObjectItemCaseSensitive(root, "import"); char *cfgFile = NULL; @@ -79,6 +79,6 @@ void ParseAllImports(cJSON *root) free(cfgFile); cfgFile = NULL; } - INIT_LOGD("parse import file done"); + INIT_LOGD("parse import file done"); return; } diff --git a/services/src/init_jobs.c b/services/src/init_jobs.c index 563a5065d..c1b7b0b74 100644 --- a/services/src/init_jobs.c +++ b/services/src/init_jobs.c @@ -23,17 +23,10 @@ #include "init_log.h" #include "securec.h" - #define JOBS_ARR_NAME_IN_JSON "jobs" #define CMDS_ARR_NAME_IN_JSON "cmds" #define MAX_JOBS_COUNT 100 -// static const char* g_supportedJobs[] = { -// "pre-init", -// "init", -// "post-init", -// }; - static Job* g_jobs = NULL; static int g_jobCnt = 0; @@ -168,8 +161,6 @@ void DoJob(const char* jobName) for (int j = 0; j < g_jobs[i].cmdLinesCnt; ++j) { DoCmd(&(cmdLines[j])); } - // Walk through all jobs - // break; } } } diff --git a/services/src/init_read_cfg.c b/services/src/init_read_cfg.c index 336820ea1..732f7db87 100644 --- a/services/src/init_read_cfg.c +++ b/services/src/init_read_cfg.c @@ -42,13 +42,13 @@ #endif #define FILE_NAME_MAX_SIZE 100 -static void ParseInitCfgContents(cJSON *root) +static void ParseInitCfgContents(const cJSON *root) { if (root == NULL) { INIT_LOGE("ParseInitCfgContents root is NULL"); return; } - // parse services + // parse services ParseAllServices(root); #ifdef OHOS_LITE // parse jobs @@ -125,7 +125,9 @@ void InitReadCfg() { #ifndef OHOS_LITE InitParamService(); - LoadDefaultParams("/system/etc/ohos.para"); + LoadDefaultParams("/system/etc/param/ohos_const", LOAD_PARAM_NORMAL); + LoadDefaultParams("/vendor/etc/param", LOAD_PARAM_NORMAL); + LoadDefaultParams("/system/etc/param", LOAD_PARAM_ONLY_ADD); #endif ParseInitCfg(INIT_CONFIGURATION_FILE); ParseOtherCfgs(); @@ -154,11 +156,11 @@ void InitReadCfg() #endif ReleaseAllJobs(); #else - PostTrigger(EVENT_BOOT, "pre-init", strlen("pre-init")); + PostTrigger(EVENT_TRIGGER_BOOT, "pre-init", strlen("pre-init")); - PostTrigger(EVENT_BOOT, "init", strlen("init")); + PostTrigger(EVENT_TRIGGER_BOOT, "init", strlen("init")); - PostTrigger(EVENT_BOOT, "post-init", strlen("post-init")); + PostTrigger(EVENT_TRIGGER_BOOT, "post-init", strlen("post-init")); #endif } diff --git a/services/src/init_reboot.c b/services/src/init_reboot.c index e65e9c65d..e80e3e572 100644 --- a/services/src/init_reboot.c +++ b/services/src/init_reboot.c @@ -37,7 +37,7 @@ struct RBMiscUpdateMessage { char update[MAX_UPDATE_SIZE]; }; -static bool RBMiscWriteUpdaterMessage(const char *path, struct RBMiscUpdateMessage *boot) +static bool RBMiscWriteUpdaterMessage(const char *path, const struct RBMiscUpdateMessage *boot) { if (path == NULL || boot == NULL) { INIT_LOGE("path or boot is NULL."); @@ -129,103 +129,86 @@ static int GetMountStatusForMountPoint(const char *mountPoint) return 0; } -static int UpdateUpdaterStatus(const char *valueData) +static int CheckAndRebootToUpdater(const char *valueData, const char *cmd, const char *cmdExt, const char *boot) { + // "updater" or "updater:" const char *miscFile = "/dev/block/platform/soc/10100000.himci.eMMC/by-name/misc"; struct RBMiscUpdateMessage msg; - bool ret = RBMiscReadUpdaterMessage(miscFile, &msg); - if (!ret) { - INIT_LOGE("RBMiscReadUpdaterMessage error."); - return -1; - } - if (snprintf_s(msg.command, MAX_COMMAND_SIZE, MAX_COMMAND_SIZE - 1, "%s", "boot_updater") == -1) { - INIT_LOGE("RBMiscWriteUpdaterMessage error"); - return -1; - } - if (strlen(valueData) > strlen("updater:") && strncmp(valueData, "updater:", strlen("updater:")) == 0) { - if (snprintf_s(msg.update, MAX_UPDATE_SIZE, MAX_UPDATE_SIZE - 1, "%s", valueData + strlen("updater:")) == -1) { - INIT_LOGE("RBMiscWriteUpdaterMessage error"); - return -1; - } - ret = RBMiscWriteUpdaterMessage(miscFile, &msg); - if (ret != true) { - INIT_LOGE("RBMiscWriteUpdaterMessage error"); - return -1; - } - } else if (strlen(valueData) == strlen("updater") && strncmp(valueData, "updater", strlen("updater")) == 0) { - ret = RBMiscWriteUpdaterMessage(miscFile, &msg); - if (ret != true) { - INIT_LOGE("RBMiscWriteUpdaterMessage error"); - return -1; - } - } else { - return -1; + bool bRet = RBMiscReadUpdaterMessage(miscFile, &msg); + INIT_ERROR_CHECK(bRet, return -1, "Failed to get misc info for %s.", cmd); + + int ret = snprintf_s(msg.command, MAX_COMMAND_SIZE, MAX_COMMAND_SIZE - 1, "%s", boot); + INIT_ERROR_CHECK(ret > 0, return -1, "Failed to format cmd for %s.", cmd); + msg.command[MAX_COMMAND_SIZE - 1] = 0; + + if (strncmp(valueData, cmdExt, strlen(cmdExt)) == 0) { + const char *p = valueData + strlen(cmdExt); + ret = snprintf_s(msg.update, MAX_UPDATE_SIZE, MAX_UPDATE_SIZE - 1, "%s", p); + INIT_ERROR_CHECK(ret > 0, return -1, "Failed to format param for %s.", cmd); + msg.update[MAX_UPDATE_SIZE - 1] = 0; } - return 0; -} -static int DoRebootCore(const char *valueData) -{ - if (valueData == NULL) { - reboot(RB_AUTOBOOT); - return 0; - } else if (strncmp(valueData, "shutdown", strlen("shutdown")) == 0) { - reboot(RB_POWER_OFF); - return 0; - } else if (strncmp(valueData, "updater", strlen("updater")) == 0) { - int ret = UpdateUpdaterStatus(valueData); - if (ret == 0) { - reboot(RB_AUTOBOOT); - return 0; - } - } else { - return -1; + if (RBMiscWriteUpdaterMessage(miscFile, &msg)) { + return reboot(RB_AUTOBOOT); } - return 0; + return -1; } +static const char *g_cmdParams[] = { + "shutdown", "updater", "updater:", "flashing", "flashing:", "NoArgument", "bootloader" +}; + void DoReboot(const char *value) { - if (value == NULL) { + if (value == NULL || strlen(value) > MAX_VALUE_LENGTH) { INIT_LOGE("DoReboot value = NULL"); return; } - INIT_LOGI("DoReboot value = %s", value); - - if (strlen(value) > MAX_VALUE_LENGTH || strlen(value) < strlen("reboot") || strlen(value) == strlen("reboot,")) { - INIT_LOGE("DoReboot reboot value error, value = %s.", value); - return; - } const char *valueData = NULL; - if (strncmp(value, "reboot,", strlen("reboot,")) == 0) { - valueData = value + strlen("reboot,"); - } else if (strlen(value) < strlen("reboot,") && strncmp(value, "reboot", strlen("reboot")) == 0) { + if (strcmp(value, "reboot") == 0) { valueData = NULL; - } else { + } else if (strncmp(value, "reboot,", strlen("reboot,")) != 0) { INIT_LOGE("DoReboot reboot value = %s, must started with reboot ,error.", value); return; + } else { + valueData = value + strlen("reboot,"); } - if (valueData != NULL && strncmp(valueData, "shutdown", strlen("shutdown")) != 0 && - strncmp(valueData, "updater:", strlen("updater:")) != 0 && - strncmp(valueData, "updater", strlen("updater")) != 0) { - INIT_LOGE("DoReboot value = %s, parameters error.", value); - return; + if (valueData != NULL) { + size_t i = 0; + for (; i < sizeof(g_cmdParams) / sizeof(g_cmdParams[0]); i++) { + if (strncmp(valueData, g_cmdParams[i], strlen(g_cmdParams[i])) == 0) { + break; + } + } + if (i >= sizeof(g_cmdParams) / sizeof(g_cmdParams[0])) { + INIT_LOGE("DoReboot value = %s, parameters error.", value); + return; + } } + StopAllServicesBeforeReboot(); sync(); - if (GetMountStatusForMountPoint("/vendor") != 0) { - if (umount("/vendor") != 0) { - INIT_LOGE("DoReboot umount vendor failed! errno = %d.", errno); - } + if (GetMountStatusForMountPoint("/vendor") != 0 && umount("/vendor") != 0) { + INIT_LOGE("DoReboot umount vendor failed! errno = %d.", errno); } - if (GetMountStatusForMountPoint("/data") != 0) { - if (umount("/data") != 0) { - INIT_LOGE("DoReboot umount data failed! errno = %d.", errno); - } + if (GetMountStatusForMountPoint("/data") != 0 && umount("/data") != 0) { + INIT_LOGE("DoReboot umount data failed! errno = %d.", errno); } - int ret = DoRebootCore(valueData); - if (ret != 0) { - INIT_LOGE("DoReboot value = %s, error.", value); + + INIT_LOGI("DoReboot value = %s valueData %s", value, valueData); + // "shutdown" + int ret = 0; + if (valueData == NULL) { + ret = reboot(RB_AUTOBOOT); + } else if (strcmp(valueData, "shutdown") == 0) { + ret = reboot(RB_POWER_OFF); + } else if (strcmp(valueData, "bootloader") == 0) { + ret = reboot(RB_POWER_OFF); + } else if (strncmp(valueData, "updater", strlen("updater")) == 0) { + ret = CheckAndRebootToUpdater(valueData, "updater", "updater:", "boot_updater"); + } else if (strncmp(valueData, "flashing", strlen("flashing")) == 0) { + ret = CheckAndRebootToUpdater(valueData, "flashing", "flashing:", "boot_flashing"); } + INIT_LOGE("DoReboot value = %s %s.", value, (ret == 0) ? "success" : "fail"); return; } diff --git a/services/src/init_service.c b/services/src/init_service.c index 248c1962d..e9b43082b 100644 --- a/services/src/init_service.c +++ b/services/src/init_service.c @@ -15,7 +15,6 @@ #include "init_service.h" -#include #include #include #include @@ -141,7 +140,7 @@ static void OpenConsole() ioctl(fd, TIOCSCTTY, 0); dup2(fd, 0); dup2(fd, 1); - dup2(fd, 2); + dup2(fd, 2); // Redirect fd to 0, 1, 2 close(fd); } else { INIT_LOGE("Open /dev/console failed. err = %d", errno); @@ -151,55 +150,32 @@ static void OpenConsole() int ServiceStart(Service *service) { - if (service == NULL) { - INIT_LOGE("start service failed! null ptr."); - return SERVICE_FAILURE; - } - if (service->pid > 0) { - INIT_LOGI("service : %s had started already.", service->name); - return SERVICE_SUCCESS; - } + INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "start service failed! null ptr."); + INIT_INFO_CHECK(service->pid <= 0, return SERVICE_SUCCESS, "service : %s had started already.", service->name); if (service->attribute & SERVICE_ATTR_INVALID) { INIT_LOGE("start service %s invalid.", service->name); return SERVICE_FAILURE; } - if (service->pathArgs == NULL) { - INIT_LOGE("start service pathArgs is NULL."); - return SERVICE_FAILURE; - } + INIT_ERROR_CHECK(service->pathArgs != NULL, return SERVICE_FAILURE, "start service pathArgs is NULL."); struct stat pathStat = {0}; service->attribute &= (~(SERVICE_ATTR_NEED_RESTART | SERVICE_ATTR_NEED_STOP)); - if (stat(service->pathArgs[0], &pathStat) != 0) { - service->attribute |= SERVICE_ATTR_INVALID; - INIT_LOGE("start service %s invalid, please check %s.",\ - service->name, service->pathArgs[0]); - return SERVICE_FAILURE; - } - int ret = 0; + INIT_ERROR_CHECK(stat(service->pathArgs[0], &pathStat) == 0, service->attribute |= SERVICE_ATTR_INVALID; + return SERVICE_FAILURE, "start service %s invalid, please check %s.", service->name, service->pathArgs[0]); int pid = fork(); if (pid == 0) { if (service->socketCfg != NULL) { // start socket service INIT_LOGI("Create socket "); - ret = DoCreateSocket(service->socketCfg); - if (ret < 0) { - INIT_LOGE("DoCreateSocket failed. "); - _exit(0x7f); // 0x7f: user specified - } + INIT_ERROR_CHECK(DoCreateSocket(service->socketCfg) >= 0, _exit(0x7f), "DoCreateSocket failed. "); } if (service->attribute & SERVICE_ATTR_CONSOLE) { OpenConsole(); } - // permissions - if (SetPerms(service) != SERVICE_SUCCESS) { - INIT_LOGE("service %s exit! set perms failed! err %d.", service->name, errno); - _exit(0x7f); // 0x7f: user specified - } - char pidString[MAX_PID_STRING_LENGTH]; // writepid + INIT_ERROR_CHECK(SetPerms(service) == SERVICE_SUCCESS, _exit(0x7f), + "service %s exit! set perms failed! err %d.", service->name, errno); + char pidString[MAX_PID_STRING_LENGTH]; pid_t childPid = getpid(); - if (snprintf_s(pidString, MAX_PID_STRING_LENGTH, MAX_PID_STRING_LENGTH - 1, "%d", childPid) < 0) { - INIT_LOGE("start service writepid sprintf failed."); - _exit(0x7f); // 0x7f: user specified - } + INIT_ERROR_CHECK(snprintf_s(pidString, MAX_PID_STRING_LENGTH, MAX_PID_STRING_LENGTH - 1, "%d", childPid) >= 0, + _exit(0x7f), "start service writepid sprintf failed."); for (int i = 0; i < MAX_WRITEPID_FILES; i++) { if (service->writepidFiles[i] == NULL) { continue; @@ -209,53 +185,38 @@ int ServiceStart(Service *service) continue; } FILE *fd = fopen(realPath, "wb"); - if (fd == NULL) { - INIT_LOGE("start service writepidFiles %s invalid.", service->writepidFiles[i]); - free(realPath); - realPath = NULL; - continue; - } - if (fwrite(pidString, 1, strlen(pidString), fd) != strlen(pidString)) { - INIT_LOGE("start service writepid error.file:%s pid:%s", service->writepidFiles[i], pidString); - } free(realPath); realPath = NULL; + INIT_ERROR_CHECK(fd != NULL, continue, "writepidFiles %s invalid.", service->writepidFiles[i]); + INIT_CHECK_ONLY_ELOG(fwrite(pidString, 1, strlen(pidString), fd) == strlen(pidString), + "writepid error.file:%s pid:%s", service->writepidFiles[i], pidString); fclose(fd); - INIT_LOGE("ServiceStart writepid filename=%s, childPid=%s, ok", service->writepidFiles[i], - pidString); + INIT_LOGI("writepid filename=%s, childPid=%s, ok", service->writepidFiles[i], pidString); } - INIT_LOGI("service->name is %s ", service->name); #ifndef OHOS_LITE if (service->importance != 0) { - if (setpriority(PRIO_PROCESS, 0, service->importance) != 0) { - INIT_LOGE("setpriority failed for %s, importance = %d", service->name, service->importance); - _exit(0x7f); // 0x7f: user specified - } + INIT_ERROR_CHECK(setpriority(PRIO_PROCESS, 0, service->importance) == 0, _exit(0x7f), + "setpriority failed for %s, importance = %d", service->name, service->importance); } // L2 Can not be reset env - if (execv(service->pathArgs[0], service->pathArgs) != 0) { - INIT_LOGE("service %s execve failed! err %d.", service->name, errno); - } + INIT_CHECK_ONLY_ELOG(execv(service->pathArgs[0], service->pathArgs) == 0, + "service %s execve failed! err %d.", service->name, errno); #else char* env[] = {"LD_LIBRARY_PATH=/storage/app/libs", NULL}; - if (execve(service->pathArgs[0], service->pathArgs, env) != 0) { - INIT_LOGE("service %s execve failed! err %d.", service->name, errno); - } + INIT_CHECK_ONLY_ELOG(execve(service->pathArgs[0], service->pathArgs, env) == 0, + "service %s execve failed! err %d.", service->name, errno); #endif - _exit(0x7f); // 0x7f: user specified } else if (pid < 0) { INIT_LOGE("start service %s fork failed!", service->name); return SERVICE_FAILURE; } - service->pid = pid; #ifndef OHOS_LITE char paramName[PARAM_NAME_LEN_MAX] = {0}; - if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "init.svc.%s", service->name) < 0) { - INIT_LOGE("snprintf_s paramName error %d ", errno); - } + INIT_CHECK_ONLY_ELOG(snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "init.svc.%s", + service->name) >= 0, "snprintf_s paramName error %d ", errno); SystemWriteParam(paramName, "running"); #endif return SERVICE_SUCCESS; @@ -338,7 +299,6 @@ void ServiceReap(Service *service) INIT_LOGE("reap service failed! null ptr."); return; } - service->pid = -1; #ifndef OHOS_LITE char paramName[PARAM_NAME_LEN_MAX] = {0}; @@ -351,14 +311,12 @@ void ServiceReap(Service *service) INIT_LOGE("ServiceReap service %s invalid.", service->name); return; } - // stopped by system-init itself, no need to restart even if it is not one-shot service if (service->attribute & SERVICE_ATTR_NEED_STOP) { service->attribute &= (~SERVICE_ATTR_NEED_STOP); service->crashCnt = 0; return; } - // for one-shot service if (service->attribute & SERVICE_ATTR_ONCE) { // no need to restart @@ -366,9 +324,7 @@ void ServiceReap(Service *service) service->attribute &= (~SERVICE_ATTR_NEED_STOP); return; } - // the service could be restart even if it is one-shot service } - // the service that does not need to be restarted restarts, indicating that it has crashed if (!(service->attribute & SERVICE_ATTR_NEED_RESTART)) { // crash time and count check @@ -387,20 +343,11 @@ void ServiceReap(Service *service) } } } - CheckCritical(service); - int ret = 0; if (service->onRestart != NULL) { - ret = ExecRestartCmd(service); - if (ret != SERVICE_SUCCESS) { - INIT_LOGE("SetOnRestart fail "); - } + INIT_CHECK_ONLY_ELOG(ExecRestartCmd(service) == SERVICE_SUCCESS, "SetOnRestart fail "); } - ret = ServiceStart(service); - if (ret != SERVICE_SUCCESS) { - INIT_LOGE("reap service %s start failed!", service->name); - } - + INIT_CHECK_ONLY_ELOG(ServiceStart(service) == SERVICE_SUCCESS, "reap service %s start failed!", service->name); service->attribute &= (~SERVICE_ATTR_NEED_RESTART); } diff --git a/services/src/init_service_manager.c b/services/src/init_service_manager.c index 8079fbe8c..f22e8acd9 100644 --- a/services/src/init_service_manager.c +++ b/services/src/init_service_manager.c @@ -158,7 +158,6 @@ static int IsForbidden(const char* fieldStr) } #endif -// TODO: move this function to common files static cJSON* GetArrItem(const cJSON* fileRoot, int* arrSize, const char* arrName) { cJSON* arrItem = cJSON_GetObjectItemCaseSensitive(fileRoot, arrName); @@ -290,9 +289,7 @@ static int GetGidArray(const cJSON *curArrItem, Service *curServ) // gid } curServ->servPerm.gIDArray[i] = gID; } - if (i == gIDCnt) { - return SERVICE_SUCCESS; - } + INIT_CHECK_RETURN_VALUE(i != gIDCnt, SERVICE_SUCCESS); for (i = 0; i < gIDCnt; ++i) { cJSON *item = cJSON_GetArrayItem(filedJ, i); if (item == NULL) { @@ -308,7 +305,7 @@ static int GetGidArray(const cJSON *curArrItem, Service *curServ) // gid } curServ->servPerm.gIDArray[i] = gID; } - int ret = i == gIDCnt ? SERVICE_SUCCESS : SERVICE_FAILURE; + int ret = ((i == gIDCnt) ? SERVICE_SUCCESS : SERVICE_FAILURE); return ret; } @@ -316,19 +313,19 @@ static int GetServicePathAndArgs(const cJSON* curArrItem, Service* curServ) { cJSON* pathItem = cJSON_GetObjectItem(curArrItem, "path"); if (!cJSON_IsArray(pathItem)) { - INIT_LOGE("GetServicePathAndArgs path item not found or not a array"); + INIT_LOGE("Path item not found or not a array"); return SERVICE_FAILURE; } int arrSize = cJSON_GetArraySize(pathItem); if (arrSize <= 0 || arrSize > MAX_PATH_ARGS_CNT) { // array size invalid - INIT_LOGE("GetServicePathAndArgs arrSize = %d, error", arrSize); + INIT_LOGE("Array size = %d is wrong", arrSize); return SERVICE_FAILURE; } curServ->pathArgs = (char**)malloc((arrSize + 1) * sizeof(char*)); if (curServ->pathArgs == NULL) { - INIT_LOGE("GetServicePathAndArgs malloc 1 error"); + INIT_LOGE("Current path is null."); return SERVICE_FAILURE; } for (int i = 0; i < arrSize + 1; ++i) { @@ -341,16 +338,16 @@ static int GetServicePathAndArgs(const cJSON* curArrItem, Service* curServ) if (curParam == NULL || strlen(curParam) > MAX_ONE_ARG_LEN) { // resources will be released by function: ReleaseServiceMem if (curParam == NULL) { - INIT_LOGE("GetServicePathAndArgs curParam == NULL, error"); + INIT_LOGE("Current param is null."); } else { - INIT_LOGE("GetServicePathAndArgs strlen = %d, error", strlen(curParam)); + INIT_LOGE("Length of current param is too long."); } return SERVICE_FAILURE; } if (i == 0 && IsForbidden(curParam)) { // resources will be released by function: ReleaseServiceMem - INIT_LOGE("GetServicePathAndArgs i == 0 && IsForbidden, error"); + INIT_LOGE("Service %s is forbidden.", curServ->name); return SERVICE_FAILURE; } @@ -358,13 +355,13 @@ static int GetServicePathAndArgs(const cJSON* curArrItem, Service* curServ) curServ->pathArgs[i] = (char*)malloc(paramLen + 1); if (curServ->pathArgs[i] == NULL) { // resources will be released by function: ReleaseServiceMem - INIT_LOGE("GetServicePathAndArgs i == 0 && IsForbidden, error"); + INIT_LOGE("Service %s path is null.", curServ->name); return SERVICE_FAILURE; } if (memcpy_s(curServ->pathArgs[i], paramLen + 1, curParam, paramLen) != EOK) { // resources will be released by function: ReleaseServiceMem - INIT_LOGE("GetServicePathAndArgs malloc 2 error."); + INIT_LOGE("memcpy_s failed."); return SERVICE_FAILURE; } curServ->pathArgs[i][paramLen] = '\0'; @@ -382,7 +379,7 @@ static int GetImportantValue(int value, Service *curServ) if (value >= MIN_IMPORTANT_LEVEL && value <= MAX_IMPORTANT_LEVEL) { // -20~19 curServ->importance = value; } else { - INIT_LOGE("importance level = %d, is not between -20 and 19, error", value); + INIT_LOGE("Importance level = %d, is not between -20 and 19, error", value); return SERVICE_FAILURE; } #endif @@ -401,7 +398,7 @@ static int GetServiceNumber(const cJSON* curArrItem, Service* curServ, const cha } if (!cJSON_IsNumber(filedJ)) { - INIT_LOGE("%s is null or is not a number, error.service name is %s", targetField, curServ->name); + INIT_LOGE("%s is null or is not a number, service name is %s", targetField, curServ->name); return SERVICE_FAILURE; } @@ -409,7 +406,7 @@ static int GetServiceNumber(const cJSON* curArrItem, Service* curServ, const cha // importance value allow < 0 if (strncmp(targetField, IMPORTANT_STR_IN_CFG, strlen(IMPORTANT_STR_IN_CFG)) != 0) { if (value < 0) { - INIT_LOGE("value = %d, error.service name is %s", value, curServ->name); + INIT_LOGE("Service %s value = %d is wrong", curServ->name, value); return SERVICE_FAILURE; } } @@ -436,7 +433,7 @@ static int GetServiceNumber(const cJSON* curArrItem, Service* curServ, const cha curServ->attribute |= SERVICE_ATTR_CONSOLE; } } else { - INIT_LOGE("item = %s, not expected, error.service name is %s", targetField, curServ->name); + INIT_LOGE("Item = %s, not expected, error.service name is %s", targetField, curServ->name); return SERVICE_FAILURE; } return SERVICE_SUCCESS; @@ -454,9 +451,9 @@ static int GetUidStringNumber(const cJSON *curArrItem, Service *curServ) if (fieldStr == NULL) { return SERVICE_FAILURE; } - int uID = DecodeUid(fieldStr); - if (uID < 0) { - INIT_LOGE("GetUidStringNumber, DecodeUid %s error.", fieldStr); + uid_t uID = DecodeUid(fieldStr); + if (uID == (uid_t)-1) { + INIT_LOGE("Decode uid %s error.", fieldStr); return SERVICE_FAILURE; } curServ->servPerm.uID = uID; @@ -466,14 +463,14 @@ static int GetUidStringNumber(const cJSON *curArrItem, Service *curServ) if (cJSON_IsNumber(filedJ)) { int uID = (int)cJSON_GetNumberValue(filedJ); if (uID < 0) { - INIT_LOGE("GetUidStringNumber, uID = %d error.", uID); + INIT_LOGE("Uid = %d error.", uID); return SERVICE_FAILURE; } curServ->servPerm.uID = uID; return SERVICE_SUCCESS; } - INIT_LOGE("GetUidStringNumber, this uid is neither a string nor a number, error."); + INIT_LOGE("This uid is neither a string nor a number, error."); return SERVICE_FAILURE; } @@ -486,8 +483,8 @@ static int ParseServiceSocket(char **opt, const int optNum, struct ServiceSocket return -1; } sockopt->type = - strncmp(opt[SERVICE_SOCK_TYPE], "stream", strlen(opt[SERVICE_SOCK_TYPE])) == 0 ? SOCK_STREAM : - (strncmp(opt[SERVICE_SOCK_TYPE], "dgram", strlen(opt[SERVICE_SOCK_TYPE])) == 0 ? SOCK_DGRAM : SOCK_SEQPACKET); + ((strncmp(opt[SERVICE_SOCK_TYPE], "stream", strlen(opt[SERVICE_SOCK_TYPE])) == 0) ? SOCK_STREAM : + ((strncmp(opt[SERVICE_SOCK_TYPE], "dgram", strlen(opt[SERVICE_SOCK_TYPE])) == 0) ? SOCK_DGRAM : SOCK_SEQPACKET)); if (opt[SERVICE_SOCK_PERM] == NULL) { return -1; @@ -496,23 +493,24 @@ static int ParseServiceSocket(char **opt, const int optNum, struct ServiceSocket if (opt[SERVICE_SOCK_UID] == NULL) { return -1; } - int uuid = DecodeUid(opt[SERVICE_SOCK_UID]); - if (uuid < 0) { + uid_t uid = DecodeUid(opt[SERVICE_SOCK_UID]); + if (uid == (uid_t)-1) { return -1; } - sockopt->uid = uuid; + sockopt->uid = uid; if (opt[SERVICE_SOCK_GID] == NULL) { return -1; } - int ggid = DecodeUid(opt[SERVICE_SOCK_GID]); - if (ggid < 0) { + gid_t gid = DecodeUid(opt[SERVICE_SOCK_GID]); + if (gid == (gid_t)-1) { return -1; } - sockopt->gid = ggid; + sockopt->gid = gid ; if (opt[SERVICE_SOCK_SETOPT] == NULL) { return -1; } - sockopt->passcred = strncmp(opt[SERVICE_SOCK_SETOPT], "passcred", strlen(opt[SERVICE_SOCK_SETOPT])) == 0 ? true : false; + sockopt->passcred = ((strncmp(opt[SERVICE_SOCK_SETOPT], "passcred", + strlen(opt[SERVICE_SOCK_SETOPT])) == 0) ? true : false); if (opt[SERVICE_SOCK_NAME] == NULL) { return -1; } @@ -533,7 +531,7 @@ static int ParseServiceSocket(char **opt, const int optNum, struct ServiceSocket static void FreeServiceSocket(struct ServiceSocket *sockopt) { - if (!sockopt) { + if (sockopt == NULL) { return; } struct ServiceSocket *tmpSock = NULL; @@ -548,6 +546,7 @@ static void FreeServiceSocket(struct ServiceSocket *sockopt) } return; } + static int GetServiceSocket(const cJSON* curArrItem, Service* curServ) { cJSON* filedJ = cJSON_GetObjectItem(curArrItem, "socket"); @@ -566,13 +565,13 @@ static int GetServiceSocket(const cJSON* curArrItem, Service* curServ) return SERVICE_FAILURE; } char *sockStr = cJSON_GetStringValue(sockJ); - char *tmpStr[SOCK_OPT_NUMS] = {NULL,}; + char *tmpStr[SOCK_OPT_NUMS] = {NULL}; int num = SplitString(sockStr, tmpStr, SOCK_OPT_NUMS); if (num != SOCK_OPT_NUMS) { return SERVICE_FAILURE; } struct ServiceSocket *socktmp = (struct ServiceSocket *)calloc(1, sizeof(struct ServiceSocket)); - if (!socktmp) { + if (socktmp == NULL) { return SERVICE_FAILURE; } int ret = ParseServiceSocket(tmpStr, SOCK_OPT_NUMS, socktmp); @@ -630,10 +629,51 @@ static int GetServiceOnRestart(const cJSON* curArrItem, Service* curServ) return SERVICE_SUCCESS; } +static bool IsServiceInMainStrap(Service *curServ) +{ + char *mainServiceList[] = { + "appspawn", "udevd", "samgr", "multimodalinput", "weston", "installs", "hiview", "hilogd", "hdf_devmgr", + "distributedsche", "softbus_server", "foundation" + }; + unsigned int length = sizeof(mainServiceList) / sizeof(mainServiceList[0]); + for (unsigned int i = 0; i < length; ++i) { + if (strncmp(curServ->name, mainServiceList[i], strlen(mainServiceList[i])) == 0) { + INIT_LOGI("%s must be main service", curServ->name); + return true; + } + } + return false; +} + +static int GetDynamicService(const cJSON *curArrItem, Service *curServ) +{ + cJSON *item = cJSON_GetObjectItem(curArrItem, "dynamic"); + if (item == NULL) { + return SERVICE_SUCCESS; + } + + INIT_ERROR_CHECK(cJSON_IsBool(item), return SERVICE_FAILURE, + "Service : %s dynamic value only support bool.", curServ->name); + bool isDynamic = (bool)cJSON_GetNumberValue(item); + if (!isDynamic) { + INIT_LOGI("Service : %s dynamic value is false, it will be started with init.", curServ->name); + return SERVICE_SUCCESS; + } + + if (IsServiceInMainStrap(curServ)) { + return SERVICE_SUCCESS; + } + INIT_LOGI("%s is dynamic service", curServ->name); + curServ->attribute |= SERVICE_ATTR_DYNAMIC; + curServ->attribute |= SERVICE_ATTR_ONCE; + return SERVICE_SUCCESS; +} + static int CheckServiceKeyName(const cJSON* curService) { - char *cfgServiceKeyList[] = {"name", "path", "uid", "gid", "once", - "importance", "caps", "disabled", "writepid", "critical", "socket", "console" + char *cfgServiceKeyList[] = { + "name", "path", "uid", "gid", "once", "importance", "caps", "disabled", + "writepid", "critical", "socket", "console", "dynamic" }; if (curService == NULL) { return SERVICE_FAILURE; @@ -642,15 +682,15 @@ static int CheckServiceKeyName(const cJSON* curService) if (child == NULL) { return SERVICE_FAILURE; } - while (child) { + while (child != NULL) { int i = 0; int keyListSize = sizeof(cfgServiceKeyList) / sizeof(char *); for (; i < keyListSize; i++) { - if (!strcmp(child->string, cfgServiceKeyList[i])) { + if (strcmp(child->string, cfgServiceKeyList[i]) == 0) { break; } } - if(i < keyListSize) { + if (i < keyListSize) { child = child->next; } else { INIT_LOGE("CheckServiceKeyName, key name %s is not found. error.", child->string); @@ -660,28 +700,41 @@ static int CheckServiceKeyName(const cJSON* curService) return SERVICE_SUCCESS; } +static int ParseOneService(const cJSON *curItem, Service *service) +{ + if (curItem == NULL || service == NULL) { + return SERVICE_FAILURE; + } + int ret = GetServiceName(curItem, service); + ret |= GetServicePathAndArgs(curItem, service); + ret |= GetUidStringNumber(curItem, service); + ret |= GetGidArray(curItem, service); + ret |= GetServiceNumber(curItem, service, ONCE_STR_IN_CFG); + ret |= GetServiceNumber(curItem, service, IMPORTANT_STR_IN_CFG); + ret |= GetServiceNumber(curItem, service, CRITICAL_STR_IN_CFG); + ret |= GetServiceNumber(curItem, service, DISABLED_STR_IN_CFG); + ret |= GetServiceNumber(curItem, service, CONSOLE_STR_IN_CFG); + ret |= GetWritepidStrings(curItem, service); + ret |= GetServiceCaps(curItem, service); + ret |= GetDynamicService(curItem, service); + return ret; +} + void ParseAllServices(const cJSON* fileRoot) { int servArrSize = 0; cJSON* serviceArr = GetArrItem(fileRoot, &servArrSize, SERVICES_ARR_NAME_IN_JSON); - if (serviceArr == NULL) { - INIT_LOGI("ParseAllServices, this config does not contain service array."); - return; - } + INIT_INFO_CHECK(serviceArr != NULL, return, "This config does not contain service array."); + + INIT_ERROR_CHECK(servArrSize <= MAX_SERVICES_CNT_IN_FILE, return, + "Too many services[cnt %d] detected, should not exceed %d.", + servArrSize, MAX_SERVICES_CNT_IN_FILE); + INIT_CHECK_ONLY_RETURN((g_servicesCnt + servArrSize) > 0); - if (servArrSize > MAX_SERVICES_CNT_IN_FILE) { - INIT_LOGE("ParseAllServices, too many services[cnt %d] detected, should not exceed %d.", - servArrSize, MAX_SERVICES_CNT_IN_FILE); - return; - } - if ((g_servicesCnt + servArrSize) <= 0) { - return; - } Service* retServices = (Service*)realloc(g_services, sizeof(Service) * (g_servicesCnt + servArrSize)); - if (retServices == NULL) { - INIT_LOGE("ParseAllServices, realloc for %s arr failed! %d.", SERVICES_ARR_NAME_IN_JSON, servArrSize); - return; - } + INIT_ERROR_CHECK(retServices != NULL, return, + "Realloc for %s arr failed! %d.", SERVICES_ARR_NAME_IN_JSON, servArrSize); + // Skip already saved services, Service* tmp = retServices + g_servicesCnt; if (memset_s(tmp, sizeof(Service) * servArrSize, 0, sizeof(Service) * servArrSize) != EOK) { @@ -697,28 +750,17 @@ void ParseAllServices(const cJSON* fileRoot) tmp[i].attribute |= SERVICE_ATTR_INVALID; continue; } - int ret1 = GetServiceName(curItem, &tmp[i]); - int ret2 = GetServicePathAndArgs(curItem, &tmp[i]); - int ret3 = GetUidStringNumber(curItem, &tmp[i]); // uid in string or number form - int ret4 = GetGidArray(curItem, &tmp[i]); // gid array - int ret5 = GetServiceNumber(curItem, &tmp[i], ONCE_STR_IN_CFG); - int ret6 = GetServiceNumber(curItem, &tmp[i], IMPORTANT_STR_IN_CFG); - int ret7 = GetServiceNumber(curItem, &tmp[i], CRITICAL_STR_IN_CFG); // critical - int ret8 = GetServiceNumber(curItem, &tmp[i], DISABLED_STR_IN_CFG); // disabled - int ret9 = GetServiceNumber(curItem, &tmp[i], CONSOLE_STR_IN_CFG); // console - int reta = GetWritepidStrings(curItem, &tmp[i]); // writepid - int retb = GetServiceCaps(curItem, &tmp[i]); - int retAll = ret1 | ret2 | ret3 | ret4 | ret5 | ret6 | ret7 | ret8 | ret9 | reta | retb; - if (retAll != SERVICE_SUCCESS) { + int ret = ParseOneService(curItem, &tmp[i]); + if (ret != SERVICE_SUCCESS) { // release resources if it fails ReleaseServiceMem(&tmp[i]); tmp[i].attribute |= SERVICE_ATTR_INVALID; - INIT_LOGE("ParseAllServices, parse information for service %s failed. ", tmp[i].name); + INIT_LOGE("Parse information for service %s failed. ", tmp[i].name); continue; } else { - INIT_LOGD("ParseAllServices ParseAllServices Service[%d] name=%s, uid=%d, critical=%d, disabled=%d", - i, tmp[i].name, tmp[i].servPerm.uID, tmp[i].attribute & SERVICE_ATTR_CRITICAL ? 1 : 0, - tmp[i].attribute & SERVICE_ATTR_DISABLED ? 1 : 0); + INIT_LOGD("service[%d] name=%s, uid=%d, critical=%d, disabled=%d", + i, tmp[i].name, tmp[i].servPerm.uID, (tmp[i].attribute & SERVICE_ATTR_CRITICAL) ? 1 : 0, + (tmp[i].attribute & SERVICE_ATTR_DISABLED) ? 1 : 0); } if (GetServiceSocket(curItem, &tmp[i]) != SERVICE_SUCCESS) { if (tmp[i].socketCfg != NULL) { @@ -747,19 +789,21 @@ static int FindServiceByName(const char* servName) return -1; } -void StartServiceByName(const char* servName) +void StartServiceByName(const char *servName, bool checkDynamic) { // find service by name int servIdx = FindServiceByName(servName); if (servIdx < 0) { - INIT_LOGE("StartServiceByName, cannot find service %s.", servName); + INIT_LOGE("Cannot find service %s.", servName); + return; + } + if (checkDynamic && (g_services[servIdx].attribute & SERVICE_ATTR_DYNAMIC)) { + INIT_LOGI("%s is dynamic service.", servName); return; } - if (ServiceStart(&g_services[servIdx]) != SERVICE_SUCCESS) { - INIT_LOGE("StartServiceByName, service %s start failed!", g_services[servIdx].name); + INIT_LOGE("Service %s start failed!", g_services[servIdx].name); } - return; } @@ -768,12 +812,12 @@ void StopServiceByName(const char* servName) // find service by name int servIdx = FindServiceByName(servName); if (servIdx < 0) { - INIT_LOGE("StopServiceByName, cannot find service %s.", servName); + INIT_LOGE("Cannot find service %s.", servName); return; } if (ServiceStop(&g_services[servIdx]) != SERVICE_SUCCESS) { - INIT_LOGE("StopServiceByName, service %s start failed!", g_services[servIdx].name); + INIT_LOGE("Service %s start failed!", g_services[servIdx].name); } return; @@ -784,10 +828,9 @@ void StopAllServices() if (g_services == NULL) { return; } - for (int i = 0; i < g_servicesCnt; i++) { if (ServiceStop(&g_services[i]) != SERVICE_SUCCESS) { - INIT_LOGE("StopAllServices, service %s stop failed!", g_services[i].name); + INIT_LOGE("Service %s stop failed!", g_services[i].name); } } } @@ -801,7 +844,7 @@ void StopAllServicesBeforeReboot() for (int i = 0; i < g_servicesCnt; i++) { g_services[i].attribute |= SERVICE_ATTR_INVALID; if (ServiceStop(&g_services[i]) != SERVICE_SUCCESS) { - INIT_LOGE("StopAllServicesBeforeReboot, service %s stop failed!", g_services[i].name); + INIT_LOGE("Service %s stop failed!", g_services[i].name); } } } @@ -828,4 +871,3 @@ void ReapServiceByPID(int pid) } } - diff --git a/services/src/init_service_socket.c b/services/src/init_service_socket.c index f6d9720c2..653f3f824 100644 --- a/services/src/init_service_socket.c +++ b/services/src/init_service_socket.c @@ -33,7 +33,7 @@ static int CreateSocket(struct ServiceSocket *sockopt) { - if (!sockopt || !sockopt->name) { + if (sockopt == NULL || sockopt->name == NULL) { return -1; } if (sockopt->sockFd >= 0) { @@ -41,13 +41,10 @@ static int CreateSocket(struct ServiceSocket *sockopt) sockopt->sockFd = -1; } sockopt->sockFd = socket(PF_UNIX, sockopt->type, 0); - if (sockopt->sockFd < 0) { - INIT_LOGE("socket fail %d ", errno); - return -1; - } + INIT_ERROR_CHECK(sockopt->sockFd >= 0, return -1, "socket fail %d ", errno); struct sockaddr_un addr; - bzero(&addr,sizeof(addr)); + bzero(&addr, sizeof(addr)); addr.sun_family = AF_UNIX; if (snprintf_s(addr.sun_path, sizeof(addr.sun_path), sizeof(addr.sun_path) - 1, HOS_SOCKET_DIR"/%s", sockopt->name) < 0) { @@ -117,11 +114,11 @@ static int SetSocketEnv(int fd, const char *name) int DoCreateSocket(struct ServiceSocket *sockopt) { - if (!sockopt) { + if (sockopt == NULL) { return -1; } struct ServiceSocket *tmpSock = sockopt; - while (tmpSock) { + while (tmpSock != NULL) { int fd = CreateSocket(tmpSock); if (fd < 0) { return -1; diff --git a/services/src/init_signal_handler.c b/services/src/init_signal_handler.c index b17fa929c..da625eeeb 100644 --- a/services/src/init_signal_handler.c +++ b/services/src/init_signal_handler.c @@ -72,7 +72,7 @@ static void SigHandler(int sig) } if (WIFEXITED(procStat)) { - INIT_LOGE("Child process %d exit with code : %d", sigPID, WEXITSTATUS(procStat)); + INIT_LOGE("Child process %d exit with code : %d", sigPID, WEXITSTATUS((unsigned int)procStat)); } #endif diff --git a/services/src/init_utils.c b/services/src/init_utils.c index f1dba38a0..760f8530a 100644 --- a/services/src/init_utils.c +++ b/services/src/init_utils.c @@ -14,20 +14,16 @@ */ #include "init_utils.h" #include -#include -#include -#include -#include -#include #include +#include #include -#include +#include #include -#include #include -#include +#include #include #include +#include #include #include "init_log.h" @@ -43,23 +39,27 @@ #endif #define MAX_JSON_FILE_LEN 102400 // max init.cfg size 100KB -#define CONVERT_MICROSEC_TO_SEC(x) ((x) / 1000 / 1000.0) -int DecodeUid(const char *name) +float ConvertMisrosecToSec(int x) +{ + return ((x/1000)/1000.0); +} + +uid_t DecodeUid(const char *name) { if (name == NULL) { return -1; } - bool digitFlag = true; + int digitFlag = 1; for (unsigned int i = 0; i < strlen(name); ++i) { if (isalpha(name[i])) { - digitFlag = false; + digitFlag = 0; break; } } if (digitFlag) { errno = 0; - uid_t result = strtoul(name, 0, 10); + uid_t result = strtoul(name, 0, DECIMAL_BASE); if (errno != 0) { return -1; } @@ -73,18 +73,6 @@ int DecodeUid(const char *name) } } -void CheckAndCreateDir(const char *fileName) -{ - if (fileName == NULL || *fileName == '\0') { - return; - } - char *path = strndup(fileName, strrchr(fileName, '/') - fileName); - if (path != NULL && access(path, F_OK) != 0) { - mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - } - free(path); -} - char* ReadFileToBuf(const char *configFile) { char* buffer = NULL; @@ -128,7 +116,7 @@ char* ReadFileToBuf(const char *configFile) int SplitString(char *srcPtr, char **dstPtr, int maxNum) { - if ((!srcPtr) || (!dstPtr)){ + if (srcPtr == NULL || dstPtr == NULL) { return -1; } char *buf = NULL; @@ -155,9 +143,9 @@ void WaitForFile(const char *source, unsigned int maxCount) usleep(waitTime); count++; } while ((stat(source, &sourceInfo) < 0) && (errno == ENOENT) && (count < maxCount)); + float secTime = ConvertMisrosecToSec(waitTime); if (count == maxCount) { - INIT_LOGE("wait for file:%s failed after %f.", source, maxCount * CONVERT_MICROSEC_TO_SEC(waitTime)); + INIT_LOGE("wait for file:%s failed after %f.", source, maxCount * secTime); } return; } - diff --git a/ueventd/list.c b/services/src/list.c similarity index 85% rename from ueventd/list.c rename to services/src/list.c index 17e6f468f..9a7cbe2e2 100755 --- a/ueventd/list.c +++ b/services/src/list.c @@ -14,15 +14,22 @@ */ #include "list.h" +#include void ListInit(struct ListNode *node) { + if (node == NULL) { + return; + } node->next = node; node->prev = node; } void ListAddTail(struct ListNode *head, struct ListNode *item) { + if (head == NULL || item == NULL) { + return; + } item->next = head; item->prev = head->prev; head->prev->next = item; @@ -31,6 +38,9 @@ void ListAddTail(struct ListNode *head, struct ListNode *item) void ListRemove(struct ListNode *item) { + if (item == NULL) { + return; + } item->next->prev = item->prev; item->prev->next = item->next; } diff --git a/services/src/main.c b/services/src/main.c index 8c027bcd2..40a6de279 100644 --- a/services/src/main.c +++ b/services/src/main.c @@ -66,14 +66,13 @@ static long TimeDiffMs(const struct timespec* tmBefore, const struct timespec* t int main(int argc, char **argv) { #ifndef OHOS_LITE - if(setenv("UV_THREADPOOL_SIZE", "1", 1) != 0) { + if (setenv("UV_THREADPOOL_SIZE", "1", 1) != 0) { INIT_LOGE("set UV_THREADPOOL_SIZE error : %d.", errno); } - CloseStdio(); OpenLogDevice(); - #endif + #ifdef OHOS_DEBUG struct timespec tmEnter; if (clock_gettime(CLOCK_REALTIME, &tmEnter) != 0) { @@ -85,19 +84,15 @@ int main(int argc, char **argv) INIT_LOGE("main, current process id is %d not %d, failed!", getpid(), INIT_PROCESS_PID); return 0; } - - // 1. print system info PrintSysInfo(); #ifndef OHOS_LITE - // 2. Mount basic filesystem and create common device node. MountBasicFs(); CreateDeviceNode(); EnableDevKmsg(); MakeSocketDir("/dev/unix/socket/", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); #endif - // 3. signal register SignalInitModule(); #ifdef OHOS_DEBUG @@ -107,7 +102,6 @@ int main(int argc, char **argv) } #endif // OHOS_DEBUG - // 4. execute rcs ExecuteRcs(); #ifdef OHOS_DEBUG @@ -116,7 +110,6 @@ int main(int argc, char **argv) INIT_LOGE("main, after rcs, get time failed! err %d.", errno); } #endif // OHOS_DEBUG - // 5. read configuration file and do jobs InitReadCfg(); #ifdef OHOS_DEBUG struct timespec tmCfg; @@ -125,7 +118,6 @@ int main(int argc, char **argv) } #endif // OHOS_DEBUG - // 6. keep process alive #ifdef OHOS_DEBUG INIT_LOGI("main, time used: sigInfo %ld ms, rcs %ld ms, cfg %ld ms.", \ TimeDiffMs(&tmEnter, &tmSysInfo), TimeDiffMs(&tmSysInfo, &tmRcs), TimeDiffMs(&tmRcs, &tmCfg)); @@ -136,8 +128,6 @@ int main(int argc, char **argv) StartParamService(); #endif while (1) { - // pause only returns when a signal was caught and the signal-catching function returned. - // pause only returns -1, no need to process the return value. (void)pause(); } return 0; diff --git a/services/test/unittest/BUILD.gn b/services/test/unittest/BUILD.gn new file mode 100755 index 000000000..18d987192 --- /dev/null +++ b/services/test/unittest/BUILD.gn @@ -0,0 +1,236 @@ +# 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/ohos.gni") + +config("utest_config") { + visibility = [ ":*" ] + + cflags = [ + "-fprofile-arcs", + "-ftest-coverage", + "-Wno-implicit-fallthrough", + "-Wno-unused-function", + ] + cflags_cc = [ + "-Wno-implicit-fallthrough", + "-fexceptions", + ] + + ldflags = [ "--coverage" ] +} + +ohos_executable("init_ut") { + sources = [ + "init_ut_entry.cpp", + "service/cmds_unittest.cpp", + ] + + sources += [ + "//base/startup/init_lite/services/src/device.c", + "//base/startup/init_lite/services/src/init_capability.c", + "//base/startup/init_lite/services/src/init_cmds.c", + "//base/startup/init_lite/services/src/init_import.c", + "//base/startup/init_lite/services/src/init_jobs.c", + "//base/startup/init_lite/services/src/init_read_cfg.c", + "//base/startup/init_lite/services/src/init_reboot.c", + "//base/startup/init_lite/services/src/init_service.c", + "//base/startup/init_lite/services/src/init_service_manager.c", + "//base/startup/init_lite/services/src/init_service_socket.c", + "//base/startup/init_lite/services/src/init_signal_handler.c", + "//base/startup/init_lite/services/src/init_utils.c", + ] + + include_dirs = [ + "//base/startup/init_lite/services/include/param", + "//base/startup/init_lite/services/include", + "//base/startup/init_lite/services/log", + "//third_party/cJSON", + "//third_party/bounds_checking_function/include", + "//third_party/libuv/include", + ] + + deps = [ + "//base/startup/init_lite/services/log:init_log", + "//base/startup/init_lite/services/param:param_service", + "//third_party/bounds_checking_function:libsec_static", + "//third_party/cJSON:cjson_static", + "//third_party/googletest:gmock", + "//third_party/googletest:gtest", + ] + + defines = [ "INIT_UT" ] + public_configs = [ ":utest_config" ] + install_enable = true + part_name = "init" +} + +ohos_executable("paramserver_ut") { + sources = [ + "param_ut_server.cpp", + "param/dac_unittest.cpp", + "param/service_unittest.cpp", + "param/trigger_unittest.cpp", + "param/selinux_unittest.cpp", + ] + + sources += [ + "//base/startup/init_lite/services/src/device.c", + "//base/startup/init_lite/services/src/init_adapter.c", + "//base/startup/init_lite/services/src/init_capability.c", + "//base/startup/init_lite/services/src/init_cmds.c", + "//base/startup/init_lite/services/src/init_import.c", + "//base/startup/init_lite/services/src/init_jobs.c", + "//base/startup/init_lite/services/src/init_read_cfg.c", + "//base/startup/init_lite/services/src/init_reboot.c", + "//base/startup/init_lite/services/src/init_service.c", + "//base/startup/init_lite/services/src/init_service_manager.c", + "//base/startup/init_lite/services/src/init_service_socket.c", + "//base/startup/init_lite/services/src/init_signal_handler.c", + "//base/startup/init_lite/services/src/init_utils.c", + "//base/startup/init_lite/services/log/init_log.c", + "//base/startup/init_lite/services/src/list.c", + "//base/startup/init_lite/services/param/manager/param_utils.c", + "//base/startup/init_lite/services/param/manager/param_manager.c", + "//base/startup/init_lite/services/param/manager/param_trie.c", + "//base/startup/init_lite/services/param/manager/param_message.c", + "//base/startup/init_lite/services/param/service/param_persist.c", + "//base/startup/init_lite/services/param/service/param_service.c", + "//base/startup/init_lite/services/param/trigger/trigger_checker.c", + "//base/startup/init_lite/services/param/trigger/trigger_manager.c", + "//base/startup/init_lite/services/param/trigger/trigger_processor.c", + "//base/startup/init_lite/services/param/adapter/param_libuvadp.c", + "//base/startup/init_lite/services/param/adapter/param_persistadp.c", + "//base/startup/init_lite/services/param/adapter/param_dac.c", + "//base/startup/init_lite/services/param/adapter/param_selinux.c" + ] + include_dirs = [ + "param", + "//base/startup/init_lite/services/include", + "//base/startup/init_lite/services/include/param", + "//base/startup/init_lite/services/param/include", + "//base/startup/init_lite/services/param/adapter", + "//base/startup/init_lite/services/log", + "//third_party/libuv/include", + "//third_party/cJSON", + "//third_party/bounds_checking_function/include", + ] + + deps = [ + "//third_party/googletest:gtest", + "//third_party/googletest:gmock", + "//utils/native/base:utils", + "//third_party/bounds_checking_function:libsec_static", + "//third_party/libuv:uv_static", + "//third_party/cJSON:cjson_static", + ] + + defines = ["STARTUP_INIT_TEST", "PARAM_SUPPORT_SAVE_PERSIST", "PARAM_SUPPORT_DAC"] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + ] + + cflags_cc = [ + "-fexceptions", + ] + + public_configs = [ ":utest_config" ] + part_name = "init" + subsystem_name = "startup" +} + +ohos_executable("paramclient_ut") { + sources = [ + "param_ut_entry.cpp", + "param/dac_unittest.cpp", + "param/client_unittest.cpp", + "param/selinux_unittest.cpp", + "param/watcher_agent_unittest.cpp", + "param/watcher_proxy_unittest.cpp", + ] + + sources += [ + "//base/startup/init_lite/services/log/init_log.c", + "//base/startup/init_lite/services/src/init_utils.c", + "//base/startup/init_lite/services/src/list.c", + "//base/startup/init_lite/services/param/adapter/param_dac.c", + "//base/startup/init_lite/services/param/adapter/param_selinux.c", + "//base/startup/init_lite/services/param/client/param_request.c", + "//base/startup/init_lite/services/param/cmd/param_cmd.c", + "//base/startup/init_lite/services/param/manager/param_utils.c", + "//base/startup/init_lite/services/param/manager/param_manager.c", + "//base/startup/init_lite/services/param/manager/param_message.c", + "//base/startup/init_lite/services/param/manager/param_trie.c", + "//base/startup/init_lite/services/param/watcher/proxy/watcher_manager.cpp", + "//base/startup/init_lite/services/param/watcher/proxy/watcher_manager_stub.cpp", + "//base/startup/init_lite/services/param/watcher/proxy/watcher_proxy.cpp", + "//base/startup/init_lite/services/param/watcher/agent/watcher_manager_kits.cpp", + "//base/startup/init_lite/services/param/watcher/agent/watcher_manager_proxy.cpp", + "//base/startup/init_lite/services/param/watcher/agent/watcher_stub.cpp", + "//base/startup/init_lite/services/param/watcher/agent/watcher.cpp" + ] + + include_dirs = [ + "param", + "//base/startup/init_lite/services/include", + "//base/startup/init_lite/services/include/param", + "//base/startup/init_lite/services/log", + "//base/startup/init_lite/services/param/include", + "//base/startup/init_lite/services/adapter", + "//base/startup/init_lite/services/param/watcher/agent", + "//base/startup/init_lite/services/param/watcher/include", + "//base/startup/init_lite/services/param/watcher/proxy", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include", + "//foundation/distributedschedule/safwk/services/safwk/include", + "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk", + "//foundation/distributedschedule/samgr/adapter/interfaces/innerkits/include", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "//third_party/libuv/include", + "//third_party/cJSON", + ] + + deps = [ + "//third_party/googletest:gtest", + "//third_party/googletest:gmock", + "//utils/native/base:utils", + "//third_party/bounds_checking_function:libsec_static", + ] + + defines = ["STARTUP_INIT_TEST", "PARAM_SUPPORT_SAVE_PERSIST", "PARAM_SUPPORT_DAC"] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", + ] + + cflags_cc = [ + "-fexceptions", + ] + + public_configs = [ ":utest_config" ] + part_name = "init" + subsystem_name = "startup" +} + +group("init_test") { + deps = [ + ":init_ut", + ":paramserver_ut", + ":paramclient_ut", + ] +} diff --git a/services/test/unittest/init_unittest_const.h b/services/test/unittest/init_unittest_const.h new file mode 100755 index 000000000..4a5262660 --- /dev/null +++ b/services/test/unittest/init_unittest_const.h @@ -0,0 +1,26 @@ +/* + * 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 INIT_UNITTEST_CONST_H +#define INIT_UNITTEST_CONST_H + + +namespace init_ut { + + + + +} // namespace init_ut +#endif // INIT_UNITTEST_CONST_H diff --git a/services/test/unittest/init_ut_entry.cpp b/services/test/unittest/init_ut_entry.cpp new file mode 100755 index 000000000..736dd4ff1 --- /dev/null +++ b/services/test/unittest/init_ut_entry.cpp @@ -0,0 +1,28 @@ +/* +* 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 +#include +#include + +using namespace testing::ext; + +int main(int argc, char* argv[]) +{ + testing::InitGoogleMock(&argc, argv); + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/services/test/unittest/param/client_unittest.cpp b/services/test/unittest/param/client_unittest.cpp new file mode 100755 index 000000000..3552d4829 --- /dev/null +++ b/services/test/unittest/param/client_unittest.cpp @@ -0,0 +1,267 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include "param_service.h" +#include "param_unittest.h" +#include "sys_param.h" + +static void TestCheckParamValue(const char *name, const char *expectValue) +{ + char tmp[PARAM_BUFFER_SIZE] = { 0 }; + u_int32_t len = sizeof(tmp); + int ret = SystemGetParameter(name, tmp, &len); + printf("TestCheckParamValue name %s value: \'%s\' expectValue:\'%s\' \n", name, tmp, expectValue); + if (ret == 0 && len > 0) { + EXPECT_NE(strlen(tmp), 0); + if (expectValue != NULL) { + EXPECT_EQ(strcmp(tmp, expectValue), 0); + } + } else { + EXPECT_NE(0, 0); + } +} + +// 多线程测试 +static void *TestSendParamSetMsg(void *args) +{ + std::string name = (char *)args; + printf("TestSendParamSetMsg name :\'%s\' \n", name.c_str()); + SystemSetParameter(name.c_str(), name.c_str()); + TestCheckParamValue(name.c_str(), name.c_str()); + return NULL; +} + +static void *TestSendParamWaitMsg(void *args) +{ + std::string name = "Wati."; + name = name + (char *)args; + printf("TestSendParamWaitMsg name :\'%s\' \n", name.c_str()); + SystemWaitParameter(name.c_str(), name.c_str(), 0); + TestCheckParamValue(name.c_str(), name.c_str()); + return NULL; +} + +std::string g_testChangeValue = {}; +static void ParameterChangeCallback(const char *key, const char *value, void *context) +{ + if (strcmp(value, g_testChangeValue.c_str()) == 0) { + printf("ParameterChangeCallback key %s value %s", key, value); + } +} + +class ParamClientTest : public ::testing::Test { +public: + ParamClientTest() {} + virtual ~ParamClientTest() {} + + void SetUp() {} + void TearDown() {} + void TestBody() {} + + int TestSetParam(const char *key, const char *value) + { + SystemSetParameter(key, value); + TestCheckParamValue(key, value); + return 0; + } + + int TestForMultiThread() + { + srand((int)time(NULL)); + printf("TestForMultiThread \n"); + pthread_t tids[THREAD_NUM_TEST + THREAD_NUM_TEST]; + const char *names[5] = { "thread.1111.2222.3333.4444.5555", "thread.2222.1111.2222.3333.4444", + "thread.3333.1111.2222.4444.5555", "thread.4444.5555.1111.2222.3333", + "thread.5555.1111.2222.3333.4444" }; + for (size_t i = 0; i < THREAD_NUM_TEST; i++) { + pthread_create(&tids[i], NULL, TestSendParamSetMsg, (void *)names[i % 5]); + } + for (size_t i = THREAD_NUM_TEST; i < THREAD_NUM_TEST + THREAD_NUM_TEST; i++) { + pthread_create(&tids[i], NULL, TestSendParamWaitMsg, (void *)names[i % 5]); + } + for (size_t i = 0; i < THREAD_NUM_TEST + THREAD_NUM_TEST; i++) { + pthread_join(tids[i], NULL); + } + return 0; + } + + int TestParamTraversal() + { + char value[PARAM_BUFFER_SIZE + PARAM_BUFFER_SIZE] = { 0 }; + SystemTraversalParameter( + [](ParamHandle handle, void *cookie) { + SystemGetParameterName(handle, (char *)cookie, PARAM_BUFFER_SIZE); + u_int32_t len = PARAM_BUFFER_SIZE; + SystemGetParameterValue(handle, ((char *)cookie) + PARAM_BUFFER_SIZE, &len); + printf("$$$$$$$$Param %s=%s \n", (char *)cookie, ((char *)cookie) + PARAM_BUFFER_SIZE); + }, + (void *)value); + return 0; + } + + int TestUpdateParam(const char *name, const char *value) + { + SystemSetParameter(name, value); + TestCheckParamValue(name, value); + return 0; + } + + int TestPersistParam() + { + SystemSetParameter("persist.111.ffff.bbbb.cccc.dddd.eeee", "1101"); + SystemSetParameter("persist.111.aaaa.bbbb.cccc.dddd.eeee", "1102"); + SystemSetParameter("persist.111.bbbb.cccc.dddd.eeee", "1103"); + TestCheckParamValue("persist.111.bbbb.cccc.dddd.eeee", "1103"); + SystemSetParameter("persist.111.cccc.bbbb.cccc.dddd.eeee", "1104"); + SystemSetParameter("persist.111.eeee.bbbb.cccc.dddd.eeee", "1105"); + TestCheckParamValue("persist.111.ffff.bbbb.cccc.dddd.eeee", "1101"); + SystemSetParameter("persist.111.ffff.bbbb.cccc.dddd.eeee", "1106"); + TestCheckParamValue("persist.111.ffff.bbbb.cccc.dddd.eeee", "1106"); + return 0; + } + + int TestPermission() + { + const char *testName = "persist.111.ffff.bbbb.cccc.dddd.eeee.55555"; + char tmp[PARAM_BUFFER_SIZE] = { 0 }; + // 允许本地校验 + ParamSecurityOps *paramSecurityOps = &GetClientParamWorkSpace()->paramSecurityOps; + paramSecurityOps->securityCheckParamPermission = TestCheckParamPermission; + g_testPermissionResult = DAC_RESULT_FORBIDED; + GetClientParamWorkSpace()->securityLabel->flags = LABEL_CHECK_FOR_ALL_PROCESS; + int ret = SystemSetParameter(testName, "22202"); + EXPECT_EQ(ret, DAC_RESULT_FORBIDED); + + paramSecurityOps->securityEncodeLabel = TestEncodeSecurityLabel; + paramSecurityOps->securityDecodeLabel = TestDecodeSecurityLabel; + paramSecurityOps->securityFreeLabel = TestFreeLocalSecurityLabel; + paramSecurityOps->securityCheckParamPermission = TestCheckParamPermission; + g_testPermissionResult = 0; + ret = SystemSetParameter(testName, "22202"); + EXPECT_EQ(ret, 0); + TestCheckParamValue(testName, "22202"); + + g_testPermissionResult = 201; + // 禁止写/读 + ret = SystemSetParameter(testName, "3333"); + EXPECT_EQ(ret, 201); + u_int32_t len = sizeof(tmp); + ret = SystemGetParameter(testName, tmp, &len); + EXPECT_EQ(ret, 201); + RegisterSecurityOps(paramSecurityOps, 0); + return 0; + } + + int TestDumpParamMemory() + { + DumpParameters(GetClientParamWorkSpace(), 1); + return 0; + } + + int TestCmd() + { + // set + const char *argForSet[] = { + "param", + "set", + "aaaa", + "2222" + }; + RunParamCommand(sizeof(argForSet) / sizeof(argForSet[0]), const_cast(argForSet)); + + // get + const char *argForGet[] = { + "param", + "get", + "aaaa" + }; + RunParamCommand(sizeof(argForGet) / sizeof(argForGet[0]), const_cast(argForGet)); + + // get all + const char *argForGet2[] = { + "param", + "get" + }; + RunParamCommand(sizeof(argForGet2) / sizeof(argForGet2[0]), const_cast(argForGet2)); + + // set 失败 + const char *argForSet2[] = { + "param", + "set", + "aaaa" + }; + RunParamCommand(sizeof(argForSet2) / sizeof(argForSet2[0]), const_cast(argForSet2)); + return 0; + } +}; + +TEST(ParamClientTest, TestSetParam) +{ + ParamClientTest test; + for (int i = 0; i < 20; i++) { + std::string info = std::to_string(i); + std::string name = "sys.init_log_level"; + name += "." + info; + std::string value = "sys.2222.3333333333333"; + value += "." + info; + test.TestSetParam(name.c_str(), value.c_str()); + } +} + +TEST(ParamClientTest, TestForMultiThread) +{ + ParamClientTest test; + test.TestForMultiThread(); +} + +TEST(ParamClientTest, TestUpdateParam) +{ + ParamClientTest test; + test.TestUpdateParam("test.aaa.bbb.ccc.ddd", "100"); + test.TestUpdateParam("test.aaa.bbb.ccc.ddd", "101"); + test.TestUpdateParam("test.aaa.bbb.ccc.ddd", "102"); + test.TestUpdateParam("test.aaa.bbb.ccc.ddd", "103"); + test.TestUpdateParam("net.tcp.default_init_rwnd", "60"); +} + +TEST(ParamClientTest, TestParamTraversal) +{ + ParamClientTest test; + test.TestParamTraversal(); +} + +TEST(ParamClientTest, TestPermission) +{ + ParamClientTest test; + test.TestPermission(); +} + +TEST(ParamClientTest, TestDumpParamMemory) +{ + ParamClientTest test; + test.TestDumpParamMemory(); +} + +TEST(ParamClientTest, TestCmd) +{ + ParamClientTest test; + test.TestCmd(); +} \ No newline at end of file diff --git a/services/test/unittest/param/dac_unittest.cpp b/services/test/unittest/param/dac_unittest.cpp new file mode 100755 index 000000000..85c6546c6 --- /dev/null +++ b/services/test/unittest/param/dac_unittest.cpp @@ -0,0 +1,346 @@ +/* + * 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 +#include +#include +#include + +#include "param_security.h" +#include "param_unittest.h" +#include "param_utils.h" +#include "securec.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif +extern int RegisterSecurityDacOps(ParamSecurityOps *ops, int isInit); +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +using namespace std; +#define CHECK_FILE_NAME "/media/sf_ubuntu/develop/startup/init_lite/services/test/unittest/test_data/build.prop" + +static int SecurityLabelGet(const ParamAuditData *auditData, void *context) +{ + return 0; +} + +class ParamDacTest : public ::testing::Test { +public: + ParamDacTest() {} + virtual ~ParamDacTest() {} + + void SetUp() {} + void TearDown() {} + void TestBody() {} + + int TestDacGetLabel() + { + int ret = RegisterSecurityDacOps(&initParamSercurityOps, LABEL_INIT_FOR_INIT); + EXPECT_EQ(ret, 0); + + if (initParamSercurityOps.securityGetLabel == NULL) { + EXPECT_EQ(1, 0); + return -1; + } + ret = initParamSercurityOps.securityGetLabel(SecurityLabelGet, PARAM_DEFAULT_PATH, NULL); + EXPECT_EQ(ret, 0); + return 0; + } + + int TestDacInitLocalLabel() + { + int ret = RegisterSecurityDacOps(&initParamSercurityOps, LABEL_INIT_FOR_INIT); + EXPECT_EQ(ret, 0); + + if (initParamSercurityOps.securityInitLabel == NULL || initParamSercurityOps.securityFreeLabel == NULL) { + return -1; + } + ParamSecurityLabel *label = NULL; + ret = initParamSercurityOps.securityInitLabel(&label, LABEL_INIT_FOR_INIT); + EXPECT_EQ(ret, 0); + ret = initParamSercurityOps.securityFreeLabel(label); + EXPECT_EQ(ret, 0); + return 0; + } + + int TestDacCheckFilePermission(const char *fileName) + { + int ret = RegisterSecurityDacOps(&initParamSercurityOps, LABEL_INIT_FOR_INIT); + EXPECT_EQ(ret, 0); + if (initParamSercurityOps.securityCheckFilePermission == NULL) { + return -1; + } + ParamSecurityLabel *label = NULL; + ret = initParamSercurityOps.securityInitLabel(&label, LABEL_INIT_FOR_INIT); + EXPECT_EQ(ret, 0); + ret = initParamSercurityOps.securityCheckFilePermission(label, fileName, DAC_WRITE); + EXPECT_EQ(ret, 0); + ret = initParamSercurityOps.securityFreeLabel(label); + EXPECT_EQ(ret, 0); + return 0; + } + + int TestDacCheckParaPermission(const char *name, ParamDacData *dacData, int mode) + { + int ret = RegisterSecurityDacOps(&initParamSercurityOps, LABEL_INIT_FOR_INIT); + EXPECT_EQ(ret, 0); + if (initParamSercurityOps.securityCheckFilePermission == NULL) { + return -1; + } + ParamSecurityLabel *srclabel = NULL; + ret = initParamSercurityOps.securityInitLabel(&srclabel, LABEL_INIT_FOR_INIT); + EXPECT_EQ(ret, 0); + + ParamAuditData auditData = {}; + auditData.name = name; + auditData.label = nullptr; + memcpy_s(&auditData.dacData, sizeof(ParamDacData), dacData, sizeof(ParamDacData)); + ret = initParamSercurityOps.securityCheckParamPermission(srclabel, &auditData, mode); + initParamSercurityOps.securityFreeLabel(srclabel); + return ret; + } + + int TestClientDacCheckFilePermission(const char *fileName) + { + int ret = RegisterSecurityDacOps(&clientParamSercurityOps, 0); + EXPECT_EQ(ret, 0); + if (clientParamSercurityOps.securityDecodeLabel != NULL) { + EXPECT_EQ(1, 0); + } + if (clientParamSercurityOps.securityGetLabel != NULL) { + EXPECT_EQ(1, 0); + } + if (clientParamSercurityOps.securityCheckFilePermission == NULL) { + EXPECT_EQ(1, 0); + return -1; + } + ParamSecurityLabel *label = NULL; + ret = clientParamSercurityOps.securityInitLabel(&label, 0); + EXPECT_EQ(ret, 0); + ret = clientParamSercurityOps.securityCheckFilePermission(label, fileName, DAC_READ); + EXPECT_EQ(ret, 0); + ret = clientParamSercurityOps.securityFreeLabel(label); + EXPECT_EQ(ret, 0); + return 0; + } + + int TestEncode(const ParamSecurityLabel *label, std::vector &buffer) + { + int ret = RegisterSecurityDacOps(&clientParamSercurityOps, 0); + EXPECT_EQ(ret, 0); + if (clientParamSercurityOps.securityDecodeLabel != NULL) { + EXPECT_EQ(1, 0); + } + if (clientParamSercurityOps.securityGetLabel != NULL) { + EXPECT_EQ(1, 0); + } + if (clientParamSercurityOps.securityEncodeLabel == NULL) { + EXPECT_EQ(1, 0); + return -1; + } + uint32_t bufferSize = 0; + ret = clientParamSercurityOps.securityEncodeLabel(label, NULL, &bufferSize); + EXPECT_EQ(ret, 0); + buffer.resize(bufferSize + 1); + ret = clientParamSercurityOps.securityEncodeLabel(label, buffer.data(), &bufferSize); + EXPECT_EQ(ret, 0); + return 0; + } + + int TestDecode(const ParamSecurityLabel *label, std::vector &buffer) + { + int ret = RegisterSecurityDacOps(&clientParamSercurityOps, 1); + EXPECT_EQ(ret, 0); + if (clientParamSercurityOps.securityDecodeLabel == NULL) { + EXPECT_EQ(1, 0); + } + if (clientParamSercurityOps.securityEncodeLabel != NULL) { + EXPECT_EQ(1, 0); + return -1; + } + ParamSecurityLabel *tmp = NULL; + ret = clientParamSercurityOps.securityDecodeLabel(&tmp, buffer.data(), buffer.size()); + EXPECT_EQ(ret, 0); + EXPECT_EQ(label->cred.gid, tmp->cred.gid); + EXPECT_EQ(label->cred.uid, tmp->cred.uid); + return 0; + } + +private: + ParamSecurityOps initParamSercurityOps; + ParamSecurityOps clientParamSercurityOps; +}; + +TEST(ParamDacTest, TestDacGetLabel) +{ + ParamDacTest test; + test.TestDacGetLabel(); +} + +TEST(ParamDacTest, TestDacInitLocalLabel) +{ + ParamDacTest test; + test.TestDacInitLocalLabel(); +} + +TEST(ParamDacTest, TestDacLabelEncode) +{ + ParamDacTest test; + std::vector buffer; + ParamSecurityLabel label = {0, { 4444, 5555}}; + test.TestEncode(&label, buffer); + test.TestDecode(&label, buffer); +} + +TEST(ParamDacTest, TestDacCheckFilePermission) +{ + ParamDacTest test; + test.TestDacCheckFilePermission(CHECK_FILE_NAME); +} + +TEST(ParamDacTest, TestDacCheckUserParaPermission) +{ + // 相同用户 + ParamDacTest test; + ParamDacData dacData; + dacData.gid = getegid(); + dacData.uid = geteuid(); + // read + dacData.mode = 0400; + int ret = test.TestDacCheckParaPermission("test.permission.read.aaa", &dacData, DAC_READ); + EXPECT_EQ(ret, 0); + dacData.mode = 0400; + ret = test.TestDacCheckParaPermission("test.permission.read.aaa", &dacData, DAC_WRITE); + EXPECT_NE(ret, 0); + dacData.mode = 0400; + ret = test.TestDacCheckParaPermission("test.permission.read.aaa", &dacData, DAC_WATCH); + EXPECT_NE(ret, 0); + + // write + dacData.mode = 0200; + ret = test.TestDacCheckParaPermission("test.permission.write.aaa", &dacData, DAC_READ); + EXPECT_NE(ret, 0); + dacData.mode = 0200; + ret = test.TestDacCheckParaPermission("test.permission.write.aaa", &dacData, DAC_WRITE); + EXPECT_EQ(ret, 0); + dacData.mode = 0200; + ret = test.TestDacCheckParaPermission("test.permission.write.aaa", &dacData, DAC_WATCH); + EXPECT_NE(ret, 0); + + // watch + dacData.mode = 0100; + ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_READ); + EXPECT_NE(ret, 0); + dacData.mode = 0100; + ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_WRITE); + EXPECT_NE(ret, 0); + dacData.mode = 0100; + ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_WATCH); + EXPECT_EQ(ret, 0); +} + +TEST(ParamDacTest, TestDacCheckGroupParaPermission) +{ + // 相同组 + ParamDacTest test; + ParamDacData dacData; + dacData.gid = getegid(); + dacData.uid = 13333; + // read + dacData.mode = 0040; + int ret = test.TestDacCheckParaPermission("test.permission.read.aaa", &dacData, DAC_READ); + EXPECT_EQ(ret, 0); + dacData.mode = 0040; + ret = test.TestDacCheckParaPermission("test.permission.read.aaa", &dacData, DAC_WRITE); + EXPECT_NE(ret, 0); + dacData.mode = 0040; + ret = test.TestDacCheckParaPermission("test.permission.read.aaa", &dacData, DAC_WATCH); + EXPECT_NE(ret, 0); + + // write + dacData.mode = 0020; + ret = test.TestDacCheckParaPermission("test.permission.write.aaa", &dacData, DAC_READ); + EXPECT_NE(ret, 0); + dacData.mode = 0020; + ret = test.TestDacCheckParaPermission("test.permission.write.aaa", &dacData, DAC_WRITE); + EXPECT_EQ(ret, 0); + dacData.mode = 0020; + ret = test.TestDacCheckParaPermission("test.permission.write.aaa", &dacData, DAC_WATCH); + EXPECT_NE(ret, 0); + + // watch + dacData.mode = 0010; + ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_READ); + EXPECT_NE(ret, 0); + dacData.mode = 0010; + ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_WRITE); + EXPECT_NE(ret, 0); + dacData.mode = 0010; + ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_WATCH); + EXPECT_EQ(ret, 0); +} + +TEST(ParamDacTest, TestDacCheckOtherParaPermission) +{ + // 其他用户 + ParamDacTest test; + ParamDacData dacData; + dacData.gid = 13333; + dacData.uid = 13333; + // read + dacData.mode = 0004; + int ret = test.TestDacCheckParaPermission("test.permission.read.aaa", &dacData, DAC_READ); + EXPECT_EQ(ret, 0); + dacData.mode = 0004; + ret = test.TestDacCheckParaPermission("test.permission.read.aaa", &dacData, DAC_WRITE); + EXPECT_NE(ret, 0); + dacData.mode = 0004; + ret = test.TestDacCheckParaPermission("test.permission.read.aaa", &dacData, DAC_WATCH); + EXPECT_NE(ret, 0); + + // write + dacData.mode = 0002; + ret = test.TestDacCheckParaPermission("test.permission.write.aaa", &dacData, DAC_READ); + EXPECT_NE(ret, 0); + dacData.mode = 0002; + ret = test.TestDacCheckParaPermission("test.permission.write.aaa", &dacData, DAC_WRITE); + EXPECT_EQ(ret, 0); + dacData.mode = 0002; + ret = test.TestDacCheckParaPermission("test.permission.write.aaa", &dacData, DAC_WATCH); + EXPECT_NE(ret, 0); + + // watch + dacData.mode = 0001; + ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_READ); + EXPECT_NE(ret, 0); + dacData.mode = 0001; + ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_WRITE); + EXPECT_NE(ret, 0); + dacData.mode = 0001; + ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_WATCH); + EXPECT_EQ(ret, 0); +} + +TEST(ParamDacTest, TestClientDacCheckFilePermission) +{ + ParamDacTest test; + test.TestClientDacCheckFilePermission(CHECK_FILE_NAME); +} diff --git a/services/test/unittest/param/param_unittest.h b/services/test/unittest/param/param_unittest.h new file mode 100755 index 000000000..9e06a946d --- /dev/null +++ b/services/test/unittest/param/param_unittest.h @@ -0,0 +1,72 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include "param_service.h" + +#define LABEL "ParamTest" +#define THREAD_NUM_TEST 10 + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif +extern int RunParamCommand(int argc, char *argv[]); +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +static ParamSecurityLabel g_testLabel; +static int g_testPermissionResult = DAC_RESULT_PERMISSION; + +static int TestEncodeSecurityLabel(const ParamSecurityLabel *srcLabel, char *buffer, uint32_t *bufferSize) +{ + PARAM_CHECK(bufferSize != NULL, return -1, "Invalid param"); + if (buffer == NULL) { + *bufferSize = sizeof(ParamSecurityLabel); + return 0; + } + PARAM_CHECK(*bufferSize >= sizeof(ParamSecurityLabel), return -1, "Invalid buffersize %u", *bufferSize); + *bufferSize = sizeof(ParamSecurityLabel); + return memcpy_s(buffer, *bufferSize, srcLabel, sizeof(ParamSecurityLabel)); +} + +static int TestDecodeSecurityLabel(ParamSecurityLabel **srcLabel, char *buffer, uint32_t bufferSize) +{ + PARAM_CHECK(bufferSize >= sizeof(ParamSecurityLabel), return -1, "Invalid buffersize %u", bufferSize); + PARAM_CHECK(srcLabel != NULL && buffer != NULL, return -1, "Invalid param"); + *srcLabel = (ParamSecurityLabel *)buffer; + return 0; +} + +static int TestCheckParamPermission(const ParamSecurityLabel *srcLabel, const ParamAuditData *auditData, int mode) +{ + // DAC_RESULT_FORBIDED + return g_testPermissionResult; +} + +static int TestFreeLocalSecurityLabel(ParamSecurityLabel *srcLabel) +{ + return 0; +} \ No newline at end of file diff --git a/services/test/unittest/param/selinux_unittest.cpp b/services/test/unittest/param/selinux_unittest.cpp new file mode 100755 index 000000000..8b67faefd --- /dev/null +++ b/services/test/unittest/param/selinux_unittest.cpp @@ -0,0 +1,236 @@ +/* + * 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 +#include +#include +#include + +#include "param_security.h" +#include "param_unittest.h" +#include "param_utils.h" +#include "securec.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif +extern int RegisterSecuritySelinuxOps(ParamSecurityOps *ops, int isInit); +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +using namespace std; +#define CHECK_FILE_NAME "/media/sf_ubuntu/develop/startup/init_lite/services/test/unittest/test_data/build.prop" + +static int SecurityLabelGet(const ParamAuditData *auditData, void *context) +{ + return 0; +} + +class ParamSelinuxTest : public ::testing::Test { +public: + ParamSelinuxTest() {} + virtual ~ParamSelinuxTest() {} + + void SetUp() {} + void TearDown() {} + void TestBody() {} + + int TestSelinuxGetLabel() + { + int ret = RegisterSecuritySelinuxOps(&initParamSercurityOps, LABEL_INIT_FOR_INIT); + EXPECT_EQ(ret, 0); + + if (initParamSercurityOps.securityGetLabel == NULL) { + EXPECT_EQ(1, 0); + return -1; + } + ret = initParamSercurityOps.securityGetLabel(SecurityLabelGet, PARAM_DEFAULT_PATH, NULL); + EXPECT_EQ(ret, 0); + return 0; + } + + int TestSelinuxInitLocalLabel() + { + int ret = RegisterSecuritySelinuxOps(&initParamSercurityOps, LABEL_INIT_FOR_INIT); + EXPECT_EQ(ret, 0); + + if (initParamSercurityOps.securityInitLabel == NULL || initParamSercurityOps.securityFreeLabel == NULL) { + return -1; + } + ParamSecurityLabel *label = NULL; + ret = initParamSercurityOps.securityInitLabel(&label, LABEL_INIT_FOR_INIT); + EXPECT_EQ(ret, 0); + ret = initParamSercurityOps.securityFreeLabel(label); + EXPECT_EQ(ret, 0); + return 0; + } + + int TestSelinuxCheckFilePermission(const char *fileName) + { + int ret = RegisterSecuritySelinuxOps(&initParamSercurityOps, LABEL_INIT_FOR_INIT); + EXPECT_EQ(ret, 0); + if (initParamSercurityOps.securityCheckFilePermission == NULL) { + return -1; + } + ParamSecurityLabel *label = NULL; + ret = initParamSercurityOps.securityInitLabel(&label, LABEL_INIT_FOR_INIT); + EXPECT_EQ(ret, 0); + ret = initParamSercurityOps.securityCheckFilePermission(label, fileName, DAC_WRITE); + EXPECT_EQ(ret, 0); + ret = initParamSercurityOps.securityFreeLabel(label); + EXPECT_EQ(ret, 0); + return 0; + } + + int TestSelinuxCheckParaPermission(const char *name, const char *label) + { + int ret = RegisterSecuritySelinuxOps(&initParamSercurityOps, LABEL_INIT_FOR_INIT); + EXPECT_EQ(ret, 0); + if (initParamSercurityOps.securityCheckFilePermission == NULL) { + return -1; + } + ParamSecurityLabel *srclabel = NULL; + ret = initParamSercurityOps.securityInitLabel(&srclabel, LABEL_INIT_FOR_INIT); + EXPECT_EQ(ret, 0); + + ParamAuditData auditData = {}; + auditData.name = name; + // auditData.cr = srclabel->cred; // "u:object_r:default_prop:s0"; + auditData.label = label; + + ret = initParamSercurityOps.securityCheckParamPermission(srclabel, &auditData, DAC_WRITE); + EXPECT_EQ(ret, 0); + ret = initParamSercurityOps.securityFreeLabel(srclabel); + EXPECT_EQ(ret, 0); + return 0; + } + + int TestClientSelinuxCheckFilePermission(const char *fileName) + { + int ret = RegisterSecuritySelinuxOps(&clientParamSercurityOps, 0); + EXPECT_EQ(ret, 0); + if (clientParamSercurityOps.securityDecodeLabel != NULL) { + EXPECT_EQ(1, 0); + } + if (clientParamSercurityOps.securityGetLabel != NULL) { + EXPECT_EQ(1, 0); + } + if (clientParamSercurityOps.securityCheckFilePermission == NULL) { + EXPECT_EQ(1, 0); + return -1; + } + ParamSecurityLabel *label = NULL; + ret = clientParamSercurityOps.securityInitLabel(&label, 0); + EXPECT_EQ(ret, 0); + ret = clientParamSercurityOps.securityCheckFilePermission(label, fileName, DAC_READ); + EXPECT_EQ(ret, 0); + ret = clientParamSercurityOps.securityFreeLabel(label); + EXPECT_EQ(ret, 0); + return 0; + } + + int TestClientSelinuxCheckParaPermissionWrite(const char *name, const char *label) + { + int ret = RegisterSecuritySelinuxOps(&clientParamSercurityOps, 0); + EXPECT_EQ(ret, 0); + + if (clientParamSercurityOps.securityCheckFilePermission == NULL) { + return -1; + } + ParamSecurityLabel *srclabel = NULL; + ret = clientParamSercurityOps.securityInitLabel(&srclabel, 0); + EXPECT_EQ(ret, 0); + + ParamAuditData auditData = {}; + auditData.name = name; + // auditData.cr = srclabel->cred; // "u:object_r:default_prop:s0"; + auditData.label = label; + + ret = clientParamSercurityOps.securityCheckParamPermission(srclabel, &auditData, DAC_WRITE); + EXPECT_EQ(ret, 0); + ret = clientParamSercurityOps.securityFreeLabel(srclabel); + EXPECT_EQ(ret, 0); + return 0; + } + + int TestClientSelinuxCheckParaPermissionRead(const char *name, const char *label) + { + int ret = RegisterSecuritySelinuxOps(&clientParamSercurityOps, 0); + EXPECT_EQ(ret, 0); + if (clientParamSercurityOps.securityCheckFilePermission == NULL) { + return -1; + } + ParamSecurityLabel *srclabel = NULL; + ret = clientParamSercurityOps.securityInitLabel(&srclabel, 0); + EXPECT_EQ(ret, 0); + + ParamAuditData auditData = {}; + auditData.name = name; + // auditData.cr = srclabel->cred; // "u:object_r:default_prop:s0"; + auditData.label = label; + + ret = clientParamSercurityOps.securityCheckParamPermission(srclabel, &auditData, DAC_READ); + EXPECT_EQ(ret, 0); + ret = clientParamSercurityOps.securityFreeLabel(srclabel); + EXPECT_EQ(ret, 0); + return 0; + } + +private: + ParamSecurityOps initParamSercurityOps; + ParamSecurityOps clientParamSercurityOps; +}; + +TEST(ParamSelinuxTest, TestSelinuxGetLabel) +{ + ParamSelinuxTest test; + test.TestSelinuxGetLabel(); +} + +TEST(ParamSelinuxTest, TestSelinuxInitLocalLabel) +{ + ParamSelinuxTest test; + test.TestSelinuxInitLocalLabel(); +} + +TEST(ParamSelinuxTest, TestSelinuxCheckFilePermission) +{ + ParamSelinuxTest test; + test.TestSelinuxCheckFilePermission(CHECK_FILE_NAME); +} + +TEST(ParamSelinuxTest, TestSelinuxCheckParaPermission) +{ + ParamSelinuxTest test; + test.TestSelinuxCheckParaPermission("aaa.bbb.bbb.ccc", "user:group1:r"); +} + +TEST(ParamSelinuxTest, TestClientDacCheckFilePermission) +{ + ParamSelinuxTest test; + test.TestClientSelinuxCheckFilePermission(CHECK_FILE_NAME); +} + +TEST(ParamSelinuxTest, TestClientDacCheckParaPermission) +{ + ParamSelinuxTest test; + test.TestClientSelinuxCheckParaPermissionWrite("aaa.bbb.bbb.ccc", "user:group1:r"); + test.TestClientSelinuxCheckParaPermissionRead("aaa.bbb.bbb.ccc", "user:group1:r"); +} \ No newline at end of file diff --git a/services/test/unittest/param/service_unittest.cpp b/services/test/unittest/param/service_unittest.cpp new file mode 100755 index 000000000..e4cc0180a --- /dev/null +++ b/services/test/unittest/param/service_unittest.cpp @@ -0,0 +1,646 @@ +/* + * 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 +#include +#include +#include +#include + +#include "init_param.h" +#include "init_utils.h" +#include "param_libuvadp.h" +#include "param_manager.h" +#include "param_service.h" +#include "param_unittest.h" +#include "param_utils.h" +#include "trigger_manager.h" + +#define TEST_PARAM_NAME 0 +#define TEST_PARAM_VALUE 1 +#define DEFAULT_PARAM_FILE PARAM_DEFAULT_PATH "/etc/param" + +static int CheckServerParamValue(const char *name, const char *expectValue) +{ + char tmp[PARAM_BUFFER_SIZE] = { 0 }; + u_int32_t len = sizeof(tmp); + SystemReadParam(name, tmp, &len); + printf("CheckParamValue name %s value: \'%s\' expectValue:\'%s\' \n", name, tmp, expectValue); + EXPECT_NE(strlen(tmp), 0); + if (expectValue != NULL) { + EXPECT_EQ(strcmp(tmp, expectValue), 0); + } + return 0; +} + +ParamTask *g_worker = NULL; +class ParamServiceTest : public ::testing::Test { +public: + ParamServiceTest() {} + virtual ~ParamServiceTest() {} + + void SetUp() {} + void TearDown() {} + void TestBody() {} + + int TestParamServiceInit() + { + InitParamService(); + LoadDefaultParams(DEFAULT_PARAM_FILE, 0); + CheckServerParamValue("const.actionable_compatible_property.enabled", "false"); + CheckServerParamValue("build_version", "2.0"); + return 0; + } + + int TestSetParams(const char *params[][TEST_PARAM_VALUE + 1], int num) + { + for (int i = 0; i < num; i++) { + SystemWriteParam(params[i][TEST_PARAM_NAME], params[i][TEST_PARAM_VALUE]); + } + + // check + for (int i = 0; i < num; i++) { + CheckServerParamValue(params[i][TEST_PARAM_NAME], params[i][TEST_PARAM_VALUE]); + } + + for (int i = num - 1; i >= 0; i--) { + CheckServerParamValue(params[i][TEST_PARAM_NAME], params[i][TEST_PARAM_VALUE]); + } + return 0; + } + + int TestAddSecurityLabel1() + { + GetParamWorkSpace()->securityLabel->cred.gid = 9999; + const char *name = "label1.test.aaa.bbb.ccc.dddd.eee"; + const char *value = "2001"; + uint32_t labelIndex = 0; + SystemWriteParam(name, value); + // 获取到跟属性 + ParamTrieNode *paramNode = FindTrieNode(&GetParamWorkSpace()->paramSpace, name, strlen(name), &labelIndex); + ParamSecruityNode *node = (ParamSecruityNode *)GetTrieNode(&GetParamWorkSpace()->paramSpace, labelIndex); + if (paramNode == NULL || node == NULL) { + EXPECT_EQ(1, 0); + return 0; + } + EXPECT_EQ(node->gid, getegid()); + return 0; + } + + // 添加一个label,最长匹配到这个节点 + int TestAddSecurityLabel2() + { + GetParamWorkSpace()->securityLabel->cred.gid = 9999; + const char *name = "label2.test.aaa.bbb.ccc.dddd.eee"; + const char *value = "2001"; + ParamAuditData auditData = {}; + auditData.name = "label2.test.aaa"; + auditData.label = "label2.test.aaa"; + auditData.dacData.gid = 2002; + auditData.dacData.uid = geteuid(); + auditData.dacData.mode = 0666; + SystemWriteParam(name, value); + uint32_t labelIndex = 0; + AddSecurityLabel(&auditData, GetParamWorkSpace()); + ParamTrieNode *paramNode = FindTrieNode(&GetParamWorkSpace()->paramSpace, name, strlen(name), &labelIndex); + ParamSecruityNode *node = (ParamSecruityNode *)GetTrieNode(&GetParamWorkSpace()->paramSpace, labelIndex); + if (paramNode == NULL || node == NULL) { + EXPECT_EQ(1, 0); + } + EXPECT_EQ(node->gid, auditData.dacData.gid); + return 0; + } + + // 添加一个label,最长匹配到最后一个相同节点 + int TestAddSecurityLabel3() + { + GetParamWorkSpace()->securityLabel->cred.gid = 9999; + const char *name = "label3.test.aaa.bbb.ccc.dddd.eee"; + const char *value = "2001"; + ParamAuditData auditData = {}; + auditData.name = "label3.test.aaa"; + auditData.label = "label3.test.aaa"; + auditData.dacData.gid = 2003; + auditData.dacData.uid = geteuid(); + auditData.dacData.mode = 0666; + SystemWriteParam(name, value); + AddSecurityLabel(&auditData, GetParamWorkSpace()); + + auditData.name = "label3.test.aaa.bbb.ccc.dddd.eee.dddd"; + auditData.label = "label3.test.aaa.bbb.ccc.dddd.eee.dddd"; + auditData.dacData.gid = 2004; + auditData.dacData.uid = geteuid(); + auditData.dacData.mode = 0666; + SystemWriteParam(name, value); + AddSecurityLabel(&auditData, GetParamWorkSpace()); + + uint32_t labelIndex = 0; + ParamTrieNode *paramNode = FindTrieNode(&GetParamWorkSpace()->paramSpace, name, strlen(name), &labelIndex); + ParamSecruityNode *node = (ParamSecruityNode *)GetTrieNode(&GetParamWorkSpace()->paramSpace, labelIndex); + if (paramNode == NULL || node == NULL) { + EXPECT_EQ(1, 0); + } + EXPECT_EQ(node->gid, 2003); + return 0; + } + + // 添加一个label,完全匹配 + int TestAddSecurityLabel4() + { + GetParamWorkSpace()->securityLabel->cred.gid = 9999; + const char *name = "label4.test.aaa.bbb.ccc.dddd.eee"; + const char *value = "2001"; + ParamAuditData auditData = {}; + auditData.name = "label4.test.aaa.bbb.ccc.dddd.eee"; + auditData.label = "label4.test.aaa.bbb.ccc.dddd.eee"; + auditData.dacData.gid = 2004; + auditData.dacData.uid = geteuid(); + auditData.dacData.mode = 0666; + SystemWriteParam(name, value); + uint32_t labelIndex = 0; + AddSecurityLabel(&auditData, GetParamWorkSpace()); + ParamTrieNode *paramNode = FindTrieNode(&GetParamWorkSpace()->paramSpace, name, strlen(name), &labelIndex); + ParamSecruityNode *node = (ParamSecruityNode *)GetTrieNode(&GetParamWorkSpace()->paramSpace, labelIndex); + if (paramNode == NULL || node == NULL) { + EXPECT_EQ(1, 0); + } + EXPECT_EQ(node->gid, auditData.dacData.gid); + return 0; + } + + void TestBufferValue(char *buffer, uint32_t len) + { + for (uint32_t index = 0; index <= len; index++) { + buffer[index] = '0' + index % 10; + if (index != 0 && index % 10 == 0) { + buffer[index] = '.'; + } + } + buffer[len] = '\0'; + } + + int TestNameIsValid() + { + char buffer[PARAM_BUFFER_SIZE]; + // set name length = 127 + TestBufferValue(buffer, PARAM_NAME_LEN_MAX - 1); + int ret = SystemWriteParam(buffer, "1111"); + EXPECT_EQ(ret, 0); + TestBufferValue(buffer, PARAM_NAME_LEN_MAX); + ret = SystemWriteParam(buffer, "1111"); + EXPECT_NE(ret, 0); + TestBufferValue(buffer, PARAM_NAME_LEN_MAX + 1); + ret = SystemWriteParam(buffer, "1111"); + EXPECT_NE(ret, 0); + + // 保存一个只读的属性,大于最大值 + TestBufferValue(buffer, PARAM_VALUE_LEN_MAX - 1); + ret = SystemWriteParam("const.test_readonly.dddddddddddddddddd.fffffffffffffffffff", buffer); + EXPECT_EQ(ret, 0); + + TestBufferValue(buffer, PARAM_VALUE_LEN_MAX + 1); + ret = SystemWriteParam("const.test_readonly.aaaaaaaaaaaaaaaaaa.fffffffffffffffffff", buffer); + EXPECT_EQ(ret, 0); + + // 更新只读项目 + TestBufferValue(buffer, PARAM_VALUE_LEN_MAX - 1); + ret = SystemWriteParam("const.test_readonly.dddddddddddddddddd.fffffffffffffffffff", buffer); + EXPECT_NE(ret, 0); + + // 写普通属性 + TestBufferValue(buffer, PARAM_VALUE_LEN_MAX - 1); + ret = SystemWriteParam("test.bigvalue.dddddddddddddddddd.fffffffffffffffffff", buffer); + EXPECT_EQ(ret, 0); + TestBufferValue(buffer, PARAM_VALUE_LEN_MAX + 1); + ret = SystemWriteParam("test.bigvalue.dddddddddddddddddd.fffffffffffffffffff", buffer); + EXPECT_NE(ret, 0); + + // invalid name + TestBufferValue(buffer, PARAM_VALUE_LEN_MAX - 1); + ret = SystemWriteParam("test.invalidname..fffffffffffffffffff", buffer); + EXPECT_NE(ret, 0); + ret = SystemWriteParam("test.invalidname.%fffffffffffffffffff", buffer); + EXPECT_NE(ret, 0); + ret = SystemWriteParam("test.invalidname.$fffffffffffffffffff", buffer); + EXPECT_NE(ret, 0); + return 0; + } + + int TestParamTraversal() + { + char value[PARAM_BUFFER_SIZE + PARAM_BUFFER_SIZE] = { 0 }; + SystemTraversalParam( + [](ParamHandle handle, void *cookie) { + ReadParamName(GetParamWorkSpace(), handle, (char *)cookie, PARAM_BUFFER_SIZE); + u_int32_t len = PARAM_BUFFER_SIZE; + ReadParamValue(GetParamWorkSpace(), handle, ((char *)cookie) + PARAM_BUFFER_SIZE, &len); + printf("$$$$$$$$Param %s=%s \n", (char *)cookie, ((char *)cookie) + PARAM_BUFFER_SIZE); + }, + (void *)value); + return 0; + } + + int TestUpdateParam(const char *name, const char *value) + { + SystemWriteParam(name, value); + SystemWriteParam(name, value); + SystemWriteParam(name, value); + SystemWriteParam(name, value); + CheckServerParamValue(name, value); + return 0; + } + + int TestPersistParam() + { + LoadPersistParams(); + SystemWriteParam("persist.111.ffff.bbbb.cccc.dddd.eeee", "1101"); + SystemWriteParam("persist.111.aaaa.bbbb.cccc.dddd.eeee", "1102"); + SystemWriteParam("persist.111.bbbb.cccc.dddd.eeee", "1103"); + CheckServerParamValue("persist.111.bbbb.cccc.dddd.eeee", "1103"); + SystemWriteParam("persist.111.cccc.bbbb.cccc.dddd.eeee", "1104"); + SystemWriteParam("persist.111.eeee.bbbb.cccc.dddd.eeee", "1105"); + CheckServerParamValue("persist.111.ffff.bbbb.cccc.dddd.eeee", "1101"); + SystemWriteParam("persist.111.ffff.bbbb.cccc.dddd.eeee", "1106"); + LoadPersistParams(); + CheckServerParamValue("persist.111.ffff.bbbb.cccc.dddd.eeee", "1106"); + return 0; + } + + int FillLabelContent(ParamSecurityOps *paramSecurityOps, ParamMessage *request, uint32_t *start, uint32_t length) + { + uint32_t bufferSize = request->msgSize - sizeof(ParamMessage); + uint32_t offset = *start; + PARAM_CHECK((offset + sizeof(ParamMsgContent) + length) <= bufferSize, + return -1, "Invalid msgSize %u offset %u", request->msgSize, offset); + ParamMsgContent *content = (ParamMsgContent *)(request->data + offset); + content->type = PARAM_LABEL; + content->contentSize = 0; + if (length != 0 && paramSecurityOps->securityEncodeLabel != NULL) { + int ret = paramSecurityOps->securityEncodeLabel( + GetParamWorkSpace()->securityLabel, content->content, &length); + PARAM_CHECK(ret == 0, return -1, "Failed to get label length"); + content->contentSize = length; + } + offset += sizeof(ParamMsgContent) + PARAM_ALIGN(content->contentSize); + *start = offset; + return 0; + } + + ParamTask *CreateAndGetStreamTask() + { + LibuvServerTask *server = (LibuvServerTask *)GetParamWorkSpace()->serverTask; + if (server == NULL) { + EXPECT_NE(0, 0); + return NULL; + } + + // 创建stream task + server->incomingConnect((ParamTaskPtr)server, WORKER_TYPE_TEST); + ParamWatcher *watcher = GetNextParamWatcher(GetTriggerWorkSpace(), NULL); + return watcher != NULL ? watcher->stream : NULL; + } + + int TestServiceProcessMessage(const char *name, const char *value, int userLabel) + { + if (g_worker == NULL) { + g_worker = CreateAndGetStreamTask(); + } + uint32_t labelLen = 0; + ParamSecurityOps *paramSecurityOps = &GetParamWorkSpace()->paramSecurityOps; + if (userLabel) { + paramSecurityOps->securityEncodeLabel = TestEncodeSecurityLabel; + paramSecurityOps->securityDecodeLabel = TestDecodeSecurityLabel; + paramSecurityOps->securityFreeLabel = TestFreeLocalSecurityLabel; + paramSecurityOps->securityCheckParamPermission = TestCheckParamPermission; + } + uint32_t msgSize = sizeof(ParamMessage) + sizeof(ParamMsgContent) + PARAM_ALIGN(strlen(value) + 1); + if (paramSecurityOps->securityEncodeLabel != NULL) { + int ret = paramSecurityOps->securityEncodeLabel(GetParamWorkSpace()->securityLabel, NULL, &labelLen); + PARAM_CHECK(ret == 0, return -1, "Failed to get label length"); + msgSize += sizeof(ParamMsgContent) + PARAM_ALIGN(labelLen); + } + ParamMessage *request = (ParamMessage *)CreateParamMessage(MSG_SET_PARAM, name, msgSize); + PARAM_CHECK(request != NULL, return -1, "Failed to malloc for connect"); + do { + request->type = MSG_SET_PARAM; + uint32_t offset = 0; + int ret = FillParamMsgContent(request, &offset, PARAM_VALUE, value, strlen(value)); + PARAM_CHECK(ret == 0, return -1, "Failed to fill value"); + ret = FillLabelContent(paramSecurityOps, request, &offset, labelLen); + PARAM_CHECK(ret == 0, return -1, "Failed to fill label"); + ProcessMessage((const ParamTaskPtr)g_worker, (const ParamMessage *)request); + } while (0); + free(request); + CheckServerParamValue(name, value); + RegisterSecurityOps(paramSecurityOps, 1); + return 0; + } + + int AddWatch(int type, const char *name, const char *value) + { + if (g_worker == NULL) { + g_worker = CreateAndGetStreamTask(); + } + uint32_t msgSize = sizeof(ParamMessage) + sizeof(ParamMsgContent) + PARAM_ALIGN(strlen(value) + 1); + ParamMessage *request = (ParamMessage *)(ParamMessage *)CreateParamMessage(MSG_SET_PARAM, name, msgSize); + PARAM_CHECK(request != NULL, return -1, "Failed to malloc for connect"); + do { + uint32_t offset = 0; + int ret = FillParamMsgContent(request, &offset, PARAM_VALUE, value, strlen(value)); + PARAM_CHECK(ret == 0, return -1, "Failed to fill value"); + ProcessMessage((const ParamTaskPtr)g_worker, (const ParamMessage *)request); + } while (0); + free(request); + return 0; + } + + // 无匹配 + int TestAddParamWait1() + { + const char *name = "wait.aaa.bbb.ccc.111"; + const char *value = "wait1"; + AddWatch(MSG_WAIT_PARAM, name, value); + SystemWriteParam(name, value); + return 0; + } + + // 模糊匹配 + int TestAddParamWait2() + { + const char *name = "wait.aaa.bbb.ccc.222"; + const char *value = "wait2"; + AddWatch(MSG_WAIT_PARAM, name, "*"); + SystemWriteParam(name, value); + return 0; + } + + // 属性存在 + int TestAddParamWait3() + { + const char *name = "wait.aaa.bbb.ccc.333"; + const char *value = "wait3"; + SystemWriteParam(name, value); + AddWatch(MSG_WAIT_PARAM, name, value); + return 0; + } + + int TestAddParamWatch1() + { + const char *name = "watch.aaa.bbb.ccc.111"; + const char *value = "watch1"; + AddWatch(MSG_ADD_WATCHER, name, value); + std::string newName = name; + newName += ".test.test.test"; + SystemWriteParam(newName.c_str(), value); + return 0; + } + + int TestAddParamWatch2() + { + const char *name = "watch.aaa.bbb.ccc.222"; + const char *value = "watch2"; + AddWatch(MSG_ADD_WATCHER, name, "*"); + SystemWriteParam(name, value); + return 0; + } + + int TestAddParamWatch3() + { + const char *name = "watch.aaa.bbb.ccc.333"; + const char *value = "watch3"; + std::string newName = name; + newName += ".test.test.test"; + SystemWriteParam(newName.c_str(), value); + AddWatch(MSG_ADD_WATCHER, name, value); + return 0; + } + + int TestCloseTriggerWatch() + { + ParamTaskClose(g_worker); + g_worker = NULL; + return 0; + } + + int TestDumpParamMemory() + { + DumpParameters(GetParamWorkSpace(), 1); + return 0; + } + + int TestServiceCtrl(const char *serviceName, int mode) + { + // service forbit + ParamAuditData auditData = {}; + auditData.name = "ohos.servicectrl."; + auditData.label = ""; + auditData.dacData.gid = 2002; + auditData.dacData.uid = 2002; + auditData.dacData.mode = mode; + AddSecurityLabel(&auditData, GetParamWorkSpace()); + return SystemWriteParam("ohos.ctl.start", serviceName); + } + + int TestPowerCtrl(const char *reboot, int mode) + { + // service forbit + ParamAuditData auditData = {}; + auditData.name = "ohos.servicectrl."; + auditData.label = ""; + auditData.dacData.gid = 2002; + auditData.dacData.uid = 2002; + auditData.dacData.mode = mode; + AddSecurityLabel(&auditData, GetParamWorkSpace()); + return SystemWriteParam("sys.powerctrl", reboot); + } +}; + +TEST(ParamServiceTest, TestParamServiceInit) +{ + ParamServiceTest test; + test.TestParamServiceInit(); +} + +TEST(ParamServiceTest, TestPersistParam) +{ + ParamServiceTest test; + test.TestPersistParam(); +} + +TEST(ParamServiceTest, TestSetParam_1) +{ + ParamServiceTest test; + const char *params[][2] = { { "111.2222", "1" }, + { "111.2222.3333", "2" }, + { "111.2222.3333.4444", "3" }, + { "111.2222.3333.4444.666", "4" }, + { "111.2222.3333.4444.666.777", "5" } }; + test.TestSetParams(params, 5); +} + +TEST(ParamServiceTest, TestSetParam_2) +{ + ParamServiceTest test; + const char *params[][2] = { { "111.2222.xxxx.xxx.xxx", "1_1" }, + { "111.2222.3333.xxx", "1_2" }, + { "111.2222.xxxx.3333.4444", "1_3" }, + { "111.2222.3333.xxxx.4444.666", "1_4" }, + { "111.2222.3333.4444.666.xxxxx.777", "1_5" } }; + test.TestSetParams(params, 5); + + const char *ctrlParams[][2] = { { "ctl.start.111.2222.xxxx.xxx.xxx", "2_1" }, + { "ctl.start.111.2222.3333.xxx", "2_2" }, + { "ctl.start.111.2222.xxxx.3333.4444", "2_3" }, + { "ctl.start.111.2222.3333.xxxx.4444.666", "2_4" }, + { "ctl.start.111.2222.3333.4444.666.xxxxx.777", "2_5" } }; + test.TestSetParams(ctrlParams, 5); + + const char *sysParams[][2] = { { "sys.powerctrl.111.2222.xxxx.xxx.xxx", "3_1" }, + { "sys.powerctrl.111.2222.3333.xxx", "3_2" }, + { "sys.powerctrl.111.2222.xxxx.3333.4444", "3_3" }, + { "sys.powerctrl.111.2222.3333.xxxx.4444.666", "3_4" }, + { "sys.powerctrl.111.2222.3333.4444.666.xxxxx.777", "3_5" } }; + test.TestSetParams(sysParams, 5); +} + +TEST(ParamServiceTest, TestNameIsValid) +{ + ParamServiceTest test; + test.TestNameIsValid(); +} + +TEST(ParamServiceTest, TestAddSecurityLabel1) +{ + ParamServiceTest test; + test.TestAddSecurityLabel1(); +} + +TEST(ParamServiceTest, TestAddSecurityLabel2) +{ + ParamServiceTest test; + test.TestAddSecurityLabel2(); +} + +TEST(ParamServiceTest, TestAddSecurityLabel3) +{ + ParamServiceTest test; + test.TestAddSecurityLabel3(); +} + +TEST(ParamServiceTest, TestAddSecurityLabel4) +{ + ParamServiceTest test; + test.TestAddSecurityLabel4(); +} + +TEST(ParamServiceTest, TestUpdateParam) +{ + ParamServiceTest test; + test.TestUpdateParam("test.aaa.bbb.ccc.ddd", "100"); + test.TestUpdateParam("test.aaa.bbb.ccc.ddd", "101"); + test.TestUpdateParam("test.aaa.bbb.ccc.ddd", "102"); + test.TestUpdateParam("test.aaa.bbb.ccc.ddd", "103"); + test.TestUpdateParam("net.tcp.default_init_rwnd", "60"); +} + +TEST(ParamServiceTest, TestServiceProcessMessage) +{ + ParamServiceTest test; + test.TestServiceProcessMessage("wertt.qqqq.wwww.rrrr", "wwww.eeeee", 1); + test.TestServiceProcessMessage("wertt.2222.wwww.3333", "wwww.eeeee", 0); +} + +TEST(ParamServiceTest, TestAddParamWait1) +{ + ParamServiceTest test; + test.TestAddParamWait1(); +} + +TEST(ParamServiceTest, TestAddParamWait2) +{ + ParamServiceTest test; + test.TestAddParamWait2(); +} + +TEST(ParamServiceTest, TestAddParamWait3) +{ + ParamServiceTest test; + test.TestAddParamWait3(); +} + +TEST(ParamServiceTest, TestAddParamWatch1) +{ + ParamServiceTest test; + test.TestAddParamWatch1(); +} + +TEST(ParamServiceTest, TestAddParamWatch2) +{ + ParamServiceTest test; + test.TestAddParamWatch2(); +} + +TEST(ParamServiceTest, TestAddParamWatch3) +{ + ParamServiceTest test; + test.TestAddParamWatch3(); +} + +TEST(ParamServiceTest, TestCloseTriggerWatch) +{ + ParamServiceTest test; + test.TestCloseTriggerWatch(); +} + +TEST(ParamServiceTest, TestParamTraversal) +{ + ParamServiceTest test; + test.TestParamTraversal(); +} + +TEST(ParamServiceTest, TestDumpParamMemory) +{ + ParamServiceTest test; + test.TestDumpParamMemory(); +} + +TEST(ParamServiceTest, TestServiceCtrl) +{ + ParamServiceTest test; + int ret = test.TestServiceCtrl("server1", 0770); + EXPECT_NE(ret, 0); + ret = test.TestServiceCtrl("server2", 0772); + EXPECT_EQ(ret, 0); +} + +TEST(ParamServiceTest, TestPowerCtrl) +{ + ParamServiceTest test; + int ret = test.TestPowerCtrl("reboot,shutdown", 0770); + EXPECT_NE(ret, 0); + ret = test.TestPowerCtrl("reboot,shutdown", 0772); + EXPECT_EQ(ret, 0); + ret = test.TestPowerCtrl("reboot,updater", 0770); + EXPECT_NE(ret, 0); + ret = test.TestPowerCtrl("reboot,updater", 0772); + EXPECT_EQ(ret, 0); + ret = test.TestPowerCtrl("reboot,flashing", 0770); + EXPECT_NE(ret, 0); + ret = test.TestPowerCtrl("reboot,flashing", 0772); + EXPECT_EQ(ret, 0); + ret = test.TestPowerCtrl("reboot", 0770); + EXPECT_NE(ret, 0); + ret = test.TestPowerCtrl("reboot", 0772); + EXPECT_EQ(ret, 0); +} \ No newline at end of file diff --git a/services/test/unittest/param/trigger_unittest.cpp b/services/test/unittest/param/trigger_unittest.cpp new file mode 100755 index 000000000..d2644fd86 --- /dev/null +++ b/services/test/unittest/param/trigger_unittest.cpp @@ -0,0 +1,536 @@ +/* + * 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 +#include +#include +#include + +#include "init_jobs.h" +#include "init_param.h" +#include "init_read_cfg.h" +#include "init_utils.h" +#include "param_libuvadp.h" +#include "param_manager.h" +#include "param_service.h" +#include "param_unittest.h" +#include "param_utils.h" +#include "securec.h" +#include "trigger_checker.h" +#include "trigger_manager.h" + +using namespace std; + +#define TRIGGER_FIEL_NAME PARAM_DEFAULT_PATH "/etc/init.cfg" +#define TRIGGER_TEST_FIEL_NAME PARAM_DEFAULT_PATH "/trigger_test.cfg" +#define LOAD_PARAM_DEFAULT_CMD PARAM_DEFAULT_PATH "//ohos.para onlyadd" + +int g_execCmdId = 0; +int g_matchTrigger = 0; +char g_matchTriggerName[256] = {}; +static void TestCmdExec(TriggerNode *trigger, CommandNode *cmd, const char *content, uint32_t size) +{ + if (cmd->cmdKeyIndex == CMD_INDEX_FOR_PARA_WAIT || cmd->cmdKeyIndex == CMD_INDEX_FOR_PARA_WATCH) { + TriggerExtData *extData = TRIGGER_GET_EXT_DATA(trigger, TriggerExtData); + if (extData != NULL && extData->excuteCmd != NULL) { + extData->excuteCmd(extData, cmd->cmdKeyIndex, content); + } + return; + } + g_execCmdId = cmd->cmdKeyIndex; +} + +static int TestTriggerExecute(TriggerNode *trigger, const char *content, uint32_t size) +{ + int ret = memcpy_s(g_matchTriggerName, (int)sizeof(g_matchTriggerName) - 1, trigger->name, strlen(trigger->name)); + EXPECT_EQ(ret, 0); + g_matchTriggerName[strlen(trigger->name)] = '\0'; + g_matchTrigger++; + return 0; +} + +class TriggerTest : public ::testing::Test { +public: + TriggerTest() {} + virtual ~TriggerTest() {} + + void SetUp() {} + void TearDown() {} + void TestBody() {} + + int TestLoadTrigger() + { + ParseInitCfg(TRIGGER_FIEL_NAME); + ParseInitCfg(TRIGGER_TEST_FIEL_NAME); + // trigger + PostTrigger(EVENT_TRIGGER_BOOT, "pre-init", strlen("pre-init")); + PostTrigger(EVENT_TRIGGER_BOOT, "init", strlen("init")); + PostTrigger(EVENT_TRIGGER_BOOT, "post-init", strlen("post-init")); + LibuvEventTask *task = (LibuvEventTask *)(GetTriggerWorkSpace()->eventHandle); + // 触发队列执行 + task->process(1, NULL, 0); + + DoCmdByName("load_param ", LOAD_PARAM_DEFAULT_CMD); + return 0; + } + + TriggerHeader *GetTriggerHeader(int type) + { + return &GetTriggerWorkSpace()->triggerHead[type]; + } + + int TestAddTriggerForBoot() + { + TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_BOOT), "init-later", "", 0); + TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), "init-later"); + EXPECT_EQ(node, trigger); + EXPECT_EQ(strcmp(trigger->name, "init-later"), 0); + + // add command + uint32_t cmdIndex = 0; + GetMatchCmd("reboot ", &cmdIndex); + int ret = AddCommand(trigger, cmdIndex, NULL); + EXPECT_EQ(ret, 0); + ret = AddCommand(trigger, cmdIndex, "update: aaaaaaa"); + EXPECT_EQ(ret, 0); + return 0; + } + + int TestAddTriggerForParm() + { + const char *triggerName = "param:test_param.000"; + TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_PARAM), triggerName, "test_param.000=1", 0); + TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); + EXPECT_EQ(trigger, node); + EXPECT_EQ(strcmp(trigger->name, triggerName), 0); + + // add command + uint32_t cmdIndex = 0; + GetMatchCmd("reboot ", &cmdIndex); + int ret = AddCommand(trigger, cmdIndex, NULL); + ret |= AddCommand(trigger, cmdIndex, "update: aaaaaaa"); + EXPECT_EQ(ret, 0); + return 0; + } + + int TestParamEvent() + { + PostParamTrigger(EVENT_TRIGGER_PARAM, "net.tcp.default_init_rwnd", "60"); + const char *sysctrl = "sys.powerctrl=reboot, shutdown"; + PostTrigger(EVENT_TRIGGER_PARAM, sysctrl, strlen(sysctrl)); + PostParamTrigger(EVENT_TRIGGER_PARAM, "sys.powerctrl", "reboot, shutdown"); + + const char *startCmd = "ohos.ctl.start=hdc -t"; + PostTrigger(EVENT_TRIGGER_PARAM, startCmd, strlen(startCmd)); + PostParamTrigger(EVENT_TRIGGER_PARAM, "ohos.ctl.start", "hdc -t"); + + const char *stopCmd = "ohos.ctl.stop=hdc -t"; + PostTrigger(EVENT_TRIGGER_PARAM, stopCmd, strlen(stopCmd)); + PostParamTrigger(EVENT_TRIGGER_PARAM, "ohos.ctl.stop", "hdc -t"); + return 0; + } + + int TestBootEvent(const char *boot) + { + PostTrigger(EVENT_TRIGGER_BOOT, boot, strlen(boot)); + return 0; + } + + int TestCheckParamTrigger1() + { + const char *triggerName = "param:test_param.111"; + const char *param = "test_param.aaa.111.2222"; + const char *value = "1"; + char buffer[512]; + int ret = sprintf_s(buffer, sizeof(buffer), "%s=%s", param, value); + TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_PARAM), triggerName, buffer, 0); + TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); + EXPECT_EQ(trigger, node); + + g_matchTrigger = 0; + ret = sprintf_s(buffer, sizeof(buffer), "%s=%s", param, "2"); + CheckTrigger(GetTriggerWorkSpace(), TRIGGER_PARAM, buffer, strlen(buffer), TestTriggerExecute); + EXPECT_EQ(0, g_matchTrigger); + + g_matchTrigger = 0; + ret = sprintf_s(buffer, sizeof(buffer), "%s=%s", param, value); + CheckTrigger(GetTriggerWorkSpace(), TRIGGER_PARAM, buffer, strlen(buffer), TestTriggerExecute); + EXPECT_EQ(1, g_matchTrigger); + EXPECT_EQ(0, strcmp(triggerName, g_matchTriggerName)); + return 0; + } + + int TestCheckParamTrigger2() + { + const char *triggerName = "param:test_param.222"; + const char *param = "test_param.aaa.222.2222"; + const char *value = "1"; + char buffer[512]; + int ret = sprintf_s(buffer, sizeof(buffer), "%s=*", param); + TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_PARAM), triggerName, buffer, 0); + TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); + EXPECT_EQ(trigger, node); + + g_matchTrigger = 0; + ret = sprintf_s(buffer, sizeof(buffer), "%s=%s", param, "2"); + CheckTrigger(GetTriggerWorkSpace(), TRIGGER_PARAM, buffer, strlen(buffer), TestTriggerExecute); + EXPECT_EQ(1, g_matchTrigger); + EXPECT_EQ(0, strcmp(triggerName, g_matchTriggerName)); + + g_matchTrigger = 0; + ret = sprintf_s(buffer, sizeof(buffer), "%s=%s", param, value); + CheckTrigger(GetTriggerWorkSpace(), TRIGGER_PARAM, param, strlen(param), TestTriggerExecute); + EXPECT_EQ(1, g_matchTrigger); + EXPECT_EQ(0, strcmp(triggerName, g_matchTriggerName)); + return 0; + } + + int TestCheckParamTrigger3() + { + const char *triggerName = "param:test_param.333"; + const char *param1 = "test_param.aaa.333.2222=1"; + const char *param2 = "test_param.aaa.333.3333=2"; + char buffer[512]; + sprintf_s(buffer, sizeof(buffer), "%s || %s", param1, param2); + TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_PARAM), triggerName, buffer, 0); + TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); + EXPECT_EQ(trigger, node); + + g_matchTrigger = 0; + CheckTrigger(GetTriggerWorkSpace(), TRIGGER_PARAM, param1, strlen(param1), TestTriggerExecute); + EXPECT_EQ(1, g_matchTrigger); + EXPECT_EQ(0, strcmp(triggerName, g_matchTriggerName)); + + g_matchTrigger = 0; + CheckTrigger(GetTriggerWorkSpace(), TRIGGER_PARAM, param2, strlen(param2), TestTriggerExecute); + EXPECT_EQ(1, g_matchTrigger); + EXPECT_EQ(0, strcmp(triggerName, g_matchTriggerName)); + return 0; + } + + int TestCheckParamTrigger4() + { + const char *triggerName = "param:test_param.444"; + const char *param1 = "test_param.aaa.444.2222"; + const char *param2 = "test_param.aaa.444.3333"; + char buffer[512]; + sprintf_s(buffer, sizeof(buffer), "%s=%s && %s=%s", param1, "1", param2, "2"); + TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_PARAM), triggerName, buffer, 0); + TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); + EXPECT_EQ(trigger, node); + + g_matchTrigger = 0; + SystemWriteParam(param1, "1"); + sprintf_s(buffer, sizeof(buffer), "%s=%s", param1, "1"); + CheckTrigger(GetTriggerWorkSpace(), TRIGGER_PARAM, buffer, strlen(buffer), TestTriggerExecute); + EXPECT_EQ(0, g_matchTrigger); + + SystemWriteParam(param2, "2"); + g_matchTrigger = 0; + sprintf_s(buffer, sizeof(buffer), "%s=%s", param2, "2"); + CheckTrigger(GetTriggerWorkSpace(), TRIGGER_PARAM, buffer, strlen(buffer), TestTriggerExecute); + EXPECT_EQ(1, g_matchTrigger); + EXPECT_EQ(0, strcmp(triggerName, g_matchTriggerName)); + return 0; + } + + // test for trigger aaaa:test_param.aaa 被加入unknown执行 + int TestCheckParamTrigger5() + { + const char *triggerName = "aaaa:test_param.aaa"; + const char *param1 = "test_param.aaa.aaa.2222"; + const char *param2 = "test_param.aaa.aaa.3333"; + char buffer[512]; + sprintf_s(buffer, sizeof(buffer), "aaaa && %s=%s && %s=%s", param1, "1", param2, "2"); + TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_UNKNOW), triggerName, buffer, 0); + TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); + EXPECT_EQ(trigger, node); + + g_matchTrigger = 0; + SystemWriteParam(param1, "1"); + sprintf_s(buffer, sizeof(buffer), "%s=%s", param1, "1"); + CheckTrigger(GetTriggerWorkSpace(), TRIGGER_PARAM, buffer, strlen(buffer), TestTriggerExecute); + EXPECT_EQ(0, g_matchTrigger); + + SystemWriteParam(param2, "2"); + g_matchTrigger = 0; + CheckTrigger(GetTriggerWorkSpace(), TRIGGER_UNKNOW, "aaaa", strlen("aaaa"), TestTriggerExecute); + EXPECT_EQ(1, g_matchTrigger); + EXPECT_EQ(0, strcmp(triggerName, g_matchTriggerName)); + return 0; + } + + int TestComputeCondition(const char *condition, const char *content, int contentSize) + { + u_int32_t size = strlen(condition) + 20; + char *prefix = (char *)malloc(size); + ConvertInfixToPrefix(condition, prefix, size); + printf("prefix %s \n", prefix); + free(prefix); + return 0; + } + + // 普通的属性trigger + int TestExecuteParamTrigger1() + { + const char *triggerName = "aaaa:test_param.eee"; + const char *param = "test_param.eee.aaa.1111"; + const char *value = "eee"; + char buffer[512]; + sprintf_s(buffer, sizeof(buffer), "%s=%s", param, value); + TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_PARAM), triggerName, buffer, 0); + TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); + EXPECT_EQ(trigger, node); + + const uint32_t cmdIndex = 100; + int ret = AddCommand(trigger, cmdIndex, value); + EXPECT_EQ(ret, 0); + // 修改命令为测试执行 + GetTriggerWorkSpace()->cmdExec = TestCmdExec; + LibuvEventTask *task = (LibuvEventTask *)(GetTriggerWorkSpace()->eventHandle); + SystemWriteParam(param, value); + // 触发队列执行 + task->process(1, NULL, 0); + EXPECT_EQ(g_execCmdId, cmdIndex); + return 0; + } + + int TestExecuteParamTrigger2() + { + const char *triggerName = "param:test_param.dddd"; + const char *param = "test_param.dddd.aaa.2222"; + const char *value = "2222"; + char buffer[512]; + sprintf_s(buffer, sizeof(buffer), "%s=%s", param, value); + TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_PARAM), triggerName, buffer, 0); + TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); + EXPECT_EQ(trigger, node); + const uint32_t cmdIndex = 102; + int ret = AddCommand(trigger, cmdIndex, value); + EXPECT_EQ(ret, 0); + // 修改命令为测试执行 + GetTriggerWorkSpace()->cmdExec = TestCmdExec; + LibuvEventTask *task = (LibuvEventTask *)(GetTriggerWorkSpace()->eventHandle); + task->beforeProcess(EVENT_TRIGGER_PARAM, buffer, strlen(buffer)); + // 触发队列执行 + task->process(EVENT_TRIGGER_PARAM, NULL, 0); + EXPECT_EQ(g_execCmdId, cmdIndex); + return 0; + } + + // 测试执行后立刻删除 + int TestExecuteParamTrigger3() + { + const char *triggerName = "param:test_param.3333"; + const char *param = "test_param.dddd.aaa.3333"; + const char *value = "3333"; + char buffer[512]; + sprintf_s(buffer, sizeof(buffer), "%s=%s", param, value); + TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_PARAM), triggerName, buffer, 0); + TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); + EXPECT_EQ(trigger, node); + const uint32_t cmdIndex = 103; + int ret = AddCommand(trigger, cmdIndex, value); + EXPECT_EQ(ret, 0); + TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_ONCE); + + // 修改命令为测试执行 + GetTriggerWorkSpace()->cmdExec = TestCmdExec; + LibuvEventTask *task = (LibuvEventTask *)(GetTriggerWorkSpace()->eventHandle); + task->beforeProcess(EVENT_TRIGGER_PARAM, buffer, strlen(buffer)); + // 触发队列执行 + task->process(EVENT_TRIGGER_PARAM, NULL, 0); + EXPECT_EQ(g_execCmdId, cmdIndex); + trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); + if (trigger != NULL) { + EXPECT_EQ(1, 0); + } + return 0; + } + + // 测试删除队列中的trigger + int TestExecuteParamTrigger4() + { + const char *triggerName = "param:test_param.4444"; + const char *param = "test_param.dddd.aaa.4444"; + const char *value = "4444"; + char buffer[512]; + sprintf_s(buffer, sizeof(buffer), "%s=%s", param, value); + TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_PARAM), triggerName, buffer, 0); + TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); + EXPECT_EQ(trigger, node); + const uint32_t cmdIndex = 105; + int ret = AddCommand(trigger, cmdIndex, value); + EXPECT_EQ(ret, 0); + TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_ONCE); + + // 修改命令为测试执行 + GetTriggerWorkSpace()->cmdExec = TestCmdExec; + LibuvEventTask *task = (LibuvEventTask *)(GetTriggerWorkSpace()->eventHandle); + task->beforeProcess(EVENT_TRIGGER_PARAM, buffer, strlen(buffer)); + + // 删除对应的trigger + FreeTrigger(trigger); + + // 触发队列执行 + task->process(EVENT_TRIGGER_PARAM, NULL, 0); + EXPECT_NE(g_execCmdId, cmdIndex); + trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); + if (trigger != NULL) { + EXPECT_EQ(1, 0); + } + return 0; + } + + // 测试执行后检查子trigger执行 + int TestExecuteParamTrigger5() + { + const char *boot = "boot2"; + const char *triggerName = "boot2:test_param.5555"; + const char *param = "test_param.dddd.aaa.5555"; + const char *value = "5555"; + TriggerNode *trigger = AddTrigger(GetTriggerHeader(TRIGGER_BOOT), boot, NULL, 0); + int ret = AddCommand(trigger, 1105, value); + EXPECT_EQ(ret, 0); + TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_SUBTRIGGER); + + char buffer[512]; + sprintf_s(buffer, sizeof(buffer), "boot2 && %s=%s", param, value); + trigger = AddTrigger(GetTriggerHeader(TRIGGER_UNKNOW), triggerName, buffer, 0); + ret = AddCommand(trigger, 105, value); + + // 修改命令为测试执行 + GetTriggerWorkSpace()->cmdExec = TestCmdExec; + // 设置属性值 + SystemWriteParam(param, value); + + // 触发boot + TestBootEvent(boot); + + LibuvEventTask *task = (LibuvEventTask *)(GetTriggerWorkSpace()->eventHandle); + // 触发队列执行 + task->process(EVENT_TRIGGER_PARAM, NULL, 0); + // 连续执行两个trigger + EXPECT_EQ(g_execCmdId, 105); + return 0; + } + + int TestDumpTrigger() + { + DumpTrigger(GetTriggerWorkSpace()); + return 0; + } +}; + +TEST(TriggerTest, TestLoadTrigger) +{ + TriggerTest test; + test.TestLoadTrigger(); +} + +TEST(TriggerTest, TestBootEvent) +{ + TriggerTest test; + test.TestBootEvent("pre-init"); + test.TestBootEvent("init"); + test.TestBootEvent("post-init"); + test.TestBootEvent("early-init"); +} + +TEST(TriggerTest, TestAddTriggerForBoot) +{ + TriggerTest test; + test.TestAddTriggerForBoot(); +} + +TEST(TriggerTest, TestAddTriggerForParm) +{ + TriggerTest test; + test.TestAddTriggerForParm(); +} + +TEST(TriggerTest, TestCheckParamTrigger1) +{ + TriggerTest test; + test.TestCheckParamTrigger1(); +} + +TEST(TriggerTest, TestCheckParamTrigger2) +{ + TriggerTest test; + test.TestCheckParamTrigger2(); +} + +TEST(TriggerTest, TestCheckParamTrigger3) +{ + TriggerTest test; + test.TestCheckParamTrigger3(); +} + +TEST(TriggerTest, TestCheckParamTrigger4) +{ + TriggerTest test; + test.TestCheckParamTrigger4(); +} + +TEST(TriggerTest, TestCheckParamTrigger5) +{ + TriggerTest test; + test.TestCheckParamTrigger5(); +} + +TEST(TriggerTest, TestParamEvent) +{ + TriggerTest test; + test.TestParamEvent(); +} + +TEST(TriggerTest, ComputerCondition) +{ + TriggerTest test; + test.TestComputeCondition("aaa=111||aaa=222||aaa=333", "aaa=111", strlen("aaa=111")); + test.TestComputeCondition("aaa=111||aaa=222&&aaa=333", "aaa=111", strlen("aaa=111")); + test.TestComputeCondition("(aaa=111||aaa=222)&&aaa=333", "aaa=111", strlen("aaa=111")); + test.TestComputeCondition("aaa=111||(aaa=222&&aaa=333)", "aaa=111", strlen("aaa=111")); +} + +TEST(TriggerTest, TestExecuteParamTrigger1) +{ + TriggerTest test; + test.TestExecuteParamTrigger1(); +} + +TEST(TriggerTest, TestExecuteParamTrigger2) +{ + TriggerTest test; + test.TestExecuteParamTrigger2(); +} + +TEST(TriggerTest, TestExecuteParamTrigger3) +{ + TriggerTest test; + test.TestExecuteParamTrigger3(); +} + +TEST(TriggerTest, TestExecuteParamTrigger4) +{ + TriggerTest test; + test.TestExecuteParamTrigger4(); +} + +TEST(TriggerTest, TestExecuteParamTrigger5) +{ + TriggerTest test; + test.TestExecuteParamTrigger5(); +} \ No newline at end of file diff --git a/services/test/unittest/param/watcher_agent_unittest.cpp b/services/test/unittest/param/watcher_agent_unittest.cpp new file mode 100755 index 000000000..467f82911 --- /dev/null +++ b/services/test/unittest/param/watcher_agent_unittest.cpp @@ -0,0 +1,87 @@ +/* + * 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 +#include +#include +#include + +#include "sys_param.h" +#include "iwatcher.h" +#include "iwatcher_manager.h" +#include "watcher_manager_kits.h" + +using namespace std; + +void TestParameterChange(const char *key, const char *value, void *context) +{ + printf("TestParameterChange key:%s %s", key, value); +} + +class WatcherAgentTest : public ::testing::Test { +public: + WatcherAgentTest() {} + virtual ~WatcherAgentTest() {} + + void SetUp() {} + void TearDown() {} + void TestBody() {} + + int TestAddWatcher() + { + int ret = SystemWatchParameter("test.permission.watcher.test1", TestParameterChange, NULL); + EXPECT_EQ(ret, 0); + ret = SystemWatchParameter("test.permission.watcher.test1*", TestParameterChange, NULL); + EXPECT_EQ(ret, 0); + // 非法 + ret = SystemWatchParameter("test.permission.watcher.tes^^^^t1*", TestParameterChange, NULL); + EXPECT_NE(ret, 0); + // 被禁止 + ret = SystemWatchParameter("test1.permission.watcher.test1*", TestParameterChange, NULL); + EXPECT_NE(ret, 0); + return 0; + } + + int TestDelWatcher() + { + int ret = SystemWatchParameter("test.permission.watcher.test1", NULL, NULL); + EXPECT_EQ(ret, 0); + ret = SystemWatchParameter("test.permission.watcher.test1*", NULL, NULL); + EXPECT_EQ(ret, 0); + // 非法 + ret = SystemWatchParameter("test.permission.watcher.tes^^^^t1*", NULL, NULL); + EXPECT_NE(ret, 0); + // 被禁止 + ret = SystemWatchParameter("test1.permission.watcher.test1*", NULL, NULL); + EXPECT_NE(ret, 0); + return 0; + } + + int TestRecvMessage() + { + return 0; + } +}; + +TEST(WatcherAgentTest, TestAddWatcher) +{ + WatcherAgentTest test; + test.TestAddWatcher(); +} + +TEST(WatcherAgentTest, TestDelWatcher) +{ + WatcherAgentTest test; + test.TestDelWatcher(); +} \ No newline at end of file diff --git a/services/test/unittest/param/watcher_proxy_unittest.cpp b/services/test/unittest/param/watcher_proxy_unittest.cpp new file mode 100755 index 000000000..9fad55652 --- /dev/null +++ b/services/test/unittest/param/watcher_proxy_unittest.cpp @@ -0,0 +1,129 @@ +/* + * 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 +#include +#include +#include + +#include "iwatcher_manager.h" +#include "message_parcel.h" +#include "param_unittest.h" +#include "param_utils.h" +#include "parcel.h" +#include "securec.h" +#include "watcher.h" +#include "watcher_manager.h" +#include "watcher_utils.h" + +using namespace std; +using namespace OHOS; +using namespace OHOS::init_param; + +class TestWatcher final : public Watcher { +public: + TestWatcher() {} + ~TestWatcher() = default; + + void OnParamerterChange(const std::string &name, const std::string &value) override + { + printf("TestWatcher::OnParamerterChange name %s %s", name.c_str(), value.c_str()); + } +}; + +class WatcherProxyTest : public ::testing::Test { +public: + WatcherProxyTest() {} + virtual ~WatcherProxyTest() {} + + void SetUp() {} + void TearDown() {} + void TestBody() {} + + int TestAddWatcher(const std::string &keyPrefix, uint32_t watcherId) + { + std::shared_ptr watcherManager = GetWatcherManager(); + WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + + data.WriteString(keyPrefix); + TestWatcher *watcher = new TestWatcher(); + bool ret = data.WriteRemoteObject(watcher->AsObject()); + WATCHER_CHECK(ret, return 0, "Can not get remote"); + watcherManager->OnRemoteRequest(IWatcherManager::ADD_WATCHER, data, reply, option); + watcherId = reply.ReadUint32(); + EXPECT_NE(watcherId, 0); + printf("TestAddWatcher %s watcherId %d", keyPrefix.c_str(), watcherId); + return 0; + } + + int TestDelWatcher(const std::string &keyPrefix, uint32_t watcherId) + { + std::shared_ptr watcherManager = GetWatcherManager(); + WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + data.WriteString(keyPrefix); + data.WriteUint32(watcherId); + watcherManager->OnRemoteRequest(IWatcherManager::DEL_WATCHER, data, reply, option); + EXPECT_NE(reply.ReadInt32(), 0); + return 0; + } + + std::shared_ptr GetWatcherManager() + { + if (watcherManager_ == nullptr) { + watcherManager_ = std::make_shared(0, true); + if (watcherManager_ == nullptr) { + return nullptr; + } + } + return watcherManager_; + } + +private: + std::shared_ptr watcherManager_ { nullptr }; +}; + +TEST(WatcherProxyTest, TestAddWatcher) +{ + WatcherProxyTest test; + uint32_t watcherId = 0; + test.TestAddWatcher("test.permission.watcher.test1", watcherId); +} + +TEST(WatcherProxyTest, TestAddWatcher2) +{ + WatcherProxyTest test; + uint32_t watcherId = 0; + test.TestAddWatcher("test.permission.watcher.test1", watcherId); +} + +TEST(WatcherProxyTest, TestAddWatcher3) +{ + WatcherProxyTest test; + uint32_t watcherId = 0; + test.TestAddWatcher("test.permission.watcher.test3", watcherId); +} + +TEST(WatcherProxyTest, TestDelWatcher) +{ + WatcherProxyTest test; + uint32_t watcherId = 0; + test.TestAddWatcher("test.permission.watcher.testDel", watcherId); + test.TestDelWatcher("test.permission.watcher.testDel", watcherId); +} \ No newline at end of file diff --git a/services/param/cmd/param_set.c b/services/test/unittest/param_ut_entry.cpp old mode 100644 new mode 100755 similarity index 51% rename from services/param/cmd/param_set.c rename to services/test/unittest/param_ut_entry.cpp index 3c3943df9..f38e5ad5a --- a/services/param/cmd/param_set.c +++ b/services/test/unittest/param_ut_entry.cpp @@ -13,27 +13,19 @@ * limitations under the License. */ -#include -#include +#include +#include +#include -#include "sys_param.h" - -#define HELP_PARAM "--help" +#include "param_unittest.h" int main(int argc, char* argv[]) { - if (argc == 1 || argc > 3) { - printf("setparam: Need 2 arguments (see \"setparam --help\")\n"); - return 0; - } - if (argc == 2 && strncmp(argv[1], HELP_PARAM, strlen(HELP_PARAM)) == 0) { - printf("usage: setparam NAME VALUE\n"); - return 0; - } - int ret = SystemSetParameter(argv[1], argv[2]); - if (ret == 0) { - printf("setparam %s %s success\n", argv[1], argv[2]); - } else { - printf("setparam %s %s fail\n", argv[1], argv[2]); + testing::InitGoogleMock(&argc, argv); + testing::InitGoogleTest(&argc, argv); + + if (argc >= 2) { + return RunParamCommand(argc, argv); } + return RUN_ALL_TESTS(); } diff --git a/services/test/unittest/param_ut_server.cpp b/services/test/unittest/param_ut_server.cpp new file mode 100755 index 000000000..c1808bf92 --- /dev/null +++ b/services/test/unittest/param_ut_server.cpp @@ -0,0 +1,138 @@ +/* +* 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 +#include +#include +#include +#include "init_cmds.h" +#include "init_param.h" +#include "param_service.h" +#include "param_unittest.h" +#include "trigger_manager.h" +#include "sys_param.h" +#include "uv.h" + +#define PARAM_CMD_PATH "/media/sf_ubuntu/develop/build/startup/init_lite/services/test/unittest/param_test" +#define MAX_COUNT 10000 +int g_repeatCount = 0; + +static int CheckServerParamValue(const char *name, const char *expectValue) +{ + char tmp[PARAM_BUFFER_SIZE] = {0}; + u_int32_t len = sizeof(tmp); + SystemReadParam(name, tmp, &len); + printf("CheckParamValue name %s value: \'%s\' expectValue:\'%s\' \n", name, tmp, expectValue); + EXPECT_NE(strlen(tmp), 0); + if (expectValue != NULL) { + EXPECT_EQ(strcmp(tmp, expectValue), 0); + } + return 0; +} + +// 多进程 +static void *TestServerByMulProcess(void *args) +{ + std::string value = "test.value."; + value += std::to_string(rand()); + std::string name = (char*)args; + name += "." + std::to_string(rand()); + char tmp[PARAM_BUFFER_SIZE * 2] = {0}; + int ret = sprintf_s(tmp, PARAM_BUFFER_SIZE * 2 - 1, + "%s set %s %s", PARAM_CMD_PATH, name.c_str(), value.c_str()); + printf("TestServerByMulProcess cmd :\'%s\' \n", tmp); + system(tmp); + ret = sprintf_s(tmp, PARAM_BUFFER_SIZE * 2 - 1, "%s get %s", PARAM_CMD_PATH, name.c_str()); + system(tmp); + + CheckServerParamValue(name.c_str(), value.c_str()); + return NULL; +} + +static void TestForWriteParam(int max) +{ + srand((unsigned)time(NULL)); // srand()函数产生一个以当前时间开始的随机种子 + int index = 0; + while (index < max) { + std::string value = std::to_string(index); + SystemWriteParam("writeparam.test.aaa.bbb.aaa", value.c_str()); + int wait = rand() / 100000 + 100000; // 100ms + usleep(wait); + + value = std::to_string(index + 100000); + SystemWriteParam("writeparam.test.aaa.bbb.aaa", value.c_str()); + wait = rand() / 100000 + 100000; // 100ms + usleep(wait); + index++; + } +} + +static int TestForMultiProcess() +{ + srand((int)time(NULL)); + printf("TestForMultiThread \n"); + pthread_t tidsForProcess[THREAD_NUM_TEST]; + const char *names[5] = { + "thread.1111.2222.3333.4444.5555", + "thread.2222.1111.2222.3333.4444", + "thread.3333.1111.2222.4444.5555", + "thread.4444.5555.1111.2222.3333", + "thread.5555.1111.2222.3333.4444" + }; + ParamAuditData auditData = {}; + auditData.name = "thread."; + auditData.label = ""; + auditData.dacData.gid = 2002; + auditData.dacData.uid = 2002; + auditData.dacData.mode = 0777; + AddSecurityLabel(&auditData, GetParamWorkSpace()); + for (size_t i = 0; i < THREAD_NUM_TEST; i++) { + pthread_create(&tidsForProcess[i], NULL, TestServerByMulProcess, (void *)names[i % 5]); + } + return 0; +} + +static void timerCallback(ParamTaskPtr timer, void *context) +{ + g_repeatCount = g_repeatCount + 1; + if (g_repeatCount == MAX_COUNT) { + ParamTaskClose(timer); + TestForWriteParam(1); + StopParamService(); + return; + } + if (g_repeatCount == 1) { + TestForMultiProcess(); + } +} + +int main(int argc, char* argv[]) +{ + testing::InitGoogleMock(&argc, argv); + testing::InitGoogleTest(&argc, argv); + + SetLogLevel(INIT_DEBUG); + InitParamService(); + + ParamTaskPtr timer = NULL; + ParamTimerCreate(&timer, timerCallback, NULL); + ParamTimerStart(timer, 1000, MAX_COUNT); +#pragma clang diagnostic push +#pragma clang diagnostic ignored"-Wunused-result" + RUN_ALL_TESTS(); + StartParamService(); + return 0; +#pragma clang diagnostic pop +} diff --git a/services/test/unittest/service/cmds_unittest.cpp b/services/test/unittest/service/cmds_unittest.cpp new file mode 100755 index 000000000..60714129a --- /dev/null +++ b/services/test/unittest/service/cmds_unittest.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020 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 +#include +#include +#include "init_cmds.h" + +using namespace testing::ext; +using namespace std; + +namespace init_ut { +class CmdsUnitTest : public testing::Test { +public: + static void SetUpTestCase(void) {}; + static void TearDownTestCase(void) {}; + void SetUp() {}; + void TearDown() {}; +}; + + +TEST(CmdsUnitTest, init_cmds_test_001) +{ + EXPECT_EQ(1, 1); +} + +} // namespace init_ut diff --git a/services/test/unittest/tools/prepare_testdata.sh b/services/test/unittest/tools/prepare_testdata.sh new file mode 100755 index 000000000..0112c6f77 --- /dev/null +++ b/services/test/unittest/tools/prepare_testdata.sh @@ -0,0 +1,123 @@ +#! /bin/bash +# 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. + +# This Script used to push test data to devices +# Usage: +# ./prepare_testdata.sh path +# path is the rootdir of ohos projects. + +if [ $# -lt 1 ];then + echo "Usage $0 " + exit 1 +fi + +function hdc_shell_cmd() { + # do nothing if there are not any arguments + if [ $# -eq 0 ];then + return; + fi + echo "Running command $@" + hdc shell $@ +} + +function hdc_push_cmd() { + # do nothing if there are not any arguments + if [ $# -ne 2 ];then + return; + fi + echo "Pushing resouces to device" + hdc file send $@ +} + +hdc target mount + +ut_target_path="/data/init_ut" +echo "Remove ${ut_target_path}" +hdc_shell_cmd "rm -rf ${ut_target_path}" + +echo "Create ${ut_target_path}" +hdc_shell_cmd "umask 022" +hdc_shell_cmd "mkdir -p ${ut_target_path}" + +ohos_root="$1" +ohos_root=${ohos_root%%/} +ohos_init="${ohos_root}/base/startup/init_lite" +ohos_init_ut="${ohos_init}/services/test/unittest" + +hdc_shell_cmd "mkdir -p ${ut_target_path}/coverage" +sleep 0.25 +hdc file send ${ohos_root}/out/ohos-arm-release/exe.unstripped/startup/init/init_ut /bin/init_ut +sleep 0.25 +hdc_shell_cmd "chmod 777 /data/init_ut/* -R" +hdc_shell_cmd "chmod 777 /bin/init_ut" + +hdc_shell_cmd "export GCOV_PREFIX=${ut_target_path}/coverage&&export GCOV_PREFIX_STRIP=14&&init_ut" + +if [ $? -ne 0 ]; then + echo "Execute init_ut in device failed. please check the log" +fi +echo "Running init unittests end..." +echo "Ready to generate coverage..." +pushd ${ohos_init} +rm -rf ./g.sh +rm -rf *.gcno +rm -rf *.gcda +echo "Copy .gcta files to ${ohos_init}}" + +for file in $(hdc_shell_cmd ls /data/init_ut/coverage/*.gcda); do + hdc file recv ${file} ${ohos_init}/${file:23} + chmod 777 ${ohos_init}/${file:23} +done + + +echo "Find out all gcno files and copy to ${ohos_init}" +find ${ohos_root}/out/ohos-arm-release/obj/ -name "*.gcno" -type f -exec cp {} . \; +if [ $? -ne 0 ]; then + echo "find gcno failed." + popd 2>&1 > /dev/null + exit 1 +fi + +if [ ! -f ${ohos_init}/g.sh ]; then + echo "create g.sh" + touch ${ohos_init}/g.sh + echo "${ohos_root}/prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-cov gcov \$@" > ${ohos_init}/g.sh + chmod 755 ${ohos_init}/g.sh +fi + +echo "Running command lcov" +lcov -d . -o "${ohos_init}/init_ut_tmp.info" -b . -c --gcov-tool ${ohos_init}/g.sh + +if [ $? -ne 0 ]; then + echo "Run command lcov failed" + popd 2>&1 > /dev/null +fi + +echo "Filter out don\'t cared dir" +lcov --remove init_ut_tmp.info "*third_party*" "*prebuilts*" "*aosp_libs*" "*base/update/updater/test*" "*${ohos_root}/hos/out*" "*services/script/yacc*" "*services/ui/recovery_ui*" "*services/ui/recovery_ui/include/recovery_ui*" "*update_image_block*" -o ${ohos_init}/init_ut.info + +genhtml -o ${HOME}/init_coverage init_ut.info +if [ $? -ne 0 ]; then + echo "Run genhtml failed." + popd 2>&1 > /dev/null + exit 1 +fi +echo "Clear tmp files" +rm -rf ./g.sh *.gcno *.gcda init_ut.info init_ut_tmp.info +hdc_shell_cmd "rm -rf ${ut_target_path}" +echo +echo "Generate init ut coverage done." +echo "Check coverage in ${HOME}/init_coverage." +echo +popd 2>&1 > /dev/null diff --git a/ueventd/BUILD.gn b/ueventd/BUILD.gn index 5d725eff9..719441da6 100755 --- a/ueventd/BUILD.gn +++ b/ueventd/BUILD.gn @@ -16,19 +16,20 @@ if (!defined(ohos_lite)) { ohos_executable("ueventd") { sources = [ - "list.c", - "ueventd.c", - "ueventd_device_handler.c", - "ueventd_firmware_handler.c", - "ueventd_read_cfg.c", - "ueventd_socket.c", - "ueventd_utils.c", + "//base/startup/init_lite/services/src/list.c", + "//base/startup/init_lite/ueventd/ueventd.c", + "//base/startup/init_lite/ueventd/ueventd_device_handler.c", + "//base/startup/init_lite/ueventd/ueventd_firmware_handler.c", + "//base/startup/init_lite/ueventd/ueventd_read_cfg.c", + "//base/startup/init_lite/ueventd/ueventd_socket.c", + "//base/startup/init_lite/ueventd/ueventd_utils.c", ] include_dirs = [ "include", "//third_party/bounds_checking_function/include", "//base/startup/init_lite/services/log", + "//base/startup/init_lite/services/include", ] deps = [ diff --git a/ueventd/ueventd.c b/ueventd/ueventd.c index 98ab43e55..c086608ba 100755 --- a/ueventd/ueventd.c +++ b/ueventd/ueventd.c @@ -140,9 +140,9 @@ static void AddUevent(struct Uevent *uevent, const char *event, size_t len) } else if (STARTSWITH(event, "MINOR=")) { uevent->minor = StringToInt(event + strlen("MINOR="), -1); } else if (STARTSWITH(event, "DEVUID")) { - uevent->ug.uid = StringToInt(event + strlen("DEVUID="), 0); + uevent->ug.uid = (uid_t)StringToInt(event + strlen("DEVUID="), 0); } else if (STARTSWITH(event, "DEVGID")) { - uevent->ug.gid = StringToInt(event + strlen("DEVGID="), 0); + uevent->ug.gid = (gid_t)StringToInt(event + strlen("DEVGID="), 0); } else if (STARTSWITH(event, "FIRMWARE=")) { uevent->firmware = event + strlen("FIRMWARE="); } else if (STARTSWITH(event, "BUSNUM=")) { @@ -153,7 +153,7 @@ static void AddUevent(struct Uevent *uevent, const char *event, size_t len) // Ignore other events } -static void ParseUeventMessage(char *buffer, ssize_t length, struct Uevent *uevent) +static void ParseUeventMessage(const char *buffer, ssize_t length, struct Uevent *uevent) { if (buffer == NULL || uevent == NULL || length == 0) { // Ignore invalid buffer @@ -168,7 +168,7 @@ static void ParseUeventMessage(char *buffer, ssize_t length, struct Uevent *ueve uevent->devNum = -1; ssize_t pos = 0; while (pos < length) { - char *event = buffer + pos; + const char *event = buffer + pos; size_t len = strlen(event); if (len == 0) { break; diff --git a/ueventd/ueventd_device_handler.c b/ueventd/ueventd_device_handler.c index d23277242..0e7940948 100755 --- a/ueventd/ueventd_device_handler.c +++ b/ueventd/ueventd_device_handler.c @@ -104,7 +104,7 @@ static int CreateDeviceNode(const struct Uevent *uevent, const char *deviceNode, INIT_LOGE("Create path \" %s \" failed", devicePath); return rc; } - + GetDeviceNodePermissions(deviceNode, &uid, &gid, &mode); mode |= isBlock ? S_IFBLK : S_IFCHR; dev_t dev = makedev(major, minor); @@ -112,15 +112,15 @@ static int CreateDeviceNode(const struct Uevent *uevent, const char *deviceNode, rc = mknod(deviceNode, mode, dev); if (rc < 0) { if (errno != EEXIST) { - INIT_LOGE("Create device node[%s %d, %d] failed", deviceNode, major, minor, errno); + INIT_LOGE("Create device node[%s %d, %d] failed. %d", deviceNode, major, minor, errno); return rc; } } AdjustDeviceNodePermissions(deviceNode, uid, gid, mode); - if (symLinks) { + if (symLinks != NULL) { CreateSymbolLinks(deviceNode, symLinks); } - // No matter what result the symbol links returns, + // No matter what result the symbol links returns, // as long as create device node done, just returns success. rc = 0; return rc; @@ -128,10 +128,9 @@ static int CreateDeviceNode(const struct Uevent *uevent, const char *deviceNode, static int RemoveDeviceNode(const char *deviceNode, char **symLinks) { - int rc = -1; if (INVALIDSTRING(deviceNode)) { INIT_LOGE("Invalid device node"); - return rc; + return -1; } if (symLinks != NULL) { for (int i = 0; symLinks[i] != NULL; i++) { @@ -151,7 +150,7 @@ static int RemoveDeviceNode(const char *deviceNode, char **symLinks) static char **GetBlockDeviceSymbolLinks(const struct Uevent *uevent) { - if (uevent == NULL || !STRINGEQUAL(uevent->subsystem, "block")) { + if (uevent == NULL || uevent->subsystem == NULL || STRINGEQUAL(uevent->subsystem, "block") == 0) { INIT_LOGW("Invalid arguments, Skip to get device symbol links."); return NULL; } @@ -163,7 +162,7 @@ static char **GetBlockDeviceSymbolLinks(const struct Uevent *uevent) // For block device under one platform device. // check subsystem file under directory, see if it links to bus/platform. // For now, only support platform device. - char sysPath[SYSPATH_SIZE] = {}; + char sysPath[SYSPATH_SIZE] = {}; if (snprintf_s(sysPath, SYSPATH_SIZE, SYSPATH_SIZE - 1, "/sys%s", uevent->syspath) == -1) { INIT_LOGE("Failed to build sys path for device %s", uevent->syspath); return NULL; @@ -207,7 +206,7 @@ static char **GetBlockDeviceSymbolLinks(const struct Uevent *uevent) if (!INVALIDSTRING(uevent->partitionName)) { if (snprintf_s(links[linkNum], DEVICE_FILE_SIZE, DEVICE_FILE_SIZE - 1, "/dev/block/platform/%s/by-name/%s", parent, uevent->partitionName) == -1) { - INIT_LOGE("Failed to build link"); + INIT_LOGE("Failed to build link"); break; } } @@ -340,6 +339,9 @@ void HandleBlockDeviceEvent(const struct Uevent *uevent) char deviceNode[DEVICE_FILE_SIZE] = {}; char sysPath[SYSPATH_SIZE] = {}; + if (uevent->syspath == NULL) { + return; + } if (strncpy_s(sysPath, SYSPATH_SIZE - 1, uevent->syspath, strlen(uevent->syspath) != EOK)) { INIT_LOGE("Failed to copy sys path"); return; @@ -359,7 +361,7 @@ void HandleBlockDeviceEvent(const struct Uevent *uevent) void HandleOtherDeviceEvent(const struct Uevent *uevent) { - if (uevent == NULL || uevent->subsystem == NULL) { + if (uevent == NULL || uevent->subsystem == NULL || uevent->syspath == NULL) { INIT_LOGE("Invalid uevent received"); return; } @@ -398,7 +400,7 @@ void HandleOtherDeviceEvent(const struct Uevent *uevent) INIT_LOGE("usb device with invalid bus number or device number"); return; } - if (snprintf_s(deviceNode, DEVICE_FILE_SIZE, DEVICE_FILE_SIZE - 1, + if (snprintf_s(deviceNode, DEVICE_FILE_SIZE, DEVICE_FILE_SIZE - 1, "/dev/bus/usb/%03d/%03d", uevent->busNum, uevent->devNum) == -1) { INIT_LOGE("Make usb device node for device [%d : %d]", uevent->busNum, uevent->devNum); } diff --git a/ueventd/ueventd_read_cfg.c b/ueventd/ueventd_read_cfg.c index ef938be08..a015681e3 100755 --- a/ueventd/ueventd_read_cfg.c +++ b/ueventd/ueventd_read_cfg.c @@ -15,6 +15,7 @@ #include "ueventd_read_cfg.h" #include +#include #include #include #include @@ -124,7 +125,7 @@ static int ParseDeviceConfig(char *p) char **items = NULL; int count = -1; // format: - int expectedCount = 4; + const int expectedCount = 4; if (INVALIDSTRING(p)) { INIT_LOGE("Invalid argument"); @@ -149,8 +150,8 @@ static int ParseDeviceConfig(char *p) INIT_LOGE("Invalid mode in config file for device node %s. use default mode", config->name); config->mode = DEVMODE; } - config->uid = StringToInt(items[2], 0); - config->gid = StringToInt(items[3], 0); + config->uid = (uid_t)StringToInt(items[2], 0); + config->gid = (gid_t)StringToInt(items[3], 0); ListAddTail(&g_devices, &config->list); FreeConfigItems(items, count); return 0; @@ -162,7 +163,7 @@ static int ParseSysfsConfig(char *p) char **items = NULL; int count = -1; // format: - int expectedCount = 5; + const int expectedCount = 5; if (INVALIDSTRING(p)) { INIT_LOGE("Invalid argument"); @@ -187,8 +188,8 @@ static int ParseSysfsConfig(char *p) INIT_LOGE("Invalid mode in config file for sys path %s. use default mode", config->sysPath); config->mode = DEVMODE; } - config->uid = StringToInt(items[3], 0); - config->gid = StringToInt(items[4], 0); + config->uid = (uid_t)StringToInt(items[3], 0); + config->gid = (gid_t)StringToInt(items[4], 0); ListAddTail(&g_sysDevices, &config->list); return 0; } @@ -222,7 +223,7 @@ static int ParseFirmwareConfig(char *p) return 0; } -static SECTION GetSection(char *section) +static SECTION GetSection(const char *section) { if (INVALIDSTRING(section)) { return SECTION_INVALID; @@ -276,11 +277,14 @@ int ParseUeventConfig(char *buffer) return callback != NULL ? callback(p) : -1; } -static void DoUeventConfigParse(char *buffer) +static void DoUeventConfigParse(char *buffer, size_t length) { + if (length < 0) { + return; + } char **items = NULL; int count = -1; - int maxItemCount = DEFAULTITEMCOUNT; + const int maxItemCount = DEFAULTITEMCOUNT; items = SplitUeventConfig(buffer, "\n", &count, maxItemCount); INIT_LOGD("Dump items count = %d", count); @@ -309,8 +313,9 @@ void ParseUeventdConfigFile(const char *file) if (INVALIDSTRING(file)) { return; } - - int fd = open(file, O_RDONLY | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + char cfgBuffer[PATH_MAX]; + char *config = realpath(file, cfgBuffer); + int fd = open(config, O_RDONLY | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd < 0) { INIT_LOGE("Read from %s failed", file); return; @@ -320,6 +325,7 @@ void ParseUeventdConfigFile(const char *file) if (fstat(fd, &st) < 0) { INIT_LOGE("Failed to get file stat. err = %d", errno); close(fd); + fd = -1; return; } @@ -337,14 +343,16 @@ void ParseUeventdConfigFile(const char *file) free(buffer); buffer = NULL; close(fd); + fd = -1; return; } buffer[size] = '\0'; - DoUeventConfigParse(buffer); + DoUeventConfigParse(buffer, size); free(buffer); buffer = NULL; close(fd); + fd = -1; } void GetDeviceNodePermissions(const char *devNode, uid_t *uid, gid_t *gid, mode_t *mode) diff --git a/ueventd/ueventd_socket.c b/ueventd/ueventd_socket.c index 2243aa7f3..56503fb44 100755 --- a/ueventd/ueventd_socket.c +++ b/ueventd/ueventd_socket.c @@ -33,7 +33,6 @@ int UeventdSocketInit() { struct sockaddr_nl addr; - int sockfd; int buffSize = 256 * 1024; int on = 1; @@ -45,7 +44,7 @@ int UeventdSocketInit() addr.nl_pid = getpid(); addr.nl_groups = 0xffffffff; - sockfd = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT); + int sockfd = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT); if (sockfd < 0) { INIT_LOGE("Create socket failed, err = %d", errno); @@ -70,7 +69,6 @@ ssize_t ReadUeventMessage(int sockFd, char *buffer, size_t length) struct iovec iov; struct sockaddr_nl addr; char credMsg[CMSG_SPACE(sizeof(struct ucred))]; - struct cmsghdr *cmsghdr; // sanity check if (sockFd < 0 || buffer == NULL) { @@ -90,7 +88,7 @@ ssize_t ReadUeventMessage(int sockFd, char *buffer, size_t length) if (n <= 0) { return n; } - cmsghdr = CMSG_FIRSTHDR(&msghdr); + struct cmsghdr *cmsghdr = CMSG_FIRSTHDR(&msghdr); if (cmsghdr == NULL || cmsghdr->cmsg_type != SCM_CREDENTIALS) { INIT_LOGE("Unexpected control message, ignored"); // Drop this message diff --git a/ueventd/ueventd_utils.c b/ueventd/ueventd_utils.c index 22b03da4b..590eae61e 100755 --- a/ueventd/ueventd_utils.c +++ b/ueventd/ueventd_utils.c @@ -77,6 +77,6 @@ int StringToInt(const char *str, int defaultValue) return defaultValue; } errno = 0; - int value = strtoul(str, NULL, DECIMALISM); + int value = (int)strtoul(str, NULL, DECIMALISM); return errno != 0 ? defaultValue : value; } -- Gitee From 6419ac9b3aa80123ec192601d809529874c3b725 Mon Sep 17 00:00:00 2001 From: sun_fan Date: Sat, 11 Sep 2021 17:38:34 +0800 Subject: [PATCH 02/14] init: fix l1 ut bug Signed-off-by: sun_fan --- services/test/unittest/common/cmd_func_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/test/unittest/common/cmd_func_test.cpp b/services/test/unittest/common/cmd_func_test.cpp index 66450f7e0..03a92d5af 100644 --- a/services/test/unittest/common/cmd_func_test.cpp +++ b/services/test/unittest/common/cmd_func_test.cpp @@ -934,7 +934,7 @@ HWTEST_F(StartupInitUTest, cmdJobTest_001, TestSize.Level0) DoJob("job name does not exist"); ReleaseAllJobs(); RegisterServices(nullptr, 0); - StartServiceByName("service name does not exist"); + StartServiceByName("service name does not exist", false); StopAllServices(); ReapServiceByPID(INVALID_PID); ServiceReap(nullptr); -- Gitee From e430e3791a27d9e221b12083c3b9eeabc79e14f1 Mon Sep 17 00:00:00 2001 From: sun_fan Date: Sat, 11 Sep 2021 18:22:49 +0800 Subject: [PATCH 03/14] init: delete ut test Signed-off-by: sun_fan --- services/test/unittest/BUILD.gn | 236 ------- services/test/unittest/init_unittest_const.h | 26 - services/test/unittest/init_ut_entry.cpp | 28 - .../test/unittest/param/client_unittest.cpp | 267 -------- services/test/unittest/param/dac_unittest.cpp | 346 ---------- services/test/unittest/param/param_unittest.h | 72 -- .../test/unittest/param/selinux_unittest.cpp | 236 ------- .../test/unittest/param/service_unittest.cpp | 646 ------------------ .../test/unittest/param/trigger_unittest.cpp | 536 --------------- .../unittest/param/watcher_agent_unittest.cpp | 87 --- .../unittest/param/watcher_proxy_unittest.cpp | 129 ---- services/test/unittest/param_ut_entry.cpp | 31 - services/test/unittest/param_ut_server.cpp | 138 ---- .../test/unittest/service/cmds_unittest.cpp | 39 -- .../test/unittest/tools/prepare_testdata.sh | 123 ---- 15 files changed, 2940 deletions(-) delete mode 100755 services/test/unittest/BUILD.gn delete mode 100755 services/test/unittest/init_unittest_const.h delete mode 100755 services/test/unittest/init_ut_entry.cpp delete mode 100755 services/test/unittest/param/client_unittest.cpp delete mode 100755 services/test/unittest/param/dac_unittest.cpp delete mode 100755 services/test/unittest/param/param_unittest.h delete mode 100755 services/test/unittest/param/selinux_unittest.cpp delete mode 100755 services/test/unittest/param/service_unittest.cpp delete mode 100755 services/test/unittest/param/trigger_unittest.cpp delete mode 100755 services/test/unittest/param/watcher_agent_unittest.cpp delete mode 100755 services/test/unittest/param/watcher_proxy_unittest.cpp delete mode 100755 services/test/unittest/param_ut_entry.cpp delete mode 100755 services/test/unittest/param_ut_server.cpp delete mode 100755 services/test/unittest/service/cmds_unittest.cpp delete mode 100755 services/test/unittest/tools/prepare_testdata.sh diff --git a/services/test/unittest/BUILD.gn b/services/test/unittest/BUILD.gn deleted file mode 100755 index 18d987192..000000000 --- a/services/test/unittest/BUILD.gn +++ /dev/null @@ -1,236 +0,0 @@ -# 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/ohos.gni") - -config("utest_config") { - visibility = [ ":*" ] - - cflags = [ - "-fprofile-arcs", - "-ftest-coverage", - "-Wno-implicit-fallthrough", - "-Wno-unused-function", - ] - cflags_cc = [ - "-Wno-implicit-fallthrough", - "-fexceptions", - ] - - ldflags = [ "--coverage" ] -} - -ohos_executable("init_ut") { - sources = [ - "init_ut_entry.cpp", - "service/cmds_unittest.cpp", - ] - - sources += [ - "//base/startup/init_lite/services/src/device.c", - "//base/startup/init_lite/services/src/init_capability.c", - "//base/startup/init_lite/services/src/init_cmds.c", - "//base/startup/init_lite/services/src/init_import.c", - "//base/startup/init_lite/services/src/init_jobs.c", - "//base/startup/init_lite/services/src/init_read_cfg.c", - "//base/startup/init_lite/services/src/init_reboot.c", - "//base/startup/init_lite/services/src/init_service.c", - "//base/startup/init_lite/services/src/init_service_manager.c", - "//base/startup/init_lite/services/src/init_service_socket.c", - "//base/startup/init_lite/services/src/init_signal_handler.c", - "//base/startup/init_lite/services/src/init_utils.c", - ] - - include_dirs = [ - "//base/startup/init_lite/services/include/param", - "//base/startup/init_lite/services/include", - "//base/startup/init_lite/services/log", - "//third_party/cJSON", - "//third_party/bounds_checking_function/include", - "//third_party/libuv/include", - ] - - deps = [ - "//base/startup/init_lite/services/log:init_log", - "//base/startup/init_lite/services/param:param_service", - "//third_party/bounds_checking_function:libsec_static", - "//third_party/cJSON:cjson_static", - "//third_party/googletest:gmock", - "//third_party/googletest:gtest", - ] - - defines = [ "INIT_UT" ] - public_configs = [ ":utest_config" ] - install_enable = true - part_name = "init" -} - -ohos_executable("paramserver_ut") { - sources = [ - "param_ut_server.cpp", - "param/dac_unittest.cpp", - "param/service_unittest.cpp", - "param/trigger_unittest.cpp", - "param/selinux_unittest.cpp", - ] - - sources += [ - "//base/startup/init_lite/services/src/device.c", - "//base/startup/init_lite/services/src/init_adapter.c", - "//base/startup/init_lite/services/src/init_capability.c", - "//base/startup/init_lite/services/src/init_cmds.c", - "//base/startup/init_lite/services/src/init_import.c", - "//base/startup/init_lite/services/src/init_jobs.c", - "//base/startup/init_lite/services/src/init_read_cfg.c", - "//base/startup/init_lite/services/src/init_reboot.c", - "//base/startup/init_lite/services/src/init_service.c", - "//base/startup/init_lite/services/src/init_service_manager.c", - "//base/startup/init_lite/services/src/init_service_socket.c", - "//base/startup/init_lite/services/src/init_signal_handler.c", - "//base/startup/init_lite/services/src/init_utils.c", - "//base/startup/init_lite/services/log/init_log.c", - "//base/startup/init_lite/services/src/list.c", - "//base/startup/init_lite/services/param/manager/param_utils.c", - "//base/startup/init_lite/services/param/manager/param_manager.c", - "//base/startup/init_lite/services/param/manager/param_trie.c", - "//base/startup/init_lite/services/param/manager/param_message.c", - "//base/startup/init_lite/services/param/service/param_persist.c", - "//base/startup/init_lite/services/param/service/param_service.c", - "//base/startup/init_lite/services/param/trigger/trigger_checker.c", - "//base/startup/init_lite/services/param/trigger/trigger_manager.c", - "//base/startup/init_lite/services/param/trigger/trigger_processor.c", - "//base/startup/init_lite/services/param/adapter/param_libuvadp.c", - "//base/startup/init_lite/services/param/adapter/param_persistadp.c", - "//base/startup/init_lite/services/param/adapter/param_dac.c", - "//base/startup/init_lite/services/param/adapter/param_selinux.c" - ] - include_dirs = [ - "param", - "//base/startup/init_lite/services/include", - "//base/startup/init_lite/services/include/param", - "//base/startup/init_lite/services/param/include", - "//base/startup/init_lite/services/param/adapter", - "//base/startup/init_lite/services/log", - "//third_party/libuv/include", - "//third_party/cJSON", - "//third_party/bounds_checking_function/include", - ] - - deps = [ - "//third_party/googletest:gtest", - "//third_party/googletest:gmock", - "//utils/native/base:utils", - "//third_party/bounds_checking_function:libsec_static", - "//third_party/libuv:uv_static", - "//third_party/cJSON:cjson_static", - ] - - defines = ["STARTUP_INIT_TEST", "PARAM_SUPPORT_SAVE_PERSIST", "PARAM_SUPPORT_DAC"] - - external_deps = [ - "hiviewdfx_hilog_native:libhilog", - ] - - cflags_cc = [ - "-fexceptions", - ] - - public_configs = [ ":utest_config" ] - part_name = "init" - subsystem_name = "startup" -} - -ohos_executable("paramclient_ut") { - sources = [ - "param_ut_entry.cpp", - "param/dac_unittest.cpp", - "param/client_unittest.cpp", - "param/selinux_unittest.cpp", - "param/watcher_agent_unittest.cpp", - "param/watcher_proxy_unittest.cpp", - ] - - sources += [ - "//base/startup/init_lite/services/log/init_log.c", - "//base/startup/init_lite/services/src/init_utils.c", - "//base/startup/init_lite/services/src/list.c", - "//base/startup/init_lite/services/param/adapter/param_dac.c", - "//base/startup/init_lite/services/param/adapter/param_selinux.c", - "//base/startup/init_lite/services/param/client/param_request.c", - "//base/startup/init_lite/services/param/cmd/param_cmd.c", - "//base/startup/init_lite/services/param/manager/param_utils.c", - "//base/startup/init_lite/services/param/manager/param_manager.c", - "//base/startup/init_lite/services/param/manager/param_message.c", - "//base/startup/init_lite/services/param/manager/param_trie.c", - "//base/startup/init_lite/services/param/watcher/proxy/watcher_manager.cpp", - "//base/startup/init_lite/services/param/watcher/proxy/watcher_manager_stub.cpp", - "//base/startup/init_lite/services/param/watcher/proxy/watcher_proxy.cpp", - "//base/startup/init_lite/services/param/watcher/agent/watcher_manager_kits.cpp", - "//base/startup/init_lite/services/param/watcher/agent/watcher_manager_proxy.cpp", - "//base/startup/init_lite/services/param/watcher/agent/watcher_stub.cpp", - "//base/startup/init_lite/services/param/watcher/agent/watcher.cpp" - ] - - include_dirs = [ - "param", - "//base/startup/init_lite/services/include", - "//base/startup/init_lite/services/include/param", - "//base/startup/init_lite/services/log", - "//base/startup/init_lite/services/param/include", - "//base/startup/init_lite/services/adapter", - "//base/startup/init_lite/services/param/watcher/agent", - "//base/startup/init_lite/services/param/watcher/include", - "//base/startup/init_lite/services/param/watcher/proxy", - "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include", - "//foundation/distributedschedule/safwk/services/safwk/include", - "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk", - "//foundation/distributedschedule/samgr/adapter/interfaces/innerkits/include", - "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include", - "//utils/native/base/include", - "//utils/system/safwk/native/include", - "//third_party/libuv/include", - "//third_party/cJSON", - ] - - deps = [ - "//third_party/googletest:gtest", - "//third_party/googletest:gmock", - "//utils/native/base:utils", - "//third_party/bounds_checking_function:libsec_static", - ] - - defines = ["STARTUP_INIT_TEST", "PARAM_SUPPORT_SAVE_PERSIST", "PARAM_SUPPORT_DAC"] - - external_deps = [ - "hiviewdfx_hilog_native:libhilog", - "ipc:ipc_core", - "safwk:system_ability_fwk", - "samgr_L2:samgr_proxy", - ] - - cflags_cc = [ - "-fexceptions", - ] - - public_configs = [ ":utest_config" ] - part_name = "init" - subsystem_name = "startup" -} - -group("init_test") { - deps = [ - ":init_ut", - ":paramserver_ut", - ":paramclient_ut", - ] -} diff --git a/services/test/unittest/init_unittest_const.h b/services/test/unittest/init_unittest_const.h deleted file mode 100755 index 4a5262660..000000000 --- a/services/test/unittest/init_unittest_const.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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 INIT_UNITTEST_CONST_H -#define INIT_UNITTEST_CONST_H - - -namespace init_ut { - - - - -} // namespace init_ut -#endif // INIT_UNITTEST_CONST_H diff --git a/services/test/unittest/init_ut_entry.cpp b/services/test/unittest/init_ut_entry.cpp deleted file mode 100755 index 736dd4ff1..000000000 --- a/services/test/unittest/init_ut_entry.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* -* 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 -#include -#include - -using namespace testing::ext; - -int main(int argc, char* argv[]) -{ - testing::InitGoogleMock(&argc, argv); - testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -} diff --git a/services/test/unittest/param/client_unittest.cpp b/services/test/unittest/param/client_unittest.cpp deleted file mode 100755 index 3552d4829..000000000 --- a/services/test/unittest/param/client_unittest.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include - -#include "param_service.h" -#include "param_unittest.h" -#include "sys_param.h" - -static void TestCheckParamValue(const char *name, const char *expectValue) -{ - char tmp[PARAM_BUFFER_SIZE] = { 0 }; - u_int32_t len = sizeof(tmp); - int ret = SystemGetParameter(name, tmp, &len); - printf("TestCheckParamValue name %s value: \'%s\' expectValue:\'%s\' \n", name, tmp, expectValue); - if (ret == 0 && len > 0) { - EXPECT_NE(strlen(tmp), 0); - if (expectValue != NULL) { - EXPECT_EQ(strcmp(tmp, expectValue), 0); - } - } else { - EXPECT_NE(0, 0); - } -} - -// 多线程测试 -static void *TestSendParamSetMsg(void *args) -{ - std::string name = (char *)args; - printf("TestSendParamSetMsg name :\'%s\' \n", name.c_str()); - SystemSetParameter(name.c_str(), name.c_str()); - TestCheckParamValue(name.c_str(), name.c_str()); - return NULL; -} - -static void *TestSendParamWaitMsg(void *args) -{ - std::string name = "Wati."; - name = name + (char *)args; - printf("TestSendParamWaitMsg name :\'%s\' \n", name.c_str()); - SystemWaitParameter(name.c_str(), name.c_str(), 0); - TestCheckParamValue(name.c_str(), name.c_str()); - return NULL; -} - -std::string g_testChangeValue = {}; -static void ParameterChangeCallback(const char *key, const char *value, void *context) -{ - if (strcmp(value, g_testChangeValue.c_str()) == 0) { - printf("ParameterChangeCallback key %s value %s", key, value); - } -} - -class ParamClientTest : public ::testing::Test { -public: - ParamClientTest() {} - virtual ~ParamClientTest() {} - - void SetUp() {} - void TearDown() {} - void TestBody() {} - - int TestSetParam(const char *key, const char *value) - { - SystemSetParameter(key, value); - TestCheckParamValue(key, value); - return 0; - } - - int TestForMultiThread() - { - srand((int)time(NULL)); - printf("TestForMultiThread \n"); - pthread_t tids[THREAD_NUM_TEST + THREAD_NUM_TEST]; - const char *names[5] = { "thread.1111.2222.3333.4444.5555", "thread.2222.1111.2222.3333.4444", - "thread.3333.1111.2222.4444.5555", "thread.4444.5555.1111.2222.3333", - "thread.5555.1111.2222.3333.4444" }; - for (size_t i = 0; i < THREAD_NUM_TEST; i++) { - pthread_create(&tids[i], NULL, TestSendParamSetMsg, (void *)names[i % 5]); - } - for (size_t i = THREAD_NUM_TEST; i < THREAD_NUM_TEST + THREAD_NUM_TEST; i++) { - pthread_create(&tids[i], NULL, TestSendParamWaitMsg, (void *)names[i % 5]); - } - for (size_t i = 0; i < THREAD_NUM_TEST + THREAD_NUM_TEST; i++) { - pthread_join(tids[i], NULL); - } - return 0; - } - - int TestParamTraversal() - { - char value[PARAM_BUFFER_SIZE + PARAM_BUFFER_SIZE] = { 0 }; - SystemTraversalParameter( - [](ParamHandle handle, void *cookie) { - SystemGetParameterName(handle, (char *)cookie, PARAM_BUFFER_SIZE); - u_int32_t len = PARAM_BUFFER_SIZE; - SystemGetParameterValue(handle, ((char *)cookie) + PARAM_BUFFER_SIZE, &len); - printf("$$$$$$$$Param %s=%s \n", (char *)cookie, ((char *)cookie) + PARAM_BUFFER_SIZE); - }, - (void *)value); - return 0; - } - - int TestUpdateParam(const char *name, const char *value) - { - SystemSetParameter(name, value); - TestCheckParamValue(name, value); - return 0; - } - - int TestPersistParam() - { - SystemSetParameter("persist.111.ffff.bbbb.cccc.dddd.eeee", "1101"); - SystemSetParameter("persist.111.aaaa.bbbb.cccc.dddd.eeee", "1102"); - SystemSetParameter("persist.111.bbbb.cccc.dddd.eeee", "1103"); - TestCheckParamValue("persist.111.bbbb.cccc.dddd.eeee", "1103"); - SystemSetParameter("persist.111.cccc.bbbb.cccc.dddd.eeee", "1104"); - SystemSetParameter("persist.111.eeee.bbbb.cccc.dddd.eeee", "1105"); - TestCheckParamValue("persist.111.ffff.bbbb.cccc.dddd.eeee", "1101"); - SystemSetParameter("persist.111.ffff.bbbb.cccc.dddd.eeee", "1106"); - TestCheckParamValue("persist.111.ffff.bbbb.cccc.dddd.eeee", "1106"); - return 0; - } - - int TestPermission() - { - const char *testName = "persist.111.ffff.bbbb.cccc.dddd.eeee.55555"; - char tmp[PARAM_BUFFER_SIZE] = { 0 }; - // 允许本地校验 - ParamSecurityOps *paramSecurityOps = &GetClientParamWorkSpace()->paramSecurityOps; - paramSecurityOps->securityCheckParamPermission = TestCheckParamPermission; - g_testPermissionResult = DAC_RESULT_FORBIDED; - GetClientParamWorkSpace()->securityLabel->flags = LABEL_CHECK_FOR_ALL_PROCESS; - int ret = SystemSetParameter(testName, "22202"); - EXPECT_EQ(ret, DAC_RESULT_FORBIDED); - - paramSecurityOps->securityEncodeLabel = TestEncodeSecurityLabel; - paramSecurityOps->securityDecodeLabel = TestDecodeSecurityLabel; - paramSecurityOps->securityFreeLabel = TestFreeLocalSecurityLabel; - paramSecurityOps->securityCheckParamPermission = TestCheckParamPermission; - g_testPermissionResult = 0; - ret = SystemSetParameter(testName, "22202"); - EXPECT_EQ(ret, 0); - TestCheckParamValue(testName, "22202"); - - g_testPermissionResult = 201; - // 禁止写/读 - ret = SystemSetParameter(testName, "3333"); - EXPECT_EQ(ret, 201); - u_int32_t len = sizeof(tmp); - ret = SystemGetParameter(testName, tmp, &len); - EXPECT_EQ(ret, 201); - RegisterSecurityOps(paramSecurityOps, 0); - return 0; - } - - int TestDumpParamMemory() - { - DumpParameters(GetClientParamWorkSpace(), 1); - return 0; - } - - int TestCmd() - { - // set - const char *argForSet[] = { - "param", - "set", - "aaaa", - "2222" - }; - RunParamCommand(sizeof(argForSet) / sizeof(argForSet[0]), const_cast(argForSet)); - - // get - const char *argForGet[] = { - "param", - "get", - "aaaa" - }; - RunParamCommand(sizeof(argForGet) / sizeof(argForGet[0]), const_cast(argForGet)); - - // get all - const char *argForGet2[] = { - "param", - "get" - }; - RunParamCommand(sizeof(argForGet2) / sizeof(argForGet2[0]), const_cast(argForGet2)); - - // set 失败 - const char *argForSet2[] = { - "param", - "set", - "aaaa" - }; - RunParamCommand(sizeof(argForSet2) / sizeof(argForSet2[0]), const_cast(argForSet2)); - return 0; - } -}; - -TEST(ParamClientTest, TestSetParam) -{ - ParamClientTest test; - for (int i = 0; i < 20; i++) { - std::string info = std::to_string(i); - std::string name = "sys.init_log_level"; - name += "." + info; - std::string value = "sys.2222.3333333333333"; - value += "." + info; - test.TestSetParam(name.c_str(), value.c_str()); - } -} - -TEST(ParamClientTest, TestForMultiThread) -{ - ParamClientTest test; - test.TestForMultiThread(); -} - -TEST(ParamClientTest, TestUpdateParam) -{ - ParamClientTest test; - test.TestUpdateParam("test.aaa.bbb.ccc.ddd", "100"); - test.TestUpdateParam("test.aaa.bbb.ccc.ddd", "101"); - test.TestUpdateParam("test.aaa.bbb.ccc.ddd", "102"); - test.TestUpdateParam("test.aaa.bbb.ccc.ddd", "103"); - test.TestUpdateParam("net.tcp.default_init_rwnd", "60"); -} - -TEST(ParamClientTest, TestParamTraversal) -{ - ParamClientTest test; - test.TestParamTraversal(); -} - -TEST(ParamClientTest, TestPermission) -{ - ParamClientTest test; - test.TestPermission(); -} - -TEST(ParamClientTest, TestDumpParamMemory) -{ - ParamClientTest test; - test.TestDumpParamMemory(); -} - -TEST(ParamClientTest, TestCmd) -{ - ParamClientTest test; - test.TestCmd(); -} \ No newline at end of file diff --git a/services/test/unittest/param/dac_unittest.cpp b/services/test/unittest/param/dac_unittest.cpp deleted file mode 100755 index 85c6546c6..000000000 --- a/services/test/unittest/param/dac_unittest.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/* - * 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 -#include -#include -#include - -#include "param_security.h" -#include "param_unittest.h" -#include "param_utils.h" -#include "securec.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif -#endif -extern int RegisterSecurityDacOps(ParamSecurityOps *ops, int isInit); -#ifdef __cplusplus -#if __cplusplus -} -#endif -#endif - -using namespace std; -#define CHECK_FILE_NAME "/media/sf_ubuntu/develop/startup/init_lite/services/test/unittest/test_data/build.prop" - -static int SecurityLabelGet(const ParamAuditData *auditData, void *context) -{ - return 0; -} - -class ParamDacTest : public ::testing::Test { -public: - ParamDacTest() {} - virtual ~ParamDacTest() {} - - void SetUp() {} - void TearDown() {} - void TestBody() {} - - int TestDacGetLabel() - { - int ret = RegisterSecurityDacOps(&initParamSercurityOps, LABEL_INIT_FOR_INIT); - EXPECT_EQ(ret, 0); - - if (initParamSercurityOps.securityGetLabel == NULL) { - EXPECT_EQ(1, 0); - return -1; - } - ret = initParamSercurityOps.securityGetLabel(SecurityLabelGet, PARAM_DEFAULT_PATH, NULL); - EXPECT_EQ(ret, 0); - return 0; - } - - int TestDacInitLocalLabel() - { - int ret = RegisterSecurityDacOps(&initParamSercurityOps, LABEL_INIT_FOR_INIT); - EXPECT_EQ(ret, 0); - - if (initParamSercurityOps.securityInitLabel == NULL || initParamSercurityOps.securityFreeLabel == NULL) { - return -1; - } - ParamSecurityLabel *label = NULL; - ret = initParamSercurityOps.securityInitLabel(&label, LABEL_INIT_FOR_INIT); - EXPECT_EQ(ret, 0); - ret = initParamSercurityOps.securityFreeLabel(label); - EXPECT_EQ(ret, 0); - return 0; - } - - int TestDacCheckFilePermission(const char *fileName) - { - int ret = RegisterSecurityDacOps(&initParamSercurityOps, LABEL_INIT_FOR_INIT); - EXPECT_EQ(ret, 0); - if (initParamSercurityOps.securityCheckFilePermission == NULL) { - return -1; - } - ParamSecurityLabel *label = NULL; - ret = initParamSercurityOps.securityInitLabel(&label, LABEL_INIT_FOR_INIT); - EXPECT_EQ(ret, 0); - ret = initParamSercurityOps.securityCheckFilePermission(label, fileName, DAC_WRITE); - EXPECT_EQ(ret, 0); - ret = initParamSercurityOps.securityFreeLabel(label); - EXPECT_EQ(ret, 0); - return 0; - } - - int TestDacCheckParaPermission(const char *name, ParamDacData *dacData, int mode) - { - int ret = RegisterSecurityDacOps(&initParamSercurityOps, LABEL_INIT_FOR_INIT); - EXPECT_EQ(ret, 0); - if (initParamSercurityOps.securityCheckFilePermission == NULL) { - return -1; - } - ParamSecurityLabel *srclabel = NULL; - ret = initParamSercurityOps.securityInitLabel(&srclabel, LABEL_INIT_FOR_INIT); - EXPECT_EQ(ret, 0); - - ParamAuditData auditData = {}; - auditData.name = name; - auditData.label = nullptr; - memcpy_s(&auditData.dacData, sizeof(ParamDacData), dacData, sizeof(ParamDacData)); - ret = initParamSercurityOps.securityCheckParamPermission(srclabel, &auditData, mode); - initParamSercurityOps.securityFreeLabel(srclabel); - return ret; - } - - int TestClientDacCheckFilePermission(const char *fileName) - { - int ret = RegisterSecurityDacOps(&clientParamSercurityOps, 0); - EXPECT_EQ(ret, 0); - if (clientParamSercurityOps.securityDecodeLabel != NULL) { - EXPECT_EQ(1, 0); - } - if (clientParamSercurityOps.securityGetLabel != NULL) { - EXPECT_EQ(1, 0); - } - if (clientParamSercurityOps.securityCheckFilePermission == NULL) { - EXPECT_EQ(1, 0); - return -1; - } - ParamSecurityLabel *label = NULL; - ret = clientParamSercurityOps.securityInitLabel(&label, 0); - EXPECT_EQ(ret, 0); - ret = clientParamSercurityOps.securityCheckFilePermission(label, fileName, DAC_READ); - EXPECT_EQ(ret, 0); - ret = clientParamSercurityOps.securityFreeLabel(label); - EXPECT_EQ(ret, 0); - return 0; - } - - int TestEncode(const ParamSecurityLabel *label, std::vector &buffer) - { - int ret = RegisterSecurityDacOps(&clientParamSercurityOps, 0); - EXPECT_EQ(ret, 0); - if (clientParamSercurityOps.securityDecodeLabel != NULL) { - EXPECT_EQ(1, 0); - } - if (clientParamSercurityOps.securityGetLabel != NULL) { - EXPECT_EQ(1, 0); - } - if (clientParamSercurityOps.securityEncodeLabel == NULL) { - EXPECT_EQ(1, 0); - return -1; - } - uint32_t bufferSize = 0; - ret = clientParamSercurityOps.securityEncodeLabel(label, NULL, &bufferSize); - EXPECT_EQ(ret, 0); - buffer.resize(bufferSize + 1); - ret = clientParamSercurityOps.securityEncodeLabel(label, buffer.data(), &bufferSize); - EXPECT_EQ(ret, 0); - return 0; - } - - int TestDecode(const ParamSecurityLabel *label, std::vector &buffer) - { - int ret = RegisterSecurityDacOps(&clientParamSercurityOps, 1); - EXPECT_EQ(ret, 0); - if (clientParamSercurityOps.securityDecodeLabel == NULL) { - EXPECT_EQ(1, 0); - } - if (clientParamSercurityOps.securityEncodeLabel != NULL) { - EXPECT_EQ(1, 0); - return -1; - } - ParamSecurityLabel *tmp = NULL; - ret = clientParamSercurityOps.securityDecodeLabel(&tmp, buffer.data(), buffer.size()); - EXPECT_EQ(ret, 0); - EXPECT_EQ(label->cred.gid, tmp->cred.gid); - EXPECT_EQ(label->cred.uid, tmp->cred.uid); - return 0; - } - -private: - ParamSecurityOps initParamSercurityOps; - ParamSecurityOps clientParamSercurityOps; -}; - -TEST(ParamDacTest, TestDacGetLabel) -{ - ParamDacTest test; - test.TestDacGetLabel(); -} - -TEST(ParamDacTest, TestDacInitLocalLabel) -{ - ParamDacTest test; - test.TestDacInitLocalLabel(); -} - -TEST(ParamDacTest, TestDacLabelEncode) -{ - ParamDacTest test; - std::vector buffer; - ParamSecurityLabel label = {0, { 4444, 5555}}; - test.TestEncode(&label, buffer); - test.TestDecode(&label, buffer); -} - -TEST(ParamDacTest, TestDacCheckFilePermission) -{ - ParamDacTest test; - test.TestDacCheckFilePermission(CHECK_FILE_NAME); -} - -TEST(ParamDacTest, TestDacCheckUserParaPermission) -{ - // 相同用户 - ParamDacTest test; - ParamDacData dacData; - dacData.gid = getegid(); - dacData.uid = geteuid(); - // read - dacData.mode = 0400; - int ret = test.TestDacCheckParaPermission("test.permission.read.aaa", &dacData, DAC_READ); - EXPECT_EQ(ret, 0); - dacData.mode = 0400; - ret = test.TestDacCheckParaPermission("test.permission.read.aaa", &dacData, DAC_WRITE); - EXPECT_NE(ret, 0); - dacData.mode = 0400; - ret = test.TestDacCheckParaPermission("test.permission.read.aaa", &dacData, DAC_WATCH); - EXPECT_NE(ret, 0); - - // write - dacData.mode = 0200; - ret = test.TestDacCheckParaPermission("test.permission.write.aaa", &dacData, DAC_READ); - EXPECT_NE(ret, 0); - dacData.mode = 0200; - ret = test.TestDacCheckParaPermission("test.permission.write.aaa", &dacData, DAC_WRITE); - EXPECT_EQ(ret, 0); - dacData.mode = 0200; - ret = test.TestDacCheckParaPermission("test.permission.write.aaa", &dacData, DAC_WATCH); - EXPECT_NE(ret, 0); - - // watch - dacData.mode = 0100; - ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_READ); - EXPECT_NE(ret, 0); - dacData.mode = 0100; - ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_WRITE); - EXPECT_NE(ret, 0); - dacData.mode = 0100; - ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_WATCH); - EXPECT_EQ(ret, 0); -} - -TEST(ParamDacTest, TestDacCheckGroupParaPermission) -{ - // 相同组 - ParamDacTest test; - ParamDacData dacData; - dacData.gid = getegid(); - dacData.uid = 13333; - // read - dacData.mode = 0040; - int ret = test.TestDacCheckParaPermission("test.permission.read.aaa", &dacData, DAC_READ); - EXPECT_EQ(ret, 0); - dacData.mode = 0040; - ret = test.TestDacCheckParaPermission("test.permission.read.aaa", &dacData, DAC_WRITE); - EXPECT_NE(ret, 0); - dacData.mode = 0040; - ret = test.TestDacCheckParaPermission("test.permission.read.aaa", &dacData, DAC_WATCH); - EXPECT_NE(ret, 0); - - // write - dacData.mode = 0020; - ret = test.TestDacCheckParaPermission("test.permission.write.aaa", &dacData, DAC_READ); - EXPECT_NE(ret, 0); - dacData.mode = 0020; - ret = test.TestDacCheckParaPermission("test.permission.write.aaa", &dacData, DAC_WRITE); - EXPECT_EQ(ret, 0); - dacData.mode = 0020; - ret = test.TestDacCheckParaPermission("test.permission.write.aaa", &dacData, DAC_WATCH); - EXPECT_NE(ret, 0); - - // watch - dacData.mode = 0010; - ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_READ); - EXPECT_NE(ret, 0); - dacData.mode = 0010; - ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_WRITE); - EXPECT_NE(ret, 0); - dacData.mode = 0010; - ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_WATCH); - EXPECT_EQ(ret, 0); -} - -TEST(ParamDacTest, TestDacCheckOtherParaPermission) -{ - // 其他用户 - ParamDacTest test; - ParamDacData dacData; - dacData.gid = 13333; - dacData.uid = 13333; - // read - dacData.mode = 0004; - int ret = test.TestDacCheckParaPermission("test.permission.read.aaa", &dacData, DAC_READ); - EXPECT_EQ(ret, 0); - dacData.mode = 0004; - ret = test.TestDacCheckParaPermission("test.permission.read.aaa", &dacData, DAC_WRITE); - EXPECT_NE(ret, 0); - dacData.mode = 0004; - ret = test.TestDacCheckParaPermission("test.permission.read.aaa", &dacData, DAC_WATCH); - EXPECT_NE(ret, 0); - - // write - dacData.mode = 0002; - ret = test.TestDacCheckParaPermission("test.permission.write.aaa", &dacData, DAC_READ); - EXPECT_NE(ret, 0); - dacData.mode = 0002; - ret = test.TestDacCheckParaPermission("test.permission.write.aaa", &dacData, DAC_WRITE); - EXPECT_EQ(ret, 0); - dacData.mode = 0002; - ret = test.TestDacCheckParaPermission("test.permission.write.aaa", &dacData, DAC_WATCH); - EXPECT_NE(ret, 0); - - // watch - dacData.mode = 0001; - ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_READ); - EXPECT_NE(ret, 0); - dacData.mode = 0001; - ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_WRITE); - EXPECT_NE(ret, 0); - dacData.mode = 0001; - ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_WATCH); - EXPECT_EQ(ret, 0); -} - -TEST(ParamDacTest, TestClientDacCheckFilePermission) -{ - ParamDacTest test; - test.TestClientDacCheckFilePermission(CHECK_FILE_NAME); -} diff --git a/services/test/unittest/param/param_unittest.h b/services/test/unittest/param/param_unittest.h deleted file mode 100755 index 9e06a946d..000000000 --- a/services/test/unittest/param/param_unittest.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include - -#include "param_service.h" - -#define LABEL "ParamTest" -#define THREAD_NUM_TEST 10 - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif -#endif -extern int RunParamCommand(int argc, char *argv[]); -#ifdef __cplusplus -#if __cplusplus -} -#endif -#endif - -static ParamSecurityLabel g_testLabel; -static int g_testPermissionResult = DAC_RESULT_PERMISSION; - -static int TestEncodeSecurityLabel(const ParamSecurityLabel *srcLabel, char *buffer, uint32_t *bufferSize) -{ - PARAM_CHECK(bufferSize != NULL, return -1, "Invalid param"); - if (buffer == NULL) { - *bufferSize = sizeof(ParamSecurityLabel); - return 0; - } - PARAM_CHECK(*bufferSize >= sizeof(ParamSecurityLabel), return -1, "Invalid buffersize %u", *bufferSize); - *bufferSize = sizeof(ParamSecurityLabel); - return memcpy_s(buffer, *bufferSize, srcLabel, sizeof(ParamSecurityLabel)); -} - -static int TestDecodeSecurityLabel(ParamSecurityLabel **srcLabel, char *buffer, uint32_t bufferSize) -{ - PARAM_CHECK(bufferSize >= sizeof(ParamSecurityLabel), return -1, "Invalid buffersize %u", bufferSize); - PARAM_CHECK(srcLabel != NULL && buffer != NULL, return -1, "Invalid param"); - *srcLabel = (ParamSecurityLabel *)buffer; - return 0; -} - -static int TestCheckParamPermission(const ParamSecurityLabel *srcLabel, const ParamAuditData *auditData, int mode) -{ - // DAC_RESULT_FORBIDED - return g_testPermissionResult; -} - -static int TestFreeLocalSecurityLabel(ParamSecurityLabel *srcLabel) -{ - return 0; -} \ No newline at end of file diff --git a/services/test/unittest/param/selinux_unittest.cpp b/services/test/unittest/param/selinux_unittest.cpp deleted file mode 100755 index 8b67faefd..000000000 --- a/services/test/unittest/param/selinux_unittest.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/* - * 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 -#include -#include -#include - -#include "param_security.h" -#include "param_unittest.h" -#include "param_utils.h" -#include "securec.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif -#endif -extern int RegisterSecuritySelinuxOps(ParamSecurityOps *ops, int isInit); -#ifdef __cplusplus -#if __cplusplus -} -#endif -#endif - -using namespace std; -#define CHECK_FILE_NAME "/media/sf_ubuntu/develop/startup/init_lite/services/test/unittest/test_data/build.prop" - -static int SecurityLabelGet(const ParamAuditData *auditData, void *context) -{ - return 0; -} - -class ParamSelinuxTest : public ::testing::Test { -public: - ParamSelinuxTest() {} - virtual ~ParamSelinuxTest() {} - - void SetUp() {} - void TearDown() {} - void TestBody() {} - - int TestSelinuxGetLabel() - { - int ret = RegisterSecuritySelinuxOps(&initParamSercurityOps, LABEL_INIT_FOR_INIT); - EXPECT_EQ(ret, 0); - - if (initParamSercurityOps.securityGetLabel == NULL) { - EXPECT_EQ(1, 0); - return -1; - } - ret = initParamSercurityOps.securityGetLabel(SecurityLabelGet, PARAM_DEFAULT_PATH, NULL); - EXPECT_EQ(ret, 0); - return 0; - } - - int TestSelinuxInitLocalLabel() - { - int ret = RegisterSecuritySelinuxOps(&initParamSercurityOps, LABEL_INIT_FOR_INIT); - EXPECT_EQ(ret, 0); - - if (initParamSercurityOps.securityInitLabel == NULL || initParamSercurityOps.securityFreeLabel == NULL) { - return -1; - } - ParamSecurityLabel *label = NULL; - ret = initParamSercurityOps.securityInitLabel(&label, LABEL_INIT_FOR_INIT); - EXPECT_EQ(ret, 0); - ret = initParamSercurityOps.securityFreeLabel(label); - EXPECT_EQ(ret, 0); - return 0; - } - - int TestSelinuxCheckFilePermission(const char *fileName) - { - int ret = RegisterSecuritySelinuxOps(&initParamSercurityOps, LABEL_INIT_FOR_INIT); - EXPECT_EQ(ret, 0); - if (initParamSercurityOps.securityCheckFilePermission == NULL) { - return -1; - } - ParamSecurityLabel *label = NULL; - ret = initParamSercurityOps.securityInitLabel(&label, LABEL_INIT_FOR_INIT); - EXPECT_EQ(ret, 0); - ret = initParamSercurityOps.securityCheckFilePermission(label, fileName, DAC_WRITE); - EXPECT_EQ(ret, 0); - ret = initParamSercurityOps.securityFreeLabel(label); - EXPECT_EQ(ret, 0); - return 0; - } - - int TestSelinuxCheckParaPermission(const char *name, const char *label) - { - int ret = RegisterSecuritySelinuxOps(&initParamSercurityOps, LABEL_INIT_FOR_INIT); - EXPECT_EQ(ret, 0); - if (initParamSercurityOps.securityCheckFilePermission == NULL) { - return -1; - } - ParamSecurityLabel *srclabel = NULL; - ret = initParamSercurityOps.securityInitLabel(&srclabel, LABEL_INIT_FOR_INIT); - EXPECT_EQ(ret, 0); - - ParamAuditData auditData = {}; - auditData.name = name; - // auditData.cr = srclabel->cred; // "u:object_r:default_prop:s0"; - auditData.label = label; - - ret = initParamSercurityOps.securityCheckParamPermission(srclabel, &auditData, DAC_WRITE); - EXPECT_EQ(ret, 0); - ret = initParamSercurityOps.securityFreeLabel(srclabel); - EXPECT_EQ(ret, 0); - return 0; - } - - int TestClientSelinuxCheckFilePermission(const char *fileName) - { - int ret = RegisterSecuritySelinuxOps(&clientParamSercurityOps, 0); - EXPECT_EQ(ret, 0); - if (clientParamSercurityOps.securityDecodeLabel != NULL) { - EXPECT_EQ(1, 0); - } - if (clientParamSercurityOps.securityGetLabel != NULL) { - EXPECT_EQ(1, 0); - } - if (clientParamSercurityOps.securityCheckFilePermission == NULL) { - EXPECT_EQ(1, 0); - return -1; - } - ParamSecurityLabel *label = NULL; - ret = clientParamSercurityOps.securityInitLabel(&label, 0); - EXPECT_EQ(ret, 0); - ret = clientParamSercurityOps.securityCheckFilePermission(label, fileName, DAC_READ); - EXPECT_EQ(ret, 0); - ret = clientParamSercurityOps.securityFreeLabel(label); - EXPECT_EQ(ret, 0); - return 0; - } - - int TestClientSelinuxCheckParaPermissionWrite(const char *name, const char *label) - { - int ret = RegisterSecuritySelinuxOps(&clientParamSercurityOps, 0); - EXPECT_EQ(ret, 0); - - if (clientParamSercurityOps.securityCheckFilePermission == NULL) { - return -1; - } - ParamSecurityLabel *srclabel = NULL; - ret = clientParamSercurityOps.securityInitLabel(&srclabel, 0); - EXPECT_EQ(ret, 0); - - ParamAuditData auditData = {}; - auditData.name = name; - // auditData.cr = srclabel->cred; // "u:object_r:default_prop:s0"; - auditData.label = label; - - ret = clientParamSercurityOps.securityCheckParamPermission(srclabel, &auditData, DAC_WRITE); - EXPECT_EQ(ret, 0); - ret = clientParamSercurityOps.securityFreeLabel(srclabel); - EXPECT_EQ(ret, 0); - return 0; - } - - int TestClientSelinuxCheckParaPermissionRead(const char *name, const char *label) - { - int ret = RegisterSecuritySelinuxOps(&clientParamSercurityOps, 0); - EXPECT_EQ(ret, 0); - if (clientParamSercurityOps.securityCheckFilePermission == NULL) { - return -1; - } - ParamSecurityLabel *srclabel = NULL; - ret = clientParamSercurityOps.securityInitLabel(&srclabel, 0); - EXPECT_EQ(ret, 0); - - ParamAuditData auditData = {}; - auditData.name = name; - // auditData.cr = srclabel->cred; // "u:object_r:default_prop:s0"; - auditData.label = label; - - ret = clientParamSercurityOps.securityCheckParamPermission(srclabel, &auditData, DAC_READ); - EXPECT_EQ(ret, 0); - ret = clientParamSercurityOps.securityFreeLabel(srclabel); - EXPECT_EQ(ret, 0); - return 0; - } - -private: - ParamSecurityOps initParamSercurityOps; - ParamSecurityOps clientParamSercurityOps; -}; - -TEST(ParamSelinuxTest, TestSelinuxGetLabel) -{ - ParamSelinuxTest test; - test.TestSelinuxGetLabel(); -} - -TEST(ParamSelinuxTest, TestSelinuxInitLocalLabel) -{ - ParamSelinuxTest test; - test.TestSelinuxInitLocalLabel(); -} - -TEST(ParamSelinuxTest, TestSelinuxCheckFilePermission) -{ - ParamSelinuxTest test; - test.TestSelinuxCheckFilePermission(CHECK_FILE_NAME); -} - -TEST(ParamSelinuxTest, TestSelinuxCheckParaPermission) -{ - ParamSelinuxTest test; - test.TestSelinuxCheckParaPermission("aaa.bbb.bbb.ccc", "user:group1:r"); -} - -TEST(ParamSelinuxTest, TestClientDacCheckFilePermission) -{ - ParamSelinuxTest test; - test.TestClientSelinuxCheckFilePermission(CHECK_FILE_NAME); -} - -TEST(ParamSelinuxTest, TestClientDacCheckParaPermission) -{ - ParamSelinuxTest test; - test.TestClientSelinuxCheckParaPermissionWrite("aaa.bbb.bbb.ccc", "user:group1:r"); - test.TestClientSelinuxCheckParaPermissionRead("aaa.bbb.bbb.ccc", "user:group1:r"); -} \ No newline at end of file diff --git a/services/test/unittest/param/service_unittest.cpp b/services/test/unittest/param/service_unittest.cpp deleted file mode 100755 index e4cc0180a..000000000 --- a/services/test/unittest/param/service_unittest.cpp +++ /dev/null @@ -1,646 +0,0 @@ -/* - * 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 -#include -#include -#include -#include - -#include "init_param.h" -#include "init_utils.h" -#include "param_libuvadp.h" -#include "param_manager.h" -#include "param_service.h" -#include "param_unittest.h" -#include "param_utils.h" -#include "trigger_manager.h" - -#define TEST_PARAM_NAME 0 -#define TEST_PARAM_VALUE 1 -#define DEFAULT_PARAM_FILE PARAM_DEFAULT_PATH "/etc/param" - -static int CheckServerParamValue(const char *name, const char *expectValue) -{ - char tmp[PARAM_BUFFER_SIZE] = { 0 }; - u_int32_t len = sizeof(tmp); - SystemReadParam(name, tmp, &len); - printf("CheckParamValue name %s value: \'%s\' expectValue:\'%s\' \n", name, tmp, expectValue); - EXPECT_NE(strlen(tmp), 0); - if (expectValue != NULL) { - EXPECT_EQ(strcmp(tmp, expectValue), 0); - } - return 0; -} - -ParamTask *g_worker = NULL; -class ParamServiceTest : public ::testing::Test { -public: - ParamServiceTest() {} - virtual ~ParamServiceTest() {} - - void SetUp() {} - void TearDown() {} - void TestBody() {} - - int TestParamServiceInit() - { - InitParamService(); - LoadDefaultParams(DEFAULT_PARAM_FILE, 0); - CheckServerParamValue("const.actionable_compatible_property.enabled", "false"); - CheckServerParamValue("build_version", "2.0"); - return 0; - } - - int TestSetParams(const char *params[][TEST_PARAM_VALUE + 1], int num) - { - for (int i = 0; i < num; i++) { - SystemWriteParam(params[i][TEST_PARAM_NAME], params[i][TEST_PARAM_VALUE]); - } - - // check - for (int i = 0; i < num; i++) { - CheckServerParamValue(params[i][TEST_PARAM_NAME], params[i][TEST_PARAM_VALUE]); - } - - for (int i = num - 1; i >= 0; i--) { - CheckServerParamValue(params[i][TEST_PARAM_NAME], params[i][TEST_PARAM_VALUE]); - } - return 0; - } - - int TestAddSecurityLabel1() - { - GetParamWorkSpace()->securityLabel->cred.gid = 9999; - const char *name = "label1.test.aaa.bbb.ccc.dddd.eee"; - const char *value = "2001"; - uint32_t labelIndex = 0; - SystemWriteParam(name, value); - // 获取到跟属性 - ParamTrieNode *paramNode = FindTrieNode(&GetParamWorkSpace()->paramSpace, name, strlen(name), &labelIndex); - ParamSecruityNode *node = (ParamSecruityNode *)GetTrieNode(&GetParamWorkSpace()->paramSpace, labelIndex); - if (paramNode == NULL || node == NULL) { - EXPECT_EQ(1, 0); - return 0; - } - EXPECT_EQ(node->gid, getegid()); - return 0; - } - - // 添加一个label,最长匹配到这个节点 - int TestAddSecurityLabel2() - { - GetParamWorkSpace()->securityLabel->cred.gid = 9999; - const char *name = "label2.test.aaa.bbb.ccc.dddd.eee"; - const char *value = "2001"; - ParamAuditData auditData = {}; - auditData.name = "label2.test.aaa"; - auditData.label = "label2.test.aaa"; - auditData.dacData.gid = 2002; - auditData.dacData.uid = geteuid(); - auditData.dacData.mode = 0666; - SystemWriteParam(name, value); - uint32_t labelIndex = 0; - AddSecurityLabel(&auditData, GetParamWorkSpace()); - ParamTrieNode *paramNode = FindTrieNode(&GetParamWorkSpace()->paramSpace, name, strlen(name), &labelIndex); - ParamSecruityNode *node = (ParamSecruityNode *)GetTrieNode(&GetParamWorkSpace()->paramSpace, labelIndex); - if (paramNode == NULL || node == NULL) { - EXPECT_EQ(1, 0); - } - EXPECT_EQ(node->gid, auditData.dacData.gid); - return 0; - } - - // 添加一个label,最长匹配到最后一个相同节点 - int TestAddSecurityLabel3() - { - GetParamWorkSpace()->securityLabel->cred.gid = 9999; - const char *name = "label3.test.aaa.bbb.ccc.dddd.eee"; - const char *value = "2001"; - ParamAuditData auditData = {}; - auditData.name = "label3.test.aaa"; - auditData.label = "label3.test.aaa"; - auditData.dacData.gid = 2003; - auditData.dacData.uid = geteuid(); - auditData.dacData.mode = 0666; - SystemWriteParam(name, value); - AddSecurityLabel(&auditData, GetParamWorkSpace()); - - auditData.name = "label3.test.aaa.bbb.ccc.dddd.eee.dddd"; - auditData.label = "label3.test.aaa.bbb.ccc.dddd.eee.dddd"; - auditData.dacData.gid = 2004; - auditData.dacData.uid = geteuid(); - auditData.dacData.mode = 0666; - SystemWriteParam(name, value); - AddSecurityLabel(&auditData, GetParamWorkSpace()); - - uint32_t labelIndex = 0; - ParamTrieNode *paramNode = FindTrieNode(&GetParamWorkSpace()->paramSpace, name, strlen(name), &labelIndex); - ParamSecruityNode *node = (ParamSecruityNode *)GetTrieNode(&GetParamWorkSpace()->paramSpace, labelIndex); - if (paramNode == NULL || node == NULL) { - EXPECT_EQ(1, 0); - } - EXPECT_EQ(node->gid, 2003); - return 0; - } - - // 添加一个label,完全匹配 - int TestAddSecurityLabel4() - { - GetParamWorkSpace()->securityLabel->cred.gid = 9999; - const char *name = "label4.test.aaa.bbb.ccc.dddd.eee"; - const char *value = "2001"; - ParamAuditData auditData = {}; - auditData.name = "label4.test.aaa.bbb.ccc.dddd.eee"; - auditData.label = "label4.test.aaa.bbb.ccc.dddd.eee"; - auditData.dacData.gid = 2004; - auditData.dacData.uid = geteuid(); - auditData.dacData.mode = 0666; - SystemWriteParam(name, value); - uint32_t labelIndex = 0; - AddSecurityLabel(&auditData, GetParamWorkSpace()); - ParamTrieNode *paramNode = FindTrieNode(&GetParamWorkSpace()->paramSpace, name, strlen(name), &labelIndex); - ParamSecruityNode *node = (ParamSecruityNode *)GetTrieNode(&GetParamWorkSpace()->paramSpace, labelIndex); - if (paramNode == NULL || node == NULL) { - EXPECT_EQ(1, 0); - } - EXPECT_EQ(node->gid, auditData.dacData.gid); - return 0; - } - - void TestBufferValue(char *buffer, uint32_t len) - { - for (uint32_t index = 0; index <= len; index++) { - buffer[index] = '0' + index % 10; - if (index != 0 && index % 10 == 0) { - buffer[index] = '.'; - } - } - buffer[len] = '\0'; - } - - int TestNameIsValid() - { - char buffer[PARAM_BUFFER_SIZE]; - // set name length = 127 - TestBufferValue(buffer, PARAM_NAME_LEN_MAX - 1); - int ret = SystemWriteParam(buffer, "1111"); - EXPECT_EQ(ret, 0); - TestBufferValue(buffer, PARAM_NAME_LEN_MAX); - ret = SystemWriteParam(buffer, "1111"); - EXPECT_NE(ret, 0); - TestBufferValue(buffer, PARAM_NAME_LEN_MAX + 1); - ret = SystemWriteParam(buffer, "1111"); - EXPECT_NE(ret, 0); - - // 保存一个只读的属性,大于最大值 - TestBufferValue(buffer, PARAM_VALUE_LEN_MAX - 1); - ret = SystemWriteParam("const.test_readonly.dddddddddddddddddd.fffffffffffffffffff", buffer); - EXPECT_EQ(ret, 0); - - TestBufferValue(buffer, PARAM_VALUE_LEN_MAX + 1); - ret = SystemWriteParam("const.test_readonly.aaaaaaaaaaaaaaaaaa.fffffffffffffffffff", buffer); - EXPECT_EQ(ret, 0); - - // 更新只读项目 - TestBufferValue(buffer, PARAM_VALUE_LEN_MAX - 1); - ret = SystemWriteParam("const.test_readonly.dddddddddddddddddd.fffffffffffffffffff", buffer); - EXPECT_NE(ret, 0); - - // 写普通属性 - TestBufferValue(buffer, PARAM_VALUE_LEN_MAX - 1); - ret = SystemWriteParam("test.bigvalue.dddddddddddddddddd.fffffffffffffffffff", buffer); - EXPECT_EQ(ret, 0); - TestBufferValue(buffer, PARAM_VALUE_LEN_MAX + 1); - ret = SystemWriteParam("test.bigvalue.dddddddddddddddddd.fffffffffffffffffff", buffer); - EXPECT_NE(ret, 0); - - // invalid name - TestBufferValue(buffer, PARAM_VALUE_LEN_MAX - 1); - ret = SystemWriteParam("test.invalidname..fffffffffffffffffff", buffer); - EXPECT_NE(ret, 0); - ret = SystemWriteParam("test.invalidname.%fffffffffffffffffff", buffer); - EXPECT_NE(ret, 0); - ret = SystemWriteParam("test.invalidname.$fffffffffffffffffff", buffer); - EXPECT_NE(ret, 0); - return 0; - } - - int TestParamTraversal() - { - char value[PARAM_BUFFER_SIZE + PARAM_BUFFER_SIZE] = { 0 }; - SystemTraversalParam( - [](ParamHandle handle, void *cookie) { - ReadParamName(GetParamWorkSpace(), handle, (char *)cookie, PARAM_BUFFER_SIZE); - u_int32_t len = PARAM_BUFFER_SIZE; - ReadParamValue(GetParamWorkSpace(), handle, ((char *)cookie) + PARAM_BUFFER_SIZE, &len); - printf("$$$$$$$$Param %s=%s \n", (char *)cookie, ((char *)cookie) + PARAM_BUFFER_SIZE); - }, - (void *)value); - return 0; - } - - int TestUpdateParam(const char *name, const char *value) - { - SystemWriteParam(name, value); - SystemWriteParam(name, value); - SystemWriteParam(name, value); - SystemWriteParam(name, value); - CheckServerParamValue(name, value); - return 0; - } - - int TestPersistParam() - { - LoadPersistParams(); - SystemWriteParam("persist.111.ffff.bbbb.cccc.dddd.eeee", "1101"); - SystemWriteParam("persist.111.aaaa.bbbb.cccc.dddd.eeee", "1102"); - SystemWriteParam("persist.111.bbbb.cccc.dddd.eeee", "1103"); - CheckServerParamValue("persist.111.bbbb.cccc.dddd.eeee", "1103"); - SystemWriteParam("persist.111.cccc.bbbb.cccc.dddd.eeee", "1104"); - SystemWriteParam("persist.111.eeee.bbbb.cccc.dddd.eeee", "1105"); - CheckServerParamValue("persist.111.ffff.bbbb.cccc.dddd.eeee", "1101"); - SystemWriteParam("persist.111.ffff.bbbb.cccc.dddd.eeee", "1106"); - LoadPersistParams(); - CheckServerParamValue("persist.111.ffff.bbbb.cccc.dddd.eeee", "1106"); - return 0; - } - - int FillLabelContent(ParamSecurityOps *paramSecurityOps, ParamMessage *request, uint32_t *start, uint32_t length) - { - uint32_t bufferSize = request->msgSize - sizeof(ParamMessage); - uint32_t offset = *start; - PARAM_CHECK((offset + sizeof(ParamMsgContent) + length) <= bufferSize, - return -1, "Invalid msgSize %u offset %u", request->msgSize, offset); - ParamMsgContent *content = (ParamMsgContent *)(request->data + offset); - content->type = PARAM_LABEL; - content->contentSize = 0; - if (length != 0 && paramSecurityOps->securityEncodeLabel != NULL) { - int ret = paramSecurityOps->securityEncodeLabel( - GetParamWorkSpace()->securityLabel, content->content, &length); - PARAM_CHECK(ret == 0, return -1, "Failed to get label length"); - content->contentSize = length; - } - offset += sizeof(ParamMsgContent) + PARAM_ALIGN(content->contentSize); - *start = offset; - return 0; - } - - ParamTask *CreateAndGetStreamTask() - { - LibuvServerTask *server = (LibuvServerTask *)GetParamWorkSpace()->serverTask; - if (server == NULL) { - EXPECT_NE(0, 0); - return NULL; - } - - // 创建stream task - server->incomingConnect((ParamTaskPtr)server, WORKER_TYPE_TEST); - ParamWatcher *watcher = GetNextParamWatcher(GetTriggerWorkSpace(), NULL); - return watcher != NULL ? watcher->stream : NULL; - } - - int TestServiceProcessMessage(const char *name, const char *value, int userLabel) - { - if (g_worker == NULL) { - g_worker = CreateAndGetStreamTask(); - } - uint32_t labelLen = 0; - ParamSecurityOps *paramSecurityOps = &GetParamWorkSpace()->paramSecurityOps; - if (userLabel) { - paramSecurityOps->securityEncodeLabel = TestEncodeSecurityLabel; - paramSecurityOps->securityDecodeLabel = TestDecodeSecurityLabel; - paramSecurityOps->securityFreeLabel = TestFreeLocalSecurityLabel; - paramSecurityOps->securityCheckParamPermission = TestCheckParamPermission; - } - uint32_t msgSize = sizeof(ParamMessage) + sizeof(ParamMsgContent) + PARAM_ALIGN(strlen(value) + 1); - if (paramSecurityOps->securityEncodeLabel != NULL) { - int ret = paramSecurityOps->securityEncodeLabel(GetParamWorkSpace()->securityLabel, NULL, &labelLen); - PARAM_CHECK(ret == 0, return -1, "Failed to get label length"); - msgSize += sizeof(ParamMsgContent) + PARAM_ALIGN(labelLen); - } - ParamMessage *request = (ParamMessage *)CreateParamMessage(MSG_SET_PARAM, name, msgSize); - PARAM_CHECK(request != NULL, return -1, "Failed to malloc for connect"); - do { - request->type = MSG_SET_PARAM; - uint32_t offset = 0; - int ret = FillParamMsgContent(request, &offset, PARAM_VALUE, value, strlen(value)); - PARAM_CHECK(ret == 0, return -1, "Failed to fill value"); - ret = FillLabelContent(paramSecurityOps, request, &offset, labelLen); - PARAM_CHECK(ret == 0, return -1, "Failed to fill label"); - ProcessMessage((const ParamTaskPtr)g_worker, (const ParamMessage *)request); - } while (0); - free(request); - CheckServerParamValue(name, value); - RegisterSecurityOps(paramSecurityOps, 1); - return 0; - } - - int AddWatch(int type, const char *name, const char *value) - { - if (g_worker == NULL) { - g_worker = CreateAndGetStreamTask(); - } - uint32_t msgSize = sizeof(ParamMessage) + sizeof(ParamMsgContent) + PARAM_ALIGN(strlen(value) + 1); - ParamMessage *request = (ParamMessage *)(ParamMessage *)CreateParamMessage(MSG_SET_PARAM, name, msgSize); - PARAM_CHECK(request != NULL, return -1, "Failed to malloc for connect"); - do { - uint32_t offset = 0; - int ret = FillParamMsgContent(request, &offset, PARAM_VALUE, value, strlen(value)); - PARAM_CHECK(ret == 0, return -1, "Failed to fill value"); - ProcessMessage((const ParamTaskPtr)g_worker, (const ParamMessage *)request); - } while (0); - free(request); - return 0; - } - - // 无匹配 - int TestAddParamWait1() - { - const char *name = "wait.aaa.bbb.ccc.111"; - const char *value = "wait1"; - AddWatch(MSG_WAIT_PARAM, name, value); - SystemWriteParam(name, value); - return 0; - } - - // 模糊匹配 - int TestAddParamWait2() - { - const char *name = "wait.aaa.bbb.ccc.222"; - const char *value = "wait2"; - AddWatch(MSG_WAIT_PARAM, name, "*"); - SystemWriteParam(name, value); - return 0; - } - - // 属性存在 - int TestAddParamWait3() - { - const char *name = "wait.aaa.bbb.ccc.333"; - const char *value = "wait3"; - SystemWriteParam(name, value); - AddWatch(MSG_WAIT_PARAM, name, value); - return 0; - } - - int TestAddParamWatch1() - { - const char *name = "watch.aaa.bbb.ccc.111"; - const char *value = "watch1"; - AddWatch(MSG_ADD_WATCHER, name, value); - std::string newName = name; - newName += ".test.test.test"; - SystemWriteParam(newName.c_str(), value); - return 0; - } - - int TestAddParamWatch2() - { - const char *name = "watch.aaa.bbb.ccc.222"; - const char *value = "watch2"; - AddWatch(MSG_ADD_WATCHER, name, "*"); - SystemWriteParam(name, value); - return 0; - } - - int TestAddParamWatch3() - { - const char *name = "watch.aaa.bbb.ccc.333"; - const char *value = "watch3"; - std::string newName = name; - newName += ".test.test.test"; - SystemWriteParam(newName.c_str(), value); - AddWatch(MSG_ADD_WATCHER, name, value); - return 0; - } - - int TestCloseTriggerWatch() - { - ParamTaskClose(g_worker); - g_worker = NULL; - return 0; - } - - int TestDumpParamMemory() - { - DumpParameters(GetParamWorkSpace(), 1); - return 0; - } - - int TestServiceCtrl(const char *serviceName, int mode) - { - // service forbit - ParamAuditData auditData = {}; - auditData.name = "ohos.servicectrl."; - auditData.label = ""; - auditData.dacData.gid = 2002; - auditData.dacData.uid = 2002; - auditData.dacData.mode = mode; - AddSecurityLabel(&auditData, GetParamWorkSpace()); - return SystemWriteParam("ohos.ctl.start", serviceName); - } - - int TestPowerCtrl(const char *reboot, int mode) - { - // service forbit - ParamAuditData auditData = {}; - auditData.name = "ohos.servicectrl."; - auditData.label = ""; - auditData.dacData.gid = 2002; - auditData.dacData.uid = 2002; - auditData.dacData.mode = mode; - AddSecurityLabel(&auditData, GetParamWorkSpace()); - return SystemWriteParam("sys.powerctrl", reboot); - } -}; - -TEST(ParamServiceTest, TestParamServiceInit) -{ - ParamServiceTest test; - test.TestParamServiceInit(); -} - -TEST(ParamServiceTest, TestPersistParam) -{ - ParamServiceTest test; - test.TestPersistParam(); -} - -TEST(ParamServiceTest, TestSetParam_1) -{ - ParamServiceTest test; - const char *params[][2] = { { "111.2222", "1" }, - { "111.2222.3333", "2" }, - { "111.2222.3333.4444", "3" }, - { "111.2222.3333.4444.666", "4" }, - { "111.2222.3333.4444.666.777", "5" } }; - test.TestSetParams(params, 5); -} - -TEST(ParamServiceTest, TestSetParam_2) -{ - ParamServiceTest test; - const char *params[][2] = { { "111.2222.xxxx.xxx.xxx", "1_1" }, - { "111.2222.3333.xxx", "1_2" }, - { "111.2222.xxxx.3333.4444", "1_3" }, - { "111.2222.3333.xxxx.4444.666", "1_4" }, - { "111.2222.3333.4444.666.xxxxx.777", "1_5" } }; - test.TestSetParams(params, 5); - - const char *ctrlParams[][2] = { { "ctl.start.111.2222.xxxx.xxx.xxx", "2_1" }, - { "ctl.start.111.2222.3333.xxx", "2_2" }, - { "ctl.start.111.2222.xxxx.3333.4444", "2_3" }, - { "ctl.start.111.2222.3333.xxxx.4444.666", "2_4" }, - { "ctl.start.111.2222.3333.4444.666.xxxxx.777", "2_5" } }; - test.TestSetParams(ctrlParams, 5); - - const char *sysParams[][2] = { { "sys.powerctrl.111.2222.xxxx.xxx.xxx", "3_1" }, - { "sys.powerctrl.111.2222.3333.xxx", "3_2" }, - { "sys.powerctrl.111.2222.xxxx.3333.4444", "3_3" }, - { "sys.powerctrl.111.2222.3333.xxxx.4444.666", "3_4" }, - { "sys.powerctrl.111.2222.3333.4444.666.xxxxx.777", "3_5" } }; - test.TestSetParams(sysParams, 5); -} - -TEST(ParamServiceTest, TestNameIsValid) -{ - ParamServiceTest test; - test.TestNameIsValid(); -} - -TEST(ParamServiceTest, TestAddSecurityLabel1) -{ - ParamServiceTest test; - test.TestAddSecurityLabel1(); -} - -TEST(ParamServiceTest, TestAddSecurityLabel2) -{ - ParamServiceTest test; - test.TestAddSecurityLabel2(); -} - -TEST(ParamServiceTest, TestAddSecurityLabel3) -{ - ParamServiceTest test; - test.TestAddSecurityLabel3(); -} - -TEST(ParamServiceTest, TestAddSecurityLabel4) -{ - ParamServiceTest test; - test.TestAddSecurityLabel4(); -} - -TEST(ParamServiceTest, TestUpdateParam) -{ - ParamServiceTest test; - test.TestUpdateParam("test.aaa.bbb.ccc.ddd", "100"); - test.TestUpdateParam("test.aaa.bbb.ccc.ddd", "101"); - test.TestUpdateParam("test.aaa.bbb.ccc.ddd", "102"); - test.TestUpdateParam("test.aaa.bbb.ccc.ddd", "103"); - test.TestUpdateParam("net.tcp.default_init_rwnd", "60"); -} - -TEST(ParamServiceTest, TestServiceProcessMessage) -{ - ParamServiceTest test; - test.TestServiceProcessMessage("wertt.qqqq.wwww.rrrr", "wwww.eeeee", 1); - test.TestServiceProcessMessage("wertt.2222.wwww.3333", "wwww.eeeee", 0); -} - -TEST(ParamServiceTest, TestAddParamWait1) -{ - ParamServiceTest test; - test.TestAddParamWait1(); -} - -TEST(ParamServiceTest, TestAddParamWait2) -{ - ParamServiceTest test; - test.TestAddParamWait2(); -} - -TEST(ParamServiceTest, TestAddParamWait3) -{ - ParamServiceTest test; - test.TestAddParamWait3(); -} - -TEST(ParamServiceTest, TestAddParamWatch1) -{ - ParamServiceTest test; - test.TestAddParamWatch1(); -} - -TEST(ParamServiceTest, TestAddParamWatch2) -{ - ParamServiceTest test; - test.TestAddParamWatch2(); -} - -TEST(ParamServiceTest, TestAddParamWatch3) -{ - ParamServiceTest test; - test.TestAddParamWatch3(); -} - -TEST(ParamServiceTest, TestCloseTriggerWatch) -{ - ParamServiceTest test; - test.TestCloseTriggerWatch(); -} - -TEST(ParamServiceTest, TestParamTraversal) -{ - ParamServiceTest test; - test.TestParamTraversal(); -} - -TEST(ParamServiceTest, TestDumpParamMemory) -{ - ParamServiceTest test; - test.TestDumpParamMemory(); -} - -TEST(ParamServiceTest, TestServiceCtrl) -{ - ParamServiceTest test; - int ret = test.TestServiceCtrl("server1", 0770); - EXPECT_NE(ret, 0); - ret = test.TestServiceCtrl("server2", 0772); - EXPECT_EQ(ret, 0); -} - -TEST(ParamServiceTest, TestPowerCtrl) -{ - ParamServiceTest test; - int ret = test.TestPowerCtrl("reboot,shutdown", 0770); - EXPECT_NE(ret, 0); - ret = test.TestPowerCtrl("reboot,shutdown", 0772); - EXPECT_EQ(ret, 0); - ret = test.TestPowerCtrl("reboot,updater", 0770); - EXPECT_NE(ret, 0); - ret = test.TestPowerCtrl("reboot,updater", 0772); - EXPECT_EQ(ret, 0); - ret = test.TestPowerCtrl("reboot,flashing", 0770); - EXPECT_NE(ret, 0); - ret = test.TestPowerCtrl("reboot,flashing", 0772); - EXPECT_EQ(ret, 0); - ret = test.TestPowerCtrl("reboot", 0770); - EXPECT_NE(ret, 0); - ret = test.TestPowerCtrl("reboot", 0772); - EXPECT_EQ(ret, 0); -} \ No newline at end of file diff --git a/services/test/unittest/param/trigger_unittest.cpp b/services/test/unittest/param/trigger_unittest.cpp deleted file mode 100755 index d2644fd86..000000000 --- a/services/test/unittest/param/trigger_unittest.cpp +++ /dev/null @@ -1,536 +0,0 @@ -/* - * 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 -#include -#include -#include - -#include "init_jobs.h" -#include "init_param.h" -#include "init_read_cfg.h" -#include "init_utils.h" -#include "param_libuvadp.h" -#include "param_manager.h" -#include "param_service.h" -#include "param_unittest.h" -#include "param_utils.h" -#include "securec.h" -#include "trigger_checker.h" -#include "trigger_manager.h" - -using namespace std; - -#define TRIGGER_FIEL_NAME PARAM_DEFAULT_PATH "/etc/init.cfg" -#define TRIGGER_TEST_FIEL_NAME PARAM_DEFAULT_PATH "/trigger_test.cfg" -#define LOAD_PARAM_DEFAULT_CMD PARAM_DEFAULT_PATH "//ohos.para onlyadd" - -int g_execCmdId = 0; -int g_matchTrigger = 0; -char g_matchTriggerName[256] = {}; -static void TestCmdExec(TriggerNode *trigger, CommandNode *cmd, const char *content, uint32_t size) -{ - if (cmd->cmdKeyIndex == CMD_INDEX_FOR_PARA_WAIT || cmd->cmdKeyIndex == CMD_INDEX_FOR_PARA_WATCH) { - TriggerExtData *extData = TRIGGER_GET_EXT_DATA(trigger, TriggerExtData); - if (extData != NULL && extData->excuteCmd != NULL) { - extData->excuteCmd(extData, cmd->cmdKeyIndex, content); - } - return; - } - g_execCmdId = cmd->cmdKeyIndex; -} - -static int TestTriggerExecute(TriggerNode *trigger, const char *content, uint32_t size) -{ - int ret = memcpy_s(g_matchTriggerName, (int)sizeof(g_matchTriggerName) - 1, trigger->name, strlen(trigger->name)); - EXPECT_EQ(ret, 0); - g_matchTriggerName[strlen(trigger->name)] = '\0'; - g_matchTrigger++; - return 0; -} - -class TriggerTest : public ::testing::Test { -public: - TriggerTest() {} - virtual ~TriggerTest() {} - - void SetUp() {} - void TearDown() {} - void TestBody() {} - - int TestLoadTrigger() - { - ParseInitCfg(TRIGGER_FIEL_NAME); - ParseInitCfg(TRIGGER_TEST_FIEL_NAME); - // trigger - PostTrigger(EVENT_TRIGGER_BOOT, "pre-init", strlen("pre-init")); - PostTrigger(EVENT_TRIGGER_BOOT, "init", strlen("init")); - PostTrigger(EVENT_TRIGGER_BOOT, "post-init", strlen("post-init")); - LibuvEventTask *task = (LibuvEventTask *)(GetTriggerWorkSpace()->eventHandle); - // 触发队列执行 - task->process(1, NULL, 0); - - DoCmdByName("load_param ", LOAD_PARAM_DEFAULT_CMD); - return 0; - } - - TriggerHeader *GetTriggerHeader(int type) - { - return &GetTriggerWorkSpace()->triggerHead[type]; - } - - int TestAddTriggerForBoot() - { - TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_BOOT), "init-later", "", 0); - TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), "init-later"); - EXPECT_EQ(node, trigger); - EXPECT_EQ(strcmp(trigger->name, "init-later"), 0); - - // add command - uint32_t cmdIndex = 0; - GetMatchCmd("reboot ", &cmdIndex); - int ret = AddCommand(trigger, cmdIndex, NULL); - EXPECT_EQ(ret, 0); - ret = AddCommand(trigger, cmdIndex, "update: aaaaaaa"); - EXPECT_EQ(ret, 0); - return 0; - } - - int TestAddTriggerForParm() - { - const char *triggerName = "param:test_param.000"; - TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_PARAM), triggerName, "test_param.000=1", 0); - TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); - EXPECT_EQ(trigger, node); - EXPECT_EQ(strcmp(trigger->name, triggerName), 0); - - // add command - uint32_t cmdIndex = 0; - GetMatchCmd("reboot ", &cmdIndex); - int ret = AddCommand(trigger, cmdIndex, NULL); - ret |= AddCommand(trigger, cmdIndex, "update: aaaaaaa"); - EXPECT_EQ(ret, 0); - return 0; - } - - int TestParamEvent() - { - PostParamTrigger(EVENT_TRIGGER_PARAM, "net.tcp.default_init_rwnd", "60"); - const char *sysctrl = "sys.powerctrl=reboot, shutdown"; - PostTrigger(EVENT_TRIGGER_PARAM, sysctrl, strlen(sysctrl)); - PostParamTrigger(EVENT_TRIGGER_PARAM, "sys.powerctrl", "reboot, shutdown"); - - const char *startCmd = "ohos.ctl.start=hdc -t"; - PostTrigger(EVENT_TRIGGER_PARAM, startCmd, strlen(startCmd)); - PostParamTrigger(EVENT_TRIGGER_PARAM, "ohos.ctl.start", "hdc -t"); - - const char *stopCmd = "ohos.ctl.stop=hdc -t"; - PostTrigger(EVENT_TRIGGER_PARAM, stopCmd, strlen(stopCmd)); - PostParamTrigger(EVENT_TRIGGER_PARAM, "ohos.ctl.stop", "hdc -t"); - return 0; - } - - int TestBootEvent(const char *boot) - { - PostTrigger(EVENT_TRIGGER_BOOT, boot, strlen(boot)); - return 0; - } - - int TestCheckParamTrigger1() - { - const char *triggerName = "param:test_param.111"; - const char *param = "test_param.aaa.111.2222"; - const char *value = "1"; - char buffer[512]; - int ret = sprintf_s(buffer, sizeof(buffer), "%s=%s", param, value); - TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_PARAM), triggerName, buffer, 0); - TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); - EXPECT_EQ(trigger, node); - - g_matchTrigger = 0; - ret = sprintf_s(buffer, sizeof(buffer), "%s=%s", param, "2"); - CheckTrigger(GetTriggerWorkSpace(), TRIGGER_PARAM, buffer, strlen(buffer), TestTriggerExecute); - EXPECT_EQ(0, g_matchTrigger); - - g_matchTrigger = 0; - ret = sprintf_s(buffer, sizeof(buffer), "%s=%s", param, value); - CheckTrigger(GetTriggerWorkSpace(), TRIGGER_PARAM, buffer, strlen(buffer), TestTriggerExecute); - EXPECT_EQ(1, g_matchTrigger); - EXPECT_EQ(0, strcmp(triggerName, g_matchTriggerName)); - return 0; - } - - int TestCheckParamTrigger2() - { - const char *triggerName = "param:test_param.222"; - const char *param = "test_param.aaa.222.2222"; - const char *value = "1"; - char buffer[512]; - int ret = sprintf_s(buffer, sizeof(buffer), "%s=*", param); - TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_PARAM), triggerName, buffer, 0); - TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); - EXPECT_EQ(trigger, node); - - g_matchTrigger = 0; - ret = sprintf_s(buffer, sizeof(buffer), "%s=%s", param, "2"); - CheckTrigger(GetTriggerWorkSpace(), TRIGGER_PARAM, buffer, strlen(buffer), TestTriggerExecute); - EXPECT_EQ(1, g_matchTrigger); - EXPECT_EQ(0, strcmp(triggerName, g_matchTriggerName)); - - g_matchTrigger = 0; - ret = sprintf_s(buffer, sizeof(buffer), "%s=%s", param, value); - CheckTrigger(GetTriggerWorkSpace(), TRIGGER_PARAM, param, strlen(param), TestTriggerExecute); - EXPECT_EQ(1, g_matchTrigger); - EXPECT_EQ(0, strcmp(triggerName, g_matchTriggerName)); - return 0; - } - - int TestCheckParamTrigger3() - { - const char *triggerName = "param:test_param.333"; - const char *param1 = "test_param.aaa.333.2222=1"; - const char *param2 = "test_param.aaa.333.3333=2"; - char buffer[512]; - sprintf_s(buffer, sizeof(buffer), "%s || %s", param1, param2); - TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_PARAM), triggerName, buffer, 0); - TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); - EXPECT_EQ(trigger, node); - - g_matchTrigger = 0; - CheckTrigger(GetTriggerWorkSpace(), TRIGGER_PARAM, param1, strlen(param1), TestTriggerExecute); - EXPECT_EQ(1, g_matchTrigger); - EXPECT_EQ(0, strcmp(triggerName, g_matchTriggerName)); - - g_matchTrigger = 0; - CheckTrigger(GetTriggerWorkSpace(), TRIGGER_PARAM, param2, strlen(param2), TestTriggerExecute); - EXPECT_EQ(1, g_matchTrigger); - EXPECT_EQ(0, strcmp(triggerName, g_matchTriggerName)); - return 0; - } - - int TestCheckParamTrigger4() - { - const char *triggerName = "param:test_param.444"; - const char *param1 = "test_param.aaa.444.2222"; - const char *param2 = "test_param.aaa.444.3333"; - char buffer[512]; - sprintf_s(buffer, sizeof(buffer), "%s=%s && %s=%s", param1, "1", param2, "2"); - TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_PARAM), triggerName, buffer, 0); - TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); - EXPECT_EQ(trigger, node); - - g_matchTrigger = 0; - SystemWriteParam(param1, "1"); - sprintf_s(buffer, sizeof(buffer), "%s=%s", param1, "1"); - CheckTrigger(GetTriggerWorkSpace(), TRIGGER_PARAM, buffer, strlen(buffer), TestTriggerExecute); - EXPECT_EQ(0, g_matchTrigger); - - SystemWriteParam(param2, "2"); - g_matchTrigger = 0; - sprintf_s(buffer, sizeof(buffer), "%s=%s", param2, "2"); - CheckTrigger(GetTriggerWorkSpace(), TRIGGER_PARAM, buffer, strlen(buffer), TestTriggerExecute); - EXPECT_EQ(1, g_matchTrigger); - EXPECT_EQ(0, strcmp(triggerName, g_matchTriggerName)); - return 0; - } - - // test for trigger aaaa:test_param.aaa 被加入unknown执行 - int TestCheckParamTrigger5() - { - const char *triggerName = "aaaa:test_param.aaa"; - const char *param1 = "test_param.aaa.aaa.2222"; - const char *param2 = "test_param.aaa.aaa.3333"; - char buffer[512]; - sprintf_s(buffer, sizeof(buffer), "aaaa && %s=%s && %s=%s", param1, "1", param2, "2"); - TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_UNKNOW), triggerName, buffer, 0); - TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); - EXPECT_EQ(trigger, node); - - g_matchTrigger = 0; - SystemWriteParam(param1, "1"); - sprintf_s(buffer, sizeof(buffer), "%s=%s", param1, "1"); - CheckTrigger(GetTriggerWorkSpace(), TRIGGER_PARAM, buffer, strlen(buffer), TestTriggerExecute); - EXPECT_EQ(0, g_matchTrigger); - - SystemWriteParam(param2, "2"); - g_matchTrigger = 0; - CheckTrigger(GetTriggerWorkSpace(), TRIGGER_UNKNOW, "aaaa", strlen("aaaa"), TestTriggerExecute); - EXPECT_EQ(1, g_matchTrigger); - EXPECT_EQ(0, strcmp(triggerName, g_matchTriggerName)); - return 0; - } - - int TestComputeCondition(const char *condition, const char *content, int contentSize) - { - u_int32_t size = strlen(condition) + 20; - char *prefix = (char *)malloc(size); - ConvertInfixToPrefix(condition, prefix, size); - printf("prefix %s \n", prefix); - free(prefix); - return 0; - } - - // 普通的属性trigger - int TestExecuteParamTrigger1() - { - const char *triggerName = "aaaa:test_param.eee"; - const char *param = "test_param.eee.aaa.1111"; - const char *value = "eee"; - char buffer[512]; - sprintf_s(buffer, sizeof(buffer), "%s=%s", param, value); - TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_PARAM), triggerName, buffer, 0); - TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); - EXPECT_EQ(trigger, node); - - const uint32_t cmdIndex = 100; - int ret = AddCommand(trigger, cmdIndex, value); - EXPECT_EQ(ret, 0); - // 修改命令为测试执行 - GetTriggerWorkSpace()->cmdExec = TestCmdExec; - LibuvEventTask *task = (LibuvEventTask *)(GetTriggerWorkSpace()->eventHandle); - SystemWriteParam(param, value); - // 触发队列执行 - task->process(1, NULL, 0); - EXPECT_EQ(g_execCmdId, cmdIndex); - return 0; - } - - int TestExecuteParamTrigger2() - { - const char *triggerName = "param:test_param.dddd"; - const char *param = "test_param.dddd.aaa.2222"; - const char *value = "2222"; - char buffer[512]; - sprintf_s(buffer, sizeof(buffer), "%s=%s", param, value); - TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_PARAM), triggerName, buffer, 0); - TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); - EXPECT_EQ(trigger, node); - const uint32_t cmdIndex = 102; - int ret = AddCommand(trigger, cmdIndex, value); - EXPECT_EQ(ret, 0); - // 修改命令为测试执行 - GetTriggerWorkSpace()->cmdExec = TestCmdExec; - LibuvEventTask *task = (LibuvEventTask *)(GetTriggerWorkSpace()->eventHandle); - task->beforeProcess(EVENT_TRIGGER_PARAM, buffer, strlen(buffer)); - // 触发队列执行 - task->process(EVENT_TRIGGER_PARAM, NULL, 0); - EXPECT_EQ(g_execCmdId, cmdIndex); - return 0; - } - - // 测试执行后立刻删除 - int TestExecuteParamTrigger3() - { - const char *triggerName = "param:test_param.3333"; - const char *param = "test_param.dddd.aaa.3333"; - const char *value = "3333"; - char buffer[512]; - sprintf_s(buffer, sizeof(buffer), "%s=%s", param, value); - TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_PARAM), triggerName, buffer, 0); - TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); - EXPECT_EQ(trigger, node); - const uint32_t cmdIndex = 103; - int ret = AddCommand(trigger, cmdIndex, value); - EXPECT_EQ(ret, 0); - TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_ONCE); - - // 修改命令为测试执行 - GetTriggerWorkSpace()->cmdExec = TestCmdExec; - LibuvEventTask *task = (LibuvEventTask *)(GetTriggerWorkSpace()->eventHandle); - task->beforeProcess(EVENT_TRIGGER_PARAM, buffer, strlen(buffer)); - // 触发队列执行 - task->process(EVENT_TRIGGER_PARAM, NULL, 0); - EXPECT_EQ(g_execCmdId, cmdIndex); - trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); - if (trigger != NULL) { - EXPECT_EQ(1, 0); - } - return 0; - } - - // 测试删除队列中的trigger - int TestExecuteParamTrigger4() - { - const char *triggerName = "param:test_param.4444"; - const char *param = "test_param.dddd.aaa.4444"; - const char *value = "4444"; - char buffer[512]; - sprintf_s(buffer, sizeof(buffer), "%s=%s", param, value); - TriggerNode *node = AddTrigger(GetTriggerHeader(TRIGGER_PARAM), triggerName, buffer, 0); - TriggerNode *trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); - EXPECT_EQ(trigger, node); - const uint32_t cmdIndex = 105; - int ret = AddCommand(trigger, cmdIndex, value); - EXPECT_EQ(ret, 0); - TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_ONCE); - - // 修改命令为测试执行 - GetTriggerWorkSpace()->cmdExec = TestCmdExec; - LibuvEventTask *task = (LibuvEventTask *)(GetTriggerWorkSpace()->eventHandle); - task->beforeProcess(EVENT_TRIGGER_PARAM, buffer, strlen(buffer)); - - // 删除对应的trigger - FreeTrigger(trigger); - - // 触发队列执行 - task->process(EVENT_TRIGGER_PARAM, NULL, 0); - EXPECT_NE(g_execCmdId, cmdIndex); - trigger = GetTriggerByName(GetTriggerWorkSpace(), triggerName); - if (trigger != NULL) { - EXPECT_EQ(1, 0); - } - return 0; - } - - // 测试执行后检查子trigger执行 - int TestExecuteParamTrigger5() - { - const char *boot = "boot2"; - const char *triggerName = "boot2:test_param.5555"; - const char *param = "test_param.dddd.aaa.5555"; - const char *value = "5555"; - TriggerNode *trigger = AddTrigger(GetTriggerHeader(TRIGGER_BOOT), boot, NULL, 0); - int ret = AddCommand(trigger, 1105, value); - EXPECT_EQ(ret, 0); - TRIGGER_SET_FLAG(trigger, TRIGGER_FLAGS_SUBTRIGGER); - - char buffer[512]; - sprintf_s(buffer, sizeof(buffer), "boot2 && %s=%s", param, value); - trigger = AddTrigger(GetTriggerHeader(TRIGGER_UNKNOW), triggerName, buffer, 0); - ret = AddCommand(trigger, 105, value); - - // 修改命令为测试执行 - GetTriggerWorkSpace()->cmdExec = TestCmdExec; - // 设置属性值 - SystemWriteParam(param, value); - - // 触发boot - TestBootEvent(boot); - - LibuvEventTask *task = (LibuvEventTask *)(GetTriggerWorkSpace()->eventHandle); - // 触发队列执行 - task->process(EVENT_TRIGGER_PARAM, NULL, 0); - // 连续执行两个trigger - EXPECT_EQ(g_execCmdId, 105); - return 0; - } - - int TestDumpTrigger() - { - DumpTrigger(GetTriggerWorkSpace()); - return 0; - } -}; - -TEST(TriggerTest, TestLoadTrigger) -{ - TriggerTest test; - test.TestLoadTrigger(); -} - -TEST(TriggerTest, TestBootEvent) -{ - TriggerTest test; - test.TestBootEvent("pre-init"); - test.TestBootEvent("init"); - test.TestBootEvent("post-init"); - test.TestBootEvent("early-init"); -} - -TEST(TriggerTest, TestAddTriggerForBoot) -{ - TriggerTest test; - test.TestAddTriggerForBoot(); -} - -TEST(TriggerTest, TestAddTriggerForParm) -{ - TriggerTest test; - test.TestAddTriggerForParm(); -} - -TEST(TriggerTest, TestCheckParamTrigger1) -{ - TriggerTest test; - test.TestCheckParamTrigger1(); -} - -TEST(TriggerTest, TestCheckParamTrigger2) -{ - TriggerTest test; - test.TestCheckParamTrigger2(); -} - -TEST(TriggerTest, TestCheckParamTrigger3) -{ - TriggerTest test; - test.TestCheckParamTrigger3(); -} - -TEST(TriggerTest, TestCheckParamTrigger4) -{ - TriggerTest test; - test.TestCheckParamTrigger4(); -} - -TEST(TriggerTest, TestCheckParamTrigger5) -{ - TriggerTest test; - test.TestCheckParamTrigger5(); -} - -TEST(TriggerTest, TestParamEvent) -{ - TriggerTest test; - test.TestParamEvent(); -} - -TEST(TriggerTest, ComputerCondition) -{ - TriggerTest test; - test.TestComputeCondition("aaa=111||aaa=222||aaa=333", "aaa=111", strlen("aaa=111")); - test.TestComputeCondition("aaa=111||aaa=222&&aaa=333", "aaa=111", strlen("aaa=111")); - test.TestComputeCondition("(aaa=111||aaa=222)&&aaa=333", "aaa=111", strlen("aaa=111")); - test.TestComputeCondition("aaa=111||(aaa=222&&aaa=333)", "aaa=111", strlen("aaa=111")); -} - -TEST(TriggerTest, TestExecuteParamTrigger1) -{ - TriggerTest test; - test.TestExecuteParamTrigger1(); -} - -TEST(TriggerTest, TestExecuteParamTrigger2) -{ - TriggerTest test; - test.TestExecuteParamTrigger2(); -} - -TEST(TriggerTest, TestExecuteParamTrigger3) -{ - TriggerTest test; - test.TestExecuteParamTrigger3(); -} - -TEST(TriggerTest, TestExecuteParamTrigger4) -{ - TriggerTest test; - test.TestExecuteParamTrigger4(); -} - -TEST(TriggerTest, TestExecuteParamTrigger5) -{ - TriggerTest test; - test.TestExecuteParamTrigger5(); -} \ No newline at end of file diff --git a/services/test/unittest/param/watcher_agent_unittest.cpp b/services/test/unittest/param/watcher_agent_unittest.cpp deleted file mode 100755 index 467f82911..000000000 --- a/services/test/unittest/param/watcher_agent_unittest.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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 -#include -#include -#include - -#include "sys_param.h" -#include "iwatcher.h" -#include "iwatcher_manager.h" -#include "watcher_manager_kits.h" - -using namespace std; - -void TestParameterChange(const char *key, const char *value, void *context) -{ - printf("TestParameterChange key:%s %s", key, value); -} - -class WatcherAgentTest : public ::testing::Test { -public: - WatcherAgentTest() {} - virtual ~WatcherAgentTest() {} - - void SetUp() {} - void TearDown() {} - void TestBody() {} - - int TestAddWatcher() - { - int ret = SystemWatchParameter("test.permission.watcher.test1", TestParameterChange, NULL); - EXPECT_EQ(ret, 0); - ret = SystemWatchParameter("test.permission.watcher.test1*", TestParameterChange, NULL); - EXPECT_EQ(ret, 0); - // 非法 - ret = SystemWatchParameter("test.permission.watcher.tes^^^^t1*", TestParameterChange, NULL); - EXPECT_NE(ret, 0); - // 被禁止 - ret = SystemWatchParameter("test1.permission.watcher.test1*", TestParameterChange, NULL); - EXPECT_NE(ret, 0); - return 0; - } - - int TestDelWatcher() - { - int ret = SystemWatchParameter("test.permission.watcher.test1", NULL, NULL); - EXPECT_EQ(ret, 0); - ret = SystemWatchParameter("test.permission.watcher.test1*", NULL, NULL); - EXPECT_EQ(ret, 0); - // 非法 - ret = SystemWatchParameter("test.permission.watcher.tes^^^^t1*", NULL, NULL); - EXPECT_NE(ret, 0); - // 被禁止 - ret = SystemWatchParameter("test1.permission.watcher.test1*", NULL, NULL); - EXPECT_NE(ret, 0); - return 0; - } - - int TestRecvMessage() - { - return 0; - } -}; - -TEST(WatcherAgentTest, TestAddWatcher) -{ - WatcherAgentTest test; - test.TestAddWatcher(); -} - -TEST(WatcherAgentTest, TestDelWatcher) -{ - WatcherAgentTest test; - test.TestDelWatcher(); -} \ No newline at end of file diff --git a/services/test/unittest/param/watcher_proxy_unittest.cpp b/services/test/unittest/param/watcher_proxy_unittest.cpp deleted file mode 100755 index 9fad55652..000000000 --- a/services/test/unittest/param/watcher_proxy_unittest.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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 -#include -#include -#include - -#include "iwatcher_manager.h" -#include "message_parcel.h" -#include "param_unittest.h" -#include "param_utils.h" -#include "parcel.h" -#include "securec.h" -#include "watcher.h" -#include "watcher_manager.h" -#include "watcher_utils.h" - -using namespace std; -using namespace OHOS; -using namespace OHOS::init_param; - -class TestWatcher final : public Watcher { -public: - TestWatcher() {} - ~TestWatcher() = default; - - void OnParamerterChange(const std::string &name, const std::string &value) override - { - printf("TestWatcher::OnParamerterChange name %s %s", name.c_str(), value.c_str()); - } -}; - -class WatcherProxyTest : public ::testing::Test { -public: - WatcherProxyTest() {} - virtual ~WatcherProxyTest() {} - - void SetUp() {} - void TearDown() {} - void TestBody() {} - - int TestAddWatcher(const std::string &keyPrefix, uint32_t watcherId) - { - std::shared_ptr watcherManager = GetWatcherManager(); - WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager"); - MessageParcel data; - MessageParcel reply; - MessageOption option; - - data.WriteString(keyPrefix); - TestWatcher *watcher = new TestWatcher(); - bool ret = data.WriteRemoteObject(watcher->AsObject()); - WATCHER_CHECK(ret, return 0, "Can not get remote"); - watcherManager->OnRemoteRequest(IWatcherManager::ADD_WATCHER, data, reply, option); - watcherId = reply.ReadUint32(); - EXPECT_NE(watcherId, 0); - printf("TestAddWatcher %s watcherId %d", keyPrefix.c_str(), watcherId); - return 0; - } - - int TestDelWatcher(const std::string &keyPrefix, uint32_t watcherId) - { - std::shared_ptr watcherManager = GetWatcherManager(); - WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to create manager"); - MessageParcel data; - MessageParcel reply; - MessageOption option; - data.WriteString(keyPrefix); - data.WriteUint32(watcherId); - watcherManager->OnRemoteRequest(IWatcherManager::DEL_WATCHER, data, reply, option); - EXPECT_NE(reply.ReadInt32(), 0); - return 0; - } - - std::shared_ptr GetWatcherManager() - { - if (watcherManager_ == nullptr) { - watcherManager_ = std::make_shared(0, true); - if (watcherManager_ == nullptr) { - return nullptr; - } - } - return watcherManager_; - } - -private: - std::shared_ptr watcherManager_ { nullptr }; -}; - -TEST(WatcherProxyTest, TestAddWatcher) -{ - WatcherProxyTest test; - uint32_t watcherId = 0; - test.TestAddWatcher("test.permission.watcher.test1", watcherId); -} - -TEST(WatcherProxyTest, TestAddWatcher2) -{ - WatcherProxyTest test; - uint32_t watcherId = 0; - test.TestAddWatcher("test.permission.watcher.test1", watcherId); -} - -TEST(WatcherProxyTest, TestAddWatcher3) -{ - WatcherProxyTest test; - uint32_t watcherId = 0; - test.TestAddWatcher("test.permission.watcher.test3", watcherId); -} - -TEST(WatcherProxyTest, TestDelWatcher) -{ - WatcherProxyTest test; - uint32_t watcherId = 0; - test.TestAddWatcher("test.permission.watcher.testDel", watcherId); - test.TestDelWatcher("test.permission.watcher.testDel", watcherId); -} \ No newline at end of file diff --git a/services/test/unittest/param_ut_entry.cpp b/services/test/unittest/param_ut_entry.cpp deleted file mode 100755 index f38e5ad5a..000000000 --- a/services/test/unittest/param_ut_entry.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* -* 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 -#include -#include - -#include "param_unittest.h" - -int main(int argc, char* argv[]) -{ - testing::InitGoogleMock(&argc, argv); - testing::InitGoogleTest(&argc, argv); - - if (argc >= 2) { - return RunParamCommand(argc, argv); - } - return RUN_ALL_TESTS(); -} diff --git a/services/test/unittest/param_ut_server.cpp b/services/test/unittest/param_ut_server.cpp deleted file mode 100755 index c1808bf92..000000000 --- a/services/test/unittest/param_ut_server.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* -* 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 -#include -#include -#include -#include "init_cmds.h" -#include "init_param.h" -#include "param_service.h" -#include "param_unittest.h" -#include "trigger_manager.h" -#include "sys_param.h" -#include "uv.h" - -#define PARAM_CMD_PATH "/media/sf_ubuntu/develop/build/startup/init_lite/services/test/unittest/param_test" -#define MAX_COUNT 10000 -int g_repeatCount = 0; - -static int CheckServerParamValue(const char *name, const char *expectValue) -{ - char tmp[PARAM_BUFFER_SIZE] = {0}; - u_int32_t len = sizeof(tmp); - SystemReadParam(name, tmp, &len); - printf("CheckParamValue name %s value: \'%s\' expectValue:\'%s\' \n", name, tmp, expectValue); - EXPECT_NE(strlen(tmp), 0); - if (expectValue != NULL) { - EXPECT_EQ(strcmp(tmp, expectValue), 0); - } - return 0; -} - -// 多进程 -static void *TestServerByMulProcess(void *args) -{ - std::string value = "test.value."; - value += std::to_string(rand()); - std::string name = (char*)args; - name += "." + std::to_string(rand()); - char tmp[PARAM_BUFFER_SIZE * 2] = {0}; - int ret = sprintf_s(tmp, PARAM_BUFFER_SIZE * 2 - 1, - "%s set %s %s", PARAM_CMD_PATH, name.c_str(), value.c_str()); - printf("TestServerByMulProcess cmd :\'%s\' \n", tmp); - system(tmp); - ret = sprintf_s(tmp, PARAM_BUFFER_SIZE * 2 - 1, "%s get %s", PARAM_CMD_PATH, name.c_str()); - system(tmp); - - CheckServerParamValue(name.c_str(), value.c_str()); - return NULL; -} - -static void TestForWriteParam(int max) -{ - srand((unsigned)time(NULL)); // srand()函数产生一个以当前时间开始的随机种子 - int index = 0; - while (index < max) { - std::string value = std::to_string(index); - SystemWriteParam("writeparam.test.aaa.bbb.aaa", value.c_str()); - int wait = rand() / 100000 + 100000; // 100ms - usleep(wait); - - value = std::to_string(index + 100000); - SystemWriteParam("writeparam.test.aaa.bbb.aaa", value.c_str()); - wait = rand() / 100000 + 100000; // 100ms - usleep(wait); - index++; - } -} - -static int TestForMultiProcess() -{ - srand((int)time(NULL)); - printf("TestForMultiThread \n"); - pthread_t tidsForProcess[THREAD_NUM_TEST]; - const char *names[5] = { - "thread.1111.2222.3333.4444.5555", - "thread.2222.1111.2222.3333.4444", - "thread.3333.1111.2222.4444.5555", - "thread.4444.5555.1111.2222.3333", - "thread.5555.1111.2222.3333.4444" - }; - ParamAuditData auditData = {}; - auditData.name = "thread."; - auditData.label = ""; - auditData.dacData.gid = 2002; - auditData.dacData.uid = 2002; - auditData.dacData.mode = 0777; - AddSecurityLabel(&auditData, GetParamWorkSpace()); - for (size_t i = 0; i < THREAD_NUM_TEST; i++) { - pthread_create(&tidsForProcess[i], NULL, TestServerByMulProcess, (void *)names[i % 5]); - } - return 0; -} - -static void timerCallback(ParamTaskPtr timer, void *context) -{ - g_repeatCount = g_repeatCount + 1; - if (g_repeatCount == MAX_COUNT) { - ParamTaskClose(timer); - TestForWriteParam(1); - StopParamService(); - return; - } - if (g_repeatCount == 1) { - TestForMultiProcess(); - } -} - -int main(int argc, char* argv[]) -{ - testing::InitGoogleMock(&argc, argv); - testing::InitGoogleTest(&argc, argv); - - SetLogLevel(INIT_DEBUG); - InitParamService(); - - ParamTaskPtr timer = NULL; - ParamTimerCreate(&timer, timerCallback, NULL); - ParamTimerStart(timer, 1000, MAX_COUNT); -#pragma clang diagnostic push -#pragma clang diagnostic ignored"-Wunused-result" - RUN_ALL_TESTS(); - StartParamService(); - return 0; -#pragma clang diagnostic pop -} diff --git a/services/test/unittest/service/cmds_unittest.cpp b/services/test/unittest/service/cmds_unittest.cpp deleted file mode 100755 index 60714129a..000000000 --- a/services/test/unittest/service/cmds_unittest.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2020 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 -#include -#include -#include "init_cmds.h" - -using namespace testing::ext; -using namespace std; - -namespace init_ut { -class CmdsUnitTest : public testing::Test { -public: - static void SetUpTestCase(void) {}; - static void TearDownTestCase(void) {}; - void SetUp() {}; - void TearDown() {}; -}; - - -TEST(CmdsUnitTest, init_cmds_test_001) -{ - EXPECT_EQ(1, 1); -} - -} // namespace init_ut diff --git a/services/test/unittest/tools/prepare_testdata.sh b/services/test/unittest/tools/prepare_testdata.sh deleted file mode 100755 index 0112c6f77..000000000 --- a/services/test/unittest/tools/prepare_testdata.sh +++ /dev/null @@ -1,123 +0,0 @@ -#! /bin/bash -# 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. - -# This Script used to push test data to devices -# Usage: -# ./prepare_testdata.sh path -# path is the rootdir of ohos projects. - -if [ $# -lt 1 ];then - echo "Usage $0 " - exit 1 -fi - -function hdc_shell_cmd() { - # do nothing if there are not any arguments - if [ $# -eq 0 ];then - return; - fi - echo "Running command $@" - hdc shell $@ -} - -function hdc_push_cmd() { - # do nothing if there are not any arguments - if [ $# -ne 2 ];then - return; - fi - echo "Pushing resouces to device" - hdc file send $@ -} - -hdc target mount - -ut_target_path="/data/init_ut" -echo "Remove ${ut_target_path}" -hdc_shell_cmd "rm -rf ${ut_target_path}" - -echo "Create ${ut_target_path}" -hdc_shell_cmd "umask 022" -hdc_shell_cmd "mkdir -p ${ut_target_path}" - -ohos_root="$1" -ohos_root=${ohos_root%%/} -ohos_init="${ohos_root}/base/startup/init_lite" -ohos_init_ut="${ohos_init}/services/test/unittest" - -hdc_shell_cmd "mkdir -p ${ut_target_path}/coverage" -sleep 0.25 -hdc file send ${ohos_root}/out/ohos-arm-release/exe.unstripped/startup/init/init_ut /bin/init_ut -sleep 0.25 -hdc_shell_cmd "chmod 777 /data/init_ut/* -R" -hdc_shell_cmd "chmod 777 /bin/init_ut" - -hdc_shell_cmd "export GCOV_PREFIX=${ut_target_path}/coverage&&export GCOV_PREFIX_STRIP=14&&init_ut" - -if [ $? -ne 0 ]; then - echo "Execute init_ut in device failed. please check the log" -fi -echo "Running init unittests end..." -echo "Ready to generate coverage..." -pushd ${ohos_init} -rm -rf ./g.sh -rm -rf *.gcno -rm -rf *.gcda -echo "Copy .gcta files to ${ohos_init}}" - -for file in $(hdc_shell_cmd ls /data/init_ut/coverage/*.gcda); do - hdc file recv ${file} ${ohos_init}/${file:23} - chmod 777 ${ohos_init}/${file:23} -done - - -echo "Find out all gcno files and copy to ${ohos_init}" -find ${ohos_root}/out/ohos-arm-release/obj/ -name "*.gcno" -type f -exec cp {} . \; -if [ $? -ne 0 ]; then - echo "find gcno failed." - popd 2>&1 > /dev/null - exit 1 -fi - -if [ ! -f ${ohos_init}/g.sh ]; then - echo "create g.sh" - touch ${ohos_init}/g.sh - echo "${ohos_root}/prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-cov gcov \$@" > ${ohos_init}/g.sh - chmod 755 ${ohos_init}/g.sh -fi - -echo "Running command lcov" -lcov -d . -o "${ohos_init}/init_ut_tmp.info" -b . -c --gcov-tool ${ohos_init}/g.sh - -if [ $? -ne 0 ]; then - echo "Run command lcov failed" - popd 2>&1 > /dev/null -fi - -echo "Filter out don\'t cared dir" -lcov --remove init_ut_tmp.info "*third_party*" "*prebuilts*" "*aosp_libs*" "*base/update/updater/test*" "*${ohos_root}/hos/out*" "*services/script/yacc*" "*services/ui/recovery_ui*" "*services/ui/recovery_ui/include/recovery_ui*" "*update_image_block*" -o ${ohos_init}/init_ut.info - -genhtml -o ${HOME}/init_coverage init_ut.info -if [ $? -ne 0 ]; then - echo "Run genhtml failed." - popd 2>&1 > /dev/null - exit 1 -fi -echo "Clear tmp files" -rm -rf ./g.sh *.gcno *.gcda init_ut.info init_ut_tmp.info -hdc_shell_cmd "rm -rf ${ut_target_path}" -echo -echo "Generate init ut coverage done." -echo "Check coverage in ${HOME}/init_coverage." -echo -popd 2>&1 > /dev/null -- Gitee From 94872691fab141f8980d73ec01868ad5eadc9be4 Mon Sep 17 00:00:00 2001 From: sun_fan Date: Sat, 11 Sep 2021 18:38:31 +0800 Subject: [PATCH 04/14] init: fix gn format Signed-off-by: sun_fan --- services/param/BUILD.gn | 47 +++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/services/param/BUILD.gn b/services/param/BUILD.gn index fff262b00..3249c348a 100644 --- a/services/param/BUILD.gn +++ b/services/param/BUILD.gn @@ -12,7 +12,9 @@ # limitations under the License. import("//build/ohos.gni") -declare_args() { param_security = "dac" } +declare_args() { + param_security = "dac" +} ohos_prebuilt_etc("param_watcher.rc") { if (use_musl) { @@ -27,17 +29,17 @@ ohos_prebuilt_etc("param_watcher.rc") { ohos_static_library("param_service") { sources = [ "//base/startup/init_lite/services/src/list.c", - "manager/param_utils.c", + "adapter/param_libuvadp.c", + "adapter/param_persistadp.c", "manager/param_manager.c", - "manager/param_trie.c", "manager/param_message.c", + "manager/param_trie.c", + "manager/param_utils.c", "service/param_persist.c", "service/param_service.c", "trigger/trigger_checker.c", "trigger/trigger_manager.c", "trigger/trigger_processor.c", - "adapter/param_libuvadp.c", - "adapter/param_persistadp.c", ] include_dirs = [ @@ -50,13 +52,13 @@ ohos_static_library("param_service") { "//third_party/cJSON", ] - defines = [ "PARAM_SUPPORT_SAVE_PERSIST"] + defines = [ "PARAM_SUPPORT_SAVE_PERSIST" ] if (param_security == "selinux") { - sources += [ "adapter/param_selinux.c"] - defines += [ "PARAM_SUPPORT_SELINUX" ] + sources += [ "adapter/param_selinux.c" ] + defines += [ "PARAM_SUPPORT_SELINUX" ] } else { - sources += [ "adapter/param_dac.c"] + sources += [ "adapter/param_dac.c" ] defines += [ "PARAM_SUPPORT_DAC" ] } @@ -71,8 +73,8 @@ ohos_static_library("param_service") { ohos_shared_library("param_client") { sources = [ "client/param_request.c", - "manager/param_message.c", "manager/param_manager.c", + "manager/param_message.c", "manager/param_trie.c", "manager/param_utils.c", ] @@ -83,16 +85,16 @@ ohos_shared_library("param_client") { "//base/startup/init_lite/services/include", "//base/startup/init_lite/services/log", "//base/hiviewdfx/hilog/interfaces/native/innerkits/include", - "//third_party/libuv/include" + "//third_party/libuv/include", ] defines = [ "INIT_AGENT" ] if (param_security == "selinux") { - sources += [ "adapter/param_selinux.c"] + sources += [ "adapter/param_selinux.c" ] defines += [ "PARAM_SUPPORT_SELINUX" ] } else { - sources += [ "adapter/param_dac.c"] + sources += [ "adapter/param_dac.c" ] defines += [ "PARAM_SUPPORT_DAC" ] } @@ -100,18 +102,16 @@ ohos_shared_library("param_client") { "//base/startup/init_lite/services/log:agent_log", "//third_party/bounds_checking_function:libsec_static", ] - external_deps = [ - "hiviewdfx_hilog_native:libhilog", - ] + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] part_name = "init" } ohos_shared_library("param_watcheragent") { sources = [ + "watcher/agent/watcher.cpp", "watcher/agent/watcher_manager_kits.cpp", "watcher/agent/watcher_manager_proxy.cpp", "watcher/agent/watcher_stub.cpp", - "watcher/agent/watcher.cpp" ] include_dirs = [ @@ -165,7 +165,7 @@ ohos_shared_library("param_watcher") { "//foundation/distributedschedule/safwk/services/safwk/include", "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk", "//foundation/distributedschedule/samgr/adapter/interfaces/innerkits/include", - "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include" + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include", ] defines = [ "INIT_AGENT" ] @@ -197,18 +197,19 @@ ohos_executable("param") { "//base/update/updateservice/interfaces/innerkits/include", ] - defines = [ "PARAM_TEST", "INIT_AGENT" ] + defines = [ + "PARAM_TEST", + "INIT_AGENT", + ] deps = [ "//base/startup/init_lite/services/log:agent_log", "//base/startup/init_lite/services/param:param_client", "//base/startup/init_lite/services/param:param_watcheragent", - "//third_party/bounds_checking_function:libsec_static", "//base/update/updateservice/interfaces/innerkits/engine:updateservicekits", + "//third_party/bounds_checking_function:libsec_static", ] - external_deps = [ - "hiviewdfx_hilog_native:libhilog", - ] + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] install_enable = true part_name = "init" } -- Gitee From ce696ef783bf3e6a7e07981cd65055554e632d72 Mon Sep 17 00:00:00 2001 From: sunfanup Date: Sun, 12 Sep 2021 06:39:04 -0700 Subject: [PATCH 05/14] init: fix codedex . Signed-off-by: sunfanup --- services/include/init_service_manager.h | 14 +++++++------- services/include/list.h | 2 +- services/log/init_log.c | 0 services/src/init_cmds.c | 12 ++++++++---- services/src/init_reboot.c | 7 +++---- services/src/init_service.c | 2 +- services/src/init_service_manager.c | 8 ++++---- services/src/init_utils.c | 2 +- ueventd/ueventd_device_handler.c | 22 +++++++++++----------- ueventd/ueventd_read_cfg.c | 19 +++++++++++++------ ueventd/ueventd_socket.c | 6 ++++-- 11 files changed, 53 insertions(+), 41 deletions(-) mode change 100644 => 100755 services/include/init_service_manager.h mode change 100644 => 100755 services/log/init_log.c mode change 100644 => 100755 services/src/init_cmds.c mode change 100644 => 100755 services/src/init_reboot.c mode change 100644 => 100755 services/src/init_service.c mode change 100644 => 100755 services/src/init_service_manager.c mode change 100644 => 100755 services/src/init_utils.c diff --git a/services/include/init_service_manager.h b/services/include/init_service_manager.h old mode 100644 new mode 100755 index 16db1933d..1208307ab --- a/services/include/init_service_manager.h +++ b/services/include/init_service_manager.h @@ -36,15 +36,15 @@ extern "C" { #define MAX_SERVICES_CNT_IN_FILE 100 -void RegisterServices(Service* services, int servicesCnt); -void StartServiceByName(const char* serviceName, bool checkDynamic); -void StopServiceByName(const char* serviceName); -void StopAllServices(); -void StopAllServicesBeforeReboot(); +void RegisterServices(Service *services, int servicesCnt); +void StartServiceByName(const char *serviceName, bool checkDynamic); +void StopServiceByName(const char *serviceName); +void StopAllServices(void); +void StopAllServicesBeforeReboot(void); void ReapServiceByPID(int pid); -void ParseAllServices(const cJSON* fileRoot); +void ParseAllServices(const cJSON *fileRoot); #ifdef OHOS_SERVICE_DUMP -void DumpAllServices(); +void DumpAllServices(void); #endif #ifdef __cplusplus #if __cplusplus diff --git a/services/include/list.h b/services/include/list.h index 06eaaff05..74a926c93 100755 --- a/services/include/list.h +++ b/services/include/list.h @@ -30,7 +30,7 @@ typedef struct ListNode { #define ListEmpty(node) ((node).next == &(node) && (node).prev == &(node)) #define ListEntry(ptr, type, member) (type *)((char *)(ptr) - offsetof(type, member)) #define ForEachListEntry(list, node) \ - for (node = (list)->next; node != (list); node = node->next) + (for (node = (list)->next; node != (list); node = node->next)) void ListInit(struct ListNode *list); void ListAddTail(struct ListNode *list, struct ListNode *item); diff --git a/services/log/init_log.c b/services/log/init_log.c old mode 100644 new mode 100755 diff --git a/services/src/init_cmds.c b/services/src/init_cmds.c old mode 100644 new mode 100755 index 40cdf8308..a1d91635a --- a/services/src/init_cmds.c +++ b/services/src/init_cmds.c @@ -427,10 +427,14 @@ static void DoCopy(const char* cmdContent, int maxArg) out: FreeCmd(ctx); ctx = NULL; - INIT_CHECK(srcFd < 0, close(srcFd); srcFd = -1); - INIT_CHECK(dstFd < 0, close(dstFd); dstFd = -1); - INIT_CHECK(realPath1 == NULL, free(realPath1); realPath1 = NULL); - INIT_CHECK(realPath2 == NULL, free(realPath2); realPath2 = NULL); + INIT_CHECK(srcFd < 0, close(srcFd); + srcFd = -1); + INIT_CHECK(dstFd < 0, close(dstFd); + dstFd = -1); + INIT_CHECK(realPath1 == NULL, free(realPath1); + realPath1 = NULL); + INIT_CHECK(realPath2 == NULL, free(realPath2); + realPath2 = NULL); return; } diff --git a/services/src/init_reboot.c b/services/src/init_reboot.c old mode 100644 new mode 100755 index e80e3e572..61ab1adf8 --- a/services/src/init_reboot.c +++ b/services/src/init_reboot.c @@ -154,12 +154,11 @@ static int CheckAndRebootToUpdater(const char *valueData, const char *cmd, const return -1; } -static const char *g_cmdParams[] = { - "shutdown", "updater", "updater:", "flashing", "flashing:", "NoArgument", "bootloader" -}; - void DoReboot(const char *value) { + const char *g_cmdParams[] = { + "shutdown", "updater", "updater:", "flashing", "flashing:", "NoArgument", "bootloader" + }; if (value == NULL || strlen(value) > MAX_VALUE_LENGTH) { INIT_LOGE("DoReboot value = NULL"); return; diff --git a/services/src/init_service.c b/services/src/init_service.c old mode 100644 new mode 100755 index e9b43082b..3f66631dc --- a/services/src/init_service.c +++ b/services/src/init_service.c @@ -64,7 +64,7 @@ static const int CRITICAL_CRASH_COUNT_LIMIT = 4; static const int MAX_PID_STRING_LENGTH = 50; -static int SetAllAmbientCapability() +static int SetAllAmbientCapability(void) { for (int i = 0; i <= CAP_LAST_CAP; ++i) { if (SetAmbientCapability(i) != 0) { diff --git a/services/src/init_service_manager.c b/services/src/init_service_manager.c old mode 100644 new mode 100755 index f22e8acd9..78012de2a --- a/services/src/init_service_manager.c +++ b/services/src/init_service_manager.c @@ -42,7 +42,7 @@ static Service* g_services = NULL; static int g_servicesCnt = 0; #ifdef OHOS_SERVICE_DUMP -void DumpAllServices() +void DumpAllServices(void) { if (g_services == NULL) { return; @@ -505,7 +505,7 @@ static int ParseServiceSocket(char **opt, const int optNum, struct ServiceSocket if (gid == (gid_t)-1) { return -1; } - sockopt->gid = gid ; + sockopt->gid = gid; if (opt[SERVICE_SOCK_SETOPT] == NULL) { return -1; } @@ -823,7 +823,7 @@ void StopServiceByName(const char* servName) return; } -void StopAllServices() +void StopAllServices(void) { if (g_services == NULL) { return; @@ -835,7 +835,7 @@ void StopAllServices() } } -void StopAllServicesBeforeReboot() +void StopAllServicesBeforeReboot(void) { if (g_services == NULL) { return; diff --git a/services/src/init_utils.c b/services/src/init_utils.c old mode 100644 new mode 100755 index 760f8530a..6d10136e9 --- a/services/src/init_utils.c +++ b/services/src/init_utils.c @@ -42,7 +42,7 @@ float ConvertMisrosecToSec(int x) { - return ((x/1000)/1000.0); + return ((x / 1000) / 1000.0); } uid_t DecodeUid(const char *name) diff --git a/ueventd/ueventd_device_handler.c b/ueventd/ueventd_device_handler.c index 0e7940948..c0a8ea378 100755 --- a/ueventd/ueventd_device_handler.c +++ b/ueventd/ueventd_device_handler.c @@ -385,10 +385,10 @@ void HandleOtherDeviceEvent(const struct Uevent *uevent) } INIT_LOGD("HandleOtherDeviceEvent, devPath = %s, devName = %s", devPath, devName); - // For usb devices, should take care of it specially. - // if usb devices report DEVNAME, just create device node. - // otherwise, create deviceNode with bus number and device number. - if (STRINGEQUAL(uevent->subsystem, "usb")) { + // For usb devices, should take care of it specially. + // if usb devices report DEVNAME, just create device node. + // otherwise, create deviceNode with bus number and device number. + if (STRINGEQUAL(uevent->subsystem, "usb")) { if (uevent->deviceName != NULL) { if (snprintf_s(deviceNode, DEVICE_FILE_SIZE, DEVICE_FILE_SIZE - 1, "/dev/%s", uevent->deviceName) == -1) { INIT_LOGE("Make device file for device [%d : %d]", uevent->major, uevent->minor); @@ -402,17 +402,17 @@ void HandleOtherDeviceEvent(const struct Uevent *uevent) } if (snprintf_s(deviceNode, DEVICE_FILE_SIZE, DEVICE_FILE_SIZE - 1, "/dev/bus/usb/%03d/%03d", uevent->busNum, uevent->devNum) == -1) { - INIT_LOGE("Make usb device node for device [%d : %d]", uevent->busNum, uevent->devNum); + INIT_LOGE("Make usb device node for device [%d : %d]", uevent->busNum, uevent->devNum); } } - } else if (STARTSWITH(uevent->subsystem, "usb")) { - // Other usb devies, do not handle it. - return; - } else { + } else if (STARTSWITH(uevent->subsystem, "usb")) { + // Other usb devies, do not handle it. + return; + } else { if (snprintf_s(deviceNode, DEVICE_FILE_SIZE, DEVICE_FILE_SIZE - 1, "%s/%s", devPath, devName) == -1) { INIT_LOGE("Make device file for device [%d : %d]", uevent->major, uevent->minor); return; } - } - HandleDeviceNode(uevent, deviceNode, false); + } + HandleDeviceNode(uevent, deviceNode, false); } diff --git a/ueventd/ueventd_read_cfg.c b/ueventd/ueventd_read_cfg.c index a015681e3..793c65161 100755 --- a/ueventd/ueventd_read_cfg.c +++ b/ueventd/ueventd_read_cfg.c @@ -30,6 +30,13 @@ // default item count in config files #define DEFAULTITEMCOUNT (100) + +#define SYS_CONFIG_PATH_NUM 0 +#define SYS_CONFIG_ATTR_NUM 1 +#define SYS_CONFIG_MODE_NUM 2 +#define SYS_CONFIG_UID_NUM 3 +#define SYS_CONFIG_GID_NUM 4 + typedef enum SECTION { SECTION_INVALID = -1, SECTION_DEVICE = 0, @@ -180,16 +187,16 @@ static int ParseSysfsConfig(char *p) FreeConfigItems(items, count); return -1; } - config->sysPath = strdup(items[0]); // sys path - config->attr = strdup(items[1]); // attribute + config->sysPath = strdup(items[SYS_CONFIG_PATH_NUM]); // sys path + config->attr = strdup(items[SYS_CONFIG_ATTR_NUM]); // attribute errno = 0; - config->mode = strtoul(items[2], NULL, OCTONARY); + config->mode = strtoul(items[SYS_CONFIG_MODE_NUM], NULL, OCTONARY); if (errno != 0) { INIT_LOGE("Invalid mode in config file for sys path %s. use default mode", config->sysPath); config->mode = DEVMODE; } - config->uid = (uid_t)StringToInt(items[3], 0); - config->gid = (gid_t)StringToInt(items[4], 0); + config->uid = (uid_t)StringToInt(items[SYS_CONFIG_UID_NUM], 0); + config->gid = (gid_t)StringToInt(items[SYS_CONFIG_GID_NUM], 0); ListAddTail(&g_sysDevices, &config->list); return 0; } @@ -369,7 +376,7 @@ void GetDeviceNodePermissions(const char *devNode, uid_t *uid, gid_t *gid, mode_ *uid = config->uid; *gid = config->gid; *mode = config->mode; - break; + break; } } } diff --git a/ueventd/ueventd_socket.c b/ueventd/ueventd_socket.c index 56503fb44..cd32c185e 100755 --- a/ueventd/ueventd_socket.c +++ b/ueventd/ueventd_socket.c @@ -30,10 +30,12 @@ #define INIT_LOG_TAG "ueventd" #include "init_log.h" +#define UEVENT_SOCKET_BUFF_SIZE (256 * 1024) + int UeventdSocketInit() { struct sockaddr_nl addr; - int buffSize = 256 * 1024; + int buffSize = UEVENT_SOCKET_BUFF_SIZE; int on = 1; if (memset_s(&addr, sizeof(addr), 0, sizeof(addr) != EOK)) { @@ -54,7 +56,7 @@ int UeventdSocketInit() setsockopt(sockfd, SOL_SOCKET, SO_RCVBUFFORCE, &buffSize, sizeof(buffSize)); setsockopt(sockfd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); - if(bind(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + if (bind(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { INIT_LOGE("Bind socket failed, err = %d", errno); close(sockfd); return -1; -- Gitee From 83a3e466c60d3f71e1ef8dfc48a19c9afd5ac03b Mon Sep 17 00:00:00 2001 From: sunfanup Date: Sun, 12 Sep 2021 08:45:14 -0700 Subject: [PATCH 06/14] init: fix codedex Signed-off-by: sunfanup --- services/include/init_jobs.h | 4 ++-- services/log/init_log.c | 5 ++++- services/log/init_log.h | 26 ++++++++++++++++---------- services/src/init_jobs.c | 4 ++-- services/src/init_service.c | 2 +- services/src/init_service_manager.c | 9 +++------ services/src/init_utils.c | 11 +++++------ ueventd/ueventd_read_cfg.c | 28 +++++++++++++++++++--------- ueventd/ueventd_socket.c | 1 - 9 files changed, 52 insertions(+), 38 deletions(-) mode change 100644 => 100755 services/include/init_jobs.h mode change 100644 => 100755 services/log/init_log.h mode change 100644 => 100755 services/src/init_jobs.c diff --git a/services/include/init_jobs.h b/services/include/init_jobs.h old mode 100644 new mode 100755 index 7c7ffaed5..47937a77e --- a/services/include/init_jobs.h +++ b/services/include/init_jobs.h @@ -36,8 +36,8 @@ typedef struct { void ParseAllJobs(const cJSON* fileRoot); void DoJob(const char* jobName); -void ReleaseAllJobs(); -void DumpAllJobs(); +void ReleaseAllJobs(void); +void DumpAllJobs(void); #ifdef __cplusplus #if __cplusplus } diff --git a/services/log/init_log.c b/services/log/init_log.c index 18e9e5559..26033f491 100755 --- a/services/log/init_log.c +++ b/services/log/init_log.c @@ -133,9 +133,12 @@ void InitLog(InitLogLevel logLevel, const char *fileName, int line, const char * const char *fmt, ...) { if (logLevel < g_logLevel) { - // return; + return; } time_t second = time(0); + if (second < 0) { + return; + } struct tm *t = localtime(&second); if (t == NULL) { return; diff --git a/services/log/init_log.h b/services/log/init_log.h old mode 100644 new mode 100755 index 9960f0c2e..84240a559 --- a/services/log/init_log.h +++ b/services/log/init_log.h @@ -78,19 +78,25 @@ void SetHiLogLevel(LogLevel logLevel); #define PARAM_AGENT_LOG_PATH "/data/init_agent/init_agent.log" #define STARTUP_LOGD(LABEL, fmt, ...) \ - InitLog(INIT_DEBUG, (FILE_NAME), (__LINE__), "", fmt "\n", ##__VA_ARGS__); \ - (void)HiLogPrint(LOG_APP, LOG_DEBUG, LOG_DOMAIN, LABEL, "[%{public}s(%{public}d)] " fmt, \ - (FILE_NAME), (__LINE__), ##__VA_ARGS__) + do { \ + InitLog(INIT_DEBUG, (FILE_NAME), (__LINE__), "", fmt "\n", ##__VA_ARGS__); \ + (void)HiLogPrint(LOG_APP, LOG_DEBUG, LOG_DOMAIN, LABEL, "[%{public}s(%{public}d)] " fmt, \ + (FILE_NAME), (__LINE__), ##__VA_ARGS__); \ + } while (0) #define STARTUP_LOGI(LABEL, fmt, ...) \ - InitLog(INIT_INFO, (FILE_NAME), (__LINE__), "", fmt "\n", ##__VA_ARGS__); \ - (void)HiLogPrint(LOG_APP, LOG_INFO, LOG_DOMAIN, LABEL, "[%{public}s(%{public}d)] " fmt, \ - FILE_NAME, __LINE__, ##__VA_ARGS__) + do { \ + InitLog(INIT_INFO, (FILE_NAME), (__LINE__), "", fmt "\n", ##__VA_ARGS__); \ + (void)HiLogPrint(LOG_APP, LOG_INFO, LOG_DOMAIN, LABEL, "[%{public}s(%{public}d)] " fmt, \ + FILE_NAME, __LINE__, ##__VA_ARGS__); \ + } while (0) #define STARTUP_LOGE(LABEL, fmt, ...) \ - InitLog(INIT_ERROR, (FILE_NAME), (__LINE__), "", fmt "\n", ##__VA_ARGS__); \ - (void)HiLogPrint(LOG_APP, LOG_ERROR, LOG_DOMAIN, LABEL, "[%{public}s(%{public}d)] " fmt, \ - FILE_NAME, __LINE__, ##__VA_ARGS__) + do { \ + InitLog(INIT_ERROR, (FILE_NAME), (__LINE__), "", fmt "\n", ##__VA_ARGS__); \ + (void)HiLogPrint(LOG_APP, LOG_ERROR, LOG_DOMAIN, LABEL, "[%{public}s(%{public}d)] " fmt, \ + FILE_NAME, __LINE__, ##__VA_ARGS__); \ + } while (0) #endif @@ -142,7 +148,7 @@ void EnableDevKmsg(void); if (!(ret)) { \ INIT_LOGE(format, ##__VA_ARGS__); \ } \ - } while(0) + } while (0) #ifdef __cplusplus #if __cplusplus diff --git a/services/src/init_jobs.c b/services/src/init_jobs.c old mode 100644 new mode 100755 index c1b7b0b74..1bac3d7fa --- a/services/src/init_jobs.c +++ b/services/src/init_jobs.c @@ -30,7 +30,7 @@ static Job* g_jobs = NULL; static int g_jobCnt = 0; -void DumpAllJobs() +void DumpAllJobs(void) { INIT_LOGD("Ready to dump all jobs:"); for (int i = 0; i < g_jobCnt; i++) { @@ -165,7 +165,7 @@ void DoJob(const char* jobName) } } -void ReleaseAllJobs() +void ReleaseAllJobs(void) { if (g_jobs == NULL) { return; diff --git a/services/src/init_service.c b/services/src/init_service.c index 3f66631dc..a9d74a5a0 100755 --- a/services/src/init_service.c +++ b/services/src/init_service.c @@ -131,7 +131,7 @@ static int SetPerms(const Service *service) return SERVICE_SUCCESS; } -static void OpenConsole() +static void OpenConsole(void) { setsid(); WaitForFile("/dev/console", WAIT_MAX_COUNT); diff --git a/services/src/init_service_manager.c b/services/src/init_service_manager.c index 78012de2a..fca4c65b0 100755 --- a/services/src/init_service_manager.c +++ b/services/src/init_service_manager.c @@ -259,13 +259,11 @@ static int GetGidArray(const cJSON *curArrItem, Service *curServ) // gid if ((gIDCnt <= 0) || (filedJ == NULL)) { // not a array, but maybe a item? return GetGidOneItem(curArrItem, curServ); } - if (gIDCnt > NGROUPS_MAX + 1) { INIT_LOGE("GetGidArray, too many gids[cnt %d] for one service, should not exceed %d.", gIDCnt, NGROUPS_MAX + 1); return SERVICE_FAILURE; } - curServ->servPerm.gIDArray = (gid_t *)malloc(sizeof(gid_t) * gIDCnt); if (curServ->servPerm.gIDArray == NULL) { INIT_LOGE("GetGidArray malloc error"); @@ -305,8 +303,7 @@ static int GetGidArray(const cJSON *curArrItem, Service *curServ) // gid } curServ->servPerm.gIDArray[i] = gID; } - int ret = ((i == gIDCnt) ? SERVICE_SUCCESS : SERVICE_FAILURE); - return ret; + return (((i == gIDCnt) ? SERVICE_SUCCESS : SERVICE_FAILURE)); } static int GetServicePathAndArgs(const cJSON* curArrItem, Service* curServ) @@ -759,8 +756,8 @@ void ParseAllServices(const cJSON* fileRoot) continue; } else { INIT_LOGD("service[%d] name=%s, uid=%d, critical=%d, disabled=%d", - i, tmp[i].name, tmp[i].servPerm.uID, (tmp[i].attribute & SERVICE_ATTR_CRITICAL) ? 1 : 0, - (tmp[i].attribute & SERVICE_ATTR_DISABLED) ? 1 : 0); + i, tmp[i].name, tmp[i].servPerm.uID, (tmp[i].attribute & SERVICE_ATTR_CRITICAL) ? 1 : 0, + (tmp[i].attribute & SERVICE_ATTR_DISABLED) ? 1 : 0); } if (GetServiceSocket(curItem, &tmp[i]) != SERVICE_SUCCESS) { if (tmp[i].socketCfg != NULL) { diff --git a/services/src/init_utils.c b/services/src/init_utils.c index 6d10136e9..ed4143b50 100755 --- a/services/src/init_utils.c +++ b/services/src/init_utils.c @@ -39,11 +39,10 @@ #endif #define MAX_JSON_FILE_LEN 102400 // max init.cfg size 100KB - -float ConvertMisrosecToSec(int x) -{ - return ((x / 1000) / 1000.0); -} +#define MICROSECOND_TO_SECOND(X) \ + do { \ + return ((X / 1000) / 1000.0); \ + } while (0) uid_t DecodeUid(const char *name) { @@ -143,7 +142,7 @@ void WaitForFile(const char *source, unsigned int maxCount) usleep(waitTime); count++; } while ((stat(source, &sourceInfo) < 0) && (errno == ENOENT) && (count < maxCount)); - float secTime = ConvertMisrosecToSec(waitTime); + float secTime = MICROSECOND_TO_SECOND(waitTime); if (count == maxCount) { INIT_LOGE("wait for file:%s failed after %f.", source, maxCount * secTime); } diff --git a/ueventd/ueventd_read_cfg.c b/ueventd/ueventd_read_cfg.c index 793c65161..c9e3ef899 100755 --- a/ueventd/ueventd_read_cfg.c +++ b/ueventd/ueventd_read_cfg.c @@ -37,6 +37,13 @@ #define SYS_CONFIG_UID_NUM 3 #define SYS_CONFIG_GID_NUM 4 +#define DEVICE_CONFIG_NAME_NUM 0 +#define DEVICE_CONFIG_MODE_NUM 1 +#define DEVICE_CONFIG_UID_NUM 2 +#define DEVICE_CONFIG_GID_NUM 3 + +#define AVERAGE_COUNT(count) (count / 2) + typedef enum SECTION { SECTION_INVALID = -1, SECTION_DEVICE = 0, @@ -95,8 +102,8 @@ static char **SplitUeventConfig(char *buffer, const char *del, int *returnCount, return NULL; } while (p != NULL) { - if (count > maxItemCount - 1) { - maxItemCount += (maxItemCount / 2) + 1; + if (count > (maxItemCount - 1)) { + maxItemCount += AVERAGE_COUNT(maxItemCount) + 1; INIT_LOGD("Too many items,expand size"); char **expand = (char **)(realloc(items, sizeof(char *) * maxItemCount)); if (expand == NULL) { @@ -150,15 +157,15 @@ static int ParseDeviceConfig(char *p) FreeConfigItems(items, count); return -1; } - config->name = strdup(items[0]); // device node + config->name = strdup(items[DEVICE_CONFIG_NAME_NUM]); // device node errno = 0; - config->mode = strtoul(items[1], NULL, OCTONARY); + config->mode = strtoul(items[DEVICE_CONFIG_MODE_NUM], NULL, OCTONARY); if (errno != 0) { INIT_LOGE("Invalid mode in config file for device node %s. use default mode", config->name); config->mode = DEVMODE; } - config->uid = (uid_t)StringToInt(items[2], 0); - config->gid = (gid_t)StringToInt(items[3], 0); + config->uid = (uid_t)StringToInt(items[DEVICE_CONFIG_UID_NUM], 0); + config->gid = (gid_t)StringToInt(items[DEVICE_CONFIG_GID_NUM], 0); ListAddTail(&g_devices, &config->list); FreeConfigItems(items, count); return 0; @@ -320,9 +327,12 @@ void ParseUeventdConfigFile(const char *file) if (INVALIDSTRING(file)) { return; } - char cfgBuffer[PATH_MAX]; - char *config = realpath(file, cfgBuffer); + char *config = realpath(file, NULL); + if (config == NULL) { + return; + } int fd = open(config, O_RDONLY | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + free(config); if (fd < 0) { INIT_LOGE("Read from %s failed", file); return; @@ -380,7 +390,7 @@ void GetDeviceNodePermissions(const char *devNode, uid_t *uid, gid_t *gid, mode_ } } } - return; + return; } void ChangeSysAttributePermissions(const char *sysPath) diff --git a/ueventd/ueventd_socket.c b/ueventd/ueventd_socket.c index cd32c185e..bbaaefc0c 100755 --- a/ueventd/ueventd_socket.c +++ b/ueventd/ueventd_socket.c @@ -47,7 +47,6 @@ int UeventdSocketInit() addr.nl_groups = 0xffffffff; int sockfd = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT); - if (sockfd < 0) { INIT_LOGE("Create socket failed, err = %d", errno); return -1; -- Gitee From ff6165b8a43cc6be269ec4d902f213ee488b7eda Mon Sep 17 00:00:00 2001 From: sunfanup Date: Sun, 12 Sep 2021 09:25:24 -0700 Subject: [PATCH 07/14] init: fix codedex .. Signed-off-by: sunfanup --- services/src/init_utils.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/services/src/init_utils.c b/services/src/init_utils.c index ed4143b50..b13c5fd30 100755 --- a/services/src/init_utils.c +++ b/services/src/init_utils.c @@ -39,10 +39,13 @@ #endif #define MAX_JSON_FILE_LEN 102400 // max init.cfg size 100KB -#define MICROSECOND_TO_SECOND(X) \ - do { \ - return ((X / 1000) / 1000.0); \ - } while (0) +#define THOUSAND_UNIT_INT 1000 +#define THOUSAND_UNIT_FLOAT 1000.0 + +float ConvertMicrosecondToSecond(int x) +{ + return ((x / THOUSAND_UNIT_INT) / THOUSAND_UNIT_FLOAT); +} uid_t DecodeUid(const char *name) { @@ -142,7 +145,7 @@ void WaitForFile(const char *source, unsigned int maxCount) usleep(waitTime); count++; } while ((stat(source, &sourceInfo) < 0) && (errno == ENOENT) && (count < maxCount)); - float secTime = MICROSECOND_TO_SECOND(waitTime); + float secTime = ConvertMicrosecondToSecond(waitTime); if (count == maxCount) { INIT_LOGE("wait for file:%s failed after %f.", source, maxCount * secTime); } -- Gitee From 1079c11bc400fdf64f980d485e4e6e87f654d1e0 Mon Sep 17 00:00:00 2001 From: sun_fan Date: Mon, 13 Sep 2021 10:59:48 +0800 Subject: [PATCH 08/14] init: fix codedex ... Signed-off-by: sun_fan --- services/include/init_utils.h | 2 + services/src/init_capability.c | 3 +- services/src/init_cmds.c | 601 ++++++++++++++-------------- services/src/init_reboot.c | 2 +- services/src/init_service_manager.c | 6 +- services/src/init_utils.c | 25 +- ueventd/ueventd_read_cfg.c | 5 +- ueventd/ueventd_socket.c | 4 +- ueventd/ueventd_socket.h | 2 +- 9 files changed, 338 insertions(+), 312 deletions(-) diff --git a/services/include/init_utils.h b/services/include/init_utils.h index 00c69b67a..17fe24239 100644 --- a/services/include/init_utils.h +++ b/services/include/init_utils.h @@ -28,10 +28,12 @@ extern "C" { #define OCTAL_BASE 8 #define DECIMAL_BASE 10 +#define ARRAY_LENGTH(array) (sizeof((array)) / sizeof((array)[0])) uid_t DecodeUid(const char *name); char* ReadFileToBuf(const char *configFile); int SplitString(char *srcPtr, char **dstPtr, int maxNum); void WaitForFile(const char *source, unsigned int maxCount); +size_t WriteAll(int fd, char *buffer, size_t size); #ifdef __cplusplus #if __cplusplus } diff --git a/services/src/init_capability.c b/services/src/init_capability.c index 179c8ea2c..d86b4b233 100644 --- a/services/src/init_capability.c +++ b/services/src/init_capability.c @@ -26,6 +26,7 @@ #include "init_log.h" #include "init_perms.h" +#include "init_utils.h" #define MAX_CAPS_CNT_FOR_ONE_SERVICE 100 @@ -89,7 +90,7 @@ static int GetServiceStringCaps(const cJSON* filedJ, Service* curServ) INIT_LOGE("fieldStr is NULL"); break; } - int mapSize = sizeof(g_capStrCapNum) / sizeof(struct CapStrCapNum); // search + int mapSize = ARRAY_LENGTH(g_capStrCapNum); // search int j = 0; for (; j < mapSize; j++) { if (!strcmp(fieldStr, g_capStrCapNum[j].capStr)) { diff --git a/services/src/init_cmds.c b/services/src/init_cmds.c index a1d91635a..76a33f28f 100755 --- a/services/src/init_cmds.c +++ b/services/src/init_cmds.c @@ -21,6 +21,7 @@ #ifndef OHOS_LITE #include #endif +#include #include #include #include @@ -132,7 +133,8 @@ struct CmdArgs* GetCmd(const char *cmdContent, const char *delim, int argsCount) argsCount = SPACES_CNT_IN_CMD_MAX; } ctx->argv = (char**)malloc(sizeof(char*) * (size_t)argsCount + 1); - INIT_CHECK(ctx->argv != NULL, FreeCmd(ctx); return NULL); + INIT_CHECK(ctx->argv != NULL, FreeCmd(ctx); + return NULL); char tmpCmd[MAX_BUFFER]; size_t cmdLength = strlen(cmdContent); @@ -142,8 +144,7 @@ struct CmdArgs* GetCmd(const char *cmdContent, const char *delim, int argsCount) return NULL; } - INIT_CHECK(strncpy_s(tmpCmd, MAX_BUFFER - 1, cmdContent, cmdLength) == EOK, - FreeCmd(ctx); + INIT_CHECK(strncpy_s(tmpCmd, MAX_BUFFER - 1, cmdContent, cmdLength) == EOK, FreeCmd(ctx); return NULL); tmpCmd[strlen(cmdContent)] = '\0'; @@ -162,9 +163,10 @@ struct CmdArgs* GetCmd(const char *cmdContent, const char *delim, int argsCount) // Make surce there is enough memory to store parameter value allocSize = (size_t)(cmdLength + MAX_PARAM_VALUE_LEN + 1); ctx->argv[ctx->argc] = calloc(sizeof(char), allocSize); - INIT_CHECK(ctx->argv[ctx->argc] != NULL, FreeCmd(ctx); return NULL); - INIT_CHECK(GetParamValue(p, ctx->argv[ctx->argc], allocSize) == 0, - FreeCmd(ctx); return NULL); + INIT_CHECK(ctx->argv[ctx->argc] != NULL, FreeCmd(ctx); + return NULL); + INIT_CHECK(GetParamValue(p, ctx->argv[ctx->argc], allocSize) == 0, FreeCmd(ctx); + return NULL); ctx->argc += 1; ctx->argv[ctx->argc] = NULL; return ctx; @@ -218,61 +220,60 @@ void FreeCmd(struct CmdArgs *cmd) return; } -static void DoSetDomainname(const char *cmdContent, int maxArg) +static void WriteCommon(const char *file, char *buffer, int flags, mode_t mode) { - struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); - if ((ctx == NULL) || (ctx->argv == NULL) || (ctx->argc != maxArg)) { - INIT_LOGE("Command domainname with invalid arguments: %s", cmdContent); - goto out; + if (file == NULL || *file == '\0' || buffer == NULL || *buffer = '\0') { + INIT_LOGE("Invalid arugment"); + return; } + char realPath[PATH_MAX] = {0}; + char *rp = realpath(file, realPath); - int fd = open("/proc/sys/kernel/domainname", O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, - S_IRUSR | S_IWUSR); - if (fd < 0) { - INIT_LOGE("DoSetDomainame failed to open \"/proc/sys/kernel/domainname\". err = %d", errno); - goto out; + if (rp == NULL) { + INIT_LOGE("Failed resolve real path name of %s", rp); + return; + } + + int fd = open(rp, flags, mode); + if (fd >= 0) { + size_t totalSize = strlen(buffer); + size_t written = WriteAll(fd, buffer, totalSize); + if (written != totoalSize) { + INIT_LOGE("Write %lu bytes to file failed", totalSize, file) + } + close(fd); } + fd = -1; +} - size_t size = strlen(ctx->argv[0]); - ssize_t n = write(fd, ctx->argv[0], size); - if (n != (ssize_t)size) { - INIT_LOGE("DoSetHostname failed to write %s to \"/proc/sys/kernel/domainname\". err = %d", - ctx->argv[0], errno); +static void DoSetDomainname(const char *cmdContent, int maxArg) +{ + struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); + + if ((ctx == NULL) || (ctx->argv == NULL) || (ctx->argc != maxArg)) { + INIT_LOGE("Command setdomainname with invalid arugment"); + FreeCmd(ctx); + return; } - close(fd); -out: + WriteCommon("/proc/sys/kernel/domainname", ctx->argv[0], O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, + S_IRUSR | S_IWUSR) FreeCmd(ctx); - fd = -1; return; } static void DoSetHostname(const char *cmdContent, int maxArg) { struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); - if ((ctx == NULL) || (ctx->argv == NULL) || (ctx->argc != maxArg)) { - INIT_LOGE("Command hostname with invalid arguments: %s", cmdContent); - goto out; - } - int fd = open("/proc/sys/kernel/hostname", O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, - S_IRUSR | S_IWUSR); - if (fd < 0) { - INIT_LOGE("DoSetHostname failed to open \"/proc/sys/kernel/hostname\". err = %d", errno); - goto out; - } - - size_t size = strlen(ctx->argv[0]); - ssize_t n = write(fd, ctx->argv[0], size); - if (n != (ssize_t)size) { - INIT_LOGE("DoSetHostname failed to write %s to \"/proc/sys/kernel/hostname\". err = %d", - ctx->argv[0], errno); + if ((ctx == NULL) || (ctx->argv == NULL) || (ctx->argc != maxArg)) { + INIT_LOGE("Command sethostname with invalid arugment"); + FreeCmd(ctx); + return; } - - close(fd); -out: + WriteCommon("/proc/sys/kernel/hostname", ctx->argv[0], O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, + S_IRUSR | S_IWUSR); FreeCmd(ctx); - fd = -1; return; } @@ -281,39 +282,36 @@ static void DoIfup(const char *cmdContent, int maxArg) { struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if ((ctx == NULL) || (ctx->argv == NULL) || (ctx->argc != maxArg)) { - INIT_LOGE("Command ifup with invalid arguments: %s", cmdContent); - goto out; + INIT_LOGE("Command ifup with invalid arguments"); + FreeCmd(ctx); + return; } struct ifreq interface; if (strncpy_s(interface.ifr_name, IFNAMSIZ - 1, ctx->argv[0], strlen(ctx->argv[0])) != EOK) { - INIT_LOGE("DoIfup failed to copy interface name"); - goto out; + INIT_LOGE("Failed to copy interface name"); + FreeCmd(ctx); + return; } - INIT_LOGD("interface name: %s", interface.ifr_name); int fd = socket(AF_INET, SOCK_DGRAM, 0); - if (fd < 0) { - INIT_LOGE("DoIfup failed to create socket, err = %d", errno); - goto out; - } - - if (ioctl(fd, SIOCGIFFLAGS, &interface) < 0) { - INIT_LOGE("DoIfup failed to do ioctl with command \"SIOCGIFFLAGS\", err = %d", errno); + if (fd >= 0) { + do { + if (ioctl(fd, SIOCGIFFLAGS, &interface) < 0) { + INIT_LOGE("Failed to do ioctl with command \"SIOCGIFFLAGS\", err = %d", errno); + break; + } + interface.ifr_flags |= IFF_UP; + if (ioctl(fd, SIOCSIFFLAGS, &interface) < 0) { + INIT_LOGE("Failed to do ioctl with command \"SIOCSIFFLAGS\", err = %d", errno); + break; + } + } while (0); close(fd); fd = -1; - goto out; } - interface.ifr_flags |= IFF_UP; - if (ioctl(fd, SIOCSIFFLAGS, &interface) < 0) { - INIT_LOGE("DoIfup failed to do ioctl with command \"SIOCSIFFLAGS\", err = %d", errno); - } - - close(fd); -out: FreeCmd(ctx); - fd = -1; return; } #endif @@ -321,18 +319,14 @@ out: static void DoSleep(const char *cmdContent, int maxArg) { struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); - if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoSleep invalid arguments :%s", cmdContent); - goto out; - } - errno = 0; - unsigned long sleepTime = strtoul(ctx->argv[0], NULL, DECIMAL_BASE); - if (errno != 0) { - INIT_LOGE("cannot covert sleep time in command \" sleep \""); - goto out; + if ((ctx == NULL) || (ctx->argv == NULL) || (ctx->argc != maxArg)) { + INIT_LOGE("Command sleep with invalid arguments"); + FreeCmd(ctx); + return; } + unsigned long sleepTime = strtoul(ctx->argv[0], NULL, DECIMAL_BASE); // Limit sleep time in 5 seconds const unsigned long sleepTimeLimit = 5; if (sleepTime > sleepTimeLimit) { @@ -340,7 +334,7 @@ static void DoSleep(const char *cmdContent, int maxArg) } INIT_LOGI("Sleeping %d second(s)", sleepTime); sleep((unsigned int)sleepTime); -out: + FreeCmd(ctx); return; } @@ -349,12 +343,13 @@ static void DoStart(const char *cmdContent, int maxArg) { struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoStart invalid arguments :%s", cmdContent); - goto out; + INIT_LOGE("Command start with invalid arguments"); + FreeCmd(ctx); + return; } - INIT_LOGD("DoStart %s", cmdContent); - StartServiceByName(cmdContent, true); -out: + INIT_LOGD("Starting service \" %s \"", ctx->argv[0]); + StartServiceByName(ctx->argv[0], true); + FreeCmd(ctx); return; } @@ -363,12 +358,13 @@ static void DoStop(const char* cmdContent, int maxArg) { struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoStop invalid arguments :%s", cmdContent); - goto out; + INIT_LOGE("Command stop with invalid arguments"); + FreeCmd(ctx); + return; } - INIT_LOGD("DoStop %s", cmdContent); - StopServiceByName(cmdContent); -out: + INIT_LOGD("Stopping service \" %s \"", ctx->argv[0]); + StopServiceByName(ctx->argv[0]); + FreeCmd(ctx); return; } @@ -377,87 +373,111 @@ static void DoReset(const char* cmdContent, int maxArg) { struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoReset invalid arguments :%s", cmdContent); - goto out; + INIT_LOGE("Command reset with invalid arguments"); + FreeCmd(ctx); + return; } - INIT_LOGD("DoReset %s", cmdContent); - DoStop(cmdContent, maxArg); - DoStart(cmdContent, maxArg); -out: + INIT_LOGD("Reseting service %s", ctx->argv[0]); + DoStop(ctx->argv[0], maxArg); + DoStart(ctx->argv[0], maxArg); + FreeCmd(ctx); return; } +static void DoCopyInernal(const char *source, const char *target) +{ + bool isSuccess = true; + if (source == NULL || target == NULL) { + INIT_LOGE("Copy file with invalid arguments"); + return; + } + + struct stat st = {0}; + int srcFd = open(source, O_RDONLY | O_CLOEXEC, S_IRUSR | S_IWUSR); + if (srcFd < 0) { + INIT_LOGE("Open \" %s \" failed, err = %d", source, errno); + close(srcFd); + srcFd = -1; + return; + } + + if (fstat(srcFd, &st) < 0) { + INIT_LOGE("Failed to get file \" %s \" stat", source); + close(srcFd); + srcFd = -1; + return; + } + int dstFd = open(target, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, st.st_mode); + if (dstFd >= 0) { + char buf[MAX_COPY_BUF_SIZE] = {0}; + ssize_t readn = -1; + ssize_t writen = -1; + while ((readn = read(srcFd, buf, MAX_COPY_BUF_SIZE - 1)) > 0) { + writen = WriteAll(dstFd, buf, (size_t)readn); + if (writen != readn) { + isSuccess = false; + break; + } + } + } + + if (!isSuccess) { + INIT_LOGE("Copy from \" %s \" to \" %s \" failed", source, target); + } else { + fsync(dstFd); + } + close(srcFd); + close(dstFd); + srcFd = -1; + dstFd = -1; +} + static void DoCopy(const char* cmdContent, int maxArg) { - int srcFd = -1; - int dstFd = -1; - int rdLen = 0; - int rtLen = 0; - char buf[MAX_COPY_BUF_SIZE] = {0}; - char *realPath1 = NULL; - char *realPath2 = NULL; - mode_t mode = 0; - struct stat fileStat = {0}; struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); - if (ctx == NULL || ctx->argv == NULL || ctx->argv[0] == NULL || ctx->argv[1] == NULL || - ctx->argc != DEFAULT_COPY_ARGS_CNT) { - INIT_LOGE("DoCopy invalid arguments :%s", cmdContent); - goto out; - } - realPath1 = realpath(ctx->argv[0], NULL); - if (realPath1 == NULL) { - goto out; - } - realPath2 = realpath(ctx->argv[1], NULL); - if (realPath2 == NULL) { - goto out; - } - srcFd = open(realPath1, O_RDONLY); - INIT_ERROR_CHECK(srcFd >= 0, goto out, "copy open %s fail %d! ", ctx->argv[0], errno); - INIT_ERROR_CHECK(stat(ctx->argv[0], &fileStat) == 0, goto out, "stat fail "); - mode = fileStat.st_mode; - dstFd = open(realPath2, O_WRONLY | O_TRUNC | O_CREAT, mode); - INIT_ERROR_CHECK(dstFd >= 0, goto out, "copy open %s fail %d! ", ctx->argv[1], errno); - while ((rdLen = read(srcFd, buf, sizeof(buf) - 1)) > 0) { - rtLen = write(dstFd, buf, rdLen); - INIT_ERROR_CHECK(rtLen == rdLen, goto out, "write %s file fail %d! ", ctx->argv[1], errno); - } - fsync(dstFd); -out: + if (ctx == NULL || ctx->argv == NULL || ctx->argc != DEFAULT_COPY_ARGS_CNT) { + INIT_LOGE("Command copy with invalid arguments"); + FreeCmd(ctx); + return; + } + char *sourceFile = realpath(ctx->argv[0], NULL); + char *targetFile = realpath(ctx->argv[1], NULL); + + if (sourceFile == NULL || targetFile == NULL) { + INIT_LOGE("Failed resolve real path name in copy command"); + FreeCmd(ctx); + return; + } + + DoCopyInernal(sourceFile, targetFile); FreeCmd(ctx); + free(sourceFile); + free(targetFile); ctx = NULL; - INIT_CHECK(srcFd < 0, close(srcFd); - srcFd = -1); - INIT_CHECK(dstFd < 0, close(dstFd); - dstFd = -1); - INIT_CHECK(realPath1 == NULL, free(realPath1); - realPath1 = NULL); - INIT_CHECK(realPath2 == NULL, free(realPath2); - realPath2 = NULL); + sourceFile = NULL; + targetFile = NULL; return; } static void DoChown(const char* cmdContent, int maxArg) { - // format: chown owner group /xxx/xxx/xxx struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoChown invalid arguments :%s", cmdContent); - goto out; + INIT_LOGE("Command chown with invalid arguments"); + FreeCmd(ctx); + return; } uid_t owner = DecodeUid(ctx->argv[0]); - INIT_ERROR_CHECK(owner != (uid_t)-1, goto out, "DoChown invalid uid :%s.", ctx->argv[0]); - gid_t group = DecodeUid(ctx->argv[1]); - INIT_ERROR_CHECK(group != (gid_t)-1, goto out, "DoChown invalid gid :%s.", ctx->argv[1]); const int pathPos = 2; if (chown(ctx->argv[pathPos], owner, group) != 0) { - INIT_LOGE("DoChown, failed for %s, err %d.", cmdContent, errno); + INIT_LOGE("Change owner of \" %s \" to [%u : %u] failed, err = %d", + ctx->argv[pathPos], owner, group, errno); } -out: + FreeCmd(ctx); return; } @@ -465,72 +485,79 @@ out: static void DoMkDir(const char* cmdContent, int maxArg) { // mkdir support format: - // 1.mkdir path - // 2.mkdir path mode - // 3.mkdir path mode owner group + // 1.mkdir path + // 2.mkdir path mode + // 3.mkdir path mode owner group struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if (ctx == NULL || ctx->argv == NULL || ctx->argc < 1) { - INIT_LOGE("DoMkDir invalid arguments :%s", cmdContent); - goto out; - } - - const int withModeArg = 2; - if (ctx->argc != 1 && ctx->argc != maxArg && ctx->argc != withModeArg) { - INIT_LOGE("DoMkDir invalid arguments: %s", cmdContent); - goto out; - } - - mode_t mode = DEFAULT_DIR_MODE; - if (mkdir(ctx->argv[0], mode) != 0 && errno != EEXIST) { - INIT_LOGE("DoMkDir, failed for %s, err %d.", cmdContent, errno); - goto out; + INIT_LOGE("Command mkdir with invalid arguments"); + FreeCmd(ctx); + return; } - if (ctx->argc > 1) { - mode = strtoul(ctx->argv[1], NULL, OCTAL_TYPE); - if (chmod(ctx->argv[0], mode) != 0) { - INIT_LOGE("DoMkDir failed for %s, err %d.", cmdContent, errno); - } - if (ctx->argc == withModeArg) { - goto out; + do { + int index = 0; + int rc = mkdir(ctx->argc[index], DEFAULT_DIR_MODE); + if (rc < 0) { + if (errno == EEXIST) { + INIT_LOGE("Path \" %s \" already exist", ctx->argv[0]); + } + break; } - const int ownerPos = 2; - const int groupPos = 3; - - uid_t owner = DecodeUid(ctx->argv[ownerPos]); - INIT_ERROR_CHECK(owner != (uid_t)-1, goto out, "DoMkDir invalid uid :%s.", ctx->argv[ownerPos]); - - gid_t group = DecodeUid(ctx->argv[groupPos]); - INIT_ERROR_CHECK(group != (gid_t)-1, goto out, "DoMkDir invalid gid :%s.", ctx->argv[groupPos]); - if (chown(ctx->argv[0], owner, group) != 0) { - INIT_LOGE("DoMkDir, chown failed for %s, err %d.", cmdContent, errno); + if (ctx->argc[++index] != NULL) { // mkdir with specific mode + mode_t mode = strtoul(ctx->argv[1], NULL, OCTAL_BASE); + rc = chmod(ctx->argc[0], mode); + if (rc < 0) { + INIT_LOGE("Change path \" %s \" mode to %04o failed", ctx->argv[0], mode); + break; + } + if (ctx->argc[++index] != NULL) { // mkdir with user and group + if (ctx->argc[index + 1] != NULL) { + uid_t user = DecodeUid(ctx->argv[index]); + gid_t group = DecodeUid(ctx->argv[index + 1]); + + if (user == (uid_t) -1 || group == (uid_t)-1) { + INIT_LOGE("Change path owner with invalid user/group"); + rc = -1; + break; + } + + rc = chown(ctx->argc[0], user, group); + if (rc < 0) { + INIT_LOGE("Change path \" %s \" ower to user: %s group: %s failed", + ctx->argv[0], ctx->argv[index], ctx->argv[index + 1]); + break; + } + } else { + rc = -1; // Miss group + break; + } + } } + } while (0); + + if (rc < 0) { + INIT_LOGE("Run command mkdir failed"); } -out: FreeCmd(ctx); - return; } static void DoChmod(const char* cmdContent, int maxArg) { - // format: chmod xxxx /xxx/xxx/xxx struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoChmod invalid arguments :%s", cmdContent); - goto out; - } - - mode_t mode = strtoul(ctx->argv[0], NULL, OCTAL_TYPE); - if (mode == 0) { - INIT_LOGE("DoChmod, strtoul failed for %s, er %d.", cmdContent, errno); - goto out; + INIT_LOGE("Command chmod with invalid arguments"); + FreeCmd(ctx); + return; } - if (chmod(ctx->argv[1], mode) != 0) { - INIT_LOGE("DoChmod, failed for %s, err %d.", cmdContent, errno); + mode_t mode = strtoul(ctx->argv[0], NULL, OCTAL_BASE); + if (mode != 0) { + if (chmod(ctx->argv[1], mode) != 0) { + INIT_LOGE("Failed to change file \" %s \" mode to %04o, err = %d", ctx->argv[0], mode, errno); + } } -out: FreeCmd(ctx); return; } @@ -785,12 +812,13 @@ static void DoSetParam(const char* cmdContent, int maxArg) { struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoSetParam invalid arguments :%s", cmdContent); - goto out; + INIT_LOGE("Command setparam with invalid arguments"); + FreeCmd(ctx); + return; } - INIT_LOGE("param name: %s, value %s ", ctx->argv[0], ctx->argv[1]); + INIT_LOGD("param name: %s, value %s ", ctx->argv[0], ctx->argv[1]); SystemWriteParam(ctx->argv[0], ctx->argv[1]); -out: + FreeCmd(ctx); return; } @@ -800,12 +828,12 @@ static void DoLoadPersistParams(const char *cmdContent, int maxArg) { struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoLoadPersistParams invalid arguments :%s", cmdContent); - goto out; + INIT_LOGE("Command load_persist_params with invalid arguments"); + FreeCmd(ctx); + return; } INIT_LOGD("load persist params : %s", cmdContent); LoadPersistParams(); -out: FreeCmd(ctx); return; } @@ -814,12 +842,12 @@ static void DoTriggerCmd(const char *cmdContent, int maxArg) { struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoTrigger invalid arguments :%s", cmdContent); - goto out; + INIT_LOGE("Command trigger with invalid arguments"); + FreeCmd(ctx); + return; } - INIT_LOGD("DoTrigger :%s", cmdContent); - DoTriggerExec(cmdContent); -out: + INIT_LOGD("Trigger job :%s", ctx->argv[0]); + DoTriggerExec(ctx->argv[0]); FreeCmd(ctx); return; } @@ -828,16 +856,15 @@ static void DoLoadDefaultParams(const char *cmdContent, int maxArg) { struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoLoadDefaultParams invalid arguments :%s", cmdContent); - goto out; + INIT_LOGE("Command load_param with invalid arguments"); + FreeCmd(ctx); + return; } int mode = 0; if (strcmp(ctx->argv[1], "onlyadd") == 0) { mode = LOAD_PARAM_ONLY_ADD; } - INIT_LOGD("DoLoadDefaultParams args : %s %d", cmdContent, mode); LoadDefaultParams(ctx->argv[0], mode); -out: FreeCmd(ctx); return; } @@ -846,7 +873,7 @@ out: static bool CheckValidCfg(const char *path) { - size_t cfgCnt = sizeof(g_supportCfg) / sizeof(g_supportCfg[0]); + size_t cfgCnt = ARRAY_LENGTH(g_supportCfg); struct stat fileStat = {0}; if (stat(path, &fileStat) != 0 || fileStat.st_size <= 0 || fileStat.st_size > LOADCFG_MAX_FILE_LEN) { @@ -919,52 +946,31 @@ static void DoWrite(const char *cmdContent, int maxArg) // format: write path content struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if (ctx == NULL || ctx->argv == NULL || ctx->argv[0] == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoWrite: invalid arguments :%s", cmdContent); - goto out; - } - char *realPath = realpath(ctx->argv[0], NULL); - if (realPath == NULL) { - goto out; - } - int fd = open(realPath, O_WRONLY | O_CREAT | O_NOFOLLOW | O_CLOEXEC, S_IRUSR | S_IWUSR); - if (fd == -1) { - INIT_LOGE("DoWrite: open %s failed: %d", ctx->argv[0], errno); - free(realPath); - realPath = NULL; - goto out; + INIT_LOGE("Command write with invalid arguments"); + FreeCmd(ctx); + return; } - ssize_t ret = write(fd, ctx->argv[1], strlen(ctx->argv[1])); - if (ret < (ssize_t)0) { - INIT_LOGE("DoWrite: write to file %s failed: %d", ctx->argv[0], errno); - free(realPath); - realPath = NULL; - close(fd); - goto out; - } - free(realPath); - realPath = NULL; - close(fd); -out: + WriteCommon(ctx->argv[0], ctx->argv[1], O_WRONLY | O_CREAT | O_NOFOLLOW | O_CLOEXEC, + S_IRUSR | S_IWUSR); + FreeCmd(ctx); return; } static void DoRmdir(const char *cmdContent, int maxArg) { - // format: rmdir path struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoRmdir: invalid arguments :%s", cmdContent); - goto out; + INIT_LOGE("Command rmdir with invalid arguments"); + FreeCmd(ctx); + return; } int ret = rmdir(ctx->argv[0]); if (ret == -1) { - INIT_LOGE("DoRmdir: remove %s failed: %d.", ctx->argv[0], errno); - goto out; + INIT_LOGE("Remove directory \" %s \" failed, err = %d", ctx->argv[0], errno); } -out: FreeCmd(ctx); return; } @@ -973,18 +979,18 @@ static void DoRebootCmd(const char *cmdContent, int maxArg) { struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoReboot invalid arguments :%s", cmdContent); - goto out; + INIT_LOGE("Command reboot with invalid arguments"); + FreeCmd(ctx); + return; } DoReboot(cmdContent); -out: FreeCmd(ctx); return; } static void DoSetrlimit(const char *cmdContent, int maxArg) { - char *resource[] = { + static const char *resource[] = { "RLIMIT_CPU", "RLIMIT_FSIZE", "RLIMIT_DATA", "RLIMIT_STACK", "RLIMIT_CORE", "RLIMIT_RSS", "RLIMIT_NPROC", "RLIMIT_NOFILE", "RLIMIT_MEMLOCK", "RLIMIT_AS", "RLIMIT_LOCKS", "RLIMIT_SIGPENDING", "RLIMIT_MSGQUEUE", "RLIMIT_NICE", "RLIMIT_RTPRIO", "RLIMIT_RTTIME", "RLIM_NLIMITS" @@ -993,72 +999,69 @@ static void DoSetrlimit(const char *cmdContent, int maxArg) struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); const int rlimMaxPos = 2; if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoSetrlimit: invalid arguments :%s", cmdContent); - goto out; + INIT_LOGE("Command setrlimit with invalid arguments"); + FreeCmd(ctx); + return; } struct rlimit limit; limit.rlim_cur = (rlim_t)atoi(ctx->argv[1]); limit.rlim_max = (rlim_t)atoi(ctx->argv[rlimMaxPos]); int rcs = -1; - for (unsigned int i = 0; i < sizeof(resource) / sizeof(char*); ++i) { + for (unsigned int i = 0; i < ARRAY_LENGTH(resource); ++i) { if (strcmp(ctx->argv[0], resource[i]) == 0) { rcs = (int)i; } } if (rcs == -1) { - INIT_LOGE("DoSetrlimit failed, resouces :%s not support.", ctx->argv[0]); - goto out; - } - int ret = setrlimit(rcs, &limit); - if (ret) { - INIT_LOGE("DoSetrlimit failed : %d", errno); - goto out; + INIT_LOGE("Set limit with unsupported resource \" %s \"", ctx->argv[0]); + } else { + int ret = setrlimit(rcs, &limit); + if (ret) { + INIT_LOGE("Set limit with resource %s, value : %lu, max value: %lu failed, err = %d", + ctx->argv[0], limit.rlim_cur, limit.rlim_max, errno); + } } -out: FreeCmd(ctx); return; } static void DoRm(const char *cmdContent, int maxArg) { - // format: rm /xxx/xxx/xxx struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoRm: invalid arguments :%s", cmdContent); - goto out; + INIT_LOGE("Command rm with invalid arguments"); + FreeCmd(ctx); + return; } int ret = unlink(ctx->argv[0]); if (ret == -1) { - INIT_LOGE("DoRm: unlink %s failed: %d.", ctx->argv[0], errno); - goto out; + INIT_LOGE("Unlink %s failed, err = %d", ctx->argv[0], errno); } -out: FreeCmd(ctx); return; } static void DoExport(const char *cmdContent, int maxArg) { - // format: export xxx /xxx/xxx/xxx struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoExport: invalid arguments :%s", cmdContent); - goto out; + INIT_LOGE("Command export with invalid arguments"); + FreeCmd(ctx); + return; } int ret = setenv(ctx->argv[0], ctx->argv[1], 1); if (ret != 0) { - INIT_LOGE("DoExport: set %s with %s failed: %d", ctx->argv[0], ctx->argv[1], errno); - goto out; + INIT_LOGE("export env name \" %s \", value \" %s \" failed, err = %d ", + ctx->argv[0], ctx->argv[1], errno); } -out: + FreeCmd(ctx); return; } static void DoExec(const char *cmdContent, int maxArg) { - // format: exec /xxx/xxx/xxx xxx pid_t pid = fork(); if (pid < 0) { INIT_LOGE("DoExec: failed to fork child process to exec \"%s\"", cmdContent); @@ -1067,7 +1070,7 @@ static void DoExec(const char *cmdContent, int maxArg) if (pid == 0) { struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if (ctx == NULL || ctx->argv == NULL || ctx->argv[0] == NULL) { - INIT_LOGE("DoExec: invalid arguments :%s", cmdContent); + INIT_LOGE("Command exec with invalid arguments"); _exit(0x7f); } #ifdef OHOS_LITE @@ -1090,16 +1093,16 @@ static void DoSymlink(const char *cmdContent, int maxArg) // format: symlink /xxx/xxx/xxx /xxx/xxx/xxx struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoSymlink: invalid arguments :%s", cmdContent); - goto out; + INIT_LOGE("Command symlink with invalid arguments"); + FreeCmd(ctx); + return; } int ret = symlink(ctx->argv[0], ctx->argv[1]); if (ret != 0) { - INIT_LOGE("DoSymlink: link %s to %s failed: %d", ctx->argv[0], ctx->argv[1], errno); - goto out; + INIT_LOGE("Link \" %s \" to target \" %s \" failed, err = %d", ctx->argv[0], ctx->argv[1], errno); } -out: + FreeCmd(ctx); return; } @@ -1129,49 +1132,47 @@ static void DoMakeNode(const char *cmdContent, int maxArg) const int authorityPos = 2; const int majorDevicePos = 3; const int minorDevicePos = 4; - const int decimal = 10; - const int octal = 8; + if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoMakeNode: invalid arguments :%s", cmdContent); - goto out; + INIT_LOGE("Command mknode with invalid arguments"); + FreeCmd(ctx); + return; } if (!access(ctx->argv[1], F_OK)) { - INIT_LOGE("DoMakeNode failed, path has not sexisted"); - goto out; - } - mode_t deviceMode = GetDeviceMode(ctx->argv[deviceTypePos]); - unsigned int major = strtoul(ctx->argv[majorDevicePos], NULL, decimal); - unsigned int minor = strtoul(ctx->argv[minorDevicePos], NULL, decimal); - mode_t authority = strtoul(ctx->argv[authorityPos], NULL, octal); + INIT_LOGE("Cannot access \" %s \", err = %d", ctx->argv[1], errno); + } else { + mode_t deviceMode = GetDeviceMode(ctx->argv[deviceTypePos]); + unsigned int major = strtoul(ctx->argv[majorDevicePos], NULL, DECIMAL_BASE); + unsigned int minor = strtoul(ctx->argv[minorDevicePos], NULL, DECIMAL_BASE); + mode_t mode = strtoul(ctx->argv[authorityPos], NULL, OCTAL_BASE); - int ret = mknod(ctx->argv[0], deviceMode | authority, makedev(major, minor)); - if (ret != 0) { - INIT_LOGE("DoMakeNode: path: %s failed: %d", ctx->argv[0], errno); - goto out; + int ret = mknod(ctx->argv[0], deviceMode | mode, makedev(major, minor)); + if (ret != 0) { + INIT_LOGE("Create device node \" %s \" failed, err = %d", ctx->argv[0], errno); + } } -out: + FreeCmd(ctx); return; } static void DoMakeDevice(const char *cmdContent, int maxArg) { - // format: makedev major minor struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); - const int decimal = 10; + if (ctx == NULL || ctx->argv == NULL || ctx->argc != maxArg) { - INIT_LOGE("DoMakedevice: invalid arguments :%s", cmdContent); - goto out; + INIT_LOGE("Command makedev with invalid arguments"); + FreeCmd(ctx); + return; } - unsigned int major = strtoul(ctx->argv[0], NULL, decimal); - unsigned int minor = strtoul(ctx->argv[1], NULL, decimal); + unsigned int major = strtoul(ctx->argv[0], NULL, DECIMAL_BASE); + unsigned int minor = strtoul(ctx->argv[1], NULL, DECIMAL_BASE); dev_t deviceId = makedev(major, minor); if (deviceId < 0) { - INIT_LOGE("DoMakedevice \" %s \" failed :%d ", cmdContent, errno); - goto out; + INIT_LOGE("Make device with major %u, minor %u failed :%d ", major, minor, errno); } -out: + FreeCmd(ctx); return; } @@ -1231,7 +1232,7 @@ void DoCmdByName(const char *name, const char *cmdContent) return; } - size_t cmdCnt = sizeof(CMD_TABLE) / sizeof(CMD_TABLE[0]); + size_t cmdCnt = ARRAY_LENGTH(CMD_TABLE); unsigned int i = 0; for (; i < cmdCnt; ++i) { if (strncmp(name, CMD_TABLE[i].name, strlen(CMD_TABLE[i].name)) == 0) { @@ -1251,7 +1252,7 @@ void ParseCmdLine(const char* cmdStr, CmdLine* resCmd) return; } - size_t supportCmdCnt = sizeof(CMD_TABLE) / sizeof(CMD_TABLE[0]); + size_t supportCmdCnt = ARRAY_LENGTH(CMD_TABLE); int foundAndSucceed = 0; for (size_t i = 0; i < supportCmdCnt; ++i) { size_t curCmdNameLen = strlen(CMD_TABLE[i].name); @@ -1284,7 +1285,7 @@ const char *GetMatchCmd(const char *cmdStr, unsigned int *index) if (cmdStr == NULL || index == NULL) { return NULL; } - size_t supportCmdCnt = sizeof(CMD_TABLE) / sizeof(CMD_TABLE[0]); + size_t supportCmdCnt = ARRAY_LENGTH(CMD_TABLE); for (size_t i = 0; i < supportCmdCnt; ++i) { size_t curCmdNameLen = strlen(CMD_TABLE[i].name); if (strncmp(CMD_TABLE[i].name, cmdStr, curCmdNameLen) == 0) { @@ -1297,7 +1298,7 @@ const char *GetMatchCmd(const char *cmdStr, unsigned int *index) const char *GetCmdKey(unsigned int index) { - size_t supportCmdCnt = sizeof(CMD_TABLE) / sizeof(CMD_TABLE[0]); + size_t supportCmdCnt = ARRAY_LENGTH(CMD_TABLE); if (index >= supportCmdCnt) { return NULL; } diff --git a/services/src/init_reboot.c b/services/src/init_reboot.c index 61ab1adf8..4c709001f 100755 --- a/services/src/init_reboot.c +++ b/services/src/init_reboot.c @@ -156,7 +156,7 @@ static int CheckAndRebootToUpdater(const char *valueData, const char *cmd, const void DoReboot(const char *value) { - const char *g_cmdParams[] = { + static const char *g_cmdParams[] = { "shutdown", "updater", "updater:", "flashing", "flashing:", "NoArgument", "bootloader" }; if (value == NULL || strlen(value) > MAX_VALUE_LENGTH) { diff --git a/services/src/init_service_manager.c b/services/src/init_service_manager.c index fca4c65b0..84f0b2fd2 100755 --- a/services/src/init_service_manager.c +++ b/services/src/init_service_manager.c @@ -499,7 +499,7 @@ static int ParseServiceSocket(char **opt, const int optNum, struct ServiceSocket return -1; } gid_t gid = DecodeUid(opt[SERVICE_SOCK_GID]); - if (gid == (gid_t)-1) { + if (gid == (gid_t)-1) { return -1; } sockopt->gid = gid; @@ -632,7 +632,7 @@ static bool IsServiceInMainStrap(Service *curServ) "appspawn", "udevd", "samgr", "multimodalinput", "weston", "installs", "hiview", "hilogd", "hdf_devmgr", "distributedsche", "softbus_server", "foundation" }; - unsigned int length = sizeof(mainServiceList) / sizeof(mainServiceList[0]); + unsigned int length = ARRAY_LENGTH(mainServiceList); for (unsigned int i = 0; i < length; ++i) { if (strncmp(curServ->name, mainServiceList[i], strlen(mainServiceList[i])) == 0) { INIT_LOGI("%s must be main service", curServ->name); @@ -681,7 +681,7 @@ static int CheckServiceKeyName(const cJSON* curService) } while (child != NULL) { int i = 0; - int keyListSize = sizeof(cfgServiceKeyList) / sizeof(char *); + int keyListSize = ARRAY_LENGTH(cfgServiceKeyList); for (; i < keyListSize; i++) { if (strcmp(child->string, cfgServiceKeyList[i]) == 0) { break; diff --git a/services/src/init_utils.c b/services/src/init_utils.c index b13c5fd30..4dc3bbe5c 100755 --- a/services/src/init_utils.c +++ b/services/src/init_utils.c @@ -15,7 +15,6 @@ #include "init_utils.h" #include #include -#include #include #include #include @@ -151,3 +150,27 @@ void WaitForFile(const char *source, unsigned int maxCount) } return; } + +size_t WriteAll(int fd, char *buffer, size_t size) +{ + if (fd < 0 || buffer == NULL || *buffer == '\0') { + return 0; + } + + char *p = buffer; + size_t left = size; + ssize_t written = -1; + + while (left > 0) { + do { + written = write(fd, p, left); + } while (written < 0 && errno == EINTR); + if (written < 0) { + INIT_LOGE("Failed to write %lu bytes to \" %s \", err = %d", totalSize, file, errno); + break; + } + p += written; + left -= written; + } + return size - left; +} \ No newline at end of file diff --git a/ueventd/ueventd_read_cfg.c b/ueventd/ueventd_read_cfg.c index c9e3ef899..a551cefdb 100755 --- a/ueventd/ueventd_read_cfg.c +++ b/ueventd/ueventd_read_cfg.c @@ -42,8 +42,6 @@ #define DEVICE_CONFIG_UID_NUM 2 #define DEVICE_CONFIG_GID_NUM 3 -#define AVERAGE_COUNT(count) (count / 2) - typedef enum SECTION { SECTION_INVALID = -1, SECTION_DEVICE = 0, @@ -89,6 +87,7 @@ static char **SplitUeventConfig(char *buffer, const char *del, int *returnCount, { char *rest = NULL; int count = 0; + int average = 2; char *p = strtok_r(buffer, del, &rest); if (maxItemCount < 0) { return NULL; @@ -103,7 +102,7 @@ static char **SplitUeventConfig(char *buffer, const char *del, int *returnCount, } while (p != NULL) { if (count > (maxItemCount - 1)) { - maxItemCount += AVERAGE_COUNT(maxItemCount) + 1; + maxItemCount += (maxItemCount / average) + 1; INIT_LOGD("Too many items,expand size"); char **expand = (char **)(realloc(items, sizeof(char *) * maxItemCount)); if (expand == NULL) { diff --git a/ueventd/ueventd_socket.c b/ueventd/ueventd_socket.c index bbaaefc0c..c34c439dc 100755 --- a/ueventd/ueventd_socket.c +++ b/ueventd/ueventd_socket.c @@ -32,7 +32,7 @@ #define UEVENT_SOCKET_BUFF_SIZE (256 * 1024) -int UeventdSocketInit() +int UeventdSocketInit(void) { struct sockaddr_nl addr; int buffSize = UEVENT_SOCKET_BUFF_SIZE; @@ -55,7 +55,7 @@ int UeventdSocketInit() setsockopt(sockfd, SOL_SOCKET, SO_RCVBUFFORCE, &buffSize, sizeof(buffSize)); setsockopt(sockfd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); - if (bind(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { INIT_LOGE("Bind socket failed, err = %d", errno); close(sockfd); return -1; diff --git a/ueventd/ueventd_socket.h b/ueventd/ueventd_socket.h index 922a94ce1..13e9ea28b 100755 --- a/ueventd/ueventd_socket.h +++ b/ueventd/ueventd_socket.h @@ -16,6 +16,6 @@ #ifndef BASE_STARTUP_INITLITE_UEVENTD_SOCKET_H #define BASE_STARTUP_INITLITE_UEVENTD_SOCKET_H #include -int UeventdSocketInit(); +int UeventdSocketInit(void); ssize_t ReadUeventMessage(int sockFd, char *buffer, size_t length); #endif // BASE_STARTUP_INITLITE_LIST_H -- Gitee From 31307bf312ae8eb603e5302d5d22faf284029a90 Mon Sep 17 00:00:00 2001 From: sun_fan Date: Mon, 13 Sep 2021 11:35:20 +0800 Subject: [PATCH 09/14] init: fix codedex .... Signed-off-by: sun_fan --- services/src/init_cmds.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/services/src/init_cmds.c b/services/src/init_cmds.c index 76a33f28f..b9f01cc83 100755 --- a/services/src/init_cmds.c +++ b/services/src/init_cmds.c @@ -222,7 +222,7 @@ void FreeCmd(struct CmdArgs *cmd) static void WriteCommon(const char *file, char *buffer, int flags, mode_t mode) { - if (file == NULL || *file == '\0' || buffer == NULL || *buffer = '\0') { + if (file == NULL || *file == '\0' || buffer == NULL || *buffer == '\0') { INIT_LOGE("Invalid arugment"); return; } @@ -238,8 +238,8 @@ static void WriteCommon(const char *file, char *buffer, int flags, mode_t mode) if (fd >= 0) { size_t totalSize = strlen(buffer); size_t written = WriteAll(fd, buffer, totalSize); - if (written != totoalSize) { - INIT_LOGE("Write %lu bytes to file failed", totalSize, file) + if (written != totalSize) { + INIT_LOGE("Write %lu bytes to file failed", totalSize, file); } close(fd); } @@ -257,7 +257,7 @@ static void DoSetDomainname(const char *cmdContent, int maxArg) } WriteCommon("/proc/sys/kernel/domainname", ctx->argv[0], O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, - S_IRUSR | S_IWUSR) + S_IRUSR | S_IWUSR); FreeCmd(ctx); return; } @@ -494,10 +494,9 @@ static void DoMkDir(const char* cmdContent, int maxArg) FreeCmd(ctx); return; } - do { int index = 0; - int rc = mkdir(ctx->argc[index], DEFAULT_DIR_MODE); + int rc = mkdir(ctx->argv[index], DEFAULT_DIR_MODE); if (rc < 0) { if (errno == EEXIST) { INIT_LOGE("Path \" %s \" already exist", ctx->argv[0]); @@ -505,15 +504,15 @@ static void DoMkDir(const char* cmdContent, int maxArg) break; } - if (ctx->argc[++index] != NULL) { // mkdir with specific mode + if (ctx->argv[++index] != NULL) { // mkdir with specific mode mode_t mode = strtoul(ctx->argv[1], NULL, OCTAL_BASE); - rc = chmod(ctx->argc[0], mode); + rc = chmod(ctx->argv[0], mode); if (rc < 0) { INIT_LOGE("Change path \" %s \" mode to %04o failed", ctx->argv[0], mode); break; } - if (ctx->argc[++index] != NULL) { // mkdir with user and group - if (ctx->argc[index + 1] != NULL) { + if (ctx->argv[++index] != NULL) { // mkdir with user and group + if (ctx->argv[index + 1] != NULL) { uid_t user = DecodeUid(ctx->argv[index]); gid_t group = DecodeUid(ctx->argv[index + 1]); @@ -523,23 +522,23 @@ static void DoMkDir(const char* cmdContent, int maxArg) break; } - rc = chown(ctx->argc[0], user, group); + rc = chown(ctx->argv[0], user, group); if (rc < 0) { INIT_LOGE("Change path \" %s \" ower to user: %s group: %s failed", ctx->argv[0], ctx->argv[index], ctx->argv[index + 1]); break; } } else { - rc = -1; // Miss group + rc = -1; // Miss group break; } } } + if (rc < 0) { + INIT_LOGE("Run command mkdir failed"); + } } while (0); - if (rc < 0) { - INIT_LOGE("Run command mkdir failed"); - } FreeCmd(ctx); } -- Gitee From 846e9926f580d74431d215f4271bbfc9d3675558 Mon Sep 17 00:00:00 2001 From: sun_fan Date: Mon, 13 Sep 2021 14:52:06 +0800 Subject: [PATCH 10/14] init: fix codedex ..... Signed-off-by: sun_fan --- services/src/init_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/src/init_utils.c b/services/src/init_utils.c index 4dc3bbe5c..58c226249 100755 --- a/services/src/init_utils.c +++ b/services/src/init_utils.c @@ -166,7 +166,7 @@ size_t WriteAll(int fd, char *buffer, size_t size) written = write(fd, p, left); } while (written < 0 && errno == EINTR); if (written < 0) { - INIT_LOGE("Failed to write %lu bytes to \" %s \", err = %d", totalSize, file, errno); + INIT_LOGE("Failed to write %lu bytes, err = %d", left, errno); break; } p += written; -- Gitee From cf86680af0eb41562f8d050731d21f0b06b800c6 Mon Sep 17 00:00:00 2001 From: "an_xinwei@hoperun.com" Date: Mon, 13 Sep 2021 16:53:08 +0800 Subject: [PATCH 11/14] fix code style Signed-off-by: an_xinwei@hoperun.com --- services/param/adapter/param_dac.c | 27 +++-- services/param/adapter/param_libuvadp.c | 36 +++--- services/param/adapter/param_persistadp.c | 9 +- services/param/adapter/param_selinux.c | 11 +- services/param/client/param_request.c | 29 +++-- services/param/cmd/param_cmd.c | 65 ++++++----- services/param/include/param_manager.h | 5 +- services/param/include/param_message.h | 2 +- services/param/include/param_security.h | 3 + services/param/include/param_service.h | 2 +- services/param/include/param_trie.h | 22 ++-- services/param/include/param_utils.h | 10 +- services/param/include/trigger_checker.h | 1 + services/param/include/trigger_manager.h | 14 ++- services/param/manager/param_manager.c | 9 +- services/param/manager/param_message.c | 12 +- services/param/manager/param_trie.c | 10 +- services/param/manager/param_utils.c | 8 +- services/param/service/param_persist.c | 17 ++- services/param/service/param_service.c | 106 ++++++++++++------ services/param/trigger/trigger_checker.c | 35 +++--- services/param/trigger/trigger_manager.c | 30 +++-- services/param/trigger/trigger_processor.c | 17 ++- services/param/watcher/agent/watcher.cpp | 2 + .../watcher/agent/watcher_manager_kits.h | 1 - .../param/watcher/include/watcher_utils.h | 1 + .../param/watcher/proxy/watcher_manager.cpp | 19 ++-- .../param/watcher/proxy/watcher_manager.h | 22 +++- .../watcher/proxy/watcher_manager_stub.cpp | 3 +- 29 files changed, 320 insertions(+), 208 deletions(-) diff --git a/services/param/adapter/param_dac.c b/services/param/adapter/param_dac.c index c6b6fbbe8..be13f99b4 100755 --- a/services/param/adapter/param_dac.c +++ b/services/param/adapter/param_dac.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 @@ -12,20 +12,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "param_security.h" + #include #include #include #include +#include "init_utils.h" +#include "param_security.h" #include "param_utils.h" + +#define OCT_BASE 8 #define LABEL "PARAM_DAC" static ParamSecurityLabel g_localSecurityLabel = {}; static void GetUserIdByName(FILE *fp, uid_t *uid, const char *name, uint32_t nameLen) { *uid = -1; - fseek(fp, 0, SEEK_SET); + (void)fseek(fp, 0, SEEK_SET); struct passwd *data = NULL; while ((data = fgetpwent(fp)) != NULL) { if (strlen(data->pw_name) == nameLen && strncmp(data->pw_name, name, nameLen) == 0) { @@ -38,7 +42,7 @@ static void GetUserIdByName(FILE *fp, uid_t *uid, const char *name, uint32_t nam static void GetGroupIdByName(FILE *fp, gid_t *gid, const char *name, uint32_t nameLen) { *gid = -1; - fseek(fp, 0, SEEK_SET); + (void)fseek(fp, 0, SEEK_SET); struct group *data = NULL; while ((data = fgetgrent(fp)) != NULL) { if (strlen(data->gr_name) == nameLen && strncmp(data->gr_name, name, nameLen) == 0) { @@ -61,12 +65,13 @@ static int GetParamDacData(FILE *fpForGroup, FILE *fpForUser, ParamDacData *dacD } GetUserIdByName(fpForUser, &dacData->uid, value, groupName - value); GetGroupIdByName(fpForGroup, &dacData->gid, groupName + 1, mode - groupName - 1); - dacData->mode = strtol(mode + 1, NULL, 8); + dacData->mode = strtol(mode + 1, NULL, OCT_BASE); return 0; } static int InitLocalSecurityLabel(ParamSecurityLabel **security, int isInit) { + UNUSED(isInit); PARAM_LOGD("InitLocalSecurityLabel uid:%d gid:%d euid: %d egid: %d ", getuid(), getgid(), geteuid(), getegid()); g_localSecurityLabel.cred.pid = getpid(); g_localSecurityLabel.cred.uid = geteuid(); @@ -107,7 +112,7 @@ static int LoadParamLabels(const char *fileName, SecurityLabelFunc label, void * FILE *fpForGroup = fopen(GROUP_FILE_PATH, "r"); FILE *fpForUser = fopen(USER_FILE_PATH, "r"); FILE *fp = fopen(fileName, "r"); - SubStringInfo *info = malloc(sizeof(SubStringInfo) * 2); + SubStringInfo *info = malloc(sizeof(SubStringInfo) * SUBSTR_INFO_DAC + 1); PARAM_CHECK(fpForGroup != NULL && fpForUser != NULL && fp != NULL && info != NULL, goto exit, "Can not open file for load param labels"); @@ -132,16 +137,16 @@ static int LoadParamLabels(const char *fileName, SecurityLabelFunc label, void * PARAM_LOGI("Load parameter label total %u success %s", infoCount, fileName); exit: if (fp) { - fclose(fp); + (void)fclose(fp); } if (info) { free(info); } if (fpForGroup) { - fclose(fpForGroup); + (void)fclose(fpForGroup); } if (fpForUser) { - fclose(fpForUser); + (void)fclose(fpForUser); } return 0; } @@ -183,9 +188,9 @@ static int CheckParamPermission(const ParamSecurityLabel *srcLabel, const ParamA if (srcLabel->cred.uid == auditData->dacData.uid) { localMode = mode & (DAC_READ | DAC_WRITE | DAC_WATCH); } else if (srcLabel->cred.gid == auditData->dacData.gid) { - localMode = (mode & (DAC_READ | DAC_WRITE | DAC_WATCH)) >> 3; + localMode = (mode & (DAC_READ | DAC_WRITE | DAC_WATCH)) >> DAC_GROUP_START; } else { - localMode = (mode & (DAC_READ | DAC_WRITE | DAC_WATCH)) >> 6; + localMode = (mode & (DAC_READ | DAC_WRITE | DAC_WATCH)) >> DAC_OTHER_START; } if ((auditData->dacData.mode & localMode) != 0) { ret = DAC_RESULT_PERMISSION; diff --git a/services/param/adapter/param_libuvadp.c b/services/param/adapter/param_libuvadp.c index 8c7b7b208..1ce83379c 100755 --- a/services/param/adapter/param_libuvadp.c +++ b/services/param/adapter/param_libuvadp.c @@ -1,10 +1,10 @@ /* - * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 + * 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, @@ -21,6 +21,8 @@ static const uint32_t RECV_BUFFER_MAX = 5 * 1024; static LibuvBaseTask *CreateLibuvTask(uint32_t size, uint32_t flags, uint16_t userDataSize, TaskClose close) { + PARAM_CHECK(size <= RECV_BUFFER_MAX, return NULL, "Invaid size %u", size); + PARAM_CHECK(userDataSize <= RECV_BUFFER_MAX, return NULL, "Invaid user size %u", userDataSize); LibuvBaseTask *worker = (LibuvBaseTask *)malloc(size + userDataSize); PARAM_CHECK(worker != NULL, return NULL, "Failed to create param woker"); worker->worker.flags = flags; @@ -64,6 +66,7 @@ static void OnTimerClose(uv_handle_t *handle) static void OnReceiveAlloc(uv_handle_t *handle, size_t suggestedSize, uv_buf_t *buf) { + UNUSED(suggestedSize); PARAM_CHECK(handle != NULL, return, "Invalid handle"); buf->len = RECV_BUFFER_MAX; buf->base = (char *)malloc(buf->len); @@ -71,6 +74,7 @@ static void OnReceiveAlloc(uv_handle_t *handle, size_t suggestedSize, uv_buf_t * static void OnWriteResponse(uv_write_t *req, int status) { + UNUSED(status); PARAM_CHECK(req != NULL, return, "Invalid req"); PARAM_LOGD("OnWriteResponse handle: %p", req); } @@ -176,15 +180,18 @@ int ParamStreamCreate(ParamTaskPtr *stream, ParamTaskPtr server, const ParamStre if (server != NULL) { uv_pipe_t *pipe = &client->stream.pipe; int ret = uv_pipe_init(uv_default_loop(), (uv_pipe_t *)pipe, 1); - PARAM_CHECK(ret == 0, free(client); return -1, "Failed to uv_pipe_init %d", ret); + PARAM_CHECK(ret == 0, free(client); + return -1, "Failed to uv_pipe_init %d", ret); pipe->data = &pipeServer->server; PARAM_LOGD("OnConnection pipeServer: %p pipe %p", pipeServer, &pipeServer->server); if ((info->flags & WORKER_TYPE_TEST) != WORKER_TYPE_TEST) { ret = uv_accept((uv_stream_t *)&pipeServer->server.pipe, (uv_stream_t *)pipe); - PARAM_CHECK(ret == 0, uv_close((uv_handle_t *)pipe, NULL); free(client); + PARAM_CHECK(ret == 0, uv_close((uv_handle_t *)pipe, NULL); + free(client); return -1, "Failed to uv_accept %d", ret); ret = uv_read_start((uv_stream_t *)pipe, OnReceiveAlloc, OnReceiveRequest); - PARAM_CHECK(ret == 0, uv_close((uv_handle_t *)pipe, NULL); free(client); + PARAM_CHECK(ret == 0, uv_close((uv_handle_t *)pipe, NULL); + free(client); return -1, "Failed to uv_read_start %d", ret); } } @@ -208,8 +215,8 @@ void *ParamGetTaskUserData(ParamTaskPtr stream) int ParamTaskSendMsg(const ParamTaskPtr stream, const ParamMessage *msg) { - PARAM_CHECK(stream != NULL, LibuvFreeMsg(stream, msg); return -1, "Invalid stream"); - PARAM_CHECK(msg != NULL, LibuvFreeMsg(stream, msg); return -1, "Invalid msg"); + PARAM_CHECK(stream != NULL && msg != NULL, LibuvFreeMsg(stream, msg); + return -1, "Invalid stream"); LibuvStreamTask *worker = (LibuvStreamTask *)stream; if ((stream->flags & WORKER_TYPE_MSG) != WORKER_TYPE_MSG) { LibuvFreeMsg(stream, msg); @@ -218,7 +225,8 @@ int ParamTaskSendMsg(const ParamTaskPtr stream, const ParamMessage *msg) if ((stream->flags & WORKER_TYPE_TEST) != WORKER_TYPE_TEST) { uv_buf_t buf = uv_buf_init((char *)msg, msg->msgSize); int ret = uv_write(&worker->writer, (uv_stream_t *)&worker->stream.pipe, &buf, 1, OnWriteResponse); - PARAM_CHECK(ret >= 0, LibuvFreeMsg(stream, msg); return -1, "Failed to uv_write2 ret %s", uv_strerror(ret)); + PARAM_CHECK(ret >= 0, LibuvFreeMsg(stream, msg); + return -1, "Failed to uv_write2 ret %s", uv_strerror(ret)); } LibuvFreeMsg(stream, msg); return 0; @@ -250,7 +258,8 @@ int ParamEventSend(ParamTaskPtr stream, uint64_t eventId, const char *content, u event->task = worker; if (content != NULL) { ret = memcpy_s(event->content, event->contentSize, content, size); - PARAM_CHECK(ret == 0, free(event); return -1, "Failed to memcpy content "); + PARAM_CHECK(ret == EOK, free(event); + return -1, "Failed to memcpy content "); event->content[size] = '\0'; } uv_async_init(uv_default_loop(), &event->async, OnAsyncCallback); @@ -309,8 +318,9 @@ int ParamTimerStart(ParamTaskPtr timer, uint64_t timeout, uint64_t repeat) return -1; } -static void SignalHandler(uv_signal_t* handle, int signum) +static void SignalHandler(uv_signal_t *handle, int signum) { + UNUSED(handle); if (signum != SIGCHLD) { return; } @@ -332,13 +342,13 @@ int ParamServiceStart(ProcessPidDelete pidDelete) libuv.pidDeleteProcess = pidDelete; uv_signal_t sigchldHandler; int ret = uv_signal_init(uv_default_loop(), &sigchldHandler); - ret |= uv_signal_start(&sigchldHandler, SignalHandler, SIGCHLD); - PARAM_CHECK(ret == 0 , return -1, "Failed to process signal "); + int ret1 = uv_signal_start(&sigchldHandler, SignalHandler, SIGCHLD); + PARAM_CHECK(ret == 0 && ret1 == 0, return -1, "Failed to process signal "); uv_run(uv_default_loop(), UV_RUN_DEFAULT); return 0; } -int ParamServiceStop() +int ParamServiceStop(void) { uv_fs_t req; uv_fs_unlink(uv_default_loop(), &req, PIPE_NAME, NULL); diff --git a/services/param/adapter/param_persistadp.c b/services/param/adapter/param_persistadp.c index a38a39aa7..60d771f7a 100755 --- a/services/param/adapter/param_persistadp.c +++ b/services/param/adapter/param_persistadp.c @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include "param_persist.h" #include #include @@ -49,7 +50,7 @@ static int LoadPersistParam(PersistParamGetPtr persistParamGet, void *context) } free(info); free(buff); - fclose(fp); + (void)fclose(fp); return 0; } @@ -73,11 +74,11 @@ static int BatchSavePersistParam(PERSIST_SAVE_HANDLE handle, const char *name, c static void BatchSavePersistParamEnd(PERSIST_SAVE_HANDLE handle) { FILE *fp = (FILE *)handle; - fclose(fp); + (void)fclose(fp); unlink(PARAM_PERSIST_SAVE_PATH); int ret = rename(PARAM_PERSIST_SAVE_TMP_PATH, PARAM_PERSIST_SAVE_PATH); - PARAM_CHECK(ret == 0, return, - "BatchSavePersistParamEnd %s fail error %s", PARAM_PERSIST_SAVE_TMP_PATH, strerror(errno)); + PARAM_CHECK(ret == 0, return, "BatchSavePersistParamEnd %s fail error %s", + PARAM_PERSIST_SAVE_TMP_PATH, strerror(errno)); } int RegisterPersistParamOps(PersistParamOps *ops) diff --git a/services/param/adapter/param_selinux.c b/services/param/adapter/param_selinux.c index 7c51e4a98..4bdfd5337 100755 --- a/services/param/adapter/param_selinux.c +++ b/services/param/adapter/param_selinux.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 @@ -12,9 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "param_security.h" + #include +#include "init_utils.h" +#include "param_security.h" #include "param_utils.h" #define LABEL "PARAM_SELINUX" @@ -29,6 +31,7 @@ static SELinuxSecurityLabel g_localSecurityLabel = {}; static int InitLocalSecurityLabel(ParamSecurityLabel **security, int isInit) { + UNUSED(isInit); PARAM_LOGI("TestDacGetLabel uid:%d gid:%d euid: %d egid: %d ", getuid(), getgid(), geteuid(), getegid()); g_localSecurityLabel.securityLabel.cred.pid = getpid(); g_localSecurityLabel.securityLabel.cred.uid = geteuid(); @@ -67,7 +70,7 @@ static int LoadParamLabels(const char *fileName, SecurityLabelFunc label, void * int ret = 0; FILE *fp = fopen(fileName, "r"); PARAM_CHECK(fp != NULL, return -1, "Open file %s fail", fileName); - SubStringInfo *info = malloc(sizeof(SubStringInfo) * 2); + SubStringInfo *info = malloc(sizeof(SubStringInfo) * SUBSTR_INFO_DAC + 1); char buff[PARAM_BUFFER_SIZE]; int infoCount = 0; ParamAuditData auditData = {}; @@ -82,7 +85,7 @@ static int LoadParamLabels(const char *fileName, SecurityLabelFunc label, void * PARAM_CHECK(ret == 0, continue, "Failed to write param info %d %s", ret, buff); infoCount++; } - fclose(fp); + (void)fclose(fp); free(info); PARAM_LOGI("Load parameter info %d success %s", infoCount, fileName); return 0; diff --git a/services/param/client/param_request.c b/services/param/client/param_request.c index 2490cf30f..f2c5bb6b4 100755 --- a/services/param/client/param_request.c +++ b/services/param/client/param_request.c @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include "param_request.h" #include #include @@ -24,12 +25,12 @@ #include "param_manager.h" #include "param_message.h" -#define INVALID_SOCKET -1 +#define INVALID_SOCKET (-1) #define LABEL "Client" static const uint32_t RECV_BUFFER_MAX = 5 * 1024; static atomic_uint g_requestId = ATOMIC_VAR_INIT(1); -static ClientWorkSpace g_clientSpace = {{}, -1, {}}; +static ClientWorkSpace g_clientSpace = { {}, -1, {} }; __attribute__((constructor)) static void ClientInit(void); __attribute__((destructor)) static void ClientDeinit(void); @@ -45,18 +46,18 @@ static int InitParamClient() return InitParamWorkSpace(&g_clientSpace.paramSpace, 1); } -void ClientInit() +void ClientInit(void) { PARAM_LOGI("ClientInit"); (void)InitParamClient(); } -void ClientDeinit() +void ClientDeinit(void) { CloseParamWorkSpace(&g_clientSpace.paramSpace); } -static ParamSecurityOps *GetClientParamSecurityOps() +static ParamSecurityOps *GetClientParamSecurityOps(void) { return &g_clientSpace.paramSpace.paramSecurityOps; } @@ -87,7 +88,7 @@ static int ProcessRecvMsg(const ParamMessage *recvMsg) int result = PARAM_CODE_INVALID_PARAM; switch (recvMsg->type) { case MSG_SET_PARAM: - result = ( (ParamResponseMessage *)recvMsg)->result; + result = ((ParamResponseMessage *)recvMsg)->result; break; case MSG_NOTIFY_PARAM: result = 0; @@ -110,7 +111,8 @@ static int StartRequest(int *fd, ParamMessage *request, int timeout) clientFd = socket(AF_UNIX, SOCK_STREAM, 0); PARAM_CHECK(clientFd >= 0, return PARAM_CODE_FAIL_CONNECT, "Failed to create socket"); ret = ConntectServer(clientFd, PIPE_NAME); - PARAM_CHECK(ret == 0, close(clientFd); return PARAM_CODE_FAIL_CONNECT, "Failed to connect server"); + PARAM_CHECK(ret == 0, close(clientFd); + return PARAM_CODE_FAIL_CONNECT, "Failed to connect server"); setsockopt(clientFd, SOL_SOCKET, SO_SNDTIMEO, (char *)&time, sizeof(struct timeval)); setsockopt(clientFd, SOL_SOCKET, SO_RCVTIMEO, (char *)&time, sizeof(struct timeval)); *fd = clientFd; @@ -163,9 +165,11 @@ int SystemSetParameter(const char *name, const char *value) PARAM_CHECK(request != NULL, return -1, "Failed to malloc for connect"); uint32_t offset = 0; ret = FillParamMsgContent(request, &offset, PARAM_VALUE, value, strlen(value)); - PARAM_CHECK(ret == 0, free(request); return -1, "Failed to fill value"); + PARAM_CHECK(ret == 0, free(request); + return -1, "Failed to fill value"); ret = FillLabelContent(request, &offset, labelLen); - PARAM_CHECK(ret == 0, free(request); return -1, "Failed to fill label"); + PARAM_CHECK(ret == 0, free(request); + return -1, "Failed to fill label"); request->msgSize = offset + sizeof(ParamMessage); request->id.msgId = atomic_fetch_add(&g_requestId, 1); @@ -205,7 +209,8 @@ int SystemWaitParameter(const char *name, const char *value, int32_t timeout) PARAM_CHECK(request != NULL, return -1, "Failed to malloc for wait"); ret = FillParamMsgContent(request, &offset, PARAM_VALUE, "*", 1); } - PARAM_CHECK(ret == 0, free(request); return -1, "Failed to fill value"); + PARAM_CHECK(ret == 0, free(request); + return -1, "Failed to fill value"); ParamMsgContent *content = (ParamMsgContent *)(request->data + offset); content->type = PARAM_WAIT_TIMEOUT; content->contentSize = sizeof(uint32_t); @@ -226,7 +231,7 @@ int SystemWaitParameter(const char *name, const char *value, int32_t timeout) int SystemGetParameter(const char *name, char *value, unsigned int *len) { - InitParamClient(); + InitParamClient(); PARAM_CHECK(name != NULL && len != NULL, return -1, "The name or value is null"); ParamHandle handle = 0; int ret = ReadParamWithCheck(&g_clientSpace.paramSpace, name, DAC_READ, &handle); @@ -299,7 +304,7 @@ int WatchParamCheck(const char *keyprefix) } #ifdef STARTUP_INIT_TEST -ParamWorkSpace *GetClientParamWorkSpace() +ParamWorkSpace *GetClientParamWorkSpace(void) { return &g_clientSpace.paramSpace; } diff --git a/services/param/cmd/param_cmd.c b/services/param/cmd/param_cmd.c index 08f609ed8..812c8814e 100755 --- a/services/param/cmd/param_cmd.c +++ b/services/param/cmd/param_cmd.c @@ -27,6 +27,16 @@ #define USAGE_INFO_PARAM_DUMP "param dump [verbose]" #define USAGE_INFO_PARAM_READ "param read key" #define USAGE_INFO_PARAM_WATCH "param watch key" +#define READ_DURATION 100000 +#define MIN_ARGC 2 +#define WAIT_TIMEOUT_INDEX 2 + +struct CmdArgs { + char name[8]; + int minArg; + void (*DoFuncion)(int argc, char *argv[], int start); + char help[128]; +}; static void ShowParam(ParamHandle handle, void *cookie) { @@ -40,7 +50,7 @@ static void ShowParam(ParamHandle handle, void *cookie) static void ExeuteCmdParamGet(int argc, char *argv[], int start) { - uint32_t size = PARAM_CONST_VALUE_LEN_MAX + PARAM_NAME_LEN_MAX + 2; + uint32_t size = PARAM_CONST_VALUE_LEN_MAX + PARAM_NAME_LEN_MAX + 1 + 1; char *buffer = (char *)malloc(size); if (buffer == NULL) { printf("Get parameterfail\n"); @@ -62,6 +72,7 @@ static void ExeuteCmdParamGet(int argc, char *argv[], int start) static void ExeuteCmdParamSet(int argc, char *argv[], int start) { + UNUSED(argc); int ret = SystemSetParameter(argv[start], argv[start + 1]); if (ret == 0) { printf("Set parameter %s %s success\n", argv[start], argv[start + 1]); @@ -87,8 +98,8 @@ static void ExeuteCmdParamWait(int argc, char *argv[], int start) if (argc > (start + 1)) { value = argv[start + 1]; } - if (argc > (start + 2)) { - timeout = atol(argv[start + 2]); + if (argc > (start + WAIT_TIMEOUT_INDEX)) { + timeout = atol(argv[start + WAIT_TIMEOUT_INDEX]); } SystemWaitParameter(argv[start], value, timeout); } @@ -99,7 +110,7 @@ static void ExeuteCmdParamRead(int argc, char *argv[], int start) srand((unsigned)time(NULL)); // srand()函数产生一个以当前时间开始的随机种子 while (1) { ExeuteCmdParamGet(argc, argv, start); - int wait = rand() / 100000 + 100000; // 100ms + int wait = rand() / READ_DURATION + READ_DURATION; // 100ms usleep(wait); } } @@ -121,45 +132,39 @@ static void ExeuteCmdParamWatch(int argc, char *argv[], int start) } #endif -struct { - char name[8]; - int minArg; - void (*DoFuncion)(int argc, char *argv[], int start); - char help[128]; -} g_paramCmds[] = { - { "set", 4, ExeuteCmdParamSet, USAGE_INFO_PARAM_SET }, - { "get", 2, ExeuteCmdParamGet, USAGE_INFO_PARAM_GET }, - { "wait", 3, ExeuteCmdParamWait, USAGE_INFO_PARAM_WAIT }, - { "dump", 2, ExeuteCmdParamDump, USAGE_INFO_PARAM_DUMP }, -#ifdef PARAM_TEST - { "read", 2, ExeuteCmdParamRead, USAGE_INFO_PARAM_READ }, - { "watch", 2, ExeuteCmdParamWatch, USAGE_INFO_PARAM_WATCH }, -#endif -}; - int RunParamCommand(int argc, char *argv[]) { - if (argc < 2) { + static struct CmdArgs paramCmds[] = { + { "set", 4, ExeuteCmdParamSet, USAGE_INFO_PARAM_SET }, + { "get", 2, ExeuteCmdParamGet, USAGE_INFO_PARAM_GET }, + { "wait", 3, ExeuteCmdParamWait, USAGE_INFO_PARAM_WAIT }, + { "dump", 2, ExeuteCmdParamDump, USAGE_INFO_PARAM_DUMP }, +#ifdef PARAM_TEST + { "read", 2, ExeuteCmdParamRead, USAGE_INFO_PARAM_READ }, + { "watch", 2, ExeuteCmdParamWatch, USAGE_INFO_PARAM_WATCH }, +#endif + }; + if (argc < MIN_ARGC) { printf("usage: \n"); - for (size_t i = 0; i < sizeof(g_paramCmds) / sizeof(g_paramCmds[0]); i++) { - printf("\t %s\n", g_paramCmds[i].help); + for (size_t i = 0; i < sizeof(paramCmds) / sizeof(paramCmds[0]); i++) { + printf("\t %s\n", paramCmds[i].help); } return 0; } - for (size_t i = 0; i < sizeof(g_paramCmds) / sizeof(g_paramCmds[0]); i++) { - if (strncmp(argv[1], g_paramCmds[i].name, strlen(g_paramCmds[i].name)) == 0) { - if (argc < g_paramCmds[i].minArg) { - printf("usage: %s\n", g_paramCmds[i].help); + for (size_t i = 0; i < sizeof(paramCmds) / sizeof(paramCmds[0]); i++) { + if (strncmp(argv[1], paramCmds[i].name, strlen(paramCmds[i].name)) == 0) { + if (argc < paramCmds[i].minArg) { + printf("usage: %s\n", paramCmds[i].help); return 0; } - g_paramCmds[i].DoFuncion(argc, argv, 2); + paramCmds[i].DoFuncion(argc, argv, MIN_ARGC); return 0; } } printf("usage: \n"); - for (size_t i = 0; i < sizeof(g_paramCmds) / sizeof(g_paramCmds[0]); i++) { - printf("\t%s\n", g_paramCmds[i].help); + for (size_t i = 0; i < sizeof(paramCmds) / sizeof(paramCmds[0]); i++) { + printf("\t%s\n", paramCmds[i].help); } return 0; } diff --git a/services/param/include/param_manager.h b/services/param/include/param_manager.h index ff3a578d8..2c1081469 100755 --- a/services/param/include/param_manager.h +++ b/services/param/include/param_manager.h @@ -69,9 +69,8 @@ typedef struct { } ParamTraversalContext; int TraversalParam(ParamWorkSpace *workSpace, TraversalParamPtr walkFunc, void *cookie); -ParamPersistWorkSpace *GeParamPersistWorkSpace(); -ParamWorkSpace *GetParamWorkSpace(); -ParamWorkSpace *GetClientParamWorkSpace(); +ParamWorkSpace *GetParamWorkSpace(void); +ParamWorkSpace *GetClientParamWorkSpace(void); void DumpParameters(ParamWorkSpace *workSpace, int verbose); #ifdef __cplusplus #if __cplusplus diff --git a/services/param/include/param_message.h b/services/param/include/param_message.h index c05f346e7..1c69f1cf3 100755 --- a/services/param/include/param_message.h +++ b/services/param/include/param_message.h @@ -108,7 +108,7 @@ typedef struct { TaskClose close; } ParamStreamInfo; -int ParamServiceStop(); +int ParamServiceStop(void); int ParamServiceStart(ProcessPidDelete pidDelete); int ParamTaskClose(ParamTaskPtr stream); diff --git a/services/param/include/param_security.h b/services/param/include/param_security.h index 74149a250..b3b15e63b 100755 --- a/services/param/include/param_security.h +++ b/services/param/include/param_security.h @@ -23,9 +23,12 @@ extern "C" { #endif #endif +#define DAC_GROUP_START 3 +#define DAC_OTHER_START 6 #define DAC_READ 0x0100 #define DAC_WRITE 0x0080 #define DAC_WATCH 0x0040 +#define DAC_ALL_PERMISSION 0777 #define LABEL_ALL_PERMISSION 0x04 #define LABEL_CHECK_FOR_ALL_PROCESS 0x02 diff --git a/services/param/include/param_service.h b/services/param/include/param_service.h index 59444ab3c..94ea4d3fc 100755 --- a/services/param/include/param_service.h +++ b/services/param/include/param_service.h @@ -32,7 +32,7 @@ extern "C" { int WriteParam(WorkSpace *workSpace, const char *name, const char *value, uint32_t *dataIndex, int onlyAdd); int InitPersistParamWorkSpace(ParamWorkSpace *workSpace); -void ClosePersistParamWorkSpace(); +void ClosePersistParamWorkSpace(void); int LoadPersistParam(ParamWorkSpace *workSpace); int WritePersistParam(ParamWorkSpace *workSpace, const char *name, const char *value); diff --git a/services/param/include/param_trie.h b/services/param/include/param_trie.h index e993e4d00..c03a9df71 100755 --- a/services/param/include/param_trie.h +++ b/services/param/include/param_trie.h @@ -27,7 +27,9 @@ #ifndef __NR_futex -#define __NR_futex 202 /* syscall number */ +#define PARAM_NR_FUTEX 202 /* syscall number */ +#else +#define PARAM_NR_FUTEX __NR_futex #endif #if defined FUTEX_WAIT || defined FUTEX_WAKE @@ -36,12 +38,12 @@ #define FUTEX_WAIT 0 #define FUTEX_WAKE 1 -#define __futex(ftx, op, value, timeout, bitset) \ +#define __futex__(ftx, op, value, timeout, bitset) \ struct timespec d_timeout = {0, 1000 * 1000 * (timeout)}; \ - syscall(__NR_futex, ftx, op, value, &d_timeout, NULL, bitset) + syscall(PARAM_NR_FUTEX, ftx, op, value, &d_timeout, NULL, bitset) -#define futex_wake(ftx, count) __futex(ftx, FUTEX_WAKE, count, 0, 0) -#define futex_wait(ftx, value) __futex(ftx, FUTEX_WAIT, value, 100, 0) +#define futex_wake(ftx, count) __futex__(ftx, FUTEX_WAKE, count, 0, 0) +#define futex_wait(ftx, value) __futex__(ftx, FUTEX_WAIT, value, 100, 0) #endif #ifdef __cplusplus @@ -50,15 +52,11 @@ extern "C" { #endif #endif -#define PARAM_WORKSPACE_MAX 80 * 1024 +#define PARAM_WORKSPACE_MAX (80 * 1024) #define FILENAME_LEN_MAX 255 - -#define TRIE_NODE_HEADER \ - uint32_t left; \ - uint32_t right; - typedef struct { - TRIE_NODE_HEADER; + uint32_t left; + uint32_t right; uint32_t child; uint32_t labelIndex; uint32_t dataIndex; diff --git a/services/param/include/param_utils.h b/services/param/include/param_utils.h index 5fa5ab93a..61decf08f 100755 --- a/services/param/include/param_utils.h +++ b/services/param/include/param_utils.h @@ -33,6 +33,8 @@ typedef enum { PARAM_CODE_ERROR_MAP_FILE, } PARAM_INNER_CODE; +#define MS_UNIT 1000 +#define UNUSED(x) (void)(x) #define PARAM_ALIGN(len) (((len) + 0x03) & (~0x03)) #define PARAM_ENTRY(ptr, type, member) (type *)((char *)(ptr)-offsetof(type, member)) @@ -48,7 +50,7 @@ typedef enum { #ifdef STARTUP_INIT_TEST #define PARAM_STATIC -#define PARAM_DEFAULT_PATH "/data/startup/test/test_data" +#define PARAM_DEFAULT_PATH "" #define PIPE_NAME "/data/paramservice" #define PARAM_STORAGE_PATH PARAM_DEFAULT_PATH"/__parameters__/param_storage" #define PARAM_PERSIST_SAVE_PATH PARAM_DEFAULT_PATH"/param/persist_parameters" @@ -82,9 +84,9 @@ typedef enum { #define PARAM_LOGD(fmt, ...) STARTUP_LOGD(LABEL, fmt, ##__VA_ARGS__) #define PARAM_CHECK(retCode, exper, ...) \ - if (!(retCode)) { \ - PARAM_LOGE(__VA_ARGS__); \ - exper; \ + if (!(retCode)) { \ + PARAM_LOGE(__VA_ARGS__); \ + exper; \ } #define MAX_LABEL_LEN 256 diff --git a/services/param/include/trigger_checker.h b/services/param/include/trigger_checker.h index 19b004222..ad38e5f71 100755 --- a/services/param/include/trigger_checker.h +++ b/services/param/include/trigger_checker.h @@ -30,6 +30,7 @@ extern "C" { #define MAX_TRIGGER_TYPE_LEN 16 #define SUPPORT_DATA_BUFFER_MAX 128 +#define MAX_DATA_BUFFER_MAX (SUPPORT_DATA_BUFFER_MAX * 5) #define CONDITION_EXTEND_LEN 32 #define LOGIC_DATA_FLAGS_ORIGINAL 0x1 diff --git a/services/param/include/trigger_manager.h b/services/param/include/trigger_manager.h index f0a604728..24225c37d 100755 --- a/services/param/include/trigger_manager.h +++ b/services/param/include/trigger_manager.h @@ -72,9 +72,11 @@ typedef struct { } TriggerHeader; #define PARAM_TRIGGER_HEAD_INIT(head) \ - ListInit(&head.triggerList); \ - head.triggerCount = 0; \ - head.cmdNodeCount = 0; + do { \ + ListInit(&head.triggerList); \ + head.triggerCount = 0; \ + head.cmdNodeCount = 0; \ + } while (0) // Command对象列表,主要存储每个triger需要执行那些Command操作。 typedef struct CommandNode_ { @@ -85,8 +87,8 @@ typedef struct CommandNode_ { typedef struct tagTriggerNode_ { ListNode node; - uint32_t flags:24; - uint32_t type:8; + uint32_t flags : 24; + uint32_t type : 8; TriggerHeader *triggerHead; CommandNode *firstCmd; CommandNode *lastCmd; @@ -158,7 +160,7 @@ TriggerNode *AddWatcherTrigger(ParamWatcher *watcher, void DelWatcherTrigger(ParamWatcher *watcher, uint32_t watcherId); void ClearWatcherTrigger(ParamWatcher *watcher); -TriggerWorkSpace *GetTriggerWorkSpace(); +TriggerWorkSpace *GetTriggerWorkSpace(void); #ifdef __cplusplus #if __cplusplus } diff --git a/services/param/manager/param_manager.c b/services/param/manager/param_manager.c index 7d67d55dd..8324197ce 100755 --- a/services/param/manager/param_manager.c +++ b/services/param/manager/param_manager.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include "param_manager.h" #include #include @@ -23,6 +24,7 @@ static ParamSecurityLabel g_defaultSecurityLabel; static int GetParamSecurityOps(ParamWorkSpace *workSpace, int isInit) { + UNUSED(isInit); int ret = 0; #if (defined PARAM_SUPPORT_SELINUX || defined PARAM_SUPPORT_DAC) ret = RegisterSecurityOps(&workSpace->paramSecurityOps, isInit); @@ -132,7 +134,7 @@ int ReadParamValue(ParamWorkSpace *workSpace, ParamHandle handle, char *value, u uint32_t commitId = ReadCommitId(entry); do { int ret = memcpy_s(value, *length, entry->data + entry->keyLength + 1, entry->valueLength); - PARAM_CHECK(ret == 0, return -1, "Failed to copy value"); + PARAM_CHECK(ret == EOK, return -1, "Failed to copy value"); value[entry->valueLength] = '\0'; *length = entry->valueLength; } while (commitId != ReadCommitId(entry)); @@ -148,7 +150,7 @@ int ReadParamName(ParamWorkSpace *workSpace, ParamHandle handle, char *name, uin } PARAM_CHECK(length > entry->keyLength, return -1, "Invalid param size %u %u", entry->keyLength, length); int ret = memcpy_s(name, length, entry->data, entry->keyLength); - PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_PARAM, "Failed to copy name"); + PARAM_CHECK(ret == EOK, return PARAM_CODE_INVALID_PARAM, "Failed to copy name"); name[entry->keyLength] = '\0'; return 0; } @@ -190,6 +192,7 @@ int CheckParamName(const char *name, int info) static int ProcessParamTraversal(WorkSpace *workSpace, ParamTrieNode *node, void *cookie) { + UNUSED(workSpace); ParamTraversalContext *context = (ParamTraversalContext *)cookie; ParamTrieNode *current = (ParamTrieNode *)node; if (current == NULL) { diff --git a/services/param/manager/param_message.c b/services/param/manager/param_message.c index 0a41d285c..9d5d8dcfa 100755 --- a/services/param/manager/param_message.c +++ b/services/param/manager/param_message.c @@ -1,10 +1,10 @@ /* - * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 + * 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, @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include "param_message.h" #include #include @@ -31,7 +32,7 @@ int ConntectServer(int fd, const char *servername) PARAM_CHECK(ret == 0, return -1, "Failed to memset server address"); addr.sun_family = AF_UNIX; ret = sprintf_s(addr.sun_path, sizeof(addr.sun_path) - 1, "%s", servername); - PARAM_CHECK(ret > 0, return -1, "Failed to sprintf_s server address"); + PARAM_CHECK(ret > EOK, return -1, "Failed to sprintf_s server address"); int len = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path); ret = connect(fd, (struct sockaddr *)&addr, len); PARAM_CHECK(ret != -1, return -1, "Failed to connect server %s %s", servername, strerror(errno)); @@ -50,7 +51,7 @@ int FillParamMsgContent(ParamMessage *request, uint32_t *start, int type, const content->type = type; content->contentSize = length + 1; int ret = memcpy_s(content->content, content->contentSize - 1, value, length); - PARAM_CHECK(ret == 0, return -1, "Failed to copy value for %d", type); + PARAM_CHECK(ret == EOK, return -1, "Failed to copy value for %d", type); content->content[length] = '\0'; offset += sizeof(ParamMsgContent) + PARAM_ALIGN(content->contentSize); *start = offset; @@ -68,7 +69,8 @@ ParamMessage *CreateParamMessage(int type, const char *name, uint32_t msgSize) msg->id.msgId = 0; msg->msgSize = msgSize; int ret = strcpy_s(msg->key, sizeof(msg->key) - 1, name); - PARAM_CHECK(ret == 0, free(msg); return NULL, "Failed to fill name"); + PARAM_CHECK(ret == EOK, free(msg); + return NULL, "Failed to fill name"); return msg; } diff --git a/services/param/manager/param_trie.c b/services/param/manager/param_trie.c index 60a7c234e..1de0df134 100755 --- a/services/param/manager/param_trie.c +++ b/services/param/manager/param_trie.c @@ -81,7 +81,7 @@ static uint32_t AllocateParamTrieNode(WorkSpace *workSpace, const char *key, uin ParamTrieNode *node = (ParamTrieNode*)(workSpace->area->data + workSpace->area->currOffset); node->length = keyLen; int ret = memcpy_s(node->key, keyLen, key, keyLen); - PARAM_CHECK(ret == 0, return 0, "Failed to copy key"); + PARAM_CHECK(ret == EOK, return 0, "Failed to copy key"); node->key[keyLen] = '\0'; node->left = 0; node->right = 0; @@ -114,7 +114,7 @@ int InitWorkSpace(const char *fileName, WorkSpace *workSpace, int onlyRead) workSpace->compareTrieNode = CompareParamTrieNode; workSpace->allocTrieNode = AllocateParamTrieNode; int ret = memcpy_s(workSpace->fileName, FILENAME_LEN_MAX, fileName, strlen(fileName)); - PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_NAME, "Copy file %s fail ", fileName); + PARAM_CHECK(ret == EOK, return PARAM_CODE_INVALID_NAME, "Copy file %s fail ", fileName); int openMode = 0; int prot = PROT_READ; if (onlyRead) { @@ -288,7 +288,7 @@ ParamTrieNode *FindTrieNode(WorkSpace *workSpace, const char *key, uint32_t keyL } static int TraversalSubTrieNode(WorkSpace *workSpace, - ParamTrieNode *current, TraversalTrieNodePtr walkFunc, void* cookie) + ParamTrieNode *current, TraversalTrieNodePtr walkFunc, void *cookie) { if (current == NULL) { return 0; @@ -337,7 +337,7 @@ uint32_t AddParamSecruityNode(WorkSpace *workSpace, const ParamAuditData *auditD node->length = 0; if (labelLen != 0) { int ret = memcpy_s(node->data, labelLen, auditData->label, labelLen); - PARAM_CHECK(ret == 0, return 0, "Failed to copy key"); + PARAM_CHECK(ret == EOK, return 0, "Failed to copy key"); node->data[labelLen] = '\0'; node->length = labelLen; } @@ -369,7 +369,7 @@ uint32_t AddParamNode(WorkSpace *workSpace, const char *key, uint32_t keyLen, co node->keyLength = keyLen; node->valueLength = valueLen; int ret = sprintf_s(node->data, realLen - 1, "%s=%s", key, value); - PARAM_CHECK(ret > 0, return 0, "Failed to sprint key and value"); + PARAM_CHECK(ret > EOK, return 0, "Failed to sprint key and value"); uint32_t offset = workSpace->area->currOffset; workSpace->area->currOffset += realLen; workSpace->area->paramNodeCount++; diff --git a/services/param/manager/param_utils.c b/services/param/manager/param_utils.c index 4ecca7c8d..4038bd9a7 100755 --- a/services/param/manager/param_utils.c +++ b/services/param/manager/param_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include "param_utils.h" #include #include @@ -45,7 +46,8 @@ int ReadFileInDir(const char *dirPath, const char *includeExt, DIR *pDir = opendir(dirPath); PARAM_CHECK(pDir != NULL, return -1, "Read dir :%s failed.%d", dirPath, errno); char *fileName = malloc(PARAM_BUFFER_SIZE); - PARAM_CHECK(fileName != NULL, closedir(pDir); return -1, "Failed to malloc for %s", dirPath); + PARAM_CHECK(fileName != NULL, closedir(pDir); + return -1, "Failed to malloc for %s", dirPath); struct dirent *dp; while ((dp = readdir(pDir)) != NULL) { @@ -63,7 +65,7 @@ int ReadFileInDir(const char *dirPath, const char *includeExt, } } int ret = snprintf_s(fileName, PARAM_BUFFER_SIZE, PARAM_BUFFER_SIZE - 1, "%s/%s", dirPath, dp->d_name); - PARAM_CHECK(ret > 0, continue, "Failed to get file name for %s", dp->d_name); + PARAM_CHECK(ret > EOK, continue, "Failed to get file name for %s", dp->d_name); struct stat st; if (stat(fileName, &st) == 0) { processFile(fileName, context); diff --git a/services/param/service/param_persist.c b/services/param/service/param_persist.c index 6f5534b52..37aa4b326 100755 --- a/services/param/service/param_persist.c +++ b/services/param/service/param_persist.c @@ -25,9 +25,7 @@ #define LABEL "Manager" -static ParamPersistWorkSpace g_persistWorkSpace = { - 0, NULL, 0, {NULL, NULL, NULL, NULL, NULL} - }; +static ParamPersistWorkSpace g_persistWorkSpace = { 0, NULL, 0, {NULL, NULL, NULL, NULL, NULL} }; static int AddPersistParam(const char *name, const char *value, void *context) { @@ -54,9 +52,9 @@ static int SavePersistParam(WorkSpace *workSpace, ParamTrieNode *node, void *coo if (strncmp(entry->data, PARAM_CONST_PREFIX, strlen(PARAM_CONST_PREFIX)) != 0) { return 0; } - static char name[PARAM_NAME_LEN_MAX] = {0}; + static char name[PARAM_NAME_LEN_MAX] = { 0 }; int ret = memcpy_s(name, PARAM_NAME_LEN_MAX - 1, entry->data, entry->keyLength); - PARAM_CHECK(ret == 0, return -1, "Failed to read param name %s", entry->data); + PARAM_CHECK(ret == EOK, return -1, "Failed to read param name %s", entry->data); name[entry->keyLength] = '\0'; ret = g_persistWorkSpace.persistParamOps.batchSave(cookie, name, entry->data + entry->keyLength + 1); PARAM_CHECK(ret == 0, return -1, "Failed to write param %s", current->key); @@ -81,7 +79,7 @@ static int BatchSavePersistParam(WorkSpace *workSpace) PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_NAME, "Save persist param fail"); PARAM_CLEAR_FLAG(g_persistWorkSpace.flags, WORKSPACE_FLAGS_UPDATE); - time(&g_persistWorkSpace.lastSaveTimer); + (void)time(&g_persistWorkSpace.lastSaveTimer); return ret; } @@ -90,7 +88,7 @@ int InitPersistParamWorkSpace(ParamWorkSpace *workSpace) if (PARAM_TEST_FLAG(g_persistWorkSpace.flags, WORKSPACE_FLAGS_INIT)) { return 0; } - time(&g_persistWorkSpace.lastSaveTimer); + (void)time(&g_persistWorkSpace.lastSaveTimer); #ifdef PARAM_SUPPORT_SAVE_PERSIST RegisterPersistParamOps(&g_persistWorkSpace.persistParamOps); #endif @@ -98,7 +96,7 @@ int InitPersistParamWorkSpace(ParamWorkSpace *workSpace) return 0; } -void ClosePersistParamWorkSpace() +void ClosePersistParamWorkSpace(void) { if (g_persistWorkSpace.saveTimer != NULL) { ParamTaskClose(g_persistWorkSpace.saveTimer); @@ -130,6 +128,7 @@ int LoadPersistParam(ParamWorkSpace *workSpace) static void TimerCallbackForSave(ParamTaskPtr timer, void *context) { + UNUSED(context); ParamTaskClose(timer); g_persistWorkSpace.saveTimer = NULL; if (!PARAM_TEST_FLAG(g_persistWorkSpace.flags, WORKSPACE_FLAGS_UPDATE)) { @@ -160,7 +159,7 @@ int WritePersistParam(ParamWorkSpace *workSpace, const char *name, const char *v // check timer for save all time_t currTimer; - time(&currTimer); + (void)time(&currTimer); uint32_t diff = (uint32_t)difftime(currTimer, g_persistWorkSpace.lastSaveTimer); if (diff > PARAM_MUST_SAVE_PARAM_DIFF) { if (g_persistWorkSpace.saveTimer != NULL) { diff --git a/services/param/service/param_service.c b/services/param/service/param_service.c index 2ec4bdb06..edbecdcc9 100755 --- a/services/param/service/param_service.c +++ b/services/param/service/param_service.c @@ -1,10 +1,10 @@ /* - * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 + * 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, @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include "param_service.h" #include #include @@ -31,9 +32,7 @@ #include "trigger_manager.h" #define LABEL "ParamServer" -static ParamWorkSpace g_paramWorkSpace = { - 0, {}, NULL, {}, NULL, NULL - }; +static ParamWorkSpace g_paramWorkSpace = { 0, {}, NULL, {}, NULL, NULL }; static void OnClose(ParamTaskPtr client) { @@ -71,7 +70,7 @@ static int UpdateParam(WorkSpace *workSpace, uint32_t *dataIndex, const char *na if (entry->valueLength < PARAM_VALUE_LEN_MAX && valueLen < PARAM_VALUE_LEN_MAX) { int ret = memcpy_s(entry->data + entry->keyLength + 1, PARAM_VALUE_LEN_MAX, value, valueLen + 1); - PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_VALUE, "Failed to copy value"); + PARAM_CHECK(ret == EOK, return PARAM_CODE_INVALID_VALUE, "Failed to copy value"); entry->valueLength = valueLen; } uint32_t flags = commitId & ~PARAM_FLAGS_COMMITID; @@ -163,7 +162,7 @@ static char *GetServiceCtrlName(const char *name, const char *value) key = (char *)malloc(keySize + 1); PARAM_CHECK(key != NULL, return NULL, "Failed to alloc memory for %s", name); int ret = sprintf_s(key, keySize, "%s%s", OHOS_SERVICE_CTRL_PREFIX, powerCtrlArg[i][1]); - PARAM_CHECK(ret > 0, return NULL, "Failed to format key for %s", name); + PARAM_CHECK(ret > EOK, return NULL, "Failed to format key for %s", name); return key; } } @@ -174,7 +173,7 @@ static char *GetServiceCtrlName(const char *name, const char *value) key = (char *)malloc(keySize + 1); PARAM_CHECK(key != NULL, return NULL, "Failed to alloc memory for %s", name); int ret = sprintf_s(key, keySize, "%s%s", OHOS_SERVICE_CTRL_PREFIX, value); - PARAM_CHECK(ret > 0, return NULL, "Failed to format key for %s", name); + PARAM_CHECK(ret > EOK, return NULL, "Failed to format key for %s", name); return key; } } @@ -252,6 +251,7 @@ static int SendResponseMsg(ParamTaskPtr worker, const ParamMessage *msg, int res static int SendWatcherNotifyMessage(TriggerExtData *extData, int cmd, const char *content) { + UNUSED(cmd); PARAM_CHECK(content != NULL, return -1, "Invalid content"); PARAM_CHECK(extData != NULL && extData->watcher != NULL, return -1, "Invalid extData"); uint32_t msgSize = sizeof(ParamMessage) + PARAM_ALIGN(strlen(content) + 1); @@ -263,13 +263,16 @@ static int SendWatcherNotifyMessage(TriggerExtData *extData, int cmd, const char char *tmp = strstr(content, "="); if (tmp != NULL) { ret = strncpy_s(msg->key, sizeof(msg->key) - 1, content, tmp - content); - PARAM_CHECK(ret == 0, free(msg); return -1, "Failed to fill value"); + PARAM_CHECK(ret == 0, free(msg); + return -1, "Failed to fill value"); tmp++; ret = FillParamMsgContent(msg, &offset, PARAM_VALUE, tmp, strlen(tmp)); - PARAM_CHECK(ret == 0, free(msg); return -1, "Failed to fill value"); + PARAM_CHECK(ret == 0, free(msg); + return -1, "Failed to fill value"); } else { ret = FillParamMsgContent(msg, &offset, PARAM_VALUE, tmp, strlen(content)); - PARAM_CHECK(ret == 0, free(msg); return -1, "Failed to fill value"); + PARAM_CHECK(ret == 0, free(msg); + return -1, "Failed to fill value"); } msg->id.msgId = extData->watcherId; @@ -284,19 +287,19 @@ static int HandleParamSet(const ParamTaskPtr worker, const ParamMessage *msg) uint32_t offset = 0; ParamMsgContent *valueContent = GetNextContent(msg, &offset); PARAM_CHECK(valueContent != NULL, return -1, "Invalid msg for %s", msg->key); - + int ret = 0; ParamMsgContent *lableContent = GetNextContent(msg, &offset); ParamSecurityLabel *srcLabel = NULL; if (lableContent != NULL && lableContent->contentSize != 0) { PARAM_CHECK(g_paramWorkSpace.paramSecurityOps.securityDecodeLabel != NULL, return -1, "Can not get decode function"); - int ret = g_paramWorkSpace.paramSecurityOps.securityDecodeLabel(&srcLabel, + ret = g_paramWorkSpace.paramSecurityOps.securityDecodeLabel(&srcLabel, lableContent->content, lableContent->contentSize); PARAM_CHECK(ret == 0, return ret, "Failed to decode param %d name %s %s", ret, msg->key, valueContent->content); } - int ret = SystemSetParam(msg->key, valueContent->content, srcLabel); + ret = SystemSetParam(msg->key, valueContent->content, srcLabel); if (srcLabel != NULL && g_paramWorkSpace.paramSecurityOps.securityFreeLabel != NULL) { g_paramWorkSpace.paramSecurityOps.securityFreeLabel(srcLabel); } @@ -361,9 +364,11 @@ static int HandleParamWaitAdd(ParamWorkSpace *worksapce, const ParamTaskPtr work char *condition = malloc(buffSize); PARAM_CHECK(condition != NULL, return -1, "Failed to create condition for %s", msg->key); int ret = sprintf_s(condition, buffSize - 1, "%s=%s", msg->key, valueContent->content); - PARAM_CHECK(ret > 0, free(condition); return -1, "Failed to copy name for %s", msg->key); + PARAM_CHECK(ret > EOK, free(condition); + return -1, "Failed to copy name for %s", msg->key); TriggerNode *trigger = AddWatcherTrigger(watcher, TRIGGER_PARAM_WAIT, msg->key, condition, &extData); - PARAM_CHECK(trigger != NULL, free(condition); return -1, "Failed to add trigger for %s", msg->key); + PARAM_CHECK(trigger != NULL, free(condition); + return -1, "Failed to add trigger for %s", msg->key); free(condition); return 0; } @@ -377,10 +382,12 @@ static int HandleParamWatcherAdd(ParamWorkSpace *workSpace, const ParamTaskPtr w int ret = 0; do { ParamWatcher *watcher = GetParamWatcher(NULL); - PARAM_CHECK(watcher != NULL, ret = -1; break, "Failed to get param watcher data"); + PARAM_CHECK(watcher != NULL, ret = -1; + break, "Failed to get param watcher data"); watcher->stream = worker; TriggerNode *trigger = AddWatcherTrigger(watcher, TRIGGER_PARAM_WATCH, msg->key, NULL, &extData); - PARAM_CHECK(trigger != NULL, ret = -1; break, "Failed to add trigger for %s", msg->key); + PARAM_CHECK(trigger != NULL, ret = -1; + break, "Failed to add trigger for %s", msg->key); } while (0); PARAM_LOGD("HandleParamWatcherAdd name %s watcher: %d", msg->key, msg->id.watcherId); return SendResponseMsg(worker, msg, ret); @@ -427,7 +434,8 @@ static int LoadDefaultParam_(const char *fileName, int mode, const char *exclude FILE *fp = fopen(fileName, "r"); PARAM_CHECK(fp != NULL, return -1, "Open file %s fail", fileName); char *buff = malloc(sizeof(SubStringInfo) * (SUBSTR_INFO_VALUE + 1) + PARAM_BUFFER_SIZE); - PARAM_CHECK(buff != NULL, fclose(fp); return -1, "Failed to alloc memory for load %s", fileName); + PARAM_CHECK(buff != NULL, (void)fclose(fp); + return -1, "Failed to alloc memory for load %s", fileName); SubStringInfo *info = (SubStringInfo *)(buff + PARAM_BUFFER_SIZE); while (fgets(buff, PARAM_BUFFER_SIZE, fp) != NULL) { @@ -451,7 +459,7 @@ static int LoadDefaultParam_(const char *fileName, int mode, const char *exclude PARAM_CHECK(ret == 0, continue, "Failed to set param %d %s", ret, buff); paramNum++; } - fclose(fp); + (void)fclose(fp); free(buff); PARAM_LOGI("Load parameters success %s total %u", fileName, paramNum); return 0; @@ -481,6 +489,7 @@ static int OnIncomingConnect(const ParamTaskPtr server, int flags) static void TimerCallback(ParamTaskPtr timer, void *context) { + UNUSED(context); ParamWatcher *watcher = GetNextParamWatcher(GetTriggerWorkSpace(), NULL); while (watcher != NULL) { ParamWatcher *next = GetNextParamWatcher(GetTriggerWorkSpace(), watcher); @@ -498,7 +507,7 @@ static int CopyBootParam(char *buffer, const char *key, size_t keyLen) { size_t bootLen = strlen(OHOS_BOOT); int ret = strncpy_s(buffer, PARAM_NAME_LEN_MAX - 1, OHOS_BOOT, bootLen); - PARAM_CHECK(ret == 0, return -1, "Failed to cpy boot"); + PARAM_CHECK(ret == EOK, return -1, "Failed to cpy boot"); size_t i = 0; for (; (i < PARAM_NAME_LEN_MAX - 1 - bootLen) && (i <= keyLen); i++) { buffer[i + bootLen] = key[i]; @@ -510,12 +519,31 @@ static int CopyBootParam(char *buffer, const char *key, size_t keyLen) return 0; } -static int LoadParamFromCmdLine() +struct CmdLineEntry { + char * key; + int set; +}; + +static int FindKey(const char *key, struct CmdLineEntry *cmdLineEntry, int length) +{ + PARAM_CHECK(key != NULL && cmdLineEntry != NULL && length > 0, return -1, "Input param error."); + for (int i = 0; i < length; i++) { + if (strstr(key, cmdLineEntry[i].key) != NULL) { + cmdLineEntry[i].set = 1; + return 1; + } + } + return 0; +} + +static int LoadParamFromCmdLine(struct CmdLineEntry *cmdLineEntry, int length) { + PARAM_CHECK(cmdLineEntry != NULL && length > 0, return -1, "Input params error."); char *buffer = ReadFileData(PARAM_CMD_LINE); PARAM_CHECK(buffer != NULL, return -1, "Failed to read file %s", PARAM_CMD_LINE); char *data = malloc(PARAM_NAME_LEN_MAX + PARAM_CONST_VALUE_LEN_MAX); - PARAM_CHECK(data != NULL, free(buffer); return -1, "Failed to read file %s", PARAM_CMD_LINE); + PARAM_CHECK(data != NULL, free(buffer); + return -1, "Failed to read file %s", PARAM_CMD_LINE); char *endBuffer = buffer + strlen(buffer); char *key = data; @@ -542,15 +570,22 @@ static int LoadParamFromCmdLine() ret1 = strncpy_s(value, PARAM_CONST_VALUE_LEN_MAX - 1, tmp + 1, endBuffer - tmp); } if ((ret == 0) && (ret1 == 0) && (CheckParamName(key, 0) == 0)) { - PARAM_LOGD("LoadParamFromCmdLine %s %s", key, value); uint32_t dataIndex = 0; - (void)WriteParam(&g_paramWorkSpace.paramSpace, key, value, &dataIndex, 0); + if (FindKey(key, cmdLineEntry, length) == 1) { + PARAM_LOGD("LoadParamFromCmdLine %s %s", key, value); + (void)WriteParam(&g_paramWorkSpace.paramSpace, key, value, &dataIndex, 0); + } } if (next == NULL) { break; } tmp = strchr(next, '='); } + for (int i = 0; i < length; i++) { + if (cmdLineEntry[i].set == 0) { + PARAM_LOGI("Warning, LoadParamFromCmdLine key %s is not found.", cmdLineEntry[i].key); + } + } free(data); free(buffer); return 0; @@ -579,7 +614,7 @@ int SystemTraversalParam(void (*traversalParameter)(ParamHandle handle, void *co return TraversalParam(&g_paramWorkSpace, traversalParameter, cookie); } -int LoadPersistParams() +int LoadPersistParams(void) { return LoadPersistParam(&g_paramWorkSpace); } @@ -614,7 +649,7 @@ int LoadDefaultParams(const char *fileName, int mode) return ret; } -void InitParamService() +void InitParamService(void) { PARAM_LOGI("InitParamService pipe: %s.", PIPE_NAME); CheckAndCreateDir(PIPE_NAME); @@ -629,14 +664,14 @@ void InitParamService() info.close = NULL; info.recvMessage = NULL; info.incomingConnect = OnIncomingConnect; - int ret = ParamServerCreate(&g_paramWorkSpace.serverTask, &info); + ret = ParamServerCreate(&g_paramWorkSpace.serverTask, &info); PARAM_CHECK(ret == 0, return, "Failed to create server"); PARAM_LOGD("OnIncomingConnect %p", g_paramWorkSpace.serverTask); } if (g_paramWorkSpace.timer == NULL) { ParamTimerCreate(&g_paramWorkSpace.timer, TimerCallback, &g_paramWorkSpace); - ParamTimerStart(g_paramWorkSpace.timer, 1, 1000); + ParamTimerStart(g_paramWorkSpace.timer, 1, MS_UNIT); PARAM_LOGD("Start timer %p", g_paramWorkSpace.timer); } ret = InitTriggerWorkSpace(); @@ -647,34 +682,35 @@ void InitParamService() auditData.label = NULL; auditData.dacData.gid = getegid(); auditData.dacData.uid = geteuid(); - auditData.dacData.mode = 0777; + auditData.dacData.mode = DAC_ALL_PERMISSION; ret = AddSecurityLabel(&auditData, (void *)&g_paramWorkSpace); PARAM_CHECK(ret == 0, return, "Failed to add default dac label"); // 读取cmdline的参数 - LoadParamFromCmdLine(); + struct CmdLineEntry cmdLineEntry[] = {{"hardware", 0}}; + LoadParamFromCmdLine(cmdLineEntry, sizeof(cmdLineEntry) / sizeof(cmdLineEntry[0])); } static void OnPidDelete(pid_t pid) { + UNUSED(pid); } -int StartParamService() +int StartParamService(void) { return ParamServiceStart(OnPidDelete); } -void StopParamService() +void StopParamService(void) { PARAM_LOGI("StopParamService."); CloseParamWorkSpace(&g_paramWorkSpace); CloseTriggerWorkSpace(); - // ParamTaskClose(g_paramWorkSpace.serverTask); g_paramWorkSpace.serverTask = NULL; ParamServiceStop(); } -ParamWorkSpace *GetParamWorkSpace() +ParamWorkSpace *GetParamWorkSpace(void) { return &g_paramWorkSpace; } diff --git a/services/param/trigger/trigger_checker.c b/services/param/trigger/trigger_checker.c index 393eb891a..90642eae2 100755 --- a/services/param/trigger/trigger_checker.c +++ b/services/param/trigger/trigger_checker.c @@ -19,6 +19,7 @@ #include "init_param.h" #include "trigger_manager.h" +#define MAX_CALC_PARAM 100 #define LABEL "Trigger" // 申请整块能存作为计算的节点 int CalculatorInit(LogicCalculator *calculator, int dataNumber, int dataUnit, int needCondition) @@ -26,7 +27,7 @@ int CalculatorInit(LogicCalculator *calculator, int dataNumber, int dataUnit, in PARAM_CHECK(calculator != NULL, return -1, "Invalid param"); int dataSize = dataUnit * dataNumber; if (needCondition) { - dataSize += 5 * SUPPORT_DATA_BUFFER_MAX; + dataSize += MAX_DATA_BUFFER_MAX; } calculator->data = (char *)malloc(dataSize); PARAM_CHECK(calculator->data != NULL, return -1, "Failed to malloc for calculator"); @@ -87,7 +88,7 @@ static int CalculatorPush(LogicCalculator *calculator, const void *data) PARAM_CHECK(calculator->endIndex < calculator->dataNumber, return -1, "More data for calculator support"); char *tmpData = (calculator->data + calculator->dataUnit * calculator->endIndex); int ret = memcpy_s(tmpData, calculator->dataUnit, data, calculator->dataUnit); - PARAM_CHECK(ret == 0, return -1, "Failed to copy logic data"); + PARAM_CHECK(ret == EOK, return -1, "Failed to copy logic data"); calculator->endIndex++; return 0; } @@ -101,7 +102,7 @@ static int CalculatorPop(LogicCalculator *calculator, void *data) } char *tmpData = calculator->data + calculator->dataUnit * (calculator->endIndex - 1); int ret = memcpy_s(data, calculator->dataUnit, tmpData, calculator->dataUnit); - PARAM_CHECK(ret == 0, return -1, "Failed to copy logic data"); + PARAM_CHECK(ret == EOK, return -1, "Failed to copy logic data"); calculator->endIndex--; return 0; } @@ -114,7 +115,7 @@ static int CalculatorLength(const LogicCalculator *calculator) static int PrefixAdd(char *prefix, uint32_t *prefixIndex, uint32_t prefixLen, char op) { - if ((*prefixIndex + 3) >= prefixLen) { + if ((*prefixIndex + 1 + 1 + 1) >= prefixLen) { return -1; } prefix[(*prefixIndex)++] = ' '; @@ -227,12 +228,11 @@ int ComputeCondition(LogicCalculator *calculator, const char *condition) int ret1 = CalculatorPop(calculator, (void*)&data1); PARAM_CHECK((ret == 0 && ret1 == 0), return -1, "Failed to pop data"); - ret = ComputeSubCondition(calculator, &data1, condition); data1.flags = 0; if (condition[currIndex] == '|' && ret == 1) { LOGIC_DATA_SET_FLAG(&data1, LOGIC_DATA_FLAGS_TRUE); - } else if (condition[currIndex] == '|' || ret == 1) { + } else if (condition[currIndex] == '&' || ret == 1) { if (ComputeSubCondition(calculator, &data2, condition) == 1) { LOGIC_DATA_SET_FLAG(&data1, LOGIC_DATA_FLAGS_TRUE); } @@ -272,24 +272,27 @@ int ConvertInfixToPrefix(const char *condition, char *prefix, uint32_t prefixLen uint32_t curr = 0; uint32_t prefixIndex = 0; LogicCalculator calculator; - CalculatorInit(&calculator, 100, 1, 0); + CalculatorInit(&calculator, MAX_CALC_PARAM, 1, 0); while (curr < strlen(condition)) { if (condition[curr] == ')') { CalculatorPopChar(&calculator, &e); while (e != '(') { ret = PrefixAdd(prefix, &prefixIndex, prefixLen, e); - PARAM_CHECK(ret == 0, CalculatorFree(&calculator); return -1, "Invalid prefix"); - ret = CalculatorPopChar(&calculator, &e); - PARAM_CHECK(ret == 0, CalculatorFree(&calculator); return -1, "Invalid calculator"); + PARAM_CHECK(ret == 0, + CalculatorFree(&calculator); return -1, "Invalid prefix"); + CalculatorPopChar(&calculator, &e); } } else if (condition[curr] == '|') { - PARAM_CHECK(condition[curr + 1] == '|', CalculatorFree(&calculator); return -1, "Invalid condition"); + PARAM_CHECK(condition[curr + 1] == '|', + CalculatorFree(&calculator); return -1, "Invalid condition"); ret = HandleOperationOr(&calculator, prefix, &prefixIndex, prefixLen); - PARAM_CHECK(ret == 0, CalculatorFree(&calculator); return -1, "Invalid prefix"); + PARAM_CHECK(ret == 0, + CalculatorFree(&calculator); return -1, "Invalid prefix"); curr++; } else if (condition[curr] == '&') { - PARAM_CHECK(condition[curr + 1] == '&', CalculatorFree(&calculator); return -1, "Invalid condition"); + PARAM_CHECK(condition[curr + 1] == '&', + CalculatorFree(&calculator); return -1, "Invalid condition"); prefix[prefixIndex++] = ' '; CalculatorPushChar(&calculator, condition[curr]); curr++; @@ -299,13 +302,15 @@ int ConvertInfixToPrefix(const char *condition, char *prefix, uint32_t prefixLen prefix[prefixIndex++] = condition[curr]; } curr++; - PARAM_CHECK(prefixIndex < prefixLen, CalculatorFree(&calculator); return -1, "Invalid prefixIndex"); + PARAM_CHECK(prefixIndex < prefixLen, + CalculatorFree(&calculator); return -1, "Invalid prefixIndex"); } while (CalculatorLength(&calculator) > 0) { CalculatorPopChar(&calculator, &e); ret = PrefixAdd(prefix, &prefixIndex, prefixLen, e); - PARAM_CHECK(ret == 0, CalculatorFree(&calculator); + PARAM_CHECK(ret == 0, + CalculatorFree(&calculator); return -1, "Invalid prefix %u %u", prefixIndex, prefixLen); } prefix[prefixIndex] = '\0'; diff --git a/services/param/trigger/trigger_manager.c b/services/param/trigger/trigger_manager.c index c3182de77..8b5d4ac44 100755 --- a/services/param/trigger/trigger_manager.c +++ b/services/param/trigger/trigger_manager.c @@ -47,7 +47,7 @@ int AddCommand(TriggerNode *trigger, uint32_t cmdKeyIndex, const char *content) if (content != NULL && strlen(content) != 0) { int ret = memcpy_s(node->content, size, content, strlen(content)); node->content[strlen(content)] = '\0'; - PARAM_CHECK(ret == 0, return 0, "Failed to copy command"); + PARAM_CHECK(ret == EOK, return 0, "Failed to copy command"); } // 插入队列 if (trigger->firstCmd == NULL) { @@ -82,13 +82,15 @@ TriggerNode *AddTrigger(TriggerHeader *triggerHead, const char *name, const char TriggerNode *node = (TriggerNode *)malloc(triggerNodeLen + conditionLen + extDataSize); PARAM_CHECK(node != NULL, return NULL, "Failed to alloc memory for trigger"); int ret = memcpy_s(node->name, triggerNodeLen - sizeof(TriggerNode), name, nameLen); - PARAM_CHECK(ret == 0, free(node); return NULL, "Failed to memcpy_s for trigger"); + PARAM_CHECK(ret == EOK, free(node); + return NULL, "Failed to memcpy_s for trigger"); node->name[nameLen] = '\0'; node->condition = NULL; if (conditionLen != 0) { char *cond = node->name + PARAM_ALIGN(nameLen + 1); - int ret = ConvertInfixToPrefix(condition, cond, conditionLen); - PARAM_CHECK(ret == 0, free(node); return NULL, "Failed to convert condition for trigger"); + ret = ConvertInfixToPrefix(condition, cond, conditionLen); + PARAM_CHECK(ret == 0, free(node); + return NULL, "Failed to convert condition for trigger"); node->condition = cond; } node->flags = 0; @@ -232,6 +234,8 @@ static int CheckWatcherTriggerMatch(TriggerWorkSpace *workSpace, LogicCalculator static int CheckParamTriggerMatch(TriggerWorkSpace *workSpace, LogicCalculator *calculator, TriggerNode *trigger, const char *content, uint32_t contentSize) { + UNUSED(content); + UNUSED(contentSize); const char *condition = GetTriggerCondition(workSpace, trigger); if (calculator->inputName != NULL) { // 存在input数据时,先过滤非input的 if (!CheckMatchSubCondition(condition, calculator->inputName, strlen(calculator->inputName))) { @@ -251,6 +255,7 @@ static int CheckOtherTriggerMatch(TriggerWorkSpace *workSpace, LogicCalculator * static int CheckParamWaitMatch(TriggerWorkSpace *workSpace, int type, LogicCalculator *calculator, const char *content, uint32_t contentSize) { + UNUSED(type); ParamWatcher *watcher = GetNextParamWatcher(workSpace, NULL); while (watcher != NULL) { TriggerNode *trigger = GetNextTrigger(&watcher->triggerHead, NULL); @@ -308,19 +313,23 @@ int CheckTrigger(TriggerWorkSpace *workSpace, int type, PARAM_CHECK(workSpace != NULL && content != NULL && triggerExecuter != NULL, return -1, "Failed arg for trigger"); PARAM_LOGD("CheckTrigger type: %d content: %s ", type, content); + int ret = 0; LogicCalculator calculator; CalculatorInit(&calculator, MAX_CONDITION_NUMBER, sizeof(LogicData), 1); calculator.triggerExecuter = triggerExecuter; if (type == TRIGGER_PARAM || type == TRIGGER_PARAM_WAIT) { - int ret = GetValueFromContent(content, contentSize, + ret = GetValueFromContent(content, contentSize, 0, calculator.inputName, SUPPORT_DATA_BUFFER_MAX); - PARAM_CHECK(ret == 0, CalculatorFree(&calculator); return -1, "Failed parse content name"); + PARAM_CHECK(ret == 0, CalculatorFree(&calculator); + return -1, "Failed parse content name"); ret = GetValueFromContent(content, contentSize, strlen(calculator.inputName) + 1, calculator.inputContent, SUPPORT_DATA_BUFFER_MAX); - PARAM_CHECK(ret == 0, CalculatorFree(&calculator); return -1, "Failed parse content value"); + PARAM_CHECK(ret == 0, CalculatorFree(&calculator); + return -1, "Failed parse content value"); } else if (type == TRIGGER_UNKNOW) { - int ret = memcpy_s(calculator.triggerContent, sizeof(calculator.triggerContent), content, contentSize); - PARAM_CHECK(ret == 0, CalculatorFree(&calculator); return -1, "Failed to memcpy"); + ret = memcpy_s(calculator.triggerContent, sizeof(calculator.triggerContent), content, contentSize); + PARAM_CHECK(ret == EOK, CalculatorFree(&calculator); + return -1, "Failed to memcpy"); calculator.inputName = NULL; calculator.inputContent = NULL; } @@ -380,7 +389,8 @@ TriggerNode *AddWatcherTrigger(ParamWatcher *watcher, cmd = CMD_INDEX_FOR_PARA_WAIT; } int ret = AddCommand(trigger, cmd, name); - PARAM_CHECK(ret == 0, FreeTrigger(trigger); return NULL, "Failed to add command for %s", name); + PARAM_CHECK(ret == 0, FreeTrigger(trigger); + return NULL, "Failed to add command for %s", name); TriggerExtData *localData = TRIGGER_GET_EXT_DATA(trigger, TriggerExtData); PARAM_CHECK(localData != NULL, return NULL, "Failed to get trigger ext data"); localData->excuteCmd = extData->excuteCmd; diff --git a/services/param/trigger/trigger_processor.c b/services/param/trigger/trigger_processor.c index 8541f507f..a8e1a2bfc 100755 --- a/services/param/trigger/trigger_processor.c +++ b/services/param/trigger/trigger_processor.c @@ -74,7 +74,8 @@ static int ExecuteTrigger(TriggerWorkSpace *workSpace, TriggerNode *trigger) static int DoTiggerCheckResult(TriggerNode *trigger, const char *content, uint32_t size) { - // 已经在队列中了,则不执行 TODO + UNUSED(content); + UNUSED(size); if (TRIGGER_IN_QUEUE(trigger)) { PARAM_LOGI("DoTiggerExecute trigger %s has been waiting execute", trigger->name); return 0; @@ -125,6 +126,9 @@ static void ExecuteQueueWork(uint32_t maxCount) static void ProcessParamEvent(uint64_t eventId, const char *content, uint32_t size) { + UNUSED(eventId); + UNUSED(content); + UNUSED(size); ExecuteQueueWork(MAX_TRIGGER_COUNT_RUN_ONCE); } @@ -204,7 +208,8 @@ void PostParamTrigger(int type, const char *name, const char *value) char *buffer = (char *)malloc(bufferSize); PARAM_CHECK(buffer != NULL, return, "Failed to alloc memory for param %s", name); int ret = sprintf_s(buffer, bufferSize - 1, "%s=%s", name, value); - PARAM_CHECK(ret > 0, free(buffer); return, "Failed to copy param"); + PARAM_CHECK(ret > EOK, free(buffer); + return, "Failed to copy param"); SendTriggerEvent(type, buffer, strlen(buffer)); free(buffer); } @@ -295,7 +300,7 @@ int ParseTriggerConfig(const cJSON *fileRoot) return 0; } -int InitTriggerWorkSpace() +int InitTriggerWorkSpace(void) { if (g_triggerWorkSpace.eventHandle != NULL) { return 0; @@ -313,7 +318,7 @@ int InitTriggerWorkSpace() return -1, "Failed to alloc memory for executeQueue"); int ret = memset_s(g_triggerWorkSpace.executeQueue.executeQueue, TRIGGER_EXECUTE_QUEUE * sizeof(TriggerNode *), 0, TRIGGER_EXECUTE_QUEUE * sizeof(TriggerNode *)); - PARAM_CHECK(ret == 0, return -1, "Failed to memset for executeQueue"); + PARAM_CHECK(ret == EOK, return -1, "Failed to memset for executeQueue"); // normal trigger for (size_t i = 0; i < sizeof(g_triggerWorkSpace.triggerHead) / sizeof(g_triggerWorkSpace.triggerHead[0]); i++) { @@ -325,7 +330,7 @@ int InitTriggerWorkSpace() return 0; } -void CloseTriggerWorkSpace() +void CloseTriggerWorkSpace(void) { // 释放trigger for (size_t i = 0; i < sizeof(g_triggerWorkSpace.triggerHead) / sizeof(g_triggerWorkSpace.triggerHead[0]); i++) { @@ -353,7 +358,7 @@ int CheckAndMarkTrigger(int type, const char *name) return 0; } -TriggerWorkSpace *GetTriggerWorkSpace() +TriggerWorkSpace *GetTriggerWorkSpace(void) { return &g_triggerWorkSpace; } diff --git a/services/param/watcher/agent/watcher.cpp b/services/param/watcher/agent/watcher.cpp index 95240e1b8..e1f099f02 100755 --- a/services/param/watcher/agent/watcher.cpp +++ b/services/param/watcher/agent/watcher.cpp @@ -24,6 +24,8 @@ namespace OHOS { namespace init_param { void Watcher::OnParamerterChange(const std::string &name, const std::string &value) { + UNUSED(name); + UNUSED(value); } } // namespace init_param } // namespace OHOS diff --git a/services/param/watcher/agent/watcher_manager_kits.h b/services/param/watcher/agent/watcher_manager_kits.h index fe7d59d0b..acca6cd79 100755 --- a/services/param/watcher/agent/watcher_manager_kits.h +++ b/services/param/watcher/agent/watcher_manager_kits.h @@ -28,7 +28,6 @@ namespace OHOS { namespace init_param { - class WatcherManagerKits final : public DelayedRefSingleton { DECLARE_DELAYED_REF_SINGLETON(WatcherManagerKits); public: diff --git a/services/param/watcher/include/watcher_utils.h b/services/param/watcher/include/watcher_utils.h index dd294d213..1026e5c47 100755 --- a/services/param/watcher/include/watcher_utils.h +++ b/services/param/watcher/include/watcher_utils.h @@ -25,6 +25,7 @@ namespace OHOS { namespace init_param { +#define UNUSED(x) (void)(x) #ifndef LABEL #define LABEL "Watcher" diff --git a/services/param/watcher/proxy/watcher_manager.cpp b/services/param/watcher/proxy/watcher_manager.cpp index b386201a7..93ab01332 100755 --- a/services/param/watcher/proxy/watcher_manager.cpp +++ b/services/param/watcher/proxy/watcher_manager.cpp @@ -28,8 +28,9 @@ namespace OHOS { namespace init_param { REGISTER_SYSTEM_ABILITY_BY_ID(WatcherManager, PARAM_WATCHER_DISTRIBUTED_SERVICE_ID, true) -const int32_t INVALID_SOCKET = -1; -const int32_t RECV_BUFFER_MAX = 5 * 1024; +const static int32_t INVALID_SOCKET = -1; +const static int32_t RECV_BUFFER_MAX = 5 * 1024; +const static int32_t SLEEP_TIME = 2000; uint32_t WatcherManager::AddWatcher(const std::string &keyPrefix, const sptr &watcher) { WATCHER_CHECK(watcher != nullptr, return 0, "Invalid remove watcher for %s", keyPrefix.c_str()); @@ -186,7 +187,7 @@ static int FilterParam(const char *name, const std::string &keyPrefix) void WatcherManager::SendLocalChange(const std::string &keyPrefix, ParamWatcherPtr watcher) { - struct Context{ + struct Context { char *buffer; ParamWatcherPtr watcher; std::string keyPrefix; @@ -254,14 +255,13 @@ int WatcherManager::GetServerFd(bool retry) do { serverFd_ = socket(AF_UNIX, SOCK_STREAM, 0); int ret = ConntectServer(serverFd_, PIPE_NAME); - if (ret == 0) { - setsockopt(serverFd_, SOL_SOCKET, SO_RCVTIMEO, (char *)&time, sizeof(struct timeval)); - break; - } if (ret != 0) { close(serverFd_); serverFd_ = INVALID_SOCKET; - usleep(2000); + usleep(SLEEP_TIME); + } else { + (void)setsockopt(serverFd_, SOL_SOCKET, SO_RCVTIMEO, (char *)&time, sizeof(struct timeval)); + break; } } while (1); return serverFd_; @@ -271,7 +271,7 @@ void WatcherManager::OnStart() { PARAM_LOGI("WatcherManager OnStart"); bool res = Publish(this); - if (res == false) { + if (!res) { PARAM_LOGI("WatcherManager OnStart failed"); } return; @@ -284,6 +284,7 @@ void WatcherManager::OnStop() { std::lock_guard lock(mutex_); close(serverFd_); + serverFd_ = INVALID_SOCKET; } if (pRecvThread_ != nullptr) { pRecvThread_->join(); diff --git a/services/param/watcher/proxy/watcher_manager.h b/services/param/watcher/proxy/watcher_manager.h index 1d76961d7..5845528ec 100755 --- a/services/param/watcher/proxy/watcher_manager.h +++ b/services/param/watcher/proxy/watcher_manager.h @@ -36,7 +36,8 @@ public: DISALLOW_COPY_AND_MOVE(WatcherManager); explicit WatcherManager(int32_t systemAbilityId, bool runOnCreate = true) : SystemAbility(systemAbilityId, runOnCreate) {} - ~WatcherManager() override { + ~WatcherManager() override + { watcherGroups_.clear(); groupMap_.clear(); }; @@ -45,7 +46,10 @@ public: public: ParamWatcher(uint32_t watcherId, const sptr &watcher) : watcherId_(watcherId), watcher_(watcher) {} ~ParamWatcher() = default; - uint32_t GetWatcherId() { return watcherId_; } + uint32_t GetWatcherId() + { + return watcherId_; + } void ProcessParameterChange(const std::string &name, const std::string &value) { watcher_->OnParamerterChange(name, value); @@ -65,9 +69,17 @@ public: void ProcessParameterChange(const std::string &name, const std::string &value); ParamWatcherPtr GetWatcher(uint32_t watcherId); - const std::string GetKeyPrefix() { return keyPrefix_; } - bool Emptry() { return watchers_.size() == 0; } - uint32_t GetGroupId() { return groupId_; } + const std::string GetKeyPrefix() + { + return keyPrefix_; + } + bool Emptry() { + return watchers_.size() == 0; + } + uint32_t GetGroupId() + { + return groupId_; + } private: uint32_t groupId_; std::string keyPrefix_ { }; diff --git a/services/param/watcher/proxy/watcher_manager_stub.cpp b/services/param/watcher/proxy/watcher_manager_stub.cpp index 209f6237b..6c1ecfe1e 100755 --- a/services/param/watcher/proxy/watcher_manager_stub.cpp +++ b/services/param/watcher/proxy/watcher_manager_stub.cpp @@ -26,7 +26,8 @@ int32_t WatcherManagerStub::OnRemoteRequest(uint32_t code, std::string key = data.ReadString(); auto remote = data.ReadRemoteObject(); // 0 is invalid watcherId - WATCHER_CHECK(remote != nullptr, reply.WriteUint32(0); return 0, "Failed to read remote watcher"); + WATCHER_CHECK(remote != nullptr, reply.WriteUint32(0); + return 0, "Failed to read remote watcher"); uint32_t watcherId = AddWatcher(key, iface_cast(remote)); reply.WriteUint32(watcherId); break; -- Gitee From fe82c25f257ee105f9647c0ea978eb65e4030593 Mon Sep 17 00:00:00 2001 From: sun_fan Date: Mon, 13 Sep 2021 18:00:52 +0800 Subject: [PATCH 12/14] init: fix codedex ...... Signed-off-by: sun_fan --- .../innerkits/dynamic_service/dynamic_service.c | 1 + services/include/list.h | 2 +- services/src/init_cmds.c | 14 +++++++++----- services/src/init_reboot.c | 13 +++++++------ services/src/init_service_manager.c | 4 ++-- services/src/list.c | 1 + ueventd/ueventd_read_cfg.c | 17 +++++++++-------- 7 files changed, 30 insertions(+), 22 deletions(-) diff --git a/interfaces/innerkits/dynamic_service/dynamic_service.c b/interfaces/innerkits/dynamic_service/dynamic_service.c index c048bcf94..db4a8c020 100755 --- a/interfaces/innerkits/dynamic_service/dynamic_service.c +++ b/interfaces/innerkits/dynamic_service/dynamic_service.c @@ -14,6 +14,7 @@ */ #include "dynamic_service.h" + #include #include "hilog/log.h" #include "parameter.h" diff --git a/services/include/list.h b/services/include/list.h index 74a926c93..9fa0c1065 100755 --- a/services/include/list.h +++ b/services/include/list.h @@ -28,7 +28,7 @@ typedef struct ListNode { } ListNode; #define ListEmpty(node) ((node).next == &(node) && (node).prev == &(node)) -#define ListEntry(ptr, type, member) (type *)((char *)(ptr) - offsetof(type, member)) +#define ListEntry(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member))) #define ForEachListEntry(list, node) \ (for (node = (list)->next; node != (list); node = node->next)) diff --git a/services/src/init_cmds.c b/services/src/init_cmds.c index b9f01cc83..8ef21a687 100755 --- a/services/src/init_cmds.c +++ b/services/src/init_cmds.c @@ -181,9 +181,11 @@ struct CmdArgs* GetCmd(const char *cmdContent, const char *delim, int argsCount) *token = '\0'; // replace it with '\0'; allocSize = (size_t)((token - p) + MAX_PARAM_VALUE_LEN + 1); ctx->argv[index] = calloc(sizeof(char), allocSize); - INIT_CHECK(ctx->argv[index] != NULL, FreeCmd(ctx); return NULL); + INIT_CHECK(ctx->argv[index] != NULL, FreeCmd(ctx); + return NULL); INIT_CHECK(GetParamValue(p, ctx->argv[index], allocSize) == 0, - FreeCmd(ctx); return NULL); + FreeCmd(ctx); + return NULL); p = token + 1; // skip '\0' // Skip lead whitespaces while (isspace(*p)) { @@ -250,7 +252,7 @@ static void DoSetDomainname(const char *cmdContent, int maxArg) { struct CmdArgs *ctx = GetCmd(cmdContent, " ", maxArg); - if ((ctx == NULL) || (ctx->argv == NULL) || (ctx->argc != maxArg)) { + if ((ctx == NULL) || (ctx->argv == NULL) || (ctx->argc != maxArg)) { INIT_LOGE("Command setdomainname with invalid arugment"); FreeCmd(ctx); return; @@ -272,7 +274,7 @@ static void DoSetHostname(const char *cmdContent, int maxArg) return; } WriteCommon("/proc/sys/kernel/hostname", ctx->argv[0], O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, - S_IRUSR | S_IWUSR); + S_IRUSR | S_IWUSR); FreeCmd(ctx); return; } @@ -515,7 +517,6 @@ static void DoMkDir(const char* cmdContent, int maxArg) if (ctx->argv[index + 1] != NULL) { uid_t user = DecodeUid(ctx->argv[index]); gid_t group = DecodeUid(ctx->argv[index + 1]); - if (user == (uid_t) -1 || group == (uid_t)-1) { INIT_LOGE("Change path owner with invalid user/group"); rc = -1; @@ -1167,6 +1168,9 @@ static void DoMakeDevice(const char *cmdContent, int maxArg) } unsigned int major = strtoul(ctx->argv[0], NULL, DECIMAL_BASE); unsigned int minor = strtoul(ctx->argv[1], NULL, DECIMAL_BASE); + if (major == 0 || minor == 0) { + return; + } dev_t deviceId = makedev(major, minor); if (deviceId < 0) { INIT_LOGE("Make device with major %u, minor %u failed :%d ", major, minor, errno); diff --git a/services/src/init_reboot.c b/services/src/init_reboot.c index 4c709001f..5c9bc9a29 100755 --- a/services/src/init_reboot.c +++ b/services/src/init_reboot.c @@ -19,14 +19,15 @@ #include #include #include -#include #include #include #include -#include "securec.h" +#include +#include "init_log.h" #include "init_service.h" #include "init_service_manager.h" -#include "init_log.h" +#include "init_utils.h" +#include "securec.h" #define MAX_VALUE_LENGTH 500 #define MAX_COMMAND_SIZE 20 @@ -157,7 +158,7 @@ static int CheckAndRebootToUpdater(const char *valueData, const char *cmd, const void DoReboot(const char *value) { static const char *g_cmdParams[] = { - "shutdown", "updater", "updater:", "flashing", "flashing:", "NoArgument", "bootloader" + "shutdown", "updater", "updater:", "flashing", "flashing:", "NoArgument", "bootloader" }; if (value == NULL || strlen(value) > MAX_VALUE_LENGTH) { INIT_LOGE("DoReboot value = NULL"); @@ -174,12 +175,12 @@ void DoReboot(const char *value) } if (valueData != NULL) { size_t i = 0; - for (; i < sizeof(g_cmdParams) / sizeof(g_cmdParams[0]); i++) { + for (; i < ARRAY_LENGTH(g_cmdParams); i++) { if (strncmp(valueData, g_cmdParams[i], strlen(g_cmdParams[i])) == 0) { break; } } - if (i >= sizeof(g_cmdParams) / sizeof(g_cmdParams[0])) { + if (i >= ARRAY_LENGTH(g_cmdParams)) { INIT_LOGE("DoReboot value = %s, parameters error.", value); return; } diff --git a/services/src/init_service_manager.c b/services/src/init_service_manager.c index 84f0b2fd2..06fca3db6 100755 --- a/services/src/init_service_manager.c +++ b/services/src/init_service_manager.c @@ -306,7 +306,7 @@ static int GetGidArray(const cJSON *curArrItem, Service *curServ) // gid return (((i == gIDCnt) ? SERVICE_SUCCESS : SERVICE_FAILURE)); } -static int GetServicePathAndArgs(const cJSON* curArrItem, Service* curServ) +static int GetServicePathAndArgs(const cJSON *curArrItem, Service *curServ) { cJSON* pathItem = cJSON_GetObjectItem(curArrItem, "path"); if (!cJSON_IsArray(pathItem)) { @@ -320,7 +320,7 @@ static int GetServicePathAndArgs(const cJSON* curArrItem, Service* curServ) return SERVICE_FAILURE; } - curServ->pathArgs = (char**)malloc((arrSize + 1) * sizeof(char*)); + curServ->pathArgs = (char **)malloc((arrSize + 1) * sizeof(char *)); if (curServ->pathArgs == NULL) { INIT_LOGE("Current path is null."); return SERVICE_FAILURE; diff --git a/services/src/list.c b/services/src/list.c index 9a7cbe2e2..805d095c8 100755 --- a/services/src/list.c +++ b/services/src/list.c @@ -14,6 +14,7 @@ */ #include "list.h" + #include void ListInit(struct ListNode *node) diff --git a/ueventd/ueventd_read_cfg.c b/ueventd/ueventd_read_cfg.c index a551cefdb..3585924b9 100755 --- a/ueventd/ueventd_read_cfg.c +++ b/ueventd/ueventd_read_cfg.c @@ -89,22 +89,23 @@ static char **SplitUeventConfig(char *buffer, const char *del, int *returnCount, int count = 0; int average = 2; char *p = strtok_r(buffer, del, &rest); - if (maxItemCount < 0) { + int maxItemCountTmp = maxItemCount; + if (maxItemCountTmp < 0) { return NULL; } - if (maxItemCount > DEFAULTITEMCOUNT) { - maxItemCount = DEFAULTITEMCOUNT; + if (maxItemCountTmp > DEFAULTITEMCOUNT) { + maxItemCountTmp = DEFAULTITEMCOUNT; } - char **items = (char **)malloc(sizeof(char*) * maxItemCount); + char **items = (char **)malloc(sizeof(char*) * maxItemCountTmp); if (items == NULL) { INIT_LOGE("No enough memory to store uevent config"); return NULL; } while (p != NULL) { - if (count > (maxItemCount - 1)) { - maxItemCount += (maxItemCount / average) + 1; + if (count > (maxItemCountTmp - 1)) { + maxItemCountTmp += (maxItemCountTmp / average) + 1; INIT_LOGD("Too many items,expand size"); - char **expand = (char **)(realloc(items, sizeof(char *) * maxItemCount)); + char **expand = (char **)(realloc(items, sizeof(char *) * maxItemCountTmp)); if (expand == NULL) { INIT_LOGE("Failed to expand memory for uevent config parser"); FreeConfigItems(items, count); @@ -404,7 +405,7 @@ void ChangeSysAttributePermissions(const char *sysPath) ForEachListEntry(&g_sysDevices, node) { config = ListEntry(node, struct SysUdevConf, list); if (STRINGEQUAL(config->sysPath, sysPath)) { - break; + break; } } } -- Gitee From b29eacb3704abe951b93eabdf2cd5e5ab6caf976 Mon Sep 17 00:00:00 2001 From: sun_fan Date: Mon, 13 Sep 2021 19:08:34 +0800 Subject: [PATCH 13/14] init : fix codedex Signed-off-by: sun_fan --- services/include/list.h | 3 +- ueventd/ueventd_device_handler.c | 70 ++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/services/include/list.h b/services/include/list.h index 9fa0c1065..ebb1dc954 100755 --- a/services/include/list.h +++ b/services/include/list.h @@ -29,8 +29,7 @@ typedef struct ListNode { #define ListEmpty(node) ((node).next == &(node) && (node).prev == &(node)) #define ListEntry(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member))) -#define ForEachListEntry(list, node) \ - (for (node = (list)->next; node != (list); node = node->next)) +#define ForEachListEntry(list, node) for (node = (list)->next; node != (list); node = node->next) void ListInit(struct ListNode *list); void ListAddTail(struct ListNode *list, struct ListNode *item); diff --git a/ueventd/ueventd_device_handler.c b/ueventd/ueventd_device_handler.c index c0a8ea378..1511ed988 100755 --- a/ueventd/ueventd_device_handler.c +++ b/ueventd/ueventd_device_handler.c @@ -148,6 +148,41 @@ static int RemoveDeviceNode(const char *deviceNode, char **symLinks) return unlink(deviceNode); } +static char *FindPlatformDeviceName(char *path) +{ + if (INVALIDSTRING(path)) { + return NULL; + } + + if (STARTSWITH(path, "/sys/devices/platform/")) { + path += strlen("/sys/devices/platform/"); + return path; + } + return NULL; +} + +static void BuildDeviceSymbolLinks(char **links, int linkNum, const char *parent, const char *partitionName) +{ + if (linkNum > BLOCKDEVICE_LINKS - 1) { + INIT_LOGW("Too many links, ignore"); + return; + } + + // If a block device without partition name. + // For now, we will not create symbol link for it. + if (!INVALIDSTRING(partitionName)) { + links[linkNum] = calloc(sizeof(char), DEVICE_FILE_SIZE); + if (links[linkNum] == NULL) { + INIT_LOGE("Failed to allocate memory for link, err = %d", errno); + return; + } + if (snprintf_s(links[linkNum], DEVICE_FILE_SIZE, DEVICE_FILE_SIZE - 1, + "/dev/block/platform/%s/by-name/%s", parent, partitionName) == -1) { + INIT_LOGE("Failed to build link"); + } + } +} + static char **GetBlockDeviceSymbolLinks(const struct Uevent *uevent) { if (uevent == NULL || uevent->subsystem == NULL || STRINGEQUAL(uevent->subsystem, "block") == 0) { @@ -172,6 +207,7 @@ static char **GetBlockDeviceSymbolLinks(const struct Uevent *uevent) int linkNum = 0; if (links == NULL) { INIT_LOGE("Failed to allocate memory for links, err = %d", errno); + return NULL; } // Reverse walk through sysPath, and check subystem file under each directory. @@ -184,39 +220,19 @@ static char **GetBlockDeviceSymbolLinks(const struct Uevent *uevent) } char *bus = realpath(subsystem, NULL); - if (bus == NULL) { - goto loop; - } - - if (STRINGEQUAL(bus, "/sys/bus/platform")) { - INIT_LOGD("Find a platform device: %s", parent); - if (STARTSWITH(parent, "/sys/devices/platform/")) { - parent += strlen("/sys/devices/platform/"); - if (linkNum > BLOCKDEVICE_LINKS - 1) { - INIT_LOGW("Too much links, ignore"); - break; - } - links[linkNum] = calloc(sizeof(char), DEVICE_FILE_SIZE); - if (links[linkNum] == NULL) { - INIT_LOGE("Failed to allocate memory for link, err = %d", errno); - break; - } - // If a block device without partition name. - // For now, we will not create symbol link for it. - if (!INVALIDSTRING(uevent->partitionName)) { - if (snprintf_s(links[linkNum], DEVICE_FILE_SIZE, DEVICE_FILE_SIZE - 1, - "/dev/block/platform/%s/by-name/%s", parent, uevent->partitionName) == -1) { - INIT_LOGE("Failed to build link"); - break; - } + if (bus != NULL) { + if (STRINGEQUAL(bus, "/sys/bus/platform")) { + INIT_LOGD("Find a platform device: %s", parent); + parent = FindPlatformDeviceName(parent); + if (parent != NULL) { + BuildDeviceSymbolLinks(links, linkNum, parent, uevent->partitionName); } linkNum++; } } -loop: parent = dirname(parent); - continue; } + links[linkNum] = NULL; return links; } -- Gitee From 020e94caeeb404f17cb963fac06216a56d8b9adc Mon Sep 17 00:00:00 2001 From: "an_xinwei@hoperun.com" Date: Mon, 13 Sep 2021 19:13:07 +0800 Subject: [PATCH 14/14] fix code style Signed-off-by: an_xinwei@hoperun.com --- services/include/param/init_param.h | 8 ++++---- services/param/adapter/param_dac.c | 4 ++-- services/param/adapter/param_libuvadp.h | 1 - services/param/adapter/param_persistadp.c | 2 +- services/param/adapter/param_selinux.c | 1 + services/param/client/param_request.c | 2 +- services/param/include/param_message.h | 1 - services/param/include/param_service.h | 4 ++++ services/param/include/param_trie.h | 13 +++++++------ services/param/include/trigger_manager.h | 11 ++++++----- services/param/manager/param_utils.c | 2 +- services/param/service/param_persist.c | 5 +++-- services/param/service/param_service.c | 6 +----- services/param/trigger/trigger_checker.c | 7 +++---- services/param/trigger/trigger_manager.c | 1 + services/param/trigger/trigger_processor.c | 6 +++--- services/param/watcher/proxy/watcher_manager.cpp | 2 +- 17 files changed, 39 insertions(+), 37 deletions(-) diff --git a/services/include/param/init_param.h b/services/include/param/init_param.h index 1526b41c5..802198f35 100644 --- a/services/include/param/init_param.h +++ b/services/include/param/init_param.h @@ -30,21 +30,21 @@ extern "C" { * 初始化参数服务 * */ -void InitParamService(); +void InitParamService(void); /** * Init 接口 * 启动参数服务,在main启动的最后调用,阻赛当前线程 * */ -int StartParamService(); +int StartParamService(void); /** * Init 接口 * 停止参数服务 * */ -void StopParamService(); +void StopParamService(void); /** * Init 接口 @@ -58,7 +58,7 @@ int LoadDefaultParams(const char *fileName, int mode); * 加载默认参数。 * */ -int LoadPersistParams(); +int LoadPersistParams(void); /** * Init 接口 diff --git a/services/param/adapter/param_dac.c b/services/param/adapter/param_dac.c index be13f99b4..4560c6c7e 100755 --- a/services/param/adapter/param_dac.c +++ b/services/param/adapter/param_dac.c @@ -12,13 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + #include #include #include #include -#include "init_utils.h" #include "param_security.h" #include "param_utils.h" @@ -170,6 +169,7 @@ static int GetParamSecurityLabel(SecurityLabelFunc label, const char *path, void static int CheckFilePermission(const ParamSecurityLabel *localLabel, const char *fileName, int flags) { + UNUSED(flags); PARAM_CHECK(localLabel != NULL && fileName != NULL, return -1, "Invalid param"); return 0; } diff --git a/services/param/adapter/param_libuvadp.h b/services/param/adapter/param_libuvadp.h index 81645b6ad..fb7ff0bcd 100755 --- a/services/param/adapter/param_libuvadp.h +++ b/services/param/adapter/param_libuvadp.h @@ -19,7 +19,6 @@ #include #include -#include "init_param.h" #include "param_message.h" #include "param_utils.h" #include "uv.h" diff --git a/services/param/adapter/param_persistadp.c b/services/param/adapter/param_persistadp.c index 60d771f7a..63673e4c1 100755 --- a/services/param/adapter/param_persistadp.c +++ b/services/param/adapter/param_persistadp.c @@ -13,12 +13,12 @@ * limitations under the License. */ -#include "param_persist.h" #include #include #include #include +#include "param_persist.h" #include "param_utils.h" #define LABEL "PERSIST_ADP" diff --git a/services/param/adapter/param_selinux.c b/services/param/adapter/param_selinux.c index 4bdfd5337..5865151c1 100755 --- a/services/param/adapter/param_selinux.c +++ b/services/param/adapter/param_selinux.c @@ -113,6 +113,7 @@ static int GetParamSecurityLabel(SecurityLabelFunc label, const char *path, void static int CheckFilePermission(const ParamSecurityLabel *localLabel, const char *fileName, int flags) { + UNUSED(flags); PARAM_CHECK(localLabel != NULL && fileName != NULL, return -1, "Invalid param"); return 0; } diff --git a/services/param/client/param_request.c b/services/param/client/param_request.c index f2c5bb6b4..b8d83f39e 100755 --- a/services/param/client/param_request.c +++ b/services/param/client/param_request.c @@ -35,7 +35,7 @@ static ClientWorkSpace g_clientSpace = { {}, -1, {} }; __attribute__((constructor)) static void ClientInit(void); __attribute__((destructor)) static void ClientDeinit(void); -static int InitParamClient() +static int InitParamClient(void) { if (PARAM_TEST_FLAG(g_clientSpace.paramSpace.flags, WORKSPACE_FLAGS_INIT)) { return 0; diff --git a/services/param/include/param_message.h b/services/param/include/param_message.h index 1c69f1cf3..f93a52505 100755 --- a/services/param/include/param_message.h +++ b/services/param/include/param_message.h @@ -20,7 +20,6 @@ #include #include -#include "list.h" #include "param.h" #include "param_utils.h" #include "securec.h" diff --git a/services/param/include/param_service.h b/services/param/include/param_service.h index 94ea4d3fc..4b048b924 100755 --- a/services/param/include/param_service.h +++ b/services/param/include/param_service.h @@ -28,6 +28,10 @@ extern "C" { #endif #define PARAM_WATCH_FLAGS_WAIT 0x01 +struct CmdLineEntry { + char *key; + int set; +}; int WriteParam(WorkSpace *workSpace, const char *name, const char *value, uint32_t *dataIndex, int onlyAdd); diff --git a/services/param/include/param_trie.h b/services/param/include/param_trie.h index c03a9df71..53bb6a54a 100755 --- a/services/param/include/param_trie.h +++ b/services/param/include/param_trie.h @@ -25,7 +25,6 @@ #include "securec.h" #include "sys_param.h" - #ifndef __NR_futex #define PARAM_NR_FUTEX 202 /* syscall number */ #else @@ -38,12 +37,14 @@ #define FUTEX_WAIT 0 #define FUTEX_WAKE 1 -#define __futex__(ftx, op, value, timeout, bitset) \ - struct timespec d_timeout = {0, 1000 * 1000 * (timeout)}; \ - syscall(PARAM_NR_FUTEX, ftx, op, value, &d_timeout, NULL, bitset) +#define PARAM_FUTEX(ftx, op, value, timeout, bitset) \ + do { \ + struct timespec d_timeout = { 0, 1000 * 1000 * (timeout) }; \ + syscall(PARAM_NR_FUTEX, ftx, op, value, &d_timeout, NULL, bitset); \ + } while (0) -#define futex_wake(ftx, count) __futex__(ftx, FUTEX_WAKE, count, 0, 0) -#define futex_wait(ftx, value) __futex__(ftx, FUTEX_WAIT, value, 100, 0) +#define futex_wake(ftx, count) PARAM_FUTEX(ftx, FUTEX_WAKE, count, 0, 0) +#define futex_wait(ftx, value) PARAM_FUTEX(ftx, FUTEX_WAIT, value, 100, 0) #endif #ifdef __cplusplus diff --git a/services/param/include/trigger_manager.h b/services/param/include/trigger_manager.h index 24225c37d..e6795d057 100755 --- a/services/param/include/trigger_manager.h +++ b/services/param/include/trigger_manager.h @@ -20,6 +20,7 @@ #include "cJSON.h" #include "init_log.h" +#include "list.h" #include "param_message.h" #include "param_utils.h" #include "securec.h" @@ -73,9 +74,9 @@ typedef struct { #define PARAM_TRIGGER_HEAD_INIT(head) \ do { \ - ListInit(&head.triggerList); \ - head.triggerCount = 0; \ - head.cmdNodeCount = 0; \ + ListInit(&(head).triggerList); \ + (head).triggerCount = 0; \ + (head).cmdNodeCount = 0; \ } while (0) // Command对象列表,主要存储每个triger需要执行那些Command操作。 @@ -128,8 +129,8 @@ typedef struct TriggerWorkSpace { ListNode waitList; } TriggerWorkSpace; -int InitTriggerWorkSpace(); -void CloseTriggerWorkSpace(); +int InitTriggerWorkSpace(void); +void CloseTriggerWorkSpace(void); typedef int (*TRIGGER_MATCH)(TriggerWorkSpace *workSpace, LogicCalculator *calculator, TriggerNode *trigger, const char *content, uint32_t contentSize); diff --git a/services/param/manager/param_utils.c b/services/param/manager/param_utils.c index 4038bd9a7..50350d2bf 100755 --- a/services/param/manager/param_utils.c +++ b/services/param/manager/param_utils.c @@ -47,7 +47,7 @@ int ReadFileInDir(const char *dirPath, const char *includeExt, PARAM_CHECK(pDir != NULL, return -1, "Read dir :%s failed.%d", dirPath, errno); char *fileName = malloc(PARAM_BUFFER_SIZE); PARAM_CHECK(fileName != NULL, closedir(pDir); - return -1, "Failed to malloc for %s", dirPath); + return -1, "Failed to malloc for %s", dirPath); struct dirent *dp; while ((dp = readdir(pDir)) != NULL) { diff --git a/services/param/service/param_persist.c b/services/param/service/param_persist.c index 37aa4b326..09df4be2a 100755 --- a/services/param/service/param_persist.c +++ b/services/param/service/param_persist.c @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include "param_persist.h" #include #include @@ -25,7 +26,7 @@ #define LABEL "Manager" -static ParamPersistWorkSpace g_persistWorkSpace = { 0, NULL, 0, {NULL, NULL, NULL, NULL, NULL} }; +static ParamPersistWorkSpace g_persistWorkSpace = { 0, NULL, 0, { NULL, NULL, NULL, NULL, NULL } }; static int AddPersistParam(const char *name, const char *value, void *context) { @@ -171,7 +172,7 @@ int WritePersistParam(ParamWorkSpace *workSpace, const char *name, const char *v PARAM_SET_FLAG(g_persistWorkSpace.flags, WORKSPACE_FLAGS_UPDATE); if (g_persistWorkSpace.saveTimer == NULL) { ParamTimerCreate(&g_persistWorkSpace.saveTimer, TimerCallbackForSave, &workSpace->paramSpace); - ParamTimerStart(g_persistWorkSpace.saveTimer, PARAM_MUST_SAVE_PARAM_DIFF * 1000, 1000); + ParamTimerStart(g_persistWorkSpace.saveTimer, PARAM_MUST_SAVE_PARAM_DIFF * MS_UNIT, MS_UNIT); } return 0; } diff --git a/services/param/service/param_service.c b/services/param/service/param_service.c index edbecdcc9..3c6e30b29 100755 --- a/services/param/service/param_service.c +++ b/services/param/service/param_service.c @@ -26,6 +26,7 @@ #include #include "init_param.h" +#include "init_utils.h" #include "param_message.h" #include "param_manager.h" #include "param_request.h" @@ -519,11 +520,6 @@ static int CopyBootParam(char *buffer, const char *key, size_t keyLen) return 0; } -struct CmdLineEntry { - char * key; - int set; -}; - static int FindKey(const char *key, struct CmdLineEntry *cmdLineEntry, int length) { PARAM_CHECK(key != NULL && cmdLineEntry != NULL && length > 0, return -1, "Input param error."); diff --git a/services/param/trigger/trigger_checker.c b/services/param/trigger/trigger_checker.c index 90642eae2..8040f4ce9 100755 --- a/services/param/trigger/trigger_checker.c +++ b/services/param/trigger/trigger_checker.c @@ -232,10 +232,9 @@ int ComputeCondition(LogicCalculator *calculator, const char *condition) data1.flags = 0; if (condition[currIndex] == '|' && ret == 1) { LOGIC_DATA_SET_FLAG(&data1, LOGIC_DATA_FLAGS_TRUE); - } else if (condition[currIndex] == '&' || ret == 1) { - if (ComputeSubCondition(calculator, &data2, condition) == 1) { - LOGIC_DATA_SET_FLAG(&data1, LOGIC_DATA_FLAGS_TRUE); - } + } else if ((condition[currIndex] == '&' || ret == 1) && + (ComputeSubCondition(calculator, &data2, condition) == 1)) { + LOGIC_DATA_SET_FLAG(&data1, LOGIC_DATA_FLAGS_TRUE); } ret = CalculatorPush(calculator, (void *)&data1); PARAM_CHECK(ret == 0, return -1, "Failed to push data"); diff --git a/services/param/trigger/trigger_manager.c b/services/param/trigger/trigger_manager.c index 8b5d4ac44..0b39010ad 100755 --- a/services/param/trigger/trigger_manager.c +++ b/services/param/trigger/trigger_manager.c @@ -72,6 +72,7 @@ CommandNode *GetNextCmdNode(TriggerNode *trigger, CommandNode *curr) TriggerNode *AddTrigger(TriggerHeader *triggerHead, const char *name, const char *condition, uint16_t extDataSize) { PARAM_CHECK(triggerHead != NULL && name != NULL, return NULL, "triggerHead is null"); + PARAM_CHECK(extDataSize <= PARAM_CONST_VALUE_LEN_MAX, return NULL, "extDataSize is longest %d", extDataSize); uint32_t nameLen = strlen(name); uint32_t triggerNodeLen = PARAM_ALIGN(nameLen + 1) + sizeof(TriggerNode); uint32_t conditionLen = 0; diff --git a/services/param/trigger/trigger_processor.c b/services/param/trigger/trigger_processor.c index a8e1a2bfc..c3ed2b818 100755 --- a/services/param/trigger/trigger_processor.c +++ b/services/param/trigger/trigger_processor.c @@ -225,12 +225,12 @@ static int GetTriggerType(const char *type) if (strncmp("param:", type, strlen("param:")) == 0) { return TRIGGER_PARAM; } - static const char *triggerType[] = { + const char *triggerTypeStr[] = { "pre-init", "boot", "early-init", "init", "early-init", "late-init", "post-init", "early-fs", "post-fs", "late-fs", "post-fs-data" }; - for (size_t i = 0; i < sizeof(triggerType) / sizeof(char *); i++) { - if (strcmp(triggerType[i], type) == 0) { + for (size_t i = 0; i < sizeof(triggerTypeStr) / sizeof(char *); i++) { + if (strcmp(triggerTypeStr[i], type) == 0) { return TRIGGER_BOOT; } } diff --git a/services/param/watcher/proxy/watcher_manager.cpp b/services/param/watcher/proxy/watcher_manager.cpp index 93ab01332..12aa136dd 100755 --- a/services/param/watcher/proxy/watcher_manager.cpp +++ b/services/param/watcher/proxy/watcher_manager.cpp @@ -260,7 +260,7 @@ int WatcherManager::GetServerFd(bool retry) serverFd_ = INVALID_SOCKET; usleep(SLEEP_TIME); } else { - (void)setsockopt(serverFd_, SOL_SOCKET, SO_RCVTIMEO, (char *)&time, sizeof(struct timeval)); + (void)setsockopt(serverFd_, SOL_SOCKET, SO_RCVTIMEO, &time, sizeof(struct timeval)); break; } } while (1); -- Gitee