void load_volume_table()
{
    int i;
    int ret;

    fstab = fs_mgr_read_fstab("/etc/recovery.fstab");
    if (!fstab) {
        LOGE("failed to read /etc/recovery.fstab\n");
        return;
    }

    ret = fs_mgr_add_entry(fstab, "/tmp", "ramdisk", "ramdisk");
    if (ret < 0 ) {
        LOGE("failed to add /tmp entry to fstab\n");
        fs_mgr_free_fstab(fstab);
        fstab = NULL;
        return;
    }

    printf("recovery filesystem table\n");
    printf("=========================\n");
    for (i = 0; i < fstab->num_entries; ++i) {
        Volume* v = &fstab->recs[i];
        printf("  %d %s %s %s %lld\n", i, v->mount_point, v->fs_type,
               v->blk_device, v->length);
    }
    printf("\n");
}
int main(int argc, char *argv[])
{
    int a_flag=0;
    int u_flag=0;
    int n_flag=0;
    char *n_name=NULL;
    char *n_blk_dev=NULL;
    char *fstab_file=NULL;
    struct fstab *fstab=NULL;

    klog_set_level(6);

    parse_options(argc, argv, &a_flag, &u_flag, &n_flag, &n_name, &n_blk_dev);

    /* The name of the fstab file is last, after the option */
    fstab_file = argv[argc - 1];

    fstab = fs_mgr_read_fstab(fstab_file);

    if (a_flag) {
        return fs_mgr_mount_all(fstab);
    } else if (n_flag) {
        return fs_mgr_do_mount(fstab, n_name, n_blk_dev, 0);
    } else if (u_flag) {
        return fs_mgr_unmount_all(fstab);
    } else {
        ERROR("%s: Internal error, unknown option\n", me);
        exit(1);
    }

    fs_mgr_free_fstab(fstab);

    /* Should not get here */
    exit(1);
}
void TrimTask::addFromFstab() {
    struct fstab *fstab;
    struct fstab_rec *prev_rec = NULL;

    fstab = fs_mgr_read_fstab(android::vold::DefaultFstabPath().c_str());
    for (int i = 0; i < fstab->num_entries; i++) {
        /* Skip raw partitions */
        if (!strcmp(fstab->recs[i].fs_type, "emmc") ||
            !strcmp(fstab->recs[i].fs_type, "mtd")) {
            continue;
        }
        /* Skip read-only filesystems */
        if (fstab->recs[i].flags & MS_RDONLY) {
            continue;
        }
        if (fs_mgr_is_voldmanaged(&fstab->recs[i])) {
            continue; /* Should we trim fat32 filesystems? */
        }
        if (fs_mgr_is_notrim(&fstab->recs[i])) {
            continue;
        }

        /* Skip the multi-type partitions, which are required to be following each other.
         * See fs_mgr.c's mount_with_alternatives().
         */
        if (prev_rec && !strcmp(prev_rec->mount_point, fstab->recs[i].mount_point)) {
            continue;
        }

        mPaths.push_back(fstab->recs[i].mount_point);
        prev_rec = &fstab->recs[i];
    }
    fs_mgr_free_fstab(fstab);
}
Beispiel #4
0
// Returns the device used to mount a directory in the fstab.
static std::string find_fstab_mount(const char* dir) {
    std::string fstab_filename = "/fstab." + android::base::GetProperty("ro.hardware", "");
    struct fstab* fstab = fs_mgr_read_fstab(fstab_filename.c_str());
    struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab, dir);
    std::string dev = rec ? std::string(rec->blk_device) : "";
    fs_mgr_free_fstab(fstab);
    return dev;
}
Beispiel #5
0
void load_volume_table()
{
    int i;
    int ret;

    fstab = fs_mgr_read_fstab("/etc/recovery.fstab");
    if (!fstab) {
        LOGE("failed to read /etc/recovery.fstab\n");
        LOGE("try read other fstab\n");
        fstab = mt_read_fstab();
        if (!fstab) {
            LOGE("failed to read fstab\n");
            return;
        }
    }

    ret = fs_mgr_add_entry(fstab, "/tmp", "ramdisk", "ramdisk");
    if (ret < 0 ) {
        LOGE("failed to add /tmp entry to fstab\n");
        fs_mgr_free_fstab(fstab);
        fstab = NULL;
        return;
    }

    ret = mt_load_volume_table(fstab);
    if (ret < 0 ) {
        LOGE("mt_load_volume_table fail to add entry to fstab\n");
        fs_mgr_free_fstab(fstab);
        fstab = NULL;
        return;
    }

    mt_ensure_dev_ready("/misc");
    mt_ensure_dev_ready("/cache");
    mt_fstab_translation_NAND(fstab);

    printf("recovery filesystem table\n");
    printf("=========================\n");
    for (i = 0; i < fstab->num_entries; ++i) {
        Volume* v = &fstab->recs[i];
        printf("  %d %s %s %s %lld\n", i, v->mount_point, v->fs_type,
               v->blk_device, v->length);
    }
    printf("\n");
}
Beispiel #6
0
int do_mount_all(int nargs, char **args)
{
    pid_t pid;
    int ret = -1;
    int child_ret = -1;
    int status;
    const char *prop;
    struct fstab *fstab;

    if (nargs != 2) {
        return -1;
    }

    /*
     * Call fs_mgr_mount_all() to mount all filesystems.  We fork(2) and
     * do the call in the child to provide protection to the main init
     * process if anything goes wrong (crash or memory leak), and wait for
     * the child to finish in the parent.
     */
    pid = fork();
    if (pid > 0) {
        /* Parent.  Wait for the child to return */
        waitpid(pid, &status, 0);
        if (WIFEXITED(status)) {
            ret = WEXITSTATUS(status);
        } else {
            ret = -1;
        }
    } else if (pid == 0) {
        /* child, call fs_mgr_mount_all() */
        klog_set_level(6);  /* So we can see what fs_mgr_mount_all() does */
        fstab = fs_mgr_read_fstab(args[1]);
        child_ret = fs_mgr_mount_all(fstab);
        fs_mgr_free_fstab(fstab);
        if (child_ret == -1) {
            ERROR("fs_mgr_mount_all returned an error\n");
        }
        exit(child_ret);
    } else {
        /* fork failed, return an error */
        return -1;
    }

    /* ret is 1 if the device is encrypted, 0 if not, and -1 on error */
    if (ret == 1) {
        property_set("ro.crypto.state", "encrypted");
        property_set("vold.decrypt", "1");
    } else if (ret == 0) {
        property_set("ro.crypto.state", "unencrypted");
        /* If fs_mgr determined this is an unencrypted device, then trigger
         * that action.
         */
        action_for_each_trigger("nonencrypted", action_add_queue_tail);
    }

    return ret;
}
static int do_swapon_all(const std::vector<std::string>& args) {
    struct fstab *fstab;
    int ret;

    fstab = fs_mgr_read_fstab(args[1].c_str());
    ret = fs_mgr_swapon_all(fstab);
    fs_mgr_free_fstab(fstab);

    return ret;
}
int do_swapon_all(int nargs, char **args)
{
    struct fstab *fstab;
    int ret;

    fstab = fs_mgr_read_fstab(args[1]);
    ret = fs_mgr_swapon_all(fstab);
    fs_mgr_free_fstab(fstab);

    return ret;
}
// Returns the device used to mount a directory in the fstab.
static std::string find_fstab_mount(const char* dir) {
    char propbuf[PROPERTY_VALUE_MAX];

    property_get("ro.hardware", propbuf, "");
    std::string fstab_filename = kFstab_Prefix + propbuf;
    struct fstab* fstab = fs_mgr_read_fstab(fstab_filename.c_str());
    struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab, dir);
    std::string dev = rec ? std::string(rec->blk_device) : "";
    fs_mgr_free_fstab(fstab);
    return dev;
}
Beispiel #10
0
void load_volume_table()
{
    int i;
    int ret;

    fstab = fs_mgr_read_fstab("/etc/recovery.fstab");
    if (!fstab) {
        LOGE("failed to read /etc/recovery.fstab\n");
        return;
    }

    ret = fs_mgr_add_entry(fstab, "/tmp", "ramdisk", "ramdisk");
    if (ret < 0 ) {
        LOGE("failed to add /tmp entry to fstab\n");
        fs_mgr_free_fstab(fstab);
        fstab = NULL;
        return;
    }

    // Create a boring /etc/fstab so tools like Busybox work
    FILE *file = fopen("/etc/fstab", "w");
    if (file == NULL) {
        LOGW("Unable to create /etc/fstab!\n");
        return;
    }

    is_datamedia = 1;

    printf("recovery filesystem table\n");
    printf("=========================\n");
    for (i = 0; i < fstab->num_entries; ++i) {
        fstab_rec* v = &fstab->recs[i];
        printf("  %d %s %s %s %lld\n", i, v->mount_point, v->fs_type,
               v->blk_device, v->length);

        write_fstab_entry(v, file);

        if (is_volume_primary_storage(v)) {
            is_datamedia = 0;
        }
    }

    fclose(file);

    printf("\n");
}
Beispiel #11
0
void load_volume_table() {
    int i;
    int ret;

    fstab = fs_mgr_read_fstab("/etc/recovery.fstab");
    if (!fstab) {
        LOGE("failed to read /etc/recovery.fstab\n");
        return;
    }

    ret = fs_mgr_add_entry(fstab, "/tmp", "ramdisk", "ramdisk", 0);
    if (ret < 0 ) {
        LOGE("failed to add /tmp entry to fstab\n");
        fs_mgr_free_fstab(fstab);
        fstab = NULL;
        return;
    }

    // Process vold-managed volumes with mount point "auto"
    for (i = 0; i < fstab->num_entries; ++i) {
        Volume* v = &fstab->recs[i];
        if (fs_mgr_is_voldmanaged(v) && strcmp(v->mount_point, "auto") == 0) {
            char mount[PATH_MAX];

            // Set the mount point to /storage/label which as used by vold
            snprintf(mount, PATH_MAX, "/storage/%s", v->label);
            free(v->mount_point);
            v->mount_point = strdup(mount);
        }
    }

    fprintf(stderr, "recovery filesystem table\n");
    fprintf(stderr, "=========================\n");
    for (i = 0; i < fstab->num_entries; ++i) {
        Volume* v = &fstab->recs[i];
        fprintf(stderr, "  %d %s %s %s %lld\n", i, v->mount_point, v->fs_type,
               v->blk_device, v->length);
    }
    fprintf(stderr, "\n");
}
struct fstab *fs_mgr_read_fstab(const char *fstab_path)
{
    FILE *fstab_file;
    int cnt, entries;
    ssize_t len;
    size_t alloc_len = 0;
    char *line = NULL;
    const char *delim = " \t";
    char *save_ptr, *p;
    struct fstab *fstab = NULL;
    struct fstab_rec *recs;
    struct fs_mgr_flag_values flag_vals;
#define FS_OPTIONS_LEN 1024
    char tmp_fs_options[FS_OPTIONS_LEN];

    fstab_file = fopen(fstab_path, "r");
    if (!fstab_file) {
        ERROR("Cannot open file %s\n", fstab_path);
        return 0;
    }

    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) {
        ERROR("No entries found in fstab\n");
        goto err;
    }

    /* Allocate and init the fstab structure */
    fstab = calloc(1, sizeof(struct fstab));
    fstab->num_entries = entries;
    fstab->fstab_filename = strdup(fstab_path);
    fstab->recs = 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') {
            line[len - 1] = '\0';
        }

        /* Skip any leading whitespace */
        p = line;
        while (isspace(*p)) {
            p++;
        }
        /* ignore comments or empty lines */
        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) {
            ERROR("Tried to process more entries than counted\n");
            break;
        }

        if (!(p = strtok_r(line, delim, &save_ptr))) {
            ERROR("Error parsing mount source\n");
            goto err;
        }
        fstab->recs[cnt].blk_device = strdup(p);

        if (!(p = strtok_r(NULL, delim, &save_ptr))) {
            ERROR("Error parsing mount_point\n");
            goto err;
        }
        fstab->recs[cnt].mount_point = strdup(p);

        if (!(p = strtok_r(NULL, delim, &save_ptr))) {
            ERROR("Error parsing fs_type\n");
            goto err;
        }
        fstab->recs[cnt].fs_type = strdup(p);

        if (!(p = strtok_r(NULL, delim, &save_ptr))) {
            ERROR("Error parsing mount_flags\n");
            goto err;
        }
        tmp_fs_options[0] = '\0';
        fstab->recs[cnt].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;
        }

        if (!(p = strtok_r(NULL, delim, &save_ptr))) {
            ERROR("Error parsing fs_mgr_options\n");
            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].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].zram_size = flag_vals.zram_size;
        cnt++;
    }
    fclose(fstab_file);
    free(line);
    return fstab;

err:
    fclose(fstab_file);
    free(line);
    if (fstab)
        fs_mgr_free_fstab(fstab);
    return NULL;
}
/*
 * This function might request a reboot, in which case it will
 * not return.
 */
int do_mount_all(int nargs, char **args)
{
    pid_t pid;
    int ret = -1;
    int child_ret = -1;
    int status;
    char boot_mode[PROP_VALUE_MAX] = {0};
    struct fstab *fstab;

    if (nargs != 2) {
        return -1;
    }

    /*
     * Call fs_mgr_mount_all() to mount all filesystems.  We fork(2) and
     * do the call in the child to provide protection to the main init
     * process if anything goes wrong (crash or memory leak), and wait for
     * the child to finish in the parent.
     */
    pid = fork();
    if (pid > 0) {
        /* Parent.  Wait for the child to return */
        int wp_ret = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
        if (wp_ret < 0) {
            /* Unexpected error code. We will continue anyway. */
            NOTICE("waitpid failed rc=%d: %s\n", wp_ret, strerror(errno));
        }

        if (WIFEXITED(status)) {
            ret = WEXITSTATUS(status);
        } else {
            ret = -1;
        }
    } else if (pid == 0) {
        /* child, call fs_mgr_mount_all() */
        klog_set_level(6);  /* So we can see what fs_mgr_mount_all() does */
        fstab = fs_mgr_read_fstab(args[1]);
        child_ret = fs_mgr_mount_all(fstab);
        fs_mgr_free_fstab(fstab);
        if (child_ret == -1) {
            ERROR("fs_mgr_mount_all returned an error\n");
        }
        _exit(child_ret);
    } else {
        /* fork failed, return an error */
        return -1;
    }

    if (ret == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) {
        property_set("vold.decrypt", "trigger_encryption");
    } else if (ret == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) {
        property_set("ro.crypto.state", "encrypted");
        property_set("ro.crypto.type", "block");
        property_set("vold.decrypt", "trigger_default_encryption");
    } else if (ret == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
        property_set("ro.crypto.state", "unencrypted");
        /* If fs_mgr determined this is an unencrypted device and we are
         * not booting into ffbm(fast factory boot mode),then trigger
	 * that action.
         */
        property_get("ro.bootmode", boot_mode);
        if (strncmp(boot_mode, "ffbm", 4))
            action_for_each_trigger("nonencrypted", action_add_queue_tail);
    } else if (ret == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) {
        /* Setup a wipe via recovery, and reboot into recovery */
        ERROR("fs_mgr_mount_all suggested recovery, so wiping data via recovery.\n");
        ret = wipe_data_via_recovery();
        /* If reboot worked, there is no return. */
    } else if (ret == FS_MGR_MNTALL_DEV_DEFAULT_FILE_ENCRYPTED) {
        if (e4crypt_install_keyring()) {
            return -1;
        }
        property_set("ro.crypto.state", "encrypted");
        property_set("ro.crypto.type", "file");

        // Although encrypted, we have device key, so we do not need to
        // do anything different from the nonencrypted case.
        property_get("ro.bootmode", boot_mode);
        if (strncmp(boot_mode, "ffbm", 4))
            action_for_each_trigger("nonencrypted", action_add_queue_tail);
    } else if (ret == FS_MGR_MNTALL_DEV_NON_DEFAULT_FILE_ENCRYPTED) {
        if (e4crypt_install_keyring()) {
            return -1;
        }
        property_set("ro.crypto.state", "encrypted");
        property_set("ro.crypto.type", "file");
        property_set("vold.decrypt", "trigger_restart_min_framework");
    } else if (ret > 0) {
        ERROR("fs_mgr_mount_all returned unexpected error %d\n", ret);
    }
    /* else ... < 0: error */

    return ret;
}
int main(int argc, char **argv)
{
    struct fstab *fstab;
    int ret=0, syspart, i, status;
    char filenamePatched[PATH_MAX], filenameSystem[PATH_MAX];

    // check arguments
    if(argc!=2) {
        ERROR("Invalid Arguments");
        return -EINVAL;
    }

    // get syspart from cmdline
    syspart = getDualbootSyspart();
    if(syspart<0) {
        ERROR("Cannot read system number");
        return -EINVAL;
    }

    // patch fstab
    sprintf(filenamePatched, "%s.patched", argv[1]);
    sprintf(filenameSystem, "%s.system", argv[1]);
    patch_fstab(argv[1], filenamePatched, filenameSystem, syspart);

    // mount system
    fstab = fs_mgr_read_fstab(filenameSystem);
    ret = fs_mgr_mount_all(fstab);
    fs_mgr_free_fstab(fstab);
    if (ret == -1) {
        ERROR("fs_mgr_mount_all returned an error\n");
    }

    // mount data
    fstab = fs_mgr_read_fstab(argv[1]);
    for (i = 0; i < fstab->num_entries; ++i) {
        struct fstab_rec* v = &fstab->recs[i];
        
        if(strcmp(PARTITION_USERDATA, v->blk_device))
            continue;

        if (v->fs_mgr_flags & MF_WAIT) {
            wait_for_file(v->blk_device, WAIT_TIMEOUT);
        }

        if (v->fs_mgr_flags & MF_CHECK) {
            check_fs(v->blk_device, v->fs_type, v->mount_point);
        }

        if(mountScriptExists()) {
            char *e2fsck_argv[] = {
                "/system/bin/mount_ext4.sh",
                v->blk_device,
                v->mount_point
            };
            ret = android_fork_execvp_ext(ARRAY_SIZE(e2fsck_argv), e2fsck_argv, &status, true, LOG_KLOG, true, NULL);
        }
        else {
            ret = mount(v->blk_device, v->mount_point,  v->fs_type, v->flags, v->fs_options);
        }
    }
    fs_mgr_free_fstab(fstab);
    if (ret == -1) {
        ERROR("error mounting userdata\n");
    }
    
    return ret;
}
int boot_info_open_partition(const char *name, uint64_t *out_size, int flags)
{
  char *path;
  int fd;
  struct fstab *fstab;
  struct fstab_rec *record;

  // We can't use fs_mgr to look up |name| because fstab doesn't list
  // every slot partition (it uses the slotselect option to mask the
  // suffix) and |slot| is expected to be of that form, e.g. boot_a.
  //
  // We can however assume that there's an entry for the /misc mount
  // point and use that to get the device file for the misc
  // partition. From there we'll assume that a by-name scheme is used
  // so we can just replace the trailing "misc" by the given |name|,
  // e.g.
  //
  //   /dev/block/platform/soc.0/7824900.sdhci/by-name/misc ->
  //   /dev/block/platform/soc.0/7824900.sdhci/by-name/boot_a
  //
  // If needed, it's possible to relax this assumption in the future
  // by trawling /sys/block looking for the appropriate sibling of
  // misc and then finding an entry in /dev matching the sysfs entry.

  fstab = open_fstab();
  if (fstab == NULL)
    return -1;
  record = fs_mgr_get_entry_for_mount_point(fstab, "/misc");
  if (record == NULL) {
    fs_mgr_free_fstab(fstab);
    return -1;
  }
  if (strcmp(name, "misc") == 0) {
    path = strdup(record->blk_device);
  } else {
    size_t trimmed_len, name_len;
    const char *end_slash = strrchr(record->blk_device, '/');
    if (end_slash == NULL) {
      fs_mgr_free_fstab(fstab);
      return -1;
    }
    trimmed_len = end_slash - record->blk_device + 1;
    name_len = strlen(name);
    path = calloc(trimmed_len + name_len + 1, 1);
    strncpy(path, record->blk_device, trimmed_len);
    strncpy(path + trimmed_len, name, name_len);
  }
  fs_mgr_free_fstab(fstab);

  fd = open(path, flags);
  free(path);

  // If we successfully opened the device, get size if requested.
  if (fd != -1 && out_size != NULL) {
    if (ioctl(fd, BLKGETSIZE64, out_size) != 0) {
      close(fd);
      return -1;
    }
  }

  return fd;
}
/*
 * This function might request a reboot, in which case it will
 * not return.
 */
int do_mount_all(int nargs, char **args)
{
    pid_t pid;
    int ret = -1;
    int child_ret = -1;
    int status;
    struct fstab *fstab;

    if (nargs != 2) {
        return -1;
    }

    /*
     * Call fs_mgr_mount_all() to mount all filesystems.  We fork(2) and
     * do the call in the child to provide protection to the main init
     * process if anything goes wrong (crash or memory leak), and wait for
     * the child to finish in the parent.
     */
    pid = fork();
    if (pid > 0) {
        /* Parent.  Wait for the child to return */
        int wp_ret = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
        if (wp_ret < 0) {
            /* Unexpected error code. We will continue anyway. */
            NOTICE("waitpid failed rc=%d, errno=%d\n", wp_ret, errno);
        }

        if (WIFEXITED(status)) {
            ret = WEXITSTATUS(status);
        } else {
            ret = -1;
        }
    } else if (pid == 0) {
        /* child, call fs_mgr_mount_all() */
        klog_set_level(6);  /* So we can see what fs_mgr_mount_all() does */
        fstab = fs_mgr_read_fstab(args[1]);
        child_ret = fs_mgr_mount_all(fstab);
        fs_mgr_free_fstab(fstab);
        if (child_ret == -1) {
            ERROR("fs_mgr_mount_all returned an error\n");
        }
        _exit(child_ret);
    } else {
        /* fork failed, return an error */
        return -1;
    }

    if (ret == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) {
        property_set("vold.decrypt", "trigger_encryption");
    } else if (ret == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) {
        property_set("ro.crypto.state", "encrypted");
        property_set("vold.decrypt", "trigger_default_encryption");
    } else if (ret == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
        property_set("ro.crypto.state", "unencrypted");
        /* If fs_mgr determined this is an unencrypted device, then trigger
         * that action.
         */
        action_for_each_trigger("nonencrypted", action_add_queue_tail);
    } else if (ret == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) {
        /* Setup a wipe via recovery, and reboot into recovery */
        ERROR("fs_mgr_mount_all suggested recovery, so wiping data via recovery.\n");
        ret = wipe_data_via_recovery();
        /* If reboot worked, there is no return. */
    } else if (ret > 0) {
        ERROR("fs_mgr_mount_all returned unexpected error %d\n", ret);
    }
    /* else ... < 0: error */

    return ret;
}