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
This commit is contained in:
parent
c1b3c8ef26
commit
47d342739a
|
@ -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<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 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<FILE, decltype(&fclose)> fstab_file(
|
||||
fmemopen(static_cast<void*>(const_cast<char*>(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.<hardware>
|
||||
*/
|
||||
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<struct fstab_rec *>(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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue