1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include <fcntl.h> 17#include <stdio.h> 18#include "appspawn_kickdog.h" 19 20static int OpenAndWriteToProc(const char *procName, const char *writeStr, size_t writeLen) 21{ 22 if (writeStr == NULL) { 23 APPSPAWN_LOGE("Write string is null"); 24 return -1; 25 } 26 27 int procFd = open(procName, O_RDWR | O_CLOEXEC); 28 if (procFd == -1) { 29 APPSPAWN_LOGE("open %{public}s fail,errno:%{public}d", procName, errno); 30 return procFd; 31 } 32 33 int writeResult = write(procFd, writeStr, writeLen); 34 if (writeResult != (int)writeLen) { 35 APPSPAWN_LOGE("write %{public}s fail,result:%{public}d", writeStr, writeResult); 36 } else { 37 APPSPAWN_LOGI("write %{public}s success", writeStr); 38 } 39 40 close(procFd); 41 return writeResult; 42} 43 44// Enable watchdog monitoring 45static int OpenAppSpawnWatchdogFile(AppSpawnContent *content) 46{ 47 APPSPAWN_LOGI("OpenAppSpawnWatchdogFile"); 48 int result = 0; 49 if (access(LINUX_APPSPAWN_WATCHDOG_FILE, F_OK) == 0) { 50 result = OpenAndWriteToProc(LINUX_APPSPAWN_WATCHDOG_FILE, LINUX_APPSPAWN_WATCHDOG_ON, 51 strlen(LINUX_APPSPAWN_WATCHDOG_ON)); 52 } else { 53 result = OpenAndWriteToProc(HM_APPSPAWN_WATCHDOG_FILE, HM_APPSPAWN_WATCHDOG_ON, 54 strlen(HM_APPSPAWN_WATCHDOG_ON)); 55 } 56 content->wdgOpened = (result != -1); 57 APPSPAWN_LOGI("open finish,result:%{public}d", result); 58 return result; 59} 60 61static void KickAppSpawnWatchdog(void) 62{ 63 APPSPAWN_LOGI("kick proc begin"); 64 int result = 0; 65 if (access(LINUX_APPSPAWN_WATCHDOG_FILE, F_OK) == 0) { 66 result = OpenAndWriteToProc(LINUX_APPSPAWN_WATCHDOG_FILE, LINUX_APPSPAWN_WATCHDOG_KICK, 67 strlen(LINUX_APPSPAWN_WATCHDOG_KICK)); 68 } else { 69 result = OpenAndWriteToProc(HM_APPSPAWN_WATCHDOG_FILE, HM_APPSPAWN_WATCHDOG_KICK, 70 strlen(HM_APPSPAWN_WATCHDOG_KICK)); 71 } 72 APPSPAWN_LOGI("kick end,result:%{public}d", result); 73} 74 75static void ProcessTimerHandle(const TimerHandle taskHandle, void *context) 76{ 77 AppSpawnContent *wdgContent = (AppSpawnContent *)context; 78 79 APPSPAWN_LOGI("kick appspawn dog start"); 80 81 if (!wdgContent->wdgOpened) { //first time deal kernel file 82 OpenAppSpawnWatchdogFile(wdgContent); 83 return; 84 } 85 86 KickAppSpawnWatchdog(); 87} 88 89static void CreateTimerLoopTask(AppSpawnContent *content) 90{ 91 LoopHandle loop = LE_GetDefaultLoop(); 92 TimerHandle timer = NULL; 93 int ret = LE_CreateTimer(loop, &timer, ProcessTimerHandle, (void *)content); 94 APPSPAWN_CHECK(ret == 0, return, "Failed to create timerLoopTask ret %{public}d", ret); 95 // start a timer to write kernel file every 10s 96 ret = LE_StartTimer(loop, timer, APPSPAWN_WATCHDOG_KICKTIME, INT64_MAX); 97 APPSPAWN_CHECK(ret == 0, return, "Failed to start timerLoopTask ret %{public}d", ret); 98} 99 100void AppSpawnKickDogStart(AppSpawnContent *content) 101{ 102 CreateTimerLoopTask(content); 103 OpenAppSpawnWatchdogFile(content); 104}