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