• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "volume/external_volume_info.h"
17 
18 #include <fcntl.h>
19 #include <future>
20 #include <sys/stat.h>
21 #include <sys/wait.h>
22 #include <unistd.h>
23 #include <filesystem>
24 
25 #include "storage_service_errno.h"
26 #include "storage_service_log.h"
27 #include "utils/disk_utils.h"
28 #include "utils/file_utils.h"
29 #include "utils/storage_radar.h"
30 #include "utils/string_utils.h"
31 #include "volume/process.h"
32 
33 #define STORAGE_MANAGER_IOC_CHK_BUSY _IOR(0xAC, 77, int)
34 constexpr uid_t FILE_MANAGER_UID = 1006;
35 constexpr gid_t FILE_MANAGER_GID = 1006;
36 using namespace std;
37 using namespace OHOS::StorageService;
38 namespace OHOS {
39 namespace StorageDaemon {
40 constexpr int32_t WAIT_THREAD_TIMEOUT_S = 15;
41 constexpr int32_t FILE_NOT_EXIST = 2;
42 constexpr int UID_FILE_MANAGER = 1006;
ReadMetadata()43 int32_t ExternalVolumeInfo::ReadMetadata()
44 {
45     int32_t ret = OHOS::StorageDaemon::ReadMetadata(devPath_, fsUuid_, fsType_, fsLabel_);
46     if (fsType_ == "ntfs" && (fsLabel_.find('?') != std::string::npos || fsLabel_ == "")) {
47         std::vector<std::string> cmd;
48         cmd = {
49             "ntfslabel",
50             devPath_
51         };
52         fsLabel_ = GetBlkidDataByCmd(cmd);
53     }
54     return ret;
55 }
56 
GetFsType()57 std::string ExternalVolumeInfo::GetFsType()
58 {
59     return fsType_;
60 }
61 
GetFsUuid()62 std::string ExternalVolumeInfo::GetFsUuid()
63 {
64     return fsUuid_;
65 }
66 
GetFsLabel()67 std::string ExternalVolumeInfo::GetFsLabel()
68 {
69     return fsLabel_;
70 }
71 
GetMountPath()72 std::string ExternalVolumeInfo::GetMountPath()
73 {
74     return mountPath_;
75 }
76 
DoCreate(dev_t dev)77 int32_t ExternalVolumeInfo::DoCreate(dev_t dev)
78 {
79     int32_t ret = 0;
80     string id = VolumeInfo::GetVolumeId();
81 
82     device_ = dev;
83     devPath_ = StringPrintf(devPathDir_.c_str(), (id).c_str());
84 
85     ret = mknod(devPath_.c_str(), S_IFBLK, dev);
86     if (ret) {
87         LOGE("External volume DoCreate error.");
88         return E_ERR;
89     }
90     return E_OK;
91 }
92 
DoDestroy()93 int32_t ExternalVolumeInfo::DoDestroy()
94 {
95     int err = remove(devPath_.c_str());
96     if (err) {
97         LOGE("External volume DoDestroy error.");
98         return E_ERR;
99     }
100     return E_OK;
101 }
102 
DoMount4Ext(uint32_t mountFlags)103 int32_t ExternalVolumeInfo::DoMount4Ext(uint32_t mountFlags)
104 {
105     mode_t mode = 0777;
106     int32_t ret = mount(devPath_.c_str(), mountPath_.c_str(), fsType_.c_str(), mountFlags, "");
107     if (ret) {
108         return E_EXT_MOUNT;
109     }
110     TravelChmod(mountPath_, mode);
111     return ret;
112 }
113 
DoMount4Hmfs(uint32_t mountFlags)114 int32_t ExternalVolumeInfo::DoMount4Hmfs(uint32_t mountFlags)
115 {
116     mode_t mode = 0777;
117     const char *fsType = "hmfs";
118     auto mountData = StringPrintf("context=u:object_r:mnt_external_file:s0");
119     int32_t ret = mount(devPath_.c_str(), mountPath_.c_str(), fsType, mountFlags, mountData.c_str());
120     if (!ret) {
121         TravelChmod(mountPath_, mode);
122         StorageRadar::ReportVolumeOperation("ExternalVolumeInfo::DoMount4Hmfs", ret);
123     }
124     return ret;
125 }
126 
DoMount4Ntfs(uint32_t mountFlags)127 int32_t ExternalVolumeInfo::DoMount4Ntfs(uint32_t mountFlags)
128 {
129 #ifdef EXTERNAL_STORAGE_QOS_TRANS
130     auto mountData = StringPrintf("rw,big_writes,uid=%d,gid=%d,dmask=0007,fmask=0007",
131         UID_FILE_MANAGER, UID_FILE_MANAGER);
132 #else
133     auto mountData = StringPrintf("rw,uid=%d,gid=%d,dmask=0007,fmask=0007", UID_FILE_MANAGER, UID_FILE_MANAGER);
134 #endif
135     if (mountFlags & MS_RDONLY) {
136         mountData = StringPrintf("ro,uid=%d,gid=%d,dmask=0007,fmask=0007", UID_FILE_MANAGER, UID_FILE_MANAGER);
137     }
138 
139     std::vector<std::string> cmd = {
140         "mount.ntfs",
141         devPath_,
142         mountPath_,
143         "-o",
144         mountData.c_str()
145     };
146     std::vector<std::string> output;
147 #ifdef EXTERNAL_STORAGE_QOS_TRANS
148     if (ExtStorageMountForkExec(cmd) != E_OK) {
149         LOGE("ext exec mount for ntfs failed, errno is %{public}d.", errno);
150         return E_NTFS_MOUNT;
151     }
152     return E_OK;
153 #else
154     if (ForkExec(cmd, &output) != E_OK) {
155         LOGE("exec mount for ntfs failed, errno is %{public}d.", errno);
156         return E_NTFS_MOUNT;
157     }
158     return E_OK;
159 #endif
160 }
161 
DoMount4Exfat(uint32_t mountFlags)162 int32_t ExternalVolumeInfo::DoMount4Exfat(uint32_t mountFlags)
163 {
164     auto mountData = StringPrintf("rw,uid=%d,gid=%d,dmask=0007,fmask=0007", UID_FILE_MANAGER, UID_FILE_MANAGER);
165     if (mountFlags & MS_RDONLY) {
166         mountData = StringPrintf("ro,uid=%d,gid=%d,dmask=0007,fmask=0007", UID_FILE_MANAGER, UID_FILE_MANAGER);
167     }
168 
169     std::vector<std::string> cmd = {
170         "mount.exfat",
171         "-o",
172         mountData.c_str(),
173         devPath_,
174         mountPath_,
175     };
176     std::vector<std::string> output;
177 #ifdef EXTERNAL_STORAGE_QOS_TRANS
178     if (ExtStorageMountForkExec(cmd) != E_OK) {
179         LOGE("ext exec mount for exfat failed, errno is %{public}d.", errno);
180         return E_EXFAT_MOUNT;
181     }
182     return E_OK;
183 #else
184     if (ForkExec(cmd, &output) != E_OK) {
185         LOGE("exec mount for exfat failed, errno is %{public}d.", errno);
186         return E_EXFAT_MOUNT;
187     }
188     return E_OK;
189 #endif
190 }
191 
DoCheck4Exfat()192 int32_t ExternalVolumeInfo::DoCheck4Exfat()
193 {
194     std::vector<std::string> cmd = {
195         "fsck.exfat",
196         "-n",
197         devPath_,
198     };
199     int execRet = ForkExecWithExit(cmd);
200     LOGI("execRet: %{public}d", execRet);
201     if (execRet != E_OK) {
202         return E_VOL_NEED_FIX;
203     }
204     return E_OK;
205 }
206 
DoCheck4Ntfs()207 int32_t ExternalVolumeInfo::DoCheck4Ntfs()
208 {
209     std::vector<std::string> cmd = {
210         "fsck.ntfs",
211         devPath_,
212     };
213     int execRet = ForkExecWithExit(cmd);
214     LOGI("execRet: %{public}d", execRet);
215     if (execRet != E_OK) {
216         return E_VOL_NEED_FIX;
217     }
218     return E_OK;
219 }
220 
DoFix4Ntfs()221 int32_t ExternalVolumeInfo::DoFix4Ntfs()
222 {
223     LOGE("DoFix4Ntfs");
224     std::vector<std::string> cmd = {
225         "ntfsfix",
226         "-d",
227         devPath_
228     };
229     std::vector<std::string> output;
230 #ifdef EXTERNAL_STORAGE_QOS_TRANS
231     if (ExtStorageMountForkExec(cmd) != E_OK) {
232         LOGE("ext exec fix for ntfs failed, errno is %{public}d.", errno);
233         return E_VOL_FIX_FAILED;
234     }
235     return E_OK;
236 #else
237     if (ForkExec(cmd, &output) != E_OK) {
238         LOGE("exec fix for ntfs failed, errno is %{public}d.", errno);
239         return E_VOL_FIX_FAILED;
240     }
241     return E_OK;
242 #endif
243 }
244 
DoFix4Exfat()245 int32_t ExternalVolumeInfo::DoFix4Exfat()
246 {
247     LOGE("DoFix4Exfat");
248     std::vector<std::string> cmd = {
249         "fsck.exfat",
250         "-p",
251         devPath_,
252     };
253     std::vector<std::string> output;
254 #ifdef EXTERNAL_STORAGE_QOS_TRANS
255     if (ExtStorageMountForkExec(cmd) != E_OK) {
256         LOGE("ext exec fix for exfat failed, errno is %{public}d.", errno);
257         return E_VOL_FIX_FAILED;
258     }
259     return E_OK;
260 #else
261     if (ForkExec(cmd, &output) != E_OK) {
262         LOGE("exec fix for exfat failed, errno is %{public}d.", errno);
263         return E_VOL_FIX_FAILED;
264     }
265     return E_OK;
266 #endif
267 }
268 
DoMount4OtherType(uint32_t mountFlags)269 int32_t ExternalVolumeInfo::DoMount4OtherType(uint32_t mountFlags)
270 {
271     mountFlags |= MS_MGC_VAL;
272     auto mountData = StringPrintf("uid=%d,gid=%d,dmask=0007,fmask=0007", UID_FILE_MANAGER, UID_FILE_MANAGER);
273     int32_t ret = mount(devPath_.c_str(), mountPath_.c_str(), fsType_.c_str(), mountFlags, mountData.c_str());
274     if (ret) {
275         return E_OTHER_MOUNT;
276     }
277     return ret;
278 }
279 
DoMount4Vfat(uint32_t mountFlags)280 int32_t ExternalVolumeInfo::DoMount4Vfat(uint32_t mountFlags)
281 {
282     mountFlags |= MS_MGC_VAL;
283     auto mountData = StringPrintf("uid=%d,gid=%d,dmask=0007,fmask=0007,utf8", UID_FILE_MANAGER, UID_FILE_MANAGER);
284     int32_t ret = mount(devPath_.c_str(), mountPath_.c_str(), fsType_.c_str(), mountFlags, mountData.c_str());
285     if (ret) {
286         return E_FAT_MOUNT;
287     }
288     return ret;
289 }
290 
DoMount(uint32_t mountFlags)291 int32_t ExternalVolumeInfo::DoMount(uint32_t mountFlags)
292 {
293     int32_t ret = DoCheck();
294     if (ret != E_OK) {
295         LOGE("External volume uuid=%{public}s check failed.", GetAnonyString(GetFsUuid()).c_str());
296         return E_DOCHECK_MOUNT;
297     }
298     if (IsUsbFuse()) {
299         ret = CreateFuseMountPath();
300     } else {
301         ret = CreateMountPath();
302     }
303     if (ret != E_OK) {
304         return ret;
305     }
306     if ((fsType_ == "hmfs" || fsType_ == "f2fs") && GetIsUserdata()) {
307         ret = DoMount4Hmfs(mountFlags);
308     }
309     if (ret) {
310         LOGE("External volume DoMount error, errno = %{public}d", errno);
311         remove(mountPath_.c_str());
312         return E_HMFS_MOUNT;
313     }
314     std::promise<int32_t> promise;
315     std::future<int32_t> future = promise.get_future();
316     std::thread mountThread ([this, mountFlags, p = std::move(promise)]() mutable {
317         LOGI("Ready to mount: volume fstype is %{public}s, mountflag is %{public}d", fsType_.c_str(), mountFlags);
318         int retValue = E_OK;
319         if (fsType_ == "ntfs") retValue = DoMount4Ntfs(mountFlags);
320         else if (fsType_ == "exfat") retValue = DoMount4Exfat(mountFlags);
321         else if (fsType_ == "vfat" || fsType_ == "fat32") retValue = DoMount4Vfat(mountFlags);
322         else if ((fsType_ == "hmfs" || fsType_ == "f2fs") && GetIsUserdata()) retValue = E_OK;
323         else retValue = E_OTHER_MOUNT;
324         p.set_value(retValue);
325     });
326     if (future.wait_for(std::chrono::seconds(WAIT_THREAD_TIMEOUT_S)) == std::future_status::timeout) {
327         LOGE("Mount timed out");
328         remove(mountPath_.c_str());
329         mountThread.detach();
330         return E_TIMEOUT_MOUNT;
331     }
332     ret = future.get();
333     mountThread.join();
334     if (ret) {
335         LOGE("External volume DoMount error, errno = %{public}d", errno);
336         remove(mountPath_.c_str());
337         return ret;
338     }
339     mountPath_ = mountBackupPath_;
340     return E_OK;
341 }
342 
IsUsbInUse(int fd)343 int32_t ExternalVolumeInfo::IsUsbInUse(int fd)
344 {
345     int32_t inUse = -1;
346     if (ioctl(fd, STORAGE_MANAGER_IOC_CHK_BUSY, &inUse) < 0) {
347         LOGE("ioctl check in use failed errno %{public}d", errno);
348         return E_IOCTL_FAILED;
349     }
350     if (inUse) {
351         LOGI("usb inuse number is %{public}d", inUse);
352         return E_USB_IN_USE;
353     }
354     LOGI("usb not inUse");
355     return E_OK;
356 }
357 
DoUMount(bool force)358 int32_t ExternalVolumeInfo::DoUMount(bool force)
359 {
360     if (force && !IsUsbFuse()) {
361         LOGI("External volume start force to unmount.");
362         Process ps(mountPath_);
363         ps.UpdatePidByPath();
364         ps.KillProcess(SIGKILL);
365         umount2(mountPath_.c_str(), MNT_DETACH);
366         remove(mountPath_.c_str());
367         LOGI("External volume force to unmount success.");
368         return E_OK;
369     }
370     if (IsUsbFuse()) {
371         mountPath_ = mountUsbFusePath_;
372     }
373     int fd = open(mountPath_.c_str(), O_RDONLY);
374     if (fd < 0) {
375         LOGE("open file fail mountPath %{public}s, errno %{public}d", GetAnonyString(mountPath_).c_str(), errno);
376     }
377     if (fd >= 0) {
378         IsUsbInUse(fd);
379     }
380 
381     LOGI("External volume start to unmount mountPath: %{public}s.", GetAnonyString(mountPath_).c_str());
382     int ret = umount2(mountPath_.c_str(), MNT_DETACH);
383     if (ret != E_OK) {
384         LOGE("umount2 failed errno %{public}d", errno);
385     }
386     if (fd >= 0) {
387         IsUsbInUse(fd);
388         close(fd);
389     }
390 
391     int err = remove(mountPath_.c_str());
392     if (err && ret) {
393         LOGE("External volume DoUmount error.");
394         return E_VOL_UMOUNT_ERR;
395     }
396     if (err && errno != FILE_NOT_EXIST) {
397         LOGE("failed to call remove(%{public}s) error, errno = %{public}d", GetAnonyString(mountPath_).c_str(), errno);
398         return E_RMDIR_MOUNT;
399     }
400     mountPath_ = mountBackupPath_;
401 
402     LOGI("External volume unmount success.");
403     return E_OK;
404 }
405 
DoUMountUsbFuse()406 int32_t ExternalVolumeInfo::DoUMountUsbFuse()
407 {
408     LOGI("DoUMountUsbFuse in.");
409     int ret = umount2(mountPath_.c_str(), MNT_DETACH);
410     if (ret != E_OK) {
411         LOGE("umount2 mountUsbFusePath failed errno %{public}d", errno);
412     }
413 
414     int err = rmdir(mountPath_.c_str());
415     if (err) {
416         LOGE("External volume DoUMountUsbFuse error: rmdir failed, errno %{public}d", errno);
417         return E_RMDIR_MOUNT;
418     }
419     LOGI("DoUMountUsbFuse success.");
420     return E_OK;
421 }
422 
DoTryToCheck()423 int32_t ExternalVolumeInfo::DoTryToCheck()
424 {
425     int32_t ret = DoCheck();
426     if (ret != E_OK) {
427         LOGE("External volume uuid=%{public}s check failed.", GetAnonyString(GetFsUuid()).c_str());
428         return E_DOCHECK_MOUNT;
429     }
430 
431     if (fsType_ != "ntfs" && fsType_ != "exfat") {
432         LOGE("Volume type %{public}s, is not support fix", fsType_.c_str());
433         return E_OK;
434     }
435 
436     std::promise<int32_t> promise;
437     std::future<int32_t> future = promise.get_future();
438     std::thread mountThread ([this, p = std::move(promise)]() mutable {
439         LOGI("Ready to DoTryToCheck: volume fstype is %{public}s", fsType_.c_str());
440         int retValue = E_OK;
441         if (fsType_ == "ntfs") retValue = DoCheck4Ntfs();
442         else if (fsType_ == "exfat") retValue = DoCheck4Exfat();
443         else retValue = E_VOL_FIX_NOT_SUPPORT;
444         LOGI("DoTryToCheck cmdRet:%{public}d", retValue);
445         p.set_value(retValue);
446     });
447     if (future.wait_for(std::chrono::seconds(WAIT_THREAD_TIMEOUT_S)) == std::future_status::timeout) {
448         LOGE("DoTryToCheck timed out");
449         mountThread.detach();
450         return E_TIMEOUT_MOUNT;
451     }
452 
453     ret = future.get();
454     mountThread.join();
455     if (ret != E_OK) {
456         LOGE("External volume DoTryToCheck error, maybe need fix, errno = %{public}d", ret);
457         return E_VOL_NEED_FIX;
458     }
459     return E_OK;
460 }
461 
DoTryToFix()462 int32_t ExternalVolumeInfo::DoTryToFix()
463 {
464     int32_t ret = DoCheck();
465     if (ret != E_OK) {
466         LOGE("External volume uuid=%{public}s check failed.", GetAnonyString(GetFsUuid()).c_str());
467         return E_DOCHECK_MOUNT;
468     }
469 
470     if (fsType_ != "ntfs" && fsType_ != "exfat") {
471         LOGE("Volume type %{public}s, is not support fix", fsType_.c_str());
472         return E_VOL_FIX_NOT_SUPPORT;
473     }
474     std::promise<int32_t> promise;
475     std::future<int32_t> future = promise.get_future();
476     std::thread mountThread ([this, p = std::move(promise)]() mutable {
477         LOGI("Ready to mount: volume fstype is %{public}s", fsType_.c_str());
478         int retValue = E_OK;
479         if (fsType_ == "ntfs") retValue = DoFix4Ntfs();
480         else if (fsType_ == "exfat") retValue = DoFix4Exfat();
481         p.set_value(retValue);
482     });
483     if (future.wait_for(std::chrono::seconds(WAIT_THREAD_TIMEOUT_S)) == std::future_status::timeout) {
484         LOGE("Fix timed out");
485         mountThread.detach();
486         return E_TIMEOUT_MOUNT;
487     }
488 
489     ret = future.get();
490     mountThread.join();
491     LOGI("DoTryToFix: volume fstype is %{public}s, ret: %{public}d, errno: %{public}d", fsType_.c_str(), ret, errno);
492     return ret;
493 }
494 
DoCheck()495 int32_t ExternalVolumeInfo::DoCheck()
496 {
497     int32_t ret = ExternalVolumeInfo::ReadMetadata();
498     if (ret) {
499         LOGE("External volume uuid=%{public}s DoCheck failed.", GetAnonyString(GetFsUuid()).c_str());
500         return E_CHECK;
501     }
502 
503     // check fstype
504     for (std::string item : supportMountType_) {
505         if (item == fsType_) {
506             return E_OK;
507         }
508     }
509     LOGE("External Volume type not support.");
510     return E_NOT_SUPPORT;
511 }
512 
DoFormat(std::string type)513 int32_t ExternalVolumeInfo::DoFormat(std::string type)
514 {
515     int32_t err = 0;
516     if (IsUsbFuse() && IsPathMounted(mountPath_)) {
517         err = DoUMountUsbFuse();
518     }
519     if (err != E_OK) {
520         return err;
521     }
522 
523     std::map<std::string, std::string>::iterator iter = supportFormatType_.find(type);
524     if (iter == supportFormatType_.end()) {
525         LOGE("External volume format not support.");
526         return E_NOT_SUPPORT;
527     }
528     std::vector<std::string> output;
529     if (type == "vfat") {
530         std::vector<std::string> cmd = {
531             iter->second,
532             "-A",
533             devPath_
534         };
535         err = ForkExec(cmd, &output);
536     } else {
537         std::vector<std::string> cmd = {
538             iter->second,
539             devPath_
540         };
541         err = ForkExec(cmd, &output);
542     }
543 
544     if (err == E_NO_CHILD) {
545         err = E_OK;
546     }
547     ReadMetadata();
548     LOGI("do format end, err is %{public}d.", err);
549     return err;
550 }
551 
DoSetVolDesc(std::string description)552 int32_t ExternalVolumeInfo::DoSetVolDesc(std::string description)
553 {
554     int32_t err = 0;
555     std::vector<std::string> output;
556     if (fsType_ == "ntfs") {
557         std::vector<std::string> fixCmd = {
558             "ntfsfix",
559             "-d",
560             devPath_
561         };
562         err = ForkExec(fixCmd, &output);
563         std::vector<std::string> labelCmd = {
564             "ntfslabel",
565             devPath_,
566             description
567         };
568         output.clear();
569         err = ForkExec(labelCmd, &output);
570     } else if (fsType_ == "exfat") {
571         std::vector<std::string> cmd = {
572             "exfatlabel",
573             devPath_,
574             description
575         };
576         err = ForkExec(cmd, &output);
577     } else if (fsType_ == "hmfs") {
578         std::vector<std::string> cmd = {
579             "hmfslabel",
580             devPath_,
581             description
582         };
583         err = ForkExec(cmd, &output);
584     } else {
585         LOGE("SetVolumeDescription fsType not support.");
586         return E_NOT_SUPPORT;
587     }
588     ReadMetadata();
589     LOGI("do set vol desc end, err is %{public}d.", err);
590     return err;
591 }
592 
CreateFuseMountPath()593 int32_t ExternalVolumeInfo::CreateFuseMountPath()
594 {
595     struct stat statbuf;
596     mountBackupPath_ = StringPrintf(mountPathDir_.c_str(), fsUuid_.c_str());
597     mountUsbFusePath_ = StringPrintf(mountFusePathDir_.c_str(), fsUuid_.c_str());
598     std::string mountFusePath = "/mnt/data/external_fuse";
599     bool ret = true;
600     if (lstat(mountFusePath.c_str(), &statbuf)) {
601         ret = PrepareDir("/mnt/data/external_fuse", S_IRWXU | S_IRWXG | S_IXOTH, FILE_MANAGER_UID, FILE_MANAGER_GID);
602         if (!ret) {
603             LOGE("create path %{public}s failed", mountFusePath.c_str());
604             return E_MKDIR_MOUNT;
605         }
606     }
607 
608     if (!lstat(mountUsbFusePath_.c_str(), &statbuf)) {
609         LOGE("volume mount path %{public}s exists, please remove first", GetAnonyString(mountUsbFusePath_).c_str());
610         remove(mountUsbFusePath_.c_str());
611         return E_SYS_KERNEL_ERR;
612     }
613     ret = PrepareDir(mountUsbFusePath_, S_IRWXU | S_IRWXG | S_IXOTH, FILE_MANAGER_UID, FILE_MANAGER_GID);
614     if (!ret) {
615         LOGE("the volume %{public}s create path %{public}s failed",
616              GetVolumeId().c_str(), GetAnonyString(mountUsbFusePath_).c_str());
617         return E_MKDIR_MOUNT;
618     }
619     mountPath_ = mountUsbFusePath_;
620     return E_OK;
621 }
622 
CreateMountPath()623 int32_t ExternalVolumeInfo::CreateMountPath()
624 {
625     struct stat statbuf;
626     mountBackupPath_ = StringPrintf(mountPathDir_.c_str(), fsUuid_.c_str());
627     if (!lstat(mountBackupPath_.c_str(), &statbuf)) {
628         LOGE("volume mount path %{public}s exists, please remove first", mountBackupPath_.c_str());
629         remove(mountBackupPath_.c_str());
630         return E_SYS_KERNEL_ERR;
631     }
632     if (mkdir(mountBackupPath_.c_str(), S_IRWXU | S_IRWXG | S_IXOTH)) {
633         LOGE("the volume %{public}s create path %{public}s failed", GetVolumeId().c_str(), mountBackupPath_.c_str());
634         return E_MKDIR_MOUNT;
635     }
636     mountPath_ = mountBackupPath_;
637     return E_OK;
638 }
639 } // StorageDaemon
640 } // OHOS
641