mdadm/0003-sysfs-functions-for-writing-md-memb-state.patch
Xiao Ni e778d07c4c Update to mdadm 4.4
Resolves: RHEL-86676, RHEL-72803, RHEL-88793, RHEL-88791

Signed-off-by: Xiao Ni <xni@redhat.com>
2025-04-30 06:54:31 -04:00

165 lines
4.9 KiB
Diff

From 42db5429cba52c7d86db965100873928e29c512b Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Mon, 4 Nov 2024 15:08:30 +0100
Subject: [PATCH 03/37] sysfs: functions for writing md/<memb>/state
Add dedicated enum to reflect possible values for mentioned file.
Not all values are mapped. Add map to present sysfs keywords.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Manage.c | 4 +---
mdadm.h | 19 +++++++++++++++++++
monitor.c | 12 ++++++------
sysfs.c | 32 ++++++++++++++++++++++++++++++++
util.c | 3 +--
5 files changed, 59 insertions(+), 11 deletions(-)
diff --git a/Manage.c b/Manage.c
index b14a9ab9..d618a2f0 100644
--- a/Manage.c
+++ b/Manage.c
@@ -1675,9 +1675,7 @@ int Manage_subdevs(char *devname, int fd,
}
case 'I':
if (is_fd_valid(sysfd)) {
- static const char val[] = "faulty";
-
- rv = sysfs_write_descriptor(sysfd, val, strlen(val), &err);
+ rv = sysfs_set_memb_state_fd(sysfd, MEMB_STATE_FAULTY, &err);
} else {
rv = ioctl(fd, SET_DISK_FAULTY, rdev);
if (rv)
diff --git a/mdadm.h b/mdadm.h
index ebb2ca18..218056c8 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -807,9 +807,28 @@ enum sysfs_read_flags {
#define SYSFS_MAX_BUF_SIZE 64
+/**
+ * Defines md/<disk>/state possible values.
+ * Note that remove can't be read-back from the file.
+ *
+ * This is not complete list.
+ */
+typedef enum memb_state {
+ MEMB_STATE_EXTERNAL_BBL,
+ MEMB_STATE_BLOCKED,
+ MEMB_STATE_SPARE,
+ MEMB_STATE_WRITE_MOSTLY,
+ MEMB_STATE_IN_SYNC,
+ MEMB_STATE_FAULTY,
+ MEMB_STATE_REMOVE,
+ MEMB_STATE_UNKNOWN
+} memb_state_t;
+char *map_memb_state(memb_state_t state);
+
extern mdadm_status_t sysfs_write_descriptor(const int fd, const char *value,
const ssize_t len, int *errno_p);
extern mdadm_status_t write_attr(const char *value, const int fd);
+extern mdadm_status_t sysfs_set_memb_state_fd(int fd, memb_state_t state, int *err);
extern void sysfs_get_container_devnm(struct mdinfo *mdi, char *buf);
extern int sysfs_open(char *devnm, char *devname, char *attr);
diff --git a/monitor.c b/monitor.c
index 3c54f8cb..b771707a 100644
--- a/monitor.c
+++ b/monitor.c
@@ -140,17 +140,17 @@ int read_dev_state(int fd)
cp = buf;
while (cp) {
- if (sysfs_attr_match(cp, "faulty"))
+ if (sysfs_attr_match(cp, map_memb_state(MEMB_STATE_FAULTY)))
rv |= DS_FAULTY;
- if (sysfs_attr_match(cp, "in_sync"))
+ if (sysfs_attr_match(cp, map_memb_state(MEMB_STATE_IN_SYNC)))
rv |= DS_INSYNC;
- if (sysfs_attr_match(cp, "write_mostly"))
+ if (sysfs_attr_match(cp, map_memb_state(MEMB_STATE_WRITE_MOSTLY)))
rv |= DS_WRITE_MOSTLY;
- if (sysfs_attr_match(cp, "spare"))
+ if (sysfs_attr_match(cp, map_memb_state(MEMB_STATE_SPARE)))
rv |= DS_SPARE;
- if (sysfs_attr_match(cp, "blocked"))
+ if (sysfs_attr_match(cp, map_memb_state(MEMB_STATE_BLOCKED)))
rv |= DS_BLOCKED;
- if (sysfs_attr_match(cp, "external_bbl"))
+ if (sysfs_attr_match(cp, map_memb_state(MEMB_STATE_EXTERNAL_BBL)))
rv |= DS_EXTERNAL_BB;
cp = strchr(cp, ',');
if (cp)
diff --git a/sysfs.c b/sysfs.c
index a3bcb432..60b27459 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -75,6 +75,23 @@ void sysfs_free(struct mdinfo *sra)
sra = sra2;
}
}
+
+mapping_t sysfs_memb_states[] = {
+ {"external_bbl", MEMB_STATE_EXTERNAL_BBL},
+ {"blocked", MEMB_STATE_BLOCKED},
+ {"spare", MEMB_STATE_SPARE},
+ {"write_mostly", MEMB_STATE_WRITE_MOSTLY},
+ {"in_sync", MEMB_STATE_IN_SYNC},
+ {"faulty", MEMB_STATE_FAULTY},
+ {"remove", MEMB_STATE_REMOVE},
+ {NULL, MEMB_STATE_UNKNOWN}
+};
+
+char *map_memb_state(memb_state_t state)
+{
+ return map_num_s(sysfs_memb_states, state);
+}
+
/**
* write_attr() - write value to fd, don't check errno.
* @attr: value to write.
@@ -117,6 +134,21 @@ mdadm_status_t sysfs_write_descriptor(const int fd, const char *value, const ssi
return MDADM_STATUS_SUCCESS;
}
+/**
+ * sysfs_set_memb_state_fd() - write to md/<memb>/state file.
+ * @fd: open file descriptor to the file.
+ * @state: enum value describing value to write
+ * @err: errno value pointer in case of error.
+ *
+ * This is helper to avoid inlining values, they are extracted from map now.
+ */
+mdadm_status_t sysfs_set_memb_state_fd(int fd, memb_state_t state, int *err)
+{
+ const char *val = map_memb_state(state);
+
+ return sysfs_write_descriptor(fd, val, strlen(val), err);
+}
+
/**
* sysfs_get_container_devnm() - extract container device name.
* @mdi: md_info describes member array, with GET_VERSION option.
diff --git a/util.c b/util.c
index a120c985..6aa44a80 100644
--- a/util.c
+++ b/util.c
@@ -1808,12 +1808,11 @@ int hot_remove_disk(int mdfd, unsigned long dev, int force)
int sys_hot_remove_disk(int statefd, int force)
{
- static const char val[] = "remove";
int cnt = force ? 500 : 5;
while (cnt--) {
int err = 0;
- int ret = sysfs_write_descriptor(statefd, val, strlen(val), &err);
+ int ret = sysfs_set_memb_state_fd(statefd, MEMB_STATE_REMOVE, &err);
if (ret == MDADM_STATUS_SUCCESS)
return 0;
--
2.41.0