[PATCH 00/17] nodedev: add optional device address of channel device to css device

While this series started with the intend to add the optional device address of a subchannel device to the nodedev css device the outcome now also includes a small fix in the error reporting of css cap XML parsing as well as a refactoring of generic ccw code into virccw in utils. Boris Fiuczynski (17): nodedev: fix reported error msg in css cap XML parsing util: refactor virDomainDeviceCCWAddress into virccw.h util: refactor virDomainCCWAddressAsString into virccw util: make reuse of ccw device address format constant util: refactor ccw address constants into virccw util: refactor virDomainCCWAddressIncrement into virccw util: refactor virDomainDeviceCCWAddressIsValid into virccw util: refactor virDomainDeviceCCWAddressEqual into virccw conf: adjust method name virDomainDeviceCCWAddressParseXML util: add ccw device address parsing into virccw util: add virCCWDeviceAddressFromString to virccw nodedev: refactor css format from ccw format method nodedev: refactor ccw device address parsing from XML nodedev: refactor css XML parsing from ccw XML parsing schemas: refactor out nodedev ccw address schema nodedev: add optional device address of channel device to css device nodedev: add tests for optional device address to css device po/POTFILES.in | 1 + src/conf/device_conf.c | 28 +-- src/conf/device_conf.h | 23 +-- src/conf/domain_addr.c | 28 +-- src/conf/domain_addr.h | 5 +- src/conf/domain_conf.c | 19 +- src/conf/domain_conf.h | 6 +- src/conf/node_device_conf.c | 171 +++++++++++++----- src/conf/node_device_conf.h | 2 + src/conf/schemas/nodedev.rng | 27 +-- src/libvirt_private.syms | 14 +- src/node_device/node_device_driver.c | 4 +- src/node_device/node_device_udev.c | 16 +- src/qemu/qemu_agent.c | 4 +- src/qemu/qemu_agent.h | 2 +- src/qemu/qemu_command.c | 2 +- src/util/meson.build | 1 + src/util/virccw.c | 103 +++++++++++ src/util/virccw.h | 52 ++++++ .../css_0_0_10000-invalid.xml | 10 + ...s_0_0_fffe_mdev_types_channel_dev_addr.xml | 22 +++ .../css_0_0_ffff_channel_dev_addr-invalid.xml | 15 ++ .../css_0_0_ffff_channel_dev_addr.xml | 15 ++ ...s_0_0_fffe_mdev_types_channel_dev_addr.xml | 1 + .../css_0_0_ffff_channel_dev_addr.xml | 1 + tests/nodedevxml2xmltest.c | 2 + 26 files changed, 418 insertions(+), 156 deletions(-) create mode 100644 src/util/virccw.c create mode 100644 src/util/virccw.h create mode 100644 tests/nodedevschemadata/css_0_0_10000-invalid.xml create mode 100644 tests/nodedevschemadata/css_0_0_fffe_mdev_types_channel_dev_addr.xml create mode 100644 tests/nodedevschemadata/css_0_0_ffff_channel_dev_addr-invalid.xml create mode 100644 tests/nodedevschemadata/css_0_0_ffff_channel_dev_addr.xml create mode 120000 tests/nodedevxml2xmlout/css_0_0_fffe_mdev_types_channel_dev_addr.xml create mode 120000 tests/nodedevxml2xmlout/css_0_0_ffff_channel_dev_addr.xml -- 2.33.1

Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com> --- src/conf/node_device_conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 8b20a7bee9..67c8c4a3fd 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -1195,7 +1195,7 @@ virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt, if (virStrToLong_uip(ssid, NULL, 0, &ccw_dev->ssid) < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("invalid ssid value '%s' for '%s'"), - cssid, def->name); + ssid, def->name); return -1; } -- 2.33.1

Refactor ccw data structure virDomainDeviceCCWAddress into util virccw.h and rename it as virCCWDeviceAddress. Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/conf/device_conf.c | 8 +++---- src/conf/device_conf.h | 19 ++++++----------- src/conf/domain_addr.c | 6 +++--- src/conf/domain_addr.h | 4 ++-- src/conf/domain_conf.c | 6 +++--- src/conf/domain_conf.h | 6 +++--- src/node_device/node_device_driver.c | 2 +- src/qemu/qemu_agent.c | 4 ++-- src/qemu/qemu_agent.h | 2 +- src/util/virccw.h | 31 ++++++++++++++++++++++++++++ 10 files changed, 56 insertions(+), 32 deletions(-) create mode 100644 src/util/virccw.h diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c index cb523d3a0d..92b908b2e6 100644 --- a/src/conf/device_conf.c +++ b/src/conf/device_conf.c @@ -259,7 +259,7 @@ virPCIDeviceAddressFormat(virBuffer *buf, } bool -virDomainDeviceCCWAddressIsValid(virDomainDeviceCCWAddress *addr) +virDomainDeviceCCWAddressIsValid(virCCWDeviceAddress *addr) { return addr->cssid <= VIR_DOMAIN_DEVICE_CCW_MAX_CSSID && addr->ssid <= VIR_DOMAIN_DEVICE_CCW_MAX_SSID && @@ -268,7 +268,7 @@ virDomainDeviceCCWAddressIsValid(virDomainDeviceCCWAddress *addr) int virDomainDeviceCCWAddressParseXML(xmlNodePtr node, - virDomainDeviceCCWAddress *addr) + virCCWDeviceAddress *addr) { int cssid; int ssid; @@ -307,8 +307,8 @@ virDomainDeviceCCWAddressParseXML(xmlNodePtr node, } bool -virDomainDeviceCCWAddressEqual(virDomainDeviceCCWAddress *addr1, - virDomainDeviceCCWAddress *addr2) +virDomainDeviceCCWAddressEqual(virCCWDeviceAddress *addr1, + virCCWDeviceAddress *addr2) { if (addr1->cssid == addr2->cssid && addr1->ssid == addr2->ssid && diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h index b6b710d313..60d90bbf19 100644 --- a/src/conf/device_conf.h +++ b/src/conf/device_conf.h @@ -27,6 +27,7 @@ #include "internal.h" #include "virthread.h" #include "virbuffer.h" +#include "virccw.h" #include "virpci.h" #include "virnetdev.h" #include "virenum.h" @@ -73,14 +74,6 @@ struct _virDomainDeviceVirtioSerialAddress { #define VIR_DOMAIN_DEVICE_CCW_MAX_SSID 3 #define VIR_DOMAIN_DEVICE_CCW_MAX_DEVNO 65535 -typedef struct _virDomainDeviceCCWAddress virDomainDeviceCCWAddress; -struct _virDomainDeviceCCWAddress { - unsigned int cssid; - unsigned int ssid; - unsigned int devno; - bool assigned; -}; - typedef struct _virDomainDeviceCcidAddress virDomainDeviceCcidAddress; struct _virDomainDeviceCcidAddress { unsigned int controller; @@ -136,7 +129,7 @@ struct _virDomainDeviceInfo { virDomainDeviceCcidAddress ccid; virDomainDeviceUSBAddress usb; virDomainDeviceSpaprVioAddress spaprvio; - virDomainDeviceCCWAddress ccw; + virCCWDeviceAddress ccw; virDomainDeviceISAAddress isa; virDomainDeviceDimmAddress dimm; } addr; @@ -204,11 +197,11 @@ void virPCIDeviceAddressFormat(virBuffer *buf, virPCIDeviceAddress addr, bool includeTypeInAddr); -bool virDomainDeviceCCWAddressIsValid(virDomainDeviceCCWAddress *addr); +bool virDomainDeviceCCWAddressIsValid(virCCWDeviceAddress *addr); int virDomainDeviceCCWAddressParseXML(xmlNodePtr node, - virDomainDeviceCCWAddress *addr); -bool virDomainDeviceCCWAddressEqual(virDomainDeviceCCWAddress *addr1, - virDomainDeviceCCWAddress *addr2); + virCCWDeviceAddress *addr); +bool virDomainDeviceCCWAddressEqual(virCCWDeviceAddress *addr1, + virCCWDeviceAddress *addr2); #define VIR_CCW_DEVICE_ADDRESS_FMT "%x.%x.%04x" int virDomainDeviceDriveAddressParseXML(xmlNodePtr node, diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 1173143635..e51056b0a9 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -1304,15 +1304,15 @@ virDomainPCIAddressSetAllMulti(virDomainDef *def) char* -virDomainCCWAddressAsString(virDomainDeviceCCWAddress *addr) +virDomainCCWAddressAsString(virCCWDeviceAddress *addr) { return g_strdup_printf("%x.%x.%04x", addr->cssid, addr->ssid, addr->devno); } static int -virDomainCCWAddressIncrement(virDomainDeviceCCWAddress *addr) +virDomainCCWAddressIncrement(virCCWDeviceAddress *addr) { - virDomainDeviceCCWAddress ccwaddr = *addr; + virCCWDeviceAddress ccwaddr = *addr; /* We are not touching subchannel sets and channel subsystems */ if (++ccwaddr.devno > VIR_DOMAIN_DEVICE_CCW_MAX_DEVNO) diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h index 1772ea7088..8a6e80a84d 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -199,7 +199,7 @@ void virDomainPCIAddressSetAllMulti(virDomainDef *def) struct _virDomainCCWAddressSet { GHashTable *defined; - virDomainDeviceCCWAddress next; + virCCWDeviceAddress next; }; typedef struct _virDomainCCWAddressSet virDomainCCWAddressSet; @@ -209,7 +209,7 @@ int virDomainCCWAddressAssign(virDomainDeviceInfo *dev, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); void virDomainCCWAddressSetFree(virDomainCCWAddressSet *addrs); -char* virDomainCCWAddressAsString(virDomainDeviceCCWAddress *addr) +char* virDomainCCWAddressAsString(virCCWDeviceAddress *addr) ATTRIBUTE_NONNULL(1); virDomainCCWAddressSet * diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index bd2884088c..7ef65ebed5 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -15368,7 +15368,7 @@ virDomainDiskControllerMatch(int controller_type, int disk_bus) int virDomainDiskIndexByAddress(virDomainDef *def, virPCIDeviceAddress *pci_address, - virDomainDeviceCCWAddress *ccw_addr, + virCCWDeviceAddress *ccw_addr, unsigned int bus, unsigned int target, unsigned int unit) { @@ -15412,7 +15412,7 @@ virDomainDiskIndexByAddress(virDomainDef *def, virDomainDiskDef * virDomainDiskByAddress(virDomainDef *def, virPCIDeviceAddress *pci_address, - virDomainDeviceCCWAddress *ccw_addr, + virCCWDeviceAddress *ccw_addr, unsigned int bus, unsigned int target, unsigned int unit) @@ -16011,7 +16011,7 @@ virDomainControllerFindByType(virDomainDef *def, int virDomainControllerFindByCCWAddress(virDomainDef *def, - virDomainDeviceCCWAddress *addr) + virCCWDeviceAddress *addr) { size_t i; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 88a411d00c..5f782a7bf9 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3655,12 +3655,12 @@ void virDomainRNGDefFree(virDomainRNGDef *def); int virDomainDiskIndexByAddress(virDomainDef *def, virPCIDeviceAddress *pci_controller, - virDomainDeviceCCWAddress *ccw_addr, + virCCWDeviceAddress *ccw_addr, unsigned int bus, unsigned int target, unsigned int unit); virDomainDiskDef *virDomainDiskByAddress(virDomainDef *def, virPCIDeviceAddress *pci_controller, - virDomainDeviceCCWAddress *ccw_addr, + virCCWDeviceAddress *ccw_addr, unsigned int bus, unsigned int target, unsigned int unit); @@ -3745,7 +3745,7 @@ void virDomainControllerInsertPreAlloced(virDomainDef *def, int virDomainControllerFind(const virDomainDef *def, int type, int idx); int virDomainControllerFindByType(virDomainDef *def, int type); int virDomainControllerFindByCCWAddress(virDomainDef *def, - virDomainDeviceCCWAddress *addr); + virCCWDeviceAddress *addr); int virDomainControllerFindByPCIAddress(virDomainDef *def, virPCIDeviceAddress *addr); int virDomainControllerFindUnusedIndex(virDomainDef const *def, int type); diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c index 1eb452b989..b9c46376f5 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -661,7 +661,7 @@ nodeDeviceObjFormatAddress(virNodeDeviceObj *obj) } case VIR_NODE_DEV_CAP_CSS_DEV: { - virDomainDeviceCCWAddress ccw_addr = { + virCCWDeviceAddress ccw_addr = { .cssid = caps->data.ccw_dev.cssid, .ssid = caps->data.ccw_dev.ssid, .devno = caps->data.ccw_dev.devno diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c index 4156cb0dca..f57a8d5f25 100644 --- a/src/qemu/qemu_agent.c +++ b/src/qemu/qemu_agent.c @@ -1764,9 +1764,9 @@ qemuAgentGetDiskAddress(virJSONValue *json) GET_DISK_ADDR(pci, &addr->pci_controller.function, "function"); if ((ccw = virJSONValueObjectGet(json, "ccw-address"))) { - g_autofree virDomainDeviceCCWAddress *ccw_addr = NULL; + g_autofree virCCWDeviceAddress *ccw_addr = NULL; - ccw_addr = g_new0(virDomainDeviceCCWAddress, 1); + ccw_addr = g_new0(virCCWDeviceAddress, 1); GET_DISK_ADDR(ccw, &ccw_addr->cssid, "cssid"); if (ccw_addr->cssid == 0) /* Guest CSSID 0 is 0xfe on host */ diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h index 862f6b0a95..c07d8507ba 100644 --- a/src/qemu/qemu_agent.h +++ b/src/qemu/qemu_agent.h @@ -72,7 +72,7 @@ struct _qemuAgentDiskAddress { unsigned int target; unsigned int unit; char *devnode; - virDomainDeviceCCWAddress *ccw_addr; + virCCWDeviceAddress *ccw_addr; }; void qemuAgentDiskAddressFree(qemuAgentDiskAddress *addr); G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuAgentDiskAddress, qemuAgentDiskAddressFree); diff --git a/src/util/virccw.h b/src/util/virccw.h new file mode 100644 index 0000000000..701e13284b --- /dev/null +++ b/src/util/virccw.h @@ -0,0 +1,31 @@ +/* + * virccw.h: helper APIs for managing host CCW devices + * + * Copyright (C) 2022 IBM Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "internal.h" + +typedef struct _virCCWDeviceAddress virCCWDeviceAddress; +struct _virCCWDeviceAddress { + unsigned int cssid; + unsigned int ssid; + unsigned int devno; + bool assigned; +}; -- 2.33.1

Move virDomainCCWAddressAsString into virccw and rename method as virCCWDeviceAddressAsString. Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/conf/domain_addr.c | 12 +++--------- src/conf/domain_addr.h | 3 --- src/conf/domain_conf.c | 2 +- src/libvirt_private.syms | 5 ++++- src/node_device/node_device_driver.c | 2 +- src/util/meson.build | 1 + src/util/virccw.c | 29 ++++++++++++++++++++++++++++ src/util/virccw.h | 3 +++ 8 files changed, 42 insertions(+), 15 deletions(-) create mode 100644 src/util/virccw.c diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index e51056b0a9..7dd26c3271 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -1303,12 +1303,6 @@ virDomainPCIAddressSetAllMulti(virDomainDef *def) } -char* -virDomainCCWAddressAsString(virCCWDeviceAddress *addr) -{ - return g_strdup_printf("%x.%x.%04x", addr->cssid, addr->ssid, addr->devno); -} - static int virDomainCCWAddressIncrement(virCCWDeviceAddress *addr) { @@ -1334,7 +1328,7 @@ virDomainCCWAddressAssign(virDomainDeviceInfo *dev, return 0; if (!autoassign && dev->addr.ccw.assigned) { - if (!(addr = virDomainCCWAddressAsString(&dev->addr.ccw))) + if (!(addr = virCCWDeviceAddressAsString(&dev->addr.ccw))) return -1; if (virHashLookup(addrs->defined, addr)) { @@ -1344,7 +1338,7 @@ virDomainCCWAddressAssign(virDomainDeviceInfo *dev, return -1; } } else if (autoassign && !dev->addr.ccw.assigned) { - if (!(addr = virDomainCCWAddressAsString(&addrs->next))) + if (!(addr = virCCWDeviceAddressAsString(&addrs->next))) return -1; while (virHashLookup(addrs->defined, addr)) { @@ -1354,7 +1348,7 @@ virDomainCCWAddressAssign(virDomainDeviceInfo *dev, return -1; } VIR_FREE(addr); - if (!(addr = virDomainCCWAddressAsString(&addrs->next))) + if (!(addr = virCCWDeviceAddressAsString(&addrs->next))) return -1; } dev->addr.ccw = addrs->next; diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h index 8a6e80a84d..e72fb48847 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -209,9 +209,6 @@ int virDomainCCWAddressAssign(virDomainDeviceInfo *dev, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); void virDomainCCWAddressSetFree(virDomainCCWAddressSet *addrs); -char* virDomainCCWAddressAsString(virCCWDeviceAddress *addr) - ATTRIBUTE_NONNULL(1); - virDomainCCWAddressSet * virDomainCCWAddressSetCreateFromDomain(virDomainDef *def) ATTRIBUTE_NONNULL(1); diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 7ef65ebed5..115a670683 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -15620,7 +15620,7 @@ virDomainNetFindIdx(virDomainDef *def, virDomainNetDef *net) alias = net->info.alias; if (CCWAddrSpecified) - addr = virDomainCCWAddressAsString(&net->info.addr.ccw); + addr = virCCWDeviceAddressAsString(&net->info.addr.ccw); else if (PCIAddrSpecified) addr = virPCIDeviceAddressAsString(&net->info.addr.pci); else diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 97bfca906b..eaf4a1da9c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -147,7 +147,6 @@ virPCIDeviceAddressParseXML; # conf/domain_addr.h virDomainCCWAddressAssign; -virDomainCCWAddressAsString; virDomainCCWAddressSetCreateFromDomain; virDomainCCWAddressSetFree; virDomainPCIAddressBusIsFullyReserved; @@ -1925,6 +1924,10 @@ virBufferUse; virBufferVasprintf; +# util/virccw.h +virCCWDeviceAddressAsString; + + # util/vircgroup.h virCgroupAddMachineProcess; virCgroupAddProcess; diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c index b9c46376f5..4b31cd5695 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -667,7 +667,7 @@ nodeDeviceObjFormatAddress(virNodeDeviceObj *obj) .devno = caps->data.ccw_dev.devno }; - addr = virDomainCCWAddressAsString(&ccw_addr); + addr = virCCWDeviceAddressAsString(&ccw_addr); break; } diff --git a/src/util/meson.build b/src/util/meson.build index 17755373c8..07ae94631c 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -9,6 +9,7 @@ util_sources = [ 'virbitmap.c', 'virbpf.c', 'virbuffer.c', + 'virccw.c', 'vircgroup.c', 'vircgroupbackend.c', 'vircgroupv1.c', diff --git a/src/util/virccw.c b/src/util/virccw.c new file mode 100644 index 0000000000..409287b380 --- /dev/null +++ b/src/util/virccw.c @@ -0,0 +1,29 @@ +/* + * virccw.c: helper APIs for managing host CCW devices + * + * Copyright (C) 2022 IBM Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include "virccw.h" + + +char* +virCCWDeviceAddressAsString(virCCWDeviceAddress *addr) +{ + return g_strdup_printf("%x.%x.%04x", addr->cssid, addr->ssid, addr->devno); +} diff --git a/src/util/virccw.h b/src/util/virccw.h index 701e13284b..21a03406fa 100644 --- a/src/util/virccw.h +++ b/src/util/virccw.h @@ -29,3 +29,6 @@ struct _virCCWDeviceAddress { unsigned int devno; bool assigned; }; + +char* virCCWDeviceAddressAsString(virCCWDeviceAddress *addr) + ATTRIBUTE_NONNULL(1); -- 2.33.1

Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/conf/device_conf.h | 1 - src/qemu/qemu_command.c | 2 +- src/util/virccw.c | 2 +- src/util/virccw.h | 2 ++ 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h index 60d90bbf19..950d333e2e 100644 --- a/src/conf/device_conf.h +++ b/src/conf/device_conf.h @@ -202,7 +202,6 @@ int virDomainDeviceCCWAddressParseXML(xmlNodePtr node, virCCWDeviceAddress *addr); bool virDomainDeviceCCWAddressEqual(virCCWDeviceAddress *addr1, virCCWDeviceAddress *addr2); -#define VIR_CCW_DEVICE_ADDRESS_FMT "%x.%x.%04x" int virDomainDeviceDriveAddressParseXML(xmlNodePtr node, virDomainDeviceDriveAddress *addr); diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 3746f02ff0..a1aa5e7cd2 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -600,7 +600,7 @@ qemuBuildDeviceAddressProps(virJSONValue *props, return 0; case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW: { - g_autofree char *devno = g_strdup_printf("%x.%x.%04x", + g_autofree char *devno = g_strdup_printf(VIR_CCW_DEVICE_ADDRESS_FMT, info->addr.ccw.cssid, info->addr.ccw.ssid, info->addr.ccw.devno); diff --git a/src/util/virccw.c b/src/util/virccw.c index 409287b380..5a19d3a112 100644 --- a/src/util/virccw.c +++ b/src/util/virccw.c @@ -25,5 +25,5 @@ char* virCCWDeviceAddressAsString(virCCWDeviceAddress *addr) { - return g_strdup_printf("%x.%x.%04x", addr->cssid, addr->ssid, addr->devno); + return g_strdup_printf(VIR_CCW_DEVICE_ADDRESS_FMT, addr->cssid, addr->ssid, addr->devno); } diff --git a/src/util/virccw.h b/src/util/virccw.h index 21a03406fa..127359c299 100644 --- a/src/util/virccw.h +++ b/src/util/virccw.h @@ -22,6 +22,8 @@ #include "internal.h" +#define VIR_CCW_DEVICE_ADDRESS_FMT "%x.%x.%04x" + typedef struct _virCCWDeviceAddress virCCWDeviceAddress; struct _virCCWDeviceAddress { unsigned int cssid; -- 2.33.1

Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/conf/device_conf.c | 6 +++--- src/conf/device_conf.h | 4 ---- src/conf/domain_addr.c | 2 +- src/util/virccw.h | 3 +++ 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c index 92b908b2e6..bdc9219f84 100644 --- a/src/conf/device_conf.c +++ b/src/conf/device_conf.c @@ -261,9 +261,9 @@ virPCIDeviceAddressFormat(virBuffer *buf, bool virDomainDeviceCCWAddressIsValid(virCCWDeviceAddress *addr) { - return addr->cssid <= VIR_DOMAIN_DEVICE_CCW_MAX_CSSID && - addr->ssid <= VIR_DOMAIN_DEVICE_CCW_MAX_SSID && - addr->devno <= VIR_DOMAIN_DEVICE_CCW_MAX_DEVNO; + return addr->cssid <= VIR_CCW_DEVICE_MAX_CSSID && + addr->ssid <= VIR_CCW_DEVICE_MAX_SSID && + addr->devno <= VIR_CCW_DEVICE_MAX_DEVNO; } int diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h index 950d333e2e..5c4b7b2f8e 100644 --- a/src/conf/device_conf.h +++ b/src/conf/device_conf.h @@ -70,10 +70,6 @@ struct _virDomainDeviceVirtioSerialAddress { unsigned int port; }; -#define VIR_DOMAIN_DEVICE_CCW_MAX_CSSID 254 -#define VIR_DOMAIN_DEVICE_CCW_MAX_SSID 3 -#define VIR_DOMAIN_DEVICE_CCW_MAX_DEVNO 65535 - typedef struct _virDomainDeviceCcidAddress virDomainDeviceCcidAddress; struct _virDomainDeviceCcidAddress { unsigned int controller; diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 7dd26c3271..65b438f13c 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -1309,7 +1309,7 @@ virDomainCCWAddressIncrement(virCCWDeviceAddress *addr) virCCWDeviceAddress ccwaddr = *addr; /* We are not touching subchannel sets and channel subsystems */ - if (++ccwaddr.devno > VIR_DOMAIN_DEVICE_CCW_MAX_DEVNO) + if (++ccwaddr.devno > VIR_CCW_DEVICE_MAX_DEVNO) return -1; *addr = ccwaddr; diff --git a/src/util/virccw.h b/src/util/virccw.h index 127359c299..c3a47127f1 100644 --- a/src/util/virccw.h +++ b/src/util/virccw.h @@ -22,6 +22,9 @@ #include "internal.h" +#define VIR_CCW_DEVICE_MAX_CSSID 254 +#define VIR_CCW_DEVICE_MAX_SSID 3 +#define VIR_CCW_DEVICE_MAX_DEVNO 65535 #define VIR_CCW_DEVICE_ADDRESS_FMT "%x.%x.%04x" typedef struct _virCCWDeviceAddress virCCWDeviceAddress; -- 2.33.1

Refactor virDomainCCWAddressIncrement into virccw and rename method as virCCWDeviceAddressIncrement. Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/conf/domain_addr.c | 16 +--------------- src/libvirt_private.syms | 1 + src/util/virccw.c | 13 +++++++++++++ src/util/virccw.h | 1 + 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 65b438f13c..edc254a6ee 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -1303,20 +1303,6 @@ virDomainPCIAddressSetAllMulti(virDomainDef *def) } -static int -virDomainCCWAddressIncrement(virCCWDeviceAddress *addr) -{ - virCCWDeviceAddress ccwaddr = *addr; - - /* We are not touching subchannel sets and channel subsystems */ - if (++ccwaddr.devno > VIR_CCW_DEVICE_MAX_DEVNO) - return -1; - - *addr = ccwaddr; - return 0; -} - - int virDomainCCWAddressAssign(virDomainDeviceInfo *dev, virDomainCCWAddressSet *addrs, @@ -1342,7 +1328,7 @@ virDomainCCWAddressAssign(virDomainDeviceInfo *dev, return -1; while (virHashLookup(addrs->defined, addr)) { - if (virDomainCCWAddressIncrement(&addrs->next) < 0) { + if (virCCWDeviceAddressIncrement(&addrs->next) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("There are no more free CCW devnos.")); return -1; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index eaf4a1da9c..fae8edb6cd 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1926,6 +1926,7 @@ virBufferVasprintf; # util/virccw.h virCCWDeviceAddressAsString; +virCCWDeviceAddressIncrement; # util/vircgroup.h diff --git a/src/util/virccw.c b/src/util/virccw.c index 5a19d3a112..d14d432414 100644 --- a/src/util/virccw.c +++ b/src/util/virccw.c @@ -27,3 +27,16 @@ virCCWDeviceAddressAsString(virCCWDeviceAddress *addr) { return g_strdup_printf(VIR_CCW_DEVICE_ADDRESS_FMT, addr->cssid, addr->ssid, addr->devno); } + +int +virCCWDeviceAddressIncrement(virCCWDeviceAddress *addr) +{ + virCCWDeviceAddress ccwaddr = *addr; + + /* We are not touching subchannel sets and channel subsystems */ + if (++ccwaddr.devno > VIR_CCW_DEVICE_MAX_DEVNO) + return -1; + + *addr = ccwaddr; + return 0; +} diff --git a/src/util/virccw.h b/src/util/virccw.h index c3a47127f1..4c48c9605e 100644 --- a/src/util/virccw.h +++ b/src/util/virccw.h @@ -37,3 +37,4 @@ struct _virCCWDeviceAddress { char* virCCWDeviceAddressAsString(virCCWDeviceAddress *addr) ATTRIBUTE_NONNULL(1); +int virCCWDeviceAddressIncrement(virCCWDeviceAddress *addr); -- 2.33.1

Refactor virDomainDeviceCCWAddressIsValid into virccw and rename method as virCCWDeviceAddressIsValid. Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/conf/device_conf.c | 12 ++---------- src/conf/device_conf.h | 1 - src/libvirt_private.syms | 2 +- src/util/virccw.c | 8 ++++++++ src/util/virccw.h | 2 ++ 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c index bdc9219f84..2385e81994 100644 --- a/src/conf/device_conf.c +++ b/src/conf/device_conf.c @@ -258,14 +258,6 @@ virPCIDeviceAddressFormat(virBuffer *buf, addr.function); } -bool -virDomainDeviceCCWAddressIsValid(virCCWDeviceAddress *addr) -{ - return addr->cssid <= VIR_CCW_DEVICE_MAX_CSSID && - addr->ssid <= VIR_CCW_DEVICE_MAX_SSID && - addr->devno <= VIR_CCW_DEVICE_MAX_DEVNO; -} - int virDomainDeviceCCWAddressParseXML(xmlNodePtr node, virCCWDeviceAddress *addr) @@ -288,7 +280,7 @@ virDomainDeviceCCWAddressParseXML(xmlNodePtr node, &addr->devno)) < 0) return -1; - if (!virDomainDeviceCCWAddressIsValid(addr)) { + if (!virCCWDeviceAddressIsValid(addr)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid specification for virtio ccw address: cssid='0x%x' ssid='0x%x' devno='0x%04x'"), addr->cssid, addr->ssid, addr->devno); @@ -453,7 +445,7 @@ virDomainDeviceAddressIsValid(virDomainDeviceInfo *info, return true; case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW: - return virDomainDeviceCCWAddressIsValid(&info->addr.ccw); + return virCCWDeviceAddressIsValid(&info->addr.ccw); case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB: return true; diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h index 5c4b7b2f8e..0ed6991c23 100644 --- a/src/conf/device_conf.h +++ b/src/conf/device_conf.h @@ -193,7 +193,6 @@ void virPCIDeviceAddressFormat(virBuffer *buf, virPCIDeviceAddress addr, bool includeTypeInAddr); -bool virDomainDeviceCCWAddressIsValid(virCCWDeviceAddress *addr); int virDomainDeviceCCWAddressParseXML(xmlNodePtr node, virCCWDeviceAddress *addr); bool virDomainDeviceCCWAddressEqual(virCCWDeviceAddress *addr1, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fae8edb6cd..8acb0e000d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -132,7 +132,6 @@ virDomainDeviceAddressIsValid; virDomainDeviceAddressTypeToString; virDomainDeviceCcidAddressParseXML; virDomainDeviceCCWAddressEqual; -virDomainDeviceCCWAddressIsValid; virDomainDeviceCCWAddressParseXML; virDomainDeviceDriveAddressParseXML; virDomainDeviceInfoAddressIsEqual; @@ -1927,6 +1926,7 @@ virBufferVasprintf; # util/virccw.h virCCWDeviceAddressAsString; virCCWDeviceAddressIncrement; +virCCWDeviceAddressIsValid; # util/vircgroup.h diff --git a/src/util/virccw.c b/src/util/virccw.c index d14d432414..c3dfda2613 100644 --- a/src/util/virccw.c +++ b/src/util/virccw.c @@ -22,6 +22,14 @@ #include "virccw.h" +bool +virCCWDeviceAddressIsValid(virCCWDeviceAddress *addr) +{ + return addr->cssid <= VIR_CCW_DEVICE_MAX_CSSID && + addr->ssid <= VIR_CCW_DEVICE_MAX_SSID && + addr->devno <= VIR_CCW_DEVICE_MAX_DEVNO; +} + char* virCCWDeviceAddressAsString(virCCWDeviceAddress *addr) { diff --git a/src/util/virccw.h b/src/util/virccw.h index 4c48c9605e..c4daaff7b3 100644 --- a/src/util/virccw.h +++ b/src/util/virccw.h @@ -35,6 +35,8 @@ struct _virCCWDeviceAddress { bool assigned; }; +bool virCCWDeviceAddressIsValid(virCCWDeviceAddress *addr); + char* virCCWDeviceAddressAsString(virCCWDeviceAddress *addr) ATTRIBUTE_NONNULL(1); int virCCWDeviceAddressIncrement(virCCWDeviceAddress *addr); -- 2.33.1

Refactor virDomainDeviceCCWAddressEqual into virccw and rename method as virCCWDeviceAddressEqual. Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/conf/device_conf.c | 12 ------------ src/conf/device_conf.h | 2 -- src/conf/domain_conf.c | 8 ++++---- src/libvirt_private.syms | 2 +- src/util/virccw.c | 12 ++++++++++++ src/util/virccw.h | 2 ++ 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c index 2385e81994..958e2f43cc 100644 --- a/src/conf/device_conf.c +++ b/src/conf/device_conf.c @@ -298,18 +298,6 @@ virDomainDeviceCCWAddressParseXML(xmlNodePtr node, return 0; } -bool -virDomainDeviceCCWAddressEqual(virCCWDeviceAddress *addr1, - virCCWDeviceAddress *addr2) -{ - if (addr1->cssid == addr2->cssid && - addr1->ssid == addr2->ssid && - addr1->devno == addr2->devno) { - return true; - } - return false; -} - int virDomainDeviceDriveAddressParseXML(xmlNodePtr node, virDomainDeviceDriveAddress *addr) diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h index 0ed6991c23..01e2edccc9 100644 --- a/src/conf/device_conf.h +++ b/src/conf/device_conf.h @@ -195,8 +195,6 @@ void virPCIDeviceAddressFormat(virBuffer *buf, int virDomainDeviceCCWAddressParseXML(xmlNodePtr node, virCCWDeviceAddress *addr); -bool virDomainDeviceCCWAddressEqual(virCCWDeviceAddress *addr1, - virCCWDeviceAddress *addr2); int virDomainDeviceDriveAddressParseXML(xmlNodePtr node, virDomainDeviceDriveAddress *addr); diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 115a670683..826ba4183d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -15393,7 +15393,7 @@ virDomainDiskIndexByAddress(virDomainDef *def, return i; if (vdisk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && ccw_addr && - virDomainDeviceCCWAddressEqual(&vdisk->info.addr.ccw, ccw_addr)) { + virCCWDeviceAddressEqual(&vdisk->info.addr.ccw, ccw_addr)) { return i; } if (vdisk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) { @@ -15582,8 +15582,8 @@ virDomainNetFindIdx(virDomainDef *def, virDomainNetDef *net) continue; if (CCWAddrSpecified && - !virDomainDeviceCCWAddressEqual(&def->nets[i]->info.addr.ccw, - &net->info.addr.ccw)) + !virCCWDeviceAddressEqual(&def->nets[i]->info.addr.ccw, + &net->info.addr.ccw)) continue; if (net->info.alias && def->nets[i]->info.alias && @@ -16019,7 +16019,7 @@ virDomainControllerFindByCCWAddress(virDomainDef *def, virDomainDeviceInfo *info = &def->controllers[i]->info; if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW && - virDomainDeviceCCWAddressEqual(&info->addr.ccw, addr)) + virCCWDeviceAddressEqual(&info->addr.ccw, addr)) return i; } diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8acb0e000d..019f7c60e4 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -131,7 +131,6 @@ virDeviceInfoPCIAddressIsWanted; virDomainDeviceAddressIsValid; virDomainDeviceAddressTypeToString; virDomainDeviceCcidAddressParseXML; -virDomainDeviceCCWAddressEqual; virDomainDeviceCCWAddressParseXML; virDomainDeviceDriveAddressParseXML; virDomainDeviceInfoAddressIsEqual; @@ -1925,6 +1924,7 @@ virBufferVasprintf; # util/virccw.h virCCWDeviceAddressAsString; +virCCWDeviceAddressEqual; virCCWDeviceAddressIncrement; virCCWDeviceAddressIsValid; diff --git a/src/util/virccw.c b/src/util/virccw.c index c3dfda2613..e2785bd9ab 100644 --- a/src/util/virccw.c +++ b/src/util/virccw.c @@ -30,6 +30,18 @@ virCCWDeviceAddressIsValid(virCCWDeviceAddress *addr) addr->devno <= VIR_CCW_DEVICE_MAX_DEVNO; } +bool +virCCWDeviceAddressEqual(virCCWDeviceAddress *addr1, + virCCWDeviceAddress *addr2) +{ + if (addr1->cssid == addr2->cssid && + addr1->ssid == addr2->ssid && + addr1->devno == addr2->devno) { + return true; + } + return false; +} + char* virCCWDeviceAddressAsString(virCCWDeviceAddress *addr) { diff --git a/src/util/virccw.h b/src/util/virccw.h index c4daaff7b3..aebbd4ab6d 100644 --- a/src/util/virccw.h +++ b/src/util/virccw.h @@ -36,6 +36,8 @@ struct _virCCWDeviceAddress { }; bool virCCWDeviceAddressIsValid(virCCWDeviceAddress *addr); +bool virCCWDeviceAddressEqual(virCCWDeviceAddress *addr1, + virCCWDeviceAddress *addr2); char* virCCWDeviceAddressAsString(virCCWDeviceAddress *addr) ATTRIBUTE_NONNULL(1); -- 2.33.1

Adjust method name virDomainDeviceCCWAddressParseXML to virCCWDeviceAddressParseXML. Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/conf/device_conf.c | 4 ++-- src/conf/device_conf.h | 4 ++-- src/conf/domain_conf.c | 3 +-- src/libvirt_private.syms | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c index 958e2f43cc..e93fd57341 100644 --- a/src/conf/device_conf.c +++ b/src/conf/device_conf.c @@ -259,8 +259,8 @@ virPCIDeviceAddressFormat(virBuffer *buf, } int -virDomainDeviceCCWAddressParseXML(xmlNodePtr node, - virCCWDeviceAddress *addr) +virCCWDeviceAddressParseXML(xmlNodePtr node, + virCCWDeviceAddress *addr) { int cssid; int ssid; diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h index 01e2edccc9..910e6b7792 100644 --- a/src/conf/device_conf.h +++ b/src/conf/device_conf.h @@ -193,8 +193,8 @@ void virPCIDeviceAddressFormat(virBuffer *buf, virPCIDeviceAddress addr, bool includeTypeInAddr); -int virDomainDeviceCCWAddressParseXML(xmlNodePtr node, - virCCWDeviceAddress *addr); +int virCCWDeviceAddressParseXML(xmlNodePtr node, + virCCWDeviceAddress *addr); int virDomainDeviceDriveAddressParseXML(xmlNodePtr node, virDomainDeviceDriveAddress *addr); diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 826ba4183d..73970e488e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6720,8 +6720,7 @@ virDomainDeviceAddressParseXML(xmlNodePtr address, break; case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW: - if (virDomainDeviceCCWAddressParseXML - (address, &info->addr.ccw) < 0) + if (virCCWDeviceAddressParseXML(address, &info->addr.ccw) < 0) return -1; break; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 019f7c60e4..09867b7876 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -124,6 +124,7 @@ virCPUModeTypeToString; # conf/device_conf.h +virCCWDeviceAddressParseXML; virDeviceInfoPCIAddressExtensionIsPresent; virDeviceInfoPCIAddressExtensionIsWanted; virDeviceInfoPCIAddressIsPresent; @@ -131,7 +132,6 @@ virDeviceInfoPCIAddressIsWanted; virDomainDeviceAddressIsValid; virDomainDeviceAddressTypeToString; virDomainDeviceCcidAddressParseXML; -virDomainDeviceCCWAddressParseXML; virDomainDeviceDriveAddressParseXML; virDomainDeviceInfoAddressIsEqual; virDomainDeviceSpaprVioAddressParseXML; -- 2.33.1

Add virCCWDeviceAddressParseFromString and use it in nodedev udev. Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/libvirt_private.syms | 1 + src/node_device/node_device_udev.c | 8 +++++--- src/util/virccw.c | 18 ++++++++++++++++++ src/util/virccw.h | 5 +++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 09867b7876..148d016e0e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1927,6 +1927,7 @@ virCCWDeviceAddressAsString; virCCWDeviceAddressEqual; virCCWDeviceAddressIncrement; virCCWDeviceAddressIsValid; +virCCWDeviceAddressParseFromString; # util/vircgroup.h diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index b68dc12158..4bb841c66b 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -36,6 +36,7 @@ #include "viruuid.h" #include "virbuffer.h" #include "virfile.h" +#include "virccw.h" #include "virpci.h" #include "virpidfile.h" #include "virstring.h" @@ -1086,9 +1087,10 @@ udevGetCCWAddress(const char *sysfs_path, char *p; if ((p = strrchr(sysfs_path, '/')) == NULL || - virStrToLong_ui(p + 1, &p, 16, &data->ccw_dev.cssid) < 0 || p == NULL || - virStrToLong_ui(p + 1, &p, 16, &data->ccw_dev.ssid) < 0 || p == NULL || - virStrToLong_ui(p + 1, &p, 16, &data->ccw_dev.devno) < 0) { + virCCWDeviceAddressParseFromString(p + 1, + &data->ccw_dev.cssid, + &data->ccw_dev.ssid, + &data->ccw_dev.devno) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to parse the CCW address from sysfs path: '%s'"), sysfs_path); diff --git a/src/util/virccw.c b/src/util/virccw.c index e2785bd9ab..33df1c2428 100644 --- a/src/util/virccw.c +++ b/src/util/virccw.c @@ -20,6 +20,7 @@ #include <config.h> #include "virccw.h" +#include "virstring.h" bool @@ -60,3 +61,20 @@ virCCWDeviceAddressIncrement(virCCWDeviceAddress *addr) *addr = ccwaddr; return 0; } + +int +virCCWDeviceAddressParseFromString(const char *address, + unsigned int *cssid, + unsigned int *ssid, + unsigned int *devno) +{ + char *p; + + if (address == NULL || virStrToLong_ui(address, &p, 16, cssid) < 0 || + p == NULL || virStrToLong_ui(p + 1, &p, 16, ssid) < 0 || + p == NULL || virStrToLong_ui(p + 1, &p, 16, devno) < 0) { + return -1; + } + + return 0; +} diff --git a/src/util/virccw.h b/src/util/virccw.h index aebbd4ab6d..df0273bcac 100644 --- a/src/util/virccw.h +++ b/src/util/virccw.h @@ -42,3 +42,8 @@ bool virCCWDeviceAddressEqual(virCCWDeviceAddress *addr1, char* virCCWDeviceAddressAsString(virCCWDeviceAddress *addr) ATTRIBUTE_NONNULL(1); int virCCWDeviceAddressIncrement(virCCWDeviceAddress *addr); + +int virCCWDeviceAddressParseFromString(const char *address, + unsigned int *cssid, + unsigned int *ssid, + unsigned int *devno); -- 2.33.1

Add a method to parse a ccw device address from a string. Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- po/POTFILES.in | 1 + src/libvirt_private.syms | 1 + src/util/virccw.c | 23 +++++++++++++++++++++++ src/util/virccw.h | 3 +++ 4 files changed, 28 insertions(+) diff --git a/po/POTFILES.in b/po/POTFILES.in index 0d9adb0758..71d113efa2 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -247,6 +247,7 @@ @SRCDIR@src/util/virauth.c @SRCDIR@src/util/virauthconfig.c @SRCDIR@src/util/virbitmap.c +@SRCDIR@src/util/virccw.c @SRCDIR@src/util/vircgroup.c @SRCDIR@src/util/vircgroupbackend.c @SRCDIR@src/util/vircgroupbackend.h diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 148d016e0e..7c37763bd7 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1925,6 +1925,7 @@ virBufferVasprintf; # util/virccw.h virCCWDeviceAddressAsString; virCCWDeviceAddressEqual; +virCCWDeviceAddressFromString; virCCWDeviceAddressIncrement; virCCWDeviceAddressIsValid; virCCWDeviceAddressParseFromString; diff --git a/src/util/virccw.c b/src/util/virccw.c index 33df1c2428..d741743050 100644 --- a/src/util/virccw.c +++ b/src/util/virccw.c @@ -20,8 +20,11 @@ #include <config.h> #include "virccw.h" +#include "virerror.h" #include "virstring.h" +#define VIR_FROM_THIS VIR_FROM_NONE + bool virCCWDeviceAddressIsValid(virCCWDeviceAddress *addr) @@ -49,6 +52,26 @@ virCCWDeviceAddressAsString(virCCWDeviceAddress *addr) return g_strdup_printf(VIR_CCW_DEVICE_ADDRESS_FMT, addr->cssid, addr->ssid, addr->devno); } +virCCWDeviceAddress * +virCCWDeviceAddressFromString(const char *address) +{ + g_autofree virCCWDeviceAddress *ccw = NULL; + + ccw = g_new0(virCCWDeviceAddress, 1); + + if (virCCWDeviceAddressParseFromString(address, + &ccw->cssid, + &ccw->ssid, + &ccw->devno) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to parse CCW address '%s'"), + address); + return NULL; + } + + return g_steal_pointer(&ccw); +} + int virCCWDeviceAddressIncrement(virCCWDeviceAddress *addr) { diff --git a/src/util/virccw.h b/src/util/virccw.h index df0273bcac..80cc716811 100644 --- a/src/util/virccw.h +++ b/src/util/virccw.h @@ -41,6 +41,9 @@ bool virCCWDeviceAddressEqual(virCCWDeviceAddress *addr1, char* virCCWDeviceAddressAsString(virCCWDeviceAddress *addr) ATTRIBUTE_NONNULL(1); +virCCWDeviceAddress *virCCWDeviceAddressFromString(const char *address) + ATTRIBUTE_NONNULL(1); + int virCCWDeviceAddressIncrement(virCCWDeviceAddress *addr); int virCCWDeviceAddressParseFromString(const char *address, -- 2.33.1

In preparation for easier extension later. Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/conf/node_device_conf.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 67c8c4a3fd..97779078e8 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -634,10 +634,21 @@ virNodeDeviceCapCCWDefFormat(virBuffer *buf, data->ccw_dev.ssid); virBufferAsprintf(buf, "<devno>0x%04x</devno>\n", data->ccw_dev.devno); - if (data->ccw_dev.flags & VIR_NODE_DEV_CAP_FLAG_CSS_MDEV) +} + + +static void +virNodeDeviceCapCSSDefFormat(virBuffer *buf, + const virNodeDevCapData *data) +{ + virNodeDevCapCCW ccw_dev = data->ccw_dev; + + virNodeDeviceCapCCWDefFormat(buf, data); + + if (ccw_dev.flags & VIR_NODE_DEV_CAP_FLAG_CSS_MDEV) virNodeDeviceCapMdevTypesFormat(buf, - data->ccw_dev.mdev_types, - data->ccw_dev.nmdev_types); + ccw_dev.mdev_types, + ccw_dev.nmdev_types); } @@ -726,9 +737,11 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def) virNodeDeviceCapMdevDefFormat(&buf, data); break; case VIR_NODE_DEV_CAP_CCW_DEV: - case VIR_NODE_DEV_CAP_CSS_DEV: virNodeDeviceCapCCWDefFormat(&buf, data); break; + case VIR_NODE_DEV_CAP_CSS_DEV: + virNodeDeviceCapCSSDefFormat(&buf, data); + break; case VIR_NODE_DEV_CAP_VDPA: virNodeDeviceCapVDPADefFormat(&buf, data); break; -- 2.33.1

Move ccw device address XML parsing into new method for later reuse. Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/conf/node_device_conf.c | 96 ++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 38 deletions(-) diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 97779078e8..8d160185eb 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -1143,6 +1143,58 @@ virNodeDevAPMatrixCapabilityParseXML(xmlXPathContextPtr ctxt, } +static int +virNodeDevCCWDeviceAddressParseXML(xmlXPathContextPtr ctxt, + xmlNodePtr node, + const char *dev_name, + virCCWDeviceAddress *ccw_addr) +{ + VIR_XPATH_NODE_AUTORESTORE(ctxt) + g_autofree char *cssid = NULL; + g_autofree char *ssid = NULL; + g_autofree char *devno = NULL; + + ctxt->node = node; + + if (!(cssid = virXPathString("string(./cssid[1])", ctxt))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("missing cssid value for '%s'"), dev_name); + return -1; + } + if (virStrToLong_uip(cssid, NULL, 0, &ccw_addr->cssid) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("invalid cssid value '%s' for '%s'"), + cssid, dev_name); + return -1; + } + + if (!(ssid = virXPathString("string(./ssid[1])", ctxt))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("missing ssid value for '%s'"), dev_name); + return -1; + } + if (virStrToLong_uip(ssid, NULL, 0, &ccw_addr->ssid) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("invalid ssid value '%s' for '%s'"), + ssid, dev_name); + return -1; + } + + if (!(devno = virXPathString("string(./devno[1])", ctxt))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("missing devno value for '%s'"), dev_name); + return -1; + } + if (virStrToLong_uip(devno, NULL, 16, &ccw_addr->devno) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("invalid devno value '%s' for '%s'"), + devno, dev_name); + return -1; + } + + return 0; +} + static int virNodeDevCSSCapabilityParseXML(xmlXPathContextPtr ctxt, xmlNodePtr node, @@ -1180,50 +1232,18 @@ virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt, g_autofree xmlNodePtr *nodes = NULL; int n = 0; size_t i = 0; - g_autofree char *cssid = NULL; - g_autofree char *ssid = NULL; - g_autofree char *devno = NULL; + g_autofree virCCWDeviceAddress *ccw_addr = NULL; ctxt->node = node; - if (!(cssid = virXPathString("string(./cssid[1])", ctxt))) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("missing cssid value for '%s'"), def->name); - return -1; - } - - if (virStrToLong_uip(cssid, NULL, 0, &ccw_dev->cssid) < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("invalid cssid value '%s' for '%s'"), - cssid, def->name); - return -1; - } - - if (!(ssid = virXPathString("string(./ssid[1])", ctxt))) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("missing ssid value for '%s'"), def->name); - return -1; - } + ccw_addr = g_new0(virCCWDeviceAddress, 1); - if (virStrToLong_uip(ssid, NULL, 0, &ccw_dev->ssid) < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("invalid ssid value '%s' for '%s'"), - ssid, def->name); + if (virNodeDevCCWDeviceAddressParseXML(ctxt, node, def->name, ccw_addr) < 0) return -1; - } - if (!(devno = virXPathString("string(./devno[1])", ctxt))) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("missing devno value for '%s'"), def->name); - return -1; - } - - if (virStrToLong_uip(devno, NULL, 16, &ccw_dev->devno) < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("invalid devno value '%s' for '%s'"), - devno, def->name); - return -1; - } + ccw_dev->cssid = ccw_addr->cssid; + ccw_dev->ssid = ccw_addr->ssid; + ccw_dev->devno = ccw_addr->devno; if ((n = virXPathNodeSet("./capability", ctxt, &nodes)) < 0) return -1; -- 2.33.1

In preparation for easier extension later. Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/conf/node_device_conf.c | 40 +++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 8d160185eb..5aafcbb838 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -1195,6 +1195,31 @@ virNodeDevCCWDeviceAddressParseXML(xmlXPathContextPtr ctxt, return 0; } + +static int +virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt, + virNodeDeviceDef *def, + xmlNodePtr node, + virNodeDevCapCCW *ccw_dev) +{ + VIR_XPATH_NODE_AUTORESTORE(ctxt) + g_autofree virCCWDeviceAddress *ccw_addr = NULL; + + ctxt->node = node; + + ccw_addr = g_new0(virCCWDeviceAddress, 1); + + if (virNodeDevCCWDeviceAddressParseXML(ctxt, node, def->name, ccw_addr) < 0) + return -1; + + ccw_dev->cssid = ccw_addr->cssid; + ccw_dev->ssid = ccw_addr->ssid; + ccw_dev->devno = ccw_addr->devno; + + return 0; +} + + static int virNodeDevCSSCapabilityParseXML(xmlXPathContextPtr ctxt, xmlNodePtr node, @@ -1223,7 +1248,7 @@ virNodeDevCSSCapabilityParseXML(xmlXPathContextPtr ctxt, static int -virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt, +virNodeDevCapCSSParseXML(xmlXPathContextPtr ctxt, virNodeDeviceDef *def, xmlNodePtr node, virNodeDevCapCCW *ccw_dev) @@ -1232,19 +1257,12 @@ virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt, g_autofree xmlNodePtr *nodes = NULL; int n = 0; size_t i = 0; - g_autofree virCCWDeviceAddress *ccw_addr = NULL; ctxt->node = node; - ccw_addr = g_new0(virCCWDeviceAddress, 1); - - if (virNodeDevCCWDeviceAddressParseXML(ctxt, node, def->name, ccw_addr) < 0) + if (virNodeDevCapCCWParseXML(ctxt, def, node, ccw_dev) < 0) return -1; - ccw_dev->cssid = ccw_addr->cssid; - ccw_dev->ssid = ccw_addr->ssid; - ccw_dev->devno = ccw_addr->devno; - if ((n = virXPathNodeSet("./capability", ctxt, &nodes)) < 0) return -1; @@ -2284,9 +2302,11 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt, ret = virNodeDevCapMdevParseXML(ctxt, def, node, &caps->data.mdev); break; case VIR_NODE_DEV_CAP_CCW_DEV: - case VIR_NODE_DEV_CAP_CSS_DEV: ret = virNodeDevCapCCWParseXML(ctxt, def, node, &caps->data.ccw_dev); break; + case VIR_NODE_DEV_CAP_CSS_DEV: + ret = virNodeDevCapCSSParseXML(ctxt, def, node, &caps->data.ccw_dev); + break; case VIR_NODE_DEV_CAP_AP_CARD: ret = virNodeDevCapAPCardParseXML(ctxt, def, node, &caps->data.ap_card); -- 2.33.1

Refactor out nodedev ccw address schema for easy reuse later. Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/conf/schemas/nodedev.rng | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/conf/schemas/nodedev.rng b/src/conf/schemas/nodedev.rng index 0d7d1168b6..a9f83e048c 100644 --- a/src/conf/schemas/nodedev.rng +++ b/src/conf/schemas/nodedev.rng @@ -658,10 +658,7 @@ </interleave> </define> - <define name="capccwdev"> - <attribute name="type"> - <value>ccw</value> - </attribute> + <define name="capccwaddress"> <element name="cssid"> <ref name="ccwCssidRange"/> </element> @@ -673,19 +670,18 @@ </element> </define> + <define name="capccwdev"> + <attribute name="type"> + <value>ccw</value> + </attribute> + <ref name="capccwaddress"/> + </define> + <define name="capcssdev"> <attribute name="type"> <value>css</value> </attribute> - <element name="cssid"> - <ref name="ccwCssidRange"/> - </element> - <element name="ssid"> - <ref name="ccwSsidRange"/> - </element> - <element name="devno"> - <ref name="ccwDevnoRange"/> - </element> + <ref name="capccwaddress"/> <optional> <ref name="mdev_types"/> </optional> -- 2.33.1

Add the new introduced sysfs attribute dev_busid which provides the address of the device in the subchannel independent from the bound device driver. It is added if available in the sysfs as optional channel_dev_addr element into the css device capabilty providing the ccw deivce address attributes cssid, ssid and devno. Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/conf/node_device_conf.c | 26 ++++++++++++++++++++++++++ src/conf/node_device_conf.h | 2 ++ src/conf/schemas/nodedev.rng | 5 +++++ src/node_device/node_device_udev.c | 8 ++++++++ 4 files changed, 41 insertions(+) diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 5aafcbb838..d5ee8da3ee 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -645,6 +645,17 @@ virNodeDeviceCapCSSDefFormat(virBuffer *buf, virNodeDeviceCapCCWDefFormat(buf, data); + if (ccw_dev.channel_dev_addr) { + virCCWDeviceAddress *ccw = ccw_dev.channel_dev_addr; + virBufferAddLit(buf, "<channel_dev_addr>\n"); + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "<cssid>0x%x</cssid>\n", ccw->cssid); + virBufferAsprintf(buf, "<ssid>0x%x</ssid>\n", ccw->ssid); + virBufferAsprintf(buf, "<devno>0x%04x</devno>\n", ccw->devno); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</channel_dev_addr>\n"); + } + if (ccw_dev.flags & VIR_NODE_DEV_CAP_FLAG_CSS_MDEV) virNodeDeviceCapMdevTypesFormat(buf, ccw_dev.mdev_types, @@ -1257,6 +1268,8 @@ virNodeDevCapCSSParseXML(xmlXPathContextPtr ctxt, g_autofree xmlNodePtr *nodes = NULL; int n = 0; size_t i = 0; + xmlNodePtr channel_ddno = NULL; + g_autofree virCCWDeviceAddress *channel_dev = NULL; ctxt->node = node; @@ -1271,6 +1284,19 @@ virNodeDevCapCSSParseXML(xmlXPathContextPtr ctxt, return -1; } + // channel_dev_addr is optional + if ((channel_ddno = virXPathNode("./channel_dev_addr[1]", ctxt))) { + channel_dev = g_new0(virCCWDeviceAddress, 1); + + if (virNodeDevCCWDeviceAddressParseXML(ctxt, + channel_ddno, + def->name, + channel_dev) < 0) + return -1; + + ccw_dev->channel_dev_addr = g_steal_pointer(&channel_dev); + } + return 0; } diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index e4d1f67d53..d1751ed874 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -24,6 +24,7 @@ #include "internal.h" #include "virbitmap.h" +#include "virccw.h" #include "virpcivpd.h" #include "virscsihost.h" #include "virpci.h" @@ -279,6 +280,7 @@ struct _virNodeDevCapCCW { unsigned int flags; /* enum virNodeDevCCWCapFlags */ virMediatedDeviceType **mdev_types; size_t nmdev_types; + virCCWDeviceAddress *channel_dev_addr; }; typedef struct _virNodeDevCapVDPA virNodeDevCapVDPA; diff --git a/src/conf/schemas/nodedev.rng b/src/conf/schemas/nodedev.rng index a9f83e048c..e40243e257 100644 --- a/src/conf/schemas/nodedev.rng +++ b/src/conf/schemas/nodedev.rng @@ -682,6 +682,11 @@ <value>css</value> </attribute> <ref name="capccwaddress"/> + <optional> + <element name="channel_dev_addr"> + <ref name="capccwaddress"/> + </element> + </optional> <optional> <ref name="mdev_types"/> </optional> diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 4bb841c66b..16314627ca 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1124,6 +1124,8 @@ static int udevProcessCSS(struct udev_device *device, virNodeDeviceDef *def) { + char *dev_busid; + /* only process IO subchannel and vfio-ccw devices to keep the list sane */ if (!def->driver || (STRNEQ(def->driver, "io_subchannel") && @@ -1135,6 +1137,12 @@ udevProcessCSS(struct udev_device *device, udevGenerateDeviceName(device, def, NULL); + /* process optional channel devices information */ + udevGetStringSysfsAttr(device, "dev_busid", &dev_busid); + + if (dev_busid != NULL) + def->caps->data.ccw_dev.channel_dev_addr = virCCWDeviceAddressFromString(dev_busid); + if (virNodeDeviceGetCSSDynamicCaps(def->sysfs_path, &def->caps->data.ccw_dev) < 0) return -1; -- 2.33.1

On 5/13/22 12:31, Boris Fiuczynski wrote:
Add the new introduced sysfs attribute dev_busid which provides the address of the device in the subchannel independent from the bound device driver. It is added if available in the sysfs as optional channel_dev_addr element into the css device capabilty providing the ccw deivce address attributes cssid, ssid and devno.
Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/conf/node_device_conf.c | 26 ++++++++++++++++++++++++++ src/conf/node_device_conf.h | 2 ++ src/conf/schemas/nodedev.rng | 5 +++++ src/node_device/node_device_udev.c | 8 ++++++++ 4 files changed, 41 insertions(+)
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 5aafcbb838..d5ee8da3ee 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -645,6 +645,17 @@ virNodeDeviceCapCSSDefFormat(virBuffer *buf,
virNodeDeviceCapCCWDefFormat(buf, data);
+ if (ccw_dev.channel_dev_addr) { + virCCWDeviceAddress *ccw = ccw_dev.channel_dev_addr; + virBufferAddLit(buf, "<channel_dev_addr>\n"); + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "<cssid>0x%x</cssid>\n", ccw->cssid); + virBufferAsprintf(buf, "<ssid>0x%x</ssid>\n", ccw->ssid); + virBufferAsprintf(buf, "<devno>0x%04x</devno>\n", ccw->devno); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</channel_dev_addr>\n"); + } + if (ccw_dev.flags & VIR_NODE_DEV_CAP_FLAG_CSS_MDEV) virNodeDeviceCapMdevTypesFormat(buf, ccw_dev.mdev_types, @@ -1257,6 +1268,8 @@ virNodeDevCapCSSParseXML(xmlXPathContextPtr ctxt, g_autofree xmlNodePtr *nodes = NULL; int n = 0; size_t i = 0; + xmlNodePtr channel_ddno = NULL; + g_autofree virCCWDeviceAddress *channel_dev = NULL;
ctxt->node = node;
@@ -1271,6 +1284,19 @@ virNodeDevCapCSSParseXML(xmlXPathContextPtr ctxt, return -1; }
+ // channel_dev_addr is optional
c89 style of comments please :-)
+ if ((channel_ddno = virXPathNode("./channel_dev_addr[1]", ctxt))) { + channel_dev = g_new0(virCCWDeviceAddress, 1);
This variable is not used anywhere else but in this block. It may be worth declaring it within.
+ + if (virNodeDevCCWDeviceAddressParseXML(ctxt, + channel_ddno, + def->name, + channel_dev) < 0) + return -1; + + ccw_dev->channel_dev_addr = g_steal_pointer(&channel_dev);
So this steals allocation from passed variable. But corresponding free() call in virNodeDevCapsDefFree() is missing.
+ } + return 0; }
diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index e4d1f67d53..d1751ed874 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -24,6 +24,7 @@
#include "internal.h" #include "virbitmap.h" +#include "virccw.h" #include "virpcivpd.h" #include "virscsihost.h" #include "virpci.h" @@ -279,6 +280,7 @@ struct _virNodeDevCapCCW { unsigned int flags; /* enum virNodeDevCCWCapFlags */ virMediatedDeviceType **mdev_types; size_t nmdev_types; + virCCWDeviceAddress *channel_dev_addr; };
typedef struct _virNodeDevCapVDPA virNodeDevCapVDPA; diff --git a/src/conf/schemas/nodedev.rng b/src/conf/schemas/nodedev.rng index a9f83e048c..e40243e257 100644 --- a/src/conf/schemas/nodedev.rng +++ b/src/conf/schemas/nodedev.rng @@ -682,6 +682,11 @@ <value>css</value> </attribute> <ref name="capccwaddress"/> + <optional> + <element name="channel_dev_addr"> + <ref name="capccwaddress"/> + </element> + </optional> <optional> <ref name="mdev_types"/> </optional> diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 4bb841c66b..16314627ca 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1124,6 +1124,8 @@ static int udevProcessCSS(struct udev_device *device, virNodeDeviceDef *def) { + char *dev_busid; + /* only process IO subchannel and vfio-ccw devices to keep the list sane */ if (!def->driver || (STRNEQ(def->driver, "io_subchannel") && @@ -1135,6 +1137,12 @@ udevProcessCSS(struct udev_device *device,
udevGenerateDeviceName(device, def, NULL);
+ /* process optional channel devices information */ + udevGetStringSysfsAttr(device, "dev_busid", &dev_busid);
This allocates dev_busid, which is never freed. it's sufficient to use g_autofree for the variable. Looking into the kernel sources, we may either get proper address here or "none": https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/driv... Is it worth to bother with "none" string here?
+ + if (dev_busid != NULL) + def->caps->data.ccw_dev.channel_dev_addr = virCCWDeviceAddressFromString(dev_busid); + if (virNodeDeviceGetCSSDynamicCaps(def->sysfs_path, &def->caps->data.ccw_dev) < 0) return -1;
Michal

On 5/23/22 4:40 PM, Michal Prívozník wrote:
On 5/13/22 12:31, Boris Fiuczynski wrote:
Add the new introduced sysfs attribute dev_busid which provides the address of the device in the subchannel independent from the bound device driver. It is added if available in the sysfs as optional channel_dev_addr element into the css device capabilty providing the ccw deivce address attributes cssid, ssid and devno.
Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- src/conf/node_device_conf.c | 26 ++++++++++++++++++++++++++ src/conf/node_device_conf.h | 2 ++ src/conf/schemas/nodedev.rng | 5 +++++ src/node_device/node_device_udev.c | 8 ++++++++ 4 files changed, 41 insertions(+)
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 5aafcbb838..d5ee8da3ee 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -645,6 +645,17 @@ virNodeDeviceCapCSSDefFormat(virBuffer *buf,
virNodeDeviceCapCCWDefFormat(buf, data);
+ if (ccw_dev.channel_dev_addr) { + virCCWDeviceAddress *ccw = ccw_dev.channel_dev_addr; + virBufferAddLit(buf, "<channel_dev_addr>\n"); + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "<cssid>0x%x</cssid>\n", ccw->cssid); + virBufferAsprintf(buf, "<ssid>0x%x</ssid>\n", ccw->ssid); + virBufferAsprintf(buf, "<devno>0x%04x</devno>\n", ccw->devno); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</channel_dev_addr>\n"); + } + if (ccw_dev.flags & VIR_NODE_DEV_CAP_FLAG_CSS_MDEV) virNodeDeviceCapMdevTypesFormat(buf, ccw_dev.mdev_types, @@ -1257,6 +1268,8 @@ virNodeDevCapCSSParseXML(xmlXPathContextPtr ctxt, g_autofree xmlNodePtr *nodes = NULL; int n = 0; size_t i = 0; + xmlNodePtr channel_ddno = NULL; + g_autofree virCCWDeviceAddress *channel_dev = NULL;
ctxt->node = node;
@@ -1271,6 +1284,19 @@ virNodeDevCapCSSParseXML(xmlXPathContextPtr ctxt, return -1; }
+ // channel_dev_addr is optional
c89 style of comments please :-)
+ if ((channel_ddno = virXPathNode("./channel_dev_addr[1]", ctxt))) { + channel_dev = g_new0(virCCWDeviceAddress, 1);
This variable is not used anywhere else but in this block. It may be worth declaring it within.
Yes, good idea.
+ + if (virNodeDevCCWDeviceAddressParseXML(ctxt, + channel_ddno, + def->name, + channel_dev) < 0) + return -1; + + ccw_dev->channel_dev_addr = g_steal_pointer(&channel_dev);
So this steals allocation from passed variable. But corresponding free() call in virNodeDevCapsDefFree() is missing.
Ups, correct. Thanks for fixing it.
+ } + return 0; }
diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index e4d1f67d53..d1751ed874 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -24,6 +24,7 @@
#include "internal.h" #include "virbitmap.h" +#include "virccw.h" #include "virpcivpd.h" #include "virscsihost.h" #include "virpci.h" @@ -279,6 +280,7 @@ struct _virNodeDevCapCCW { unsigned int flags; /* enum virNodeDevCCWCapFlags */ virMediatedDeviceType **mdev_types; size_t nmdev_types; + virCCWDeviceAddress *channel_dev_addr; };
typedef struct _virNodeDevCapVDPA virNodeDevCapVDPA; diff --git a/src/conf/schemas/nodedev.rng b/src/conf/schemas/nodedev.rng index a9f83e048c..e40243e257 100644 --- a/src/conf/schemas/nodedev.rng +++ b/src/conf/schemas/nodedev.rng @@ -682,6 +682,11 @@ <value>css</value> </attribute> <ref name="capccwaddress"/> + <optional> + <element name="channel_dev_addr"> + <ref name="capccwaddress"/> + </element> + </optional> <optional> <ref name="mdev_types"/> </optional> diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 4bb841c66b..16314627ca 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1124,6 +1124,8 @@ static int udevProcessCSS(struct udev_device *device, virNodeDeviceDef *def) { + char *dev_busid; + /* only process IO subchannel and vfio-ccw devices to keep the list sane */ if (!def->driver || (STRNEQ(def->driver, "io_subchannel") && @@ -1135,6 +1137,12 @@ udevProcessCSS(struct udev_device *device,
udevGenerateDeviceName(device, def, NULL);
+ /* process optional channel devices information */ + udevGetStringSysfsAttr(device, "dev_busid", &dev_busid);
This allocates dev_busid, which is never freed. it's sufficient to use g_autofree for the variable.
Looking into the kernel sources, we may either get proper address here or "none":
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/driv...
Is it worth to bother with "none" string here?
OK, it's fair as it currently would result in a libvirt internal error. I will send another patch with an additional check for "none" shortly.
+ + if (dev_busid != NULL) + def->caps->data.ccw_dev.channel_dev_addr = virCCWDeviceAddressFromString(dev_busid); + if (virNodeDeviceGetCSSDynamicCaps(def->sysfs_path, &def->caps->data.ccw_dev) < 0) return -1;
Michal
-- Mit freundlichen Grüßen/Kind regards Boris Fiuczynski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Gregor Pillen Geschäftsführung: David Faller Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294

Add nodedev schema parsing and format tests for the optional new device address on the css devices. Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> --- .../css_0_0_10000-invalid.xml | 10 +++++++++ ...s_0_0_fffe_mdev_types_channel_dev_addr.xml | 22 +++++++++++++++++++ .../css_0_0_ffff_channel_dev_addr-invalid.xml | 15 +++++++++++++ .../css_0_0_ffff_channel_dev_addr.xml | 15 +++++++++++++ ...s_0_0_fffe_mdev_types_channel_dev_addr.xml | 1 + .../css_0_0_ffff_channel_dev_addr.xml | 1 + tests/nodedevxml2xmltest.c | 2 ++ 7 files changed, 66 insertions(+) create mode 100644 tests/nodedevschemadata/css_0_0_10000-invalid.xml create mode 100644 tests/nodedevschemadata/css_0_0_fffe_mdev_types_channel_dev_addr.xml create mode 100644 tests/nodedevschemadata/css_0_0_ffff_channel_dev_addr-invalid.xml create mode 100644 tests/nodedevschemadata/css_0_0_ffff_channel_dev_addr.xml create mode 120000 tests/nodedevxml2xmlout/css_0_0_fffe_mdev_types_channel_dev_addr.xml create mode 120000 tests/nodedevxml2xmlout/css_0_0_ffff_channel_dev_addr.xml diff --git a/tests/nodedevschemadata/css_0_0_10000-invalid.xml b/tests/nodedevschemadata/css_0_0_10000-invalid.xml new file mode 100644 index 0000000000..740bb489a7 --- /dev/null +++ b/tests/nodedevschemadata/css_0_0_10000-invalid.xml @@ -0,0 +1,10 @@ +<device> + <name>css_0_0_10000</name> + <path>/sys/devices/css0/0.0.10000</path> + <parent>computer</parent> + <capability type='css'> + <cssid>0x0</cssid> + <ssid>0x0</ssid> + <devno>0x10000</devno> + </capability> +</device> diff --git a/tests/nodedevschemadata/css_0_0_fffe_mdev_types_channel_dev_addr.xml b/tests/nodedevschemadata/css_0_0_fffe_mdev_types_channel_dev_addr.xml new file mode 100644 index 0000000000..198dcb0cb0 --- /dev/null +++ b/tests/nodedevschemadata/css_0_0_fffe_mdev_types_channel_dev_addr.xml @@ -0,0 +1,22 @@ +<device> + <name>css_0_0_fffe</name> + <path>/sys/devices/css0/0.0.fffe</path> + <parent>computer</parent> + <capability type='css'> + <cssid>0x0</cssid> + <ssid>0x0</ssid> + <devno>0xfffe</devno> + <channel_dev_addr> + <cssid>0x0</cssid> + <ssid>0x0</ssid> + <devno>0x0815</devno> + </channel_dev_addr> + <capability type='mdev_types'> + <type id='vfio_ccw-io'> + <name>I/O subchannel (Non-QDIO)</name> + <deviceAPI>vfio-ccw</deviceAPI> + <availableInstances>1</availableInstances> + </type> + </capability> + </capability> +</device> diff --git a/tests/nodedevschemadata/css_0_0_ffff_channel_dev_addr-invalid.xml b/tests/nodedevschemadata/css_0_0_ffff_channel_dev_addr-invalid.xml new file mode 100644 index 0000000000..3f2c5558c7 --- /dev/null +++ b/tests/nodedevschemadata/css_0_0_ffff_channel_dev_addr-invalid.xml @@ -0,0 +1,15 @@ +<device> + <name>css_0_0_ffff</name> + <path>/sys/devices/css0/0.0.ffff</path> + <parent>computer</parent> + <capability type='css'> + <cssid>0x0</cssid> + <ssid>0x0</ssid> + <devno>0xffff</devno> + <channel_dev_addr> + <cssid>0x0</cssid> + <ssid>0x0</ssid> + <devno>0x10000</devno> + </channel_dev_addr> + </capability> +</device> diff --git a/tests/nodedevschemadata/css_0_0_ffff_channel_dev_addr.xml b/tests/nodedevschemadata/css_0_0_ffff_channel_dev_addr.xml new file mode 100644 index 0000000000..17a77cb282 --- /dev/null +++ b/tests/nodedevschemadata/css_0_0_ffff_channel_dev_addr.xml @@ -0,0 +1,15 @@ +<device> + <name>css_0_0_ffff</name> + <path>/sys/devices/css0/0.0.ffff</path> + <parent>computer</parent> + <capability type='css'> + <cssid>0x0</cssid> + <ssid>0x0</ssid> + <devno>0xffff</devno> + <channel_dev_addr> + <cssid>0x0</cssid> + <ssid>0x0</ssid> + <devno>0x0815</devno> + </channel_dev_addr> + </capability> +</device> diff --git a/tests/nodedevxml2xmlout/css_0_0_fffe_mdev_types_channel_dev_addr.xml b/tests/nodedevxml2xmlout/css_0_0_fffe_mdev_types_channel_dev_addr.xml new file mode 120000 index 0000000000..65ab582ee8 --- /dev/null +++ b/tests/nodedevxml2xmlout/css_0_0_fffe_mdev_types_channel_dev_addr.xml @@ -0,0 +1 @@ +../nodedevschemadata/css_0_0_fffe_mdev_types_channel_dev_addr.xml \ No newline at end of file diff --git a/tests/nodedevxml2xmlout/css_0_0_ffff_channel_dev_addr.xml b/tests/nodedevxml2xmlout/css_0_0_ffff_channel_dev_addr.xml new file mode 120000 index 0000000000..cbfe719777 --- /dev/null +++ b/tests/nodedevxml2xmlout/css_0_0_ffff_channel_dev_addr.xml @@ -0,0 +1 @@ +../nodedevschemadata/css_0_0_ffff_channel_dev_addr.xml \ No newline at end of file diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c index 557347fb07..ad9562cc82 100644 --- a/tests/nodedevxml2xmltest.c +++ b/tests/nodedevxml2xmltest.c @@ -125,7 +125,9 @@ mymain(void) DO_TEST("mdev_3627463d_b7f0_4fea_b468_f1da537d301b"); DO_TEST("ccw_0_0_ffff"); DO_TEST("css_0_0_ffff"); + DO_TEST("css_0_0_ffff_channel_dev_addr"); DO_TEST("css_0_0_fffe_mdev_types"); + DO_TEST("css_0_0_fffe_mdev_types_channel_dev_addr"); DO_TEST("ap_card07"); DO_TEST("ap_07_0038"); DO_TEST("ap_matrix"); -- 2.33.1

On 5/13/22 12:30, Boris Fiuczynski wrote:
While this series started with the intend to add the optional device address of a subchannel device to the nodedev css device the outcome now also includes a small fix in the error reporting of css cap XML parsing as well as a refactoring of generic ccw code into virccw in utils.
Boris Fiuczynski (17): nodedev: fix reported error msg in css cap XML parsing util: refactor virDomainDeviceCCWAddress into virccw.h util: refactor virDomainCCWAddressAsString into virccw util: make reuse of ccw device address format constant util: refactor ccw address constants into virccw util: refactor virDomainCCWAddressIncrement into virccw util: refactor virDomainDeviceCCWAddressIsValid into virccw util: refactor virDomainDeviceCCWAddressEqual into virccw conf: adjust method name virDomainDeviceCCWAddressParseXML util: add ccw device address parsing into virccw util: add virCCWDeviceAddressFromString to virccw nodedev: refactor css format from ccw format method nodedev: refactor ccw device address parsing from XML nodedev: refactor css XML parsing from ccw XML parsing schemas: refactor out nodedev ccw address schema nodedev: add optional device address of channel device to css device nodedev: add tests for optional device address to css device
po/POTFILES.in | 1 + src/conf/device_conf.c | 28 +-- src/conf/device_conf.h | 23 +-- src/conf/domain_addr.c | 28 +-- src/conf/domain_addr.h | 5 +- src/conf/domain_conf.c | 19 +- src/conf/domain_conf.h | 6 +- src/conf/node_device_conf.c | 171 +++++++++++++----- src/conf/node_device_conf.h | 2 + src/conf/schemas/nodedev.rng | 27 +-- src/libvirt_private.syms | 14 +- src/node_device/node_device_driver.c | 4 +- src/node_device/node_device_udev.c | 16 +- src/qemu/qemu_agent.c | 4 +- src/qemu/qemu_agent.h | 2 +- src/qemu/qemu_command.c | 2 +- src/util/meson.build | 1 + src/util/virccw.c | 103 +++++++++++ src/util/virccw.h | 52 ++++++ .../css_0_0_10000-invalid.xml | 10 + ...s_0_0_fffe_mdev_types_channel_dev_addr.xml | 22 +++ .../css_0_0_ffff_channel_dev_addr-invalid.xml | 15 ++ .../css_0_0_ffff_channel_dev_addr.xml | 15 ++ ...s_0_0_fffe_mdev_types_channel_dev_addr.xml | 1 + .../css_0_0_ffff_channel_dev_addr.xml | 1 + tests/nodedevxml2xmltest.c | 2 + 26 files changed, 418 insertions(+), 156 deletions(-) create mode 100644 src/util/virccw.c create mode 100644 src/util/virccw.h create mode 100644 tests/nodedevschemadata/css_0_0_10000-invalid.xml create mode 100644 tests/nodedevschemadata/css_0_0_fffe_mdev_types_channel_dev_addr.xml create mode 100644 tests/nodedevschemadata/css_0_0_ffff_channel_dev_addr-invalid.xml create mode 100644 tests/nodedevschemadata/css_0_0_ffff_channel_dev_addr.xml create mode 120000 tests/nodedevxml2xmlout/css_0_0_fffe_mdev_types_channel_dev_addr.xml create mode 120000 tests/nodedevxml2xmlout/css_0_0_ffff_channel_dev_addr.xml
I'm fixing small memleaks I've raised in 16/17 and merging. Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Michal

On 5/23/22 4:40 PM, Michal Prívozník wrote:
I'm fixing small memleaks I've raised in 16/17 and merging.
Reviewed-by: Michal Privoznik<mprivozn@redhat.com>
Michal
Thanks Michal -- Mit freundlichen Grüßen/Kind regards Boris Fiuczynski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Gregor Pillen Geschäftsführung: David Faller Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294
participants (2)
-
Boris Fiuczynski
-
Michal Prívozník