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