summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>2024-11-04 15:08:30 +0100
committerMariusz Tkaczyk <mtkaczyk@kernel.org>2024-12-16 10:11:31 +0100
commit42db5429cba52c7d86db965100873928e29c512b (patch)
treec009623d3d286b8a3596a8d5c554d77c604c8111
parentIncremental: Document workaround (diff)
downloadmdadm-42db5429cba52c7d86db965100873928e29c512b.tar.xz
mdadm-42db5429cba52c7d86db965100873928e29c512b.zip
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>
-rw-r--r--Manage.c4
-rw-r--r--mdadm.h19
-rw-r--r--monitor.c12
-rw-r--r--sysfs.c32
-rw-r--r--util.c3
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.
@@ -118,6 +135,21 @@ mdadm_status_t sysfs_write_descriptor(const int fd, const char *value, const ssi
}
/**
+ * 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.
* @buf: buf to fill, must be MD_NAME_MAX.
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;