Example #1
0
/* This function deals with the complexity of adding the domain,
 * launching the handle, and mounting up filesystems.  See
 * 'examples/inspect-vm.c' to understand how this works.
 */
static int
open_guest (guestfs_h *g, const char *dom, int readonly)
{
    char **roots, *root, **mountpoints;
    size_t i;

    /* Use libvirt to find the guest disks and add them to the handle. */
    if (guestfs_add_domain (g, dom,
                            GUESTFS_ADD_DOMAIN_READONLY, readonly,
                            -1) == -1)
        return -1;

    if (guestfs_launch (g) == -1)
        return -1;

    /* Inspect the guest, looking for operating systems. */
    roots = guestfs_inspect_os (g);
    if (roots == NULL)
        return -1;

    if (roots[0] == NULL || roots[1] != NULL) {
        fprintf (stderr, "copy-over: %s: no operating systems or multiple operating systems found\n", dom);
        return -1;
    }

    root = roots[0];

    /* Mount up the filesystems (like 'guestfish -i'). */
    mountpoints = guestfs_inspect_get_mountpoints (g, root);
    if (mountpoints == NULL)
        return -1;

    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.
         */
        (readonly ? guestfs_mount_ro : guestfs_mount)
        (g, mountpoints[i+1], mountpoints[i]);
        free (mountpoints[i]);
        free (mountpoints[i+1]);
    }

    free (mountpoints);

    free (root);
    free (roots);

    /* Everything ready, no error. */
    return 0;
}
Example #2
0
int
main (int argc, char *argv[])
{
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEBASEDIR);
  textdomain (PACKAGE);

  enum { HELP_OPTION = CHAR_MAX + 1 };

  static const char *options = "a:c:d:vVx";
  static const struct option long_options[] = {
    { "add", 1, 0, 'a' },
    { "connect", 1, 0, 'c' },
    { "domain", 1, 0, 'd' },
    { "echo-keys", 0, 0, 0 },
    { "format", 2, 0, 0 },
    { "help", 0, 0, HELP_OPTION },
    { "keys-from-stdin", 0, 0, 0 },
    { "long-options", 0, 0, 0 },
    { "short-options", 0, 0, 0 },
    { "verbose", 0, 0, 'v' },
    { "version", 0, 0, 'V' },
    { "xpath", 1, 0, 0 },
    { 0, 0, 0, 0 }
  };
  struct drv *drvs = NULL;
  struct drv *drv;
  const char *format = NULL;
  bool format_consumed = true;
  int c;
  int option_index;

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

  for (;;) {
    c = getopt_long (argc, argv, options, long_options, &option_index);
    if (c == -1) break;

    switch (c) {
    case 0:			/* options which are long only */
      if (STREQ (long_options[option_index].name, "long-options"))
        display_long_options (long_options);
      else if (STREQ (long_options[option_index].name, "short-options"))
        display_short_options (options);
      else if (STREQ (long_options[option_index].name, "keys-from-stdin")) {
        keys_from_stdin = 1;
      } else if (STREQ (long_options[option_index].name, "echo-keys")) {
        echo_keys = 1;
      } else if (STREQ (long_options[option_index].name, "format")) {
        OPTION_format;
      } else if (STREQ (long_options[option_index].name, "xpath")) {
        xpath = optarg;
      } else {
        fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                 guestfs_int_program_name,
                 long_options[option_index].name, option_index);
        exit (EXIT_FAILURE);
      }
      break;

    case 'a':
      OPTION_a;
      break;

    case 'c':
      OPTION_c;
      break;

    case 'd':
      OPTION_d;
      break;

    case 'v':
      OPTION_v;
      break;

    case 'V':
      OPTION_V;
      break;

    case 'x':
      OPTION_x;
      break;

    case HELP_OPTION:
      usage (EXIT_SUCCESS);

    default:
      usage (EXIT_FAILURE);
    }
  }

  /* Old-style syntax?  There were no -a or -d options in the old
   * virt-inspector which is how we detect this.
   */
  if (drvs == NULL) {
    while (optind < argc) {
      if (strchr (argv[optind], '/') ||
          access (argv[optind], F_OK) == 0) { /* simulate -a option */
        drv = calloc (1, sizeof (struct drv));
        if (!drv) {
          perror ("calloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_a;
        drv->a.filename = strdup (argv[optind]);
        if (!drv->a.filename) {
          perror ("strdup");
          exit (EXIT_FAILURE);
        }
        drv->next = drvs;
        drvs = drv;
      } else {                  /* simulate -d option */
        drv = calloc (1, sizeof (struct drv));
        if (!drv) {
          perror ("calloc");
          exit (EXIT_FAILURE);
        }
        drv->type = drv_d;
        drv->d.guest = argv[optind];
        drv->next = drvs;
        drvs = drv;
      }

      optind++;
    }
  }

  /* These are really constants, but they have to be variables for the
   * options parsing code.  Assert here that they have known-good
   * values.
   */
  assert (read_only == 1);
  assert (inspector == 1);
  assert (live == 0);

  /* Must be no extra arguments on the command line. */
  if (optind != argc)
    usage (EXIT_FAILURE);

  CHECK_OPTION_format_consumed;

  /* XPath is modal: no drives should be specified.  There must be
   * one extra parameter on the command line.
   */
  if (xpath) {
    if (drvs != NULL) {
      fprintf (stderr, _("%s: cannot use --xpath together with other options.\n"),
               guestfs_int_program_name);
      exit (EXIT_FAILURE);
    }

    do_xpath (xpath);

    exit (EXIT_SUCCESS);
  }

  /* User must have specified some drives. */
  if (drvs == NULL)
    usage (EXIT_FAILURE);

  /* Add drives, inspect and mount.  Note that inspector is always true,
   * and there is no -m option.
   */
  add_drives (drvs, 'a');

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

  /* Free up data structures, no longer needed after this point. */
  free_drives (drvs);

  /* NB. Can't call inspect_mount () here (ie. normal processing of
   * the -i option) because it can only handle a single root.  So we
   * use low-level APIs.
   */
  inspect_do_decrypt (g);

  {
    CLEANUP_FREE_STRING_LIST char **roots = guestfs_inspect_os (g);
    if (roots == NULL) {
      fprintf (stderr, _("%s: no operating system could be detected inside this disk image.\n\nThis may be because the file is not a disk image, or is not a virtual machine\nimage, or because the OS type is not understood by libguestfs.\n\nNOTE for Red Hat Enterprise Linux 6 users: for Windows guest support you must\ninstall the separate libguestfs-winsupport package.\n\nIf you feel this is an error, please file a bug report including as much\ninformation about the disk image as possible.\n"),
               guestfs_int_program_name);
      exit (EXIT_FAILURE);
    }

    output (roots);
  }

  guestfs_close (g);

  exit (EXIT_SUCCESS);
}
Example #3
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);
}
Example #4
0
/* This function implements the -i option. */
void
inspect_mount (void)
{
  if (live) {
    fprintf (stderr, _("%s: don't use --live and -i options together\n"),
             program_name);
    exit (EXIT_FAILURE);
  }

  inspect_do_decrypt ();

  char **roots = guestfs_inspect_os (g);
  if (roots == NULL)
    exit (EXIT_FAILURE);

  if (roots[0] == NULL) {
    fprintf (stderr,
      _("%s: no operating system was found on this disk\n"
        "\n"
        "If using guestfish '-i' option, remove this option and instead\n"
        "use the commands 'run' followed by 'list-filesystems'.\n"
        "You can then mount filesystems you want by hand using the\n"
        "'mount' or 'mount-ro' command.\n"
        "\n"
        "If using guestmount '-i', remove this option and choose the\n"
        "filesystem(s) you want to see by manually adding '-m' option(s).\n"
        "Use 'virt-filesystems' to see what filesystems are available.\n"
        "\n"
        "If using other virt tools, this disk image won't work\n"
        "with these tools.  Use the guestfish equivalent commands\n"
        "(see the virt tool manual page).\n"),
             program_name);
    guestfs___free_string_list (roots);
    exit (EXIT_FAILURE);
  }

  if (roots[1] != NULL) {
    fprintf (stderr,
      _("%s: multi-boot operating systems are not supported\n"
        "\n"
        "If using guestfish '-i' option, remove this option and instead\n"
        "use the commands 'run' followed by 'list-filesystems'.\n"
        "You can then mount filesystems you want by hand using the\n"
        "'mount' or 'mount-ro' command.\n"
        "\n"
        "If using guestmount '-i', remove this option and choose the\n"
        "filesystem(s) you want to see by manually adding '-m' option(s).\n"
        "Use 'virt-filesystems' to see what filesystems are available.\n"
        "\n"
        "If using other virt tools, multi-boot operating systems won't work\n"
        "with these tools.  Use the guestfish equivalent commands\n"
        "(see the virt tool manual page).\n"),
             program_name);
    guestfs___free_string_list (roots);
    exit (EXIT_FAILURE);
  }

  root = roots[0];
  free (roots);

  inspect_mount_root (root);
}