diff --git a/CommandListener.cpp b/CommandListener.cpp index 5168de6..ee99479 100644 --- a/CommandListener.cpp +++ b/CommandListener.cpp @@ -258,6 +258,11 @@ int CommandListener::VolumeCmd::runCommand(SocketClient *cli, nsecs_t res = vm->benchmarkVolume(id); return cli->sendMsg(ResponseCode::CommandOkay, android::base::StringPrintf("%" PRId64, res).c_str(), false); + + } else if (cmd == "forget_partition" && argc > 2) { + // forget_partition [partGuid] + std::string partGuid(argv[2]); + return sendGenericOkFail(cli, vm->forgetPartition(partGuid)); } return cli->sendMsg(ResponseCode::CommandSyntaxError, nullptr, false); diff --git a/Disk.cpp b/Disk.cpp index a536dbf..c680a43 100644 --- a/Disk.cpp +++ b/Disk.cpp @@ -72,8 +72,6 @@ static const char* kGptBasicData = "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7"; static const char* kGptAndroidMeta = "19A710A2-B3CA-11E4-B026-10604B889DCF"; static const char* kGptAndroidExpand = "193D1EA4-B3CA-11E4-B075-10604B889DCF"; -static const char* kKeyPath = "/data/misc/vold"; - enum class Table { kUnknown, kMbr, @@ -126,10 +124,6 @@ status_t Disk::destroy() { return OK; } -static std::string BuildKeyPath(const std::string& partGuid) { - return StringPrintf("%s/expand_%s.key", kKeyPath, partGuid.c_str()); -} - void Disk::createPublicVolume(dev_t device) { auto vol = std::shared_ptr(new PublicVolume(device)); if (mJustPartitioned) { @@ -147,13 +141,11 @@ void Disk::createPublicVolume(dev_t device) { } void Disk::createPrivateVolume(dev_t device, const std::string& partGuid) { - std::string tmp; std::string normalizedGuid; - if (HexToStr(partGuid, tmp)) { + if (NormalizeHex(partGuid, normalizedGuid)) { LOG(WARNING) << "Invalid GUID " << partGuid; return; } - StrToHex(tmp, normalizedGuid); std::string keyRaw; if (!ReadFileToString(BuildKeyPath(normalizedGuid), &keyRaw)) { @@ -175,6 +167,7 @@ void Disk::createPrivateVolume(dev_t device, const std::string& partGuid) { mVolumes.push_back(vol); vol->setDiskId(getId()); + vol->setPartGuid(partGuid); vol->create(); } diff --git a/Utils.cpp b/Utils.cpp index e06111a..2ccd45f 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -52,6 +52,7 @@ security_context_t sFsckContext = nullptr; security_context_t sFsckUntrustedContext = nullptr; static const char* kBlkidPath = "/system/bin/blkid"; +static const char* kKeyPath = "/data/misc/vold"; static const char* kProcFilesystems = "/proc/filesystems"; @@ -391,6 +392,14 @@ status_t StrToHex(const std::string& str, std::string& hex) { return OK; } +status_t NormalizeHex(const std::string& in, std::string& out) { + std::string tmp; + if (HexToStr(in, tmp)) { + return -EINVAL; + } + return StrToHex(tmp, out); +} + uint64_t GetFreeBytes(const std::string& path) { struct statvfs sb; if (statvfs(path.c_str(), &sb) == 0) { @@ -509,5 +518,9 @@ done: return res; } +std::string BuildKeyPath(const std::string& partGuid) { + return StringPrintf("%s/expand_%s.key", kKeyPath, partGuid.c_str()); +} + } // namespace vold } // namespace android diff --git a/Utils.h b/Utils.h index ab151aa..8d6bf38 100644 --- a/Utils.h +++ b/Utils.h @@ -77,6 +77,8 @@ status_t ReadRandomBytes(size_t bytes, std::string& out); status_t HexToStr(const std::string& hex, std::string& str); /* Converts raw bytes to hex string */ status_t StrToHex(const std::string& str, std::string& hex); +/* Normalize given hex string into consistent format */ +status_t NormalizeHex(const std::string& in, std::string& out); uint64_t GetFreeBytes(const std::string& path); uint64_t GetTreeBytes(const std::string& path); @@ -86,6 +88,8 @@ bool IsFilesystemSupported(const std::string& fsType); /* Wipes contents of block device at given path */ status_t WipeBlockDevice(const std::string& path); +std::string BuildKeyPath(const std::string& partGuid); + } // namespace vold } // namespace android diff --git a/VolumeBase.cpp b/VolumeBase.cpp index 05a61ed..7d733cb 100644 --- a/VolumeBase.cpp +++ b/VolumeBase.cpp @@ -59,6 +59,16 @@ status_t VolumeBase::setDiskId(const std::string& diskId) { return OK; } +status_t VolumeBase::setPartGuid(const std::string& partGuid) { + if (mCreated) { + LOG(WARNING) << getId() << " partGuid change requires destroyed"; + return -EBUSY; + } + + mPartGuid = partGuid; + return OK; +} + status_t VolumeBase::setMountFlags(int mountFlags) { if ((mState != State::kUnmounted) && (mState != State::kUnmountable)) { LOG(WARNING) << getId() << " flags change requires state unmounted or unmountable"; @@ -155,7 +165,8 @@ status_t VolumeBase::create() { mCreated = true; status_t res = doCreate(); - notifyEvent(ResponseCode::VolumeCreated, StringPrintf("%d %s", mType, mDiskId.c_str())); + notifyEvent(ResponseCode::VolumeCreated, + StringPrintf("%d \"%s\" \"%s\"", mType, mDiskId.c_str(), mPartGuid.c_str())); setState(State::kUnmounted); return res; } diff --git a/VolumeBase.h b/VolumeBase.h index 42b4d65..d417019 100644 --- a/VolumeBase.h +++ b/VolumeBase.h @@ -76,6 +76,7 @@ public: const std::string& getId() { return mId; } const std::string& getDiskId() { return mDiskId; } + const std::string& getPartGuid() { return mPartGuid; } Type getType() { return mType; } int getMountFlags() { return mMountFlags; } userid_t getMountUserId() { return mMountUserId; } @@ -84,6 +85,7 @@ public: const std::string& getInternalPath() { return mInternalPath; } status_t setDiskId(const std::string& diskId); + status_t setPartGuid(const std::string& partGuid); status_t setMountFlags(int mountFlags); status_t setMountUserId(userid_t mountUserId); status_t setSilent(bool silent); @@ -120,6 +122,8 @@ private: std::string mId; /* ID that uniquely references parent disk while alive */ std::string mDiskId; + /* Partition GUID of this volume */ + std::string mPartGuid; /* Volume type */ Type mType; /* Flags used when mounting this volume */ diff --git a/VolumeManager.cpp b/VolumeManager.cpp index 6f783a2..f1667f2 100755 --- a/VolumeManager.cpp +++ b/VolumeManager.cpp @@ -59,6 +59,7 @@ #include "Asec.h" #include "VoldUtil.h" #include "cryptfs.h" +#include "fstrim.h" #define MASS_STORAGE_FILE_PATH "/sys/class/android_usb/android0/f_mass_storage/lun/file" @@ -405,6 +406,22 @@ nsecs_t VolumeManager::benchmarkVolume(const std::string& id) { return android::vold::Benchmark(path, sysPath); } +int VolumeManager::forgetPartition(const std::string& partGuid) { + std::string normalizedGuid; + if (android::vold::NormalizeHex(partGuid, normalizedGuid)) { + LOG(WARNING) << "Invalid GUID " << partGuid; + return -1; + } + + std::string keyPath = android::vold::BuildKeyPath(normalizedGuid); + if (unlink(keyPath.c_str()) != 0) { + LOG(ERROR) << "Failed to unlink " << keyPath; + return -1; + } + + return 0; +} + int VolumeManager::linkPrimary(userid_t userId) { std::string source(mPrimary->getPath()); if (mPrimary->getType() == android::vold::VolumeBase::Type::kEmulated) { diff --git a/VolumeManager.h b/VolumeManager.h index 3207de8..8620d25 100644 --- a/VolumeManager.h +++ b/VolumeManager.h @@ -120,6 +120,8 @@ public: nsecs_t benchmarkVolume(const std::string& id); + int forgetPartition(const std::string& partGuid); + int onUserAdded(userid_t userId, int userSerialNumber); int onUserRemoved(userid_t userId); int onUserStarted(userid_t userId);