
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