From e88b06163982ade242e336e4d93a748b756af0ba Mon Sep 17 00:00:00 2001 From: Ilho Kim Date: Tue, 19 Jul 2022 15:43:17 +0900 Subject: [PATCH 01/16] Implement launch of light user application Change-Id: I9ab41fe9e0dca4e2b40051a741182067a20f99f9 Signed-off-by: Ilho Kim --- src/launchpad-process-pool/src/launchpad.c | 8 +++++--- src/lib/common/inc/key.h | 1 + src/lib/launchpad/src/launchpad_lib.c | 8 +++++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/launchpad-process-pool/src/launchpad.c b/src/launchpad-process-pool/src/launchpad.c index 85e3c7a..1ba060b 100644 --- a/src/launchpad-process-pool/src/launchpad.c +++ b/src/launchpad-process-pool/src/launchpad.c @@ -1230,6 +1230,7 @@ static int __prepare_exec(const char *appid, const char *app_path, appinfo_t *menu_info, bundle *kb) { char *file_name; + const char *enabled_light_user; char process_name[AUL_PR_NAME]; int ret; @@ -1267,9 +1268,10 @@ static int __prepare_exec(const char *appid, const char *app_path, _debug_change_mount_namespace(); /* SET PRIVILEGES*/ - _W("security_manager_prepare_app ++"); - ret = security_manager_prepare_app(appid); - _W("security_manager_prepare_app --"); + enabled_light_user = bundle_get_val(kb, AUL_K_ENABLED_LIGHT_USER); + _W("security_manager_prepare_app2 ++"); + ret = security_manager_prepare_app2(appid, enabled_light_user); + _W("security_manager_prepare_app2 --"); if (ret != SECURITY_MANAGER_SUCCESS) return PAD_ERR_REJECTED; diff --git a/src/lib/common/inc/key.h b/src/lib/common/inc/key.h index 19493c6..8889cca 100644 --- a/src/lib/common/inc/key.h +++ b/src/lib/common/inc/key.h @@ -51,6 +51,7 @@ extern "C" { #define AUL_K_INSTALLED_STORAGE "__AUL_INSTALLED_STORAGE__" #define AUL_K_MOUNT_GLOBAL_RES_DIR "__AUL_MOUNT_GLOBAL_RES_DIR__" #define AUL_K_MOUNT_ALLOWED_RES_DIR "__AUL_MOUNT_ALLOWED_RES_DIR__" +#define AUL_K_ENABLED_LIGHT_USER "__AUL_ENABLED_LIGHT_USER__" #ifdef __cplusplus } diff --git a/src/lib/launchpad/src/launchpad_lib.c b/src/lib/launchpad/src/launchpad_lib.c index e14894f..437dbbe 100644 --- a/src/lib/launchpad/src/launchpad_lib.c +++ b/src/lib/launchpad/src/launchpad_lib.c @@ -65,6 +65,7 @@ static int __prepare_exec(const char *appid, const char *app_path, const char *root_path, bool global, bundle *kb) { const char *file_name = NULL; + const char *enabled_light_user; char process_name[AUL_PR_NAME] = { 0, }; int ret; struct buxton_client *bxt_cli; @@ -94,9 +95,10 @@ static int __prepare_exec(const char *appid, const char *app_path, if (ret < 0) return -1; - _W("security_manager_prepare_app ++"); - ret = security_manager_prepare_app(appid); - _W("security_manager_prepare_app --"); + enabled_light_user = bundle_get_val(kb, AUL_K_ENABLED_LIGHT_USER); + _W("security_manager_prepare_app2 ++"); + ret = security_manager_prepare_app2(appid, enabled_light_user); + _W("security_manager_prepare_app2 --"); if (ret != SECURITY_MANAGER_SUCCESS) { _E("Failed to set privileges %s:%d", appid, ret); return -1; -- 2.7.4 From 03ae0ef0750fef5422a3b29233fe31a967105436 Mon Sep 17 00:00:00 2001 From: Changgyu Choi Date: Fri, 5 Aug 2022 10:27:17 +0900 Subject: [PATCH 02/16] Release version 0.19.0 Changes: - Implement launch of light user application Change-Id: I090af4f7c74ff05a8fee7d1ea82df059a8a42dc7 Signed-off-by: Changgyu Choi --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 91785ee..0525399 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.18.14 +Version: 0.19.0 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From ab8d49d2fdf501ced10464e69275c8de86eced5f Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 19 Sep 2022 07:45:29 +0000 Subject: [PATCH 03/16] Fix resource leak The allocated memory has to be released. The xmlGetProp() returns the allocated value. It should be released using xmlFree(). Change-Id: I031d76c587ad8dcab9141c585d732893d916eea9 Signed-off-by: Hwankyu Jhun --- src/launchpad-parser/launchpad_parser_plugin.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/launchpad-parser/launchpad_parser_plugin.cc b/src/launchpad-parser/launchpad_parser_plugin.cc index f873673..d8b23c0 100644 --- a/src/launchpad-parser/launchpad_parser_plugin.cc +++ b/src/launchpad-parser/launchpad_parser_plugin.cc @@ -103,15 +103,21 @@ int LaunchpadParser::Install(xmlDocPtr doc, std::string pkgid) { continue; xmlChar* val = xmlGetProp(node, reinterpret_cast("id")); + if (val == nullptr) + continue; + std::shared_ptr info = std::make_shared(std::string(reinterpret_cast(val))); + xmlFree(val); if (!IsValidId(info->GetId(), pkgid)) return -1; xmlChar* ttl = xmlGetProp(node, reinterpret_cast("time-to-live")); - if (ttl) + if (ttl) { info->SetTimeToLive(std::stoi(std::string(reinterpret_cast(ttl)))); + xmlFree(ttl); + } for (xmlNode* iter = node->children; iter; iter = iter->next) { if (!iter->name) @@ -120,10 +126,11 @@ int LaunchpadParser::Install(xmlDocPtr doc, std::string pkgid) { std::string(reinterpret_cast(iter->name)); if (child_name == "preload-library") { xmlChar* libname = xmlGetProp(iter, - reinterpret_cast("name")); + reinterpret_cast("name")); if (!libname) continue; info->AddPreloadLib(std::string(reinterpret_cast(libname))); + xmlFree(libname); } } loader_list_.push_back(info); @@ -158,6 +165,7 @@ int LaunchpadParser::UnInstall(xmlDocPtr doc, std::string pkgid) { return -1; std::string id = std::string(reinterpret_cast(val)); + xmlFree(val); if (!IsValidId(id, pkgid)) return -1; remove(GetFilePath(id).c_str()); -- 2.7.4 From bbedcfaa2bbe9e8971a4f3688117f3167850481e Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 19 Sep 2022 07:57:12 +0000 Subject: [PATCH 04/16] Release version 0.19.1 Changes: - Fix resource leak Change-Id: Idc73789582823bab17303215ca0d10b31b59bc3b Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 0525399..9ce9f6c 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.19.0 +Version: 0.19.1 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From 9a607a8212db01af57616c36eb55ba4b4887b454 Mon Sep 17 00:00:00 2001 From: Changgyu Choi Date: Mon, 17 Oct 2022 12:12:25 +0900 Subject: [PATCH 05/16] Fix static analysis issues Change-Id: I6ef67f0f1b6423756955a94370fbcee51b1d81ee Signed-off-by: Changgyu Choi --- src/launchpad-process-pool/src/launchpad.c | 6 ++-- src/lib/common/src/launchpad_common.c | 8 ++--- src/lib/common/src/launchpad_socket.c | 58 +++++++++++++++--------------- 3 files changed, 35 insertions(+), 37 deletions(-) diff --git a/src/launchpad-process-pool/src/launchpad.c b/src/launchpad-process-pool/src/launchpad.c index 1ba060b..83e1d21 100644 --- a/src/launchpad-process-pool/src/launchpad.c +++ b/src/launchpad-process-pool/src/launchpad.c @@ -93,7 +93,7 @@ typedef struct { int type; bool prepared; int pid; /* for hydra this pid is not the pid of hydra itself */ - /* but pid of non-hydra candidate, which was forked from hydra */ + /* but pid of non-hydra candidate, which was forked from hydra */ int hydra_pid; int loader_id; int caller_pid; @@ -627,7 +627,7 @@ static int __accept_candidate_process(int server_fd, int *out_client_fd, goto error; } - len = sizeof(cred); + len = (socklen_t)sizeof(cred); ret = getsockopt(client_fd, SOL_SOCKET, SO_PEERCRED, &cred, &len); if (ret < 0) { _E("getsockopt error"); @@ -847,7 +847,7 @@ static void __set_live_timer(candidate_process_context_t *cpc) static int __hydra_send_request(int fd, enum hydra_cmd cmd) { int sent = 0; - int size = sizeof(cmd); + int size = (int)sizeof(cmd); int send_ret = 0; while (sent != size) { diff --git a/src/lib/common/src/launchpad_common.c b/src/lib/common/src/launchpad_common.c index 0717c95..0db3125 100644 --- a/src/lib/common/src/launchpad_common.c +++ b/src/lib/common/src/launchpad_common.c @@ -415,12 +415,10 @@ retry_recv: app_pkt_t *_accept_recv_pkt_raw(int fd, int *clifd, struct ucred *cr) { struct sockaddr_un aul_addr = { 0, }; - int sun_size; + int sun_size = (int)sizeof(struct sockaddr_un); app_pkt_t *pkt; int newfd; - int cl = sizeof(struct ucred); - - sun_size = sizeof(struct sockaddr_un); + int cl = (int)sizeof(struct ucred); newfd = accept(fd, (struct sockaddr *)&aul_addr, (socklen_t *) &sun_size); @@ -1513,7 +1511,7 @@ void _print_hwc_log(const char *format, ...) static int __get_mount_opt(const char *srcs[], size_t srcs_len, const char *dest, char *opt, size_t opt_len) { - int i; + size_t i; char buf[PATH_MAX]; int ret; diff --git a/src/lib/common/src/launchpad_socket.c b/src/lib/common/src/launchpad_socket.c index a79905b..16241f7 100644 --- a/src/lib/common/src/launchpad_socket.c +++ b/src/lib/common/src/launchpad_socket.c @@ -42,26 +42,26 @@ struct socket_s { static int __set_socket_option(int fd, bool client) { - struct timeval tv = { 5, 200 * 1000 }; /* 5.2 sec */ - int size = LAUNCHPAD_SOCKET_MAX_BUFF; - int flag; - int ret; + struct timeval tv = { 5, 200 * 1000 }; /* 5.2 sec */ + int size = LAUNCHPAD_SOCKET_MAX_BUFF; + int flag; + int ret; - ret = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); - if (ret < 0) { + ret = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); + if (ret < 0) { ret = -errno; _E("setsockopt(SO_SNDBUF) is failed. fd(%d), errno(%d)", fd, errno); - return ret; - } + return ret; + } - ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); - if (ret < 0) { + ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); + if (ret < 0) { ret = -errno; _E("setsockopt(SO_RCVBUF) is failed. fd(%d), errno(%d)", fd, errno); - return ret; - } + return ret; + } if (!client) return 0; @@ -83,7 +83,7 @@ static int __set_socket_option(int fd, bool client) return ret; } - return 0; + return 0; } static int __create_server_socket(const char *path) @@ -136,27 +136,27 @@ static int __create_client_socket(const char *path) int fd; fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); - if (fd < 0) { + if (fd < 0) { ret = -errno; _E("socket() is failed. path(%s), errno(%d)", path, errno); - return ret; - } + return ret; + } - addr.sun_family = AF_UNIX; - snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path); - while (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - if (errno != ETIMEDOUT || retry <= 0) { + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path); + while (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + if (errno != ETIMEDOUT || retry <= 0) { ret = -errno; _E("connect() is failed. path(%s), errno(%d)", path, errno); - close(fd); - return ret; - } + close(fd); + return ret; + } - usleep(LAUNCHPAD_SOCKET_RETRY_TIME); - retry--; - _W("Retry(%d) to connect to %s", retry, path); - } + usleep(LAUNCHPAD_SOCKET_RETRY_TIME); + retry--; + _W("Retry(%d) to connect to %s", retry, path); + } ret = __set_socket_option(fd, true); if (ret < 0) { @@ -273,8 +273,8 @@ int _socket_accept(socket_h handle, socket_h *client_socket) struct socket_s *sock; struct sockaddr_un addr = { 0, }; struct ucred cred = { 0, }; - socklen_t addr_size = sizeof(struct sockaddr_un); - socklen_t cred_size = sizeof(struct ucred); + socklen_t addr_size = (socklen_t)sizeof(struct sockaddr_un); + socklen_t cred_size = (socklen_t)sizeof(struct ucred); int client_fd; int ret; -- 2.7.4 From 27c46a599f0ff9df93cd29f939515174a754a400 Mon Sep 17 00:00:00 2001 From: Changgyu Choi Date: Tue, 18 Oct 2022 11:26:24 +0900 Subject: [PATCH 06/16] Release version 0.19.2 Changes: - Fix static analysis issues Change-Id: I5fd2f82cf99c3ab8360780f98db913f81496f378 Signed-off-by: Changgyu Choi --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 9ce9f6c..b4f0553 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.19.1 +Version: 0.19.2 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From 0baf8cf694388fe40535340a9a5dc1569006333c Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 18 Oct 2022 09:22:59 +0000 Subject: [PATCH 07/16] Add an environmant variable related to ASAN While getting a launch request for ASAN debugging, the launchpad adds 'TIZEN_ASAN_ACTIVATION' environment variable for activating ASAN. Related: - https://review.tizen.org/gerrit/#/c/platform/upstream/gcc/+/283119/ Change-Id: I5d6fdf47d872de4f7985e074ada550368ebaced3 Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/src/launchpad_debug.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/launchpad-process-pool/src/launchpad_debug.c b/src/launchpad-process-pool/src/launchpad_debug.c index 8040f45..da59159 100644 --- a/src/launchpad-process-pool/src/launchpad_debug.c +++ b/src/launchpad-process-pool/src/launchpad_debug.c @@ -403,6 +403,9 @@ void _debug_prepare_debugger(bundle *kb) if (debugger == NULL) return; + if (!strcmp(debugger, "ASAN")) + setenv("TIZEN_ASAN_ACTIVATION", "1", 1); + ret = __redirect_std_fds(kb); if (ret < 0) _E("[DEBUG] Failed to redirect standard fds"); -- 2.7.4 From 5f6582e1e6befd3eb8ccd620e9bdb7325404fed2 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 18 Oct 2022 10:36:39 +0000 Subject: [PATCH 08/16] Release version 0.19.3 Changes: - Add an environmant variable related to ASAN Change-Id: Ib84a6127f8d2a0a041a07cb7b371a2a36f3b844b Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index b4f0553..574dbae 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.19.2 +Version: 0.19.3 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From 7a0291e7ff6c31fa9c8f89b5beb6d884ca053a6b Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 8 Nov 2022 01:48:16 +0000 Subject: [PATCH 09/16] Create a child process in the worker thread To avoid blocking main thread of launchpad-process-pool, the worker thread creates a child process. Change-Id: I6cd499a6d6a5fc3d0d2d81f2256e299f4067eb68 Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/inc/launchpad_worker.h | 8 +- src/launchpad-process-pool/src/launchpad.c | 702 +++++++++++++++------- src/launchpad-process-pool/src/launchpad_worker.c | 77 ++- 3 files changed, 536 insertions(+), 251 deletions(-) diff --git a/src/launchpad-process-pool/inc/launchpad_worker.h b/src/launchpad-process-pool/inc/launchpad_worker.h index cee3000..0276545 100644 --- a/src/launchpad-process-pool/inc/launchpad_worker.h +++ b/src/launchpad-process-pool/inc/launchpad_worker.h @@ -23,13 +23,15 @@ extern "C" { #endif +typedef struct worker_s *worker_h; + typedef bool (*worker_job_cb)(void *user_data); -int _worker_add_job(worker_job_cb callback, void *user_data); +int _worker_add_job(worker_h worker, worker_job_cb callback, void *user_data); -int _worker_init(void); +int _worker_create(const char *name, worker_h *worker); -void _worker_fini(void); +void _worker_destroy(worker_h worker); #ifdef __cplusplus } diff --git a/src/launchpad-process-pool/src/launchpad.c b/src/launchpad-process-pool/src/launchpad.c index 83e1d21..3d03c43 100644 --- a/src/launchpad-process-pool/src/launchpad.c +++ b/src/launchpad-process-pool/src/launchpad.c @@ -165,6 +165,33 @@ struct cleanup_info_s { int pid; }; +typedef struct candidate_info_s { + char **argv; + int argc; + int loader_id; + int type; + pid_t pid; +} candidate_info_t; + +typedef struct request_s { + app_pkt_t *pkt; + appinfo_t *menu_info; + bundle *kb; + candidate_process_context_t *cpc; + candidate_process_context_t *org_cpc; + const char *app_path; + int clifd; + int cmd; + int loader_id; + pid_t caller_pid; + uid_t caller_uid; + pid_t pid; /* result */ +} request_t; + +typedef request_t *request_h; + +typedef int (*request_handler)(request_h request); + static int __sys_hwacc; static GList *loader_info_list; static GList *app_defined_loader_info_list; @@ -184,6 +211,8 @@ static io_channel_h __logger_channel; static io_channel_h __label_monitor_channel; static io_channel_h __launchpad_channel; static int __client_fd = -1; +static worker_h __cleaner; +static worker_h __forker; static candidate_process_context_t *__add_slot(int type, int loader_id, int caller_pid, const char *loader_name, @@ -754,30 +783,12 @@ static int __real_send(int clifd, int ret) return 0; } -static void __send_result_to_caller(int clifd, int ret) -{ - _W("send result: %d", ret); - - if (clifd == -1) - return; - - if (ret <= 1) { - _E("launching failed"); - __real_send(clifd, ret); - return; - } - - if (__real_send(clifd, ret) < 0) - __kill_process(ret); -} - static int __fork_app_process(int (*child_fn)(void *), void *arg) { int pid; int ret; pid = fork(); - if (pid == -1) { _E("failed to fork child process"); return -1; @@ -872,52 +883,131 @@ static int __hydra_send_launch_candidate_request(int fd) return __hydra_send_request(fd, LAUNCH_CANDIDATE); } -static int __prepare_candidate_process(int type, int loader_id) +static void __candidate_info_free(candidate_info_t *info) +{ + int i; + + if (info == NULL) + return; + + if (info->argv) { + for (i = 0; i < info->argc; i++) + free(info->argv[i]); + + free(info->argv); + } + + free(info); +} + +static int __candidate_info_create(candidate_process_context_t *cpt, + candidate_info_t **candidate_info) { - int pid; char type_str[12] = {0, }; char loader_id_str[12] = {0, }; char argbuf[LOADER_ARG_LEN]; - char *argv[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; - candidate_process_context_t *cpt = __find_slot(type, loader_id); + candidate_info_t *info; if (cpt == NULL) - return -1; + return -EINVAL; - if (cpt->is_hydra && cpt->hydra_pid != HYDRA_NONE) - return __hydra_send_launch_candidate_request(cpt->hydra_fd); + info = calloc(1, sizeof(candidate_info_t)); + if (info == NULL) { + _E("calloc() is failed"); + return -ENOMEM; + } + + info->argv = calloc(LOADER_ARG_DUMMY + 1, sizeof(char *)); + if (info->argv == NULL) { + _E("calloc() is failed"); + __candidate_info_free(info); + return -ENOMEM; + } - _D("prepare candidate process / type:%d", type); memset(argbuf, ' ', LOADER_ARG_LEN); argbuf[LOADER_ARG_LEN - 1] = '\0'; - argv[LOADER_ARG_DUMMY] = argbuf; + info->argv[LOADER_ARG_DUMMY] = strdup(argbuf); - cpt->last_exec_time = time(NULL); + snprintf(loader_id_str, sizeof(loader_id_str), "%d", cpt->loader_id); + snprintf(type_str, sizeof(type_str), "%d", cpt->type); + info->argv[LOADER_ARG_PATH] = strdup(cpt->loader_path); + info->argv[LOADER_ARG_TYPE] = strdup(type_str); + info->argv[LOADER_ARG_ID] = strdup(loader_id_str); + info->argv[LOADER_ARG_HYDRA] = strdup(cpt->is_hydra ? "1" : "0"); + info->argv[LOADER_ARG_EXTRA] = strdup(cpt->loader_extra); - snprintf(loader_id_str, sizeof(loader_id_str), "%d", loader_id); - snprintf(type_str, sizeof(type_str), "%d", type); - argv[LOADER_ARG_PATH] = cpt->loader_path; - argv[LOADER_ARG_TYPE] = type_str; - argv[LOADER_ARG_ID] = loader_id_str; - argv[LOADER_ARG_HYDRA] = cpt->is_hydra ? "1" : "0"; - argv[LOADER_ARG_EXTRA] = cpt->loader_extra; + info->argc = LOADER_ARG_DUMMY + 1; + info->type = cpt->type; + info->loader_id = cpt->loader_id; - pid = __fork_app_process(__exec_loader_process, argv); - if (pid == -1) { - _E("Failed to fork candidate_process"); - return -1; - } + *candidate_info = info; + return 0; +} - if (cpt->is_hydra) { - cpt->hydra_pid = pid; - } else { - cpt->pid = pid; - __set_live_timer(cpt); +static gboolean __handle_exec_loader_process(gpointer user_data) +{ + candidate_process_context_t *cpt; + candidate_info_t *info = user_data; + + _W("Candidate process. type: %d, loader_id: %d, pid: %d", + info->type, info->loader_id, info->pid); + if (info->pid > 0) { + cpt = __find_slot(info->type, info->loader_id); + cpt->last_exec_time = time(NULL); + if (cpt->is_hydra) { + cpt->hydra_pid = info->pid; + } else { + cpt->pid = info->pid; + __set_live_timer(cpt); + } + + _log_print("[CANDIDATE]", "pid(%7d) | type(%d) | loader(%s)", + info->pid, cpt->loader_id, cpt->loader_name); + _memory_monitor_reset_timer(); } - _log_print("[CANDIDATE]", "pid(%7d) | type(%d) | loader(%s)", - pid, cpt->loader_id, cpt->loader_name); - _memory_monitor_reset_timer(); + __candidate_info_free(info); + return G_SOURCE_REMOVE; +} + +static bool __exec_loader_process_cb(void *user_data) +{ + candidate_info_t *info = user_data; + + if (info == NULL) + return false; + + info->pid = __fork_app_process(__exec_loader_process, info->argv); + if (info->pid == -1) + _E("Failed to create a child process"); + + g_idle_add(__handle_exec_loader_process, info); + return false; +} + +static int __prepare_candidate_process(int type, int loader_id) +{ + candidate_process_context_t *cpt = __find_slot(type, loader_id); + candidate_info_t *info; + int ret; + + if (cpt == NULL) + return -1; + + if (cpt->is_hydra && cpt->hydra_pid != HYDRA_NONE) + return __hydra_send_launch_candidate_request(cpt->hydra_fd); + + _D("prepare candidate process / type:%d", type); + ret = __candidate_info_create(cpt, &info); + if (ret < 0) + return ret; + + ret = _worker_add_job(__forker, __exec_loader_process_cb, info); + if (ret != 0) { + _E("_worker_add_job() is failed"); + __candidate_info_free(info); + return -1; + } return 0; } @@ -1612,7 +1702,7 @@ static void __handle_sigchild(int pid, void *user_data) if (appid) { info = __create_cleanup_info(appid, pid); if (info) - ret = _worker_add_job(__cleanup_app_cb, info); + ret = _worker_add_job(__cleaner, __cleanup_app_cb, info); if (ret != 0) { __destroy_cleanup_info(info); @@ -2160,228 +2250,391 @@ static void __update_slot_state(candidate_process_context_t *cpc, int method, } } -static bool __handle_launch_event(int fd, io_condition_e cond, void *data) +static void __request_destroy(request_t *request) +{ + if (request == NULL) + return; + + if (request->clifd > -1) + close(request->clifd); + if (request->menu_info) + _appinfo_free(request->menu_info); + if (request->kb) + bundle_free(request->kb); + if (request->pkt) + free(request->pkt); + free(request); +} + +static int __request_create(int fd, request_t **request) { - bundle *kb = NULL; - app_pkt_t *pkt = NULL; - appinfo_t *menu_info = NULL; - candidate_process_context_t *cpc = NULL; - candidate_process_context_t *org_cpc = NULL; - const char *app_path = NULL; - int pid = -1; - int clifd = -1; struct ucred cr; - int type = -1; - int loader_id; - int ret; + request_t *req; - if (cond & (IO_ERR | IO_HUP | IO_NVAL)) { - _E("fd(%d), condition(%d)", fd, cond); - g_idle_add(__launchpad_recovery_cb, __launchpad_channel); - __launchpad_channel = NULL; - return false; + if (request == NULL) { + _E("Invalid parameter"); + return -EINVAL; } - traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "LAUNCHPAD:LAUNCH"); - pkt = _accept_recv_pkt_raw(fd, &clifd, &cr); - if (!pkt) { - _E("packet is NULL"); - goto end; + req = calloc(1, sizeof(request_t)); + if (req == NULL) { + _E("calloc() is failed"); + return -ENOMEM; } - _W("cmd(%d), caller(%d)", pkt->cmd, cr.pid); - if (cr.uid >= REGULAR_UID_MIN) { - if (__check_caller_by_pid(cr.pid) < 0) { - _E("Invalid caller pid"); - goto end; - } + req->clifd = -1; + req->pkt = _accept_recv_pkt_raw(fd, &req->clifd, &cr); + if (req->pkt == NULL) { + _E("_accept_recv_pkt_raw() is failed"); + __request_destroy(req); + return -ECOMM; } - kb = bundle_decode(pkt->data, pkt->len); - if (!kb) { - _E("bundle decode error"); - goto end; + req->kb = bundle_decode(req->pkt->data, req->pkt->len); + if (req->kb == NULL) { + _E("bundle_decode() is failed"); + __real_send(req->clifd, -EINVAL); + req->clifd = -1; + __request_destroy(req); + return -EINVAL; } - if (bundle_get_type(kb, AUL_K_SDK) != BUNDLE_TYPE_NONE) - _debug_init(); + req->cmd = req->pkt->cmd; + req->caller_pid = cr.pid; + req->caller_uid = cr.uid; + *request = req; + return 0; +} - switch (pkt->cmd) { - case PAD_CMD_VISIBILITY: - ret = __dispatch_cmd_hint(kb, METHOD_VISIBILITY); - __real_send(clifd, ret); - clifd = -1; - goto end; - case PAD_CMD_ADD_LOADER: - ret = __dispatch_cmd_add_loader(kb); - __real_send(clifd, ret); - clifd = -1; - goto end; - case PAD_CMD_REMOVE_LOADER: - ret = __dispatch_cmd_remove_loader(kb); - __real_send(clifd, ret); - clifd = -1; - goto end; - case PAD_CMD_MAKE_DEFAULT_SLOTS: - ret = __add_default_slots(); - if (ret != 0) - _E("Failed to make default slots"); - __real_send(clifd, ret); - clifd = -1; - goto end; - case PAD_CMD_PREPARE_APP_DEFINED_LOADER: - ret = __dispatch_cmd_add_app_defined_loader(kb); - __real_send(clifd, ret); - clifd = -1; - goto end; - case PAD_CMD_DEMAND: - ret = __dispatch_cmd_hint(kb, METHOD_DEMAND); - __real_send(clifd, ret); - clifd = -1; - goto end; - case PAD_CMD_PING: - __real_send(clifd, getpid()); - clifd = -1; - goto end; - case PAD_CMD_UPDATE_APP_TYPE: - __dispatch_cmd_update_app_type(kb); - close(clifd); - clifd = -1; - goto end; - case PAD_CMD_CONNECT: - _W("Connected. fd(%d)", clifd); - if (__client_fd != -1) - close(__client_fd); +static void __request_send_result(request_h request, int result) +{ + if (request->clifd < 0) + return; - __client_fd = clifd; - clifd = -1; - goto end; - } + __real_send(request->clifd, result); + request->clifd = -1; +} - INIT_PERF(kb); - PERF("packet processing start"); +static int __visibility_request_handler(request_h request) +{ + int ret = __dispatch_cmd_hint(request->kb, METHOD_VISIBILITY); - menu_info = _appinfo_create(kb); - if (menu_info == NULL) { - _E("such pkg no found"); - __send_result_to_caller(clifd, -EINVAL); - clifd = -1; - goto end; + __request_send_result(request, ret); + _D("[PAD_CMD_VISIBILITY] result: %d", ret); + return ret; +} + +static int __add_loader_request_handler(request_h request) +{ + int ret = __dispatch_cmd_add_loader(request->kb); + + __request_send_result(request, ret); + _D("[PAD_CMD_ADD_LOADER] result: %d", ret); + return ret; +} + +static int __remove_loader_request_handler(request_h request) +{ + int ret = __dispatch_cmd_remove_loader(request->kb); + + __request_send_result(request, ret); + _D("[PAD_CMD_REMOVE_LOADER] result: %d", ret); + return ret; +} + +static int __make_default_slots_request_handler(request_h request) +{ + int ret = __add_default_slots(); + + __request_send_result(request, ret); + _D("[PAD_CMD_MAKE_DEFAULT_SLOTS] result: %d", ret); + return ret; +} + +static int __prepare_app_defined_loader_request_handler(request_h request) +{ + int ret = __dispatch_cmd_add_app_defined_loader(request->kb); + + __request_send_result(request, ret); + _D("[PAD_CMD_PREPARE_APP_DEFINED_LOADER] result: %d", ret); + return ret; +} + +static int __demand_request_handler(request_h request) +{ + int ret = __dispatch_cmd_hint(request->kb, METHOD_DEMAND); + + __request_send_result(request, ret); + _D("[PAD_CMD_DEMAND] result: %d", ret); + return ret; +} + +static int __ping_request_handler(request_h request) +{ + __request_send_result(request, getpid()); + _D("[PAD_CMD_PING] result: %d", getpid()); + return 0; +} + +static int __update_app_type_request_handler(request_h request) +{ + int ret = __dispatch_cmd_update_app_type(request->kb); + + _D("[PAD_CMD_UPDATE_APP_TYPE] result: %d", ret); + return ret; +} + +static int __connect_request_handler(request_h request) +{ + if (__client_fd != -1) + close(__client_fd); + + __client_fd = request->clifd; + request->clifd = -1; + _D("[PAD_CMD_CONNECT] client fd: %d", __client_fd); + return 0; +} + +static int __launch_request_prepare(request_h request) +{ + const appinfo_t *menu_info; + int type = -1; + + request->menu_info = _appinfo_create(request->kb); + if (request->menu_info == NULL) { + _E("_appinfo_create() is failed"); + return -1; } - app_path = _appinfo_get_app_path(menu_info); - if (app_path == NULL) { - _E("app_path is NULL"); - __send_result_to_caller(clifd, -EINVAL); - clifd = -1; - goto end; + request->app_path = _appinfo_get_app_path(request->menu_info); + if (request->app_path == NULL) { + _E("_appinfo_get_app_path() is failed"); + return -1; } - if (app_path[0] != '/') { - _E("app_path is not absolute path"); - __send_result_to_caller(clifd, -EINVAL); - clifd = -1; - goto end; + if (request->app_path[0] != '/') { + _E("app path is not absolute path"); + return -1; } + menu_info = request->menu_info; if (menu_info->hwacc == NULL) { - _E("[launchpad] Failed to find H/W acceleration type"); - __send_result_to_caller(clifd, -EINVAL); - clifd = -1; - goto end; + _E("Failed to find HW acceeleration type"); + return -1; } - SECURE_LOGD("exec : %s", menu_info->app_path); - SECURE_LOGD("comp_type : %s", menu_info->comp_type); - SECURE_LOGD("internal pool : %s", menu_info->internal_pool); - SECURE_LOGD("hwacc : %s", menu_info->hwacc); - SECURE_LOGD("app_type : %s", menu_info->app_type); - SECURE_LOGD("pkg_type : %s", menu_info->pkg_type); + SECURE_LOGD("appid: %s", menu_info->appid); + SECURE_LOGD("exec: %s", menu_info->app_path); + SECURE_LOGD("comp_type: %s", menu_info->comp_type); + SECURE_LOGD("internal pool: %s", menu_info->internal_pool); + SECURE_LOGD("hwacc: %s", menu_info->hwacc); + SECURE_LOGD("app_type: %s", menu_info->app_type); + SECURE_LOGD("pkg_type: %s", menu_info->pkg_type); - if (menu_info->comp_type && - strcmp(menu_info->comp_type, "svcapp") == 0) { - loader_id = __get_loader_id(kb); - if (loader_id > PAD_LOADER_ID_DYNAMIC_BASE) { + if (menu_info->comp_type && !strcmp(menu_info->comp_type, "svcapp")) { + request->loader_id = __get_loader_id(request->kb); + if (request->loader_id > PAD_LOADER_ID_DYNAMIC_BASE) { type = LAUNCHPAD_LOADER_TYPE_DYNAMIC; - cpc = __find_slot(type, loader_id); - if (cpc && !cpc->prepared) - cpc = NULL; + request->cpc = __find_slot(type, request->loader_id); + if (request->cpc && !request->cpc->prepared) + request->cpc = NULL; } else { - loader_id = PAD_LOADER_ID_DIRECT; + request->loader_id = PAD_LOADER_ID_DIRECT; } } else if (menu_info->comp_type && menu_info->app_type && - strcmp(menu_info->comp_type, "widgetapp") == 0 && - strcmp(menu_info->app_type, "webapp") == 0) { - loader_id = PAD_LOADER_ID_DIRECT; + !strcmp(menu_info->comp_type, "widgetapp") && + !strcmp(menu_info->app_type, "webapp")) { + request->loader_id = PAD_LOADER_ID_DIRECT; } else { - loader_id = __get_loader_id(kb); - if (loader_id <= PAD_LOADER_ID_STATIC) { - cpc = __find_available_slot(menu_info->hwacc, + request->loader_id = __get_loader_id(request->kb); + if (request->loader_id <= PAD_LOADER_ID_STATIC) { + request->cpc = __find_available_slot(menu_info->hwacc, menu_info->app_type, - menu_info->loader_name, &org_cpc); + menu_info->loader_name, + &request->org_cpc); } else { type = LAUNCHPAD_LOADER_TYPE_DYNAMIC; - cpc = __find_slot(type, loader_id); - if (cpc && !cpc->prepared) - cpc = NULL; + request->cpc = __find_slot(type, request->loader_id); + if (request->cpc && !request->cpc->prepared) + request->cpc = NULL; } } - _modify_bundle(kb, cr.pid, menu_info, pkt->cmd); + _modify_bundle(request->kb, request->caller_pid, request->menu_info, + request->cmd); if (menu_info->appid == NULL) { - _E("unable to get appid from menu_info"); - __send_result_to_caller(clifd, -EINVAL); - clifd = -1; - goto end; + _E("Unable to get appid from app info"); + return -1; } - PERF("get package information & modify bundle done"); + PERF("Getting package information & modifying bundle done"); + return 0; +} - if (loader_id == PAD_LOADER_ID_DIRECT || cpc == NULL) { - _W("Launch directly %d %p", loader_id, cpc); - pid = __launch_directly(menu_info->appid, app_path, clifd, kb, - menu_info, NULL); - if (org_cpc && (!org_cpc->app_check || org_cpc->app_exists) && - org_cpc->pid == CANDIDATE_NONE && - !__sequencer_slot_exist(org_cpc)) { - if (org_cpc->timer > 0) { - g_source_remove(org_cpc->timer); - org_cpc->timer = 0; - } +static void __launch_request_complete(request_h request) +{ + _memory_monitor_reset_timer(); + __request_send_result(request, request->pid); - __update_slot_state(org_cpc, METHOD_REQUEST, true); - __set_timer(org_cpc); + if (request->pid > 0) { + _dbus_send_app_launch_signal(request->pid, + request->menu_info->appid); + g_hash_table_insert(__pid_table, GINT_TO_POINTER(request->pid), + strdup(request->menu_info->appid)); + _log_print("[LAUNCH]", "pid(%7d) | appid(%s)", + request->pid, request->menu_info->appid); + } +} + +static gboolean __handle_direct_launch(gpointer user_data) +{ + request_h request = user_data; + + if (request->org_cpc && (!request->org_cpc->app_check || + request->org_cpc->app_exists) && + request->org_cpc->pid == CANDIDATE_NONE && + !__sequencer_slot_exist(request->org_cpc)) { + if (request->org_cpc->timer > 0) { + g_source_remove(request->org_cpc->timer); + request->org_cpc->timer = 0; } - } else { - _W("Launch %d type process", cpc->type); - pid = __send_launchpad_loader(cpc, pkt, app_path, clifd); + + __update_slot_state(request->org_cpc, METHOD_REQUEST, true); + __set_timer(request->org_cpc); } - _memory_monitor_reset_timer(); - __send_result_to_caller(clifd, pid); - clifd = -1; -end: - if (clifd != -1) - close(clifd); + __launch_request_complete(request); + __request_destroy(request); + return G_SOURCE_REMOVE; +} - if (pid > 0) { - _dbus_send_app_launch_signal(pid, menu_info->appid); - g_hash_table_insert(__pid_table, GINT_TO_POINTER(pid), - strdup(menu_info->appid)); - _log_print("[LAUNCH]", "pid(%7d) | appid(%s)", - pid, menu_info->appid); +static bool __fork_processing_cb(void *user_data) +{ + request_h request = user_data; + + if (bundle_get_type(request->kb, AUL_K_SDK) != BUNDLE_TYPE_NONE) + _debug_init(); + + _W("appid: %s", request->menu_info->appid); + request->pid = __launch_directly(request->menu_info->appid, + request->app_path, request->clifd, request->kb, + request->menu_info, NULL); + if (request->pid == -1) { + _E("Failed to create a child process. appid(%s)", + request->menu_info->appid); + } + + __request_send_result(request, request->pid); + _W("appid: %s, pid: %d", request->menu_info->appid, request->pid); + g_idle_add(__handle_direct_launch, request); + return false; +} + +static int __launch_request_do(request_h request) +{ + int ret; + + if (request->loader_id == PAD_LOADER_ID_DIRECT || + request->cpc == NULL) { + ret = _worker_add_job(__forker, __fork_processing_cb, request); + if (ret != 0) + return -1; + + return 1; } - if (menu_info != NULL) - _appinfo_free(menu_info); + _W("Launch %d type process. appid(%s)", + request->cpc->type, request->menu_info->appid); + request->pid = __send_launchpad_loader(request->cpc, request->pkt, + request->app_path, request->clifd); + return 0; +} - if (kb != NULL) - bundle_free(kb); - if (pkt != NULL) - free(pkt); +static int __launch_request_handler(request_h request) +{ + int ret; + traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "LAUNCHPAD:LAUNCH"); + INIT_PERF(kb); + PERF("Packet processing start"); + + ret = __launch_request_prepare(request); + if (ret < 0) { + traceEnd(TTRACE_TAG_APPLICATION_MANAGER); + __request_send_result(request, ret); + return ret; + } + + ret = __launch_request_do(request); + if (ret == 1) { + traceEnd(TTRACE_TAG_APPLICATION_MANAGER); + return ret; + } + + if (ret < 0) + request->pid = ret; + + __launch_request_complete(request); traceEnd(TTRACE_TAG_APPLICATION_MANAGER); + _D("[PAD_CMD_LAUNCH] appid: %s, result: %d", + request->menu_info->appid, request->pid); + return 0; +} +static request_handler __request_handlers[] = { + [PAD_CMD_VISIBILITY] = __visibility_request_handler, + [PAD_CMD_ADD_LOADER] = __add_loader_request_handler, + [PAD_CMD_REMOVE_LOADER] = __remove_loader_request_handler, + [PAD_CMD_MAKE_DEFAULT_SLOTS] = __make_default_slots_request_handler, + [PAD_CMD_PREPARE_APP_DEFINED_LOADER] = + __prepare_app_defined_loader_request_handler, + [PAD_CMD_DEMAND] = __demand_request_handler, + [PAD_CMD_PING] = __ping_request_handler, + [PAD_CMD_UPDATE_APP_TYPE] = __update_app_type_request_handler, + [PAD_CMD_CONNECT] = __connect_request_handler, + [PAD_CMD_LAUNCH] = __launch_request_handler, +}; + +static bool __handle_launch_event(int fd, io_condition_e cond, void *data) +{ + request_t *request = NULL; + int ret; + + if (cond & (IO_ERR | IO_HUP | IO_NVAL)) { + _E("fd(%d), condition(%d)", fd, cond); + g_idle_add(__launchpad_recovery_cb, __launchpad_channel); + __launchpad_channel = NULL; + return false; + } + + ret = __request_create(fd, &request); + if (ret != 0) + return true; + + _W("cmd(%d), caller(%d)", request->cmd, request->caller_pid); + if (request->caller_uid >= REGULAR_UID_MIN) { + if (__check_caller_by_pid(request->caller_pid) < 0) { + _E("Permission denied. pid(%d)", request->caller_pid); + __request_send_result(request, -EPERM); + __request_destroy(request); + return true; + } + } + + if (request->cmd < 0 || request->cmd > ARRAY_SIZE(__request_handlers) || + __request_handlers[request->cmd] == NULL) { + _E("Unknown command: %d", request->cmd); + __request_send_result(request, -EINVAL); + return true; + } + + ret = __request_handlers[request->cmd](request); + if (ret == 1) { + _W("Request is forwarded to the worker thread"); + return true; + } + + __request_destroy(request); return true; } @@ -3232,7 +3485,11 @@ static int __before_loop(int argc, char **argv) return -1; } - ret = _worker_init(); + ret = _worker_create("cleaner+", &__cleaner); + if (ret < 0) + return ret; + + ret = _worker_create("forker+", &__forker); if (ret < 0) return ret; @@ -3251,7 +3508,8 @@ static void __after_loop(void) _log_fini(); _memory_monitor_fini(); __unregister_vconf_events(); - _worker_fini(); + _worker_destroy(__forker); + _worker_destroy(__cleaner); if (__pid_table) g_hash_table_destroy(__pid_table); diff --git a/src/launchpad-process-pool/src/launchpad_worker.c b/src/launchpad-process-pool/src/launchpad_worker.c index 3f600d7..019e4a2 100644 --- a/src/launchpad-process-pool/src/launchpad_worker.c +++ b/src/launchpad-process-pool/src/launchpad_worker.c @@ -35,19 +35,18 @@ struct job_s { }; struct worker_s { + char *name; GThread *thread; GMutex mutex; GCond cond; GQueue *queue; }; -static struct worker_s __worker; - -int _worker_add_job(worker_job_cb callback, void *user_data) +int _worker_add_job(worker_h worker, worker_job_cb callback, void *user_data) { struct job_s *job; - if (!callback) { + if (!worker || !callback) { _E("Invalid parameter"); return -EINVAL; } @@ -61,10 +60,10 @@ int _worker_add_job(worker_job_cb callback, void *user_data) job->callback = callback; job->user_data = user_data; - g_mutex_lock(&__worker.mutex); - g_queue_push_tail(__worker.queue, job); - g_cond_signal(&__worker.cond); - g_mutex_unlock(&__worker.mutex); + g_mutex_lock(&worker->mutex); + g_queue_push_tail(worker->queue, job); + g_cond_signal(&worker->cond); + g_mutex_unlock(&worker->mutex); return 0; } @@ -101,7 +100,7 @@ static gpointer __worker_thread_cb(gpointer data) struct job_s *job; bool done = false; - __set_comm("worker"); + __set_comm(worker->name); do { g_mutex_lock(&worker->mutex); if (g_queue_is_empty(worker->queue)) @@ -116,25 +115,46 @@ static gpointer __worker_thread_cb(gpointer data) return NULL; } -int _worker_init(void) +int _worker_create(const char *name, worker_h *worker) { - _W("WORKER_INIT"); + struct worker_s *handle; + + if (name == NULL || worker == NULL) { + _E("Invalid parameter"); + return -EINVAL; + } + + handle = calloc(1, sizeof(struct worker_s)); + if (handle == NULL) { + _E("calloc() is failed"); + return -ENOMEM; + } + + g_mutex_init(&handle->mutex); + g_cond_init(&handle->cond); - g_mutex_init(&__worker.mutex); - g_cond_init(&__worker.cond); + handle->name = strdup(name); + if (!handle->name) { + _E("strdup() is failed"); + _worker_destroy(handle); + return -ENOMEM; + } - __worker.queue = g_queue_new(); - if (!__worker.queue) { + handle->queue = g_queue_new(); + if (!handle->queue) { _E("g_queue_new() is failed"); + _worker_destroy(handle); return -ENOMEM; } - __worker.thread = g_thread_new("worker", __worker_thread_cb, &__worker); - if (!__worker.thread) { + handle->thread = g_thread_new(name, __worker_thread_cb, handle); + if (!handle->thread) { _E("g_thread_new() is failed"); + _worker_destroy(handle); return -ENOMEM; } + *worker = handle; return 0; } @@ -144,18 +164,23 @@ static bool __worker_done_cb(void *user_data) return true; } -void _worker_fini(void) +void _worker_destroy(worker_h worker) { - _W("WORKER_FINI"); + if (worker == NULL) + return; - if (__worker.thread) { - _worker_add_job(__worker_done_cb, NULL); - g_thread_join(__worker.thread); + if (worker->thread) { + _worker_add_job(worker, __worker_done_cb, NULL); + g_thread_join(worker->thread); } - if (__worker.queue) - g_queue_free_full(__worker.queue, (GDestroyNotify)free); + if (worker->queue) + g_queue_free_full(worker->queue, (GDestroyNotify)free); + + if (worker->name) + free(worker->name); - g_cond_clear(&__worker.cond); - g_mutex_clear(&__worker.mutex); + g_cond_clear(&worker->cond); + g_mutex_clear(&worker->mutex); + free(worker); } -- 2.7.4 From dd012c262f60b26e2ff75d4187b0e34d0496cd36 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 14 Nov 2022 05:40:02 +0000 Subject: [PATCH 10/16] Release version 0.20.0 Changes: - Create a child process in the worker thread Change-Id: I411e8cc77ff26bb7f733c0d0c974312eb2acba57 Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 574dbae..fb74f55 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.19.3 +Version: 0.20.0 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From de5b982716f8d7459eee11eb3f5cd442f3dd11ae Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 15 Nov 2022 00:06:39 +0000 Subject: [PATCH 11/16] Move calling fork() to main thread After the previous patchset is applied, dyntranstion feature is not working fine as below: +------------------------------------------------------------------------------+ | security_manager_sync_threads_internal(671) > Not all threads synchronized: | | threads left: 15 | | operator()(1013) > Can't properly setup application threads (Smack label & | | capabilities) for application | +------------------------------------------------------------------------------+ To avoid the issue, creating a child process for a candidate process is moved to the main thread. Change-Id: If58914fb04b8b07782f624ffcc1b9342ad1a7b4a Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/src/launchpad.c | 62 +++++++++--------------------- 1 file changed, 18 insertions(+), 44 deletions(-) diff --git a/src/launchpad-process-pool/src/launchpad.c b/src/launchpad-process-pool/src/launchpad.c index 3d03c43..1d2eb62 100644 --- a/src/launchpad-process-pool/src/launchpad.c +++ b/src/launchpad-process-pool/src/launchpad.c @@ -944,47 +944,6 @@ static int __candidate_info_create(candidate_process_context_t *cpt, return 0; } -static gboolean __handle_exec_loader_process(gpointer user_data) -{ - candidate_process_context_t *cpt; - candidate_info_t *info = user_data; - - _W("Candidate process. type: %d, loader_id: %d, pid: %d", - info->type, info->loader_id, info->pid); - if (info->pid > 0) { - cpt = __find_slot(info->type, info->loader_id); - cpt->last_exec_time = time(NULL); - if (cpt->is_hydra) { - cpt->hydra_pid = info->pid; - } else { - cpt->pid = info->pid; - __set_live_timer(cpt); - } - - _log_print("[CANDIDATE]", "pid(%7d) | type(%d) | loader(%s)", - info->pid, cpt->loader_id, cpt->loader_name); - _memory_monitor_reset_timer(); - } - - __candidate_info_free(info); - return G_SOURCE_REMOVE; -} - -static bool __exec_loader_process_cb(void *user_data) -{ - candidate_info_t *info = user_data; - - if (info == NULL) - return false; - - info->pid = __fork_app_process(__exec_loader_process, info->argv); - if (info->pid == -1) - _E("Failed to create a child process"); - - g_idle_add(__handle_exec_loader_process, info); - return false; -} - static int __prepare_candidate_process(int type, int loader_id) { candidate_process_context_t *cpt = __find_slot(type, loader_id); @@ -1002,13 +961,28 @@ static int __prepare_candidate_process(int type, int loader_id) if (ret < 0) return ret; - ret = _worker_add_job(__forker, __exec_loader_process_cb, info); - if (ret != 0) { - _E("_worker_add_job() is failed"); + info->pid = __fork_app_process(__exec_loader_process, info->argv); + if (info->pid == -1) { + _E("Failed to create a child process. type: %d", type); __candidate_info_free(info); return -1; } + _W("Candidate process. type: %d, loader_id: %d, pid: %d", + info->type, info->loader_id, info->pid); + cpt = __find_slot(info->type, info->loader_id); + cpt->last_exec_time = time(NULL); + if (cpt->is_hydra) { + cpt->hydra_pid = info->pid; + } else { + cpt->pid = info->pid; + __set_live_timer(cpt); + } + + _log_print("[CANDIDATE]", "pid(%7d) | type(%d) | loader(%s)", + info->pid, cpt->loader_id, cpt->loader_name); + _memory_monitor_reset_timer(); + __candidate_info_free(info); return 0; } -- 2.7.4 From 3d09196a1b43fa1889858db30e0a7f56e95b8a56 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 15 Nov 2022 02:37:57 +0000 Subject: [PATCH 12/16] Release version 0.20.1 Changes: - Move calling fork() to main thread Change-Id: If303c4ccb6c820206133bf0fe0be931eca7c9d6e Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index fb74f55..21a8a2d 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.20.0 +Version: 0.20.1 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From fb5923d897e00c0e33d9a295ba82ab0560f75d8f Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 17 Nov 2022 22:49:05 +0000 Subject: [PATCH 13/16] Make enumeration for commands This patch defines enumeration for launchpad commands. Change-Id: Iee03d39889d7f1b0d2a051d97167f4045f1d23c8 Signed-off-by: Hwankyu Jhun --- src/lib/common/inc/launchpad_common.h | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/lib/common/inc/launchpad_common.h b/src/lib/common/inc/launchpad_common.h index a1a7784..000606a 100644 --- a/src/lib/common/inc/launchpad_common.h +++ b/src/lib/common/inc/launchpad_common.h @@ -40,17 +40,6 @@ #define AUL_SOCK_MAXBUFF 131071 #define LOADER_ARG_LEN 1024 -#define PAD_CMD_LAUNCH 0 -#define PAD_CMD_VISIBILITY 10 -#define PAD_CMD_ADD_LOADER 11 -#define PAD_CMD_REMOVE_LOADER 12 -#define PAD_CMD_MAKE_DEFAULT_SLOTS 13 -#define PAD_CMD_DEMAND 14 -#define PAD_CMD_PING 15 -#define PAD_CMD_UPDATE_APP_TYPE 16 -#define PAD_CMD_PREPARE_APP_DEFINED_LOADER 17 -#define PAD_CMD_CONNECT 18 - #define LAUNCHPAD_LAUNCH_SIGNAL 83 #define LAUNCHPAD_DEAD_SIGNAL 61 #define APP_STARTUP_SIGNAL 89 @@ -83,6 +72,19 @@ extern "C" { #endif +typedef enum { + PAD_CMD_LAUNCH = 0, + PAD_CMD_VISIBILITY = 10, + PAD_CMD_ADD_LOADER = 11, + PAD_CMD_REMOVE_LOADER = 12, + PAD_CMD_MAKE_DEFAULT_SLOTS = 13, + PAD_CMD_DEMAND = 14, + PAD_CMD_PING = 15, + PAD_CMD_UPDATE_APP_TYPE = 16, + PAD_CMD_PREPARE_APP_DEFINED_LOADER = 17, + PAD_CMD_CONNECT = 18, +} pad_cmd_e; + typedef struct _app_pkt_t { int cmd; int len; -- 2.7.4 From b4dfef6155a1f63191e3a22509e9ce8368800ab2 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 17 Nov 2022 23:51:04 +0000 Subject: [PATCH 14/16] Modify slot addition function To reduce the number of parameters of the __add_slot() function, the slot_info_t is added. Change-Id: I487e1eb1172ff667531c7ad2e9c6a1ff3fdf3296 Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/inc/slot_info.h | 42 ++++++ src/launchpad-process-pool/src/launchpad.c | 232 ++++++++++++++--------------- 2 files changed, 154 insertions(+), 120 deletions(-) create mode 100644 src/launchpad-process-pool/inc/slot_info.h diff --git a/src/launchpad-process-pool/inc/slot_info.h b/src/launchpad-process-pool/inc/slot_info.h new file mode 100644 index 0000000..fdb08b7 --- /dev/null +++ b/src/launchpad-process-pool/inc/slot_info.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 __SLOT_INFO_H__ +#define __SLOT_INFO_H__ + +#include + +typedef struct slot_info_s { + int type; + int loader_id; + int caller_pid; + const char *loader_name; + const char *loader_path; + const char *loader_extra; + int detection_method; + int activation_method; + int deactivation_method; + unsigned int ttl; + int timeout_val; + int threshold_max; + int threshold_min; + bool on_boot; + bool app_exists; + bool is_hydra; + bool app_check; +} slot_info_t; + +#endif /* __SLOT_INFO_H__ */ diff --git a/src/launchpad-process-pool/src/launchpad.c b/src/launchpad-process-pool/src/launchpad.c index 1d2eb62..22edbea 100644 --- a/src/launchpad-process-pool/src/launchpad.c +++ b/src/launchpad-process-pool/src/launchpad.c @@ -57,6 +57,7 @@ #include "launchpad_worker.h" #include "loader_info.h" #include "perf.h" +#include "slot_info.h" #define AUL_PR_NAME 16 #define EXEC_CANDIDATE_EXPIRED 5 @@ -214,13 +215,7 @@ static int __client_fd = -1; static worker_h __cleaner; static worker_h __forker; -static candidate_process_context_t *__add_slot(int type, int loader_id, - int caller_pid, const char *loader_name, - const char *loader_path, const char *extra, - int detection_method, int activation_method, - int deactivation_method, unsigned int ttl, int timeout_val, - int threshold_max, int threshold_min, bool on_boot, - bool app_exists, bool is_hydra, bool app_check); +static candidate_process_context_t *__add_slot(slot_info_t *info); static int __remove_slot(int type, int loader_id); static int __add_default_slots(void); static gboolean __handle_idle_checker(gpointer data); @@ -1907,44 +1902,51 @@ static int __dispatch_cmd_add_loader(bundle *kb) int lid, size; char *loader_name; candidate_process_context_t *cpc; + slot_info_t slot_info; _W("cmd add loader"); add_slot_str = bundle_get_val(kb, AUL_K_LOADER_PATH); caller_pid = bundle_get_val(kb, AUL_K_CALLER_PID); extra = bundle_get_val(kb, AUL_K_LOADER_EXTRA); - if (add_slot_str && caller_pid) { - lid = __make_loader_id(); - - size = snprintf(0, 0, "%s%s%d", add_slot_str, caller_pid, lid); - loader_name = (char *)malloc(size + 1); - if (loader_name == NULL) { - _E("Out of memory"); - return -1; - } + if (add_slot_str == NULL || caller_pid == NULL) + return -1; - snprintf(loader_name, size, "%s%s%d", add_slot_str, caller_pid, lid); - - cpc = __add_slot(LAUNCHPAD_LOADER_TYPE_DYNAMIC, lid, - atoi(caller_pid), loader_name, - add_slot_str, extra, - METHOD_TIMEOUT | METHOD_VISIBILITY, - METHOD_REQUEST | METHOD_AVAILABLE_MEMORY, - METHOD_TTL | METHOD_OUT_OF_MEMORY, - 600, - 2000, - DEFAULT_CPU_THRESHOLD_MAX, - DEFAULT_CPU_THRESHOLD_MIN, - false, - true, - false, - true); - __set_timer(cpc); - free(loader_name); - return lid; + lid = __make_loader_id(); + size = snprintf(0, 0, "%s%s%d", add_slot_str, caller_pid, lid); + loader_name = (char *)malloc(size + 1); + if (loader_name == NULL) { + _E("Out of memory"); + return -1; } - return -1; + snprintf(loader_name, size, "%s%s%d", add_slot_str, caller_pid, lid); + + slot_info.type = LAUNCHPAD_LOADER_TYPE_DYNAMIC; + slot_info.loader_id = lid; + slot_info.caller_pid = atoi(caller_pid); + slot_info.loader_name = loader_name; + slot_info.loader_path = add_slot_str; + slot_info.loader_extra = extra; + slot_info.detection_method = METHOD_TIMEOUT | METHOD_VISIBILITY; + slot_info.activation_method = METHOD_REQUEST | METHOD_AVAILABLE_MEMORY; + slot_info.deactivation_method = METHOD_TTL | METHOD_OUT_OF_MEMORY; + slot_info.ttl = 600; + slot_info.timeout_val = 2000; + slot_info.threshold_max = DEFAULT_CPU_THRESHOLD_MAX; + slot_info.threshold_min = DEFAULT_CPU_THRESHOLD_MIN; + slot_info.on_boot = false; + slot_info.app_exists = true; + slot_info.is_hydra = false; + slot_info.app_check = true; + + cpc = __add_slot(&slot_info); + free(loader_name); + if (cpc == NULL) + return -1; + + __set_timer(cpc); + return lid; } static int __dispatch_cmd_add_app_defined_loader(bundle *kb) @@ -1954,6 +1956,7 @@ static int __dispatch_cmd_add_app_defined_loader(bundle *kb) candidate_process_context_t *cpc; loader_info_t *info; bundle_raw *extra; + slot_info_t slot_info; _W("cmd add defined loader"); loader_name = bundle_get_val(kb, AUL_K_LOADER_NAME); @@ -1975,20 +1978,27 @@ static int __dispatch_cmd_add_app_defined_loader(bundle *kb) if (cpc == NULL) { lid = __make_loader_id(); bundle_encode(info->extra, &extra, &len); - cpc = __add_slot(LAUNCHPAD_LOADER_TYPE_DYNAMIC, lid, 0, - loader_name, "/usr/bin/app-defined-loader", (const char *)extra, - METHOD_TIMEOUT | METHOD_VISIBILITY, - METHOD_REQUEST | METHOD_AVAILABLE_MEMORY, - METHOD_TTL | METHOD_OUT_OF_MEMORY, - info->ttl, - 2000, - DEFAULT_CPU_THRESHOLD_MAX, - DEFAULT_CPU_THRESHOLD_MIN, - false, - true, - false, - true); - + slot_info.type = LAUNCHPAD_LOADER_TYPE_DYNAMIC; + slot_info.loader_id = lid; + slot_info.caller_pid = 0; + slot_info.loader_name = loader_name; + slot_info.loader_path = "/usr/bin/app-defined-loader"; + slot_info.loader_extra = (const char *)extra; + slot_info.detection_method = METHOD_TIMEOUT | METHOD_VISIBILITY; + slot_info.activation_method = + METHOD_REQUEST | METHOD_AVAILABLE_MEMORY; + slot_info.deactivation_method = + METHOD_TTL | METHOD_OUT_OF_MEMORY; + slot_info.ttl = info->ttl; + slot_info.timeout_val = 2000; + slot_info.threshold_max = DEFAULT_CPU_THRESHOLD_MAX; + slot_info.threshold_min = DEFAULT_CPU_THRESHOLD_MIN; + slot_info.on_boot = false; + slot_info.app_exists = true; + slot_info.is_hydra = false; + slot_info.app_check = true; + + cpc = __add_slot(&slot_info); bundle_free_encoded_rawdata(&extra); if (cpc == NULL) { _E("cpc is NULL"); @@ -2635,13 +2645,7 @@ static void __destroy_slot(candidate_process_context_t *cpc) free(cpc); } -static candidate_process_context_t *__create_slot(int type, int loader_id, - int caller_pid, const char *loader_name, const char *loader_path, - const char *loader_extra, int detection_method, - int activation_method, int deactivation_method, - unsigned int ttl, int timeout_val, - int threshold_max, int threshold_min, - bool on_boot, bool app_exists, bool is_hydra, bool app_check) +static candidate_process_context_t *__create_slot(slot_info_t *info) { candidate_process_context_t *cpc; @@ -2651,55 +2655,55 @@ static candidate_process_context_t *__create_slot(int type, int loader_id, return NULL; } - cpc->loader_name = strdup(loader_name); + cpc->loader_name = strdup(info->loader_name); if (cpc->loader_name == NULL) { - _E("Failed to duplicate loader name(%s)", loader_name); + _E("Failed to duplicate loader name(%s)", info->loader_name); __destroy_slot(cpc); return NULL; } - cpc->loader_path = strdup(loader_path); + cpc->loader_path = strdup(info->loader_path); if (cpc->loader_path == NULL) { - _E("Failed to duplicate loader path(%s)", loader_path); + _E("Failed to duplicate loader path(%s)", info->loader_path); __destroy_slot(cpc); return NULL; } - cpc->loader_extra = loader_extra ? strdup(loader_extra) : strdup(""); + cpc->loader_extra = + info->loader_extra ? strdup(info->loader_extra) : strdup(""); if (cpc->loader_extra == NULL) { - _E("Failed to duplicate loader extra(%s)", - loader_extra ? loader_extra : "null"); + _E("Failed to duplicate loader extra(%s)", info->loader_extra); __destroy_slot(cpc); return NULL; } - cpc->type = type; + cpc->type = info->type; cpc->prepared = false; cpc->pid = CANDIDATE_NONE; cpc->hydra_pid = HYDRA_NONE; - cpc->caller_pid = caller_pid; - cpc->loader_id = loader_id; + cpc->caller_pid = info->caller_pid; + cpc->loader_id = info->loader_id; cpc->send_fd = -1; cpc->hydra_fd = -1; cpc->last_exec_time = 0; cpc->timer = 0; - cpc->detection_method = detection_method; - cpc->timeout_val = timeout_val; + cpc->detection_method = info->detection_method; + cpc->timeout_val = info->timeout_val; cpc->cpu_total_time = 0; cpc->cpu_idle_time = 0; - cpc->threshold = threshold_max; - cpc->threshold_max = threshold_max; - cpc->threshold_min = threshold_min; - cpc->on_boot = on_boot; - cpc->app_exists = app_exists; + cpc->threshold = info->threshold_max; + cpc->threshold_max = info->threshold_max; + cpc->threshold_min = info->threshold_min; + cpc->on_boot = info->on_boot; + cpc->app_exists = info->app_exists; cpc->touched = false; cpc->cur_event = 0; - cpc->activation_method = activation_method; - cpc->deactivation_method = deactivation_method; - cpc->ttl = ttl; + cpc->activation_method = info->activation_method; + cpc->deactivation_method = info->deactivation_method; + cpc->ttl = info->ttl; cpc->live_timer = 0; - cpc->is_hydra = is_hydra; - cpc->app_check = app_check; + cpc->is_hydra = info->is_hydra; + cpc->app_check = info->app_check; cpc->score = WIN_SCORE; cpc->pss = 0; cpc->cpu_check_count = 0; @@ -2715,13 +2719,7 @@ static candidate_process_context_t *__create_slot(int type, int loader_id, return cpc; } -static candidate_process_context_t *__add_slot(int type, int loader_id, - int caller_pid, const char *loader_name, const char *loader_path, - const char *loader_extra, int detection_method, - int activation_method, int deactivation_method, - unsigned int ttl, int timeout_val, - int threshold_max, int threshold_min, - bool on_boot, bool app_exists, bool is_hydra, bool app_check) +static candidate_process_context_t *__add_slot(slot_info_t *info) { candidate_process_context_t *cpc; int fd; @@ -2729,16 +2727,13 @@ static candidate_process_context_t *__add_slot(int type, int loader_id, int hydra_fd; io_channel_h hydra_channel; - if (__find_slot(type, loader_id) != NULL) + if (info == NULL) + return NULL; + + if (__find_slot(info->type, info->loader_id) != NULL) return NULL; - cpc = __create_slot(type, loader_id, - caller_pid, loader_name, loader_path, - loader_extra, detection_method, - activation_method, deactivation_method, - ttl, timeout_val, - threshold_max, threshold_min, - on_boot, app_exists, is_hydra, app_check); + cpc = __create_slot(info); if (cpc == NULL) return NULL; @@ -2760,7 +2755,7 @@ static candidate_process_context_t *__add_slot(int type, int loader_id, cpc->channel = channel; - if (is_hydra) { + if (info->is_hydra) { hydra_fd = __listen_hydra_process(cpc->type, cpc->loader_id); if (hydra_fd == -1) { _E("[launchpad] Listening the socket to " \ @@ -2781,7 +2776,6 @@ static candidate_process_context_t *__add_slot(int type, int loader_id, cpc->hydra_channel = hydra_channel; } - candidate_slot_list = g_list_append(candidate_slot_list, cpc); return cpc; @@ -3029,18 +3023,21 @@ static void __add_slot_from_info(gpointer data, gpointer user_data) bundle_raw *extra = NULL; int len; char buf[2048] = {0, }; + slot_info_t slot_info = { + .type = LAUNCHPAD_LOADER_TYPE_USER + user_slot_offset, + .loader_name = info->name, + .loader_path = info->exe, + .threshold_max = info->cpu_threshold_max, + .threshold_min = info->cpu_threshold_min, + .app_exists = info->app_exists, + .is_hydra = info->is_hydra, + .app_check = info->app_check, + }; if (!strcmp(info->exe, "null")) { - cpc = __add_slot(LAUNCHPAD_LOADER_TYPE_USER + user_slot_offset, - PAD_LOADER_ID_DIRECT, - 0, info->name, info->exe, NULL, - 0, 0, 0, 0, 0, - info->cpu_threshold_max, - info->cpu_threshold_min, - false, - info->app_exists, - info->is_hydra, - info->app_check); + slot_info.loader_id = PAD_LOADER_ID_DIRECT; + + cpc = __add_slot(&slot_info); if (cpc == NULL) return; @@ -3056,21 +3053,16 @@ static void __add_slot_from_info(gpointer data, gpointer user_data) if (info->extra) bundle_encode(info->extra, &extra, &len); - cpc = __add_slot(LAUNCHPAD_LOADER_TYPE_USER + user_slot_offset, - PAD_LOADER_ID_STATIC, - 0, info->name, info->exe, (char *)extra, - info->detection_method, - info->activation_method, - info->deactivation_method, - info->ttl, - info->timeout_val, - info->cpu_threshold_max, - info->cpu_threshold_min, - info->on_boot, - info->app_exists, - info->is_hydra, - info->app_check); + slot_info.loader_id = PAD_LOADER_ID_STATIC; + slot_info.loader_extra = (const char *)extra; + slot_info.detection_method = info->detection_method; + slot_info.activation_method = info->activation_method; + slot_info.deactivation_method = info->deactivation_method; + slot_info.ttl = info->ttl; + slot_info.timeout_val = info->timeout_val; + slot_info.on_boot = info->on_boot; + cpc = __add_slot(&slot_info); bundle_free_encoded_rawdata(&extra); if (cpc == NULL) return; -- 2.7.4 From f65bd8fbc63ce9e28d50555c1f0ea86c499b631a Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 18 Nov 2022 00:26:46 +0000 Subject: [PATCH 15/16] Support timeout feature related on boot To exeucte the loader process forcedly, the feature is supported. "ON_BOOT_TIMEOUT" tag is added for parsing on boot timeout value. Even if the CPU threshold is not exceeded, the loader process will be executed by the timer. Change-Id: I6a588d28ed1c81685f5718b9c03a680d6d0631d3 Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/inc/loader_info.h | 1 + src/launchpad-process-pool/inc/slot_info.h | 1 + src/launchpad-process-pool/src/launchpad.c | 45 ++++++++++++++++++++++++++++ src/launchpad-process-pool/src/loader_info.c | 8 +++-- 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/launchpad-process-pool/inc/loader_info.h b/src/launchpad-process-pool/inc/loader_info.h index e3ae865..79ec242 100644 --- a/src/launchpad-process-pool/inc/loader_info.h +++ b/src/launchpad-process-pool/inc/loader_info.h @@ -54,6 +54,7 @@ typedef struct _loader_info { unsigned int ttl; bool is_hydra; bool app_check; + int on_boot_timeout; } loader_info_t; typedef void (*loader_info_foreach_cb)(loader_info_t *info, void *data); diff --git a/src/launchpad-process-pool/inc/slot_info.h b/src/launchpad-process-pool/inc/slot_info.h index fdb08b7..31cbc16 100644 --- a/src/launchpad-process-pool/inc/slot_info.h +++ b/src/launchpad-process-pool/inc/slot_info.h @@ -37,6 +37,7 @@ typedef struct slot_info_s { bool app_exists; bool is_hydra; bool app_check; + int on_boot_timeout; } slot_info_t; #endif /* __SLOT_INFO_H__ */ diff --git a/src/launchpad-process-pool/src/launchpad.c b/src/launchpad-process-pool/src/launchpad.c index 22edbea..1e88226 100644 --- a/src/launchpad-process-pool/src/launchpad.c +++ b/src/launchpad-process-pool/src/launchpad.c @@ -129,6 +129,8 @@ typedef struct { unsigned int score; unsigned int pss; int cpu_check_count; + int on_boot_timeout; + guint on_boot_timer; } candidate_process_context_t; typedef struct { @@ -1021,6 +1023,7 @@ static void __reset_slot(candidate_process_context_t *cpc) cpc->client_channel = NULL; cpc->timer = 0; cpc->live_timer = 0; + cpc->on_boot_timer = 0; } static void __dispose_candidate_process(candidate_process_context_t *cpc) @@ -1041,6 +1044,8 @@ static void __dispose_candidate_process(candidate_process_context_t *cpc) g_source_remove(cpc->timer); if (cpc->send_fd > 0) close(cpc->send_fd); + if (cpc->on_boot_timer > 0) + g_source_remove(cpc->on_boot_timer); __reset_slot(cpc); } @@ -1805,6 +1810,14 @@ static gboolean __handle_idle_checker(gpointer data) return G_SOURCE_REMOVE; } + if (cpc->pid != CANDIDATE_NONE) { + _W("Slot is already running. %d:%s:%d", + cpc->type, cpc->loader_name, cpc->pid); + __sequencer.idle_checker = 0; + __sequencer.running_cpc = NULL; + return G_SOURCE_REMOVE; + } + _get_cpu_idle(&total, &idle); if (total == cpc->cpu_total_time) total++; @@ -1840,6 +1853,33 @@ static gboolean __handle_idle_checker(gpointer data) return G_SOURCE_CONTINUE; } +static gboolean __on_boot_timeout_cb(gpointer user_data) +{ + candidate_process_context_t *context = user_data; + + _W("type(%d), loader_name(%s)", context->type, context->loader_name); + context->on_boot_timer = 0; + if (context->pid != CANDIDATE_NONE) { + _E("Candidate process is already running. %d:%s:%d", + context->type, context->loader_name, + context->pid); + } else { + __prepare_candidate_process(context->type, context->loader_id); + context->touched = true; + } + + return G_SOURCE_REMOVE; +} + +static void __add_on_boot_timer(candidate_process_context_t *context) +{ + if (context->on_boot_timer != 0) + return; + + context->on_boot_timer = g_timeout_add(context->on_boot_timeout, + __on_boot_timeout_cb, context); +} + static int __add_idle_checker(int detection_method, GList *cur) { candidate_process_context_t *cpc; @@ -1862,6 +1902,9 @@ static int __add_idle_checker(int detection_method, GList *cur) continue; } + if (!cpc->touched && cpc->on_boot && cpc->on_boot_timeout > 0) + __add_on_boot_timer(cpc); + if (cpc->app_check && !cpc->app_exists) { iter = g_list_next(iter); continue; @@ -2707,6 +2750,7 @@ static candidate_process_context_t *__create_slot(slot_info_t *info) cpc->score = WIN_SCORE; cpc->pss = 0; cpc->cpu_check_count = 0; + cpc->on_boot_timeout = info->on_boot_timeout; if ((cpc->deactivation_method & METHOD_OUT_OF_MEMORY) && __is_low_memory()) @@ -3032,6 +3076,7 @@ static void __add_slot_from_info(gpointer data, gpointer user_data) .app_exists = info->app_exists, .is_hydra = info->is_hydra, .app_check = info->app_check, + .on_boot_timeout = info->on_boot_timeout, }; if (!strcmp(info->exe, "null")) { diff --git a/src/launchpad-process-pool/src/loader_info.c b/src/launchpad-process-pool/src/loader_info.c index 3493366..3788b90 100644 --- a/src/launchpad-process-pool/src/loader_info.c +++ b/src/launchpad-process-pool/src/loader_info.c @@ -43,6 +43,7 @@ #define TAG_ON_BOOT "ON_BOOT" #define TAG_HYDRA "HYDRA" #define TAG_APP_CHECK "APP_CHECK" +#define TAG_ON_BOOT_TIMEOUT "ON_BOOT_TIMEOUT" #define VAL_ON "ON" #define VAL_OFF "OFF" @@ -302,14 +303,15 @@ static GList *__parse_file(GList *list, const char *path) if (tok2 && strcasecmp(VAL_OFF, tok2) == 0) cur_info->on_boot = false; } else if (strcasecmp(TAG_HYDRA, tok1) == 0) { - if (strcasecmp(VAL_ON, tok2) == 0) { + if (strcasecmp(VAL_ON, tok2) == 0) cur_info->is_hydra = 1; - } else { + else cur_info->is_hydra = 0; - } } else if (strcasecmp(TAG_APP_CHECK, tok1) == 0) { if (tok2 && strcasecmp(VAL_OFF, tok2) == 0) cur_info->app_check = false; + } else if (strcasecmp(TAG_ON_BOOT_TIMEOUT, tok1) == 0) { + cur_info->on_boot_timeout = atoi(tok2); } } -- 2.7.4 From 9170b9d2372f24a31006f40cb823af51965c5709 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 18 Nov 2022 02:19:52 +0000 Subject: [PATCH 16/16] Release version 0.21.0 Changes: - Make enumeration for commands - Modify slot addition function - Support timeout feature related on boot Change-Id: I7d588a3ef2c0d3360d6f158d9938749e6eb78768 Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 21a8a2d..2ef53bc 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.20.1 +Version: 0.21.0 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4