qemu: Build usb controller command line more wisely

https://bugzilla.redhat.com/show_bug.cgi?id=1552127

When building command line for USB controllers we have to do more
than just put controller's alias onto the command line. QEMU has
concept of these joined USB controllers. For instance ehci and
uhci controllers need to create the same USB bus. To achieve that
the slave controller needs to refer the master controller. This
worked until we've introduced user aliases because both master
and slave had the same alias. With user aliases slave can have
different alias than master. Therefore, when generating command
line for slave we need to look up the master's alias.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Michal Privoznik 2018-03-16 15:53:32 +01:00
parent c8935705f1
commit b133fac356
4 changed files with 158 additions and 5 deletions

View File

@ -2545,8 +2545,34 @@ qemuControllerModelUSBToCaps(int model)
}
static const char *
qemuBuildUSBControllerFindMasterAlias(const virDomainDef *domainDef,
const virDomainControllerDef *def)
{
size_t i;
for (i = 0; i < domainDef->ncontrollers; i++) {
const virDomainControllerDef *tmp = domainDef->controllers[i];
if (tmp->type != VIR_DOMAIN_CONTROLLER_TYPE_USB)
continue;
if (tmp->idx != def->idx)
continue;
if (tmp->info.mastertype == VIR_DOMAIN_CONTROLLER_MASTER_USB)
continue;
return tmp->info.alias;
}
return NULL;
}
static int
qemuBuildUSBControllerDevStr(virDomainControllerDefPtr def,
qemuBuildUSBControllerDevStr(const virDomainDef *domainDef,
virDomainControllerDefPtr def,
virQEMUCapsPtr qemuCaps,
virBuffer *buf)
{
@ -2586,11 +2612,19 @@ qemuBuildUSBControllerDevStr(virDomainControllerDefPtr def,
def->opts.usbopts.ports, def->opts.usbopts.ports);
}
if (def->info.mastertype == VIR_DOMAIN_CONTROLLER_MASTER_USB)
if (def->info.mastertype == VIR_DOMAIN_CONTROLLER_MASTER_USB) {
const char *masterbus;
if (!(masterbus = qemuBuildUSBControllerFindMasterAlias(domainDef, def))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("masterbus not found"));
return -1;
}
virBufferAsprintf(buf, ",masterbus=%s.0,firstport=%d",
def->info.alias, def->info.master.usb.startport);
else
masterbus, def->info.master.usb.startport);
} else {
virBufferAsprintf(buf, ",id=%s", def->info.alias);
}
return 0;
}
@ -2722,7 +2756,7 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef,
break;
case VIR_DOMAIN_CONTROLLER_TYPE_USB:
if (qemuBuildUSBControllerDevStr(def, qemuCaps, &buf) == -1)
if (qemuBuildUSBControllerDevStr(domainDef, def, qemuCaps, &buf) == -1)
goto error;
if (nusbcontroller)

View File

@ -0,0 +1,38 @@
LC_ALL=C \
PATH=/bin \
HOME=/home/test \
USER=test \
LOGNAME=test \
QEMU_AUDIO_DRV=none \
/usr/bin/qemu-system-x86_64 \
-name gentoo \
-S \
-M pc-i440fx-1.4 \
-m 4096 \
-smp 4,sockets=4,cores=1,threads=1 \
-uuid a75aca4b-a02f-2bcb-4a91-c93cd848c34b \
-nographic \
-nodefaults \
-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-gentoo/monitor.sock,\
server,nowait \
-mon chardev=charmonitor,id=monitor,mode=readline \
-global PIIX4_PM.disable_s3=0 \
-global PIIX4_PM.disable_s4=0 \
-boot cd \
-device ich9-usb-ehci1,id=ua-myUSB1,bus=pci.0,addr=0x4.0x7 \
-device ich9-usb-uhci1,masterbus=ua-myUSB1.0,firstport=0,bus=pci.0,\
multifunction=on,addr=0x4 \
-device ich9-usb-uhci2,masterbus=ua-myUSB1.0,firstport=2,bus=pci.0,\
addr=0x4.0x1 \
-device ich9-usb-uhci3,masterbus=ua-myUSB1.0,firstport=4,bus=pci.0,\
addr=0x4.0x2 \
-device ich9-usb-ehci1,id=ua-myUSB5,bus=pci.0,addr=0x5.0x7 \
-device ich9-usb-uhci1,masterbus=ua-myUSB5.0,firstport=0,bus=pci.0,\
multifunction=on,addr=0x5 \
-device ich9-usb-uhci2,masterbus=ua-myUSB5.0,firstport=2,bus=pci.0,\
addr=0x5.0x1 \
-device ich9-usb-uhci3,masterbus=ua-myUSB5.0,firstport=4,bus=pci.0,\
addr=0x5.0x2 \
-device usb-host,hostbus=14,hostaddr=6,id=hostdev0,bus=ua-myUSB1.0,port=3 \
-device usb-host,hostbus=15,hostaddr=6,id=hostdev1,bus=ua-myUSB5.0,port=3 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3

View File

@ -0,0 +1,78 @@
<domain type='kvm'>
<name>gentoo</name>
<uuid>a75aca4b-a02f-2bcb-4a91-c93cd848c34b</uuid>
<memory unit='KiB'>4194304</memory>
<currentMemory unit='KiB'>4194304</currentMemory>
<vcpu placement='static'>4</vcpu>
<os>
<type arch='x86_64' machine='pc-i440fx-1.4'>hvm</type>
<boot dev='hd'/>
<boot dev='cdrom'/>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<pm>
<suspend-to-mem enabled='yes'/>
<suspend-to-disk enabled='yes'/>
</pm>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<controller type='usb' index='0' model='ich9-ehci1'>
<alias name='ua-myUSB1'/>
<address type='pci' domain='0' bus='0' slot='4' function='7'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci1'>
<alias name='ua-myUSB2'/>
<master startport='0'/>
<address type='pci' domain='0' bus='0' slot='4' function='0' multifunction='on'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci2'>
<alias name='ua-myUSB3'/>
<master startport='2'/>
<address type='pci' domain='0' bus='0' slot='4' function='1'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci3'>
<alias name='ua-myUSB4'/>
<master startport='4'/>
<address type='pci' domain='0' bus='0' slot='4' function='2'/>
</controller>
<controller type='usb' index='1' model='ich9-ehci1'>
<alias name='ua-myUSB5'/>
<address type='pci' domain='0' bus='0' slot='5' function='7'/>
</controller>
<controller type='usb' index='1' model='ich9-uhci1'>
<alias name='ua-myUSB6'/>
<master startport='0'/>
<address type='pci' domain='0' bus='0' slot='5' function='0' multifunction='on'/>
</controller>
<controller type='usb' index='1' model='ich9-uhci2'>
<alias name='ua-myUSB7'/>
<master startport='2'/>
<address type='pci' domain='0' bus='0' slot='5' function='1'/>
</controller>
<controller type='usb' index='1' model='ich9-uhci3'>
<alias name='ua-myUSB8'/>
<master startport='4'/>
<address type='pci' domain='0' bus='0' slot='5' function='2'/>
</controller>
<hostdev mode='subsystem' type='usb' managed='yes'>
<source>
<address bus='14' device='6'/>
</source>
<address type='usb' bus='0' port='3'/>
</hostdev>
<hostdev mode='subsystem' type='usb' managed='yes'>
<source>
<address bus='15' device='6'/>
</source>
<address type='usb' bus='1' port='3'/>
</hostdev>
</devices>
</domain>

View File

@ -2997,6 +2997,9 @@ mymain(void)
QEMU_CAPS_DEVICE_ISA_SERIAL,
QEMU_CAPS_HDA_DUPLEX);
DO_TEST("user-aliases2", QEMU_CAPS_DEVICE_IOH3420, QEMU_CAPS_ICH9_AHCI);
DO_TEST("user-aliases-usb", QEMU_CAPS_KVM,
QEMU_CAPS_PIIX_DISABLE_S3, QEMU_CAPS_PIIX_DISABLE_S4,
QEMU_CAPS_ICH9_USB_EHCI1, QEMU_CAPS_PCI_MULTIFUNCTION);
/* Test disks with format probing enabled for legacy reasons.
* New tests should not go in this section. */