From 47d342739a295a39684c8531d83cd385cbf7d885 Mon Sep 17 00:00:00 2001 From: Bowgo Tsai Date: Mon, 6 Mar 2017 22:22:07 +0800 Subject: [PATCH] fs_mgr: add fs_mgr_read_fstab_with_dt() API With the early mount support in init, fstab entries of verified partitions (e.g., /system, /vendor) will be moved into device tree in kernel image. Those early mount fstab entries will be removed from the fstab file to prevent duplicated and/or inconsistent settings. This change adds a new function: fs_mgr_read_fstab_with_dt(), to return the combined results from both places. It also removes fs_mgr_read_fstab_file() from the public APIs and makes it as an internal function. Bug: 35811655 Test: early mount /vendor with dm-verity on sailfish Change-Id: I2fba3614685bf9f852a789cda6f53013e2164e60 --- fs_mgr/fs_mgr_fstab.cpp | 111 +++++++++++++++++++++++----------------- fs_mgr/include/fs_mgr.h | 2 +- 2 files changed, 65 insertions(+), 48 deletions(-) diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp index 5b0243d0e..b1ca0a2ac 100644 --- a/fs_mgr/fs_mgr_fstab.cpp +++ b/fs_mgr/fs_mgr_fstab.cpp @@ -404,7 +404,7 @@ bool is_dt_compatible() { return false; } -struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file) +static struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file) { int cnt, entries; ssize_t len; @@ -540,6 +540,41 @@ err: 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) 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 pointer directly *without* malloc and memcpy + a->recs[i] = b->recs[j]; + } + + // Frees up b, but don't free b->recs[X] to make sure they are + // accessible through a->recs[X]. + free(b->fstab_filename); + free(b); + + a->num_entries = total_entries; + return a; +} + struct fstab *fs_mgr_read_fstab(const char *fstab_path) { FILE *fstab_file; @@ -547,13 +582,17 @@ struct fstab *fs_mgr_read_fstab(const char *fstab_path) fstab_file = fopen(fstab_path, "r"); if (!fstab_file) { - LERROR << "Cannot open file " << fstab_path; - return NULL; + PERROR << __FUNCTION__<< "(): cannot open file: '" << fstab_path << "'"; + return nullptr; } + fstab = fs_mgr_read_fstab_file(fstab_file); if (fstab) { fstab->fstab_filename = strdup(fstab_path); + } else { + LERROR << __FUNCTION__ << "(): failed to load fstab from : '" << fstab_path << "'"; } + fclose(fstab_file); return fstab; } @@ -565,75 +604,53 @@ struct fstab *fs_mgr_read_fstab_dt() { std::string fstab_buf = read_fstab_from_dt(); if (fstab_buf.empty()) { - return NULL; + LERROR << __FUNCTION__ << "(): failed to read fstab from dt"; + return nullptr; } std::unique_ptr fstab_file( fmemopen(static_cast(const_cast(fstab_buf.c_str())), fstab_buf.length(), "r"), fclose); if (!fstab_file) { - return NULL; + PERROR << __FUNCTION__ << "(): failed to create a file stream for fstab dt"; + return nullptr; } struct fstab *fstab = fs_mgr_read_fstab_file(fstab_file.get()); if (!fstab) { - LERROR << "failed to load fstab from kernel:" << std::endl << fstab_buf; + LERROR << __FUNCTION__ << "(): failed to load fstab from kernel:" + << std::endl << fstab_buf; } return fstab; } +/* combines fstab entries passed in from device tree with + * the ones found from fstab_path + */ +struct fstab *fs_mgr_read_fstab_with_dt(const char *fstab_path) +{ + struct fstab *fstab_dt = fs_mgr_read_fstab_dt(); + struct fstab *fstab = fs_mgr_read_fstab(fstab_path); + + return in_place_merge(fstab_dt, fstab); +} + /* combines fstab entries passed in from device tree with * the ones found in /fstab. */ struct fstab *fs_mgr_read_fstab_default() { - struct fstab *fstab = fs_mgr_read_fstab_dt(); std::string hw; - if (!fs_mgr_get_boot_config("hardware", &hw)) { - // if we fail to find this, return whatever was found in device tree - LWARNING << "failed to find device hardware name"; - return fstab; - } + std::string default_fstab; - std::string default_fstab = FSTAB_PREFIX + hw; - struct fstab *f = fs_mgr_read_fstab(default_fstab.c_str()); - if (!f) { - // return what we have - LWARNING << "failed to read fstab entries from '" << default_fstab << "'"; - return fstab; - } - - // return the fstab read from file if device tree doesn't - // have one, other wise merge the two - if (!fstab) { - fstab = f; + if (fs_mgr_get_boot_config("hardware", &hw)) { + default_fstab = FSTAB_PREFIX + hw; } else { - int total_entries = fstab->num_entries + f->num_entries; - fstab->recs = static_cast(realloc( - fstab->recs, total_entries * (sizeof(struct fstab_rec)))); - if (!fstab->recs) { - LERROR << "failed to allocate fstab recs"; - fstab->num_entries = 0; - fs_mgr_free_fstab(fstab); - return NULL; - } - - for (int i = fstab->num_entries, j = 0; i < total_entries; i++, j++) { - // copy everything and *not* strdup - fstab->recs[i] = f->recs[j]; - } - - // free up fstab entries read from file, but don't cleanup - // the strings within f->recs[X] to make sure they are accessible - // through fstab->recs[X]. - free(f->fstab_filename); - free(f); - - fstab->num_entries = total_entries; + LWARNING << __FUNCTION__ << "(): failed to find device hardware name"; } - return fstab; + return fs_mgr_read_fstab_with_dt(default_fstab.c_str()); } void fs_mgr_free_fstab(struct fstab *fstab) diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h index a5e5bebb9..e4aeb482a 100644 --- a/fs_mgr/include/fs_mgr.h +++ b/fs_mgr/include/fs_mgr.h @@ -87,8 +87,8 @@ typedef void (*fs_mgr_verity_state_callback)(struct fstab_rec *fstab, struct fstab *fs_mgr_read_fstab_default(); struct fstab *fs_mgr_read_fstab_dt(); -struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file); struct fstab *fs_mgr_read_fstab(const char *fstab_path); +struct fstab *fs_mgr_read_fstab_with_dt(const char *fstab_path); void fs_mgr_free_fstab(struct fstab *fstab); #define FS_MGR_MNTALL_DEV_FILE_ENCRYPTED 5