vold: Support internal storage partitions
* Support nonremovable disks and expose a nonremovable flag in the
DiskCreated message.
* New DiskPartition class to hold single partitions. DiskPartition is
used when the fs_mgr entry has a partnum (eg. when fs_mgr_flags
contains voldmanaged=label:#). Override disk partitioning methods
to prevent destroying the emmc.
Change-Id: Id7ec3ea409b5c96e691730604e4b1e9cc3aa9d33
vold: Correct base header paths
These headers were moved to android-base
Change-Id: I3eaa8316006b9017c5f5e31cd1e91efc2862106d
DiskPartition.cpp: Add sysmacros.h dependency for major/minor
Change-Id: I22c267c8f12b40fb3e2295becd88f12b75907b69
Signed-off-by: Adrian DC <radian.dc@gmail.com>
[mikeioannina] Adapt for Pie and Q
Change-Id: Id7ec3ea409b5c96e691730604e4b1e9cc3aa9d33
diff --git a/Android.bp b/Android.bp
index 1112b55..81cd274 100644
--- a/Android.bp
+++ b/Android.bp
@@ -137,6 +137,7 @@
"fs/Ntfs.cpp",
"fs/Vfat.cpp",
"model/Disk.cpp",
+ "model/DiskPartition.cpp",
"model/EmulatedVolume.cpp",
"model/ObbVolume.cpp",
"model/PrivateVolume.cpp",
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index a7d39c1..a978fdc 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -227,8 +227,12 @@
flags |= android::vold::Disk::Flags::kUsb;
}
- auto disk =
- new android::vold::Disk(eventPath, device, source->getNickname(), flags);
+ android::vold::Disk* disk = (source->getPartNum() == -1) ?
+ new android::vold::Disk(eventPath, device,
+ source->getNickname(), flags) :
+ new android::vold::DiskPartition(eventPath, device,
+ source->getNickname(), flags,
+ source->getPartNum());
handleDiskAdded(std::shared_ptr<android::vold::Disk>(disk));
break;
}
diff --git a/VolumeManager.h b/VolumeManager.h
index a8117c9..8b5f946 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -37,6 +37,7 @@
#include "android/os/IVoldListener.h"
#include "model/Disk.h"
+#include "model/DiskPartition.h"
#include "model/VolumeBase.h"
class VolumeManager {
@@ -61,19 +62,21 @@
class DiskSource {
public:
- DiskSource(const std::string& sysPattern, const std::string& nickname, int flags)
- : mSysPattern(sysPattern), mNickname(nickname), mFlags(flags) {}
+ DiskSource(const std::string& sysPattern, const std::string& nickname, int partnum, int flags)
+ : mSysPattern(sysPattern), mNickname(nickname), mPartNum(partnum), mFlags(flags) {}
bool matches(const std::string& sysPath) {
return !fnmatch(mSysPattern.c_str(), sysPath.c_str(), 0);
}
const std::string& getNickname() const { return mNickname; }
+ int getPartNum() const { return mPartNum; }
int getFlags() const { return mFlags; }
private:
std::string mSysPattern;
std::string mNickname;
+ int mPartNum;
int mFlags;
};
diff --git a/main.cpp b/main.cpp
index 74f314d..92f04f4 100644
--- a/main.cpp
+++ b/main.cpp
@@ -260,13 +260,9 @@
}
if (entry.fs_mgr_flags.vold_managed) {
- if (entry.fs_mgr_flags.nonremovable) {
- LOG(WARNING) << "nonremovable no longer supported; ignoring volume";
- continue;
- }
-
std::string sysPattern(entry.blk_device);
std::string nickname(entry.label);
+ int partnum = entry.partnum;
int flags = 0;
if (entry.is_encryptable()) {
@@ -277,9 +273,12 @@
android::base::GetBoolProperty("vold.debug.default_primary", false)) {
flags |= android::vold::Disk::Flags::kDefaultPrimary;
}
+ if (entry.fs_mgr_flags.nonremovable) {
+ flags |= android::vold::Disk::Flags::kNonRemovable;
+ }
vm->addDiskSource(std::shared_ptr<VolumeManager::DiskSource>(
- new VolumeManager::DiskSource(sysPattern, nickname, flags)));
+ new VolumeManager::DiskSource(sysPattern, nickname, partnum, flags)));
}
}
return 0;
diff --git a/model/Disk.h b/model/Disk.h
index cc1d66d..4779ed4 100644
--- a/model/Disk.h
+++ b/model/Disk.h
@@ -59,6 +59,8 @@
/* Flag that disk is a visible Stub disk, i.e., disk that is managed from outside
* Android (e.g., ARC++) and visible to apps. */
kStubVisible = 1 << 6,
+ /* Flag that disk is non-removable */
+ kNonRemovable = 1 << 7,
};
const std::string& getId() const { return mId; }
@@ -78,20 +80,20 @@
std::vector<std::shared_ptr<VolumeBase>> getVolumes() const;
- status_t create();
- status_t destroy();
+ virtual status_t create();
+ virtual status_t destroy();
- status_t readMetadata();
- status_t readPartitions();
+ virtual status_t readMetadata();
+ virtual status_t readPartitions();
void initializePartition(std::shared_ptr<StubVolume> vol);
status_t unmountAll();
- status_t partitionPublic();
- status_t partitionPrivate();
- status_t partitionMixed(int8_t ratio);
+ virtual status_t partitionPublic();
+ virtual status_t partitionPrivate();
+ virtual status_t partitionMixed(int8_t ratio);
- private:
+ protected:
/* ID that uniquely references this disk */
std::string mId;
/* Original event path */
diff --git a/model/DiskPartition.cpp b/model/DiskPartition.cpp
new file mode 100644
index 0000000..1cbcfbb
--- /dev/null
+++ b/model/DiskPartition.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2015 Cyanogen, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "DiskPartition.h"
+#include "PublicVolume.h"
+#include "PrivateVolume.h"
+#include "Utils.h"
+#include "VolumeBase.h"
+#include "VolumeManager.h"
+
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <android-base/logging.h>
+#include <diskconfig/diskconfig.h>
+
+#include <vector>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/sysmacros.h>
+#include <sys/stat.h>
+#include <sys/mount.h>
+
+using android::base::ReadFileToString;
+using android::base::WriteStringToFile;
+using android::base::StringPrintf;
+
+namespace android {
+namespace vold {
+
+DiskPartition::DiskPartition(const std::string& eventPath, dev_t device,
+ const std::string& nickname, int flags, int partnum) :
+ Disk(eventPath, device, nickname, flags),
+ mPartNum(partnum) {
+ // Empty
+}
+
+DiskPartition::~DiskPartition() {
+ // Empty
+}
+
+status_t DiskPartition::create() {
+ CHECK(!mCreated);
+ mCreated = true;
+ auto listener = VolumeManager::Instance()->getListener();
+ if (listener) listener->onDiskCreated(getId(), mFlags);
+ dev_t partDevice = makedev(major(mDevice), minor(mDevice) + mPartNum);
+ createPublicVolume(partDevice);
+ return OK;
+}
+
+status_t DiskPartition::destroy() {
+ CHECK(mCreated);
+ destroyAllVolumes();
+ mCreated = false;
+ auto listener = VolumeManager::Instance()->getListener();
+ if (listener) listener->onDiskDestroyed(getId());
+ return OK;
+}
+
+status_t DiskPartition::partitionPublic() {
+ return -1;
+}
+
+status_t DiskPartition::partitionPrivate() {
+ return -1;
+}
+
+status_t DiskPartition::partitionMixed(int8_t ratio) {
+ return -1;
+}
+
+} // namespace vold
+} // namespace android
+
diff --git a/model/DiskPartition.h b/model/DiskPartition.h
new file mode 100644
index 0000000..274d6be
--- /dev/null
+++ b/model/DiskPartition.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 Cyanogen, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_VOLD_DISKPARTITION_H
+#define ANDROID_VOLD_DISKPARTITION_H
+
+#include "Disk.h"
+
+namespace android {
+namespace vold {
+
+/*
+ * Representation of a single partition on physical media. Useful for
+ * single media partitions such as "internal" sdcard partitions.
+ */
+
+class DiskPartition : public Disk {
+public:
+ DiskPartition(const std::string& eventPath, dev_t device,
+ const std::string& nickname,
+ int flags, int partnum);
+ virtual ~DiskPartition();
+
+ virtual status_t create();
+ virtual status_t destroy();
+
+ virtual status_t partitionPublic();
+ virtual status_t partitionPrivate();
+ virtual status_t partitionMixed(int8_t ratio);
+
+private:
+ /* Partition number */
+ int mPartNum;
+};
+
+} // namespace vold
+} // namespace android
+
+#endif
+