From 120f6b260c268c677735fcef434f9480223725ed Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 4 Mar 2022 15:06:02 -0800 Subject: [PATCH] Init: add dev.mnt.blk.bootdevice to access device sysfs This patch adds a new property, 'dev.mnt.root.', which provides, for example of /data, 1. dm-N dev.mnt.dev.data = dm-N dev.mnt.blk.data = sdaN or mmcblk0pN dev.mnt.rootdisk.data = sda or mmcblk0 2. sdaN or mmcblk0pN dev.mnt.dev.data = sdaN or mmcblk0pN dev.mnt.blk.data = sdaN or mmcblk0pN dev.mnt.rootdisk.data = sda or mmcblk0 Signed-off-by: Jaegeuk Kim Change-Id: I0a58a62d416f966f26b5de04112c2f9a7eceb22c --- init/README.md | 15 +++++++---- init/mount_handler.cpp | 58 ++++++++++++++++++++++++++++++++---------- rootdir/init.rc | 7 +++-- 3 files changed, 60 insertions(+), 20 deletions(-) diff --git a/init/README.md b/init/README.md index c82dbfbfc..13c6ebdfa 100644 --- a/init/README.md +++ b/init/README.md @@ -804,13 +804,18 @@ Init provides state information with the following properties. `init.svc.` > State of a named service ("stopped", "stopping", "running", "restarting") -`dev.mnt.blk.` +`dev.mnt.dev.`, `dev.mnt.blk.`, `dev.mnt.rootdisk.` > Block device base name associated with a *mount_point*. The *mount_point* has / replaced by . and if referencing the root mount point - "/", it will use "/root", specifically `dev.mnt.blk.root`. - Meant for references to `/sys/device/block/${dev.mnt.blk.}/` and - `/sys/fs/ext4/${dev.mnt.blk.}/` to tune the block device - characteristics in a device agnostic manner. + "/", it will use "/root". + `dev.mnt.dev.` indicates a block device attached to filesystems. + (e.g., dm-N or sdaN/mmcblk0pN to access `/sys/fs/ext4/${dev.mnt.dev.}/`) + + `dev.mnt.blk.` indicates the disk partition to the above block device. + (e.g., sdaN / mmcblk0pN to access `/sys/class/block/${dev.mnt.blk.}/`) + + `dev.mnt.rootdisk.` indicates the root disk to contain the above disk partition. + (e.g., sda / mmcblk0 to access `/sys/class/block/${dev.mnt.rootdisk.}/queue`) Init responds to properties that begin with `ctl.`. These properties take the format of `ctl.[_]` and the _value_ of the system property is used as a parameter. The diff --git a/init/mount_handler.cpp b/init/mount_handler.cpp index 15ac30590..227ce2fe4 100644 --- a/init/mount_handler.cpp +++ b/init/mount_handler.cpp @@ -72,8 +72,25 @@ MountHandlerEntry ParseMount(const std::string& line) { return MountHandlerEntry(fields[0], fields[1], fields[2]); } -// return dm-4 or dm-8 for dm-4, sda for sda25, or mmcblk0 for mmcblk0p24 +// return sda25 for dm-4, sda25 for sda25, or mmcblk0p24 for mmcblk0p24 +std::string GetDiskPart(std::string blockdev) { + if (blockdev.find('/') != std::string::npos) return {}; + + while (android::base::StartsWith(blockdev, "dm-")) { + auto& dm = dm::DeviceMapper::Instance(); + std::optional parent = dm.GetParentBlockDeviceByPath("/dev/block/" + blockdev); + if (parent) { + blockdev = android::base::Basename(*parent); + } else { + return {}; + } + } + return blockdev; +} + +// return sda for sda25, or mmcblk0 for mmcblk0p24 std::string GetRootDisk(std::string blockdev) { + if (blockdev.empty()) return {}; if (blockdev.find('/') != std::string::npos) return {}; std::error_code ec; @@ -83,7 +100,6 @@ std::string GetRootDisk(std::string blockdev) { return Basename(path); } } - if (android::base::StartsWith(blockdev, "dm-")) return blockdev; return {}; } @@ -91,31 +107,47 @@ void SetMountProperty(const MountHandlerEntry& entry, bool add) { static constexpr char devblock[] = "/dev/block/"; if (!android::base::StartsWith(entry.blk_device, devblock)) return; auto target = entry.blk_device.substr(strlen(devblock)); - std::string value; + std::string diskpart, rootdisk; if (add) { - value = GetRootDisk(target); + diskpart = GetDiskPart(target); + rootdisk = GetRootDisk(diskpart); struct stat sb; - if (stat(entry.mount_point.c_str(), &sb) || !S_ISDIR(sb.st_mode)) value = ""; + if (stat(entry.mount_point.c_str(), &sb) || !S_ISDIR(sb.st_mode)) rootdisk = ""; // Clear the noise associated with loopback and APEX. - if (android::base::StartsWith(value, "loop")) value = ""; - if (android::base::StartsWith(entry.mount_point, "/apex/")) value = ""; + if (android::base::StartsWith(target, "loop")) rootdisk = ""; + if (android::base::StartsWith(entry.mount_point, "/apex/")) rootdisk = ""; } auto mount_prop = entry.mount_point; if (mount_prop == "/") mount_prop = "/root"; std::replace(mount_prop.begin(), mount_prop.end(), '/', '.'); auto blk_mount_prop = "dev.mnt.blk" + mount_prop; auto dev_mount_prop = "dev.mnt.dev" + mount_prop; - // Set property even if its value does not change to trigger 'on property:' + auto rootdisk_mount_prop = "dev.mnt.rootdisk" + mount_prop; + // Set property even if its rootdisk does not change to trigger 'on property:' // handling, except for clearing non-existent or already clear property. // Goal is reduction of empty properties and associated triggers. - if (value.empty() && android::base::GetProperty(blk_mount_prop, "").empty()) return; - android::base::SetProperty(blk_mount_prop, value); - if (!value.empty()) { - android::base::SetProperty(dev_mount_prop, target); - } else { + if (rootdisk.empty() && android::base::GetProperty(blk_mount_prop, "").empty()) return; + + if (rootdisk.empty()) { + android::base::SetProperty(blk_mount_prop, ""); android::base::SetProperty(dev_mount_prop, ""); + android::base::SetProperty(rootdisk_mount_prop, ""); + return; } + + // 1. dm-N + // dev.mnt.dev.data = dm-N + // dev.mnt.blk.data = sdaN or mmcblk0pN + // dev.mnt.rootdisk.data = sda or mmcblk0 + // + // 2. sdaN or mmcblk0pN + // dev.mnt.dev.data = sdaN or mmcblk0pN + // dev.mnt.blk.data = sdaN or mmcblk0pN + // dev.mnt.rootdisk.data = sda or mmcblk0 + android::base::SetProperty(dev_mount_prop, target); + android::base::SetProperty(blk_mount_prop, diskpart); + android::base::SetProperty(rootdisk_mount_prop, rootdisk); } } // namespace diff --git a/rootdir/init.rc b/rootdir/init.rc index 224f605ac..404d7aecc 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -1085,9 +1085,11 @@ on boot mkdir /dev/sys/fs/by-name 0755 system system symlink /sys/fs/f2fs/${dev.mnt.dev.data} /dev/sys/fs/by-name/userdata - # to access dm- sysfs + # dev.mnt.dev.data=dm-N, dev.mnt.blk.data=sdaN/mmcblk0pN, dev.mnt.rootdisk.data=sda/mmcblk0, or + # dev.mnt.dev.data=sdaN/mmcblk0pN, dev.mnt.blk.data=sdaN/mmcblk0pN, dev.mnt.rootdisk.data=sda/mmcblk0 mkdir /dev/sys/block/by-name 0755 system system symlink /sys/class/block/${dev.mnt.dev.data} /dev/sys/block/by-name/userdata + symlink /sys/class/block/${dev.mnt.rootdisk.data} /dev/sys/block/by-name/rootdisk # F2FS tuning. Set cp_interval larger than dirty_expire_centisecs, 30 secs, # to avoid power consumption when system becomes mostly idle. Be careful @@ -1099,8 +1101,9 @@ on boot # limit discard size to 128MB in order to avoid long IO latency # for filesystem tuning first (dm or sda) - # Note that, if dm- is used, sda/mmcblk0 should be tuned in vendor/init.rc + # this requires enabling selinux entry for sda/mmcblk0 in vendor side write /dev/sys/block/by-name/userdata/queue/discard_max_bytes 134217728 + write /dev/sys/block/by-name/rootdisk/queue/discard_max_bytes 134217728 # Permissions for System Server and daemons. chown system system /sys/power/autosleep