• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd. 2021-2021.
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 #include "filesystem_manager.h"
16 
17 #include <algorithm>
18 #include <array>
19 #include <cctype>
20 #include <cstddef>
21 #include <cstdio>
22 #include <cstdlib>
23 #include <cstring>
24 #include <dirent.h>
25 #include <fcntl.h>
26 #include <iostream>
27 #include <map>
28 #include <string>
29 #include <sys/mount.h>
30 #include <sys/stat.h>
31 #include <sys/types.h>
32 #include <sys/wait.h>
33 #include <unistd.h>
34 #include <utility>
35 #include <vector>
36 
37 #include "filesystem_log.h"
38 
39 /*
40 MS_RDONLY
41 MS_NOSUID
42 MS_NODEV
43 MS_NOEXEC
44 MS_SYNCHRONOUS
45 MS_REMOUNT
46 MS_MANDLOCK
47 MS_DIRSYNC
48 MS_NOATIME
49 MS_NODIRATIME
50 MS_BIND
51 MS_MOVE
52 MS_REC
53 MS_SILENT
54 MS_POSIXACL
55 MS_UNBINDABLE
56 MS_PRIVATE
57 MS_SLAVE
58 MS_SHARED
59 MS_RELATIME
60 MS_KERNMOUNT
61 MS_I_VERSION
62 MS_STRICTATIME
63 MS_LAZYTIME
64 MS_ACTIVE
65 MS_NOUSER
66 MS_RMT_MASK
67 MS_MGC_VAL
68 MS_MGC_MSK
69 */
70 
71 using namespace OHOS::FsMountTab;
72 namespace OHOS {
73 constexpr int MAX_FORMAT_OPTION_COUNT = 2;
74 
FsMount(const FsMountTab::FsMountEntry & entry)75 int FileSystemManager::FsMount(const FsMountTab::FsMountEntry &entry)
76 {
77     int ret = -1;
78     struct stat st {};
79     if (!entry.IsValid()) {
80         SSLOG_E("Invalid mount entry,exit");
81         return -1;
82     }
83     if (stat(entry.mountPoint.c_str(), &st) != 0 && errno != ENOENT) {
84         SSLOG_E("Cannot get %{public}s status: %{public}d", entry.mountPoint.c_str(), errno);
85         return -1;
86     }
87     if ((st.st_mode & S_IFMT) == S_IFLNK) { // link, delete it.
88         unlink(entry.mountPoint.c_str());
89     }
90     mkdir(entry.mountPoint.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
91     SSLOG_D("cSource:%{public}s", entry.blkDev.c_str());
92     SSLOG_D("cTarget:%{public}s", entry.mountPoint.c_str());
93     SSLOG_D("cfsType:%{public}s", entry.fsType.c_str());
94     SSLOG_D("mountFlag:%{public}lu", entry.mountFlags);
95     SSLOG_D("fsOption:%{public}s", entry.mountExtra.c_str());
96 
97     if (entry.mountExtra.empty()) {
98         ret = mount(entry.blkDev.c_str(), entry.mountPoint.c_str(), entry.fsType.c_str(), entry.mountFlags,
99                     nullptr);
100         SSLOG_D("The fifth parameter of this mount is NULL");
101     } else {
102         ret = mount(entry.blkDev.c_str(), entry.mountPoint.c_str(), entry.fsType.c_str(), entry.mountFlags,
103                     entry.mountExtra.c_str());
104         SSLOG_D("The fifth parameter of this mount is not NULL");
105     }
106     if (ret < 0) {
107         return -1;
108     }
109     return 0;
110 }
111 
FsIsSupport(const std::string & fsType)112 int FileSystemManager::FsIsSupport(const std::string &fsType)
113 {
114     std::vector<std::string> supportedFilesystems = { "ext4", "f2fs", "vfat", "exfat", "ntfs" };
115     for (auto it : supportedFilesystems) {
116         if (it == fsType) {
117             return 1;
118         }
119     }
120     return 0;
121 }
122 
FormatCommandPatch(FormatInfo & stFormatAttr)123 int FileSystemManager::FormatCommandPatch(FormatInfo &stFormatAttr)
124 {
125     static std::map<std::string, std::string> formatCommandMap = { { "ext4", "/system/bin/mke2fs" },
126                                                                    { "f2fs", "/system/bin/make_f2fs" },
127                                                                    { "vfat", "/system/bin/newfs_msdos" },
128                                                                    { "exfat", "/system/bin/mkfs.exfat" },
129                                                                    { "ntfs", "/system/bin/mkfs.ntfs" } };
130     auto it = formatCommandMap.find(stFormatAttr.type);
131     if (it == formatCommandMap.end()) {
132         return -1;
133     }
134 
135     if (access(it->second.c_str(), X_OK) != 0) {
136         return -1;
137     }
138     stFormatAttr.cmd = it->second;
139     return 0;
140 }
141 
FsUMount(const std::string & tarGet)142 int FileSystemManager::FsUMount(const std::string &tarGet)
143 {
144     int ret = -1;
145     if (tarGet.size() <= 0) {
146         SSLOG_E("invalid tarGet");
147         return -1;
148     }
149     ret = umount(tarGet.c_str());
150     if (ret < 0) {
151         SSLOG_E("call mount failed");
152         perror("mount");
153         return -1;
154     }
155     SSLOG_D("umount(%s) successful", tarGet.c_str());
156     return 0;
157 }
158 
ParseFormatAttr(const std::string & formatAttr,FormatInfo & stFormatAttr)159 int FileSystemManager::ParseFormatAttr(const std::string &formatAttr, FormatInfo &stFormatAttr)
160 {
161     const std::string delim(" ");
162     std::vector<std::string> formatAttrVector;
163     Split(formatAttr, delim, formatAttrVector);
164     if (formatAttrVector.size() != MAX_FORMAT_OPTION_COUNT) {
165         return -1;
166     }
167     stFormatAttr.source = formatAttrVector[0];
168     stFormatAttr.type = formatAttrVector[1];
169     return 0;
170 }
171 
GetFormatParameters(const FormatInfo & stFormatInfo,std::vector<std::string> & formatParameters)172 int FileSystemManager::GetFormatParameters(const FormatInfo &stFormatInfo,
173                                            std::vector<std::string> &formatParameters)
174 {
175     constexpr int blockSize = 4096;
176 
177     if (stFormatInfo.type == "ext4") {
178         formatParameters.push_back("-F");
179         formatParameters.push_back("-f");
180         formatParameters.push_back("ext4");
181         formatParameters.push_back("-b");
182         formatParameters.push_back(std::to_string(blockSize));
183     } else if (stFormatInfo.type == "vfat") {
184         formatParameters.push_back("-p");
185         formatParameters.push_back("-f");
186         formatParameters.push_back("-y");
187     } else {
188         SSLOG_I("No Need add Extra paramter");
189     }
190     formatParameters.push_back(stFormatInfo.source);
191     if (PerformFormatting(formatParameters) < 0) {
192         SSLOG_E("call PerformFormatting failed\n");
193         return -1;
194     }
195     return 0;
196 }
197 
PerformFormatting(std::vector<std::string> & formatParameters)198 int FileSystemManager::PerformFormatting(std::vector<std::string> &formatParameters)
199 {
200     int formatParaSize = 0;
201     std::vector<char *> cmds;
202     std::vector<char *> newenviron = {};
203     newenviron.push_back(nullptr);
204 
205     formatParaSize = formatParameters.size();
206     for (int i = 0; i < formatParaSize; i++) {
207         cmds.emplace_back(const_cast<char *>(formatParameters[i].c_str()));
208     }
209     cmds.emplace_back(nullptr);
210 
211     if (MOUNT_ERROR == (execve(formatParameters[0].data(), cmds.data(), newenviron.data()))) {
212         SSLOG_E("call execve failed\n");
213         return -1;
214     }
215     return 0;
216 }
217 
DoMount(const std::string & mountAttr)218 int FileSystemManager::DoMount(const std::string &mountAttr)
219 {
220     int mountRet = -1;
221     FsMountTab::FsMountEntry entry;
222     if (!FsMountTab::ParseMountEntry(mountAttr, entry)) {
223         SSLOG_E("call ParseMountAttr failed\n");
224         return -1;
225     }
226     mountRet = FsMount(entry);
227     if (mountRet != 0) {
228         return -1;
229     }
230     // SendMountOption(mountAttr);
231     return 0;
232 }
233 
DoUMount(const std::string & umountAttr)234 int FileSystemManager::DoUMount(const std::string &umountAttr)
235 {
236     const std::string delim(" ");
237     std::vector<std::string> umountAttrVector;
238     Split(umountAttr, delim, umountAttrVector);
239     size_t umountSize = 0;
240     int ret = 0;
241     for (umountSize = 0; umountSize < umountAttrVector.size(); umountSize++) {
242         ret = FsUMount(umountAttrVector[umountSize]);
243         if (ret < 0) {
244             return -1;
245         }
246     }
247     return 0;
248 }
249 
DoFormat(const std::string & formatAttr)250 int FileSystemManager::DoFormat(const std::string &formatAttr)
251 {
252     std::vector<std::string> formatParameters = {};
253     FileSystemManager::FormatInfo stFormatInfo;
254     if (ParseFormatAttr(formatAttr, stFormatInfo) < 0) {
255         SSLOG_E("call ParseMountAttr failed\n");
256         return -1;
257     }
258     if (FormatCommandPatch(stFormatInfo) < 0) {
259         SSLOG_E("call ParseFormatCommand failed\n");
260         return -1;
261     }
262     if (GetFormatParameters(stFormatInfo, formatParameters) < 0) {
263         SSLOG_E("call GetFormatParameters failed\n");
264         return -1;
265     }
266 
267     return 0;
268 }
269 
270 } // namespace OHOS
271 
DoMountTo(const char * mountAttr,int maxArg)272 extern "C" void DoMountTo(const char *mountAttr, int maxArg)
273 {
274     std::string str(mountAttr);
275     OHOS::FileSystemManager::DoMount(str);
276 }
277 
DoUnMountTo(const char * mountAttr,int maxArg)278 extern "C" int DoUnMountTo(const char *mountAttr, int maxArg)
279 {
280     std::string str(mountAttr);
281     int ret = OHOS::FileSystemManager::DoUMount(str);
282     return ret;
283 }