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