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