mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
Added to-xml program.
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -29,8 +29,8 @@ daemon/install-sh
|
||||
daemon/missing
|
||||
depcomp
|
||||
emptydisk
|
||||
examples/df
|
||||
examples/hello
|
||||
examples/to-xml
|
||||
fish/guestfish
|
||||
guestfish.1
|
||||
guestfs.3
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
# libguestfs examples
|
||||
|
||||
noinst_PROGRAMS = hello
|
||||
noinst_PROGRAMS = hello to-xml
|
||||
|
||||
hello_SOURCES = hello.c
|
||||
hello_CFLAGS = -I$(top_builddir)/src -Wall
|
||||
hello_LDADD = $(top_builddir)/src/libguestfs.la
|
||||
|
||||
to_xml_SOURCES = to-xml.c
|
||||
to_xml_CFLAGS = -I$(top_builddir)/src -Wall
|
||||
to_xml_LDADD = $(top_builddir)/src/libguestfs.la
|
||||
|
||||
CLEANFILES = *~ $(noinst_PROGRAMS)
|
||||
|
||||
@@ -4,5 +4,12 @@ libguestfs API.
|
||||
As they are examples, these are licensed so they can be freely copied
|
||||
and used without any restrictions.
|
||||
|
||||
Tip: To enable verbose messages, set environment variable
|
||||
Tips:
|
||||
|
||||
(1) To enable verbose messages, set environment variable
|
||||
LIBGUESTFS_DEBUG=1
|
||||
|
||||
(2) If you haven't installed libguestfs, run the examples like this:
|
||||
LIBGUESTFS_PATH=. examples/to-xml
|
||||
(the path should point to the directory containing vmlinuz.* and
|
||||
initramfs.* files).
|
||||
|
||||
158
examples/to-xml.c
Normal file
158
examples/to-xml.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/* This inspects a block device and produces an XML representation of
|
||||
* the partitions, LVM, filesystems that we find there. This could be
|
||||
* useful as example code of how to do this sort of probing, or to
|
||||
* feed the XML to other programs.
|
||||
*
|
||||
* Usage:
|
||||
* to-xml guest.img [guest.img ...]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <guestfs.h>
|
||||
|
||||
/* Note that if any API call fails, we can just exit. The
|
||||
* standard error handler will have printed the error message
|
||||
* to stderr already.
|
||||
*/
|
||||
#define CALL(call,errcode) \
|
||||
if ((call) == (errcode)) exit (1);
|
||||
|
||||
static void display_partition (guestfs_h *g, const char *dev);
|
||||
static void display_partitions (guestfs_h *g, const char *dev);
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
guestfs_h *g;
|
||||
int i;
|
||||
|
||||
if (argc < 2 || access (argv[1], F_OK) != 0) {
|
||||
fprintf (stderr, "Usage: to-xml guest.img [guest.img ...]\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (!(g = guestfs_create ())) {
|
||||
fprintf (stderr, "Cannot create libguestfs handle.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; ++i)
|
||||
CALL (guestfs_add_drive (g, argv[i]), -1);
|
||||
|
||||
CALL (guestfs_launch (g), -1);
|
||||
CALL (guestfs_wait_ready (g), -1);
|
||||
|
||||
printf ("<guestfs-system>\n");
|
||||
|
||||
/* list-devices should return the devices that we just attached?
|
||||
* Better to find out what the kernel thinks are devices anyway ...
|
||||
*/
|
||||
char **devices;
|
||||
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]);
|
||||
free (devices[i]);
|
||||
printf ("</device>\n");
|
||||
}
|
||||
free (devices);
|
||||
printf ("</devices>\n");
|
||||
|
||||
/* Now do the same for VGs and LVs. Note that a VG may span
|
||||
* multiple PVs / block devices, in arbitrary ways, which is
|
||||
* why VGs are in a separate top-level XML class.
|
||||
*/
|
||||
char **vgs;
|
||||
char **lvs;
|
||||
printf ("<volgroups>\n");
|
||||
CALL (vgs = guestfs_vgs (g), NULL);
|
||||
CALL (lvs = guestfs_lvs (g), NULL);
|
||||
for (i = 0; vgs[i] != NULL; ++i) {
|
||||
printf ("<volgroup name=\"%s\">\n", vgs[i]);
|
||||
|
||||
/* Just the LVs in this VG. */
|
||||
int len = strlen (vgs[i]);
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
free (vgs[i]);
|
||||
printf ("</volgroup>\n");
|
||||
}
|
||||
free (vgs);
|
||||
free (lvs);
|
||||
printf ("</volgroups>\n");
|
||||
|
||||
guestfs_close (g);
|
||||
printf ("</guestfs-system>\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Display a partition or LV. */
|
||||
static void
|
||||
display_partition (guestfs_h *g, const char *dev)
|
||||
{
|
||||
char *what;
|
||||
|
||||
CALL (what = guestfs_file (g, dev), NULL);
|
||||
|
||||
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
|
||||
printf ("<unknown/>\n");
|
||||
|
||||
free (what);
|
||||
}
|
||||
|
||||
/* Display an MBR-formatted boot sector. */
|
||||
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).
|
||||
*/
|
||||
if (strncmp (dev, "/dev/sd", 7) != 0) {
|
||||
printf ("<vm-image dev=\"%s\"/>\n", dev);
|
||||
return;
|
||||
}
|
||||
|
||||
char **parts;
|
||||
int i, len;
|
||||
CALL (parts = guestfs_list_partitions (g), NULL);
|
||||
printf ("<partitions>\n");
|
||||
|
||||
len = strlen (dev);
|
||||
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]);
|
||||
display_partition (g, parts[i]);
|
||||
printf ("</partition>\n");
|
||||
}
|
||||
|
||||
free (parts[i]);
|
||||
}
|
||||
free (parts);
|
||||
printf ("</partitions>\n");
|
||||
}
|
||||
Reference in New Issue
Block a user