* to-xml guest.img [guest.img ...]
*/
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdint.h>
+#include <inttypes.h>
#include <unistd.h>
+#include <ctype.h>
#include <guestfs.h>
static void display_partition (guestfs_h *g, const char *dev);
static void display_partitions (guestfs_h *g, const char *dev);
+static void display_ext234 (guestfs_h *g, const char *dev, const char *fstype);
int
main (int argc, char *argv[])
CALL (devices = guestfs_list_devices (g), NULL);
printf ("<devices>\n");
for (i = 0; devices[i] != NULL; ++i) {
- printf ("<device dev=\"%s\">\n", devices[i]);
- display_partition (g, devices[i]);
+ int64_t size;
+ CALL (size = guestfs_blockdev_getsize64 (g, devices[i]), -1);
+ printf ("<device dev=\"%s\" size=\"%" PRIi64 "\">\n", devices[i], size);
+ display_partitions (g, devices[i]);
free (devices[i]);
printf ("</device>\n");
}
int j;
for (j = 0; lvs[j] != NULL; ++j) {
if (strncmp (lvs[j], "/dev/", 5) == 0 &&
- strncmp (&lvs[j][5], vgs[i], len) == 0 &&
- lvs[j][len+5] == '/') {
- printf ("<logvol name=\"%s\">\n", lvs[j]);
- display_partition (g, lvs[j]);
- printf ("</logvol>\n");
- free (lvs[j]);
+ strncmp (&lvs[j][5], vgs[i], len) == 0 &&
+ lvs[j][len+5] == '/') {
+ int64_t size;
+ CALL (size = guestfs_blockdev_getsize64 (g, lvs[j]), -1);
+ printf ("<logvol name=\"%s\" size=\"%" PRIi64 "\">\n", lvs[j], size);
+ display_partition (g, lvs[j]);
+ printf ("</logvol>\n");
+ free (lvs[j]);
}
}
CALL (what = guestfs_file (g, dev), NULL);
- if (strstr (what, "boot sector") != NULL)
+ if (strcmp (what, "x86 boot sector") == 0)
+ /* This is what 'file' program shows for Windows/NTFS partitions. */
+ printf ("<windows/>\n");
+ else if (strstr (what, "boot sector") != NULL)
display_partitions (g, dev);
else if (strncmp (what, "LVM2", 4) == 0)
printf ("<physvol/>\n");
- else if (strstr (what, "ext2 filesystem data") == 0)
- printf ("<fs type=\"ext2\"/>\n");
- else if (strstr (what, "ext3 filesystem data") == 0)
- printf ("<fs type=\"ext3\"/>\n");
+ else if (strstr (what, "ext2 filesystem data") != NULL)
+ display_ext234 (g, dev, "ext2");
+ else if (strstr (what, "ext3 filesystem data") != NULL)
+ display_ext234 (g, dev, "ext3");
+ else if (strstr (what, "ext4 filesystem data") != NULL)
+ display_ext234 (g, dev, "ext4");
+ else if (strstr (what, "Linux/i386 swap file") != NULL)
+ printf ("<linux-swap/>\n");
else
printf ("<unknown/>\n");
static void
display_partitions (guestfs_h *g, const char *dev)
{
- /* We can't look into a boot sector which is an LV. That's
- * a limitation of sorts of the Linux kernel. (Actually, we
- * could do this if we add the kpartx program to libguestfs).
+ /* We can't look into a boot sector which is an LV or partition.
+ * That's a limitation of sorts of the Linux kernel. (Actually,
+ * we could do this if we add the kpartx program to libguestfs).
*/
- if (strncmp (dev, "/dev/sd", 7) != 0) {
+ if (strncmp (dev, "/dev/sd", 7) != 0 || isdigit (dev[strlen(dev)-1])) {
printf ("<vm-image dev=\"%s\"/>\n", dev);
return;
}
for (i = 0; parts[i] != NULL; ++i) {
/* Only display partition if it's in the device. */
if (strncmp (parts[i], dev, len) == 0) {
- printf ("<partition dev=\"%s\">\n", parts[i]);
+ int64_t size;
+ CALL (size = guestfs_blockdev_getsize64 (g, parts[i]), -1);
+ printf ("<partition dev=\"%s\" size=\"%" PRIi64 "\">\n", parts[i], size);
display_partition (g, parts[i]);
printf ("</partition>\n");
}
free (parts);
printf ("</partitions>\n");
}
+
+/* Display some details on the ext2/3/4 filesystem on dev. */
+static void
+display_ext234 (guestfs_h *g, const char *dev, const char *fstype)
+{
+ char **sbfields;
+ int i;
+
+ printf ("<fs type=\"%s\">\n", fstype);
+ CALL (sbfields = guestfs_tune2fs_l (g, dev), NULL);
+
+ for (i = 0; sbfields[i] != NULL; i += 2) {
+ /* Just pick out a few important fields to display. There
+ * is much more that could be displayed here.
+ */
+ if (strcmp (sbfields[i], "Filesystem UUID") == 0)
+ printf ("<uuid>%s</uuid>\n", sbfields[i+1]);
+ else if (strcmp (sbfields[i], "Block size") == 0)
+ printf ("<blocksize>%s</blocksize>\n", sbfields[i+1]);
+
+ free (sbfields[i]);
+ free (sbfields[i+1]);
+ }
+ free (sbfields);
+
+ printf ("</fs>\n");
+}