|
|
|
@ -65,6 +65,8 @@ 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";
|
|
|
|
@ -76,6 +78,33 @@ 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(
|
|
|
|
@ -197,7 +226,8 @@ status_t Disk::readMetadata() {
|
|
|
|
|
close(fd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (major(mDevice)) {
|
|
|
|
|
unsigned int majorId = major(mDevice);
|
|
|
|
|
switch (majorId) {
|
|
|
|
|
case kMajorBlockScsiA: case kMajorBlockScsiB: case kMajorBlockScsiC: case kMajorBlockScsiD:
|
|
|
|
|
case kMajorBlockScsiE: case kMajorBlockScsiF: case kMajorBlockScsiG: case kMajorBlockScsiH:
|
|
|
|
|
case kMajorBlockScsiI: case kMajorBlockScsiJ: case kMajorBlockScsiK: case kMajorBlockScsiL:
|
|
|
|
@ -231,7 +261,13 @@ status_t Disk::readMetadata() {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default: {
|
|
|
|
|
LOG(WARNING) << "Unsupported block major type" << major(mDevice);
|
|
|
|
|
if (isVirtioBlkDevice(majorId)) {
|
|
|
|
|
LOG(DEBUG) << "Recognized experimental block major ID " << majorId
|
|
|
|
|
<< " as virtio-blk (emulator's virtual SD card device)";
|
|
|
|
|
mLabel = "Virtual";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
LOG(WARNING) << "Unsupported block major type " << majorId;
|
|
|
|
|
return -ENOTSUP;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -490,7 +526,8 @@ void Disk::notifyEvent(int event, const std::string& value) {
|
|
|
|
|
|
|
|
|
|
int Disk::getMaxMinors() {
|
|
|
|
|
// Figure out maximum partition devices supported
|
|
|
|
|
switch (major(mDevice)) {
|
|
|
|
|
unsigned int majorId = major(mDevice);
|
|
|
|
|
switch (majorId) {
|
|
|
|
|
case kMajorBlockScsiA: case kMajorBlockScsiB: case kMajorBlockScsiC: case kMajorBlockScsiD:
|
|
|
|
|
case kMajorBlockScsiE: case kMajorBlockScsiF: case kMajorBlockScsiG: case kMajorBlockScsiH:
|
|
|
|
|
case kMajorBlockScsiI: case kMajorBlockScsiJ: case kMajorBlockScsiK: case kMajorBlockScsiL:
|
|
|
|
@ -507,9 +544,16 @@ int Disk::getMaxMinors() {
|
|
|
|
|
}
|
|
|
|
|
return atoi(tmp.c_str());
|
|
|
|
|
}
|
|
|
|
|
default: {
|
|
|
|
|
if (isVirtioBlkDevice(majorId)) {
|
|
|
|
|
// drivers/block/virtio_blk.c has "#define PART_BITS 4", so max is
|
|
|
|
|
// 2^4 - 1 = 15
|
|
|
|
|
return 15;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LOG(ERROR) << "Unsupported block major type " << major(mDevice);
|
|
|
|
|
LOG(ERROR) << "Unsupported block major type " << majorId;
|
|
|
|
|
return -ENOTSUP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|