Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a9c227a4 authored by Dan Pasanen's avatar Dan Pasanen Committed by Tom Marshall
Browse files

recovery: autodetect filesystem type

* Multiple fstab lines (supported in android) cause recovery to fail
  to mount partitions if the fs type is not the same as the first
  fstab entry. So when we attempt to find an fstab entry that matches
  a path for an f2fs, ext4 or vfat type, check it against blkid's
  determination of what filesystem type it is. If there is a discrepancy,
  query fs_mgr for the next possible entry that matches that path until
  either we find one that is good, or run out of fstab entries.

* Also attempt to autodetect the filesystem type for mounting from
  update.zips.

Change-Id: Ib6f4535dd88ef714ae1ca6fb0ffae1c7dac0f7ce
parent 07b55776
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -154,6 +154,7 @@ endif

LOCAL_C_INCLUDES += \
    system/vold \
    external/e2fsprogs/lib

LOCAL_STATIC_LIBRARIES := \
    libmksh_driver \
@@ -163,6 +164,8 @@ LOCAL_STATIC_LIBRARIES := \
    libbootloader_message \
    libfs_mgr \
    libext4_utils \
    libext2_blkid \
    libext2_uuid \
    libsparse \
    libreboot \
    libziparchive \
@@ -318,6 +321,8 @@ LOCAL_CFLAGS += -DMINIVOLD
LOCAL_CFLAGS += -Wno-unused-parameter
LOCAL_STATIC_LIBRARIES += \
    libext4_utils \
    libext2_blkid \
    libext2_uuid \
    libsparse \
    libmounts \
    libz \
@@ -344,7 +349,8 @@ LOCAL_C_INCLUDES += \
    external/libtar/listhash \
    external/openssl/include \
    external/zlib \
    bionic/libc/bionic
    bionic/libc/bionic \
    external/e2fsprogs/lib

include $(BUILD_EXECUTABLE)

+30 −1
Original line number Diff line number Diff line
@@ -39,6 +39,11 @@

#include "voldclient.h"

#ifdef __bitwise
#undef __bitwise
#endif
#include <blkid/blkid.h>

static struct fstab* fstab = nullptr;

extern struct selabel_handle* sehandle;
@@ -120,7 +125,31 @@ void load_volume_table() {
}

Volume* volume_for_path(const char* path) {
  return fs_mgr_get_entry_for_mount_point(fstab, path);
  Volume *rec = fs_mgr_get_entry_for_mount_point(fstab, path);

  if (rec == nullptr) {
    return rec;
  }

  if (strcmp(rec->fs_type, "ext4") == 0 || strcmp(rec->fs_type, "f2fs") == 0 ||
      strcmp(rec->fs_type, "vfat") == 0) {
    char *detected_fs_type = blkid_get_tag_value(nullptr, "TYPE", rec->blk_device);

    if (detected_fs_type == nullptr) {
      return rec;
    }

    Volume *fetched_rec = rec;
    while (rec != nullptr && strcmp(rec->fs_type, detected_fs_type) != 0) {
      rec = fs_mgr_get_entry_for_mount_point_after(rec, fstab, path);
    }

    if (rec == nullptr) {
      return fetched_rec;
    }
  }

  return rec;
}

Volume* volume_for_label(const char* label) {
+5 −0
Original line number Diff line number Diff line
@@ -46,6 +46,11 @@
#include "updater/install.h"
#include "updater/updater.h"

// For e2fsprogs
extern "C" {
const char* program_name = "updater";
}

struct selabel_handle *sehandle = nullptr;

static void expect(const char* expected, const char* expr_str, CauseCode cause_code,
+8 −0
Original line number Diff line number Diff line
@@ -100,6 +100,14 @@ LOCAL_STATIC_LIBRARIES := \
    $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS) \
    $(updater_common_static_libraries)

# XXX: this does not seem to work, why?
# LOCAL_HEADER_LIBRARIES := libext2-headers

LOCAL_C_INCLUDES += \
    $(call project-path-for,recovery)/otafault \
    external/e2fsprogs/lib
LOCAL_STATIC_LIBRARIES += libext2_blkid libext2_uuid

# Each library in TARGET_RECOVERY_UPDATER_LIBS should have a function
# named "Register_<libname>()".  Here we emit a little C function that
# gets #included by updater.c.  It calls all those registration
+16 −1
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include <time.h>
#include <unistd.h>
#include <utime.h>
#include <blkid/blkid.h>

#include <memory>
#include <string>
@@ -138,7 +139,7 @@ Value* MountFn(const char* name, State* state, const std::vector<std::unique_ptr
  if (!ReadArgs(state, argv, &args)) {
    return ErrorAbort(state, kArgsParsingFailure, "%s() Failed to parse the argument(s)", name);
  }
  const std::string& fs_type = args[0];
  std::string& fs_type = args[0];
  const std::string& partition_type = args[1];
  const std::string& location = args[2];
  const std::string& mount_point = args[3];
@@ -179,6 +180,20 @@ Value* MountFn(const char* name, State* state, const std::vector<std::unique_ptr
    }
  }

  std::string detected_fs_type;
  char *val = blkid_get_tag_value(NULL, "TYPE", location.c_str());
  if (val) {
      detected_fs_type = val;
  }
  if (!detected_fs_type.empty()) {
      uiPrintf(state, "detected filesystem %s for %s\n",
              detected_fs_type.c_str(), location.c_str());
      fs_type = detected_fs_type;
  } else {
      uiPrintf(state, "could not detect filesystem for %s, assuming %s\n",
              location.c_str(), fs_type.c_str());
  }

  if (mount(location.c_str(), mount_point.c_str(), fs_type.c_str(),
            MS_NOATIME | MS_NODEV | MS_NODIRATIME, mount_options.c_str()) < 0) {
    uiPrintf(state, "%s: Failed to mount %s at %s: %s", name, location.c_str(), mount_point.c_str(),
Loading