struct fstab_rec *fs_mgr_get_by_ueventblock(struct fstab *fstab, uevent_block_t *block) { int i = 0; char buf[PATH_MAX]; char *fstype = NULL; struct fstab_rec *ret = NULL; int rc; if (!fstab) { return NULL; } // build dev name rc = snprintf(buf, sizeof(buf), MBPATH_DEV"/block/%s", block->devname); if (rc<0 || (size_t)rc>=sizeof(buf)) { return NULL; } // get fstype fstype = util_get_fstype(buf); for (i = 0; i < fstab->num_entries; i++) { uevent_block_t *fstab_block = get_blockinfo_for_path(multiboot_get_data()->blockinfo, fstab->recs[i].blk_device); if (!fstab_block) continue; // assume that we only have one global blockinfo list if (fstab_block==block) { ret = &fstab->recs[i]; break; } } free(fstype); return ret; }
static int patch_fstab(struct module_data *data, int index) { int i; struct fstab_rec *rec; struct fstab *fstab_orig = data->target_fstabs[index]; struct fstab *mbfstab = data->multiboot_fstab; // open fstab for writing FILE *f = fopen(fstab_orig->fstab_filename, "w"); if (!f) { ERROR("Error opening fstab!\n"); return -1; } // write new fstab for (i = 0; i < fstab_orig->num_entries; i++) { const char *blk_device = fstab_orig->recs[i].blk_device; const char *mount_point = fstab_orig->recs[i].mount_point; const char *fs_type = fstab_orig->recs[i].fs_type; const char *fs_options = fstab_orig->recs[i].fs_options_unparsed ? : ""; const char *fs_mgr_flags = fstab_orig->recs[i].fs_mgr_flags_unparsed ? : ""; const char *unhandled_columns = fstab_orig->recs[i].unhandled_columns ? : ""; // lookup partition in multiboot fstab bool use_bind = false; // fixup for boot and recovery partitions on 2ndstage devices (busy partition) if (data->sndstage_enabled && data->grub_device.blk_device && data->grub_path) { struct sys_block_uevent *event = get_blockinfo_for_path(data->block_info, blk_device); if (!event) { WARNING ("Couldn't find event_info for path %s!\n", blk_device); } else if (event->linux_major == data->grub_blockinfo->linux_major && event->linux_minor == data->grub_blockinfo->linux_minor) { blk_device = PATH_MOUNTPOINT_GRUB; fs_options = "bind"; } } if (data->multiboot_enabled) { rec = fs_mgr_get_entry_for_mount_point(mbfstab, mount_point); if (rec && fs_mgr_is_multiboot(rec)) { // bind mount if (rec->replacement_bind) { // set new args blk_device = rec->replacement_device; fs_options = "bind"; use_bind = true; } // fsimage mount else { blk_device = rec->replacement_device; } } } // write new entry file_write_fstabrec(f, fstab_orig->twrp, blk_device, mount_point, fs_type, fs_options, fs_mgr_flags, unhandled_columns); // we need a remount for bind mounts to set the flags if (use_bind && strcmp(mount_point, "/system")) { const char *local_fs_options = fstab_orig->recs[i].fs_options_unparsed; char *new_fs_options = NULL; int size = strlen(FS_OPTION_REMOUNT) + strlen(local_fs_options) + 1; // create remount options new_fs_options = malloc(size); snprintf(new_fs_options, size, "%s%s", FS_OPTION_REMOUNT, local_fs_options); // add remount entry file_write_fstabrec(f, fstab_orig->twrp, blk_device, mount_point, fs_type, new_fs_options, "wait", unhandled_columns); // cleanup free(new_fs_options); } } fclose(f); return 0; }