From c29ee0b719c521961214606cdd450133cce2a128 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 22 Aug 2019 10:46:01 +0900 Subject: [PATCH 01/16] Fix error log message Change-Id: I39ca41aeb806388c4e8a37ccf1c4c913668d133e Signed-off-by: Hwankyu Jhun --- src/launchpad_loader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/launchpad_loader.c b/src/launchpad_loader.c index 849b050..cf92185 100644 --- a/src/launchpad_loader.c +++ b/src/launchpad_loader.c @@ -341,8 +341,8 @@ do_dlopen: handle = dlopen(argv[LOADER_ARG_PATH], RTLD_LAZY | RTLD_GLOBAL | RTLD_NODELETE); if (handle == NULL) { - _E("dlopen failed(%s). Please complile with -fPIE and " \ - "link with -pie flag", dlerror()); + _E("dlopen(%s) is failed. error(%s)", + argv[LOADER_ARG_PATH], dlerror()); goto do_exec; } -- 2.7.4 From db2580ea7b17d38b7032d35083d5caebfed07502 Mon Sep 17 00:00:00 2001 From: Yunmi Ha Date: Tue, 20 Aug 2019 08:12:37 +0000 Subject: [PATCH 02/16] Revert "tizen: Add additional unit for "unified" user session" This reverts commit 371f1ade513b56bb89b8ecedbef16d6c3d7392c3. We've optimized systemd-user without unified system/session. So, we revert the patch for unified system/session. Change-Id: I9102ccb19b82e3321c4e67d5f30c09643a85e585 --- packaging/launchpad-process-pool@.service | 28 ---------------------------- packaging/launchpad-process-pool@.socket | 12 ------------ packaging/launchpad.spec | 13 ------------- 3 files changed, 53 deletions(-) delete mode 100644 packaging/launchpad-process-pool@.service delete mode 100644 packaging/launchpad-process-pool@.socket diff --git a/packaging/launchpad-process-pool@.service b/packaging/launchpad-process-pool@.service deleted file mode 100644 index 92b1b4b..0000000 --- a/packaging/launchpad-process-pool@.service +++ /dev/null @@ -1,28 +0,0 @@ -# -# Systemd script to Launch AMD Session agent -# - -[Unit] -PartOf=userlogin@%i.target -Description=Start the USER Access Control Agent -DefaultDependencies=no -Requires=enlightenment-user@%i.service -After=enlightenment-user@%i.service - -[Service] -User=%i -Environment=DBUS_SESSION_BUS_ADDRESS=kernel:path=/sys/fs/kdbus/%i-user/bus;unix:path=/run/user/%i/bus -Environment=XDG_RUNTIME_DIR=/run/user/%i -SmackProcessLabel=User -Capabilities=cap_sys_admin,cap_mac_admin,cap_setgid,cap_dac_override=i -SecureBits=keep-caps -ExecStartPre=-/usr/bin/mkdir -p /run/aul/daemons/%i -ExecStartPre=-/usr/bin/chmod 0777 /run/aul/daemons/%i -ExecStartPre=-/usr/bin/mkdir -p /run/aul/apps/%i -ExecStartPre=-/usr/bin/chmod 0700 /run/aul/apps/%i -ExecStartPre=-/usr/bin/mkdir -p /run/aul/dbspace/%i -ExecStartPre=-/usr/bin/chmod 0701 /run/aul/dbspace/%i -ExecStartPre=-/usr/bin/mkdir -p /run/aul/log/widget/%i -ExecStartPre=-/usr/bin/chmod 0777 /run/aul/log/widget/%i -ExecStart=/bin/sh -l -c "/usr/bin/launchpad-process-pool" -Sockets=launchpad-process-pool@%i.socket diff --git a/packaging/launchpad-process-pool@.socket b/packaging/launchpad-process-pool@.socket deleted file mode 100644 index c408ac3..0000000 --- a/packaging/launchpad-process-pool@.socket +++ /dev/null @@ -1,12 +0,0 @@ -[Unit] -PartOf=userlogin@%i.target -DefaultDependencies=no -After=systemd-logind.service -[Socket] -SocketUser=%i -ListenStream=/run/aul/daemons/%i/.launchpad-process-pool-sock -DirectoryMode=0777 -Service=launchpad-process-pool@%i.service - -[Install] -WantedBy=user-sockets@.target diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 895e9ec..e50fc06 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -7,8 +7,6 @@ License: Apache-2.0 Source0: %{name}-%{version}.tar.gz Source101: launchpad-process-pool.service Source102: launchpad-process-pool.socket -Source201: launchpad-process-pool@.service -Source202: launchpad-process-pool@.socket BuildRequires: cmake @@ -118,13 +116,6 @@ install -m 0644 %SOURCE102 %{buildroot}%{_unitdir_user}/launchpad-process-pool.s ln -sf ../launchpad-process-pool.socket %{buildroot}%{_unitdir_user}/sockets.target.wants/launchpad-process-pool.socket ln -sf ../launchpad-process-pool.service %{buildroot}%{_unitdir_user}/basic.target.wants/launchpad-process-pool.service -mkdir -p %{buildroot}%{_unitdir}/user-basic@.target.wants -mkdir -p %{buildroot}%{_unitdir}/user-sockets@.target.wants -install -m 0644 %SOURCE201 %{buildroot}%{_unitdir}/launchpad-process-pool@.service -install -m 0644 %SOURCE202 %{buildroot}%{_unitdir}/launchpad-process-pool@.socket -ln -sf ../launchpad-process-pool@.socket %{buildroot}%{_unitdir}/user-sockets@.target.wants/launchpad-process-pool@.socket -ln -sf ../launchpad-process-pool@.service %{buildroot}%{_unitdir}/user-basic@.target.wants/launchpad-process-pool@.service - %post %files @@ -135,10 +126,6 @@ ln -sf ../launchpad-process-pool@.service %{buildroot}%{_unitdir}/user-basic@.ta %{_unitdir_user}/launchpad-process-pool.socket %{_unitdir_user}/sockets.target.wants/launchpad-process-pool.socket %{_unitdir_user}/basic.target.wants/launchpad-process-pool.service -%{_unitdir}/launchpad-process-pool@.service -%{_unitdir}/launchpad-process-pool@.socket -%{_unitdir}/user-sockets@.target.wants/launchpad-process-pool@.socket -%{_unitdir}/user-basic@.target.wants/launchpad-process-pool@.service %{_bindir}/launchpad-process-pool %{_prefix}/share/aul/launchpad.conf -- 2.7.4 From cded5c8e50ddb0d999832c16e06918b79590bd63 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 23 Aug 2019 09:22:42 +0900 Subject: [PATCH 03/16] Release version 0.7.1 Changes: - Fix error log message - Revert "tizen: Add additional unit for "unified" user session" Change-Id: Ie9184d61bce168277418f9ab85a852d6c127ed30 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 e50fc06..ed8eb7c 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.7.0 +Version: 0.7.1 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From d053c3457221714587f7c0fed5e60da6d06636e2 Mon Sep 17 00:00:00 2001 From: Tomasz Swierczek Date: Thu, 22 Aug 2019 14:02:45 +0200 Subject: [PATCH 04/16] Add candidate process preparation Setting up security context of new application requires some actions to be done in single-threaded environment (currently, this comes down to setting up per-app mount namespace). This requires to be done before custom app loader is exec'ed. Change-Id: I90735052e8cb60d49f402dbe8c8977d14aecb875 --- src/launchpad.c | 8 ++++++++ src/launchpad_lib.c | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/launchpad.c b/src/launchpad.c index 17c7449..6a676d9 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -571,6 +571,14 @@ static int __fork_app_process(int (*child_fn)(void *), void *arg) } if (pid == 0) { + _W("security_manager_prepare_app_candidate ++"); + ret = security_manager_prepare_app_candidate(); + _W("security_manager_prepare_app_candidate --"); + if (ret != SECURITY_MANAGER_SUCCESS) { + _E("failed to prepare app candidate process (%d)", ret); + exit(1); + } + ret = child_fn(arg); _E("failed to exec app process (%d)", errno); exit(ret); diff --git a/src/launchpad_lib.c b/src/launchpad_lib.c index 4041141..1b88835 100644 --- a/src/launchpad_lib.c +++ b/src/launchpad_lib.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2019 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. -- 2.7.4 From f2472eb0cb99988556f47bac16b67479964907e8 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 27 Aug 2019 10:21:44 +0900 Subject: [PATCH 05/16] Release version 0.8.0 Changes: - Add candidate process preparation Change-Id: I2d2ba1ca6269cf56150f1c394c5a36e80f4c744b 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 ed8eb7c..1ddb1e7 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.7.1 +Version: 0.8.0 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From e8b42e9ce8e398d9f181bef0c90b699c825986b9 Mon Sep 17 00:00:00 2001 From: INSUN PYO Date: Tue, 27 Aug 2019 09:22:53 +0900 Subject: [PATCH 06/16] Remove unnecessary setting Change-Id: I5836bf2a21239e8416ea02d8b72b1c5d6ccf3450 Signed-off-by: INSUN PYO --- packaging/launchpad-process-pool.socket | 1 - 1 file changed, 1 deletion(-) diff --git a/packaging/launchpad-process-pool.socket b/packaging/launchpad-process-pool.socket index 2306963..44edc7d 100644 --- a/packaging/launchpad-process-pool.socket +++ b/packaging/launchpad-process-pool.socket @@ -1,7 +1,6 @@ [Socket] ListenStream=/run/aul/daemons/%U/.launchpad-process-pool-sock DirectoryMode=0777 -Service=launchpad-process-pool.service [Install] WantedBy=sockets.target -- 2.7.4 From 1ccc5f258d800a0074fbc464127003a08b302168 Mon Sep 17 00:00:00 2001 From: Yeongjong Lee Date: Mon, 16 Sep 2019 11:07:34 +0900 Subject: [PATCH 07/16] Bump up efl module version. efl version is updated to 1.23, efl module patch should be synchronized with it. Change-Id: I1246299e92f637baec950f5680d9e500e58983af --- packaging/default.loader.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packaging/default.loader.in b/packaging/default.loader.in index 4b3867a..a910c96 100644 --- a/packaging/default.loader.in +++ b/packaging/default.loader.in @@ -10,12 +10,12 @@ EXTRA_ARRAY preload EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/libappcore-efl.so.1 EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/libappcore-common.so.1 EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/libcapi-appfw-application.so.0 -EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/ecore_imf/modules/wayland/v-1.22/module.so +EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/ecore_imf/modules/wayland/v-1.23/module.so EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/libdali-toolkit.so EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/libcairo.so.2 EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/libcapi-media-player.so.0 EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/libcapi-media-camera.so.0 -EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/ecore_evas/engines/extn/v-1.22/module.so +EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/ecore_evas/engines/extn/v-1.23/module.so ALTERNATIVE_LOADER common-loader1 [LOADER] @@ -29,8 +29,8 @@ EXTRA_ARRAY preload EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/libappcore-efl.so.1 EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/libappcore-common.so.1 EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/libcapi-appfw-application.so.0 -EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/ecore_imf/modules/wayland/v-1.22/module.so -EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/ecore_evas/engines/extn/v-1.22/module.so +EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/ecore_imf/modules/wayland/v-1.23/module.so +EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/ecore_evas/engines/extn/v-1.23/module.so -- 2.7.4 From ef447e76ec8a05a586d3a14bbec4848da2f91601 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 17 Sep 2019 08:11:38 +0900 Subject: [PATCH 08/16] Validate a custom loader process Before sending a launch request, the launchpad checks whether the custom loader is prepared or not. If it's not prepared, the application will be launched by exec(). Change-Id: Ibcd04f8506c41d493f1afd35bbe5c90337eb6443 Signed-off-by: Hwankyu Jhun --- src/launchpad.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/launchpad.c b/src/launchpad.c index 6a676d9..1e11e19 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -1836,6 +1836,8 @@ static gboolean __handle_launch_event(gpointer data) } else { type = LAUNCHPAD_TYPE_DYNAMIC; cpc = __find_slot(type, loader_id); + if (cpc && !cpc->prepared) + cpc = NULL; } } -- 2.7.4 From 0117c4edf8a0ccc76d4a7883673b457c8074e1c1 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 17 Sep 2019 08:45:13 +0900 Subject: [PATCH 09/16] Release version 0.8.1 Changes: - Remove unnecessary setting - Validate a custom loader process Change-Id: I5dc23690e8e983b8439b7b79a44077480754ae9e 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 1ddb1e7..fa8208f 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.8.0 +Version: 0.8.1 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From 06d1a54bbfeb308ecfe0da9e5eb4899f8dfca97a Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 17 Sep 2019 13:56:16 +0900 Subject: [PATCH 10/16] Release version 0.8.2 Changes: - Bump up efl module version. Change-Id: I472dc34df1afff50de5428449e24585247022602 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 fa8208f..fa5906b 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.8.1 +Version: 0.8.2 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From 9c425707f66f33f3e5d353894c8c3a5a73b92d78 Mon Sep 17 00:00:00 2001 From: Gleb Balykov Date: Tue, 19 Feb 2019 17:09:18 +0300 Subject: [PATCH 11/16] Introduce new API for hydra mode: typedef void (*hydra_precreate_cb)(void *user_data); typedef void (*hydra_create_cb)(void *user_data); typedef void (*hydra_fork_cb)(void *user_data); typedef int (*hydra_terminate_cb)(void *user_data); typedef struct { hydra_precreate_cb precreate; hydra_create_cb create; hydra_fork_cb fork; hydra_terminate_cb terminate; } hydra_lifecycle_callback_s; int launchpad_hydra_main(int argc, char **argv, hydra_lifecycle_callback_s *hydra_callbacks, loader_lifecycle_callback_s *callbacks, loader_adapter_s *adapter, void *user_data); In this mode candidates fork from one "hydra" candidate that allows to share memory between them: Launchpad | | (fork initial loader in hydra mode) | +----+ | loader (hydra-mode) | | launchpad_hydra_main | | precreate (hydra callback) | | (decide run in hydra mode or call launchpad_loader_main) | | create (hydra callback) | | (initial hydra fork) | +-------+-------+ <- initial candidate | | | | fork (hydra callback) | | | | launchpad_loader_main | | | (loader event loop) | | | _connect_to_launchpad_hydra | (hydra event loop) <- waits commands from launchpad | | (fork on request) | +-------+ <- new candidate | | fork (hydra callback) | | quit from hydra loop | | terminate (hydra callback) | | launchpad_loader_main | (loader event loop) Change-Id: I68566cb0e45031b9f4f8039ca2f1de09bb6dafe9 --- inc/launchpad.h | 17 ++++ inc/launchpad_common.h | 7 ++ inc/loader_info.h | 1 + src/launchpad.c | 255 +++++++++++++++++++++++++++++++++++++++++++------ src/launchpad_common.c | 30 ++++++ src/launchpad_lib.c | 250 +++++++++++++++++++++++++++++++++++++++++++++++- src/launchpad_signal.c | 22 +++-- src/loader_info.c | 8 ++ 8 files changed, 551 insertions(+), 39 deletions(-) diff --git a/inc/launchpad.h b/inc/launchpad.h index b5a11db..0dfea81 100644 --- a/inc/launchpad.h +++ b/inc/launchpad.h @@ -29,6 +29,11 @@ typedef int (*loader_launch_cb)(int argc, char **argv, const char *app_path, void *user_data); typedef int (*loader_terminate_cb)(int argc, char **argv, void *user_data); +typedef void (*hydra_precreate_cb)(void *user_data); +typedef void (*hydra_create_cb)(void *user_data); +typedef void (*hydra_fork_cb)(void *user_data); +typedef int (*hydra_terminate_cb)(void *user_data); + typedef void (*loader_receiver_cb)(int fd); typedef void (*loader_loop_begin_cb)(void *user_data); typedef void (*loader_loop_quit_cb)(void *user_data); @@ -43,6 +48,13 @@ typedef struct { } loader_lifecycle_callback_s; typedef struct { + hydra_precreate_cb precreate; + hydra_create_cb create; + hydra_fork_cb fork; + hydra_terminate_cb terminate; +} hydra_lifecycle_callback_s; + +typedef struct { loader_loop_begin_cb loop_begin; loader_loop_quit_cb loop_quit; loader_add_fd_cb add_fd; @@ -60,6 +72,11 @@ int launchpad_loader_main(int argc, char **argv, loader_lifecycle_callback_s *callbacks, loader_adapter_s *adapter, void *user_data); +int launchpad_hydra_main(int argc, char **argv, + hydra_lifecycle_callback_s *hydra_callbacks, + loader_lifecycle_callback_s *callbacks, + loader_adapter_s *adapter, void *user_data); + /* * @par Description * Set program scheduling priority. diff --git a/inc/launchpad_common.h b/inc/launchpad_common.h index b6aa841..0ebb452 100644 --- a/inc/launchpad_common.h +++ b/inc/launchpad_common.h @@ -35,6 +35,7 @@ #define SOCKET_PATH "/run/aul" #define LAUNCHPAD_LOADER_SOCKET_NAME ".launchpad-type" +#define HYDRA_LOADER_SOCKET_NAME ".hydra-loader" #define MAX_PENDING_CONNECTIONS 10 #define MAX_LOCAL_BUFSZ 128 #define AUL_SOCK_MAXBUFF 131071 @@ -77,10 +78,15 @@ enum loader_arg { LOADER_ARG_PATH, LOADER_ARG_TYPE, LOADER_ARG_ID, + LOADER_ARG_HYDRA, LOADER_ARG_EXTRA, LOADER_ARG_DUMMY, }; +enum hydra_cmd { + LAUNCH_CANDIDATE, +}; + typedef struct _app_pkt_t { int cmd; int len; @@ -113,6 +119,7 @@ app_pkt_t *_recv_pkt_raw(int fd); app_pkt_t *_accept_recv_pkt_raw(int fd, int *clifd, struct ucred *cr); int _send_pkt_raw(int client_fd, app_pkt_t *pkt); int _connect_to_launchpad(int type, int id); +int _connect_to_launchpad_hydra(int type, int id); int _set_sock_option(int fd, int cli); void _set_env(appinfo_t *menu_info, bundle *kb); char **_create_argc_argv(bundle *kb, int *margc); diff --git a/inc/loader_info.h b/inc/loader_info.h index 2245107..8714198 100644 --- a/inc/loader_info.h +++ b/inc/loader_info.h @@ -52,6 +52,7 @@ typedef struct _loader_info { int activation_method; int deactivation_method; unsigned int ttl; + bool is_hydra; } loader_info_t; typedef void (*loader_info_foreach_cb)(loader_info_t *info, void *data); diff --git a/src/launchpad.c b/src/launchpad.c index c5d097f..75d6331 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -52,6 +52,7 @@ #define EXEC_CANDIDATE_WAIT 1 #define DIFF(a, b) (((a) > (b)) ? (a) - (b) : (b) - (a)) #define CANDIDATE_NONE 0 +#define HYDRA_NONE 0 #define PROCESS_POOL_LAUNCHPAD_SOCK ".launchpad-process-pool-sock" #define LAUNCHPAD_LOGGER_SOCK ".launchpad-logger-sock" #define LOADER_PATH_DEFAULT "/usr/bin/launchpad-loader" @@ -73,10 +74,13 @@ enum candidate_process_state_e { typedef struct { int type; bool prepared; - int pid; + int pid; /* for hydra this pid is not the pid of hydra itself */ + /* but pid of non-hydra candidate, which was forked from hydra */ + int hydra_pid; int loader_id; int caller_pid; int send_fd; + int hydra_fd; int last_exec_time; guint source; guint timer; @@ -98,6 +102,7 @@ typedef struct { unsigned int ttl; guint live_timer; int state; + bool is_hydra; } candidate_process_context_t; typedef struct { @@ -145,7 +150,7 @@ static candidate_process_context_t *__add_slot(int type, int loader_id, 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 app_exists, bool is_hydra); static int __remove_slot(int type, int loader_id); static int __add_default_slots(void); static gboolean __handle_idle_checker(gpointer data); @@ -342,6 +347,22 @@ static candidate_process_context_t *__find_slot_from_pid(int pid) return NULL; } +static candidate_process_context_t *__find_hydra_slot_from_pid(int pid) +{ + candidate_process_context_t *cpc; + GList *iter = candidate_slot_list; + + while (iter) { + cpc = (candidate_process_context_t *)iter->data; + if (cpc->is_hydra && pid == cpc->hydra_pid) + return cpc; + + iter = g_list_next(iter); + } + + return NULL; +} + static candidate_process_context_t *__find_slot_from_caller_pid(int caller_pid) { candidate_process_context_t *cpc; @@ -457,34 +478,24 @@ error: return -1; } -static int __listen_candidate_process(int type, int loader_id) +static int __listen_addr(struct sockaddr_un *addr) { - struct sockaddr_un addr; int fd = -1; - - _D("[launchpad] enter, type: %d", type); - - memset(&addr, 0x00, sizeof(struct sockaddr_un)); - addr.sun_family = AF_UNIX; - snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/daemons/%d/%s%d-%d", - SOCKET_PATH, getuid(), LAUNCHPAD_LOADER_SOCKET_NAME, - type, loader_id); - fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); if (fd < 0) { _E("Socket error"); goto error; } - unlink(addr.sun_path); + unlink(addr->sun_path); - _D("bind to %s", addr.sun_path); - if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + _D("bind to %s", addr->sun_path); + if (bind(fd, (struct sockaddr *)addr, sizeof(struct sockaddr_un)) < 0) { _E("bind error"); goto error; } - _D("listen to %s", addr.sun_path); + _D("listen to %s", addr->sun_path); if (listen(fd, MAX_PENDING_CONNECTIONS) == -1) { _E("listen error"); goto error; @@ -500,6 +511,36 @@ error: return -1; } +static int __listen_candidate_process(int type, int loader_id) +{ + struct sockaddr_un addr; + + _D("[launchpad] enter, type: %d", type); + + memset(&addr, 0x00, sizeof(struct sockaddr_un)); + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/daemons/%d/%s%d-%d", + SOCKET_PATH, getuid(), LAUNCHPAD_LOADER_SOCKET_NAME, + type, loader_id); + + return __listen_addr(&addr); +} + +static int __listen_hydra_process(int type, int loader_id) +{ + struct sockaddr_un addr; + + _D("[launchpad] enter, type: %d", type); + + memset(&addr, 0x00, sizeof(struct sockaddr_un)); + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/daemons/%d/%s%d-%d", + SOCKET_PATH, getuid(), HYDRA_LOADER_SOCKET_NAME, + type, loader_id); + + return __listen_addr(&addr); +} + static int __get_loader_id(bundle *kb) { const char *val; @@ -620,18 +661,49 @@ 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 send_ret = 0; + + while (sent != size) { + send_ret = send(fd, (char *)&cmd + sent, + size - sent, MSG_NOSIGNAL); + if (send_ret == -1) { + _E("send error! (%d)", errno); + return -1; + } + + sent += send_ret; + _D("send(%d: ret: %d) : %d / %d", + fd, send_ret, sent, size); + } + + return 0; +} + +static int __hydra_send_launch_candidate_request(int fd) +{ + SECURE_LOGD("Send launch cmd to hydra, fd: %d", fd); + return __hydra_send_request(fd, LAUNCH_CANDIDATE); +} + static int __prepare_candidate_process(int type, int loader_id) { int pid; char type_str[2] = {0, }; char loader_id_str[10] = {0, }; char argbuf[LOADER_ARG_LEN]; - char *argv[] = {NULL, NULL, NULL, NULL, NULL, NULL}; + char *argv[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; candidate_process_context_t *cpt = __find_slot(type, loader_id); 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); memset(argbuf, ' ', LOADER_ARG_LEN); argbuf[LOADER_ARG_LEN - 1] = '\0'; @@ -644,6 +716,7 @@ static int __prepare_candidate_process(int type, int loader_id) 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; pid = __fork_app_process(__exec_loader_process, argv); @@ -652,8 +725,12 @@ static int __prepare_candidate_process(int type, int loader_id) return -1; } - cpt->pid = pid; - __set_live_timer(cpt); + if (cpt->is_hydra) { + cpt->hydra_pid = pid; + } else { + cpt->pid = pid; + __set_live_timer(cpt); + } return 0; } @@ -721,6 +798,26 @@ static void __dispose_candidate_process(candidate_process_context_t *cpc) __reset_slot(cpc); } +static void __dispose_hydra_process(candidate_process_context_t *cpc) +{ + if (!cpc) + return; + + __dispose_candidate_process(cpc); + + _D("Dispose hydra process %d", cpc->type); + if (cpc->hydra_pid > 0) { + _D("kill process %d", cpc->hydra_pid); + __kill_process(cpc->hydra_pid); + cpc->hydra_pid = HYDRA_NONE; + } + + if (cpc->hydra_fd > 0) { + close(cpc->hydra_fd); + cpc->hydra_fd = -1; + } +} + static int __send_launchpad_loader(candidate_process_context_t *cpc, app_pkt_t *pkt, const char *app_path, int clifd) { @@ -1230,6 +1327,30 @@ static gboolean __handle_loader_client_event(gpointer data) return G_SOURCE_CONTINUE; } +static gboolean __handle_hydra_client_event(gpointer data) +{ + loader_context_t *lc = (loader_context_t *)data; + int type = lc->type; + int loader_id = lc->loader_id; + gushort revents = lc->gpollfd->revents; + candidate_process_context_t *cpc = __find_slot(type, loader_id); + + if (cpc == NULL) + return G_SOURCE_REMOVE; + + if (revents & (G_IO_HUP | G_IO_NVAL)) { + SECURE_LOGE("Type %d hydra process was " \ + "(POLLHUP|POLLNVAL), pid: %d", + cpc->type, cpc->hydra_pid); + cpc->hydra_pid = HYDRA_NONE; + __dispose_hydra_process(cpc); + __prepare_candidate_process(cpc->type, cpc->loader_id); + return G_SOURCE_REMOVE; + } + + return G_SOURCE_CONTINUE; +} + static gboolean __handle_loader_event(gpointer data) { loader_context_t *lc = (loader_context_t *) data; @@ -1248,6 +1369,11 @@ static gboolean __handle_loader_event(gpointer data) if (!cpc->prepared) { ret = __accept_candidate_process(fd, &client_fd, &client_pid); if (ret >= 0) { + /* for hydra need to set pid to pid of non-hydra candidate, */ + /* which is connecting now */ + if (cpc->is_hydra) + cpc->pid = client_pid; + cpc->prepared = true; cpc->send_fd = client_fd; @@ -1267,6 +1393,43 @@ static gboolean __handle_loader_event(gpointer data) return G_SOURCE_CONTINUE; } +static gboolean __handle_hydra_event(gpointer data) +{ + loader_context_t *lc = (loader_context_t *) data; + int fd = lc->gpollfd->fd; + int type = lc->type; + int loader_id = lc->loader_id; + int client_fd; + int client_pid; + int ret; + + candidate_process_context_t *cpc = __find_slot(type, loader_id); + + if (cpc == NULL) + return G_SOURCE_REMOVE; + + if (!cpc->prepared) { + ret = __accept_candidate_process(fd, &client_fd, &client_pid); + if (ret >= 0) { + cpc->hydra_fd = client_fd; + + SECURE_LOGD("Type %d hydra process was connected," \ + " pid: %d", type, cpc->hydra_pid); + + cpc->source = __poll_fd(client_fd, G_IO_IN | G_IO_HUP, + __handle_hydra_client_event, type, + loader_id); + if (cpc->source == 0) + close(client_fd); + } + } else { + __refuse_candidate_process(fd); + _E("Refused hydra process connection"); + } + + return G_SOURCE_CONTINUE; +} + static gboolean __handle_sigchild(gpointer data) { candidate_process_context_t *cpc; @@ -1275,6 +1438,7 @@ static gboolean __handle_sigchild(gpointer data) struct signalfd_siginfo siginfo; ssize_t s; char *appid; + int pid; do { s = read(fd, &siginfo, sizeof(struct signalfd_siginfo)); @@ -1286,25 +1450,34 @@ static gboolean __handle_sigchild(gpointer data) _signal_process_sigchld(&siginfo); + pid = siginfo.ssi_code != SI_QUEUE ? siginfo.ssi_pid : siginfo.ssi_int; + appid = g_hash_table_lookup(__pid_table, - GINT_TO_POINTER(siginfo.ssi_pid)); + GINT_TO_POINTER(pid)); if (appid) { - security_manager_cleanup_app(appid, siginfo.ssi_uid, siginfo.ssi_pid); + security_manager_cleanup_app(appid, siginfo.ssi_uid, pid); g_hash_table_remove(__pid_table, - GINT_TO_POINTER(siginfo.ssi_pid)); + GINT_TO_POINTER(pid)); } - cpc = __find_slot_from_pid(siginfo.ssi_pid); + cpc = __find_slot_from_pid(pid); if (cpc != NULL) { cpc->pid = CANDIDATE_NONE; __dispose_candidate_process(cpc); __prepare_candidate_process(cpc->type, cpc->loader_id); + } else { + cpc = __find_hydra_slot_from_pid(pid); + if (cpc != NULL) { + cpc->hydra_pid = HYDRA_NONE; + __dispose_hydra_process(cpc); + __prepare_candidate_process(cpc->type, cpc->loader_id); + } } - cpc = __find_slot_from_caller_pid(siginfo.ssi_pid); + cpc = __find_slot_from_caller_pid(pid); while (cpc) { __remove_slot(LAUNCHPAD_TYPE_DYNAMIC, cpc->loader_id); - cpc = __find_slot_from_caller_pid(siginfo.ssi_pid); + cpc = __find_slot_from_caller_pid(pid); } } while (s > 0); @@ -1498,7 +1671,7 @@ static int __dispatch_cmd_add_loader(bundle *kb) DEFAULT_CPU_THRESHOLD_MAX, DEFAULT_CPU_THRESHOLD_MIN, false, - true); + true, 0); __set_timer(cpc); return lid; } @@ -1886,7 +2059,7 @@ static candidate_process_context_t *__add_slot(int type, int loader_id, 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 on_boot, bool app_exists, bool is_hydra) { candidate_process_context_t *cpc; int fd = -1; @@ -1903,9 +2076,11 @@ static candidate_process_context_t *__add_slot(int type, int loader_id, cpc->type = type; cpc->prepared = false; cpc->pid = CANDIDATE_NONE; + cpc->hydra_pid = HYDRA_NONE; cpc->caller_pid = caller_pid; cpc->loader_id = loader_id; cpc->send_fd = -1; + cpc->hydra_fd = -1; cpc->last_exec_time = 0; cpc->source = 0; cpc->timer = 0; @@ -1926,6 +2101,7 @@ static candidate_process_context_t *__add_slot(int type, int loader_id, cpc->deactivation_method = deactivation_method; cpc->ttl = ttl; cpc->live_timer = 0; + cpc->is_hydra = is_hydra; if ((cpc->deactivation_method & METHOD_OUT_OF_MEMORY) && __is_low_memory()) @@ -1950,6 +2126,25 @@ static candidate_process_context_t *__add_slot(int type, int loader_id, return NULL; } + if (is_hydra) { + fd = __listen_hydra_process(cpc->type, cpc->loader_id); + if (fd == -1) { + _E("[launchpad] Listening the socket to " \ + "the type %d hydra process failed.", + cpc->type); + free(cpc); + return NULL; + } + + pollfd = __poll_fd(fd, G_IO_IN, (GSourceFunc)__handle_hydra_event, + cpc->type, cpc->loader_id); + if (pollfd == 0) { + close(fd); + free(cpc); + return NULL; + } + } + candidate_slot_list = g_list_append(candidate_slot_list, cpc); return cpc; @@ -2122,7 +2317,7 @@ static void __add_slot_from_info(gpointer data, gpointer user_data) info->cpu_threshold_max, info->cpu_threshold_min, false, - info->app_exists); + info->app_exists, info->is_hydra); if (cpc == NULL) return; @@ -2149,7 +2344,7 @@ static void __add_slot_from_info(gpointer data, gpointer user_data) info->cpu_threshold_max, info->cpu_threshold_min, info->on_boot, - info->app_exists); + info->app_exists, info->is_hydra); if (cpc == NULL) return; diff --git a/src/launchpad_common.c b/src/launchpad_common.c index 13055e2..eade9b5 100644 --- a/src/launchpad_common.c +++ b/src/launchpad_common.c @@ -708,6 +708,36 @@ int _connect_to_launchpad(int type, int id) return fd; } +int _connect_to_launchpad_hydra(int type, int id) +{ + char path[PATH_MAX]; + int fd; + int send_ret; + pid_t client_pid; + + + _D("[hydra] enter, type: %d", type); + + snprintf(path, sizeof(path), "%s/daemons/%d/%s%d-%d", + SOCKET_PATH, getuid(), HYDRA_LOADER_SOCKET_NAME, + type, id); + fd = __create_client_socket(path); + if (fd < 0) + return -1; + + client_pid = getpid(); + send_ret = send(fd, &client_pid, sizeof(client_pid), MSG_NOSIGNAL); + _D("send(%d) : %d", client_pid, send_ret); + if (send_ret == -1) { + _E("send error"); + close(fd); + return -1; + } + + SECURE_LOGD("[hydra] done, connect fd: %d", fd); + return fd; +} + #ifdef TIZEN_FEATURE_SET_PERSONALITY_32 static void __set_execution_domain(void) { diff --git a/src/launchpad_lib.c b/src/launchpad_lib.c index 4041141..ab243f1 100644 --- a/src/launchpad_lib.c +++ b/src/launchpad_lib.c @@ -29,6 +29,10 @@ #include #include +#include +#include +#include + #include "launchpad_common.h" #include "launchpad.h" #include "preexec.h" @@ -39,6 +43,7 @@ #define AUL_PR_NAME 16 +static hydra_lifecycle_callback_s *__hydra_callbacks; static loader_lifecycle_callback_s *__loader_callbacks; static loader_adapter_s *__loader_adapter; static void *__loader_user_data; @@ -47,6 +52,8 @@ static char **__argv; static bundle *__bundle; static int __loader_type = LAUNCHPAD_TYPE_UNSUPPORTED; static int __loader_id; +static pid_t __candidate_pid = -1; +static struct sigaction __prev_sigchld; static void __at_exit_to_release_bundle(void) { @@ -305,6 +312,82 @@ static void __receiver_cb(int fd) } } +static void __hydra_receiver_cb(int fd) +{ + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + enum hydra_cmd cmd = -1; + int len; + pid_t pid; + int r; + + _D("[hydra] ECORE_FD_READ"); + +retry_recv: + len = recv(fd, &cmd, sizeof(cmd), MSG_WAITALL); + if (len < 0) + if (errno == EINTR) + goto retry_recv; + + if (len < sizeof(cmd)) { + _E("[hydra] failed to recv: %s", + strerror_r(errno, err_str, sizeof(err_str))); + goto err; + } + + _D("[hydra] success recv cmd: %d", cmd); + + switch (cmd) { + case LAUNCH_CANDIDATE: + _D("[hydra] launch new child"); + break; + default: + _E("[hydra] unknown command from launchpad: %d", cmd); + goto err; + } + + pid = fork(); + if (pid < 0) { + _E("[hydra] unable to fork: %s", + strerror_r(errno, err_str, sizeof(err_str))); + } else if (pid > 0) { + SECURE_LOGD("[hydra] forked candidate with pid=%d", pid); + + __candidate_pid = pid; + + return; + } else { + if (sigaction(SIGCHLD, &__prev_sigchld, NULL)) { + _E("[hydra] sigaction failed: %s", + strerror_r(errno, err_str, sizeof(err_str))); + exit(-1); + } + + if (__hydra_callbacks->fork) + __hydra_callbacks->fork(__loader_user_data); + + /* child, exit loop and start initialization */ + __loader_adapter->remove_fd(__loader_user_data, fd); + close(fd); + + __loader_adapter->loop_quit(__loader_user_data); + + if (__hydra_callbacks->terminate) + __hydra_callbacks->terminate(__loader_user_data); + + r = launchpad_loader_main(__argc, __argv, __loader_callbacks, + __loader_adapter, __loader_user_data); + if (r != 0) + _E("[hydra] launchpad_loader_main failed. Error: %d", r); + + exit(r); + } + +err: + __loader_adapter->remove_fd(__loader_user_data, fd); + close(fd); + exit(-1); +} + static void __update_lang(keynode_t *node, void *user_data) { char *lang = vconf_keynode_get_str(node); @@ -380,15 +463,52 @@ bundle *launchpad_loader_get_bundle() return __bundle; } +static void sigchld_hdl(int code, siginfo_t *siginfo, void *context) +{ + pid_t child_pid; + union sigval val; + bool is_group_leader = !kill(-siginfo->si_pid, 0); + + while ((child_pid = waitpid(-1, NULL, WNOHANG)) > 0) { + /* sigqueue to launchpad getppid() with data=child_pid */ + if (child_pid == __candidate_pid) + __candidate_pid = -1; + + if (is_group_leader) + kill(-child_pid, SIGKILL); + + val.sival_int = child_pid; + sigqueue(getppid(), SIGCHLD, val); + } + + if (__prev_sigchld.sa_flags & SA_SIGINFO) { + if (__prev_sigchld.sa_sigaction) + __prev_sigchld.sa_sigaction(code, siginfo, context); + } else if (__prev_sigchld.sa_handler && + __prev_sigchld.sa_handler != SIG_IGN && + __prev_sigchld.sa_handler != SIG_DFL) { + __prev_sigchld.sa_handler(code); + } +} + API int launchpad_loader_main(int argc, char **argv, loader_lifecycle_callback_s *callbacks, loader_adapter_s *adapter, void *user_data) { - if (argc < 3) { + int is_hydra; + + if (argc < 4) { _E("too few argument."); return -1; } + is_hydra = argv[LOADER_ARG_HYDRA][0] - '0'; + + if (is_hydra) { + _D("Cannot run in hydra mode"); + return -1; + } + __loader_type = argv[LOADER_ARG_TYPE][0] - '0'; if (__loader_type < 0 || __loader_type >= LAUNCHPAD_TYPE_MAX) { _E("invalid argument. (type: %d)", __loader_type); @@ -434,3 +554,131 @@ API int launchpad_loader_set_priority(int prio) { return _set_priority(prio); } + +API int launchpad_hydra_main(int argc, char **argv, + hydra_lifecycle_callback_s *hydra_callbacks, + loader_lifecycle_callback_s *callbacks, + loader_adapter_s *adapter, void *user_data) +{ + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + int is_hydra; + int loader_type; + int loader_id; + int client_fd; + pid_t pid; + struct sigaction new_act; + + if (argc < 4) { + _E("[hydra] too few argument."); + return -1; + } + + is_hydra = argv[LOADER_ARG_HYDRA][0] - '0'; + argv[LOADER_ARG_HYDRA] = "0"; + _D("[hydra] mode: %d", is_hydra); + + loader_type = argv[LOADER_ARG_TYPE][0] - '0'; + if (loader_type < 0 || loader_type >= LAUNCHPAD_TYPE_MAX) { + _E("[hydra] invalid argument. (type: %d)", loader_type); + return -1; + } + + loader_id = atoi(argv[LOADER_ARG_ID]); + + if (hydra_callbacks == NULL) { + _E("[hydra] invalid argument. hydra_callback is null"); + return -1; + } + + if (adapter == NULL) { + _E("[hydra] invalid argument. adapter is null"); + return -1; + } + + if (adapter->loop_begin == NULL || adapter->loop_quit == NULL + || adapter->add_fd == NULL || adapter->remove_fd == NULL) { + _E("[hydra] invalid argument. adapter callback is null"); + return -1; + } + + if (hydra_callbacks->precreate) + hydra_callbacks->precreate(user_data); + + if (!is_hydra) { + _D("Run in non hydra mode"); + return launchpad_loader_main(argc, argv, callbacks, + adapter, user_data); + } + + if (hydra_callbacks->create) + hydra_callbacks->create(user_data); + + /* Set sigchld handler after calling create, because it can overwrite */ + /* our handler */ + memset(&new_act, 0, sizeof(new_act)); + new_act.sa_sigaction = sigchld_hdl; + new_act.sa_flags |= SA_SIGINFO; + + if (sigaction(SIGCHLD, &new_act, &__prev_sigchld)) { + _E("[hydra] sigaction failed: %s", + strerror_r(errno, err_str, sizeof(err_str))); + return -1; + } + + /* initial fork to prepare first loader */ + _D("[hydra] initial fork"); + + pid = fork(); + if (pid < 0) { + _E("[hydra] unable to fork: %s", + strerror_r(errno, err_str, sizeof(err_str))); + return -1; + } else if (pid == 0) { + if (sigaction(SIGCHLD, &__prev_sigchld, NULL)) { + _E("[hydra] sigaction failed: %s", + strerror_r(errno, err_str, sizeof(err_str))); + return -1; + } + + if (hydra_callbacks->fork) + hydra_callbacks->fork(user_data); + + return launchpad_loader_main(argc, argv, callbacks, + adapter, user_data); + } else { + __hydra_callbacks = hydra_callbacks; + __loader_callbacks = callbacks; + __loader_adapter = adapter; + __loader_user_data = user_data; + __candidate_pid = pid; + __argc = argc; + __argv = argv; + + __preexec_init(argc, argv); + + /* Set new session ID & new process group ID*/ + /* In linux, child can set new session ID without check permission */ + /* TODO : should be add to check permission in the kernel*/ + setsid(); + + malloc_trim(0); + + client_fd = _connect_to_launchpad_hydra(loader_type, loader_id); + if (client_fd == -1) { + _D("[hydra] connecting to launchpad process was failed."); + return -1; + } + + __loader_adapter->add_fd(__loader_user_data, client_fd, + __hydra_receiver_cb); + + __loader_adapter->loop_begin(__loader_user_data); + + if (__hydra_callbacks->terminate) + return __hydra_callbacks->terminate(__loader_user_data); + + return -1; + } + + return 0; +} \ No newline at end of file diff --git a/src/launchpad_signal.c b/src/launchpad_signal.c index deb581c..e6a6503 100644 --- a/src/launchpad_signal.c +++ b/src/launchpad_signal.c @@ -281,14 +281,20 @@ void _signal_process_sigchld(struct signalfd_siginfo *info) pid_t child_pid; pid_t child_pgid; - child_pgid = getpgid(info->ssi_pid); - _D("dead_pid = %d pgid = %d signo = %d status = %d", info->ssi_pid, - child_pgid, info->ssi_signo, info->ssi_status); - - while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) { - if (child_pid == child_pgid) - killpg(child_pgid, SIGKILL); - __sigchild_action(child_pid); + if (info->ssi_code != SI_QUEUE) { + child_pgid = getpgid(info->ssi_pid); + _D("dead_pid = %d pgid = %d signo = %d status = %d", info->ssi_pid, + child_pgid, info->ssi_signo, info->ssi_status); + + while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) { + if (child_pid == child_pgid) + killpg(child_pgid, SIGKILL); + __sigchild_action(child_pid); + } + } else { + _D("queued signal: dead_pid = %d signo = %d", info->ssi_int, + info->ssi_signo); + __sigchild_action(info->ssi_int); } } diff --git a/src/loader_info.c b/src/loader_info.c index 55ea192..39e9f21 100644 --- a/src/loader_info.c +++ b/src/loader_info.c @@ -41,6 +41,7 @@ #define TAG_CPU_THRESHOLD_MAX "CPU_THRESHOLD_MAX" #define TAG_CPU_THRESHOLD_MIN "CPU_THRESHOLD_MIN" #define TAG_ON_BOOT "ON_BOOT" +#define TAG_HYDRA "HYDRA" #define VAL_ON "ON" #define VAL_OFF "OFF" @@ -79,6 +80,7 @@ static loader_info_t *__create_loader_info() info->activation_method = 0; info->deactivation_method = 0; info->ttl = 600; /* 10 minutes */ + info->is_hydra = false; return info; } @@ -294,6 +296,12 @@ static GList *__parse_file(GList *list, const char *path) } else if (strcasecmp(TAG_ON_BOOT, tok1) == 0) { 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) { + cur_info->is_hydra = 1; + } else { + cur_info->is_hydra = 0; + } } } -- 2.7.4 From 054ec23fc577dd1341ebc0a2f82810594d8e083a Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 20 Sep 2019 12:44:05 +0900 Subject: [PATCH 12/16] Release version 0.9.0 Changes: - Introduce new API for hydra mode: Change-Id: If3882a81163100c9ad51215daa4c0092690f2579 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 fa5906b..d17f4c3 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.8.2 +Version: 0.9.0 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From fb41a54c41ab8a8422451eb20f9848d0799eae2f Mon Sep 17 00:00:00 2001 From: Wonki Kim Date: Wed, 18 Sep 2019 15:40:42 +0900 Subject: [PATCH 13/16] Add a logic to specify the app id while forking Application runs by forking a launchpad process in Tizen. A forked application process inherits whole information of launchpad including atspi application name that is specified by calling elm_app_name_set. this patch adds a logic to have the own name for each forked applications in atspi point of view. Change-Id: I42c892e4c8c15a67ddc5fac0bdd435305fcababe --- src/launchpad_loader.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/launchpad_loader.c b/src/launchpad_loader.c index cf92185..d91fd97 100644 --- a/src/launchpad_loader.c +++ b/src/launchpad_loader.c @@ -274,6 +274,8 @@ static int __loader_launch_cb(int argc, char **argv, const char *app_path, const char *high_priority; #endif + elm_app_name_set(appid); + vconf_ignore_key_changed(VCONFKEY_SETAPPL_APP_HW_ACCELERATION, __vconf_cb); if (kb == NULL) -- 2.7.4 From 178013f98aeb2c190071fd96895a84c5a415033e Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 25 Sep 2019 09:20:55 +0900 Subject: [PATCH 14/16] Release version 0.9.1 Changes: - Add a logic to specify the app id while forking Change-Id: I731f7de141e70819c5ece3ba4a617a194b0f9f3c 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 d17f4c3..acd4cce 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.9.0 +Version: 0.9.1 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From 418490a0284aa5e08921fd6a6480fdee1369056d Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 2 Oct 2019 10:42:17 +0900 Subject: [PATCH 15/16] Print HW clock logs for performance measurement Change-Id: I69f247fcd08e4a03912f0e2257912a8f234187bc Signed-off-by: Hwankyu Jhun --- inc/launchpad_common.h | 1 + src/launchpad.c | 3 +++ src/launchpad_common.c | 17 +++++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/inc/launchpad_common.h b/inc/launchpad_common.h index 0ebb452..b66fa62 100644 --- a/inc/launchpad_common.h +++ b/inc/launchpad_common.h @@ -139,6 +139,7 @@ int _prepare_app_socket(void); int _enable_external_pkg(bundle *b, const char *pkgid, uid_t pkg_uid); int _verify_proc_caps(void); int _prepare_id_file(void); +void _print_hwc_log(const char *format, ...); #endif /* __LAUNCHPAD_COMMON_H__ */ diff --git a/src/launchpad.c b/src/launchpad.c index 4d6cabb..cf54b45 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -1131,6 +1131,8 @@ static int __exec_app_process(void *arg) struct app_launch_arg *launch_arg = arg; int ret; + _print_hwc_log("%d|after calling fork(). %s", + getpid(), launch_arg->appid); PERF("fork done"); _D("lock up test log(no error) : fork done"); @@ -1166,6 +1168,7 @@ static int __launch_directly(const char *appid, const char *app_path, int clifd, arg.menu_info = menu_info; arg.kb = kb; + _print_hwc_log("before calling fork(). %s", appid); pid = __fork_app_process(__exec_app_process, &arg); if (pid <= 0) _E("failed to fork app process"); diff --git a/src/launchpad_common.c b/src/launchpad_common.c index eade9b5..5607c77 100644 --- a/src/launchpad_common.c +++ b/src/launchpad_common.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -68,6 +69,10 @@ #define APP2SD_RETRY_MAX 5 #define APP2SD_WAIT_USEC (1000000 / 2) /* 0.5 sec */ +#ifndef PR_TASK_PERF_USER_TRACE +#define PR_TASK_PERF_USER_TRACE 666 +#endif + static int __read_proc(const char *path, char *buf, int size) { int fd; @@ -1437,3 +1442,15 @@ int _send_message_to_logger(const char *tag, const char *format, ...) return 0; } + +void _print_hwc_log(const char *format, ...) +{ + char buf[1024]; + va_list ap; + + va_start(ap, format); + vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + + prctl(PR_TASK_PERF_USER_TRACE, buf, strlen(buf)); +} -- 2.7.4 From d1564d55441f39dbeef1617455205ab86698dfbd Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 2 Oct 2019 11:24:07 +0900 Subject: [PATCH 16/16] Release version 0.9.2 Changes: - Print HW clock logs for performance measurement Change-Id: I6e851e6e1643b6cba3a4547701822124828a009e 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 acd4cce..8b887f7 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.9.1 +Version: 0.9.2 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4