From 12328f2af5955e562eec91bc00a7f30f4e1467bf Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Mon, 15 Mar 2010 15:11:58 +0000 Subject: [PATCH] Implement libvirt calls. --- configure.ac | 3 ++ src/Makefile.am | 4 +- src/internal.h | 4 +- src/main.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++---------- 4 files changed, 116 insertions(+), 26 deletions(-) diff --git a/configure.ac b/configure.ac index 1f0f27f..e923c06 100644 --- a/configure.ac +++ b/configure.ac @@ -38,6 +38,9 @@ AM_GNU_GETTEXT_VERSION([0.17]) dnl Check support for 64 bit file offsets. AC_SYS_LARGEFILE +dnl Check for libvirt. +PKG_CHECK_MODULES([LIBVIRT], [libvirt]) + # Generate output files. AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([Makefile diff --git a/src/Makefile.am b/src/Makefile.am index 74f48dd..8103f1d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -25,4 +25,6 @@ virt_kernel_info_SOURCES = \ virt_kernel_info_SOURCES += \ dmesg.c -virt_kernel_info_CFLAGS = -DDATADIR=\"$(datadir)\" +virt_kernel_info_CFLAGS = -DDATADIR=\"$(datadir)\" $(LIBVIRT_CFLAGS) + +virt_kernel_info_LDADD = $(LIBVIRT_LIBS) \ No newline at end of file diff --git a/src/internal.h b/src/internal.h index 7bc4832..300b7f6 100644 --- a/src/internal.h +++ b/src/internal.h @@ -71,9 +71,9 @@ typedef void (*tool_run_fn) (void); /* XXX */ struct tool { - const char *name; /* Tool name, eg. "ps" */ + const char *name; /* Tool name, eg. "dmesg" */ - int external_cmd; /* Is the tool an external command, eg. "virt-ps" */ + int external_cmd; /* Is the tool an external command, eg. "virt-dmesg" */ const char *summary; /* Tool-specific one line summary. */ const char *description; /* Long description. */ diff --git a/src/main.c b/src/main.c index 5de205a..787ec4c 100644 --- a/src/main.c +++ b/src/main.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include @@ -245,26 +247,34 @@ static void usage (void) struct tool *t; printf (_("\ +\n\ virt-kernel-info: Tools for providing information about virtual machines\n\ \n\ General usage is:\n\ +\n\ [-options]\n\ [-options] [domain-name|ID|UUID ...]\n\ [-options] -t \n\ -where is 'virt-ps', 'virt-dmesg' etc. (full list below) or a\n\ -subtool such as 'virt-kernel-info ps', 'virt-kernel-info capture' etc.\n\ +\n\ +where is 'virt-dmesg' etc. (full list below) or a subtool\n\ +such as 'virt-kernel-info dmesg', 'virt-kernel-info capture' etc.\n\ \n\ General options:\n\ - --connect | -c Connect to URI (default: autodetect)\n\ - --csv Output in CSV format for spreadsheets etc.\n\ - --debug Print extra debugging information\n\ - --list-kernels List known kernels, then exit\n\ - --image | -t Examine saved image (see: virt-kernel-info capture)\n\ - --externaldb | -x Load/override external kernels database\n\ - --version Print program name and version, then exit\n\ +\n\ + -c | --connect \n\ + Connect to URI (default: autodetect)\n\ + --csv Output in CSV format for spreadsheets etc.\n\ + --debug Print extra debugging information\n\ + --list-kernels List known kernels, then exit\n\ + -t | --image Examine saved image (see: virt-kernel-info capture)\n\ + --version Print program name and version, then exit\n\ + -x | --externaldb \n\ + Load/override external kernels database\n\ \n\ These options may be used to override automatic detection of guest\n\ -architecture, endianness, kernel location, etc.:\n\ +architecture, endianness, kernel location, etc. The default for all\n\ +of them is 'auto':\n\ +\n\ -A | --arch auto | | ...\n\ -E | --endian auto | le | be\n\ --kernel-min auto | | ... | 0x\n\ @@ -294,15 +304,7 @@ List of tools:\n\ static void load_externaldb (const char *externaldb, int fail_if_no_externaldb) { - - - - - - - - - NOT_IMPL; + //NOT_IMPL; } static void @@ -311,16 +313,99 @@ do_list_kernels (void) NOT_IMPL; } +static void +discard_virterror (void *user_data, virErrorPtr err) +{ + /* nothing */ +} + +/* Get all running domains, named by domname/ID/UUID. */ static virDomainPtr * -get_named_domains (char * const *domains, int nr_domains) +get_named_domains (char * const *domains, int n) { - NOT_IMPL; + assert (conn != NULL); + + virDomainPtr *doms = malloc (sizeof (virDomainPtr) * (n+1)); + if (doms == NULL) { + perror ("malloc"); + exit (1); + } + + /* Discard 'domain not found' errors from libvirt while we + * run this loop. + */ + virConnSetErrorFunc (conn, NULL, discard_virterror); + + int i; + for (i = 0; i < n; ++i) { + /* Try in the order: UUID, name, ID. */ + doms[i] = virDomainLookupByUUIDString (conn, domains[i]); + if (!doms[i]) { + doms[i] = virDomainLookupByName (conn, domains[i]); + if (!doms[i] && domains[i][0] >= '0' && domains[i][0] <= '9') { + errno = 0; + char *endptr; + int id = strtol (domains[i], &endptr, 10); + if ((errno == ERANGE && (id == LONG_MAX || id == LONG_MIN)) || + (errno != 0 && id == 0)) { + perror ("strtol"); + exit (EXIT_FAILURE); + } + if (endptr == domains[i]) + error (_("no digits found while trying to parse ID '%s'"), + domains[i]); + if (*endptr) + error (_("parse error, extra digits after ID '%s'"), + domains[i]); + doms[i] = virDomainLookupByID (conn, id); + } + } + + if (!doms[i]) + error (_("%s: libvirt guest not found (use name, UUID or ID here)"), + domains[i]); + + if (!virDomainIsActive (doms[i])) + error (_("%s: this domain is inactive. This program only works on running guests."), + virDomainGetName (doms[i])); + } + + /* Restore default virterror behaviour. */ + virConnSetErrorFunc (conn, NULL, NULL); + + return doms; } +/* Get all (running) domains. */ static virDomainPtr * get_all_domains (void) { - NOT_IMPL; + assert (conn != NULL); + + int n; + n = virConnectNumOfDomains (conn); + if (n == -1) + error (_("failed to get number of domains")); + + int ids[n]; + n = virConnectListDomains (conn, ids, n); + if (n == -1) + error (_("failed to list domains")); + + int i, j; + virDomainPtr *doms = malloc (sizeof (virDomainPtr) * (n+1)); + if (doms == NULL) { + perror ("malloc"); + exit (1); + } + for (i = 0; i < n; ++i) { + /* Ignore failures, but don't increment 'j' if that happens. */ + doms[j] = virDomainLookupByID (conn, ids[i]); + if (doms[j]) j++; + } + + doms[j] = NULL; + return doms; } /* Tools register themselves by calling this function. Note that the @@ -348,7 +433,7 @@ register_tool (struct tool *tool) static void message (const char *pre, const char *fs, va_list args) { - fprintf (stderr, "%s-%s: %s: ", PACKAGE_NAME, PACKAGE_VERSION, pre); + fprintf (stderr, "%s: %s: ", PACKAGE_NAME, pre); vfprintf (stderr, fs, args); fprintf (stderr, "\n"); } -- 1.8.3.1