[libvirt] AHCI support in qemu driver

Daniel P. Berrange berrange at redhat.com
Wed Sep 28 08:12:38 UTC 2011


On Tue, Sep 27, 2011 at 10:22:48PM -0600, Jim Fehlig wrote:
> I have some time this week to work on libvirt and thought Daniel's
> suggestion [1] for adding AHCI support in the qemu driver would be a
> useful endeavor.
> 
> I've managed to start a qemu instance using AHCI with attached hackery,
> iff I have a controller defined.  E.g.
> 
>   <disk type='file' device='disk'>
>     <driver name='qemu' type='raw'/>
>     <source file='/var/lib/libvirt/images/test/disk0.raw'/>
>     <target dev='sda' bus='sata'/>
>   </disk>
>   <controller type='sata' index='0'>
>     <address type='pci' domain='0x0000' bus='0x00' slot='0x03'
> function='0x0'/>
>   </controller>
> 
> which results in qemu args
> 
> -device ahci,id=ahci0,bus=pci.0,multifunction=on,addr=0x3.0x0 -drive
> file=/var/lib/libvirt/images/test/disk0.raw,if=none,id=drive-sata-dik0,format=raw
> -device
> ide-drive,bus=ahci0.0,drive=drive-sata-disk0,id=sata-disk0,bootindex=1
> 
> If the controller is not explicitly defined, the AHCI device (-device
> ahci,...) is not created and qemu fails with
> 
> qemu-kvm: -device
> ide-drive,bus=ahci0.0,drive=drive-sata-disk0,id=sata-disk0,bootindex=1:
> Bus 'a
> hci0.0' not found
> 
> I'm not quite sure how to create the controller when not explicitly
> defined in the config.

There is a function virDomainDefAddImplicitControllers() in the
domain_conf.c which looks to be missing the SATA case.

> Also, I suspect there are many things I'm missing in adding support for
> this controller.  E.g., I've ignored hotplug for the moment.  What would
> be considered minimal functionality for supporting this controller?

Just being able to launch a guest + the test data files for qemuxml2argvtest
would be the minimum. Hotplug would be desirable if it works in QEMU, but
not critical.


> >From 02c793bdc86e3f7f1775f58ef4776e32512ecdb8 Mon Sep 17 00:00:00 2001
> From: Jim Fehlig <jfehlig at suse.com>
> Date: Tue, 27 Sep 2011 21:46:08 -0600
> Subject: [PATCH] Add AHCI support to qemu driver
> 
> ---
>  src/qemu/qemu_capabilities.c |    3 +++
>  src/qemu/qemu_capabilities.h |    1 +
>  src/qemu/qemu_command.c      |   32 +++++++++++++++++++++++++-------
>  3 files changed, 29 insertions(+), 7 deletions(-)
> 
> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> index 8e20e3f..7122756 100644
> --- a/src/qemu/qemu_capabilities.c
> +++ b/src/qemu/qemu_capabilities.c
> @@ -139,6 +139,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
>                "no-shutdown",
>  
>                "cache-unsafe", /* 75 */
> +              "ich9-ahci",
>      );
>  
>  struct qemu_feature_flags {
> @@ -1241,6 +1242,8 @@ qemuCapsParseDeviceStr(const char *str, virBitmapPtr flags)
>          qemuCapsSet(flags, QEMU_CAPS_USB_REDIR);
>      if (strstr(str, "name \"usb-hub\""))
>          qemuCapsSet(flags, QEMU_CAPS_USB_HUB);
> +    if (strstr(str, "name \"ich9-ahci\""))
> +        qemuCapsSet(flags, QEMU_CAPS_ICH9_AHCI);
>  
>      /* Prefer -chardev spicevmc (detected earlier) over -device spicevmc */
>      if (!qemuCapsGet(flags, QEMU_CAPS_CHARDEV_SPICEVMC) &&
> diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
> index ae3de90..1e23451 100644
> --- a/src/qemu/qemu_capabilities.h
> +++ b/src/qemu/qemu_capabilities.h
> @@ -113,6 +113,7 @@ enum qemuCapsFlags {
>      QEMU_CAPS_NO_SHUTDOWN       = 74, /* usable -no-shutdown */
>  
>      QEMU_CAPS_DRIVE_CACHE_UNSAFE = 75, /* Is cache=unsafe supported? */
> +    QEMU_CAPS_ICH9_AHCI         = 76, /* -device ich9-ahci */
>  
>      QEMU_CAPS_LAST,                   /* this must always be the last item */
>  };
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 9174a5f..86c3f86 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -1702,6 +1702,12 @@ qemuBuildDriveDevStr(virDomainDiskDefPtr disk,
>                            disk->info.addr.drive.bus,
>                            disk->info.addr.drive.unit);
>          break;
> +    case VIR_DOMAIN_DISK_BUS_SATA:
> +        virBufferAddLit(&opt, "ide-drive");

Oh, AHCI still wants the 'ide-drive' devices ? I always figured it would
have a new type of device there too, but perhaps not.

> +        virBufferAsprintf(&opt, ",bus=ahci%d.%d",
> +                          disk->info.addr.drive.controller,
> +                          disk->info.addr.drive.bus);
> +        break;
>      case VIR_DOMAIN_DISK_BUS_VIRTIO:
>          virBufferAddLit(&opt, "virtio-blk-pci");
>          qemuBuildIoEventFdStr(&opt, disk->ioeventfd, qemuCaps);
> @@ -1902,6 +1908,10 @@ qemuBuildControllerDevStr(virDomainControllerDefPtr def,
>          virBufferAsprintf(&buf, "usb-ccid,id=ccid%d", def->idx);
>          break;
>  
> +    case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
> +        virBufferAsprintf(&buf, "ahci,id=ahci%d", def->idx);
> +        break;
> +
>      case VIR_DOMAIN_CONTROLLER_TYPE_USB:
>          if (qemuBuildUSBControllerDevStr(def, qemuCaps, &buf) == -1)
>              goto error;
> @@ -3683,14 +3693,22 @@ qemuBuildCommandLine(virConnectPtr conn,
>                  cont->type == VIR_DOMAIN_CONTROLLER_TYPE_FDC)
>                  continue;
>  
> -            /* QEMU doesn't implement a SATA driver */
> +            /* Only recent QEMU implements a SATA (AHCI) controller */
>              if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_SATA) {
> -                qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> -                                "%s", _("SATA is not supported with this QEMU binary"));
> -                goto error;
> -            }
> -
> -            if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB &&
> +                if (!qemuCapsGet(qemuCaps, QEMU_CAPS_ICH9_AHCI)) {
> +                    qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> +                                    "%s", _("SATA is not supported with this QEMU binary"));
> +                    goto error;
> +                } else {
> +                    char *devstr;
> +                    
> +                    virCommandAddArg(cmd, "-device");
> +                    if (!(devstr = qemuBuildControllerDevStr(cont, qemuCaps, NULL)))
> +                        goto error;
> +                    
> +                    virCommandAddArg(cmd, devstr);
> +                }
> +            } else if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB &&
>                  def->controllers[i]->model == -1 &&
>                  !qemuCapsGet(qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI)) {
>                  if (usblegacy) {


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