aboutsummaryrefslogtreecommitdiff
path: root/src/lxc
diff options
context:
space:
mode:
authorLaine Stump <laine@laine.org>2012-08-09 02:18:23 -0400
committerLaine Stump <laine@laine.org>2012-08-09 23:28:00 -0400
commitb8a56f12f55d9dd71cfdb2c1178ee3bf7a9b79f4 (patch)
treec6f32446fe62471e4470324d26d6fb7bb5701b8a /src/lxc
parentbuild: fix PROBE() usage of intptr_t (diff)
downloadlibvirt-b8a56f12f55d9dd71cfdb2c1178ee3bf7a9b79f4.tar.gz
libvirt-b8a56f12f55d9dd71cfdb2c1178ee3bf7a9b79f4.tar.bz2
libvirt-b8a56f12f55d9dd71cfdb2c1178ee3bf7a9b79f4.zip
nwfilter: fix crash during filter define when lxc driver failed startup
The meat of this patch is just moving the calls to virNWFilterRegisterCallbackDriver from each hypervisor's "register" function into its "initialize" function. The rest is just code movement to allow that, and a new virNWFilterUnRegisterCallbackDriver function to undo what the register function does. The long explanation: There is an array in nwfilter called callbackDrvArray that has pointers to a table of functions for each hypervisor driver that are called by nwfilter. One of those function pointers is to a function that will lock the hypervisor driver. Entries are added to the table by calling each driver's "register" function, which happens quite early in libvirtd's startup. Sometime later, each driver's "initialize" function is called. This function allocates a driver object and stores a pointer to it in a static variable that was previously initialized to NULL. (and here's the important part...) If the "initialize" function fails, the driver object is freed, and that pointer set back to NULL (but the entry in nwfilter's callbackDrvArray is still there). When the "lock the driver" function mentioned above is called, it assumes that the driver was successfully loaded, so it blindly tries to call virMutexLock on "driver->lock". BUT, if the initialize never happened, or if it failed, "driver" is NULL. And it just happens that "lock" is always the first field in driver so it is also NULL. Boom. To fix this, the call to virNWFilterRegisterCallbackDriver for each driver shouldn't be called until the end of its (*already guaranteed successful*) "initialize" function, not during its "register" function (which is currently the case). This implies that there should also be a virNWFilterUnregisterCallbackDriver() function that is called in a driver's "shutdown" function (although in practice, that function is currently never called).
Diffstat (limited to 'src/lxc')
-rw-r--r--src/lxc/lxc_driver.c60
1 files changed, 31 insertions, 29 deletions
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index d118dd238..b7b119c9d 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -74,6 +74,35 @@ static int lxcStartup(int privileged);
static int lxcShutdown(void);
virLXCDriverPtr lxc_driver = NULL;
+/* callbacks for nwfilter */
+static int
+lxcVMFilterRebuild(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virHashIterator iter, void *data)
+{
+ virHashForEach(lxc_driver->domains.objs, iter, data);
+
+ return 0;
+}
+
+static void
+lxcVMDriverLock(void)
+{
+ lxcDriverLock(lxc_driver);
+}
+
+static void
+lxcVMDriverUnlock(void)
+{
+ lxcDriverUnlock(lxc_driver);
+}
+
+static virNWFilterCallbackDriver lxcCallbackDriver = {
+ .name = "LXC",
+ .vmFilterRebuild = lxcVMFilterRebuild,
+ .vmDriverLock = lxcVMDriverLock,
+ .vmDriverUnlock = lxcVMDriverUnlock,
+};
+
/* Functions */
static virDrvOpenStatus lxcOpen(virConnectPtr conn,
@@ -1465,6 +1494,7 @@ static int lxcStartup(int privileged)
virLXCProcessAutostartAll(lxc_driver);
+ virNWFilterRegisterCallbackDriver(&lxcCallbackDriver);
return 0;
cleanup:
@@ -1516,6 +1546,7 @@ static int lxcShutdown(void)
return -1;
lxcDriverLock(lxc_driver);
+ virNWFilterUnRegisterCallbackDriver(&lxcCallbackDriver);
virDomainObjListDeinit(&lxc_driver->domains);
virDomainEventStateFree(lxc_driver->domainEventState);
@@ -2654,34 +2685,6 @@ lxcListAllDomains(virConnectPtr conn,
return ret;
}
-static int
-lxcVMFilterRebuild(virConnectPtr conn ATTRIBUTE_UNUSED,
- virHashIterator iter, void *data)
-{
- virHashForEach(lxc_driver->domains.objs, iter, data);
-
- return 0;
-}
-
-static void
-lxcVMDriverLock(void)
-{
- lxcDriverLock(lxc_driver);
-}
-
-static void
-lxcVMDriverUnlock(void)
-{
- lxcDriverUnlock(lxc_driver);
-}
-
-static virNWFilterCallbackDriver lxcCallbackDriver = {
- .name = "LXC",
- .vmFilterRebuild = lxcVMFilterRebuild,
- .vmDriverLock = lxcVMDriverLock,
- .vmDriverUnlock = lxcVMDriverUnlock,
-};
-
/* Function Tables */
static virDriver lxcDriver = {
.no = VIR_DRV_LXC,
@@ -2761,6 +2764,5 @@ int lxcRegister(void)
{
virRegisterDriver(&lxcDriver);
virRegisterStateDriver(&lxcStateDriver);
- virNWFilterRegisterCallbackDriver(&lxcCallbackDriver);
return 0;
}