qemu: command: support -chardev for platform devices

Some qemu arch/machine types have built in platform devices that
are always implicitly available. For platform serial devices, the
current code assumes that only old style -serial config can be
used for these devices.

Apparently though since -chardev was introduced, we can use -chardev
in these cases, like this:

  -chardev pty,id=foo
  -serial chardev:foo

Since -chardev enables all sorts of modern features, use this method
for platform devices.

Reviewed-by: Andrea Bolognani <abologna@redhat.com>
Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
Cole Robinson 2017-06-26 14:01:52 -04:00
parent b4d5604350
commit 426dc5eb28
11 changed files with 32 additions and 129 deletions

View File

@ -5514,106 +5514,6 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd,
return 0;
}
static char *
qemuBuildChrArgStr(const virDomainChrSourceDef *dev,
const char *prefix)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
if (dev->logfile) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("logfile not supported in this QEMU binary"));
goto error;
}
if (prefix)
virBufferAdd(&buf, prefix, strlen(prefix));
switch ((virDomainChrType)dev->type) {
case VIR_DOMAIN_CHR_TYPE_NULL:
virBufferAddLit(&buf, "null");
break;
case VIR_DOMAIN_CHR_TYPE_VC:
virBufferAddLit(&buf, "vc");
break;
case VIR_DOMAIN_CHR_TYPE_PTY:
virBufferAddLit(&buf, "pty");
break;
case VIR_DOMAIN_CHR_TYPE_DEV:
virBufferStrcat(&buf, dev->data.file.path, NULL);
break;
case VIR_DOMAIN_CHR_TYPE_FILE:
virBufferAsprintf(&buf, "file:%s", dev->data.file.path);
break;
case VIR_DOMAIN_CHR_TYPE_PIPE:
virBufferAsprintf(&buf, "pipe:%s", dev->data.file.path);
break;
case VIR_DOMAIN_CHR_TYPE_STDIO:
virBufferAddLit(&buf, "stdio");
break;
case VIR_DOMAIN_CHR_TYPE_UDP: {
const char *connectHost = dev->data.udp.connectHost;
const char *bindHost = dev->data.udp.bindHost;
const char *bindService = dev->data.udp.bindService;
if (connectHost == NULL)
connectHost = "";
if (bindHost == NULL)
bindHost = "";
if (bindService == NULL)
bindService = "0";
virBufferAsprintf(&buf, "udp:%s:%s@%s:%s",
connectHost,
dev->data.udp.connectService,
bindHost,
bindService);
break;
}
case VIR_DOMAIN_CHR_TYPE_TCP:
if (dev->data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET) {
virBufferAsprintf(&buf, "telnet:%s:%s%s",
dev->data.tcp.host,
dev->data.tcp.service,
dev->data.tcp.listen ? ",server,nowait" : "");
} else {
virBufferAsprintf(&buf, "tcp:%s:%s%s",
dev->data.tcp.host,
dev->data.tcp.service,
dev->data.tcp.listen ? ",server,nowait" : "");
}
break;
case VIR_DOMAIN_CHR_TYPE_UNIX:
virBufferAsprintf(&buf, "unix:%s%s",
dev->data.nix.path,
dev->data.nix.listen ? ",server,nowait" : "");
break;
case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
case VIR_DOMAIN_CHR_TYPE_NMDM:
case VIR_DOMAIN_CHR_TYPE_LAST:
break;
}
if (virBufferCheckError(&buf) < 0)
goto error;
return virBufferContentAndReset(&buf);
error:
virBufferFreeAndReset(&buf);
return NULL;
}
static int
qemuBuildMonitorCommandLine(virLogManagerPtr logManager,
@ -9226,26 +9126,23 @@ qemuBuildSerialCommandLine(virLogManagerPtr logManager,
if (serial->source->type == VIR_DOMAIN_CHR_TYPE_SPICEPORT && !havespice)
continue;
if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, cfg, def,
serial->source,
serial->info.alias,
qemuCaps, true,
chardevStdioLogd)))
return -1;
virCommandAddArg(cmd, "-chardev");
virCommandAddArg(cmd, devstr);
VIR_FREE(devstr);
/* Use -chardev with -device if they are available */
if (virQEMUCapsSupportsChardev(def, qemuCaps, serial)) {
if (!(devstr = qemuBuildChrChardevStr(logManager, cmd, cfg, def,
serial->source,
serial->info.alias,
qemuCaps, true,
chardevStdioLogd)))
return -1;
virCommandAddArg(cmd, "-chardev");
virCommandAddArg(cmd, devstr);
VIR_FREE(devstr);
if (qemuBuildChrDeviceCommandLine(cmd, def, serial, qemuCaps) < 0)
return -1;
} else {
virCommandAddArg(cmd, "-serial");
if (!(devstr = qemuBuildChrArgStr(serial->source, NULL)))
return -1;
virCommandAddArg(cmd, devstr);
VIR_FREE(devstr);
virCommandAddArgFormat(cmd, "chardev:char%s", serial->info.alias);
}
}

View File

@ -1877,8 +1877,8 @@ qemuProcessMonitorReportLogError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
static int
qemuProcessLookupPTYs(virDomainDefPtr def,
virQEMUCapsPtr qemuCaps,
qemuProcessLookupPTYs(virDomainDefPtr def ATTRIBUTE_UNUSED,
virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED,
virDomainChrDefPtr *devices,
int count,
virHashTablePtr info)
@ -1887,14 +1887,11 @@ qemuProcessLookupPTYs(virDomainDefPtr def,
for (i = 0; i < count; i++) {
virDomainChrDefPtr chr = devices[i];
bool chardevfmt = virQEMUCapsSupportsChardev(def, qemuCaps, chr);
if (chr->source->type == VIR_DOMAIN_CHR_TYPE_PTY) {
char id[32];
qemuMonitorChardevInfoPtr entry;
if (snprintf(id, sizeof(id), "%s%s",
chardevfmt ? "char" : "",
if (snprintf(id, sizeof(id), "char%s",
chr->info.alias) >= sizeof(id)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("failed to format device alias "

View File

@ -26,4 +26,5 @@ server,nowait \
-device virtio-blk-device,drive=drive-virtio-disk0,id=virtio-disk0 \
-device virtio-net-device,vlan=0,id=net0,mac=52:54:00:09:a4:37 \
-net user,vlan=0,name=hostnet0 \
-serial pty
-chardev pty,id=charserial0 \
-serial chardev:charserial0

View File

@ -33,7 +33,8 @@ path=/tmp/lib/domain--1-aarch64test/monitor.sock,server,nowait \
id=virtio-disk0 \
-device virtio-net-pci,vlan=0,id=net0,mac=52:54:00:09:a4:37,bus=pci.2,addr=0x1 \
-net user,vlan=0,name=hostnet0 \
-serial pty \
-chardev pty,id=charserial0 \
-serial chardev:charserial0 \
-chardev pty,id=charconsole1 \
-device virtconsole,chardev=charconsole1,id=console1 \
-device virtio-balloon-pci,id=balloon0,bus=pci.2,addr=0x4 \

View File

@ -29,7 +29,8 @@ path=/tmp/lib/domain--1-aarch64test/monitor.sock,server,nowait \
-device virtio-blk-device,drive=drive-virtio-disk0,id=virtio-disk0 \
-device virtio-net-device,vlan=0,id=net0,mac=52:54:00:09:a4:37 \
-net user,vlan=0,name=hostnet0 \
-serial pty \
-chardev pty,id=charserial0 \
-serial chardev:charserial0 \
-chardev pty,id=charconsole1 \
-device virtconsole,chardev=charconsole1,id=console1 \
-device virtio-balloon-device,id=balloon0 \

View File

@ -37,7 +37,8 @@ addr=0x1 \
id=virtio-disk0 \
-device virtio-net-pci,vlan=0,id=net0,mac=52:54:00:09:a4:37,bus=pci.1,addr=0x0 \
-net user,vlan=0,name=hostnet0 \
-serial pty \
-chardev pty,id=charserial0 \
-serial chardev:charserial0 \
-chardev pty,id=charconsole1 \
-device virtconsole,chardev=charconsole1,id=console1 \
-device virtio-balloon-pci,id=balloon0,bus=pci.4,addr=0x0 \

View File

@ -27,4 +27,5 @@ server,nowait \
-drive file=/arm.raw,format=raw,if=sd,index=0 \
-net nic,macaddr=52:54:00:09:a4:37,vlan=0,model=lan9118,name=net0 \
-net user,vlan=0,name=hostnet0 \
-serial pty
-chardev pty,id=charserial0 \
-serial chardev:charserial0

View File

@ -29,7 +29,8 @@ server,nowait \
-device virtio-blk-device,drive=drive-virtio-disk0,id=virtio-disk0 \
-device virtio-net-device,vlan=0,id=net0,mac=52:54:00:09:a4:37 \
-net user,vlan=0,name=hostnet0 \
-serial pty \
-chardev pty,id=charserial0 \
-serial chardev:charserial0 \
-chardev pty,id=charconsole1 \
-device virtconsole,chardev=charconsole1,id=console1 \
-device virtio-balloon-device,id=balloon0 \

View File

@ -27,7 +27,8 @@ server,nowait \
-device virtio-blk-device,drive=drive-virtio-disk0,id=virtio-disk0 \
-device virtio-net-device,vlan=0,id=net0,mac=52:54:00:09:a4:37 \
-net user,vlan=0,name=hostnet0 \
-serial pty \
-chardev pty,id=charserial0 \
-serial chardev:charserial0 \
-chardev pty,id=charconsole1 \
-device virtconsole,chardev=charconsole1,id=console1 \
-device virtio-balloon-device,id=balloon0 \

View File

@ -22,5 +22,6 @@ server,nowait \
-append 'root=/dev/ram rw console=ttyS0,115200' \
-dtb /media/ram/test.dtb \
-usb \
-serial pty \
-chardev pty,id=charserial0 \
-serial chardev:charserial0 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2

View File

@ -21,5 +21,6 @@ server,nowait \
-initrd /media/ram/ramdisk \
-append 'root=/dev/ram rw console=ttyS0,115200' \
-usb \
-serial pty \
-chardev pty,id=charserial0 \
-serial chardev:charserial0 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2