[libvirt] [PATCH v2 5/5] qemu: Use transactions from security driver

John Ferlan jferlan at redhat.com
Mon Jan 9 22:18:31 UTC 2017



On 01/09/2017 07:58 AM, Michal Privoznik wrote:
> So far if qemu is spawned under separate mount namespace in order
> to relabel everything it needs an access to the security driver
> is run in that namespace too. This has a very nasty down side -

s/is/to/

> it is being run in a separate process, so any internal state
> transition is NOT reflected in the dameon. This can lead to many

s/dameon/daemon

> sleepless nights. Therefore, use the transaction APIs so that
> libvirt developers can sleep tight again.

Having trouble sleeping lately? ;-)


> 
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
>  src/qemu/qemu_security.c | 100 ++++++++++++++---------------------------------
>  1 file changed, 30 insertions(+), 70 deletions(-)
> 
> diff --git a/src/qemu/qemu_security.c b/src/qemu/qemu_security.c
> index 9ab91e9f2..544feeb4a 100644
> --- a/src/qemu/qemu_security.c
> +++ b/src/qemu/qemu_security.c
> @@ -40,66 +40,31 @@ struct qemuSecuritySetRestoreAllLabelData {
>  };
>  
>  
> -static int
> -qemuSecuritySetRestoreAllLabelHelper(pid_t pid,
> -                                     void *opaque)
> -{
> -    struct qemuSecuritySetRestoreAllLabelData *data = opaque;
> -
> -    virSecurityManagerPostFork(data->driver->securityManager);
> -
> -    if (data->set) {
> -        VIR_DEBUG("Setting up security labels inside namespace pid=%lld",
> -                  (long long) pid);
> -        if (virSecurityManagerSetAllLabel(data->driver->securityManager,
> -                                          data->vm->def,
> -                                          data->stdin_path) < 0)
> -            return -1;
> -    } else {
> -        VIR_DEBUG("Restoring security labels inside namespace pid=%lld",
> -                  (long long) pid);
> -        if (virSecurityManagerRestoreAllLabel(data->driver->securityManager,
> -                                              data->vm->def,
> -                                              data->migrated) < 0)
> -            return -1;
> -    }
> -
> -    return 0;
> -}
> -
> -
>  int
>  qemuSecuritySetAllLabel(virQEMUDriverPtr driver,
>                          virDomainObjPtr vm,
>                          const char *stdin_path)
>  {
> -    struct qemuSecuritySetRestoreAllLabelData data;
> +    int ret = -1;
>  
> -    memset(&data, 0, sizeof(data));
> +    if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT) &&
> +        virSecurityManagerTransactionStart(driver->securityManager) < 0)
> +        goto cleanup;
>  
> -    data.set = true;
> -    data.driver = driver;
> -    data.vm = vm;
> -    data.stdin_path = stdin_path;
> +    if (virSecurityManagerSetAllLabel(driver->securityManager,
> +                                      vm->def,
> +                                      stdin_path) < 0)
> +        goto cleanup;
>  
> -    if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT)) {
> -        if (virSecurityManagerPreFork(driver->securityManager) < 0)
> -            return -1;

Both paths have removed the PreFork/PostFork processing... Is that then
no longer required?  This is/was the only PreFork caller I think.

> -        if (virProcessRunInMountNamespace(vm->pid,
> -                                          qemuSecuritySetRestoreAllLabelHelper,
> -                                          &data) < 0) {
> -            virSecurityManagerPostFork(driver->securityManager);
> -            return -1;
> -        }
> -        virSecurityManagerPostFork(driver->securityManager);
> +    if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT) &&
> +        virSecurityManagerTransactionCommit(driver->securityManager,
> +                                            vm->pid) < 0)
> +        goto cleanup;


Once we've entered Commit - calling Abort is a noop since Commit takes
the 'list', clears the thread local storage, and will free the list on exit.

>  
> -    } else {
> -        if (virSecurityManagerSetAllLabel(driver->securityManager,
> -                                          vm->def,
> -                                          stdin_path) < 0)
> -            return -1;
> -    }
> -    return 0;
> +    ret = 0;
> + cleanup:
> +    virSecurityManagerTransactionAbort(driver->securityManager);
> +    return ret;
>  }
>  
>  
> @@ -108,27 +73,22 @@ qemuSecurityRestoreAllLabel(virQEMUDriverPtr driver,
>                              virDomainObjPtr vm,
>                              bool migrated)
>  {
> -    struct qemuSecuritySetRestoreAllLabelData data;
> +    if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT) &&
> +        virSecurityManagerTransactionStart(driver->securityManager) < 0)
> +        goto cleanup;
>  
> -    memset(&data, 0, sizeof(data));
> -
> -    data.driver = driver;
> -    data.vm = vm;
> -    data.migrated = migrated;
> -
> -    if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT)) {
> -        if (virSecurityManagerPreFork(driver->securityManager) < 0)
> -            return;
> -
> -        virProcessRunInMountNamespace(vm->pid,
> -                                      qemuSecuritySetRestoreAllLabelHelper,
> -                                      &data);
> -        virSecurityManagerPostFork(driver->securityManager);
> -    } else {
> -        virSecurityManagerRestoreAllLabel(driver->securityManager,
> +    if (virSecurityManagerRestoreAllLabel(driver->securityManager,
>                                            vm->def,
> -                                          migrated);
> -    }
> +                                          migrated) < 0)
> +        goto cleanup;

This would seemingly be the only place where goto cleanup is necessary

John

> +
> +    if (qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT) &&
> +        virSecurityManagerTransactionCommit(driver->securityManager,
> +                                            vm->pid) < 0)
> +        goto cleanup;
> +
> + cleanup:
> +    virSecurityManagerTransactionAbort(driver->securityManager);
>  }
>  
>  
> 




More information about the libvir-list mailing list