[libvirt] [PATCH 11/34] Properly support SCSI drive hotplug

Daniel Veillard veillard at redhat.com
Fri Jan 15 14:59:56 UTC 2010


On Fri, Jan 08, 2010 at 05:23:07PM +0000, Daniel P. Berrange wrote:
> The current SCSI hotplug support attaches a brand new SCSI controller
> for every disk. This is broken because the semantics differ from those
> used when starting the VM initially. In the latter case, each SCSI
> controller is filled before a new one is added.
> 
> If the user specifies an high drive index (sdazz) then at initial
> startup, many intermediate SCSI controllers may be added with no
> drives.

  Argh, okay :-)

> This patch changes SCSI hotplug so that it exactly matches the
> behaviour of initial startup. First the SCSI controller number is
> determined for the drive to be hotplugged. If any controller upto
> and including that controller number is not yet present, it is
> attached. Then finally the drive is attached to the last controller.
> 
> NB, this breaks SCSI hotunplug, because there is no 'drive_del'
> command in current QEMU. Previous SCSI hotunplug was broken in
> any case because it was unplugging the entire controller, not
> just the drive in question.
> 
> A future QEMU will allow proper SCSI hotunplug of a drive.
> 
> This patch is derived from work done by Wolfgang Mauerer on disk
> controllers.
> 
> * src/qemu/qemu_driver.c: Fix SCSI hotplug to add a drive to
>  the correct controller, instead of just attaching a new
>   controller.
> * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
>   src/qemu/qemu_monitor_json.c, src/qemu/qemu_monitor_json.h,
>   src/qemu/qemu_monitor_text.c, src/qemu/qemu_monitor_text.h: Add
>   support for 'drive_add' command
> ---
>  src/libvirt_private.syms     |    1 +
>  src/qemu/qemu_driver.c       |  123 +++++++++++++++++++++++++++++++++++++++--
>  src/qemu/qemu_monitor.c      |   20 +++++++
>  src/qemu/qemu_monitor.h      |    5 ++
>  src/qemu/qemu_monitor_json.c |   81 +++++++++++++++++++++++++---
>  src/qemu/qemu_monitor_json.h |    5 ++
>  src/qemu/qemu_monitor_text.c |  102 ++++++++++++++++++++++++++++++++++
>  src/qemu/qemu_monitor_text.h |    5 ++
>  8 files changed, 329 insertions(+), 13 deletions(-)
[...]
> +static virDomainControllerDefPtr
> +qemuDomainFindOrCreateSCSIDiskController(virConnectPtr conn,
> +                                         struct qemud_driver *driver,
> +                                         virDomainObjPtr vm,
> +                                         int controller)
> +{
> +    int i;
> +    virDomainControllerDefPtr cont;
> +    for (i = 0 ; i < vm->def->ncontrollers ; i++) {
> +        cont = vm->def->controllers[i];
> +
> +        if (cont->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
> +            continue;
> +
> +        if (cont->idx == controller)
> +            return cont;
> +    }
> +
> +    /* No SCSI controller present, for back compatability we
> +     * now hotplug a controller */
> +    if (VIR_ALLOC(cont) < 0) {
> +        virReportOOMError(conn);
> +        return NULL;
> +    }
> +    cont->type = VIR_DOMAIN_CONTROLLER_TYPE_SCSI;
> +    cont->idx = 0;
> +
> +    VIR_INFO0("No SCSI controller present, hotplugging one");
> +    if (qemudDomainAttachPciControllerDevice(conn, driver,
> +                                             vm, cont) < 0) {
> +        VIR_FREE(cont);
> +        return NULL;
> +    }
> +    return cont;
> +}

  cosmetic change, formatting the comment and blank line after
argument declaration, if you can sneak it in

> @@ -1515,7 +1514,75 @@ int qemuMonitorJSONAttachPCIDiskController(qemuMonitorPtr mon,
>          ret = qemuMonitorJSONCheckError(cmd, reply);
>  
>      if (ret == 0 &&
> -        qemuMonitorJSONGetGuestAddress(reply, guestAddr) < 0)
> +        qemuMonitorJSONGetGuestPCIAddress(reply, guestAddr) < 0)
> +        ret = -1;
> +
> +    virJSONValueFree(cmd);
> +    virJSONValueFree(reply);
> +    return ret;
> +}

  Hum, looks like a leak plug too here, or I got confused by the patch


> +    if (ret == 0 &&
> +        qemuMonitorJSONGetGuestDriveAddress(reply, driveAddr) < 0)
>          ret = -1;
>  
>      virJSONValueFree(cmd);

  okay probably a patch side effect


> +static int
> +qemudParseDriveAddReply(const char *reply,
> +                        virDomainDeviceDriveAddressPtr addr)
> +{
> +    char *s, *e;
> +
> +    /* If the command succeeds qemu prints:
> +     * OK bus X, unit Y
> +     */
> +
> +    if (!(s = strstr(reply, "OK ")))
> +        return -1;
> +
> +    s += 3;

  I would rather search for "bus " in the string here

> +    if (STRPREFIX(s, "bus ")) {
> +        s += strlen("bus ");
> +
> +        if (virStrToLong_ui(s, &e, 10, &addr->bus) == -1) {
> +            VIR_WARN(_("Unable to parse bus '%s'\n"), s);
> +            return -1;
> +        }
> +
> +        if (!STRPREFIX(e, ", ")) {
> +            VIR_WARN(_("Expected ', ' parsing drive_add reply '%s'\n"), s);
> +            return -1;
> +        }
> +        s = e + 2;
> +    }

  and then search for "unit " for inceased flexibility

> +    if (!STRPREFIX(s, "unit ")) {
> +        VIR_WARN(_("Expected 'unit ' parsing drive_add reply '%s'\n"), s);
> +        return -1;
> +    }
> +    s += strlen("bus ");
> +
> +    if (virStrToLong_ui(s, &e, 10, &addr->unit) == -1) {
> +        VIR_WARN(_("Unable to parse unit number '%s'\n"), s);
> +        return -1;
> +    }
> +
> +    return 0;
> +}

  ACK,

Daniel

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list