#include <string.h>
#include <assert.h>
#include <getopt.h>
+#include <errno.h>
+#include <limits.h>
#include <libvirt/libvirt.h>
#include <libvirt/virterror.h>
struct tool *t;
printf (_("\
+\n\
virt-kernel-info: Tools for providing information about virtual machines\n\
\n\
General usage is:\n\
+\n\
<tool> [-options]\n\
<tool> [-options] [domain-name|ID|UUID ...]\n\
<tool> [-options] -t <image>\n\
-where <tool> 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 <tool> 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 <libvirt-uri> 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 <image> Examine saved image (see: virt-kernel-info capture)\n\
- --externaldb | -x <externaldb> Load/override external kernels database\n\
- --version Print program name and version, then exit\n\
+\n\
+ -c | --connect <libvirt-uri>\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 <image> Examine saved image (see: virt-kernel-info capture)\n\
+ --version Print program name and version, then exit\n\
+ -x | --externaldb <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 | <arch> | ...\n\
-E | --endian auto | le | be\n\
--kernel-min auto | <arch> | ... | 0x<addr>\n\
static void
load_externaldb (const char *externaldb, int fail_if_no_externaldb)
{
-
-
-
-
-
-
-
-
- NOT_IMPL;
+ //NOT_IMPL;
}
static 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
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");
}