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_REALLOC_N(*arrPtr, *cntPtr + 1);
+}
+
+void
+virDomainChrInsertPreAlloced(virDomainDefPtr vmdef,
+ virDomainChrDefPtr chr)
{
virDomainChrDefPtr **arrPtr = NULL;
size_t *cntPtr = NULL;
virDomainChrGetDomainPtrsInternal(vmdef, chr->deviceType, &arrPtr, &cntPtr);
- return VIR_APPEND_ELEMENT(*arrPtr, *cntPtr, chr);
+ ignore_value(VIR_APPEND_ELEMENT_INPLACE(*arrPtr, *cntPtr, chr));
}
virDomainChrDefPtr
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);
}
-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) {
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;
}