[PATCH 4/4] nodedev: add ccw device state and remove fencing

Boris Fiuczynski posted 4 patches 4 months ago
[PATCH 4/4] nodedev: add ccw device state and remove fencing
Posted by Boris Fiuczynski 4 months ago
Instead of fencing offline ccw devices add the state to the ccw
capability.

Resolves: https://issues.redhat.com/browse/RHEL-39497
Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
---
 src/conf/node_device_conf.c        | 24 ++++++++++++++++++++++++
 src/conf/node_device_conf.h        | 11 +++++++++++
 src/conf/schemas/nodedev.rng       |  8 ++++++++
 src/node_device/node_device_udev.c | 27 ++++++++++++++++++++++++---
 4 files changed, 67 insertions(+), 3 deletions(-)

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, "<state>%s</state>\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..32a8a5884b 100644
--- a/src/conf/node_device_conf.h
+++ b/src/conf/node_device_conf.h
@@ -112,6 +112,16 @@ typedef enum {
     VIR_NODE_DEV_CAP_FLAG_CSS_MDEV                  = (1 << 0),
 } virNodeDevCCWCapFlags;
 
+typedef enum {
+    /* Keep in sync with VIR_ENUM_IMPL in node_device_conf.c */
+    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 +289,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 @@
     <attribute name="type">
       <value>ccw</value>
     </attribute>
+    <optional>
+      <element name="state">
+        <choice>
+          <value>online</value>
+          <value>offline</value>
+        </choice>
+      </element>
+    </optional>
     <ref name="capccwaddress"/>
   </define>
 
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index ad994ef0b2..9d11261b88 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1199,13 +1199,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)
-- 
2.45.0
Re: [PATCH 4/4] nodedev: add ccw device state and remove fencing
Posted by Michal Prívozník 3 months, 4 weeks ago
On 6/19/24 14:29, Boris Fiuczynski wrote:
> Instead of fencing offline ccw devices add the state to the ccw
> capability.
> 
> Resolves: https://issues.redhat.com/browse/RHEL-39497
> Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
> ---
>  src/conf/node_device_conf.c        | 24 ++++++++++++++++++++++++
>  src/conf/node_device_conf.h        | 11 +++++++++++
>  src/conf/schemas/nodedev.rng       |  8 ++++++++
>  src/node_device/node_device_udev.c | 27 ++++++++++++++++++++++++---
>  4 files changed, 67 insertions(+), 3 deletions(-)
> 
> 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, "<state>%s</state>\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..32a8a5884b 100644
> --- a/src/conf/node_device_conf.h
> +++ b/src/conf/node_device_conf.h
> @@ -112,6 +112,16 @@ typedef enum {
>      VIR_NODE_DEV_CAP_FLAG_CSS_MDEV                  = (1 << 0),
>  } virNodeDevCCWCapFlags;
>  
> +typedef enum {
> +    /* Keep in sync with VIR_ENUM_IMPL in node_device_conf.c */

This is not needed because our VIR_ENUM_* macros do a compile time
asserts to check if respective enums have the same number of members.
I know you copied this over from a pre-existing code but the comment
there is also unnecessary.

> +    VIR_NODE_DEV_CCW_STATE_OFFLINE = 0,
> +    VIR_NODE_DEV_CCW_STATE_ONLINE,
> +
> +    VIR_NODE_DEV_CCW_STATE_LAST
> +} virNodeDevCCWStateType;
> +
> +VIR_ENUM_DECL(virNodeDevCCWState);
> +

Michal