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 }