示例#1
0
文件: df.c 项目: limohua/libguestfs
static void
try_df (const char *name, const char *uuid,
        const char *dev, int offset)
{
  struct guestfs_statvfs *stat = NULL;
  guestfs_error_handler_cb old_error_cb;
  void *old_error_data;

  if (verbose)
    fprintf (stderr, "try_df %s %s %d\n", name, dev, offset);

  /* Try mounting and stating the device.  This might reasonably fail,
   * so don't show errors.
   */
  old_error_cb = guestfs_get_error_handler (g, &old_error_data);
  guestfs_set_error_handler (g, NULL, NULL);

  if (guestfs_mount_ro (g, dev, "/") == 0) {
    stat = guestfs_statvfs (g, "/");
    guestfs_umount_all (g);
  }

  guestfs_set_error_handler (g, old_error_cb, old_error_data);

  if (stat) {
    print_stat (name, uuid, dev, offset, stat);
    guestfs_free_statvfs (stat);
  }
}
示例#2
0
int
init_iso_fs (guestfs_h *g)
{
  if (init_empty (g) == -1)
    return -1;

  if (guestfs_mount_ro (g, "/dev/sdd", "/") == -1)
    return -1;

  return 0;
}
示例#3
0
/* Since we want this function to be robust against very bad failure
 * cases (hello, https://bugzilla.kernel.org/show_bug.cgi?id=18792) it
 * won't exit on guestfs failures.
 */
int
df_on_handle (guestfs_h *g, const char *name, const char *uuid, FILE *fp)
{
  size_t i;
  CLEANUP_FREE_STRING_LIST char **devices = NULL;
  CLEANUP_FREE_STRING_LIST char **fses = NULL;

  if (verbose)
    fprintf (stderr, "df_on_handle: %s\n", name);

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

  fses = guestfs_list_filesystems (g);
  if (fses == NULL)
    return -1;

  for (i = 0; fses[i] != NULL; i += 2) {
    if (STRNEQ (fses[i+1], "") &&
        STRNEQ (fses[i+1], "swap") &&
        STRNEQ (fses[i+1], "unknown")) {
      const char *dev = fses[i];
      CLEANUP_FREE_STATVFS struct guestfs_statvfs *stat = NULL;

      if (verbose)
        fprintf (stderr, "df_on_handle: %s dev %s\n", name, dev);

      /* Try mounting and stating the device.  This might reasonably
       * fail, so don't show errors.
       */
      guestfs_push_error_handler (g, NULL, NULL);

      if (guestfs_mount_ro (g, dev, "/") == 0) {
        stat = guestfs_statvfs (g, "/");
        guestfs_umount_all (g);
      }

      guestfs_pop_error_handler (g);

      if (stat)
        print_stat (fp, name, uuid, dev, stat);
    }
  }

  return 0;
}
示例#4
0
static void
mount_drive_letter_ro (char drive_letter, const char *root)
{
  char **drives;
  char *device;
  size_t i;

  /* Resolve the drive letter using the drive mappings table. */
  drives = guestfs_inspect_get_drive_mappings (g, root);
  if (drives == NULL || drives[0] == NULL) {
    fprintf (stderr, _("%s: to use Windows drive letters, this must be a Windows guest\n"),
             program_name);
    exit (EXIT_FAILURE);
  }

  device = NULL;
  for (i = 0; drives[i] != NULL; i += 2) {
    if (c_tolower (drives[i][0]) == drive_letter && drives[i][1] == '\0') {
      device = drives[i+1];
      break;
    }
  }

  if (device == NULL) {
    fprintf (stderr, _("%s: drive '%c:' not found.\n"),
             program_name, drive_letter);
    exit (EXIT_FAILURE);
  }

  /* Unmount current disk and remount device. */
  if (guestfs_umount_all (g) == -1)
    exit (EXIT_FAILURE);

  if (guestfs_mount_ro (g, device, "/") == -1)
    exit (EXIT_FAILURE);

  for (i = 0; drives[i] != NULL; ++i)
    free (drives[i]);
  free (drives);
  /* Don't need to free (device) because that string was in the
   * drives array.
   */
}
示例#5
0
void
inspect_mount_root (const char *root)
{
  CLEANUP_FREE_STRING_LIST char **mountpoints =
    guestfs_inspect_get_mountpoints (g, root);
  if (mountpoints == NULL)
    exit (EXIT_FAILURE);

  /* Sort by key length, shortest key first, so that we end up
   * mounting the filesystems in the correct order.
   */
  qsort (mountpoints, guestfs___count_strings (mountpoints) / 2,
         2 * sizeof (char *),
         compare_keys_len);

  size_t i;
  size_t mount_errors = 0;
  for (i = 0; mountpoints[i] != NULL; i += 2) {
    int r;
    if (!read_only)
      r = guestfs_mount (g, mountpoints[i+1], mountpoints[i]);
    else
      r = guestfs_mount_ro (g, mountpoints[i+1], mountpoints[i]);
    if (r == -1) {
      /* If the "/" filesystem could not be mounted, give up, else
       * just count the errors and print a warning.
       */
      if (STREQ (mountpoints[i], "/"))
        exit (EXIT_FAILURE);
      mount_errors++;
    }
  }

  if (mount_errors)
    fprintf (stderr, _("%s: some filesystems could not be mounted (ignored)\n"),
             program_name);
}
示例#6
0
/* Find out if 'device' contains a filesystem.  If it does, add
 * another entry in g->fses.
 */
int
guestfs_int_check_for_filesystem_on (guestfs_h *g, const char *mountable)
{
  CLEANUP_FREE char *vfs_type = NULL;
  int is_swap, r;
  struct inspect_fs *fs;
  CLEANUP_FREE_INTERNAL_MOUNTABLE struct guestfs_internal_mountable *m = NULL;
  int whole_device = 0;

  /* Get vfs-type in order to check if it's a Linux(?) swap device.
   * If there's an error we should ignore it, so to do that we have to
   * temporarily replace the error handler with a null one.
   */
  guestfs_push_error_handler (g, NULL, NULL);
  vfs_type = guestfs_vfs_type (g, mountable);
  guestfs_pop_error_handler (g);

  is_swap = vfs_type && STREQ (vfs_type, "swap");
  debug (g, "check_for_filesystem_on: %s (%s)",
         mountable, vfs_type ? vfs_type : "failed to get vfs type");

  if (is_swap) {
    extend_fses (g);
    fs = &g->fses[g->nr_fses-1];
    fs->mountable = safe_strdup (g, mountable);
    return 0;
  }

  m = guestfs_internal_parse_mountable (g, mountable);
  if (m == NULL)
    return -1;

  /* If it's a whole device, see if it is an install ISO. */
  if (m->im_type == MOUNTABLE_DEVICE) {
    whole_device = guestfs_is_whole_device (g, m->im_device);
    if (whole_device == -1) {
      return -1;
    }
  }

  if (whole_device) {
    extend_fses (g);
    fs = &g->fses[g->nr_fses-1];

    r = guestfs_int_check_installer_iso (g, fs, m->im_device);
    if (r == -1) {              /* Fatal error. */
      g->nr_fses--;
      return -1;
    }
    if (r > 0)                  /* Found something. */
      return 0;

    /* Didn't find anything.  Fall through ... */
    g->nr_fses--;
  }

  /* Try mounting the device.  As above, ignore errors. */
  guestfs_push_error_handler (g, NULL, NULL);
  if (vfs_type && STREQ (vfs_type, "ufs")) { /* Hack for the *BSDs. */
    /* FreeBSD fs is a variant of ufs called ufs2 ... */
    r = guestfs_mount_vfs (g, "ro,ufstype=ufs2", "ufs", mountable, "/");
    if (r == -1)
      /* while NetBSD and OpenBSD use another variant labeled 44bsd */
      r = guestfs_mount_vfs (g, "ro,ufstype=44bsd", "ufs", mountable, "/");
  } else {
    r = guestfs_mount_ro (g, mountable, "/");
  }
  guestfs_pop_error_handler (g);
  if (r == -1)
    return 0;

  /* Do the rest of the checks. */
  r = check_filesystem (g, mountable, m, whole_device);

  /* Unmount the filesystem. */
  if (guestfs_umount_all (g) == -1)
    return -1;

  return r;
}
示例#7
0
int
main (int argc, char *argv[])
{
  guestfs_h *g;
  const char *disk;
  char **roots, *root, *str, **mountpoints, **lines;
  size_t i, j;

  if (argc != 2) {
    fprintf (stderr, "usage: inspect_vm disk.img\n");
    exit (EXIT_FAILURE);
  }
  disk = argv[1];

  g = guestfs_create ();
  if (g == NULL) {
    perror ("failed to create libguestfs handle");
    exit (EXIT_FAILURE);
  }

  /* Attach the disk image read-only to libguestfs. */
  if (guestfs_add_drive_opts (g, disk,
			      /* GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw", */
			      GUESTFS_ADD_DRIVE_OPTS_READONLY, 1,
			      -1) /* this marks end of optional arguments */
      == -1)
    exit (EXIT_FAILURE);

  /* Run the libguestfs back-end. */
  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);

  /* Ask libguestfs to inspect for operating systems. */
  roots = guestfs_inspect_os (g);
  if (roots == NULL)
    exit (EXIT_FAILURE);
  if (roots[0] == NULL) {
    fprintf (stderr, "inspect_vm: no operating systems found\n");
    exit (EXIT_FAILURE);
  }

  for (j = 0; roots[j] != NULL; ++j) {
    root = roots[j];

    printf ("Root device: %s\n", root);

    /* Print basic information about the operating system. */
    str = guestfs_inspect_get_product_name (g, root);
    if (str)
      printf ("  Product name: %s\n", str);
    free (str);

    printf ("  Version:      %d.%d\n",
            guestfs_inspect_get_major_version (g, root),
            guestfs_inspect_get_minor_version (g, root));

    str = guestfs_inspect_get_type (g, root);
    if (str)
      printf ("  Type:         %s\n", str);
    free (str);
    str = guestfs_inspect_get_distro (g, root);
    if (str)
      printf ("  Distro:       %s\n", str);
    free (str);

    /* Mount up the disks, like guestfish -i.
     *
     * Sort keys by length, shortest first, so that we end up
     * mounting the filesystems in the correct order.
     */
    mountpoints = guestfs_inspect_get_mountpoints (g, root);
    if (mountpoints == NULL)
      exit (EXIT_FAILURE);

    qsort (mountpoints, count_strings (mountpoints) / 2, 2 * sizeof (char *),
           compare_keys_len);
    for (i = 0; mountpoints[i] != NULL; i += 2) {
      /* Ignore failures from this call, since bogus entries can
       * appear in the guest's /etc/fstab.
       */
      guestfs_mount_ro (g, mountpoints[i+1], mountpoints[i]);
      free (mountpoints[i]);
      free (mountpoints[i+1]);
    }
    free (mountpoints);

    /* If /etc/issue.net file exists, print up to 3 lines. */
    if (guestfs_is_file (g, "/etc/issue.net") > 0) {
      printf ("--- /etc/issue.net ---\n");
      lines = guestfs_head_n (g, 3, "/etc/issue.net");
      if (lines == NULL)
        exit (EXIT_FAILURE);
      for (i = 0; lines[i] != NULL; ++i) {
        printf ("%s\n", lines[i]);
        free (lines[i]);
      }
      free (lines);
    }

    /* Unmount everything. */
    if (guestfs_umount_all (g) == -1)
      exit (EXIT_FAILURE);

    free (root);
  }
  free (roots);

  guestfs_close (g);

  exit (EXIT_SUCCESS);
}
示例#8
0
int
main (int argc, char *argv[])
{
  guestfs_h *g;
  int r, err;
  struct guestfs_stat *stat;

  g = guestfs_create ();
  if (g == NULL) {
    fprintf (stderr, "failed to create handle\n");
    exit (EXIT_FAILURE);
  }

  if (guestfs_add_drive_scratch (g, 524288000, -1) == -1)
    exit (EXIT_FAILURE);

  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);

  if (guestfs_part_disk (g, "/dev/sda", "mbr") == -1)
    exit (EXIT_FAILURE);

  if (guestfs_mkfs (g, "ext2", "/dev/sda1") == -1)
    exit (EXIT_FAILURE);

  /* Mount read-only, and check that errno == EROFS is passed back when
   * we create a file.
   */
  if (guestfs_mount_ro (g, "/dev/sda1", "/") == -1)
    exit (EXIT_FAILURE);

  r = guestfs_touch (g, "/test");
  if (r != -1) {
    fprintf (stderr,
             "guestfs_touch: expected error for read-only filesystem\n");
    exit (EXIT_FAILURE);
  }

  err = guestfs_last_errno (g);
  if (err != EROFS) {
    fprintf (stderr,
             "guestfs_touch: expected errno == EROFS, but got %d\n", err);
    exit (EXIT_FAILURE);
  }

  if (guestfs_umount (g, "/") == -1)
    exit (EXIT_FAILURE);

  /* Mount it writable and test some other errors. */
  if (guestfs_mount (g, "/dev/sda1", "/") == -1)
    exit (EXIT_FAILURE);

  stat = guestfs_lstat (g, "/nosuchfile");
  if (stat != NULL) {
    fprintf (stderr,
             "guestfs_lstat: expected error for missing file\n");
    exit (EXIT_FAILURE);
  }

  err = guestfs_last_errno (g);
  if (err != ENOENT) {
    fprintf (stderr,
             "guestfs_lstat: expected errno == ENOENT, but got %d\n", err);
    exit (EXIT_FAILURE);
  }

  if (guestfs_touch (g, "/test") == -1)
    exit (EXIT_FAILURE);

  r = guestfs_mkdir (g, "/test");
  if (r != -1) {
    fprintf (stderr,
             "guestfs_mkdir: expected error for file which exists\n");
    exit (EXIT_FAILURE);
  }

  err = guestfs_last_errno (g);
  if (err != EEXIST) {
    fprintf (stderr,
             "guestfs_mkdir: expected errno == EEXIST, but got %d\n", err);
    exit (EXIT_FAILURE);
  }

  guestfs_close (g);

  exit (EXIT_SUCCESS);
}