summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2020-05-18 01:49:49 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2020-05-18 01:49:49 +0000
commit2d421f4fec5189956593773e6d1ab185609bf573 (patch)
treee966193b23da012ec3a8081d1ccbc029cd8a335e
parentca19a8425b19df385cb9a2eace0387b359d15351 (diff)
parentc253e515e583174a3c22e0c8efcfab90cccb9afa (diff)
downloadvold-pie-gsi.tar.gz
Merge "Expand virtio_block check to other virtual devices" into pie-gsipie-gsi
-rw-r--r--Utils.cpp36
-rw-r--r--Utils.h4
-rw-r--r--VolumeManager.cpp11
-rw-r--r--model/Disk.cpp33
4 files changed, 41 insertions, 43 deletions
diff --git a/Utils.cpp b/Utils.cpp
index d17de626..959658b4 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -65,6 +65,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
@@ -732,8 +733,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;
}
// TODO(118708649): fix duplication with init/util.h
diff --git a/Utils.h b/Utils.h
index fb0d3893..234de70a 100644
--- a/Utils.h
+++ b/Utils.h
@@ -123,8 +123,8 @@ status_t RestoreconRecursive(const std::string& path);
// TODO: promote to android::base
bool Readlinkat(int dirfd, const std::string& path, std::string* result);
-/* Checks if Android is running in QEMU */
-bool IsRunningInEmulator();
+// Handles dynamic major assignment for virtio-block
+bool IsVirtioBlkDevice(unsigned int major);
status_t WaitForFile(const char* filename, std::chrono::nanoseconds timeout);
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 21e132a3..cf36c698 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -76,8 +76,6 @@ static const char* kPropVirtualDisk = "persist.sys.virtual_disk";
static const unsigned int kSizeVirtualDisk = 536870912;
static const unsigned int kMajorBlockMmc = 179;
-static const unsigned int kMajorBlockExperimentalMin = 240;
-static const unsigned int kMajorBlockExperimentalMax = 254;
VolumeManager *VolumeManager::sInstance = NULL;
@@ -196,13 +194,10 @@ void VolumeManager::handleBlockEvent(NetlinkEvent *evt) {
for (const auto& source : mDiskSources) {
if (source->matches(eventPath)) {
// For now, assume that MMC and virtio-blk (the latter is
- // emulator-specific; see Disk.cpp for details) devices are SD,
- // and that everything else is USB
+ // specific to virtual platforms; see Utils.cpp for details)
+ // devices are SD, and that everything else is USB
int flags = source->getFlags();
- if (major == kMajorBlockMmc
- || (android::vold::IsRunningInEmulator()
- && major >= (int) kMajorBlockExperimentalMin
- && major <= (int) kMajorBlockExperimentalMax)) {
+ if (major == kMajorBlockMmc || android::vold::IsVirtioBlkDevice(major)) {
flags |= android::vold::Disk::Flags::kSd;
} else {
flags |= android::vold::Disk::Flags::kUsb;
diff --git a/model/Disk.cpp b/model/Disk.cpp
index d7b19ac3..7b77af28 100644
--- a/model/Disk.cpp
+++ b/model/Disk.cpp
@@ -74,8 +74,6 @@ static const unsigned int kMajorBlockScsiN = 133;
static const unsigned int kMajorBlockScsiO = 134;
static const unsigned int kMajorBlockScsiP = 135;
static const unsigned int kMajorBlockMmc = 179;
-static const unsigned int kMajorBlockExperimentalMin = 240;
-static const unsigned int kMajorBlockExperimentalMax = 254;
static const char* kGptBasicData = "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7";
static const char* kGptAndroidMeta = "19A710A2-B3CA-11E4-B026-10604B889DCF";
@@ -87,33 +85,6 @@ enum class Table {
kGpt,
};
-static bool isVirtioBlkDevice(unsigned int major) {
- /*
- * The new emulator's "ranchu" virtual board no longer includes a goldfish
- * MMC-based SD card device; instead, it emulates SD cards with virtio-blk,
- * which has been supported by upstream kernel and QEMU for quite a while.
- * Unfortunately, the virtio-blk block device 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).
- *
- * This makes it difficult for vold to detect a virtio-blk based SD card.
- * The current solution checks two conditions (both must be met):
- *
- * a) If the running environment is the emulator;
- * b) If the major number is an experimental block device major number (for
- * x86/x86_64 3.10 ranchu kernels, virtio-blk always gets major number
- * 253, but it is safer to match the range than just one value).
- *
- * Other conditions could be used, too, e.g. the hardware name should be
- * "ranchu", the device's sysfs path should end with "/block/vd[d-z]", etc.
- * But just having a) and b) is enough for now.
- */
- return IsRunningInEmulator() && major >= kMajorBlockExperimentalMin
- && major <= kMajorBlockExperimentalMax;
-}
-
Disk::Disk(const std::string& eventPath, dev_t device,
const std::string& nickname, int flags) :
mDevice(device), mSize(-1), mNickname(nickname), mFlags(flags), mCreated(
@@ -286,7 +257,7 @@ status_t Disk::readMetadata() {
break;
}
default: {
- if (isVirtioBlkDevice(majorId)) {
+ if (IsVirtioBlkDevice(majorId)) {
LOG(DEBUG) << "Recognized experimental block major ID " << majorId
<< " as virtio-blk (emulator's virtual SD card device)";
mLabel = "Virtual";
@@ -571,7 +542,7 @@ int Disk::getMaxMinors() {
return std::stoi(tmp);
}
default: {
- if (isVirtioBlkDevice(majorId)) {
+ if (IsVirtioBlkDevice(majorId)) {
// drivers/block/virtio_blk.c has "#define PART_BITS 4", so max is
// 2^4 - 1 = 15
return 15;