Beispiel #1
0
/* Given a partition (eg. /dev/sda2) then return the partition number
 * (eg. 2) and the total number of other partitions.
 */
static int
get_partition_context (guestfs_h *g, const char *partition,
                       int *partnum_ret, int *nr_partitions_ret)
{
  int partnum, nr_partitions;
  CLEANUP_FREE char *device = NULL;
  CLEANUP_FREE_PARTITION_LIST struct guestfs_partition_list *partitions = NULL;

  partnum = guestfs_part_to_partnum (g, partition);
  if (partnum == -1)
    return -1;

  device = guestfs_part_to_dev (g, partition);
  if (device == NULL)
    return -1;

  partitions = guestfs_part_list (g, device);
  if (partitions == NULL)
    return -1;

  nr_partitions = partitions->len;

  *partnum_ret = partnum;
  *nr_partitions_ret = nr_partitions;
  return 0;
}
/* Windows Registry HKLM\SYSTEM\MountedDevices uses a blob of data
 * to store partitions.  This blob is described here:
 * http://www.goodells.net/multiboot/partsigs.shtml
 * The following function maps this blob to a libguestfs partition
 * name, if possible.
 */
static char *
map_registry_disk_blob (guestfs_h *g, const void *blob)
{
  CLEANUP_FREE_STRING_LIST char **devices = NULL;
  CLEANUP_FREE_PARTITION_LIST struct guestfs_partition_list *partitions = NULL;
  size_t i, j, len;
  uint64_t part_offset;

  /* First 4 bytes are the disk ID.  Search all devices to find the
   * disk with this disk ID.
   */
  devices = guestfs_list_devices (g);
  if (devices == NULL)
    return NULL;

  for (i = 0; devices[i] != NULL; ++i) {
    /* Read the disk ID. */
    CLEANUP_FREE char *diskid =
      guestfs_pread_device (g, devices[i], 4, 0x01b8, &len);
    if (diskid == NULL)
      continue;
    if (len < 4)
      continue;
    if (memcmp (diskid, blob, 4) == 0) /* found it */
      goto found_disk;
  }
  return NULL;

 found_disk:
  /* Next 8 bytes are the offset of the partition in bytes(!) given as
   * a 64 bit little endian number.  Luckily it's easy to get the
   * partition byte offset from guestfs_part_list.
   */
  memcpy (&part_offset, (char *) blob + 4, sizeof (part_offset));
  part_offset = le64toh (part_offset);

  partitions = guestfs_part_list (g, devices[i]);
  if (partitions == NULL)
    return NULL;

  for (j = 0; j < partitions->len; ++j) {
    if (partitions->val[j].part_start == part_offset) /* found it */
      goto found_partition;
  }
  return NULL;

 found_partition:
  /* Construct the full device name. */
  return safe_asprintf (g, "%s%d", devices[i], partitions->val[j].part_num);
}
Beispiel #3
0
void
scan (size_t *worst_alignment, const char *prefix)
{
  char **devices, *p;
  size_t i, j;
  size_t alignment;
  uint64_t start;
  struct guestfs_partition_list *parts;

  devices = guestfs_list_devices (g);
  if (devices == NULL)
    exit (EXIT_FAILURE);

  for (i = 0; devices[i] != NULL; ++i) {
    parts = guestfs_part_list (g, devices[i]);
    if (parts == NULL)
      exit (EXIT_FAILURE);

    /* Canonicalize the name of the device for printing. */
    p = guestfs_canonical_device_name (g, devices[i]);
    if (p == NULL)
      exit (EXIT_FAILURE);
    free (devices[i]);
    devices[i] = p;

    for (j = 0; j < parts->len; ++j) {
      /* Start offset of the partition in bytes. */
      start = parts->val[j].part_start;

      if (!quiet) {
        if (prefix)
          printf ("%s:", prefix);

        printf ("%s%d %12" PRIu64 " ",
                devices[i], (int) parts->val[j].part_num, start);
      }

      /* What's the alignment? */
      if (start == 0)           /* Probably not possible, but anyway. */
        alignment = 64;
      else
        for (alignment = 0; (start & 1) == 0; alignment++, start /= 2)
          ;

      if (!quiet) {
        if (alignment < 10)
          printf ("%12" PRIu64 "    ", UINT64_C(1) << alignment);
        else if (alignment < 64)
          printf ("%12" PRIu64 "K   ", UINT64_C(1) << (alignment - 10));
        else
          printf ("- ");
      }

      if (alignment < *worst_alignment)
        *worst_alignment = alignment;

      if (alignment < 12) {     /* Bad in general: < 4K alignment */
        if (!quiet)
          printf ("bad (%s)\n", _("alignment < 4K"));
      } else if (alignment < 16) { /* Bad on NetApps: < 64K alignment */
        if (!quiet)
          printf ("bad (%s)\n", _("alignment < 64K"));
      } else {
        if (!quiet)
          printf ("ok\n");
      }
    }

    guestfs_free_partition_list (parts);
    free (devices[i]);
  }
  free (devices);
}
Beispiel #4
0
static int
scan (guestfs_h *g, const char *prefix, FILE *fp)
{
  size_t i, j;
  size_t alignment;
  uint64_t start;
  int err;

  CLEANUP_FREE_STRING_LIST char **devices = guestfs_list_devices (g);
  if (devices == NULL)
    return -1;

  for (i = 0; devices[i] != NULL; ++i) {
    CLEANUP_FREE char *name = NULL;

    CLEANUP_FREE_PARTITION_LIST struct guestfs_partition_list *parts =
      guestfs_part_list (g, devices[i]);
    if (parts == NULL)
      return -1;

    /* Canonicalize the name of the device for printing. */
    name = guestfs_canonical_device_name (g, devices[i]);
    if (name == NULL)
      return -1;

    for (j = 0; j < parts->len; ++j) {
      /* Start offset of the partition in bytes. */
      start = parts->val[j].part_start;

      if (!quiet) {
        if (prefix)
          fprintf (fp, "%s:", prefix);

        fprintf (fp, "%s%d %12" PRIu64 " ",
                 name, (int) parts->val[j].part_num, start);
      }

      /* What's the alignment? */
      if (start == 0)           /* Probably not possible, but anyway. */
        alignment = 64;
      else
        for (alignment = 0; (start & 1) == 0; alignment++, start /= 2)
          ;

      if (!quiet) {
        if (alignment < 10)
          fprintf (fp, "%12" PRIu64 "    ", UINT64_C(1) << alignment);
        else if (alignment < 64)
          fprintf (fp, "%12" PRIu64 "K   ", UINT64_C(1) << (alignment - 10));
        else
          fprintf (fp, "- ");
      }

      err = pthread_mutex_lock (&worst_alignment_mutex);
      assert (err == 0);
      if (alignment < worst_alignment)
        worst_alignment = alignment;
      err = pthread_mutex_unlock (&worst_alignment_mutex);
      assert (err == 0);

      if (alignment < 12) {     /* Bad in general: < 4K alignment */
        if (!quiet)
          fprintf (fp, "bad (%s)\n", _("alignment < 4K"));
      } else if (alignment < 16) { /* Bad on NetApps: < 64K alignment */
        if (!quiet)
          fprintf (fp, "bad (%s)\n", _("alignment < 64K"));
      } else {
        if (!quiet)
          fprintf (fp, "ok\n");
      }
    }
  }

  return 0;
}