• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 <dirent.h>
18 #include <fcntl.h>
19 #include <regex>
20 #include "crypto/key_manager.h"
21 #include "utils/disk_utils.h"
22 #include "utils/storage_radar.h"
23 #include "parameter.h"
24 #include "parameters.h"
25 #include "quota/quota_manager.h"
26 #include "observer/appstate_observer.h"
27 #include "storage_service_errno.h"
28 #include "storage_service_log.h"
29 #include "utils/mount_argument_utils.h"
30 #include "utils/string_utils.h"
31 #ifdef DFS_SERVICE
32 #include "cloud_daemon_manager.h"
33 #endif
34 #ifdef USE_LIBRESTORECON
35 #include "policycoreutils.h"
36 #endif
37 
38 namespace OHOS {
39 namespace StorageDaemon {
40 using namespace std;
41 #define HMDFS_IOC 0xf2
42 #define HMDFS_IOC_FORBID_OPEN _IO(HMDFS_IOC, 12)
43 #ifdef DFS_SERVICE
44 using namespace OHOS::FileManagement::CloudFile;
45 #endif
46 using namespace OHOS::StorageService;
47 constexpr int32_t PATH_MAX_FOR_LINK = 4096;
48 constexpr int32_t DEFAULT_USERID = 100;
49 
MountManager()50 MountManager::MountManager() : hmdfsDirVec_(InitHmdfsDirVec()), virtualDir_(InitVirtualDir()),
51     systemServiceDir_(InitSystemServiceDir()), fileManagerDir_(InitFileManagerDir()), appdataDir_(InitAppdataDir())
52 {
53 }
54 
GetInstance()55 MountManager &MountManager::GetInstance()
56 {
57     static MountManager instance_;
58     return instance_;
59 }
60 
InitHmdfsDirVec()61 std::vector<DirInfo> MountManager::InitHmdfsDirVec()
62 {
63     return {{"/data/service/el2/%d/share", MODE_0711, OID_SYSTEM, OID_SYSTEM},
64             {"/data/service/el2/%d/hmdfs", MODE_0711, OID_DFS, OID_DFS},
65             {"/data/service/el2/%d/hmdfs/account", MODE_0711, OID_SYSTEM, OID_SYSTEM},
66             {"/data/service/el2/%d/hmdfs/account/files", MODE_02771, OID_USER_DATA_RW, OID_USER_DATA_RW},
67             {"/data/service/el2/%d/hmdfs/account/data", MODE_0711, OID_SYSTEM, OID_SYSTEM},
68             {"/data/service/el2/%d/hmdfs/non_account", MODE_0711, OID_SYSTEM, OID_SYSTEM},
69             {"/data/service/el2/%d/hmdfs/non_account/files", MODE_0711, OID_USER_DATA_RW, OID_USER_DATA_RW},
70             {"/data/service/el2/%d/hmdfs/non_account/data", MODE_0711, OID_SYSTEM, OID_SYSTEM},
71             {"/data/service/el2/%d/hmdfs/cloud", MODE_0711, OID_DFS, OID_DFS},
72             {"/data/service/el2/%d/hmdfs/cloud/data", MODE_0711, OID_DFS, OID_DFS},
73             {"/data/service/el2/%d/hmdfs/cache", MODE_0711, OID_DFS, OID_DFS},
74             {"/data/service/el2/%d/hmdfs/cloudfile_manager", MODE_0711, OID_DFS, OID_DFS},
75             {"/data/service/el2/%d/hmdfs/cache/account_cache", MODE_0711, OID_DFS, OID_DFS},
76             {"/data/service/el2/%d/hmdfs/cache/non_account_cache", MODE_0711, OID_DFS, OID_DFS},
77             {"/data/service/el2/%d/hmdfs/cache/cloud_cache", MODE_0711, OID_DFS, OID_DFS},
78             {"/data/service/el2/%d/hmdfs/account/services", MODE_0771, OID_DFS_SHARE, OID_DFS_SHARE}};
79 }
80 
InitVirtualDir()81 std::vector<DirInfo> MountManager::InitVirtualDir()
82 {
83     return {{"/storage/media/%d", MODE_0711, OID_USER_DATA_RW, OID_USER_DATA_RW},
84             {"/storage/media/%d/local", MODE_0711, OID_USER_DATA_RW, OID_USER_DATA_RW},
85             {"/storage/cloud", MODE_0711, OID_ROOT, OID_ROOT},
86             {"/storage/cloud/%d", MODE_0711, OID_USER_DATA_RW, OID_USER_DATA_RW},
87             {"/mnt/share/", MODE_0711, OID_ROOT, OID_ROOT},
88             {"/mnt/share/%d/", MODE_0711, OID_ROOT, OID_ROOT},
89             {"/mnt/data/%d/", MODE_0711, OID_ROOT, OID_ROOT},
90             {"/mnt/data/%d/cloud", MODE_0711, OID_ROOT, OID_ROOT},
91             {"/mnt/data/%d/cloud_fuse", MODE_0711, OID_DFS, OID_DFS},
92             {"/mnt/data/%d/media_fuse", MODE_0711, OID_USER_DATA_RW, OID_USER_DATA_RW},
93             {"/mnt/data/%d/userExternal", MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER},
94             {"/mnt/data/%d/hmdfs", MODE_0711, OID_FILE_MANAGER, OID_FILE_MANAGER},
95             {"/mnt/hmdfs/", MODE_0711, OID_ROOT, OID_ROOT},
96             {"/mnt/hmdfs/%d/", MODE_0711, OID_ROOT, OID_ROOT},
97             {"/mnt/hmdfs/%d/cloud", MODE_0711, OID_ROOT, OID_ROOT},
98             {"/mnt/hmdfs/%d/account", MODE_0711, OID_ROOT, OID_ROOT},
99             {"/mnt/hmdfs/%d/non_account", MODE_0711, OID_ROOT, OID_ROOT}};
100 }
101 
InitSystemServiceDir()102 std::vector<DirInfo> MountManager::InitSystemServiceDir()
103 {
104     return {{"/data/service/el2/%d/tee", MODE_0711, OID_TEE, OID_TEE},
105             {"/data/service/el2/%d/cloud_backup_service", MODE_0711, OID_CLOUD_BACK, OID_CLOUD_BACK},
106             {"/data/service/el2/%d/deviceauth", MODE_0711, OID_DEVICE_AUTH, OID_DEVICE_AUTH},
107             {"/data/service/el3/%d/device_standby", MODE_0711, OID_RSS, OID_RSS},
108             {"/data/service/el2/%d/trustedringsvc", MODE_0711, OID_TRUSTED_RING, OID_TRUSTED_RING},
109             {"/data/service/el2/%d/hwid_service", MODE_0711, OID_HWID, OID_HWID},
110             {"/data/service/el2/%d/cloud_develop_proxy",
111                     MODE_0711, OID_CLOUD_DEVELOP_PROXY, OID_CLOUD_DEVELOP_PROXY},
112             {"/data/service/el2/%d/media_cloud_enhance_service",
113                     MODE_0711, OID_MEDIA_ENHANCE_SERVICE, OID_MEDIA_ENHANCE_SERVICE},
114             {"/data/service/el2/%d/push_manager_service", MODE_0711, OID_PUSH, OID_PUSH},
115             {"/data/service/el2/%d/push_manager_service/database", MODE_0711, OID_PUSH, OID_PUSH},
116             {"/data/service/el2/%d/healthsport", MODE_0711, OID_HEALTH_SPORT, OID_HEALTH_SPORT},
117             {"/data/service/el2/%d/huks_service", MODE_0711, OID_HUKS, OID_HUKS},
118             {"/data/service/el2/%d/parentcontrol", MODE_0711, OID_PARENT_CONTROL, OID_PARENT_CONTROL},
119             {"/data/service/el4/%d/huks_service", MODE_0711, OID_HUKS, OID_HUKS},
120             {"/data/chipset/el2/%d/multimedia", MODE_0711, OID_MEDIA, OID_MEDIA},
121             {"/data/chipset/el2/%d/multimedia/algorithm_camera", MODE_0711, OID_MEDIA, OID_MEDIA},
122             {"/data/service/el2/%d/asset_service", MODE_0711, OID_ASSET, OID_ASSET},
123             {"/data/service/el4/%d/asset_clone", MODE_0711, OID_ASSET, OID_ASSET},
124             {"/data/service/el2/%d/account", MODE_0711, OID_ACCOUNT, OID_ACCOUNT},
125             {"/data/service/el2/%d/dlp_credential_service", MODE_0711, OID_DLP_CREDENTIAL, OID_DLP_CREDENTIAL},
126             {"/data/service/el2/%d/xpower", MODE_0711, OID_HIVIEW, OID_HIVIEW},
127             {"/data/service/el2/%d/iShare", MODE_0711, OID_COLLABORATION_FWK, OID_COLLABORATION_FWK},
128             {"/data/service/el2/%d/fusion_awareness", MODE_0711, OID_COLLABORATION_FWK, OID_COLLABORATION_FWK},
129             {"/data/service/el2/%d/av_session", MODE_0711, OID_AV_SESSION, OID_AV_SESSION},
130             {"/data/service/el2/%d/file_transfer_service", MODE_0711, 7017, 7017},
131             {"/data/service/el2/%d/gameservice_server",
132                     MODE_0711, OID_GAMESERVICE_SERVER, OID_GAMESERVICE_SERVER},
133             {"/data/service/el2/%d/gameservice_server/ucs",
134                     MODE_0711, OID_GAMESERVICE_SERVER, OID_GAMESERVICE_SERVER},
135             {"/data/service/el2/%d/virt_service", MODE_0711, OID_SYSTEM, OID_SYSTEM},
136             {"/data/service/el2/%d/virt_service/hwf_service", MODE_0711, OID_HWF_SERVICE, OID_HWF_SERVICE},
137             {"/data/service/el2/%d/virt_service/vm_manager", MODE_0711, OID_HWF_SERVICE, OID_HWF_SERVICE},
138             {"/data/service/el2/%d/file_monitor_service", MODE_0711, OID_USER_DATA_RW, OID_USER_DATA_RW},
139             {"/data/service/el2/%d/print_service", MODE_0711, OID_PRINT, OID_PRINT},
140             {"/data/service/el2/%d/database", MODE_0711, OID_DDMS, OID_DDMS},
141             {"/data/service/el2/%d/database/pasteboard_service", MODE_02771, OID_PASTEBOARD, OID_DDMS},
142             {"/data/service/el2/%d/findnetwork", MODE_0711, OID_FINDNETWORK, OID_FINDNETWORK},
143             {"/data/service/el2/%d/findnetwork/database", MODE_0711, OID_FINDNETWORK, OID_FINDNETWORK},
144             {"/data/service/el4/%d/findnetwork", MODE_0711, OID_FINDNETWORK, OID_FINDNETWORK},
145             {"/data/service/el2/%d/backup", MODE_02771, OID_BACKUP, OID_BACKUP},
146             {"/data/service/el2/%d/backup/backup_sa", MODE_0711, OID_BACKUP, OID_BACKUP},
147             {"/data/service/el2/%d/backup/bundles", MODE_0711, OID_BACKUP, OID_BACKUP},
148             {"/data/service/el2/%d/glasses_collaboration_service",
149                     MODE_0711, OID_GLASSES_COLLABORATION_SERVICE, OID_GLASSES_COLLABORATION_SERVICE}};
150 }
151 
InitFileManagerDir()152 std::vector<DirInfo> MountManager::InitFileManagerDir()
153 {
154     return {{"/data/service/el2/%d/hmdfs/account/files/Docs", MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER},
155             {"/data/service/el2/%d/hmdfs/account/files/Docs/Documents",
156                                                               MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER},
157             {"/data/service/el2/%d/hmdfs/account/files/Docs/Download",
158                                                               MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER},
159             {"/data/service/el2/%d/hmdfs/account/files/Docs/Desktop",
160                                                               MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER},
161             {"/data/service/el2/%d/hmdfs/account/files/Docs/.Trash",
162                                                               MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER},
163             {"/data/service/el2/%d/hmdfs/account/files/.Recent", MODE_02771, OID_FILE_MANAGER, OID_FILE_MANAGER}};
164 }
165 
InitAppdataDir()166 std::vector<DirInfo> MountManager::InitAppdataDir()
167 {
168     return {{"/mnt/user", MODE_0711, OID_ROOT, OID_ROOT},
169             {"/mnt/user/%d", MODE_0711, OID_ROOT, OID_ROOT},
170             {"/mnt/user/%d/nosharefs", MODE_0711, OID_ROOT, OID_ROOT},
171             {"/mnt/user/%d/nosharefs/docs", MODE_0711, OID_ROOT, OID_ROOT},
172             {"/mnt/user/%d/nosharefs/docs/currentUser", MODE_0711, OID_ROOT, OID_ROOT},
173             {"/mnt/user/%d/nosharefs/appdata", MODE_0711, OID_ROOT, OID_ROOT},
174             {"/mnt/user/%d/nosharefs/appdata/el1", MODE_0711, OID_ROOT, OID_ROOT},
175             {"/mnt/user/%d/nosharefs/appdata/el1/base", MODE_0711, OID_ROOT, OID_ROOT},
176             {"/mnt/user/%d/nosharefs/appdata/el2", MODE_0711, OID_ROOT, OID_ROOT},
177             {"/mnt/user/%d/nosharefs/appdata/el2/base", MODE_0711, OID_ROOT, OID_ROOT},
178             {"/mnt/user/%d/nosharefs/appdata/el2/cloud", MODE_0711, OID_ROOT, OID_ROOT},
179             {"/mnt/user/%d/nosharefs/appdata/el2/distributedfiles", MODE_0711, OID_ROOT, OID_ROOT},
180             {"/mnt/user/%d/nosharefs/appdata/el5", MODE_0711, OID_ROOT, OID_ROOT},
181             {"/mnt/user/%d/nosharefs/appdata/el5/base", MODE_0711, OID_ROOT, OID_ROOT},
182             {"/mnt/user/%d/sharefs", MODE_0711, OID_ROOT, OID_ROOT},
183             {"/mnt/user/%d/sharefs/docs", MODE_0711, OID_ROOT, OID_ROOT},
184             {"/mnt/user/%d/sharefs/docs/currentUser", MODE_0711, OID_ROOT, OID_ROOT},
185             {"/mnt/user/%d/currentUser", MODE_0711, OID_ROOT, OID_ROOT},
186             {"/mnt/user/%d/currentUser/filemgr", MODE_0711, OID_ROOT, OID_ROOT},
187             {"/mnt/user/%d/currentUser/other", MODE_0711, OID_ROOT, OID_ROOT},
188             {"/data/service/el1/%d/utdtypes", MODE_0711, OID_FOUNDATION, OID_FOUNDATION}};
189 }
190 
HmdfsTwiceMount(int32_t userId,const std::string & relativePath)191 int32_t MountManager::HmdfsTwiceMount(int32_t userId, const std::string &relativePath)
192 {
193     Utils::MountArgument hmdfsMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, relativePath));
194     std::string srcPath = hmdfsMntArgs.GetFullDst() + "/device_view/";
195     std::string dstPath = hmdfsMntArgs.GetCommFullPath();
196     int32_t mountRes = BindMount(srcPath, dstPath);
197     if (mountRes != E_OK) {
198         LOGE("failed to bind mount device_view, err %{public}d", mountRes);
199         std::string extraData = "srcPath=" + srcPath + ",dstPath=" + dstPath + ",kernelCode=" + to_string(errno);
200         StorageRadar::ReportUserManager("HmdfsTwiceMount", userId, E_MOUNT_HMDFS_MEDIA, extraData);
201         return E_MOUNT_HMDFS_MEDIA;
202     }
203     srcPath = hmdfsMntArgs.GetFullDst() + "/cloud_merge_view/";
204     dstPath = hmdfsMntArgs.GetCloudFullPath();
205     mountRes = BindMount(srcPath, dstPath);
206     if (mountRes != E_OK) {
207         LOGE("failed to bind mount cloud_merge_view, err %{public}d", errno);
208         std::string extraData = "srcPath=" + srcPath + ",dstPath=" + dstPath + ",kernelCode=" + to_string(errno);
209         StorageRadar::ReportUserManager("HmdfsTwiceMount", userId, E_MOUNT_HMDFS_CLOUD, extraData);
210         return E_MOUNT_HMDFS_CLOUD;
211     }
212     srcPath = hmdfsMntArgs.GetLocalDocsPath();
213     dstPath = hmdfsMntArgs.GetCloudDocsPath();
214     mountRes = BindMount(srcPath, dstPath);
215     if (mountRes != E_OK) {
216         LOGE("failed to bind mount docs, err %{public}d", errno);
217         std::string extraData = "srcPath=" + srcPath + ",dstPath=" + dstPath + ",kernelCode=" + to_string(errno);
218         StorageRadar::ReportUserManager("HmdfsTwiceMount", userId, E_MOUNT_HMDFS_CLOUD_DOCS, extraData);
219         return E_MOUNT_HMDFS_CLOUD_DOCS;
220     }
221     return E_OK;
222 }
223 
BindMount(std::string & srcPath,std::string & dstPath)224 int32_t MountManager::BindMount(std::string &srcPath, std::string &dstPath)
225 {
226     if (srcPath.empty() || !IsDir(srcPath)) {
227         LOGE("path invalid, %{public}s", srcPath.c_str());
228         return E_NON_EXIST;
229     }
230     if (dstPath.empty() || !IsDir(dstPath)) {
231         LOGE("path invalid, %{public}s", dstPath.c_str());
232         return E_NON_EXIST;
233     }
234     if (IsPathMounted(dstPath)) {
235         LOGE("path has mounted, %{public}s", dstPath.c_str());
236         return E_OK;
237     }
238     auto startTime = StorageService::StorageRadar::RecordCurrentTime();
239     int32_t ret = Mount(srcPath, dstPath, nullptr, MS_BIND, nullptr);
240     if (ret != 0 && errno != EEXIST && errno != EBUSY) {
241         LOGE("failed to bind mount, srcPath is %{public}s, dstPath is %{public}s, err is %{public}d",
242             srcPath.c_str(), dstPath.c_str(), errno);
243         return E_MOUNT_BIND_MOUNT;
244     }
245     auto delay = StorageService::StorageRadar::ReportDuration("MOUNT: BIND MOUNT",
246         startTime, StorageService::DELAY_TIME_THRESH_HIGH, StorageService::DEFAULT_USERID);
247     LOGI("SD_DURATION: MOUNT: BIND MOUNT, delayTime = %{public}s", delay.c_str());
248     return E_OK;
249 }
250 
SharefsMount(int32_t userId)251 int32_t MountManager::SharefsMount(int32_t userId)
252 {
253     Utils::MountArgument sharefsMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, ""));
254     std::string dst = sharefsMntArgs.GetShareDst();
255     if (IsPathMounted(dst)) {
256         LOGI("path has mounted, %{public}s", dst.c_str());
257     } else {
258         std::string srcPath = sharefsMntArgs.GetShareSrc();
259         auto startTime = StorageService::StorageRadar::RecordCurrentTime();
260         int ret = Mount(srcPath, dst, "sharefs", sharefsMntArgs.GetFlags(),
261                         sharefsMntArgs.GetUserIdPara().c_str());
262         if (ret != 0 && errno != EEXIST && errno != EBUSY) {
263             LOGE("failed to mount sharefs, err %{public}d", errno);
264             std::string extraData = "srcPath=" + srcPath + ",dstPath=" + dst + ",kernelCode=" + to_string(errno);
265             StorageRadar::ReportUserManager("SharefsMount", userId, E_MOUNT_SHAREFS, extraData);
266             return E_MOUNT_SHAREFS;
267         }
268         auto delay = StorageService::StorageRadar::ReportDuration("MOUNT: SHARE FS MOUNT",
269             startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId);
270         LOGI("SD_DURATION: SHARE FS MOUNT, delayTime = %{public}s", delay.c_str());
271     }
272     return E_OK;
273 }
274 
HmSharefsMount(int32_t userId,std::string & srcPath,std::string & dstPath)275 int32_t MountManager::HmSharefsMount(int32_t userId, std::string &srcPath, std::string &dstPath)
276 {
277     if (!IsDir(srcPath)) {
278         LOGE("srcPath not exist, %{public}s", srcPath.c_str());
279         return E_OK;
280     }
281     if (!IsDir(dstPath)) {
282         LOGE("dstPath not exist, %{public}s", dstPath.c_str());
283         return E_OK;
284     }
285     if (IsPathMounted(dstPath)) {
286         LOGI("path has mounted, %{public}s", dstPath.c_str());
287         return E_OK;
288     }
289     Utils::MountArgument sharefsMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, ""));
290     auto startTime = StorageService::StorageRadar::RecordCurrentTime();
291     int ret = Mount(srcPath, dstPath, "sharefs", sharefsMntArgs.GetFlags(),
292                     sharefsMntArgs.GetHmUserIdPara().c_str());
293     if (ret != 0 && errno != EEXIST && errno != EBUSY) {
294         LOGE("failed to mount hmSharefs, err %{public}d", errno);
295         std::string extraData = "srcPath=" + srcPath + ",dstPath=" + dstPath + ",kernelCode=" + to_string(errno);
296         StorageRadar::ReportUserManager("HmSharefsMount", userId, E_MOUNT_HM_SHAREFS, extraData);
297         return E_MOUNT_HM_SHAREFS;
298     }
299     auto delay = StorageService::StorageRadar::ReportDuration("MOUNT: HM SHARE FS MOUNT",
300         startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId);
301     LOGI("SD_DURATION: HM SHARE FS MOUNT, delayTime = %{public}s", delay.c_str());
302     return E_OK;
303 }
304 
HmdfsMount(int32_t userId,std::string relativePath,bool mountCloudDisk)305 int32_t MountManager::HmdfsMount(int32_t userId, std::string relativePath, bool mountCloudDisk)
306 {
307     Utils::MountArgument hmdfsMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, relativePath));
308     std::string srcPath = hmdfsMntArgs.GetFullSrc();
309     if (mountCloudDisk) {
310         hmdfsMntArgs.enableCloudDisk_ = true;
311         hmdfsMntArgs.useCloudDir_ = false;
312         hmdfsMntArgs.enableMergeView_ = false;
313         srcPath = hmdfsMntArgs.GetFullCloud();
314     }
315 
316     std::string dstPath = hmdfsMntArgs.GetFullDst();
317     if (IsPathMounted(dstPath)) {
318         LOGI("path has mounted, %{public}s", dstPath.c_str());
319         return E_OK;
320     }
321     auto startTime = StorageService::StorageRadar::RecordCurrentTime();
322     int ret = Mount(srcPath, dstPath, "hmdfs", hmdfsMntArgs.GetFlags(), hmdfsMntArgs.OptionsToString().c_str());
323     if (ret != 0 && errno != EEXIST && errno != EBUSY) {
324         LOGE("failed to mount hmdfs, err %{public}d", errno);
325         std::string extraData = "srcPath=" + srcPath + ",dstPath=" + dstPath + ",kernelCode=" + to_string(errno);
326         StorageRadar::ReportUserManager("HmdfsMount", userId, E_MOUNT_HMDFS, extraData);
327         return E_MOUNT_HMDFS;
328     }
329     auto delay = StorageService::StorageRadar::ReportDuration("MOUNT: HMDFS MOUNT",
330         startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId);
331     LOGI("SD_DURATION: HMDFS MOUNT, delayTime = %{public}s", delay.c_str());
332 
333     ret = chown(hmdfsMntArgs.GetCtrlPath().c_str(), OID_DFS, OID_SYSTEM);
334     if (ret != 0) {
335         LOGE("failed to chown hmdfs sysfs node, err %{public}d", errno);
336     }
337     return E_OK;
338 }
339 
FindProcess(std::list<std::string> & unMountFailList,std::vector<ProcessInfo> & proInfos,std::list<std::string> & excludeProcess)340 int32_t MountManager::FindProcess(std::list<std::string> &unMountFailList, std::vector<ProcessInfo> &proInfos,
341     std::list<std::string> &excludeProcess)
342 {
343     LOGI("find process start.");
344     auto procDir = std::unique_ptr<DIR, int (*)(DIR*)>(opendir("/proc"), closedir);
345     if (!procDir) {
346         LOGE("failed to open dir proc, err %{public}d", errno);
347         return E_UMOUNT_PROC_OPEN;
348     }
349     struct dirent *entry;
350     while ((entry = readdir(procDir.get())) != nullptr) {
351         if (entry->d_type != DT_DIR) {
352             continue;
353         }
354         std::string name = entry->d_name;
355         if (!StringIsNumber(name)) {
356             continue;
357         }
358         ProcessInfo info;
359         std::string filename = "/proc/" + name + "/stat";
360         if (!GetProcessInfo(filename, info)) {
361             LOGE("failed to get process info, pid is %{public}s.", name.c_str());
362             continue;
363         }
364         if (IsStringExist(excludeProcess, info.name)) {
365             continue;
366         }
367         std::string pidPath = "/proc/" + name;
368         LOGD("check pid using start, pid is %{public}d, processName is %{public}s.", info.pid, info.name.c_str());
369         if (PidUsingFlag(pidPath, unMountFailList)) {
370             proInfos.push_back(info);
371         }
372     }
373     std::string info = ProcessToString(proInfos);
374     int count = static_cast<int>(proInfos.size());
375     LOGE("find process end, total find %{public}d, process is: %{public}s", count, info.c_str());
376     return E_OK;
377 }
378 
PidUsingFlag(std::string & pidPath,std::list<std::string> & mountFailList)379 bool MountManager::PidUsingFlag(std::string &pidPath, std::list<std::string> &mountFailList)
380 {
381     std::string fdPath = pidPath + "/fd";
382     auto fdDir = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(fdPath.c_str()), closedir);
383     if (!fdDir) {
384         LOGE("unable to open %{public}s, err %{public}d", fdPath.c_str(), errno);
385     } else {
386         struct dirent* fdDirent;
387         while ((fdDirent = readdir(fdDir.get())) != nullptr) {
388             if (fdDirent->d_type != DT_LNK) {
389                 continue;
390             }
391             if (CheckSymlink(fdPath + "/" +fdDirent->d_name, mountFailList)) {
392                 return true;
393             }
394         }
395     }
396     if (CheckMaps(pidPath + "/maps", mountFailList)) {
397         return true;
398     }
399     if (CheckSymlink(pidPath + "/cwd", mountFailList)) {
400         return true;
401     }
402     if (CheckSymlink(pidPath + "/root", mountFailList)) {
403         return true;
404     }
405     if (CheckSymlink(pidPath + "/exe", mountFailList)) {
406         return true;
407     }
408     return false;
409 }
410 
GetProcessInfo(const std::string & filename,ProcessInfo & info)411 bool MountManager::GetProcessInfo(const std::string &filename, ProcessInfo &info)
412 {
413     if (filename.empty()) {
414         return false;
415     }
416     std::ifstream inputStream(filename.c_str(), std::ios::in);
417     if (!inputStream.is_open()) {
418         LOGE("unable to open %{public}s, err %{public}d", filename.c_str(), errno);
419         return false;
420     }
421     std::string line;
422     std::getline(inputStream, line);
423     if (line.empty()) {
424         LOGE("line is empty");
425         inputStream.close();
426         return false;
427     }
428     std::stringstream ss(line);
429     std::string pid;
430     ss >> pid;
431     std::string processName;
432     ss >> processName;
433     info.pid = std::atoi(pid.c_str());
434     info.name = processName;
435     inputStream.close();
436     return true;
437 }
438 
CheckMaps(const std::string & path,std::list<std::string> & mountFailList)439 bool MountManager::CheckMaps(const std::string &path, std::list<std::string> &mountFailList)
440 {
441     if (path.empty()) {
442         return false;
443     }
444     std::ifstream inputStream(path.c_str(), std::ios::in);
445     if (!inputStream.is_open()) {
446         LOGE("unable to open %{public}s, err %{public}d", path.c_str(), errno);
447         return false;
448     }
449     std::string tmpLine;
450     while (std::getline(inputStream, tmpLine)) {
451         std::string::size_type pos = tmpLine.find('/');
452         if (pos == std::string::npos) {
453             continue;
454         }
455         tmpLine = tmpLine.substr(pos);
456         for (const auto &item: mountFailList) {
457             if (tmpLine.find(item) == 0) {
458                 LOGE("find a fd from maps, %{public}s", tmpLine.c_str());
459                 inputStream.close();
460                 return true;
461             }
462         }
463     }
464     inputStream.close();
465     return false;
466 }
467 
CheckSymlink(const std::string & path,std::list<std::string> & mountFailList)468 bool MountManager::CheckSymlink(const std::string &path, std::list<std::string> &mountFailList)
469 {
470     if (path.empty()) {
471         return false;
472     }
473     char realPath[PATH_MAX_FOR_LINK];
474     int res = readlink(path.c_str(), realPath, sizeof(realPath) - 1);
475     if (res < 0) {
476         LOGE("readlink failed for path, errno is %{public}d.", errno);
477         return false;
478     }
479     realPath[res] = '\0';
480     std::string realPathStr(realPath);
481     for (const auto &item: mountFailList) {
482         if (realPathStr.find(item) == 0) {
483             LOGE("find a fd from link, %{public}s", realPathStr.c_str());
484             return true;
485         }
486     }
487     return false;
488 }
489 
CloudMount(int32_t userId,const string & path)490 int32_t MountManager::CloudMount(int32_t userId, const string &path)
491 {
492 #ifdef DFS_SERVICE
493     string opt;
494     int ret;
495     if (!cloudReady_) {
496         LOGI("Cloud Service has not started");
497         return E_CLOUD_NOT_READY;
498     }
499     FILE *f = fopen("/dev/fuse", "r+");
500     if (f == nullptr) {
501         LOGE("open /dev/fuse fail");
502         return E_USER_MOUNT_ERR;
503     }
504     int fd = fileno(f);
505     if (fd < 0) {
506         LOGE("open /dev/fuse fail");
507         (void)fclose(f);
508         return E_USER_MOUNT_ERR;
509     }
510     LOGI("open fuse end");
511     opt = StringPrintf("fd=%i,"
512         "rootmode=40000,"
513         "default_permissions,"
514         "allow_other,"
515         "user_id=0,group_id=0,"
516         "context=\"u:object_r:hmdfs:s0\","
517         "fscontext=u:object_r:hmdfs:s0",
518         fd);
519     auto startTime = StorageService::StorageRadar::RecordCurrentTime();
520     ret = Mount("/dev/fuse", path.c_str(), "fuse", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opt.c_str());
521     if (ret) {
522         LOGE("failed to mount fuse, err %{public}d %{public}d %{public}s", errno, ret, path.c_str());
523         (void)fclose(f);
524         return ret;
525     }
526     auto delay = StorageService::StorageRadar::ReportDuration("MOUNT: CLOUD MOUNT",
527         startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId);
528     LOGI("SD_DURATION: CLOUD MOUNT, delayTime = %{public}s. start cloud daemon fuse.", delay.c_str());
529     ret = CloudDaemonManager::GetInstance().StartFuse(userId, fd, path);
530     if (ret) {
531         LOGE("failed to connect fuse, err %{public}d %{public}d %{public}s", errno, ret, path.c_str());
532         UMount(path.c_str());
533     }
534     LOGI("mount %{public}s success", path.c_str());
535     (void)fclose(f);
536     return ret;
537 #else
538     return E_OK;
539 #endif
540 }
541 
CloudTwiceMount(int32_t userId)542 int32_t MountManager::CloudTwiceMount(int32_t userId)
543 {
544     LOGI("mount cloud start");
545     int32_t ret = E_OK;
546 #ifdef DFS_SERVICE
547     Utils::MountArgument cloudMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, ""));
548     string cloudPath = cloudMntArgs.GetFullCloud();
549     int32_t mountRet = E_OK;
550     if (IsPathMounted(cloudPath)) {
551         LOGI("path has mounted, %{public}s", cloudPath.c_str());
552     } else {
553         mountRet = CloudMount(userId, cloudPath);
554         if (mountRet != E_OK && mountRet != E_CLOUD_NOT_READY) {
555             std::string extraData = "dstPath=" + cloudPath + ",kernelCode=" + to_string(mountRet);
556             StorageRadar::ReportUserManager("CloudTwiceMount", userId, E_MOUNT_CLOUD_FUSE, extraData);
557             ret = E_MOUNT_CLOUD_FUSE;
558         }
559     }
560     string cloudMediaPath = cloudMntArgs.GetFullMediaCloud();
561     if (IsPathMounted(cloudMediaPath)) {
562         LOGI("path has mounted, %{public}s", cloudMediaPath.c_str());
563     } else {
564         mountRet = CloudMount(userId, cloudMediaPath);
565         if (mountRet != E_OK && mountRet != E_CLOUD_NOT_READY) {
566             std::string extraData = "dstPath=" + cloudMediaPath + ",kernelCode=" + to_string(mountRet);
567             StorageRadar::ReportUserManager("CloudTwiceMount", userId, E_MOUNT_CLOUD, extraData);
568             ret = E_MOUNT_CLOUD;
569         }
570     }
571     return ret;
572 #else
573     return ret;
574 #endif
575 }
576 
ParseSandboxPath(string & path,const string & userId,const string & bundleName)577 static void ParseSandboxPath(string &path, const string &userId, const string &bundleName)
578 {
579     size_t pos = path.find(CURRENT_USER_ID_FLAG);
580     if (pos != string::npos) {
581         path = path.replace(pos, CURRENT_USER_ID_FLAG.length(), userId);
582     }
583 
584     pos = path.find(PACKAGE_NAME_FLAG);
585     if (pos != string::npos) {
586         path = path.replace(pos, PACKAGE_NAME_FLAG.length(), bundleName);
587     }
588 }
589 
CheckPathValid(const std::string & bundleNameStr,uint32_t userId)590 bool MountManager::CheckPathValid(const std::string &bundleNameStr, uint32_t userId)
591 {
592     string completePath =
593         SANDBOX_ROOT_PATH + to_string(userId) + "/" + bundleNameStr + EL2_BASE;
594     if (!IsDir(completePath)) {
595         LOGE("Invalid directory path: %{public}s", completePath.c_str());
596         return false;
597     }
598 
599     if (!std::filesystem::is_empty(completePath)) {
600         LOGE("The directory has been mounted, path is %{public}s", completePath.c_str());
601         return false;
602     }
603     return true;
604 }
605 
MountCryptoPathAgain(uint32_t userId)606 int32_t MountManager::MountCryptoPathAgain(uint32_t userId)
607 {
608     filesystem::path rootDir(SANDBOX_ROOT_PATH + to_string(userId));
609     std::error_code errCode;
610     if (!exists(rootDir, errCode)) {
611         LOGE("root path not exists, rootDir is %{public}s", SANDBOX_ROOT_PATH.c_str());
612         return -ENOENT;
613     }
614 
615     int32_t ret = 0;
616     filesystem::directory_iterator bundleNameList(rootDir);
617     for (const auto &bundleName : bundleNameList) {
618         if (SANDBOX_EXCLUDE_PATH.find(bundleName.path().filename()) != SANDBOX_EXCLUDE_PATH.end()) {
619             continue;
620         }
621         std::string bundleNameStr = bundleName.path().filename().generic_string();
622         std::string::size_type point = bundleNameStr.find(MOUNT_SUFFIX);
623         if (point == string::npos) {
624             continue;
625         }
626         bundleNameStr = bundleNameStr.substr(0, point);
627         if (!CheckPathValid(bundleNameStr, userId)) {
628             continue;
629         }
630         vector<string> dstPaths = CRYPTO_SANDBOX_PATH;
631         vector<string> srcPaths = CRYPTO_SRC_PATH;
632         MountSandboxPath(srcPaths, dstPaths, bundleNameStr, to_string(userId));
633     }
634     LOGI("mount crypto path success, userId is %{public}d", userId);
635     return ret;
636 }
637 
MountSandboxPath(const std::vector<std::string> & srcPaths,const std::vector<std::string> & dstPaths,const std::string & bundleName,const std::string & userId)638 void MountManager::MountSandboxPath(const std::vector<std::string> &srcPaths, const std::vector<std::string> &dstPaths,
639     const std::string &bundleName, const std::string &userId)
640 {
641     int srcCnt = static_cast<int>(srcPaths.size());
642     int dstCnt = static_cast<int>(dstPaths.size());
643     if (srcCnt == 0 || dstCnt == 0 || srcCnt != dstCnt) {
644         LOGE("invalid params, srcPaths total %{public}d, dstPaths total %{public}d", srcCnt, dstCnt);
645         return;
646     }
647     LOGI("MountSandboxPath, bundleName: %{public}s, userID: %{public}s", bundleName.c_str(), userId.c_str());
648     for (int i = 0; i < dstCnt; i++) {
649         std::string dstPath = SANDBOX_ROOT_PATH;
650         dstPath = dstPath.append(userId).append("/").append(bundleName).append(dstPaths[i]);
651         string srcPath = srcPaths[i];
652         ParseSandboxPath(srcPath, userId, bundleName);
653         if (!IsDir(dstPath)) {
654             LOGE("dstPath is not a dir: %{public}s", dstPath.c_str());
655             continue;
656         }
657         if (!IsDir(srcPath)) {
658             LOGE("srcPath is not a dir: %{public}s", srcPath.c_str());
659             continue;
660         }
661         int32_t ret = mount(srcPath.c_str(), dstPath.c_str(), nullptr, MS_BIND | MS_REC, nullptr);
662         if (ret != E_OK && errno == EBUSY) {
663             ret = mount(srcPath.c_str(), dstPath.c_str(), nullptr, MS_BIND | MS_REC, nullptr);
664             LOGI("mount again ret is %{public}d.", ret);
665         }
666         if (ret != 0) {
667             LOGE("mount bind failed, srcPath is %{public}s dstPath is %{public}s errno is %{public}d",
668                  srcPath.c_str(), dstPath.c_str(), errno);
669             std::string extraData = "srcPath=" + srcPath + ",dstPath=" + dstPath + ",kernelCode=" + to_string(errno);
670             StorageRadar::ReportUserManager("MountSandboxPath", atoi(userId.c_str()), E_MOUNT_SANDBOX, extraData);
671             continue;
672         }
673         LOGI("bind mount success, num:%{public}d", i);
674         ret = mount(nullptr, dstPath.c_str(), nullptr, MS_SHARED, nullptr);
675         if (ret != 0) {
676             LOGE("mount to share failed, srcPath is %{public}s dstPath is %{public}s errno is %{public}d",
677                  srcPath.c_str(), dstPath.c_str(), errno);
678             continue;
679         }
680         LOGI("shared mount success, num:%{public}d", i);
681     }
682 }
683 
MountPointToList(std::list<std::string> & hmdfsList,std::list<std::string> & hmfsList,std::list<std::string> & sharefsList,std::string & line,int32_t userId)684 void MountManager::MountPointToList(std::list<std::string> &hmdfsList, std::list<std::string> &hmfsList,
685     std::list<std::string> &sharefsList, std::string &line, int32_t userId)
686 {
687     if (line.empty()) {
688         return;
689     }
690     Utils::MountArgument hmdfsMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, ""));
691     const string &hmdfsPrefix = hmdfsMntArgs.GetMountPointPrefix();
692     const string &hmfsPrefix = hmdfsMntArgs.GetSandboxPath();
693     const string &mntUserPrefix = hmdfsMntArgs.GetMntUserPath();
694     const string &sharefsPrefix = hmdfsMntArgs.GetShareSrc();
695     const string &cloudPrefix = hmdfsMntArgs.GetFullCloud();
696     std::stringstream ss(line);
697     std::string src;
698     ss >> src;
699     std::string dst;
700     ss >> dst;
701     std::string type;
702     ss >> type;
703     if (type == MOUNT_POINT_TYPE_HMDFS) {
704         if (src.length() >= hmdfsPrefix.length() && src.substr(0, hmdfsPrefix.length()) == hmdfsPrefix) {
705             hmdfsList.push_front(dst);
706         }
707         if (src.length() >= cloudPrefix.length() && src.substr(0, cloudPrefix.length()) == cloudPrefix) {
708             hmdfsList.push_front(dst);
709         }
710         return;
711     }
712     if (type == MOUNT_POINT_TYPE_HMFS || type == MOUNT_POINT_TYPE_F2FS) {
713         if (dst.length() >= hmfsPrefix.length() && dst.substr(0, hmfsPrefix.length()) == hmfsPrefix) {
714             hmfsList.push_front(dst);
715         }
716         if (dst.length() >= mntUserPrefix.length() && dst.substr(0, mntUserPrefix.length()) == mntUserPrefix) {
717             hmfsList.push_front(dst);
718         }
719         return;
720     }
721     if (type == MOUNT_POINT_TYPE_SHAREFS) {
722         if (src.length() >= sharefsPrefix.length() && src.substr(0, sharefsPrefix.length()) == sharefsPrefix) {
723             sharefsList.push_front(dst);
724         }
725         if (src.length() >= mntUserPrefix.length() && src.substr(0, mntUserPrefix.length()) == mntUserPrefix) {
726             sharefsList.push_front(dst);
727         }
728         return;
729     }
730 }
731 
FindMountPointsToMap(std::map<std::string,std::list<std::string>> & mountMap,int32_t userId)732 int32_t MountManager::FindMountPointsToMap(std::map<std::string, std::list<std::string>> &mountMap, int32_t userId)
733 {
734     std::ifstream inputStream(MOUNT_POINT_INFO.c_str(), std::ios::in);
735     if (!inputStream.is_open()) {
736         LOGE("unable to open /proc/mounts, errno is %{public}d", errno);
737         return E_UMOUNT_PROC_MOUNTS_OPEN;
738     }
739     std::list<std::string> hmdfsList;
740     std::list<std::string> hmfsList;
741     std::list<std::string> sharefsList;
742     std::string tmpLine;
743     while (std::getline(inputStream, tmpLine)) {
744         MountPointToList(hmdfsList, hmfsList, sharefsList, tmpLine, userId);
745     }
746     inputStream.close();
747     mountMap[MOUNT_POINT_TYPE_HMDFS] = hmdfsList;
748     mountMap[MOUNT_POINT_TYPE_HMFS] = hmfsList;
749     mountMap[MOUNT_POINT_TYPE_SHAREFS] = sharefsList;
750     hmdfsList.clear();
751     hmfsList.clear();
752     sharefsList.clear();
753     return E_OK;
754 }
755 
UMountAllPath(int32_t userId,std::list<std::string> & unMountFailList)756 int32_t MountManager::UMountAllPath(int32_t userId, std::list<std::string> &unMountFailList)
757 {
758     std::map<std::string, std::list<std::string>> mountMap;
759     int32_t res = FindMountPointsToMap(mountMap, userId);
760     if (res != E_OK) {
761         return res;
762     }
763     int32_t result = E_OK;
764     std::list<std::string> list = mountMap[MOUNT_POINT_TYPE_SHAREFS];
765     int total = static_cast<int>(list.size());
766     LOGI("unmount sharefs path start, total %{public}d.", total);
767     res = UMountByList(list, unMountFailList);
768     if (res != E_OK) {
769         LOGE("failed to umount sharefs mount point, res is %{public}d", res);
770         result = E_UMOUNT_SHAREFS;
771     }
772 
773     list = mountMap[MOUNT_POINT_TYPE_HMFS];
774     total = static_cast<int>(list.size());
775     LOGI("unmount hmfs path start, total %{public}d.", total);
776     res = UMountByList(list, unMountFailList);
777     if (res != E_OK) {
778         LOGE("failed to umount hmfs mount point, res is %{public}d", res);
779         result = E_UMOUNT_HMFS;
780     }
781     UmountMntUserTmpfs(userId);
782 
783     list = mountMap[MOUNT_POINT_TYPE_HMDFS];
784     total = static_cast<int>(list.size());
785     LOGI("unmount hmdfs path start, total %{public}d.", total);
786     res = UMountHmdfsByList(userId, list, unMountFailList);
787     if (res != E_OK) {
788         LOGE("failed to umount hmdfs mount point, res is %{public}d", res);
789         result = E_UMOUNT_HMDFS;
790     }
791     if (!unMountFailList.empty()) {
792         std::string extraData = "dstPath=" + ListToString(unMountFailList) + ",kernelCode=" + to_string(result);
793         StorageRadar::ReportUserManager("UMountAllPath", userId, E_UMOUNT_ALL_PATH, extraData);
794     }
795     LOGI("UMountAllPath end, res is %{public}d", result);
796     return result;
797 }
798 
UMountHmdfsByList(int32_t userId,std::list<std::string> & list,std::list<std::string> & unMountFailList)799 int32_t MountManager::UMountHmdfsByList(int32_t userId, std::list<std::string> &list,
800     std::list<std::string> &unMountFailList)
801 {
802     if (list.empty()) {
803         return E_OK;
804     }
805     int32_t result = E_OK;
806     auto startTime = StorageService::StorageRadar::RecordCurrentTime();
807     for (std::string &path: list) {
808         LOGD("umount path %{public}s.", path.c_str());
809         if (IsSysMountPoint(userId, path)) {
810             continue;
811         }
812         int32_t res = UMount(path);
813         if (res != E_OK && errno != ENOENT && errno != EINVAL) {
814             LOGE("failed to unmount path %{public}s, errno %{public}d.", path.c_str(), errno);
815             result = errno;
816             unMountFailList.push_back(path);
817         }
818     }
819     auto delay = StorageService::StorageRadar::ReportDuration("UMOUNT: UMOUNT HMDFS BY LIST",
820         startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId);
821     LOGI("SD_DURATION: UMOUNT: UMOUNT HMDFS BY LIST, delayTime = %{public}s", delay.c_str());
822     return result;
823 }
824 
IsSysMountPoint(int32_t userId,std::string & path)825 bool MountManager::IsSysMountPoint(int32_t userId, std::string &path)
826 {
827     auto count = static_cast<int32_t>(SYS_PATH.size());
828     for (int i = 0; i < count; i++) {
829         std::string tempPath = SYS_PATH[i];
830         ParseSandboxPath(tempPath, to_string(userId), "");
831         if (path == tempPath) {
832             return true;
833         }
834     }
835     return false;
836 }
837 
UMountByList(std::list<std::string> & list,std::list<std::string> & unMountFailList)838 int32_t MountManager::UMountByList(std::list<std::string> &list, std::list<std::string> &unMountFailList)
839 {
840     if (list.empty()) {
841         return E_OK;
842     }
843     int32_t result = E_OK;
844     auto startTime = StorageService::StorageRadar::RecordCurrentTime();
845     for (const std::string &path: list) {
846         LOGD("umount path %{public}s.", path.c_str());
847         int32_t res = UMount(path);
848         if (res != E_OK && errno != ENOENT && errno != EINVAL) {
849             LOGE("failed to unmount path %{public}s, errno %{public}d.", path.c_str(), errno);
850             result = errno;
851             unMountFailList.push_back(path);
852         }
853     }
854     auto delay = StorageService::StorageRadar::ReportDuration("UMOUNT: UMOUNT BY LIST",
855         startTime, StorageService::DELAY_TIME_THRESH_HIGH, StorageService::DEFAULT_USERID);
856     LOGI("SD_DURATION: UMOUNT: UMOUNT BY LIST, delayTime = %{public}s", delay.c_str());
857     return result;
858 }
859 
UMountByListWithDetach(std::list<std::string> & list)860 int32_t MountManager::UMountByListWithDetach(std::list<std::string> &list)
861 {
862     if (list.empty()) {
863         return E_OK;
864     }
865     int32_t result = E_OK;
866     auto startTime = StorageService::StorageRadar::RecordCurrentTime();
867     for (const std::string &path: list) {
868         LOGD("umount path %{public}s.", path.c_str());
869         int32_t res = UMount2(path, MNT_DETACH);
870         if (res != E_OK && errno != ENOENT && errno != EINVAL) {
871             LOGE("failed to unmount path %{public}s, errno %{public}d.", path.c_str(), errno);
872             result = errno;
873         }
874     }
875     auto delay = StorageService::StorageRadar::ReportDuration("UMOUNT2: UMOUNT LIST WITH DETACH",
876         startTime, StorageService::DELAY_TIME_THRESH_HIGH, StorageService::DEFAULT_USERID);
877     LOGI("SD_DURATION: UMOUNT2: UMOUNT LIST WITH DETACH, delayTime = %{public}s", delay.c_str());
878     return result;
879 }
880 
MountCloudForUsers(void)881 void MountManager::MountCloudForUsers(void)
882 {
883     for (auto it = fuseToMountUsers_.begin(); it != fuseToMountUsers_.end();) {
884         int32_t res = CloudTwiceMount(*it);
885         if (res == E_OK) {
886             fuseMountedUsers_.push_back(*it);
887             it = fuseToMountUsers_.erase(it);
888         } else {
889             it++;
890         }
891     }
892 }
893 
UMountCloudForUsers(void)894 void MountManager::UMountCloudForUsers(void)
895 {
896     for (auto it = fuseMountedUsers_.begin(); it != fuseMountedUsers_.end();) {
897         int32_t res = CloudUMount(*it);
898         if (res == E_OK) {
899             fuseToMountUsers_.push_back(*it);
900             it = fuseMountedUsers_.erase(it);
901         } else {
902             it++;
903         }
904     }
905 }
906 
SetCloudState(bool active)907 void MountManager::SetCloudState(bool active)
908 {
909     LOGI("set cloud state start, active is %{public}d", active);
910     mountMutex_.lock();
911     cloudReady_ = active;
912     if (cloudReady_) {
913         MountCloudForUsers();
914     } else {
915         UMountCloudForUsers();
916     }
917     mountMutex_.unlock();
918     LOGI("set cloud state end");
919 }
920 
CloudUMount(int32_t userId)921 int32_t MountManager::CloudUMount(int32_t userId)
922 {
923 #ifdef DFS_SERVICE
924     int32_t err = E_OK;
925     Utils::MountArgument cloudMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, ""));
926     const string cloudFusePath = cloudMntArgs.GetFullCloud();
927     auto startTime = StorageService::StorageRadar::RecordCurrentTime();
928     err = UMount2(cloudFusePath, MNT_DETACH);
929     if (err != E_OK && errno != ENOENT && errno != EINVAL) {
930         LOGE("cloud fuse umount failed, errno is %{public}d.", errno);
931         std::string extraData = "dstPath=" + cloudFusePath + ",kernelCode=" + to_string(errno);
932         StorageRadar::ReportUserManager("CloudUMount", userId, E_UMOUNT_CLOUD_FUSE, extraData);
933         return E_UMOUNT_CLOUD_FUSE;
934     }
935     auto delay = StorageService::StorageRadar::ReportDuration("UMOUNT2: UMOUNT FULL COULD",
936         startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId);
937     LOGI("SD_DURATION: UMOUNT2: UMOUNT FULL COULD, delayTime = %{public}s", delay.c_str());
938 
939     startTime = StorageService::StorageRadar::RecordCurrentTime();
940     const std::string cloudPath = cloudMntArgs.GetFullMediaCloud();
941     err = UMount2(cloudPath, MNT_DETACH);
942     if (err != E_OK && errno != ENOENT && errno != EINVAL) {
943         LOGE("cloud umount failed, errno %{public}d", errno);
944         std::string extraData = "dstPath=" + cloudPath + ",kernelCode=" + to_string(errno);
945         StorageRadar::ReportUserManager("CloudUMount", userId, E_UMOUNT_CLOUD, extraData);
946         return E_UMOUNT_CLOUD;
947     }
948     delay = StorageService::StorageRadar::ReportDuration("UMOUNT2: UMOUNT FULL MEDIA COULD",
949         startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId);
950     LOGI("SD_DURATION: UMOUNT2: UMOUNT FULL MEDIA COULD, delayTime = %{public}s. cloud umount success", delay.c_str());
951     return E_OK;
952 #else
953     return E_OK;
954 #endif
955 }
956 
SupportHmdfs()957 bool MountManager::SupportHmdfs()
958 {
959     char hmdfsEnable[HMDFS_VAL_LEN + 1] = {"false"};
960     int ret = GetParameter(HMDFS_SYS_CAP.c_str(), "", hmdfsEnable, HMDFS_VAL_LEN);
961     LOGI("GetParameter hmdfsEnable %{public}s, ret %{public}d", hmdfsEnable, ret);
962     if (strncmp(hmdfsEnable, "true", HMDFS_TRUE_LEN) == 0) {
963         return true;
964     }
965     return false;
966 }
967 
LocalMount(int32_t userId)968 int32_t MountManager::LocalMount(int32_t userId)
969 {
970     Utils::MountArgument LocalMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, "account"));
971     std::string srcPath = LocalMntArgs.GetFullSrc();
972     std::string dstPath = LocalMntArgs.GetCommFullPath() + "local/";
973     int ret = BindMount(srcPath, dstPath);
974     if (ret != E_OK) {
975         LOGE("failed to mount local media path, %{public}s, err is %{public}d", srcPath.c_str(), errno);
976         std::string extraData = "srcPath=" + srcPath + ",dstPath=" + dstPath + ",kernelCode = " + to_string(ret);
977         StorageRadar::ReportUserManager("LocalMount", userId, E_MOUNT_LOCAL_MEDIA, extraData);
978         return E_MOUNT_LOCAL_MEDIA;
979     }
980     dstPath = LocalMntArgs.GetCloudFullPath();
981     ret = BindMount(srcPath, dstPath);
982     if (ret != E_OK) {
983         LOGE("failed to mount local cloud path, %{public}s, err is %{public}d", srcPath.c_str(), errno);
984         std::string extraData = "srcPath=" + srcPath + ",dstPath=" + dstPath + ",kernelCode = " + to_string(ret);
985         StorageRadar::ReportUserManager("LocalMount", userId, E_MOUNT_LOCAL_CLOUD, extraData);
986         return E_MOUNT_LOCAL_CLOUD;
987     }
988     return E_OK;
989 }
990 
RmExistDir(const std::string & dirPath)991 static void RmExistDir(const std::string &dirPath)
992 {
993     if (access(dirPath.c_str(), 0) == 0) {
994         if (!RmDirRecurse(dirPath)) {
995             LOGE("Failed to remove dir %{public}s", dirPath.c_str());
996         }
997     }
998 }
999 
ClearRedundantResources(int32_t userId)1000 static void ClearRedundantResources(int32_t userId)
1001 {
1002     std::string sharePath = StringPrintf("/data/service/el2/%d/share", userId);
1003     filesystem::path rootDir(sharePath);
1004     std::error_code errCode;
1005     if (!exists(rootDir, errCode)) {
1006         LOGE("Bundles share path not exists, rootDir is %{public}s", sharePath.c_str());
1007         return;
1008     }
1009 
1010     filesystem::directory_iterator bundleNameList(rootDir);
1011     for (const auto &bundleName : bundleNameList) {
1012         RmExistDir(bundleName.path().generic_string() + "/r");
1013         RmExistDir(bundleName.path().generic_string() + "/rw");
1014     }
1015 }
1016 
MountByUser(int32_t userId)1017 int32_t MountManager::MountByUser(int32_t userId)
1018 {
1019     bool isCeEncrypt = false;
1020     int ret = KeyManager::GetInstance().GetFileEncryptStatus(userId, isCeEncrypt);
1021     if (ret != E_OK || isCeEncrypt) {
1022         LOGE("User %{public}d de has not decrypt.", userId);
1023         return E_KEY_NOT_ACTIVED;
1024     }
1025     std::thread thread([userId]() { ClearRedundantResources(userId); });
1026     thread.detach();
1027     PrepareFileManagerDir(userId);
1028     CreateVirtualDirs(userId);
1029     PrepareHmdfsDirs(userId);
1030 
1031     int32_t mountHmdfsRes = MountFileSystem(userId);
1032     if (mountHmdfsRes != E_OK) {
1033         return mountHmdfsRes;
1034     }
1035     SetFafQuotaProId(userId);
1036     CreateSystemServiceDirs(userId);
1037     LOGI("MountByUser success, userId is %{public}d.", userId);
1038     return E_OK;
1039 }
1040 
MountFileSystem(int32_t userId)1041 int32_t MountManager::MountFileSystem(int32_t userId)
1042 {
1043     int32_t ret;
1044     if (SupportHmdfs()) {
1045         ret = HmdfsMount(userId, "account");
1046         if (ret != E_OK) {
1047             return ret;
1048         }
1049         ret = HmdfsTwiceMount(userId, "account");
1050         if (ret != E_OK) {
1051             return ret;
1052         }
1053         ret = HmdfsMount(userId, "non_account");
1054         if (ret != E_OK) {
1055             return ret;
1056         }
1057         mountMutex_.lock();
1058         if (CloudTwiceMount(userId) == E_OK) {
1059             fuseMountedUsers_.push_back(userId);
1060         } else {
1061             fuseToMountUsers_.push_back(userId);
1062         }
1063         mountMutex_.unlock();
1064         HmdfsMount(userId, "cloud", true);
1065     } else {
1066         ret = LocalMount(userId);
1067     }
1068     if (ret != E_OK) {
1069         return ret;
1070     }
1071     SharefsMount(userId);
1072     MountAppdataAndSharefs(userId);
1073     return E_OK;
1074 }
1075 
GetFileManagerUid(uid_t uid,int32_t userId)1076 static uid_t GetFileManagerUid(uid_t uid, int32_t userId)
1077 {
1078     return USER_ID_BASE * userId + uid;
1079 }
1080 
PrepareFileManagerDir(int32_t userId)1081 void MountManager::PrepareFileManagerDir(int32_t userId)
1082 {
1083     std::string filesPath = StringPrintf("/data/service/el2/%d/hmdfs/account/files/", userId);
1084     // move file manager dir
1085     MoveFileManagerData(filesPath);
1086     for (const DirInfo &dir : fileManagerDir_) {
1087         uid_t dirUid = GetFileManagerUid(dir.uid, userId);
1088         std::string path = StringPrintf(dir.path.c_str(), userId);
1089         int ret = IsSameGidUid(path, dirUid, dir.gid);
1090         LOGD("prepareDir %{public}s ret %{public}d, dirUid: %{public}d", path.c_str(), ret, dirUid);
1091         // Dir exist and same uid, gid
1092         if (ret == E_OK) {
1093             continue;
1094         }
1095         // system error
1096         if (ret == E_SYS_KERNEL_ERR) {
1097             LOGE("system err %{public}s ", path.c_str());
1098             continue;
1099         }
1100         // Dir exist and different uid, gid
1101         if (ret == E_DIFF_UID_GID) {
1102             ChownRecursion(path, dirUid, OID_FILE_MANAGER);
1103             continue;
1104         }
1105         // Dir not exist
1106         if (ret == E_NON_EXIST && !PrepareDir(path, dir.mode, dirUid, dir.gid)) {
1107             LOGE("failed to prepareDir %{public}s ", path.c_str());
1108         }
1109     }
1110 }
1111 
LocalUMount(int32_t userId)1112 int32_t MountManager::LocalUMount(int32_t userId)
1113 {
1114     int res = E_OK;
1115     Utils::MountArgument LocalMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, "account"));
1116     std::string path = LocalMntArgs.GetCommFullPath() + "local/";
1117     auto startTime = StorageService::StorageRadar::RecordCurrentTime();
1118     int unMountRes = UMount(path);
1119     if (unMountRes != E_OK && errno != ENOENT && errno != EINVAL) {
1120         LOGE("failed to unmount local, errno %{public}d, path is %{public}s", errno, path.c_str());
1121         std::string extraData = "dstPath=" + path + ",kernelCode=" + to_string(errno);
1122         StorageRadar::ReportUserManager("LocalUMount", userId, E_UMOUNT_LOCAL_MEDIA, extraData);
1123         res = E_UMOUNT_LOCAL_MEDIA;
1124     }
1125     auto delay = StorageService::StorageRadar::ReportDuration("UMOUNT: LOCAL UMOUNT COMM FUL PATH",
1126         startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId);
1127     LOGI("SD_DURATION: UMOUNT: LOCAL UMOUNT COMM FUL PATH, delayTime = %{public}s", delay.c_str());
1128 
1129     startTime = StorageService::StorageRadar::RecordCurrentTime();
1130     path = LocalMntArgs.GetCloudFullPath();
1131     unMountRes = UMount(path);
1132     if (unMountRes != E_OK && errno != ENOENT && errno != EINVAL) {
1133         LOGE("failed to unmount local, errno %{public}d, path is %{public}s", errno, path.c_str());
1134         std::string extraData = "dstPath=" + path + ",kernelCode=" + to_string(errno);
1135         StorageRadar::ReportUserManager("LocalUMount", userId, E_UMOUNT_LOCAL_CLOUD, extraData);
1136         res = E_UMOUNT_LOCAL_CLOUD;
1137     }
1138     delay = StorageService::StorageRadar::ReportDuration("UMOUNT: LOCAL UMOUNT CLOUD FUL PATH",
1139         startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId);
1140     LOGI("SD_DURATION: UMOUNT: LOCAL UMOUNT CLOUD FUL PATH, delayTime = %{public}s", delay.c_str());
1141     return res;
1142 }
1143 
UmountByUser(int32_t userId)1144 int32_t MountManager::UmountByUser(int32_t userId)
1145 {
1146     int32_t res = E_OK;
1147     if (!SupportHmdfs() && LocalUMount(userId) != E_OK) {
1148         res = E_UMOUNT_LOCAL;
1149     } else {
1150         int unMount = UmountFileSystem(userId);
1151         if (unMount != E_OK) {
1152             res = unMount;
1153         }
1154     }
1155 
1156     LOGI("umount cloud mount point start.");
1157     int32_t cloudUMount = CloudUMount(userId);
1158     if (cloudUMount != E_OK) {
1159         res = cloudUMount;
1160     }
1161     UMountMediaFuse(userId);
1162     FindSaFd(userId);
1163     LOGI("unmount end, res is %{public}d.", res);
1164     return res;
1165 }
1166 
FindSaFd(int32_t userId)1167 int32_t MountManager::FindSaFd(int32_t userId)
1168 {
1169     LOGI("find sa fd start.");
1170     std::list<std::string> list;
1171     for (const std::string &item: FD_PATH) {
1172         std::string temp = item;
1173         ParseSandboxPath(temp, to_string(userId), "");
1174         list.push_back(temp);
1175     }
1176     std::vector<ProcessInfo> proInfos;
1177     std::list<std::string> excludeProcess;
1178     FindProcess(list, proInfos, excludeProcess);
1179     if (!proInfos.empty()) {
1180         std::string extraData = "process=" + ProcessToString(proInfos);
1181         StorageRadar::ReportUserManager("FindSaFd", userId, E_UMOUNT_FIND_FD, extraData);
1182     }
1183     LOGI("find sa fd end.");
1184     return E_OK;
1185 }
1186 
UmountFileSystem(int32_t userId)1187 int32_t MountManager::UmountFileSystem(int32_t userId)
1188 {
1189     LOGI("try to force umount all path start.");
1190     std::list<std::string> unMountFailList;
1191     int32_t unMountRes = UMountAllPath(userId, unMountFailList);
1192     for (const auto &item: HMDFS_SUFFIX) {
1193         Utils::MountArgument mountArg(Utils::MountArgumentDescriptors::Alpha(userId, item));
1194         unMountFailList.push_back(mountArg.GetFullDst());
1195     }
1196     if (CheckSysFs(userId) || unMountRes != E_OK) {
1197         ForbidOpen(userId);
1198         LOGE("force umount failed, try to kill process, res is %{public}d.", unMountRes);
1199         FindAndKillProcess(userId, unMountFailList, unMountRes);
1200     }
1201     LOGE("try to force umount again.");
1202     std::list<std::string> tempList;
1203     int32_t unMountAgain = UMountByList(unMountFailList, tempList);
1204     if (unMountAgain == E_OK) {
1205         return E_OK;
1206     }
1207     LOGE("force umount again failed, try to kill process again, res is %{public}d.", unMountAgain);
1208     FindAndKillProcess(userId, unMountFailList, unMountAgain);
1209     LOGE("try to umount by detach.");
1210     return UMountByListWithDetach(unMountFailList) == E_OK ? E_OK : E_UMOUNT_DETACH;
1211 }
1212 
CheckSysFs(int32_t userId)1213 bool MountManager::CheckSysFs(int32_t userId)
1214 {
1215     for (const auto &item: HMDFS_SUFFIX) {
1216         Utils::MountArgument mountArg(Utils::MountArgumentDescriptors::Alpha(userId, item));
1217         std::string path = mountArg.GetFullDst();
1218         if (IsSysFsInUse(path)) {
1219             return true;
1220         }
1221     }
1222     return false;
1223 }
1224 
IsSysFsInUse(std::string & path)1225 bool MountManager::IsSysFsInUse(std::string &path)
1226 {
1227     FILE *f = fopen(path.c_str(), "r");
1228     if (f == nullptr) {
1229         LOGE("sys fs fopen fail, path is %{public}s, errno is %{public}d.", path.c_str(), errno);
1230         return true;
1231     }
1232     int fd = fileno(f);
1233     if (fd < 0) {
1234         LOGE("sys fs fileno fail, path is %{public}s, errno is %{public}d.", path.c_str(), errno);
1235         (void)fclose(f);
1236         return true;
1237     }
1238     int inUse = -1;
1239     int cmd = _IOR(0xAC, 77, int);
1240     if (ioctl(fd, cmd, &inUse) < 0) {
1241         LOGE("sys fs ioctl fail, path is %{public}s, errno is %{public}d.", path.c_str(), errno);
1242         (void)fclose(f);
1243         return true;
1244     }
1245     if (inUse > 0) {
1246         LOGE("sys fs is in use, path is %{public}s, use count is %{public}d.", path.c_str(), inUse);
1247         (void)fclose(f);
1248         return true;
1249     }
1250     LOGE("sys fs is not use, path is %{public}s.", path.c_str());
1251     (void)fclose(f);
1252     return false;
1253 }
1254 
ForbidOpen(int32_t userId)1255 void MountManager::ForbidOpen(int32_t userId)
1256 {
1257     for (const auto &item: HMDFS_SUFFIX) {
1258         Utils::MountArgument mountArg(Utils::MountArgumentDescriptors::Alpha(userId, item));
1259         std::string path = mountArg.GetFullDst();
1260         FILE *f = fopen(path.c_str(), "r");
1261         if (f == nullptr) {
1262             LOGE("forbid fopen fail, path is %{public}s, errno is %{public}d.", path.c_str(), errno);
1263             return;
1264         }
1265         int fd = fileno(f);
1266         if (fd < 0) {
1267             LOGE("forbid fileno fail, path is %{public}s, errno is %{public}d.", path.c_str(), errno);
1268             (void)fclose(f);
1269             return;
1270         }
1271         if (ioctl(fd, HMDFS_IOC_FORBID_OPEN) < 0) {
1272             LOGE("forbid ioctl fail, path is %{public}s, errno is %{public}d.", path.c_str(), errno);
1273         } else {
1274             LOGE("forbid ioctl success, path is %{public}s.", path.c_str());
1275         }
1276         (void)fclose(f);
1277     }
1278 }
1279 
FindAndKillProcess(int32_t userId,std::list<std::string> & unMountFailList,int32_t radar)1280 int32_t MountManager::FindAndKillProcess(int32_t userId, std::list<std::string> &unMountFailList, int32_t radar)
1281 {
1282     std::vector<ProcessInfo> processInfos;
1283     std::list<std::string> excludeProcess = {"(storage_daemon)"};
1284     FindProcess(unMountFailList, processInfos, excludeProcess);
1285     if (processInfos.empty()) {
1286         LOGE("no process find.");
1287         return E_UMOUNT_NO_PROCESS_FIND;
1288     }
1289     std::string extraData = "process=" + ProcessToString(processInfos) + ",kernelCode=" + to_string(radar);
1290     StorageRadar::ReportUserManager("FindAndKillProcess", userId, E_UMOUNT_FIND_PROCESS, extraData);
1291 
1292     std::vector<ProcessInfo> killFailList;
1293     KillProcess(processInfos, killFailList);
1294     if (!killFailList.empty()) {
1295         std::string info = ProcessToString(killFailList);
1296         LOGE("kill process failed, process is %{public}s.", info.c_str());
1297         return E_UMOUNT_PROCESS_KILL;
1298     }
1299     return E_OK;
1300 }
1301 
CheckProcessUserId(int32_t userId,std::vector<ProcessInfo> & proInfos,std::vector<ProcessInfo> & processKillInfos)1302 int32_t MountManager::CheckProcessUserId(int32_t userId, std::vector<ProcessInfo> &proInfos,
1303                                          std::vector<ProcessInfo> &processKillInfos)
1304 {
1305     for (auto proInfo : proInfos) {
1306         std::string filename = "/proc/" + std::to_string(proInfo.pid) + "/status";
1307         std::ifstream inputStream(filename.c_str(), std::ios::in);
1308         if (!inputStream.is_open()) {
1309             LOGE("open %{public}s failed, err %{public}d", filename.c_str(), errno);
1310             continue;
1311         }
1312         std::string line;
1313         std::string uidKey = "Uid:";
1314         while (std::getline(inputStream, line)) {
1315             if (line.find(uidKey) == 0) {
1316                 break;
1317             }
1318         }
1319         std::stringstream ss(line);
1320         std::string key;
1321         int32_t uid;
1322         ss >> key >> uid;
1323         int32_t procUserId = uid / USER_ID_BASE;
1324         if (procUserId == userId) {
1325             processKillInfos.push_back(proInfo);
1326         }
1327         inputStream.close();
1328     }
1329     return E_OK;
1330 }
1331 
FindAndKillProcessWithoutRadar(int32_t userId,std::list<std::string> & killList)1332 int32_t MountManager::FindAndKillProcessWithoutRadar(int32_t userId, std::list<std::string> &killList)
1333 {
1334     std::vector<ProcessInfo> processInfos;
1335     std::vector<ProcessInfo> processKillInfos;
1336     std::list<std::string> excludeProcess = {"(storage_daemon)"};
1337     FindProcess(killList, processInfos, excludeProcess);
1338     if (processInfos.empty()) {
1339         LOGE("no process find without radar");
1340         return E_UMOUNT_NO_PROCESS_FIND;
1341     }
1342     CheckProcessUserId(userId, processInfos, processKillInfos);
1343     std::vector<ProcessInfo> killFailList;
1344     KillProcess(processKillInfos, killFailList);
1345     if (!killFailList.empty()) {
1346         std::string info = ProcessToString(killFailList);
1347         LOGE("kill process failed without radar, process is %{public}s.", info.c_str());
1348         return E_UMOUNT_PROCESS_KILL;
1349     }
1350     return E_OK;
1351 }
1352 
PrepareHmdfsDirs(int32_t userId)1353 int32_t MountManager::PrepareHmdfsDirs(int32_t userId)
1354 {
1355     for (const DirInfo &dir : hmdfsDirVec_) {
1356         std::string path = StringPrintf(dir.path.c_str(), userId);
1357         if (!PrepareDir(path, dir.mode, dir.uid, dir.gid)) {
1358             std::string extraData = "dirPath=" + path + ",kernelCode=" + to_string(errno);
1359             StorageRadar::ReportUserManager("PrepareHmdfsDirs", userId, E_CREATE_DIR_HMDFS, extraData);
1360             return E_CREATE_DIR_HMDFS;
1361         }
1362     }
1363     return E_OK;
1364 }
1365 
PrepareFileManagerDirs(int32_t userId)1366 int32_t MountManager::PrepareFileManagerDirs(int32_t userId)
1367 {
1368     for (const DirInfo &dir : fileManagerDir_) {
1369         uid_t dirUid = GetFileManagerUid(dir.uid, userId);
1370         std::string path = StringPrintf(dir.path.c_str(), userId);
1371         if (!PrepareDir(path, dir.mode, dirUid, dir.gid)) {
1372             std::string extraData = "dirPath=" + path + ",kernelCode=" + to_string(errno);
1373             StorageRadar::ReportUserManager("PrepareFileManagerDirs", userId, E_CREATE_DIR_FILE_MANAGER, extraData);
1374             return E_CREATE_DIR_FILE_MANAGER;
1375         }
1376     }
1377     return E_OK;
1378 }
1379 
CreateVirtualDirs(int32_t userId)1380 int32_t MountManager::CreateVirtualDirs(int32_t userId)
1381 {
1382     for (const DirInfo &dir : virtualDir_) {
1383         std::string path = StringPrintf(dir.path.c_str(), userId);
1384         if (CloudAndFuseDirFlag(path) && IsDir(path)) {
1385             continue;
1386         }
1387         /* 只要错误码不是ENOENT, 能够保证目录已经创建 */
1388         if (MediaFuseDirFlag(path) && (IsDir(path) || (errno != ENOENT))) {
1389             continue;
1390         }
1391         if (!PrepareDir(path, dir.mode, dir.uid, dir.gid)) {
1392             std::string extraData = "dirPath=" + path + ",kernelCode=" + to_string(errno);
1393             StorageRadar::ReportUserManager("CreateVirtualDirs", userId, E_CREATE_DIR_VIRTUAL, extraData);
1394             return E_CREATE_DIR_VIRTUAL;
1395         }
1396     }
1397     return E_OK;
1398 }
1399 
MountDfsDocs(int32_t userId,const std::string & relativePath,const std::string & networkId,const std::string & deviceId)1400 int32_t MountManager::MountDfsDocs(int32_t userId, const std::string &relativePath,
1401     const std::string &networkId, const std::string &deviceId)
1402 {
1403     LOGI("MountManager::MountDfsDocs start.");
1404     std::string dstPath = StringPrintf("/mnt/data/%d/hmdfs/%s/", userId, deviceId.c_str());
1405     if (!PrepareDir(dstPath, MODE_0711, OID_FILE_MANAGER, OID_FILE_MANAGER)) {
1406         return E_PREPARE_DIR;
1407     }
1408 
1409     std::regex pathRegex("^[a-zA-Z0-9_/]+$");
1410     if (relativePath.empty() || relativePath.length() > PATH_MAX || !std::regex_match(relativePath, pathRegex)) {
1411         LOGE("[MountDfsDocs]invalid relativePath");
1412         return E_PARAMS_INVALID;
1413     }
1414 
1415     Utils::MountArgument hmdfsMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, relativePath));
1416     std::string srcPath = hmdfsMntArgs.GetFullDst() + "/device_view/" + networkId + "/files/Docs/";
1417     auto startTime = StorageService::StorageRadar::RecordCurrentTime();
1418     int32_t ret = Mount(srcPath, dstPath, nullptr, MS_BIND, nullptr);
1419     if (ret != 0 && errno != EEXIST && errno != EBUSY) {
1420         LOGE("MountDfsDocs mount bind failed, errno is %{public}d", errno);
1421         return E_USER_MOUNT_ERR;
1422     }
1423     auto delay = StorageService::StorageRadar::ReportDuration(" MOUNT: MOUNT_DFS_DOCS",
1424         startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId);
1425     LOGI("SD_DURATION: MOUNT: MOUNT_DFS_DOCS, delayTime = %{public}s", delay.c_str());
1426     return E_OK;
1427 }
1428 
UMountDfsDocs(int32_t userId,const std::string & relativePath,const std::string & networkId,const std::string & deviceId)1429 int32_t MountManager::UMountDfsDocs(int32_t userId, const std::string &relativePath,
1430     const std::string &networkId, const std::string &deviceId)
1431 {
1432     LOGI("MountManager::UMountDfsDocs start.");
1433 
1434     std::regex pathRegex("^[a-zA-Z0-9_/]+$");
1435     if (relativePath.empty() || relativePath.length() > PATH_MAX || !std::regex_match(relativePath, pathRegex)) {
1436         LOGE("[UMountDfsDocs]invalid relativePath");
1437         return E_PARAMS_INVALID;
1438     }
1439 
1440     std::string dstPath = StringPrintf("/mnt/data/%d/hmdfs/%s", userId, deviceId.c_str());
1441     sync();
1442     auto startTime = StorageService::StorageRadar::RecordCurrentTime();
1443     int32_t ret = UMount2(dstPath, MNT_FORCE);
1444     if (ret != E_OK) {
1445         LOGE("UMountDfsDocs unmount bind failed, srcPath is %{public}s errno is %{public}d",
1446              dstPath.c_str(), errno);
1447         return E_USER_UMOUNT_ERR;
1448     }
1449     auto delay = StorageService::StorageRadar::ReportDuration("UMOUNT2: UMOUNT DFS DOCS",
1450         startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId);
1451     LOGI("MountManager::UMountDfsDocs end. SD_DURATION: delayTime = %{public}s", delay.c_str());
1452     if (!filesystem::is_empty(dstPath)) {
1453         LOGE("[UMountDfsDocs] Failed to umount");
1454         return E_NOT_EMPTY_TO_UMOUNT;
1455     }
1456     if (!RmDirRecurse(dstPath)) {
1457         LOGE("Failed to remove dir %{public}s", dstPath.c_str());
1458     }
1459     return E_OK;
1460 }
1461 
RestoreconSystemServiceDirs(int32_t userId)1462 int32_t MountManager::RestoreconSystemServiceDirs(int32_t userId)
1463 {
1464     int32_t err = E_OK;
1465 #ifdef USE_LIBRESTORECON
1466     for (const DirInfo &dir : systemServiceDir_) {
1467         std::string path = StringPrintf(dir.path.c_str(), userId);
1468         RestoreconRecurse(path.c_str());
1469         LOGD("systemServiceDir_ RestoreconRecurse path is %{public}s ", path.c_str());
1470     }
1471 #endif
1472     return err;
1473 }
1474 
CreateSystemServiceDirs(int32_t userId)1475 int32_t MountManager::CreateSystemServiceDirs(int32_t userId)
1476 {
1477     int32_t err = E_OK;
1478     for (const DirInfo &dir : systemServiceDir_) {
1479         std::string path = StringPrintf(dir.path.c_str(), userId);
1480         if (!PrepareDir(path, dir.mode, dir.uid, dir.gid)) {
1481             LOGE("failed to prepareDir %{public}s ", path.c_str());
1482             std::string extraData = "dirPath=" + path + ",kernelCode=" + to_string(errno);
1483             StorageRadar::ReportUserManager("CreateSystemServiceDirs", userId, E_CREATE_DIR_SA, extraData);
1484             err = E_CREATE_DIR_SA;
1485         }
1486     }
1487     return err;
1488 }
1489 
DestroySystemServiceDirs(int32_t userId)1490 int32_t MountManager::DestroySystemServiceDirs(int32_t userId)
1491 {
1492     bool err = true;
1493     for (const DirInfo &dir : systemServiceDir_) {
1494         std::string path = StringPrintf(dir.path.c_str(), userId);
1495         err = err && RmDirRecurse(path);
1496     }
1497     return err ? E_OK : E_DESTROY_DIR;
1498 }
1499 
DestroyHmdfsDirs(int32_t userId)1500 int32_t MountManager::DestroyHmdfsDirs(int32_t userId)
1501 {
1502     bool err = true;
1503 
1504     for (const DirInfo &dir : hmdfsDirVec_) {
1505         if (IsEndWith(dir.path.c_str(), "%d")) {
1506             err = err && RmDirRecurse(StringPrintf(dir.path.c_str(), userId));
1507         }
1508     }
1509 
1510     return err ? E_OK : E_DESTROY_DIR;
1511 }
1512 
1513 
DestroyFileManagerDirs(int32_t userId)1514 int32_t MountManager::DestroyFileManagerDirs(int32_t userId)
1515 {
1516     bool err = true;
1517 
1518     for (const DirInfo &dir : fileManagerDir_) {
1519         if (IsEndWith(dir.path.c_str(), "%d")) {
1520             err = err && RmDirRecurse(StringPrintf(dir.path.c_str(), userId));
1521         }
1522     }
1523 
1524     return err ? E_OK : E_DESTROY_DIR;
1525 }
1526 
SetFafQuotaProId(int32_t userId)1527 int32_t MountManager::SetFafQuotaProId(int32_t userId)
1528 {
1529     int32_t prjId = 0;
1530     for (const DirInfo &dir: fileManagerDir_) {
1531         QuotaManager::GetInstance().SetQuotaPrjId(StringPrintf(dir.path.c_str(), userId), prjId, true);
1532     }
1533     QuotaManager::GetInstance().SetQuotaPrjId(StringPrintf(SHARE_PATH.c_str(), userId), prjId, true);
1534     return E_OK;
1535 }
1536 
CheckMountFileByUser(int32_t userId)1537 bool MountManager::CheckMountFileByUser(int32_t userId)
1538 {
1539     for (const DirInfo &dir : virtualDir_) {
1540         std::string path = StringPrintf(dir.path.c_str(), userId);
1541         if (CloudAndFuseDirFlag(path) || MediaFuseDirFlag(path)) {
1542             continue;
1543         }
1544         if (access(path.c_str(), 0) != 0) {
1545             LOGI("VirtualDir : %{public}s is not exists", path.c_str());
1546             return false;
1547         }
1548     }
1549     LOGI("MountFile is exists");
1550     return true;
1551 }
1552 
CloudAndFuseDirFlag(const std::string & path)1553 bool MountManager::CloudAndFuseDirFlag(const std::string &path)
1554 {
1555     if (path.empty()) {
1556         return true;
1557     }
1558     std::regex cloudPattern("\\/mnt\\/data.*cloud");
1559     if (std::regex_match(path.c_str(), cloudPattern)) {
1560         return true;
1561     }
1562     std::regex cloudFusePattern("\\/mnt\\/data.*cloud_fuse");
1563     if (std::regex_match(path.c_str(), cloudFusePattern)) {
1564         return true;
1565     }
1566     return false;
1567 }
1568 
MediaFuseDirFlag(const std::string & path)1569 bool MountManager::MediaFuseDirFlag(const std::string &path)
1570 {
1571     if (path.empty()) {
1572         return true;
1573     }
1574     std::regex mediaFusePattern("\\/mnt\\/data.*media_fuse");
1575     if (std::regex_match(path.c_str(), mediaFusePattern)) {
1576         return true;
1577     }
1578     return false;
1579 }
1580 
SharedMount(int32_t userId,const std::string & path)1581 int32_t MountManager::SharedMount(int32_t userId, const std::string &path)
1582 {
1583     if (path.empty() || !IsDir(path)) {
1584         LOGE("path invalid, %{public}s", path.c_str());
1585         return E_OK;
1586     }
1587     int32_t ret = mount(path.c_str(), path.c_str(), nullptr, MS_BIND | MS_REC, nullptr);
1588     if (ret != 0) {
1589         LOGE("SharedMount failed, path is %{public}s, errno is %{public}d.", path.c_str(), errno);
1590         std::string extraData = "path=" + path + ",kernelCode=" + to_string(errno);
1591         StorageRadar::ReportUserManager("SharedMount", userId, E_MOUNT_SHARED, extraData);
1592         return E_MOUNT_SHARED;
1593     }
1594     ret = mount(nullptr, path.c_str(), nullptr, MS_SHARED, nullptr);
1595     if (ret != 0) {
1596         LOGE("SharedMount shared failed, path is %{public}s, errno is %{public}d.", path.c_str(), errno);
1597         return E_MOUNT_SHARED;
1598     }
1599     return E_OK;
1600 }
1601 
BindAndRecMount(int32_t userId,std::string & srcPath,std::string & dstPath,bool isUseSlave)1602 int32_t MountManager::BindAndRecMount(int32_t userId, std::string &srcPath, std::string &dstPath, bool isUseSlave)
1603 {
1604     if (srcPath.empty() || !IsDir(srcPath)) {
1605         LOGE("path invalid, %{public}s", srcPath.c_str());
1606         return E_NON_EXIST;
1607     }
1608     if (dstPath.empty() || !IsDir(dstPath)) {
1609         LOGE("path invalid, %{public}s", dstPath.c_str());
1610         return E_NON_EXIST;
1611     }
1612     if (IsPathMounted(dstPath)) {
1613         LOGE("path has mounted, %{public}s", dstPath.c_str());
1614         return E_OK;
1615     }
1616     int32_t ret = mount(srcPath.c_str(), dstPath.c_str(), nullptr, MS_BIND | MS_REC, nullptr);
1617     if (ret != 0 && errno != EEXIST && errno != EBUSY) {
1618         LOGE("bind and rec mount failed, srcPath is %{public}s, dstPath is %{public}s, errno is %{public}d.",
1619              srcPath.c_str(), dstPath.c_str(), errno);
1620         std::string extraData = "srcPath=" + srcPath + ",dstPath=" + dstPath + ",kernelCode=" + to_string(errno);
1621         StorageRadar::ReportUserManager("BindAndRecMount", userId, E_MOUNT_BIND_AND_REC, extraData);
1622         return E_MOUNT_BIND_AND_REC;
1623     }
1624     if (isUseSlave) {
1625         ret = mount(nullptr, dstPath.c_str(), nullptr, MS_SLAVE, nullptr);
1626     } else {
1627         ret = mount(nullptr, dstPath.c_str(), nullptr, MS_SHARED, nullptr);
1628     }
1629     if (ret != 0 && errno != EEXIST && errno != EBUSY) {
1630         LOGE("mount to slave or shared failed, path is %{public}s, errno is %{public}d.", dstPath.c_str(), errno);
1631         return ret;
1632     }
1633     return E_OK;
1634 }
1635 
GetAllUserId(std::vector<int32_t> & userIds)1636 void MountManager::GetAllUserId(std::vector<int32_t> &userIds)
1637 {
1638     const std::string &path = APP_EL1_PATH;
1639     if (!DirExist(path)) {
1640         return;
1641     }
1642     for (const auto &entry : filesystem::directory_iterator(path)) {
1643         if (!entry.is_directory()) {
1644             continue;
1645         }
1646         std::string subPath = entry.path().filename().string();
1647         if (!StringIsNumber(subPath)) {
1648             continue;
1649         }
1650         int32_t userId = atoi(subPath.c_str());
1651         if (userId < DEFAULT_USERID) {
1652             continue;
1653         }
1654         userIds.push_back(userId);
1655     }
1656 }
1657 
DirExist(const std::string & dir)1658 bool MountManager::DirExist(const std::string &dir)
1659 {
1660     filesystem::path filePath(dir);
1661     std::error_code errCode;
1662     if (!exists(filePath, errCode)) {
1663         LOGE("dir not exists, %{public}s", dir.c_str());
1664         return false;
1665     }
1666     return true;
1667 }
1668 
MountAppdata(const std::string & userId)1669 int32_t MountManager::MountAppdata(const std::string &userId)
1670 {
1671     std::vector<std::string> appdataSrc = APPDATA_SRC_PATH;
1672     std::vector<std::string> appdataDst = APPDATA_DST_PATH;
1673     int count = static_cast<int>(appdataSrc.size());
1674     int32_t uid = atoi(userId.c_str());
1675     for (int i = 0; i < count; i++) {
1676         std::string src = appdataSrc[i];
1677         std::string dst = appdataDst[i];
1678         ParseSandboxPath(src, userId, "");
1679         ParseSandboxPath(dst, userId, "");
1680         BindAndRecMount(uid, src, dst);
1681     }
1682     return E_OK;
1683 }
1684 
MountSharefsAndNoSharefs(int32_t userId)1685 int32_t MountManager::MountSharefsAndNoSharefs(int32_t userId)
1686 {
1687     Utils::MountArgument mountArgument(Utils::MountArgumentDescriptors::Alpha(userId, ""));
1688     std::string path = mountArgument.GetNoSharefsDocPath();
1689     SharedMount(userId, path);
1690 
1691     path = mountArgument.GetSharefsDocPath();
1692     SharedMount(userId, path);
1693 
1694     std::string src = APPDATA_SRC_PATH[0];
1695     std::string dst = APPDATA_DST_PATH[0];
1696     ParseSandboxPath(src, to_string(userId), "");
1697     ParseSandboxPath(dst, to_string(userId), "");
1698     BindAndRecMount(userId, src, dst);
1699     return E_OK;
1700 }
1701 
PrepareAppdataDirByUserId(int32_t userId)1702 int32_t MountManager::PrepareAppdataDirByUserId(int32_t userId)
1703 {
1704     for (const DirInfo &dir: appdataDir_) {
1705         std::string path = StringPrintf(dir.path.c_str(), userId);
1706         if (!PrepareDir(path, dir.mode, dir.uid, dir.gid)) {
1707             std::string extraData = "dirPath=" + path + ",kernelCode=" + to_string(errno);
1708             StorageRadar::ReportUserManager("PrepareAppdataDirByUserId", userId, E_CREATE_DIR_APPDATA, extraData);
1709             return E_CREATE_DIR_APPDATA;
1710         }
1711     }
1712     MountSharefsAndNoSharefs(userId);
1713     return E_OK;
1714 }
1715 
MountAppdataAndSharefs(int32_t userId)1716 int32_t MountManager::MountAppdataAndSharefs(int32_t userId)
1717 {
1718     LOGI("mount currentUser/other");
1719     Utils::MountArgument mountArgument(Utils::MountArgumentDescriptors::Alpha(userId, ""));
1720     std::string mediaDocPath = mountArgument.GetMediaDocsPath();
1721     std::string curOtherPath = mountArgument.GetCurOtherPath();
1722     BindAndRecMount(userId, mediaDocPath, curOtherPath);
1723 
1724     LOGI("mount currentUser/other/appdata");
1725     std::string noSharefsAppdataPath = mountArgument.GetNoSharefsAppdataPath();
1726     std::string curOtherAppdataPath = mountArgument.GetCurOtherAppdataPath();
1727     if (!IsDir(curOtherAppdataPath)) {
1728         if (MkDir(curOtherAppdataPath, MODE_0711)) {
1729             std::string extraData = "dirPath=" + curOtherAppdataPath + ",kernelCode=" + to_string(errno);
1730             StorageRadar::ReportUserManager("MountAppdataAndSharefs", userId, E_CREATE_DIR_APPDATA_OTHER, extraData);
1731         }
1732     }
1733     std::string curFileMgrAppdataPath = mountArgument.GetCurFileMgrAppdataPath();
1734     if (!IsDir(curFileMgrAppdataPath)) {
1735         if (MkDir(curFileMgrAppdataPath, MODE_0711)) {
1736             std::string extraData = "dirPath=" + curFileMgrAppdataPath + ",kernelCode=" + to_string(errno);
1737             StorageRadar::ReportUserManager("MountAppdataAndSharefs", userId, E_CREATE_DIR_APPDATA_FILEMGR, extraData);
1738         }
1739     }
1740     BindAndRecMount(userId, noSharefsAppdataPath, curOtherAppdataPath);
1741 
1742     LOGI("mount currentUser/filemgr");
1743     std::string curFileMgrPath = mountArgument.GetCurFileMgrPath();
1744     BindAndRecMount(userId, mediaDocPath, curFileMgrPath);
1745 
1746     LOGI("mount currentUser/filemgr/appdata");
1747     HmSharefsMount(userId, noSharefsAppdataPath, curFileMgrAppdataPath);
1748 
1749     LOGI("mount sharefs/docs/currentUser");
1750     std::string sharefsDocCurPath = mountArgument.GetSharefsDocCurPath();
1751     BindAndRecMount(userId, curOtherPath, sharefsDocCurPath, false);
1752 
1753     LOGI("mount nosharefs/docs/currentUser");
1754     std::string noSharefsDocCurPath = mountArgument.GetNoSharefsDocCurPath();
1755     BindAndRecMount(userId, curFileMgrPath, noSharefsDocCurPath, false);
1756     return E_OK;
1757 }
1758 
PrepareAppdataDir(int32_t userId)1759 int32_t MountManager::PrepareAppdataDir(int32_t userId)
1760 {
1761     if (userId == 0) {
1762         std::vector<int32_t> userIds;
1763         GetAllUserId(userIds);
1764         if (userIds.empty()) {
1765             return E_OK;
1766         }
1767         for (const int32_t &item: userIds) {
1768             PrepareAppdataDirByUserId(item);
1769         }
1770     } else {
1771         PrepareAppdataDirByUserId(userId);
1772     }
1773     return E_OK;
1774 }
1775 
UmountMntUserTmpfs(int32_t userId)1776 int32_t MountManager::UmountMntUserTmpfs(int32_t userId)
1777 {
1778     Utils::MountArgument mountArgument(Utils::MountArgumentDescriptors::Alpha(userId, ""));
1779     std::string path = mountArgument.GetSharefsDocCurPath() + "/appdata";
1780     auto startTime = StorageService::StorageRadar::RecordCurrentTime();
1781     int32_t res = UMount2(path, MNT_DETACH);
1782     if (res != E_OK && errno != ENOENT && errno != EINVAL) {
1783         LOGE("failed to umount with detach, path %{public}s, errno %{public}d.", path.c_str(), errno);
1784     }
1785     auto delay = StorageService::StorageRadar::ReportDuration("UMOUNT2: UMOUNT SHARE FS DOC CUR APPDATA",
1786         startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId);
1787     LOGI("SD_DURATION: UMOUNT2: UMOUNT SHARE FS DOC CUR APPDATA, delayTime = %{public}s", delay.c_str());
1788 
1789     startTime = StorageService::StorageRadar::RecordCurrentTime();
1790     path = mountArgument.GetCurOtherAppdataPath();
1791     res = UMount2(path, MNT_DETACH);
1792     if (res != E_OK && errno != ENOENT && errno != EINVAL) {
1793         LOGE("failed to umount with detach, path %{public}s, errno %{public}d.", path.c_str(), errno);
1794     }
1795     delay = StorageService::StorageRadar::ReportDuration("UMOUNT2: UMOUNT OTHER TEMP CUR APPDATA",
1796         startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId);
1797     LOGI("SD_DURATION: UMOUNT2: UMOUNT OTHER TEMP CUR APPDATA, delayTime = %{public}s", delay.c_str());
1798     return E_OK;
1799 }
1800 
1801 #ifdef STORAGE_SERVICE_MEDIA_FUSE
SetMediaObserverState(bool active)1802 void MountManager::SetMediaObserverState(bool active)
1803 {
1804     LOGI("set meidalibrary observer state start, active is %{public}d", active);
1805     if (active == true) {
1806         vector<string> bandleNameList = { MEDIALIBRARY_NAME };
1807         AppStateObserverManager::GetInstance().UnSubscribeAppState();
1808         AppStateObserverManager::GetInstance().SubscribeAppState(bandleNameList);
1809     }
1810     LOGI("set meidalibrary observer state end");
1811 }
1812 #endif
1813 
MountMediaFuse(int32_t userId,int32_t & devFd)1814 int32_t MountManager::MountMediaFuse(int32_t userId, int32_t &devFd)
1815 {
1816 #ifdef STORAGE_SERVICE_MEDIA_FUSE
1817     LOGI("start mount media fuse");
1818     UMountMediaFuse(userId);
1819     Utils::MountArgument mediaMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, ""));
1820     const string path = mediaMntArgs.GetFullMediaFuse();
1821     // open fuse
1822     devFd = open("/dev/fuse", O_RDWR);
1823     if (devFd < 0) {
1824         LOGE("open /dev/fuse fail for media, errno is %{public}d.", errno);
1825         return E_USER_MOUNT_ERR;
1826     }
1827     // mount fuse mountpoint
1828     string opt = StringPrintf("fd=%i,"
1829         "rootmode=40000,"
1830         "default_permissions,"
1831         "allow_other,"
1832         "user_id=0,group_id=0,"
1833         "context=\"u:object_r:hmdfs:s0\","
1834         "fscontext=u:object_r:hmdfs:s0",
1835         devFd);
1836     auto startTime = StorageService::StorageRadar::RecordCurrentTime();
1837     int ret = Mount("/dev/fuse", path.c_str(), "fuse", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opt.c_str());
1838     if (ret) {
1839         LOGE("failed to mount fuse for media, ret is %{public}d, errno is %{public}d.", ret, errno);
1840         close(devFd);
1841         std::string extraData = "dstPath=" + path + ",kernelCode=" + to_string(errno);
1842         StorageRadar::ReportUserManager("MountMediaFuse", userId, E_MOUNT_MEDIA_FUSE, extraData);
1843         return E_MOUNT_MEDIA_FUSE;
1844     }
1845     auto delay = StorageService::StorageRadar::ReportDuration("MOUNT: MOUNT MEDIA FUSE",
1846         startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId);
1847     LOGI("SD_DURATION: MOUNT: MOUNT MEDIA FUSE, delayTime = %{public}s", delay.c_str());
1848     SetMediaObserverState(true);
1849     LOGI("mount media fuse success, path is %{public}s", path.c_str());
1850 #endif
1851     return E_OK;
1852 }
1853 
UMountMediaFuse(int32_t userId)1854 int32_t MountManager::UMountMediaFuse(int32_t userId)
1855 {
1856 #ifdef STORAGE_SERVICE_MEDIA_FUSE
1857     int32_t err = E_OK;
1858     LOGI("start umount media fuse");
1859     Utils::MountArgument mediaMntArgs(Utils::MountArgumentDescriptors::Alpha(userId, ""));
1860     const string path = mediaMntArgs.GetFullMediaFuse();
1861     auto startTime = StorageService::StorageRadar::RecordCurrentTime();
1862     err = UMount2(path, MNT_DETACH);
1863     if (err != E_OK && errno != ENOENT && errno != EINVAL) {
1864         LOGE("media fuse umount failed, errno %{public}d", errno);
1865         std::string extraData = "dstPath=" + path + ",kernelCode=" + to_string(errno);
1866         StorageRadar::ReportUserManager("UMountMediaFuse", userId, E_UMOUNT_MEDIA_FUSE, extraData);
1867         return E_UMOUNT_MEDIA_FUSE;
1868     }
1869     auto delay = StorageService::StorageRadar::ReportDuration("UMOUNT2: UMOUNT MEDIA FUSE",
1870         startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId);
1871     LOGI("SD_DURATION: umount media fuse success, delayTime = %{public}s", delay.c_str());
1872 #endif
1873     return E_OK;
1874 }
1875 
MountFileMgrFuse(int32_t userId,const std::string & path,int32_t & fuseFd)1876 int32_t MountManager::MountFileMgrFuse(int32_t userId, const std::string &path, int32_t &fuseFd)
1877 {
1878     LOGI("mount file mgr fuse start, userId is %{public}d.", userId);
1879     fuseFd = open("/dev/fuse", O_RDWR);
1880     if (fuseFd < 0) {
1881         LOGE("open /dev/fuse fail for file mgr, errno is %{public}d.", errno);
1882         return E_OPEN_FUSE;
1883     }
1884     LOGI("open fuse end.");
1885     string opt = StringPrintf("fd=%i,"
1886         "rootmode=40000,"
1887         "default_permissions,"
1888         "allow_other,"
1889         "user_id=0,group_id=0,"
1890         "context=\"u:object_r:hmdfs:s0\","
1891         "fscontext=u:object_r:hmdfs:s0",
1892         fuseFd);
1893     auto startTime = StorageService::StorageRadar::RecordCurrentTime();
1894     int ret = Mount("/dev/fuse", path.c_str(), "fuse", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opt.c_str());
1895     if (ret) {
1896         LOGE("failed to mount fuse for file mgr, ret is %{public}d, errno is %{public}d.", ret, errno);
1897         close(fuseFd);
1898         std::string extraData = "dstPath=" + path + ",kernelCode=" + to_string(errno);
1899         StorageRadar::ReportUserManager("MountFileMgrFuse", userId, E_MOUNT_FILE_MGR_FUSE, extraData);
1900         return E_MOUNT_FILE_MGR_FUSE;
1901     }
1902     auto delay = StorageService::StorageRadar::ReportDuration("MOUNT: FILE MGR FUSE",
1903         startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId);
1904     LOGI("SD_DURATION: file mgr mount fuse success, delayTime = %{public}s", delay.c_str());
1905     return E_OK;
1906 }
1907 
UMountFileMgrFuse(int32_t userId,const std::string & path)1908 int32_t MountManager::UMountFileMgrFuse(int32_t userId, const std::string &path)
1909 {
1910     LOGI("umount file mgr fuse start, userId is %{public}d.", userId);
1911     auto startTime = StorageService::StorageRadar::RecordCurrentTime();
1912     int32_t ret = UMount2(path, MNT_DETACH);
1913     if (ret != E_OK && errno != ENOENT && errno != EINVAL) {
1914         LOGE("failed to umount fuse for file mgr, ret is %{public}d, errno is %{public}d.", ret, errno);
1915         std::string extraData = "dstPath=" + path + ",kernelCode=" + to_string(errno);
1916         StorageRadar::ReportUserManager("UMountFileMgrFuse", userId, E_UMOUNT_FILE_MGR_FUSE, extraData);
1917         return E_UMOUNT_FILE_MGR_FUSE;
1918     }
1919     auto delay = StorageService::StorageRadar::ReportDuration("UMOUNT2: UMOUNT FILE MGR FUSE",
1920         startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId);
1921     LOGI("SD_DURATION: UMOUNT2: UMOUNT FILE MGR FUSE success, delayTime = %{public}s.", delay.c_str());
1922     return E_OK;
1923 }
1924 
IsFileOccupied(const std::string & path,const std::vector<std::string> & inputList,std::vector<std::string> & outputList,bool & isOccupy)1925 int32_t MountManager::IsFileOccupied(const std::string &path, const std::vector<std::string> &inputList,
1926     std::vector<std::string> &outputList, bool &isOccupy)
1927 {
1928     if (path.empty()) {
1929         LOGE("path is invalid.");
1930         return E_PARAMS_INVALID;
1931     }
1932     if (inputList.empty() && path.back() == FILE_SEPARATOR_CHAR && path != FILE_MGR_ROOT_PATH) {
1933         LOGI("only modify dir.");
1934         return OpenProcForPath(path, isOccupy, true);
1935     }
1936     if (inputList.empty() && path.back() != FILE_SEPARATOR_CHAR) {
1937         LOGI("only modify file.");
1938         return OpenProcForPath(path, isOccupy, false);
1939     }
1940     if (path == FILE_MGR_ROOT_PATH || (!inputList.empty() && path.back() == FILE_SEPARATOR_CHAR)) {
1941         LOGI("multi select file, input size is %{public}zu.", inputList.size());
1942         std::set<std::string> occupyFiles;
1943         int32_t ret = OpenProcForMulti(path, occupyFiles);
1944         if (ret != E_OK) {
1945             LOGE("failed to open proc, ret is %{public}d", ret);
1946             return ret;
1947         }
1948         if (occupyFiles.empty()) {
1949             LOGI("there has no occupy.");
1950             isOccupy = false;
1951             return E_OK;
1952         }
1953         if (path == FILE_MGR_ROOT_PATH) {
1954             for (const std::string &item: occupyFiles) {
1955                 outputList.push_back(item);
1956             }
1957             isOccupy = !outputList.empty();
1958             LOGI("output size is %{public}zu.", outputList.size());
1959             return E_OK;
1960         }
1961         for (const std::string &item: inputList) {
1962             if (occupyFiles.find(item) != occupyFiles.end()) {
1963                 outputList.push_back(item);
1964             }
1965         }
1966         isOccupy = !outputList.empty();
1967         LOGI("output size is %{public}zu.", outputList.size());
1968         return E_OK;
1969     }
1970     LOGE("param is invalid.");
1971     return E_PARAMS_INVALID;
1972 }
1973 
OpenProcForMulti(const std::string & path,std::set<std::string> & occupyFiles)1974 int32_t MountManager::OpenProcForMulti(const std::string &path, std::set<std::string> &occupyFiles)
1975 {
1976     auto procDir = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(PID_PROC.c_str()), closedir);
1977     if (!procDir) {
1978         LOGE("failed to open dir proc, err %{public}d", errno);
1979         return E_UMOUNT_PROC_OPEN;
1980     }
1981     struct dirent *entry;
1982     while ((entry = readdir(procDir.get())) != nullptr) {
1983         if (entry->d_type != DT_DIR) {
1984             continue;
1985         }
1986         std::string name = entry->d_name;
1987         if (!StringIsNumber(name)) {
1988             continue;
1989         }
1990         std::string pidPath = PID_PROC + FILE_SEPARATOR_CHAR + name;
1991         FindProcForMulti(pidPath, path, occupyFiles);
1992     }
1993     return E_OK;
1994 }
1995 
OpenProcForPath(const std::string & path,bool & isOccupy,bool isDir)1996 int32_t MountManager::OpenProcForPath(const std::string &path, bool &isOccupy, bool isDir)
1997 {
1998     auto procDir = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(PID_PROC.c_str()), closedir);
1999     if (!procDir) {
2000         LOGE("failed to open dir proc, err %{public}d", errno);
2001         return E_UMOUNT_PROC_OPEN;
2002     }
2003     struct dirent *entry;
2004     while ((entry = readdir(procDir.get())) != nullptr) {
2005         if (entry->d_type != DT_DIR) {
2006             continue;
2007         }
2008         std::string name = entry->d_name;
2009         if (!StringIsNumber(name)) {
2010             continue;
2011         }
2012         std::string pidPath = PID_PROC + FILE_SEPARATOR_CHAR + name;
2013         if (FindProcForPath(pidPath, path, isDir)) {
2014             isOccupy = true;
2015             break;
2016         }
2017     }
2018     LOGI("OpenProcForPath end, res is %{public}d.", isOccupy);
2019     return E_OK;
2020 }
2021 
FindProcForPath(const std::string & pidPath,const std::string & path,bool isDir)2022 bool MountManager::FindProcForPath(const std::string &pidPath, const std::string &path, bool isDir)
2023 {
2024     if (CheckSymlinkForPath(pidPath + FILE_SEPARATOR_CHAR + PID_CWD, path, isDir)) {
2025         return true;
2026     }
2027     if (CheckSymlinkForPath(pidPath + FILE_SEPARATOR_CHAR + PID_EXE, path, isDir)) {
2028         return true;
2029     }
2030     if (CheckSymlinkForPath(pidPath + FILE_SEPARATOR_CHAR + PID_ROOT, path, isDir)) {
2031         return true;
2032     }
2033     std::string fdPath = pidPath + FILE_SEPARATOR_CHAR + PID_FD;
2034     auto fdDir = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(fdPath.c_str()), closedir);
2035     if (!fdDir) {
2036         LOGE("unable to open %{public}s, err %{public}d", fdPath.c_str(), errno);
2037         return false;
2038     }
2039     struct dirent* fdDirent;
2040     while ((fdDirent = readdir(fdDir.get())) != nullptr) {
2041         if (fdDirent->d_type != DT_LNK) {
2042             continue;
2043         }
2044         if (CheckSymlinkForPath(fdPath + FILE_SEPARATOR_CHAR + fdDirent->d_name, path, isDir)) {
2045             return true;
2046         }
2047     }
2048     return false;
2049 }
2050 
CheckSymlinkForPath(const std::string & fdPath,const std::string & path,bool isDir)2051 bool MountManager::CheckSymlinkForPath(const std::string &fdPath, const std::string &path, bool isDir)
2052 {
2053     char realPath[PATH_MAX_FOR_LINK];
2054     int res = readlink(fdPath.c_str(), realPath, sizeof(realPath) - 1);
2055     if (res < 0) {
2056         LOGE("readlink failed for path, errno is %{public}d.", errno);
2057         return false;
2058     }
2059     realPath[res] = '\0';
2060     std::string realPathStr(realPath);
2061     if (isDir) {
2062         if (realPathStr.find(UN_REACHABLE) == 0) {
2063             realPathStr = realPathStr.substr(UN_REACHABLE.size()) + FILE_SEPARATOR_CHAR;
2064         }
2065         if (realPathStr.find(path) == 0) {
2066             LOGE("find a fd from link for dir, %{public}s", realPathStr.c_str());
2067             return true;
2068         }
2069     } else {
2070         if (realPathStr.find(UN_REACHABLE) == 0) {
2071             realPathStr = realPathStr.substr(UN_REACHABLE.size());
2072         }
2073         if (realPathStr == path) {
2074             LOGE("find a fd from link for file, %{public}s", realPathStr.c_str());
2075             return true;
2076         }
2077     }
2078     return false;
2079 }
2080 
FindProcForMulti(const std::string & pidPath,const std::string & path,std::set<std::string> & occupyFiles)2081 void MountManager::FindProcForMulti(const std::string &pidPath, const std::string &path,
2082     std::set<std::string> &occupyFiles)
2083 {
2084     CheckSymlinkForMulti(pidPath + FILE_SEPARATOR_CHAR + PID_CWD, path, occupyFiles);
2085     CheckSymlinkForMulti(pidPath + FILE_SEPARATOR_CHAR + PID_EXE, path, occupyFiles);
2086     CheckSymlinkForMulti(pidPath + FILE_SEPARATOR_CHAR + PID_ROOT, path, occupyFiles);
2087     std::string fdPath = pidPath + FILE_SEPARATOR_CHAR + PID_FD;
2088     auto fdDir = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(fdPath.c_str()), closedir);
2089     if (!fdDir) {
2090         LOGE("unable to open %{public}s, err %{public}d", fdPath.c_str(), errno);
2091         return;
2092     }
2093     struct dirent* fdDirent;
2094     while ((fdDirent = readdir(fdDir.get())) != nullptr) {
2095         if (fdDirent->d_type != DT_LNK) {
2096             continue;
2097         }
2098         CheckSymlinkForMulti(fdPath + FILE_SEPARATOR_CHAR + fdDirent->d_name, path, occupyFiles);
2099     }
2100 }
2101 } // namespace StorageDaemon
2102 } // namespace OHOS
2103