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