From nobody Mon Feb 9 04:42:18 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=reject dis=none) header.from=linux.ibm.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1738689303358892.9923613270028; Tue, 4 Feb 2025 09:15:03 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 996) id CF0C91D87; Tue, 4 Feb 2025 12:14:36 -0500 (EST) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id B21AE1D65; Tue, 4 Feb 2025 12:12:03 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 996) id 06A101B66; Tue, 4 Feb 2025 12:11:51 -0500 (EST) Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id C38EE1BD9 for ; Tue, 4 Feb 2025 12:11:49 -0500 (EST) Received: from pps.filterd (m0360072.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 514GEmJc030533 for ; Tue, 4 Feb 2025 17:11:49 GMT Received: from ppma22.wdc07v.mail.ibm.com (5c.69.3da9.ip4.static.sl-reverse.com [169.61.105.92]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 44kekp2rgq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 04 Feb 2025 17:11:49 +0000 (GMT) Received: from pps.filterd (ppma22.wdc07v.mail.ibm.com [127.0.0.1]) by ppma22.wdc07v.mail.ibm.com (8.18.1.2/8.18.1.2) with ESMTP id 514FsYkG007136 for ; Tue, 4 Feb 2025 17:11:48 GMT Received: from smtprelay05.fra02v.mail.ibm.com ([9.218.2.225]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 44hxaymnau-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 04 Feb 2025 17:11:48 +0000 Received: from smtpav04.fra02v.mail.ibm.com (smtpav04.fra02v.mail.ibm.com [10.20.54.103]) by smtprelay05.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 514HBimM42598748 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 4 Feb 2025 17:11:44 GMT Received: from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C006C200B5; Tue, 4 Feb 2025 17:11:44 +0000 (GMT) Received: from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A4D9A200B9; Tue, 4 Feb 2025 17:11:44 +0000 (GMT) Received: from fiuczyvm.. (unknown [9.152.222.247]) by smtpav04.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 4 Feb 2025 17:11:44 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-1.4 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=/sGQwU9Vm4PWFlUDB wqgOAIqJZF1BG3MgWARMTg1Xow=; b=YR42MDAQOxuVn6oH6ueVm7scjZ16w2QNF zbDoDmmFMIvo6PJf/S6uhXmx58HWp3tdX2uq0NVDGTa0YQWx13/wUCc5jcf1PZIo PbBBR+kJsq1SBSahwlBcEfI48G5VTIRy7FkXBCqwZCyd3JJ1FvBF6p4Rgzxg8r8N LHzUs6LJAKxjftTcsOldTgDGbI28NJzVqqpcJG/+FokkwXObCgFyxDyJ4SFTVQpU Y5x0UKIEHBqsqGHcsryAk4tlB0VD4XFnGzI9AmjFKExB649zc+it+nUPHC5fITeH ByK1eEN191/HRExuc55gFqyW9iecveiUPPNd6McVl3Sq6fQ9dQNbg== From: Boris Fiuczynski To: devel@lists.libvirt.org Subject: [PATCH 7/8] nodedev: add ccwgroup capability support to ccw devices Date: Tue, 4 Feb 2025 18:11:42 +0100 Message-ID: <20250204171143.93141-8-fiuczy@linux.ibm.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250204171143.93141-1-fiuczy@linux.ibm.com> References: <20250204171143.93141-1-fiuczy@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: 6yyvu0htmRRHyEFiY_p19bEe63jRaV4s X-Proofpoint-GUID: 6yyvu0htmRRHyEFiY_p19bEe63jRaV4s X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1057,Hydra:6.0.680,FMLib:17.12.68.34 definitions=2025-02-04_08,2025-02-04_01,2024-11-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 bulkscore=0 adultscore=0 lowpriorityscore=0 clxscore=1015 mlxscore=0 malwarescore=0 spamscore=0 priorityscore=1501 phishscore=0 mlxlogscore=999 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2501170000 definitions=main-2502040131 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: 52BEFUGADAXJXJYCJANMJDO62XVCYIKW X-Message-ID-Hash: 52BEFUGADAXJXJYCJANMJDO62XVCYIKW X-MailFrom: fiuczy@linux.ibm.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: Boris Fiuczynski X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1738689304234019100 Content-Type: text/plain; charset="utf-8" Add the group membership information to a CCW device. Allow to filter CCW devices based on a group membership. Signed-off-by: Boris Fiuczynski --- docs/manpages/virsh.rst | 19 ++-- include/libvirt/libvirt-nodedev.h | 1 + src/conf/node_device_conf.c | 105 +++++++++++++++++- src/conf/node_device_conf.h | 10 +- src/conf/schemas/nodedev.rng | 12 ++ src/conf/virnodedeviceobj.c | 11 +- src/libvirt_private.syms | 1 + src/node_device/node_device_driver.c | 2 + src/node_device/node_device_udev.c | 4 + src/util/virccw.c | 23 ++++ src/util/virccw.h | 3 + .../ccw_0_0_ff02_ccwgroup.xml | 13 +++ .../ccw_0_0_ff02_ccwgroup.xml | 1 + tests/nodedevxml2xmltest.c | 1 + tools/virsh-nodedev.c | 3 + 15 files changed, 196 insertions(+), 13 deletions(-) create mode 100644 tests/nodedevschemadata/ccw_0_0_ff02_ccwgroup.xml create mode 120000 tests/nodedevxml2xmlout/ccw_0_0_ff02_ccwgroup.xml diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst index 5e5734dff1..9e549f25a6 100644 --- a/docs/manpages/virsh.rst +++ b/docs/manpages/virsh.rst @@ -5532,15 +5532,16 @@ List all of the devices available on the node that = are known by libvirt. separated by comma, e.g. --cap pci,scsi. Valid capability types include 'system', 'pci', 'usb_device', 'usb', 'net', 'scsi_host', 'scsi_target', 'scsi', 'storage', 'fc_host', 'vports', 'scsi_generic', 'drm', 'mdev', -'mdev_types', 'ccw', 'ccwgroup', 'css', 'ap_card', 'ap_queue', 'ap_matrix'. -By default, only active devices are listed. *--inactive* is used to list o= nly -inactive devices, and *--all* is used to list both active and inactive dev= ices. -*--persistent* is used to list only persistent devices, and *--transient* = is -used to list only transient devices. Not providing *--persistent* or -*--transient* will list all devices unless filtered otherwise. *--transien= t* -is mutually exclusive with *--persistent* and *--inactive*. -If *--tree* is used, the output is formatted in a tree representing parent= s of -each node. *--tree* is mutually exclusive with all other options but *--al= l*. +'mdev_types', 'ccw', 'ccwgroup', 'ccwgroup_member', 'css', 'ap_card', +'ap_queue', 'ap_matrix'. By default, only active devices are listed. +*--inactive* is used to list only inactive devices, and *--all* is used to +list both active and inactive devices. *--persistent* is used to list only +persistent devices, and *--transient* is used to list only transient devic= es. +Not providing *--persistent* or *--transient* will list all devices unless +filtered otherwise. *--transient* is mutually exclusive with *--persistent* +and *--inactive*. If *--tree* is used, the output is formatted in a tree +representing parents of each node. *--tree* is mutually exclusive with all +other options but *--all*. =20 =20 nodedev-reattach diff --git a/include/libvirt/libvirt-nodedev.h b/include/libvirt/libvirt-no= dedev.h index 79bee4fb04..9fccbeefeb 100644 --- a/include/libvirt/libvirt-nodedev.h +++ b/include/libvirt/libvirt-nodedev.h @@ -91,6 +91,7 @@ typedef enum { VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_MATRIX =3D 1 << 20, /* s390 A= P Matrix (Since: 7.0.0) */ VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPD =3D 1 << 21, /* Device= with VPD (Since: 7.9.0) */ VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCWGROUP_DEV =3D 1 << 22, /* s390 C= CWGROUP device (Since: 11.1.0) */ + VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCWGROUP_MEMBER =3D 1 << 23, /* s390= CCW device member of CCWGROUP device (Since: 11.1.0) */ =20 VIR_CONNECT_LIST_NODE_DEVICES_PERSISTENT =3D 1 << 28, /* Persis= ted devices (Since: 10.1.0) */ VIR_CONNECT_LIST_NODE_DEVICES_TRANSIENT =3D 1 << 29, /* Transi= ent devices (Since: 10.1.0) */ diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 1649df09a1..3e88f5da87 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -72,6 +72,7 @@ VIR_ENUM_IMPL(virNodeDevCap, "ap_matrix", "vpd", "ccwgroup", + "ccwgroup_member", ); =20 VIR_ENUM_IMPL(virNodeDevCCWGroupCap, @@ -642,6 +643,23 @@ virCCWDeviceAddressFormat(virBuffer *buf, } =20 =20 +static void +virNodeDeviceCapCCWGroupMemberDefFormat(virBuffer *buf, + const virNodeDevCapData *data) +{ + virNodeDevCapCCW ccw_dev =3D data->ccw_dev; + + if (ccw_dev.group_dev) { + virBufferAddLit(buf, "\n"); + virBufferAdjustIndent(buf, 2); + virBufferEscapeString(buf, "%s\n", + ccw_dev.group_dev); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); + } +} + + static void virNodeDeviceCapCSSDefFormat(virBuffer *buf, const virNodeDevCapData *data) @@ -812,6 +830,8 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def, uns= igned int flags) case VIR_NODE_DEV_CAP_CCW_DEV: virNodeDeviceCapCCWStateTypeFormat(&buf, data->ccw_dev.state); virCCWDeviceAddressFormat(&buf, data->ccw_dev.dev_addr); + if (data->ccw_dev.flags & VIR_NODE_DEV_CAP_FLAG_CCW_CCWGROUP_M= EMBER) + virNodeDeviceCapCCWGroupMemberDefFormat(&buf, data); break; case VIR_NODE_DEV_CAP_CSS_DEV: virNodeDeviceCapCSSDefFormat(&buf, data); @@ -843,6 +863,7 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def, uns= igned int flags) case VIR_NODE_DEV_CAP_CCWGROUP_DEV: virNodeDeviceCapCCWGroupDefFormat(&buf, data); break; + case VIR_NODE_DEV_CAP_CCWGROUP_MEMBER: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: case VIR_NODE_DEV_CAP_VPD: @@ -1252,6 +1273,33 @@ virNodeDevCCWDeviceAddressParseXML(xmlXPathContextPt= r ctxt, } =20 =20 +static int +virNodeDevCCWCapabilityParseXML(xmlXPathContextPtr ctxt, + xmlNodePtr node, + const char *dev_name, + virNodeDevCapCCW *ccw_dev) +{ + g_autofree char *type =3D virXMLPropString(node, "type"); + VIR_XPATH_NODE_AUTORESTORE(ctxt) + + ctxt->node =3D node; + + if (!type) + return 0; /* optional */ + + if (STREQ(type, "ccwgroup_member")) { + if (!(ccw_dev->group_dev =3D virXPathString("string(./group_device= [1])", ctxt))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("missing group_device value for '%1$s'"), dev= _name); + return -1; + } + ccw_dev->flags |=3D VIR_NODE_DEV_CAP_FLAG_CCW_CCWGROUP_MEMBER; + } + + return 0; +} + + static int virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt, virNodeDeviceDef *def, @@ -1260,7 +1308,10 @@ virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt, { VIR_XPATH_NODE_AUTORESTORE(ctxt) g_autofree virCCWDeviceAddress *ccw_addr =3D NULL; + g_autofree xmlNodePtr *nodes =3D NULL; g_autofree char *state =3D NULL; + int n =3D 0; + size_t i =3D 0; int val; =20 ctxt->node =3D node; @@ -1284,6 +1335,15 @@ virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt, =20 ccw_dev->dev_addr =3D g_steal_pointer(&ccw_addr); =20 + /* capabilities are optional */ + if ((n =3D virXPathNodeSet("./capability", ctxt, &nodes)) < 0) + return -1; + + for (i =3D 0; i < n; i++) { + if (virNodeDevCCWCapabilityParseXML(ctxt, nodes[i], def->name, ccw= _dev) < 0) + return -1; + } + return 0; } =20 @@ -2504,6 +2564,7 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt, ret =3D virNodeDevCapCCWGroupParseXML(ctxt, def, node, &caps->data.ccwgroup_dev); break; + case VIR_NODE_DEV_CAP_CCWGROUP_MEMBER: case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: @@ -2795,6 +2856,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDef *caps) break; case VIR_NODE_DEV_CAP_CCW_DEV: g_free(data->ccw_dev.dev_addr); + g_free(data->ccw_dev.group_dev); break; case VIR_NODE_DEV_CAP_CCWGROUP_DEV: g_free(data->ccwgroup_dev.address); @@ -2809,6 +2871,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDef *caps) break; } break; + case VIR_NODE_DEV_CAP_CCWGROUP_MEMBER: case VIR_NODE_DEV_CAP_DRM: case VIR_NODE_DEV_CAP_FC_HOST: case VIR_NODE_DEV_CAP_VPORTS: @@ -2868,6 +2931,12 @@ virNodeDeviceUpdateCaps(virNodeDeviceDef *def) &cap->data.mdev_pare= nt) < 0) return -1; break; + case VIR_NODE_DEV_CAP_CCW_DEV: + case VIR_NODE_DEV_CAP_CCWGROUP_MEMBER: + if (virNodeDeviceGetCCWDynamicCaps(def->sysfs_path, + &cap->data.ccw_dev) < 0) + return -1; + break; case VIR_NODE_DEV_CAP_CCWGROUP_DEV: if (virNodeDeviceGetCCWGroupDynamicCaps(def->sysfs_path, &cap->data.ccwgroup_de= v) < 0) @@ -2887,7 +2956,6 @@ virNodeDeviceUpdateCaps(virNodeDeviceDef *def) case VIR_NODE_DEV_CAP_VPORTS: case VIR_NODE_DEV_CAP_SCSI_GENERIC: case VIR_NODE_DEV_CAP_MDEV: - case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_VDPA: case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_AP_QUEUE: @@ -2986,6 +3054,15 @@ virNodeDeviceCapsListExport(virNodeDeviceDef *def, ncaps++; } } + + if (caps->data.type =3D=3D VIR_NODE_DEV_CAP_CCW_DEV) { + flags =3D caps->data.ccw_dev.flags; + + if (flags & VIR_NODE_DEV_CAP_FLAG_CCW_CCWGROUP_MEMBER) { + MAYBE_ADD_CAP(VIR_NODE_DEV_CAP_CCWGROUP_MEMBER); + ncaps++; + } + } } =20 #undef MAYBE_ADD_CAP @@ -3335,6 +3412,25 @@ virNodeDeviceGetCSSDynamicCaps(const char *sysfsPath, return 0; } =20 +/* virNodeDeviceGetCCWDynamicCaps() get info that is stored in sysfs + * about devices related to this device, i.e. things that can change + * without this device itself changing. These must be refreshed + * anytime full XML of the device is requested, because they can + * change with no corresponding notification from the kernel/udev. + */ +int +virNodeDeviceGetCCWDynamicCaps(const char *sysfsPath, + virNodeDevCapCCW *ccw_dev) +{ + g_free(ccw_dev->group_dev); + ccw_dev->flags &=3D ~VIR_NODE_DEV_CAP_FLAG_CCW_CCWGROUP_MEMBER; + + if ((ccw_dev->group_dev =3D virCCWDeviceGetGroupDev(sysfsPath))) + ccw_dev->flags |=3D VIR_NODE_DEV_CAP_FLAG_CCW_CCWGROUP_MEMBER; + + return 0; +} + /* virNodeDeviceGetAPMatrixDynamicCaps() get info that is stored in sysfs * about devices related to this device, i.e. things that can change * without this device itself changing. These must be refreshed @@ -3428,6 +3524,13 @@ virNodeDeviceGetCSSDynamicCaps(const char *sysfsPath= G_GNUC_UNUSED, return -1; } =20 +int +virNodeDeviceGetCCWDynamicCaps(const char *sysfsPath G_GNUC_UNUSED, + virNodeDevCapCCW *ccw_dev G_GNUC_UNUSED) +{ + return -1; +} + int virNodeDeviceGetAPMatrixDynamicCaps(const char *sysfsPath G_GNUC_UNUSED, virNodeDevCapAPMatrix *ap_matrix G_GNU= C_UNUSED) diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index d94670e074..a6cef57b95 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -72,6 +72,7 @@ typedef enum { VIR_NODE_DEV_CAP_AP_MATRIX, /* s390 AP Matrix device */ VIR_NODE_DEV_CAP_VPD, /* Device provides VPD */ VIR_NODE_DEV_CAP_CCWGROUP_DEV, /* s390 CCWGROUP device */ + VIR_NODE_DEV_CAP_CCWGROUP_MEMBER, /* s390 CCW device is member of CC= WGROUP */ =20 VIR_NODE_DEV_CAP_LAST } virNodeDevCapType; @@ -118,6 +119,7 @@ typedef enum { =20 typedef enum { VIR_NODE_DEV_CAP_FLAG_CSS_MDEV =3D (1 << 0), + VIR_NODE_DEV_CAP_FLAG_CCW_CCWGROUP_MEMBER =3D (2 << 0), } virNodeDevCCWCapFlags; =20 typedef enum { @@ -295,6 +297,7 @@ struct _virNodeDevCapCCW { size_t nmdev_types; virCCWDeviceAddress *channel_dev_addr; virNodeDevCCWStateType state; + char *group_dev; }; =20 typedef struct _virNodeDevCapVDPA virNodeDevCapVDPA; @@ -457,7 +460,8 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNodeDevCapsDef, virNod= eDevCapsDefFree); VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_QUEUE | \ VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_MATRIX | \ VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPD | \ - VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCWGROUP_DEV) + VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCWGROUP_DEV | \ + VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCWGROUP_MEMBER) =20 #define VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_ACTIVE \ VIR_CONNECT_LIST_NODE_DEVICES_ACTIVE | \ @@ -495,6 +499,10 @@ int virNodeDeviceGetMdevParentDynamicCaps(const char *sysfsPath, virNodeDevCapMdevParent *mdev_parent= ); =20 +int +virNodeDeviceGetCCWDynamicCaps(const char *sysfsPath, + virNodeDevCapCCW *ccw_dev); + int virNodeDeviceGetCCWGroupDynamicCaps(const char *sysfsPath, virNodeDevCapCCWGroup *ccwgroup); diff --git a/src/conf/schemas/nodedev.rng b/src/conf/schemas/nodedev.rng index ebcda30f1f..f52c6ab752 100644 --- a/src/conf/schemas/nodedev.rng +++ b/src/conf/schemas/nodedev.rng @@ -712,6 +712,17 @@ =20 + + + + + ccwgroup_member + + + + + + ccw @@ -725,6 +736,7 @@ + =20 diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c index 23984995c8..c5ddf0b4fb 100644 --- a/src/conf/virnodedeviceobj.c +++ b/src/conf/virnodedeviceobj.c @@ -723,6 +723,12 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj, return true; break; =20 + case VIR_NODE_DEV_CAP_CCW_DEV: + if (type =3D=3D VIR_NODE_DEV_CAP_CCWGROUP_MEMBER && + (cap->data.ccw_dev.flags & VIR_NODE_DEV_CAP_FLAG_CCW_CCWGR= OUP_MEMBER)) + return true; + break; + case VIR_NODE_DEV_CAP_SYSTEM: case VIR_NODE_DEV_CAP_USB_DEV: case VIR_NODE_DEV_CAP_USB_INTERFACE: @@ -736,12 +742,12 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj, case VIR_NODE_DEV_CAP_DRM: case VIR_NODE_DEV_CAP_MDEV_TYPES: case VIR_NODE_DEV_CAP_MDEV: - case VIR_NODE_DEV_CAP_CCW_DEV: case VIR_NODE_DEV_CAP_VDPA: case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_AP_QUEUE: case VIR_NODE_DEV_CAP_VPD: case VIR_NODE_DEV_CAP_CCWGROUP_DEV: + case VIR_NODE_DEV_CAP_CCWGROUP_MEMBER: case VIR_NODE_DEV_CAP_LAST: break; } @@ -901,7 +907,8 @@ virNodeDeviceObjMatch(virNodeDeviceObj *obj, MATCH_CAP(AP_QUEUE) || MATCH_CAP(AP_MATRIX) || MATCH_CAP(VPD) || - MATCH_CAP(CCWGROUP_DEV))) + MATCH_CAP(CCWGROUP_DEV) || + MATCH_CAP(CCWGROUP_MEMBER))) return false; } =20 diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 07e1e673f0..8abda5fa7e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -899,6 +899,7 @@ virNodeDeviceDefFree; virNodeDeviceDefParse; virNodeDeviceDefParseXML; virNodeDeviceGetAPMatrixDynamicCaps; +virNodeDeviceGetCCWDynamicCaps; virNodeDeviceGetCCWGroupDynamicCaps; virNodeDeviceGetCSSDynamicCaps; virNodeDeviceGetMdevParentDynamicCaps; diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_de= vice_driver.c index d716561361..123b16a292 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -717,6 +717,7 @@ nodeDeviceObjFormatAddress(virNodeDeviceObj *obj) case VIR_NODE_DEV_CAP_AP_CARD: case VIR_NODE_DEV_CAP_AP_QUEUE: case VIR_NODE_DEV_CAP_VPD: + case VIR_NODE_DEV_CAP_CCWGROUP_MEMBER: case VIR_NODE_DEV_CAP_LAST: break; } @@ -2194,6 +2195,7 @@ int nodeDeviceDefValidate(virNodeDeviceDef *def, case VIR_NODE_DEV_CAP_AP_MATRIX: case VIR_NODE_DEV_CAP_VPD: case VIR_NODE_DEV_CAP_CCWGROUP_DEV: + case VIR_NODE_DEV_CAP_CCWGROUP_MEMBER: case VIR_NODE_DEV_CAP_LAST: break; } diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_devi= ce_udev.c index a78f47b65a..ba5727ed8f 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1239,6 +1239,9 @@ udevProcessCCW(struct udev_device *device, =20 udevGenerateDeviceName(device, def, NULL); =20 + if (virNodeDeviceGetCCWDynamicCaps(def->sysfs_path, &def->caps->data.c= cw_dev) < 0) + return -1; + return 0; } =20 @@ -1575,6 +1578,7 @@ udevGetDeviceDetails(virNodeDeviceDriverState *driver= _state, return udevProcessMdevParent(device, def); case VIR_NODE_DEV_CAP_CCWGROUP_DEV: return udevProcessCCWGroup(device, def); + case VIR_NODE_DEV_CAP_CCWGROUP_MEMBER: case VIR_NODE_DEV_CAP_VPD: case VIR_NODE_DEV_CAP_SYSTEM: case VIR_NODE_DEV_CAP_FC_HOST: diff --git a/src/util/virccw.c b/src/util/virccw.c index 0873c61889..762ef671a2 100644 --- a/src/util/virccw.c +++ b/src/util/virccw.c @@ -203,3 +203,26 @@ virCCWGroupTypeQethFree(virCCWGroupTypeQeth *qeth) VIR_FREE(qeth->card_type); VIR_FREE(qeth->chpid); } + +char * +virCCWDeviceGetGroupDev(const char *sysfs_path) +{ + g_autofree char *ccwgroup_path =3D NULL; + g_autofree char *group_dev_path =3D NULL; + + group_dev_path =3D g_build_filename(sysfs_path, "group_device", NULL); + + if (!virFileExists(group_dev_path)) + return NULL; + + if (virFileIsLink(group_dev_path) !=3D 1) + return NULL; + + if (virFileResolveLink(group_dev_path, &ccwgroup_path) < 0) + return NULL; + + if (!virFileExists(ccwgroup_path)) + return NULL; + + return virCCWGroupDeviceDevNodeName("ccwgroup", ccwgroup_path); +} diff --git a/src/util/virccw.h b/src/util/virccw.h index a8c9fa83ef..67faf878a8 100644 --- a/src/util/virccw.h +++ b/src/util/virccw.h @@ -71,4 +71,7 @@ int virCCWGroupDeviceGetMembers(const char *sysfs_path, =20 void virCCWGroupTypeQethFree(virCCWGroupTypeQeth *qeth); =20 +char* virCCWDeviceGetGroupDev(const char *sysfs_path) + ATTRIBUTE_NONNULL(1); + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCCWGroupMemberType, virCCWGroupMemberType= Free); diff --git a/tests/nodedevschemadata/ccw_0_0_ff02_ccwgroup.xml b/tests/node= devschemadata/ccw_0_0_ff02_ccwgroup.xml new file mode 100644 index 0000000000..11767facd3 --- /dev/null +++ b/tests/nodedevschemadata/ccw_0_0_ff02_ccwgroup.xml @@ -0,0 +1,13 @@ + + ccw_0_0_ff02 + /sys/devices/css0/0.0.0070/0.0.ff02 + css_0_0_0070 + + 0x0 + 0x0 + 0xff02 + + ccwgroup_0_0_ff00 + + + diff --git a/tests/nodedevxml2xmlout/ccw_0_0_ff02_ccwgroup.xml b/tests/node= devxml2xmlout/ccw_0_0_ff02_ccwgroup.xml new file mode 120000 index 0000000000..4d2b000b11 --- /dev/null +++ b/tests/nodedevxml2xmlout/ccw_0_0_ff02_ccwgroup.xml @@ -0,0 +1 @@ +../nodedevschemadata/ccw_0_0_ff02_ccwgroup.xml \ No newline at end of file diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c index d4d87b3bdc..265b37b218 100644 --- a/tests/nodedevxml2xmltest.c +++ b/tests/nodedevxml2xmltest.c @@ -146,6 +146,7 @@ mymain(void) DO_TEST("mdev_3627463d_b7f0_4fea_b468_f1da537d301b"); DO_TEST_INACTIVE("mdev_3627463d_b7f0_4fea_b468_f1da537d301b"); DO_TEST("ccw_0_0_ffff"); + DO_TEST("ccw_0_0_ff02_ccwgroup"); DO_TEST("ccwgroup_0_0_bd00"); DO_TEST("css_0_0_ffff"); DO_TEST("css_0_0_ffff_channel_dev_addr"); diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c index 3aae7285a9..e759b9f629 100644 --- a/tools/virsh-nodedev.c +++ b/tools/virsh-nodedev.c @@ -504,6 +504,9 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G= _GNUC_UNUSED) case VIR_NODE_DEV_CAP_CCWGROUP_DEV: flags |=3D VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCWGROUP_DEV; break; + case VIR_NODE_DEV_CAP_CCWGROUP_MEMBER: + flags |=3D VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCWGROUP_MEMBER; + break; case VIR_NODE_DEV_CAP_LAST: break; } --=20 2.47.0