• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "fs_manager/mount.h"
17 #include <cerrno>
18 #include <map>
19 #include <string>
20 #include <sys/mount.h>
21 #include <sys/stat.h>
22 #include <sys/wait.h>
23 #include <unistd.h>
24 #include <vector>
25 #include "log/log.h"
26 #include "utils.h"
27 
28 namespace updater {
29 using updater::utils::SplitString;
30 static std::string g_defaultUpdaterFstab = "";
31 static Fstab *g_fstab;
GetFstabFile()32 static std::string GetFstabFile()
33 {
34     /* check vendor fstab files from specific directory */
35     std::vector<const std::string> specificFstabFiles = {"/vendor/etc/fstab.updater"};
36     for (auto& fstabFile : specificFstabFiles) {
37         if (access(fstabFile.c_str(), F_OK) == 0) {
38             return fstabFile;
39         }
40     }
41     return "";
42 }
43 
GetMountStatusForPath(const std::string & path)44 MountStatus GetMountStatusForPath(const std::string &path)
45 {
46     FstabItem *item = FindFstabItemForPath(*g_fstab, path.c_str());
47     if (item == nullptr) {
48         return MountStatus::MOUNT_ERROR;
49     }
50     return GetMountStatusForMountPoint(item->mountPoint);
51 }
52 
LoadFstab()53 void LoadFstab()
54 {
55     std::string fstabFile = g_defaultUpdaterFstab;
56     if (fstabFile.empty()) {
57         fstabFile = GetFstabFile();
58         if (fstabFile.empty()) {
59             fstabFile = "/etc/fstab.updater";
60         }
61     }
62     // Clear fstab before read fstab file.
63     if ((g_fstab = ReadFstabFromFile(fstabFile.c_str(), false)) == nullptr) {
64         LOG(WARNING) << "Read " << fstabFile << " failed";
65         return;
66     }
67 
68     LOG(DEBUG) << "Updater filesystem config info:";
69     for (FstabItem *item = g_fstab->head; item != nullptr; item = item->next) {
70         LOG(DEBUG) << "\tDevice: " << item->deviceName;
71         LOG(DEBUG) << "\tMount point : " << item->mountPoint;
72         LOG(DEBUG) << "\tFs type : " << item->fsType;
73         LOG(DEBUG) << "\tMount options: " << item->mountOptions;
74     }
75 }
76 
LoadSpecificFstab(const std::string & fstabName)77 void LoadSpecificFstab(const std::string &fstabName)
78 {
79     g_defaultUpdaterFstab = fstabName;
80     LoadFstab();
81     g_defaultUpdaterFstab = "";
82 }
83 
UmountForPath(const std::string & path)84 int UmountForPath(const std::string& path)
85 {
86     FstabItem *item = FindFstabItemForPath(*g_fstab, path.c_str());
87     if (item == nullptr) {
88         LOG(ERROR) << "Cannot find fstab item for " << path << " to umount.";
89         return -1;
90     }
91 
92     LOG(DEBUG) << "Umount for path " << path;
93     MountStatus rc = GetMountStatusForMountPoint(item->mountPoint);
94     if (rc == MOUNT_ERROR) {
95         return -1;
96     } else if (rc == MOUNT_UMOUNTED) {
97         return 0;
98     } else {
99         int ret = umount(item->mountPoint);
100         if (ret == -1) {
101             LOG(ERROR) << "Umount " << item->mountPoint << "failed: " << errno;
102             return -1;
103         }
104     }
105     return 0;
106 }
107 
MountForPath(const std::string & path)108 int MountForPath(const std::string &path)
109 {
110     FstabItem *item = FindFstabItemForPath(*g_fstab, path.c_str());
111     int ret = -1;
112     if (item == nullptr) {
113         LOG(ERROR) << "Cannot find fstab item for " << path << " to mount.";
114         return -1;
115     }
116 
117     LOG(DEBUG) << "Mount for path " << path;
118     MountStatus rc = GetMountStatusForMountPoint(item->mountPoint);
119     if (rc == MountStatus::MOUNT_ERROR) {
120         ret = -1;
121     } else if (rc == MountStatus::MOUNT_MOUNTED) {
122         LOG(INFO) << path << " already mounted";
123         ret = 0;
124     } else {
125         ret = MountOneItem(item);
126     }
127     return ret;
128 }
129 
FormatPartition(const std::string & path)130 int FormatPartition(const std::string &path)
131 {
132     FstabItem *item = FindFstabItemForPath(*g_fstab, path.c_str());
133     if (item == nullptr) {
134         LOG(ERROR) << "Cannot find fstab item for " << path << " to format.";
135         return -1;
136     }
137 
138     if (strcmp(item->mountPoint, "/") == 0) {
139         /* Can not format root */
140         return 0;
141     }
142 
143     if (!IsSupportedFilesystem(item->fsType)) {
144         LOG(ERROR) << "Try to format " << item->mountPoint << " with unsupported file system type: " << item->fsType;
145         return -1;
146     }
147 
148     // Umount first
149     if (UmountForPath(path) != 0) {
150         return -1;
151     }
152     int ret = DoFormat(item->deviceName, item->fsType);
153     if (ret != 0) {
154         LOG(ERROR) << "Format " << path << " failed";
155     }
156     return ((ret != 0) ? -1 : 0);
157 }
158 
SetupPartitions()159 int SetupPartitions()
160 {
161     if (g_fstab == NULL || g_fstab->head == NULL) {
162         LOG(ERROR) << "Fstab is invalid";
163         return -1;
164     }
165     for (const FstabItem *item = g_fstab->head; item != nullptr; item = item->next) {
166         std::string mountPoint(item->mountPoint);
167         std::string fsType(item->fsType);
168         if (mountPoint == "/" || mountPoint == "/tmp" || fsType == "none" ||
169             mountPoint == "/sdcard") {
170             continue;
171         }
172 
173         if (mountPoint == "/data") {
174             if (MountForPath(mountPoint) != 0) {
175                 LOG(ERROR) << "Expected partition " << mountPoint << " is not mounted.";
176                 return -1;
177             }
178             continue;
179         }
180         if (UmountForPath(mountPoint) != 0) {
181             LOG(ERROR) << "Umount " << mountPoint << " failed";
182             return -1;
183         }
184     }
185     return 0;
186 }
187 
GetBlockDeviceByMountPoint(const std::string & mountPoint)188 const std::string GetBlockDeviceByMountPoint(const std::string &mountPoint)
189 {
190     std::string blockDevice = "";
191     if (!mountPoint.empty()) {
192         FstabItem *item = FindFstabItemForMountPoint(*g_fstab, mountPoint.c_str());
193         if (item != NULL) {
194             blockDevice = item->deviceName;
195         }
196     }
197     return blockDevice;
198 }
199 } // updater
200