blob: 96011306ee592e9d542b756c32b4f80a5bedecca [file] [log] [blame]
Tom Marshalla08c6f12019-01-04 14:37:31 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 * Copyright (C) 2019 The LineageOS Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#include "EmulatedVolume.h"
19#include <volume_manager/VolumeManager.h>
20#include "ResponseCode.h"
21#include "Utils.h"
22
23#include <android-base/logging.h>
24#include <android-base/stringprintf.h>
25#include <cutils/fs.h>
26#include <private/android_filesystem_config.h>
27
28#include <fcntl.h>
29#include <stdlib.h>
30#include <sys/mount.h>
31#include <sys/stat.h>
32#include <sys/sysmacros.h>
33#include <sys/types.h>
34#include <sys/wait.h>
35
36#include <fs_mgr.h>
37
38using android::base::StringPrintf;
39
40namespace android {
41namespace volmgr {
42
Nolen Johnson8efd2e42019-03-29 22:45:56 +000043static const std::string kStagingPath = "/mnt/staging/emulated/0";
Tom Marshalla08c6f12019-01-04 14:37:31 -080044
45EmulatedVolume::EmulatedVolume(fstab_rec* rec, const std::string& subdir)
46 : VolumeBase(Type::kEmulated),
47 mSubdir(subdir),
48 mDevPath(rec->blk_device),
49 mFsType(rec->fs_type),
50 mFlags(rec->flags),
51 mFsOptions(rec->fs_options) {
52 setId("emulated");
53 setPartLabel("emulated");
Nolen Johnson8efd2e42019-03-29 22:45:56 +000054 setPath("/storage/emulated/0");
Tom Marshalla08c6f12019-01-04 14:37:31 -080055}
56
57EmulatedVolume::~EmulatedVolume() {}
58
59status_t EmulatedVolume::doMount() {
Nolen Johnson8efd2e42019-03-29 22:45:56 +000060 if (createMountPointRecursive(kStagingPath, 0700, AID_ROOT, AID_ROOT)) {
Tom Marshalla08c6f12019-01-04 14:37:31 -080061 return -errno;
62 }
Nolen Johnson8efd2e42019-03-29 22:45:56 +000063 if (createMountPointRecursive(getPath(), 0700, AID_ROOT, AID_ROOT)) {
Tom Marshalla08c6f12019-01-04 14:37:31 -080064 return -errno;
65 }
66
67 std::string bindPath = kStagingPath + "/" + mSubdir;
68
69 if (::mount(mDevPath.c_str(), kStagingPath.c_str(), mFsType.c_str(), mFlags,
70 mFsOptions.c_str()) != 0) {
71 PLOG(ERROR) << getId() << " failed to mount " << mDevPath << " on " << kStagingPath;
72 return -EIO;
73 }
74 if (BindMount(bindPath, getPath()) != OK) {
75 PLOG(ERROR) << getId() << " failed to bind mount " << bindPath << " on " << getPath();
76 ForceUnmount(kStagingPath);
77 return -EIO;
78 }
79
80 return OK;
81}
82
83status_t EmulatedVolume::doUnmount(bool detach /* = false */) {
84 ForceUnmount(getPath(), detach);
85 ForceUnmount(kStagingPath, detach);
86
87 rmdir(getPath().c_str());
88 rmdir(kStagingPath.c_str());
89
90 return OK;
91}
92
Nolen Johnson8efd2e42019-03-29 22:45:56 +000093int EmulatedVolume::createMountPointRecursive(const std::string& path, mode_t mode, uid_t uid,
94 gid_t gid) {
95 auto pos = path.find("/", 1);
96 while (pos != std::string::npos) {
97 std::string tmp = path.substr(0, pos);
98 mkdir(tmp.c_str(), mode);
99 pos = path.find("/", pos + 1);
100 }
101
102 if (fs_prepare_dir(path.c_str(), mode, uid, gid)) {
103 PLOG(ERROR) << getId() << " failed to create mount point " << path.c_str();
104 return -1;
105 }
106
107 return 0;
108}
109
Tom Marshalla08c6f12019-01-04 14:37:31 -0800110} // namespace volmgr
111} // namespace android