diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 4e5c538a3f258222f8931c8985e28d68da683e56..1763305e648a0910bf42fd19114a8c2c62b59055 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3512,21 +3512,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 */
@@ -12499,6 +12484,20 @@ virDomainControllerFind(virDomainDefPtr def,
return -1;
}
+int
+virDomainControllerFindByType(virDomainDefPtr def,
+ int type)
+{
+ size_t i;
+
+ for (i = 0; i < def->ncontrollers; i++) {
+ if (def->controllers[i]->type == type)
+ return i;
+ }
+
+ return -1;
+}
+
int
virDomainControllerFindByPCIAddress(virDomainDefPtr def,
virDevicePCIAddressPtr addr)
@@ -14935,25 +14934,6 @@ virDomainDefParseXML(xmlDocPtr xml,
goto error;
def->channels[def->nchannels++] = chr;
-
- if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
- 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/conf/domain_conf.h b/src/conf/domain_conf.h
index 33200846a2f605bf414c7f9780179083db1d05c1..0b2f1c9bf055da727958c0b3a2c058cad1566177 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2717,6 +2717,7 @@ int virDomainControllerInsert(virDomainDefPtr def,
void virDomainControllerInsertPreAlloced(virDomainDefPtr def,
virDomainControllerDefPtr controller);
int virDomainControllerFind(virDomainDefPtr def, int type, int idx);
+int virDomainControllerFindByType(virDomainDefPtr def, int type);
int virDomainControllerFindByPCIAddress(virDomainDefPtr def,
virDevicePCIAddressPtr addr);
virDomainControllerDefPtr virDomainControllerRemove(virDomainDefPtr def, size_t i);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 5201416c4e059721bcd754fffb21c1f9b42e4041..36797c55b5e221dfc6f9897d12431f6452f13f89 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -184,6 +184,7 @@ virDomainClockOffsetTypeToString;
virDomainConfigFile;
virDomainControllerDefFree;
virDomainControllerFind;
+virDomainControllerFindByType;
virDomainControllerInsert;
virDomainControllerInsertPreAlloced;
virDomainControllerModelPCITypeToString;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index bcb54fae4bb2c2d3016d2b1a51809b88f1e0271f..85d2f4d040bf94f31dd9932f69b177c116c6d823 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1403,6 +1403,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 (virDomainControllerFindByType(def, VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL) == -1)
+ return 0;
+
+ if (!(addrs = virDomainVirtioSerialAddrSetCreate()))
+ goto cleanup;
+
+ 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 &&
+ !virDomainVirtioSerialAddrIsComplete(&chr->info) &&
+ virDomainVirtioSerialAddrAutoAssign(addrs, &chr->info, true) < 0)
+ goto cleanup;
+ }
+
+ for (i = 0; i < def->nchannels; i++) {
+ virDomainChrDefPtr chr = def->channels[i];
+ if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
+ chr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO &&
+ !virDomainVirtioSerialAddrIsComplete(&chr->info) &&
+ virDomainVirtioSerialAddrAutoAssign(addrs, &chr->info, false) < 0)
+ goto cleanup;
+ }
+
+ if (obj && obj->privateData) {
+ priv = obj->privateData;
+ /* if this is the live domain object, we persist the addresses */
+ virDomainVirtioSerialAddrSetFree(priv->vioserialaddrs);
+ priv->persistentAddrs = 1;
+ priv->vioserialaddrs = addrs;
+ addrs = NULL;
+ }
+ ret = 0;
+
+ cleanup:
+ virDomainVirtioSerialAddrSetFree(addrs);
+ return ret;
+}
+
+
int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def,
virQEMUCapsPtr qemuCaps)
{
@@ -1649,6 +1708,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 d1be66e54818d5e77f578da112b00acdbc9c6500..786e0b8da165581ea246325b694bd683b6552ae6 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -436,6 +436,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 e4140d8c58a137e8f2ca497dac2bf91855223e55..0ea6d2f49a58ebeeae527d732ead3fc2372ec579 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -163,6 +163,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 93768993490c08fbe485d038b6992cb67e9c3f35..ed8f65a5870d436c42e292e6e870b203dbcd7b70 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5188,6 +5188,8 @@ void qemuProcessStop(virQEMUDriverPtr driver,
virDomainDefClearCCWAddresses(vm->def);
virDomainCCWAddressSetFree(priv->ccwaddrs);
priv->ccwaddrs = NULL;
+ virDomainVirtioSerialAddrSetFree(priv->vioserialaddrs);
+ priv->vioserialaddrs = NULL;
}
qemuDomainReAttachHostDevices(driver, vm->def);
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-auto.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-auto.args
index f7d7409708513bb611bd36a6d9b8b07f854012ca..1806b20d382557997374f9957a8edbfa45ee5a97 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-auto.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-auto.args
@@ -15,7 +15,7 @@ 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,\
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-serial1.0,nr=2,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,\
name=org.linux-kvm.port.lla -device virtio-balloon-pci,id=balloon0,\
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-autoassign.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-autoassign.args
index f7f7b8da579577ea925da6223d762585a506fa98..f11039dcd44691e1369c62e05eceb86d785e6f7c 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.2,nr=1,\
+-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.0,nr=2,\
+-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 fd6b8524e84773158a880f4262ba922f28259986..7a608a86b209097711903786a6f386ae46eec0dd 100644
--- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-channel-virtio-auto.xml
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-channel-virtio-auto.xml
@@ -29,11 +29,10 @@
-
-
+
@@ -41,15 +40,15 @@
-
+
-
+
-
+