// 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; }
// 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; }
void load_recovery_id_prop() { char fstab_filename[PROP_VALUE_MAX + sizeof(FSTAB_PREFIX)]; char propbuf[PROP_VALUE_MAX]; int ret = property_get("ro.hardware", propbuf); if (!ret) { ERROR("ro.hardware not set - unable to load recovery id\n"); return; } snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX "%s", propbuf); std::unique_ptr<fstab, void(*)(fstab*)> tab(fs_mgr_read_fstab(fstab_filename), fs_mgr_free_fstab); if (!tab) { ERROR("unable to read fstab %s: %s\n", fstab_filename, strerror(errno)); return; } fstab_rec* rec = fs_mgr_get_entry_for_mount_point(tab.get(), RECOVERY_MOUNT_POINT); if (rec == NULL) { ERROR("/recovery not specified in fstab\n"); return; } int fd = open(rec->blk_device, O_RDONLY); if (fd == -1) { ERROR("error opening block device %s: %s\n", rec->blk_device, strerror(errno)); return; } boot_img_hdr hdr; if (android::base::ReadFully(fd, &hdr, sizeof(hdr))) { std::string hex = bytes_to_hex(reinterpret_cast<uint8_t*>(hdr.id), sizeof(hdr.id)); property_set("ro.recovery_id", hex.c_str()); } else { ERROR("error reading /recovery: %s\n", strerror(errno)); } close(fd); }
Volume* volume_for_path(const char* path) { fstab_rec *rec = fs_mgr_get_entry_for_mount_point(fstab, path); if (rec == NULL) 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(NULL, "TYPE", rec->blk_device); if (detected_fs_type == NULL) return rec; fstab_rec *fetched_rec = rec; while (rec != NULL && strcmp(rec->fs_type, detected_fs_type) != 0) rec = fs_mgr_get_entry_for_mount_point_after(rec, fstab, path); if (rec == NULL) return fetched_rec; } return rec; }
void load_recovery_id_prop() { std::string ro_hardware = property_get("ro.hardware"); if (ro_hardware.empty()) { LOG(ERROR) << "ro.hardware not set - unable to load recovery id"; return; } std::string fstab_filename = FSTAB_PREFIX + ro_hardware; std::unique_ptr<fstab, void(*)(fstab*)> tab(fs_mgr_read_fstab(fstab_filename.c_str()), fs_mgr_free_fstab); if (!tab) { PLOG(ERROR) << "unable to read fstab " << fstab_filename; return; } fstab_rec* rec = fs_mgr_get_entry_for_mount_point(tab.get(), RECOVERY_MOUNT_POINT); if (rec == NULL) { LOG(ERROR) << "/recovery not specified in fstab"; return; } int fd = open(rec->blk_device, O_RDONLY); if (fd == -1) { PLOG(ERROR) << "error opening block device " << rec->blk_device; return; } boot_img_hdr hdr; if (android::base::ReadFully(fd, &hdr, sizeof(hdr))) { std::string hex = bytes_to_hex(reinterpret_cast<uint8_t*>(hdr.id), sizeof(hdr.id)); property_set("ro.recovery_id", hex.c_str()); } else { PLOG(ERROR) << "error reading /recovery"; } close(fd); }
Volume* volume_for_path(const char* path) { return fs_mgr_get_entry_for_mount_point(fstab, path); }
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; }
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; }