mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-04-26 15:14:42 +00:00
Allocate virtio-serial addresses when starting a domain
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 Test changes: * virtio-auto.args Filling out the port when just the controller is specified. switched from using maxport + 1 to: first free port on the controller * virtio-autoassign.args Filling out the address when no <address> is specified. Started using all the controllers instead of 0, also discards the bus value. * xml -> xml output of virtio-auto The port assignment is no longer done as a part of XML parsing, so the unspecified values stay 0.
This commit is contained in:
parent
16db8d2ec5
commit
5903378834
@ -3512,21 +3512,6 @@ virDomainDeviceDefPostParseInternal(virDomainDeviceDefPtr dev,
|
|||||||
|
|
||||||
chr->target.port = maxport + 1;
|
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 */
|
/* set default path for virtio-rng "random" backend to /dev/random */
|
||||||
@ -12499,6 +12484,20 @@ virDomainControllerFind(virDomainDefPtr def,
|
|||||||
return -1;
|
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
|
int
|
||||||
virDomainControllerFindByPCIAddress(virDomainDefPtr def,
|
virDomainControllerFindByPCIAddress(virDomainDefPtr def,
|
||||||
virDevicePCIAddressPtr addr)
|
virDevicePCIAddressPtr addr)
|
||||||
@ -14935,25 +14934,6 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
def->channels[def->nchannels++] = chr;
|
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);
|
VIR_FREE(nodes);
|
||||||
|
|
||||||
|
@ -2717,6 +2717,7 @@ int virDomainControllerInsert(virDomainDefPtr def,
|
|||||||
void virDomainControllerInsertPreAlloced(virDomainDefPtr def,
|
void virDomainControllerInsertPreAlloced(virDomainDefPtr def,
|
||||||
virDomainControllerDefPtr controller);
|
virDomainControllerDefPtr controller);
|
||||||
int virDomainControllerFind(virDomainDefPtr def, int type, int idx);
|
int virDomainControllerFind(virDomainDefPtr def, int type, int idx);
|
||||||
|
int virDomainControllerFindByType(virDomainDefPtr def, int type);
|
||||||
int virDomainControllerFindByPCIAddress(virDomainDefPtr def,
|
int virDomainControllerFindByPCIAddress(virDomainDefPtr def,
|
||||||
virDevicePCIAddressPtr addr);
|
virDevicePCIAddressPtr addr);
|
||||||
virDomainControllerDefPtr virDomainControllerRemove(virDomainDefPtr def, size_t i);
|
virDomainControllerDefPtr virDomainControllerRemove(virDomainDefPtr def, size_t i);
|
||||||
|
@ -184,6 +184,7 @@ virDomainClockOffsetTypeToString;
|
|||||||
virDomainConfigFile;
|
virDomainConfigFile;
|
||||||
virDomainControllerDefFree;
|
virDomainControllerDefFree;
|
||||||
virDomainControllerFind;
|
virDomainControllerFind;
|
||||||
|
virDomainControllerFindByType;
|
||||||
virDomainControllerInsert;
|
virDomainControllerInsert;
|
||||||
virDomainControllerInsertPreAlloced;
|
virDomainControllerInsertPreAlloced;
|
||||||
virDomainControllerModelPCITypeToString;
|
virDomainControllerModelPCITypeToString;
|
||||||
|
@ -1403,6 +1403,65 @@ qemuAssignSpaprVIOAddress(virDomainDefPtr def, virDomainDeviceInfoPtr info,
|
|||||||
return 0;
|
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,
|
int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def,
|
||||||
virQEMUCapsPtr qemuCaps)
|
virQEMUCapsPtr qemuCaps)
|
||||||
{
|
{
|
||||||
@ -1649,6 +1708,10 @@ int qemuDomainAssignAddresses(virDomainDefPtr def,
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
rc = qemuDomainAssignVirtioSerialAddresses(def, obj);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
rc = qemuDomainAssignSpaprVIOAddresses(def, qemuCaps);
|
rc = qemuDomainAssignSpaprVIOAddresses(def, qemuCaps);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -436,6 +436,7 @@ qemuDomainObjPrivateFree(void *data)
|
|||||||
virCgroupFree(&priv->cgroup);
|
virCgroupFree(&priv->cgroup);
|
||||||
virDomainPCIAddressSetFree(priv->pciaddrs);
|
virDomainPCIAddressSetFree(priv->pciaddrs);
|
||||||
virDomainCCWAddressSetFree(priv->ccwaddrs);
|
virDomainCCWAddressSetFree(priv->ccwaddrs);
|
||||||
|
virDomainVirtioSerialAddrSetFree(priv->vioserialaddrs);
|
||||||
virDomainChrSourceDefFree(priv->monConfig);
|
virDomainChrSourceDefFree(priv->monConfig);
|
||||||
qemuDomainObjFreeJob(priv);
|
qemuDomainObjFreeJob(priv);
|
||||||
VIR_FREE(priv->vcpupids);
|
VIR_FREE(priv->vcpupids);
|
||||||
|
@ -163,6 +163,7 @@ struct _qemuDomainObjPrivate {
|
|||||||
|
|
||||||
virDomainPCIAddressSetPtr pciaddrs;
|
virDomainPCIAddressSetPtr pciaddrs;
|
||||||
virDomainCCWAddressSetPtr ccwaddrs;
|
virDomainCCWAddressSetPtr ccwaddrs;
|
||||||
|
virDomainVirtioSerialAddrSetPtr vioserialaddrs;
|
||||||
int persistentAddrs;
|
int persistentAddrs;
|
||||||
|
|
||||||
virQEMUCapsPtr qemuCaps;
|
virQEMUCapsPtr qemuCaps;
|
||||||
|
@ -5188,6 +5188,8 @@ void qemuProcessStop(virQEMUDriverPtr driver,
|
|||||||
virDomainDefClearCCWAddresses(vm->def);
|
virDomainDefClearCCWAddresses(vm->def);
|
||||||
virDomainCCWAddressSetFree(priv->ccwaddrs);
|
virDomainCCWAddressSetFree(priv->ccwaddrs);
|
||||||
priv->ccwaddrs = NULL;
|
priv->ccwaddrs = NULL;
|
||||||
|
virDomainVirtioSerialAddrSetFree(priv->vioserialaddrs);
|
||||||
|
priv->vioserialaddrs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemuDomainReAttachHostDevices(driver, vm->def);
|
qemuDomainReAttachHostDevices(driver, vm->def);
|
||||||
|
@ -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 \
|
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=2,chardev=charchannel3,id=channel3,\
|
||||||
name=org.linux-kvm.port.wizz -chardev pty,id=charchannel4 -device \
|
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 \
|
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-serial2.0,nr=1,chardev=charchannel5,id=channel5,\
|
||||||
name=org.linux-kvm.port.lla -device virtio-balloon-pci,id=balloon0,\
|
name=org.linux-kvm.port.lla -device virtio-balloon-pci,id=balloon0,\
|
||||||
|
@ -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\
|
-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 \
|
,addr=0x3 -device virtio-serial-pci,id=virtio-serial1,bus=pci.0,addr=0xa \
|
||||||
-usb -hda /dev/HostVG/QEMUGuest1 \
|
-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=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=charchannel1,id=channel1,name=org.linux-kvm.port.foo \
|
||||||
-chardev pty,id=charchannel2 -device virtserialport,bus=virtio-serial0.0,nr=1,\
|
-chardev pty,id=charchannel2 -device virtserialport,bus=virtio-serial0.0,nr=1,\
|
||||||
chardev=charchannel2,id=channel2,name=org.linux-kvm.port.bar \
|
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=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=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 \
|
chardev=charchannel5,id=channel5,name=org.linux-kvm.port.lla \
|
||||||
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
|
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
|
||||||
|
@ -29,11 +29,10 @@
|
|||||||
<controller type='virtio-serial' index='2'/>
|
<controller type='virtio-serial' index='2'/>
|
||||||
<channel type='pty'>
|
<channel type='pty'>
|
||||||
<target type='virtio' name='org.linux-kvm.port.0'/>
|
<target type='virtio' name='org.linux-kvm.port.0'/>
|
||||||
<address type='virtio-serial' controller='0' bus='0' port='1'/>
|
|
||||||
</channel>
|
</channel>
|
||||||
<channel type='pty'>
|
<channel type='pty'>
|
||||||
<target type='virtio' name='org.linux-kvm.port.foo'/>
|
<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>
|
||||||
<channel type='pty'>
|
<channel type='pty'>
|
||||||
<target type='virtio' name='org.linux-kvm.port.bar'/>
|
<target type='virtio' name='org.linux-kvm.port.bar'/>
|
||||||
@ -41,15 +40,15 @@
|
|||||||
</channel>
|
</channel>
|
||||||
<channel type='pty'>
|
<channel type='pty'>
|
||||||
<target type='virtio' name='org.linux-kvm.port.wizz'/>
|
<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>
|
||||||
<channel type='pty'>
|
<channel type='pty'>
|
||||||
<target type='virtio' name='org.linux-kvm.port.ooh'/>
|
<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>
|
||||||
<channel type='pty'>
|
<channel type='pty'>
|
||||||
<target type='virtio' name='org.linux-kvm.port.lla'/>
|
<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>
|
</channel>
|
||||||
<memballoon model='virtio'/>
|
<memballoon model='virtio'/>
|
||||||
</devices>
|
</devices>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user