recovery: Implement a volume manager
This is a copy of the pre-binderized vold which has been converted to
use direct calls instead of sockets and stripped down to only what is
needed to support recovery.
Change-Id: Ic82d929e052b5ba70ecf7b475e0a223d77d9687e
diff --git a/volume_manager/EmulatedVolume.cpp b/volume_manager/EmulatedVolume.cpp
new file mode 100644
index 0000000..8260563
--- /dev/null
+++ b/volume_manager/EmulatedVolume.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2019 The LineageOS 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 "EmulatedVolume.h"
+#include <volume_manager/VolumeManager.h>
+#include "ResponseCode.h"
+#include "Utils.h"
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.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/sysmacros.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+using android::base::StringPrintf;
+
+namespace android {
+namespace volmgr {
+
+static const std::string kStagingPath = "/mnt/staging/emulated";
+
+EmulatedVolume::EmulatedVolume(FstabEntry* rec, const std::string& subdir)
+ : VolumeBase(Type::kEmulated),
+ mSubdir(subdir),
+ mDevPath(rec->blk_device),
+ mFsType(rec->fs_type),
+ mFlags(rec->flags),
+ mFsOptions(rec->fs_options) {
+ setId("emulated");
+ setPartLabel("internal storage");
+ setPath("/storage/emulated");
+}
+
+EmulatedVolume::~EmulatedVolume() {}
+
+status_t EmulatedVolume::doMount() {
+ if (fs_prepare_dir(kStagingPath.c_str(), 0700, AID_ROOT, AID_ROOT)) {
+ PLOG(ERROR) << getId() << " failed to create mount points";
+ return -errno;
+ }
+ if (fs_prepare_dir(getPath().c_str(), 0700, AID_ROOT, AID_ROOT)) {
+ PLOG(ERROR) << getId() << " failed to create mount points";
+ return -errno;
+ }
+
+ std::string bindPath = kStagingPath + "/" + mSubdir;
+
+ if (::mount(mDevPath.c_str(), kStagingPath.c_str(), mFsType.c_str(), mFlags,
+ mFsOptions.c_str()) != 0) {
+ PLOG(ERROR) << getId() << " failed to mount " << mDevPath << " on " << kStagingPath;
+ return -EIO;
+ }
+ if (BindMount(bindPath, getPath()) != OK) {
+ PLOG(ERROR) << getId() << " failed to bind mount " << bindPath << " on " << getPath();
+ ForceUnmount(kStagingPath);
+ return -EIO;
+ }
+
+ return OK;
+}
+
+status_t EmulatedVolume::doUnmount(bool detach /* = false */) {
+ ForceUnmount(getPath(), detach);
+ ForceUnmount(kStagingPath, detach);
+
+ rmdir(getPath().c_str());
+ rmdir(kStagingPath.c_str());
+
+ return OK;
+}
+
+} // namespace volmgr
+} // namespace android