From 43618df1d49d59a5ff0ba7d982644a58b6804a14 Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Sun, 6 Oct 2013 15:14:15 -0400 Subject: [PATCH] Allow QoS change with update-device (bz #1014200) Fix nwfilter crash during firewalld install (bz #1014762) Fix crash with nographics (bz #1014088) --- ...ow-QoS-update-in-qemuDomainChangeNet.patch | 66 +++ ...evBandwidthEqual-Make-it-more-robust.patch | 57 +++ ...nectPtr-arg-from-virNWFilterDefParse.patch | 105 +++++ ...nnectPtr-in-nwfilter-struct-domUpdat.patch | 355 ++++++++++++++++ ...rConnectPtr-from-all-remaining-nwfil.patch | 382 ++++++++++++++++++ ...x-crash-if-starting-nographics-guest.patch | 31 ++ libvirt.spec | 27 +- 7 files changed, 1022 insertions(+), 1 deletion(-) create mode 100644 0001-qemu_hotplug-Allow-QoS-update-in-qemuDomainChangeNet.patch create mode 100644 0002-virNetDevBandwidthEqual-Make-it-more-robust.patch create mode 100644 0003-Remove-virConnectPtr-arg-from-virNWFilterDefParse.patch create mode 100644 0004-Don-t-pass-virConnectPtr-in-nwfilter-struct-domUpdat.patch create mode 100644 0005-Remove-use-of-virConnectPtr-from-all-remaining-nwfil.patch create mode 100644 0006-qemu-cgroup-Fix-crash-if-starting-nographics-guest.patch diff --git a/0001-qemu_hotplug-Allow-QoS-update-in-qemuDomainChangeNet.patch b/0001-qemu_hotplug-Allow-QoS-update-in-qemuDomainChangeNet.patch new file mode 100644 index 0000000..2f04849 --- /dev/null +++ b/0001-qemu_hotplug-Allow-QoS-update-in-qemuDomainChangeNet.patch @@ -0,0 +1,66 @@ +From d519f225d79a61451cfa62b463ea3083e9367353 Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +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 +(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; diff --git a/0002-virNetDevBandwidthEqual-Make-it-more-robust.patch b/0002-virNetDevBandwidthEqual-Make-it-more-robust.patch new file mode 100644 index 0000000..695341d --- /dev/null +++ b/0002-virNetDevBandwidthEqual-Make-it-more-robust.patch @@ -0,0 +1,57 @@ +From 658f4b3c39c9bdd490a44175742f8259dd10b84f Mon Sep 17 00:00:00 2001 +From: Michal Privoznik +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 +(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; + } diff --git a/0003-Remove-virConnectPtr-arg-from-virNWFilterDefParse.patch b/0003-Remove-virConnectPtr-arg-from-virNWFilterDefParse.patch new file mode 100644 index 0000000..cc711e2 --- /dev/null +++ b/0003-Remove-virConnectPtr-arg-from-virNWFilterDefParse.patch @@ -0,0 +1,105 @@ +From 56c170544f7a71749ef63fef650c71787c05e8af Mon Sep 17 00:00:00 2001 +From: "Daniel P. Berrange" +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 +--- + 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; diff --git a/0004-Don-t-pass-virConnectPtr-in-nwfilter-struct-domUpdat.patch b/0004-Don-t-pass-virConnectPtr-in-nwfilter-struct-domUpdat.patch new file mode 100644 index 0000000..1ada4d9 --- /dev/null +++ b/0004-Don-t-pass-virConnectPtr-in-nwfilter-struct-domUpdat.patch @@ -0,0 +1,355 @@ +From 0a5abfb22d5d030cc3780c44b805b5b92567b44a Mon Sep 17 00:00:00 2001 +From: "Daniel P. Berrange" +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 +--- + 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); + } diff --git a/0005-Remove-use-of-virConnectPtr-from-all-remaining-nwfil.patch b/0005-Remove-use-of-virConnectPtr-from-all-remaining-nwfil.patch new file mode 100644 index 0000000..8b57d20 --- /dev/null +++ b/0005-Remove-use-of-virConnectPtr-from-all-remaining-nwfil.patch @@ -0,0 +1,382 @@ +From 1766db28533e2b5a96792aa0811e5364e0bb54d4 Mon Sep 17 00:00:00 2001 +From: "Daniel P. Berrange" +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 +--- + 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); + } diff --git a/0006-qemu-cgroup-Fix-crash-if-starting-nographics-guest.patch b/0006-qemu-cgroup-Fix-crash-if-starting-nographics-guest.patch new file mode 100644 index 0000000..8b688a1 --- /dev/null +++ b/0006-qemu-cgroup-Fix-crash-if-starting-nographics-guest.patch @@ -0,0 +1,31 @@ +From 009332c5530a3f3419578b62b44a98ff8de31ca2 Mon Sep 17 00:00:00 2001 +From: Cole Robinson +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, diff --git a/libvirt.spec b/libvirt.spec index 0ce6329..7f9530d 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -367,7 +367,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 1.1.3 -Release: 1%{?dist}%{?extra_release} +Release: 2%{?dist}%{?extra_release} License: LGPLv2+ Group: Development/Libraries BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root @@ -378,6 +378,16 @@ URL: http://libvirt.org/ %endif 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} Requires: libvirt-daemon = %{version}-%{release} %if %{with_network} @@ -1152,6 +1162,16 @@ of recent versions of Linux (and other OSes). %prep %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 %if ! %{with_xen} %define _without_xen --without-xen @@ -2111,6 +2131,11 @@ fi %endif %changelog +* Sun Oct 06 2013 Cole Robinson - 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 - 1.1.3-1 - VMware: Initial VMware Fusion support and various improvements - libvirt: add new public API virConnectGetCPUModelNames