/* do this by looking for the longest mount point which matches the current directory */ int guess_disk ( char * cwd, size_t cwd_len, char ** dn_guess, char ** mpt_guess) { size_t longest_match = 0; size_t current_length; size_t cwd_length; int local_disk = 0; generic_fsent_t fsent; char *fsname = NULL; char *disk_try = NULL; *dn_guess = NULL; *mpt_guess = NULL; if (getcwd(cwd, cwd_len) == NULL) { return -1; /*NOTREACHED*/ } cwd_length = strlen(cwd); dbprintf(_("guess_disk: %zu: \"%s\"\n"), cwd_length, cwd); if (open_fstab() == 0) { return -1; /*NOTREACHED*/ } while (get_fstab_nextentry(&fsent)) { current_length = fsent.mntdir ? strlen(fsent.mntdir) : (size_t)0; dbprintf(_("guess_disk: %zu: %zu: \"%s\": \"%s\"\n"), longest_match, current_length, fsent.mntdir ? fsent.mntdir : _("(mntdir null)"), fsent.fsname ? fsent.fsname : _("(fsname null)")); if ((current_length > longest_match) && (current_length <= cwd_length) && (g_str_has_prefix(cwd, fsent.mntdir))) { longest_match = current_length; g_free(*mpt_guess); *mpt_guess = g_strdup(fsent.mntdir); if(strncmp(fsent.fsname,DEV_PREFIX,(strlen(DEV_PREFIX)))) { g_free(fsname); fsname = g_strdup(fsent.fsname); } else { g_free(fsname); fsname = g_strdup(fsent.fsname + strlen(DEV_PREFIX)); } local_disk = is_local_fstype(&fsent); dbprintf(_("guess_disk: local_disk = %d, fsname = \"%s\"\n"), local_disk, fsname); } } close_fstab(); if (longest_match == 0) { amfree(*mpt_guess); amfree(fsname); return -1; /* ? at least / should match */ } if (!local_disk) { amfree(*mpt_guess); amfree(fsname); return 0; } /* have mount point now */ /* disk name may be specified by mount point (logical name) or device name, have to determine */ g_printf(_("Trying disk %s ...\n"), *mpt_guess); disk_try = g_strconcat("DISK ", *mpt_guess, NULL); /* try logical name */ if (exchange(disk_try) == -1) exit(1); amfree(disk_try); if (server_happy()) { *dn_guess = g_strdup(*mpt_guess); /* logical is okay */ amfree(fsname); return 1; } g_printf(_("Trying disk %s ...\n"), fsname); disk_try = g_strconcat("DISK ", fsname, NULL); /* try device name */ if (exchange(disk_try) == -1) exit(1); amfree(disk_try); if (server_happy()) { *dn_guess = g_strdup(fsname); /* dev name is okay */ amfree(fsname); return 1; } /* neither is okay */ amfree(*mpt_guess); amfree(fsname); return 2; }
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; }