Merge "Add ro.boot.fstab_suffix and modify mount_all to use it" am: 510d2437b4
am: f19c48f85f
Change-Id: I88a1fec9407fbdb9c175aaa0b35fd5e6dbc69519
This commit is contained in:
commit
e25f3d349a
7 changed files with 139 additions and 43 deletions
|
@ -403,16 +403,17 @@ std::string ReadFstabFromDt() {
|
|||
return fstab_result;
|
||||
}
|
||||
|
||||
// Identify path to fstab file. Lookup is based on pattern fstab.<hardware>,
|
||||
// fstab.<hardware.platform> in folders /odm/etc, vendor/etc, or /.
|
||||
// Identify path to fstab file. Lookup is based on pattern
|
||||
// fstab.<fstab_suffix>, fstab.<hardware>, fstab.<hardware.platform> in
|
||||
// folders /odm/etc, vendor/etc, or /.
|
||||
std::string GetFstabPath() {
|
||||
for (const char* prop : {"hardware", "hardware.platform"}) {
|
||||
std::string hw;
|
||||
for (const char* prop : {"fstab_suffix", "hardware", "hardware.platform"}) {
|
||||
std::string suffix;
|
||||
|
||||
if (!fs_mgr_get_boot_config(prop, &hw)) continue;
|
||||
if (!fs_mgr_get_boot_config(prop, &suffix)) continue;
|
||||
|
||||
for (const char* prefix : {"/odm/etc/fstab.", "/vendor/etc/fstab.", "/fstab."}) {
|
||||
std::string fstab_path = prefix + hw;
|
||||
std::string fstab_path = prefix + suffix;
|
||||
if (access(fstab_path.c_str(), F_OK) == 0) {
|
||||
return fstab_path;
|
||||
}
|
||||
|
|
|
@ -547,13 +547,16 @@ provides the `aidl_lazy_test_1` interface.
|
|||
* `ref`: use the systemwide DE key
|
||||
* `per_boot_ref`: use the key freshly generated on each boot.
|
||||
|
||||
`mount_all <fstab> [ <path> ]\* [--<option>]`
|
||||
`mount_all [ <fstab> ] [--<option>]`
|
||||
> Calls fs\_mgr\_mount\_all on the given fs\_mgr-format fstab with optional
|
||||
options "early" and "late".
|
||||
With "--early" set, the init executable will skip mounting entries with
|
||||
"latemount" flag and triggering fs encryption state event. With "--late" set,
|
||||
init executable will only mount entries with "latemount" flag. By default,
|
||||
no option is set, and mount\_all will process all entries in the given fstab.
|
||||
If the fstab parameter is not specified, fstab.${ro.boot.fstab_suffix},
|
||||
fstab.${ro.hardware} or fstab.${ro.hardware.platform} will be scanned for
|
||||
under /odm/etc, /vendor/etc, or / at runtime, in that order.
|
||||
|
||||
`mount <type> <device> <dir> [ <flag>\* ] [<options>]`
|
||||
> Attempt to mount the named device at the directory _dir_
|
||||
|
|
|
@ -518,21 +518,21 @@ static Result<void> do_mount(const BuiltinArguments& args) {
|
|||
|
||||
/* Imports .rc files from the specified paths. Default ones are applied if none is given.
|
||||
*
|
||||
* start_index: index of the first path in the args list
|
||||
* rc_paths: list of paths to rc files to import
|
||||
*/
|
||||
static void import_late(const std::vector<std::string>& args, size_t start_index, size_t end_index) {
|
||||
static void import_late(const std::vector<std::string>& rc_paths) {
|
||||
auto& action_manager = ActionManager::GetInstance();
|
||||
auto& service_list = ServiceList::GetInstance();
|
||||
Parser parser = CreateParser(action_manager, service_list);
|
||||
if (end_index <= start_index) {
|
||||
if (rc_paths.empty()) {
|
||||
// Fallbacks for partitions on which early mount isn't enabled.
|
||||
for (const auto& path : late_import_paths) {
|
||||
parser.ParseConfig(path);
|
||||
}
|
||||
late_import_paths.clear();
|
||||
} else {
|
||||
for (size_t i = start_index; i < end_index; ++i) {
|
||||
parser.ParseConfig(args[i]);
|
||||
for (const auto& rc_path : rc_paths) {
|
||||
parser.ParseConfig(rc_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -633,48 +633,44 @@ static Result<void> queue_fs_event(int code, bool userdata_remount) {
|
|||
|
||||
static int initial_mount_fstab_return_code = -1;
|
||||
|
||||
/* mount_all <fstab> [ <path> ]* [--<options>]*
|
||||
/* <= Q: mount_all <fstab> [ <path> ]* [--<options>]*
|
||||
* >= R: mount_all [ <fstab> ] [--<options>]*
|
||||
*
|
||||
* This function might request a reboot, in which case it will
|
||||
* not return.
|
||||
*/
|
||||
static Result<void> do_mount_all(const BuiltinArguments& args) {
|
||||
std::size_t na = 0;
|
||||
bool import_rc = true;
|
||||
bool queue_event = true;
|
||||
int mount_mode = MOUNT_MODE_DEFAULT;
|
||||
const auto& fstab_file = args[1];
|
||||
std::size_t path_arg_end = args.size();
|
||||
const char* prop_post_fix = "default";
|
||||
auto mount_all = ParseMountAll(args.args);
|
||||
if (!mount_all.ok()) return mount_all.error();
|
||||
|
||||
for (na = args.size() - 1; na > 1; --na) {
|
||||
if (args[na] == "--early") {
|
||||
path_arg_end = na;
|
||||
queue_event = false;
|
||||
mount_mode = MOUNT_MODE_EARLY;
|
||||
prop_post_fix = "early";
|
||||
} else if (args[na] == "--late") {
|
||||
path_arg_end = na;
|
||||
import_rc = false;
|
||||
mount_mode = MOUNT_MODE_LATE;
|
||||
prop_post_fix = "late";
|
||||
}
|
||||
const char* prop_post_fix = "default";
|
||||
bool queue_event = true;
|
||||
if (mount_all->mode == MOUNT_MODE_EARLY) {
|
||||
prop_post_fix = "early";
|
||||
queue_event = false;
|
||||
} else if (mount_all->mode == MOUNT_MODE_LATE) {
|
||||
prop_post_fix = "late";
|
||||
}
|
||||
|
||||
std::string prop_name = "ro.boottime.init.mount_all."s + prop_post_fix;
|
||||
android::base::Timer t;
|
||||
|
||||
Fstab fstab;
|
||||
if (!ReadFstabFromFile(fstab_file, &fstab)) {
|
||||
return Error() << "Could not read fstab";
|
||||
if (mount_all->fstab_path.empty()) {
|
||||
if (!ReadDefaultFstab(&fstab)) {
|
||||
return Error() << "Could not read default fstab";
|
||||
}
|
||||
} else {
|
||||
if (!ReadFstabFromFile(mount_all->fstab_path, &fstab)) {
|
||||
return Error() << "Could not read fstab";
|
||||
}
|
||||
}
|
||||
|
||||
auto mount_fstab_return_code = fs_mgr_mount_all(&fstab, mount_mode);
|
||||
auto mount_fstab_return_code = fs_mgr_mount_all(&fstab, mount_all->mode);
|
||||
SetProperty(prop_name, std::to_string(t.duration().count()));
|
||||
|
||||
if (import_rc && SelinuxGetVendorAndroidVersion() <= __ANDROID_API_Q__) {
|
||||
/* Paths of .rc files are specified at the 2nd argument and beyond */
|
||||
import_late(args.args, 2, path_arg_end);
|
||||
if (mount_all->import_rc) {
|
||||
import_late(mount_all->rc_paths);
|
||||
}
|
||||
|
||||
if (queue_event) {
|
||||
|
@ -690,11 +686,20 @@ static Result<void> do_mount_all(const BuiltinArguments& args) {
|
|||
return {};
|
||||
}
|
||||
|
||||
/* umount_all <fstab> */
|
||||
/* umount_all [ <fstab> ] */
|
||||
static Result<void> do_umount_all(const BuiltinArguments& args) {
|
||||
auto umount_all = ParseUmountAll(args.args);
|
||||
if (!umount_all.ok()) return umount_all.error();
|
||||
|
||||
Fstab fstab;
|
||||
if (!ReadFstabFromFile(args[1], &fstab)) {
|
||||
return Error() << "Could not read fstab";
|
||||
if (umount_all->empty()) {
|
||||
if (!ReadDefaultFstab(&fstab)) {
|
||||
return Error() << "Could not read default fstab";
|
||||
}
|
||||
} else {
|
||||
if (!ReadFstabFromFile(*umount_all, &fstab)) {
|
||||
return Error() << "Could not read fstab";
|
||||
}
|
||||
}
|
||||
|
||||
if (auto result = fs_mgr_umount_all(&fstab); result != 0) {
|
||||
|
@ -1349,11 +1354,11 @@ const BuiltinFunctionMap& GetBuiltinFunctionMap() {
|
|||
// mount_all is currently too complex to run in vendor_init as it queues action triggers,
|
||||
// imports rc scripts, etc. It should be simplified and run in vendor_init context.
|
||||
// mount and umount are run in the same context as mount_all for symmetry.
|
||||
{"mount_all", {1, kMax, {false, do_mount_all}}},
|
||||
{"mount_all", {0, kMax, {false, do_mount_all}}},
|
||||
{"mount", {3, kMax, {false, do_mount}}},
|
||||
{"perform_apex_config", {0, 0, {false, do_perform_apex_config}}},
|
||||
{"umount", {1, 1, {false, do_umount}}},
|
||||
{"umount_all", {1, 1, {false, do_umount_all}}},
|
||||
{"umount_all", {0, 1, {false, do_umount_all}}},
|
||||
{"update_linker_config", {0, 0, {false, do_update_linker_config}}},
|
||||
{"readahead", {1, 2, {true, do_readahead}}},
|
||||
{"remount_userdata", {0, 0, {false, do_remount_userdata}}},
|
||||
|
|
|
@ -123,6 +123,14 @@ Result<void> check_loglevel(const BuiltinArguments& args) {
|
|||
return {};
|
||||
}
|
||||
|
||||
Result<void> check_mount_all(const BuiltinArguments& args) {
|
||||
auto options = ParseMountAll(args.args);
|
||||
if (!options.ok()) {
|
||||
return options.error();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<void> check_mkdir(const BuiltinArguments& args) {
|
||||
auto options = ParseMkdir(args.args);
|
||||
if (!options.ok()) {
|
||||
|
@ -204,6 +212,14 @@ Result<void> check_sysclktz(const BuiltinArguments& args) {
|
|||
return {};
|
||||
}
|
||||
|
||||
Result<void> check_umount_all(const BuiltinArguments& args) {
|
||||
auto options = ParseUmountAll(args.args);
|
||||
if (!options.ok()) {
|
||||
return options.error();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<void> check_wait(const BuiltinArguments& args) {
|
||||
if (args.size() == 3 && !args[2].empty()) {
|
||||
double timeout_double;
|
||||
|
|
|
@ -32,11 +32,13 @@ Result<void> check_interface_stop(const BuiltinArguments& args);
|
|||
Result<void> check_load_system_props(const BuiltinArguments& args);
|
||||
Result<void> check_loglevel(const BuiltinArguments& args);
|
||||
Result<void> check_mkdir(const BuiltinArguments& args);
|
||||
Result<void> check_mount_all(const BuiltinArguments& args);
|
||||
Result<void> check_restorecon(const BuiltinArguments& args);
|
||||
Result<void> check_restorecon_recursive(const BuiltinArguments& args);
|
||||
Result<void> check_setprop(const BuiltinArguments& args);
|
||||
Result<void> check_setrlimit(const BuiltinArguments& args);
|
||||
Result<void> check_sysclktz(const BuiltinArguments& args);
|
||||
Result<void> check_umount_all(const BuiltinArguments& args);
|
||||
Result<void> check_wait(const BuiltinArguments& args);
|
||||
Result<void> check_wait_for_prop(const BuiltinArguments& args);
|
||||
|
||||
|
|
|
@ -572,6 +572,48 @@ Result<MkdirOptions> ParseMkdir(const std::vector<std::string>& args) {
|
|||
return MkdirOptions{args[1], mode, *uid, *gid, fscrypt_action, ref_option};
|
||||
}
|
||||
|
||||
Result<MountAllOptions> ParseMountAll(const std::vector<std::string>& args) {
|
||||
bool compat_mode = false;
|
||||
bool import_rc = false;
|
||||
if (SelinuxGetVendorAndroidVersion() <= __ANDROID_API_Q__) {
|
||||
if (args.size() <= 1) {
|
||||
return Error() << "mount_all requires at least 1 argument";
|
||||
}
|
||||
compat_mode = true;
|
||||
import_rc = true;
|
||||
}
|
||||
|
||||
std::size_t first_option_arg = args.size();
|
||||
enum mount_mode mode = MOUNT_MODE_DEFAULT;
|
||||
|
||||
// If we are <= Q, then stop looking for non-fstab arguments at slot 2.
|
||||
// Otherwise, stop looking at slot 1 (as the fstab path argument is optional >= R).
|
||||
for (std::size_t na = args.size() - 1; na > (compat_mode ? 1 : 0); --na) {
|
||||
if (args[na] == "--early") {
|
||||
first_option_arg = na;
|
||||
mode = MOUNT_MODE_EARLY;
|
||||
} else if (args[na] == "--late") {
|
||||
first_option_arg = na;
|
||||
mode = MOUNT_MODE_LATE;
|
||||
import_rc = false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string fstab_path;
|
||||
if (first_option_arg > 1) {
|
||||
fstab_path = args[1];
|
||||
} else if (compat_mode) {
|
||||
return Error() << "mount_all argument 1 must be the fstab path";
|
||||
}
|
||||
|
||||
std::vector<std::string> rc_paths;
|
||||
for (std::size_t na = 2; na < first_option_arg; ++na) {
|
||||
rc_paths.push_back(args[na]);
|
||||
}
|
||||
|
||||
return MountAllOptions{rc_paths, fstab_path, mode, import_rc};
|
||||
}
|
||||
|
||||
Result<std::pair<int, std::vector<std::string>>> ParseRestorecon(
|
||||
const std::vector<std::string>& args) {
|
||||
struct flag_type {
|
||||
|
@ -612,6 +654,15 @@ Result<std::pair<int, std::vector<std::string>>> ParseRestorecon(
|
|||
return std::pair(flag, paths);
|
||||
}
|
||||
|
||||
Result<std::string> ParseUmountAll(const std::vector<std::string>& args) {
|
||||
if (SelinuxGetVendorAndroidVersion() <= __ANDROID_API_Q__) {
|
||||
if (args.size() <= 1) {
|
||||
return Error() << "umount_all requires at least 1 argument";
|
||||
}
|
||||
}
|
||||
return args[1];
|
||||
}
|
||||
|
||||
static void InitAborter(const char* abort_message) {
|
||||
// When init forks, it continues to use this aborter for LOG(FATAL), but we want children to
|
||||
// simply abort instead of trying to reboot the system.
|
||||
|
|
18
init/util.h
18
init/util.h
|
@ -22,6 +22,7 @@
|
|||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <android-base/chrono_utils.h>
|
||||
|
||||
|
@ -33,6 +34,12 @@ using android::base::boot_clock;
|
|||
namespace android {
|
||||
namespace init {
|
||||
|
||||
enum mount_mode {
|
||||
MOUNT_MODE_DEFAULT = 0,
|
||||
MOUNT_MODE_EARLY = 1,
|
||||
MOUNT_MODE_LATE = 2,
|
||||
};
|
||||
|
||||
static const char kColdBootDoneProp[] = "ro.cold_boot_done";
|
||||
|
||||
extern void (*trigger_shutdown)(const std::string& command);
|
||||
|
@ -73,9 +80,20 @@ struct MkdirOptions {
|
|||
|
||||
Result<MkdirOptions> ParseMkdir(const std::vector<std::string>& args);
|
||||
|
||||
struct MountAllOptions {
|
||||
std::vector<std::string> rc_paths;
|
||||
std::string fstab_path;
|
||||
mount_mode mode;
|
||||
bool import_rc;
|
||||
};
|
||||
|
||||
Result<MountAllOptions> ParseMountAll(const std::vector<std::string>& args);
|
||||
|
||||
Result<std::pair<int, std::vector<std::string>>> ParseRestorecon(
|
||||
const std::vector<std::string>& args);
|
||||
|
||||
Result<std::string> ParseUmountAll(const std::vector<std::string>& args);
|
||||
|
||||
void SetStdioToDevNull(char** argv);
|
||||
void InitKernelLogging(char** argv);
|
||||
void InitSecondStageLogging(char** argv);
|
||||
|
|
Loading…
Reference in a new issue