diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 416238bec1..08a89942ba 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -86,6 +86,12 @@ VIR_ENUM_IMPL(virNodeDevDRM, "render", ); +VIR_ENUM_IMPL(virNodeDevCCWState, + VIR_NODE_DEV_CCW_STATE_LAST, + "offline", + "online", +); + static int virNodeDevCapsDefParseString(const char *xpath, xmlXPathContextPtr ctxt, @@ -743,6 +749,10 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def, unsigned int flags) virNodeDeviceCapMdevDefFormat(&buf, data, inactive_state); break; case VIR_NODE_DEV_CAP_CCW_DEV: + if (data->ccw_dev.state != VIR_NODE_DEV_CCW_STATE_LAST) { + const char *state = virNodeDevCCWStateTypeToString(data->ccw_dev.state); + virBufferEscapeString(&buf, "%s\n", state); + } virNodeDeviceCapCCWDefFormat(&buf, data); break; case VIR_NODE_DEV_CAP_CSS_DEV: @@ -1189,9 +1199,23 @@ virNodeDevCapCCWParseXML(xmlXPathContextPtr ctxt, { VIR_XPATH_NODE_AUTORESTORE(ctxt) g_autofree virCCWDeviceAddress *ccw_addr = NULL; + g_autofree char *state = NULL; + int val; ctxt->node = node; + /* state is optional */ + ccw_dev->state = VIR_NODE_DEV_CCW_STATE_LAST; + + if ((state = virXPathString("string(./state[1])", ctxt))) { + if ((val = virNodeDevCCWStateTypeFromString(state)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown state '%1$s' for '%2$s'"), state, def->name); + return -1; + } + ccw_dev->state = val; + } + ccw_addr = g_new0(virCCWDeviceAddress, 1); if (virNodeDevCCWDeviceAddressParseXML(ctxt, node, def->name, ccw_addr) < 0) diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index 4b82636af7..25666a333e 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -112,6 +112,15 @@ typedef enum { VIR_NODE_DEV_CAP_FLAG_CSS_MDEV = (1 << 0), } virNodeDevCCWCapFlags; +typedef enum { + VIR_NODE_DEV_CCW_STATE_OFFLINE = 0, + VIR_NODE_DEV_CCW_STATE_ONLINE, + + VIR_NODE_DEV_CCW_STATE_LAST +} virNodeDevCCWStateType; + +VIR_ENUM_DECL(virNodeDevCCWState); + typedef enum { VIR_NODE_DEV_CAP_FLAG_AP_MATRIX_MDEV = (1 << 0), } virNodeDevAPMatrixCapFlags; @@ -279,6 +288,7 @@ struct _virNodeDevCapCCW { virMediatedDeviceType **mdev_types; size_t nmdev_types; virCCWDeviceAddress *channel_dev_addr; + virNodeDevCCWStateType state; }; typedef struct _virNodeDevCapVDPA virNodeDevCapVDPA; diff --git a/src/conf/schemas/nodedev.rng b/src/conf/schemas/nodedev.rng index ff07313968..42a0cdcfd9 100644 --- a/src/conf/schemas/nodedev.rng +++ b/src/conf/schemas/nodedev.rng @@ -673,6 +673,14 @@ ccw + + + + online + offline + + + diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 226bea4025..1d8486f623 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1201,13 +1201,34 @@ udevGetCCWAddress(const char *sysfs_path, static int -udevProcessCCW(struct udev_device *device, - virNodeDeviceDef *def) +udevCCWGetState(struct udev_device *device, + virNodeDevCapData *data) { int online = 0; + if (udevGetIntSysfsAttr(device, "online", &online, 0) < 0 || online < 0) + return -1; + + switch (online) { + case VIR_NODE_DEV_CCW_STATE_OFFLINE: + case VIR_NODE_DEV_CCW_STATE_ONLINE: + data->ccw_dev.state = online; + break; + default: + data->ccw_dev.state = VIR_NODE_DEV_CCW_STATE_LAST; + break; + } + + return 0; +} + + +static int +udevProcessCCW(struct udev_device *device, + virNodeDeviceDef *def) +{ /* process only online devices to keep the list sane */ - if (udevGetIntSysfsAttr(device, "online", &online, 0) < 0 || online != 1) + if (udevCCWGetState(device, &def->caps->data) < 0) return -1; if (udevGetCCWAddress(def->sysfs_path, &def->caps->data) < 0)