mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-11 06:01:33 +00:00
nodedev: add ccwgroup capability support to ccw devices
Add the group membership information to a CCW device. Allow to filter CCW devices based on a group membership. Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
985cb9c32a
commit
55e921d5cb
@ -5533,15 +5533,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
|
separated by comma, e.g. --cap pci,scsi. Valid capability types include
|
||||||
'system', 'pci', 'usb_device', 'usb', 'net', 'scsi_host', 'scsi_target',
|
'system', 'pci', 'usb_device', 'usb', 'net', 'scsi_host', 'scsi_target',
|
||||||
'scsi', 'storage', 'fc_host', 'vports', 'scsi_generic', 'drm', 'mdev',
|
'scsi', 'storage', 'fc_host', 'vports', 'scsi_generic', 'drm', 'mdev',
|
||||||
'mdev_types', 'ccw', 'ccwgroup', 'css', 'ap_card', 'ap_queue', 'ap_matrix'.
|
'mdev_types', 'ccw', 'ccwgroup', 'ccwgroup_member', 'css', 'ap_card',
|
||||||
By default, only active devices are listed. *--inactive* is used to list only
|
'ap_queue', 'ap_matrix'. By default, only active devices are listed.
|
||||||
inactive devices, and *--all* is used to list both active and inactive devices.
|
*--inactive* is used to list only inactive devices, and *--all* is used to
|
||||||
*--persistent* is used to list only persistent devices, and *--transient* is
|
list both active and inactive devices. *--persistent* is used to list only
|
||||||
used to list only transient devices. Not providing *--persistent* or
|
persistent devices, and *--transient* is used to list only transient devices.
|
||||||
*--transient* will list all devices unless filtered otherwise. *--transient*
|
Not providing *--persistent* or *--transient* will list all devices unless
|
||||||
is mutually exclusive with *--persistent* and *--inactive*.
|
filtered otherwise. *--transient* is mutually exclusive with *--persistent*
|
||||||
If *--tree* is used, the output is formatted in a tree representing parents of
|
and *--inactive*. If *--tree* is used, the output is formatted in a tree
|
||||||
each node. *--tree* is mutually exclusive with all other options but *--all*.
|
representing parents of each node. *--tree* is mutually exclusive with all
|
||||||
|
other options but *--all*.
|
||||||
|
|
||||||
|
|
||||||
nodedev-reattach
|
nodedev-reattach
|
||||||
|
@ -91,6 +91,7 @@ typedef enum {
|
|||||||
VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_MATRIX = 1 << 20, /* s390 AP Matrix (Since: 7.0.0) */
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_MATRIX = 1 << 20, /* s390 AP Matrix (Since: 7.0.0) */
|
||||||
VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPD = 1 << 21, /* Device with VPD (Since: 7.9.0) */
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPD = 1 << 21, /* Device with VPD (Since: 7.9.0) */
|
||||||
VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCWGROUP_DEV = 1 << 22, /* s390 CCWGROUP device (Since: 11.1.0) */
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCWGROUP_DEV = 1 << 22, /* s390 CCWGROUP device (Since: 11.1.0) */
|
||||||
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCWGROUP_MEMBER = 1 << 23, /* s390 CCW device member of CCWGROUP device (Since: 11.1.0) */
|
||||||
|
|
||||||
VIR_CONNECT_LIST_NODE_DEVICES_PERSISTENT = 1 << 28, /* Persisted devices (Since: 10.1.0) */
|
VIR_CONNECT_LIST_NODE_DEVICES_PERSISTENT = 1 << 28, /* Persisted devices (Since: 10.1.0) */
|
||||||
VIR_CONNECT_LIST_NODE_DEVICES_TRANSIENT = 1 << 29, /* Transient devices (Since: 10.1.0) */
|
VIR_CONNECT_LIST_NODE_DEVICES_TRANSIENT = 1 << 29, /* Transient devices (Since: 10.1.0) */
|
||||||
|
@ -72,6 +72,7 @@ VIR_ENUM_IMPL(virNodeDevCap,
|
|||||||
"ap_matrix",
|
"ap_matrix",
|
||||||
"vpd",
|
"vpd",
|
||||||
"ccwgroup",
|
"ccwgroup",
|
||||||
|
"ccwgroup_member",
|
||||||
);
|
);
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virNodeDevCCWGroupCap,
|
VIR_ENUM_IMPL(virNodeDevCCWGroupCap,
|
||||||
@ -642,6 +643,23 @@ virCCWDeviceAddressFormat(virBuffer *buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
virNodeDeviceCapCCWGroupMemberDefFormat(virBuffer *buf,
|
||||||
|
const virNodeDevCapData *data)
|
||||||
|
{
|
||||||
|
virNodeDevCapCCW ccw_dev = data->ccw_dev;
|
||||||
|
|
||||||
|
if (ccw_dev.group_dev) {
|
||||||
|
virBufferAddLit(buf, "<capability type='ccwgroup_member'>\n");
|
||||||
|
virBufferAdjustIndent(buf, 2);
|
||||||
|
virBufferEscapeString(buf, "<group_device>%s</group_device>\n",
|
||||||
|
ccw_dev.group_dev);
|
||||||
|
virBufferAdjustIndent(buf, -2);
|
||||||
|
virBufferAddLit(buf, "</capability>\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
virNodeDeviceCapCSSDefFormat(virBuffer *buf,
|
virNodeDeviceCapCSSDefFormat(virBuffer *buf,
|
||||||
const virNodeDevCapData *data)
|
const virNodeDevCapData *data)
|
||||||
@ -813,6 +831,8 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def, unsigned int flags)
|
|||||||
case VIR_NODE_DEV_CAP_CCW_DEV:
|
case VIR_NODE_DEV_CAP_CCW_DEV:
|
||||||
virNodeDeviceCapCCWStateTypeFormat(&buf, data->ccw_dev.state);
|
virNodeDeviceCapCCWStateTypeFormat(&buf, data->ccw_dev.state);
|
||||||
virCCWDeviceAddressFormat(&buf, data->ccw_dev.dev_addr);
|
virCCWDeviceAddressFormat(&buf, data->ccw_dev.dev_addr);
|
||||||
|
if (data->ccw_dev.flags & VIR_NODE_DEV_CAP_FLAG_CCW_CCWGROUP_MEMBER)
|
||||||
|
virNodeDeviceCapCCWGroupMemberDefFormat(&buf, data);
|
||||||
break;
|
break;
|
||||||
case VIR_NODE_DEV_CAP_CSS_DEV:
|
case VIR_NODE_DEV_CAP_CSS_DEV:
|
||||||
virNodeDeviceCapCSSDefFormat(&buf, data);
|
virNodeDeviceCapCSSDefFormat(&buf, data);
|
||||||
@ -844,6 +864,7 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def, unsigned int flags)
|
|||||||
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
||||||
virNodeDeviceCapCCWGroupDefFormat(&buf, data);
|
virNodeDeviceCapCCWGroupDefFormat(&buf, data);
|
||||||
break;
|
break;
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_MEMBER:
|
||||||
case VIR_NODE_DEV_CAP_FC_HOST:
|
case VIR_NODE_DEV_CAP_FC_HOST:
|
||||||
case VIR_NODE_DEV_CAP_VPORTS:
|
case VIR_NODE_DEV_CAP_VPORTS:
|
||||||
case VIR_NODE_DEV_CAP_VPD:
|
case VIR_NODE_DEV_CAP_VPD:
|
||||||
@ -1253,6 +1274,33 @@ virNodeDevCCWDeviceAddressParseXML(xmlXPathContextPtr ctxt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virNodeDevCCWCapabilityParseXML(xmlXPathContextPtr ctxt,
|
||||||
|
xmlNodePtr node,
|
||||||
|
const char *dev_name,
|
||||||
|
virNodeDevCapCCW *ccw_dev)
|
||||||
|
{
|
||||||
|
g_autofree char *type = virXMLPropString(node, "type");
|
||||||
|
VIR_XPATH_NODE_AUTORESTORE(ctxt)
|
||||||
|
|
||||||
|
ctxt->node = node;
|
||||||
|
|
||||||
|
if (!type)
|
||||||
|
return 0; /* optional */
|
||||||
|
|
||||||
|
if (STREQ(type, "ccwgroup_member")) {
|
||||||
|
if (!(ccw_dev->group_dev = 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 |= VIR_NODE_DEV_CAP_FLAG_CCW_CCWGROUP_MEMBER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt,
|
virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt,
|
||||||
virNodeDeviceDef *def,
|
virNodeDeviceDef *def,
|
||||||
@ -1261,7 +1309,10 @@ virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt,
|
|||||||
{
|
{
|
||||||
VIR_XPATH_NODE_AUTORESTORE(ctxt)
|
VIR_XPATH_NODE_AUTORESTORE(ctxt)
|
||||||
g_autofree virCCWDeviceAddress *ccw_addr = NULL;
|
g_autofree virCCWDeviceAddress *ccw_addr = NULL;
|
||||||
|
g_autofree xmlNodePtr *nodes = NULL;
|
||||||
g_autofree char *state = NULL;
|
g_autofree char *state = NULL;
|
||||||
|
int n = 0;
|
||||||
|
size_t i = 0;
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
ctxt->node = node;
|
ctxt->node = node;
|
||||||
@ -1285,6 +1336,15 @@ virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt,
|
|||||||
|
|
||||||
ccw_dev->dev_addr = g_steal_pointer(&ccw_addr);
|
ccw_dev->dev_addr = g_steal_pointer(&ccw_addr);
|
||||||
|
|
||||||
|
/* capabilities are optional */
|
||||||
|
if ((n = virXPathNodeSet("./capability", ctxt, &nodes)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
if (virNodeDevCCWCapabilityParseXML(ctxt, nodes[i], def->name, ccw_dev) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2505,6 +2565,7 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt,
|
|||||||
ret = virNodeDevCapCCWGroupParseXML(ctxt, def, node,
|
ret = virNodeDevCapCCWGroupParseXML(ctxt, def, node,
|
||||||
&caps->data.ccwgroup_dev);
|
&caps->data.ccwgroup_dev);
|
||||||
break;
|
break;
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_MEMBER:
|
||||||
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
||||||
case VIR_NODE_DEV_CAP_FC_HOST:
|
case VIR_NODE_DEV_CAP_FC_HOST:
|
||||||
case VIR_NODE_DEV_CAP_VPORTS:
|
case VIR_NODE_DEV_CAP_VPORTS:
|
||||||
@ -2796,6 +2857,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDef *caps)
|
|||||||
break;
|
break;
|
||||||
case VIR_NODE_DEV_CAP_CCW_DEV:
|
case VIR_NODE_DEV_CAP_CCW_DEV:
|
||||||
g_free(data->ccw_dev.dev_addr);
|
g_free(data->ccw_dev.dev_addr);
|
||||||
|
g_free(data->ccw_dev.group_dev);
|
||||||
break;
|
break;
|
||||||
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
||||||
g_free(data->ccwgroup_dev.address);
|
g_free(data->ccwgroup_dev.address);
|
||||||
@ -2810,6 +2872,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDef *caps)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_MEMBER:
|
||||||
case VIR_NODE_DEV_CAP_DRM:
|
case VIR_NODE_DEV_CAP_DRM:
|
||||||
case VIR_NODE_DEV_CAP_FC_HOST:
|
case VIR_NODE_DEV_CAP_FC_HOST:
|
||||||
case VIR_NODE_DEV_CAP_VPORTS:
|
case VIR_NODE_DEV_CAP_VPORTS:
|
||||||
@ -2869,6 +2932,12 @@ virNodeDeviceUpdateCaps(virNodeDeviceDef *def)
|
|||||||
&cap->data.mdev_parent) < 0)
|
&cap->data.mdev_parent) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
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:
|
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
||||||
if (virNodeDeviceGetCCWGroupDynamicCaps(def->sysfs_path,
|
if (virNodeDeviceGetCCWGroupDynamicCaps(def->sysfs_path,
|
||||||
&cap->data.ccwgroup_dev) < 0)
|
&cap->data.ccwgroup_dev) < 0)
|
||||||
@ -2888,7 +2957,6 @@ virNodeDeviceUpdateCaps(virNodeDeviceDef *def)
|
|||||||
case VIR_NODE_DEV_CAP_VPORTS:
|
case VIR_NODE_DEV_CAP_VPORTS:
|
||||||
case VIR_NODE_DEV_CAP_SCSI_GENERIC:
|
case VIR_NODE_DEV_CAP_SCSI_GENERIC:
|
||||||
case VIR_NODE_DEV_CAP_MDEV:
|
case VIR_NODE_DEV_CAP_MDEV:
|
||||||
case VIR_NODE_DEV_CAP_CCW_DEV:
|
|
||||||
case VIR_NODE_DEV_CAP_VDPA:
|
case VIR_NODE_DEV_CAP_VDPA:
|
||||||
case VIR_NODE_DEV_CAP_AP_CARD:
|
case VIR_NODE_DEV_CAP_AP_CARD:
|
||||||
case VIR_NODE_DEV_CAP_AP_QUEUE:
|
case VIR_NODE_DEV_CAP_AP_QUEUE:
|
||||||
@ -2987,6 +3055,15 @@ virNodeDeviceCapsListExport(virNodeDeviceDef *def,
|
|||||||
ncaps++;
|
ncaps++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (caps->data.type == VIR_NODE_DEV_CAP_CCW_DEV) {
|
||||||
|
flags = 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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef MAYBE_ADD_CAP
|
#undef MAYBE_ADD_CAP
|
||||||
@ -3336,6 +3413,25 @@ virNodeDeviceGetCSSDynamicCaps(const char *sysfsPath,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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 &= ~VIR_NODE_DEV_CAP_FLAG_CCW_CCWGROUP_MEMBER;
|
||||||
|
|
||||||
|
if ((ccw_dev->group_dev = virCCWDeviceGetGroupDev(sysfsPath)))
|
||||||
|
ccw_dev->flags |= VIR_NODE_DEV_CAP_FLAG_CCW_CCWGROUP_MEMBER;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* virNodeDeviceGetAPMatrixDynamicCaps() get info that is stored in sysfs
|
/* virNodeDeviceGetAPMatrixDynamicCaps() get info that is stored in sysfs
|
||||||
* about devices related to this device, i.e. things that can change
|
* about devices related to this device, i.e. things that can change
|
||||||
* without this device itself changing. These must be refreshed
|
* without this device itself changing. These must be refreshed
|
||||||
@ -3429,6 +3525,13 @@ virNodeDeviceGetCSSDynamicCaps(const char *sysfsPath G_GNUC_UNUSED,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virNodeDeviceGetCCWDynamicCaps(const char *sysfsPath G_GNUC_UNUSED,
|
||||||
|
virNodeDevCapCCW *ccw_dev G_GNUC_UNUSED)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
virNodeDeviceGetAPMatrixDynamicCaps(const char *sysfsPath G_GNUC_UNUSED,
|
virNodeDeviceGetAPMatrixDynamicCaps(const char *sysfsPath G_GNUC_UNUSED,
|
||||||
virNodeDevCapAPMatrix *ap_matrix G_GNUC_UNUSED)
|
virNodeDevCapAPMatrix *ap_matrix G_GNUC_UNUSED)
|
||||||
|
@ -72,6 +72,7 @@ typedef enum {
|
|||||||
VIR_NODE_DEV_CAP_AP_MATRIX, /* s390 AP Matrix device */
|
VIR_NODE_DEV_CAP_AP_MATRIX, /* s390 AP Matrix device */
|
||||||
VIR_NODE_DEV_CAP_VPD, /* Device provides VPD */
|
VIR_NODE_DEV_CAP_VPD, /* Device provides VPD */
|
||||||
VIR_NODE_DEV_CAP_CCWGROUP_DEV, /* s390 CCWGROUP device */
|
VIR_NODE_DEV_CAP_CCWGROUP_DEV, /* s390 CCWGROUP device */
|
||||||
|
VIR_NODE_DEV_CAP_CCWGROUP_MEMBER, /* s390 CCW device is member of CCWGROUP */
|
||||||
|
|
||||||
VIR_NODE_DEV_CAP_LAST
|
VIR_NODE_DEV_CAP_LAST
|
||||||
} virNodeDevCapType;
|
} virNodeDevCapType;
|
||||||
@ -118,6 +119,7 @@ typedef enum {
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
VIR_NODE_DEV_CAP_FLAG_CSS_MDEV = (1 << 0),
|
VIR_NODE_DEV_CAP_FLAG_CSS_MDEV = (1 << 0),
|
||||||
|
VIR_NODE_DEV_CAP_FLAG_CCW_CCWGROUP_MEMBER = (2 << 0),
|
||||||
} virNodeDevCCWCapFlags;
|
} virNodeDevCCWCapFlags;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -295,6 +297,7 @@ struct _virNodeDevCapCCW {
|
|||||||
size_t nmdev_types;
|
size_t nmdev_types;
|
||||||
virCCWDeviceAddress *channel_dev_addr;
|
virCCWDeviceAddress *channel_dev_addr;
|
||||||
virNodeDevCCWStateType state;
|
virNodeDevCCWStateType state;
|
||||||
|
char *group_dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _virNodeDevCapVDPA virNodeDevCapVDPA;
|
typedef struct _virNodeDevCapVDPA virNodeDevCapVDPA;
|
||||||
@ -457,7 +460,8 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNodeDevCapsDef, virNodeDevCapsDefFree);
|
|||||||
VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_QUEUE | \
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_QUEUE | \
|
||||||
VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_MATRIX | \
|
VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_MATRIX | \
|
||||||
VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPD | \
|
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)
|
||||||
|
|
||||||
#define VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_ACTIVE \
|
#define VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_ACTIVE \
|
||||||
VIR_CONNECT_LIST_NODE_DEVICES_ACTIVE | \
|
VIR_CONNECT_LIST_NODE_DEVICES_ACTIVE | \
|
||||||
@ -495,6 +499,10 @@ int
|
|||||||
virNodeDeviceGetMdevParentDynamicCaps(const char *sysfsPath,
|
virNodeDeviceGetMdevParentDynamicCaps(const char *sysfsPath,
|
||||||
virNodeDevCapMdevParent *mdev_parent);
|
virNodeDevCapMdevParent *mdev_parent);
|
||||||
|
|
||||||
|
int
|
||||||
|
virNodeDeviceGetCCWDynamicCaps(const char *sysfsPath,
|
||||||
|
virNodeDevCapCCW *ccw_dev);
|
||||||
|
|
||||||
int
|
int
|
||||||
virNodeDeviceGetCCWGroupDynamicCaps(const char *sysfsPath,
|
virNodeDeviceGetCCWGroupDynamicCaps(const char *sysfsPath,
|
||||||
virNodeDevCapCCWGroup *ccwgroup);
|
virNodeDevCapCCWGroup *ccwgroup);
|
||||||
|
@ -712,6 +712,17 @@
|
|||||||
</element>
|
</element>
|
||||||
</define>
|
</define>
|
||||||
|
|
||||||
|
<define name="capccwgroupmember">
|
||||||
|
<optional>
|
||||||
|
<element name="capability">
|
||||||
|
<attribute name="type">
|
||||||
|
<value>ccwgroup_member</value>
|
||||||
|
</attribute>
|
||||||
|
<element name="group_device"><text/></element>
|
||||||
|
</element>
|
||||||
|
</optional>
|
||||||
|
</define>
|
||||||
|
|
||||||
<define name="capccwdev">
|
<define name="capccwdev">
|
||||||
<attribute name="type">
|
<attribute name="type">
|
||||||
<value>ccw</value>
|
<value>ccw</value>
|
||||||
@ -725,6 +736,7 @@
|
|||||||
</element>
|
</element>
|
||||||
</optional>
|
</optional>
|
||||||
<ref name="capccwaddress"/>
|
<ref name="capccwaddress"/>
|
||||||
|
<ref name="capccwgroupmember"/>
|
||||||
</define>
|
</define>
|
||||||
|
|
||||||
<define name="capcssdev">
|
<define name="capcssdev">
|
||||||
|
@ -723,6 +723,12 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj,
|
|||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIR_NODE_DEV_CAP_CCW_DEV:
|
||||||
|
if (type == VIR_NODE_DEV_CAP_CCWGROUP_MEMBER &&
|
||||||
|
(cap->data.ccw_dev.flags & VIR_NODE_DEV_CAP_FLAG_CCW_CCWGROUP_MEMBER))
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
|
||||||
case VIR_NODE_DEV_CAP_SYSTEM:
|
case VIR_NODE_DEV_CAP_SYSTEM:
|
||||||
case VIR_NODE_DEV_CAP_USB_DEV:
|
case VIR_NODE_DEV_CAP_USB_DEV:
|
||||||
case VIR_NODE_DEV_CAP_USB_INTERFACE:
|
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_DRM:
|
||||||
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
case VIR_NODE_DEV_CAP_MDEV_TYPES:
|
||||||
case VIR_NODE_DEV_CAP_MDEV:
|
case VIR_NODE_DEV_CAP_MDEV:
|
||||||
case VIR_NODE_DEV_CAP_CCW_DEV:
|
|
||||||
case VIR_NODE_DEV_CAP_VDPA:
|
case VIR_NODE_DEV_CAP_VDPA:
|
||||||
case VIR_NODE_DEV_CAP_AP_CARD:
|
case VIR_NODE_DEV_CAP_AP_CARD:
|
||||||
case VIR_NODE_DEV_CAP_AP_QUEUE:
|
case VIR_NODE_DEV_CAP_AP_QUEUE:
|
||||||
case VIR_NODE_DEV_CAP_VPD:
|
case VIR_NODE_DEV_CAP_VPD:
|
||||||
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_MEMBER:
|
||||||
case VIR_NODE_DEV_CAP_LAST:
|
case VIR_NODE_DEV_CAP_LAST:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -901,7 +907,8 @@ virNodeDeviceObjMatch(virNodeDeviceObj *obj,
|
|||||||
MATCH_CAP(AP_QUEUE) ||
|
MATCH_CAP(AP_QUEUE) ||
|
||||||
MATCH_CAP(AP_MATRIX) ||
|
MATCH_CAP(AP_MATRIX) ||
|
||||||
MATCH_CAP(VPD) ||
|
MATCH_CAP(VPD) ||
|
||||||
MATCH_CAP(CCWGROUP_DEV)))
|
MATCH_CAP(CCWGROUP_DEV) ||
|
||||||
|
MATCH_CAP(CCWGROUP_MEMBER)))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -900,6 +900,7 @@ virNodeDeviceDefFree;
|
|||||||
virNodeDeviceDefParse;
|
virNodeDeviceDefParse;
|
||||||
virNodeDeviceDefParseXML;
|
virNodeDeviceDefParseXML;
|
||||||
virNodeDeviceGetAPMatrixDynamicCaps;
|
virNodeDeviceGetAPMatrixDynamicCaps;
|
||||||
|
virNodeDeviceGetCCWDynamicCaps;
|
||||||
virNodeDeviceGetCCWGroupDynamicCaps;
|
virNodeDeviceGetCCWGroupDynamicCaps;
|
||||||
virNodeDeviceGetCSSDynamicCaps;
|
virNodeDeviceGetCSSDynamicCaps;
|
||||||
virNodeDeviceGetMdevParentDynamicCaps;
|
virNodeDeviceGetMdevParentDynamicCaps;
|
||||||
@ -2032,6 +2033,7 @@ virCCWDeviceAddressFromString;
|
|||||||
virCCWDeviceAddressIncrement;
|
virCCWDeviceAddressIncrement;
|
||||||
virCCWDeviceAddressIsValid;
|
virCCWDeviceAddressIsValid;
|
||||||
virCCWDeviceAddressParseFromString;
|
virCCWDeviceAddressParseFromString;
|
||||||
|
virCCWDeviceGetGroupDev;
|
||||||
virCCWGroupDeviceGetMembers;
|
virCCWGroupDeviceGetMembers;
|
||||||
virCCWGroupMemberTypeFree;
|
virCCWGroupMemberTypeFree;
|
||||||
virCCWGroupTypeQethFree;
|
virCCWGroupTypeQethFree;
|
||||||
|
@ -717,6 +717,7 @@ nodeDeviceObjFormatAddress(virNodeDeviceObj *obj)
|
|||||||
case VIR_NODE_DEV_CAP_AP_CARD:
|
case VIR_NODE_DEV_CAP_AP_CARD:
|
||||||
case VIR_NODE_DEV_CAP_AP_QUEUE:
|
case VIR_NODE_DEV_CAP_AP_QUEUE:
|
||||||
case VIR_NODE_DEV_CAP_VPD:
|
case VIR_NODE_DEV_CAP_VPD:
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_MEMBER:
|
||||||
case VIR_NODE_DEV_CAP_LAST:
|
case VIR_NODE_DEV_CAP_LAST:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2194,6 +2195,7 @@ int nodeDeviceDefValidate(virNodeDeviceDef *def,
|
|||||||
case VIR_NODE_DEV_CAP_AP_MATRIX:
|
case VIR_NODE_DEV_CAP_AP_MATRIX:
|
||||||
case VIR_NODE_DEV_CAP_VPD:
|
case VIR_NODE_DEV_CAP_VPD:
|
||||||
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_MEMBER:
|
||||||
case VIR_NODE_DEV_CAP_LAST:
|
case VIR_NODE_DEV_CAP_LAST:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1239,6 +1239,9 @@ udevProcessCCW(struct udev_device *device,
|
|||||||
|
|
||||||
udevGenerateDeviceName(device, def, NULL);
|
udevGenerateDeviceName(device, def, NULL);
|
||||||
|
|
||||||
|
if (virNodeDeviceGetCCWDynamicCaps(def->sysfs_path, &def->caps->data.ccw_dev) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1575,6 +1578,7 @@ udevGetDeviceDetails(virNodeDeviceDriverState *driver_state,
|
|||||||
return udevProcessMdevParent(device, def);
|
return udevProcessMdevParent(device, def);
|
||||||
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
||||||
return udevProcessCCWGroup(device, def);
|
return udevProcessCCWGroup(device, def);
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_MEMBER:
|
||||||
case VIR_NODE_DEV_CAP_VPD:
|
case VIR_NODE_DEV_CAP_VPD:
|
||||||
case VIR_NODE_DEV_CAP_SYSTEM:
|
case VIR_NODE_DEV_CAP_SYSTEM:
|
||||||
case VIR_NODE_DEV_CAP_FC_HOST:
|
case VIR_NODE_DEV_CAP_FC_HOST:
|
||||||
|
@ -203,3 +203,26 @@ virCCWGroupTypeQethFree(virCCWGroupTypeQeth *qeth)
|
|||||||
VIR_FREE(qeth->card_type);
|
VIR_FREE(qeth->card_type);
|
||||||
VIR_FREE(qeth->chpid);
|
VIR_FREE(qeth->chpid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
virCCWDeviceGetGroupDev(const char *sysfs_path)
|
||||||
|
{
|
||||||
|
g_autofree char *ccwgroup_path = NULL;
|
||||||
|
g_autofree char *group_dev_path = NULL;
|
||||||
|
|
||||||
|
group_dev_path = g_build_filename(sysfs_path, "group_device", NULL);
|
||||||
|
|
||||||
|
if (!virFileExists(group_dev_path))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (virFileIsLink(group_dev_path) != 1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (virFileResolveLink(group_dev_path, &ccwgroup_path) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!virFileExists(ccwgroup_path))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return virCCWGroupDeviceDevNodeName("ccwgroup", ccwgroup_path);
|
||||||
|
}
|
||||||
|
@ -71,4 +71,7 @@ int virCCWGroupDeviceGetMembers(const char *sysfs_path,
|
|||||||
|
|
||||||
void virCCWGroupTypeQethFree(virCCWGroupTypeQeth *qeth);
|
void virCCWGroupTypeQethFree(virCCWGroupTypeQeth *qeth);
|
||||||
|
|
||||||
|
char* virCCWDeviceGetGroupDev(const char *sysfs_path)
|
||||||
|
ATTRIBUTE_NONNULL(1);
|
||||||
|
|
||||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCCWGroupMemberType, virCCWGroupMemberTypeFree);
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCCWGroupMemberType, virCCWGroupMemberTypeFree);
|
||||||
|
13
tests/nodedevschemadata/ccw_0_0_ff02_ccwgroup.xml
Normal file
13
tests/nodedevschemadata/ccw_0_0_ff02_ccwgroup.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<device>
|
||||||
|
<name>ccw_0_0_ff02</name>
|
||||||
|
<path>/sys/devices/css0/0.0.0070/0.0.ff02</path>
|
||||||
|
<parent>css_0_0_0070</parent>
|
||||||
|
<capability type='ccw'>
|
||||||
|
<cssid>0x0</cssid>
|
||||||
|
<ssid>0x0</ssid>
|
||||||
|
<devno>0xff02</devno>
|
||||||
|
<capability type='ccwgroup_member'>
|
||||||
|
<group_device>ccwgroup_0_0_ff00</group_device>
|
||||||
|
</capability>
|
||||||
|
</capability>
|
||||||
|
</device>
|
1
tests/nodedevxml2xmlout/ccw_0_0_ff02_ccwgroup.xml
Symbolic link
1
tests/nodedevxml2xmlout/ccw_0_0_ff02_ccwgroup.xml
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../nodedevschemadata/ccw_0_0_ff02_ccwgroup.xml
|
@ -146,6 +146,7 @@ mymain(void)
|
|||||||
DO_TEST("mdev_3627463d_b7f0_4fea_b468_f1da537d301b");
|
DO_TEST("mdev_3627463d_b7f0_4fea_b468_f1da537d301b");
|
||||||
DO_TEST_INACTIVE("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_ffff");
|
||||||
|
DO_TEST("ccw_0_0_ff02_ccwgroup");
|
||||||
DO_TEST("ccwgroup_0_0_bd00");
|
DO_TEST("ccwgroup_0_0_bd00");
|
||||||
DO_TEST("css_0_0_ffff");
|
DO_TEST("css_0_0_ffff");
|
||||||
DO_TEST("css_0_0_ffff_channel_dev_addr");
|
DO_TEST("css_0_0_ffff_channel_dev_addr");
|
||||||
|
@ -504,6 +504,9 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED)
|
|||||||
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
case VIR_NODE_DEV_CAP_CCWGROUP_DEV:
|
||||||
flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCWGROUP_DEV;
|
flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCWGROUP_DEV;
|
||||||
break;
|
break;
|
||||||
|
case VIR_NODE_DEV_CAP_CCWGROUP_MEMBER:
|
||||||
|
flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCWGROUP_MEMBER;
|
||||||
|
break;
|
||||||
case VIR_NODE_DEV_CAP_LAST:
|
case VIR_NODE_DEV_CAP_LAST:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user