This is the implementation (currently Xen, local only).
It includes a couple of virsh commands if you want to play with looking at the stats.
Rich. -- Emerging Technologies, Red Hat - http://et.redhat.com/~rjones/ Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SL4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 03798903
Index: include/libvirt/libvirt.h.in
===================================================================
RCS file: /data/cvs/libvirt/include/libvirt/libvirt.h.in,v
retrieving revision 1.31
diff -u -p -r1.31 libvirt.h.in
--- include/libvirt/libvirt.h.in 18 Jul 2007 10:11:10 -0000 1.31
+++ include/libvirt/libvirt.h.in 10 Aug 2007 14:30:21 -0000
@@ -14,6 +14,9 @@
#ifndef __VIR_VIRLIB_H__
#define __VIR_VIRLIB_H__
+#include <sys/types.h>
+#include <stdint.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -197,6 +200,37 @@ int virDomainSetSchedulerParameters (vir
virSchedParameterPtr params,
int nparams);
+/* Block device stats for virDomainBlockStats.
+ *
+ * Hypervisors may return a field set to (int64_t)-1 which indicates
+ * that the hypervisor does not support that statistic.
+ */
+struct _virDomainBlockStats {
+ int64_t rd_req;
+ int64_t rd_bytes;
+ int64_t wr_req;
+ int64_t wr_bytes;
+ int64_t errs; // In Xen this returns the mysterious 'oo_req'.
+};
+typedef struct _virDomainBlockStats *virDomainBlockStatsPtr;
+
+/* Network interface stats for virDomainInterfaceStats.
+ *
+ * Hypervisors may return a field set to (int64_t)-1 which indicates
+ * that the hypervisor does not support that statistic.
+ */
+struct _virDomainInterfaceStats {
+ int64_t rx_bytes;
+ int64_t rx_packets;
+ int64_t rx_errs;
+ int64_t rx_drop;
+ int64_t tx_bytes;
+ int64_t tx_packets;
+ int64_t tx_errs;
+ int64_t tx_drop;
+};
+typedef struct _virDomainInterfaceStats *virDomainInterfaceStatsPtr;
+
/**
* VIR_NODEINFO_MAXCPUS:
* @nodeinfo: virNodeInfo instance
@@ -369,6 +403,16 @@ int virDomainGetMaxVcpus (virDomainPtr
char * virDomainGetXMLDesc (virDomainPtr domain,
int flags);
+int virDomainBlockStats (virDomainPtr dom,
+ const char *path,
+ virDomainBlockStatsPtr stats,
+ size_t size);
+int virDomainInterfaceStats (virDomainPtr dom,
+ const char *path,
+ virDomainInterfaceStatsPtr stats,
+ size_t size);
+
+
/*
* defined but not running domains
*/
Index: src/driver.h
===================================================================
RCS file: /data/cvs/libvirt/src/driver.h,v
retrieving revision 1.32
diff -u -p -r1.32 driver.h
--- src/driver.h 27 Jul 2007 23:23:00 -0000 1.32
+++ src/driver.h 10 Aug 2007 14:30:21 -0000
@@ -181,6 +181,17 @@ typedef int
virSchedParameterPtr params,
int nparams);
+typedef int
+ (*virDrvDomainBlockStats)
+ (virDomainPtr domain,
+ const char *path,
+ struct _virDomainBlockStats *stats);
+typedef int
+ (*virDrvDomainInterfaceStats)
+ (virDomainPtr domain,
+ const char *path,
+ struct _virDomainInterfaceStats *stats);
+
typedef struct _virDriver virDriver;
typedef virDriver *virDriverPtr;
@@ -245,6 +256,8 @@ struct _virDriver {
virDrvDomainGetSchedulerType domainGetSchedulerType;
virDrvDomainGetSchedulerParameters domainGetSchedulerParameters;
virDrvDomainSetSchedulerParameters domainSetSchedulerParameters;
+ virDrvDomainBlockStats domainBlockStats;
+ virDrvDomainInterfaceStats domainInterfaceStats;
};
typedef int
Index: src/libvirt.c
===================================================================
RCS file: /data/cvs/libvirt/src/libvirt.c,v
retrieving revision 1.93
diff -u -p -r1.93 libvirt.c
--- src/libvirt.c 9 Aug 2007 20:19:12 -0000 1.93
+++ src/libvirt.c 10 Aug 2007 14:30:23 -0000
@@ -1830,6 +1830,116 @@ virDomainSetSchedulerParameters(virDomai
}
+/**
+ * virDomainBlockStats
+ * @dom: pointer to the domain object
+ * @path: path to the block device
+ * @stats: block device stats (returned)
+ * @size: size of stats structure
+ *
+ * This function returns block device (disk) stats for block
+ * devices attached to the domain.
+ *
+ * The path parameter is the name of the block device. Get this
+ * by calling virDomainGetXMLDesc and finding the <target dev='...'>
+ * attribute within //domain/devices/disk. (For example, "xvda").
+ *
+ * Domains may have more than one block device. To get stats for
+ * each you should make multiple calls to this function.
+ *
+ * Individual fields within the stats structure may be returned
+ * as -1, which indicates that the hypervisor does not support
+ * that particular statistic.
+ *
+ * Returns: 0 in case of success or -1 in case of failure.
+ */
+int
+virDomainBlockStats (virDomainPtr dom, const char *path,
+ virDomainBlockStatsPtr stats, size_t size)
+{
+ virConnectPtr conn;
+ struct _virDomainBlockStats stats2 = { -1, -1, -1, -1, -1 };
+ DEBUG("domain=%p, path=%s, stats=%p, size=%zi", dom, path, stats, size);
+
+ if (!stats || size > sizeof stats2) {
+ virLibDomainError (dom, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return -1;
+ }
+ if (!VIR_IS_CONNECTED_DOMAIN (dom)) {
+ virLibDomainError (dom, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return -1;
+ }
+ conn = dom->conn;
+
+ if (conn->driver->domainBlockStats) {
+ if (conn->driver->domainBlockStats (dom, path, &stats2) == -1)
+ return -1;
+
+ memcpy (stats, &stats2, size);
+ return 0;
+ }
+
+ virLibDomainError (dom, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+/**
+ * virDomainInterfaceStats
+ * @dom: pointer to the domain object
+ * @path: path to the interface
+ * @stats: network interface stats (returned)
+ * @size: size of stats structure
+ *
+ * This function returns network interface stats for interfaces
+ * attached to the domain.
+ *
+ * The path parameter is the name of the network interface. Get
+ * this by calling virDomainGetXMLDesc and finding the
+ * <source ...> attribute within //domain/devices/interface.
+ * (For example, "xenbr0" or "virbr0").
+ *
+ * Domains may have more than network interface. To get stats for
+ * each you should make multiple calls to this function.
+ *
+ * Individual fields within the stats structure may be returned
+ * as -1, which indicates that the hypervisor does not support
+ * that particular statistic.
+ *
+ * Returns: 0 in case of success or -1 in case of failure.
+ */
+int
+virDomainInterfaceStats (virDomainPtr dom, const char *path,
+ virDomainInterfaceStatsPtr stats, size_t size)
+{
+ virConnectPtr conn;
+ struct _virDomainInterfaceStats stats2 = { -1, -1, -1, -1,
+ -1, -1, -1, -1 };
+ DEBUG("domain=%p, path=%s, stats=%p, size=%zi", dom, path, stats, size);
+
+ if (!stats || size > sizeof stats2) {
+ virLibDomainError (dom, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return -1;
+ }
+ if (!VIR_IS_CONNECTED_DOMAIN (dom)) {
+ virLibDomainError (dom, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return -1;
+ }
+ conn = dom->conn;
+
+ if (conn->driver->domainInterfaceStats) {
+ if (conn->driver->domainInterfaceStats (dom, path, &stats2) == -1)
+ return -1;
+
+ memcpy (stats, &stats2, size);
+ return 0;
+ }
+
+ virLibDomainError (dom, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+
+
/************************************************************************
* *
Index: src/libvirt_sym.version
===================================================================
RCS file: /data/cvs/libvirt/src/libvirt_sym.version,v
retrieving revision 1.25
diff -u -p -r1.25 libvirt_sym.version
--- src/libvirt_sym.version 26 Jun 2007 22:56:14 -0000 1.25
+++ src/libvirt_sym.version 10 Aug 2007 14:30:23 -0000
@@ -65,7 +65,8 @@
virDomainGetSchedulerType;
virDomainGetSchedulerParameters;
virDomainSetSchedulerParameters;
-
+ virDomainBlockStats;
+ virDomainInterfaceStats;
virDomainAttachDevice;
virDomainDetachDevice;
Index: src/qemu_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_driver.c,v
retrieving revision 1.14
diff -u -p -r1.14 qemu_driver.c
--- src/qemu_driver.c 30 Jul 2007 09:59:06 -0000 1.14
+++ src/qemu_driver.c 10 Aug 2007 14:30:24 -0000
@@ -2386,6 +2386,8 @@ static virDriver qemuDriver = {
NULL, /* domainGetSchedulerType */
NULL, /* domainGetSchedulerParameters */
NULL, /* domainSetSchedulerParameters */
+ NULL, /* domainBlockStats */
+ NULL, /* domainInterfaceStats */
};
static virNetworkDriver qemuNetworkDriver = {
Index: src/test.c
===================================================================
RCS file: /data/cvs/libvirt/src/test.c,v
retrieving revision 1.44
diff -u -p -r1.44 test.c
--- src/test.c 9 Aug 2007 20:19:12 -0000 1.44
+++ src/test.c 10 Aug 2007 14:30:26 -0000
@@ -1963,6 +1963,8 @@ static virDriver testDriver = {
testDomainGetSchedulerType, /* domainGetSchedulerType */
testDomainGetSchedulerParams, /* domainGetSchedulerParameters */
testDomainSetSchedulerParams, /* domainSetSchedulerParameters */
+ NULL, /* domainBlockStats */
+ NULL, /* domainInterfaceStats */
};
static virNetworkDriver testNetworkDriver = {
Index: src/virsh.c
===================================================================
RCS file: /data/cvs/libvirt/src/virsh.c,v
retrieving revision 1.94
diff -u -p -r1.94 virsh.c
--- src/virsh.c 7 Aug 2007 15:26:51 -0000 1.94
+++ src/virsh.c 10 Aug 2007 14:30:28 -0000
@@ -31,6 +31,7 @@
#include <assert.h>
#include <errno.h>
#include <sys/stat.h>
+#include <inttypes.h>
#include <test.h>
#include <libxml/parser.h>
@@ -659,6 +660,129 @@ cmdDomstate(vshControl * ctl, vshCmd * c
return ret;
}
+/* "domblkstat" command
+ */
+static vshCmdInfo info_domblkstat[] = {
+ {"syntax", "domblkstat <domain> <dev>"},
+ {"help", gettext_noop("get device block stats for a domain")},
+ {"desc", gettext_noop("Get device block stats for a running domain.")},
+ {NULL,NULL}
+};
+
+static vshCmdOptDef opts_domblkstat[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")},
+ {"device", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("block device")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdDomblkstat (vshControl *ctl, vshCmd *cmd)
+{
+ virDomainPtr dom;
+ char *name, *device;
+ struct _virDomainBlockStats stats;
+
+ if (!vshConnectionUsability (ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ if (!(dom = vshCommandOptDomain (ctl, cmd, "domain", &name)))
+ return FALSE;
+
+ if (!(device = vshCommandOptString (cmd, "device", NULL)))
+ return FALSE;
+
+ if (virDomainBlockStats (dom, device, &stats, sizeof stats) == -1) {
+ vshError (ctl, FALSE, _("Failed to get block stats %s %s"),
+ name, device);
+ virDomainFree(dom);
+ return FALSE;
+ }
+
+ if (stats.rd_req >= 0)
+ vshPrint (ctl, "%s rd_req %" PRId64 "\n", device, stats.rd_req);
+
+ if (stats.rd_bytes >= 0)
+ vshPrint (ctl, "%s rd_bytes %" PRId64 "\n", device, stats.rd_bytes);
+
+ if (stats.wr_req >= 0)
+ vshPrint (ctl, "%s wr_req %" PRId64 "\n", device, stats.wr_req);
+
+ if (stats.wr_bytes >= 0)
+ vshPrint (ctl, "%s wr_bytes %" PRId64 "\n", device, stats.wr_bytes);
+
+ if (stats.errs >= 0)
+ vshPrint (ctl, "%s errs %" PRId64 "\n", device, stats.errs);
+
+ virDomainFree(dom);
+ return TRUE;
+}
+
+/* "domifstat" command
+ */
+static vshCmdInfo info_domifstat[] = {
+ {"syntax", "domifstat <domain> <dev>"},
+ {"help", gettext_noop("get network interface stats for a domain")},
+ {"desc", gettext_noop("Get network interface stats for a running domain.")},
+ {NULL,NULL}
+};
+
+static vshCmdOptDef opts_domifstat[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")},
+ {"interface", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("interface device")},
+ {NULL, 0, 0, NULL}
+};
+
+static int
+cmdDomIfstat (vshControl *ctl, vshCmd *cmd)
+{
+ virDomainPtr dom;
+ char *name, *device;
+ struct _virDomainInterfaceStats stats;
+
+ if (!vshConnectionUsability (ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ if (!(dom = vshCommandOptDomain (ctl, cmd, "domain", &name)))
+ return FALSE;
+
+ if (!(device = vshCommandOptString (cmd, "interface", NULL)))
+ return FALSE;
+
+ if (virDomainInterfaceStats (dom, device, &stats, sizeof stats) == -1) {
+ vshError (ctl, FALSE, _("Failed to get interface stats %s %s"),
+ name, device);
+ virDomainFree(dom);
+ return FALSE;
+ }
+
+ if (stats.rx_bytes >= 0)
+ vshPrint (ctl, "%s rx_bytes %" PRId64 "\n", device, stats.rx_bytes);
+
+ if (stats.rx_packets >= 0)
+ vshPrint (ctl, "%s rx_packets %" PRId64 "\n", device, stats.rx_packets);
+
+ if (stats.rx_errs >= 0)
+ vshPrint (ctl, "%s rx_errs %" PRId64 "\n", device, stats.rx_errs);
+
+ if (stats.rx_drop >= 0)
+ vshPrint (ctl, "%s rx_drop %" PRId64 "\n", device, stats.rx_drop);
+
+ if (stats.tx_bytes >= 0)
+ vshPrint (ctl, "%s tx_bytes %" PRId64 "\n", device, stats.tx_bytes);
+
+ if (stats.tx_packets >= 0)
+ vshPrint (ctl, "%s tx_packets %" PRId64 "\n", device, stats.tx_packets);
+
+ if (stats.tx_errs >= 0)
+ vshPrint (ctl, "%s tx_errs %" PRId64 "\n", device, stats.tx_errs);
+
+ if (stats.tx_drop >= 0)
+ vshPrint (ctl, "%s tx_drop %" PRId64 "\n", device, stats.tx_drop);
+
+ virDomainFree(dom);
+ return TRUE;
+}
+
/*
* "suspend" command
*/
@@ -3466,6 +3590,8 @@ static vshCmdDef commands[] = {
{"dominfo", cmdDominfo, opts_dominfo, info_dominfo},
{"domname", cmdDomname, opts_domname, info_domname},
{"domstate", cmdDomstate, opts_domstate, info_domstate},
+ {"domblkstat", cmdDomblkstat, opts_domblkstat, info_domblkstat},
+ {"domifstat", cmdDomIfstat, opts_domifstat, info_domifstat},
{"dumpxml", cmdDumpXML, opts_dumpxml, info_dumpxml},
{"hostname", cmdHostname, NULL, info_hostname},
{"list", cmdList, opts_list, info_list},
Index: src/xen_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xen_internal.c,v
retrieving revision 1.90
diff -u -p -r1.90 xen_internal.c
--- src/xen_internal.c 30 Jul 2007 10:15:58 -0000 1.90
+++ src/xen_internal.c 10 Aug 2007 14:30:30 -0000
@@ -1291,6 +1291,141 @@ xenHypervisorSetSchedulerParameters(virD
return 0;
}
+static int64_t
+read_stat (const char *path)
+{
+ char str[64];
+ int64_t r;
+ int i;
+ FILE *fp;
+
+ fp = fopen (path, "r");
+ if (!fp) return -1;
+ /* stupid GCC warning */ i = fread (str, sizeof str, 1, fp);
+ r = strtoll (str, NULL, 10);
+ fclose (fp);
+ return r;
+}
+
+static int64_t
+read_bd_stat (int device, int domid, const char *str)
+{
+ char path[PATH_MAX];
+ int64_t r;
+
+ snprintf (path, sizeof path,
+ "/sys/devices/xen-backend/vbd-%d-%d/statistics/%s_req",
+ domid, device, str);
+ r = read_stat (path);
+ if (r >= 0) return r;
+
+ snprintf (path, sizeof path,
+ "/sys/devices/xen-backend/tap-%d-%d/statistics/%s_req",
+ domid, device, str);
+ r = read_stat (path);
+ return r;
+}
+
+/* Paths have the form "xvd[a-]" and map to paths /sys/devices/xen-backend/
+ * (vbd|tap)-domid-major:minor/statistics/(rd|wr|oo)_req. The major:minor
+ * is in this case fixed as 202*256 + 16*minor where minor is 0 for xvda,
+ * 1 for xvdb and so on.
+ */
+int
+xenHypervisorDomainBlockStats (virDomainPtr dom,
+ const char *path,
+ struct _virDomainBlockStats *stats)
+{
+ int minor, device;
+
+ if (strlen (path) != 4 ||
+ STRNEQLEN (path, "xvd", 3) ||
+ (minor = path[3] - 'a') < 0 ||
+ minor > 26) {
+ virXenErrorFunc (VIR_ERR_INVALID_ARG, __FUNCTION__,
+ "invalid path, should be xvda, xvdb, etc.", 0);
+ return -1;
+ }
+ device = 202 * 256 + minor;
+
+ stats->rd_req = read_bd_stat (device, dom->id, "rd");
+ stats->wr_req = read_bd_stat (device, dom->id, "wr");
+ stats->errs = read_bd_stat (device, dom->id, "oo");
+
+ if (stats->rd_req == -1 && stats->wr_req == -1 && stats->errs == -1) {
+ virXenErrorFunc (VIR_ERR_NO_SUPPORT, __FUNCTION__,
+ "Failed to read any block statistics", dom->id);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Paths have the form "virbr\d+" or "xenbr\d+". On Linux we open
+ * /proc/net/dev and look for the device called vif<domid>.<n>.
+ */
+int
+xenHypervisorDomainInterfaceStats (virDomainPtr dom,
+ const char *path,
+ struct _virDomainInterfaceStats *stats)
+{
+ int device;
+ FILE *fp;
+ char line[256];
+
+ if (sscanf (path, "virbr%d", &device) != 1 &&
+ sscanf (path, "xenbr%d", &device) != 1) {
+ virXenErrorFunc (VIR_ERR_INVALID_ARG, __FUNCTION__,
+ "invalid path, should be virbrN or xenbrN.", 0);
+ return -1;
+ }
+
+ fp = fopen ("/proc/net/dev", "r");
+ if (!fp) {
+ virXenErrorFunc (VIR_ERR_NO_SUPPORT, __FUNCTION__,
+ "/proc/net/dev", errno);
+ return -1;
+ }
+ while (fgets (line, sizeof line, fp)) {
+ int domid, port;
+ long long dummy;
+ long long rx_bytes;
+ long long rx_packets;
+ long long rx_errs;
+ long long rx_drop;
+ long long tx_bytes;
+ long long tx_packets;
+ long long tx_errs;
+ long long tx_drop;
+
+ if (sscanf (line, "vif%d.%d: %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld",
+ &domid, &port,
+ &rx_bytes, &rx_packets, &rx_errs, &rx_drop,
+ &dummy, &dummy, &dummy, &dummy,
+ &tx_bytes, &tx_packets, &tx_errs, &tx_drop,
+ &dummy, &dummy, &dummy, &dummy) != 18)
+ continue;
+
+ if (domid == dom->id && port == device) {
+ stats->rx_bytes = rx_bytes;
+ stats->rx_packets = rx_packets;
+ stats->rx_errs = rx_errs;
+ stats->rx_drop = rx_drop;
+ stats->tx_bytes = tx_bytes;
+ stats->tx_packets = tx_packets;
+ stats->tx_errs = tx_errs;
+ stats->tx_drop = tx_drop;
+ fclose (fp);
+ return 0;
+ }
+ }
+ fclose (fp);
+
+ virXenErrorFunc (VIR_ERR_NO_SUPPORT, __FUNCTION__,
+ "/proc/net/dev: Interface not found", 0);
+ return -1;
+}
+
/**
* virXen_pausedomain:
* @handle: the hypervisor handle
Index: src/xen_internal.h
===================================================================
RCS file: /data/cvs/libvirt/src/xen_internal.h,v
retrieving revision 1.21
diff -u -p -r1.21 xen_internal.h
--- src/xen_internal.h 6 Jul 2007 15:11:22 -0000 1.21
+++ src/xen_internal.h 10 Aug 2007 14:30:30 -0000
@@ -77,6 +77,13 @@ int xenHypervisorSetSchedulerParameters
virSchedParameterPtr params,
int nparams);
+int xenHypervisorDomainBlockStats (virDomainPtr domain,
+ const char *path,
+ struct _virDomainBlockStats *stats);
+int xenHypervisorDomainInterfaceStats (virDomainPtr domain,
+ const char *path,
+ struct _virDomainInterfaceStats *stats);
+
#ifdef __cplusplus
}
#endif
Index: src/xen_unified.c
===================================================================
RCS file: /data/cvs/libvirt/src/xen_unified.c,v
retrieving revision 1.17
diff -u -p -r1.17 xen_unified.c
--- src/xen_unified.c 12 Jul 2007 08:34:51 -0000 1.17
+++ src/xen_unified.c 10 Aug 2007 14:30:31 -0000
@@ -948,6 +948,32 @@ xenUnifiedDomainSetSchedulerParameters (
return(-1);
}
+static int
+xenUnifiedDomainBlockStats (virDomainPtr dom, const char *path,
+ struct _virDomainBlockStats *stats)
+{
+ GET_PRIVATE (dom->conn);
+
+ if (priv->opened[XEN_UNIFIED_HYPERVISOR_OFFSET])
+ return xenHypervisorDomainBlockStats (dom, path, stats);
+
+ xenUnifiedError (dom->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+static int
+xenUnifiedDomainInterfaceStats (virDomainPtr dom, const char *path,
+ struct _virDomainInterfaceStats *stats)
+{
+ GET_PRIVATE (dom->conn);
+
+ if (priv->opened[XEN_UNIFIED_HYPERVISOR_OFFSET])
+ return xenHypervisorDomainInterfaceStats (dom, path, stats);
+
+ xenUnifiedError (dom->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
/*----- Register with libvirt.c, and initialise Xen drivers. -----*/
#define VERSION ((DOM0_INTERFACE_VERSION >> 24) * 1000000 + \
@@ -1002,6 +1028,8 @@ static virDriver xenUnifiedDriver = {
.domainGetSchedulerType = xenUnifiedDomainGetSchedulerType,
.domainGetSchedulerParameters = xenUnifiedDomainGetSchedulerParameters,
.domainSetSchedulerParameters = xenUnifiedDomainSetSchedulerParameters,
+ .domainBlockStats = xenUnifiedDomainBlockStats,
+ .domainInterfaceStats = xenUnifiedDomainInterfaceStats,
};
/**
smime.p7s
Description: S/MIME Cryptographic Signature
-- Libvir-list mailing list [email protected] https://www.redhat.com/mailman/listinfo/libvir-list
