1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-01-09 01:18:00 +03:00

Split qemuDomainChrInsert into two parts

Do the allocation first, then add the actual device.
The second part should never fail. This is good
for live hotplug where we don't want to remove the device
on OOM after the monitor command succeeded.

The only change in behavior is that on failure, the
vmdef->consoles array is freed, not just the first console.
This commit is contained in:
Ján Tomko 2015-01-27 18:30:15 +01:00
parent a2bdfa5261
commit daf51be5f1
4 changed files with 68 additions and 14 deletions

View File

@ -12027,15 +12027,27 @@ virDomainChrGetDomainPtrs(const virDomainDef *vmdef,
int
virDomainChrInsert(virDomainDefPtr vmdef,
virDomainChrDefPtr chr)
virDomainChrPreAlloc(virDomainDefPtr vmdef,
virDomainChrDefPtr chr)
{
virDomainChrDefPtr **arrPtr = NULL;
size_t *cntPtr = NULL;
virDomainChrGetDomainPtrsInternal(vmdef, chr->deviceType, &arrPtr, &cntPtr);
return VIR_APPEND_ELEMENT(*arrPtr, *cntPtr, chr);
return VIR_REALLOC_N(*arrPtr, *cntPtr + 1);
}
void
virDomainChrInsertPreAlloced(virDomainDefPtr vmdef,
virDomainChrDefPtr chr)
{
virDomainChrDefPtr **arrPtr = NULL;
size_t *cntPtr = NULL;
virDomainChrGetDomainPtrsInternal(vmdef, chr->deviceType, &arrPtr, &cntPtr);
ignore_value(VIR_APPEND_ELEMENT_INPLACE(*arrPtr, *cntPtr, chr));
}
virDomainChrDefPtr

View File

@ -2652,8 +2652,11 @@ bool
virDomainChrEquals(virDomainChrDefPtr src,
virDomainChrDefPtr tgt);
int
virDomainChrInsert(virDomainDefPtr vmdef,
virDomainChrDefPtr chr);
virDomainChrPreAlloc(virDomainDefPtr vmdef,
virDomainChrDefPtr chr);
void
virDomainChrInsertPreAlloced(virDomainDefPtr vmdef,
virDomainChrDefPtr chr);
virDomainChrDefPtr
virDomainChrRemove(virDomainDefPtr vmdef,
virDomainChrDefPtr chr);

View File

@ -153,7 +153,8 @@ virDomainChrDefNew;
virDomainChrEquals;
virDomainChrFind;
virDomainChrGetDomainPtrs;
virDomainChrInsert;
virDomainChrInsertPreAlloced;
virDomainChrPreAlloc;
virDomainChrRemove;
virDomainChrSerialTargetTypeFromString;
virDomainChrSerialTargetTypeToString;

View File

@ -1403,9 +1403,9 @@ int qemuDomainAttachRedirdevDevice(virQEMUDriverPtr driver,
}
int
qemuDomainChrInsert(virDomainDefPtr vmdef,
virDomainChrDefPtr chr)
static int
qemuDomainChrPreInsert(virDomainDefPtr vmdef,
virDomainChrDefPtr chr)
{
if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL) {
@ -1420,25 +1420,63 @@ qemuDomainChrInsert(virDomainDefPtr vmdef,
return -1;
}
if (virDomainChrInsert(vmdef, chr) < 0)
if (virDomainChrPreAlloc(vmdef, chr) < 0)
return -1;
/* Due to some crazy backcompat stuff, the first serial device is an alias
* to the first console too. If this is the case, the definition must be
* duplicated as first console device. */
if (vmdef->nserials == 1 && vmdef->nconsoles == 0) {
if ((!vmdef->consoles && VIR_ALLOC(vmdef->consoles) < 0) ||
VIR_ALLOC(vmdef->consoles[0]) < 0) {
virDomainChrRemove(vmdef, chr);
if (vmdef->nserials == 0 && vmdef->nconsoles == 0 &&
chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL) {
if (!vmdef->consoles && VIR_ALLOC(vmdef->consoles) < 0)
return -1;
if (VIR_ALLOC(vmdef->consoles[0]) < 0) {
VIR_FREE(vmdef->consoles);
return -1;
}
vmdef->nconsoles++;
}
return 0;
}
static void
qemuDomainChrInsertPreAlloced(virDomainDefPtr vmdef,
virDomainChrDefPtr chr)
{
virDomainChrInsertPreAlloced(vmdef, chr);
if (vmdef->nserials == 1 && vmdef->nconsoles == 0 &&
chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL) {
vmdef->nconsoles = 1;
/* Create an console alias for the serial port */
vmdef->consoles[0]->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE;
vmdef->consoles[0]->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
}
}
static void
qemuDomainChrInsertPreAllocCleanup(virDomainDefPtr vmdef,
virDomainChrDefPtr chr)
{
/* Remove the stub console added by qemuDomainChrPreInsert */
if (vmdef->nserials == 0 && vmdef->nconsoles == 1 &&
chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL) {
VIR_FREE(vmdef->consoles[0]);
VIR_FREE(vmdef->consoles);
vmdef->nconsoles = 0;
}
}
int
qemuDomainChrInsert(virDomainDefPtr vmdef,
virDomainChrDefPtr chr)
{
if (qemuDomainChrPreInsert(vmdef, chr) < 0) {
qemuDomainChrInsertPreAllocCleanup(vmdef, chr);
return -1;
}
qemuDomainChrInsertPreAlloced(vmdef, chr);
return 0;
}