Merge "fs_mgr: Create a C++ Fstab struct"
This commit is contained in:
commit
0c7fb42949
|
@ -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<struct fstab *>(calloc(1, sizeof(struct fstab)));
|
||||
fstab->num_entries = entries;
|
||||
fstab->recs = static_cast<struct fstab_rec *>(
|
||||
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<struct fstab_rec *>(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 <device>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<std::string> extract_boot_devices(const fstab& fstab) {
|
||||
static std::set<std::string> extract_boot_devices(const Fstab& fstab) {
|
||||
std::set<std::string> 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<std::string> 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<FILE, decltype(&fclose)>{fopen(fstab_path, "re"), fclose};
|
||||
bool ReadFstabFromFile(const std::string& path, Fstab* fstab) {
|
||||
auto fstab_file = std::unique_ptr<FILE, decltype(&fclose)>{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<FILE, decltype(&fclose)> 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<std::string> fs_mgr_get_boot_devices() {
|
|||
}
|
||||
|
||||
// Fallback to extract boot devices from fstab.
|
||||
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> 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<struct fstab*>(calloc(1, sizeof(struct fstab)));
|
||||
legacy_fstab->num_entries = fstab.size();
|
||||
legacy_fstab->recs =
|
||||
static_cast<fstab_rec*>(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)
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <android-base/logging.h>
|
||||
#include <fs_mgr.h>
|
||||
#include <fstab/fstab.h>
|
||||
|
||||
#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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CORE_FS_TAB_H
|
||||
#define __CORE_FS_TAB_H
|
||||
#pragma once
|
||||
|
||||
#include <linux/dm-ioctl.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -25,6 +24,7 @@
|
|||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/*
|
||||
* 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<std::string> 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<FstabEntry>;
|
||||
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue