[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] AHCI support in qemu driver



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.

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?

Thanks!
Jim

[1] http://www.redhat.com/archives/libvir-list/2011-August/msg01034.html

>From 02c793bdc86e3f7f1775f58ef4776e32512ecdb8 Mon Sep 17 00:00:00 2001
From: Jim Fehlig <jfehlig 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");
+        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) {
-- 
1.7.5.4


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]