提交 daf51be5 编写于 作者: J Ján Tomko

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.
上级 a2bdfa52
...@@ -12027,15 +12027,27 @@ virDomainChrGetDomainPtrs(const virDomainDef *vmdef, ...@@ -12027,15 +12027,27 @@ virDomainChrGetDomainPtrs(const virDomainDef *vmdef,
int int
virDomainChrInsert(virDomainDefPtr vmdef, virDomainChrPreAlloc(virDomainDefPtr vmdef,
virDomainChrDefPtr chr) virDomainChrDefPtr chr)
{
virDomainChrDefPtr **arrPtr = NULL;
size_t *cntPtr = NULL;
virDomainChrGetDomainPtrsInternal(vmdef, chr->deviceType, &arrPtr, &cntPtr);
return VIR_REALLOC_N(*arrPtr, *cntPtr + 1);
}
void
virDomainChrInsertPreAlloced(virDomainDefPtr vmdef,
virDomainChrDefPtr chr)
{ {
virDomainChrDefPtr **arrPtr = NULL; virDomainChrDefPtr **arrPtr = NULL;
size_t *cntPtr = NULL; size_t *cntPtr = NULL;
virDomainChrGetDomainPtrsInternal(vmdef, chr->deviceType, &arrPtr, &cntPtr); virDomainChrGetDomainPtrsInternal(vmdef, chr->deviceType, &arrPtr, &cntPtr);
return VIR_APPEND_ELEMENT(*arrPtr, *cntPtr, chr); ignore_value(VIR_APPEND_ELEMENT_INPLACE(*arrPtr, *cntPtr, chr));
} }
virDomainChrDefPtr virDomainChrDefPtr
......
...@@ -2652,8 +2652,11 @@ bool ...@@ -2652,8 +2652,11 @@ bool
virDomainChrEquals(virDomainChrDefPtr src, virDomainChrEquals(virDomainChrDefPtr src,
virDomainChrDefPtr tgt); virDomainChrDefPtr tgt);
int int
virDomainChrInsert(virDomainDefPtr vmdef, virDomainChrPreAlloc(virDomainDefPtr vmdef,
virDomainChrDefPtr chr); virDomainChrDefPtr chr);
void
virDomainChrInsertPreAlloced(virDomainDefPtr vmdef,
virDomainChrDefPtr chr);
virDomainChrDefPtr virDomainChrDefPtr
virDomainChrRemove(virDomainDefPtr vmdef, virDomainChrRemove(virDomainDefPtr vmdef,
virDomainChrDefPtr chr); virDomainChrDefPtr chr);
......
...@@ -153,7 +153,8 @@ virDomainChrDefNew; ...@@ -153,7 +153,8 @@ virDomainChrDefNew;
virDomainChrEquals; virDomainChrEquals;
virDomainChrFind; virDomainChrFind;
virDomainChrGetDomainPtrs; virDomainChrGetDomainPtrs;
virDomainChrInsert; virDomainChrInsertPreAlloced;
virDomainChrPreAlloc;
virDomainChrRemove; virDomainChrRemove;
virDomainChrSerialTargetTypeFromString; virDomainChrSerialTargetTypeFromString;
virDomainChrSerialTargetTypeToString; virDomainChrSerialTargetTypeToString;
......
...@@ -1403,9 +1403,9 @@ int qemuDomainAttachRedirdevDevice(virQEMUDriverPtr driver, ...@@ -1403,9 +1403,9 @@ int qemuDomainAttachRedirdevDevice(virQEMUDriverPtr driver,
} }
int static int
qemuDomainChrInsert(virDomainDefPtr vmdef, qemuDomainChrPreInsert(virDomainDefPtr vmdef,
virDomainChrDefPtr chr) virDomainChrDefPtr chr)
{ {
if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE && if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL) { chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL) {
...@@ -1420,25 +1420,63 @@ qemuDomainChrInsert(virDomainDefPtr vmdef, ...@@ -1420,25 +1420,63 @@ qemuDomainChrInsert(virDomainDefPtr vmdef,
return -1; return -1;
} }
if (virDomainChrInsert(vmdef, chr) < 0) if (virDomainChrPreAlloc(vmdef, chr) < 0)
return -1; return -1;
/* Due to some crazy backcompat stuff, the first serial device is an alias /* 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 * to the first console too. If this is the case, the definition must be
* duplicated as first console device. */ * duplicated as first console device. */
if (vmdef->nserials == 1 && vmdef->nconsoles == 0) { if (vmdef->nserials == 0 && vmdef->nconsoles == 0 &&
if ((!vmdef->consoles && VIR_ALLOC(vmdef->consoles) < 0) || chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL) {
VIR_ALLOC(vmdef->consoles[0]) < 0) { if (!vmdef->consoles && VIR_ALLOC(vmdef->consoles) < 0)
virDomainChrRemove(vmdef, chr); return -1;
if (VIR_ALLOC(vmdef->consoles[0]) < 0) {
VIR_FREE(vmdef->consoles);
return -1; 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; vmdef->nconsoles = 1;
/* Create an console alias for the serial port */ /* Create an console alias for the serial port */
vmdef->consoles[0]->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE; vmdef->consoles[0]->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE;
vmdef->consoles[0]->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL; 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; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册