Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 37792d99 authored by Yuan Yao's avatar Yuan Yao
Browse files

init: Replace IsDataMounted function with GetDataFsType

This change introduces the GetDataFsType function to get the filesystem
type of the /data partition. This function reads /proc/mounts and
returns the filesystem type or an empty string if the mount point is not
found or an error occurs.

The IsDataMounted calls are replaced with GetDataFsType to better handle
cases where /data is not mounted. Reduce duplicate reads of /proc/mounts.

Bug: 408963180
Test: Mount a dummy tmpfs in /data, reboot, and verify log in pstore
Change-Id: I125e6b677b7523d4bd7a5c982990c70b02be05c7
parent 3b73c8f8
Loading
Loading
Loading
Loading
+33 −22
Original line number Diff line number Diff line
@@ -210,19 +210,22 @@ static void LogShutdownTime(UmountStat stat, Timer* t) {
                 << stat;
}

static bool IsDataMounted(const std::string& fstype) {
// Gets the filesystem type of the /data partition.
// Returns the filesystem type as a string (e.g., "ext4", "f2fs") or an empty string if not found
// or if an error occurs.
static std::string GetDataFsType() {
    std::unique_ptr<std::FILE, int (*)(std::FILE*)> fp(setmntent("/proc/mounts", "re"), endmntent);
    if (fp == nullptr) {
        PLOG(ERROR) << "Failed to open /proc/mounts";
        return false;
        return "";
    }
    mntent* mentry;
    while ((mentry = getmntent(fp.get())) != nullptr) {
        if (mentry->mnt_dir == "/data"s) {
            return fstype == "*" || mentry->mnt_type == fstype;
            return mentry->mnt_type;
        }
    }
    return false;
    return "";
}

// Find all read+write block devices and emulated devices in /proc/mounts and add them to
@@ -701,7 +704,7 @@ static void DoReboot(unsigned int cmd, const std::string& reason, const std::str

    // If /data isn't mounted then we can skip the extra reboot steps below, since we don't need to
    // worry about unmounting it.
    if (!IsDataMounted("*")) {
    if (GetDataFsType().empty()) {
        sync();
        RebootSystem(cmd, reboot_target, reason);
        abort();
@@ -826,7 +829,10 @@ static void DoReboot(unsigned int cmd, const std::string& reason, const std::str
    sem_post(&reboot_semaphore);

    // Reboot regardless of umount status. If umount fails, fsck after reboot will fix it.
    if (IsDataMounted("f2fs")) {
    std::string data_fs_type = GetDataFsType();
    if (!data_fs_type.empty()) {
        LOG(WARNING) << "Umount /data failed, try to use ioctl to shutdown";
        if (data_fs_type == "f2fs") {
            uint32_t flag = F2FS_GOING_DOWN_FULLSYNC;
            unique_fd fd(TEMP_FAILURE_RETRY(open("/data", O_RDONLY)));
            LOG(INFO) << "Invoking F2FS_IOC_SHUTDOWN during shutdown";
@@ -836,16 +842,21 @@ static void DoReboot(unsigned int cmd, const std::string& reason, const std::str
            } else {
                LOG(INFO) << "Shutdown /data";
            }
    } else if (IsDataMounted("ext4")) {
        } else if (data_fs_type == "ext4") {
            uint32_t flag = EXT4_GOING_FLAGS_DEFAULT;
            unique_fd fd(TEMP_FAILURE_RETRY(open("/data", O_RDONLY)));
            LOG(INFO) << "Invoking EXT4_IOC_SHUTDOWN during shutdown";
            int ret = ioctl(fd.get(), EXT4_IOC_SHUTDOWN, &flag);
            if (ret) {
                PLOG(ERROR) << "Shutdown /data: ";
            } else {
                LOG(INFO) << "Shutdown /data";
            }
        } else {
            LOG(ERROR) << "Unknown /data fs type: " << data_fs_type;
        }
    }

    RebootSystem(cmd, reboot_target, reason);
    abort();
}