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)); }
void prep_postlaunch_bootrootlv (const char *filename, prep_data *data, const char *device) { off_t bootsize; if (parse_size (data->params[4], &bootsize) == -1) prep_error (data, filename, _("could not parse boot size")); const int sector = guestfs_blockdev_getss (g, device); if (sector == -1) prep_error (data, filename, _("failed to get sector size of disk: %s"), guestfs_last_error (g)); if (guestfs_part_init (g, device, data->params[5]) == -1) prep_error (data, filename, _("failed to partition disk: %s"), guestfs_last_error (g)); off_t lastbootsect = 64 + bootsize/sector - 1; if (guestfs_part_add (g, device, "primary", 64, lastbootsect) == -1) prep_error (data, filename, _("failed to add boot partition: %s"), guestfs_last_error (g)); if (guestfs_part_add (g, device, "primary", lastbootsect+1, -64) == -1) prep_error (data, filename, _("failed to add root partition: %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) error (EXIT_FAILURE, errno, "asprintf"); if (guestfs_mkfs (g, data->params[1], part) == -1) prep_error (data, filename, _("failed to create boot filesystem: %s"), guestfs_last_error (g)); CLEANUP_FREE char *part2; if (asprintf (&part2, "%s2", device) == -1) error (EXIT_FAILURE, errno, "asprintf"); if (guestfs_pvcreate (g, part2) == -1) prep_error (data, filename, _("failed to create PV: %s: %s"), part2, guestfs_last_error (g)); char *parts[] = { part2, 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)); if (guestfs_mkfs (g, data->params[2], data->params[0]) == -1) prep_error (data, filename, _("failed to create root filesystem: %s"), guestfs_last_error (g)); }
/* 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; }