summaryrefslogtreecommitdiffstats
path: root/fs_mgr/fs_mgr_fstab.cpp
diff options
context:
space:
mode:
authorBowgo Tsai <bowgotsai@google.com>2017-03-06 22:22:07 +0800
committerBowgo Tsai <bowgotsai@google.com>2017-03-09 21:15:08 +0800
commit47d342739a295a39684c8531d83cd385cbf7d885 (patch)
tree094c1a49869cf7e1598d86ae9a62a714c3f72fab /fs_mgr/fs_mgr_fstab.cpp
parentc1b3c8ef2629eac2a73aa4a95bf43a66edf4cd0f (diff)
downloadsystem_core-47d342739a295a39684c8531d83cd385cbf7d885.tar.gz
system_core-47d342739a295a39684c8531d83cd385cbf7d885.tar.bz2
system_core-47d342739a295a39684c8531d83cd385cbf7d885.zip
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
Diffstat (limited to 'fs_mgr/fs_mgr_fstab.cpp')
-rw-r--r--fs_mgr/fs_mgr_fstab.cpp111
1 files changed, 64 insertions, 47 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<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 = 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;
- }
+ std::string default_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)