From 98405d45c88d385d2765240f129e5c7f1b428887 Mon Sep 17 00:00:00 2001 From: wanglei Date: Tue, 22 Jul 2025 07:54:11 +0000 Subject: [PATCH 1/5] appspawn dlopen akrweb so Signed-off-by: wanglei --- interfaces/innerkits/include/appspawn.h | 2 + modules/ace_adapter/BUILD.gn | 3 + modules/ace_adapter/ace_adapter.cpp | 39 ++++++++- standard/BUILD.gn | 3 + standard/appspawn_service.c | 111 ++++++++++++++++++++++++ 5 files changed, 156 insertions(+), 2 deletions(-) diff --git a/interfaces/innerkits/include/appspawn.h b/interfaces/innerkits/include/appspawn.h index 8a53fdc7..70463ee0 100644 --- a/interfaces/innerkits/include/appspawn.h +++ b/interfaces/innerkits/include/appspawn.h @@ -122,6 +122,8 @@ typedef enum { MSG_UNINSTALL_DEBUG_HAP, MSG_LOCK_STATUS, MSG_OBSERVE_PROCESS_SIGNAL_STATUS, + MSG_UNLOAD_WEBLIB_IN_APPSPAWN, + MSG_LOAD_WEBLIB_IN_APPSPAWN, MAX_TYPE_INVALID } AppSpawnMsgType; diff --git a/modules/ace_adapter/BUILD.gn b/modules/ace_adapter/BUILD.gn index 6b648902..5f94d3bb 100644 --- a/modules/ace_adapter/BUILD.gn +++ b/modules/ace_adapter/BUILD.gn @@ -30,6 +30,9 @@ ohos_shared_library("appspawn_ace") { "${appspawn_path}/util:libappspawn_util", ] defines = [] + if (target_cpu == "arm64") { + defines += [ "PRE_DLOPEN_ARKWEB_LIB" ] + } if (asan_detector || is_asan) { defines += [ "ASAN_DETECTOR" ] } diff --git a/modules/ace_adapter/ace_adapter.cpp b/modules/ace_adapter/ace_adapter.cpp index 1b00fe42..4573d886 100644 --- a/modules/ace_adapter/ace_adapter.cpp +++ b/modules/ace_adapter/ace_adapter.cpp @@ -32,6 +32,7 @@ #include "hitrace_meter.h" #include "js_runtime.h" #include "json_utils.h" +#include "parameter.h" #include "parameters.h" #include "resource_manager.h" #ifndef APPSPAWN_TEST @@ -132,8 +133,6 @@ static void LoadExtendLib(void) PreloadModule(); SetTraceDisabled(false); - APPSPAWN_LOGI("LoadExtendLib: Start reclaim file cache"); - OHOS::Ace::AceForwardCompatibility::ReclaimFileCache(getpid()); Resource::ResourceManager *systemResMgr = Resource::GetSystemResourceManagerNoSandBox(); APPSPAWN_CHECK(systemResMgr != nullptr, return, "Fail to get system resource manager"); APPSPAWN_LOGI("LoadExtendLib: End preload VM"); @@ -318,6 +317,37 @@ APPSPAWN_STATIC int DoDlopenLibs(const cJSON *root, ParseJsonContext *context) return 0; } +#ifdef PRE_DLOPEN_ARKWEB_LIB +static void DlopenArkWebLib() +{ + char packageName[PATH_MAX] = {0}; + GetParameter("persist.arkwebcore.package_name", "", packageName, PATH_MAX); + if (strlen(packageName) == 0) { + APPSPAWN_LOGE("persist.arkwebcore.package_name is empty"); + return; + } + + std::string arkwebLibPath = "/data/app/el1/bundle/public/" + std::string(packageName) + + "/libs/arm64:/data/storage/el1/bundle/arkwebcore/libs/arm64"; + APPSPAWN_LOGI("DlopenArkWebLib arkwebLibPath: %{public}s", arkwebLibPath.c_str()); + + Dl_namespace dlns; + dlns_init(&dlns, "nweb_ns"); + dlns_create(&dlns, arkwebLibPath.c_str()); + + Dl_namespace ndkns; + dlns_get("ndk", &ndkns); + dlns_inherit(&dlns, &ndkns, "allow_all_shared_libs"); + + void* webEngineHandle = dlopen_ns(&dlns, "libarkweb_engine.so", RTLD_NOW | RTLD_GLOBAL); + if (!webEngineHandle) { + APPSPAWN_LOGE("FAILED to dlopen libarkweb_engine.so in appspawn %{public}s", dlerror()); + } else { + APPSPAWN_LOGI("SUCCESS to dlopen libarkweb_engine.so in appspawn"); + } +} +#endif + APPSPAWN_STATIC int DlopenAppSpawn(AppSpawnMgr *content) { if (!IsAppSpawnMode(content)) { @@ -325,6 +355,11 @@ APPSPAWN_STATIC int DlopenAppSpawn(AppSpawnMgr *content) } (void)ParseJsonConfig("etc/appspawn", SYSTEMLIB_JSON, DoDlopenLibs, nullptr); +#ifdef PRE_DLOPEN_ARKWEB_LIB + DlopenArkWebLib(); + APPSPAWN_LOGI("DlopenAppSpawn: Start reclaim file cache"); + OHOS::Ace::AceForwardCompatibility::ReclaimFileCache(getpid()); +#endif return 0; } diff --git a/standard/BUILD.gn b/standard/BUILD.gn index f04763dd..9d6f694d 100644 --- a/standard/BUILD.gn +++ b/standard/BUILD.gn @@ -52,6 +52,9 @@ ohos_executable("appspawn") { ] defines = [] + if (target_cpu == "arm64") { + defines += [ "PRE_DLOPEN_ARKWEB_LIB" ] + } configs = [ ":appspawn_server_config", "${appspawn_path}:appspawn_config", diff --git a/standard/appspawn_service.c b/standard/appspawn_service.c index 49fce144..02f65c2e 100644 --- a/standard/appspawn_service.c +++ b/standard/appspawn_service.c @@ -15,6 +15,7 @@ #include "appspawn_service.h" +#include #include #include #include @@ -61,6 +62,9 @@ #define PIDFD_NONBLOCK O_NONBLOCK #endif +// When arkweb is upgraded, the maximum number of dlclose loop iterations. +#define MAX_DLCLOSE_COUNT 10 + static void WaitChildTimeout(const TimerHandle taskHandle, void *context); static void ProcessChildResponse(const WatcherHandle taskHandle, int fd, uint32_t *events, const void *context); static void WaitChildDied(pid_t pid); @@ -1765,6 +1769,95 @@ APPSPAWN_STATIC void ProcessObserveProcessSignalMsg(AppSpawnConnection *connecti DeleteAppSpawnMsg(&message); } +#ifdef PRE_DLOPEN_ARKWEB_LIB +static bool IsNWebLibLoaded(Dl_namespace dlns) +{ + void* handler = dlopen_ns(&dlns, "libarkweb_engine.so", RTLD_NOW | RTLD_NOLOAD); + if (handler) { + dlclose(handler); + return true; + } + return false; +} + +static int ProcessSpawnDlopenMsg(AppSpawnMsgNode *message) +{ + AppSpawnMsg* msg = &message->msgHeader; + APPSPAWN_LOGI("Recv ProcessSpawnReqMsg message header magic: 0x%{public}x type: %{public}u" + "id: %{public}u len: %{public}u processName: %{public}s", + msg->magic, + msg->msgType, + msg->msgId, + msg->msgLen, + msg->processName); + + Dl_namespace dlns; + if (dlns_get("nweb_ns", &dlns) != 0) { + char arkwebLibPath[PATH_SIZE] = ""; + if (snprintf_s(arkwebLibPath, sizeof(arkwebLibPath), sizeof(arkwebLibPath) - 1, + "%s%s%s", "/data/app/el1/bundle/public/", msg->processName, + "/libs/arm64:/data/storage/el1/bundle/arkwebcore/libs/arm64") < 0) { + APPSPAWN_LOGE("FAILED to get arkwebLibPath"); + return -1; + } + APPSPAWN_LOGI("ProcessSpawnDlopenMsg arkwebLibPath: %{public}s", arkwebLibPath); + + dlns_init(&dlns, "nweb_ns"); + dlns_create(&dlns, arkwebLibPath); + } + + Dl_namespace ndkns; + dlns_get("ndk", &ndkns); + dlns_inherit(&dlns, &ndkns, "allow_all_shared_libs"); + + void* webEngineHandle = dlopen_ns(&dlns, "libarkweb_engine.so", RTLD_NOW | RTLD_GLOBAL); + if (!webEngineHandle) { + APPSPAWN_LOGE("FAILED to dlopen libarkweb_engine.so in appspawn %{public}s", dlerror()); + return -1; + } else { + APPSPAWN_LOGI("SUCCESS to dlopen libarkweb_engine.so in appspawn"); + return 0; + } +} + +static int ProcessSpawnDlcloseMsg(AppSpawnMsgNode *message) +{ + AppSpawnMsg* msg = &message->msgHeader; + APPSPAWN_LOGI("Recv ProcessSpawnReqMsg message header magic: 0x%{public}x type: %{public}u" + "id: %{public}u len: %{public}u processName: %{public}s", + msg->magic, + msg->msgType, + msg->msgId, + msg->msgLen, + msg->processName); + Dl_namespace dlns; + if (dlns_get("nweb_ns", &dlns) != 0) { + APPSPAWN_LOGE("Failed to get nweb ns"); + return 0; + } + + void* webEngineHandle = dlopen_ns(&dlns, "libarkweb_engine.so", RTLD_NOW | RTLD_NOLOAD); + if (!webEngineHandle) { + APPSPAWN_LOGI("FAILED to dlopen libarkweb_engine.so in appspawn %{public}s", dlerror()); + return 0; + } + + int cnt = MAX_DLCLOSE_COUNT; + do { + cnt--; + dlclose(webEngineHandle); + } while (cnt > 0 && IsNWebLibLoaded(dlns)); + + if (cnt == 0 && IsNWebLibLoaded(dlns)) { + APPSPAWN_LOGE("ProcessSpawnDlcloseMsg failed to dlclose arkweb so"); + return -1; + } + + APPSPAWN_LOGE("ProcessSpawnDlcloseMsg success to dlclose arkweb so"); + return 0; +} +#endif + static void ProcessRecvMsg(AppSpawnConnection *connection, AppSpawnMsgNode *message) { AppSpawnMsg *msg = &message->msgHeader; @@ -1825,6 +1918,24 @@ static void ProcessRecvMsg(AppSpawnConnection *connection, AppSpawnMsgNode *mess case MSG_OBSERVE_PROCESS_SIGNAL_STATUS: ProcessObserveProcessSignalMsg(connection, message); break; + case MSG_UNLOAD_WEBLIB_IN_APPSPAWN: +#ifdef PRE_DLOPEN_ARKWEB_LIB + ret = ProcessSpawnDlcloseMsg(message); + SendResponse(connection, msg, ret, 0); +#else + SendResponse(connection, msg, 0, 0); +#endif + DeleteAppSpawnMsg(&message); + break; + case MSG_LOAD_WEBLIB_IN_APPSPAWN: +#ifdef PRE_DLOPEN_ARKWEB_LIB + ret = ProcessSpawnDlopenMsg(message); + SendResponse(connection, msg, ret, 0); +#else + SendResponse(connection, msg, 0, 0); +#endif + DeleteAppSpawnMsg(&message); + break; default: SendResponse(connection, msg, APPSPAWN_MSG_INVALID, 0); DeleteAppSpawnMsg(&message); -- Gitee From c62552d9edab1908528e40320ac9f3c5eef284c4 Mon Sep 17 00:00:00 2001 From: wanglei Date: Wed, 23 Jul 2025 15:29:39 +0000 Subject: [PATCH 2/5] fix review comments Signed-off-by: wanglei --- standard/appspawn_service.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/standard/appspawn_service.c b/standard/appspawn_service.c index 02f65c2e..22a83883 100644 --- a/standard/appspawn_service.c +++ b/standard/appspawn_service.c @@ -1804,11 +1804,12 @@ static int ProcessSpawnDlopenMsg(AppSpawnMsgNode *message) dlns_init(&dlns, "nweb_ns"); dlns_create(&dlns, arkwebLibPath); + + Dl_namespace ndkns; + dlns_get("ndk", &ndkns); + dlns_inherit(&dlns, &ndkns, "allow_all_shared_libs"); } - Dl_namespace ndkns; - dlns_get("ndk", &ndkns); - dlns_inherit(&dlns, &ndkns, "allow_all_shared_libs"); void* webEngineHandle = dlopen_ns(&dlns, "libarkweb_engine.so", RTLD_NOW | RTLD_GLOBAL); if (!webEngineHandle) { -- Gitee From faa238cd5f34de6e85b95e4ba6e966db37599fc0 Mon Sep 17 00:00:00 2001 From: wanglei Date: Thu, 24 Jul 2025 06:31:19 +0000 Subject: [PATCH 3/5] fix review comments Signed-off-by: wanglei --- modules/ace_adapter/ace_adapter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ace_adapter/ace_adapter.cpp b/modules/ace_adapter/ace_adapter.cpp index 4573d886..3641a3a4 100644 --- a/modules/ace_adapter/ace_adapter.cpp +++ b/modules/ace_adapter/ace_adapter.cpp @@ -357,9 +357,9 @@ APPSPAWN_STATIC int DlopenAppSpawn(AppSpawnMgr *content) (void)ParseJsonConfig("etc/appspawn", SYSTEMLIB_JSON, DoDlopenLibs, nullptr); #ifdef PRE_DLOPEN_ARKWEB_LIB DlopenArkWebLib(); +#endif APPSPAWN_LOGI("DlopenAppSpawn: Start reclaim file cache"); OHOS::Ace::AceForwardCompatibility::ReclaimFileCache(getpid()); -#endif return 0; } -- Gitee From 72a9d41f04f2a4965147410dceb2474e3d0ce23a Mon Sep 17 00:00:00 2001 From: wanglei Date: Fri, 25 Jul 2025 03:22:56 +0000 Subject: [PATCH 4/5] fix review comments Signed-off-by: wanglei --- interfaces/innerkits/include/appspawn.h | 1 - standard/appspawn_service.c | 79 ++++--------------------- 2 files changed, 10 insertions(+), 70 deletions(-) diff --git a/interfaces/innerkits/include/appspawn.h b/interfaces/innerkits/include/appspawn.h index 70463ee0..5ae89a22 100644 --- a/interfaces/innerkits/include/appspawn.h +++ b/interfaces/innerkits/include/appspawn.h @@ -122,7 +122,6 @@ typedef enum { MSG_UNINSTALL_DEBUG_HAP, MSG_LOCK_STATUS, MSG_OBSERVE_PROCESS_SIGNAL_STATUS, - MSG_UNLOAD_WEBLIB_IN_APPSPAWN, MSG_LOAD_WEBLIB_IN_APPSPAWN, MAX_TYPE_INVALID } AppSpawnMsgType; diff --git a/standard/appspawn_service.c b/standard/appspawn_service.c index 22a83883..af2e74d7 100644 --- a/standard/appspawn_service.c +++ b/standard/appspawn_service.c @@ -1769,18 +1769,7 @@ APPSPAWN_STATIC void ProcessObserveProcessSignalMsg(AppSpawnConnection *connecti DeleteAppSpawnMsg(&message); } -#ifdef PRE_DLOPEN_ARKWEB_LIB -static bool IsNWebLibLoaded(Dl_namespace dlns) -{ - void* handler = dlopen_ns(&dlns, "libarkweb_engine.so", RTLD_NOW | RTLD_NOLOAD); - if (handler) { - dlclose(handler); - return true; - } - return false; -} - -static int ProcessSpawnDlopenMsg(AppSpawnMsgNode *message) +static void ProcessSpawnDlopenMsg(AppSpawnConnection *connection, AppSpawnMsgNode *message) { AppSpawnMsg* msg = &message->msgHeader; APPSPAWN_LOGI("Recv ProcessSpawnReqMsg message header magic: 0x%{public}x type: %{public}u" @@ -1791,6 +1780,7 @@ static int ProcessSpawnDlopenMsg(AppSpawnMsgNode *message) msg->msgLen, msg->processName); +#ifdef PRE_DLOPEN_ARKWEB_LIB Dl_namespace dlns; if (dlns_get("nweb_ns", &dlns) != 0) { char arkwebLibPath[PATH_SIZE] = ""; @@ -1798,7 +1788,8 @@ static int ProcessSpawnDlopenMsg(AppSpawnMsgNode *message) "%s%s%s", "/data/app/el1/bundle/public/", msg->processName, "/libs/arm64:/data/storage/el1/bundle/arkwebcore/libs/arm64") < 0) { APPSPAWN_LOGE("FAILED to get arkwebLibPath"); - return -1; + SendResponse(connection, msg, -1, 0); + return; } APPSPAWN_LOGI("ProcessSpawnDlopenMsg arkwebLibPath: %{public}s", arkwebLibPath); @@ -1810,54 +1801,18 @@ static int ProcessSpawnDlopenMsg(AppSpawnMsgNode *message) dlns_inherit(&dlns, &ndkns, "allow_all_shared_libs"); } - void* webEngineHandle = dlopen_ns(&dlns, "libarkweb_engine.so", RTLD_NOW | RTLD_GLOBAL); if (!webEngineHandle) { APPSPAWN_LOGE("FAILED to dlopen libarkweb_engine.so in appspawn %{public}s", dlerror()); - return -1; + SendResponse(connection, msg, -1, 0); } else { APPSPAWN_LOGI("SUCCESS to dlopen libarkweb_engine.so in appspawn"); - return 0; - } -} - -static int ProcessSpawnDlcloseMsg(AppSpawnMsgNode *message) -{ - AppSpawnMsg* msg = &message->msgHeader; - APPSPAWN_LOGI("Recv ProcessSpawnReqMsg message header magic: 0x%{public}x type: %{public}u" - "id: %{public}u len: %{public}u processName: %{public}s", - msg->magic, - msg->msgType, - msg->msgId, - msg->msgLen, - msg->processName); - Dl_namespace dlns; - if (dlns_get("nweb_ns", &dlns) != 0) { - APPSPAWN_LOGE("Failed to get nweb ns"); - return 0; + SendResponse(connection, msg, 0, 0); } - - void* webEngineHandle = dlopen_ns(&dlns, "libarkweb_engine.so", RTLD_NOW | RTLD_NOLOAD); - if (!webEngineHandle) { - APPSPAWN_LOGI("FAILED to dlopen libarkweb_engine.so in appspawn %{public}s", dlerror()); - return 0; - } - - int cnt = MAX_DLCLOSE_COUNT; - do { - cnt--; - dlclose(webEngineHandle); - } while (cnt > 0 && IsNWebLibLoaded(dlns)); - - if (cnt == 0 && IsNWebLibLoaded(dlns)) { - APPSPAWN_LOGE("ProcessSpawnDlcloseMsg failed to dlclose arkweb so"); - return -1; - } - - APPSPAWN_LOGE("ProcessSpawnDlcloseMsg success to dlclose arkweb so"); - return 0; -} +#else + SendResponse(connection, msg, 0, 0); #endif +} static void ProcessRecvMsg(AppSpawnConnection *connection, AppSpawnMsgNode *message) { @@ -1919,22 +1874,8 @@ static void ProcessRecvMsg(AppSpawnConnection *connection, AppSpawnMsgNode *mess case MSG_OBSERVE_PROCESS_SIGNAL_STATUS: ProcessObserveProcessSignalMsg(connection, message); break; - case MSG_UNLOAD_WEBLIB_IN_APPSPAWN: -#ifdef PRE_DLOPEN_ARKWEB_LIB - ret = ProcessSpawnDlcloseMsg(message); - SendResponse(connection, msg, ret, 0); -#else - SendResponse(connection, msg, 0, 0); -#endif - DeleteAppSpawnMsg(&message); - break; case MSG_LOAD_WEBLIB_IN_APPSPAWN: -#ifdef PRE_DLOPEN_ARKWEB_LIB - ret = ProcessSpawnDlopenMsg(message); - SendResponse(connection, msg, ret, 0); -#else - SendResponse(connection, msg, 0, 0); -#endif + ProcessSpawnDlopenMsg(connection, message); DeleteAppSpawnMsg(&message); break; default: -- Gitee From 2eae7222a603078bff805b7394d2b50500ac41cb Mon Sep 17 00:00:00 2001 From: wanglei Date: Fri, 25 Jul 2025 06:17:47 +0000 Subject: [PATCH 5/5] remove unused code Signed-off-by: wanglei --- standard/appspawn_service.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/standard/appspawn_service.c b/standard/appspawn_service.c index af2e74d7..459311a0 100644 --- a/standard/appspawn_service.c +++ b/standard/appspawn_service.c @@ -62,9 +62,6 @@ #define PIDFD_NONBLOCK O_NONBLOCK #endif -// When arkweb is upgraded, the maximum number of dlclose loop iterations. -#define MAX_DLCLOSE_COUNT 10 - static void WaitChildTimeout(const TimerHandle taskHandle, void *context); static void ProcessChildResponse(const WatcherHandle taskHandle, int fd, uint32_t *events, const void *context); static void WaitChildDied(pid_t pid); -- Gitee