Ejemplo n.º 1
0
static int
check_ntfs_available (void)
{
  const char *ntfs_features[] = { "ntfs3g", "ntfsprogs", NULL };

  if (STREQ (type, "ntfs") &&
      guestfs_feature_available (g, (char **) ntfs_features) == 0) {
    fprintf (stderr, _("%s: NTFS support was disabled when libguestfs was compiled\n"),
             guestfs_int_program_name);
    return -1;
  }

  return 0;
}
Ejemplo n.º 2
0
static int
copy_attributes (const char *src, const char *dest)
{
  CLEANUP_FREE_STAT struct guestfs_stat *stat = NULL;
  const char *linuxxattrs[] = { "linuxxattrs", NULL };
  int has_linuxxattrs;
  CLEANUP_FREE char *selinux_context = NULL;
  size_t selinux_context_size;

  has_linuxxattrs = guestfs_feature_available (g, (char **) linuxxattrs);

  /* Get the mode. */
  stat = guestfs_stat (g, src);
  if (stat == NULL)
    return -1;

  /* Get the SELinux context.  XXX Should we copy over other extended
   * attributes too?
   */
  if (has_linuxxattrs) {
    guestfs_push_error_handler (g, NULL, NULL);

    selinux_context = guestfs_getxattr (g, src, "security.selinux",
                                        &selinux_context_size);
    /* selinux_context could be NULL.  This isn't an error. */

    guestfs_pop_error_handler (g);
  }

  /* Set the permissions (inc. sticky and set*id bits), UID, GID. */
  if (guestfs_chmod (g, stat->mode & 07777, dest) == -1)
    return -1;
  if (guestfs_chown (g, stat->uid, stat->gid, dest) == -1)
    return -1;

  /* Set the SELinux context. */
  if (has_linuxxattrs && selinux_context) {
    if (guestfs_setxattr (g, "security.selinux", selinux_context,
                          (int) selinux_context_size, dest) == -1)
      return -1;
  }

  return 0;
}
Ejemplo n.º 3
0
/* This function coordinates the test for each filesystem type. */
static void
test_filesystem (guestfs_h *g, const struct filesystem *fs)
{
  const char *feature[] = { fs->fs_feature, NULL };
  char envvar[sizeof (ourenvvar) + 20];
  char *str;

  if (fs->fs_feature && !guestfs_feature_available (g, (char **) feature)) {
    printf ("skipped test of %s because %s feature not available\n",
            fs->fs_name, fs->fs_feature);
    return;
  }

  snprintf (envvar, sizeof envvar, "%s_%s", ourenvvar, fs->fs_name);
  str = getenv (envvar);
  if (str && STREQ (str, "1")) {
    printf ("skipped test of %s because environment variable is set\n",
            fs->fs_name);
    return;
  }

  printf ("testing charset fidelity on %s\n", fs->fs_name);

  make_filesystem (g, fs);
  mount_filesystem (g, fs);

  test_ascii (g, fs);

  if (fs->fs_8bit_only)
    goto out;

  if (!fs->fs_skip_latin1)
    test_latin1 (g, fs);
  if (!fs->fs_skip_latin2)
    test_latin2 (g, fs);
  test_chinese (g, fs);

 out:
  unmount_filesystem (g, fs);
}
int
main (int argc, char *argv[])
{
    guestfs_h *g;
    struct guestfs_internal_mountable *mountable;
    const char *devices[] = { "/dev/VG/LV", NULL };
    const char *feature[] = { "btrfs", NULL };

    g = guestfs_create ();
    if (g == NULL) {
        perror ("could not create handle");
        exit (EXIT_FAILURE);
    }

    if (guestfs_add_drive_scratch (g, 1024*1024*1024, -1) == -1) {
error:
        guestfs_close (g);
        exit (EXIT_FAILURE);
    }

    if (guestfs_launch (g) == -1) goto error;

    if (!guestfs_feature_available (g, (char **) feature)) {
        printf ("skipping test because btrfs is not available\n");
        guestfs_close (g);
        exit (77);
    }

    if (!guestfs_filesystem_available (g, "btrfs")) {
        printf ("skipping test because btrfs filesystem is not available\n");
        guestfs_close (g);
        exit (77);
    }

    if (guestfs_part_disk (g, "/dev/sda", "mbr") == -1) goto error;

    if (guestfs_pvcreate (g, "/dev/sda1") == -1) goto error;

    const char *pvs[] = { "/dev/sda1", NULL };
    if (guestfs_vgcreate (g, "VG", (char **) pvs) == -1) goto error;

    if (guestfs_lvcreate (g, "LV", "VG", 900) == -1) goto error;

    if (guestfs_mkfs_btrfs (g, (char * const *)devices, -1) == -1) goto error;

    if (guestfs_mount (g, "/dev/VG/LV", "/") == -1) goto error;

    if (guestfs_btrfs_subvolume_create (g, "/sv") == -1) goto error;

    mountable = guestfs_internal_parse_mountable (g, "/dev/VG/LV");
    if (mountable == NULL) goto error;

    if (mountable->im_type != MOUNTABLE_DEVICE ||
            STRNEQ ("/dev/VG/LV", mountable->im_device)) {
        fprintf (stderr, "incorrectly parsed /dev/VG/LV: im_device=%s\n",
                 mountable->im_device);
        goto error;
    }

    guestfs_free_internal_mountable (mountable);

    mountable = guestfs_internal_parse_mountable (g, "btrfsvol:/dev/VG/LV/sv");
    if (mountable == NULL) goto error;

    if (mountable->im_type != MOUNTABLE_BTRFSVOL ||
            STRNEQ ("/dev/VG/LV", mountable->im_device) ||
            STRNEQ ("sv", mountable->im_volume)) {
        fprintf (stderr, "incorrectly parsed /dev/VG/LV/sv: im_device=%s, im_volume=%s\n",
                 mountable->im_device, mountable->im_volume);
        goto error;
    }
    guestfs_free_internal_mountable (mountable);

    guestfs_close (g);

    exit (EXIT_SUCCESS);
}
Ejemplo n.º 5
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:qvVx";
  static const struct option long_options[] = {
    { "add", 1, 0, 'a' },
    { "filesystem", 1, 0, 0 },
    { "format", 2, 0, 0 },
    { "help", 0, 0, HELP_OPTION },
    { "label", 1, 0, 0 },
    { "long-options", 0, 0, 0 },
    { "lvm", 2, 0, 0 },
    { "partition", 2, 0, 0 },
    { "verbose", 0, 0, 'v' },
    { "version", 0, 0, 'V' },
    { "wipe", 0, 0, 0 },
    { 0, 0, 0, 0 }
  };
  struct drv *drvs = NULL;
  const char *format = NULL;
  bool format_consumed = true;
  int c;
  int option_index;
  int retry, retries;

  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, "format")) {
        OPTION_format;
      } else if (STREQ (long_options[option_index].name, "filesystem")) {
        if (STREQ (optarg, "none"))
          filesystem = NULL;
        else if (optarg[0] == '-') { /* eg: --filesystem --lvm */
          fprintf (stderr, _("%s: no filesystem was specified\n"),
                   program_name);
          exit (EXIT_FAILURE);
        } else
          filesystem = optarg;
      } else if (STREQ (long_options[option_index].name, "lvm")) {
        if (vg || lv) {
          fprintf (stderr,
                   _("%s: --lvm option cannot be given multiple times\n"),
                   program_name);
          exit (EXIT_FAILURE);
        }
        if (optarg == NULL) {
          vg = strdup ("VG");
          lv = strdup ("LV");
          if (!vg || !lv) { perror ("strdup"); exit (EXIT_FAILURE); }
        }
        else if (STREQ (optarg, "none"))
          vg = lv = NULL;
        else
          parse_vg_lv (optarg);
      } else if (STREQ (long_options[option_index].name, "partition")) {
        if (optarg == NULL)
          partition = "DEFAULT";
        else if (STREQ (optarg, "none"))
          partition = NULL;
        else
          partition = optarg;
      } else if (STREQ (long_options[option_index].name, "wipe")) {
        wipe = 1;
      } else if (STREQ (long_options[option_index].name, "label")) {
        label = optarg;
      } else {
        fprintf (stderr, _("%s: unknown long option: %s (%d)\n"),
                 program_name, long_options[option_index].name, option_index);
        exit (EXIT_FAILURE);
      }
      break;

    case 'a':
      OPTION_a;

      /* Enable discard on all drives added on the command line. */
      assert (drvs != NULL);
      assert (drvs->type == drv_a);
      drvs->a.discard = "besteffort";
      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);
    }
  }

  /* 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 == 0);
  assert (inspector == 0);
  assert (live == 0);

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

  CHECK_OPTION_format_consumed;

  /* The user didn't specify any drives to format. */
  if (drvs == NULL)
    usage (EXIT_FAILURE);

  /* Because the libguestfs kernel can get stuck rereading the
   * partition table after things have been erased, we sometimes need
   * to completely restart the guest.  Hence this complex retry logic.
   */
  for (retries = 0; retries <= 1; ++retries) {
    const char *wipefs[] = { "wipefs", NULL };

    /* Add domains/drives from the command line (for a single guest). */
    add_drives (drvs, 'a');

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

    /* Test if the wipefs API is available. */
    have_wipefs = guestfs_feature_available (g, (char **) wipefs);

    /* Perform the format. */
    retry = do_format ();
    if (!retry)
      break;

    if (retries == 0) {
      /* We're going to silently retry, after reopening the connection. */
      guestfs_h *g2;

      g2 = guestfs_create ();
      guestfs_set_verbose (g2, guestfs_get_verbose (g));
      guestfs_set_trace (g2, guestfs_get_trace (g));

      if (guestfs_shutdown (g) == -1)
        exit (EXIT_FAILURE);
      guestfs_close (g);
      g = g2;
    }
    else {
      /* Failed. */
      fprintf (stderr,
               _("%s: failed to rescan the disks after two attempts.  This\n"
                 "may mean there is some sort of partition table or disk\n"
                 "data which we are unable to remove.  If you think this\n"
                 "is a bug, please file a bug at http://libguestfs.org/\n"),
               program_name);
      exit (EXIT_FAILURE);
    }
  }

  /* Free up data structures. */
  free_drives (drvs);

  if (guestfs_shutdown (g) == -1)
    exit (EXIT_FAILURE);
  guestfs_close (g);

  exit (EXIT_SUCCESS);
}