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