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 "utils/storage_radar.h"
30 #include "ipc/istorage_daemon.h"
31 #include "parameter.h"
32 #include "quota/quota_manager.h"
33 #include "storage_service_constant.h"
34 #include "storage_service_errno.h"
35 #include "storage_service_log.h"
36 #include "utils/file_utils.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 UMOUNT_RETRY_TIMES = 3;
55 constexpr int32_t ONE_KB = 1024;
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 SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
62 const string PUBLIC_DIR_SANDBOX_PATH = "/storage/Users/currentUser";
63 const string PUBLIC_DIR_SRC_PATH = "/storage/media/<currentUserId>/local/files/Docs";
64 const string MOUNT_POINT_INFO = "/proc/mounts";
65 const string MOUNT_POINT_TYPE_HMDFS = "hmdfs";
66 const string MOUNT_POINT_TYPE_HMFS = "hmfs";
67 const string MOUNT_POINT_TYPE_SHAREFS = "sharefs";
68 const string EL2_BASE = "/data/storage/el2/base/";
69 const string MOUNT_SUFFIX = "_locked";
70 const set<string> SANDBOX_EXCLUDE_PATH = {
71 "chipset",
72 "system",
73 "com.ohos.render"
74 };
75 const vector<string> CRYPTO_SANDBOX_PATH = {
76 "/data/storage/el2/base/",
77 "/data/storage/el2/database/",
78 "/data/storage/el2/share/",
79 "/data/storage/el2/log/",
80 "/data/storage/el2/distributedfiles/",
81 "/data/storage/el2/cloud/",
82 "/data/storage/el3/base/",
83 "/data/storage/el3/database/",
84 "/data/storage/el4/base/",
85 "/data/storage/el4/database/",
86 "/data/storage/el5/base/",
87 "/data/storage/el5/database/"
88 };
89 const vector<string> CRYPTO_SRC_PATH = {
90 "/data/app/el2/<currentUserId>/base/<bundleName>/",
91 "/data/app/el2/<currentUserId>/database/<bundleName>/",
92 "/mnt/share/<currentUserId>/<bundleName>/",
93 "/data/app/el2/<currentUserId>/log/<bundleName>/",
94 "/mnt/hmdfs/<currentUserId>/account/merge_view/data/<bundleName>/",
95 "/mnt/hmdfs/<currentUserId>/cloud/data/<bundleName>/",
96 "/data/app/el3/<currentUserId>/base/<bundleName>/",
97 "/data/app/el3/<currentUserId>/database/<bundleName>/",
98 "/data/app/el4/<currentUserId>/base/<bundleName>/",
99 "/data/app/el4/<currentUserId>/database/<bundleName>/",
100 "/data/app/el5/<currentUserId>/base/<bundleName>/",
101 "/data/app/el5/<currentUserId>/database/<bundleName>/"
102 };
103 const std::string HMDFS_SYS_CAP = "const.distributed_file_property.enabled";
104 const int32_t HMDFS_VAL_LEN = 6;
105 const int32_t HMDFS_TRUE_LEN = 5;
106 const string SHARE_PATH = "/data/service/el1/public/storage_daemon/share/public";
107 static constexpr int MODE_0711 = 0711;
108 static constexpr int MODE_0771 = 0771;
109 static constexpr int MODE_02771 = 02771;
MountManager()110 MountManager::MountManager()
111 : hmdfsDirVec_{{"/data/service/el2/%d/share", MODE_0711, OID_SYSTEM, OID_SYSTEM},
112 {"/data/service/el2/%d/hmdfs", MODE_0711, OID_DFS, OID_DFS},
113 {"/data/service/el2/%d/hmdfs/account", MODE_0711, OID_SYSTEM, OID_SYSTEM},
114 {"/data/service/el2/%d/hmdfs/account/files", MODE_02771, OID_USER_DATA_RW, OID_USER_DATA_RW},
115 {"/data/service/el2/%d/hmdfs/account/data", MODE_0711, OID_SYSTEM, OID_SYSTEM},
116 {"/data/service/el2/%d/hmdfs/non_account", MODE_0711, OID_SYSTEM, OID_SYSTEM},
117 {"/data/service/el2/%d/hmdfs/non_account/files", MODE_0711, OID_USER_DATA_RW, OID_USER_DATA_RW},
118 {"/data/service/el2/%d/hmdfs/non_account/data", MODE_0711, OID_SYSTEM, OID_SYSTEM},
119 {"/data/service/el2/%d/hmdfs/cloud", MODE_0711, OID_DFS, OID_DFS},
120 {"/data/service/el2/%d/hmdfs/cloud/data", MODE_0711, OID_DFS, OID_DFS},
121 {"/data/service/el2/%d/hmdfs/cache", MODE_0711, OID_DFS, OID_DFS},
122 {"/data/service/el2/%d/hmdfs/cloudfile_manager", MODE_0711, OID_DFS, OID_DFS},
123 {"/data/service/el2/%d/hmdfs/cache/account_cache", MODE_0711, OID_DFS, OID_DFS},
124 {"/data/service/el2/%d/hmdfs/cache/non_account_cache", MODE_0711, OID_DFS, OID_DFS},
125 {"/data/service/el2/%d/hmdfs/cache/cloud_cache", MODE_0711, OID_DFS, OID_DFS},
126 {"/data/service/el2/%d/hmdfs/account/services", MODE_0771, OID_DFS_SHARE, OID_DFS_SHARE}},
127 virtualDir_{{"/storage/media/%d", MODE_0711, OID_USER_DATA_RW, OID_USER_DATA_RW},
128 {"/storage/media/%d/local", MODE_0711, OID_USER_DATA_RW, OID_USER_DATA_RW},
129 {"/storage/cloud", MODE_0711, OID_ROOT, OID_ROOT},
130 {"/storage/cloud/%d", MODE_0711, OID_USER_DATA_RW, OID_USER_DATA_RW},
131 {"/mnt/share/", MODE_0711, OID_ROOT, OID_ROOT},
132 {"/mnt/share/%d/", MODE_0711, OID_ROOT, OID_ROOT},
133 {"/mnt/data/%d/", MODE_0711, OID_ROOT, OID_ROOT},
134 {"/mnt/data/%d/cloud", MODE_0711, OID_ROOT, OID_ROOT},
135 {"/mnt/data/%d/cloud_fuse", MODE_0711, OID_DFS, OID_DFS},
136 {"/mnt/data/%d/hmdfs", MODE_0711, OID_FILE_MANAGER, OID_FILE_MANAGER},
137 {"/mnt/hmdfs/", MODE_0711, OID_ROOT, OID_ROOT},
138 {"/mnt/hmdfs/%d/", MODE_0711, OID_ROOT, OID_ROOT},
139 {"/mnt/hmdfs/%d/cloud", MODE_0711, OID_ROOT, OID_ROOT},
140 {"/mnt/hmdfs/%d/account", MODE_0711, OID_ROOT, OID_ROOT},
141 {"/mnt/hmdfs/%d/non_account", MODE_0711, OID_ROOT, OID_ROOT}},
142 systemServiceDir_{{"/data/service/el2/%d/tee", MODE_0711, OID_TEE, OID_TEE},
143 {"/data/service/el2/%d/deviceauth", MODE_0711, OID_DEVICE_AUTH, OID_DEVICE_AUTH},
144 {"/data/service/el2/%d/hwid_service", MODE_0711, OID_HWID, OID_HWID},
145 {"/data/service/el2/%d/huks_service", MODE_0711, OID_HUKS, OID_HUKS},
146 {"/data/service/el4/%d/huks_service", MODE_0711, OID_HUKS, OID_HUKS},
147 {"/data/service/el2/%d/asset_service", MODE_0711, OID_ASSET, OID_ASSET},
148 {"/data/service/el2/%d/account", MODE_0711, OID_ACCOUNT, OID_ACCOUNT},
149 {"/data/service/el2/%d/parentcontrol", MODE_0711, OID_PARENT_CONTROL, OID_PARENT_CONTROL},
150 {"/data/service/el2/%d/dlp_credential_service", MODE_0711, OID_DLP_CREDENTIAL, OID_DLP_CREDENTIAL},
151 {"/data/service/el2/%d/xpower", MODE_0711, OID_HIVIEW, OID_HIVIEW},
152 {"/data/service/el2/%d/av_session", MODE_0711, OID_AV_SESSION, OID_AV_SESSION}},
153 fileManagerDir_{{"/data/service/el2/%d/hmdfs/account/files/Docs", MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER},
154 {"/data/service/el2/%d/hmdfs/account/files/Docs/Documents",
155 MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER},
156 {"/data/service/el2/%d/hmdfs/account/files/Docs/Download",
157 MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER},
158 {"/data/service/el2/%d/hmdfs/account/files/Docs/Desktop",
159 MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER},
160 {"/data/service/el2/%d/hmdfs/account/files/Docs/.Trash",
161 MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER},
162 {"/data/service/el2/%d/hmdfs/account/files/.Recent", MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER}}
163 {
164 }
165
GetInstance()166 std::shared_ptr<MountManager> MountManager::GetInstance()
167 {
168 static std::once_flag onceFlag;
169 std::call_once(onceFlag, [&]() { instance_ = std::make_shared<MountManager>(); });
170
171 return instance_;
172 }
173
HmdfsTwiceMount(int32_t userId,std::string relativePath)174 int32_t MountManager::HmdfsTwiceMount(int32_t userId, std::string relativePath)
175 {
176 int32_t ret = HmdfsMount(userId, relativePath);
177
178 // bind mount
179 Utils::MountArgument hmdfsMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, relativePath));
180 ret += Mount(hmdfsMntArgs.GetFullDst() + "/device_view/", hmdfsMntArgs.GetCommFullPath(),
181 nullptr, MS_BIND, nullptr);
182 if (ret != 0 && errno != EEXIST && errno != EBUSY) {
183 LOGE("failed to bind mount device_view, err %{public}d", errno);
184 return E_MOUNT;
185 }
186 ret += Mount(hmdfsMntArgs.GetFullDst() + "/cloud_merge_view/", hmdfsMntArgs.GetCloudFullPath(),
187 nullptr, MS_BIND, nullptr);
188 if (ret != 0 && errno != EEXIST && errno != EBUSY) {
189 LOGE("failed to bind mount cloud_merge_view, err %{public}d", errno);
190 return E_MOUNT;
191 }
192
193 if (Mount(hmdfsMntArgs.GetLocalDocsPath(), hmdfsMntArgs.GetCloudDocsPath(),
194 nullptr, MS_BIND, nullptr)) {
195 LOGE("failed to bind mount docs, err %{public}d", errno);
196 }
197 return E_OK;
198 }
199
SharefsMount(int32_t userId)200 int32_t MountManager::SharefsMount(int32_t userId)
201 {
202 Utils::MountArgument sharefsMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, ""));
203 int ret = Mount(sharefsMntArgs.GetShareSrc(), sharefsMntArgs.GetShareDst(), "sharefs",
204 sharefsMntArgs.GetFlags(), sharefsMntArgs.GetUserIdPara().c_str());
205 if (ret != 0 && errno != EEXIST && errno != EBUSY) {
206 LOGE("failed to mount sharefs, err %{public}d", errno);
207 return E_MOUNT;
208 }
209 return E_OK;
210 }
211
HmdfsMount(int32_t userId,std::string relativePath,bool mountCloudDisk)212 int32_t MountManager::HmdfsMount(int32_t userId, std::string relativePath, bool mountCloudDisk)
213 {
214 Utils::MountArgument hmdfsMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, relativePath));
215 std::string mountSrcPath = hmdfsMntArgs.GetFullSrc();
216 if (mountCloudDisk) {
217 hmdfsMntArgs.enableCloudDisk_ = true;
218 hmdfsMntArgs.useCloudDir_ = false;
219 hmdfsMntArgs.enableMergeView_ = false;
220 mountSrcPath = hmdfsMntArgs.GetFullCloud();
221 }
222
223 int ret = Mount(mountSrcPath, hmdfsMntArgs.GetFullDst(), "hmdfs",
224 hmdfsMntArgs.GetFlags(), hmdfsMntArgs.OptionsToString().c_str());
225 if (ret != 0 && errno != EEXIST && errno != EBUSY) {
226 LOGE("failed to mount hmdfs, err %{public}d", errno);
227 return E_MOUNT;
228 }
229
230 ret = chown(hmdfsMntArgs.GetCtrlPath().c_str(), OID_DFS, OID_SYSTEM);
231 if (ret != 0) {
232 LOGE("failed to chown hmdfs sysfs node, err %{public}d", errno);
233 }
234
235 return E_OK;
236 }
237
FindAndKillProcess(int32_t userId,std::list<std::string> & mountFailList)238 int32_t MountManager::FindAndKillProcess(int32_t userId, std::list<std::string> &mountFailList)
239 {
240 if (userId <= 0) {
241 return E_OK;
242 }
243 LOGI("FindAndKillProcess start, userId is %{public}d", userId);
244 auto procDir = std::unique_ptr<DIR, int (*)(DIR*)>(opendir("/proc"), closedir);
245 if (!procDir) {
246 LOGE("failed to open dir proc, err %{public}d", errno);
247 return -errno;
248 }
249 std::vector<ProcessInfo> processInfos;
250 struct dirent *entry;
251 while ((entry = readdir(procDir.get())) != nullptr) {
252 if (entry->d_type != DT_DIR) {
253 continue;
254 }
255 std::string name = entry->d_name;
256 if (!StringIsNumber(name)) {
257 continue;
258 }
259 ProcessInfo info;
260 std::string filename = "/proc/" + name + "/stat";
261 if (!GetProcessInfo(filename, info)) {
262 LOGE("failed to get process info, pid is %{public}s.", name.c_str());
263 continue;
264 }
265 if (info.name == "(storage_daemon)") {
266 continue;
267 }
268 Utils::MountArgument argument(Utils::MountArgumentDescriptors::Alpha(userId, ""));
269 const string &prefix = argument.GetMountPointPrefix();
270 std::string pidPath = "/proc/" + name;
271 if (PidUsingFlag(pidPath, prefix, mountFailList)) {
272 LOGE("find a link pid is %{public}d, processName is %{public}s.", info.pid, info.name.c_str());
273 processInfos.push_back(info);
274 }
275 }
276 LOGI("FindAndKillProcess end, total find %{public}d", static_cast<int>(processInfos.size()));
277 KillProcess(processInfos);
278 UmountFailRadar(processInfos);
279 return E_OK;
280 }
281
UmountFailRadar(std::vector<ProcessInfo> & processInfos)282 void MountManager::UmountFailRadar(std::vector<ProcessInfo> &processInfos)
283 {
284 if (processInfos.empty()) {
285 return;
286 }
287 std::string ss;
288 int32_t ret = E_UMOUNT;
289 for (const auto &item:processInfos) {
290 ss += item.name + ",";
291 }
292 if (StorageService::StorageRadar::GetInstance().RecordKillProcessResult(ss, ret)) {
293 LOGI("StorageRadar record FindAndKillProcess result success, ret = %{public}d, process is %{public}s",
294 ret, ss.c_str());
295 }
296 }
297
PidUsingFlag(std::string & pidPath,const std::string & prefix,std::list<std::string> & mountFailList)298 bool MountManager::PidUsingFlag(std::string &pidPath, const std::string &prefix, std::list<std::string> &mountFailList)
299 {
300 bool found = false;
301 found |= CheckMaps(pidPath + "/maps", prefix, mountFailList);
302 found |= CheckSymlink(pidPath + "/cwd", prefix, mountFailList);
303 found |= CheckSymlink(pidPath + "/root", prefix, mountFailList);
304 found |= CheckSymlink(pidPath + "/exe", prefix, mountFailList);
305
306 std::string fdPath = pidPath + "/fd";
307 auto fdDir = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(fdPath.c_str()), closedir);
308 if (!fdDir) {
309 LOGE("unable to open %{public}s, err %{public}d", fdPath.c_str(), errno);
310 } else {
311 struct dirent* fdDirent;
312 while ((fdDirent = readdir(fdDir.get())) != nullptr) {
313 if (fdDirent->d_type != DT_LNK) {
314 continue;
315 }
316 found |= CheckSymlink(fdPath + "/" +fdDirent->d_name, prefix, mountFailList);
317 }
318 }
319 return found;
320 }
321
KillProcess(std::vector<ProcessInfo> & processInfo)322 void MountManager::KillProcess(std::vector<ProcessInfo> &processInfo)
323 {
324 if (processInfo.empty()) {
325 return;
326 }
327 for (const auto &item: processInfo) {
328 LOGI("KILL PID %{public}d", item.pid);
329 kill(item.pid, SIGKILL);
330 }
331 }
332
GetProcessInfo(const std::string & filename,ProcessInfo & info)333 bool MountManager::GetProcessInfo(const std::string &filename, ProcessInfo &info)
334 {
335 if (filename.empty()) {
336 return false;
337 }
338 LOGE("GetProcessInfo path is %{public}s", filename.c_str());
339 std::ifstream inputStream(filename.c_str(), std::ios::in);
340 if (!inputStream.is_open()) {
341 LOGE("unable to open %{public}s, err %{public}d", filename.c_str(), errno);
342 return false;
343 }
344 std::string line;
345 std::getline(inputStream, line);
346 if (line.empty()) {
347 LOGE("line is empty");
348 inputStream.close();
349 return false;
350 }
351 std::stringstream ss(line);
352 std::string pid;
353 ss >> pid;
354 std::string processName;
355 ss >> processName;
356 info.pid = std::stoi(pid);
357 info.name = processName;
358 LOGE("GetProcessInfo pid is %{public}s and name is %{public}s", pid.c_str(), processName.c_str());
359 inputStream.close();
360 return true;
361 }
362
CheckMaps(const std::string & path,const std::string & prefix,std::list<std::string> & mountFailList)363 bool MountManager::CheckMaps(const std::string &path, const std::string &prefix, std::list<std::string> &mountFailList)
364 {
365 if (path.empty()) {
366 return false;
367 }
368 std::ifstream inputStream(path.c_str(), std::ios::in);
369 if (!inputStream.is_open()) {
370 LOGE("unable to open %{public}s, err %{public}d", path.c_str(), errno);
371 return false;
372 }
373 LOGE("CheckMaps path is %{public}s", path.c_str());
374 std::string tmpLine;
375 while (std::getline(inputStream, tmpLine)) {
376 std::string::size_type pos = tmpLine.find("/");
377 if (pos == std::string::npos) {
378 continue;
379 }
380 tmpLine = tmpLine.substr(pos);
381 if (tmpLine.find(prefix) == 0) {
382 LOGE("find a fd %{public}s", tmpLine.c_str());
383 inputStream.close();
384 return true;
385 }
386 for (const auto &item: mountFailList) {
387 if (tmpLine.find(item) == 0) {
388 LOGE("find a fd %{public}s", tmpLine.c_str());
389 inputStream.close();
390 return true;
391 }
392 }
393 }
394 inputStream.close();
395 return false;
396 }
397
CheckSymlink(const std::string & path,const std::string & prefix,std::list<std::string> & mountFailList)398 bool MountManager::CheckSymlink(const std::string &path,
399 const std::string &prefix, std::list<std::string> &mountFailList)
400 {
401 if (path.empty()) {
402 return false;
403 }
404 char realPath[ONE_KB];
405 int res = readlink(path.c_str(), realPath, sizeof(realPath) - 1);
406 if (res < 0 || res >= ONE_KB) {
407 return false;
408 }
409 realPath[res] = '\0';
410 std::string realPathStr(realPath);
411 if (realPathStr.find(prefix) == 0) {
412 LOGE("find a fd %{public}s", realPathStr.c_str());
413 return true;
414 }
415 for (const auto &item: mountFailList) {
416 if (realPathStr.find(item) == 0) {
417 LOGE("find a fd %{public}s", realPathStr.c_str());
418 return true;
419 }
420 }
421 return false;
422 }
423
CloudMount(int32_t userId,const string & path)424 int32_t MountManager::CloudMount(int32_t userId, const string& path)
425 {
426 LOGI("cloud mount start");
427 #ifdef DFS_SERVICE
428 int fd = -1;
429 string opt;
430 int ret;
431 if (!cloudReady_) {
432 LOGI("Cloud Service has not started");
433 return E_MOUNT;
434 }
435
436 fd = open("/dev/fuse", O_RDWR);
437 if (fd < 0) {
438 LOGE("open /dev/fuse fail");
439 return E_MOUNT;
440 }
441 LOGI("open fuse end");
442 opt = StringPrintf("fd=%i,"
443 "rootmode=40000,"
444 "default_permissions,"
445 "allow_other,"
446 "user_id=0,group_id=0,"
447 "context=\"u:object_r:hmdfs:s0\","
448 "fscontext=u:object_r:hmdfs:s0",
449 fd);
450 LOGI("start to mount fuse");
451 ret = Mount("/dev/fuse", path.c_str(), "fuse", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opt.c_str());
452 if (ret) {
453 LOGE("failed to mount fuse, err %{public}d %{public}d %{public}s", errno, ret, path.c_str());
454 close(fd);
455 return ret;
456 }
457 LOGI("start cloud daemon fuse");
458 ret = CloudDaemonManager::GetInstance().StartFuse(userId, fd, path);
459 if (ret) {
460 LOGE("failed to connect fuse, err %{public}d %{public}d %{public}s", errno, ret, path.c_str());
461 UMount(path.c_str());
462 }
463 LOGI("mount %{public}s success", path.c_str());
464 close(fd);
465 return ret;
466 #else
467 return E_OK;
468 #endif
469 }
470
CloudTwiceMount(int32_t userId)471 int32_t MountManager::CloudTwiceMount(int32_t userId)
472 {
473 LOGI("mount cloud twice start");
474 #ifdef DFS_SERVICE
475 Utils::MountArgument cloudMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, ""));
476 const string cloudPath = cloudMntArgs.GetFullCloud();
477 const string cloudMediaPath = cloudMntArgs.GetFullMediaCloud();
478 return (CloudMount(userId, cloudPath) | CloudMount(userId, cloudMediaPath));
479 #else
480 return E_OK;
481 #endif
482 }
483
HmdfsMount(int32_t userId)484 int32_t MountManager::HmdfsMount(int32_t userId)
485 {
486 int32_t err = PrepareHmdfsDirs(userId);
487 if (err != E_OK) {
488 LOGE("Prepare fileManager dir error");
489 }
490
491 int32_t ret = HmdfsTwiceMount(userId, "account");
492
493 ret += HmdfsMount(userId, "non_account");
494 if (ret != E_OK) {
495 return E_MOUNT;
496 }
497
498 LOGI("ready to mount cloud");
499 mountMutex_.lock();
500 ret = CloudTwiceMount(userId);
501 if (ret == E_OK) {
502 fuseMountedUsers_.push_back(userId);
503 } else {
504 fuseToMountUsers_.push_back(userId);
505 }
506 mountMutex_.unlock();
507
508 ret = HmdfsMount(userId, "cloud", true);
509 if (ret != E_OK) {
510 LOGE("mount cloud to hmdfs failed!");
511 }
512
513 return E_OK;
514 }
515
ParseSandboxPath(string & path,const string & userId,const string & bundleName)516 static void ParseSandboxPath(string &path, const string &userId, const string &bundleName)
517 {
518 size_t pos = path.find(CURRENT_USER_ID_FLAG);
519 if (pos != string::npos) {
520 path = path.replace(pos, CURRENT_USER_ID_FLAG.length(), userId);
521 }
522
523 pos = path.find(PACKAGE_NAME_FLAG);
524 if (pos != string::npos) {
525 path = path.replace(pos, PACKAGE_NAME_FLAG.length(), bundleName);
526 }
527 }
528
CheckPathValid(const std::string & bundleNameStr,uint32_t userId)529 bool MountManager::CheckPathValid(const std::string &bundleNameStr, uint32_t userId)
530 {
531 string completePath =
532 SANDBOX_ROOT_PATH + to_string(userId) + "/" + bundleNameStr + EL2_BASE;
533 if (!IsDir(completePath)) {
534 LOGE("Invalid directory path: %{public}s", completePath.c_str());
535 return false;
536 }
537
538 if (!std::filesystem::is_empty(completePath)) {
539 LOGE("The directory has been mounted, path is %{public}s", completePath.c_str());
540 return false;
541 }
542 return true;
543 }
544
MountCryptoPathAgain(uint32_t userId)545 int32_t MountManager::MountCryptoPathAgain(uint32_t userId)
546 {
547 filesystem::path rootDir(SANDBOX_ROOT_PATH + to_string(userId));
548 std::error_code errCode;
549 if (!exists(rootDir, errCode)) {
550 LOGE("root path not exists, rootDir is %{public}s", SANDBOX_ROOT_PATH.c_str());
551 return -ENOENT;
552 }
553
554 int32_t ret = 0;
555 filesystem::directory_iterator bundleNameList(rootDir);
556 for (const auto &bundleName : bundleNameList) {
557 if (SANDBOX_EXCLUDE_PATH.find(bundleName.path().filename()) != SANDBOX_EXCLUDE_PATH.end()) {
558 continue;
559 }
560 std::string bundleNameStr = bundleName.path().filename().generic_string();
561 std::string::size_type point = bundleNameStr.find(MOUNT_SUFFIX);
562 if (point == std::string::npos) {
563 LOGI("bundleName do not need to mount: %{public}s", bundleNameStr.c_str());
564 continue;
565 }
566 bundleNameStr = bundleNameStr.substr(0, point);
567 if (!CheckPathValid(bundleNameStr, userId)) {
568 continue;
569 }
570 vector<string> dstPaths = CRYPTO_SANDBOX_PATH;
571 vector<string> srcPaths = CRYPTO_SRC_PATH;
572 if (bundleNameStr == SCENE_BOARD_BUNDLE_NAME) {
573 dstPaths.push_back(PUBLIC_DIR_SANDBOX_PATH);
574 srcPaths.push_back(PUBLIC_DIR_SRC_PATH);
575 }
576 MountSandboxPath(srcPaths, dstPaths, bundleNameStr, to_string(userId));
577 }
578 LOGI("mount crypto path success, userId is %{public}d", userId);
579 return ret;
580 }
581
MountSandboxPath(const std::vector<std::string> & srcPaths,const std::vector<std::string> & dstPaths,const std::string & bundleName,const std::string & userId)582 void MountManager::MountSandboxPath(const std::vector<std::string> &srcPaths, const std::vector<std::string> &dstPaths,
583 const std::string &bundleName, const std::string &userId)
584 {
585 int srcCnt = static_cast<int>(srcPaths.size());
586 int dstCnt = static_cast<int>(dstPaths.size());
587 if (srcCnt == 0 || dstCnt == 0 || srcCnt != dstCnt) {
588 LOGE("invalid params, srcPaths total %{public}d, dstPaths total %{public}d", srcCnt, dstCnt);
589 return;
590 }
591 for (int i = 0; i < dstCnt; i++) {
592 std::string dstPath = SANDBOX_ROOT_PATH;
593 dstPath = dstPath.append(userId).append("/").append(bundleName).append(dstPaths[i]);
594 string srcPath = srcPaths[i];
595 ParseSandboxPath(srcPath, userId, bundleName);
596 if (!IsDir(dstPath)) {
597 LOGE("dstPath is not a dir: %{public}s", dstPath.c_str());
598 continue;
599 }
600 if (!IsDir(srcPath)) {
601 LOGE("srcPath is not a dir: %{public}s", srcPath.c_str());
602 continue;
603 }
604 LOGD("mount crypto path, srcPath is %{public}s, dstPath is %{public}s", srcPath.c_str(), dstPath.c_str());
605 int32_t ret = mount(srcPath.c_str(), dstPath.c_str(), nullptr, MS_BIND | MS_REC, nullptr);
606 if (ret != E_OK && errno == EBUSY) {
607 ret = mount(srcPath.c_str(), dstPath.c_str(), nullptr, MS_BIND | MS_REC, nullptr);
608 LOGI("mount again dstPath is %{public}s, ret is %{public}d.", dstPath.c_str(), ret);
609 }
610 if (ret != 0) {
611 LOGE("mount bind failed, srcPath is %{public}s dstPath is %{public}s errno is %{public}d",
612 srcPath.c_str(), dstPath.c_str(), errno);
613 continue;
614 }
615 LOGI("bind mount path, srcPath is %{public}s, dstPath is %{public}s", srcPath.c_str(), dstPath.c_str());
616 ret = mount(nullptr, dstPath.c_str(), nullptr, MS_SHARED, nullptr);
617 if (ret != 0) {
618 LOGE("mount to share failed, srcPath is %{public}s dstPath is %{public}s errno is %{public}d",
619 srcPath.c_str(), dstPath.c_str(), errno);
620 continue;
621 }
622 LOGI("shared mount success, dstPath is %{public}s", dstPath.c_str());
623 }
624 }
625
MountPointToList(std::list<std::string> & hmdfsList,std::list<std::string> & hmfsList,std::list<std::string> & sharefsList,std::string & line,int32_t userId)626 void MountManager::MountPointToList(std::list<std::string> &hmdfsList, std::list<std::string> &hmfsList,
627 std::list<std::string> &sharefsList, std::string &line, int32_t userId)
628 {
629 if (line.empty()) {
630 return;
631 }
632 Utils::MountArgument hmdfsMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, ""));
633 const string &hmdfsPrefix = hmdfsMntArgs.GetMountPointPrefix();
634 const string &hmfsPrefix = hmdfsMntArgs.GetSandboxPath();
635 const string &sharefsPrefix = hmdfsMntArgs.GetShareSrc();
636 const string &cloudPrefix = hmdfsMntArgs.GetFullCloud();
637 std::stringstream ss(line);
638 std::string src;
639 ss >> src;
640 std::string dst;
641 ss >> dst;
642 std::string type;
643 ss >> type;
644 if (type == MOUNT_POINT_TYPE_HMDFS) {
645 if (src.length() >= hmdfsPrefix.length() && src.substr(0, hmdfsPrefix.length()) == hmdfsPrefix) {
646 hmdfsList.push_front(dst);
647 }
648 if (src.length() >= cloudPrefix.length() && src.substr(0, cloudPrefix.length()) == cloudPrefix) {
649 hmdfsList.push_front(dst);
650 }
651 return;
652 }
653 if (type == MOUNT_POINT_TYPE_HMFS) {
654 if (dst.length() >= hmfsPrefix.length() && dst.substr(0, hmfsPrefix.length()) == hmfsPrefix) {
655 hmfsList.push_front(dst);
656 }
657 return;
658 }
659 if (type == MOUNT_POINT_TYPE_SHAREFS) {
660 if (src.length() >= sharefsPrefix.length() &&
661 src.substr(0, sharefsPrefix.length()) == sharefsPrefix) {
662 sharefsList.push_front(dst);
663 }
664 return;
665 }
666 }
667
FindMountPointsToMap(std::map<std::string,std::list<std::string>> & mountMap,int32_t userId)668 int32_t MountManager::FindMountPointsToMap(std::map<std::string, std::list<std::string>> &mountMap, int32_t userId)
669 {
670 std::ifstream inputStream(MOUNT_POINT_INFO.c_str(), std::ios::in);
671 if (!inputStream.is_open()) {
672 LOGE("unable to open /proc/mounts, errno is %{public}d", errno);
673 return -errno;
674 }
675 std::list<std::string> hmdfsList;
676 std::list<std::string> hmfsList;
677 std::list<std::string> sharefsList;
678 std::string tmpLine;
679 while (std::getline(inputStream, tmpLine)) {
680 MountPointToList(hmdfsList, hmfsList, sharefsList, tmpLine, userId);
681 }
682 inputStream.close();
683 mountMap[MOUNT_POINT_TYPE_HMDFS] = hmdfsList;
684 mountMap[MOUNT_POINT_TYPE_HMFS] = hmfsList;
685 mountMap[MOUNT_POINT_TYPE_SHAREFS] = sharefsList;
686 hmdfsList.clear();
687 hmfsList.clear();
688 sharefsList.clear();
689 return E_OK;
690 }
691
UMountAllPath(int32_t userId,std::list<std::string> & mountFailList)692 int32_t MountManager::UMountAllPath(int32_t userId, std::list<std::string> &mountFailList)
693 {
694 std::map<std::string, std::list<std::string>> mountMap;
695 int32_t res = FindMountPointsToMap(mountMap, userId);
696 if (res != E_OK) {
697 return res;
698 }
699 int32_t result = 0;
700 std::list<std::string> list = mountMap[MOUNT_POINT_TYPE_SHAREFS];
701 int total = static_cast<int>(list.size());
702 LOGI("unmount sharefs path start, total %{public}d.", total);
703 res = UMountByList(list, mountFailList);
704 if (res != E_OK) {
705 result = res;
706 }
707
708 list = mountMap[MOUNT_POINT_TYPE_HMDFS];
709 total = static_cast<int>(list.size());
710 LOGI("unmount hmdfs path start, total %{public}d.", total);
711 res = UMountByList(list, mountFailList);
712 if (res != E_OK) {
713 result = res;
714 }
715 LOGI("result is %{public}d.", result);
716 list = mountMap[MOUNT_POINT_TYPE_HMFS];
717 total = static_cast<int>(list.size());
718 LOGI("unmount hmfs path start, total %{public}d.", total);
719 res = UMountByList(list, mountFailList);
720 if (res != E_OK) {
721 result = res;
722 }
723 if (result != E_OK) {
724 for (const auto &item: mountFailList) {
725 res = UMount2(item.c_str(), MNT_DETACH);
726 if (res != E_OK) {
727 LOGE("failed to unmount with detach, path %{public}s, errno %{public}d.", item.c_str(), errno);
728 }
729 }
730 return result;
731 }
732 LOGI("UMountAllPath success");
733 return E_OK;
734 }
735
UMountByList(std::list<std::string> & list,std::list<std::string> & mountFailList)736 int32_t MountManager::UMountByList(std::list<std::string> &list, std::list<std::string> &mountFailList)
737 {
738 if (list.empty()) {
739 return E_OK;
740 }
741 int32_t result = E_OK;
742 for (const std::string &path: list) {
743 LOGD("umount path %{public}s.", path.c_str());
744 int32_t res = UMount(path);
745 if (res != E_OK) {
746 LOGE("failed to unmount path %{public}s, errno %{public}d.", path.c_str(), errno);
747 result = errno;
748 mountFailList.push_back(path);
749 }
750 }
751 LOGI("UMountByList result is %{public}d.", result);
752 return result;
753 }
754
MountCloudForUsers(void)755 void MountManager::MountCloudForUsers(void)
756 {
757 for (auto it = fuseToMountUsers_.begin(); it != fuseToMountUsers_.end();) {
758 int32_t res = CloudTwiceMount(*it);
759 if (res == E_OK) {
760 fuseMountedUsers_.push_back(*it);
761 it = fuseToMountUsers_.erase(it);
762 } else {
763 it++;
764 }
765 }
766 }
767
UMountCloudForUsers(void)768 void MountManager::UMountCloudForUsers(void)
769 {
770 for (auto it = fuseMountedUsers_.begin(); it != fuseMountedUsers_.end();) {
771 int32_t res = CloudUMount(*it);
772 if (res == E_OK) {
773 fuseToMountUsers_.push_back(*it);
774 it = fuseMountedUsers_.erase(it);
775 } else {
776 it++;
777 }
778 }
779 }
780
SetCloudState(bool active)781 void MountManager::SetCloudState(bool active)
782 {
783 LOGI("set cloud state start, active is %{public}d", active);
784 mountMutex_.lock();
785 cloudReady_ = active;
786 if (cloudReady_) {
787 MountCloudForUsers();
788 } else {
789 UMountCloudForUsers();
790 }
791 mountMutex_.unlock();
792 LOGI("set cloud state end");
793 }
794
HmdfsUMount(int32_t userId,std::string relativePath)795 int32_t MountManager::HmdfsUMount(int32_t userId, std::string relativePath)
796 {
797 Utils::MountArgument hmdfsAuthMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, relativePath));
798 int32_t ret = UMount2(hmdfsAuthMntArgs.GetFullDst().c_str(), MNT_DETACH);
799 if (ret != E_OK) {
800 LOGE("umount auth hmdfs, errno %{public}d, auth hmdfs dst %{public}s", errno,
801 hmdfsAuthMntArgs.GetFullDst().c_str());
802 return E_UMOUNT;
803 }
804 return E_OK;
805 }
806
CloudUMount(int32_t userId)807 int32_t MountManager::CloudUMount(int32_t userId)
808 {
809 #ifdef DFS_SERVICE
810 int32_t err = E_OK;
811 Utils::MountArgument cloudMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, ""));
812 const string path = cloudMntArgs.GetFullCloud();
813 const string mediaCloudPath = cloudMntArgs.GetFullMediaCloud();
814
815 HmdfsUMount(userId, "cloud");
816
817 err = UMount2(path, MNT_DETACH);
818 if (err != E_OK) {
819 LOGE("fuse umount2 failed, errno %{public}d, fuse dst %{public}s", errno, path.c_str());
820 return E_UMOUNT;
821 }
822
823 err = UMount2(mediaCloudPath, MNT_DETACH);
824 if (err != E_OK) {
825 LOGE("fuse umount2 failed, errno %{public}d, fuse dst %{public}s", errno, mediaCloudPath.c_str());
826 return E_UMOUNT;
827 }
828 LOGI("umount2 media cloud path:%{public}s cloud path:%{public}s success", mediaCloudPath.c_str(), path.c_str());
829 return E_OK;
830 #else
831 return E_OK;
832 #endif
833 }
834
SupportHmdfs()835 bool MountManager::SupportHmdfs()
836 {
837 char hmdfsEnable[HMDFS_VAL_LEN + 1] = {"false"};
838 int ret = GetParameter(HMDFS_SYS_CAP.c_str(), "", hmdfsEnable, HMDFS_VAL_LEN);
839 LOGI("GetParameter hmdfsEnable %{public}s, ret %{public}d", hmdfsEnable, ret);
840 if (strncmp(hmdfsEnable, "true", HMDFS_TRUE_LEN) == 0) {
841 return true;
842 }
843 return false;
844 }
845
LocalMount(int32_t userId)846 int32_t MountManager::LocalMount(int32_t userId)
847 {
848 Utils::MountArgument LocalMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, "account"));
849 if (Mount(LocalMntArgs.GetFullSrc(), LocalMntArgs.GetCommFullPath() + "local/",
850 nullptr, MS_BIND, nullptr)) {
851 LOGE("failed to bind mount, err %{public}d", errno);
852 return E_MOUNT;
853 }
854 if (Mount(LocalMntArgs.GetFullSrc(), LocalMntArgs.GetCloudFullPath(),
855 nullptr, MS_BIND, nullptr)) {
856 LOGE("failed to bind mount, err %{public}d", errno);
857 return E_MOUNT;
858 }
859 return E_OK;
860 }
861
RmExistDir(const std::string & dirPath)862 static void RmExistDir(const std::string &dirPath)
863 {
864 if (access(dirPath.c_str(), 0) == 0) {
865 if (!RmDirRecurse(dirPath)) {
866 LOGE("Failed to remove dir %{public}s", dirPath.c_str());
867 }
868 }
869 }
870
ClearRedundantResources(int32_t userId)871 static void ClearRedundantResources(int32_t userId)
872 {
873 std::string sharePath = StringPrintf("/data/service/el2/%d/share", userId);
874 filesystem::path rootDir(sharePath);
875 std::error_code errCode;
876 if (!exists(rootDir, errCode)) {
877 LOGE("Bundles share path not exists, rootDir is %{public}s", sharePath.c_str());
878 return;
879 }
880
881 filesystem::directory_iterator bundleNameList(rootDir);
882 for (const auto &bundleName : bundleNameList) {
883 RmExistDir(bundleName.path().generic_string() + "/r");
884 RmExistDir(bundleName.path().generic_string() + "/rw");
885 }
886 }
887
MountByUser(int32_t userId)888 int32_t MountManager::MountByUser(int32_t userId)
889 {
890 int ret = E_OK;
891 // The Documnets and Download directories are managed by the File access framework,
892 // and the UID GID is changed to filemanager
893 std::thread thread([userId]() { ClearRedundantResources(userId); });
894 thread.detach();
895 PrepareFileManagerDir(userId);
896 if (CreateVirtualDirs(userId) != E_OK) {
897 LOGE("create hmdfs virtual dir error");
898 return E_PREPARE_DIR;
899 }
900
901 if (!SupportHmdfs()) {
902 ret = LocalMount(userId);
903 } else {
904 ret = HmdfsMount(userId);
905 }
906
907 if (ret != E_OK) {
908 LOGE("hmdfs mount error");
909 return ret;
910 }
911
912 ret = SharefsMount(userId);
913 if (ret != E_OK) {
914 LOGE("sharefs mount error");
915 }
916 SetFafQuotaProId(userId);
917
918 if (CreateSystemServiceDirs(userId) != E_OK) {
919 LOGE("create system service dir error");
920 return E_PREPARE_DIR;
921 }
922 return E_OK;
923 }
924
GetFileManagerUid(uid_t uid,int32_t userId)925 static uid_t GetFileManagerUid(uid_t uid, int32_t userId)
926 {
927 return USER_ID_BASE * userId + uid;
928 }
929
PrepareFileManagerDir(int32_t userId)930 void MountManager::PrepareFileManagerDir(int32_t userId)
931 {
932 std::string filesPath = StringPrintf("/data/service/el2/%d/hmdfs/account/files/", userId);
933 // move file manager dir
934 MoveFileManagerData(filesPath);
935 for (const DirInfo &dir : fileManagerDir_) {
936 uid_t dirUid = GetFileManagerUid(dir.uid, userId);
937 std::string path = StringPrintf(dir.path.c_str(), userId);
938 int ret = IsSameGidUid(path, dirUid, dir.gid);
939 LOGD("prepareDir %{public}s ret %{public}d, dirUid: %{public}d", path.c_str(), ret, dirUid);
940 // Dir exist and same uid, gid
941 if (ret == E_OK) {
942 continue;
943 }
944 // system error
945 if (ret == E_SYS_ERR) {
946 LOGE("system err %{public}s ", path.c_str());
947 continue;
948 }
949 // Dir exist and different uid, gid
950 if (ret == E_DIFF_UID_GID) {
951 ChownRecursion(path, dirUid, OID_FILE_MANAGER);
952 continue;
953 }
954 // Dir not exist
955 if (ret == E_NON_EXIST && !PrepareDir(path, dir.mode, dirUid, dir.gid)) {
956 LOGE("failed to prepareDir %{public}s ", path.c_str());
957 }
958 }
959 }
960
LocalUMount(int32_t userId)961 int32_t MountManager::LocalUMount(int32_t userId)
962 {
963 Utils::MountArgument LocalMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, "account"));
964 int err = UMount(LocalMntArgs.GetCommFullPath() + "local/");
965 if (err != E_OK) {
966 LOGE("failed to un bind mount, errno %{public}d, ComDataDir dst %{public}s", errno,
967 LocalMntArgs.GetCommFullPath().c_str());
968 }
969 err = UMount(LocalMntArgs.GetCloudFullPath());
970 if (err != E_OK) {
971 LOGE("failed to un bind mount, errno %{public}d, CloudDataDir dst %{public}s", errno,
972 LocalMntArgs.GetCloudFullPath().c_str());
973 }
974 return err;
975 }
976
UmountByUser(int32_t userId)977 int32_t MountManager::UmountByUser(int32_t userId)
978 {
979 LOGI("umount hmdfs mount point start.");
980 int32_t err = E_OK;
981 if (!SupportHmdfs()) {
982 err = LocalUMount(userId);
983 } else {
984 std::list<std::string> mountFailList;
985 err = UMountAllPath(userId, mountFailList);
986 if (err != E_OK) {
987 LOGE("failed to umount hmdfs mount point, err is %{public}d", err);
988 FindAndKillProcess(userId, mountFailList);
989 }
990 }
991
992 LOGI("umount cloud mount point start.");
993 int32_t count = 0;
994 while (count < UMOUNT_RETRY_TIMES) {
995 err = CloudUMount(userId);
996 if (err == E_OK) {
997 break;
998 } else if (errno == EBUSY) {
999 count++;
1000 continue;
1001 }
1002 LOGE("failed to umount cloud mount point, err %{public}d", err);
1003 return E_UMOUNT;
1004 }
1005 return E_OK;
1006 }
1007
PrepareHmdfsDirs(int32_t userId)1008 int32_t MountManager::PrepareHmdfsDirs(int32_t userId)
1009 {
1010 for (const DirInfo &dir : hmdfsDirVec_) {
1011 if (!PrepareDir(StringPrintf(dir.path.c_str(), userId), dir.mode, dir.uid, dir.gid)) {
1012 return E_PREPARE_DIR;
1013 }
1014 }
1015
1016 return E_OK;
1017 }
1018
PrepareFileManagerDirs(int32_t userId)1019 int32_t MountManager::PrepareFileManagerDirs(int32_t userId)
1020 {
1021 for (const DirInfo &dir : fileManagerDir_) {
1022 uid_t dirUid = GetFileManagerUid(dir.uid, userId);
1023 if (!PrepareDir(StringPrintf(dir.path.c_str(), userId), dir.mode, dirUid, dir.gid)) {
1024 return E_PREPARE_DIR;
1025 }
1026 }
1027
1028 return E_OK;
1029 }
1030
CreateVirtualDirs(int32_t userId)1031 int32_t MountManager::CreateVirtualDirs(int32_t userId)
1032 {
1033 for (const DirInfo &dir : virtualDir_) {
1034 if (!PrepareDir(StringPrintf(dir.path.c_str(), userId), dir.mode, dir.uid, dir.gid)) {
1035 return E_PREPARE_DIR;
1036 }
1037 }
1038
1039 return E_OK;
1040 }
1041
MountDfsDocs(int32_t userId,const std::string & relativePath,const std::string & networkId,const std::string & deviceId)1042 int32_t MountManager::MountDfsDocs(int32_t userId, const std::string &relativePath,
1043 const std::string &networkId, const std::string &deviceId)
1044 {
1045 LOGI("MountManager::MountDfsDocs start.");
1046 std::string dstPath = StringPrintf("/mnt/data/%d/hmdfs/%s/", userId, deviceId.c_str());
1047 if (!PrepareDir(dstPath, MODE_0711, OID_FILE_MANAGER, OID_FILE_MANAGER)) {
1048 return E_PREPARE_DIR;
1049 }
1050
1051 std::regex pathRegex("^[a-zA-Z0-9_/]+$");
1052 if (relativePath.empty() || relativePath.length() > PATH_MAX || !std::regex_match(relativePath, pathRegex)) {
1053 LOGE("[MountDfsDocs]invalid relativePath");
1054 return E_MOUNT;
1055 }
1056
1057 Utils::MountArgument hmdfsMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, relativePath));
1058 std::string srcPath = hmdfsMntArgs.GetFullDst() + "/device_view/" + networkId + "/files/Docs/";
1059 int32_t ret = Mount(srcPath, dstPath, nullptr, MS_BIND, nullptr);
1060 if (ret != 0 && errno != EEXIST && errno != EBUSY) {
1061 LOGE("MountDfsDocs mount bind failed, srcPath is %{public}s dstPath is %{public}s errno is %{public}d",
1062 srcPath.c_str(), dstPath.c_str(), errno);
1063 return E_MOUNT;
1064 }
1065 return E_OK;
1066 }
1067
UMountDfsDocs(int32_t userId,const std::string & relativePath,const std::string & networkId,const std::string & deviceId)1068 int32_t MountManager::UMountDfsDocs(int32_t userId, const std::string &relativePath,
1069 const std::string &networkId, const std::string &deviceId)
1070 {
1071 LOGI("MountManager::UMountDfsDocs start.");
1072
1073 std::regex pathRegex("^[a-zA-Z0-9_/]+$");
1074 if (relativePath.empty() || relativePath.length() > PATH_MAX || !std::regex_match(relativePath, pathRegex)) {
1075 LOGE("[UMountDfsDocs]invalid relativePath");
1076 return E_UMOUNT;
1077 }
1078
1079 std::string dstPath = StringPrintf("/mnt/data/%d/hmdfs/%s", userId, deviceId.c_str());
1080 sync();
1081 int32_t ret = UMount2(dstPath, MNT_FORCE);
1082 if (ret != E_OK) {
1083 LOGE("UMountDfsDocs unmount bind failed, srcPath is %{public}s errno is %{public}d",
1084 dstPath.c_str(), errno);
1085 return E_UMOUNT;
1086 }
1087 LOGI("MountManager::UMountDfsDocs end.");
1088 if (!filesystem::is_empty(dstPath)) {
1089 LOGE("[UMountDfsDocs] Failed to umount");
1090 return E_UMOUNT;
1091 }
1092 if (!RmDirRecurse(dstPath)) {
1093 LOGE("Failed to remove dir %{public}s", dstPath.c_str());
1094 }
1095 return E_OK;
1096 }
1097
RestoreconSystemServiceDirs(int32_t userId)1098 int32_t MountManager::RestoreconSystemServiceDirs(int32_t userId)
1099 {
1100 int32_t err = E_OK;
1101 #ifdef USE_LIBRESTORECON
1102 for (const DirInfo &dir : systemServiceDir_) {
1103 std::string path = StringPrintf(dir.path.c_str(), userId);
1104 RestoreconRecurse(path.c_str());
1105 LOGD("systemServiceDir_ RestoreconRecurse path is %{public}s ", path.c_str());
1106 }
1107 #endif
1108 return err;
1109 }
1110
CreateSystemServiceDirs(int32_t userId)1111 int32_t MountManager::CreateSystemServiceDirs(int32_t userId)
1112 {
1113 int32_t err = E_OK;
1114 for (const DirInfo &dir : systemServiceDir_) {
1115 std::string path = StringPrintf(dir.path.c_str(), userId);
1116 if (!PrepareDir(path, dir.mode, dir.uid, dir.gid)) {
1117 LOGE("failed to prepareDir %{public}s ", path.c_str());
1118 err = E_PREPARE_DIR;
1119 }
1120 }
1121 return err;
1122 }
1123
DestroySystemServiceDirs(int32_t userId)1124 int32_t MountManager::DestroySystemServiceDirs(int32_t userId)
1125 {
1126 bool err = true;
1127 for (const DirInfo &dir : systemServiceDir_) {
1128 std::string path = StringPrintf(dir.path.c_str(), userId);
1129 err = err && RmDirRecurse(path);
1130 }
1131 return err ? E_OK : E_DESTROY_DIR;
1132 }
1133
DestroyHmdfsDirs(int32_t userId)1134 int32_t MountManager::DestroyHmdfsDirs(int32_t userId)
1135 {
1136 bool err = true;
1137
1138 for (const DirInfo &dir : hmdfsDirVec_) {
1139 if (IsEndWith(dir.path.c_str(), "%d")) {
1140 err = err && RmDirRecurse(StringPrintf(dir.path.c_str(), userId));
1141 }
1142 }
1143
1144 return err ? E_OK : E_DESTROY_DIR;
1145 }
1146
1147
DestroyFileManagerDirs(int32_t userId)1148 int32_t MountManager::DestroyFileManagerDirs(int32_t userId)
1149 {
1150 bool err = true;
1151
1152 for (const DirInfo &dir : fileManagerDir_) {
1153 if (IsEndWith(dir.path.c_str(), "%d")) {
1154 err = err && RmDirRecurse(StringPrintf(dir.path.c_str(), userId));
1155 }
1156 }
1157
1158 return err ? E_OK : E_DESTROY_DIR;
1159 }
1160
SetFafQuotaProId(int32_t userId)1161 int32_t MountManager::SetFafQuotaProId(int32_t userId)
1162 {
1163 int32_t prjId = 0;
1164 for (const DirInfo &dir: fileManagerDir_) {
1165 QuotaManager::GetInstance()->SetQuotaPrjId(StringPrintf(dir.path.c_str(), userId), prjId, true);
1166 }
1167 QuotaManager::GetInstance()->SetQuotaPrjId(StringPrintf(SHARE_PATH.c_str(), userId), prjId, true);
1168 return E_OK;
1169 }
1170
CheckMountFileByUser(int32_t userId)1171 bool MountManager::CheckMountFileByUser(int32_t userId)
1172 {
1173 for (const DirInfo &dir : virtualDir_) {
1174 std::string path = StringPrintf(dir.path.c_str(), userId);
1175 if (CloudDirFlag(path)) {
1176 continue;
1177 }
1178 if (access(path.c_str(), 0) != 0) {
1179 LOGI("VirtualDir : %{public}s is not exists", path.c_str());
1180 return false;
1181 }
1182 }
1183 LOGI("MountFile is exists");
1184 return true;
1185 }
1186
CloudDirFlag(const std::string & path)1187 bool MountManager::CloudDirFlag(const std::string &path)
1188 {
1189 if (path.empty()) {
1190 return true;
1191 }
1192 std::regex cloudPattern("\\/mnt\\/data.*cloud");
1193 if (std::regex_match(path.c_str(), cloudPattern)) {
1194 return true;
1195 }
1196 std::regex cloudFusePattern("\\/mnt\\/data.*cloud_fuse");
1197 if (std::regex_match(path.c_str(), cloudFusePattern)) {
1198 return true;
1199 }
1200 return false;
1201 }
1202 } // namespace StorageDaemon
1203 } // namespace OHOS
1204