mirror of
https://gitee.com/openharmony/startup_appspawn
synced 2024-11-30 10:40:33 +00:00
ec2927c82d
Signed-off-by: 陈其文 <chenqiwen6@huawei.com>
143 lines
4.5 KiB
C
143 lines
4.5 KiB
C
/*
|
|
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include "appspawn_kickdog.h"
|
|
|
|
static int OpenAndWriteToProc(const char *procName, const char *writeStr, size_t writeLen)
|
|
{
|
|
if (writeStr == NULL) {
|
|
APPSPAWN_LOGE("Write string is null");
|
|
return -1;
|
|
}
|
|
|
|
int procFd = open(procName, O_WRONLY | O_CLOEXEC);
|
|
if (procFd == -1) {
|
|
APPSPAWN_LOGE("open %{public}s fail,errno:%{public}d", procName, errno);
|
|
return procFd;
|
|
}
|
|
|
|
int writeResult = write(procFd, writeStr, writeLen);
|
|
if (writeResult != (int)writeLen) {
|
|
APPSPAWN_LOGE("write %{public}s fail,result:%{public}d", writeStr, writeResult);
|
|
} else {
|
|
APPSPAWN_LOGI("write %{public}s success", writeStr);
|
|
}
|
|
|
|
close(procFd);
|
|
return writeResult;
|
|
}
|
|
|
|
static const char *GetProcFile(bool isLinux)
|
|
{
|
|
if (isLinux) {
|
|
return LINUX_APPSPAWN_WATCHDOG_FILE;
|
|
}
|
|
return HM_APPSPAWN_WATCHDOG_FILE;
|
|
}
|
|
|
|
static const char *GetProcContent(bool isLinux, bool isOpen, int mode)
|
|
{
|
|
if (isOpen) {
|
|
if (isLinux) {
|
|
return LINUX_APPSPAWN_WATCHDOG_ON;
|
|
}
|
|
return (mode == MODE_FOR_NWEB_SPAWN) ? HM_NWEBSPAWN_WATCHDOG_ON : HM_APPSPAWN_WATCHDOG_ON;
|
|
}
|
|
|
|
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;
|
|
|
|
if (!wdgContent->wdgOpened) { //first time deal kernel file
|
|
DealSpawnWatchdog(wdgContent, true);
|
|
return;
|
|
}
|
|
|
|
DealSpawnWatchdog(wdgContent, false);
|
|
}
|
|
|
|
static void CreateTimerLoopTask(AppSpawnContent *content)
|
|
{
|
|
LoopHandle loop = LE_GetDefaultLoop();
|
|
TimerHandle timer = NULL;
|
|
int ret = LE_CreateTimer(loop, &timer, ProcessTimerHandle, (void *)content);
|
|
APPSPAWN_CHECK(ret == 0, return, "Failed to create timerLoopTask ret %{public}d", ret);
|
|
// start a timer to write kernel file every 10s
|
|
ret = LE_StartTimer(loop, timer, APPSPAWN_WATCHDOG_KICKTIME, INT64_MAX);
|
|
APPSPAWN_CHECK(ret == 0, return, "Failed to start timerLoopTask ret %{public}d", ret);
|
|
}
|
|
|
|
static int CheckKernelType(bool *isLinux)
|
|
{
|
|
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;
|
|
}
|
|
|
|
APPSPAWN_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);
|
|
} |