Beispiel #1
0
/* 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;
}