OSDN Git Service

vold: Honor mount options for ext4/f2fs partitions
[android-x86/system-vold.git] / VolumeManager.h
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef ANDROID_VOLD_VOLUME_MANAGER_H
18 #define ANDROID_VOLD_VOLUME_MANAGER_H
19
20 #include <fnmatch.h>
21 #include <pthread.h>
22 #include <stdlib.h>
23
24 #include <list>
25 #include <mutex>
26 #include <set>
27 #include <string>
28 #include <unordered_map>
29 #include <unordered_set>
30
31 #include <android-base/unique_fd.h>
32 #include <cutils/multiuser.h>
33 #include <sysutils/NetlinkEvent.h>
34 #include <utils/List.h>
35 #include <utils/Timers.h>
36
37 #include "android/os/IVoldListener.h"
38
39 #include "model/Disk.h"
40 #include "model/DiskPartition.h"
41 #include "model/VolumeBase.h"
42
43 class VolumeManager {
44   private:
45     static VolumeManager* sInstance;
46
47     bool mDebug;
48
49   public:
50     virtual ~VolumeManager();
51
52     // TODO: pipe all requests through VM to avoid exposing this lock
53     std::mutex& getLock() { return mLock; }
54     std::mutex& getCryptLock() { return mCryptLock; }
55
56     void setListener(android::sp<android::os::IVoldListener> listener) { mListener = listener; }
57     android::sp<android::os::IVoldListener> getListener() const { return mListener; }
58
59     int start();
60
61     void handleBlockEvent(NetlinkEvent* evt);
62
63     class DiskSource {
64       public:
65         DiskSource(const std::string& sysPattern, const std::string& nickname,
66                         int partnum, int flags,
67                         const std::string& fstype, const std::string mntopts) :
68                 mSysPattern(sysPattern), mNickname(nickname),
69                 mPartNum(partnum), mFlags(flags),
70                 mFsType(fstype), mMntOpts(mntopts) {
71         }
72
73         bool matches(const std::string& sysPath) {
74             return !fnmatch(mSysPattern.c_str(), sysPath.c_str(), 0);
75         }
76
77         const std::string& getNickname() const { return mNickname; }
78         int getPartNum() const { return mPartNum; }
79         int getFlags() const { return mFlags; }
80         const std::string& getFsType() const { return mFsType; }
81         const std::string& getMntOpts() const { return mMntOpts; }
82
83       private:
84         std::string mSysPattern;
85         std::string mNickname;
86         int mPartNum;
87         int mFlags;
88         std::string mFsType;
89         std::string mMntOpts;
90     };
91
92     void addDiskSource(const std::shared_ptr<DiskSource>& diskSource);
93
94     std::shared_ptr<android::vold::Disk> findDisk(const std::string& id);
95     std::shared_ptr<android::vold::VolumeBase> findVolume(const std::string& id);
96
97     template <typename Fn>
98     std::shared_ptr<android::vold::VolumeBase> findVolumeWithFilter(Fn fn) {
99         for (const auto& vol : mInternalEmulatedVolumes) {
100             if (fn(*vol)) {
101                 return vol;
102             }
103         }
104         for (const auto& disk : mDisks) {
105             for (const auto& vol : disk->getVolumes()) {
106                 if (fn(*vol)) {
107                     return vol;
108                 }
109             }
110         }
111
112         return nullptr;
113     }
114
115     void listVolumes(android::vold::VolumeBase::Type type, std::list<std::string>& list) const;
116
117     const std::set<userid_t>& getStartedUsers() const { return mStartedUsers; }
118
119     int forgetPartition(const std::string& partGuid, const std::string& fsUuid);
120
121     int onUserAdded(userid_t userId, int userSerialNumber);
122     int onUserRemoved(userid_t userId);
123     int onUserStarted(userid_t userId);
124     int onUserStopped(userid_t userId);
125
126     void createPendingDisksIfNeeded();
127     int onSecureKeyguardStateChanged(bool isShowing);
128
129     int remountUid(uid_t uid, int32_t remountMode) { return 0; }
130     int handleAppStorageDirs(int uid, int pid,
131             bool doUnmount, const std::vector<std::string>& packageNames);
132
133     /* Aborts all FUSE filesystems, in case the FUSE daemon is no longer up. */
134     int abortFuse();
135     /* Reset all internal state, typically during framework boot */
136     int reset();
137     /* Prepare for device shutdown, safely unmounting all devices */
138     int shutdown();
139     /* Unmount all volumes, usually for encryption */
140     int unmountAll();
141
142     int updateVirtualDisk();
143     int setDebug(bool enable);
144
145     bool forkAndRemountStorage(int uid, int pid, bool doUnmount,
146         const std::vector<std::string>& packageNames);
147
148     static VolumeManager* Instance();
149
150     /*
151      * Creates a directory 'path' for an application, automatically creating
152      * directories along the given path if they don't exist yet.
153      *
154      * Example:
155      *   path = /storage/emulated/0/Android/data/com.foo/files/
156      *
157      * This function will first match the first part of the path with the volume
158      * root of any known volumes; in this case, "/storage/emulated/0" matches
159      * with the volume root of the emulated volume for user 0.
160      *
161      * The subseqent part of the path must start with one of the well-known
162      * Android/ data directories, /Android/data, /Android/obb or
163      * /Android/media.
164      *
165      * The final part of the path is application specific. This function will
166      * create all directories, including the application-specific ones, and
167      * set the UID of all app-specific directories below the well-known data
168      * directories to the 'appUid' argument. In the given example, the UID
169      * of /storage/emulated/0/Android/data/com.foo and
170      * /storage/emulated/0/Android/data/com.foo/files would be set to 'appUid'.
171      *
172      * The UID/GID of the parent directories will be set according to the
173      * requirements of the underlying filesystem and are of no concern to the
174      * caller.
175      *
176      * If fixupExistingOnly is set, we make sure to fixup any existing dirs and
177      * files in the passed in path, but only if that path exists; if it doesn't
178      * exist, this function doesn't create them.
179      *
180      * If skipIfDirExists is set, we will not fix any existing dirs, we will
181      * only create app dirs if it doesn't exist.
182      *
183      * Validates that given paths are absolute and that they contain no relative
184      * "." or ".." paths or symlinks.  Last path segment is treated as filename
185      * and ignored, unless the path ends with "/".  Also ensures that path
186      * belongs to a volume managed by vold.
187      */
188     int setupAppDir(const std::string& path, int32_t appUid, bool fixupExistingOnly = false,
189             bool skipIfDirExists = false);
190
191     /**
192      * Fixes up an existing application directory, as if it was created with
193      * setupAppDir() above. This includes fixing up the UID/GID, permissions and
194      * project IDs of the contained files and directories.
195      */
196     int fixupAppDir(const std::string& path, int32_t appUid);
197
198     // Called before zygote starts to ensure dir exists so zygote can bind mount them.
199     int ensureAppDirsCreated(const std::vector<std::string>& paths, int32_t appUid);
200
201     int createObb(const std::string& path, const std::string& key, int32_t ownerGid,
202                   std::string* outVolId);
203     int destroyObb(const std::string& volId);
204
205     int createStubVolume(const std::string& sourcePath, const std::string& mountPath,
206                          const std::string& fsType, const std::string& fsUuid,
207                          const std::string& fsLabel, int32_t flags, std::string* outVolId);
208     int destroyStubVolume(const std::string& volId);
209
210     int mountAppFuse(uid_t uid, int mountId, android::base::unique_fd* device_fd);
211     int unmountAppFuse(uid_t uid, int mountId);
212     int openAppFuseFile(uid_t uid, int mountId, int fileId, int flags);
213
214   private:
215     VolumeManager();
216     void readInitialState();
217
218     int linkPrimary(userid_t userId);
219
220     void createEmulatedVolumesForUser(userid_t userId);
221     void destroyEmulatedVolumesForUser(userid_t userId);
222
223     void handleDiskAdded(const std::shared_ptr<android::vold::Disk>& disk);
224     void handleDiskChanged(dev_t device);
225     void handleDiskRemoved(dev_t device);
226
227     bool updateFuseMountedProperty();
228
229     std::mutex mLock;
230     std::mutex mCryptLock;
231
232     android::sp<android::os::IVoldListener> mListener;
233
234     std::list<std::shared_ptr<DiskSource>> mDiskSources;
235     std::list<std::shared_ptr<android::vold::Disk>> mDisks;
236     std::list<std::shared_ptr<android::vold::Disk>> mPendingDisks;
237     std::list<std::shared_ptr<android::vold::VolumeBase>> mObbVolumes;
238     std::list<std::shared_ptr<android::vold::VolumeBase>> mInternalEmulatedVolumes;
239
240     std::unordered_map<userid_t, int> mAddedUsers;
241     // This needs to be a regular set because we care about the ordering here;
242     // user 0 should always go first, because it is responsible for sdcardfs.
243     std::set<userid_t> mStartedUsers;
244
245     std::string mVirtualDiskPath;
246     std::shared_ptr<android::vold::Disk> mVirtualDisk;
247     std::shared_ptr<android::vold::VolumeBase> mPrimary;
248
249     int mNextObbId;
250     int mNextStubId;
251     bool mSecureKeyguardShowing;
252 };
253
254 #endif