1 /*
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "user/mount_manager.h"
17 #include <cstdlib>
18 #include <csignal>
19 #include <dirent.h>
20 #include <fcntl.h>
21 #include <set>
22 #include <sys/mount.h>
23 #include <sys/types.h>
24 #include <thread>
25 #include <unistd.h>
26 #include <regex>
27 #include <filesystem>
28 #include "hisysevent.h"
29 #include "crypto/key_manager.h"
30 #include "utils/storage_radar.h"
31 #include "ipc/istorage_daemon.h"
32 #include "parameter.h"
33 #include "quota/quota_manager.h"
34 #include "storage_service_constant.h"
35 #include "storage_service_errno.h"
36 #include "storage_service_log.h"
37 #include "utils/mount_argument_utils.h"
38 #include "utils/string_utils.h"
39 #include "system_ability_definition.h"
40 #ifdef DFS_SERVICE
41 #include "cloud_daemon_manager.h"
42 #endif
43 #ifdef USE_LIBRESTORECON
44 #include "policycoreutils.h"
45 #endif
46 
47 namespace OHOS {
48 namespace StorageDaemon {
49 using namespace std;
50 #ifdef DFS_SERVICE
51 using namespace OHOS::FileManagement::CloudFile;
52 #endif
53 using namespace OHOS::StorageService;
54 constexpr int32_t ONE_KB = 1024;
55 constexpr int32_t DEFAULT_USERID = 100;
56 std::shared_ptr<MountManager> MountManager::instance_ = nullptr;
57 
58 const string SANDBOX_ROOT_PATH = "/mnt/sandbox/";
59 const string CURRENT_USER_ID_FLAG = "<currentUserId>";
60 const string PACKAGE_NAME_FLAG = "<bundleName>";
61 const string MOUNT_POINT_INFO = "/proc/mounts";
62 const string MOUNT_POINT_TYPE_HMDFS = "hmdfs";
63 const string MOUNT_POINT_TYPE_HMFS = "hmfs";
64 const string MOUNT_POINT_TYPE_F2FS = "f2fs";
65 const string MOUNT_POINT_TYPE_SHAREFS = "sharefs";
66 const string EL2_BASE = "/data/storage/el2/base/";
67 const string MOUNT_SUFFIX = "_locked";
68 const string APP_EL1_PATH = "/data/app/el1";
69 const set<string> SANDBOX_EXCLUDE_PATH = {
70     "chipset",
71     "system",
72     "com.ohos.render"
73 };
74 const vector<string> CRYPTO_SANDBOX_PATH = {
75     "/data/storage/el2/base/",
76     "/data/storage/el2/database/",
77     "/data/storage/el2/share/",
78     "/data/storage/el2/log/",
79     "/data/storage/el2/distributedfiles/",
80     "/data/storage/el2/cloud/",
81     "/data/storage/el3/base/",
82     "/data/storage/el3/database/",
83     "/data/storage/el4/base/",
84     "/data/storage/el4/database/",
85     "/data/storage/el5/base/",
86     "/data/storage/el5/database/"
87 };
88 const vector<string> CRYPTO_SRC_PATH = {
89     "/data/app/el2/<currentUserId>/base/<bundleName>/",
90     "/data/app/el2/<currentUserId>/database/<bundleName>/",
91     "/mnt/share/<currentUserId>/<bundleName>/",
92     "/data/app/el2/<currentUserId>/log/<bundleName>/",
93     "/mnt/hmdfs/<currentUserId>/account/merge_view/data/<bundleName>/",
94     "/mnt/hmdfs/<currentUserId>/cloud/data/<bundleName>/",
95     "/data/app/el3/<currentUserId>/base/<bundleName>/",
96     "/data/app/el3/<currentUserId>/database/<bundleName>/",
97     "/data/app/el4/<currentUserId>/base/<bundleName>/",
98     "/data/app/el4/<currentUserId>/database/<bundleName>/",
99     "/data/app/el5/<currentUserId>/base/<bundleName>/",
100     "/data/app/el5/<currentUserId>/database/<bundleName>/"
101 };
102 
103 const vector<string> APPDATA_DST_PATH = {
104     "/mnt/user/<currentUserId>/nosharefs/appdata/el1/base/",
105     "/mnt/user/<currentUserId>/nosharefs/appdata/el2/base/",
106     "/mnt/user/<currentUserId>/nosharefs/appdata/el2/cloud/",
107     "/mnt/user/<currentUserId>/nosharefs/appdata/el2/distributedfiles/"
108 };
109 
110 const vector<string> APPDATA_SRC_PATH = {
111     "/data/app/el1/<currentUserId>/base/",
112     "/data/app/el2/<currentUserId>/base/",
113     "/mnt/hmdfs/<currentUserId>/cloud/data/",
114     "/mnt/hmdfs/<currentUserId>/account/merge_view/data/"
115 };
116 
117 const vector<string> FD_PATH = {
118     "/data/service/el2/<currentUserId>",
119     "/data/service/el3/<currentUserId>",
120     "/data/service/el4/<currentUserId>",
121     "/data/service/el5/<currentUserId>",
122     "/storage/media/<currentUserId>"
123 };
124 
125 const std::string HMDFS_SYS_CAP = "const.distributed_file_property.enabled";
126 const int32_t HMDFS_VAL_LEN = 6;
127 const int32_t HMDFS_TRUE_LEN = 5;
128 const string SHARE_PATH = "/data/service/el1/public/storage_daemon/share/public";
129 static constexpr int MODE_0711 = 0711;
130 static constexpr int MODE_0771 = 0771;
131 static constexpr int MODE_02771 = 02771;
MountManager()132 MountManager::MountManager() : hmdfsDirVec_(InitHmdfsDirVec()), virtualDir_(InitVirtualDir()),
133     systemServiceDir_(InitSystemServiceDir()), fileManagerDir_(InitFileManagerDir()), appdataDir_(InitAppdataDir())
134 {
135 }
136 
GetInstance()137 std::shared_ptr<MountManager> MountManager::GetInstance()
138 {
139     static std::once_flag onceFlag;
140     std::call_once(onceFlag, [&]() { instance_ = std::make_shared<MountManager>(); });
141 
142     return instance_;
143 }
144 
InitHmdfsDirVec()145 std::vector<DirInfo> MountManager::InitHmdfsDirVec()
146 {
147     return {{"/data/service/el2/%d/share", MODE_0711, OID_SYSTEM, OID_SYSTEM},
148             {"/data/service/el2/%d/hmdfs", MODE_0711, OID_DFS, OID_DFS},
149             {"/data/service/el2/%d/hmdfs/account", MODE_0711, OID_SYSTEM, OID_SYSTEM},
150             {"/data/service/el2/%d/hmdfs/account/files", MODE_02771, OID_USER_DATA_RW, OID_USER_DATA_RW},
151             {"/data/service/el2/%d/hmdfs/account/data", MODE_0711, OID_SYSTEM, OID_SYSTEM},
152             {"/data/service/el2/%d/hmdfs/non_account", MODE_0711, OID_SYSTEM, OID_SYSTEM},
153             {"/data/service/el2/%d/hmdfs/non_account/files", MODE_0711, OID_USER_DATA_RW, OID_USER_DATA_RW},
154             {"/data/service/el2/%d/hmdfs/non_account/data", MODE_0711, OID_SYSTEM, OID_SYSTEM},
155             {"/data/service/el2/%d/hmdfs/cloud", MODE_0711, OID_DFS, OID_DFS},
156             {"/data/service/el2/%d/hmdfs/cloud/data", MODE_0711, OID_DFS, OID_DFS},
157             {"/data/service/el2/%d/hmdfs/cache", MODE_0711, OID_DFS, OID_DFS},
158             {"/data/service/el2/%d/hmdfs/cloudfile_manager", MODE_0711, OID_DFS, OID_DFS},
159             {"/data/service/el2/%d/hmdfs/cache/account_cache", MODE_0711, OID_DFS, OID_DFS},
160             {"/data/service/el2/%d/hmdfs/cache/non_account_cache", MODE_0711, OID_DFS, OID_DFS},
161             {"/data/service/el2/%d/hmdfs/cache/cloud_cache", MODE_0711, OID_DFS, OID_DFS},
162             {"/data/service/el2/%d/hmdfs/account/services", MODE_0771, OID_DFS_SHARE, OID_DFS_SHARE}};
163 }
164 
InitVirtualDir()165 std::vector<DirInfo> MountManager::InitVirtualDir()
166 {
167     return {{"/storage/media/%d", MODE_0711, OID_USER_DATA_RW, OID_USER_DATA_RW},
168             {"/storage/media/%d/local", MODE_0711, OID_USER_DATA_RW, OID_USER_DATA_RW},
169             {"/storage/cloud", MODE_0711, OID_ROOT, OID_ROOT},
170             {"/storage/cloud/%d", MODE_0711, OID_USER_DATA_RW, OID_USER_DATA_RW},
171             {"/mnt/share/", MODE_0711, OID_ROOT, OID_ROOT},
172             {"/mnt/share/%d/", MODE_0711, OID_ROOT, OID_ROOT},
173             {"/mnt/data/%d/", MODE_0711, OID_ROOT, OID_ROOT},
174             {"/mnt/data/%d/cloud", MODE_0711, OID_ROOT, OID_ROOT},
175             {"/mnt/data/%d/cloud_fuse", MODE_0711, OID_DFS, OID_DFS},
176             {"/mnt/data/%d/media_fuse", MODE_0711, OID_USER_DATA_RW, OID_USER_DATA_RW},
177             {"/mnt/data/%d/hmdfs", MODE_0711, OID_FILE_MANAGER, OID_FILE_MANAGER},
178             {"/mnt/hmdfs/", MODE_0711, OID_ROOT, OID_ROOT},
179             {"/mnt/hmdfs/%d/", MODE_0711, OID_ROOT, OID_ROOT},
180             {"/mnt/hmdfs/%d/cloud", MODE_0711, OID_ROOT, OID_ROOT},
181             {"/mnt/hmdfs/%d/account", MODE_0711, OID_ROOT, OID_ROOT},
182             {"/mnt/hmdfs/%d/non_account", MODE_0711, OID_ROOT, OID_ROOT}};
183 }
184 
InitSystemServiceDir()185 std::vector<DirInfo> MountManager::InitSystemServiceDir()
186 {
187     return {{"/data/service/el2/%d/tee", MODE_0711, OID_TEE, OID_TEE},
188             {"/data/service/el2/%d/cloud_backup_service", MODE_0711, OID_CLOUD_BACK, OID_CLOUD_BACK},
189             {"/data/service/el2/%d/deviceauth", MODE_0711, OID_DEVICE_AUTH, OID_DEVICE_AUTH},
190             {"/data/service/el3/%d/device_standby", MODE_0711, OID_RSS, OID_RSS},
191             {"/data/service/el2/%d/hwid_service", MODE_0711, OID_HWID, OID_HWID},
192             {"/data/service/el2/%d/healthsport", MODE_0711, OID_HEALTH_SPORT, OID_HEALTH_SPORT},
193             {"/data/service/el2/%d/huks_service", MODE_0711, OID_HUKS, OID_HUKS},
194             {"/data/service/el2/%d/parentcontrol", MODE_0711, OID_PARENT_CONTROL, OID_PARENT_CONTROL},
195             {"/data/service/el4/%d/huks_service", MODE_0711, OID_HUKS, OID_HUKS},
196             {"/data/service/el2/%d/asset_service", MODE_0711, OID_ASSET, OID_ASSET},
197             {"/data/service/el2/%d/account", MODE_0711, OID_ACCOUNT, OID_ACCOUNT},
198             {"/data/service/el2/%d/dlp_credential_service", MODE_0711, OID_DLP_CREDENTIAL, OID_DLP_CREDENTIAL},
199             {"/data/service/el2/%d/xpower", MODE_0711, OID_HIVIEW, OID_HIVIEW},
200             {"/data/service/el2/%d/iShare", MODE_0711, OID_COLLABORATION_FWK, OID_COLLABORATION_FWK},
201             {"/data/service/el2/%d/av_session", MODE_0711, OID_AV_SESSION, OID_AV_SESSION},
202             {"/data/service/el2/%d/file_transfer_service", MODE_0711, 7017, 7017},
203             {"/data/service/el2/%d/print_service", MODE_0711, OID_PRINT, OID_PRINT},
204             {"/data/service/el2/%d/database", MODE_0711, OID_DDMS, OID_DDMS},
205             {"/data/service/el2/%d/database/pasteboard_service", MODE_02771, OID_PASTEBOARD, OID_DDMS},
206             {"/data/service/el2/%d/findnetwork", MODE_0711, OID_FINDNETWORK, OID_FINDNETWORK},
207             {"/data/service/el2/%d/findnetwork/database", MODE_0711, OID_FINDNETWORK, OID_FINDNETWORK}};
208 }
209 
InitFileManagerDir()210 std::vector<DirInfo> MountManager::InitFileManagerDir()
211 {
212     return {{"/data/service/el2/%d/hmdfs/account/files/Docs", MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER},
213             {"/data/service/el2/%d/hmdfs/account/files/Docs/Documents",
214                                                               MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER},
215             {"/data/service/el2/%d/hmdfs/account/files/Docs/Download",
216                                                               MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER},
217             {"/data/service/el2/%d/hmdfs/account/files/Docs/Desktop",
218                                                               MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER},
219             {"/data/service/el2/%d/hmdfs/account/files/Docs/.Trash",
220                                                               MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER},
221             {"/data/service/el2/%d/hmdfs/account/files/.Recent", MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER}};
222 }
223 
InitAppdataDir()224 std::vector<DirInfo> MountManager::InitAppdataDir()
225 {
226     return {{"/mnt/user", MODE_0711, OID_ROOT, OID_ROOT},
227             {"/mnt/user/%d", MODE_0711, OID_ROOT, OID_ROOT},
228             {"/mnt/user/%d/nosharefs", MODE_0711, OID_ROOT, OID_ROOT},
229             {"/mnt/user/%d/nosharefs/docs", MODE_0711, OID_ROOT, OID_ROOT},
230             {"/mnt/user/%d/nosharefs/docs/currentUser", MODE_0711, OID_ROOT, OID_ROOT},
231             {"/mnt/user/%d/nosharefs/appdata", MODE_0711, OID_ROOT, OID_ROOT},
232             {"/mnt/user/%d/nosharefs/appdata/el1", MODE_0711, OID_ROOT, OID_ROOT},
233             {"/mnt/user/%d/nosharefs/appdata/el1/base", MODE_0711, OID_ROOT, OID_ROOT},
234             {"/mnt/user/%d/nosharefs/appdata/el2", MODE_0711, OID_ROOT, OID_ROOT},
235             {"/mnt/user/%d/nosharefs/appdata/el2/base", MODE_0711, OID_ROOT, OID_ROOT},
236             {"/mnt/user/%d/nosharefs/appdata/el2/cloud", MODE_0711, OID_ROOT, OID_ROOT},
237             {"/mnt/user/%d/nosharefs/appdata/el2/distributedfiles", MODE_0711, OID_ROOT, OID_ROOT},
238             {"/mnt/user/%d/sharefs", MODE_0711, OID_ROOT, OID_ROOT},
239             {"/mnt/user/%d/sharefs/docs", MODE_0711, OID_ROOT, OID_ROOT},
240             {"/mnt/user/%d/sharefs/docs/currentUser", MODE_0711, OID_ROOT, OID_ROOT},
241             {"/mnt/user/%d/currentUser", MODE_0711, OID_ROOT, OID_ROOT},
242             {"/mnt/user/%d/currentUser/filemgr", MODE_0711, OID_ROOT, OID_ROOT},
243             {"/mnt/user/%d/currentUser/other", MODE_0711, OID_ROOT, OID_ROOT}};
244 }
245 
HmdfsTwiceMount(int32_t userId,const std::string & relativePath)246 int32_t MountManager::HmdfsTwiceMount(int32_t userId, const std::string &relativePath)
247 {
248     int32_t ret = HmdfsMount(userId, relativePath);
249     // bind mount
250     Utils::MountArgument hmdfsMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, relativePath));
251     std::string dst = hmdfsMntArgs.GetCommFullPath();
252     if (IsPathMounted(dst)) {
253         LOGI("path has mounted, %{public}s", dst.c_str());
254     } else {
255         ret += Mount(hmdfsMntArgs.GetFullDst() + "/device_view/", dst, nullptr, MS_BIND, nullptr);
256         if (ret != 0 && errno != EEXIST && errno != EBUSY) {
257             LOGE("failed to bind mount device_view, err %{public}d", errno);
258             return E_MOUNT;
259         }
260     }
261     dst = hmdfsMntArgs.GetCloudFullPath();
262     if (IsPathMounted(dst)) {
263         LOGI("path has mounted, %{public}s", dst.c_str());
264     } else {
265         ret += Mount(hmdfsMntArgs.GetFullDst() + "/cloud_merge_view/", dst, nullptr, MS_BIND, nullptr);
266         if (ret != 0 && errno != EEXIST && errno != EBUSY) {
267             LOGE("failed to bind mount cloud_merge_view, err %{public}d", errno);
268             return E_MOUNT;
269         }
270     }
271     dst = hmdfsMntArgs.GetCloudDocsPath();
272     if (IsPathMounted(dst)) {
273         LOGI("path has mounted, %{public}s", dst.c_str());
274     } else {
275         ret += Mount(hmdfsMntArgs.GetLocalDocsPath(), dst, nullptr, MS_BIND, nullptr);
276         if (ret != 0 && errno != EEXIST && errno != EBUSY) {
277             LOGE("failed to bind mount docs, err %{public}d", errno);
278         }
279     }
280     return E_OK;
281 }
282 
SharefsMount(int32_t userId)283 int32_t MountManager::SharefsMount(int32_t userId)
284 {
285     Utils::MountArgument sharefsMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, ""));
286     std::string dst = sharefsMntArgs.GetShareDst();
287     if (IsPathMounted(dst)) {
288         LOGI("path has mounted, %{public}s", dst.c_str());
289     } else {
290         int ret = Mount(sharefsMntArgs.GetShareSrc(), dst, "sharefs", sharefsMntArgs.GetFlags(),
291                         sharefsMntArgs.GetUserIdPara().c_str());
292         if (ret != 0 && errno != EEXIST && errno != EBUSY) {
293             LOGE("failed to mount sharefs, err %{public}d", errno);
294             return E_MOUNT;
295         }
296     }
297     return E_OK;
298 }
299 
HmSharefsMount(int32_t userId,std::string & srcPath,std::string & dstPath)300 int32_t MountManager::HmSharefsMount(int32_t userId, std::string &srcPath, std::string &dstPath)
301 {
302     if (!IsDir(srcPath)) {
303         LOGE("srcPath not exist, %{public}s", srcPath.c_str());
304         return E_OK;
305     }
306     if (!IsDir(dstPath)) {
307         LOGE("dstPath not exist, %{public}s", dstPath.c_str());
308         return E_OK;
309     }
310     if (IsPathMounted(dstPath)) {
311         LOGI("path has mounted, %{public}s", dstPath.c_str());
312         return E_OK;
313     }
314     Utils::MountArgument sharefsMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, ""));
315     int ret = Mount(srcPath, dstPath, "sharefs", sharefsMntArgs.GetFlags(),
316                     sharefsMntArgs.GetHmUserIdPara().c_str());
317     if (ret != 0) {
318         LOGE("failed to mount hmSharefs, err %{public}d", errno);
319         return E_MOUNT;
320     }
321     return E_OK;
322 }
323 
HmdfsMount(int32_t userId,std::string relativePath,bool mountCloudDisk)324 int32_t MountManager::HmdfsMount(int32_t userId, std::string relativePath, bool mountCloudDisk)
325 {
326     Utils::MountArgument hmdfsMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, relativePath));
327     std::string mountSrcPath = hmdfsMntArgs.GetFullSrc();
328     if (mountCloudDisk) {
329         hmdfsMntArgs.enableCloudDisk_ = true;
330         hmdfsMntArgs.useCloudDir_ = false;
331         hmdfsMntArgs.enableMergeView_ = false;
332         mountSrcPath = hmdfsMntArgs.GetFullCloud();
333     }
334 
335     std::string dst = hmdfsMntArgs.GetFullDst();
336     if (IsPathMounted(dst)) {
337         LOGI("path has mounted, %{public}s", dst.c_str());
338         return E_OK;
339     }
340     int ret = Mount(mountSrcPath, dst, "hmdfs", hmdfsMntArgs.GetFlags(), hmdfsMntArgs.OptionsToString().c_str());
341     if (ret != 0 && errno != EEXIST && errno != EBUSY) {
342         LOGE("failed to mount hmdfs, err %{public}d", errno);
343         return E_MOUNT;
344     }
345 
346     ret = chown(hmdfsMntArgs.GetCtrlPath().c_str(), OID_DFS, OID_SYSTEM);
347     if (ret != 0) {
348         LOGE("failed to chown hmdfs sysfs node, err %{public}d", errno);
349     }
350     return E_OK;
351 }
352 
FindProcess(std::list<std::string> & unMountFailList,std::vector<ProcessInfo> & proInfos,std::list<std::string> & excludeProcess)353 int32_t MountManager::FindProcess(std::list<std::string> &unMountFailList, std::vector<ProcessInfo> &proInfos,
354     std::list<std::string> &excludeProcess)
355 {
356     LOGI("find process start.");
357     auto procDir = std::unique_ptr<DIR, int (*)(DIR*)>(opendir("/proc"), closedir);
358     if (!procDir) {
359         LOGE("failed to open dir proc, err %{public}d", errno);
360         return E_UMOUNT_PROC_OPEN;
361     }
362     struct dirent *entry;
363     while ((entry = readdir(procDir.get())) != nullptr) {
364         if (entry->d_type != DT_DIR) {
365             continue;
366         }
367         std::string name = entry->d_name;
368         if (!StringIsNumber(name)) {
369             continue;
370         }
371         ProcessInfo info;
372         std::string filename = "/proc/" + name + "/stat";
373         if (!GetProcessInfo(filename, info)) {
374             LOGE("failed to get process info, pid is %{public}s.", name.c_str());
375             continue;
376         }
377         if (IsStringExist(excludeProcess, info.name)) {
378             continue;
379         }
380         std::string pidPath = "/proc/" + name;
381         LOGD("check pid using start, pid is %{public}d, processName is %{public}s.", info.pid, info.name.c_str());
382         if (PidUsingFlag(pidPath, unMountFailList)) {
383             proInfos.push_back(info);
384         }
385     }
386     LOGE("find process end, total find %{public}d", static_cast<int>(proInfos.size()));
387     return E_OK;
388 }
389 
UmountFailRadar(std::vector<ProcessInfo> & processInfos,int32_t radar)390 void MountManager::UmountFailRadar(std::vector<ProcessInfo> &processInfos, int32_t radar)
391 {
392     if (processInfos.empty()) {
393         return;
394     }
395     std::string info = ProcessToString(processInfos);
396     LOGE("record process, ret = %{public}d, process is %{public}s", radar, info.c_str());
397     StorageService::StorageRadar::GetInstance().RecordKillProcessResult(info, radar);
398 }
399 
PidUsingFlag(std::string & pidPath,std::list<std::string> & mountFailList)400 bool MountManager::PidUsingFlag(std::string &pidPath, std::list<std::string> &mountFailList)
401 {
402     std::string fdPath = pidPath + "/fd";
403     auto fdDir = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(fdPath.c_str()), closedir);
404     if (!fdDir) {
405         LOGE("unable to open %{public}s, err %{public}d", fdPath.c_str(), errno);
406     } else {
407         struct dirent* fdDirent;
408         while ((fdDirent = readdir(fdDir.get())) != nullptr) {
409             if (fdDirent->d_type != DT_LNK) {
410                 continue;
411             }
412             if (CheckSymlink(fdPath + "/" +fdDirent->d_name, mountFailList)) {
413                 return true;
414             }
415         }
416     }
417     if (CheckMaps(pidPath + "/maps", mountFailList)) {
418         return true;
419     }
420     if (CheckSymlink(pidPath + "/cwd", mountFailList)) {
421         return true;
422     }
423     if (CheckSymlink(pidPath + "/root", mountFailList)) {
424         return true;
425     }
426     if (CheckSymlink(pidPath + "/exe", mountFailList)) {
427         return true;
428     }
429     return false;
430 }
431 
GetProcessInfo(const std::string & filename,ProcessInfo & info)432 bool MountManager::GetProcessInfo(const std::string &filename, ProcessInfo &info)
433 {
434     if (filename.empty()) {
435         return false;
436     }
437     std::ifstream inputStream(filename.c_str(), std::ios::in);
438     if (!inputStream.is_open()) {
439         LOGE("unable to open %{public}s, err %{public}d", filename.c_str(), errno);
440         return false;
441     }
442     std::string line;
443     std::getline(inputStream, line);
444     if (line.empty()) {
445         LOGE("line is empty");
446         inputStream.close();
447         return false;
448     }
449     std::stringstream ss(line);
450     std::string pid;
451     ss >> pid;
452     std::string processName;
453     ss >> processName;
454     info.pid = std::stoi(pid);
455     info.name = processName;
456     inputStream.close();
457     return true;
458 }
459 
CheckMaps(const std::string & path,std::list<std::string> & mountFailList)460 bool MountManager::CheckMaps(const std::string &path, std::list<std::string> &mountFailList)
461 {
462     if (path.empty()) {
463         return false;
464     }
465     std::ifstream inputStream(path.c_str(), std::ios::in);
466     if (!inputStream.is_open()) {
467         LOGE("unable to open %{public}s, err %{public}d", path.c_str(), errno);
468         return false;
469     }
470     std::string tmpLine;
471     while (std::getline(inputStream, tmpLine)) {
472         std::string::size_type pos = tmpLine.find('/');
473         if (pos == std::string::npos) {
474             continue;
475         }
476         tmpLine = tmpLine.substr(pos);
477         for (const auto &item: mountFailList) {
478             if (tmpLine.find(item) == 0) {
479                 LOGE("find a fd from maps, %{public}s", tmpLine.c_str());
480                 inputStream.close();
481                 return true;
482             }
483         }
484     }
485     inputStream.close();
486     return false;
487 }
488 
CheckSymlink(const std::string & path,std::list<std::string> & mountFailList)489 bool MountManager::CheckSymlink(const std::string &path, std::list<std::string> &mountFailList)
490 {
491     if (path.empty()) {
492         return false;
493     }
494     char realPath[ONE_KB];
495     int res = readlink(path.c_str(), realPath, sizeof(realPath) - 1);
496     if (res < 0 || res >= ONE_KB) {
497         return false;
498     }
499     realPath[res] = '\0';
500     std::string realPathStr(realPath);
501     for (const auto &item: mountFailList) {
502         if (realPathStr.find(item) == 0) {
503             LOGE("find a fd from link, %{public}s", realPathStr.c_str());
504             return true;
505         }
506     }
507     return false;
508 }
509 
CloudMount(int32_t userId,const string & path)510 int32_t MountManager::CloudMount(int32_t userId, const string& path)
511 {
512     LOGI("cloud mount start");
513 #ifdef DFS_SERVICE
514     int fd = -1;
515     string opt;
516     int ret;
517     if (!cloudReady_) {
518         LOGI("Cloud Service has not started");
519         return E_MOUNT;
520     }
521 
522     fd = open("/dev/fuse", O_RDWR);
523     if (fd < 0) {
524         LOGE("open /dev/fuse fail");
525         return E_MOUNT;
526     }
527     LOGI("open fuse end");
528     opt = StringPrintf("fd=%i,"
529         "rootmode=40000,"
530         "default_permissions,"
531         "allow_other,"
532         "user_id=0,group_id=0,"
533         "context=\"u:object_r:hmdfs:s0\","
534         "fscontext=u:object_r:hmdfs:s0",
535         fd);
536     LOGI("start to mount fuse");
537     ret = Mount("/dev/fuse", path.c_str(), "fuse", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opt.c_str());
538     if (ret) {
539         LOGE("failed to mount fuse, err %{public}d %{public}d %{public}s", errno, ret, path.c_str());
540         close(fd);
541         return ret;
542     }
543     LOGI("start cloud daemon fuse");
544     ret = CloudDaemonManager::GetInstance().StartFuse(userId, fd, path);
545     if (ret) {
546         LOGE("failed to connect fuse, err %{public}d %{public}d %{public}s", errno, ret, path.c_str());
547         UMount(path.c_str());
548     }
549     LOGI("mount %{public}s success", path.c_str());
550     close(fd);
551     return ret;
552 #else
553     return E_OK;
554 #endif
555 }
556 
CloudTwiceMount(int32_t userId)557 int32_t MountManager::CloudTwiceMount(int32_t userId)
558 {
559     LOGI("mount cloud twice start");
560     int32_t ret = E_OK;
561 #ifdef DFS_SERVICE
562     Utils::MountArgument cloudMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, ""));
563     string cloudPath = cloudMntArgs.GetFullCloud();
564     string cloudMediaPath = cloudMntArgs.GetFullMediaCloud();
565     int32_t mountRet = E_OK;
566     if (IsPathMounted(cloudPath)) {
567         LOGI("path has mounted, %{public}s", cloudPath.c_str());
568     } else {
569         mountRet = CloudMount(userId, cloudPath);
570         if (mountRet != E_OK) {
571             ret = mountRet;
572         }
573     }
574     if (IsPathMounted(cloudMediaPath)) {
575         LOGI("path has mounted, %{public}s", cloudMediaPath.c_str());
576     } else {
577         mountRet = CloudMount(userId, cloudMediaPath);
578         if (mountRet != E_OK) {
579             ret = mountRet;
580         }
581     }
582     return ret;
583 #else
584     return ret;
585 #endif
586 }
587 
HmdfsMount(int32_t userId)588 int32_t MountManager::HmdfsMount(int32_t userId)
589 {
590     int32_t err = PrepareHmdfsDirs(userId);
591     if (err != E_OK) {
592         LOGE("Prepare fileManager dir error");
593     }
594 
595     int32_t ret = HmdfsTwiceMount(userId, "account");
596 
597     ret += HmdfsMount(userId, "non_account");
598     if (ret != E_OK) {
599         return E_MOUNT;
600     }
601 
602     LOGI("ready to mount cloud");
603     mountMutex_.lock();
604     ret = CloudTwiceMount(userId);
605     if (ret == E_OK) {
606         fuseMountedUsers_.push_back(userId);
607     } else {
608         fuseToMountUsers_.push_back(userId);
609     }
610     mountMutex_.unlock();
611 
612     ret = HmdfsMount(userId, "cloud", true);
613     if (ret != E_OK) {
614         LOGE("mount cloud to hmdfs failed!");
615     }
616 
617     return E_OK;
618 }
619 
ParseSandboxPath(string & path,const string & userId,const string & bundleName)620 static void ParseSandboxPath(string &path, const string &userId, const string &bundleName)
621 {
622     size_t pos = path.find(CURRENT_USER_ID_FLAG);
623     if (pos != string::npos) {
624         path = path.replace(pos, CURRENT_USER_ID_FLAG.length(), userId);
625     }
626 
627     pos = path.find(PACKAGE_NAME_FLAG);
628     if (pos != string::npos) {
629         path = path.replace(pos, PACKAGE_NAME_FLAG.length(), bundleName);
630     }
631 }
632 
CheckPathValid(const std::string & bundleNameStr,uint32_t userId)633 bool MountManager::CheckPathValid(const std::string &bundleNameStr, uint32_t userId)
634 {
635     string completePath =
636         SANDBOX_ROOT_PATH + to_string(userId) + "/" + bundleNameStr + EL2_BASE;
637     if (!IsDir(completePath)) {
638         LOGE("Invalid directory path: %{public}s", completePath.c_str());
639         return false;
640     }
641 
642     if (!std::filesystem::is_empty(completePath)) {
643         LOGE("The directory has been mounted, path is %{public}s", completePath.c_str());
644         return false;
645     }
646     return true;
647 }
648 
MountCryptoPathAgain(uint32_t userId)649 int32_t MountManager::MountCryptoPathAgain(uint32_t userId)
650 {
651     filesystem::path rootDir(SANDBOX_ROOT_PATH + to_string(userId));
652     std::error_code errCode;
653     if (!exists(rootDir, errCode)) {
654         LOGE("root path not exists, rootDir is %{public}s", SANDBOX_ROOT_PATH.c_str());
655         return -ENOENT;
656     }
657 
658     int32_t ret = 0;
659     filesystem::directory_iterator bundleNameList(rootDir);
660     for (const auto &bundleName : bundleNameList) {
661         if (SANDBOX_EXCLUDE_PATH.find(bundleName.path().filename()) != SANDBOX_EXCLUDE_PATH.end()) {
662             continue;
663         }
664         std::string bundleNameStr = bundleName.path().filename().generic_string();
665         std::string::size_type point = bundleNameStr.find(MOUNT_SUFFIX);
666         if (point == std::string::npos) {
667             continue;
668         }
669         bundleNameStr = bundleNameStr.substr(0, point);
670         if (!CheckPathValid(bundleNameStr, userId)) {
671             continue;
672         }
673         vector<string> dstPaths = CRYPTO_SANDBOX_PATH;
674         vector<string> srcPaths = CRYPTO_SRC_PATH;
675         MountSandboxPath(srcPaths, dstPaths, bundleNameStr, to_string(userId));
676     }
677     LOGI("mount crypto path success, userId is %{public}d", userId);
678     return ret;
679 }
680 
MountSandboxPath(const std::vector<std::string> & srcPaths,const std::vector<std::string> & dstPaths,const std::string & bundleName,const std::string & userId)681 void MountManager::MountSandboxPath(const std::vector<std::string> &srcPaths, const std::vector<std::string> &dstPaths,
682     const std::string &bundleName, const std::string &userId)
683 {
684     int srcCnt = static_cast<int>(srcPaths.size());
685     int dstCnt = static_cast<int>(dstPaths.size());
686     if (srcCnt == 0 || dstCnt == 0 || srcCnt != dstCnt) {
687         LOGE("invalid params, srcPaths total %{public}d, dstPaths total %{public}d", srcCnt, dstCnt);
688         return;
689     }
690     for (int i = 0; i < dstCnt; i++) {
691         std::string dstPath = SANDBOX_ROOT_PATH;
692         dstPath = dstPath.append(userId).append("/").append(bundleName).append(dstPaths[i]);
693         string srcPath = srcPaths[i];
694         ParseSandboxPath(srcPath, userId, bundleName);
695         if (!IsDir(dstPath)) {
696             LOGE("dstPath is not a dir: %{public}s", dstPath.c_str());
697             continue;
698         }
699         if (!IsDir(srcPath)) {
700             LOGE("srcPath is not a dir: %{public}s", srcPath.c_str());
701             continue;
702         }
703         LOGD("mount crypto path, srcPath is %{public}s, dstPath is %{public}s", srcPath.c_str(), dstPath.c_str());
704         int32_t ret = mount(srcPath.c_str(), dstPath.c_str(), nullptr, MS_BIND | MS_REC, nullptr);
705         if (ret != E_OK && errno == EBUSY) {
706             ret = mount(srcPath.c_str(), dstPath.c_str(), nullptr, MS_BIND | MS_REC, nullptr);
707             LOGI("mount again dstPath is %{public}s, ret is %{public}d.", dstPath.c_str(), ret);
708         }
709         if (ret != 0) {
710             LOGE("mount bind failed, srcPath is %{public}s dstPath is %{public}s errno is %{public}d",
711                  srcPath.c_str(), dstPath.c_str(), errno);
712             continue;
713         }
714         LOGI("bind mount path, srcPath is %{public}s, dstPath is %{public}s", srcPath.c_str(), dstPath.c_str());
715         ret = mount(nullptr, dstPath.c_str(), nullptr, MS_SHARED, nullptr);
716         if (ret != 0) {
717             LOGE("mount to share failed, srcPath is %{public}s dstPath is %{public}s errno is %{public}d",
718                  srcPath.c_str(), dstPath.c_str(), errno);
719             continue;
720         }
721         LOGI("shared mount success, dstPath is %{public}s", dstPath.c_str());
722     }
723 }
724 
MountPointToList(std::list<std::string> & hmdfsList,std::list<std::string> & hmfsList,std::list<std::string> & sharefsList,std::string & line,int32_t userId)725 void MountManager::MountPointToList(std::list<std::string> &hmdfsList, std::list<std::string> &hmfsList,
726     std::list<std::string> &sharefsList, std::string &line, int32_t userId)
727 {
728     if (line.empty()) {
729         return;
730     }
731     Utils::MountArgument hmdfsMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, ""));
732     const string &hmdfsPrefix = hmdfsMntArgs.GetMountPointPrefix();
733     const string &hmfsPrefix = hmdfsMntArgs.GetSandboxPath();
734     const string &mntUserPrefix = hmdfsMntArgs.GetMntUserPath();
735     const string &sharefsPrefix = hmdfsMntArgs.GetShareSrc();
736     const string &cloudPrefix = hmdfsMntArgs.GetFullCloud();
737     std::stringstream ss(line);
738     std::string src;
739     ss >> src;
740     std::string dst;
741     ss >> dst;
742     std::string type;
743     ss >> type;
744     if (type == MOUNT_POINT_TYPE_HMDFS) {
745         if (src.length() >= hmdfsPrefix.length() && src.substr(0, hmdfsPrefix.length()) == hmdfsPrefix) {
746             hmdfsList.push_front(dst);
747         }
748         if (src.length() >= cloudPrefix.length() && src.substr(0, cloudPrefix.length()) == cloudPrefix) {
749             hmdfsList.push_front(dst);
750         }
751         return;
752     }
753     if (type == MOUNT_POINT_TYPE_HMFS || type == MOUNT_POINT_TYPE_F2FS) {
754         if (dst.length() >= hmfsPrefix.length() && dst.substr(0, hmfsPrefix.length()) == hmfsPrefix) {
755             hmfsList.push_front(dst);
756         }
757         if (dst.length() >= mntUserPrefix.length() && dst.substr(0, mntUserPrefix.length()) == mntUserPrefix) {
758             hmfsList.push_front(dst);
759         }
760         return;
761     }
762     if (type == MOUNT_POINT_TYPE_SHAREFS) {
763         if (src.length() >= sharefsPrefix.length() && src.substr(0, sharefsPrefix.length()) == sharefsPrefix) {
764             sharefsList.push_front(dst);
765         }
766         if (src.length() >= mntUserPrefix.length() && src.substr(0, mntUserPrefix.length()) == mntUserPrefix) {
767             sharefsList.push_front(dst);
768         }
769         return;
770     }
771 }
772 
FindMountPointsToMap(std::map<std::string,std::list<std::string>> & mountMap,int32_t userId)773 int32_t MountManager::FindMountPointsToMap(std::map<std::string, std::list<std::string>> &mountMap, int32_t userId)
774 {
775     std::ifstream inputStream(MOUNT_POINT_INFO.c_str(), std::ios::in);
776     if (!inputStream.is_open()) {
777         LOGE("unable to open /proc/mounts, errno is %{public}d", errno);
778         return E_UMOUNT_PROC_MOUNTS_OPEN;
779     }
780     std::list<std::string> hmdfsList;
781     std::list<std::string> hmfsList;
782     std::list<std::string> sharefsList;
783     std::string tmpLine;
784     while (std::getline(inputStream, tmpLine)) {
785         MountPointToList(hmdfsList, hmfsList, sharefsList, tmpLine, userId);
786     }
787     inputStream.close();
788     mountMap[MOUNT_POINT_TYPE_HMDFS] = hmdfsList;
789     mountMap[MOUNT_POINT_TYPE_HMFS] = hmfsList;
790     mountMap[MOUNT_POINT_TYPE_SHAREFS] = sharefsList;
791     hmdfsList.clear();
792     hmfsList.clear();
793     sharefsList.clear();
794     return E_OK;
795 }
796 
UMountAllPath(int32_t userId,std::list<std::string> & unMountFailList)797 int32_t MountManager::UMountAllPath(int32_t userId, std::list<std::string> &unMountFailList)
798 {
799     std::map<std::string, std::list<std::string>> mountMap;
800     int32_t res = FindMountPointsToMap(mountMap, userId);
801     if (res != E_OK) {
802         return res;
803     }
804     int32_t result = E_OK;
805     std::list<std::string> list = mountMap[MOUNT_POINT_TYPE_SHAREFS];
806     int total = static_cast<int>(list.size());
807     LOGI("unmount sharefs path start, total %{public}d.", total);
808     res = UMountByList(list, unMountFailList);
809     if (res != E_OK) {
810         LOGE("failed to umount sharefs mount point, res is %{public}d", res);
811         result = E_UMOUNT_SHAREFS;
812     }
813 
814     list = mountMap[MOUNT_POINT_TYPE_HMFS];
815     total = static_cast<int>(list.size());
816     LOGI("unmount hmfs path start, total %{public}d.", total);
817     res = UMountByList(list, unMountFailList);
818     if (res != E_OK) {
819         LOGE("failed to umount hmfs mount point, res is %{public}d", res);
820         result = E_UMOUNT_HMFS;
821     }
822     UmountMntUserTmpfs(userId);
823 
824     list = mountMap[MOUNT_POINT_TYPE_HMDFS];
825     total = static_cast<int>(list.size());
826     LOGI("unmount hmdfs path start, total %{public}d.", total);
827     res = UMountByList(list, unMountFailList);
828     if (res != E_OK) {
829         LOGE("failed to umount hmdfs mount point, res is %{public}d", res);
830         result = E_UMOUNT_HMDFS;
831     }
832     LOGI("UMountAllPath end, res is %{public}d", result);
833     return result;
834 }
835 
UMountByList(std::list<std::string> & list,std::list<std::string> & unMountFailList)836 int32_t MountManager::UMountByList(std::list<std::string> &list, std::list<std::string> &unMountFailList)
837 {
838     if (list.empty()) {
839         return E_OK;
840     }
841     int32_t result = E_OK;
842     for (const std::string &path: list) {
843         LOGD("umount path %{public}s.", path.c_str());
844         int32_t res = UMount(path);
845         if (res != E_OK && errno != ENOENT && errno != EINVAL) {
846             LOGE("failed to unmount path %{public}s, errno %{public}d.", path.c_str(), errno);
847             result = errno;
848             unMountFailList.push_back(path);
849         }
850     }
851     return result;
852 }
853 
UMountByListWithDetach(std::list<std::string> & list)854 int32_t MountManager::UMountByListWithDetach(std::list<std::string> &list)
855 {
856     if (list.empty()) {
857         return E_OK;
858     }
859     int32_t result = E_OK;
860     for (const std::string &path: list) {
861         LOGD("umount path %{public}s.", path.c_str());
862         int32_t res = UMount2(path, MNT_DETACH);
863         if (res != E_OK && errno != ENOENT && errno != EINVAL) {
864             LOGE("failed to unmount path %{public}s, errno %{public}d.", path.c_str(), errno);
865             result = errno;
866         }
867     }
868     return result;
869 }
870 
MountCloudForUsers(void)871 void MountManager::MountCloudForUsers(void)
872 {
873     for (auto it = fuseToMountUsers_.begin(); it != fuseToMountUsers_.end();) {
874         int32_t res = CloudTwiceMount(*it);
875         if (res == E_OK) {
876             fuseMountedUsers_.push_back(*it);
877             it = fuseToMountUsers_.erase(it);
878         } else {
879             it++;
880         }
881     }
882 }
883 
UMountCloudForUsers(void)884 void MountManager::UMountCloudForUsers(void)
885 {
886     for (auto it = fuseMountedUsers_.begin(); it != fuseMountedUsers_.end();) {
887         int32_t res = CloudUMount(*it);
888         if (res == E_OK) {
889             fuseToMountUsers_.push_back(*it);
890             it = fuseMountedUsers_.erase(it);
891         } else {
892             it++;
893         }
894     }
895 }
896 
SetCloudState(bool active)897 void MountManager::SetCloudState(bool active)
898 {
899     LOGI("set cloud state start, active is %{public}d", active);
900     mountMutex_.lock();
901     cloudReady_ = active;
902     if (cloudReady_) {
903         MountCloudForUsers();
904     } else {
905         UMountCloudForUsers();
906     }
907     mountMutex_.unlock();
908     LOGI("set cloud state end");
909 }
910 
CloudUMount(int32_t userId)911 int32_t MountManager::CloudUMount(int32_t userId)
912 {
913 #ifdef DFS_SERVICE
914     int32_t err = E_OK;
915     Utils::MountArgument cloudMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, ""));
916     const string cloudFusePath = cloudMntArgs.GetFullCloud();
917     err = UMount2(cloudFusePath, MNT_DETACH);
918     if (err != E_OK && errno != ENOENT && errno != EINVAL) {
919         LOGE("cloud fuse umount failed, errno is %{public}d.", errno);
920         return E_UMOUNT_CLOUD_FUSE;
921     }
922     const string cloudPath = cloudMntArgs.GetFullMediaCloud();
923     err = UMount2(cloudPath, MNT_DETACH);
924     if (err != E_OK && errno != ENOENT && errno != EINVAL) {
925         LOGE("cloud umount failed, errno %{public}d", errno);
926         return E_UMOUNT_CLOUD;
927     }
928     LOGI("cloud umount success");
929     return E_OK;
930 #else
931     return E_OK;
932 #endif
933 }
934 
SupportHmdfs()935 bool MountManager::SupportHmdfs()
936 {
937     char hmdfsEnable[HMDFS_VAL_LEN + 1] = {"false"};
938     int ret = GetParameter(HMDFS_SYS_CAP.c_str(), "", hmdfsEnable, HMDFS_VAL_LEN);
939     LOGI("GetParameter hmdfsEnable %{public}s, ret %{public}d", hmdfsEnable, ret);
940     if (strncmp(hmdfsEnable, "true", HMDFS_TRUE_LEN) == 0) {
941         return true;
942     }
943     return false;
944 }
945 
LocalMount(int32_t userId)946 int32_t MountManager::LocalMount(int32_t userId)
947 {
948     Utils::MountArgument LocalMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, "account"));
949     if (Mount(LocalMntArgs.GetFullSrc(), LocalMntArgs.GetCommFullPath() + "local/",
950               nullptr, MS_BIND, nullptr)) {
951         LOGE("failed to bind mount, err %{public}d", errno);
952         return E_MOUNT;
953     }
954     if (Mount(LocalMntArgs.GetFullSrc(), LocalMntArgs.GetCloudFullPath(),
955               nullptr, MS_BIND, nullptr)) {
956         LOGE("failed to bind mount, err %{public}d", errno);
957         return E_MOUNT;
958     }
959     return E_OK;
960 }
961 
RmExistDir(const std::string & dirPath)962 static void RmExistDir(const std::string &dirPath)
963 {
964     if (access(dirPath.c_str(), 0) == 0) {
965         if (!RmDirRecurse(dirPath)) {
966             LOGE("Failed to remove dir %{public}s", dirPath.c_str());
967         }
968     }
969 }
970 
ClearRedundantResources(int32_t userId)971 static void ClearRedundantResources(int32_t userId)
972 {
973     std::string sharePath = StringPrintf("/data/service/el2/%d/share", userId);
974     filesystem::path rootDir(sharePath);
975     std::error_code errCode;
976     if (!exists(rootDir, errCode)) {
977         LOGE("Bundles share path not exists, rootDir is %{public}s", sharePath.c_str());
978         return;
979     }
980 
981     filesystem::directory_iterator bundleNameList(rootDir);
982     for (const auto &bundleName : bundleNameList) {
983         RmExistDir(bundleName.path().generic_string() + "/r");
984         RmExistDir(bundleName.path().generic_string() + "/rw");
985     }
986 }
987 
MountByUser(int32_t userId)988 int32_t MountManager::MountByUser(int32_t userId)
989 {
990     bool isCeEncrypt = false;
991     int ret = KeyManager::GetInstance()->GetFileEncryptStatus(userId, isCeEncrypt);
992     if (ret != E_OK || isCeEncrypt) {
993         LOGE("User %{public}d de has not decrypt.", userId);
994         return E_KEY_NOT_ACTIVED;
995     }
996     // The Documnets and Download directories are managed by the File access framework,
997     // and the UID GID is changed to filemanager
998     std::thread thread([userId]() { ClearRedundantResources(userId); });
999     thread.detach();
1000     PrepareFileManagerDir(userId);
1001     if (CreateVirtualDirs(userId) != E_OK) {
1002         LOGE("create hmdfs virtual dir error");
1003         return E_PREPARE_DIR;
1004     }
1005 
1006     if (!SupportHmdfs()) {
1007         ret = LocalMount(userId);
1008     } else {
1009         ret = HmdfsMount(userId);
1010     }
1011 
1012     if (ret != E_OK) {
1013         LOGE("hmdfs mount error");
1014         return ret;
1015     }
1016 
1017     ret = SharefsMount(userId);
1018     if (ret != E_OK) {
1019         LOGE("sharefs mount error");
1020     }
1021     SetFafQuotaProId(userId);
1022     if (CreateSystemServiceDirs(userId) != E_OK) {
1023         LOGE("create system service dir error");
1024         return E_PREPARE_DIR;
1025     }
1026     MountAppdataAndSharefs(userId);
1027     LOGI("MountByUser success, userId is %{public}d.", userId);
1028     return E_OK;
1029 }
1030 
GetFileManagerUid(uid_t uid,int32_t userId)1031 static uid_t GetFileManagerUid(uid_t uid, int32_t userId)
1032 {
1033     return USER_ID_BASE * userId + uid;
1034 }
1035 
PrepareFileManagerDir(int32_t userId)1036 void MountManager::PrepareFileManagerDir(int32_t userId)
1037 {
1038     std::string filesPath = StringPrintf("/data/service/el2/%d/hmdfs/account/files/", userId);
1039     // move file manager dir
1040     MoveFileManagerData(filesPath);
1041     for (const DirInfo &dir : fileManagerDir_) {
1042         uid_t dirUid = GetFileManagerUid(dir.uid, userId);
1043         std::string path = StringPrintf(dir.path.c_str(), userId);
1044         int ret = IsSameGidUid(path, dirUid, dir.gid);
1045         LOGD("prepareDir %{public}s ret %{public}d, dirUid: %{public}d", path.c_str(), ret, dirUid);
1046         // Dir exist and same uid, gid
1047         if (ret == E_OK) {
1048             continue;
1049         }
1050         // system error
1051         if (ret == E_SYS_ERR) {
1052             LOGE("system err %{public}s ", path.c_str());
1053             continue;
1054         }
1055         // Dir exist and different uid, gid
1056         if (ret == E_DIFF_UID_GID) {
1057             ChownRecursion(path, dirUid, OID_FILE_MANAGER);
1058             continue;
1059         }
1060         // Dir not exist
1061         if (ret == E_NON_EXIST && !PrepareDir(path, dir.mode, dirUid, dir.gid)) {
1062             LOGE("failed to prepareDir %{public}s ", path.c_str());
1063         }
1064     }
1065 }
1066 
LocalUMount(int32_t userId)1067 int32_t MountManager::LocalUMount(int32_t userId)
1068 {
1069     int res = E_OK;
1070     Utils::MountArgument LocalMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, "account"));
1071     std::string path = LocalMntArgs.GetCommFullPath() + "local/";
1072     int unMountRes = UMount(path);
1073     if (unMountRes != E_OK && errno != ENOENT && errno != EINVAL) {
1074         LOGE("failed to unmount local, errno %{public}d, path is %{public}s", errno, path.c_str());
1075         res = unMountRes;
1076     }
1077     path = LocalMntArgs.GetCloudFullPath();
1078     unMountRes = UMount(path);
1079     if (unMountRes != E_OK && errno != ENOENT && errno != EINVAL) {
1080         LOGE("failed to unmount local, errno %{public}d, path is %{public}s", errno, path.c_str());
1081         res = unMountRes;
1082     }
1083     return res;
1084 }
1085 
UmountByUser(int32_t userId)1086 int32_t MountManager::UmountByUser(int32_t userId)
1087 {
1088     int32_t res = E_OK;
1089     if (!SupportHmdfs() && LocalUMount(userId) != E_OK) {
1090         res = E_UMOUNT_LOCAL;
1091     } else {
1092         int unMount = UmountFileSystem(userId);
1093         if (unMount != E_OK) {
1094             res = unMount;
1095         }
1096     }
1097 
1098     LOGI("umount cloud mount point start.");
1099     int32_t cloudUMount = CloudUMount(userId);
1100     if (cloudUMount != E_OK) {
1101         res = cloudUMount;
1102     }
1103     FindSaFd(userId);
1104     LOGI("unmount end, res is %{public}d.", res);
1105     return res;
1106 }
1107 
FindSaFd(int32_t userId)1108 int32_t MountManager::FindSaFd(int32_t userId)
1109 {
1110     LOGI("find sa fd start.");
1111     std::list<std::string> list;
1112     for (const std::string &item: FD_PATH) {
1113         std::string temp = item;
1114         ParseSandboxPath(temp, to_string(userId), "");
1115         list.push_back(temp);
1116     }
1117     std::vector<ProcessInfo> proInfos;
1118     std::list<std::string> excludeProcess;
1119     FindProcess(list, proInfos, excludeProcess);
1120     if (!proInfos.empty()) {
1121         UmountFailRadar(proInfos, E_UMOUNT_FIND_FD);
1122     }
1123     LOGI("find sa fd end.");
1124     return E_OK;
1125 }
1126 
UmountFileSystem(int32_t userId)1127 int32_t MountManager::UmountFileSystem(int32_t userId)
1128 {
1129     LOGI("try to force umount all path start.");
1130     std::list<std::string> unMountFailList;
1131     int32_t unMountRes = UMountAllPath(userId, unMountFailList);
1132     if (unMountRes == E_OK || unMountRes == E_UMOUNT_PROC_MOUNTS_OPEN) {
1133         return E_OK;
1134     }
1135     LOGE("force umount failed, try to kill process, res is %{public}d.", unMountRes);
1136     int32_t findAndKill = FindAndKillProcess(userId, unMountFailList, unMountRes);
1137     if (findAndKill == E_UMOUNT_NO_PROCESS_FIND || findAndKill == E_UMOUNT_PROCESS_KILL) {
1138         return UMountByListWithDetach(unMountFailList) == E_OK ? E_OK : E_UMOUNT_DETACH;
1139     }
1140     LOGE("try to force umount again.");
1141     std::list<std::string> tempList;
1142     int32_t unMountAgain = UMountByList(unMountFailList, tempList);
1143     if (unMountAgain == E_OK) {
1144         return E_OK;
1145     }
1146     LOGE("force umount again failed, try to kill process again, res is %{public}d.", unMountAgain);
1147     FindAndKillProcess(userId, unMountFailList, unMountAgain);
1148     LOGE("try to umount by detach.");
1149     return UMountByListWithDetach(unMountFailList) == E_OK ? E_OK : E_UMOUNT_DETACH;
1150 }
1151 
FindAndKillProcess(int32_t userId,std::list<std::string> & unMountFailList,int32_t radar)1152 int32_t MountManager::FindAndKillProcess(int32_t userId, std::list<std::string> &unMountFailList, int32_t radar)
1153 {
1154     std::vector<ProcessInfo> processInfos;
1155     std::list<std::string> excludeProcess = {"(storage_daemon)"};
1156     FindProcess(unMountFailList, processInfos, excludeProcess);
1157     if (processInfos.empty()) {
1158         LOGE("no process find.");
1159         return E_UMOUNT_NO_PROCESS_FIND;
1160     }
1161     UmountFailRadar(processInfos, radar);
1162     std::vector<ProcessInfo> killFailList;
1163     KillProcess(processInfos, killFailList);
1164     if (!killFailList.empty()) {
1165         std::string info = ProcessToString(killFailList);
1166         LOGE("kill process failed, process is %{public}s.", info.c_str());
1167         return E_UMOUNT_PROCESS_KILL;
1168     }
1169     return E_OK;
1170 }
1171 
PrepareHmdfsDirs(int32_t userId)1172 int32_t MountManager::PrepareHmdfsDirs(int32_t userId)
1173 {
1174     for (const DirInfo &dir : hmdfsDirVec_) {
1175         if (!PrepareDir(StringPrintf(dir.path.c_str(), userId), dir.mode, dir.uid, dir.gid)) {
1176             return E_PREPARE_DIR;
1177         }
1178     }
1179     return E_OK;
1180 }
1181 
PrepareFileManagerDirs(int32_t userId)1182 int32_t MountManager::PrepareFileManagerDirs(int32_t userId)
1183 {
1184     for (const DirInfo &dir : fileManagerDir_) {
1185         uid_t dirUid = GetFileManagerUid(dir.uid, userId);
1186         if (!PrepareDir(StringPrintf(dir.path.c_str(), userId), dir.mode, dirUid, dir.gid)) {
1187             return E_PREPARE_DIR;
1188         }
1189     }
1190 
1191     return E_OK;
1192 }
1193 
CreateVirtualDirs(int32_t userId)1194 int32_t MountManager::CreateVirtualDirs(int32_t userId)
1195 {
1196     for (const DirInfo &dir : virtualDir_) {
1197         std::string path = StringPrintf(dir.path.c_str(), userId);
1198         if (CloudDirFlag(path) && IsDir(path)) {
1199             continue;
1200         }
1201         if (!PrepareDir(path, dir.mode, dir.uid, dir.gid)) {
1202             return E_PREPARE_DIR;
1203         }
1204     }
1205 
1206     return E_OK;
1207 }
1208 
MountDfsDocs(int32_t userId,const std::string & relativePath,const std::string & networkId,const std::string & deviceId)1209 int32_t MountManager::MountDfsDocs(int32_t userId, const std::string &relativePath,
1210     const std::string &networkId, const std::string &deviceId)
1211 {
1212     LOGI("MountManager::MountDfsDocs start.");
1213     std::string dstPath = StringPrintf("/mnt/data/%d/hmdfs/%s/", userId, deviceId.c_str());
1214     if (!PrepareDir(dstPath, MODE_0711, OID_FILE_MANAGER, OID_FILE_MANAGER)) {
1215         return E_PREPARE_DIR;
1216     }
1217 
1218     std::regex pathRegex("^[a-zA-Z0-9_/]+$");
1219     if (relativePath.empty() || relativePath.length() > PATH_MAX || !std::regex_match(relativePath, pathRegex)) {
1220         LOGE("[MountDfsDocs]invalid relativePath");
1221         return E_MOUNT;
1222     }
1223 
1224     Utils::MountArgument hmdfsMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, relativePath));
1225     std::string srcPath = hmdfsMntArgs.GetFullDst() + "/device_view/" + networkId + "/files/Docs/";
1226     int32_t ret = Mount(srcPath, dstPath, nullptr, MS_BIND, nullptr);
1227     if (ret != 0 && errno != EEXIST && errno != EBUSY) {
1228         LOGE("MountDfsDocs mount bind failed, srcPath is %{public}s dstPath is %{public}s errno is %{public}d",
1229              srcPath.c_str(), dstPath.c_str(), errno);
1230         return E_MOUNT;
1231     }
1232     return E_OK;
1233 }
1234 
UMountDfsDocs(int32_t userId,const std::string & relativePath,const std::string & networkId,const std::string & deviceId)1235 int32_t MountManager::UMountDfsDocs(int32_t userId, const std::string &relativePath,
1236     const std::string &networkId, const std::string &deviceId)
1237 {
1238     LOGI("MountManager::UMountDfsDocs start.");
1239 
1240     std::regex pathRegex("^[a-zA-Z0-9_/]+$");
1241     if (relativePath.empty() || relativePath.length() > PATH_MAX || !std::regex_match(relativePath, pathRegex)) {
1242         LOGE("[UMountDfsDocs]invalid relativePath");
1243         return E_UMOUNT;
1244     }
1245 
1246     std::string dstPath = StringPrintf("/mnt/data/%d/hmdfs/%s", userId, deviceId.c_str());
1247     sync();
1248     int32_t ret = UMount2(dstPath, MNT_FORCE);
1249     if (ret != E_OK) {
1250         LOGE("UMountDfsDocs unmount bind failed, srcPath is %{public}s errno is %{public}d",
1251              dstPath.c_str(), errno);
1252         return E_UMOUNT;
1253     }
1254     LOGI("MountManager::UMountDfsDocs end.");
1255     if (!filesystem::is_empty(dstPath)) {
1256         LOGE("[UMountDfsDocs] Failed to umount");
1257         return E_UMOUNT;
1258     }
1259     if (!RmDirRecurse(dstPath)) {
1260         LOGE("Failed to remove dir %{public}s", dstPath.c_str());
1261     }
1262     return E_OK;
1263 }
1264 
RestoreconSystemServiceDirs(int32_t userId)1265 int32_t MountManager::RestoreconSystemServiceDirs(int32_t userId)
1266 {
1267     int32_t err = E_OK;
1268 #ifdef USE_LIBRESTORECON
1269     for (const DirInfo &dir : systemServiceDir_) {
1270         std::string path = StringPrintf(dir.path.c_str(), userId);
1271         RestoreconRecurse(path.c_str());
1272         LOGD("systemServiceDir_ RestoreconRecurse path is %{public}s ", path.c_str());
1273     }
1274 #endif
1275     return err;
1276 }
1277 
CreateSystemServiceDirs(int32_t userId)1278 int32_t MountManager::CreateSystemServiceDirs(int32_t userId)
1279 {
1280     int32_t err = E_OK;
1281     for (const DirInfo &dir : systemServiceDir_) {
1282         std::string path = StringPrintf(dir.path.c_str(), userId);
1283         if (!PrepareDir(path, dir.mode, dir.uid, dir.gid)) {
1284             LOGE("failed to prepareDir %{public}s ", path.c_str());
1285             err = E_PREPARE_DIR;
1286         }
1287     }
1288     return err;
1289 }
1290 
DestroySystemServiceDirs(int32_t userId)1291 int32_t MountManager::DestroySystemServiceDirs(int32_t userId)
1292 {
1293     bool err = true;
1294     for (const DirInfo &dir : systemServiceDir_) {
1295         std::string path = StringPrintf(dir.path.c_str(), userId);
1296         err = err && RmDirRecurse(path);
1297     }
1298     return err ? E_OK : E_DESTROY_DIR;
1299 }
1300 
DestroyHmdfsDirs(int32_t userId)1301 int32_t MountManager::DestroyHmdfsDirs(int32_t userId)
1302 {
1303     bool err = true;
1304 
1305     for (const DirInfo &dir : hmdfsDirVec_) {
1306         if (IsEndWith(dir.path.c_str(), "%d")) {
1307             err = err && RmDirRecurse(StringPrintf(dir.path.c_str(), userId));
1308         }
1309     }
1310 
1311     return err ? E_OK : E_DESTROY_DIR;
1312 }
1313 
1314 
DestroyFileManagerDirs(int32_t userId)1315 int32_t MountManager::DestroyFileManagerDirs(int32_t userId)
1316 {
1317     bool err = true;
1318 
1319     for (const DirInfo &dir : fileManagerDir_) {
1320         if (IsEndWith(dir.path.c_str(), "%d")) {
1321             err = err && RmDirRecurse(StringPrintf(dir.path.c_str(), userId));
1322         }
1323     }
1324 
1325     return err ? E_OK : E_DESTROY_DIR;
1326 }
1327 
SetFafQuotaProId(int32_t userId)1328 int32_t MountManager::SetFafQuotaProId(int32_t userId)
1329 {
1330     int32_t prjId = 0;
1331     for (const DirInfo &dir: fileManagerDir_) {
1332         QuotaManager::GetInstance()->SetQuotaPrjId(StringPrintf(dir.path.c_str(), userId), prjId, true);
1333     }
1334     QuotaManager::GetInstance()->SetQuotaPrjId(StringPrintf(SHARE_PATH.c_str(), userId), prjId, true);
1335     return E_OK;
1336 }
1337 
CheckMountFileByUser(int32_t userId)1338 bool MountManager::CheckMountFileByUser(int32_t userId)
1339 {
1340     for (const DirInfo &dir : virtualDir_) {
1341         std::string path = StringPrintf(dir.path.c_str(), userId);
1342         if (CloudDirFlag(path)) {
1343             continue;
1344         }
1345         if (access(path.c_str(), 0) != 0) {
1346             LOGI("VirtualDir : %{public}s is not exists", path.c_str());
1347             return false;
1348         }
1349     }
1350     LOGI("MountFile is exists");
1351     return true;
1352 }
1353 
CloudDirFlag(const std::string & path)1354 bool MountManager::CloudDirFlag(const std::string &path)
1355 {
1356     if (path.empty()) {
1357         return true;
1358     }
1359     std::regex cloudPattern("\\/mnt\\/data.*cloud");
1360     if (std::regex_match(path.c_str(), cloudPattern)) {
1361         return true;
1362     }
1363     std::regex cloudFusePattern("\\/mnt\\/data.*cloud_fuse");
1364     if (std::regex_match(path.c_str(), cloudFusePattern)) {
1365         return true;
1366     }
1367     return false;
1368 }
1369 
SharedMount(const std::string & path)1370 int32_t MountManager::SharedMount(const std::string &path)
1371 {
1372     if (path.empty() || !IsDir(path)) {
1373         LOGE("path invalid, %{public}s", path.c_str());
1374         return E_OK;
1375     }
1376     int32_t ret = mount(path.c_str(), path.c_str(), nullptr, MS_BIND | MS_REC, nullptr);
1377     if (ret != 0) {
1378         LOGE("SharedMount failed, path is %{public}s, errno is %{public}d.", path.c_str(), errno);
1379         return ret;
1380     }
1381     ret = mount(nullptr, path.c_str(), nullptr, MS_SHARED, nullptr);
1382     if (ret != 0) {
1383         LOGE("SharedMount shared failed, path is %{public}s, errno is %{public}d.", path.c_str(), errno);
1384         return ret;
1385     }
1386     return E_OK;
1387 }
1388 
BindAndRecMount(std::string & srcPath,std::string & dstPath,bool isUseSlave)1389 int32_t MountManager::BindAndRecMount(std::string &srcPath, std::string &dstPath, bool isUseSlave)
1390 {
1391     if (srcPath.empty() || !IsDir(srcPath)) {
1392         LOGE("path invalid, %{public}s", srcPath.c_str());
1393         return E_OK;
1394     }
1395     if (dstPath.empty() || !IsDir(dstPath)) {
1396         LOGE("path invalid, %{public}s", dstPath.c_str());
1397         return E_OK;
1398     }
1399     if (IsPathMounted(dstPath)) {
1400         LOGE("path has mounted, %{public}s", dstPath.c_str());
1401         return E_OK;
1402     }
1403     int32_t ret = mount(srcPath.c_str(), dstPath.c_str(), nullptr, MS_BIND | MS_REC, nullptr);
1404     if (ret != 0) {
1405         LOGE("bind and rec mount failed, srcPath is %{public}s, dstPath is %{public}s, errno is %{public}d.",
1406              srcPath.c_str(), dstPath.c_str(), errno);
1407         return ret;
1408     }
1409     if (isUseSlave) {
1410         ret = mount(nullptr, dstPath.c_str(), nullptr, MS_SLAVE, nullptr);
1411         if (ret != 0) {
1412             LOGE("mount to slave failed, path is %{public}s, errno is %{public}d.", dstPath.c_str(), errno);
1413             return ret;
1414         }
1415     }
1416     return E_OK;
1417 }
1418 
GetAllUserId(std::vector<int32_t> & userIds)1419 void MountManager::GetAllUserId(std::vector<int32_t> &userIds)
1420 {
1421     const std::string &path = APP_EL1_PATH;
1422     if (!DirExist(path)) {
1423         return;
1424     }
1425     for (const auto &entry : filesystem::directory_iterator(path)) {
1426         if (!entry.is_directory()) {
1427             continue;
1428         }
1429         std::string subPath = entry.path().filename().string();
1430         if (!StringIsNumber(subPath)) {
1431             continue;
1432         }
1433         int32_t userId = stoi(subPath);
1434         if (userId < DEFAULT_USERID) {
1435             continue;
1436         }
1437         userIds.push_back(userId);
1438     }
1439 }
1440 
DirExist(const std::string & dir)1441 bool MountManager::DirExist(const std::string &dir)
1442 {
1443     filesystem::path filePath(dir);
1444     std::error_code errCode;
1445     if (!exists(filePath, errCode)) {
1446         LOGE("dir not exists, %{public}s", dir.c_str());
1447         return false;
1448     }
1449     return true;
1450 }
1451 
MountAppdata(const std::string & userId)1452 int32_t MountManager::MountAppdata(const std::string &userId)
1453 {
1454     std::vector<std::string> appdataSrc = APPDATA_SRC_PATH;
1455     std::vector<std::string> appdataDst = APPDATA_DST_PATH;
1456     int count = static_cast<int>(appdataSrc.size());
1457     for (int i = 0; i < count; i++) {
1458         std::string src = appdataSrc[i];
1459         std::string dst = appdataDst[i];
1460         ParseSandboxPath(src, userId, "");
1461         ParseSandboxPath(dst, userId, "");
1462         BindAndRecMount(src, dst);
1463     }
1464     return E_OK;
1465 }
1466 
MountSharefsAndNoSharefs(int32_t userId)1467 int32_t MountManager::MountSharefsAndNoSharefs(int32_t userId)
1468 {
1469     Utils::MountArgument mountArgument(Utils::MountArgumentDescriptors::Alpha(userId, ""));
1470     std::string path = mountArgument.GetNoSharefsDocPath();
1471     SharedMount(path);
1472     path = mountArgument.GetSharefsDocPath();
1473     SharedMount(path);
1474 
1475     std::string src = APPDATA_SRC_PATH[0];
1476     std::string dst = APPDATA_DST_PATH[0];
1477     ParseSandboxPath(src, to_string(userId), "");
1478     ParseSandboxPath(dst, to_string(userId), "");
1479     BindAndRecMount(src, dst);
1480     return E_OK;
1481 }
1482 
PrepareAppdataDirByUserId(int32_t userId)1483 int32_t MountManager::PrepareAppdataDirByUserId(int32_t userId)
1484 {
1485     for (const DirInfo &dir: appdataDir_) {
1486         if (!PrepareDir(StringPrintf(dir.path.c_str(), userId), dir.mode, dir.uid, dir.gid)) {
1487             return E_PREPARE_DIR;
1488         }
1489     }
1490     MountSharefsAndNoSharefs(userId);
1491     return E_OK;
1492 }
1493 
MountAppdataAndSharefs(int32_t userId)1494 int32_t MountManager::MountAppdataAndSharefs(int32_t userId)
1495 {
1496     LOGI("mount currentUser/other");
1497     Utils::MountArgument mountArgument(Utils::MountArgumentDescriptors::Alpha(userId, ""));
1498     std::string mediaDocPath = mountArgument.GetMediaDocsPath();
1499     std::string curOtherPath = mountArgument.GetCurOtherPath();
1500     BindAndRecMount(mediaDocPath, curOtherPath);
1501 
1502     LOGI("mount currentUser/other/appdata");
1503     std::string noSharefsAppdataPath = mountArgument.GetNoSharefsAppdataPath();
1504     std::string curOtherAppdataPath = mountArgument.GetCurOtherAppdataPath();
1505     if (!IsDir(curOtherAppdataPath)) {
1506         MkDir(curOtherAppdataPath, MODE_0711);
1507     }
1508     std::string curFileMgrAppdataPath = mountArgument.GetCurFileMgrAppdataPath();
1509     if (!IsDir(curFileMgrAppdataPath)) {
1510         MkDir(curFileMgrAppdataPath, MODE_0711);
1511     }
1512     BindAndRecMount(noSharefsAppdataPath, curOtherAppdataPath);
1513 
1514     LOGI("mount currentUser/filemgr");
1515     std::string curFileMgrPath = mountArgument.GetCurFileMgrPath();
1516     BindAndRecMount(mediaDocPath, curFileMgrPath);
1517 
1518     LOGI("mount currentUser/filemgr/appdata");
1519     HmSharefsMount(userId, noSharefsAppdataPath, curFileMgrAppdataPath);
1520 
1521     LOGI("mount sharefs/docs/currentUser");
1522     std::string sharefsDocCurPath = mountArgument.GetSharefsDocCurPath();
1523     BindAndRecMount(curOtherPath, sharefsDocCurPath);
1524 
1525     LOGI("mount nosharefs/docs/currentUser");
1526     std::string noSharefsDocCurPath = mountArgument.GetNoSharefsDocCurPath();
1527     BindAndRecMount(curFileMgrPath, noSharefsDocCurPath);
1528     return E_OK;
1529 }
1530 
PrepareAppdataDir(int32_t userId)1531 int32_t MountManager::PrepareAppdataDir(int32_t userId)
1532 {
1533     if (userId == 0) {
1534         std::vector<int32_t> userIds;
1535         GetAllUserId(userIds);
1536         if (userIds.empty()) {
1537             return E_OK;
1538         }
1539         for (const int32_t &item: userIds) {
1540             PrepareAppdataDirByUserId(item);
1541         }
1542     } else {
1543         PrepareAppdataDirByUserId(userId);
1544     }
1545     return E_OK;
1546 }
1547 
UmountMntUserTmpfs(int32_t userId)1548 int32_t MountManager::UmountMntUserTmpfs(int32_t userId)
1549 {
1550     Utils::MountArgument mountArgument(Utils::MountArgumentDescriptors::Alpha(userId, ""));
1551     std::string path = mountArgument.GetSharefsDocCurPath() + "/appdata";
1552     int32_t res = UMount2(path, MNT_DETACH);
1553     if (res != E_OK && errno != ENOENT && errno != EINVAL) {
1554         LOGE("failed to umount with detach, path %{public}s, errno %{public}d.", path.c_str(), errno);
1555     }
1556     path = mountArgument.GetCurOtherAppdataPath();
1557     res = UMount2(path, MNT_DETACH);
1558     if (res != E_OK && errno != ENOENT && errno != EINVAL) {
1559         LOGE("failed to umount with detach, path %{public}s, errno %{public}d.", path.c_str(), errno);
1560     }
1561     return E_OK;
1562 }
1563 } // namespace StorageDaemon
1564 } // namespace OHOS
1565