[libvirt] [RFC PATCH] check whether domain is active after qemuDomainObjExitMonitor* returns

Daniel P. Berrange berrange at redhat.com
Wed Apr 13 18:34:23 UTC 2011


On Mon, Apr 11, 2011 at 01:41:55PM +0800, Wen Congyang wrote:
> qemu may quited unexpectedly when invoking a monitor command. And priv->mon
> will be NULL after qemuDomainObjExitMonitor* returns. So we must not use it.
> Unfortunately we still use it, and it will cause libvirtd crashed.
> 
> As Eric suggested, qemuDomainObjExitMonitor* should be made to return the value
> of vm active after regaining lock, and marked ATTRIBUTE_RETURN_CHECK, to force
> all other callers to detect the case of a monitor command completing successfully
> but then the VM disappearing in the window between command completion and regaining
> the vm lock.

> @@ -578,7 +578,7 @@ void qemuDomainObjEnterMonitor(virDomainObjPtr obj)
>   *
>   * Should be paired with an earlier qemuDomainObjEnterMonitor() call
>   */
> -void qemuDomainObjExitMonitor(virDomainObjPtr obj)
> +int qemuDomainObjExitMonitor(virDomainObjPtr obj)
>  {
>      qemuDomainObjPrivatePtr priv = obj->privateData;
>      int refs;
> @@ -588,11 +588,20 @@ void qemuDomainObjExitMonitor(virDomainObjPtr obj)
>      if (refs > 0)
>          qemuMonitorUnlock(priv->mon);
>  
> +    /* Note: qemu may quited unexpectedly here, and the monitor will be freed.
> +     * If it happened, priv->mon will be null.
> +     */
> +
>      virDomainObjLock(obj);
>  
>      if (refs == 0) {
>          priv->mon = NULL;
>      }
> +
> +    if (priv->mon == NULL)
> +        return -1;

Perhaps here we should do

          qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("guest unexpectedly quit"));


> +    else
> +        return 0;
>  }
>  
>  
> @@ -621,8 +630,8 @@ void qemuDomainObjEnterMonitorWithDriver(struct qemud_driver *driver,
>   *
>   * Should be paired with an earlier qemuDomainObjEnterMonitorWithDriver() call
>   */
> -void qemuDomainObjExitMonitorWithDriver(struct qemud_driver *driver,
> -                                        virDomainObjPtr obj)
> +int qemuDomainObjExitMonitorWithDriver(struct qemud_driver *driver,
> +                                       virDomainObjPtr obj)
>  {
>      qemuDomainObjPrivatePtr priv = obj->privateData;
>      int refs;
> @@ -632,12 +641,21 @@ void qemuDomainObjExitMonitorWithDriver(struct qemud_driver *driver,
>      if (refs > 0)
>          qemuMonitorUnlock(priv->mon);
>  
> +    /* Note: qemu may quited unexpectedly here, and the monitor will be freed.
> +     * If it happened, priv->mon will be null.
> +     */
> +
>      qemuDriverLock(driver);
>      virDomainObjLock(obj);
>  
>      if (refs == 0) {
>          priv->mon = NULL;
>      }
> +
> +    if (priv->mon == NULL)
> +        return -1;

And the same here

> +    else
> +        return 0;
>  }
>  

> @@ -1452,7 +1452,11 @@ static int qemudDomainShutdown(virDomainPtr dom) {
>      priv = vm->privateData;
>      qemuDomainObjEnterMonitor(vm);
>      ret = qemuMonitorSystemPowerdown(priv->mon);
> -    qemuDomainObjExitMonitor(vm);
> +    if (qemuDomainObjExitMonitor(vm) < 0) {
> +        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                        _("guest unexpectedly quit"));
> +        ret = -1;
> +    }

So we can avoid qemuReportError() here, and in every single other
place where ExitMonitor is called. It would make the code a bit
shorter

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 :|




More information about the libvir-list mailing list