Move even more vold commands over to Binder.
This moves fstrim, obb and appfuse commands over to the new Binder
interface. This change also separates creating/destroying and
mounting/unmounting of OBB volumes, which means they finally flow
nicely into the modern VolumeInfo/VolumeBase design.
We now generate unique identifiers for all OBB volumes, instead of
using a shady MD5 hash.
Change all "loop" and "dm" devices to tag the kernel resources with
a vold-specific prefix so that we can clean them up if vold crashes;
there are new destroyAll() methods that handle this cleanup.
Move appfuse mounting/unmounting into VolumeManager so it can be
shared. Move various model objects into a separate directory to
tidy things up.
Test: cts-tradefed run commandAndExit cts-dev -m CtsOsTestCases -t android.os.storage.cts.StorageManagerTest
Bug: 13758960
Change-Id: I7294e32b3fb6efe07cb3b77bd20166e70b66958f
diff --git a/model/ObbVolume.cpp b/model/ObbVolume.cpp
new file mode 100644
index 0000000..709c7a3
--- /dev/null
+++ b/model/ObbVolume.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * 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 "fs/Vfat.h"
+#include "Devmapper.h"
+#include "Loop.h"
+#include "ObbVolume.h"
+#include "Utils.h"
+#include "VoldUtil.h"
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
+#include <cutils/fs.h>
+#include <private/android_filesystem_config.h>
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/sysmacros.h>
+#include <sys/wait.h>
+
+using android::base::StringPrintf;
+using android::base::unique_fd;
+
+namespace android {
+namespace vold {
+
+ObbVolume::ObbVolume(int id, const std::string& sourcePath, const std::string& sourceKey,
+ gid_t ownerGid) : VolumeBase(Type::kObb) {
+ setId(StringPrintf("obb:%d", id));
+ mSourcePath = sourcePath;
+ mSourceKey = sourceKey;
+ mOwnerGid = ownerGid;
+}
+
+ObbVolume::~ObbVolume() {
+}
+
+status_t ObbVolume::doCreate() {
+ if (Loop::create(mSourcePath, mLoopPath)) {
+ PLOG(ERROR) << getId() << " failed to create loop";
+ return -1;
+ }
+
+ if (!mSourceKey.empty()) {
+ unsigned long nr_sec = 0;
+ {
+ unique_fd loop_fd(open(mLoopPath.c_str(), O_RDWR | O_CLOEXEC));
+ if (loop_fd.get() == -1) {
+ PLOG(ERROR) << getId() << " failed to open loop";
+ return -1;
+ }
+
+ get_blkdev_size(loop_fd.get(), &nr_sec);
+ if (nr_sec == 0) {
+ PLOG(ERROR) << getId() << " failed to get loop size";
+ return -1;
+ }
+ }
+
+ char tmp[PATH_MAX];
+ if (Devmapper::create(getId().c_str(), mLoopPath.c_str(), mSourceKey.c_str(), nr_sec,
+ tmp, PATH_MAX)) {
+ PLOG(ERROR) << getId() << " failed to create dm";
+ return -1;
+ }
+ mDmPath = tmp;
+ mMountPath = mDmPath;
+ } else {
+ mMountPath = mLoopPath;
+ }
+ return OK;
+}
+
+status_t ObbVolume::doDestroy() {
+ if (!mDmPath.empty() && Devmapper::destroy(getId().c_str())) {
+ PLOG(WARNING) << getId() << " failed to destroy dm";
+ }
+ if (!mLoopPath.empty() && Loop::destroyByDevice(mLoopPath.c_str())) {
+ PLOG(WARNING) << getId() << " failed to destroy loop";
+ }
+ mDmPath.clear();
+ mLoopPath.clear();
+ return OK;
+}
+
+status_t ObbVolume::doMount() {
+ auto path = StringPrintf("/mnt/obb/%s", getId().c_str());
+ setPath(path);
+
+ if (fs_prepare_dir(path.c_str(), 0700, AID_ROOT, AID_ROOT)) {
+ PLOG(ERROR) << getId() << " failed to create mount point";
+ return -1;
+ }
+ if (android::vold::vfat::Mount(mMountPath, path,
+ true, false, true, 0, mOwnerGid, 0227, false)) {
+ PLOG(ERROR) << getId() << " failed to mount";
+ return -1;
+ }
+ return OK;
+}
+
+status_t ObbVolume::doUnmount() {
+ auto path = getPath();
+
+ KillProcessesUsingPath(path);
+ ForceUnmount(path);
+ rmdir(path.c_str());
+
+ return OK;
+}
+
+} // namespace vold
+} // namespace android