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); }
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; }
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; }
/* * 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; }
/* * 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; }