[libvirt PATCH 2/5] nwfilter: hold filter update lock when creating/deleting bindings

Laine Stump laine at redhat.com
Mon Feb 28 16:22:37 UTC 2022


On 2/25/22 10:30 AM, Daniel P. Berrangé wrote:
> The nwfilter update lock is historically acquired by the virt
> drivers in order to achieve serialization between nwfilter
> define/undefine, and instantiation/teardown of filters.
> 
> When running in the modular daemons, however, the mutex that
> the virt drivers are locking is in a completely different
> process from the mutex that the nwfilter driver is locking.
> 
> Serialization is lost and thus call from the virt driver to
> virNWFilterBindingCreateXML can deadlock with a concurrent
> call to the virNWFilterDefineXML method.
> 
> The solution is surprisingly easy, the update lock simply
> needs acquiring in the virNWFilterBindingCreateXML method
> and virNWFilterBindingUndefine method instead of in the
> virt drivers.
> 
> The only semantic difference here is that when a virtual
> machine has multiple NICs, the instantiation and teardown
> of filters is no longer serialized for the whole VM, but
> rather for each NIC. This should not be a problem since
> the virt drivers already need to cope with tearing down
> a partially created VM where only some of the NICs are
> setup.
> 
> Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>


Reviewed-by: Laine Stump <laine at redhat.com>

(I considered this patch together with 3/5 - see my comment there of why 
I think the re-ordering of the locking is safe)

> ---
>   src/nwfilter/nwfilter_driver.c | 5 +++++
>   1 file changed, 5 insertions(+)
> 
> diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
> index 08f138dd79..3ce8fce7f9 100644
> --- a/src/nwfilter/nwfilter_driver.c
> +++ b/src/nwfilter/nwfilter_driver.c
> @@ -760,11 +760,14 @@ nwfilterBindingCreateXML(virConnectPtr conn,
>       if (!(ret = virGetNWFilterBinding(conn, def->portdevname, def->filter)))
>           goto cleanup;
>   
> +    virNWFilterReadLockFilterUpdates();
>       if (virNWFilterInstantiateFilter(driver, def) < 0) {
> +        virNWFilterUnlockFilterUpdates();
>           virNWFilterBindingObjListRemove(driver->bindings, obj);
>           g_clear_pointer(&ret, virObjectUnref);
>           goto cleanup;
>       }
> +    virNWFilterUnlockFilterUpdates();
>       virNWFilterBindingObjSave(obj, driver->bindingDir);
>   
>    cleanup:
> @@ -801,7 +804,9 @@ nwfilterBindingDelete(virNWFilterBindingPtr binding)
>       if (virNWFilterBindingDeleteEnsureACL(binding->conn, def) < 0)
>           goto cleanup;
>   
> +    virNWFilterReadLockFilterUpdates();
>       virNWFilterTeardownFilter(def);
> +    virNWFilterUnlockFilterUpdates();
>       virNWFilterBindingObjDelete(obj, driver->bindingDir);
>       virNWFilterBindingObjListRemove(driver->bindings, obj);
>   




More information about the libvir-list mailing list