diff options
| author | Alistair Delva <adelva@google.com> | 2020-05-14 16:35:03 -0700 |
|---|---|---|
| committer | doc HD <doc.divxm@gmail.com> | 2020-06-06 23:33:55 +0300 |
| commit | d8999d77d60b933ada9098569bd38e6181bcafbd (patch) | |
| tree | a60bd2895599cb465ec604bdc493fd969b964c97 /Utils.cpp | |
| parent | 420ae89c626ddea6e63362f5627abfe580d4e45b (diff) | |
The Android Emulator isn't the only virtual device the virtio-block
detection code is useful for, and those platforms might not set any
discriminating properties to indicate that they are virtual.
Rework the virtio-block major detection to use /proc/devices instead
of hardcoding the assumption that any virtual platform can have
virtio-block at any experimental major; the new code permits only the
exact experimental major assigned to virtio-block.
The new code runs everywhere, but it will only run once and could be
expanded later to detect dynamic or experimental majors.
Bug: 156286088
Change-Id: Ieae805d08fddd0124a397636f04d99194a9ef7e5
Merged-In: Ieae805d08fddd0124a397636f04d99194a9ef7e5
(cherry picked from commit d3c230b5c9ba6e242c0a6b290a185517f2c118e8)
Diffstat (limited to 'Utils.cpp')
| -rw-r--r-- | Utils.cpp | 36 |
1 files changed, 34 insertions, 2 deletions
@@ -69,6 +69,7 @@ bool sSleepOnUnmount = true; static const char* kBlkidPath = "/system/bin/blkid"; static const char* kKeyPath = "/data/misc/vold"; +static const char* kProcDevices = "/proc/devices"; static const char* kProcFilesystems = "/proc/filesystems"; // Lock used to protect process-level SELinux changes from racing with each @@ -799,8 +800,39 @@ bool Readlinkat(int dirfd, const std::string& path, std::string* result) { } } -bool IsRunningInEmulator() { - return android::base::GetBoolProperty("ro.kernel.qemu", false); +static unsigned int GetMajorBlockVirtioBlk() { + std::string devices; + if (!ReadFileToString(kProcDevices, &devices)) { + PLOG(ERROR) << "Unable to open /proc/devices"; + return 0; + } + + bool blockSection = false; + for (auto line : android::base::Split(devices, "\n")) { + if (line == "Block devices:") { + blockSection = true; + } else if (line == "Character devices:") { + blockSection = false; + } else if (blockSection) { + auto tokens = android::base::Split(line, " "); + if (tokens.size() == 2 && tokens[1] == "virtblk") { + return std::stoul(tokens[0]); + } + } + } + + return 0; +} + +bool IsVirtioBlkDevice(unsigned int major) { + // Most virtualized platforms expose block devices with the virtio-blk + // block device driver. Unfortunately, this driver does not use a fixed + // major number, but relies on the kernel to assign one from a specific + // range of block majors, which are allocated for "LOCAL/EXPERIMENAL USE" + // per Documentation/devices.txt. This is true even for the latest Linux + // kernel (4.4; see init() in drivers/block/virtio_blk.c). + static unsigned int kMajorBlockVirtioBlk = GetMajorBlockVirtioBlk(); + return kMajorBlockVirtioBlk && major == kMajorBlockVirtioBlk; } static status_t findMountPointsWithPrefix(const std::string& prefix, |
