From 7aa5f8a850f6048dda25ad1bcceee1d2e1864ee5 Mon Sep 17 00:00:00 2001 From: Changgyu Choi Date: Tue, 27 Dec 2022 17:49:41 +0900 Subject: [PATCH 01/16] Fix static analysis issues Change-Id: If01054da536adbfe4afc5a6fece227b5ba252264 Signed-off-by: Changgyu Choi --- src/launchpad-process-pool/src/launchpad.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/launchpad-process-pool/src/launchpad.c b/src/launchpad-process-pool/src/launchpad.c index 3b8bfbf..39c52f9 100644 --- a/src/launchpad-process-pool/src/launchpad.c +++ b/src/launchpad-process-pool/src/launchpad.c @@ -1987,6 +1987,7 @@ static int __dispatch_cmd_add_loader(bundle *kb) slot_info.app_exists = true; slot_info.is_hydra = false; slot_info.app_check = true; + slot_info.on_boot_timeout = 0; cpc = __add_slot(&slot_info); free(loader_name); @@ -2045,6 +2046,7 @@ static int __dispatch_cmd_add_app_defined_loader(bundle *kb) slot_info.app_exists = true; slot_info.is_hydra = false; slot_info.app_check = true; + slot_info.on_boot_timeout = 0; cpc = __add_slot(&slot_info); bundle_free_encoded_rawdata(&extra); -- 2.7.4 From fbb2f021d5938da4e4be2909b80749e7205710b8 Mon Sep 17 00:00:00 2001 From: Changgyu Choi Date: Tue, 27 Dec 2022 18:58:30 +0900 Subject: [PATCH 02/16] Release version 0.21.5 Changes: - Fix static analysis issues Change-Id: I892a5db902e63797fd9b3a960e058722a45b66b3 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 fef2d29..15bbc94 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.21.4 +Version: 0.21.5 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From 613177dc278c176f0128c641bd8e1bd1d4c11367 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 3 Jan 2023 04:44:28 +0000 Subject: [PATCH 03/16] Create aul worker thread before running the main loop To improve launching performance, the launchpad library calls the aul_launch_worker_init() function to prepare the aul worker thread. Requires: - https://review.tizen.org/gerrit/#/c/platform/core/appfw/aul-1/+/286270 Change-Id: I09da6090fafc4148cb6532307a69cfeb7b703f70 Signed-off-by: Hwankyu Jhun --- src/lib/launchpad/src/launchpad_lib.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/launchpad/src/launchpad_lib.c b/src/lib/launchpad/src/launchpad_lib.c index 437dbbe..7980efc 100644 --- a/src/lib/launchpad/src/launchpad_lib.c +++ b/src/lib/launchpad/src/launchpad_lib.c @@ -409,6 +409,8 @@ static int __before_loop(int argc, char **argv) if (r != VCONF_OK) _E("Failed to register callback for regionformat. error(%d)", r); + aul_launch_worker_init(); + return ret; } -- 2.7.4 From 4f6b91133941181077971e7db5076ddd3b2fac15 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 3 Jan 2023 06:24:26 +0000 Subject: [PATCH 04/16] Release version 0.21.6 Changes: - Create aul worker thread before running the main loop Change-Id: Icea70fcc50d99488bfa3a7b42986abd2e031a58f 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 15bbc94..9e3b75a 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.21.5 +Version: 0.21.6 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From 33927bf0d74fba50e583c8ae6826e250e3d868af Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Mon, 21 Nov 2022 10:18:01 +0900 Subject: [PATCH 05/16] Add res pkgids to env Change-Id: I920242fa6eda3bf634f527f83b46b89c3bd0eef0 Signed-off-by: Sangyoon Jang --- src/lib/common/inc/key.h | 1 + src/lib/common/src/launchpad_common.c | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/lib/common/inc/key.h b/src/lib/common/inc/key.h index 8889cca..cde7c3f 100644 --- a/src/lib/common/inc/key.h +++ b/src/lib/common/inc/key.h @@ -52,6 +52,7 @@ extern "C" { #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__" +#define AUL_K_MOUNT_RES_PKGIDS "__AUL_MOUNT_RES_PKGIDS__" #ifdef __cplusplus } diff --git a/src/lib/common/src/launchpad_common.c b/src/lib/common/src/launchpad_common.c index 0db3125..d474ebc 100644 --- a/src/lib/common/src/launchpad_common.c +++ b/src/lib/common/src/launchpad_common.c @@ -1553,6 +1553,21 @@ static int __mount_dir(const char *srcs[], size_t srcs_len, const char *dest) return 0; } +static void __set_mount_pkgids_to_env(const char *pkgids[], size_t len) +{ + int i; + char val[PATH_MAX] = { 0 }; + + for (i = 0; i < len; i++) + snprintf(val + strlen(val), sizeof(val) - strlen(val), "%s:", + pkgids[i]); + + val[strlen(val) - 1] = '\0'; + + /* RES_PKGIDS=org.tizen.res1:org.tizen.res2:org.tizen.res3 */ + setenv("RES_PKGIDS", val, 1); +} + int _mount_res_dir(const char *root_path, bundle *kb) { const char **val; @@ -1577,6 +1592,13 @@ int _mount_res_dir(const char *root_path, bundle *kb) return -1; } + val = bundle_get_str_array(kb, AUL_K_MOUNT_RES_PKGIDS, &len); + if (val) { + __set_mount_pkgids_to_env(val, len); + } else if (get_last_result() != BUNDLE_ERROR_KEY_NOT_AVAILABLE) { + _E("invalid mount info"); + return -1; + } return 0; } -- 2.7.4 From afccb132833e60184d85e485f40eefc261c67141 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 9 Jan 2023 07:42:15 +0000 Subject: [PATCH 06/16] Release version 0.22.0 Changes: - Add res pkgids to env Change-Id: I272ee28057a015f8371de7358d6ce9fc51021bc3 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 9e3b75a..3fd262b 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.21.6 +Version: 0.22.0 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From 1080ea9ca645a8c5babfdc65982297a3e57ce922 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 12 Jan 2023 06:47:20 +0000 Subject: [PATCH 07/16] Print appid for debugging To debug which the application is calling security_manager_prepare_app_v2(), the launchpad prints the application ID. This patch fixes the typo and removes build warning message. Change-Id: I3c38ff369ab4cc01aac2c8fdfd3d1e74c3f490ee Signed-off-by: Hwankyu Jhun --- src/launchpad-parser/launchpad_parser_plugin.cc | 2 +- src/launchpad-process-pool/src/launchpad.c | 4 ++-- src/lib/launchpad/src/launchpad_lib.c | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/launchpad-parser/launchpad_parser_plugin.cc b/src/launchpad-parser/launchpad_parser_plugin.cc index 135a554..eacfbf2 100644 --- a/src/launchpad-parser/launchpad_parser_plugin.cc +++ b/src/launchpad-parser/launchpad_parser_plugin.cc @@ -54,7 +54,7 @@ int LaunchpadParser::WriteToFile(std::string pkgid) { if (i->GetPreloadLib().size() > 0) { out_file << "EXTRA_ARRAY preload \n"; for (auto& lib : i->GetPreloadLib()) { - out_file << "EXTRA_ARRAY_VAL "LIBDIR"/" + lib + "\n"; + out_file << "EXTRA_ARRAY_VAL " LIBDIR "/" + lib + "\n"; } } out_file.close(); diff --git a/src/launchpad-process-pool/src/launchpad.c b/src/launchpad-process-pool/src/launchpad.c index 39c52f9..be6ab2a 100644 --- a/src/launchpad-process-pool/src/launchpad.c +++ b/src/launchpad-process-pool/src/launchpad.c @@ -1338,9 +1338,9 @@ static int __prepare_exec(const char *appid, const char *app_path, /* SET PRIVILEGES*/ enabled_light_user = bundle_get_val(kb, AUL_K_ENABLED_LIGHT_USER); - _W("security_manager_prepare_app2 ++"); + _W("security_manager_prepare_app2 ++ %s", appid); ret = security_manager_prepare_app2(appid, enabled_light_user); - _W("security_manager_prepare_app2 --"); + _W("security_manager_prepare_app2 -- %s", appid); if (ret != SECURITY_MANAGER_SUCCESS) return PAD_ERR_REJECTED; diff --git a/src/lib/launchpad/src/launchpad_lib.c b/src/lib/launchpad/src/launchpad_lib.c index 7980efc..9bd3832 100644 --- a/src/lib/launchpad/src/launchpad_lib.c +++ b/src/lib/launchpad/src/launchpad_lib.c @@ -77,7 +77,7 @@ static int __prepare_exec(const char *appid, const char *app_path, return -1; /* SET PRIVILEGES*/ - SECURE_LOGD("[candidata] appid : %s / pkg_type : %s / app_path : %s", + SECURE_LOGD("[candidate] appid : %s / pkg_type : %s / app_path : %s", appid, pkg_type, app_path); if (global) @@ -96,9 +96,9 @@ static int __prepare_exec(const char *appid, const char *app_path, return -1; enabled_light_user = bundle_get_val(kb, AUL_K_ENABLED_LIGHT_USER); - _W("security_manager_prepare_app2 ++"); + _W("security_manager_prepare_app2 ++ %s", appid); ret = security_manager_prepare_app2(appid, enabled_light_user); - _W("security_manager_prepare_app2 --"); + _W("security_manager_prepare_app2 -- %s", appid); if (ret != SECURITY_MANAGER_SUCCESS) { _E("Failed to set privileges %s:%d", appid, ret); return -1; -- 2.7.4 From 7176f3184a8761b202cb7189020a46f80cf2459b Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 16 Jan 2023 05:02:08 +0000 Subject: [PATCH 08/16] Fix build error If the priority change feature is enabled, the build error is occurred. This patch fixes the build error. The TIZEN_FEATURE_PRIORITY_CHANGE feature is not used in the loader process. It's removed from the app-defined-loader. Change-Id: Ia6333c0195b5db3baaa7ce5aa6feb7cd7b08d23e Signed-off-by: Hwankyu Jhun --- src/app-defined-loader/src/app-defined-loader.cc | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/src/app-defined-loader/src/app-defined-loader.cc b/src/app-defined-loader/src/app-defined-loader.cc index 4ae4471..b96e72e 100644 --- a/src/app-defined-loader/src/app-defined-loader.cc +++ b/src/app-defined-loader/src/app-defined-loader.cc @@ -89,18 +89,10 @@ class AppDefinedLoader { loader_priority_enabled_ = enable; } - void SetPriorityChanged(bool enable) { - priority_change_enabled_ = enable; - } - bool IsLoaderPriorityEnabled() { return loader_priority_enabled_; } - bool IsPriorityChangeEnabled() { - return priority_change_enabled_; - } - void SetFdHandler(Ecore_Fd_Handler* fd_handler) { fd_handler_ = fd_handler; } @@ -152,6 +144,7 @@ class AppDefinedLoader { if (loader->IsLoaderPriorityEnabled()) launchpad_loader_set_priority(19); + loader->PreloadLib(ex); ecore_init(); setenv("AUL_LOADER_INIT", "1", 1); @@ -160,6 +153,9 @@ class AppDefinedLoader { setenv("AUL_HWACC", "none", 1); else if (loader_type == LOADER_TYPE_HW) setenv("AUL_HWACC", "hw", 1); + + if (loader->IsLoaderPriorityEnabled()) + launchpad_loader_set_priority(0); } static int OnLaunch(int argc, char** argv, const char* app_path, @@ -167,9 +163,6 @@ class AppDefinedLoader { void* user_data) { _I("on launch"); AppDefinedLoader* loader = static_cast(user_data); - if (!loader->IsPriorityChangeEnabled()) - return 0; - bundle* kb = launchpad_loader_get_bundle(); if (kb == nullptr) return 0; @@ -326,7 +319,6 @@ class AppDefinedLoader { std::shared_ptr lifecycle_cb_ = nullptr; std::shared_ptr adapter_ = nullptr; bool loader_priority_enabled_ = false; - bool priority_change_enabled_ = false; loader_receiver_cb receiver_cb_ = nullptr; Ecore_Fd_Handler* fd_handler_ = nullptr; std::unique_ptr proc_; @@ -341,10 +333,7 @@ int main(int argc, char** argv) { launchpad::AppDefinedLoader loader(argc, argv); #ifdef TIZEN_FEATURE_LOADER_PRIORITY - loader->SetLoaderPriority(true); -#endif -#ifdef TIZEN_FEATURE_PRIORITY_CHANGE - loader->SetPriorityChanged(true); + loader.SetLoaderPriority(true); #endif return launchpad_loader_main(argc, argv, -- 2.7.4 From be806bb06e6891bf88fed19a8ed14024234d5351 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 16 Jan 2023 01:00:42 +0000 Subject: [PATCH 09/16] Wait for threads ready Before calling the security_manager_prepare_app2() function, all threads of the loader process MUST be ready. After this patch is applied, the loader porcess waits until threads are ready if the key-value data related to the thread exists in the extra data. Change-Id: I871b1a53e602dadc50134fca5575a54d6fc1b249 Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 15 +++- src/launchpad-loader/conf/default_arch32.loader.in | 3 +- src/launchpad-loader/conf/default_arch64.loader.in | 3 +- src/lib/launchpad/src/launchpad_lib.c | 92 +++++++++++++++++++--- 4 files changed, 101 insertions(+), 12 deletions(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 3fd262b..8ad01c6 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -45,12 +45,18 @@ Obsoletes: amd-mod-launchpad %define tizen_feature_priority_change 0 %define tizen_feature_loader_priority 0 -%ifarch armv7l i586 +%ifarch armv7l i686 i586 %define tizen_arch32 1 %else %define tizen_arch32 0 %endif +%ifarch x86_64 i686 i586 +%define tizen_emulator 1 +%else +%define tizen_emulator 0 +%endif + %if "%{?_prelink_enable}" == "y" %define tizen_feature_prelink 1 %else @@ -125,9 +131,16 @@ _TIZEN_FEATURE_LOADER_ARCH64=ON _TIZEN_FEATURE_PRELINK=ON %endif +%if 0%{?tizen_emulator} +HW_LOADER_THREADS=7 +%else +HW_LOADER_THREADS=8 +%endif + MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` %cmake -DVERSION=%{version} \ -DMAJORVER=${MAJORVER} \ + -DHW_LOADER_THREADS=${HW_LOADER_THREADS} \ -D_TIZEN_FEATURE_PRIORITY_CHANGE:BOOL=${_TIZEN_FEATURE_PRIORITY_CHANGE} \ -D_TIZEN_FEATURE_LOADER_PRIORITY:BOOL=${_TIZEN_FEATURE_LOADER_PRIORITY} \ -D_TIZEN_FEATURE_SET_PERSONALITY_32:BOOL=${_TIZEN_FEATURE_SET_PERSONALITY_32} \ diff --git a/src/launchpad-loader/conf/default_arch32.loader.in b/src/launchpad-loader/conf/default_arch32.loader.in index 3e076ce..b663eb7 100644 --- a/src/launchpad-loader/conf/default_arch32.loader.in +++ b/src/launchpad-loader/conf/default_arch32.loader.in @@ -17,6 +17,7 @@ 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/@EFL_MODULE_VERSION@/module.so ALTERNATIVE_LOADER common-loader1 +EXTRA threads @HW_LOADER_THREADS@ [LOADER] NAME common-loader1 @@ -31,6 +32,6 @@ 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/@EFL_MODULE_VERSION@/module.so EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/ecore_evas/engines/extn/@EFL_MODULE_VERSION@/module.so - +EXTRA threads 6 diff --git a/src/launchpad-loader/conf/default_arch64.loader.in b/src/launchpad-loader/conf/default_arch64.loader.in index c1fdc92..bb50a88 100644 --- a/src/launchpad-loader/conf/default_arch64.loader.in +++ b/src/launchpad-loader/conf/default_arch64.loader.in @@ -13,6 +13,7 @@ EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/libcapi-appfw-application.so.0 EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/ecore_imf/modules/wayland/@EFL_MODULE_VERSION@/module.so EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/ecore_evas/engines/extn/@EFL_MODULE_VERSION@/module.so ALTERNATIVE_LOADER common-loader1 +EXTRA threads @HW_LOADER_THREADS@ [LOADER] NAME common-loader1 @@ -27,6 +28,6 @@ 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/@EFL_MODULE_VERSION@/module.so EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/ecore_evas/engines/extn/@EFL_MODULE_VERSION@/module.so - +EXTRA threads 6 diff --git a/src/lib/launchpad/src/launchpad_lib.c b/src/lib/launchpad/src/launchpad_lib.c index 9bd3832..af20cae 100644 --- a/src/lib/launchpad/src/launchpad_lib.c +++ b/src/lib/launchpad/src/launchpad_lib.c @@ -15,13 +15,18 @@ */ #define _GNU_SOURCE +#include +#include +#include #include #include +#include #include -#include #include -#include -#include +#include +#include +#include + #include #include #include @@ -29,10 +34,6 @@ #include #include -#include -#include -#include - #include "launchpad.h" #include "launchpad_common.h" #include "launchpad_types.h" @@ -355,11 +356,78 @@ static void __region_format_changed_cb(keynode_t *node, void *user_data) setenv("LC_CTYPE", region, 1); } +#ifndef USE_STATUS +static unsigned int __get_thread_count(void) +{ + DIR *dp; + struct dirent *dentry; + unsigned int count = 0; + + dp = opendir("/proc/self/task"); + if (dp == NULL) { + _E("opendir() is failed. errno(%d)", errno); + return 0; + } + + while ((dentry = readdir(dp)) != NULL) { + if (!isdigit(dentry->d_name[0])) + continue; + + count++; + } + + closedir(dp); + return count; +} +#else +static unsigned int __get_thread_count(void) +{ + unsigned int count = 0; + char line[LINE_MAX]; + FILE *fp; + + fp = fopen("/proc/self/status", "r"); + if (fp == NULL) { + _E("fopen() is failed"); + return 0; + } + + while (fgets(line, sizeof(line), fp)) { + if (sscanf(line, "Threads: %u", &count) == 1) + break; + } + + fclose(fp); + return count; +} +#endif + +static void __wait_for_threads(unsigned int threads) +{ + unsigned int thread_count; + + if (threads <= 1) + return; + + _W("Thread count = %u", threads); + do { + thread_count = __get_thread_count(); + _D("Current thread count = %u", thread_count); + if (thread_count >= threads) + break; + + usleep(50 * 1000); + } while (threads != thread_count); + _E("Threads(%u) are ready", thread_count); +} + static int __before_loop(int argc, char **argv) { int client_fd; int ret = -1; bundle *extra = NULL; + const char *val; + unsigned int threads = 0; int r; if (_verify_proc_caps() < 0) @@ -382,9 +450,17 @@ static int __before_loop(int argc, char **argv) } if (__loader_callbacks->create) { + val = bundle_get_val(extra, "threads"); + if (val && isdigit(val[0])) { + _D("threads: %s", val); + threads = atoi(val); + } + __loader_callbacks->create(extra, __loader_type, __loader_user_data); ret = 0; + aul_launch_worker_init(); + __wait_for_threads(threads); } if (extra) @@ -409,8 +485,6 @@ static int __before_loop(int argc, char **argv) if (r != VCONF_OK) _E("Failed to register callback for regionformat. error(%d)", r); - aul_launch_worker_init(); - return ret; } -- 2.7.4 From 8250edb891e7e9c7ba67ed4c5e0c0f4c68a91f3b Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 16 Jan 2023 05:37:58 +0000 Subject: [PATCH 10/16] Release version 0.22.1 Changes: - Print appid for debugging - Fix build error - Wait for threads ready Change-Id: I0c31efefc993cf2f3916edd1606d9f6e86aea4a5 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 8ad01c6..bd7a843 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.22.0 +Version: 0.22.1 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From 979cea589c8ac2bbf593e3cf1b8d4510921dbc8a Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 16 Jan 2023 23:27:29 +0000 Subject: [PATCH 11/16] Add retrying count check for waiting threads If the retyring count is exceeded, the candidate process stops to wait for threads ready. The maximum retrying count is 600. In the worst case, the candidate process can be waitted until 30 seconds. Change-Id: I4c73674c9f783499af1087c3855f56205a52a6ad Signed-off-by: Hwankyu Jhun --- src/lib/launchpad/src/launchpad_lib.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/lib/launchpad/src/launchpad_lib.c b/src/lib/launchpad/src/launchpad_lib.c index af20cae..0c7dd27 100644 --- a/src/lib/launchpad/src/launchpad_lib.c +++ b/src/lib/launchpad/src/launchpad_lib.c @@ -404,7 +404,9 @@ static unsigned int __get_thread_count(void) static void __wait_for_threads(unsigned int threads) { +#define MAX_RETRYING_COUNT 600 unsigned int thread_count; + unsigned int retrying_count = 0; if (threads <= 1) return; @@ -412,13 +414,16 @@ static void __wait_for_threads(unsigned int threads) _W("Thread count = %u", threads); do { thread_count = __get_thread_count(); - _D("Current thread count = %u", thread_count); - if (thread_count >= threads) - break; + if (thread_count >= threads) { + _E("Threads(%u) are ready", thread_count); + return; + } + _D("Current thread count = %u", thread_count); usleep(50 * 1000); - } while (threads != thread_count); - _E("Threads(%u) are ready", thread_count); + retrying_count++; + } while (retrying_count < MAX_RETRYING_COUNT); + _E("Maximum retrying count exceeded"); } static int __before_loop(int argc, char **argv) -- 2.7.4 From bee27c1c04f682ab5ca96abaf66157abee2c4eef Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 17 Jan 2023 00:25:59 +0000 Subject: [PATCH 12/16] Release version 0.22.2 Changes: - Add retrying count check for waiting threads Change-Id: Ifb70ace83d91cf386993b37ccca4c97c69182d50 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 bd7a843..0cbc72e 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.22.1 +Version: 0.22.2 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From 4c969c4a6db986fb18a745b613dc0997a1cc95d2 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 19 Jan 2023 01:47:28 +0000 Subject: [PATCH 13/16] Add new APIs for loader process Before calling the loader_launch_cb() callback function, the loader process has to make blocking all sub threads if a new thread is able to be created by the sub thread. This patch adds new functions for the loader process. Some loader process creates a new process while calling the security_manager_prepare_app2(). It makes an application launch failure issue. When calling the loader_prelaunch_cb() callback function, the loader should call the launchpad_loader_block_threads() to make blocking all sub threads. And then, the loader calls the launchpad_loader_unblock_threads() while calling the launchpad_launch_cb() callback function. Even if the sub thread creates a new thread while calling the launchpad_loader_block_threads(), it handles by the security_manager_prepare_app2() function. This is not complete solution. But, this patch is able to reduce the risk about the launch failure issues. Adds: - launchpad_loader_block_threads() - launchpad_loader_unblock_threads() Change-Id: Ib98d435507abbb0d3ebe0a5617d7fcb2509c154e Signed-off-by: Hwankyu Jhun --- src/lib/launchpad/inc/launchpad.h | 21 +++++++ src/lib/launchpad/src/launchpad_lib.c | 111 ++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) diff --git a/src/lib/launchpad/inc/launchpad.h b/src/lib/launchpad/inc/launchpad.h index 86ea976..b7d6c21 100644 --- a/src/lib/launchpad/inc/launchpad.h +++ b/src/lib/launchpad/inc/launchpad.h @@ -81,6 +81,27 @@ int launchpad_loader_set_priority(int prio); bundle *launchpad_loader_get_bundle(void); +/** + * @brief Blocks all sub threads of the loader. + * @remarks This function has to be called in the main thread. + * + * @return @c on success, + * otherwise a negative error value + * + * @see #launchpad_loader_unblock_threads() + */ +int launchpad_loader_block_threads(void); + +/** + * @brief Unblocks all sub threads of the loader. + * @remarks This function has to be called in the main thread. + * + * @return @c on success, + * otherwise a negative error value + * @see #launchpad_loader_block_threads() + */ +int launchpad_loader_unblock_threads(void); + #ifdef __cplusplus } #endif diff --git a/src/lib/launchpad/src/launchpad_lib.c b/src/lib/launchpad/src/launchpad_lib.c index 0c7dd27..7c4512f 100644 --- a/src/lib/launchpad/src/launchpad_lib.c +++ b/src/lib/launchpad/src/launchpad_lib.c @@ -44,6 +44,17 @@ #endif #define AUL_PR_NAME 16 +#define SIGRTINT (SIGRTMIN + 2) + +typedef struct thread_handler_s { + struct sigaction old; + GMutex mutex; + GCond cond; + gint count; + gint num; + bool blocked; + bool done; +} thread_handler_t; static loader_lifecycle_callback_s *__loader_callbacks; static loader_adapter_s *__loader_adapter; @@ -54,6 +65,7 @@ static bundle *__bundle; static int __loader_type = LAUNCHPAD_TYPE_UNSUPPORTED; static int __loader_id; static bool __loop_quit; +static thread_handler_t __thread_handler; static void __at_exit_to_release_bundle(void) { @@ -580,3 +592,102 @@ API int launchpad_loader_set_priority(int prio) { return _set_priority(prio); } + +static void __signal_handler(int signo) +{ + _D("Block thread"); + g_mutex_lock(&__thread_handler.mutex); + g_atomic_int_set(&__thread_handler.count, + g_atomic_int_get(&__thread_handler.count) - 1); + while (!__thread_handler.done) + g_cond_wait(&__thread_handler.cond, &__thread_handler.mutex); + g_mutex_unlock(&__thread_handler.mutex); + g_atomic_int_inc(&__thread_handler.count); + _D("Unblock thread"); +} + +API int launchpad_loader_block_threads(void) +{ + struct sigaction act; + struct dirent *dentry; + DIR *dp; + pid_t pid = getpid(); + pid_t tid; + gint i; + + if (__thread_handler.blocked) { + _D("Already blocked"); + return 0; + } + + g_mutex_init(&__thread_handler.mutex); + g_cond_init(&__thread_handler.cond); + + memset(&act, '\0', sizeof(act)); + sigemptyset(&act.sa_mask); + act.sa_flags = SA_RESTART; + act.sa_handler = __signal_handler; + + if (sigaction(SIGRTINT, &act, &__thread_handler.old) != 0) { + _E("sigaction() is failed. errno(%d)", errno); + return -1; + } + + __thread_handler.done = false; + __thread_handler.count = 0; + __thread_handler.num = 0; + + dp = opendir("/proc/self/task"); + if (dp == NULL) { + _E("opendir() is failed. errno(%d)", errno); + sigaction(SIGRTINT, &__thread_handler.old, NULL); + return -1; + } + + while ((dentry = readdir(dp)) != NULL) { + if (!isdigit(dentry->d_name[0])) + continue; + + tid = atoi(dentry->d_name); + if (tid != pid) { + _D("Send signal to thread(%d)", tid); + if (tgkill(pid, tid, SIGRTINT) != 0) { + _E("tgkill() is failed. errno(%d)", errno); + } else { + g_atomic_int_inc(&__thread_handler.count); + __thread_handler.num++; + } + } + } + closedir(dp); + + for (i = 1000; g_atomic_int_get(&__thread_handler.count) && i; --i) + usleep(2000); + + __thread_handler.blocked = true; + + return 0; +} + +API int launchpad_loader_unblock_threads(void) +{ + gint i; + + if (!__thread_handler.blocked) + return 0; + + g_mutex_lock(&__thread_handler.mutex); + __thread_handler.done = true; + g_cond_broadcast(&__thread_handler.cond); + g_mutex_unlock(&__thread_handler.mutex); + + for (i = 1000; g_atomic_int_get(&__thread_handler.count) != __thread_handler.num && i; --i) + usleep(2000); + + sigaction(SIGRTINT, &__thread_handler.old, NULL); + g_mutex_clear(&__thread_handler.mutex); + g_cond_clear(&__thread_handler.cond); + __thread_handler.blocked = false; + + return 0; +} -- 2.7.4 From 3fe83ade5610d4189122df06b2c29854321f26b4 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 30 Jan 2023 01:33:22 +0000 Subject: [PATCH 14/16] Release version 0.23.0 Changes: - Add new APIs for loader process Change-Id: I8bc1e832f5e1e53a720638eef47111fbad7e06d5 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 0cbc72e..a91fa3c 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.22.2 +Version: 0.23.0 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From 697c543ccc5e2f54e6ca9b6280e12e5b1d30d189 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 31 Jan 2023 06:35:46 +0000 Subject: [PATCH 15/16] Modify loader priority feature After this patch is applied, the loader priority feature is basically activated. The platform developer can adjust a scheduling priority using the loader configuration file. The 'SCEHD_PRIORITY' tag is added for the loader process. The loader developer can set the scheduling priority as below: +------------------------------------------------------------------------------+ | [LOADER] | | NAME hw-loader | | ... | | SCEHD_PRIORITY -20 | +------------------------------------------------------------------------------+ The range of the priority is -20 to 19. (-20 being the highest priority and 19 being the lowest priority.) If the loader has the sched priority tag, the child process sets the scheduling priority using the configure information after the process is created. And then, the loader process sets the priority to the normal priority before running the main loop. Change-Id: I531cc8381936ef4f6c9b8bad1640a0a8714f2777 Signed-off-by: Hwankyu Jhun --- CMakeLists.txt | 3 --- packaging/launchpad.spec | 5 ----- src/app-defined-loader/src/app-defined-loader.cc | 21 --------------------- src/launchpad-loader/src/launchpad_loader.c | 7 ------- 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 | 16 +++++++++++++--- src/launchpad-process-pool/src/loader_info.c | 9 ++++++++- src/lib/common/src/launchpad_common.c | 10 ++++++---- src/lib/launchpad/src/launchpad_lib.c | 1 + 10 files changed, 30 insertions(+), 44 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fc8276c..1708bfa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,9 +4,6 @@ PROJECT(launchpad) IF(_TIZEN_FEATURE_PRIORITY_CHANGE) ADD_DEFINITIONS("-DTIZEN_FEATURE_PRIORITY_CHANGE") ENDIF(_TIZEN_FEATURE_PRIORITY_CHANGE) -IF(_TIZEN_FEATURE_LOADER_PRIORITY) - ADD_DEFINITIONS("-DTIZEN_FEATURE_LOADER_PRIORITY") -ENDIF(_TIZEN_FEATURE_LOADER_PRIORITY) IF(_TIZEN_FEATURE_SET_PERSONALITY_32) ADD_DEFINITIONS("-DTIZEN_FEATURE_SET_PERSONALITY_32") ENDIF(_TIZEN_FEATURE_SET_PERSONALITY_32) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index a91fa3c..a48227f 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -44,7 +44,6 @@ Provides: app-launchpad Obsoletes: amd-mod-launchpad %define tizen_feature_priority_change 0 -%define tizen_feature_loader_priority 0 %ifarch armv7l i686 i586 %define tizen_arch32 1 %else @@ -119,9 +118,6 @@ export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" %if 0%{?tizen_feature_priority_change} _TIZEN_FEATURE_PRIORITY_CHANGE=ON %endif -%if 0%{?tizen_feature_loader_priority} -_TIZEN_FEATURE_LOADER_PRIORITY=ON -%endif %if 0%{?tizen_arch32} _TIZEN_FEATURE_SET_PERSONALITY_32=ON %else @@ -142,7 +138,6 @@ MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` -DMAJORVER=${MAJORVER} \ -DHW_LOADER_THREADS=${HW_LOADER_THREADS} \ -D_TIZEN_FEATURE_PRIORITY_CHANGE:BOOL=${_TIZEN_FEATURE_PRIORITY_CHANGE} \ - -D_TIZEN_FEATURE_LOADER_PRIORITY:BOOL=${_TIZEN_FEATURE_LOADER_PRIORITY} \ -D_TIZEN_FEATURE_SET_PERSONALITY_32:BOOL=${_TIZEN_FEATURE_SET_PERSONALITY_32} \ -D_TIZEN_FEATURE_PRELINK:BOOL=${_TIZEN_FEATURE_PRELINK} \ -D_TIZEN_FEATURE_LOADER_ARCH64:BOOL=${_TIZEN_FEATURE_LOADER_ARCH64} \ diff --git a/src/app-defined-loader/src/app-defined-loader.cc b/src/app-defined-loader/src/app-defined-loader.cc index b96e72e..3e9f368 100644 --- a/src/app-defined-loader/src/app-defined-loader.cc +++ b/src/app-defined-loader/src/app-defined-loader.cc @@ -85,14 +85,6 @@ class AppDefinedLoader { return adapter_; } - void SetLoaderPriority(bool enable) { - loader_priority_enabled_ = enable; - } - - bool IsLoaderPriorityEnabled() { - return loader_priority_enabled_; - } - void SetFdHandler(Ecore_Fd_Handler* fd_handler) { fd_handler_ = fd_handler; } @@ -142,9 +134,6 @@ class AppDefinedLoader { return; } - if (loader->IsLoaderPriorityEnabled()) - launchpad_loader_set_priority(19); - loader->PreloadLib(ex); ecore_init(); setenv("AUL_LOADER_INIT", "1", 1); @@ -153,16 +142,12 @@ class AppDefinedLoader { setenv("AUL_HWACC", "none", 1); else if (loader_type == LOADER_TYPE_HW) setenv("AUL_HWACC", "hw", 1); - - if (loader->IsLoaderPriorityEnabled()) - launchpad_loader_set_priority(0); } static int OnLaunch(int argc, char** argv, const char* app_path, const char* appid, const char* pkgid, const char* pkg_type, void* user_data) { _I("on launch"); - AppDefinedLoader* loader = static_cast(user_data); bundle* kb = launchpad_loader_get_bundle(); if (kb == nullptr) return 0; @@ -318,7 +303,6 @@ class AppDefinedLoader { private: std::shared_ptr lifecycle_cb_ = nullptr; std::shared_ptr adapter_ = nullptr; - bool loader_priority_enabled_ = false; loader_receiver_cb receiver_cb_ = nullptr; Ecore_Fd_Handler* fd_handler_ = nullptr; std::unique_ptr proc_; @@ -331,11 +315,6 @@ class AppDefinedLoader { int main(int argc, char** argv) { launchpad::AppDefinedLoader loader(argc, argv); - -#ifdef TIZEN_FEATURE_LOADER_PRIORITY - loader.SetLoaderPriority(true); -#endif - return launchpad_loader_main(argc, argv, loader.GetLifeCycle().get(), loader.GetAdapter().get(), &loader); } diff --git a/src/launchpad-loader/src/launchpad_loader.c b/src/launchpad-loader/src/launchpad_loader.c index f87150b..b815e48 100644 --- a/src/launchpad-loader/src/launchpad_loader.c +++ b/src/launchpad-loader/src/launchpad_loader.c @@ -203,10 +203,6 @@ static void __loader_create_cb(bundle *extra, int type, void *user_data) return; } -#ifdef TIZEN_FEATURE_LOADER_PRIORITY - launchpad_loader_set_priority(19); -#endif - if (!strcmp(LOADER_TYPE_COMMON, ltype)) __type = TYPE_COMMON; else if (!strcmp(LOADER_TYPE_SW, ltype)) @@ -252,9 +248,6 @@ static void __loader_create_cb(bundle *extra, int type, void *user_data) _E("Failed to register callback for %s", VCONFKEY_SETAPPL_APP_HW_ACCELERATION); } -#ifdef TIZEN_FEATURE_LOADER_PRIORITY - launchpad_loader_set_priority(0); -#endif } static loader_convertible __converter_table[MAX_LOADER_TYPE][MAX_ACC_TYPE] = { diff --git a/src/launchpad-process-pool/inc/loader_info.h b/src/launchpad-process-pool/inc/loader_info.h index 79ec242..6d44b1d 100644 --- a/src/launchpad-process-pool/inc/loader_info.h +++ b/src/launchpad-process-pool/inc/loader_info.h @@ -55,6 +55,7 @@ typedef struct _loader_info { bool is_hydra; bool app_check; int on_boot_timeout; + int sched_priority; } 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 31cbc16..58de327 100644 --- a/src/launchpad-process-pool/inc/slot_info.h +++ b/src/launchpad-process-pool/inc/slot_info.h @@ -38,6 +38,7 @@ typedef struct slot_info_s { bool is_hydra; bool app_check; int on_boot_timeout; + int sched_priority; } 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 be6ab2a..e5ca890 100644 --- a/src/launchpad-process-pool/src/launchpad.c +++ b/src/launchpad-process-pool/src/launchpad.c @@ -131,6 +131,7 @@ typedef struct { int cpu_check_count; int on_boot_timeout; guint on_boot_timer; + int sched_priority; } candidate_process_context_t; typedef struct { @@ -779,7 +780,8 @@ static int __real_send(int clifd, int ret) return 0; } -static int __fork_app_process(int (*child_fn)(void *), void *arg) +static int __fork_app_process(int (*child_fn)(void *), void *arg, + int sched_priority) { int pid; int ret; @@ -791,6 +793,9 @@ static int __fork_app_process(int (*child_fn)(void *), void *arg) } if (pid == 0) { + if (sched_priority != 0) + _set_priority(sched_priority); + _W("security_manager_prepare_app_candidate ++"); ret = security_manager_prepare_app_candidate(); _W("security_manager_prepare_app_candidate --"); @@ -957,7 +962,8 @@ static int __prepare_candidate_process(int type, int loader_id) if (ret < 0) return ret; - info->pid = __fork_app_process(__exec_loader_process, info->argv); + info->pid = __fork_app_process(__exec_loader_process, info->argv, + cpt->sched_priority); if (info->pid == -1) { _E("Failed to create a child process. type: %d", type); __candidate_info_free(info); @@ -1430,7 +1436,7 @@ static int __launch_directly(const char *appid, const char *app_path, int clifd, arg.kb = kb; _print_hwc_log("before calling fork(). %s", appid); - pid = __fork_app_process(__exec_app_process, &arg); + pid = __fork_app_process(__exec_app_process, &arg, 0); if (pid <= 0) _E("failed to fork app process"); @@ -1988,6 +1994,7 @@ static int __dispatch_cmd_add_loader(bundle *kb) slot_info.is_hydra = false; slot_info.app_check = true; slot_info.on_boot_timeout = 0; + slot_info.sched_priority = 0; cpc = __add_slot(&slot_info); free(loader_name); @@ -2047,6 +2054,7 @@ static int __dispatch_cmd_add_app_defined_loader(bundle *kb) slot_info.is_hydra = false; slot_info.app_check = true; slot_info.on_boot_timeout = 0; + slot_info.sched_priority = 0; cpc = __add_slot(&slot_info); bundle_free_encoded_rawdata(&extra); @@ -2735,6 +2743,7 @@ static candidate_process_context_t *__create_slot(slot_info_t *info) cpc->pss = 0; cpc->cpu_check_count = 0; cpc->on_boot_timeout = info->on_boot_timeout; + cpc->sched_priority = info->sched_priority; if ((cpc->deactivation_method & METHOD_OUT_OF_MEMORY) && __is_low_memory()) @@ -3061,6 +3070,7 @@ static void __add_slot_from_info(gpointer data, gpointer user_data) .is_hydra = info->is_hydra, .app_check = info->app_check, .on_boot_timeout = info->on_boot_timeout, + .sched_priority = info->sched_priority, }; 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 3788b90..c43986f 100644 --- a/src/launchpad-process-pool/src/loader_info.c +++ b/src/launchpad-process-pool/src/loader_info.c @@ -44,6 +44,7 @@ #define TAG_HYDRA "HYDRA" #define TAG_APP_CHECK "APP_CHECK" #define TAG_ON_BOOT_TIMEOUT "ON_BOOT_TIMEOUT" +#define TAG_SCHED_PRIORITY "SCHED_PRIORITY" #define VAL_ON "ON" #define VAL_OFF "OFF" @@ -62,7 +63,7 @@ static loader_info_t *__create_loader_info() { loader_info_t *info; - info = malloc(sizeof(loader_info_t)); + info = calloc(1, sizeof(loader_info_t)); if (info == NULL) { _E("Out of memory"); return NULL; @@ -312,6 +313,12 @@ static GList *__parse_file(GList *list, const char *path) cur_info->app_check = false; } else if (strcasecmp(TAG_ON_BOOT_TIMEOUT, tok1) == 0) { cur_info->on_boot_timeout = atoi(tok2); + } else if (strcasecmp(TAG_SCHED_PRIORITY, tok1) == 0) { + cur_info->sched_priority = atoi(tok2); + if (cur_info->sched_priority < -20) + cur_info->sched_priority = -20; + else if (cur_info->sched_priority > 19) + cur_info->sched_priority = 19; } } diff --git a/src/lib/common/src/launchpad_common.c b/src/lib/common/src/launchpad_common.c index d474ebc..f062423 100644 --- a/src/lib/common/src/launchpad_common.c +++ b/src/lib/common/src/launchpad_common.c @@ -1049,15 +1049,17 @@ int _setup_stdio(const char *ident) int _set_priority(int prio) { - int r; + int ret; - r = setpriority(PRIO_PGRP, 0, prio); - if (r < 0) { + ret = setpriority(PRIO_PROCESS, 0, prio); + if (ret != 0) { SECURE_LOGE("Failed to set process(%d) priority(%d) - err(%d)", getpid(), prio, errno); + } else { + SECURE_LOGD("priority(%d)", prio); } - return r; + return ret; } static int __dbus_send_message(DBusMessage *callback(void *), void *user_data, diff --git a/src/lib/launchpad/src/launchpad_lib.c b/src/lib/launchpad/src/launchpad_lib.c index 7c4512f..a96f468 100644 --- a/src/lib/launchpad/src/launchpad_lib.c +++ b/src/lib/launchpad/src/launchpad_lib.c @@ -577,6 +577,7 @@ API int launchpad_loader_main(int argc, char **argv, return -1; } + _set_priority(0); _D("[candidate] ecore main loop begin"); __loader_adapter->loop_begin(__loader_user_data); -- 2.7.4 From ce362d2a16d35005af14e68d9cdd9d962f0d38a4 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 31 Jan 2023 22:54:52 +0000 Subject: [PATCH 16/16] Release version 0.23.1 Changes: - Modify loader priority feature Change-Id: I62b68f788ebd326857aef54ff7c013724c368028 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 a48227f..89341a4 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.23.0 +Version: 0.23.1 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4