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)); }
int init_basic_fs_on_lvm (guestfs_h *g) { const char *pvs[] = { "/dev/sda1", NULL }; if (init_partition (g) == -1) return -1; if (guestfs_pvcreate (g, "/dev/sda1") == -1) return -1; if (guestfs_vgcreate (g, "VG", (char **) pvs) == -1) return -1; if (guestfs_lvcreate (g, "LV", "VG", 8) == -1) return -1; if (guestfs_mkfs (g, "ext2", "/dev/VG/LV") == -1) return -1; if (guestfs_mount (g, "/dev/VG/LV", "/") == -1) return -1; return 0; }
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)); }
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); }
/* 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; }