
On Thu, Jan 23, 2014 at 04:13:57PM -0500, Stefan Berger wrote:
On 01/23/2014 07:37 AM, Daniel P. Berrange wrote:
Makes sense... there are other paths as well:
- SIGHUP or restart of libvirt that recreates all filters - late instantiation of filters following detection of VM's IP address
Ok, yes, I see those now. I was struggling to understand just what codepaths could result in __virNWFilterInstantiateFilter being invoked so I generated a callgraph for that function http://berrange.fedorapeople.org/nwfilter.ps tracing the calls, confirms there are the 6 entry points - filter define - filter undefine - state reload on sighup or dbus notify - vm startup / hotplug - vm shutdown / hotunplug - dhcp / ip snooping the first 3 will require write locks, while the last three will only require read locks. I'm squashing the conversion to read/write lock into this patch, since otherwise the intermediate state would be deadlock prone.
src/conf/nwfilter_conf.c::virNWFilterObjLoad : I don't see this function grabbing the lock. I think this is missing.
virNWFilterObjLoad is called by StateInitialize or StateReload and only the reload function requires the lock. So I'm adding the lock to that function
diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index 89913cf8..f0e78ed 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -935,7 +935,6 @@ _virNWFilterInstantiateFilter(virNWFilterDriverStatePtr driver, int ifindex; int rc;
- virNWFilterLockFilterUpdates();
/* after grabbing the filter update lock check for the interface; if it's not there anymore its filters will be or are being removed @@ -964,7 +963,6 @@ _virNWFilterInstantiateFilter(virNWFilterDriverStatePtr driver, foundNewFilter);
cleanup: - virNWFilterUnlockFilterUpdates();
return rc; }
This function is called by virNWFilterInstantiateFilter and virNWFilterUpdateInstantiateFilter. So, in the former case this is called when a VM is started, in the latter case if VMs' filters are updated while the VM is running. I think you are covering the VM creation case with the above calls for lxc and further below with the changes to the qemu driver and the uml driver.
There is at least one other part that needs to be covered:
src/conf/nwfilter_conf.c::virNWFilterInstFiltersOnAllVMs :: kicked off by nwfilterStateReload upon SIGHUP. We need a lock there now.
src/conf/nwfilter_conf.c::virNWFilterTriggerVMFilterRebuild:: - called by virNWFilterTestUnassignDef: - called by src/nwfilter/nwfilter/nwfilterUndefine:: You seem to just reorder some locks there; now we need a (writer) lock there - called by virNWFilterObjAssignDef: which must be called with lock called following above reasoning
Yep, I concur and have added lock calls to the StateReload function
@@ -984,8 +982,6 @@ virNWFilterInstantiateFilterLate(virNWFilterDriverStatePtr driver, int rc; bool foundNewFilter = false;
- virNWFilterLockFilterUpdates(); - rc = __virNWFilterInstantiateFilter(driver, vmuuid, true, @@ -1009,8 +1005,6 @@ virNWFilterInstantiateFilterLate(virNWFilterDriverStatePtr driver, } }
- virNWFilterUnlockFilterUpdates(); - return rc; }
This function here is called by src/nwfilter/nwfilter_learnip.c::learnIPAddressThread src/nwfilter/nwfilter_dhcpsnoop.c::virNWFilterSnoopIPLeaseInstallRule
They instantiate the filters once a VM's IP address has been detected. So this is where the *Late() comes from.
If you remove the locking from here, you have to lock it there. Considering what you do layer, I would keep the lock here and convert this into a reader lock layer on.
Yes, now I'm squashing the read/write lock conversion in, I'll keep the locking in this location. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|