提交 c1bc3d89 编写于 作者: J Jim Fehlig

Add AHCI support to qemu driver

Tested with multiple AHCI controllers and multiple disks attached
to a controller. 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'/>
      <address type='drive' controller='0' bus='0' unit='0'/>
    </disk>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/test/disk1.raw'/>
      <target dev='sdb' bus='sata'/>
      <address type='drive' controller='0' bus='0' unit='1'/>
    </disk>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/test/disk2.raw'/>
      <target dev='sdc' bus='sata'/>
      <address type='drive' controller='1' bus='0' unit='0'/>
    </disk>
    <controller type='sata' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
    </controller>
    <controller type='sata' index='1'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
    </controller>
上级 e570d7c4
...@@ -972,11 +972,12 @@ ...@@ -972,11 +972,12 @@
as a device ordering hint. The optional <code>bus</code> as a device ordering hint. The optional <code>bus</code>
attribute specifies the type of disk device to emulate; attribute specifies the type of disk device to emulate;
possible values are driver specific, with typical values being possible values are driver specific, with typical values being
"ide", "scsi", "virtio", "xen" or "usb". If omitted, the bus type is "ide", "scsi", "virtio", "xen", "usb" or "sata". If omitted, the bus
inferred from the style of the device name. eg, a device named 'sda' type is inferred from the style of the device name. eg, a device named
will typically be exported using a SCSI bus. 'sda' will typically be exported using a SCSI bus.
<span class="since">Since 0.0.3; <code>bus</code> attribute since 0.4.3; <span class="since">Since 0.0.3; <code>bus</code> attribute since 0.4.3;
"usb" attribute value since after 0.4.4</span></dd> "usb" attribute value since after 0.4.4; "sata" attribute value since
0.9.7</span></dd>
<dt><code>driver</code></dt> <dt><code>driver</code></dt>
<dd> <dd>
The optional driver element allows specifying further details The optional driver element allows specifying further details
......
...@@ -790,6 +790,7 @@ ...@@ -790,6 +790,7 @@
<value>xen</value> <value>xen</value>
<value>usb</value> <value>usb</value>
<value>uml</value> <value>uml</value>
<value>sata</value>
</choice> </choice>
</attribute> </attribute>
</optional> </optional>
......
...@@ -2189,6 +2189,15 @@ virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def) ...@@ -2189,6 +2189,15 @@ virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def)
def->info.addr.drive.unit = (idx % 2); def->info.addr.drive.unit = (idx % 2);
break; 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: case VIR_DOMAIN_DISK_BUS_FDC:
/* For FDC we define the default mapping to be 2 units /* For FDC we define the default mapping to be 2 units
* per bus, 1 bus per controller, many controllers */ * per bus, 1 bus per controller, many controllers */
...@@ -8748,6 +8757,11 @@ int virDomainDefAddImplicitControllers(virDomainDefPtr def) ...@@ -8748,6 +8757,11 @@ int virDomainDefAddImplicitControllers(virDomainDefPtr def)
VIR_DOMAIN_DISK_BUS_IDE) < 0) VIR_DOMAIN_DISK_BUS_IDE) < 0)
return -1; return -1;
if (virDomainDefAddDiskControllersForType(def,
VIR_DOMAIN_CONTROLLER_TYPE_SATA,
VIR_DOMAIN_DISK_BUS_SATA) < 0)
return -1;
if (virDomainDefMaybeAddVirtioSerialController(def) < 0) if (virDomainDefMaybeAddVirtioSerialController(def) < 0)
return -1; return -1;
......
...@@ -140,6 +140,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST, ...@@ -140,6 +140,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
"cache-unsafe", /* 75 */ "cache-unsafe", /* 75 */
"rombar", "rombar",
"ich9-ahci",
); );
struct qemu_feature_flags { struct qemu_feature_flags {
...@@ -1255,6 +1256,8 @@ qemuCapsParseDeviceStr(const char *str, virBitmapPtr flags) ...@@ -1255,6 +1256,8 @@ qemuCapsParseDeviceStr(const char *str, virBitmapPtr flags)
qemuCapsSet(flags, QEMU_CAPS_USB_REDIR); qemuCapsSet(flags, QEMU_CAPS_USB_REDIR);
if (strstr(str, "name \"usb-hub\"")) if (strstr(str, "name \"usb-hub\""))
qemuCapsSet(flags, QEMU_CAPS_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 */ /* Prefer -chardev spicevmc (detected earlier) over -device spicevmc */
if (!qemuCapsGet(flags, QEMU_CAPS_CHARDEV_SPICEVMC) && if (!qemuCapsGet(flags, QEMU_CAPS_CHARDEV_SPICEVMC) &&
......
...@@ -114,6 +114,7 @@ enum qemuCapsFlags { ...@@ -114,6 +114,7 @@ enum qemuCapsFlags {
QEMU_CAPS_DRIVE_CACHE_UNSAFE = 75, /* Is cache=unsafe supported? */ QEMU_CAPS_DRIVE_CACHE_UNSAFE = 75, /* Is cache=unsafe supported? */
QEMU_CAPS_PCI_ROMBAR = 76, /* -device rombar=0|1 */ 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 */ QEMU_CAPS_LAST, /* this must always be the last item */
}; };
......
...@@ -1776,6 +1776,12 @@ qemuBuildDriveDevStr(virDomainDiskDefPtr disk, ...@@ -1776,6 +1776,12 @@ qemuBuildDriveDevStr(virDomainDiskDefPtr disk,
disk->info.addr.drive.bus, disk->info.addr.drive.bus,
disk->info.addr.drive.unit); disk->info.addr.drive.unit);
break; 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: case VIR_DOMAIN_DISK_BUS_VIRTIO:
virBufferAddLit(&opt, "virtio-blk-pci"); virBufferAddLit(&opt, "virtio-blk-pci");
qemuBuildIoEventFdStr(&opt, disk->ioeventfd, qemuCaps); qemuBuildIoEventFdStr(&opt, disk->ioeventfd, qemuCaps);
...@@ -1983,6 +1989,10 @@ qemuBuildControllerDevStr(virDomainControllerDefPtr def, ...@@ -1983,6 +1989,10 @@ qemuBuildControllerDevStr(virDomainControllerDefPtr def,
virBufferAsprintf(&buf, "usb-ccid,id=ccid%d", def->idx); virBufferAsprintf(&buf, "usb-ccid,id=ccid%d", def->idx);
break; break;
case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
virBufferAsprintf(&buf, "ahci,id=ahci%d", def->idx);
break;
case VIR_DOMAIN_CONTROLLER_TYPE_USB: case VIR_DOMAIN_CONTROLLER_TYPE_USB:
if (qemuBuildUSBControllerDevStr(def, qemuCaps, &buf) == -1) if (qemuBuildUSBControllerDevStr(def, qemuCaps, &buf) == -1)
goto error; goto error;
...@@ -3783,14 +3793,22 @@ qemuBuildCommandLine(virConnectPtr conn, ...@@ -3783,14 +3793,22 @@ qemuBuildCommandLine(virConnectPtr conn,
cont->type == VIR_DOMAIN_CONTROLLER_TYPE_FDC) cont->type == VIR_DOMAIN_CONTROLLER_TYPE_FDC)
continue; continue;
/* QEMU doesn't implement a SATA driver */ /* Only recent QEMU implements a SATA (AHCI) controller */
if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_SATA) { if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_SATA) {
if (!qemuCapsGet(qemuCaps, QEMU_CAPS_ICH9_AHCI)) {
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s", _("SATA is not supported with this QEMU binary")); "%s", _("SATA is not supported with this QEMU binary"));
goto error; goto error;
} } else {
char *devstr;
virCommandAddArg(cmd, "-device");
if (!(devstr = qemuBuildControllerDevStr(cont, qemuCaps, NULL)))
goto error;
if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB && virCommandAddArg(cmd, devstr);
}
} else if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB &&
def->controllers[i]->model == -1 && def->controllers[i]->model == -1 &&
!qemuCapsGet(qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI)) { !qemuCapsGet(qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI)) {
if (usblegacy) { if (usblegacy) {
......
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
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory>219136</memory>
<currentMemory>219136</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='sda' bus='sata'/>
<address type='drive' controller='0' bus='0' unit='0'/>
</disk>
<controller type='sata' index='0'/>
<memballoon model='virtio'/>
</devices>
</domain>
...@@ -363,6 +363,9 @@ mymain(void) ...@@ -363,6 +363,9 @@ mymain(void)
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG);
DO_TEST("disk-scsi-device-auto", false, DO_TEST("disk-scsi-device-auto", false,
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); 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, DO_TEST("disk-aio", false,
QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_AIO, QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_AIO,
QEMU_CAPS_DRIVE_CACHE_V2, QEMU_CAPS_DRIVE_FORMAT); QEMU_CAPS_DRIVE_CACHE_V2, QEMU_CAPS_DRIVE_FORMAT);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册