Exemple #1
0
void
prep_postlaunch_part (const char *filename, prep_data *data, const char *device)
{
  if (guestfs_part_disk (g, device, data->params[1]) == -1)
    prep_error (data, filename, _("failed to partition disk: %s"),
                guestfs_last_error (g));
}
Exemple #2
0
void
prep_postlaunch_lv (const char *filename, prep_data *data, const char *device)
{
  if (guestfs_part_disk (g, device, data->params[2]) == -1)
    prep_error (data, filename, _("failed to partition disk: %s"),
                guestfs_last_error (g));

  CLEANUP_FREE char *vg;
  CLEANUP_FREE char *lv;
  if (vg_lv_parse (data->params[0], &vg, &lv) == -1)
    prep_error (data, filename, _("incorrect format for LV name, use '/dev/VG/LV'"));

  CLEANUP_FREE char *part;
  if (asprintf (&part, "%s1", device) == -1) {
    perror ("asprintf");
    exit (EXIT_FAILURE);
  }

  if (guestfs_pvcreate (g, part) == -1)
    prep_error (data, filename, _("failed to create PV: %s: %s"),
                part, guestfs_last_error (g));

  char *parts[] = { part, NULL };
  if (guestfs_vgcreate (g, vg, parts) == -1)
    prep_error (data, filename, _("failed to create VG: %s: %s"),
                vg, guestfs_last_error (g));

  /* Create the largest possible LV. */
  if (guestfs_lvcreate_free (g, lv, vg, 100) == -1)
    prep_error (data, filename, _("failed to create LV: /dev/%s/%s: %s"),
                vg, lv, guestfs_last_error (g));
}
Exemple #3
0
int
init_gpt (guestfs_h *g)
{
  if (init_empty (g) == -1)
    return -1;

  if (guestfs_part_disk (g, "/dev/sda", "gpt") == -1)
    return -1;

  return 0;
}
Exemple #4
0
int
init_partition (guestfs_h *g)
{
  if (init_empty (g) == -1)
    return -1;

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

  return 0;
}
Exemple #5
0
/* Create the handle, with attached disks. */
static guestfs_h *
create_handle (void)
{
  guestfs_h *g;

  g = guestfs_create ();
  if (g == NULL) {
    printf ("FAIL: guestfs_create\n");
    exit (EXIT_FAILURE);
  }

  if (guestfs_add_drive_scratch (g, 524288000, -1) == -1) {
    printf ("FAIL: guestfs_add_drive_scratch\n");
    exit (EXIT_FAILURE);
  }

  if (guestfs_add_drive_scratch (g, 52428800, -1) == -1) {
    printf ("FAIL: guestfs_add_drive_scratch\n");
    exit (EXIT_FAILURE);
  }

  if (guestfs_add_drive_scratch (g, 10485760, -1) == -1) {
    printf ("FAIL: guestfs_add_drive_scratch\n");
    exit (EXIT_FAILURE);
  }

  if (guestfs_add_drive_ro (g, "../data/test.iso") == -1) {
    printf ("FAIL: guestfs_add_drive_ro ../data/test.iso\n");
    exit (EXIT_FAILURE);
  }

  /* Set a timeout in case qemu hangs during launch (RHBZ#505329). */
  alarm (600);

  if (guestfs_launch (g) == -1) {
    printf ("FAIL: guestfs_launch\n");
    exit (EXIT_FAILURE);
  }

  /* Cancel previous alarm. */
  alarm (0);

  /* Create ext2 filesystem on /dev/sdb1 partition. */
  if (guestfs_part_disk (g, "/dev/sdb", "mbr") == -1) {
    printf ("FAIL: guestfs_part_disk\n");
    exit (EXIT_FAILURE);
  }
  if (guestfs_mkfs (g, "ext2", "/dev/sdb1") == -1) {
    printf ("FAIL: guestfs_mkfs (/dev/sdb1)\n");
    exit (EXIT_FAILURE);
  }

  return g;
}
int
main (int argc, char *argv[])
{
  char *str;
  guestfs_h *g;
  char tmp[] = "/tmp/charsetXXXXXX";
  int fd;
  size_t i;
  struct filesystem *fs;

  /* Allow this test to be skipped. */
  str = getenv ("SKIP_TEST_CHARSET_FIDELITY");
  if (str && STREQ (str, "1")) {
    printf ("%s: test skipped because environment variable is set.\n",
            argv[0]);
    exit (77);
  }

  g = guestfs_create ();
  if (g == NULL)
    error (EXIT_FAILURE, 0, "failed to create handle");

  fd = mkstemp (tmp);
  if (fd == -1)
    error (EXIT_FAILURE, errno, "mkstemp");

  if (ftruncate (fd, 1024 * 1024 * 1024) == -1)
    error (EXIT_FAILURE, errno, "ftruncate: %s", tmp);

  if (close (fd) == -1)
    error (EXIT_FAILURE, errno, "close: %s", tmp);

  if (guestfs_add_drive_opts (g, tmp, -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);

  for (i = 0; i < sizeof filesystems / sizeof filesystems[0]; ++i) {
    fs = &filesystems[i];
    test_filesystem (g, fs);
  }

  guestfs_close (g);
  unlink (tmp);

  exit (EXIT_SUCCESS);
}
Exemple #7
0
void
prep_postlaunch_fs (const char *filename, prep_data *data, const char *device)
{
  if (guestfs_part_disk (g, device, data->params[2]) == -1)
    prep_error (data, filename, _("failed to partition disk: %s"),
                guestfs_last_error (g));

  CLEANUP_FREE char *part;
  if (asprintf (&part, "%s1", device) == -1)
    error (EXIT_FAILURE, errno, "asprintf");

  if (guestfs_mkfs (g, data->params[0], part) == -1)
    prep_error (data, filename, _("failed to create filesystem (%s): %s"),
                data->params[0], guestfs_last_error (g));
}
int
main (int argc, char *argv[])
{
  char *str;
  guestfs_h *g;
  size_t i;
  struct filesystem *fs;

  /* Allow this test to be skipped. */
  str = getenv (ourenvvar);
  if (str && STREQ (str, "1")) {
    printf ("%s: test skipped because environment variable is set.\n",
            program_name);
    exit (77);
  }

  g = guestfs_create ();
  if (g == NULL)
    error (EXIT_FAILURE, 0, "failed to create handle");

  if (guestfs_add_drive_scratch (g, 1024*1024*1024, -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);

  for (i = 0; i < sizeof filesystems / sizeof filesystems[0]; ++i) {
    fs = &filesystems[i];
    test_filesystem (g, fs);
  }

  guestfs_close (g);

  exit (EXIT_SUCCESS);
}
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);
}
Exemple #10
0
int
main (int argc, char *argv[])
{
    guestfs_h *g;
    int fd, r;
    char tempdir[] = "/tmp/mlXXXXXX";
    pid_t pid;
    char *shell, *p;

    if (argc != 2) {
        usage ();
        exit (EXIT_FAILURE);
    }

    printf ("\n"
            "This is the 'mount-local' demonstration program.  Follow the\n"
            "instructions on screen.\n"
            "\n"
            "Creating and formatting the disk image, please wait a moment ...\n");
    fflush (stdout);

    /* Create the output disk image: raw sparse. */
    fd = open (argv[1], O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0644);
    if (fd == -1) {
        perror (argv[1]);
        exit (EXIT_FAILURE);
    }
    if (ftruncate (fd, SIZE_MB * 1024 * 1024) == -1) {
        perror ("truncate");
        close (fd);
        exit (EXIT_FAILURE);
    }
    if (close (fd) == -1) {
        perror ("close");
        exit (EXIT_FAILURE);
    }

    /* Guestfs handle. */
    g = guestfs_create ();
    if (g == NULL) {
        perror ("could not create libguestfs handle");
        exit (EXIT_FAILURE);
    }

    /* Create the disk image and format it with a partition and a filesystem. */
    if (guestfs_add_drive_opts (g, argv[1],
                                GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
                                -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 the empty filesystem. */
    if (guestfs_mount_options (g, MOUNT_OPTIONS, "/dev/sda1", "/") == -1)
        exit (EXIT_FAILURE);

    /* Create a file in the new filesystem. */
    if (guestfs_touch (g, "/PUT_FILES_AND_DIRECTORIES_HERE") == -1)
        exit (EXIT_FAILURE);

    /* Create a temporary mount directory. */
    if (mkdtemp (tempdir) == NULL) {
        perror ("mkdtemp");
        exit (EXIT_FAILURE);
    }

    /* Mount the filesystem. */
    if (guestfs_mount_local (g, tempdir, -1) == -1)
        exit (EXIT_FAILURE);

    /* Fork the shell for the user. */
    pid = fork ();
    if (pid == -1) {
        perror ("fork");
        exit (EXIT_FAILURE);
    }

    if (pid == 0) {               /* Child. */
        if (chdir (tempdir) == -1) {
            perror (tempdir);
            _exit (EXIT_FAILURE);
        }

        printf ("\n"
                "The *current directory* is a FUSE filesystem backed by the disk\n"
                "image which is managed by libguestfs.  Any files or directories\n"
                "you copy into here (up to %d MB) will be saved into the disk\n"
                "image.  You can also delete files, create certain special files\n"
                "and so on.\n"
                "\n"
                "When you have finished adding files, hit ^D or type 'exit' to\n"
                "exit the shell and return to the mount-local program.\n"
                "\n",
                SIZE_MB);

        shell = getenv ("SHELL");
        if (!shell)
            r = system ("/bin/sh");
        else {
            /* Set a magic prompt.  We only know how to do this for bash. */
            p = strrchr (shell, '/');
            if (p && strcmp (p+1, "bash") == 0) {
                size_t len = 64 + strlen (shell);
                char buf[len];

                snprintf (buf, len, "PS1='mount-local-shell> ' %s --norc -i", shell);
                r = system (buf);
            } else
                r = system (shell);
        }
        if (r == -1) {
            fprintf (stderr, "error: failed to run sub-shell (%s) "
                     "(is $SHELL set correctly?)\n",
                     shell);
            //FALLTHROUGH
        }

        chdir ("/");
        guestfs_umount_local (g, GUESTFS_UMOUNT_LOCAL_RETRY, 1, -1);
        _exit (EXIT_SUCCESS);
    }

    /* Note that we are *not* waiting for the child yet.  We want to
     * run the FUSE code in parallel with the subshell.
     */

    /* We're going to hide libguestfs errors here, but in a real program
     * you would probably want to log them somewhere.
     */
    guestfs_push_error_handler (g, NULL, NULL);

    /* Now run the FUSE thread. */
    if (guestfs_mount_local_run (g) == -1)
        exit (EXIT_FAILURE);

    guestfs_pop_error_handler (g);

    waitpid (pid, NULL, 0);

    /* Shutdown the handle explicitly so write errors can be detected. */
    if (guestfs_shutdown (g) == -1)
        exit (EXIT_FAILURE);

    guestfs_close (g);

    printf ("\n"
            "Any files or directories that you copied in have been saved into\n"
            "the disk image called '%s'.\n"
            "\n"
            "Try opening the disk image with guestfish to see those files:\n"
            "\n"
            "  guestfish -a %s -m /dev/sda1\n"
            "\n",
            argv[1], argv[1]);

    exit (EXIT_SUCCESS);
}
Exemple #11
0
static int
do_make_fs (const char *input, const char *output_str)
{
  const char *dev, *options;
  CLEANUP_UNLINK_FREE char *output = NULL;
  uint64_t estimate, size;
  struct guestfs_disk_create_argv optargs;
  CLEANUP_FREE char *ifmt = NULL;
  CLEANUP_FREE char *ifile = NULL;
  pid_t pid;
  int status, fd;

  /* Use of CLEANUP_UNLINK_FREE *output ensures the output file is
   * deleted unless we successfully reach the end of this function.
   */
  output = strdup (output_str);
  if (output == NULL) {
    perror ("strdup");
    return -1;
  }

  /* Input.  What is it?  Estimate how much space it will need. */
  if (estimate_input (input, &estimate, &ifmt) == -1)
    return -1;

  if (verbose) {
    fprintf (stderr, "input format = %s\n", ifmt);
    fprintf (stderr, "estimate = %" PRIu64 " bytes "
             "(%" PRIu64 " 1K blocks, %" PRIu64 " 4K blocks)\n",
             estimate, estimate / 1024, estimate / 4096);
  }

  estimate += 256 * 1024;       /* For superblocks &c. */

  if (STRPREFIX (type, "ext") && type[3] >= '3') {
    /* For ext3+, add some more for the journal. */
    estimate += 1024 * 1024;
  }

  else if (STREQ (type, "ntfs")) {
    estimate += 4 * 1024 * 1024; /* NTFS journal. */
  }

  else if (STREQ (type, "btrfs")) {
    /* For BTRFS, the minimum metadata allocation is 256MB, with data
     * additional to that.  Note that we disable data and metadata
     * duplication below.
     */
    estimate += 256 * 1024 * 1024;
  }

  /* Add 10%, see above. */
  estimate *= 1.10;

  /* Calculate the output size. */
  if (size_str == NULL)
    size = estimate;
  else
    if (parse_size (size_str, estimate, &size) == -1)
      return -1;

  /* Create the output disk. */
  optargs.bitmask = 0;
  if (STREQ (format, "qcow2")) {
    optargs.bitmask |= GUESTFS_DISK_CREATE_PREALLOCATION_BITMASK;
    optargs.preallocation = "metadata";
  }
  if (guestfs_disk_create_argv (g, output, format, size, &optargs) == -1)
    return -1;

  if (guestfs_add_drive_opts (g, output,
                              GUESTFS_ADD_DRIVE_OPTS_FORMAT, format,
                              -1) == -1)
    return -1;

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

  if (check_ntfs_available () == -1)
    return -1;

  /* Partition the disk. */
  dev = "/dev/sda";
  if (partition) {
    int mbr_id = 0;

    if (STREQ (partition, ""))
      partition = "mbr";

    if (guestfs_part_disk (g, dev, partition) == -1)
      return -1;

    dev = "/dev/sda1";

    /* Set the partition type byte if it's MBR and the filesystem type
     * is one that we know about.
     */
    if (STREQ (partition, "mbr") || STREQ (partition, "msdos")) {
      if (STREQ (type, "msdos"))
        /* According to Wikipedia.  However I have not actually tried this. */
        mbr_id = 0x1;
      else if (STREQ (type, "vfat") || STREQ (type, "fat"))
        mbr_id = 0xb;
      else if (STREQ (type, "ntfs"))
        mbr_id = 0x7;
      else if (STRPREFIX (type, "ext"))
        mbr_id = 0x83;
      else if (STREQ (type, "minix"))
        mbr_id = 0x81;
    }
    if (mbr_id != 0) {
      if (guestfs_part_set_mbr_id (g, "/dev/sda", 1, mbr_id) == -1)
        return -1;
    }
  }

  if (verbose)
    fprintf (stderr, "creating %s filesystem on %s ...\n", type, dev);

  /* Create the filesystem. */
  if (STRNEQ (type, "btrfs")) {
    int r;
    struct guestfs_mkfs_opts_argv optargs = { .bitmask = 0 };

    if (label) {
      optargs.label = label;
      optargs.bitmask |= GUESTFS_MKFS_OPTS_LABEL_BITMASK;
    }

    guestfs_push_error_handler (g, NULL, NULL);
    r = guestfs_mkfs_opts_argv (g, type, dev, &optargs);
    guestfs_pop_error_handler (g);

    if (r == -1) {
      /* Provide more guidance in the error message (RHBZ#823883). */
      fprintf (stderr, "%s: 'mkfs' (create filesystem) operation failed: %s\n",
               guestfs_int_program_name, guestfs_last_error (g));
      if (STREQ (type, "fat"))
        fprintf (stderr, "Instead of 'fat', try 'vfat' (long filenames) or 'msdos' (short filenames).\n");
      else
        fprintf (stderr, "Is '%s' a correct filesystem type?\n", type);

      return -1;
    }
  }
  else {
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);
}
Exemple #13
0
/* Returns 0 on success, 1 if we need to retry. */
static int
do_format (void)
{
  char **devices;
  size_t i;
  int ret;

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

  /* Erase the disks. */
  if (!wipe) {
    for (i = 0; devices[i] != NULL; ++i) {
      /* erase the filesystem signatures on each device */
      if (have_wipefs && guestfs_wipefs (g, devices[i]) == -1)
        exit (EXIT_FAILURE);
      /* Then erase the partition table on each device. */
      if (guestfs_zero (g, devices[i]) == -1)
        exit (EXIT_FAILURE);
    }
  }
  else /* wipe */ {
    for (i = 0; devices[i] != NULL; ++i) {
      if (guestfs_zero_device (g, devices[i]) == -1)
        exit (EXIT_FAILURE);
    }
  }

  if (do_rescan (devices)) {
    ret = 1; /* which means, reopen the handle and retry */
    goto out;
  }

  /* Format each disk. */
  for (i = 0; devices[i] != NULL; ++i) {
    char *dev = devices[i];
    int free_dev = 0;

    if (partition) {
      const char *ptype = partition;
      int64_t dev_size;

      /* If partition has the magic value "DEFAULT", choose either MBR or GPT.*/
      if (STREQ (partition, "DEFAULT")) {
        dev_size = guestfs_blockdev_getsize64 (g, devices[i]);
        if (dev_size == -1)
          exit (EXIT_FAILURE);
        ptype = dev_size < INT64_C(2)*1024*1024*1024*1024 ? "mbr" : "gpt";
      }

      if (guestfs_part_disk (g, devices[i], ptype) == -1)
        exit (EXIT_FAILURE);
      if (asprintf (&dev, "%s1", devices[i]) == -1) {
        perror ("asprintf");
        exit (EXIT_FAILURE);
      }
      free_dev = 1;
    }

    if (vg && lv) {
      char *devs[2] = { dev, NULL };

      if (guestfs_pvcreate (g, dev) == -1)
        exit (EXIT_FAILURE);

      if (guestfs_vgcreate (g, vg, devs) == -1)
        exit (EXIT_FAILURE);

      if (guestfs_lvcreate_free (g, lv, vg, 100) == -1)
        exit (EXIT_FAILURE);

      if (free_dev)
        free (dev);
      if (asprintf (&dev, "/dev/%s/%s", vg, lv) == -1) {
        perror ("asprintf");
        exit (EXIT_FAILURE);
      }
      free_dev = 1;
    }

    if (filesystem) {
      if (guestfs_mkfs_opts (g, filesystem, dev, -1) == -1)
        exit (EXIT_FAILURE);
    }

    if (free_dev)
      free (dev);
  }

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

  ret = 0;

 out:
  /* Free device list. */
  for (i = 0; devices[i] != NULL; ++i)
    free (devices[i]);
  free (devices);

  return ret;
}
Exemple #14
0
/* Returns 0 on success, 1 if we need to retry. */
static int
do_format (void)
{
  size_t i;

  CLEANUP_FREE_STRING_LIST char **devices =
    guestfs_list_devices (g);
  if (devices == NULL)
    exit (EXIT_FAILURE);

  /* Erase the disks. */
  if (!wipe) {
    for (i = 0; devices[i] != NULL; ++i) {
      /* erase the filesystem signatures on each device */
      if (have_wipefs && guestfs_wipefs (g, devices[i]) == -1)
        exit (EXIT_FAILURE);
      /* Then erase the partition table on each device. */
      if (guestfs_zero (g, devices[i]) == -1)
        exit (EXIT_FAILURE);
    }
  }
  else /* wipe */ {
    for (i = 0; devices[i] != NULL; ++i) {
      if (guestfs_zero_device (g, devices[i]) == -1)
        exit (EXIT_FAILURE);
    }
  }

  /* Send TRIM/UNMAP to all block devices, to give back the space to
   * the host.  However don't fail if this doesn't work.
   */
  guestfs_push_error_handler (g, NULL, NULL);
  for (i = 0; devices[i] != NULL; ++i)
    guestfs_blkdiscard (g, devices[i]);
  guestfs_pop_error_handler (g);

  if (do_rescan (devices))
    return 1; /* which means, reopen the handle and retry */

  /* Format each disk. */
  for (i = 0; devices[i] != NULL; ++i) {
    char *dev = devices[i];
    int free_dev = 0;

    if (partition) {
      const char *ptype = partition;
      int64_t dev_size;

      /* If partition has the magic value "DEFAULT", choose either MBR or GPT.*/
      if (STREQ (partition, "DEFAULT")) {
        dev_size = guestfs_blockdev_getsize64 (g, devices[i]);
        if (dev_size == -1)
          exit (EXIT_FAILURE);
        ptype = dev_size < INT64_C(2)*1024*1024*1024*1024 ? "mbr" : "gpt";
      }

      if (guestfs_part_disk (g, devices[i], ptype) == -1)
        exit (EXIT_FAILURE);
      if (asprintf (&dev, "%s1", devices[i]) == -1) {
        perror ("asprintf");
        exit (EXIT_FAILURE);
      }
      free_dev = 1;

      /* Set the partition type byte appropriately, otherwise Windows
       * won't see the filesystem (RHBZ#1000428).
       */
      if (STREQ (ptype, "mbr") || STREQ (ptype, "msdos")) {
        int mbr_id = 0;

        if (vg && lv)
          mbr_id = 0x8e;
        else if (filesystem) {
          if (STREQ (filesystem, "msdos"))
            mbr_id = 0x01;
          else if (STREQ (filesystem, "fat") || STREQ (filesystem, "vfat"))
            mbr_id = 0x0b;
          else if (STREQ (filesystem, "ntfs"))
            mbr_id = 0x07;
          else if (STRPREFIX (filesystem, "ext"))
            mbr_id = 0x83;
          else if (STREQ (filesystem, "minix"))
            mbr_id = 0x81;
        }

        if (mbr_id > 0)
          guestfs_part_set_mbr_id (g, devices[i], 1, mbr_id);
      }
    }

    if (vg && lv) {
      char *devs[2] = { dev, NULL };

      if (guestfs_pvcreate (g, dev) == -1)
        exit (EXIT_FAILURE);

      if (guestfs_vgcreate (g, vg, devs) == -1)
        exit (EXIT_FAILURE);

      if (guestfs_lvcreate_free (g, lv, vg, 100) == -1)
        exit (EXIT_FAILURE);

      if (free_dev)
        free (dev);
      if (asprintf (&dev, "/dev/%s/%s", vg, lv) == -1) {
        perror ("asprintf");
        exit (EXIT_FAILURE);
      }
      free_dev = 1;
    }

    if (filesystem) {
      if (guestfs_mkfs_opts (g, filesystem, dev, -1) == -1)
        exit (EXIT_FAILURE);

      if (label) {
        if (guestfs_set_label (g, dev, label) == -1)
          exit (EXIT_FAILURE);
      }
    }

    if (free_dev)
      free (dev);
  }

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

  return 0;
}