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