From c1bc3d892c7388ad5c7c70a298107236717a009a Mon Sep 17 00:00:00 2001 From: Jim Fehlig Date: Tue, 27 Sep 2011 21:46:08 -0600 Subject: [PATCH] Add AHCI support to qemu driver Tested with multiple AHCI controllers and multiple disks attached to a controller. E.g.,
--- docs/formatdomain.html.in | 9 +++--- docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c | 14 +++++++++ src/qemu/qemu_capabilities.c | 3 ++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 30 +++++++++++++++---- .../qemuxml2argv-disk-sata-device.args | 6 ++++ .../qemuxml2argv-disk-sata-device.xml | 25 ++++++++++++++++ tests/qemuxml2argvtest.c | 3 ++ 9 files changed, 82 insertions(+), 10 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-sata-device.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-sata-device.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index c007dff848..186b724ac0 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -972,11 +972,12 @@ as a device ordering hint. The optional bus attribute specifies the type of disk device to emulate; possible values are driver specific, with typical values being - "ide", "scsi", "virtio", "xen" or "usb". If omitted, the bus type is - inferred from the style of the device name. eg, a device named 'sda' - will typically be exported using a SCSI bus. + "ide", "scsi", "virtio", "xen", "usb" or "sata". If omitted, the bus + type is inferred from the style of the device name. eg, a device named + 'sda' will typically be exported using a SCSI bus. Since 0.0.3; bus attribute since 0.4.3; - "usb" attribute value since after 0.4.4 + "usb" attribute value since after 0.4.4; "sata" attribute value since + 0.9.7
driver
The optional driver element allows specifying further details diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index c75ea3776e..cd1a067a8e 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -790,6 +790,7 @@ xen usb uml + sata diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 844af27fee..595959384b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2189,6 +2189,15 @@ virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def) def->info.addr.drive.unit = (idx % 2); break; + case VIR_DOMAIN_DISK_BUS_SATA: + /* For SATA we define the default mapping to be 6 units + * per bus, 1 bus per controller, many controllers */ + def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE; + def->info.addr.drive.controller = idx / 6; + def->info.addr.drive.bus = 0; + def->info.addr.drive.unit = idx % 6; + break; + case VIR_DOMAIN_DISK_BUS_FDC: /* For FDC we define the default mapping to be 2 units * per bus, 1 bus per controller, many controllers */ @@ -8748,6 +8757,11 @@ int virDomainDefAddImplicitControllers(virDomainDefPtr def) VIR_DOMAIN_DISK_BUS_IDE) < 0) return -1; + if (virDomainDefAddDiskControllersForType(def, + VIR_DOMAIN_CONTROLLER_TYPE_SATA, + VIR_DOMAIN_DISK_BUS_SATA) < 0) + return -1; + if (virDomainDefMaybeAddVirtioSerialController(def) < 0) return -1; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 2f55000a69..5f0356c518 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -140,6 +140,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST, "cache-unsafe", /* 75 */ "rombar", + "ich9-ahci", ); struct qemu_feature_flags { @@ -1255,6 +1256,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 062f239e72..00e521434a 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -114,6 +114,7 @@ enum qemuCapsFlags { QEMU_CAPS_DRIVE_CACHE_UNSAFE = 75, /* Is cache=unsafe supported? */ QEMU_CAPS_PCI_ROMBAR = 76, /* -device rombar=0|1 */ + QEMU_CAPS_ICH9_AHCI = 77, /* -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 b4f4bd8943..30c0be6509 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1776,6 +1776,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.unit); + break; case VIR_DOMAIN_DISK_BUS_VIRTIO: virBufferAddLit(&opt, "virtio-blk-pci"); qemuBuildIoEventFdStr(&opt, disk->ioeventfd, qemuCaps); @@ -1983,6 +1989,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; @@ -3783,14 +3793,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 (!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; - if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB && + 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) { diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-sata-device.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-sata-device.args new file mode 100644 index 0000000000..9908da6e33 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-sata-device.args @@ -0,0 +1,6 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \ +pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -monitor \ +unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -device ahci,id=ahci0,\ +bus=pci.0,addr=0x3 -drive file=/dev/HostVG/QEMUGuest1,if=none,\ +id=drive-sata0-0-0 -device ide-drive,bus=ahci0.0,drive=drive-sata0-0-0,\ +id=sata0-0-0 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-sata-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-sata-device.xml new file mode 100644 index 0000000000..68a14f2850 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-sata-device.xml @@ -0,0 +1,25 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + 219136 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + +
+ + + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 3d65d5f64b..a7ae925f1f 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -363,6 +363,9 @@ mymain(void) QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); DO_TEST("disk-scsi-device-auto", false, QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); + DO_TEST("disk-sata-device", false, + QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, + QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_ICH9_AHCI); DO_TEST("disk-aio", false, QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_AIO, QEMU_CAPS_DRIVE_CACHE_V2, QEMU_CAPS_DRIVE_FORMAT);