[libvirt] [PATCH] event: move event filtering to daemon (regression fix)
by Eric Blake
Commit f9f56340 for CVE-2014-0028 almost had the right idea - we
need to check the ACL rules to filter which events to send. But
it overlooked one thing: the event dispatch queue is running in
the main loop thread, and therefore does not normally have a
current virIdentityPtr. But filter checks can be based on current
identity, so when libvirtd.conf contains access_drivers=["polkit"],
we ended up rejecting access for EVERY event due to failure to
look up the current identity, even if it should have been allowed.
Furthermore, even for events that are triggered by API calls, it
is important to remember that the point of events is that they can
be copied across multiple connections, which may have separate
identities and permissions. So even if events were dispatched
from a context where we have an identity, we must change to the
correct identity of the connection that will be receiving the
event, rather than basing a decision on the context that triggered
the event, when deciding whether to filter an event to a
particular connection.
If there were an easy way to get from virConnectPtr to the
appropriate virIdentityPtr, then object_event.c could adjust the
identity prior to checking whether to dispatch an event. But
setting up that back-reference is a bit invasive. Instead, it
is easier to delay the filtering check until lower down the
stack, at the point where we have direct access to the RPC
client object that owns an identity. As such, this patch ends
up reverting a large portion of the framework of commit f9f56340.
We also have to teach 'make check' to special-case the fact that
the event registration filtering is done at the point of dispatch,
rather than the point of registration. Note that even though we
don't actually use virConnectDomainEventRegisterCheckACL (because
the RegisterAny variant is sufficient), we still generate the
function for the purposes of documenting that the filtering
takes place.
Also note that I did not entirely delete the notion of a filter
from object_event.c; I still plan on using that for my upcoming
patch series for qemu monitor events in libvirt-qemu.so. In
other words, while this patch changes ACL filtering to live in
remote.c and therefore we have no current client of the filtering
in object_event.c, the notion of filtering in object_event.c is
still useful down the road.
* src/check-aclrules.pl: Exempt event registration from having to
pass checkACL filter down call stack.
* daemon/remote.c (remoteRelayDomainEventCheckACL)
(remoteRelayNetworkEventCheckACL): New functions.
(remoteRelay*Event*): Use new functions.
* src/conf/domain_event.h (virDomainEventStateRegister)
(virDomainEventStateRegisterID): Drop unused parameter.
* src/conf/network_event.h (virNetworkEventStateRegisterID):
Likewise.
* src/conf/domain_event.c (virDomainEventFilter): Delete unused
function.
* src/conf/network_event.c (virNetworkEventFilter): Likewise.
* src/libxl/libxl_driver.c: Adjust caller.
* src/lxc/lxc_driver.c: Likewise.
* src/network/bridge_driver.c: Likewise.
* src/qemu/qemu_driver.c: Likewise.
* src/remote/remote_driver.c: Likewise.
* src/test/test_driver.c: Likewise.
* src/uml/uml_driver.c: Likewise.
* src/vbox/vbox_tmpl.c: Likewise.
* src/xen/xen_driver.c: Likewise.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
daemon/remote.c | 257 ++++++++++++++++++++++++++++----------------
src/check-aclrules.pl | 7 +-
src/conf/domain_event.c | 35 +-----
src/conf/domain_event.h | 8 +-
src/conf/network_event.c | 31 +-----
src/conf/network_event.h | 6 +-
src/libxl/libxl_driver.c | 2 -
src/lxc/lxc_driver.c | 2 -
src/network/bridge_driver.c | 1 -
src/qemu/qemu_driver.c | 2 -
src/remote/remote_driver.c | 4 +-
src/test/test_driver.c | 6 +-
src/uml/uml_driver.c | 2 -
src/vbox/vbox_tmpl.c | 4 +-
src/xen/xen_driver.c | 2 -
15 files changed, 188 insertions(+), 181 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index d2aafbe..5baf0b6 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -50,6 +50,9 @@
#include "lxc_protocol.h"
#include "virstring.h"
#include "object_event.h"
+#include "domain_conf.h"
+#include "network_conf.h"
+#include "viraccessapicheck.h"
#define VIR_FROM_THIS VIR_FROM_RPC
@@ -127,16 +130,72 @@ remoteEventCallbackFree(void *opaque)
VIR_FREE(opaque);
}
-static int remoteRelayDomainEventLifecycle(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int event,
- int detail,
- void *opaque)
+
+static bool
+remoteRelayDomainEventCheckACL(virNetServerClientPtr client,
+ virConnectPtr conn, virDomainPtr dom)
+{
+ virDomainDef def;
+ virIdentityPtr identity = NULL;
+ bool ret = false;
+
+ /* For now, we just create a virDomainDef with enough contents to
+ * satisfy what viraccessdriverpolkit.c references. This is a bit
+ * fragile, but I don't know of anything better. */
+ def.name = dom->name;
+ memcpy(def.uuid, dom->uuid, VIR_UUID_BUFLEN);
+
+ if (!(identity = virNetServerClientGetIdentity(client)))
+ goto cleanup;
+ if (virIdentitySetCurrent(identity) < 0)
+ goto cleanup;
+ ret = virConnectDomainEventRegisterAnyCheckACL(conn, &def);
+
+cleanup:
+ ignore_value(virIdentitySetCurrent(NULL));
+ virObjectUnref(identity);
+ return ret;
+}
+
+
+static bool
+remoteRelayNetworkEventCheckACL(virNetServerClientPtr client,
+ virConnectPtr conn, virNetworkPtr net)
+{
+ virNetworkDef def;
+ virIdentityPtr identity = NULL;
+ bool ret = false;
+
+ /* For now, we just create a virNetworkDef with enough contents to
+ * satisfy what viraccessdriverpolkit.c references. This is a bit
+ * fragile, but I don't know of anything better. */
+ def.name = net->name;
+ memcpy(def.uuid, net->uuid, VIR_UUID_BUFLEN);
+
+ if (!(identity = virNetServerClientGetIdentity(client)))
+ goto cleanup;
+ if (virIdentitySetCurrent(identity) < 0)
+ goto cleanup;
+ ret = virConnectNetworkEventRegisterAnyCheckACL(conn, &def);
+
+cleanup:
+ ignore_value(virIdentitySetCurrent(NULL));
+ virObjectUnref(identity);
+ return ret;
+}
+
+
+static int
+remoteRelayDomainEventLifecycle(virConnectPtr conn,
+ virDomainPtr dom,
+ int event,
+ int detail,
+ void *opaque)
{
virNetServerClientPtr client = opaque;
remote_domain_event_lifecycle_msg data;
- if (!client)
+ if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain lifecycle event %d %d", event, detail);
@@ -154,14 +213,15 @@ static int remoteRelayDomainEventLifecycle(virConnectPtr conn ATTRIBUTE_UNUSED,
return 0;
}
-static int remoteRelayDomainEventReboot(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- void *opaque)
+static int
+remoteRelayDomainEventReboot(virConnectPtr conn,
+ virDomainPtr dom,
+ void *opaque)
{
virNetServerClientPtr client = opaque;
remote_domain_event_reboot_msg data;
- if (!client)
+ if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain reboot event %s %d", dom->name, dom->id);
@@ -178,15 +238,16 @@ static int remoteRelayDomainEventReboot(virConnectPtr conn ATTRIBUTE_UNUSED,
}
-static int remoteRelayDomainEventRTCChange(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- long long offset,
- void *opaque)
+static int
+remoteRelayDomainEventRTCChange(virConnectPtr conn,
+ virDomainPtr dom,
+ long long offset,
+ void *opaque)
{
virNetServerClientPtr client = opaque;
remote_domain_event_rtc_change_msg data;
- if (!client)
+ if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain rtc change event %s %d %lld", dom->name, dom->id, offset);
@@ -204,15 +265,16 @@ static int remoteRelayDomainEventRTCChange(virConnectPtr conn ATTRIBUTE_UNUSED,
}
-static int remoteRelayDomainEventWatchdog(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int action,
- void *opaque)
+static int
+remoteRelayDomainEventWatchdog(virConnectPtr conn,
+ virDomainPtr dom,
+ int action,
+ void *opaque)
{
virNetServerClientPtr client = opaque;
remote_domain_event_watchdog_msg data;
- if (!client)
+ if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain watchdog event %s %d %d", dom->name, dom->id, action);
@@ -230,17 +292,18 @@ static int remoteRelayDomainEventWatchdog(virConnectPtr conn ATTRIBUTE_UNUSED,
}
-static int remoteRelayDomainEventIOError(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *srcPath,
- const char *devAlias,
- int action,
- void *opaque)
+static int
+remoteRelayDomainEventIOError(virConnectPtr conn,
+ virDomainPtr dom,
+ const char *srcPath,
+ const char *devAlias,
+ int action,
+ void *opaque)
{
virNetServerClientPtr client = opaque;
remote_domain_event_io_error_msg data;
- if (!client)
+ if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain io error %s %d %s %s %d", dom->name, dom->id, srcPath, devAlias, action);
@@ -265,18 +328,19 @@ error:
}
-static int remoteRelayDomainEventIOErrorReason(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *srcPath,
- const char *devAlias,
- int action,
- const char *reason,
- void *opaque)
+static int
+remoteRelayDomainEventIOErrorReason(virConnectPtr conn,
+ virDomainPtr dom,
+ const char *srcPath,
+ const char *devAlias,
+ int action,
+ const char *reason,
+ void *opaque)
{
virNetServerClientPtr client = opaque;
remote_domain_event_io_error_reason_msg data;
- if (!client)
+ if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain io error %s %d %s %s %d %s",
@@ -306,20 +370,21 @@ error:
}
-static int remoteRelayDomainEventGraphics(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int phase,
- virDomainEventGraphicsAddressPtr local,
- virDomainEventGraphicsAddressPtr remote,
- const char *authScheme,
- virDomainEventGraphicsSubjectPtr subject,
- void *opaque)
+static int
+remoteRelayDomainEventGraphics(virConnectPtr conn,
+ virDomainPtr dom,
+ int phase,
+ virDomainEventGraphicsAddressPtr local,
+ virDomainEventGraphicsAddressPtr remote,
+ const char *authScheme,
+ virDomainEventGraphicsSubjectPtr subject,
+ void *opaque)
{
virNetServerClientPtr client = opaque;
remote_domain_event_graphics_msg data;
size_t i;
- if (!client)
+ if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain graphics event %s %d %d - %d %s %s - %d %s %s - %s", dom->name, dom->id, phase,
@@ -377,17 +442,18 @@ error:
return -1;
}
-static int remoteRelayDomainEventBlockJob(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *path,
- int type,
- int status,
- void *opaque)
+static int
+remoteRelayDomainEventBlockJob(virConnectPtr conn,
+ virDomainPtr dom,
+ const char *path,
+ int type,
+ int status,
+ void *opaque)
{
virNetServerClientPtr client = opaque;
remote_domain_event_block_job_msg data;
- if (!client)
+ if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain block job event %s %d %s %i, %i",
@@ -412,14 +478,15 @@ error:
}
-static int remoteRelayDomainEventControlError(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- void *opaque)
+static int
+remoteRelayDomainEventControlError(virConnectPtr conn,
+ virDomainPtr dom,
+ void *opaque)
{
virNetServerClientPtr client = opaque;
remote_domain_event_control_error_msg data;
- if (!client)
+ if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain control error %s %d", dom->name, dom->id);
@@ -436,19 +503,20 @@ static int remoteRelayDomainEventControlError(virConnectPtr conn ATTRIBUTE_UNUSE
}
-static int remoteRelayDomainEventDiskChange(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *oldSrcPath,
- const char *newSrcPath,
- const char *devAlias,
- int reason,
- void *opaque)
+static int
+remoteRelayDomainEventDiskChange(virConnectPtr conn,
+ virDomainPtr dom,
+ const char *oldSrcPath,
+ const char *newSrcPath,
+ const char *devAlias,
+ int reason,
+ void *opaque)
{
virNetServerClientPtr client = opaque;
remote_domain_event_disk_change_msg data;
char **oldSrcPath_p = NULL, **newSrcPath_p = NULL;
- if (!client)
+ if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain %s %d disk change %s %s %s %d",
@@ -487,15 +555,17 @@ error:
}
-static int remoteRelayDomainEventTrayChange(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *devAlias,
- int reason,
- void *opaque) {
+static int
+remoteRelayDomainEventTrayChange(virConnectPtr conn,
+ virDomainPtr dom,
+ const char *devAlias,
+ int reason,
+ void *opaque)
+{
virNetServerClientPtr client = opaque;
remote_domain_event_tray_change_msg data;
- if (!client)
+ if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain %s %d tray change devAlias: %s reason: %d",
@@ -517,14 +587,16 @@ static int remoteRelayDomainEventTrayChange(virConnectPtr conn ATTRIBUTE_UNUSED,
return 0;
}
-static int remoteRelayDomainEventPMWakeup(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int reason ATTRIBUTE_UNUSED,
- void *opaque) {
+static int
+remoteRelayDomainEventPMWakeup(virConnectPtr conn,
+ virDomainPtr dom,
+ int reason ATTRIBUTE_UNUSED,
+ void *opaque)
+{
virNetServerClientPtr client = opaque;
remote_domain_event_pmwakeup_msg data;
- if (!client)
+ if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain %s %d system pmwakeup", dom->name, dom->id);
@@ -540,14 +612,16 @@ static int remoteRelayDomainEventPMWakeup(virConnectPtr conn ATTRIBUTE_UNUSED,
return 0;
}
-static int remoteRelayDomainEventPMSuspend(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int reason ATTRIBUTE_UNUSED,
- void *opaque) {
+static int
+remoteRelayDomainEventPMSuspend(virConnectPtr conn,
+ virDomainPtr dom,
+ int reason ATTRIBUTE_UNUSED,
+ void *opaque)
+{
virNetServerClientPtr client = opaque;
remote_domain_event_pmsuspend_msg data;
- if (!client)
+ if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain %s %d system pmsuspend", dom->name, dom->id);
@@ -564,7 +638,7 @@ static int remoteRelayDomainEventPMSuspend(virConnectPtr conn ATTRIBUTE_UNUSED,
}
static int
-remoteRelayDomainEventBalloonChange(virConnectPtr conn ATTRIBUTE_UNUSED,
+remoteRelayDomainEventBalloonChange(virConnectPtr conn,
virDomainPtr dom,
unsigned long long actual,
void *opaque)
@@ -572,7 +646,7 @@ remoteRelayDomainEventBalloonChange(virConnectPtr conn ATTRIBUTE_UNUSED,
virNetServerClientPtr client = opaque;
remote_domain_event_balloon_change_msg data;
- if (!client)
+ if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain balloon change event %s %d %lld", dom->name, dom->id, actual);
@@ -590,14 +664,16 @@ remoteRelayDomainEventBalloonChange(virConnectPtr conn ATTRIBUTE_UNUSED,
}
-static int remoteRelayDomainEventPMSuspendDisk(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int reason ATTRIBUTE_UNUSED,
- void *opaque) {
+static int
+remoteRelayDomainEventPMSuspendDisk(virConnectPtr conn,
+ virDomainPtr dom,
+ int reason ATTRIBUTE_UNUSED,
+ void *opaque)
+{
virNetServerClientPtr client = opaque;
remote_domain_event_pmsuspend_disk_msg data;
- if (!client)
+ if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain %s %d system pmsuspend-disk", dom->name, dom->id);
@@ -614,7 +690,7 @@ static int remoteRelayDomainEventPMSuspendDisk(virConnectPtr conn ATTRIBUTE_UNUS
}
static int
-remoteRelayDomainEventDeviceRemoved(virConnectPtr conn ATTRIBUTE_UNUSED,
+remoteRelayDomainEventDeviceRemoved(virConnectPtr conn,
virDomainPtr dom,
const char *devAlias,
void *opaque)
@@ -622,7 +698,7 @@ remoteRelayDomainEventDeviceRemoved(virConnectPtr conn ATTRIBUTE_UNUSED,
virNetServerClientPtr client = opaque;
remote_domain_event_device_removed_msg data;
- if (!client)
+ if (!client || !remoteRelayDomainEventCheckACL(client, conn, dom))
return -1;
VIR_DEBUG("Relaying domain device removed event %s %d %s",
@@ -667,7 +743,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
static int
-remoteRelayNetworkEventLifecycle(virConnectPtr conn ATTRIBUTE_UNUSED,
+remoteRelayNetworkEventLifecycle(virConnectPtr conn,
virNetworkPtr net,
int event,
int detail,
@@ -676,7 +752,8 @@ remoteRelayNetworkEventLifecycle(virConnectPtr conn ATTRIBUTE_UNUSED,
daemonClientEventCallbackPtr callback = opaque;
remote_network_event_lifecycle_msg data;
- if (callback->callbackID < 0)
+ if (callback->callbackID < 0 ||
+ !remoteRelayNetworkEventCheckACL(callback->client, conn, net))
return -1;
VIR_DEBUG("Relaying network lifecycle event %d, detail %d, callback %d",
diff --git a/src/check-aclrules.pl b/src/check-aclrules.pl
index 057517e..f54b934 100755
--- a/src/check-aclrules.pl
+++ b/src/check-aclrules.pl
@@ -1,6 +1,6 @@
#!/usr/bin/perl
#
-# Copyright (C) 2013 Red Hat, Inc.
+# Copyright (C) 2013-2014 Red Hat, Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -140,7 +140,10 @@ while (<PROTO>) {
} elsif ($filtered &&
m,REMOTE_PROC_(.*)\s+=\s*\d+,) {
my $api = name_to_ProcName($1);
- $filtered{$api} = 1;
+ # Event filtering is handled in daemon/remote.c instead of drivers
+ if (! m,_EVENT_REGISTER,) {
+ $filtered{$api} = 1;
+ }
$incomment = 0;
}
}
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
index f56aed3..8639a01 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -360,30 +360,6 @@ virDomainEventDeviceRemovedDispose(void *obj)
}
-/**
- * virDomainEventFilter:
- * @conn: pointer to the connection
- * @event: the event to check
- * @opaque: opaque data holding ACL filter to use
- *
- * Internal function to run ACL filtering before dispatching an event
- */
-static bool
-virDomainEventFilter(virConnectPtr conn, virObjectEventPtr event, void *opaque)
-{
- virDomainDef dom;
- virDomainObjListFilter filter = opaque;
-
- /* For now, we just create a virDomainDef with enough contents to
- * satisfy what viraccessdriverpolkit.c references. This is a bit
- * fragile, but I don't know of anything better. */
- dom.name = event->meta.name;
- memcpy(dom.uuid, event->meta.uuid, VIR_UUID_BUFLEN);
-
- return (filter)(conn, &dom);
-}
-
-
static void *
virDomainEventNew(virClassPtr klass,
int eventID,
@@ -1289,7 +1265,6 @@ cleanup:
* virDomainEventStateRegister:
* @conn: connection to associate with callback
* @state: object event state
- * @filter: optional ACL filter to limit which events can be sent
* @callback: the callback to add
* @opaque: data blob to pass to @callback
* @freecb: callback to free @opaque
@@ -1302,7 +1277,6 @@ cleanup:
int
virDomainEventStateRegister(virConnectPtr conn,
virObjectEventStatePtr state,
- virDomainObjListFilter filter,
virConnectDomainEventCallback callback,
void *opaque,
virFreeCallback freecb)
@@ -1311,8 +1285,7 @@ virDomainEventStateRegister(virConnectPtr conn,
return -1;
return virObjectEventStateRegisterID(conn, state, NULL,
- filter ? virDomainEventFilter : NULL,
- filter, virDomainEventClass,
+ NULL, NULL, virDomainEventClass,
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
VIR_OBJECT_EVENT_CALLBACK(callback),
opaque, freecb, NULL, false);
@@ -1323,7 +1296,6 @@ virDomainEventStateRegister(virConnectPtr conn,
* virDomainEventStateRegisterID:
* @conn: connection to associate with callback
* @state: object event state
- * @filter: optional ACL filter to limit which events can be sent
* @dom: optional domain for filtering the event
* @eventID: ID of the event type to register for
* @cb: function to invoke when event fires
@@ -1340,7 +1312,6 @@ virDomainEventStateRegister(virConnectPtr conn,
int
virDomainEventStateRegisterID(virConnectPtr conn,
virObjectEventStatePtr state,
- virDomainObjListFilter filter,
virDomainPtr dom,
int eventID,
virConnectDomainEventGenericCallback cb,
@@ -1352,8 +1323,8 @@ virDomainEventStateRegisterID(virConnectPtr conn,
return -1;
return virObjectEventStateRegisterID(conn, state, dom ? dom->uuid : NULL,
- filter ? virDomainEventFilter : NULL,
- filter, virDomainEventClass, eventID,
+ NULL, NULL,
+ virDomainEventClass, eventID,
VIR_OBJECT_EVENT_CALLBACK(cb),
opaque, freecb, callbackID, false);
}
diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
index b39d5cd..b033b23 100644
--- a/src/conf/domain_event.h
+++ b/src/conf/domain_event.h
@@ -177,24 +177,20 @@ virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
int
virDomainEventStateRegister(virConnectPtr conn,
virObjectEventStatePtr state,
- virDomainObjListFilter filter,
virConnectDomainEventCallback callback,
void *opaque,
virFreeCallback freecb)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4);
-
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
int
virDomainEventStateRegisterID(virConnectPtr conn,
virObjectEventStatePtr state,
- virDomainObjListFilter filter,
virDomainPtr dom,
int eventID,
virConnectDomainEventGenericCallback cb,
void *opaque,
virFreeCallback freecb,
int *callbackID)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(6);
-
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5);
int
virDomainEventStateDeregister(virConnectPtr conn,
virObjectEventStatePtr state,
diff --git a/src/conf/network_event.c b/src/conf/network_event.c
index f27b7e9..4c59356 100644
--- a/src/conf/network_event.c
+++ b/src/conf/network_event.c
@@ -122,35 +122,9 @@ cleanup:
/**
- * virNetworkEventFilter:
- * @conn: pointer to the connection
- * @event: the event to check
- * @opaque: opaque data holding ACL filter to use
- *
- * Internal function to run ACL filtering before dispatching an event
- */
-static bool
-virNetworkEventFilter(virConnectPtr conn, virObjectEventPtr event,
- void *opaque)
-{
- virNetworkDef net;
- virNetworkObjListFilter filter = opaque;
-
- /* For now, we just create a virNetworkDef with enough contents to
- * satisfy what viraccessdriverpolkit.c references. This is a bit
- * fragile, but I don't know of anything better. */
- net.name = event->meta.name;
- memcpy(net.uuid, event->meta.uuid, VIR_UUID_BUFLEN);
-
- return (filter)(conn, &net);
-}
-
-
-/**
* virNetworkEventStateRegisterID:
* @conn: connection to associate with callback
* @state: object event state
- * @filter: optional ACL filter to limit which events can be sent
* @net: network to filter on or NULL for all networks
* @eventID: ID of the event type to register for
* @cb: function to invoke when event occurs
@@ -167,7 +141,6 @@ virNetworkEventFilter(virConnectPtr conn, virObjectEventPtr event,
int
virNetworkEventStateRegisterID(virConnectPtr conn,
virObjectEventStatePtr state,
- virNetworkObjListFilter filter,
virNetworkPtr net,
int eventID,
virConnectNetworkEventGenericCallback cb,
@@ -179,8 +152,8 @@ virNetworkEventStateRegisterID(virConnectPtr conn,
return -1;
return virObjectEventStateRegisterID(conn, state, net ? net->uuid : NULL,
- filter ? virNetworkEventFilter : NULL,
- filter, virNetworkEventClass, eventID,
+ NULL, NULL,
+ virNetworkEventClass, eventID,
VIR_OBJECT_EVENT_CALLBACK(cb),
opaque, freecb, callbackID, false);
}
diff --git a/src/conf/network_event.h b/src/conf/network_event.h
index 0812752..51bd949 100644
--- a/src/conf/network_event.h
+++ b/src/conf/network_event.h
@@ -24,7 +24,6 @@
#include "internal.h"
#include "object_event.h"
#include "object_event_private.h"
-#include "network_conf.h"
#ifndef __NETWORK_EVENT_H__
# define __NETWORK_EVENT_H__
@@ -32,15 +31,14 @@
int
virNetworkEventStateRegisterID(virConnectPtr conn,
virObjectEventStatePtr state,
- virNetworkObjListFilter filter,
virNetworkPtr net,
int eventID,
virConnectNetworkEventGenericCallback cb,
void *opaque,
virFreeCallback freecb,
int *callbackID)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(6)
- ATTRIBUTE_NONNULL(9);
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(5)
+ ATTRIBUTE_NONNULL(8);
int
virNetworkEventStateRegisterClient(virConnectPtr conn,
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index fc0efa2..ad6231f 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -3654,7 +3654,6 @@ libxlConnectDomainEventRegister(virConnectPtr conn,
if (virDomainEventStateRegister(conn,
driver->domainEventState,
- virConnectDomainEventRegisterCheckACL,
callback, opaque, freecb) < 0)
return -1;
@@ -4260,7 +4259,6 @@ libxlConnectDomainEventRegisterAny(virConnectPtr conn, virDomainPtr dom, int eve
if (virDomainEventStateRegisterID(conn,
driver->domainEventState,
- virConnectDomainEventRegisterAnyCheckACL,
dom, eventID, callback, opaque,
freecb, &ret) < 0)
ret = -1;
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 982f3fc..46c16bc 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -1293,7 +1293,6 @@ lxcConnectDomainEventRegister(virConnectPtr conn,
if (virDomainEventStateRegister(conn,
driver->domainEventState,
- virConnectDomainEventRegisterCheckACL,
callback, opaque, freecb) < 0)
return -1;
@@ -1335,7 +1334,6 @@ lxcConnectDomainEventRegisterAny(virConnectPtr conn,
if (virDomainEventStateRegisterID(conn,
driver->domainEventState,
- virConnectDomainEventRegisterAnyCheckACL,
dom, eventID,
callback, opaque, freecb, &ret) < 0)
ret = -1;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 6bdd1d6..45dff8a 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -2310,7 +2310,6 @@ networkConnectNetworkEventRegisterAny(virConnectPtr conn,
goto cleanup;
if (virNetworkEventStateRegisterID(conn, driver->networkEventState,
- virConnectNetworkEventRegisterAnyCheckACL,
net, eventID, callback,
opaque, freecb, &ret) < 0)
ret = -1;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index a555470..4f134e9 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10340,7 +10340,6 @@ qemuConnectDomainEventRegister(virConnectPtr conn,
if (virDomainEventStateRegister(conn,
driver->domainEventState,
- virConnectDomainEventRegisterCheckACL,
callback, opaque, freecb) < 0)
goto cleanup;
@@ -10389,7 +10388,6 @@ qemuConnectDomainEventRegisterAny(virConnectPtr conn,
if (virDomainEventStateRegisterID(conn,
driver->domainEventState,
- virConnectDomainEventRegisterAnyCheckACL,
dom, eventID,
callback, opaque, freecb, &ret) < 0)
ret = -1;
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index ca86e3c..18eb454 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -4427,7 +4427,7 @@ remoteConnectDomainEventRegister(virConnectPtr conn,
remoteDriverLock(priv);
- if ((count = virDomainEventStateRegister(conn, priv->eventState, NULL,
+ if ((count = virDomainEventStateRegister(conn, priv->eventState,
callback, opaque, freecb)) < 0)
goto done;
@@ -5245,7 +5245,7 @@ remoteConnectDomainEventRegisterAny(virConnectPtr conn,
remoteDriverLock(priv);
- if ((count = virDomainEventStateRegisterID(conn, priv->eventState, NULL,
+ if ((count = virDomainEventStateRegisterID(conn, priv->eventState,
dom, eventID,
callback, opaque, freecb,
&callbackID)) < 0)
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 4c277bd..b724f82 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -6145,7 +6145,7 @@ testConnectDomainEventRegister(virConnectPtr conn,
int ret = 0;
testDriverLock(driver);
- if (virDomainEventStateRegister(conn, driver->eventState, NULL,
+ if (virDomainEventStateRegister(conn, driver->eventState,
callback, opaque, freecb) < 0)
ret = -1;
testDriverUnlock(driver);
@@ -6183,7 +6183,7 @@ testConnectDomainEventRegisterAny(virConnectPtr conn,
int ret;
testDriverLock(driver);
- if (virDomainEventStateRegisterID(conn, driver->eventState, NULL,
+ if (virDomainEventStateRegisterID(conn, driver->eventState,
dom, eventID,
callback, opaque, freecb, &ret) < 0)
ret = -1;
@@ -6221,7 +6221,7 @@ testConnectNetworkEventRegisterAny(virConnectPtr conn,
int ret;
testDriverLock(driver);
- if (virNetworkEventStateRegisterID(conn, driver->eventState, NULL,
+ if (virNetworkEventStateRegisterID(conn, driver->eventState,
net, eventID, callback,
opaque, freecb, &ret) < 0)
ret = -1;
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index 89afefe..dbd5da9 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -2617,7 +2617,6 @@ umlConnectDomainEventRegister(virConnectPtr conn,
umlDriverLock(driver);
if (virDomainEventStateRegister(conn,
driver->domainEventState,
- virConnectDomainEventRegisterCheckACL,
callback, opaque, freecb) < 0)
ret = -1;
umlDriverUnlock(driver);
@@ -2662,7 +2661,6 @@ umlConnectDomainEventRegisterAny(virConnectPtr conn,
umlDriverLock(driver);
if (virDomainEventStateRegisterID(conn,
driver->domainEventState,
- virConnectDomainEventRegisterAnyCheckACL,
dom, eventID,
callback, opaque, freecb, &ret) < 0)
ret = -1;
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 1be4dc4..382d7b4 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -7332,7 +7332,7 @@ vboxConnectDomainEventRegister(virConnectPtr conn,
* later you can iterate over them
*/
- ret = virDomainEventStateRegister(conn, data->domainEvents, NULL,
+ ret = virDomainEventStateRegister(conn, data->domainEvents,
callback, opaque, freecb);
VIR_DEBUG("virObjectEventStateRegister (ret = %d) (conn: %p, "
"callback: %p, opaque: %p, "
@@ -7429,7 +7429,7 @@ static int vboxConnectDomainEventRegisterAny(virConnectPtr conn,
* later you can iterate over them
*/
- if (virDomainEventStateRegisterID(conn, data->domainEvents, NULL,
+ if (virDomainEventStateRegisterID(conn, data->domainEvents,
dom, eventID,
callback, opaque, freecb, &ret) < 0)
ret = -1;
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index c45d980..7506e8c 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -2323,7 +2323,6 @@ xenUnifiedConnectDomainEventRegister(virConnectPtr conn,
}
if (virDomainEventStateRegister(conn, priv->domainEvents,
- virConnectDomainEventRegisterCheckACL,
callback, opaque, freefunc) < 0)
ret = -1;
@@ -2383,7 +2382,6 @@ xenUnifiedConnectDomainEventRegisterAny(virConnectPtr conn,
}
if (virDomainEventStateRegisterID(conn, priv->domainEvents,
- virConnectDomainEventRegisterAnyCheckACL,
dom, eventID,
callback, opaque, freefunc, &ret) < 0)
ret = -1;
--
1.8.5.3
10 years, 10 months
[libvirt] [PATCH] conf: add localtime support in guest clock with variable attibute
by Jincheng Miao
commit b8bf79a, which add clock=variable, forgets to check localtime
basis in qemuBuildClockArgStr(). So that localtime basis could not
be used, like this bug:
https://bugzilla.redhat.com/show_bug.cgi?id=1046192
---
src/qemu/qemu_command.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index d723dc8..749ad54 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6490,15 +6490,21 @@ qemuBuildClockArgStr(virDomainClockDefPtr def)
time_t now = time(NULL);
struct tm nowbits;
- if (def->data.variable.basis != VIR_DOMAIN_CLOCK_BASIS_UTC) {
+ if (def->data.variable.basis == VIR_DOMAIN_CLOCK_BASIS_UTC) {
+ now += def->data.variable.adjustment;
+ gmtime_r(&now, &nowbits);
+ }
+ else if (def->data.variable.basis == VIR_DOMAIN_CLOCK_BASIS_LOCALTIME) {
+ now += def->data.variable.adjustment;
+ localtime_r(&now, &nowbits);
+ }
+ else {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported clock basis '%s'"),
virDomainClockBasisTypeToString(def->data.variable.basis));
goto error;
}
- now += def->data.variable.adjustment;
- gmtime_r(&now, &nowbits);
-
+
/* Store the guest's basedate */
def->data.variable.basedate = now;
--
1.8.3.1
10 years, 10 months
[libvirt] [PATCH] network: disallow <bandwidth>/<mac> for bridged/macvtap networks
by Laine Stump
https://bugzilla.redhat.com/show_bug.cgi?id=1057321 pointed out that
we weren't honoring the <bandwidth> element in libvirt networks using
<forward mode='bridge'/>. In fact, these networks are just a method of
giving a libvirt network name to an existing Linux host bridge on the
system, and even if it were technically possible for us to set
network-wide bandwidth limits for all the taps on a bridge, it's
probably not a polite thing to do since libvirt is just using a bridge
that was created by someone else for other purposes. So the proper
thing is to just log an error when someone tries to put a <bandwidth>
element in that type of network.
While looking through the network XML documentation and comparing it
to the networkValidate function, I noticed that we also ignore the
presence of a mac address in the config, even though we do nothing
with it in this case either.
This patch updates networkValidate() (which is called any time a
persistent network is defined, or a transient network created) to log
an error and fail if it finds either a <bandwidth> or <mac> element
and the network forward mode is anything except 'route'. 'nat', or
nothing. (Yes, neither of those elements is acceptable for any macvtap
mode, nor for a hostdev network).
NB: This does *not* cause failure to start any existing network that
contains one of those elements, so someone might have erroneously
defined such a network in the past, and that network will continue to
function unmodified. I considered it too disruptive to suddenly break
working configs on the next reboot after a libvirt upgrade.
---
src/network/bridge_driver.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 0b43a67..3b9b58d 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -2407,8 +2407,17 @@ networkValidate(virNetworkDriverStatePtr driver,
virNetworkSetBridgeMacAddr(def);
} else {
/* They are also the only types that currently support setting
- * an IP address for the host-side device (bridge)
+ * a MAC or IP address for the host-side device (bridge), DNS
+ * configuration, or network-wide bandwidth limits.
*/
+ if (def->mac_specified) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Unsupported <mac> element in network %s "
+ "with forward mode='%s'"),
+ def->name,
+ virNetworkForwardTypeToString(def->forward.type));
+ return -1;
+ }
if (virNetworkDefGetIpByIndex(def, AF_UNSPEC, 0)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Unsupported <ip> element in network %s "
@@ -2433,6 +2442,14 @@ networkValidate(virNetworkDriverStatePtr driver,
virNetworkForwardTypeToString(def->forward.type));
return -1;
}
+ if (def->bandwidth) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Unsupported network-wide <bandwidth> element "
+ "in network %s with forward mode='%s'"),
+ def->name,
+ virNetworkForwardTypeToString(def->forward.type));
+ return -1;
+ }
}
/* We only support dhcp on one IPv4 address and
--
1.8.5.3
10 years, 10 months
[libvirt] [PATCH python] Fix calling of virStreamSend method
by Daniel P. Berrange
Change d40861 removed the 'len' argument from the virStreamSend
C level wrapper, but forgot to remove it from the python level
wrapper.
Reported-by: Robie Basak <robie.basak(a)canonical.com>
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
libvirt-override-virStream.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libvirt-override-virStream.py b/libvirt-override-virStream.py
index cd44314..ce82da6 100644
--- a/libvirt-override-virStream.py
+++ b/libvirt-override-virStream.py
@@ -122,6 +122,6 @@
with the call, but may instead be delayed until a
subsequent call.
"""
- ret = libvirtmod.virStreamSend(self._o, data, len(data))
+ ret = libvirtmod.virStreamSend(self._o, data)
if ret == -1: raise libvirtError ('virStreamSend() failed')
return ret
--
1.8.4.2
10 years, 10 months
[libvirt] [PATCH] qemu: hyperv: Add enlightenment support for TSC timekeeping
by Peter Krempa
The hyperv enlightenment features allow to ease guests timekeeping by
allowing to store offset from the TSC as a reference. Add the support
for enabling this flag in qemu.
---
Notes:
This feature is still under development in qemu. I will wait until it's finished before pushing this:
http://lists.nongnu.org/archive/html/qemu-devel/2014-01/msg02569.html
docs/formatdomain.html.in | 7 +++++++
src/conf/domain_conf.c | 6 +++++-
src/conf/domain_conf.h | 1 +
src/qemu/qemu_command.c | 2 ++
4 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index ff50214..6e1f93a 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1194,6 +1194,7 @@
<hyperv>
<relaxed state='on'/>
<vapic state='on'/>
+ <time state='on'/>
<spinlocks state='on' retries='4096'/>
</hyperv>
<pvspinlock/>
@@ -1266,6 +1267,12 @@
<td>on, off; retries - at least 4095</td>
<td><span class="since">1.1.0 (QEMU only)</span></td>
</tr>
+ <tr>
+ <td>time</td>
+ <td>Ease timekeeping in guests by providing reference TSC offsets</td>
+ <td>on, off</td>
+ <td><span class="since">1.2.2 (QEMU only)</span></td>
+ </tr>
</table>
</dd>
<dt><code>pvspinlock</code></dt>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 28e24f9..a3f7284 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -153,7 +153,8 @@ VIR_ENUM_IMPL(virDomainFeatureState, VIR_DOMAIN_FEATURE_STATE_LAST,
VIR_ENUM_IMPL(virDomainHyperv, VIR_DOMAIN_HYPERV_LAST,
"relaxed",
"vapic",
- "spinlocks")
+ "spinlocks",
+ "time")
VIR_ENUM_IMPL(virDomainLifecycle, VIR_DOMAIN_LIFECYCLE_LAST,
"destroy",
@@ -11720,6 +11721,7 @@ virDomainDefParseXML(xmlDocPtr xml,
switch ((enum virDomainHyperv) feature) {
case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_TIME:
if (!(tmp = virXPathString("string(./@state)", ctxt))) {
virReportError(VIR_ERR_XML_ERROR,
_("missing 'state' attribute for "
@@ -13744,6 +13746,7 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
switch ((enum virDomainHyperv) i) {
case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_TIME:
if (src->hyperv_features[i] != dst->hyperv_features[i]) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("State of HyperV enlightenment "
@@ -17226,6 +17229,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
switch ((enum virDomainHyperv) j) {
case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_TIME:
if (def->hyperv_features[j])
virBufferAsprintf(buf, " <%s state='%s'/>\n",
virDomainHypervTypeToString(j),
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index d8f2e49..2516341 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1658,6 +1658,7 @@ enum virDomainHyperv {
VIR_DOMAIN_HYPERV_RELAXED = 0,
VIR_DOMAIN_HYPERV_VAPIC,
VIR_DOMAIN_HYPERV_SPINLOCKS,
+ VIR_DOMAIN_HYPERV_TIME,
VIR_DOMAIN_HYPERV_LAST
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 96b8825..7cf9ec9 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6779,6 +6779,7 @@ qemuBuildCpuArgStr(virQEMUDriverPtr driver,
switch ((enum virDomainHyperv) i) {
case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_TIME:
if (def->hyperv_features[i] == VIR_DOMAIN_FEATURE_STATE_ON)
virBufferAsprintf(&buf, ",hv_%s",
virDomainHypervTypeToString(i));
@@ -10971,6 +10972,7 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
switch ((enum virDomainHyperv) f) {
case VIR_DOMAIN_HYPERV_RELAXED:
case VIR_DOMAIN_HYPERV_VAPIC:
+ case VIR_DOMAIN_HYPERV_TIME:
if (value) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("HyperV feature '%s' should not "
--
1.8.5.3
10 years, 10 months
[libvirt] [PATCH v3 0/3] Honor blacklist for modprobe command
by John Ferlan
Rework changes from code review
v2 here: http://www.redhat.com/archives/libvir-list/2014-January/msg01473.html
v3 changes over v2:
* Changed configure.ac for "RMMOD" definition
* Use "virKMod*()" instead of "virModprobe*()" for function names
* Adjust virKModLoad() to take boolean parameter for using -b or not
* Add virKModIsBlacklisted() to perform the blacklist check
* Adjust virkmodtest.c to use the virCommandSetDryRun()
John Ferlan (3):
utils: Introduce functions for modprobe
tests: Add test for new virkmod functions
Honor blacklist for modprobe command
.gitignore | 2 +
configure.ac | 6 ++
src/Makefile.am | 1 +
src/libvirt_private.syms | 7 ++
src/util/virkmod.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++
src/util/virkmod.h | 34 +++++++++
src/util/virpci.c | 28 +++++---
tests/Makefile.am | 5 ++
tests/virkmodtest.c | 183 +++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 439 insertions(+), 9 deletions(-)
create mode 100644 src/util/virkmod.c
create mode 100644 src/util/virkmod.h
create mode 100644 tests/virkmodtest.c
--
1.8.4.2
10 years, 10 months
[libvirt] [PATCH] event: improve public API docs
by Eric Blake
Since libvirt 0.9.3, the entire virevent.c file has been a public
API, so improve the documentation in this file. Also, fix a
potential core dump - it could only be triggered by bogus use of
the API and would only affect the caller (not libvirtd), but we
might as well be nice.
* src/libvirt.c (virConnectDomainEventRegister)
(virConnectDomainEventRegisterAny)
(virConnectNetworkEventRegisterAny): Document event loop requirement.
* src/util/virevent.c (virEventAddHandle, virEventRemoveHandle)
(virEventAddTimeout, virEventRemoveTimeout): Likewise.
(virEventUpdateHandle, virEventUpdateTimeout): Likewise, and avoid
core dump if caller didn't register handler.
(virEventRunDefaultImpl): Expand example, and set up code block in
html docs.
(virEventRegisterImpl, virEventRegisterDefaultImpl): Document more
on the use of the event loop.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
src/libvirt.c | 24 ++++++++++------
src/util/virevent.c | 82 +++++++++++++++++++++++++++++++++++------------------
2 files changed, 70 insertions(+), 36 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index 66841c8..f43718d 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -16121,11 +16121,13 @@ error:
* @freecb: optional function to deallocate opaque when not used anymore
*
* Adds a callback to receive notifications of domain lifecycle events
- * occurring on a connection
+ * occurring on a connection. This function requires that an event loop
+ * has been previously registered with virEventRegisterImpl() or
+ * virEventRegisterDefaultImpl().
*
* Use of this method is no longer recommended. Instead applications
* should try virConnectDomainEventRegisterAny() which has a more flexible
- * API contract
+ * API contract.
*
* The virDomainPtr object handle passed into the callback upon delivery
* of an event is only valid for the duration of execution of the callback.
@@ -16134,7 +16136,7 @@ error:
* The reference can be released once the object is no longer required
* by calling virDomainFree.
*
- * Returns 0 on success, -1 on failure
+ * Returns 0 on success, -1 on failure.
*/
int
virConnectDomainEventRegister(virConnectPtr conn,
@@ -19064,10 +19066,12 @@ error:
* @freecb: optional function to deallocate opaque when not used anymore
*
* Adds a callback to receive notifications of arbitrary domain events
- * occurring on a domain.
+ * occurring on a domain. This function requires that an event loop
+ * has been previously registered with virEventRegisterImpl() or
+ * virEventRegisterDefaultImpl().
*
* If @dom is NULL, then events will be monitored for any domain. If @dom
- * is non-NULL, then only the specific domain will be monitored
+ * is non-NULL, then only the specific domain will be monitored.
*
* Most types of event have a callback providing a custom set of parameters
* for the event. When registering an event, it is thus necessary to use
@@ -19085,7 +19089,7 @@ error:
* for the callback. To unregister a callback, this callback ID should
* be passed to the virConnectDomainEventDeregisterAny() method.
*
- * Returns a callback identifier on success, -1 on failure
+ * Returns a callback identifier on success, -1 on failure.
*/
int
virConnectDomainEventRegisterAny(virConnectPtr conn,
@@ -19183,10 +19187,12 @@ error:
* @freecb: optional function to deallocate opaque when not used anymore
*
* Adds a callback to receive notifications of arbitrary network events
- * occurring on a network.
+ * occurring on a network. This function requires that an event loop
+ * has been previously registered with virEventRegisterImpl() or
+ * virEventRegisterDefaultImpl().
*
* If @net is NULL, then events will be monitored for any network. If @net
- * is non-NULL, then only the specific network will be monitored
+ * is non-NULL, then only the specific network will be monitored.
*
* Most types of event have a callback providing a custom set of parameters
* for the event. When registering an event, it is thus necessary to use
@@ -19204,7 +19210,7 @@ error:
* for the callback. To unregister a callback, this callback ID should
* be passed to the virConnectNetworkEventDeregisterAny() method.
*
- * Returns a callback identifier on success, -1 on failure
+ * Returns a callback identifier on success, -1 on failure.
*/
int
virConnectNetworkEventRegisterAny(virConnectPtr conn,
diff --git a/src/util/virevent.c b/src/util/virevent.c
index fde29a2..0c94946 100644
--- a/src/util/virevent.c
+++ b/src/util/virevent.c
@@ -37,6 +37,16 @@ static virEventAddTimeoutFunc addTimeoutImpl = NULL;
static virEventUpdateTimeoutFunc updateTimeoutImpl = NULL;
static virEventRemoveTimeoutFunc removeTimeoutImpl = NULL;
+
+/*****************************************************
+ *
+ * Below this point are *PUBLIC* APIs for event
+ * loop integration with applications using libvirt.
+ * These API contracts cannot be changed.
+ *
+ *****************************************************/
+
+
/**
* virEventAddHandle:
*
@@ -46,10 +56,12 @@ static virEventRemoveTimeoutFunc removeTimeoutImpl = NULL;
* @opaque: user data to pass to callback
* @ff: callback to free opaque when handle is removed
*
- * Register a callback for monitoring file handle events.
+ * Register a callback for monitoring file handle events. This function
+ * requires that an event loop has previously been registered with
+ * virEventRegisterImpl() or virEventRegisterDefaultImpl().
*
* Returns -1 if the file handle cannot be registered, otherwise a handle
- * watch number to be used for updating and unregistering for events
+ * watch number to be used for updating and unregistering for events.
*/
int
virEventAddHandle(int fd,
@@ -70,14 +82,17 @@ virEventAddHandle(int fd,
* @watch: watch whose file handle to update
* @events: bitset of events to watch from virEventHandleType constants
*
- * Change event set for a monitored file handle.
+ * Change event set for a monitored file handle. This function
+ * requires that an event loop has previously been registered with
+ * virEventRegisterImpl() or virEventRegisterDefaultImpl().
*
- * Will not fail if fd exists
+ * Will not fail if fd exists.
*/
void
virEventUpdateHandle(int watch, int events)
{
- updateHandleImpl(watch, events);
+ if (updateHandleImpl)
+ updateHandleImpl(watch, events);
}
/**
@@ -85,7 +100,9 @@ virEventUpdateHandle(int watch, int events)
*
* @watch: watch whose file handle to remove
*
- * Unregister a callback from a file handle.
+ * Unregister a callback from a file handle. This function
+ * requires that an event loop has previously been registered with
+ * virEventRegisterImpl() or virEventRegisterDefaultImpl().
*
* Returns -1 if the file handle was not registered, 0 upon success.
*/
@@ -106,7 +123,9 @@ virEventRemoveHandle(int watch)
* @opaque: user data to pass to callback
* @ff: callback to free opaque when timeout is removed
*
- * Register a callback for a timer event.
+ * Register a callback for a timer event. This function
+ * requires that an event loop has previously been registered with
+ * virEventRegisterImpl() or virEventRegisterDefaultImpl().
*
* Setting timeout to -1 will disable the timer. Setting the timeout
* to zero will cause it to fire on every event loop iteration.
@@ -132,17 +151,20 @@ virEventAddTimeout(int timeout,
* @timer: timer id to change
* @timeout: time between events in milliseconds
*
- * Change frequency for a timer.
+ * Change frequency for a timer. This function
+ * requires that an event loop has previously been registered with
+ * virEventRegisterImpl() or virEventRegisterDefaultImpl().
*
* Setting frequency to -1 will disable the timer. Setting the frequency
* to zero will cause it to fire on every event loop iteration.
*
- * Will not fail if timer exists
+ * Will not fail if timer exists.
*/
void
virEventUpdateTimeout(int timer, int timeout)
{
- updateTimeoutImpl(timer, timeout);
+ if (updateTimeoutImpl)
+ updateTimeoutImpl(timer, timeout);
}
/**
@@ -150,7 +172,9 @@ virEventUpdateTimeout(int timer, int timeout)
*
* @timer: the timer id to remove
*
- * Unregister a callback for a timer.
+ * Unregister a callback for a timer. This function
+ * requires that an event loop has previously been registered with
+ * virEventRegisterImpl() or virEventRegisterDefaultImpl().
*
* Returns -1 if the timer was not registered, 0 upon success.
*/
@@ -164,14 +188,6 @@ virEventRemoveTimeout(int timer)
}
-/*****************************************************
- *
- * Below this point are 3 *PUBLIC* APIs for event
- * loop integration with applications using libvirt.
- * These API contracts cannot be changed.
- *
- *****************************************************/
-
/**
* virEventRegisterImpl:
* @addHandle: the callback to add fd handles
@@ -186,9 +202,14 @@ virEventRemoveTimeout(int timer)
* to integrate with the libglib2 event loop, or libevent
* or the QT event loop.
*
+ * Use of the virEventAddHandle() and similar APIs require that the
+ * corresponding handler be registered. Use of the
+ * virConnectDomainEventRegisterAny() and similar APIs requires that
+ * the three timeout handlers be registered.
+ *
* If an application does not need to integrate with an
* existing event loop implementation, then the
- * virEventRegisterDefaultImpl method can be used to setup
+ * virEventRegisterDefaultImpl() method can be used to setup
* the generic libvirt implementation.
*/
void virEventRegisterImpl(virEventAddHandleFunc addHandle,
@@ -220,9 +241,12 @@ void virEventRegisterImpl(virEventAddHandleFunc addHandle,
* not have a need to integrate with an external event
* loop impl.
*
- * Once registered, the application has to invoke virEventRunDefaultImpl in
+ * Once registered, the application has to invoke virEventRunDefaultImpl() in
* a loop to process events. Failure to do so may result in connections being
- * closed unexpectedly as a result of keepalive timeout.
+ * closed unexpectedly as a result of keepalive timeout. The default
+ * event loop fully supports handle and and timeout events, but only
+ * wakes up on events registered by libvirt API calls such as
+ * virEventAddHandle() or virConnectDomainEventRegisterAny().
*
* Returns 0 on success, -1 on failure.
*/
@@ -255,14 +279,18 @@ int virEventRegisterDefaultImpl(void)
*
* Run one iteration of the event loop. Applications
* will generally want to have a thread which invokes
- * this method in an infinite loop
+ * this method in an infinite loop. Furthermore, it is wise
+ * to set up a pipe-to-self handler (via virEventAddHandle())
+ * or a timeout (via virEventAddTimeout()) before calling this
+ * function, as it will block forever if there are no
+ * registered events.
*
- * static bool quit = false;
+ * static bool quit = false;
*
- * while (!quit) {
- * if (virEventRunDefaultImpl() < 0)
+ * while (!quit) {
+ * if (virEventRunDefaultImpl() < 0)
* ...print error...
- * }
+ * }
*
* Returns 0 on success, -1 on failure.
*/
--
1.8.4.2
10 years, 10 months
[libvirt] [RFC PATCH] libvirt support to force convergence of live guest migration
by Chegu Vinod
Busy enterprise workloads hosted on large sized VM's tend to dirty
memory faster than the transfer rate achieved via live guest migration.
Despite some good recent improvements (& using dedicated 10Gig NICs
between hosts) the live migration may NOT converge.
Recently support was added in qemu (version 1.6) to allow a user to
choose if they wish to force convergence of their migration via a
new migration capability : "auto-converge". This feature allows for qemu
to auto-detect lack of convergence and trigger a throttle-down of the
VCPUs.
This RFC patch includes the libvirt support needed to trigger this
feature. (Testing is still in progress)
Signed-off-by: Chegu Vinod <chegu_vinod(a)hp.com>
---
include/libvirt/libvirt.h.in | 1 +
src/qemu/qemu_migration.c | 44 ++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_migration.h | 1 +
src/qemu/qemu_monitor.c | 2 +-
src/qemu/qemu_monitor.h | 1 +
tools/virsh-domain.c | 7 ++++++
6 files changed, 55 insertions(+), 1 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 146a59b..13b0bfc 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1192,6 +1192,7 @@ typedef enum {
VIR_MIGRATE_OFFLINE = (1 << 10), /* offline migrate */
VIR_MIGRATE_COMPRESSED = (1 << 11), /* compress data during migration */
VIR_MIGRATE_ABORT_ON_ERROR = (1 << 12), /* abort migration on I/O errors happened during migration */
+ VIR_MIGRATE_AUTO_CONVERGE = (1 << 13), /* force auto-convergence during during migration */
} virDomainMigrateFlags;
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index e87ea85..8cc0c56 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1565,6 +1565,40 @@ cleanup:
}
static int
+qemuMigrationSetAutoConverge(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ enum qemuDomainAsyncJob job)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ int ret;
+
+ if (qemuDomainObjEnterMonitorAsync(driver, vm, job) < 0)
+ return -1;
+
+ ret = qemuMonitorGetMigrationCapability(
+ priv->mon,
+ QEMU_MONITOR_MIGRATION_CAPS_AUTO_CONVERGE);
+
+ if (ret < 0) {
+ goto cleanup;
+ } else if (ret == 0) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("Auto-Converge migration is not supported by "
+ "QEMU binary"));
+ ret = -1;
+ goto cleanup;
+ }
+
+ ret = qemuMonitorSetMigrationCapability(
+ priv->mon,
+ QEMU_MONITOR_MIGRATION_CAPS_AUTO_CONVERGE);
+
+cleanup:
+ qemuDomainObjExitMonitor(driver, vm);
+ return ret;
+}
+
+static int
qemuMigrationWaitForSpice(virQEMUDriverPtr driver,
virDomainObjPtr vm)
{
@@ -2389,6 +2423,11 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
QEMU_ASYNC_JOB_MIGRATION_IN) < 0)
goto stop;
+ if (flags & VIR_MIGRATE_AUTO_CONVERGE &&
+ qemuMigrationSetAutoConverge(driver, vm,
+ QEMU_ASYNC_JOB_MIGRATION_IN) < 0)
+ goto stop;
+
if (mig->lockState) {
VIR_DEBUG("Received lockstate %s", mig->lockState);
VIR_FREE(priv->lockState);
@@ -3181,6 +3220,11 @@ qemuMigrationRun(virQEMUDriverPtr driver,
QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
goto cleanup;
+ if (flags & VIR_MIGRATE_AUTO_CONVERGE &&
+ qemuMigrationSetAutoConverge(driver, vm,
+ QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
+ goto cleanup;
+
if (qemuDomainObjEnterMonitorAsync(driver, vm,
QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
goto cleanup;
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index cafa2a2..c4258a1 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -39,6 +39,7 @@
VIR_MIGRATE_UNSAFE | \
VIR_MIGRATE_OFFLINE | \
VIR_MIGRATE_COMPRESSED | \
+ VIR_MIGRATE_AUTO_CONVERGE | \
VIR_MIGRATE_ABORT_ON_ERROR)
/* All supported migration parameters and their types. */
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 1514715..780a29a 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -118,7 +118,7 @@ VIR_ENUM_IMPL(qemuMonitorMigrationStatus,
VIR_ENUM_IMPL(qemuMonitorMigrationCaps,
QEMU_MONITOR_MIGRATION_CAPS_LAST,
- "xbzrle")
+ "xbzrle", "auto-converge")
VIR_ENUM_IMPL(qemuMonitorVMStatus,
QEMU_MONITOR_VM_STATUS_LAST,
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index eabf000..95e70ab 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -440,6 +440,7 @@ int qemuMonitorGetSpiceMigrationStatus(qemuMonitorPtr mon,
typedef enum {
QEMU_MONITOR_MIGRATION_CAPS_XBZRLE,
+ QEMU_MONITOR_MIGRATION_CAPS_AUTO_CONVERGE,
QEMU_MONITOR_MIGRATION_CAPS_LAST
} qemuMonitorMigrationCaps;
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 1fe138c..d94a81b 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -8532,6 +8532,10 @@ static const vshCmdOptDef opts_migrate[] = {
.type = VSH_OT_BOOL,
.help = N_("compress repeated pages during live migration")
},
+ {.name = "auto-converge",
+ .type = VSH_OT_BOOL,
+ .help = N_("force auto convergence during live migration")
+ },
{.name = "abort-on-error",
.type = VSH_OT_BOOL,
.help = N_("abort on soft errors during migration")
@@ -8676,6 +8680,9 @@ doMigrate(void *opaque)
if (vshCommandOptBool(cmd, "compressed"))
flags |= VIR_MIGRATE_COMPRESSED;
+ if (vshCommandOptBool(cmd, "auto-converge"))
+ flags |= VIR_MIGRATE_AUTO_CONVERGE;
+
if (vshCommandOptBool(cmd, "offline")) {
flags |= VIR_MIGRATE_OFFLINE;
}
--
1.7.1
10 years, 10 months
[libvirt] [PATCH v1 0/2] Network hooks
by Michal Privoznik
With the latest noise I made on the list with QoS I'm coming forward with this
idea. Network hooks can fill some holes in our functionality. For instance if
somebody is willing to set a QoS that is not covered by libvirt, or just want
to insert some additional iptables rules, etc. You name it.
Michal Privoznik (2):
networkStartNetwork: Be more verbose
network: Introduce start and shutdown hooks
docs/hooks.html.in | 43 ++++++++++++++++++++----------
src/network/bridge_driver.c | 64 +++++++++++++++++++++++++++++++++------------
src/util/virhook.c | 10 ++++++-
src/util/virhook.h | 8 ++++++
4 files changed, 94 insertions(+), 31 deletions(-)
--
1.8.5.2
10 years, 10 months
[libvirt] [PATCH v2 00/18] LXC configuration conversion to domain XML
by Cédric Bosdonnat
This new version of the patchset, fixes all comments from Daniel. It also adds
two more commits: one extending virConf to use it later in lxc_native.c and one
for some documentation on the new feature and its limitations.
Several RFEs have been filesd for this patchset: they are mentioned in the
appropriate commit log, and I still hope to be able to provide patches for them
later.
Cédric Bosdonnat (18):
Improve virConf parse to handle LXC config format
LXC driver: started implementing connectDomainXMLFromNative
LXC from native: import rootfs
LXC from native: migrate fstab and lxc.mount.entry
LXC from native: implement no network conversion
LXC from native: migrate veth network configuration
LXC from native: convert phys network types to net hostdev devices
LXC from native: convert lxc.tty to console devices
LXC from native: convert macvlan network configuration
LXC from native: convert lxc.id_map into <idmap>
LXC from native: migrate memory tuning
LXC from native: map lxc.cgroup.cpu.*
LXC from native: map lxc.cgroup.cpuset.*
LXC from native: add lxc.cgroup.blkio.* mapping
LXC from native: map lxc.arch to /domain/os/type@arch
LXC from native: map block filesystems
LXC from native: map vlan network type
LXC: added some doc on domxml-from-native with mention of limitations
.gitignore | 1 +
docs/drvlxc.html.in | 34 +-
po/POTFILES.in | 1 +
src/Makefile.am | 1 +
src/libvirt_private.syms | 1 +
src/lxc/lxc_container.c | 2 +-
src/lxc/lxc_container.h | 2 +
src/lxc/lxc_driver.c | 31 +
src/lxc/lxc_native.c | 883 +++++++++++++++++++++
src/lxc/lxc_native.h | 32 +
src/util/virconf.c | 46 +-
src/util/virconf.h | 10 +
tests/Makefile.am | 7 +-
tests/lxcconf2xmldata/lxcconf2xml-blkiotune.config | 7 +
tests/lxcconf2xmldata/lxcconf2xml-blkiotune.xml | 35 +
.../lxcconf2xmldata/lxcconf2xml-cpusettune.config | 6 +
tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml | 27 +
tests/lxcconf2xmldata/lxcconf2xml-cputune.config | 7 +
tests/lxcconf2xmldata/lxcconf2xml-cputune.xml | 29 +
tests/lxcconf2xmldata/lxcconf2xml-fstab.config | 37 +
tests/lxcconf2xmldata/lxcconf2xml-idmap.config | 5 +
tests/lxcconf2xmldata/lxcconf2xml-idmap.xml | 28 +
.../lxcconf2xml-macvlannetwork.config | 13 +
.../lxcconf2xmldata/lxcconf2xml-macvlannetwork.xml | 26 +
tests/lxcconf2xmldata/lxcconf2xml-memtune.config | 10 +
tests/lxcconf2xmldata/lxcconf2xml-memtune.xml | 29 +
.../lxcconf2xmldata/lxcconf2xml-nonenetwork.config | 4 +
tests/lxcconf2xmldata/lxcconf2xml-nonenetwork.xml | 21 +
tests/lxcconf2xmldata/lxcconf2xml-nonetwork.config | 3 +
tests/lxcconf2xmldata/lxcconf2xml-nonetwork.xml | 24 +
.../lxcconf2xmldata/lxcconf2xml-physnetwork.config | 6 +
tests/lxcconf2xmldata/lxcconf2xml-physnetwork.xml | 26 +
tests/lxcconf2xmldata/lxcconf2xml-simple.config | 41 +
tests/lxcconf2xmldata/lxcconf2xml-simple.xml | 41 +
.../lxcconf2xmldata/lxcconf2xml-vlannetwork.config | 12 +
tests/lxcconf2xmldata/lxcconf2xml-vlannetwork.xml | 26 +
tests/lxcconf2xmltest.c | 131 +++
37 files changed, 1640 insertions(+), 5 deletions(-)
create mode 100644 src/lxc/lxc_native.c
create mode 100644 src/lxc/lxc_native.h
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-blkiotune.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-blkiotune.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-cpusettune.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-cputune.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-cputune.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-fstab.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-idmap.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-idmap.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-macvlannetwork.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-macvlannetwork.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-memtune.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-memtune.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-nonenetwork.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-nonenetwork.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-nonetwork.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-nonetwork.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-physnetwork.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-physnetwork.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-simple.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-simple.xml
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-vlannetwork.config
create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-vlannetwork.xml
create mode 100644 tests/lxcconf2xmltest.c
--
1.8.5.2
10 years, 10 months