qemu: Introduce qemuBuildChrDeviceStr

The function being introduced is responsible for creating command
line argument for '-device' for given character device. Based on
the chardev type, it calls appropriate qemuBuild.*ChrDeviceStr(),
e.g.  qemuBuildSerialChrDeviceStr() for serial chardev and so on.
This commit is contained in:
Michal Privoznik 2013-03-13 16:20:34 +01:00
parent 2a9a5bef97
commit f293d76333
2 changed files with 163 additions and 51 deletions

View File

@ -6596,6 +6596,21 @@ cleanup:
return ret; return ret;
} }
static int
qemuBuildChrDeviceCommandLine(virCommandPtr cmd,
virDomainDefPtr def,
virDomainChrDefPtr chr,
virQEMUCapsPtr qemuCaps)
{
char *devstr = NULL;
if (qemuBuildChrDeviceStr(&devstr, def, chr, qemuCaps) < 0)
return -1;
virCommandAddArgList(cmd, "-device", devstr, NULL);
return 0;
}
qemuBuildCommandLineCallbacks buildCommandLineCallbacks = { qemuBuildCommandLineCallbacks buildCommandLineCallbacks = {
.qemuGetSCSIDeviceSgName = virSCSIDeviceGetSgName, .qemuGetSCSIDeviceSgName = virSCSIDeviceGetSgName,
}; };
@ -7675,13 +7690,8 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArg(cmd, devstr); virCommandAddArg(cmd, devstr);
VIR_FREE(devstr); VIR_FREE(devstr);
virCommandAddArg(cmd, "-device"); if (qemuBuildChrDeviceCommandLine(cmd, def, serial, qemuCaps) < 0)
if (!(devstr = qemuBuildChrDeviceStr(serial, qemuCaps,
def->os.arch,
def->os.machine)))
goto error; goto error;
virCommandAddArg(cmd, devstr);
VIR_FREE(devstr);
} else { } else {
virCommandAddArg(cmd, "-serial"); virCommandAddArg(cmd, "-serial");
if (!(devstr = qemuBuildChrArgStr(&serial->source, NULL))) if (!(devstr = qemuBuildChrArgStr(&serial->source, NULL)))
@ -7712,10 +7722,8 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArg(cmd, devstr); virCommandAddArg(cmd, devstr);
VIR_FREE(devstr); VIR_FREE(devstr);
virCommandAddArg(cmd, "-device"); if (qemuBuildChrDeviceCommandLine(cmd, def, parallel, qemuCaps) < 0)
virCommandAddArgFormat(cmd, "isa-parallel,chardev=char%s,id=%s", goto error;
parallel->info.alias,
parallel->info.alias);
} else { } else {
virCommandAddArg(cmd, "-parallel"); virCommandAddArg(cmd, "-parallel");
if (!(devstr = qemuBuildChrArgStr(&parallel->source, NULL))) if (!(devstr = qemuBuildChrArgStr(&parallel->source, NULL)))
@ -7729,8 +7737,6 @@ qemuBuildCommandLine(virConnectPtr conn,
for (i = 0; i < def->nchannels; i++) { for (i = 0; i < def->nchannels; i++) {
virDomainChrDefPtr channel = def->channels[i]; virDomainChrDefPtr channel = def->channels[i];
char *devstr; char *devstr;
char *addr;
int port;
switch (channel->targetType) { switch (channel->targetType) {
case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD: case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD:
@ -7749,17 +7755,10 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArg(cmd, devstr); virCommandAddArg(cmd, devstr);
VIR_FREE(devstr); VIR_FREE(devstr);
addr = virSocketAddrFormat(channel->target.addr); if (qemuBuildChrDeviceStr(&devstr, def, channel, qemuCaps) < 0)
if (!addr)
goto error; goto error;
port = virSocketAddrGetPort(channel->target.addr); virCommandAddArgList(cmd, "-netdev", devstr, NULL);
VIR_FREE(devstr);
virCommandAddArg(cmd, "-netdev");
virCommandAddArgFormat(cmd,
"user,guestfwd=tcp:%s:%i,chardev=char%s,id=user-%s",
addr, port, channel->info.alias,
channel->info.alias);
VIR_FREE(addr);
break; break;
case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO: case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO:
@ -7785,12 +7784,8 @@ qemuBuildCommandLine(virConnectPtr conn,
VIR_FREE(devstr); VIR_FREE(devstr);
} }
virCommandAddArg(cmd, "-device"); if (qemuBuildChrDeviceCommandLine(cmd, def, channel, qemuCaps) < 0)
if (!(devstr = qemuBuildVirtioSerialPortDevStr(channel,
qemuCaps)))
goto error; goto error;
virCommandAddArg(cmd, devstr);
VIR_FREE(devstr);
break; break;
} }
} }
@ -7822,11 +7817,8 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArg(cmd, devstr); virCommandAddArg(cmd, devstr);
VIR_FREE(devstr); VIR_FREE(devstr);
virCommandAddArg(cmd, "-device"); if (qemuBuildChrDeviceCommandLine(cmd, def, console, qemuCaps) < 0)
if (!(devstr = qemuBuildSclpDevStr(console)))
goto error; goto error;
virCommandAddArg(cmd, devstr);
VIR_FREE(devstr);
break; break;
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO: case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO:
@ -7844,12 +7836,8 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArg(cmd, devstr); virCommandAddArg(cmd, devstr);
VIR_FREE(devstr); VIR_FREE(devstr);
virCommandAddArg(cmd, "-device"); if (qemuBuildChrDeviceCommandLine(cmd, def, console, qemuCaps) < 0)
if (!(devstr = qemuBuildVirtioSerialPortDevStr(console,
qemuCaps)))
goto error; goto error;
virCommandAddArg(cmd, devstr);
VIR_FREE(devstr);
break; break;
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL: case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL:
@ -8538,11 +8526,12 @@ error:
/* This function generates the correct '-device' string for character /* This function generates the correct '-device' string for character
* devices of each architecture. * devices of each architecture.
*/ */
char * static int
qemuBuildChrDeviceStr(virDomainChrDefPtr serial, qemuBuildSerialChrDeviceStr(char **deviceStr,
virQEMUCapsPtr qemuCaps, virDomainChrDefPtr serial,
virArch arch, virQEMUCapsPtr qemuCaps,
char *machine) virArch arch,
char *machine)
{ {
virBuffer cmd = VIR_BUFFER_INITIALIZER; virBuffer cmd = VIR_BUFFER_INITIALIZER;
@ -8574,7 +8563,7 @@ qemuBuildChrDeviceStr(virDomainChrDefPtr serial,
} }
if (qemuBuildDeviceAddressStr(&cmd, &serial->info, qemuCaps) < 0) if (qemuBuildDeviceAddressStr(&cmd, &serial->info, qemuCaps) < 0)
goto error; goto error;
} }
} }
@ -8583,13 +8572,136 @@ qemuBuildChrDeviceStr(virDomainChrDefPtr serial,
goto error; goto error;
} }
return virBufferContentAndReset(&cmd); *deviceStr = virBufferContentAndReset(&cmd);
return 0;
error: error:
virBufferFreeAndReset(&cmd); virBufferFreeAndReset(&cmd);
return NULL; return -1;
} }
static int
qemuBuildParallelChrDeviceStr(char **deviceStr,
virDomainChrDefPtr chr)
{
if (virAsprintf(deviceStr, "isa-parallel,chardev=char%s,id=%s",
chr->info.alias, chr->info.alias) < 0) {
virReportOOMError();
return -1;
}
return 0;
}
static int
qemuBuildChannelChrDeviceStr(char **deviceStr,
virDomainChrDefPtr chr,
virQEMUCapsPtr qemuCaps)
{
int ret = -1;
char *addr = NULL;
int port;
switch ((enum virDomainChrChannelTargetType) chr->targetType) {
case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD:
addr = virSocketAddrFormat(chr->target.addr);
if (!addr)
return ret;
port = virSocketAddrGetPort(chr->target.addr);
if (virAsprintf(deviceStr,
"user,guestfwd=tcp:%s:%i,chardev=char%s,id=user-%s",
addr, port, chr->info.alias, chr->info.alias) < 0) {
virReportOOMError();
goto cleanup;
}
break;
case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO:
if (!(*deviceStr = qemuBuildVirtioSerialPortDevStr(chr, qemuCaps)))
goto cleanup;
break;
case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_NONE:
case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_LAST:
return ret;
}
ret = 0;
cleanup:
VIR_FREE(addr);
return ret;
}
static int
qemuBuildConsoleChrDeviceStr(char **deviceStr,
virDomainChrDefPtr chr,
virQEMUCapsPtr qemuCaps)
{
int ret = -1;
switch ((enum virDomainChrConsoleTargetType) chr->targetType) {
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SCLP:
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SCLPLM:
if (!(*deviceStr = qemuBuildSclpDevStr(chr)))
goto cleanup;
break;
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO:
if (!(*deviceStr = qemuBuildVirtioSerialPortDevStr(chr, qemuCaps)))
goto cleanup;
break;
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL:
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_NONE:
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_XEN:
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_UML:
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LXC:
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_OPENVZ:
case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LAST:
break;
}
ret = 0;
cleanup:
return ret;
}
int
qemuBuildChrDeviceStr(char **deviceStr,
virDomainDefPtr vmdef,
virDomainChrDefPtr chr,
virQEMUCapsPtr qemuCaps)
{
int ret = -1;
switch ((enum virDomainChrDeviceType) chr->deviceType) {
case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL:
ret = qemuBuildSerialChrDeviceStr(deviceStr, chr, qemuCaps,
vmdef->os.arch,
vmdef->os.machine);
break;
case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL:
ret = qemuBuildParallelChrDeviceStr(deviceStr, chr);
break;
case VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL:
ret = qemuBuildChannelChrDeviceStr(deviceStr, chr, qemuCaps);
break;
case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE:
ret = qemuBuildConsoleChrDeviceStr(deviceStr, chr, qemuCaps);
break;
case VIR_DOMAIN_CHR_DEVICE_TYPE_LAST:
return ret;
}
return ret;
}
/* /*
* This method takes a string representing a QEMU command line ARGV set * This method takes a string representing a QEMU command line ARGV set
* optionally prefixed by a list of environment variables. It then tries * optionally prefixed by a list of environment variables. It then tries

View File

@ -75,12 +75,12 @@ virCommandPtr qemuBuildCommandLine(virConnectPtr conn,
qemuBuildCommandLineCallbacksPtr callbacks) qemuBuildCommandLineCallbacksPtr callbacks)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(11); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(11);
/* Generate string for arch-specific '-device' parameter */ /* Generate '-device' string for chardev device */
char * int
qemuBuildChrDeviceStr (virDomainChrDefPtr serial, qemuBuildChrDeviceStr(char **deviceStr,
virQEMUCapsPtr qemuCaps, virDomainDefPtr vmdef,
virArch arch, virDomainChrDefPtr chr,
char *machine); virQEMUCapsPtr qemuCaps);
/* With vlan == -1, use netdev syntax, else old hostnet */ /* With vlan == -1, use netdev syntax, else old hostnet */
char * qemuBuildHostNetStr(virDomainNetDefPtr net, char * qemuBuildHostNetStr(virDomainNetDefPtr net,