提交 d2e5538b 编写于 作者: J Joao Martins 提交者: Jim Fehlig

libxl: implement virDomainInterfaceStats

Introduce support for domainInterfaceStats API call for querying
network interface statistics. Consequently it also enables the
use of `virsh domifstat <dom> <interface name>` command plus
seeing the interfaces names instead of "-" when doing
`virsh domiflist <dom>`.

After successful guest creation we fill the network
interfaces names based on domain, device id and append suffix
if it's emulated in the following form: vif<domid>.<devid>[-emu].
We extract the network interfaces info from the libxl_domain_config
object in libxlDomainCreateIfaceNames() to generate ifname. On domain
cleanup we also clear ifname, in case it was set by libvirt (i.e.
being prefixed with "vif"). We also skip these two steps in case the name
of the interface was manually inserted by the adminstrator.

For getting the interface statistics we resort to virNetInterfaceStats
and let libvirt handle the platform specific nits. Note that the latter
is not yet supported in FreeBSD.
Signed-off-by: NJoao Martins <joao.m.martins@oracle.com>
上级 af2954ae
...@@ -728,6 +728,17 @@ libxlDomainCleanup(libxlDriverPrivatePtr driver, ...@@ -728,6 +728,17 @@ libxlDomainCleanup(libxlDriverPrivatePtr driver,
} }
} }
if ((vm->def->nnets)) {
size_t i;
for (i = 0; i < vm->def->nnets; i++) {
virDomainNetDefPtr net = vm->def->nets[i];
if (STRPREFIX(net->ifname, "vif"))
VIR_FREE(net->ifname);
}
}
if (virAsprintf(&file, "%s/%s.xml", cfg->stateDir, vm->def->name) > 0) { if (virAsprintf(&file, "%s/%s.xml", cfg->stateDir, vm->def->name) > 0) {
if (unlink(file) < 0 && errno != ENOENT && errno != ENOTDIR) if (unlink(file) < 0 && errno != ENOENT && errno != ENOTDIR)
VIR_DEBUG("Failed to remove domain XML for %s", vm->def->name); VIR_DEBUG("Failed to remove domain XML for %s", vm->def->name);
...@@ -887,6 +898,31 @@ libxlConsoleCallback(libxl_ctx *ctx, libxl_event *ev, void *for_callback) ...@@ -887,6 +898,31 @@ libxlConsoleCallback(libxl_ctx *ctx, libxl_event *ev, void *for_callback)
libxl_event_free(ctx, ev); libxl_event_free(ctx, ev);
} }
/*
* Create interface names for the network devices in parameter def.
* Names are created with the pattern 'vif<domid>.<devid><suffix>'.
* devid is extracted from the network devices in the d_config
* parameter. User-provided interface names are skipped.
*/
static void
libxlDomainCreateIfaceNames(virDomainDefPtr def, libxl_domain_config *d_config)
{
size_t i;
for (i = 0; i < def->nnets && i < d_config->num_nics; i++) {
virDomainNetDefPtr net = def->nets[i];
libxl_device_nic *x_nic = &d_config->nics[i];
const char *suffix =
x_nic->nictype != LIBXL_NIC_TYPE_VIF ? "-emu" : "";
if (net->ifname)
continue;
ignore_value(virAsprintf(&net->ifname, "vif%d.%d%s",
def->id, x_nic->devid, suffix));
}
}
/* /*
* Start a domain through libxenlight. * Start a domain through libxenlight.
...@@ -1027,6 +1063,7 @@ libxlDomainStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm, ...@@ -1027,6 +1063,7 @@ libxlDomainStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
if (libxl_evenable_domain_death(cfg->ctx, vm->def->id, 0, &priv->deathW)) if (libxl_evenable_domain_death(cfg->ctx, vm->def->id, 0, &priv->deathW))
goto cleanup_dom; goto cleanup_dom;
libxlDomainCreateIfaceNames(vm->def, &d_config);
if ((dom_xml = virDomainDefFormat(vm->def, 0)) == NULL) if ((dom_xml = virDomainDefFormat(vm->def, 0)) == NULL)
goto cleanup_dom; goto cleanup_dom;
......
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
#include "virhostdev.h" #include "virhostdev.h"
#include "network/bridge_driver.h" #include "network/bridge_driver.h"
#include "locking/domain_lock.h" #include "locking/domain_lock.h"
#include "virstats.h"
#define VIR_FROM_THIS VIR_FROM_LIBXL #define VIR_FROM_THIS VIR_FROM_LIBXL
...@@ -4642,6 +4643,56 @@ libxlDomainIsUpdated(virDomainPtr dom) ...@@ -4642,6 +4643,56 @@ libxlDomainIsUpdated(virDomainPtr dom)
return ret; return ret;
} }
static int
libxlDomainInterfaceStats(virDomainPtr dom,
const char *path,
virDomainInterfaceStatsPtr stats)
{
libxlDriverPrivatePtr driver = dom->conn->privateData;
virDomainObjPtr vm;
ssize_t i;
int ret = -1;
if (!(vm = libxlDomObjFromDomain(dom)))
goto cleanup;
if (virDomainInterfaceStatsEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_QUERY) < 0)
goto cleanup;
if (!virDomainObjIsActive(vm)) {
virReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("domain is not running"));
goto endjob;
}
/* Check the path is one of the domain's network interfaces. */
for (i = 0; i < vm->def->nnets; i++) {
if (vm->def->nets[i]->ifname &&
STREQ(vm->def->nets[i]->ifname, path)) {
ret = 0;
break;
}
}
if (ret == 0)
ret = virNetInterfaceStats(path, stats);
else
virReportError(VIR_ERR_INVALID_ARG,
_("'%s' is not a known interface"), path);
endjob:
if (!libxlDomainObjEndJob(driver, vm))
vm = NULL;
cleanup:
if (vm)
virObjectUnlock(vm);
return ret;
}
static int static int
libxlDomainGetTotalCPUStats(libxlDriverPrivatePtr driver, libxlDomainGetTotalCPUStats(libxlDriverPrivatePtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
...@@ -5423,6 +5474,7 @@ static virHypervisorDriver libxlHypervisorDriver = { ...@@ -5423,6 +5474,7 @@ static virHypervisorDriver libxlHypervisorDriver = {
.nodeGetCellsFreeMemory = libxlNodeGetCellsFreeMemory, /* 1.1.1 */ .nodeGetCellsFreeMemory = libxlNodeGetCellsFreeMemory, /* 1.1.1 */
.domainMemoryStats = libxlDomainMemoryStats, /* 1.3.0 */ .domainMemoryStats = libxlDomainMemoryStats, /* 1.3.0 */
.domainGetCPUStats = libxlDomainGetCPUStats, /* 1.3.0 */ .domainGetCPUStats = libxlDomainGetCPUStats, /* 1.3.0 */
.domainInterfaceStats = libxlDomainInterfaceStats, /* 1.3.0 */
.connectDomainEventRegister = libxlConnectDomainEventRegister, /* 0.9.0 */ .connectDomainEventRegister = libxlConnectDomainEventRegister, /* 0.9.0 */
.connectDomainEventDeregister = libxlConnectDomainEventDeregister, /* 0.9.0 */ .connectDomainEventDeregister = libxlConnectDomainEventDeregister, /* 0.9.0 */
.domainManagedSave = libxlDomainManagedSave, /* 0.9.2 */ .domainManagedSave = libxlDomainManagedSave, /* 0.9.2 */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册