Nwebspawn接入hungtask监测

Signed-off-by: 陈其文 <chenqiwen6@huawei.com>
This commit is contained in:
陈其文 2024-10-26 19:56:36 +08:00
parent fd19ca8757
commit 54f7a1a2dd
6 changed files with 135 additions and 43 deletions

View File

@ -17,6 +17,7 @@
#define APPSPAWN_SERVER_H
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include "appspawn_utils.h"
@ -60,6 +61,7 @@ typedef struct AppSpawnContent {
uint32_t longProcNameLen;
uint32_t sandboxNsFlags;
int wdgOpened;
bool isLinux;
#ifdef USE_ENCAPS
int fdEncaps;
#endif

View File

@ -51,6 +51,7 @@ AppSpawnMgr *CreateAppSpawnMgr(int mode)
appMgr->content.mode = mode;
appMgr->content.sandboxNsFlags = 0;
appMgr->content.wdgOpened = 0;
appMgr->content.isLinux = false;
appMgr->servicePid = getpid();
appMgr->server = NULL;
appMgr->sigHandler = NULL;

View File

@ -24,7 +24,7 @@ static int OpenAndWriteToProc(const char *procName, const char *writeStr, size_t
return -1;
}
int procFd = open(procName, O_RDWR | O_CLOEXEC);
int procFd = open(procName, O_WRONLY | O_CLOEXEC);
if (procFd == -1) {
APPSPAWN_LOGE("open %{public}s fail,errno:%{public}d", procName, errno);
return procFd;
@ -41,49 +41,54 @@ static int OpenAndWriteToProc(const char *procName, const char *writeStr, size_t
return writeResult;
}
// Enable watchdog monitoring
static int OpenAppSpawnWatchdogFile(AppSpawnContent *content)
static const char *GetProcFile(bool isLinux)
{
APPSPAWN_LOGI("OpenAppSpawnWatchdogFile");
int result = 0;
if (access(LINUX_APPSPAWN_WATCHDOG_FILE, F_OK) == 0) {
result = OpenAndWriteToProc(LINUX_APPSPAWN_WATCHDOG_FILE, LINUX_APPSPAWN_WATCHDOG_ON,
strlen(LINUX_APPSPAWN_WATCHDOG_ON));
} else {
result = OpenAndWriteToProc(HM_APPSPAWN_WATCHDOG_FILE, HM_APPSPAWN_WATCHDOG_ON,
strlen(HM_APPSPAWN_WATCHDOG_ON));
if (isLinux) {
return LINUX_APPSPAWN_WATCHDOG_FILE;
}
content->wdgOpened = (result != -1);
APPSPAWN_LOGI("open finish,result:%{public}d", result);
return result;
return HM_APPSPAWN_WATCHDOG_FILE;
}
static void KickAppSpawnWatchdog(void)
static const char *GetProcContent(bool isLinux, bool isOpen, int mode)
{
APPSPAWN_LOGI("kick proc begin");
int result = 0;
if (access(LINUX_APPSPAWN_WATCHDOG_FILE, F_OK) == 0) {
result = OpenAndWriteToProc(LINUX_APPSPAWN_WATCHDOG_FILE, LINUX_APPSPAWN_WATCHDOG_KICK,
strlen(LINUX_APPSPAWN_WATCHDOG_KICK));
} else {
result = OpenAndWriteToProc(HM_APPSPAWN_WATCHDOG_FILE, HM_APPSPAWN_WATCHDOG_KICK,
strlen(HM_APPSPAWN_WATCHDOG_KICK));
if (isOpen) {
if (isLinux) {
return LINUX_APPSPAWN_WATCHDOG_ON;
}
return (mode == MODE_FOR_NWEB_SPAWN) ? HM_NWEBSPAWN_WATCHDOG_ON : HM_APPSPAWN_WATCHDOG_ON;
}
APPSPAWN_LOGI("kick end,result:%{public}d", result);
if (isLinux) {
return LINUX_APPSPAWN_WATCHDOG_KICK;
}
return (mode == MODE_FOR_NWEB_SPAWN) ? HM_NWEBSPAWN_WATCHDOG_KICK : HM_APPSPAWN_WATCHDOG_KICK;
}
static void DealSpawnWatchdog(AppSpawnContent *content, bool isOpen)
{
APPSPAWN_LOGI("%{public}s %{public}s watchdog begin",
(content->mode == MODE_FOR_NWEB_SPAWN) ? "Nwebspawn" : "Appspawn", isOpen ? "enable" : "kick");
int result = 0;
const char *procFile = GetProcFile(content->isLinux);
const char *procContent = GetProcContent(content->isLinux, isOpen, content->mode);
result = OpenAndWriteToProc(procFile, procContent, strlen(procContent));
if (isOpen) {
content->wdgOpened = (result != -1);
}
APPSPAWN_LOGI("%{public}s %{public}s watchdog end, result:%{public}d",
(content->mode == MODE_FOR_NWEB_SPAWN) ? "Nwebspawn" : "Appspawn", isOpen ? "enable" : "kick", result);
}
static void ProcessTimerHandle(const TimerHandle taskHandle, void *context)
{
AppSpawnContent *wdgContent = (AppSpawnContent *)context;
APPSPAWN_LOGI("kick appspawn dog start");
if (!wdgContent->wdgOpened) { //first time deal kernel file
OpenAppSpawnWatchdogFile(wdgContent);
DealSpawnWatchdog(wdgContent, true);
return;
}
KickAppSpawnWatchdog();
DealSpawnWatchdog(wdgContent, false);
}
static void CreateTimerLoopTask(AppSpawnContent *content)
@ -97,8 +102,42 @@ static void CreateTimerLoopTask(AppSpawnContent *content)
APPSPAWN_CHECK(ret == 0, return, "Failed to start timerLoopTask ret %{public}d", ret);
}
void AppSpawnKickDogStart(AppSpawnContent *content)
static int CheckKernelType(bool *isLinux)
{
CreateTimerLoopTask(content);
OpenAppSpawnWatchdogFile(content);
struct utsname uts;
if (uname(&uts) == -1) {
APPSPAWN_LOGE("Kernel type get failed,errno:%{public}d", errno);
return -1;
}
if (strcmp(uts.sysname, "Linux") == 0) {
APPSPAWN_LOGI("Kernel type is linux");
*isLinux = true;
return 0;
}
*isLinux = false;
return 0;
}
static int SpawnKickDogStart(AppSpawnMgr *mgrContent)
{
APPSPAWN_CHECK(mgrContent != NULL, return 0, "content is null");
APPSPAWN_CHECK((mgrContent->content.mode == MODE_FOR_APP_SPAWN) ||
(mgrContent->content.mode == MODE_FOR_NWEB_SPAWN), return 0, "Mode %{public}u no need enable watchdog",
mgrContent->content.mode);
if (CheckKernelType(&mgrContent->content.isLinux) != 0) {
return 0;
}
DealSpawnWatchdog(&mgrContent->content, true);
CreateTimerLoopTask(&mgrContent->content);
return 0;
}
MODULE_CONSTRUCTOR(void)
{
AddPreloadHook(HOOK_PRIO_COMMON, SpawnKickDogStart);
}

View File

@ -18,10 +18,12 @@
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
#include <sys/utsname.h>
#include "loop_event.h"
#include "appspawn_utils.h"
#include "appspawn_server.h"
#include "appspawn_modulemgr.h"
#include "appspawn_manager.h"
#ifdef __cplusplus
extern "C" {
@ -39,11 +41,11 @@ extern "C" {
#define LINUX_APPSPAWN_WATCHDOG_KICK "kick"
#define HM_APPSPAWN_WATCHDOG_ON "on,10,appspawn"
#define HM_APPSPAWN_WATCHDOG_KICK "kick,appspawn"
#define HM_NWEBSPAWN_WATCHDOG_ON "on,10,nwebspawn"
#define HM_NWEBSPAWN_WATCHDOG_KICK "kick,nwebspawn"
#define APPSPAWN_WATCHDOG_KICKTIME (10 * 1000) //10s
void AppSpawnKickDogStart(AppSpawnContent *content);
#ifdef __cplusplus
}
#endif

View File

@ -21,7 +21,6 @@
#include "appspawn_modulemgr.h"
#include "appspawn_manager.h"
#include "appspawn_service.h"
#include "appspawn_kickdog.h"
#include "parameter.h"
#include "securec.h"
@ -137,9 +136,6 @@ int main(int argc, char *const argv[])
}
AppSpawnContent *content = StartSpawnService(arg, argvSize, argc, argv);
if (content != NULL) {
if ((arg->moduleType == MODULE_APPSPAWN) && (arg->mode != MODE_FOR_APP_COLD_RUN)) {
AppSpawnKickDogStart(content);
}
content->runAppSpawn(content, argc, argv);
}
return 0;

View File

@ -73,22 +73,34 @@ static int CheckFileContent(const char *filePath, const char *targetStr)
return 0;
}
static bool CheckDeviceInLinux()
{
struct utsname uts;
if (uname(&uts) == -1) {
printf("uname get failed");
return false;
}
if (strcmp(uts.sysname, "Linux") == 0) {
printf("uname sysname is Linux");
return true;
}
return false;
}
/**
* @brief watchdog开启及定时kickdog
*
*/
HWTEST_F(AppSpawnKickDogTest, App_Spawn_AppSpawnKickDog_001, TestSize.Level0)
{
AppSpawnContent content;
int fileFd = open(HM_APPSPAWN_WATCHDOG_FILE, O_CREAT);
EXPECT_EQ(fileFd != -1, 1);
close(fileFd);
AppSpawnKickDogStart(&content);
std::unique_ptr<OHOS::AppSpawnTestServer> testServer =
std::make_unique<OHOS::AppSpawnTestServer>("appspawn -mode appspawn");
testServer->Start(nullptr);
if (access(LINUX_APPSPAWN_WATCHDOG_FILE, F_OK) == 0) {
if (CheckDeviceInLinux()) {
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, LINUX_APPSPAWN_WATCHDOG_ON), 0);
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, LINUX_APPSPAWN_WATCHDOG_KICK), -1);
} else {
@ -96,7 +108,7 @@ HWTEST_F(AppSpawnKickDogTest, App_Spawn_AppSpawnKickDog_001, TestSize.Level0)
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, HM_APPSPAWN_WATCHDOG_KICK), -1);
}
sleep(12); // wait for kick dog(kick every 10 seconds)
if (access(LINUX_APPSPAWN_WATCHDOG_FILE, F_OK) == 0) {
if (CheckDeviceInLinux()) {
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, LINUX_APPSPAWN_WATCHDOG_ON), -1);
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, LINUX_APPSPAWN_WATCHDOG_KICK), 0);
} else {
@ -104,7 +116,7 @@ HWTEST_F(AppSpawnKickDogTest, App_Spawn_AppSpawnKickDog_001, TestSize.Level0)
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, HM_APPSPAWN_WATCHDOG_KICK), 0);
}
sleep(10);
if (access(LINUX_APPSPAWN_WATCHDOG_FILE, F_OK) == 0) {
if (CheckDeviceInLinux()) {
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, LINUX_APPSPAWN_WATCHDOG_KICK), 0);
} else {
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, HM_APPSPAWN_WATCHDOG_KICK), 0);
@ -114,4 +126,44 @@ HWTEST_F(AppSpawnKickDogTest, App_Spawn_AppSpawnKickDog_001, TestSize.Level0)
remove(HM_APPSPAWN_WATCHDOG_FILE);
}
/**
* @brief nwebspawn接入hungtask定时kickdog
*
*/
HWTEST_F(AppSpawnKickDogTest, App_Spawn_AppSpawnKickDog_002, TestSize.Level0)
{
int fileFd = open(HM_APPSPAWN_WATCHDOG_FILE, O_CREAT);
EXPECT_EQ(fileFd != -1, 1);
close(fileFd);
std::unique_ptr<OHOS::AppSpawnTestServer> testServer =
std::make_unique<OHOS::AppSpawnTestServer>("appspawn -mode nwebspawn");
testServer->Start(nullptr);
if (CheckDeviceInLinux()) {
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, LINUX_APPSPAWN_WATCHDOG_ON), 0);
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, LINUX_APPSPAWN_WATCHDOG_KICK), -1);
} else {
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, HM_NWEBSPAWN_WATCHDOG_ON), 0);
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, HM_NWEBSPAWN_WATCHDOG_KICK), -1);
}
sleep(12); // wait for kick dog(kick every 10 seconds)
if (CheckDeviceInLinux()) {
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, LINUX_APPSPAWN_WATCHDOG_ON), -1);
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, LINUX_APPSPAWN_WATCHDOG_KICK), 0);
} else {
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, HM_NWEBSPAWN_WATCHDOG_ON), -1);
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, HM_NWEBSPAWN_WATCHDOG_KICK), 0);
}
sleep(10);
if (CheckDeviceInLinux()) {
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, LINUX_APPSPAWN_WATCHDOG_KICK), 0);
} else {
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, HM_NWEBSPAWN_WATCHDOG_KICK), 0);
}
testServer->Stop();
EXPECT_EQ(CheckFileContent(HM_APPSPAWN_WATCHDOG_FILE, nullptr), -1);
remove(HM_APPSPAWN_WATCHDOG_FILE);
}
} // namespace OHOS