diff --git a/hisysevent.yaml b/hisysevent.yaml index 38bcc4645907ba9c3c4bb41f214e6da1a9f306ae..68a22d79d714fdef9a475e547b19f36c219e0379 100644 --- a/hisysevent.yaml +++ b/hisysevent.yaml @@ -17,6 +17,13 @@ SPAWN_CHILD_PROCESS_FAIL: __BASE: {type: FAULT, level: CRITICAL, desc: Spawn Child Process Fail} PROCESS_NAME: {type: STRING, desc: Process Name} ERROR_CODE: {type: INT32, desc: Error Code} + SRC_PATH : {type: STRING, desc: Source Path For Mount Failed} + TARGET_PATH: {type: STRING, desc: Target Path For Mount Failed} + SPAWN_RESULT : {type: INT32, desc: Process Spawn Result} + +SPAWN_KEY_EVENT: + __BASE: {type: BEHAVIOR, level: CRITICAL, desc: Spawn Key Event Finish} + EVENT_NAME: {type: STRING, desc: Event Name} SPAWN_PROCESS_DURATION: __BASE: {type: STATISTIC, level: CRITICAL, desc: Boot Process Duration} @@ -24,4 +31,9 @@ SPAWN_PROCESS_DURATION: MINDURATION: {type: INT64, desc: Min Spawn Process Duration} TOTALDURATION: {type: INT64, desc: Total Spawn Process Duration} EVENTCOUNT: {type: INT64, desc: Total Spawn Process Count} - STAGE: {type: STRING, desc: Boot Stage Or BootFinished Stage} \ No newline at end of file + STAGE: {type: STRING, desc: Boot Stage Or BootFinished Stage} + +SPAWN_SCENE_DURATION: + __BASE: {type: STATISTIC, level: CRITICAL, desc: Scene Duration} + SCENE_NAME: {type: STRING, desc: Scene Name} + DURATION: {type: INT64, desc: Scene Duration} \ No newline at end of file diff --git a/modules/common/BUILD.gn b/modules/common/BUILD.gn index 41c028f05e43bc3660593add8a1b1116fe1ced01..a8441284e6a382e00e7405c7acd3995d671530cf 100644 --- a/modules/common/BUILD.gn +++ b/modules/common/BUILD.gn @@ -84,6 +84,12 @@ ohos_shared_library("appspawn_common") { if (appspawn_allow_internet_permission) { defines += [ "APPSPAWN_ALLOW_INTERNET_PERMISSION" ] } + if (appspawn_report_event) { + defines += [ "APPSPAWN_HISYSEVENT" ] + external_deps += [ "hisysevent:libhisysevent" ] + include_dirs += [ "${appspawn_path}/modules/sysevent" ] + sources += [ "${appspawn_path}/modules/sysevent/hisysevent_adapter.cpp" ] + } subsystem_name = "${subsystem_name}" part_name = "${part_name}" diff --git a/modules/common/appspawn_encaps.c b/modules/common/appspawn_encaps.c index d048b869cb201606c9851fe6043099159c3197af..9337ce167cc978803e81e3545e9148531746d786 100644 --- a/modules/common/appspawn_encaps.c +++ b/modules/common/appspawn_encaps.c @@ -269,8 +269,8 @@ APPSPAWN_STATIC int SpawnSetEncapsPermissions(AppSpawnMgr *content, AppSpawningC return APPSPAWN_ARG_INVALID; } - // The trustlist is used to control not appspawn - if (!IsAppSpawnMode(content)) { + // The trustlist is used to control not appspawn or nativespawn + if (!(IsAppSpawnMode(content) || IsNativeSpawnMode(content))) { return 0; } diff --git a/modules/sandbox/sandbox_utils.cpp b/modules/sandbox/sandbox_utils.cpp index fccbb286348d700915bc89201599744a3ce159f8..85badeeae946549d949173d6827c99ee9826d16d 100644 --- a/modules/sandbox/sandbox_utils.cpp +++ b/modules/sandbox/sandbox_utils.cpp @@ -208,6 +208,10 @@ std::vector &SandboxUtils::GetJsonConfig(SandboxConfigType type) static void MakeDirRecursive(const std::string &path, mode_t mode) { +#ifdef APPSPAWN_HISYSEVENT + struct timespec startClock = {0}; + clock_gettime(CLOCK_MONOTONIC_COARSE, &startClock); +#endif size_t size = path.size(); if (size == 0) { return; @@ -223,6 +227,14 @@ static void MakeDirRecursive(const std::string &path, mode_t mode) return, "errno is %{public}d, mkdir %{public}s failed", errno, dir.c_str()); #endif } while (index < size); + +#ifdef APPSPAWN_HISYSEVENT + struct timespec endClock = {0}; + clock_gettime(CLOCK_MONOTONIC_COARSE, &endClock); + uint64_t diff = DiffTime(&startClock, &endClock); + APPSPAWN_CHECK_ONLY_EXPER(diff < FUNC_REPORT_DURATION, + ReportAbnormalDuration("MakeDirRecursive", diff)); +#endif } static bool CheckDirRecursive(const std::string &path) @@ -308,6 +320,9 @@ int32_t SandboxUtils::DoAppSandboxMountOnce(const char *originPath, const char * clock_gettime(CLOCK_MONOTONIC_COARSE, &mountEnd); uint64_t diff = DiffTime(&mountStart, &mountEnd); APPSPAWN_CHECK_ONLY_LOG(diff < MAX_MOUNT_TIME, "mount %{public}s time %{public}" PRId64 " us", originPath, diff); +#ifdef APPSPAWN_HISYSEVENT + APPSPAWN_CHECK_ONLY_EXPER(diff < FUNC_REPORT_DURATION, ReportAbnormalDuration("MOUNT", diff)); +#endif if (ret != 0) { APPSPAWN_LOGI("errno is: %{public}d, bind mount %{public}s to %{public}s", errno, originPath, destinationPath); std::string originPathStr = originPath == nullptr ? "" : originPath; @@ -884,6 +899,9 @@ int SandboxUtils::DoAllMntPointsMount(const AppSpawningCtx *appProperty, if (actionStatus == g_statusCheck) { APPSPAWN_LOGE("DoAppSandboxMountOnce section %{public}s failed, %{public}s", section.c_str(), sandboxPath.c_str()); +#ifdef APPSPAWN_HISYSEVENT + ReportMountFail(bundleName.c_str(), srcPath.c_str(), sandboxPath.c_str(), errno); +#endif return ret; } } @@ -1646,9 +1664,19 @@ int32_t SandboxUtils::ChangeCurrentDir(std::string &sandboxPackagePath, const st return ret; } -static inline int EnableSandboxNamespace(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags) +static int EnableSandboxNamespace(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags) { +#ifdef APPSPAWN_HISYSEVENT + struct timespec startClock = {0}; + clock_gettime(CLOCK_MONOTONIC_COARSE, &startClock); +#endif int rc = unshare(sandboxNsFlags); +#ifdef APPSPAWN_HISYSEVENT + struct timespec endClock = {0}; + clock_gettime(CLOCK_MONOTONIC_COARSE, &endClock); + uint64_t diff = DiffTime(&startClock, &endClock); + APPSPAWN_CHECK_ONLY_EXPER(diff < FUNC_REPORT_DURATION, ReportAbnormalDuration("unshare", diff)); +#endif APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %{public}s", GetBundleName(appProperty)); if ((sandboxNsFlags & CLONE_NEWNET) == CLONE_NEWNET) { diff --git a/modules/sysevent/hisysevent_adapter.cpp b/modules/sysevent/hisysevent_adapter.cpp index 8e1dbad17a42251afd35f8ab1d8ed84fb044b0b0..cdfbc3d94937dc49458eea544e3e872fdd5a6b8c 100644 --- a/modules/sysevent/hisysevent_adapter.cpp +++ b/modules/sysevent/hisysevent_adapter.cpp @@ -19,13 +19,28 @@ using namespace OHOS::HiviewDFX; namespace { -// event -constexpr const char* SPAWN_PROCESS_DURATION = "SPAWN_PROCESS_DURATION"; +// fail event constexpr const char* SPAWN_CHILD_PROCESS_FAIL = "SPAWN_CHILD_PROCESS_FAIL"; +// behavior event +constexpr const char* SPAWN_KEY_EVENT = "SPAWN_KEY_EVENT"; +constexpr const char* SPAWN_ABNORMAL_DURATION = "SPAWN_ABNORMAL_DURATION"; + +// statistic event +constexpr const char* SPAWN_PROCESS_DURATION = "SPAWN_PROCESS_DURATION"; + // param constexpr const char* PROCESS_NAME = "PROCESS_NAME"; constexpr const char* ERROR_CODE = "ERROR_CODE"; +constexpr const char* SPAWN_RESULT = "SPAWN_RESULT"; +constexpr const char* SRC_PATH = "SRC_PATH"; +constexpr const char* TARGET_PATH = "TARGET_PATH"; + +constexpr const char* EVENT_NAME = "EVENT_NAME"; + +constexpr const char* SCENE_NAME = "SCENE_NAME"; +constexpr const char* DURATION = "DURATION"; + constexpr const char* MAXDURATION = "MAXDURATION"; constexpr const char* MINDURATION = "MINDURATION"; constexpr const char* TOTALDURATION = "TOTALDURATION"; @@ -121,14 +136,56 @@ AppSpawnHisyseventInfo *InitHisyseventTimer(void) return hisyseventInfo; } -void ReportSpawnChildProcessFail(const char* processName, int32_t errorCode) +void ReportSpawnChildProcessFail(const char* processName, int32_t errorCode, int32_t spawnResult) { int ret = HiSysEventWrite(HiSysEvent::Domain::APPSPAWN, SPAWN_CHILD_PROCESS_FAIL, HiSysEvent::EventType::FAULT, PROCESS_NAME, processName, - ERROR_CODE, errorCode); + ERROR_CODE, errorCode, + SPAWN_RESULT, spawnResult); + if (ret != 0) { + APPSPAWN_LOGE("ReportSpawnChildProcessFail error, ret: %{public}d", ret); + } +} + +void ReportMountFail(const char* bundleName, const char* srcPath, const char* targetPath, + int32_t errorCode) +{ + if (srcPath == nullptr || strstr(srcPath, "data/app/el1/") == nullptr || + strstr(srcPath, "data/app/el2/") == nullptr) { + return; + } + int ret = HiSysEventWrite(HiSysEvent::Domain::APPSPAWN, SPAWN_CHILD_PROCESS_FAIL, + HiSysEvent::EventType::FAULT, + PROCESS_NAME, bundleName, + ERROR_CODE, ERR_APPSPAWN_CHILD_MOUNT_FAILED, + SPAWN_RESULT, APPSPAWN_SANDBOX_MOUNT_FAIL, + SRC_PATH, srcPath, + TARGET_PATH, targetPath, + SPAWN_RESULT, errorCode); + if (ret != 0) { + APPSPAWN_LOGE("ReportMountFail error, ret: %{public}d", ret); + } +} + +void ReportKeyEvent(const char *eventName) +{ + int ret = HiSysEventWrite(HiSysEvent::Domain::APPSPAWN, SPAWN_KEY_EVENT, + HiSysEvent::EventType::BEHAVIOR, + EVENT_NAME, eventName); + if (ret != 0) { + APPSPAWN_LOGE("ReportKeyEvent error, ret: %{public}d", ret); + } +} + +void ReportAbnormalDuration(const char* scene, uint64_t duration) +{ + int ret = HiSysEventWrite(HiSysEvent::Domain::APPSPAWN, SPAWN_ABNORMAL_DURATION, + HiSysEvent::EventType::BEHAVIOR, + SCENE_NAME, scene, + DURATION, duration); if (ret != 0) { - APPSPAWN_LOGE("HiSysEventWrite error, ret: %{public}d", ret); + APPSPAWN_LOGE("ReportAbnormalDuration error, ret: %{public}d", ret); } } @@ -142,7 +199,7 @@ void ReportSpawnProcessDuration(AppSpawnHisysevent *hisysevent, const char* stag EVENTCOUNT, hisysevent->eventCount, STAGE, stage); if (ret != 0) { - APPSPAWN_LOGE("HiSysEventWrite error, ret: %{public}d", ret); + APPSPAWN_LOGE("ReportSpawnProcessDuration error, ret: %{public}d", ret); } } diff --git a/modules/sysevent/hisysevent_adapter.h b/modules/sysevent/hisysevent_adapter.h index 89f3fbacc5889a3a81a2edd6a9d75d801a29cb68..89b2669421acf22b538e8d2b4ab61524e9824718 100644 --- a/modules/sysevent/hisysevent_adapter.h +++ b/modules/sysevent/hisysevent_adapter.h @@ -73,6 +73,7 @@ typedef enum { ERR_APPSPAWN_SPAWN_FAIL = ERR_APPSPAWN_BASE + 0x0381, ERR_APPSPAWN_SPAWN_TIMEOUT, ERR_APPSPAWN_CHILD_CRASH, + ERR_APPSPAWN_CHILD_MOUNT_FAILED, ERR_APPSPAWN_MAX_FAILURES_EXCEEDED, } AppSpawnHisysErrorCode; @@ -87,13 +88,21 @@ typedef struct { AppSpawnHisysevent bootEvent; // bootStage AppSpawnHisysevent manualEvent; // bootFinished } AppSpawnHisyseventInfo; - +#define FUNC_REPORT_DURATION (10 * 1000) +#define SPAWN_REPORT_DURATION (100 * 1000) +#define UNLOCK_SUCCESS "UNLOCK_SUCCESS" +#define LOCK_SUCCESS "LOCK_SUCCESS" +#define APPSPAWN_MAX_FAILURES_EXCEEDED "APPSPAWN_MAX_FAILURES_EXCEEDED" AppSpawnHisyseventInfo *InitHisyseventTimer(void); AppSpawnHisyseventInfo *GetAppSpawnHisyseventInfo(void); void AddStatisticEventInfo(AppSpawnHisyseventInfo *hisyseventInfo, uint32_t duration, bool stage); void DeleteHisyseventInfo(AppSpawnHisyseventInfo *hisyseventInfo); -void ReportSpawnChildProcessFail(const char* processName, int32_t errorCode); +void ReportSpawnChildProcessFail(const char* processName, int32_t errorCode, int32_t spawnResult); +void ReportMountFail(const char* bundleName, const char* srcPath, const char* targetPath, + int32_t errorCode); +void ReportKeyEvent(const char *eventName); +void ReportAbnormalDuration(const char* funcName, uint64_t duration); void ReportSpawnStatisticDuration(const TimerHandle taskHandle, void* content); #ifdef __cplusplus diff --git a/standard/appspawn_manager.h b/standard/appspawn_manager.h index 2cca34d8a86eda773ae353289b9e69e69082f098..1cb026acf8c510f4a9e5d8f6d4a99aefd832c089 100644 --- a/standard/appspawn_manager.h +++ b/standard/appspawn_manager.h @@ -221,6 +221,12 @@ APPSPAWN_INLINE int IsNWebSpawnMode(const AppSpawnMgr *content) (content->content.mode == MODE_FOR_NWEB_SPAWN || content->content.mode == MODE_FOR_NWEB_COLD_RUN); } +APPSPAWN_INLINE int IsNativeSpawnMode(const AppSpawnMgr *content) +{ + return (content != NULL) && + (content->content.mode == MODE_FOR_NATIVE_SPAWN); +} + APPSPAWN_INLINE int IsColdRunMode(const AppSpawnMgr *content) { return (content != NULL) && diff --git a/standard/appspawn_service.c b/standard/appspawn_service.c index 1764d93c5eef9cb6a16f8e16224524401cf8a8d9..df7efb06284c8cb6cd95db3fc7fce2618170c7b3 100644 --- a/standard/appspawn_service.c +++ b/standard/appspawn_service.c @@ -943,7 +943,7 @@ static void WaitChildDied(pid_t pid) APPSPAWN_LOGI("Child process %{public}s fail \'child crash \'pid %{public}d appId: %{public}d", processName, property->pid, property->client.id); #ifdef APPSPAWN_HISYSEVENT - ReportSpawnChildProcessFail(processName, ERR_APPSPAWN_CHILD_CRASH); + ReportSpawnChildProcessFail(processName, ERR_APPSPAWN_CHILD_CRASH, APPSPAWN_CHILD_CRASH); #endif if (property->client.id == g_lastDiedAppId + 1) { g_crashTimes++; @@ -958,7 +958,7 @@ static void WaitChildDied(pid_t pid) if (g_crashTimes >= MAX_CRASH_TIME) { APPSPAWN_LOGW("Continuous failures in spawning the app, restart appspawn"); #ifdef APPSPAWN_HISYSEVENT - ReportSpawnChildProcessFail(processName, ERR_APPSPAWN_MAX_FAILURES_EXCEEDED); + ReportKeyEvent(APPSPAWN_MAX_FAILURES_EXCEEDED); #endif StopAppSpawn(); } @@ -977,7 +977,7 @@ static void WaitChildTimeout(const TimerHandle taskHandle, void *context) kill(property->pid, SIGKILL); } #ifdef APPSPAWN_HISYSEVENT - ReportSpawnChildProcessFail(GetProcessName(property), ERR_APPSPAWN_SPAWN_TIMEOUT); + ReportSpawnChildProcessFail(GetProcessName(property), ERR_APPSPAWN_SPAWN_TIMEOUT, APPSPAWN_SPAWN_TIMEOUT); #endif SendResponse(property->message->connection, &property->message->msgHeader, APPSPAWN_SPAWN_TIMEOUT, 0); DeleteAppSpawningCtx(property); @@ -993,7 +993,7 @@ static int ProcessChildFdCheck(int fd, AppSpawningCtx *property) if (result != 0) { #ifdef APPSPAWN_HISYSEVENT - ReportSpawnChildProcessFail(GetProcessName(property), ERR_APPSPAWN_SPAWN_FAIL); + ReportSpawnChildProcessFail(GetProcessName(property), ERR_APPSPAWN_SPAWN_FAIL, result); #endif SendResponse(property->message->connection, &property->message->msgHeader, result, property->pid); DeleteAppSpawningCtx(property); @@ -1038,6 +1038,8 @@ static void ProcessChildResponse(const WatcherHandle taskHandle, int fd, uint32_ if (appspawnMgr != NULL) { AddStatisticEventInfo(appspawnMgr->hisyseventInfo, spawnProcessDuration, IsBootFinished()); } + uint64_t diff = DiffTime(&appInfo->spawnStart, &appInfo->spawnEnd); + APPSPAWN_CHECK_ONLY_EXPER(diff < SPAWN_REPORT_DURATION, ReportAbnormalDuration("SPAWNCHILD", diff)); #endif } @@ -1685,6 +1687,9 @@ static void ProcessAppSpawnLockStatusMsg(AppSpawnMsgNode *message) APPSPAWN_CHECK(ret > 0, return, "get lock status param failed, errno %{public}d", errno); ret = SetParameter(lockStatusParam, userLockStatus); APPSPAWN_CHECK(ret == 0, return, "failed to set lockstatus param value ret %{public}d", ret); +#ifdef APPSPAWN_HISYSEVENT + ReportKeyEvent(strcmp(userLockStatus, "0") == 0 ? UNLOCK_SUCCESS : LOCK_SUCCESS); +#endif #ifndef APPSPAWN_SANDBOX_NEW if (strcmp(userLockStatus, "0") == 0) { ServerStageHookExecute(STAGE_SERVER_LOCK, GetAppSpawnContent());