diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp index 52eeb83f7..31b09448d 100644 --- a/fs_mgr/fs_mgr_fstab.cpp +++ b/fs_mgr/fs_mgr_fstab.cpp @@ -38,21 +38,21 @@ using android::base::StartsWith; const std::string kDefaultAndroidDtDir("/proc/device-tree/firmware/android"); struct fs_mgr_flag_values { - char *key_loc; - char* key_dir; - char *verity_loc; - char *sysfs_path; - off64_t part_length; - char *label; - int partnum; - int swap_prio; - int max_comp_streams; - off64_t zram_size; - off64_t reserved_size; - int file_contents_mode; - int file_names_mode; - off64_t erase_blk_size; - off64_t logical_blk_size; + std::string key_loc; + std::string key_dir; + std::string verity_loc; + std::string sysfs_path; + off64_t part_length = 0; + std::string label; + int partnum = -1; + int swap_prio = -1; + int max_comp_streams = 0; + off64_t zram_size = 0; + off64_t reserved_size = 0; + int file_contents_mode = 0; + int file_names_mode = 0; + off64_t erase_blk_size = 0; + off64_t logical_blk_size = 0; }; struct flag_list { @@ -209,14 +209,6 @@ static int parse_flags(char *flags, struct flag_list *fl, char *p; char *savep; - /* initialize flag values. If we find a relevant flag, we'll - * update the value */ - if (flag_vals) { - memset(flag_vals, 0, sizeof(*flag_vals)); - flag_vals->partnum = -1; - flag_vals->swap_prio = -1; /* negative means it wasn't specified. */ - } - /* initialize fs_options to the null string */ if (fs_options && (fs_options_len > 0)) { fs_options[0] = '\0'; @@ -242,22 +234,22 @@ static int parse_flags(char *flags, struct flag_list *fl, /* The encryptable flag is followed by an = and the * location of the keys. Get it and return it. */ - flag_vals->key_loc = strdup(arg); + flag_vals->key_loc = arg; } else if (flag == MF_VERIFY) { /* If the verify flag is followed by an = and the * location for the verity state, get it and return it. */ - flag_vals->verity_loc = strdup(arg); + flag_vals->verity_loc = arg; } else if (flag == MF_FORCECRYPT) { /* The forceencrypt flag is followed by an = and the * location of the keys. Get it and return it. */ - flag_vals->key_loc = strdup(arg); + flag_vals->key_loc = arg; } else if (flag == MF_FORCEFDEORFBE) { /* The forcefdeorfbe flag is followed by an = and the * location of the keys. Get it and return it. */ - flag_vals->key_loc = strdup(arg); + flag_vals->key_loc = arg; flag_vals->file_contents_mode = EM_AES_256_XTS; flag_vals->file_names_mode = EM_AES_256_CTS; } else if (flag == MF_FILEENCRYPTION) { @@ -285,7 +277,7 @@ static int parse_flags(char *flags, struct flag_list *fl, /* The metadata flag is followed by an = and the * directory for the keys. Get it and return it. */ - flag_vals->key_dir = strdup(arg); + flag_vals->key_dir = arg; } else if (flag == MF_LENGTH) { /* The length flag is followed by an = and the * size of the partition. Get it and return it. @@ -302,8 +294,7 @@ static int parse_flags(char *flags, struct flag_list *fl, auto label_end = strchr(label_start, ':'); if (label_end) { - flag_vals->label = strndup(label_start, - (int) (label_end - label_start)); + flag_vals->label = std::string(label_start, (int)(label_end - label_start)); auto part_start = label_end + 1; if (!strcmp(part_start, "auto")) { flag_vals->partnum = -1; @@ -347,7 +338,7 @@ static int parse_flags(char *flags, struct flag_list *fl, flag_vals->logical_blk_size = val; } else if (flag == MF_SYSFS) { /* The path to trigger device gc by idle-maint of vold. */ - flag_vals->sysfs_path = strdup(arg); + flag_vals->sysfs_path = arg; } break; } @@ -504,49 +495,17 @@ bool is_dt_compatible() { return false; } -static struct fstab* fs_mgr_read_fstab_file(FILE* fstab_file, bool proc_mounts) { - int cnt, entries; +static bool fs_mgr_read_fstab_file(FILE* fstab_file, bool proc_mounts, Fstab* fstab_out) { ssize_t len; size_t alloc_len = 0; char *line = NULL; const char *delim = " \t"; char *save_ptr, *p; - struct fstab *fstab = NULL; + Fstab fstab; struct fs_mgr_flag_values flag_vals; #define FS_OPTIONS_LEN 1024 char tmp_fs_options[FS_OPTIONS_LEN]; - entries = 0; - while ((len = getline(&line, &alloc_len, fstab_file)) != -1) { - /* if the last character is a newline, shorten the string by 1 byte */ - if (line[len - 1] == '\n') { - line[len - 1] = '\0'; - } - /* Skip any leading whitespace */ - p = line; - while (isspace(*p)) { - p++; - } - /* ignore comments or empty lines */ - if (*p == '#' || *p == '\0') - continue; - entries++; - } - - if (!entries) { - LERROR << "No entries found in fstab"; - goto err; - } - - /* Allocate and init the fstab structure */ - fstab = static_cast(calloc(1, sizeof(struct fstab))); - fstab->num_entries = entries; - fstab->recs = static_cast( - calloc(fstab->num_entries, sizeof(struct fstab_rec))); - - fseek(fstab_file, 0, SEEK_SET); - - cnt = 0; while ((len = getline(&line, &alloc_len, fstab_file)) != -1) { /* if the last character is a newline, shorten the string by 1 byte */ if (line[len - 1] == '\n') { @@ -562,46 +521,36 @@ static struct fstab* fs_mgr_read_fstab_file(FILE* fstab_file, bool proc_mounts) if (*p == '#' || *p == '\0') continue; - /* If a non-comment entry is greater than the size we allocated, give an - * error and quit. This can happen in the unlikely case the file changes - * between the two reads. - */ - if (cnt >= entries) { - LERROR << "Tried to process more entries than counted"; - break; - } + FstabEntry entry; if (!(p = strtok_r(line, delim, &save_ptr))) { LERROR << "Error parsing mount source"; goto err; } - fstab->recs[cnt].blk_device = strdup(p); + entry.blk_device = p; if (!(p = strtok_r(NULL, delim, &save_ptr))) { LERROR << "Error parsing mount_point"; goto err; } - fstab->recs[cnt].mount_point = strdup(p); + entry.mount_point = p; if (!(p = strtok_r(NULL, delim, &save_ptr))) { LERROR << "Error parsing fs_type"; goto err; } - fstab->recs[cnt].fs_type = strdup(p); + entry.fs_type = p; if (!(p = strtok_r(NULL, delim, &save_ptr))) { LERROR << "Error parsing mount_flags"; goto err; } tmp_fs_options[0] = '\0'; - fstab->recs[cnt].flags = parse_flags(p, mount_flags, NULL, - tmp_fs_options, FS_OPTIONS_LEN); + entry.flags = parse_flags(p, mount_flags, NULL, tmp_fs_options, FS_OPTIONS_LEN); /* fs_options are optional */ if (tmp_fs_options[0]) { - fstab->recs[cnt].fs_options = strdup(tmp_fs_options); - } else { - fstab->recs[cnt].fs_options = NULL; + entry.fs_options = tmp_fs_options; } // For /proc/mounts, ignore everything after mnt_freq and mnt_passno @@ -611,78 +560,47 @@ static struct fstab* fs_mgr_read_fstab_file(FILE* fstab_file, bool proc_mounts) LERROR << "Error parsing fs_mgr_options"; goto err; } - fstab->recs[cnt].fs_mgr_flags = parse_flags(p, fs_mgr_flags, - &flag_vals, NULL, 0); - fstab->recs[cnt].key_loc = flag_vals.key_loc; - fstab->recs[cnt].key_dir = flag_vals.key_dir; - fstab->recs[cnt].verity_loc = flag_vals.verity_loc; - fstab->recs[cnt].length = flag_vals.part_length; - fstab->recs[cnt].label = flag_vals.label; - fstab->recs[cnt].partnum = flag_vals.partnum; - fstab->recs[cnt].swap_prio = flag_vals.swap_prio; - fstab->recs[cnt].max_comp_streams = flag_vals.max_comp_streams; - fstab->recs[cnt].zram_size = flag_vals.zram_size; - fstab->recs[cnt].reserved_size = flag_vals.reserved_size; - fstab->recs[cnt].file_contents_mode = flag_vals.file_contents_mode; - fstab->recs[cnt].file_names_mode = flag_vals.file_names_mode; - fstab->recs[cnt].erase_blk_size = flag_vals.erase_blk_size; - fstab->recs[cnt].logical_blk_size = flag_vals.logical_blk_size; - fstab->recs[cnt].sysfs_path = flag_vals.sysfs_path; - if (fstab->recs[cnt].fs_mgr_flags & MF_LOGICAL) { - fstab->recs[cnt].logical_partition_name = strdup(fstab->recs[cnt].blk_device); + entry.fs_mgr_flags.val = parse_flags(p, fs_mgr_flags, &flag_vals, NULL, 0); + + entry.key_loc = std::move(flag_vals.key_loc); + entry.key_dir = std::move(flag_vals.key_dir); + entry.verity_loc = std::move(flag_vals.verity_loc); + entry.length = flag_vals.part_length; + entry.label = std::move(flag_vals.label); + entry.partnum = flag_vals.partnum; + entry.swap_prio = flag_vals.swap_prio; + entry.max_comp_streams = flag_vals.max_comp_streams; + entry.zram_size = flag_vals.zram_size; + entry.reserved_size = flag_vals.reserved_size; + entry.file_contents_mode = flag_vals.file_contents_mode; + entry.file_names_mode = flag_vals.file_names_mode; + entry.erase_blk_size = flag_vals.erase_blk_size; + entry.logical_blk_size = flag_vals.logical_blk_size; + entry.sysfs_path = std::move(flag_vals.sysfs_path); + if (entry.fs_mgr_flags.logical) { + entry.logical_partition_name = entry.blk_device; } - cnt++; + fstab.emplace_back(std::move(entry)); } + + if (fstab.empty()) { + LERROR << "No entries found in fstab"; + goto err; + } + /* If an A/B partition, modify block device to be the real block device */ - if (!fs_mgr_update_for_slotselect(fstab)) { + if (!fs_mgr_update_for_slotselect(&fstab)) { LERROR << "Error updating for slotselect"; goto err; } free(line); - return fstab; + *fstab_out = std::move(fstab); + return true; err: free(line); - if (fstab) - fs_mgr_free_fstab(fstab); - return NULL; -} - -/* merges fstab entries from both a and b, then returns the merged result. - * note that the caller should only manage the return pointer without - * doing further memory management for the two inputs, i.e. only need to - * frees up memory of the return value without touching a and b. */ -static struct fstab *in_place_merge(struct fstab *a, struct fstab *b) -{ - if (!a && !b) return nullptr; - if (!a) return b; - if (!b) return a; - - int total_entries = a->num_entries + b->num_entries; - a->recs = static_cast(realloc( - a->recs, total_entries * (sizeof(struct fstab_rec)))); - if (!a->recs) { - LERROR << __FUNCTION__ << "(): failed to allocate fstab recs"; - // If realloc() fails the original block is left untouched; - // it is not freed or moved. So we have to free both a and b here. - fs_mgr_free_fstab(a); - fs_mgr_free_fstab(b); - return nullptr; - } - - for (int i = a->num_entries, j = 0; i < total_entries; i++, j++) { - // Copy the structs by assignment. - a->recs[i] = b->recs[j]; - } - - // We can't call fs_mgr_free_fstab because a->recs still references the - // memory allocated by strdup. - free(b->recs); - free(b); - - a->num_entries = total_entries; - return a; + return false; } /* Extracts s from the by-name symlinks specified in a fstab: @@ -695,11 +613,11 @@ static struct fstab *in_place_merge(struct fstab *a, struct fstab *b) * /dev/block/pci/soc.0/f9824900.sdhci/by-name/vendor * it returns a set { "soc/1da4000.ufshc", "soc.0/f9824900.sdhci" }. */ -static std::set extract_boot_devices(const fstab& fstab) { +static std::set extract_boot_devices(const Fstab& fstab) { std::set boot_devices; - for (int i = 0; i < fstab.num_entries; i++) { - std::string blk_device(fstab.recs[i].blk_device); + for (const auto& entry : fstab) { + std::string blk_device = entry.blk_device; // Skips blk_device that doesn't conform to the format. if (!android::base::StartsWith(blk_device, "/dev/block") || android::base::StartsWith(blk_device, "/dev/block/by-name") || @@ -728,33 +646,36 @@ static std::set extract_boot_devices(const fstab& fstab) { return boot_devices; } -struct fstab *fs_mgr_read_fstab(const char *fstab_path) -{ - struct fstab *fstab; - - auto fstab_file = std::unique_ptr{fopen(fstab_path, "re"), fclose}; +bool ReadFstabFromFile(const std::string& path, Fstab* fstab) { + auto fstab_file = std::unique_ptr{fopen(path.c_str(), "re"), fclose}; if (!fstab_file) { - PERROR << __FUNCTION__<< "(): cannot open file: '" << fstab_path << "'"; + PERROR << __FUNCTION__ << "(): cannot open file: '" << path << "'"; + return false; + } + + if (!fs_mgr_read_fstab_file(fstab_file.get(), path == "/proc/mounts", fstab)) { + LERROR << __FUNCTION__ << "(): failed to load fstab from : '" << path << "'"; + return false; + } + + return true; +} + +struct fstab* fs_mgr_read_fstab(const char* fstab_path) { + Fstab fstab; + if (!ReadFstabFromFile(fstab_path, &fstab)) { return nullptr; } - fstab = fs_mgr_read_fstab_file(fstab_file.get(), !strcmp("/proc/mounts", fstab_path)); - if (!fstab) { - LERROR << __FUNCTION__ << "(): failed to load fstab from : '" << fstab_path << "'"; - } - - return fstab; + return FstabToLegacyFstab(fstab); } -/* Returns fstab entries parsed from the device tree if they - * exist - */ -struct fstab *fs_mgr_read_fstab_dt() -{ +// Returns fstab entries parsed from the device tree if they exist +bool ReadFstabFromDt(Fstab* fstab) { std::string fstab_buf = read_fstab_from_dt(); if (fstab_buf.empty()) { LINFO << __FUNCTION__ << "(): failed to read fstab from dt"; - return nullptr; + return false; } std::unique_ptr fstab_file( @@ -762,16 +683,25 @@ struct fstab *fs_mgr_read_fstab_dt() fstab_buf.length(), "r"), fclose); if (!fstab_file) { PERROR << __FUNCTION__ << "(): failed to create a file stream for fstab dt"; + return false; + } + + if (!fs_mgr_read_fstab_file(fstab_file.get(), false, fstab)) { + LERROR << __FUNCTION__ << "(): failed to load fstab from kernel:" + << std::endl << fstab_buf; + return false; + } + + return true; +} + +struct fstab* fs_mgr_read_fstab_dt() { + Fstab fstab; + if (!ReadFstabFromDt(&fstab)) { return nullptr; } - struct fstab* fstab = fs_mgr_read_fstab_file(fstab_file.get(), false); - if (!fstab) { - LERROR << __FUNCTION__ << "(): failed to load fstab from kernel:" - << std::endl << fstab_buf; - } - - return fstab; + return FstabToLegacyFstab(fstab); } /* @@ -797,32 +727,42 @@ static std::string get_fstab_path() return std::string(); } -/* - * loads the fstab file and combines with fstab entries passed in from device tree. - */ -struct fstab *fs_mgr_read_fstab_default() -{ - std::string default_fstab; +// Loads the fstab file and combines with fstab entries passed in from device tree. +bool ReadDefaultFstab(Fstab* fstab) { + Fstab dt_fstab; + ReadFstabFromDt(&dt_fstab); + *fstab = std::move(dt_fstab); + + std::string default_fstab_path; // Use different fstab paths for normal boot and recovery boot, respectively if (access("/system/bin/recovery", F_OK) == 0) { - default_fstab = "/etc/recovery.fstab"; + default_fstab_path = "/etc/recovery.fstab"; } else { // normal boot - default_fstab = get_fstab_path(); + default_fstab_path = get_fstab_path(); } - struct fstab* fstab = nullptr; - if (!default_fstab.empty()) { - fstab = fs_mgr_read_fstab(default_fstab.c_str()); + Fstab default_fstab; + if (!default_fstab_path.empty()) { + ReadFstabFromFile(default_fstab_path, &default_fstab); } else { LINFO << __FUNCTION__ << "(): failed to find device default fstab"; } - struct fstab* fstab_dt = fs_mgr_read_fstab_dt(); + for (auto&& entry : default_fstab) { + fstab->emplace_back(std::move(entry)); + } - // combines fstab entries passed in from device tree with - // the ones found from default_fstab file - return in_place_merge(fstab_dt, fstab); + return !fstab->empty(); +} + +struct fstab* fs_mgr_read_fstab_default() { + Fstab fstab; + if (!ReadDefaultFstab(&fstab)) { + return nullptr; + } + + return FstabToLegacyFstab(fstab); } void fs_mgr_free_fstab(struct fstab *fstab) @@ -908,11 +848,83 @@ std::set fs_mgr_get_boot_devices() { } // Fallback to extract boot devices from fstab. - std::unique_ptr fstab(fs_mgr_read_fstab_default(), - fs_mgr_free_fstab); - if (fstab) return extract_boot_devices(*fstab); + Fstab fstab; + if (!ReadDefaultFstab(&fstab)) { + return {}; + } - return {}; + return extract_boot_devices(fstab); +} + +FstabEntry FstabRecToFstabEntry(const fstab_rec* fstab_rec) { + FstabEntry entry; + entry.blk_device = fstab_rec->blk_device; + entry.logical_partition_name = fstab_rec->logical_partition_name; + entry.mount_point = fstab_rec->mount_point; + entry.fs_type = fstab_rec->fs_type; + entry.flags = fstab_rec->flags; + entry.fs_options = fstab_rec->fs_options; + entry.fs_mgr_flags.val = fstab_rec->fs_mgr_flags; + entry.key_loc = fstab_rec->key_loc; + entry.key_dir = fstab_rec->key_dir; + entry.verity_loc = fstab_rec->verity_loc; + entry.length = fstab_rec->length; + entry.label = fstab_rec->label; + entry.partnum = fstab_rec->partnum; + entry.swap_prio = fstab_rec->swap_prio; + entry.max_comp_streams = fstab_rec->max_comp_streams; + entry.zram_size = fstab_rec->zram_size; + entry.reserved_size = fstab_rec->reserved_size; + entry.file_contents_mode = fstab_rec->file_contents_mode; + entry.file_names_mode = fstab_rec->file_names_mode; + entry.erase_blk_size = fstab_rec->erase_blk_size; + entry.logical_blk_size = fstab_rec->logical_blk_size; + entry.sysfs_path = fstab_rec->sysfs_path; + + return entry; +} + +Fstab LegacyFstabToFstab(const struct fstab* legacy_fstab) { + Fstab fstab; + for (int i = 0; i < legacy_fstab->num_entries; i++) { + fstab.emplace_back(FstabRecToFstabEntry(&legacy_fstab->recs[i])); + } + + return fstab; +} + +fstab* FstabToLegacyFstab(const Fstab& fstab) { + struct fstab* legacy_fstab = static_cast(calloc(1, sizeof(struct fstab))); + legacy_fstab->num_entries = fstab.size(); + legacy_fstab->recs = + static_cast(calloc(legacy_fstab->num_entries, sizeof(fstab_rec))); + + for (int i = 0; i < legacy_fstab->num_entries; i++) { + legacy_fstab->recs[i].blk_device = strdup(fstab[i].blk_device.c_str()); + legacy_fstab->recs[i].logical_partition_name = + strdup(fstab[i].logical_partition_name.c_str()); + legacy_fstab->recs[i].mount_point = strdup(fstab[i].mount_point.c_str()); + legacy_fstab->recs[i].fs_type = strdup(fstab[i].fs_type.c_str()); + legacy_fstab->recs[i].flags = fstab[i].flags; + legacy_fstab->recs[i].fs_options = strdup(fstab[i].fs_options.c_str()); + legacy_fstab->recs[i].fs_mgr_flags = fstab[i].fs_mgr_flags.val; + legacy_fstab->recs[i].key_loc = strdup(fstab[i].key_loc.c_str()); + legacy_fstab->recs[i].key_dir = strdup(fstab[i].key_dir.c_str()); + legacy_fstab->recs[i].verity_loc = strdup(fstab[i].verity_loc.c_str()); + legacy_fstab->recs[i].length = fstab[i].length; + legacy_fstab->recs[i].label = strdup(fstab[i].label.c_str()); + legacy_fstab->recs[i].partnum = fstab[i].partnum; + legacy_fstab->recs[i].swap_prio = fstab[i].swap_prio; + legacy_fstab->recs[i].max_comp_streams = fstab[i].max_comp_streams; + legacy_fstab->recs[i].zram_size = fstab[i].zram_size; + legacy_fstab->recs[i].reserved_size = fstab[i].reserved_size; + legacy_fstab->recs[i].file_contents_mode = fstab[i].file_contents_mode; + legacy_fstab->recs[i].file_names_mode = fstab[i].file_names_mode; + legacy_fstab->recs[i].erase_blk_size = fstab[i].erase_blk_size; + legacy_fstab->recs[i].logical_blk_size = fstab[i].logical_blk_size; + legacy_fstab->recs[i].sysfs_path = strdup(fstab[i].sysfs_path.c_str()); + } + return legacy_fstab; } int fs_mgr_is_voldmanaged(const struct fstab_rec *fstab) diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h index 87c971ad7..711446c91 100644 --- a/fs_mgr/fs_mgr_priv.h +++ b/fs_mgr/fs_mgr_priv.h @@ -22,6 +22,7 @@ #include #include +#include #include "fs_mgr_priv_boot_config.h" @@ -130,7 +131,7 @@ bool fs_mgr_wait_for_file(const std::string& filename, FileWaitMode wait_mode = FileWaitMode::Exists); int fs_mgr_set_blk_ro(const char* blockdev); -bool fs_mgr_update_for_slotselect(fstab* fstab); +bool fs_mgr_update_for_slotselect(Fstab* fstab); bool fs_mgr_is_device_unlocked(); const std::string& get_android_dt_dir(); bool is_dt_compatible(); diff --git a/fs_mgr/fs_mgr_slotselect.cpp b/fs_mgr/fs_mgr_slotselect.cpp index 3b01d0e80..20d60aea5 100644 --- a/fs_mgr/fs_mgr_slotselect.cpp +++ b/fs_mgr/fs_mgr_slotselect.cpp @@ -31,36 +31,23 @@ std::string fs_mgr_get_slot_suffix() { } // Updates |fstab| for slot_suffix. Returns true on success, false on error. -bool fs_mgr_update_for_slotselect(struct fstab *fstab) { +bool fs_mgr_update_for_slotselect(Fstab* fstab) { int n; std::string ab_suffix; - for (n = 0; n < fstab->num_entries; n++) { - fstab_rec& record = fstab->recs[n]; - if (record.fs_mgr_flags & MF_SLOTSELECT) { - if (ab_suffix.empty()) { - ab_suffix = fs_mgr_get_slot_suffix(); - // Return false if failed to get ab_suffix when MF_SLOTSELECT is specified. - if (ab_suffix.empty()) return false; - } - - char* new_blk_device; - if (asprintf(&new_blk_device, "%s%s", record.blk_device, ab_suffix.c_str()) <= 0) { - return false; - } - free(record.blk_device); - record.blk_device = new_blk_device; - - char* new_partition_name; - if (record.logical_partition_name) { - if (asprintf(&new_partition_name, "%s%s", record.logical_partition_name, - ab_suffix.c_str()) <= 0) { - return false; - } - free(record.logical_partition_name); - record.logical_partition_name = new_partition_name; - } + for (auto& entry : *fstab) { + if (!entry.fs_mgr_flags.slot_select) { + continue; } + + if (ab_suffix.empty()) { + ab_suffix = fs_mgr_get_slot_suffix(); + // Return false if failed to get ab_suffix when MF_SLOTSELECT is specified. + if (ab_suffix.empty()) return false; + } + + entry.blk_device = entry.blk_device + ab_suffix; + entry.logical_partition_name = entry.logical_partition_name + ab_suffix; } return true; } diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h index da13899e0..80bdb8780 100644 --- a/fs_mgr/include_fstab/fstab/fstab.h +++ b/fs_mgr/include_fstab/fstab/fstab.h @@ -14,8 +14,7 @@ * limitations under the License. */ -#ifndef __CORE_FS_TAB_H -#define __CORE_FS_TAB_H +#pragma once #include #include @@ -25,6 +24,7 @@ #include #include +#include /* * The entries must be kept in the same order as they were seen in the fstab. @@ -95,4 +95,82 @@ int fs_mgr_has_sysfs_path(const struct fstab_rec* fstab); std::string fs_mgr_get_slot_suffix(); std::set fs_mgr_get_boot_devices(); -#endif /* __CORE_FS_TAB_H */ +struct FstabEntry { + std::string blk_device; + std::string logical_partition_name; + std::string mount_point; + std::string fs_type; + unsigned long flags = 0; + std::string fs_options; + std::string key_loc; + std::string key_dir; + std::string verity_loc; + off64_t length = 0; + std::string label; + int partnum = -1; + int swap_prio = -1; + int max_comp_streams = 0; + off64_t zram_size = 0; + off64_t reserved_size = 0; + int file_contents_mode = 0; + int file_names_mode = 0; + off64_t erase_blk_size = 0; + off64_t logical_blk_size = 0; + std::string sysfs_path; + + // TODO: Remove this union once fstab_rec is deprecated. It only serves as a + // convenient way to convert between fstab_rec::fs_mgr_flags and these bools. + union { + int val; + struct { + bool wait : 1; + bool check : 1; + bool crypt : 1; + bool nonremovable : 1; + bool vold_managed : 1; + bool length : 1; + bool recovery_only : 1; + bool swap_prio : 1; + bool zram_size : 1; + bool verify : 1; + bool force_crypt : 1; + bool no_emulated_sd : 1; // No emulated sdcard daemon; sd card is the only external + // storage. + bool no_trim : 1; + bool file_encryption : 1; + bool formattable : 1; + bool slot_select : 1; + bool force_fde_or_fbe : 1; + bool late_mount : 1; + bool no_fail : 1; + bool verify_at_boot : 1; + bool max_comp_streams : 1; + bool reserved_size : 1; + bool quota : 1; + bool erase_blk_size : 1; + bool logical_blk_size : 1; + bool avb : 1; + bool key_directory : 1; + bool sysfs : 1; + bool logical : 1; + bool checkpoint_blk : 1; + bool checkpoint_fs : 1; + }; + } fs_mgr_flags; + + bool is_encryptable() const { + return fs_mgr_flags.crypt || fs_mgr_flags.force_crypt || fs_mgr_flags.force_fde_or_fbe; + } +}; + +// An Fstab is a collection of FstabEntry structs. +using Fstab = std::vector; + +bool ReadFstabFromFile(const std::string& path, Fstab* fstab); +bool ReadFstabFromDt(Fstab* fstab); +bool ReadDefaultFstab(Fstab* fstab); + +// Temporary conversion functions. +FstabEntry FstabRecToFstabEntry(const fstab_rec* fstab_rec); +Fstab LegacyFstabToFstab(const struct fstab* legacy_fstab); +fstab* FstabToLegacyFstab(const Fstab& fstab);