static void do_output_blockdevs (void) { size_t i; CLEANUP_FREE_STRING_LIST char **devices = guestfs_list_devices (g); if (devices == NULL) exit (EXIT_FAILURE); for (i = 0; devices[i] != NULL; ++i) { int64_t size = -1; CLEANUP_FREE_STRING_LIST char **parents = NULL; CLEANUP_FREE char *dev; dev = guestfs_canonical_device_name (g, devices[i]); if (!dev) exit (EXIT_FAILURE); if ((columns & COLUMN_SIZE)) { size = guestfs_blockdev_getsize64 (g, devices[i]); if (size == -1) exit (EXIT_FAILURE); } if (is_md (devices[i])) parents = parents_of_md (devices[i]); else parents = no_parents (); write_row (dev, "device", NULL, NULL, -1, size, parents, NULL); } }
static void do_output_partitions (void) { size_t i; CLEANUP_FREE_STRING_LIST char **parts = guestfs_list_partitions (g); if (parts == NULL) exit (EXIT_FAILURE); for (i = 0; parts[i] != NULL; ++i) { CLEANUP_FREE char *dev = NULL, *parent_name = NULL, *canonical_name = NULL; const char *parents[2]; int64_t size = -1; int mbr_id = -1; dev = guestfs_canonical_device_name (g, parts[i]); if (!dev) exit (EXIT_FAILURE); if ((columns & COLUMN_SIZE)) { size = guestfs_blockdev_getsize64 (g, parts[i]); if (size == -1) exit (EXIT_FAILURE); } if ((columns & COLUMN_PARENTS)) { parent_name = guestfs_part_to_dev (g, parts[i]); if (parent_name == NULL) exit (EXIT_FAILURE); if ((columns & COLUMN_MBR)) mbr_id = get_mbr_id (parts[i], parent_name); canonical_name = guestfs_canonical_device_name (g, parent_name); if (!canonical_name) exit (EXIT_FAILURE); parents[0] = canonical_name; parents[1] = NULL; } write_row (dev, "partition", NULL, NULL, mbr_id, size, (char **) parents, NULL); } }
static void do_output_lvs (void) { size_t i; CLEANUP_FREE_STRING_LIST char **lvs = guestfs_lvs (g); if (lvs == NULL) exit (EXIT_FAILURE); for (i = 0; lvs[i] != NULL; ++i) { CLEANUP_FREE char *uuid = NULL, *parent_name = NULL; const char *parents[2]; int64_t size = -1; if ((columns & COLUMN_SIZE)) { size = guestfs_blockdev_getsize64 (g, lvs[i]); if (size == -1) exit (EXIT_FAILURE); } if ((columns & COLUMN_UUID)) { uuid = guestfs_lvuuid (g, lvs[i]); if (uuid == NULL) exit (EXIT_FAILURE); } if ((columns & COLUMN_PARENTS)) { parent_name = strdup (lvs[i]); if (parent_name == NULL) { perror ("strdup"); exit (EXIT_FAILURE); } char *p = strrchr (parent_name, '/'); if (p) *p = '\0'; parents[0] = parent_name; parents[1] = NULL; } write_row (lvs[i], "lv", NULL, NULL, -1, size, (char **) parents, uuid); } }
/* Get the size of the file or block device. */ static off_t get_size (const char *filename) { int64_t size; if (STRPREFIX (filename, "/dev/")) { size = guestfs_blockdev_getsize64 (g, filename); if (size == -1) return -1; } else { size = guestfs_filesize (g, filename); if (size == -1) return -1; } /* This case should be safe because we always compile with * 64 bit file offsets. */ return (off_t) size; }
static void do_output_filesystems (void) { size_t i; CLEANUP_FREE_STRING_LIST char **fses = guestfs_list_filesystems (g); if (fses == NULL) exit (EXIT_FAILURE); for (i = 0; fses[i] != NULL; i += 2) { CLEANUP_FREE char *dev = NULL, *vfs_label = NULL, *vfs_uuid = NULL; CLEANUP_FREE_STRING_LIST char **parents = NULL; int64_t size = -1; /* Skip swap and unknown, unless --extra flag was given. */ if (!(output & OUTPUT_FILESYSTEMS_EXTRA) && (STREQ (fses[i+1], "swap") || STREQ (fses[i+1], "unknown"))) continue; dev = guestfs_canonical_device_name (g, fses[i]); if (dev == NULL) exit (EXIT_FAILURE); /* Only bother to look these up if we will be displaying them, * otherwise pass them as NULL. */ if ((columns & COLUMN_VFS_LABEL)) { guestfs_push_error_handler (g, NULL, NULL); vfs_label = guestfs_vfs_label (g, fses[i]); guestfs_pop_error_handler (g); if (vfs_label == NULL) { vfs_label = strdup (""); if (!vfs_label) { perror ("strdup"); exit (EXIT_FAILURE); } } } if ((columns & COLUMN_UUID)) { guestfs_push_error_handler (g, NULL, NULL); vfs_uuid = guestfs_vfs_uuid (g, fses[i]); guestfs_pop_error_handler (g); if (vfs_uuid == NULL) { vfs_uuid = strdup (""); if (!vfs_uuid) { perror ("strdup"); exit (EXIT_FAILURE); } } } if ((columns & COLUMN_SIZE)) { size = guestfs_blockdev_getsize64 (g, fses[i]); if (size == -1) exit (EXIT_FAILURE); } if (is_md (fses[i])) parents = parents_of_md (fses[i]); else parents = no_parents (); write_row (dev, "filesystem", fses[i+1], vfs_label, -1, size, parents, vfs_uuid); } }
/* 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; }