169570cc8Sopenharmony_ci/* 269570cc8Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 369570cc8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 469570cc8Sopenharmony_ci * you may not use this file except in compliance with the License. 569570cc8Sopenharmony_ci * You may obtain a copy of the License at 669570cc8Sopenharmony_ci * 769570cc8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 869570cc8Sopenharmony_ci * 969570cc8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1069570cc8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1169570cc8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1269570cc8Sopenharmony_ci * See the License for the specific language governing permissions and 1369570cc8Sopenharmony_ci * limitations under the License. 1469570cc8Sopenharmony_ci */ 1569570cc8Sopenharmony_ci 1669570cc8Sopenharmony_ci#include <fcntl.h> 1769570cc8Sopenharmony_ci#include <stdio.h> 1869570cc8Sopenharmony_ci#include "appspawn_kickdog.h" 1969570cc8Sopenharmony_ci 2069570cc8Sopenharmony_cistatic int OpenAndWriteToProc(const char *procName, const char *writeStr, size_t writeLen) 2169570cc8Sopenharmony_ci{ 2269570cc8Sopenharmony_ci if (writeStr == NULL) { 2369570cc8Sopenharmony_ci APPSPAWN_LOGE("Write string is null"); 2469570cc8Sopenharmony_ci return -1; 2569570cc8Sopenharmony_ci } 2669570cc8Sopenharmony_ci 2769570cc8Sopenharmony_ci int procFd = open(procName, O_RDWR | O_CLOEXEC); 2869570cc8Sopenharmony_ci if (procFd == -1) { 2969570cc8Sopenharmony_ci APPSPAWN_LOGE("open %{public}s fail,errno:%{public}d", procName, errno); 3069570cc8Sopenharmony_ci return procFd; 3169570cc8Sopenharmony_ci } 3269570cc8Sopenharmony_ci 3369570cc8Sopenharmony_ci int writeResult = write(procFd, writeStr, writeLen); 3469570cc8Sopenharmony_ci if (writeResult != (int)writeLen) { 3569570cc8Sopenharmony_ci APPSPAWN_LOGE("write %{public}s fail,result:%{public}d", writeStr, writeResult); 3669570cc8Sopenharmony_ci } else { 3769570cc8Sopenharmony_ci APPSPAWN_LOGI("write %{public}s success", writeStr); 3869570cc8Sopenharmony_ci } 3969570cc8Sopenharmony_ci 4069570cc8Sopenharmony_ci close(procFd); 4169570cc8Sopenharmony_ci return writeResult; 4269570cc8Sopenharmony_ci} 4369570cc8Sopenharmony_ci 4469570cc8Sopenharmony_ci// Enable watchdog monitoring 4569570cc8Sopenharmony_cistatic int OpenAppSpawnWatchdogFile(AppSpawnContent *content) 4669570cc8Sopenharmony_ci{ 4769570cc8Sopenharmony_ci APPSPAWN_LOGI("OpenAppSpawnWatchdogFile"); 4869570cc8Sopenharmony_ci int result = 0; 4969570cc8Sopenharmony_ci if (access(LINUX_APPSPAWN_WATCHDOG_FILE, F_OK) == 0) { 5069570cc8Sopenharmony_ci result = OpenAndWriteToProc(LINUX_APPSPAWN_WATCHDOG_FILE, LINUX_APPSPAWN_WATCHDOG_ON, 5169570cc8Sopenharmony_ci strlen(LINUX_APPSPAWN_WATCHDOG_ON)); 5269570cc8Sopenharmony_ci } else { 5369570cc8Sopenharmony_ci result = OpenAndWriteToProc(HM_APPSPAWN_WATCHDOG_FILE, HM_APPSPAWN_WATCHDOG_ON, 5469570cc8Sopenharmony_ci strlen(HM_APPSPAWN_WATCHDOG_ON)); 5569570cc8Sopenharmony_ci } 5669570cc8Sopenharmony_ci content->wdgOpened = (result != -1); 5769570cc8Sopenharmony_ci APPSPAWN_LOGI("open finish,result:%{public}d", result); 5869570cc8Sopenharmony_ci return result; 5969570cc8Sopenharmony_ci} 6069570cc8Sopenharmony_ci 6169570cc8Sopenharmony_cistatic void KickAppSpawnWatchdog(void) 6269570cc8Sopenharmony_ci{ 6369570cc8Sopenharmony_ci APPSPAWN_LOGI("kick proc begin"); 6469570cc8Sopenharmony_ci int result = 0; 6569570cc8Sopenharmony_ci if (access(LINUX_APPSPAWN_WATCHDOG_FILE, F_OK) == 0) { 6669570cc8Sopenharmony_ci result = OpenAndWriteToProc(LINUX_APPSPAWN_WATCHDOG_FILE, LINUX_APPSPAWN_WATCHDOG_KICK, 6769570cc8Sopenharmony_ci strlen(LINUX_APPSPAWN_WATCHDOG_KICK)); 6869570cc8Sopenharmony_ci } else { 6969570cc8Sopenharmony_ci result = OpenAndWriteToProc(HM_APPSPAWN_WATCHDOG_FILE, HM_APPSPAWN_WATCHDOG_KICK, 7069570cc8Sopenharmony_ci strlen(HM_APPSPAWN_WATCHDOG_KICK)); 7169570cc8Sopenharmony_ci } 7269570cc8Sopenharmony_ci APPSPAWN_LOGI("kick end,result:%{public}d", result); 7369570cc8Sopenharmony_ci} 7469570cc8Sopenharmony_ci 7569570cc8Sopenharmony_cistatic void ProcessTimerHandle(const TimerHandle taskHandle, void *context) 7669570cc8Sopenharmony_ci{ 7769570cc8Sopenharmony_ci AppSpawnContent *wdgContent = (AppSpawnContent *)context; 7869570cc8Sopenharmony_ci 7969570cc8Sopenharmony_ci APPSPAWN_LOGI("kick appspawn dog start"); 8069570cc8Sopenharmony_ci 8169570cc8Sopenharmony_ci if (!wdgContent->wdgOpened) { //first time deal kernel file 8269570cc8Sopenharmony_ci OpenAppSpawnWatchdogFile(wdgContent); 8369570cc8Sopenharmony_ci return; 8469570cc8Sopenharmony_ci } 8569570cc8Sopenharmony_ci 8669570cc8Sopenharmony_ci KickAppSpawnWatchdog(); 8769570cc8Sopenharmony_ci} 8869570cc8Sopenharmony_ci 8969570cc8Sopenharmony_cistatic void CreateTimerLoopTask(AppSpawnContent *content) 9069570cc8Sopenharmony_ci{ 9169570cc8Sopenharmony_ci LoopHandle loop = LE_GetDefaultLoop(); 9269570cc8Sopenharmony_ci TimerHandle timer = NULL; 9369570cc8Sopenharmony_ci int ret = LE_CreateTimer(loop, &timer, ProcessTimerHandle, (void *)content); 9469570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return, "Failed to create timerLoopTask ret %{public}d", ret); 9569570cc8Sopenharmony_ci // start a timer to write kernel file every 10s 9669570cc8Sopenharmony_ci ret = LE_StartTimer(loop, timer, APPSPAWN_WATCHDOG_KICKTIME, INT64_MAX); 9769570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return, "Failed to start timerLoopTask ret %{public}d", ret); 9869570cc8Sopenharmony_ci} 9969570cc8Sopenharmony_ci 10069570cc8Sopenharmony_civoid AppSpawnKickDogStart(AppSpawnContent *content) 10169570cc8Sopenharmony_ci{ 10269570cc8Sopenharmony_ci CreateTimerLoopTask(content); 10369570cc8Sopenharmony_ci OpenAppSpawnWatchdogFile(content); 10469570cc8Sopenharmony_ci}