From 49e05a15beb2aa692303b6a0b3d93e32adb9988d Mon Sep 17 00:00:00 2001 From: cat Date: Sat, 13 Sep 2025 15:43:24 +0800 Subject: [PATCH] reboot umount fail Signed-off-by: cat --- services/init/standard/init_cmds.c | 73 ++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/services/init/standard/init_cmds.c b/services/init/standard/init_cmds.c index bdb282e5b..f0e87203e 100755 --- a/services/init/standard/init_cmds.c +++ b/services/init/standard/init_cmds.c @@ -30,6 +30,10 @@ #include #include #include +#include +#include +#include +#include #include "bootstage.h" #include "fs_manager/fs_manager.h" @@ -55,6 +59,11 @@ #define SET_SHUT_STAGE _IOW(BOOT_DETECTOR_IOCTL_BASE, 106, int) #define SHUT_STAGE_FRAMEWORK_START 1 +#define SYSRQ_TRIGGER_PATH "/proc/sysrq-trigger" +#define PROC_PATH "/proc" +#define KILL_WAIT_TIME 100000 +#define INTERVAL_WAIT 10 + int GetParamValue(const char *symValue, unsigned int symLen, char *paramValue, unsigned int paramLen) { INIT_CHECK_RETURN_VALUE((symValue != NULL) && (paramValue != NULL) && (paramLen != 0), -1); @@ -401,6 +410,65 @@ static void DoStopAllServices(const struct CmdArgs *ctx) return; } +static void SetDeviceReadonly() +{ + FILE *file = fopen(SYSRQ_TRIGGER_PATH, "wb"); + INIT_ERROR_CHECK(file != NULL, return, "failed to open sysrq file"); + int byte = fwrite((void *)"u", 1, 1, file); + INIT_ERROR_CHECK(byte != 1, fclose(file); + return, "failed to write sysrq file"); + (void)fclose(file); +} + +static void WaitAfterKillPid() +{ + INIT_TIMING_STAT cmdTimer; + (void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.startTime); + long long count = 1; + while (count > 0) { + usleep(INTERVAL_WAIT); + count++; + (void)clock_gettime(CLOCK_MONOTONIC, &cmdTimer.endTime); + long long diff = InitDiffTime(&cmdTimer); + if (diff > KILL_WAIT_TIME) { + count = 0; + } + } +} + +static void DoKillAllPid() +{ + DIR *procDir = opendir(PROC_PATH); + INIT_ERROR_CHECK(procDir != NULL, return, "failed to open proc dir"); + struct dirent *entry; + while ((entry = readdir(procDir)) != NULL) { + if (entry->d_type == DT_DIR) { + const char *dirName = entry->d_name; + if (dirName[0] != '\0' && isdigit(dirName[0])) { + size_t len = strlen(dirName); + bool isNumeric = true; + for (size_t i = 0; i < len; ++i) { + if (!isdigit(dirName[i])) { + isNumeric = false; + break; + } + } + + if (isNumeric) { + int pid = atoi(dirName); + if (pid != 1) { + INIT_LOGI("send sig 9 to %d", pid); + INIT_ERROR_CHECK(kill(pid, SIGKILL) == 0, closedir(procDir); + return, "kill pid %d failed! err %d", pid, errno); + } + } + } + } + } + WaitAfterKillPid(); + closedir(procDir); +} + static void DoUmount(const struct CmdArgs *ctx) { INIT_LOGI("DoUmount %s", ctx->argv[0]); @@ -411,6 +479,11 @@ static void DoUmount(const struct CmdArgs *ctx) ret = umount2(ctx->argv[0], MNT_FORCE); } INIT_CHECK_ONLY_ELOG(ret == 0, "Failed to umount %s, errno %d", ctx->argv[0], errno); + if (ret !=0 && strcmp(ctx->argv[0], "/data") == 0) { + INIT_LOGE("Doumount data fail, kill all pid and set device readonly"); + DoKillAllPid(); + SetDeviceReadonly(); + } } else if (status == MOUNT_UMOUNTED) { INIT_LOGI("%s is already umounted", ctx->argv[0]); } else { -- Gitee