/* 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; }
/* 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; }