[libvirt] [PATCH v2 05/11] qemu: handle libvirtd restart after host usb device unplug

Daniel Henrique Barboza danielhb413 at gmail.com
Thu Sep 12 19:49:50 UTC 2019



On 9/9/19 8:33 AM, Nikolay Shirokovskiy wrote:
> It is possible for libvirtd to go down before DEVICE_DELETED event is
> delivered upon usb hostdev unplug and to receive the event after the
> libvirtd is up. In order to handle this case we need to save
> usb hostdev deleteAction is status file.

nit: s/is/in ?


Reviewed-by: Daniel Henrique Barboza <danielhb413 at gmail.com>



>
> Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy at virtuozzo.com>
> ---
>   src/conf/domain_conf.c | 26 ++++++++++++++++++++++++++
>   src/conf/domain_conf.h |  1 +
>   src/qemu/qemu_driver.c | 20 ++++++++++++++++++--
>   3 files changed, 45 insertions(+), 2 deletions(-)
>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index b7a342bb91..c200af050c 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -1236,6 +1236,13 @@ VIR_ENUM_IMPL(virDomainShmemModel,
>                 "ivshmem-doorbell",
>   );
>   
> +VIR_ENUM_IMPL(virDomainHostdevDeleteAction,
> +              VIR_DOMAIN_HOSTDEV_DELETE_ACTION_LAST,
> +              "none",
> +              "delete",
> +              "unplug"
> +);
> +
>   VIR_ENUM_IMPL(virDomainLaunchSecurity,
>                 VIR_DOMAIN_LAUNCH_SECURITY_LAST,
>                 "",
> @@ -7533,6 +7540,7 @@ virDomainHostdevSubsysUSBDefParseXML(xmlNodePtr node,
>       virDomainHostdevSubsysUSBPtr usbsrc = &def->source.subsys.u.usb;
>       VIR_AUTOFREE(char *) startupPolicy = NULL;
>       VIR_AUTOFREE(char *) autoAddress = NULL;
> +    VIR_AUTOFREE(char *) deleteAction = NULL;
>   
>       if ((startupPolicy = virXMLPropString(node, "startupPolicy"))) {
>           def->startupPolicy =
> @@ -7550,6 +7558,18 @@ virDomainHostdevSubsysUSBDefParseXML(xmlNodePtr node,
>               usbsrc->autoAddress = true;
>       }
>   
> +    if ((deleteAction = virXMLPropString(node, "deleteAction"))) {
> +        def->deleteAction =
> +            virDomainHostdevDeleteActionTypeFromString(deleteAction);
> +
> +        if (def->deleteAction <= 0) {
> +            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> +                           _("Unknown deleteAction '%s'"),
> +                           deleteAction);
> +            goto out;
> +        }
> +    }
> +
>       /* Product can validly be 0, so we need some extra help to determine
>        * if it is uninitialized*/
>       got_product = false;
> @@ -24905,6 +24925,12 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
>   
>           if (def->missing && !(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE))
>               virBufferAddLit(buf, " missing='yes'");
> +
> +        if (def->deleteAction && (flags & VIR_DOMAIN_DEF_FORMAT_STATUS)) {
> +            const char *deleteAction;
> +            deleteAction = virDomainHostdevDeleteActionTypeToString(def->deleteAction);
> +            virBufferAsprintf(buf, " deleteAction='%s'", deleteAction);
> +        }
>       }
>   
>       if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI &&
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 19a5b21462..df88790ac0 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -338,6 +338,7 @@ typedef enum {
>   
>       VIR_DOMAIN_HOSTDEV_DELETE_ACTION_LAST
>   } virDomainHostdevDeleteActionType;
> +VIR_ENUM_DECL(virDomainHostdevDeleteAction);
>   
>   
>   /* basic device for direct passthrough */
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index ce41b0a8d9..f1802b5d44 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -5272,10 +5272,13 @@ processUSBAddedEvent(virQEMUDriverPtr driver,
>   {
>       virDomainHostdevDefPtr hostdev;
>       virDomainHostdevSubsysUSBPtr usbsrc;
> +    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
>       size_t i;
>   
> -    if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
> +    if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) {
> +        virObjectUnref(cfg);
>           return;
> +    }
>   
>       if (!virDomainObjIsActive(vm)) {
>           VIR_DEBUG("Domain is not running");
> @@ -5300,8 +5303,13 @@ processUSBAddedEvent(virQEMUDriverPtr driver,
>       if (qemuDomainAttachHostDevice(driver, vm, hostdev) < 0)
>           goto cleanup;
>   
> +    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
> +        VIR_WARN("unable to save domain status after plugging device %s",
> +                 hostdev->info->alias);
> +
>    cleanup:
>       qemuDomainObjEndJob(driver, vm);
> +    virObjectUnref(cfg);
>   }
>   
>   
> @@ -5313,9 +5321,12 @@ processUSBRemovedEvent(virQEMUDriverPtr driver,
>       size_t i;
>       virDomainHostdevDefPtr hostdev;
>       virDomainDeviceDef dev = { .type = VIR_DOMAIN_DEVICE_HOSTDEV };
> +    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
>   
> -    if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
> +    if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) {
> +        virObjectUnref(cfg);
>           return;
> +    }
>   
>       if (!virDomainObjIsActive(vm)) {
>           VIR_DEBUG("Domain is not running");
> @@ -5348,8 +5359,13 @@ processUSBRemovedEvent(virQEMUDriverPtr driver,
>       if (qemuDomainDetachDeviceLive(vm, &dev, driver, true, true) < 0)
>           goto cleanup;
>   
> +    if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
> +        VIR_WARN("unable to save domain status after unplugging device %s",
> +                 hostdev->info->alias);
> +
>    cleanup:
>       qemuDomainObjEndJob(driver, vm);
> +    virObjectUnref(cfg);
>   }
>   
>   




More information about the libvir-list mailing list