qemu: command: Introduce JSON equivalent of qemuBuildDeviceAddressStr

Upcoming patches will start converting the formatting of arguments for
-device from a string to JSON so that we can keep proper types around
when using it via QMP.

This means we will need an equivalet for the device address builder
function. 'qemuBuildDeviceAddressProps' provides equal functionality,
but the output differs for fields where a number is expected, where
we've previously formatted a hex value but now end up with a decimal
value per JSON standard.

For given address types I've selected an example device and used
'-device $DEV,help' to obtain the current types recognized by qemu:

Note that 'bus' is not shown below, but it's already a string so we can
keep using it as a string.

VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI (virtio-balloon-pci)
  acpi-index=<uint32>    -  (default: 0)
  addr=<int32>           - Slot and optional function number, example: 06.0 or 06 (default: -1)
  multifunction=<bool>   - on/off (default: false)

Note that 'addr' is here defined as 'int32' but in fact internally in
qemu is an alternate type between a number and a string so we can keep
using strings here.

VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB (usb-tablet)
  port=<str>

VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO (spapr-vty)
  reg=<uint32>           -  (default: 4294967295)

VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW (virtio-blk-cww)
  devno=<str>            - Identifier of an I/O device in the channel subsystem, example: fe.1.23ab

VIR_DOMAIN_DEVICE_ADDRESS_TYPE_ISA (isa-serial)
  iobase=<uint32>        -  (default: 4294967295)
  irq=<uint32>           -  (default: 4294967295)

VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM (pc-dimm)
  slot=<int32>           -  (default: -1)
  addr=<uint64>          -  (default: 0)

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2021-03-26 15:43:14 +01:00
parent e1eae5c430
commit bc130288a3

View File

@ -416,7 +416,7 @@ qemuBuildDeviceAddressPCIStr(virBuffer *buf,
}
static int
static int G_GNUC_UNUSED
qemuBuildDeviceAddressStr(virBuffer *buf,
const virDomainDef *domainDef,
virDomainDeviceInfo *info)
@ -484,6 +484,112 @@ qemuBuildDeviceAddressStr(virBuffer *buf,
}
static int G_GNUC_UNUSED
qemuBuildDeviceAddressProps(virJSONValue *props,
const virDomainDef *domainDef,
virDomainDeviceInfo *info)
{
switch ((virDomainDeviceAddressType) info->type) {
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI: {
g_autofree char *pciaddr = NULL;
g_autofree char *bus = qemuBuildDeviceAddressPCIGetBus(domainDef, info);
if (!bus)
return -1;
if (info->addr.pci.function != 0)
pciaddr = g_strdup_printf("0x%x.0x%x", info->addr.pci.slot, info->addr.pci.function);
else
pciaddr = g_strdup_printf("0x%x", info->addr.pci.slot);
if (virJSONValueObjectAdd(props,
"s:bus", bus,
"T:multifunction", info->addr.pci.multi,
"s:addr", pciaddr,
"p:acpi-index", info->acpiIndex,
NULL) < 0)
return -1;
return 0;
}
break;
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB: {
const char *contAlias = NULL;
g_auto(virBuffer) port = VIR_BUFFER_INITIALIZER;
g_autofree char *bus = NULL;
if (!(contAlias = virDomainControllerAliasFind(domainDef,
VIR_DOMAIN_CONTROLLER_TYPE_USB,
info->addr.usb.bus)))
return -1;
bus = g_strdup_printf("%s.0", contAlias);
virDomainUSBAddressPortFormatBuf(&port, info->addr.usb.port);
if (virJSONValueObjectAdd(props,
"s:bus", bus,
"S:port", virBufferCurrentContent(&port),
NULL) < 0)
return -1;
return 0;
}
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO:
if (info->addr.spaprvio.has_reg) {
if (virJSONValueObjectAdd(props,
"P:reg", info->addr.spaprvio.reg,
NULL) < 0)
return -1;
}
return 0;
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW: {
g_autofree char *devno = g_strdup_printf("%x.%x.%04x",
info->addr.ccw.cssid,
info->addr.ccw.ssid,
info->addr.ccw.devno);
if (virJSONValueObjectAdd(props, "s:devno", devno, NULL) < 0)
return -1;
return 0;
}
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_ISA:
if (virJSONValueObjectAdd(props,
"u:iobase", info->addr.isa.iobase,
"p:irq", info->addr.isa.irq,
NULL) < 0)
return -1;
return 0;
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM:
if (virJSONValueObjectAdd(props,
"u:slot", info->addr.dimm.slot,
"P:addr", info->addr.dimm.base,
NULL) < 0)
return -1;
return 0;
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE:
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE:
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL:
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID:
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390:
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO:
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED:
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST:
default:
return 0;
}
}
/**
* qemuBuildVirtioDevStr
* @buf: virBuffer * to append the built string