[libvirt] [PATCHv2 3/5] Allocate virtio-serial addresses when starting a domain
John Ferlan
jferlan at redhat.com
Mon Mar 23 21:46:23 UTC 2015
On 03/17/2015 07:41 AM, Ján Tomko wrote:
> Instead of always using controller 0 and incrementing port number,
> respect the maximum port numbers of controllers and use all of them.
>
> Ports for virtio consoles are quietly reserved, but not formatted
> (neither in XML nor on QEMU command line).
>
> Also rejects duplicate virtio-serial addresses.
> https://bugzilla.redhat.com/show_bug.cgi?id=890606
> https://bugzilla.redhat.com/show_bug.cgi?id=1076708
> ---
> src/conf/domain_conf.c | 29 ----------
> src/qemu/qemu_command.c | 63 ++++++++++++++++++++++
> src/qemu/qemu_domain.c | 1 +
> src/qemu/qemu_domain.h | 1 +
> src/qemu/qemu_process.c | 2 +
> .../qemuxml2argv-channel-virtio-auto.args | 8 +--
> .../qemuxml2argv-channel-virtio-autoassign.args | 10 ++--
> .../qemuxml2xmlout-channel-virtio-auto.xml | 10 ++--
> 8 files changed, 81 insertions(+), 43 deletions(-)
>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index c75b543..89357d2 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -3402,21 +3402,6 @@ virDomainDeviceDefPostParseInternal(virDomainDeviceDefPtr dev,
>
> chr->target.port = maxport + 1;
> }
> -
> - if (chr->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL &&
> - chr->info.addr.vioserial.port == 0) {
> - int maxport = 0;
> -
> - for (i = 0; i < cnt; i++) {
> - const virDomainChrDef *thischr = arrPtr[i];
> - if (thischr->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL &&
> - thischr->info.addr.vioserial.controller == chr->info.addr.vioserial.controller &&
> - thischr->info.addr.vioserial.bus == chr->info.addr.vioserial.bus &&
> - (int)thischr->info.addr.vioserial.port > maxport)
> - maxport = thischr->info.addr.vioserial.port;
> - }
> - chr->info.addr.vioserial.port = maxport + 1;
> - }
> }
>
> /* set default path for virtio-rng "random" backend to /dev/random */
> @@ -14526,20 +14511,6 @@ virDomainDefParseXML(xmlDocPtr xml,
> chr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO &&
> chr->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
> chr->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL;
> -
> - if (chr->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL &&
> - chr->info.addr.vioserial.port == 0) {
> - int maxport = 0;
> - for (j = 0; j < i; j++) {
> - virDomainChrDefPtr thischr = def->channels[j];
> - if (thischr->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL &&
> - thischr->info.addr.vioserial.controller == chr->info.addr.vioserial.controller &&
> - thischr->info.addr.vioserial.bus == chr->info.addr.vioserial.bus &&
> - (int)thischr->info.addr.vioserial.port > maxport)
> - maxport = thischr->info.addr.vioserial.port;
> - }
> - chr->info.addr.vioserial.port = maxport + 1;
> - }
> }
> VIR_FREE(nodes);
>
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 02105c3..e7f86e1 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -1399,6 +1399,65 @@ qemuAssignSpaprVIOAddress(virDomainDefPtr def, virDomainDeviceInfoPtr info,
> return 0;
> }
>
> +
> +static int
> +qemuDomainAssignVirtioSerialAddresses(virDomainDefPtr def,
> + virDomainObjPtr obj)
> +{
> + int ret = -1;
> + size_t i;
> + virDomainVirtioSerialAddrSetPtr addrs = NULL;
> + qemuDomainObjPrivatePtr priv = NULL;
> +
> + if (!(addrs = virDomainVirtioSerialAddrSetCreate()))
> + goto cleanup;
Coverity determines addrs != NULL, but
> +
> + if (virDomainVirtioSerialAddrSetAddControllers(addrs, def) < 0)
> + goto cleanup;
> +
> + if (virDomainDeviceInfoIterate(def, virDomainVirtioSerialAddrReserve,
> + addrs) < 0)
> + goto cleanup;
> +
> + VIR_DEBUG("Finished reserving existing ports");
> +
> + for (i = 0; i < def->nconsoles; i++) {
> + virDomainChrDefPtr chr = def->consoles[i];
> + if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
> + chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO) {
> + if (virDomainVirtioSerialAddrAssign(addrs, &chr->info, true) < 0)
> + goto cleanup;
> + }
> + }
> +
> + for (i = 0; i < def->nchannels; i++) {
> + virDomainChrDefPtr chr = def->channels[i];
> + if (chr->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL &&
> + chr->info.addr.vioserial.port == 0 &&
> + virDomainVirtioSerialAddrAssign(addrs, &chr->info, false) < 0)
> + goto cleanup;
> + }
> +
> + if (obj && obj->privateData) {
> + priv = obj->privateData;
> + if (addrs) {
There's a check here where the "else" is DEADCODE
> + /* if this is the live domain object, we persist the addresses */
> + virDomainVirtioSerialAddrSetFree(priv->vioserialaddrs);
> + priv->persistentAddrs = 1;
> + priv->vioserialaddrs = addrs;
> + addrs = NULL;
> + } else {
> + priv->persistentAddrs = 0;
> + }
> + }
> + ret = 0;
> +
> + cleanup:
> + virDomainVirtioSerialAddrSetFree(addrs);
> + return ret;
> +}
> +
> +
> int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def,
> virQEMUCapsPtr qemuCaps)
> {
> @@ -1645,6 +1704,10 @@ int qemuDomainAssignAddresses(virDomainDefPtr def,
> {
> int rc;
>
> + rc = qemuDomainAssignVirtioSerialAddresses(def, obj);
> + if (rc)
> + return rc;
> +
> rc = qemuDomainAssignSpaprVIOAddresses(def, qemuCaps);
> if (rc)
> return rc;
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index 2eacef2..cb2c166 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -431,6 +431,7 @@ qemuDomainObjPrivateFree(void *data)
> virCgroupFree(&priv->cgroup);
> virDomainPCIAddressSetFree(priv->pciaddrs);
> virDomainCCWAddressSetFree(priv->ccwaddrs);
> + virDomainVirtioSerialAddrSetFree(priv->vioserialaddrs);
> virDomainChrSourceDefFree(priv->monConfig);
> qemuDomainObjFreeJob(priv);
> VIR_FREE(priv->vcpupids);
> diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
> index ba8d398..9ad88a8 100644
> --- a/src/qemu/qemu_domain.h
> +++ b/src/qemu/qemu_domain.h
> @@ -159,6 +159,7 @@ struct _qemuDomainObjPrivate {
>
> virDomainPCIAddressSetPtr pciaddrs;
> virDomainCCWAddressSetPtr ccwaddrs;
> + virDomainVirtioSerialAddrSetPtr vioserialaddrs;
> int persistentAddrs;
>
> virQEMUCapsPtr qemuCaps;
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index ae315df..5589f22 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -5205,6 +5205,8 @@ void qemuProcessStop(virQEMUDriverPtr driver,
> virDomainDefClearCCWAddresses(vm->def);
> virDomainCCWAddressSetFree(priv->ccwaddrs);
> priv->ccwaddrs = NULL;
> + virDomainVirtioSerialAddrSetFree(priv->vioserialaddrs);
> + priv->vioserialaddrs = NULL;
> }
>
> qemuDomainReAttachHostDevices(driver, vm->def);
Mostly for my edification... These examples previously although
indicating they were "auto-assign" (of sorts) really weren't - they were
more force-assign for each example. The way to auto-assign is by
setting port='0', correct?
However, I'm still missing something from the *auto.args output. It
seems the controller='#' is ignored and I guess I don't understand
that... Sure "port='0'" (meaning first available port on the
controller), but I would have expected to see :
kvm.port.0 use "virtio.serial.0.0,nr=1..." (which it does)
kvm.port.foo use "virtio.serial.1.0,nr=1..." (on controller 0?, but XML
has controller='1')
kvm.port.bar use "virtio.serial.1.0,nr=3..." (which it does)
kvm.port.wizz use "virtio.serial.0.0,nr=2" (incorrect due to others)
kvm.port.ooh use "virtio.serial.1.0,nr=2", (on controller 0?, but XML
has controller='1'
kvm.port.lla use "virtio.serial.2.0,nr=1" (on controller 0?, but XML has
controller='2')
Now if been if "lla" used controller='0', then I assume would nr=4 be
chosen since 1,2 were auto-assigned, 3 was specifically assigned, thus 4
would be the next one.
Continuing with that same logic, the *-autoassign example could have
shown that if controller='0',port='2' and 'controller='1',port='1' were
preassigned, then the controllers/ports assigned would be 0.0,nr=1,
0.0,nr=3, 0.0,nr=4, 1.0,nr=2 (since only 4 ports on controller='0' can
be used w/ 2 be static and controller='1' having port '1' already in use).
John
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-auto.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-auto.args
> index f7d7409..71edfae 100644
> --- a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-auto.args
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-auto.args
> @@ -9,14 +9,14 @@ virtio-serial-pci,id=virtio-serial2,bus=pci.0,addr=0x4 -usb -hda \
> /dev/HostVG/QEMUGuest1 -chardev pty,id=charchannel0 -device virtserialport,\
> bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,\
> name=org.linux-kvm.port.0 -chardev pty,id=charchannel1 -device virtserialport,\
> -bus=virtio-serial1.0,nr=1,chardev=charchannel1,id=channel1,\
> +bus=virtio-serial0.0,nr=2,chardev=charchannel1,id=channel1,\
> name=org.linux-kvm.port.foo -chardev pty,id=charchannel2 -device \
> virtserialport,bus=virtio-serial1.0,nr=3,chardev=charchannel2,id=channel2,\
> name=org.linux-kvm.port.bar -chardev pty,id=charchannel3 -device \
> -virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel3,id=channel3,\
> +virtserialport,bus=virtio-serial0.0,nr=3,chardev=charchannel3,id=channel3,\
> name=org.linux-kvm.port.wizz -chardev pty,id=charchannel4 -device \
> -virtserialport,bus=virtio-serial1.0,nr=4,chardev=charchannel4,id=channel4,\
> +virtserialport,bus=virtio-serial0.0,nr=4,chardev=charchannel4,id=channel4,\
> name=org.linux-kvm.port.ooh -chardev pty,id=charchannel5 -device \
> -virtserialport,bus=virtio-serial2.0,nr=1,chardev=charchannel5,id=channel5,\
> +virtserialport,bus=virtio-serial0.0,nr=5,chardev=charchannel5,id=channel5,\
> name=org.linux-kvm.port.lla -device virtio-balloon-pci,id=balloon0,\
> bus=pci.0,addr=0x5
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-autoassign.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-autoassign.args
> index d64a228..f11039d 100644
> --- a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-autoassign.args
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-autoassign.args
> @@ -5,16 +5,16 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
> -device virtio-serial-pci,id=virtio-serial0,max_ports=4,vectors=4,bus=pci.0\
> ,addr=0x3 -device virtio-serial-pci,id=virtio-serial1,bus=pci.0,addr=0xa \
> -usb -hda /dev/HostVG/QEMUGuest1 \
> --chardev pty,id=charchannel0 -device virtserialport,bus=virtio-serial0.0,nr=1,\
> +-chardev pty,id=charchannel0 -device virtserialport,bus=virtio-serial0.0,nr=2,\
> chardev=charchannel0,id=channel0,name=org.linux-kvm.port.0 \
> --chardev pty,id=charchannel1 -device virtserialport,bus=virtio-serial0.0,nr=2,\
> +-chardev pty,id=charchannel1 -device virtserialport,bus=virtio-serial0.0,nr=3,\
> chardev=charchannel1,id=channel1,name=org.linux-kvm.port.foo \
> -chardev pty,id=charchannel2 -device virtserialport,bus=virtio-serial0.0,nr=1,\
> chardev=charchannel2,id=channel2,name=org.linux-kvm.port.bar \
> --chardev pty,id=charchannel3 -device virtserialport,bus=virtio-serial0.2,nr=1,\
> +-chardev pty,id=charchannel3 -device virtserialport,bus=virtio-serial1.0,nr=1,\
> chardev=charchannel3,id=channel3,name=org.linux-kvm.port.wizz \
> --chardev pty,id=charchannel4 -device virtserialport,bus=virtio-serial0.0,nr=3,\
> +-chardev pty,id=charchannel4 -device virtserialport,bus=virtio-serial1.0,nr=2,\
> chardev=charchannel4,id=channel4,name=org.linux-kvm.port.ooh \
> --chardev pty,id=charchannel5 -device virtserialport,bus=virtio-serial0.0,nr=4,\
> +-chardev pty,id=charchannel5 -device virtserialport,bus=virtio-serial1.0,nr=3,\
> chardev=charchannel5,id=channel5,name=org.linux-kvm.port.lla \
> -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-channel-virtio-auto.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-channel-virtio-auto.xml
> index fd6b852..afe41cf 100644
> --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-channel-virtio-auto.xml
> +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-channel-virtio-auto.xml
> @@ -29,11 +29,11 @@
> <controller type='virtio-serial' index='2'/>
> <channel type='pty'>
> <target type='virtio' name='org.linux-kvm.port.0'/>
> - <address type='virtio-serial' controller='0' bus='0' port='1'/>
> + <address type='virtio-serial' controller='0' bus='0' port='0'/>
> </channel>
> <channel type='pty'>
> <target type='virtio' name='org.linux-kvm.port.foo'/>
> - <address type='virtio-serial' controller='1' bus='0' port='1'/>
> + <address type='virtio-serial' controller='1' bus='0' port='0'/>
> </channel>
> <channel type='pty'>
> <target type='virtio' name='org.linux-kvm.port.bar'/>
> @@ -41,15 +41,15 @@
> </channel>
> <channel type='pty'>
> <target type='virtio' name='org.linux-kvm.port.wizz'/>
> - <address type='virtio-serial' controller='0' bus='0' port='2'/>
> + <address type='virtio-serial' controller='0' bus='0' port='0'/>
> </channel>
> <channel type='pty'>
> <target type='virtio' name='org.linux-kvm.port.ooh'/>
> - <address type='virtio-serial' controller='1' bus='0' port='4'/>
> + <address type='virtio-serial' controller='1' bus='0' port='0'/>
> </channel>
> <channel type='pty'>
> <target type='virtio' name='org.linux-kvm.port.lla'/>
> - <address type='virtio-serial' controller='2' bus='0' port='1'/>
> + <address type='virtio-serial' controller='2' bus='0' port='0'/>
> </channel>
> <memballoon model='virtio'/>
> </devices>
>
More information about the libvir-list
mailing list