Allow QoS change with update-device (bz #1014200)

Fix nwfilter crash during firewalld install (bz #1014762)
Fix crash with nographics (bz #1014088)
This commit is contained in:
Cole Robinson 2013-10-06 15:14:15 -04:00
parent a2951dccb5
commit 43618df1d4
7 changed files with 1022 additions and 1 deletions

View File

@ -0,0 +1,66 @@
From d519f225d79a61451cfa62b463ea3083e9367353 Mon Sep 17 00:00:00 2001
From: Michal Privoznik <mprivozn@redhat.com>
Date: Tue, 1 Oct 2013 15:04:48 +0200
Subject: [PATCH] qemu_hotplug: Allow QoS update in qemuDomainChangeNet
The qemuDomainChangeNet() is called when 'virsh update-device' is
invoked on a NIC. Currently, we fail to update the QoS even though
we have routines for that.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 9fa10d3901a14997f724fe50ad8a33d7f0d23abe)
---
src/qemu/qemu_hotplug.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index f06930e..818c726 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1799,6 +1799,7 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
bool needFilterChange = false;
bool needLinkStateChange = false;
bool needReplaceDevDef = false;
+ bool needBandwidthSet = false;
int ret = -1;
if (!devslot || !(olddev = *devslot)) {
@@ -2062,8 +2063,6 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
virDomainNetGetActualDirectMode(olddev) != virDomainNetGetActualDirectMode(olddev) ||
!virNetDevVPortProfileEqual(virDomainNetGetActualVirtPortProfile(olddev),
virDomainNetGetActualVirtPortProfile(newdev)) ||
- !virNetDevBandwidthEqual(virDomainNetGetActualBandwidth(olddev),
- virDomainNetGetActualBandwidth(newdev)) ||
!virNetDevVlanEqual(virDomainNetGetActualVlan(olddev),
virDomainNetGetActualVlan(newdev))) {
needReconnect = true;
@@ -2072,6 +2071,10 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
if (olddev->linkstate != newdev->linkstate)
needLinkStateChange = true;
+ if (!virNetDevBandwidthEqual(virDomainNetGetActualBandwidth(olddev),
+ virDomainNetGetActualBandwidth(newdev)))
+ needBandwidthSet = true;
+
/* FINALLY - actually perform the required actions */
if (needReconnect) {
@@ -2081,6 +2084,18 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
goto cleanup;
}
+ if (needBandwidthSet) {
+ if (virNetDevBandwidthSet(newdev->ifname,
+ virDomainNetGetActualBandwidth(newdev),
+ false) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot set bandwidth limits on %s"),
+ newdev->ifname);
+ goto cleanup;
+ }
+ needReplaceDevDef = true;
+ }
+
if (needBridgeChange) {
if (qemuDomainChangeNetBridge(dom->conn, vm, olddev, newdev) < 0)
goto cleanup;

View File

@ -0,0 +1,57 @@
From 658f4b3c39c9bdd490a44175742f8259dd10b84f Mon Sep 17 00:00:00 2001
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 2 Oct 2013 09:18:02 +0200
Subject: [PATCH] virNetDevBandwidthEqual: Make it more robust
So far the virNetDevBandwidthEqual() expected both ->in and ->out items
to be allocated for both @a and @b compared. This is not necessary true
for all our code. For instance, running 'update-device' twice over a NIC
with the very same XML results in SIGSEGV-ing in this function.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit ee02fbc8e4a24c1347761ceff2ddb2c108e9611c)
---
src/util/virnetdevbandwidth.c | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/src/util/virnetdevbandwidth.c b/src/util/virnetdevbandwidth.c
index 42b0a50..17f4fa3 100644
--- a/src/util/virnetdevbandwidth.c
+++ b/src/util/virnetdevbandwidth.c
@@ -335,16 +335,30 @@ virNetDevBandwidthEqual(virNetDevBandwidthPtr a,
return false;
/* in */
- if (a->in->average != b->in->average ||
- a->in->peak != b->in->peak ||
- a->in->burst != b->in->burst)
+ if (a->in) {
+ if (!b->in)
+ return false;
+
+ if (a->in->average != b->in->average ||
+ a->in->peak != b->in->peak ||
+ a->in->burst != b->in->burst)
+ return false;
+ } else if (b->in) {
return false;
+ }
/*out*/
- if (a->out->average != b->out->average ||
- a->out->peak != b->out->peak ||
- a->out->burst != b->out->burst)
+ if (a->out) {
+ if (!b->out)
+ return false;
+
+ if (a->out->average != b->out->average ||
+ a->out->peak != b->out->peak ||
+ a->out->burst != b->out->burst)
+ return false;
+ } else if (b->out) {
return false;
+ }
return true;
}

View File

@ -0,0 +1,105 @@
From 56c170544f7a71749ef63fef650c71787c05e8af Mon Sep 17 00:00:00 2001
From: "Daniel P. Berrange" <berrange@redhat.com>
Date: Thu, 3 Oct 2013 14:06:58 +0100
Subject: [PATCH] Remove virConnectPtr arg from virNWFilterDefParse*
None of the virNWFilterDefParse* methods require a virConnectPtr
arg, so just drop it
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
src/conf/nwfilter_conf.c | 15 ++++++---------
src/conf/nwfilter_conf.h | 6 ++----
src/nwfilter/nwfilter_driver.c | 2 +-
tests/nwfilterxml2xmltest.c | 2 +-
4 files changed, 10 insertions(+), 15 deletions(-)
diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c
index 3456b77..c009921 100644
--- a/src/conf/nwfilter_conf.c
+++ b/src/conf/nwfilter_conf.c
@@ -2634,8 +2634,7 @@ cleanup:
static virNWFilterDefPtr
-virNWFilterDefParse(virConnectPtr conn ATTRIBUTE_UNUSED,
- const char *xmlStr,
+virNWFilterDefParse(const char *xmlStr,
const char *filename) {
virNWFilterDefPtr def = NULL;
xmlDocPtr xml;
@@ -2650,18 +2649,16 @@ virNWFilterDefParse(virConnectPtr conn ATTRIBUTE_UNUSED,
virNWFilterDefPtr
-virNWFilterDefParseString(virConnectPtr conn,
- const char *xmlStr)
+virNWFilterDefParseString(const char *xmlStr)
{
- return virNWFilterDefParse(conn, xmlStr, NULL);
+ return virNWFilterDefParse(xmlStr, NULL);
}
virNWFilterDefPtr
-virNWFilterDefParseFile(virConnectPtr conn,
- const char *filename)
+virNWFilterDefParseFile(const char *filename)
{
- return virNWFilterDefParse(conn, NULL, filename);
+ return virNWFilterDefParse(NULL, filename);
}
@@ -3056,7 +3053,7 @@ virNWFilterObjLoad(virConnectPtr conn,
virNWFilterDefPtr def;
virNWFilterObjPtr nwfilter;
- if (!(def = virNWFilterDefParseFile(conn, path))) {
+ if (!(def = virNWFilterDefParseFile(path))) {
return NULL;
}
diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h
index 5d04cff..faa7527 100644
--- a/src/conf/nwfilter_conf.h
+++ b/src/conf/nwfilter_conf.h
@@ -713,10 +713,8 @@ int virNWFilterLoadAllConfigs(virConnectPtr conn,
char *virNWFilterConfigFile(const char *dir,
const char *name);
-virNWFilterDefPtr virNWFilterDefParseString(virConnectPtr conn,
- const char *xml);
-virNWFilterDefPtr virNWFilterDefParseFile(virConnectPtr conn,
- const char *filename);
+virNWFilterDefPtr virNWFilterDefParseString(const char *xml);
+virNWFilterDefPtr virNWFilterDefParseFile(const char *filename);
void virNWFilterObjLock(virNWFilterObjPtr obj);
void virNWFilterObjUnlock(virNWFilterObjPtr obj);
diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
index 1ed28a2..c2afdfc 100644
--- a/src/nwfilter/nwfilter_driver.c
+++ b/src/nwfilter/nwfilter_driver.c
@@ -566,7 +566,7 @@ nwfilterDefineXML(virConnectPtr conn,
nwfilterDriverLock(driver);
virNWFilterCallbackDriversLock();
- if (!(def = virNWFilterDefParseString(conn, xml)))
+ if (!(def = virNWFilterDefParseString(xml)))
goto cleanup;
if (virNWFilterDefineXMLEnsureACL(conn, def) < 0)
diff --git a/tests/nwfilterxml2xmltest.c b/tests/nwfilterxml2xmltest.c
index 84e61da..14191a6 100644
--- a/tests/nwfilterxml2xmltest.c
+++ b/tests/nwfilterxml2xmltest.c
@@ -36,7 +36,7 @@ testCompareXMLToXMLFiles(const char *inxml, const char *outxml,
virResetLastError();
- if (!(dev = virNWFilterDefParseString(NULL, inXmlData))) {
+ if (!(dev = virNWFilterDefParseString(inXmlData))) {
if (expect_error) {
virResetLastError();
goto done;

View File

@ -0,0 +1,355 @@
From 0a5abfb22d5d030cc3780c44b805b5b92567b44a Mon Sep 17 00:00:00 2001
From: "Daniel P. Berrange" <berrange@redhat.com>
Date: Thu, 3 Oct 2013 14:06:59 +0100
Subject: [PATCH] Don't pass virConnectPtr in nwfilter 'struct
domUpdateCBStruct'
The nwfilter driver only needs a reference to its private
state object, not a full virConnectPtr. Update the domUpdateCBStruct
struct to have a 'void *opaque' field instead of a virConnectPtr.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
src/conf/nwfilter_conf.c | 14 +++++++++++---
src/conf/nwfilter_conf.h | 4 ++--
src/nwfilter/nwfilter_dhcpsnoop.c | 12 ++++++------
src/nwfilter/nwfilter_driver.c | 5 +++--
src/nwfilter/nwfilter_gentech_driver.c | 32 ++++++++++++++++----------------
src/nwfilter/nwfilter_gentech_driver.h | 10 +++++-----
src/nwfilter/nwfilter_learnipaddr.c | 6 +++---
7 files changed, 46 insertions(+), 37 deletions(-)
diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c
index c009921..9927f7e 100644
--- a/src/conf/nwfilter_conf.c
+++ b/src/conf/nwfilter_conf.c
@@ -2850,6 +2850,7 @@ virNWFilterCallbackDriversUnlock(void)
static virDomainObjListIterator virNWFilterDomainFWUpdateCB;
+static void *virNWFilterDomainFWUpdateOpaque;
/**
* virNWFilterInstFiltersOnAllVMs:
@@ -2861,7 +2862,7 @@ virNWFilterInstFiltersOnAllVMs(virConnectPtr conn)
{
size_t i;
struct domUpdateCBStruct cb = {
- .conn = conn,
+ .opaque = virNWFilterDomainFWUpdateOpaque,
.step = STEP_APPLY_CURRENT,
.skipInterfaces = NULL, /* not needed */
};
@@ -2880,7 +2881,7 @@ virNWFilterTriggerVMFilterRebuild(virConnectPtr conn)
size_t i;
int ret = 0;
struct domUpdateCBStruct cb = {
- .conn = conn,
+ .opaque = virNWFilterDomainFWUpdateOpaque,
.step = STEP_APPLY_NEW,
.skipInterfaces = virHashCreate(0, NULL),
};
@@ -3474,9 +3475,14 @@ char *virNWFilterConfigFile(const char *dir,
}
-int virNWFilterConfLayerInit(virDomainObjListIterator domUpdateCB)
+int virNWFilterConfLayerInit(virDomainObjListIterator domUpdateCB,
+ void *opaque)
{
+ if (initialized)
+ return -1;
+
virNWFilterDomainFWUpdateCB = domUpdateCB;
+ virNWFilterDomainFWUpdateOpaque = opaque;
initialized = true;
@@ -3495,6 +3501,8 @@ void virNWFilterConfLayerShutdown(void)
virMutexDestroy(&updateMutex);
initialized = false;
+ virNWFilterDomainFWUpdateOpaque = NULL;
+ virNWFilterDomainFWUpdateCB = NULL;
}
diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h
index faa7527..e470615 100644
--- a/src/conf/nwfilter_conf.h
+++ b/src/conf/nwfilter_conf.h
@@ -586,7 +586,7 @@ enum UpdateStep {
};
struct domUpdateCBStruct {
- virConnectPtr conn;
+ void *opaque;
enum UpdateStep step;
virHashTablePtr skipInterfaces;
};
@@ -722,7 +722,7 @@ void virNWFilterObjUnlock(virNWFilterObjPtr obj);
void virNWFilterLockFilterUpdates(void);
void virNWFilterUnlockFilterUpdates(void);
-int virNWFilterConfLayerInit(virDomainObjListIterator domUpdateCB);
+int virNWFilterConfLayerInit(virDomainObjListIterator domUpdateCB, void *opaque);
void virNWFilterConfLayerShutdown(void);
int virNWFilterInstFiltersOnAllVMs(virConnectPtr conn);
diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c b/src/nwfilter/nwfilter_dhcpsnoop.c
index 3e9f046..2bc1686 100644
--- a/src/nwfilter/nwfilter_dhcpsnoop.c
+++ b/src/nwfilter/nwfilter_dhcpsnoop.c
@@ -481,15 +481,15 @@ virNWFilterSnoopIPLeaseInstallRule(virNWFilterSnoopIPLeasePtr ipl,
/* instantiate the filters */
if (req->ifname)
- rc = virNWFilterInstantiateFilterLate(NULL,
+ rc = virNWFilterInstantiateFilterLate(req->driver,
+ NULL,
req->ifname,
req->ifindex,
req->linkdev,
req->nettype,
&req->macaddr,
req->filtername,
- req->vars,
- req->driver);
+ req->vars);
exit_snooprequnlock:
virNWFilterSnoopReqUnlock(req);
@@ -867,15 +867,15 @@ virNWFilterSnoopReqLeaseDel(virNWFilterSnoopReqPtr req,
goto skip_instantiate;
if (ipAddrLeft) {
- ret = virNWFilterInstantiateFilterLate(NULL,
+ ret = virNWFilterInstantiateFilterLate(req->driver,
+ NULL,
req->ifname,
req->ifindex,
req->linkdev,
req->nettype,
&req->macaddr,
req->filtername,
- req->vars,
- req->driver);
+ req->vars);
} else {
const virNWFilterVarValuePtr dhcpsrvrs =
virHashLookup(req->vars->hashTable, NWFILTER_VARNAME_DHCPSERVER);
diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
index c2afdfc..6e20e03 100644
--- a/src/nwfilter/nwfilter_driver.c
+++ b/src/nwfilter/nwfilter_driver.c
@@ -203,7 +203,8 @@ nwfilterStateInitialize(bool privileged,
virNWFilterTechDriversInit(privileged);
- if (virNWFilterConfLayerInit(virNWFilterDomainFWUpdateCB) < 0)
+ if (virNWFilterConfLayerInit(virNWFilterDomainFWUpdateCB,
+ driverState) < 0)
goto err_techdrivers_shutdown;
/*
@@ -681,7 +682,7 @@ nwfilterInstantiateFilter(virConnectPtr conn,
const unsigned char *vmuuid,
virDomainNetDefPtr net)
{
- return virNWFilterInstantiateFilter(conn, vmuuid, net);
+ return virNWFilterInstantiateFilter(conn->nwfilterPrivateData, vmuuid, net);
}
diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c
index 382d73f..5961165 100644
--- a/src/nwfilter/nwfilter_gentech_driver.c
+++ b/src/nwfilter/nwfilter_gentech_driver.c
@@ -800,7 +800,8 @@ err_unresolvable_vars:
* Call this function while holding the NWFilter filter update lock
*/
static int
-__virNWFilterInstantiateFilter(const unsigned char *vmuuid,
+__virNWFilterInstantiateFilter(virNWFilterDriverStatePtr driver,
+ const unsigned char *vmuuid,
bool teardownOld,
const char *ifname,
int ifindex,
@@ -810,7 +811,6 @@ __virNWFilterInstantiateFilter(const unsigned char *vmuuid,
const char *filtername,
virNWFilterHashTablePtr filterparams,
enum instCase useNewFilter,
- virNWFilterDriverStatePtr driver,
bool forceWithPendingReq,
bool *foundNewFilter)
{
@@ -921,7 +921,7 @@ err_exit:
static int
-_virNWFilterInstantiateFilter(virConnectPtr conn,
+_virNWFilterInstantiateFilter(virNWFilterDriverStatePtr driver,
const unsigned char *vmuuid,
const virDomainNetDefPtr net,
bool teardownOld,
@@ -948,7 +948,8 @@ _virNWFilterInstantiateFilter(virConnectPtr conn,
goto cleanup;
}
- rc = __virNWFilterInstantiateFilter(vmuuid,
+ rc = __virNWFilterInstantiateFilter(driver,
+ vmuuid,
teardownOld,
net->ifname,
ifindex,
@@ -958,7 +959,6 @@ _virNWFilterInstantiateFilter(virConnectPtr conn,
net->filter,
net->filterparams,
useNewFilter,
- conn->nwfilterPrivateData,
false,
foundNewFilter);
@@ -970,22 +970,23 @@ cleanup:
int
-virNWFilterInstantiateFilterLate(const unsigned char *vmuuid,
+virNWFilterInstantiateFilterLate(virNWFilterDriverStatePtr driver,
+ const unsigned char *vmuuid,
const char *ifname,
int ifindex,
const char *linkdev,
enum virDomainNetType nettype,
const virMacAddrPtr macaddr,
const char *filtername,
- virNWFilterHashTablePtr filterparams,
- virNWFilterDriverStatePtr driver)
+ virNWFilterHashTablePtr filterparams)
{
int rc;
bool foundNewFilter = false;
virNWFilterLockFilterUpdates();
- rc = __virNWFilterInstantiateFilter(vmuuid,
+ rc = __virNWFilterInstantiateFilter(driver,
+ vmuuid,
true,
ifname,
ifindex,
@@ -995,7 +996,6 @@ virNWFilterInstantiateFilterLate(const unsigned char *vmuuid,
filtername,
filterparams,
INSTANTIATE_ALWAYS,
- driver,
true,
&foundNewFilter);
if (rc < 0) {
@@ -1015,13 +1015,13 @@ virNWFilterInstantiateFilterLate(const unsigned char *vmuuid,
int
-virNWFilterInstantiateFilter(virConnectPtr conn,
+virNWFilterInstantiateFilter(virNWFilterDriverStatePtr driver,
const unsigned char *vmuuid,
const virDomainNetDefPtr net)
{
bool foundNewFilter = false;
- return _virNWFilterInstantiateFilter(conn, vmuuid, net,
+ return _virNWFilterInstantiateFilter(driver, vmuuid, net,
1,
INSTANTIATE_ALWAYS,
&foundNewFilter);
@@ -1029,14 +1029,14 @@ virNWFilterInstantiateFilter(virConnectPtr conn,
int
-virNWFilterUpdateInstantiateFilter(virConnectPtr conn,
+virNWFilterUpdateInstantiateFilter(virNWFilterDriverStatePtr driver,
const unsigned char *vmuuid,
const virDomainNetDefPtr net,
bool *skipIface)
{
bool foundNewFilter = false;
- int rc = _virNWFilterInstantiateFilter(conn, vmuuid, net,
+ int rc = _virNWFilterInstantiateFilter(driver, vmuuid, net,
0,
INSTANTIATE_FOLLOW_NEWFILTER,
&foundNewFilter);
@@ -1154,7 +1154,7 @@ virNWFilterDomainFWUpdateCB(virDomainObjPtr obj,
if ((net->filter) && (net->ifname)) {
switch (cb->step) {
case STEP_APPLY_NEW:
- ret = virNWFilterUpdateInstantiateFilter(cb->conn,
+ ret = virNWFilterUpdateInstantiateFilter(cb->opaque,
vm->uuid,
net,
&skipIface);
@@ -1179,7 +1179,7 @@ virNWFilterDomainFWUpdateCB(virDomainObjPtr obj,
break;
case STEP_APPLY_CURRENT:
- ret = virNWFilterInstantiateFilter(cb->conn,
+ ret = virNWFilterInstantiateFilter(cb->opaque,
vm->uuid,
net);
if (ret)
diff --git a/src/nwfilter/nwfilter_gentech_driver.h b/src/nwfilter/nwfilter_gentech_driver.h
index 4b47b4a..8528e2a 100644
--- a/src/nwfilter/nwfilter_gentech_driver.h
+++ b/src/nwfilter/nwfilter_gentech_driver.h
@@ -39,23 +39,23 @@ enum instCase {
};
-int virNWFilterInstantiateFilter(virConnectPtr conn,
+int virNWFilterInstantiateFilter(virNWFilterDriverStatePtr driver,
const unsigned char *vmuuid,
const virDomainNetDefPtr net);
-int virNWFilterUpdateInstantiateFilter(virConnectPtr conn,
+int virNWFilterUpdateInstantiateFilter(virNWFilterDriverStatePtr driver,
const unsigned char *vmuuid,
const virDomainNetDefPtr net,
bool *skipIface);
-int virNWFilterInstantiateFilterLate(const unsigned char *vmuuid,
+int virNWFilterInstantiateFilterLate(virNWFilterDriverStatePtr driver,
+ const unsigned char *vmuuid,
const char *ifname,
int ifindex,
const char *linkdev,
enum virDomainNetType nettype,
const virMacAddrPtr macaddr,
const char *filtername,
- virNWFilterHashTablePtr filterparams,
- virNWFilterDriverStatePtr driver);
+ virNWFilterHashTablePtr filterparams);
int virNWFilterTeardownFilter(const virDomainNetDefPtr net);
diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c
index 7e67203..093158a 100644
--- a/src/nwfilter/nwfilter_learnipaddr.c
+++ b/src/nwfilter/nwfilter_learnipaddr.c
@@ -612,15 +612,15 @@ learnIPAddressThread(void *arg)
"cache for interface %s"), inetaddr, req->ifname);
}
- ret = virNWFilterInstantiateFilterLate(NULL,
+ ret = virNWFilterInstantiateFilterLate(req->driver,
+ NULL,
req->ifname,
req->ifindex,
req->linkdev,
req->nettype,
&req->macaddr,
req->filtername,
- req->filterparams,
- req->driver);
+ req->filterparams);
VIR_DEBUG("Result from applying firewall rules on "
"%s with IP addr %s : %d\n", req->ifname, inetaddr, ret);
}

View File

@ -0,0 +1,382 @@
From 1766db28533e2b5a96792aa0811e5364e0bb54d4 Mon Sep 17 00:00:00 2001
From: "Daniel P. Berrange" <berrange@redhat.com>
Date: Thu, 3 Oct 2013 14:07:00 +0100
Subject: [PATCH] Remove use of virConnectPtr from all remaining nwfilter code
The virConnectPtr is passed around loads of nwfilter code in
order to provide it as a parameter to the callback registered
by the virt drivers. None of the virt drivers use this param
though, so it serves no purpose.
Avoiding the need to pass a virConnectPtr means that the
nwfilterStateReload method no longer needs to open a bogus
QEMU driver connection. This addresses a race condition that
can lead to a crash on startup.
The nwfilter driver starts before the QEMU driver and registers
some callbacks with DBus to detect firewalld reload. If the
firewalld reload happens while the QEMU driver is still starting
up though, the nwfilterStateReload method will open a connection
to the partially initialized QEMU driver and cause a crash.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
src/conf/nwfilter_conf.c | 49 ++++++++++++++++--------------------------
src/conf/nwfilter_conf.h | 14 +++++-------
src/lxc/lxc_driver.c | 3 +--
src/nwfilter/nwfilter_driver.c | 42 ++++++++++++++----------------------
src/qemu/qemu_driver.c | 3 +--
src/uml/uml_driver.c | 3 +--
6 files changed, 43 insertions(+), 71 deletions(-)
diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c
index 9927f7e..7152aae 100644
--- a/src/conf/nwfilter_conf.c
+++ b/src/conf/nwfilter_conf.c
@@ -2744,8 +2744,7 @@ cleanup:
static int
-_virNWFilterDefLoopDetect(virConnectPtr conn,
- virNWFilterObjListPtr nwfilters,
+_virNWFilterDefLoopDetect(virNWFilterObjListPtr nwfilters,
virNWFilterDefPtr def,
const char *filtername)
{
@@ -2769,7 +2768,7 @@ _virNWFilterDefLoopDetect(virConnectPtr conn,
obj = virNWFilterObjFindByName(nwfilters,
entry->include->filterref);
if (obj) {
- rc = _virNWFilterDefLoopDetect(conn, nwfilters,
+ rc = _virNWFilterDefLoopDetect(nwfilters,
obj->def, filtername);
virNWFilterObjUnlock(obj);
@@ -2785,7 +2784,6 @@ _virNWFilterDefLoopDetect(virConnectPtr conn,
/*
* virNWFilterDefLoopDetect:
- * @conn: pointer to virConnect object
* @nwfilters : the nwfilters to search
* @def : the filter definition that may add a loop and is to be tested
*
@@ -2795,11 +2793,10 @@ _virNWFilterDefLoopDetect(virConnectPtr conn,
* Returns 0 in case no loop was detected, -1 otherwise.
*/
static int
-virNWFilterDefLoopDetect(virConnectPtr conn,
- virNWFilterObjListPtr nwfilters,
+virNWFilterDefLoopDetect(virNWFilterObjListPtr nwfilters,
virNWFilterDefPtr def)
{
- return _virNWFilterDefLoopDetect(conn, nwfilters, def, def->name);
+ return _virNWFilterDefLoopDetect(nwfilters, def, def->name);
}
int nCallbackDriver;
@@ -2858,7 +2855,7 @@ static void *virNWFilterDomainFWUpdateOpaque;
* error. This should be called upon reloading of the driver.
*/
int
-virNWFilterInstFiltersOnAllVMs(virConnectPtr conn)
+virNWFilterInstFiltersOnAllVMs(void)
{
size_t i;
struct domUpdateCBStruct cb = {
@@ -2868,15 +2865,14 @@ virNWFilterInstFiltersOnAllVMs(virConnectPtr conn)
};
for (i = 0; i < nCallbackDriver; i++)
- callbackDrvArray[i]->vmFilterRebuild(conn,
- virNWFilterDomainFWUpdateCB,
+ callbackDrvArray[i]->vmFilterRebuild(virNWFilterDomainFWUpdateCB,
&cb);
return 0;
}
static int
-virNWFilterTriggerVMFilterRebuild(virConnectPtr conn)
+virNWFilterTriggerVMFilterRebuild(void)
{
size_t i;
int ret = 0;
@@ -2890,8 +2886,7 @@ virNWFilterTriggerVMFilterRebuild(virConnectPtr conn)
return -1;
for (i = 0; i < nCallbackDriver; i++) {
- if (callbackDrvArray[i]->vmFilterRebuild(conn,
- virNWFilterDomainFWUpdateCB,
+ if (callbackDrvArray[i]->vmFilterRebuild(virNWFilterDomainFWUpdateCB,
&cb) < 0)
ret = -1;
}
@@ -2900,15 +2895,13 @@ virNWFilterTriggerVMFilterRebuild(virConnectPtr conn)
cb.step = STEP_TEAR_NEW; /* rollback */
for (i = 0; i < nCallbackDriver; i++)
- callbackDrvArray[i]->vmFilterRebuild(conn,
- virNWFilterDomainFWUpdateCB,
+ callbackDrvArray[i]->vmFilterRebuild(virNWFilterDomainFWUpdateCB,
&cb);
} else {
cb.step = STEP_TEAR_OLD; /* switch over */
for (i = 0; i < nCallbackDriver; i++)
- callbackDrvArray[i]->vmFilterRebuild(conn,
- virNWFilterDomainFWUpdateCB,
+ callbackDrvArray[i]->vmFilterRebuild(virNWFilterDomainFWUpdateCB,
&cb);
}
@@ -2919,14 +2912,13 @@ virNWFilterTriggerVMFilterRebuild(virConnectPtr conn)
int
-virNWFilterTestUnassignDef(virConnectPtr conn,
- virNWFilterObjPtr nwfilter)
+virNWFilterTestUnassignDef(virNWFilterObjPtr nwfilter)
{
int rc = 0;
nwfilter->wantRemoved = 1;
/* trigger the update on VMs referencing the filter */
- if (virNWFilterTriggerVMFilterRebuild(conn))
+ if (virNWFilterTriggerVMFilterRebuild())
rc = -1;
nwfilter->wantRemoved = 0;
@@ -2965,8 +2957,7 @@ cleanup:
}
virNWFilterObjPtr
-virNWFilterObjAssignDef(virConnectPtr conn,
- virNWFilterObjListPtr nwfilters,
+virNWFilterObjAssignDef(virNWFilterObjListPtr nwfilters,
virNWFilterDefPtr def)
{
virNWFilterObjPtr nwfilter;
@@ -2985,7 +2976,7 @@ virNWFilterObjAssignDef(virConnectPtr conn,
virNWFilterObjUnlock(nwfilter);
}
- if (virNWFilterDefLoopDetect(conn, nwfilters, def) < 0) {
+ if (virNWFilterDefLoopDetect(nwfilters, def) < 0) {
virReportError(VIR_ERR_OPERATION_FAILED,
"%s", _("filter would introduce a loop"));
return NULL;
@@ -3004,7 +2995,7 @@ virNWFilterObjAssignDef(virConnectPtr conn,
nwfilter->newDef = def;
/* trigger the update on VMs referencing the filter */
- if (virNWFilterTriggerVMFilterRebuild(conn)) {
+ if (virNWFilterTriggerVMFilterRebuild()) {
nwfilter->newDef = NULL;
virNWFilterUnlockFilterUpdates();
virNWFilterObjUnlock(nwfilter);
@@ -3046,8 +3037,7 @@ virNWFilterObjAssignDef(virConnectPtr conn,
static virNWFilterObjPtr
-virNWFilterObjLoad(virConnectPtr conn,
- virNWFilterObjListPtr nwfilters,
+virNWFilterObjLoad(virNWFilterObjListPtr nwfilters,
const char *file,
const char *path)
{
@@ -3066,7 +3056,7 @@ virNWFilterObjLoad(virConnectPtr conn,
return NULL;
}
- if (!(nwfilter = virNWFilterObjAssignDef(conn, nwfilters, def))) {
+ if (!(nwfilter = virNWFilterObjAssignDef(nwfilters, def))) {
virNWFilterDefFree(def);
return NULL;
}
@@ -3082,8 +3072,7 @@ virNWFilterObjLoad(virConnectPtr conn,
int
-virNWFilterLoadAllConfigs(virConnectPtr conn,
- virNWFilterObjListPtr nwfilters,
+virNWFilterLoadAllConfigs(virNWFilterObjListPtr nwfilters,
const char *configDir)
{
DIR *dir;
@@ -3111,7 +3100,7 @@ virNWFilterLoadAllConfigs(virConnectPtr conn,
if (!(path = virFileBuildPath(configDir, entry->d_name, NULL)))
continue;
- nwfilter = virNWFilterObjLoad(conn, nwfilters, entry->d_name, path);
+ nwfilter = virNWFilterObjLoad(nwfilters, entry->d_name, path);
if (nwfilter)
virNWFilterObjUnlock(nwfilter);
diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h
index e470615..29906f1 100644
--- a/src/conf/nwfilter_conf.h
+++ b/src/conf/nwfilter_conf.h
@@ -687,12 +687,10 @@ int virNWFilterObjSaveDef(virNWFilterDriverStatePtr driver,
int virNWFilterObjDeleteDef(virNWFilterObjPtr nwfilter);
-virNWFilterObjPtr virNWFilterObjAssignDef(virConnectPtr conn,
- virNWFilterObjListPtr nwfilters,
+virNWFilterObjPtr virNWFilterObjAssignDef(virNWFilterObjListPtr nwfilters,
virNWFilterDefPtr def);
-int virNWFilterTestUnassignDef(virConnectPtr conn,
- virNWFilterObjPtr nwfilter);
+int virNWFilterTestUnassignDef(virNWFilterObjPtr nwfilter);
virNWFilterDefPtr virNWFilterDefParseNode(xmlDocPtr xml,
xmlNodePtr root);
@@ -706,8 +704,7 @@ int virNWFilterSaveXML(const char *configDir,
int virNWFilterSaveConfig(const char *configDir,
virNWFilterDefPtr def);
-int virNWFilterLoadAllConfigs(virConnectPtr conn,
- virNWFilterObjListPtr nwfilters,
+int virNWFilterLoadAllConfigs(virNWFilterObjListPtr nwfilters,
const char *configDir);
char *virNWFilterConfigFile(const char *dir,
@@ -725,11 +722,10 @@ void virNWFilterUnlockFilterUpdates(void);
int virNWFilterConfLayerInit(virDomainObjListIterator domUpdateCB, void *opaque);
void virNWFilterConfLayerShutdown(void);
-int virNWFilterInstFiltersOnAllVMs(virConnectPtr conn);
+int virNWFilterInstFiltersOnAllVMs(void);
-typedef int (*virNWFilterRebuild)(virConnectPtr conn,
- virDomainObjListIterator domUpdateCB,
+typedef int (*virNWFilterRebuild)(virDomainObjListIterator domUpdateCB,
void *data);
typedef void (*virNWFilterVoidCall)(void);
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 8b13f84..e3a34d6 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -84,8 +84,7 @@ virLXCDriverPtr lxc_driver = NULL;
/* callbacks for nwfilter */
static int
-lxcVMFilterRebuild(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainObjListIterator iter, void *data)
+lxcVMFilterRebuild(virDomainObjListIterator iter, void *data)
{
return virDomainObjListForEach(lxc_driver->domains, iter, data);
}
diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
index 6e20e03..d25c6f2 100644
--- a/src/nwfilter/nwfilter_driver.c
+++ b/src/nwfilter/nwfilter_driver.c
@@ -235,8 +235,7 @@ nwfilterStateInitialize(bool privileged,
VIR_FREE(base);
- if (virNWFilterLoadAllConfigs(NULL,
- &driverState->nwfilters,
+ if (virNWFilterLoadAllConfigs(&driverState->nwfilters,
driverState->configDir) < 0)
goto error;
@@ -272,37 +271,28 @@ err_free_driverstate:
* files and update its state
*/
static int
-nwfilterStateReload(void) {
- virConnectPtr conn;
-
- if (!driverState) {
+nwfilterStateReload(void)
+{
+ if (!driverState)
return -1;
- }
if (!driverState->privileged)
return 0;
- conn = virConnectOpen("qemu:///system");
-
- if (conn) {
- virNWFilterDHCPSnoopEnd(NULL);
- /* shut down all threads -- they will be restarted if necessary */
- virNWFilterLearnThreadsTerminate(true);
-
- nwfilterDriverLock(driverState);
- virNWFilterCallbackDriversLock();
+ virNWFilterDHCPSnoopEnd(NULL);
+ /* shut down all threads -- they will be restarted if necessary */
+ virNWFilterLearnThreadsTerminate(true);
- virNWFilterLoadAllConfigs(conn,
- &driverState->nwfilters,
- driverState->configDir);
+ nwfilterDriverLock(driverState);
+ virNWFilterCallbackDriversLock();
- virNWFilterCallbackDriversUnlock();
- nwfilterDriverUnlock(driverState);
+ virNWFilterLoadAllConfigs(&driverState->nwfilters,
+ driverState->configDir);
- virNWFilterInstFiltersOnAllVMs(conn);
+ virNWFilterCallbackDriversUnlock();
+ nwfilterDriverUnlock(driverState);
- virConnectClose(conn);
- }
+ virNWFilterInstFiltersOnAllVMs();
return 0;
}
@@ -573,7 +563,7 @@ nwfilterDefineXML(virConnectPtr conn,
if (virNWFilterDefineXMLEnsureACL(conn, def) < 0)
goto cleanup;
- if (!(nwfilter = virNWFilterObjAssignDef(conn, &driver->nwfilters, def)))
+ if (!(nwfilter = virNWFilterObjAssignDef(&driver->nwfilters, def)))
goto cleanup;
if (virNWFilterObjSaveDef(driver, nwfilter, def) < 0) {
@@ -617,7 +607,7 @@ nwfilterUndefine(virNWFilterPtr obj) {
if (virNWFilterUndefineEnsureACL(obj->conn, nwfilter->def) < 0)
goto cleanup;
- if (virNWFilterTestUnassignDef(obj->conn, nwfilter) < 0) {
+ if (virNWFilterTestUnassignDef(nwfilter) < 0) {
virReportError(VIR_ERR_OPERATION_INVALID,
"%s",
_("nwfilter is in use"));
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e8bc04d..068d29f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -177,8 +177,7 @@ static void
qemuVMDriverUnlock(void) {}
static int
-qemuVMFilterRebuild(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainObjListIterator iter, void *data)
+qemuVMFilterRebuild(virDomainObjListIterator iter, void *data)
{
return virDomainObjListForEach(qemu_driver->domains, iter, data);
}
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index 9ca352f..eb02542 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -148,8 +148,7 @@ static int umlMonitorCommand(const struct uml_driver *driver,
static struct uml_driver *uml_driver = NULL;
static int
-umlVMFilterRebuild(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainObjListIterator iter, void *data)
+umlVMFilterRebuild(virDomainObjListIterator iter, void *data)
{
return virDomainObjListForEach(uml_driver->domains, iter, data);
}

View File

@ -0,0 +1,31 @@
From 009332c5530a3f3419578b62b44a98ff8de31ca2 Mon Sep 17 00:00:00 2001
From: Cole Robinson <crobinso@redhat.com>
Date: Tue, 1 Oct 2013 07:55:19 -0400
Subject: [PATCH] qemu: cgroup: Fix crash if starting nographics guest
We can dereference graphics[0] even if guest has no graphics device
configured. I screwed this up in a216e6487255d3b65d97c7ec1fa5da63dbced902
https://bugzilla.redhat.com/show_bug.cgi?id=1014088
(cherry picked from commit a924d9d083c215df6044387057c501d9aa338b96)
---
src/qemu/qemu_cgroup.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index f95c7f2..ace7e35 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -490,9 +490,10 @@ qemuSetupDevicesCgroup(virQEMUDriverPtr driver,
if (vm->def->nsounds &&
((!vm->def->ngraphics && cfg->nogfxAllowHostAudio) ||
- ((vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
+ (vm->def->graphics &&
+ ((vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
cfg->vncAllowHostAudio) ||
- (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL)))) {
+ (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL))))) {
rv = virCgroupAllowDeviceMajor(priv->cgroup, 'c', DEVICE_SND_MAJOR,
VIR_CGROUP_DEVICE_RW);
virDomainAuditCgroupMajor(vm, priv->cgroup, "allow", DEVICE_SND_MAJOR,

View File

@ -367,7 +367,7 @@
Summary: Library providing a simple virtualization API Summary: Library providing a simple virtualization API
Name: libvirt Name: libvirt
Version: 1.1.3 Version: 1.1.3
Release: 1%{?dist}%{?extra_release} Release: 2%{?dist}%{?extra_release}
License: LGPLv2+ License: LGPLv2+
Group: Development/Libraries Group: Development/Libraries
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
@ -378,6 +378,16 @@ URL: http://libvirt.org/
%endif %endif
Source: http://libvirt.org/sources/%{?mainturl}libvirt-%{version}.tar.gz Source: http://libvirt.org/sources/%{?mainturl}libvirt-%{version}.tar.gz
# Allow QoS change with update-device (bz #1014200)
Patch0001: 0001-qemu_hotplug-Allow-QoS-update-in-qemuDomainChangeNet.patch
Patch0002: 0002-virNetDevBandwidthEqual-Make-it-more-robust.patch
# Fix nwfilter crash during firewalld install (bz #1014762)
Patch0003: 0003-Remove-virConnectPtr-arg-from-virNWFilterDefParse.patch
Patch0004: 0004-Don-t-pass-virConnectPtr-in-nwfilter-struct-domUpdat.patch
Patch0005: 0005-Remove-use-of-virConnectPtr-from-all-remaining-nwfil.patch
# Fix crash with nographics (bz #1014088)
Patch0006: 0006-qemu-cgroup-Fix-crash-if-starting-nographics-guest.patch
%if %{with_libvirtd} %if %{with_libvirtd}
Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon = %{version}-%{release}
%if %{with_network} %if %{with_network}
@ -1152,6 +1162,16 @@ of recent versions of Linux (and other OSes).
%prep %prep
%setup -q %setup -q
# Allow QoS change with update-device (bz #1014200)
%patch0001 -p1
%patch0002 -p1
# Fix nwfilter crash during firewalld install (bz #1014762)
%patch0003 -p1
%patch0004 -p1
%patch0005 -p1
# Fix crash with nographics (bz #1014088)
%patch0006 -p1
%build %build
%if ! %{with_xen} %if ! %{with_xen}
%define _without_xen --without-xen %define _without_xen --without-xen
@ -2111,6 +2131,11 @@ fi
%endif %endif
%changelog %changelog
* Sun Oct 06 2013 Cole Robinson <crobinso@redhat.com> - 1.1.3-2
- Allow QoS change with update-device (bz #1014200)
- Fix nwfilter crash during firewalld install (bz #1014762)
- Fix crash with nographics (bz #1014088)
* Tue Oct 1 2013 Daniel Veillard <veillard@redhat.com> - 1.1.3-1 * Tue Oct 1 2013 Daniel Veillard <veillard@redhat.com> - 1.1.3-1
- VMware: Initial VMware Fusion support and various improvements - VMware: Initial VMware Fusion support and various improvements
- libvirt: add new public API virConnectGetCPUModelNames - libvirt: add new public API virConnectGetCPUModelNames