Loading fs_mgr/fs_mgr_remount.cpp +50 −10 Original line number Diff line number Diff line Loading @@ -42,13 +42,14 @@ namespace { [[noreturn]] void usage(int exit_status) { LOG(INFO) << getprogname() << " [-h] [-R] [-T fstab_file]\n" << " [-h] [-R] [-T fstab_file] [partition]...\n" "\t-h --help\tthis help\n" "\t-R --reboot\tdisable verity & reboot to facilitate remount\n" "\t-T --fstab\tcustom fstab file location\n" "\tpartition\tspecific partition(s) (empty does all)\n" "\n" "Remount all partitions read-write.\n" "-R notwithstanding, verity must be disabled."; "Remount specified partition(s) read-write, by name or mount point.\n" "-R notwithstanding, verity must be disabled on partition(s)."; ::exit(exit_status); } Loading Loading @@ -138,6 +139,8 @@ int main(int argc, char* argv[]) { BADARG, NOT_ROOT, NO_FSTAB, UNKNOWN_PARTITION, INVALID_PARTITION, VERITY_PARTITION, BAD_OVERLAY, NO_MOUNTS, Loading Loading @@ -183,11 +186,6 @@ int main(int argc, char* argv[]) { } } if (argc > optind) { LOG(ERROR) << "Bad Argument " << argv[optind]; usage(BADARG); } // Make sure we are root. if (::getuid() != 0) { LOG(ERROR) << "must be run as root"; Loading @@ -211,16 +209,58 @@ int main(int argc, char* argv[]) { auto overlayfs_candidates = fs_mgr_overlayfs_candidate_list(fstab); // Generate the all remountable partitions sub-list android::fs_mgr::Fstab partitions; android::fs_mgr::Fstab all; for (auto const& entry : fstab) { if (!remountable_partition(entry)) continue; if (overlayfs_candidates.empty() || GetEntryForMountPoint(&overlayfs_candidates, entry.mount_point) || (is_wrapped(overlayfs_candidates, entry) == nullptr)) { partitions.emplace_back(entry); all.emplace_back(entry); } } // Parse the unique list of valid partition arguments. android::fs_mgr::Fstab partitions; for (; argc > optind; ++optind) { auto partition = std::string(argv[optind]); if (partition.empty()) continue; if (partition == "/") partition = "/system"; auto find_part = [&partition](const auto& entry) { const auto mount_point = system_mount_point(entry); if (partition == mount_point) return true; if (partition == android::base::Basename(mount_point)) return true; return false; }; // Do we know about the partition? auto it = std::find_if(fstab.begin(), fstab.end(), find_part); if (it == fstab.end()) { LOG(ERROR) << "Unknown partition " << partition << ", skipping"; retval = UNKNOWN_PARTITION; continue; } // Is that one covered by an existing overlayfs? auto wrap = is_wrapped(overlayfs_candidates, *it); if (wrap) { LOG(INFO) << "partition " << partition << " covered by overlayfs for " << wrap->mount_point << ", switching"; partition = system_mount_point(*wrap); } // Is it a remountable partition? it = std::find_if(all.begin(), all.end(), find_part); if (it == all.end()) { LOG(ERROR) << "Invalid partition " << partition << ", skipping"; retval = INVALID_PARTITION; continue; } if (GetEntryForMountPoint(&partitions, it->mount_point) == nullptr) { partitions.emplace_back(*it); } } if (partitions.empty() && !retval) { partitions = all; } // Check verity and optionally setup overlayfs backing. auto reboot_later = false; for (auto it = partitions.begin(); it != partitions.end();) { Loading fs_mgr/tests/adb-remount-test.sh +7 −3 Original line number Diff line number Diff line Loading @@ -620,7 +620,7 @@ if [ "orange" = "`get_property ro.boot.verifiedbootstate`" -a \ echo "${GREEN}[ RUN ]${NORMAL} Testing adb shell su root remount -R command" >&2 adb_su remount -R </dev/null || true adb_su remount -R system </dev/null || true sleep 2 adb_wait 2m || die "waiting for device after remount -R `usb_status`" Loading Loading @@ -1159,10 +1159,12 @@ adb_reboot && die "lost device after reboot to ro state (USB stack broken?)" adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null && die "/vendor is not read-only" adb_su remount </dev/null || adb_su remount vendor </dev/null || die "remount command" adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null || die "/vendor is not read-write" adb_sh grep " /system .* rw," /proc/mounts >/dev/null </dev/null && die "/vendor is not read-only" echo "${GREEN}[ OK ]${NORMAL} remount command works from setup" >&2 # Prerequisite is an overlayfs deconstructed device but with verity disabled. Loading @@ -1177,10 +1179,12 @@ adb_reboot && die "lost device after reboot after wipe (USB stack broken?)" adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null && die "/vendor is not read-only" adb_su remount </dev/null || adb_su remount vendor </dev/null || die "remount command" adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null || die "/vendor is not read-write" adb_sh grep " /system .* rw," /proc/mounts >/dev/null </dev/null && die "/system is not read-only" echo "${GREEN}[ OK ]${NORMAL} remount command works from scratch" >&2 restore Loading init/builtins.cpp +10 −1 Original line number Diff line number Diff line Loading @@ -1119,13 +1119,21 @@ static Result<Success> do_parse_apex_configs(const BuiltinArguments& args) { } static Result<Success> do_setup_runtime_bionic(const BuiltinArguments& args) { if (SwitchToDefaultMountNamespace()) { if (SetupRuntimeBionic()) { return Success(); } else { return Error() << "Failed to setup runtime bionic"; } } static Result<Success> do_enter_default_mount_ns(const BuiltinArguments& args) { if (SwitchToDefaultMountNamespace()) { return Success(); } else { return Error() << "Failed to enter into default mount namespace"; } } // Builtin-function-map start const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const { constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max(); Loading Loading @@ -1177,6 +1185,7 @@ const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const { {"start", {1, 1, {false, do_start}}}, {"stop", {1, 1, {false, do_stop}}}, {"swapon_all", {1, 1, {false, do_swapon_all}}}, {"enter_default_mount_ns", {0, 0, {false, do_enter_default_mount_ns}}}, {"symlink", {2, 2, {true, do_symlink}}}, {"sysclktz", {1, 1, {false, do_sysclktz}}}, {"trigger", {1, 1, {false, do_trigger}}}, Loading init/first_stage_init.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -155,6 +155,10 @@ int FirstStageMain(int argc, char** argv) { // part of the product partition, e.g. because they are mounted read-write. CHECKCALL(mkdir("/mnt/product", 0755)); // /apex is used to mount APEXes CHECKCALL(mount("tmpfs", "/apex", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV, "mode=0755,uid=0,gid=0")); #undef CHECKCALL // Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually Loading init/mount_namespace.cpp +17 −1 Original line number Diff line number Diff line Loading @@ -172,6 +172,11 @@ bool SetupMountNamespaces() { kBionicLibsMountPointDir64)) return false; // /apex is also a private mountpoint to give different sets of APEXes for // the bootstrap and default mount namespaces. The processes running with // the bootstrap namespace get APEXes from the read-only partition. if (!(MakePrivate("/apex"))) return false; bootstrap_ns_fd.reset(OpenMountNamespace()); bootstrap_ns_id = GetMountNamespaceId(); Loading Loading @@ -227,6 +232,17 @@ bool SwitchToDefaultMountNamespace() { } } LOG(INFO) << "Switched to default mount namespace"; return true; } // TODO(jiyong): remove this when /system/lib/libc.so becomes // a symlink to /apex/com.android.runtime/lib/bionic/libc.so bool SetupRuntimeBionic() { if (IsRecoveryMode()) { // We don't have multiple namespaces in recovery mode return true; } // Bind-mount bionic from the runtime APEX since it is now available. Note // that in case of IsBionicUpdatable() == false, these mounts are over the // existing existing bind mounts for the bootstrap bionic, which effectively Loading @@ -238,7 +254,7 @@ bool SwitchToDefaultMountNamespace() { kBionicLibsMountPointDir64)) return false; LOG(INFO) << "Switched to default mount namespace"; LOG(INFO) << "Runtime bionic is set up"; return true; } Loading Loading
fs_mgr/fs_mgr_remount.cpp +50 −10 Original line number Diff line number Diff line Loading @@ -42,13 +42,14 @@ namespace { [[noreturn]] void usage(int exit_status) { LOG(INFO) << getprogname() << " [-h] [-R] [-T fstab_file]\n" << " [-h] [-R] [-T fstab_file] [partition]...\n" "\t-h --help\tthis help\n" "\t-R --reboot\tdisable verity & reboot to facilitate remount\n" "\t-T --fstab\tcustom fstab file location\n" "\tpartition\tspecific partition(s) (empty does all)\n" "\n" "Remount all partitions read-write.\n" "-R notwithstanding, verity must be disabled."; "Remount specified partition(s) read-write, by name or mount point.\n" "-R notwithstanding, verity must be disabled on partition(s)."; ::exit(exit_status); } Loading Loading @@ -138,6 +139,8 @@ int main(int argc, char* argv[]) { BADARG, NOT_ROOT, NO_FSTAB, UNKNOWN_PARTITION, INVALID_PARTITION, VERITY_PARTITION, BAD_OVERLAY, NO_MOUNTS, Loading Loading @@ -183,11 +186,6 @@ int main(int argc, char* argv[]) { } } if (argc > optind) { LOG(ERROR) << "Bad Argument " << argv[optind]; usage(BADARG); } // Make sure we are root. if (::getuid() != 0) { LOG(ERROR) << "must be run as root"; Loading @@ -211,16 +209,58 @@ int main(int argc, char* argv[]) { auto overlayfs_candidates = fs_mgr_overlayfs_candidate_list(fstab); // Generate the all remountable partitions sub-list android::fs_mgr::Fstab partitions; android::fs_mgr::Fstab all; for (auto const& entry : fstab) { if (!remountable_partition(entry)) continue; if (overlayfs_candidates.empty() || GetEntryForMountPoint(&overlayfs_candidates, entry.mount_point) || (is_wrapped(overlayfs_candidates, entry) == nullptr)) { partitions.emplace_back(entry); all.emplace_back(entry); } } // Parse the unique list of valid partition arguments. android::fs_mgr::Fstab partitions; for (; argc > optind; ++optind) { auto partition = std::string(argv[optind]); if (partition.empty()) continue; if (partition == "/") partition = "/system"; auto find_part = [&partition](const auto& entry) { const auto mount_point = system_mount_point(entry); if (partition == mount_point) return true; if (partition == android::base::Basename(mount_point)) return true; return false; }; // Do we know about the partition? auto it = std::find_if(fstab.begin(), fstab.end(), find_part); if (it == fstab.end()) { LOG(ERROR) << "Unknown partition " << partition << ", skipping"; retval = UNKNOWN_PARTITION; continue; } // Is that one covered by an existing overlayfs? auto wrap = is_wrapped(overlayfs_candidates, *it); if (wrap) { LOG(INFO) << "partition " << partition << " covered by overlayfs for " << wrap->mount_point << ", switching"; partition = system_mount_point(*wrap); } // Is it a remountable partition? it = std::find_if(all.begin(), all.end(), find_part); if (it == all.end()) { LOG(ERROR) << "Invalid partition " << partition << ", skipping"; retval = INVALID_PARTITION; continue; } if (GetEntryForMountPoint(&partitions, it->mount_point) == nullptr) { partitions.emplace_back(*it); } } if (partitions.empty() && !retval) { partitions = all; } // Check verity and optionally setup overlayfs backing. auto reboot_later = false; for (auto it = partitions.begin(); it != partitions.end();) { Loading
fs_mgr/tests/adb-remount-test.sh +7 −3 Original line number Diff line number Diff line Loading @@ -620,7 +620,7 @@ if [ "orange" = "`get_property ro.boot.verifiedbootstate`" -a \ echo "${GREEN}[ RUN ]${NORMAL} Testing adb shell su root remount -R command" >&2 adb_su remount -R </dev/null || true adb_su remount -R system </dev/null || true sleep 2 adb_wait 2m || die "waiting for device after remount -R `usb_status`" Loading Loading @@ -1159,10 +1159,12 @@ adb_reboot && die "lost device after reboot to ro state (USB stack broken?)" adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null && die "/vendor is not read-only" adb_su remount </dev/null || adb_su remount vendor </dev/null || die "remount command" adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null || die "/vendor is not read-write" adb_sh grep " /system .* rw," /proc/mounts >/dev/null </dev/null && die "/vendor is not read-only" echo "${GREEN}[ OK ]${NORMAL} remount command works from setup" >&2 # Prerequisite is an overlayfs deconstructed device but with verity disabled. Loading @@ -1177,10 +1179,12 @@ adb_reboot && die "lost device after reboot after wipe (USB stack broken?)" adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null && die "/vendor is not read-only" adb_su remount </dev/null || adb_su remount vendor </dev/null || die "remount command" adb_sh grep " /vendor .* rw," /proc/mounts >/dev/null </dev/null || die "/vendor is not read-write" adb_sh grep " /system .* rw," /proc/mounts >/dev/null </dev/null && die "/system is not read-only" echo "${GREEN}[ OK ]${NORMAL} remount command works from scratch" >&2 restore Loading
init/builtins.cpp +10 −1 Original line number Diff line number Diff line Loading @@ -1119,13 +1119,21 @@ static Result<Success> do_parse_apex_configs(const BuiltinArguments& args) { } static Result<Success> do_setup_runtime_bionic(const BuiltinArguments& args) { if (SwitchToDefaultMountNamespace()) { if (SetupRuntimeBionic()) { return Success(); } else { return Error() << "Failed to setup runtime bionic"; } } static Result<Success> do_enter_default_mount_ns(const BuiltinArguments& args) { if (SwitchToDefaultMountNamespace()) { return Success(); } else { return Error() << "Failed to enter into default mount namespace"; } } // Builtin-function-map start const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const { constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max(); Loading Loading @@ -1177,6 +1185,7 @@ const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const { {"start", {1, 1, {false, do_start}}}, {"stop", {1, 1, {false, do_stop}}}, {"swapon_all", {1, 1, {false, do_swapon_all}}}, {"enter_default_mount_ns", {0, 0, {false, do_enter_default_mount_ns}}}, {"symlink", {2, 2, {true, do_symlink}}}, {"sysclktz", {1, 1, {false, do_sysclktz}}}, {"trigger", {1, 1, {false, do_trigger}}}, Loading
init/first_stage_init.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -155,6 +155,10 @@ int FirstStageMain(int argc, char** argv) { // part of the product partition, e.g. because they are mounted read-write. CHECKCALL(mkdir("/mnt/product", 0755)); // /apex is used to mount APEXes CHECKCALL(mount("tmpfs", "/apex", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV, "mode=0755,uid=0,gid=0")); #undef CHECKCALL // Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually Loading
init/mount_namespace.cpp +17 −1 Original line number Diff line number Diff line Loading @@ -172,6 +172,11 @@ bool SetupMountNamespaces() { kBionicLibsMountPointDir64)) return false; // /apex is also a private mountpoint to give different sets of APEXes for // the bootstrap and default mount namespaces. The processes running with // the bootstrap namespace get APEXes from the read-only partition. if (!(MakePrivate("/apex"))) return false; bootstrap_ns_fd.reset(OpenMountNamespace()); bootstrap_ns_id = GetMountNamespaceId(); Loading Loading @@ -227,6 +232,17 @@ bool SwitchToDefaultMountNamespace() { } } LOG(INFO) << "Switched to default mount namespace"; return true; } // TODO(jiyong): remove this when /system/lib/libc.so becomes // a symlink to /apex/com.android.runtime/lib/bionic/libc.so bool SetupRuntimeBionic() { if (IsRecoveryMode()) { // We don't have multiple namespaces in recovery mode return true; } // Bind-mount bionic from the runtime APEX since it is now available. Note // that in case of IsBionicUpdatable() == false, these mounts are over the // existing existing bind mounts for the bootstrap bionic, which effectively Loading @@ -238,7 +254,7 @@ bool SwitchToDefaultMountNamespace() { kBionicLibsMountPointDir64)) return false; LOG(INFO) << "Switched to default mount namespace"; LOG(INFO) << "Runtime bionic is set up"; return true; } Loading