diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 452c8b28ea..e98625307f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -956,6 +956,82 @@ virDomainChrSourceDefClear(virDomainChrSourceDefPtr def) } } +/* Deep copies the contents of src into dest. Return -1 and report + * error on failure. */ +int +virDomainChrSourceDefCopy(virDomainChrSourceDefPtr dest, + virDomainChrSourceDefPtr src) +{ + if (!dest || !src) + return -1; + + virDomainChrSourceDefClear(dest); + + switch (src->type) { + case VIR_DOMAIN_CHR_TYPE_PTY: + case VIR_DOMAIN_CHR_TYPE_DEV: + case VIR_DOMAIN_CHR_TYPE_FILE: + case VIR_DOMAIN_CHR_TYPE_PIPE: + if (src->data.file.path && + !(dest->data.file.path = strdup(src->data.file.path))) { + virReportOOMError(); + return -1; + } + break; + + case VIR_DOMAIN_CHR_TYPE_UDP: + if (src->data.udp.bindHost && + !(dest->data.udp.bindHost = strdup(src->data.udp.bindHost))) { + virReportOOMError(); + return -1; + } + + if (src->data.udp.bindService && + !(dest->data.udp.bindService = strdup(src->data.udp.bindService))) { + virReportOOMError(); + return -1; + } + + if (src->data.udp.connectHost && + !(dest->data.udp.connectHost = strdup(src->data.udp.connectHost))) { + virReportOOMError(); + return -1; + } + + + if (src->data.udp.connectService && + !(dest->data.udp.connectService = strdup(src->data.udp.connectService))) { + virReportOOMError(); + return -1; + } + break; + + case VIR_DOMAIN_CHR_TYPE_TCP: + if (src->data.tcp.host && + !(dest->data.tcp.host = strdup(src->data.tcp.host))) { + virReportOOMError(); + return -1; + } + + if (src->data.tcp.service && + !(dest->data.tcp.service = strdup(src->data.tcp.service))) { + virReportOOMError(); + return -1; + } + break; + + case VIR_DOMAIN_CHR_TYPE_UNIX: + if (src->data.nix.path && + !(dest->data.nix.path = strdup(src->data.nix.path))) { + virReportOOMError(); + return -1; + } + break; + } + + return 0; +} + void virDomainChrSourceDefFree(virDomainChrSourceDefPtr def) { if (!def) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 4e86d30eab..481dfc6d0b 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1662,6 +1662,8 @@ void virDomainNetDefFree(virDomainNetDefPtr def); void virDomainSmartcardDefFree(virDomainSmartcardDefPtr def); void virDomainChrDefFree(virDomainChrDefPtr def); void virDomainChrSourceDefFree(virDomainChrSourceDefPtr def); +int virDomainChrSourceDefCopy(virDomainChrSourceDefPtr src, + virDomainChrSourceDefPtr dest); void virDomainSoundDefFree(virDomainSoundDefPtr def); void virDomainMemballoonDefFree(virDomainMemballoonDefPtr def); void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index f4e25c1760..e5784f579c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -242,6 +242,7 @@ virDomainChrConsoleTargetTypeToString; virDomainChrDefForeach; virDomainChrDefFree; virDomainChrDefNew; +virDomainChrSourceDefCopy; virDomainChrSourceDefFree; virDomainChrSpicevmcTypeFromString; virDomainChrSpicevmcTypeToString; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 04fcdefff0..2563f97ba2 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1163,11 +1163,22 @@ qemuProcessFindCharDevicePTYs(virDomainObjPtr vm, for (i = 0 ; i < vm->def->nconsoles ; i++) { virDomainChrDefPtr chr = vm->def->consoles[i]; - if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY && - chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO) { - if ((ret = qemuProcessExtractTTYPath(output, &offset, - &chr->source.data.file.path)) != 0) + /* For historical reasons, console[0] can be just an alias + * for serial[0]; That's why we need to update it as well */ + if (i == 0 && vm->def->nserials && + chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE && + chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL) { + if ((ret = virDomainChrSourceDefCopy(&chr->source, + &((vm->def->serials[0])->source))) != 0) return ret; + chr->source.type = VIR_DOMAIN_CHR_TYPE_PTY; + } else { + if (chr->source.type == VIR_DOMAIN_CHR_TYPE_PTY && + chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO) { + if ((ret = qemuProcessExtractTTYPath(output, &offset, + &chr->source.data.file.path)) != 0) + return ret; + } } }