blob: deaf5f72ddbca5602b554a21996e8679623a94ed [file] [log] [blame]
Mark Salyzyn6b3f5872019-02-20 08:32:36 -08001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <errno.h>
18#include <getopt.h>
19#include <stdio.h>
20#include <sys/mount.h>
21#include <sys/types.h>
22#include <sys/vfs.h>
23#include <unistd.h>
24
25#include <string>
David Anderson8696a5d2020-06-10 23:50:02 -070026#include <thread>
Mark Salyzyn6b3f5872019-02-20 08:32:36 -080027#include <utility>
28#include <vector>
29
30#include <android-base/file.h>
31#include <android-base/logging.h>
32#include <android-base/properties.h>
33#include <android-base/strings.h>
David Anderson8696a5d2020-06-10 23:50:02 -070034#include <android/os/IVold.h>
35#include <binder/IServiceManager.h>
Mark Salyzyn1188ce42019-01-25 11:05:40 -080036#include <bootloader_message/bootloader_message.h>
37#include <cutils/android_reboot.h>
Mark Salyzyn4469fb12019-01-30 10:19:15 -080038#include <fec/io.h>
Mark Salyzyn6b3f5872019-02-20 08:32:36 -080039#include <fs_mgr_overlayfs.h>
40#include <fs_mgr_priv.h>
41#include <fstab/fstab.h>
Yo Chiangd5429102021-01-21 18:14:47 +080042#include <libavb_user/libavb_user.h>
43#include <libgsi/libgsid.h>
Mark Salyzyn6b3f5872019-02-20 08:32:36 -080044
Yi-Yo Chiang6455f272021-11-02 21:37:03 +080045using namespace std::literals;
46
Mark Salyzyn6b3f5872019-02-20 08:32:36 -080047namespace {
48
49[[noreturn]] void usage(int exit_status) {
50 LOG(INFO) << getprogname()
Mark Salyzynf4e74222019-01-24 11:08:10 -080051 << " [-h] [-R] [-T fstab_file] [partition]...\n"
Mark Salyzyn6b3f5872019-02-20 08:32:36 -080052 "\t-h --help\tthis help\n"
Mark Salyzyn1188ce42019-01-25 11:05:40 -080053 "\t-R --reboot\tdisable verity & reboot to facilitate remount\n"
Mark Salyzyn8c07db62019-01-24 11:08:10 -080054 "\t-T --fstab\tcustom fstab file location\n"
Mark Salyzynf4e74222019-01-24 11:08:10 -080055 "\tpartition\tspecific partition(s) (empty does all)\n"
Mark Salyzyn6b3f5872019-02-20 08:32:36 -080056 "\n"
Mark Salyzynf4e74222019-01-24 11:08:10 -080057 "Remount specified partition(s) read-write, by name or mount point.\n"
Yo Chiangd5429102021-01-21 18:14:47 +080058 "-R notwithstanding, verity must be disabled on partition(s).\n"
59 "-R within a DSU guest system reboots into the DSU instead of the host system,\n"
60 "this command would enable DSU (one-shot) if not already enabled.";
Mark Salyzyn6b3f5872019-02-20 08:32:36 -080061
62 ::exit(exit_status);
63}
64
65bool remountable_partition(const android::fs_mgr::FstabEntry& entry) {
66 if (entry.fs_mgr_flags.vold_managed) return false;
67 if (entry.fs_mgr_flags.recovery_only) return false;
68 if (entry.fs_mgr_flags.slot_select_other) return false;
69 if (!(entry.flags & MS_RDONLY)) return false;
70 if (entry.fs_type == "vfat") return false;
71 return true;
72}
73
74const std::string system_mount_point(const android::fs_mgr::FstabEntry& entry) {
75 if (entry.mount_point == "/") return "/system";
76 return entry.mount_point;
77}
78
79const android::fs_mgr::FstabEntry* is_wrapped(const android::fs_mgr::Fstab& overlayfs_candidates,
80 const android::fs_mgr::FstabEntry& entry) {
81 auto mount_point = system_mount_point(entry);
82 auto it = std::find_if(overlayfs_candidates.begin(), overlayfs_candidates.end(),
83 [&mount_point](const auto& entry) {
84 return android::base::StartsWith(mount_point,
85 system_mount_point(entry) + "/");
86 });
87 if (it == overlayfs_candidates.end()) return nullptr;
88 return &(*it);
89}
90
Mark Salyzynba2449b2020-02-13 13:42:55 -080091auto verbose = false;
92
Mark Salyzyn75941f22019-02-12 15:26:34 -080093void MyLogger(android::base::LogId id, android::base::LogSeverity severity, const char* tag,
94 const char* file, unsigned int line, const char* message) {
Mark Salyzynba2449b2020-02-13 13:42:55 -080095 if (verbose || severity == android::base::ERROR || message[0] != '[') {
96 fprintf(stderr, "%s\n", message);
97 }
Mark Salyzyn75941f22019-02-12 15:26:34 -080098 static auto logd = android::base::LogdLogger();
99 logd(id, severity, tag, file, line, message);
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800100}
101
Mark Salyzynd9b60302019-05-28 08:55:48 -0700102[[noreturn]] void reboot(bool overlayfs = false) {
103 if (overlayfs) {
104 LOG(INFO) << "Successfully setup overlayfs\nrebooting device";
Mark Salyzyn1188ce42019-01-25 11:05:40 -0800105 } else {
106 LOG(INFO) << "Successfully disabled verity\nrebooting device";
107 }
108 ::sync();
Mark Salyzynd9b60302019-05-28 08:55:48 -0700109 android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot,remount");
Mark Salyzyn1188ce42019-01-25 11:05:40 -0800110 ::sleep(60);
111 ::exit(0); // SUCCESS
112}
113
David Anderson8696a5d2020-06-10 23:50:02 -0700114static android::sp<android::os::IVold> GetVold() {
115 while (true) {
116 if (auto sm = android::defaultServiceManager()) {
117 if (auto binder = sm->getService(android::String16("vold"))) {
118 if (auto vold = android::interface_cast<android::os::IVold>(binder)) {
119 return vold;
120 }
121 }
122 }
123 std::this_thread::sleep_for(2s);
124 }
125}
126
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800127} // namespace
128
David Anderson8696a5d2020-06-10 23:50:02 -0700129using namespace std::chrono_literals;
130
David Anderson45253ae2020-04-28 20:38:15 -0700131enum RemountStatus {
132 REMOUNT_SUCCESS = 0,
133 NOT_USERDEBUG,
134 BADARG,
135 NOT_ROOT,
136 NO_FSTAB,
137 UNKNOWN_PARTITION,
138 INVALID_PARTITION,
139 VERITY_PARTITION,
140 BAD_OVERLAY,
141 NO_MOUNTS,
142 REMOUNT_FAILED,
David Anderson8696a5d2020-06-10 23:50:02 -0700143 MUST_REBOOT,
144 BINDER_ERROR,
Yo Chiangd5429102021-01-21 18:14:47 +0800145 CHECKPOINTING,
146 GSID_ERROR,
Yi-Yo Chiang6455f272021-11-02 21:37:03 +0800147 CLEAN_SCRATCH_FILES,
David Anderson45253ae2020-04-28 20:38:15 -0700148};
149
Josh Gao8c2198c2019-07-11 14:15:32 -0700150static int do_remount(int argc, char* argv[]) {
David Anderson45253ae2020-04-28 20:38:15 -0700151 RemountStatus retval = REMOUNT_SUCCESS;
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800152
153 // If somehow this executable is delivered on a "user" build, it can
154 // not function, so providing a clear message to the caller rather than
155 // letting if fall through and provide a lot of confusing failure messages.
156 if (!ALLOW_ADBD_DISABLE_VERITY || (android::base::GetProperty("ro.debuggable", "0") != "1")) {
157 LOG(ERROR) << "only functions on userdebug or eng builds";
158 return NOT_USERDEBUG;
159 }
160
Mark Salyzyn8c07db62019-01-24 11:08:10 -0800161 const char* fstab_file = nullptr;
Mark Salyzyn1188ce42019-01-25 11:05:40 -0800162 auto can_reboot = false;
Mark Salyzyn8c07db62019-01-24 11:08:10 -0800163
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800164 struct option longopts[] = {
Mark Salyzyn8c07db62019-01-24 11:08:10 -0800165 {"fstab", required_argument, nullptr, 'T'},
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800166 {"help", no_argument, nullptr, 'h'},
Mark Salyzyn1188ce42019-01-25 11:05:40 -0800167 {"reboot", no_argument, nullptr, 'R'},
Mark Salyzynba2449b2020-02-13 13:42:55 -0800168 {"verbose", no_argument, nullptr, 'v'},
Yi-Yo Chiang6455f272021-11-02 21:37:03 +0800169 {"clean_scratch_files", no_argument, nullptr, 'C'},
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800170 {0, 0, nullptr, 0},
171 };
Mark Salyzynba2449b2020-02-13 13:42:55 -0800172 for (int opt; (opt = ::getopt_long(argc, argv, "hRT:v", longopts, nullptr)) != -1;) {
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800173 switch (opt) {
Mark Salyzynba2449b2020-02-13 13:42:55 -0800174 case 'h':
175 usage(SUCCESS);
176 break;
Mark Salyzyn1188ce42019-01-25 11:05:40 -0800177 case 'R':
178 can_reboot = true;
179 break;
Mark Salyzyn8c07db62019-01-24 11:08:10 -0800180 case 'T':
181 if (fstab_file) {
182 LOG(ERROR) << "Cannot supply two fstabs: -T " << fstab_file << " -T" << optarg;
183 usage(BADARG);
184 }
185 fstab_file = optarg;
186 break;
Mark Salyzynba2449b2020-02-13 13:42:55 -0800187 case 'v':
188 verbose = true;
189 break;
Yi-Yo Chiang6455f272021-11-02 21:37:03 +0800190 case 'C':
191 return CLEAN_SCRATCH_FILES;
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800192 default:
193 LOG(ERROR) << "Bad Argument -" << char(opt);
194 usage(BADARG);
195 break;
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800196 }
197 }
198
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800199 // Make sure we are root.
200 if (::getuid() != 0) {
Josh Gao8c2198c2019-07-11 14:15:32 -0700201 LOG(ERROR) << "Not running as root. Try \"adb root\" first.";
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800202 return NOT_ROOT;
203 }
204
Mark Salyzyn8c07db62019-01-24 11:08:10 -0800205 // Read the selected fstab.
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800206 android::fs_mgr::Fstab fstab;
Mark Salyzyn8c07db62019-01-24 11:08:10 -0800207 auto fstab_read = false;
208 if (fstab_file) {
209 fstab_read = android::fs_mgr::ReadFstabFromFile(fstab_file, &fstab);
210 } else {
211 fstab_read = android::fs_mgr::ReadDefaultFstab(&fstab);
Mark Salyzyna497ab92019-03-19 13:50:57 -0700212 // Manufacture a / entry from /proc/mounts if missing.
213 if (!GetEntryForMountPoint(&fstab, "/system") && !GetEntryForMountPoint(&fstab, "/")) {
214 android::fs_mgr::Fstab mounts;
215 if (android::fs_mgr::ReadFstabFromFile("/proc/mounts", &mounts)) {
216 if (auto entry = GetEntryForMountPoint(&mounts, "/")) {
217 if (entry->fs_type != "rootfs") fstab.emplace_back(*entry);
218 }
219 }
220 }
Mark Salyzyn8c07db62019-01-24 11:08:10 -0800221 }
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800222 if (!fstab_read || fstab.empty()) {
Mark Salyzyn8c07db62019-01-24 11:08:10 -0800223 PLOG(ERROR) << "Failed to read fstab";
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800224 return NO_FSTAB;
225 }
226
David Anderson8696a5d2020-06-10 23:50:02 -0700227 if (android::base::GetBoolProperty("ro.virtual_ab.enabled", false) &&
228 !android::base::GetBoolProperty("ro.virtual_ab.retrofit", false)) {
229 // Virtual A/B devices can use /data as backing storage; make sure we're
230 // not checkpointing.
231 auto vold = GetVold();
232 bool checkpointing = false;
233 if (!vold->isCheckpointing(&checkpointing).isOk()) {
234 LOG(ERROR) << "Could not determine checkpointing status.";
235 return BINDER_ERROR;
236 }
237 if (checkpointing) {
238 LOG(ERROR) << "Cannot use remount when a checkpoint is in progress.";
239 return CHECKPOINTING;
240 }
241 }
242
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800243 // Generate the list of supported overlayfs mount points.
244 auto overlayfs_candidates = fs_mgr_overlayfs_candidate_list(fstab);
245
246 // Generate the all remountable partitions sub-list
Mark Salyzynf4e74222019-01-24 11:08:10 -0800247 android::fs_mgr::Fstab all;
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800248 for (auto const& entry : fstab) {
249 if (!remountable_partition(entry)) continue;
250 if (overlayfs_candidates.empty() ||
251 GetEntryForMountPoint(&overlayfs_candidates, entry.mount_point) ||
252 (is_wrapped(overlayfs_candidates, entry) == nullptr)) {
Mark Salyzynf4e74222019-01-24 11:08:10 -0800253 all.emplace_back(entry);
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800254 }
255 }
256
Mark Salyzynf4e74222019-01-24 11:08:10 -0800257 // Parse the unique list of valid partition arguments.
258 android::fs_mgr::Fstab partitions;
259 for (; argc > optind; ++optind) {
260 auto partition = std::string(argv[optind]);
261 if (partition.empty()) continue;
262 if (partition == "/") partition = "/system";
263 auto find_part = [&partition](const auto& entry) {
264 const auto mount_point = system_mount_point(entry);
265 if (partition == mount_point) return true;
266 if (partition == android::base::Basename(mount_point)) return true;
267 return false;
268 };
269 // Do we know about the partition?
270 auto it = std::find_if(fstab.begin(), fstab.end(), find_part);
271 if (it == fstab.end()) {
Mark Salyzyna497ab92019-03-19 13:50:57 -0700272 LOG(ERROR) << "Unknown partition " << argv[optind] << ", skipping";
Mark Salyzynf4e74222019-01-24 11:08:10 -0800273 retval = UNKNOWN_PARTITION;
274 continue;
275 }
276 // Is that one covered by an existing overlayfs?
277 auto wrap = is_wrapped(overlayfs_candidates, *it);
278 if (wrap) {
Mark Salyzyna497ab92019-03-19 13:50:57 -0700279 LOG(INFO) << "partition " << argv[optind] << " covered by overlayfs for "
Mark Salyzynf4e74222019-01-24 11:08:10 -0800280 << wrap->mount_point << ", switching";
281 partition = system_mount_point(*wrap);
282 }
283 // Is it a remountable partition?
284 it = std::find_if(all.begin(), all.end(), find_part);
285 if (it == all.end()) {
Mark Salyzyna497ab92019-03-19 13:50:57 -0700286 LOG(ERROR) << "Invalid partition " << argv[optind] << ", skipping";
Mark Salyzynf4e74222019-01-24 11:08:10 -0800287 retval = INVALID_PARTITION;
288 continue;
289 }
290 if (GetEntryForMountPoint(&partitions, it->mount_point) == nullptr) {
291 partitions.emplace_back(*it);
292 }
293 }
294
295 if (partitions.empty() && !retval) {
296 partitions = all;
297 }
298
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800299 // Check verity and optionally setup overlayfs backing.
Mark Salyzyn1188ce42019-01-25 11:05:40 -0800300 auto reboot_later = false;
Mark Salyzync3fc2aa2019-04-30 13:21:04 -0700301 auto user_please_reboot_later = false;
Mark Salyzynd9b60302019-05-28 08:55:48 -0700302 auto setup_overlayfs = false;
Mark Salyzyne0c581f2019-05-29 14:01:56 -0700303 auto just_disabled_verity = false;
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800304 for (auto it = partitions.begin(); it != partitions.end();) {
305 auto& entry = *it;
306 auto& mount_point = entry.mount_point;
307 if (fs_mgr_is_verity_enabled(entry)) {
Mark Salyzyn6a26b4b2019-03-05 12:21:28 -0800308 retval = VERITY_PARTITION;
Mark Salyzyne0c581f2019-05-29 14:01:56 -0700309 auto ret = false;
Bowgo Tsai2badf732019-05-09 13:16:07 +0800310 if (android::base::GetProperty("ro.boot.vbmeta.device_state", "") != "locked") {
Mark Salyzyn1188ce42019-01-25 11:05:40 -0800311 if (AvbOps* ops = avb_ops_user_new()) {
Mark Salyzyne0c581f2019-05-29 14:01:56 -0700312 ret = avb_user_verity_set(
Mark Salyzyn1188ce42019-01-25 11:05:40 -0800313 ops, android::base::GetProperty("ro.boot.slot_suffix", "").c_str(),
314 false);
315 avb_ops_user_free(ops);
Mark Salyzyne0c581f2019-05-29 14:01:56 -0700316 }
317 if (!ret && fs_mgr_set_blk_ro(entry.blk_device, false)) {
318 fec::io fh(entry.blk_device.c_str(), O_RDWR);
319 ret = fh && fh.set_verity_status(false);
320 }
321 if (ret) {
322 LOG(WARNING) << "Disabling verity for " << mount_point;
323 just_disabled_verity = true;
324 reboot_later = can_reboot;
325 user_please_reboot_later = true;
Mark Salyzyn1188ce42019-01-25 11:05:40 -0800326 }
327 }
Mark Salyzyne0c581f2019-05-29 14:01:56 -0700328 if (!ret) {
329 LOG(ERROR) << "Skipping " << mount_point << " for remount";
330 it = partitions.erase(it);
331 continue;
332 }
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800333 }
334
335 auto change = false;
336 errno = 0;
Ed Chen19814012019-12-17 08:53:13 +0000337 if (fs_mgr_overlayfs_setup(nullptr, mount_point.c_str(), &change, just_disabled_verity)) {
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800338 if (change) {
339 LOG(INFO) << "Using overlayfs for " << mount_point;
Mark Salyzynd9b60302019-05-28 08:55:48 -0700340 reboot_later = can_reboot;
341 user_please_reboot_later = true;
342 setup_overlayfs = true;
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800343 }
344 } else if (errno) {
345 PLOG(ERROR) << "Overlayfs setup for " << mount_point << " failed, skipping";
346 retval = BAD_OVERLAY;
347 it = partitions.erase(it);
348 continue;
349 }
350 ++it;
351 }
352
Yo Chiangd5429102021-01-21 18:14:47 +0800353 // If (1) remount requires a reboot to take effect, (2) system is currently
354 // running a DSU guest and (3) DSU is disabled, then enable DSU so that the
355 // next reboot would not take us back to the host system but stay within
356 // the guest system.
357 if (reboot_later) {
358 if (auto gsid = android::gsi::GetGsiService()) {
359 auto dsu_running = false;
360 if (auto status = gsid->isGsiRunning(&dsu_running); !status.isOk()) {
361 LOG(ERROR) << "Failed to get DSU running state: " << status;
362 return BINDER_ERROR;
363 }
364 auto dsu_enabled = false;
365 if (auto status = gsid->isGsiEnabled(&dsu_enabled); !status.isOk()) {
366 LOG(ERROR) << "Failed to get DSU enabled state: " << status;
367 return BINDER_ERROR;
368 }
369 if (dsu_running && !dsu_enabled) {
370 std::string dsu_slot;
371 if (auto status = gsid->getActiveDsuSlot(&dsu_slot); !status.isOk()) {
372 LOG(ERROR) << "Failed to get active DSU slot: " << status;
373 return BINDER_ERROR;
374 }
375 LOG(INFO) << "DSU is running but disabled, enable DSU so that we stay within the "
376 "DSU guest system after reboot";
377 int error = 0;
378 if (auto status = gsid->enableGsi(/* oneShot = */ true, dsu_slot, &error);
379 !status.isOk() || error != android::gsi::IGsiService::INSTALL_OK) {
380 LOG(ERROR) << "Failed to enable DSU: " << status << ", error code: " << error;
381 return !status.isOk() ? BINDER_ERROR : GSID_ERROR;
382 }
383 LOG(INFO) << "Successfully enabled DSU (one-shot mode)";
384 }
385 }
386 }
387
Mark Salyzyne0c581f2019-05-29 14:01:56 -0700388 if (partitions.empty() || just_disabled_verity) {
Mark Salyzynd9b60302019-05-28 08:55:48 -0700389 if (reboot_later) reboot(setup_overlayfs);
Mark Salyzync3fc2aa2019-04-30 13:21:04 -0700390 if (user_please_reboot_later) {
David Anderson45253ae2020-04-28 20:38:15 -0700391 return MUST_REBOOT;
Mark Salyzync3fc2aa2019-04-30 13:21:04 -0700392 }
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800393 LOG(WARNING) << "No partitions to remount";
394 return retval;
395 }
396
397 // Mount overlayfs.
Mark Salyzyn6a26b4b2019-03-05 12:21:28 -0800398 errno = 0;
399 if (!fs_mgr_overlayfs_mount_all(&partitions) && errno) {
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800400 retval = BAD_OVERLAY;
401 PLOG(ERROR) << "Can not mount overlayfs for partitions";
402 }
403
404 // Get actual mounts _after_ overlayfs has been added.
405 android::fs_mgr::Fstab mounts;
406 if (!android::fs_mgr::ReadFstabFromFile("/proc/mounts", &mounts) || mounts.empty()) {
407 PLOG(ERROR) << "Failed to read /proc/mounts";
408 retval = NO_MOUNTS;
409 }
410
411 // Remount selected partitions.
412 for (auto& entry : partitions) {
413 // unlock the r/o key for the mount point device
414 if (entry.fs_mgr_flags.logical) {
415 fs_mgr_update_logical_partition(&entry);
416 }
417 auto blk_device = entry.blk_device;
418 auto mount_point = entry.mount_point;
419
Jaegeuk Kim5ad7b3c2021-02-17 12:48:53 -0800420 auto found = false;
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800421 for (auto it = mounts.rbegin(); it != mounts.rend(); ++it) {
422 auto& rentry = *it;
423 if (mount_point == rentry.mount_point) {
424 blk_device = rentry.blk_device;
Jaegeuk Kim5ad7b3c2021-02-17 12:48:53 -0800425 found = true;
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800426 break;
427 }
Mark Salyzynb18aba02019-04-02 11:15:02 -0700428 // Find overlayfs mount point?
Leo Yane81be342021-06-04 15:19:33 +0100429 if ((mount_point == "/" && rentry.mount_point == "/system") ||
430 (mount_point == "/system" && rentry.mount_point == "/")) {
Mark Salyzyn3babd842019-03-05 12:00:10 -0800431 blk_device = rentry.blk_device;
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800432 mount_point = "/system";
Jaegeuk Kim5ad7b3c2021-02-17 12:48:53 -0800433 found = true;
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800434 break;
435 }
436 }
Jaegeuk Kim5ad7b3c2021-02-17 12:48:53 -0800437 if (!found) {
438 PLOG(INFO) << "skip unmounted partition dev:" << blk_device << " mnt:" << mount_point;
439 continue;
440 }
Mark Salyzyn3babd842019-03-05 12:00:10 -0800441 if (blk_device == "/dev/root") {
442 auto from_fstab = GetEntryForMountPoint(&fstab, mount_point);
443 if (from_fstab) blk_device = from_fstab->blk_device;
444 }
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800445 fs_mgr_set_blk_ro(blk_device, false);
446
Mark Salyzynb18aba02019-04-02 11:15:02 -0700447 // Find system-as-root mount point?
448 if ((mount_point == "/system") && !GetEntryForMountPoint(&mounts, mount_point) &&
449 GetEntryForMountPoint(&mounts, "/")) {
450 mount_point = "/";
451 }
452
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800453 // Now remount!
454 if (::mount(blk_device.c_str(), mount_point.c_str(), entry.fs_type.c_str(), MS_REMOUNT,
455 nullptr) == 0) {
456 continue;
457 }
458 if ((errno == EINVAL) && (mount_point != entry.mount_point)) {
459 mount_point = entry.mount_point;
460 if (::mount(blk_device.c_str(), mount_point.c_str(), entry.fs_type.c_str(), MS_REMOUNT,
461 nullptr) == 0) {
462 continue;
463 }
464 }
Mark Salyzynd6ef9d22019-04-11 12:58:19 -0700465 PLOG(ERROR) << "failed to remount partition dev:" << blk_device << " mnt:" << mount_point;
466 // If errno is EROFS at this point, we are dealing with r/o
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800467 // filesystem types like squashfs, erofs or ext4 dedupe. We will
468 // consider such a device that does not have CONFIG_OVERLAY_FS
Mark Salyzynd6ef9d22019-04-11 12:58:19 -0700469 // in the kernel as a misconfigured.
470 if (errno == EROFS) {
471 LOG(ERROR) << "Consider providing all the dependencies to enable overlayfs";
Mark Salyzyn1188ce42019-01-25 11:05:40 -0800472 }
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800473 retval = REMOUNT_FAILED;
474 }
475
Mark Salyzynd9b60302019-05-28 08:55:48 -0700476 if (reboot_later) reboot(setup_overlayfs);
Mark Salyzync3fc2aa2019-04-30 13:21:04 -0700477 if (user_please_reboot_later) {
478 LOG(INFO) << "Now reboot your device for settings to take effect";
479 return 0;
480 }
Mark Salyzyn1188ce42019-01-25 11:05:40 -0800481
Mark Salyzyn6b3f5872019-02-20 08:32:36 -0800482 return retval;
483}
Josh Gao8c2198c2019-07-11 14:15:32 -0700484
Yi-Yo Chiang6455f272021-11-02 21:37:03 +0800485static int do_clean_scratch_files() {
486 android::fs_mgr::CleanupOldScratchFiles();
487 return 0;
488}
489
Josh Gao8c2198c2019-07-11 14:15:32 -0700490int main(int argc, char* argv[]) {
491 android::base::InitLogging(argv, MyLogger);
Yi-Yo Chiang6455f272021-11-02 21:37:03 +0800492 if (argc > 0 && android::base::Basename(argv[0]) == "clean_scratch_files"s) {
493 return do_clean_scratch_files();
494 }
Josh Gao8c2198c2019-07-11 14:15:32 -0700495 int result = do_remount(argc, argv);
David Anderson45253ae2020-04-28 20:38:15 -0700496 if (result == MUST_REBOOT) {
497 LOG(INFO) << "Now reboot your device for settings to take effect";
Shaju Mathew7e5451a2021-11-01 16:39:14 -0700498 result = 0;
David Anderson45253ae2020-04-28 20:38:15 -0700499 } else if (result == REMOUNT_SUCCESS) {
500 printf("remount succeeded\n");
Yi-Yo Chiang6455f272021-11-02 21:37:03 +0800501 } else if (result == CLEAN_SCRATCH_FILES) {
502 return do_clean_scratch_files();
David Anderson45253ae2020-04-28 20:38:15 -0700503 } else {
504 printf("remount failed\n");
505 }
Josh Gao8c2198c2019-07-11 14:15:32 -0700506 return result;
507}