Compare commits

..

No commits in common. "c8" and "c10s" have entirely different histories.
c8 ... c10s

281 changed files with 10632 additions and 23916 deletions

7
.gitignore vendored
View File

@ -1 +1,6 @@
SOURCES/mdadm-4.2.tar.xz
.build*
clog
*.src.rpm
*/
/mdadm-4.*.tar.xz
/mdadm-4.4.tar.gz

View File

@ -1 +0,0 @@
27f240cff200e00c28a486a028bcdb14f67f8790 SOURCES/mdadm-4.2.tar.xz

View File

@ -0,0 +1,91 @@
From 8f54ce5b7eb0ca982803e270082e33f50897b9a6 Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Mon, 4 Nov 2024 11:17:46 -0500
Subject: [PATCH 01/37] Coverity fixes resources leaks
Handle variable going out of scope leaks the handle.
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
---
Assemble.c | 3 ++-
Incremental.c | 2 +-
bitmap.c | 7 +++++--
3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index 37a530ee..f8099cd3 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -753,6 +753,7 @@ static int load_devices(struct devs *devices, char *devmap,
tst->ss->free_super(tst);
free(tst);
*stp = st;
+ free(best);
return -1;
}
close(dfd);
@@ -834,7 +835,6 @@ static int load_devices(struct devs *devices, char *devmap,
inargv ? "the list" :
"the\n DEVICE list in mdadm.conf"
);
- free(best);
*stp = st;
goto error;
}
@@ -857,6 +857,7 @@ error:
close(mdfd);
free(devices);
free(devmap);
+ free(best);
return -1;
}
diff --git a/Incremental.c b/Incremental.c
index aa5db3bf..9b455a12 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -282,7 +282,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
* clustering resource agents
*/
if (info.array.state & (1 << MD_SB_CLUSTERED))
- goto out;
+ goto out_unlock;
/* Couldn't find an existing array, maybe make a new one */
mdfd = create_mddev(match ? match->devname : NULL, name_to_use, trustworthy,
diff --git a/bitmap.c b/bitmap.c
index c62d18d4..3f8da63d 100644
--- a/bitmap.c
+++ b/bitmap.c
@@ -260,8 +260,11 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
return rv;
info = bitmap_fd_read(fd, brief);
- if (!info)
+ if (!info) {
+ close_fd(&fd);
+ free(info);
return rv;
+ }
sb = &info->sb;
if (sb->magic != BITMAP_MAGIC) {
pr_err("This is an md array. To view a bitmap you need to examine\n");
@@ -336,7 +339,6 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
printf(" Cluster name : %-64s\n", sb->cluster_name);
for (i = 0; i < (int)sb->nodes; i++) {
st = NULL;
- free(info);
fd = bitmap_file_open(filename, &st, i, fd);
if (fd < 0) {
printf(" Unable to open bitmap file on node: %i\n", i);
@@ -347,6 +349,7 @@ int ExamineBitmap(char *filename, int brief, struct supertype *st)
printf(" Unable to read bitmap on node: %i\n", i);
continue;
}
+ free(sb);
sb = &info->sb;
if (sb->magic != BITMAP_MAGIC)
pr_err("invalid bitmap magic 0x%x, the bitmap file appears to be corrupted\n", sb->magic);
--
2.41.0

View File

@ -0,0 +1,64 @@
From 7de5dc53bfbc3bae7d43fc81e51c7c56638004f6 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Mon, 4 Nov 2024 11:37:41 +0100
Subject: [PATCH 02/37] Incremental: Document workaround
Keep it documented in code.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Incremental.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/Incremental.c b/Incremental.c
index 9b455a12..60d6f8cb 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -1693,15 +1693,30 @@ int Incremental_remove(char *devname, char *id_path, int verbose)
mdfd = open_dev_excl(ent->devnm);
if (is_fd_valid(mdfd)) {
+ char *array_state_file = "array_state";
+
+ /**
+ * This is a workaround for the old issue.
+ * Incremental_remove() triggered from udev rule when disk is removed from OS
+ * tries to set array in auto-read-only mode. This can interrupt rebuild
+ * process which is started automatically, e.g. if array is mounted and
+ * spare disk is available (I/O errors limit might be achieved faster than disk is
+ * removed by mdadm). Prevent Incremental_remove() from setting array
+ * into "auto-read-only", by requiring exclusive open to succeed.
+ */
close_fd(&mdfd);
- if (sysfs_get_str(&mdi, NULL, "array_state",
- buf, sizeof(buf)) > 0) {
- if (strncmp(buf, "active", 6) == 0 ||
- strncmp(buf, "clean", 5) == 0)
- sysfs_set_str(&mdi, NULL,
- "array_state", "read-auto");
+
+ if (sysfs_get_str(&mdi, NULL, array_state_file, buf, sizeof(buf)) > 0) {
+ char *str_read_auto = map_num_s(sysfs_array_states, ARRAY_READ_AUTO);
+ char *str_active = map_num_s(sysfs_array_states, ARRAY_ACTIVE);
+ char *str_clean = map_num_s(sysfs_array_states, ARRAY_CLEAN);
+
+ if (strncmp(buf, str_active, strlen(str_active)) == 0 ||
+ strncmp(buf, str_clean, strlen(str_clean)) == 0)
+ sysfs_set_str(&mdi, NULL, array_state_file, str_read_auto);
}
}
+
mdfd = open_dev(ent->devnm);
if (mdfd < 0) {
if (verbose >= 0)
@@ -1711,6 +1726,7 @@ int Incremental_remove(char *devname, char *id_path, int verbose)
if (id_path) {
struct map_ent *map = NULL, *me;
+
me = map_by_devnm(&map, ent->devnm);
if (me)
policy_save_path(id_path, me);
--
2.41.0

View File

@ -0,0 +1,164 @@
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

View File

@ -0,0 +1,259 @@
From b9888145987e273a7613209721a68f75e060263e Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Tue, 5 Nov 2024 13:07:16 +0100
Subject: [PATCH 04/37] Incremental: Simplify remove logic
Incremental_remove() does not execute Manage_subdevs() now.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Incremental.c | 116 ++++++++++++++++++++++++++++++++------------------
Manage.c | 10 ++---
mdadm.h | 1 +
sysfs.c | 23 ++++++++++
4 files changed, 102 insertions(+), 48 deletions(-)
diff --git a/Incremental.c b/Incremental.c
index 60d6f8cb..228d2bdd 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -1610,22 +1610,6 @@ release:
return rv;
}
-static void remove_from_member_array(struct mdstat_ent *memb,
- struct mddev_dev *devlist, int verbose)
-{
- int subfd = open_dev(memb->devnm);
-
- if (subfd >= 0) {
- /*
- * Ignore the return value because it's necessary
- * to handle failure condition here.
- */
- Manage_subdevs(memb->devnm, subfd, devlist, verbose,
- 0, UOPT_UNDEFINED, 0);
- close(subfd);
- }
-}
-
/**
* is_devnode_path() - check if the devname passed might be devnode path.
* @devnode: the path to check.
@@ -1646,25 +1630,81 @@ static bool is_devnode_path(char *devnode)
return false;
}
+/**
+ * Incremental_remove_external() - Remove the device from external container.
+ * @device_devnm: block device to remove.
+ * @container_devnm: the parent container
+ * @mdstat: mdstat file content.
+ * @verbose: verbose flag.
+ *
+ * Fail member device in each subarray and remove member device from external container.
+ * The resposibility of removing member disks from external subararys belongs to mdmon.
+ */
+static mdadm_status_t Incremental_remove_external(char *device_devnm, char *container_devnm,
+ struct mdstat_ent *mdstat, int verbose)
+{
+ mdadm_status_t rv = MDADM_STATUS_SUCCESS;
+ struct mdstat_ent *memb;
+
+ for (memb = mdstat ; memb ; memb = memb->next) {
+ mdadm_status_t ret = MDADM_STATUS_SUCCESS;
+ int state_fd;
+
+ if (!is_container_member(memb, container_devnm))
+ continue;
+
+ /*
+ * Checking mdstat is pointles because it might be outdated, try open descriptor
+ * instead. If it fails, we are fine with that, device is already gone.
+ */
+ state_fd = sysfs_open_memb_attr(memb->devnm, device_devnm, "state", O_RDWR);
+ if (!is_fd_valid(state_fd))
+ continue;
+
+ ret = sysfs_set_memb_state_fd(state_fd, MEMB_STATE_FAULTY, NULL);
+ if (ret && verbose >= 0)
+ pr_err("Cannot fail member device %s in external subarray %s.\n",
+ device_devnm, memb->devnm);
+
+ close_fd(&state_fd);
+
+ /*
+ * Don't remove member device from container if it failed to remove it
+ * from any member array.
+ */
+ rv |= ret;
+ }
+
+ if (rv == MDADM_STATUS_SUCCESS)
+ rv = sysfs_set_memb_state(container_devnm, device_devnm, MEMB_STATE_REMOVE);
+
+ if (rv && verbose >= 0)
+ pr_err("Cannot remove member device %s from container %s.\n", device_devnm,
+ container_devnm);
+
+ return rv;
+}
+
/**
* Incremental_remove() - Remove the device from all raid arrays.
* @devname: the device we want to remove, it could be kernel device name or devnode.
* @id_path: optional, /dev/disk/by-path path to save for bare scenarios support.
* @verbose: verbose flag.
*
- * First, fail the device (if needed) and then remove the device from native raid array or external
- * container. If it is external container, the device is removed from each subarray first.
+ * First, fail the device (if needed) and then remove the device. This code is critical for system
+ * funtionality and that is why it is keept as simple as possible. We do not load devices using
+ * sysfs_read() because any unerelated failure may lead us to abort. We also do not call
+ * Manage_Subdevs().
*/
int Incremental_remove(char *devname, char *id_path, int verbose)
{
+ mdadm_status_t rv = MDADM_STATUS_SUCCESS;
char *devnm = basename(devname);
- struct mddev_dev devlist = {0};
char buf[SYSFS_MAX_BUF_SIZE];
struct mdstat_ent *mdstat;
struct mdstat_ent *ent;
struct mdinfo mdi;
- int rv = 1;
- int mdfd;
+ int mdfd = -1;
if (strcmp(devnm, devname) != 0)
if (!is_devnode_path(devname)) {
@@ -1733,32 +1773,24 @@ int Incremental_remove(char *devname, char *id_path, int verbose)
map_free(map);
}
- devlist.devname = devnm;
- devlist.disposition = 'I';
- /* for a container, we must fail each member array */
if (is_mdstat_ent_external(ent)) {
- struct mdstat_ent *memb;
- for (memb = mdstat ; memb ; memb = memb->next) {
- if (is_container_member(memb, ent->devnm))
- remove_from_member_array(memb,
- &devlist, verbose);
- }
- } else {
- /*
- * This 'I' incremental remove is a try-best effort,
- * the failure condition can be safely ignored
- * because of the following up 'r' remove.
- */
- Manage_subdevs(ent->devnm, mdfd, &devlist,
- verbose, 0, UOPT_UNDEFINED, 0);
+ rv = Incremental_remove_external(devnm, ent->devnm, mdstat, verbose);
+ goto out;
}
- devlist.disposition = 'r';
- rv = Manage_subdevs(ent->devnm, mdfd, &devlist,
- verbose, 0, UOPT_UNDEFINED, 0);
+ /* Native arrays are handled separatelly to provide more detailed error handling */
+ rv = sysfs_set_memb_state(ent->devnm, devnm, MEMB_STATE_FAULTY);
+ if (rv && verbose >= 0)
+ pr_err("Cannot fail member device %s in array %s.\n", devnm, ent->devnm);
+
+ if (rv == MDADM_STATUS_SUCCESS)
+ rv = sysfs_set_memb_state(ent->devnm, devnm, MEMB_STATE_REMOVE);
+
+ if (rv && verbose >= 0)
+ pr_err("Cannot remove member device %s from %s.\n", devnm, ent->devnm);
- close_fd(&mdfd);
out:
+ close_fd(&mdfd);
free_mdstat(mdstat);
return rv;
}
diff --git a/Manage.c b/Manage.c
index d618a2f0..034eb00c 100644
--- a/Manage.c
+++ b/Manage.c
@@ -1381,8 +1381,6 @@ bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const
* 'f' - set the device faulty SET_DISK_FAULTY
* device can be 'detached' in which case any device that
* is inaccessible will be marked faulty.
- * 'I' - remove device by using incremental fail
- * which is executed when device is removed surprisingly.
* 'R' - mark this device as wanting replacement.
* 'W' - this device is added if necessary and activated as
* a replacement for a previous 'R' device.
@@ -1544,9 +1542,9 @@ int Manage_subdevs(char *devname, int fd,
/* This is a kernel-internal name like 'sda1' */
- if (!strchr("rfI", dv->disposition)) {
- pr_err("%s only meaningful with -r, -f or -I, not -%c\n",
- dv->devname, dv->disposition);
+ if (!strchr("rf", dv->disposition)) {
+ pr_err("%s only meaningful with -r, -f, not -%c\n", dv->devname,
+ dv->disposition);
goto abort;
}
@@ -1673,7 +1671,7 @@ int Manage_subdevs(char *devname, int fd,
close_fd(&sysfd);
goto abort;
}
- case 'I':
+
if (is_fd_valid(sysfd)) {
rv = sysfs_set_memb_state_fd(sysfd, MEMB_STATE_FAULTY, &err);
} else {
diff --git a/mdadm.h b/mdadm.h
index 218056c8..77705b11 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -829,6 +829,7 @@ 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 mdadm_status_t sysfs_set_memb_state(char *array_devnm, char *memb_devnm, memb_state_t state);
extern void sysfs_get_container_devnm(struct mdinfo *mdi, char *buf);
extern int sysfs_open(char *devnm, char *devname, char *attr);
diff --git a/sysfs.c b/sysfs.c
index 60b27459..c030d634 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -149,6 +149,29 @@ mdadm_status_t sysfs_set_memb_state_fd(int fd, memb_state_t state, int *err)
return sysfs_write_descriptor(fd, val, strlen(val), err);
}
+/**
+ * sysfs_set_memb_state() - write to member disk state file.
+ * @array_devnm: kernel name of the array.
+ * @memb_devnm: kernel name of member device.
+ * @state: value to write.
+ *
+ * Function expects that the device exists, error is unconditionally printed.
+ */
+mdadm_status_t sysfs_set_memb_state(char *array_devnm, char *memb_devnm, memb_state_t state)
+{
+ int state_fd = sysfs_open_memb_attr(array_devnm, memb_devnm, "state", O_RDWR);
+
+ if (!is_fd_valid(state_fd)) {
+ pr_err("Cannot open file descriptor to %s in array %s, aborting.\n",
+ memb_devnm, array_devnm);
+ return MDADM_STATUS_ERROR;
+ }
+
+ return sysfs_set_memb_state_fd(state_fd, state, NULL);
+
+ close_fd(&state_fd);
+}
+
/**
* sysfs_get_container_devnm() - extract container device name.
* @mdi: md_info describes member array, with GET_VERSION option.
--
2.41.0

View File

@ -0,0 +1,24 @@
From 143d94f684b738d1aa89024b182ad4cfa1b9018b Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Tue, 12 Nov 2024 14:05:11 +0100
Subject: [PATCH 05/37] checkpatch.conf: ignore NEW_TYPEDEFS
In mdadm, we have more flexible apporach to typedefs.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
.github/tools/.checkpatch.conf | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/tools/.checkpatch.conf b/.github/tools/.checkpatch.conf
index d6e3bc44..03114847 100644
--- a/.github/tools/.checkpatch.conf
+++ b/.github/tools/.checkpatch.conf
@@ -8,3 +8,4 @@
--exclude tests
--ignore FILE_PATH_CHANGES
--ignore EMAIL_SUBJECT
+--ignore NEW_TYPEDEFS
--
2.41.0

View File

@ -0,0 +1,55 @@
From 7f57f9b79dada30cdc64de1d2fe7541093c5b4e3 Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Thu, 9 Jan 2025 15:09:51 -0500
Subject: [PATCH 06/37] mdadm: add MAINTAINERS file
Create a maintainers file to keep track of people
to contact when dealing with mdadm questions/issues.
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
---
MAINTAINERS | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
create mode 100644 MAINTAINERS
diff --git a/MAINTAINERS b/MAINTAINERS
new file mode 100644
index 00000000..0a1229fd
--- /dev/null
+++ b/MAINTAINERS
@@ -0,0 +1,32 @@
+
+# List of maintainers for mdadm
+
+
+Descriptions of section entries:
+
+M: Mail patches to: FullName <address@domain>
+L: Mailing list that is relevant to mdadm
+
+
+Alphabetical Order:
+
+M: Blazej Kucman <blazej.kucman@linux.intel.com>
+L: linux-raid@vger.kernel.org
+
+M: Mateusz Kusiak <mateusz.kusiak@intel.com>
+L: linux-raid@vger.kernel.org
+
+M: Mariusz Tkaczyk <mtkaczyk@kernel.org>
+L: linux-raid@vger.kernel.org
+
+M: Nigel Croxon <ncroxon@redhat.com>
+L: linux-raid@vger.kernel.org
+
+M: Song Liu <song@kernel.org>
+L: linux-raid@vger.kernel.org
+
+M: Xiao Ni <xni@redhat.com>
+L: linux-raid@vger.kernel.org
+
+M: Yu Kuai <yukuai@kernel.org>
+L: linux-raid@vger.kernel.org
--
2.41.0

View File

@ -0,0 +1,127 @@
From ef4b6a23189d804bfd8fa81f5038afe6ce825bde Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mtkaczyk@kernel.org>
Date: Tue, 7 Jan 2025 10:09:16 +0100
Subject: [PATCH 07/37] mdadm.man: Remove external bitmap
Remove external bitmap support from manual.
Signed-off-by: Mariusz Tkaczyk <mtkaczyk@kernel.org>
---
mdadm.8.in | 55 ++++++------------------------------------------------
1 file changed, 6 insertions(+), 49 deletions(-)
diff --git a/mdadm.8.in b/mdadm.8.in
index 2b6f3e50..83c0689f 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -740,27 +740,11 @@ parameter and are stored internally.
.B none
- create array with no bitmap or remove any present bitmap (grow mode).
-Setting bitmap for file is deprecated and should not be used. The file should not exist unless
-.B \-\-force
-is also given. The same file should be provided when assembling the array. The file name must
-contain at least one slash ('/'). Bitmap files are only known to work on ext2 and ext3. Storing
-bitmap files on other filesystems may result in serious problems.
-
-When creating an array on devices which are 100G or larger,
-.I mdadm
-automatically adds an internal bitmap as it will usually be
-beneficial. This can be suppressed with
-.B "\-\-bitmap=none"
-or by selecting a different consistency policy with
-.BR \-\-consistency\-policy .
-
.TP
.BR \-\-bitmap\-chunk=
Set the chunk size of the bitmap. Each bit corresponds to that many
Kilobytes of storage.
-When using a file-based bitmap, the default is to use the smallest
-size that is at least 4 and requires no more than 2^21 chunks.
-When using an
+
.B internal
bitmap, the chunk size defaults to 64Meg, or larger if necessary to
fit the bitmap into the available space.
@@ -1108,13 +1092,6 @@ are present. This is only needed with
and can be used if the physical connections to devices are
not as reliable as you would like.
-.TP
-.BR \-b ", " \-\-bitmap=
-Specify the bitmap file that was given when the array was created. If
-an array has an
-.B internal
-bitmap, there is no need to specify this when assembling the array.
-
.TP
.BR \-\-backup\-file=
If
@@ -1614,9 +1591,8 @@ applies to a whole array which is currently active.
.TP
.BR \-X ", " \-\-examine\-bitmap
-Report information about a bitmap file.
-The argument is either an external bitmap file or an array component
-in case of an internal bitmap. Note that running this on an array
+Report information about a bitmap.
+The argument is an array component. Note that running this on an array
device (e.g.
.BR /dev/md0 )
does not report the bitmap for that array.
@@ -1774,10 +1750,7 @@ Only meaningful with
this will scan the
.B map
file for arrays that are being incrementally assembled and will try to
-start any that are not already started. If any such array is listed
-in
-.B mdadm.conf
-as requiring an external bitmap, that bitmap will be attached first.
+start any that are not already started.
.TP
.BR \-\-fail ", " \-f
@@ -2151,15 +2124,7 @@ setting.
.\".B \-\-size
.\"is given, the apparent size of the smallest drive given is used.
-If the array type supports a write-intent bitmap, and if the devices
-in the array exceed 100G is size, an internal write-intent bitmap
-will automatically be added unless some other option is explicitly
-requested with the
-.B \-\-bitmap
-option or a different consistency policy is selected with the
-.B \-\-consistency\-policy
-option. In any case, space for a bitmap will be reserved so that one
-can be added later with
+Space for a bitmap will be reserved so that one can be added later with
.BR "\-\-grow \-\-bitmap=internal" .
If the metadata type supports it (currently only 1.x and IMSM metadata),
@@ -2735,11 +2700,6 @@ Also, the size of an array cannot be changed while it has an active
bitmap. If an array has a bitmap, it must be removed before the size
can be changed. Once the change is complete a new bitmap can be created.
-.PP
-Note:
-.B "--grow --size"
-is not yet supported for external file bitmap.
-
.SS RAID\-DEVICES CHANGES
A RAID1 array can work with any number of devices from 1 upwards
@@ -2834,10 +2794,7 @@ stored on the device being reshaped.
.SS BITMAP CHANGES
A write-intent bitmap can be added to, or removed from, an active
-array. Either internal bitmaps, or bitmaps stored in a separate file,
-can be added. Note that if you add a bitmap stored in a file which is
-in a filesystem that is on the RAID array being affected, the system
-will deadlock. The bitmap must be on a separate filesystem.
+array.
.SS CONSISTENCY POLICY CHANGES
--
2.41.0

View File

@ -0,0 +1,223 @@
From cbc1cd589496a4ae16eb226a7fbad71a7d3d842d Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Wed, 16 Oct 2024 10:48:08 +0000
Subject: [PATCH 08/37] Remove --freeze-reshape logic
This commit removes --freeze-reshape logic, it basicaly reverts
commit b76b30e0f950 ("Do not continue reshape during initrd phase").
--freeze-reshape was supposed to be used to restore critical sector in
incremental and assemble operations without starting a reshape process,
but it's meaning has been lost through the years and it is not
currently used.
A replacement for this logic will be added in incoming patches, so
reshapes won't be started in initrd phrase.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
---
Grow.c | 30 +++++++-----------------------
ReadMe.c | 1 -
mdadm.8.in | 37 -------------------------------------
mdadm.c | 6 ------
mdadm.h | 2 --
5 files changed, 7 insertions(+), 69 deletions(-)
diff --git a/Grow.c b/Grow.c
index cc1be6cc..0d9e3b53 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1746,7 +1746,7 @@ static int reshape_array(char *container, int fd, char *devname,
int force, struct mddev_dev *devlist,
unsigned long long data_offset,
char *backup_file, int verbose, int forked,
- int restart, int freeze_reshape);
+ int restart);
static int reshape_container(char *container, char *devname,
int mdfd,
struct supertype *st,
@@ -2341,7 +2341,7 @@ size_change_error:
sync_metadata(st);
rv = reshape_array(container, fd, devname, st, &info, c->force,
devlist, s->data_offset, c->backup_file,
- c->verbose, 0, 0, 0);
+ c->verbose, 0, 0);
frozen = 0;
}
release:
@@ -3000,7 +3000,7 @@ static int reshape_array(char *container, int fd, char *devname,
int force, struct mddev_dev *devlist,
unsigned long long data_offset,
char *backup_file, int verbose, int forked,
- int restart, int freeze_reshape)
+ int restart)
{
struct reshape reshape;
int spares_needed;
@@ -3484,14 +3484,6 @@ started:
}
if (restart)
sysfs_set_str(sra, NULL, "array_state", "active");
- if (freeze_reshape) {
- free(fdlist);
- free(offsets);
- sysfs_free(sra);
- pr_err("Reshape has to be continued from location %llu when root filesystem has been mounted.\n",
- sra->reshape_progress);
- return 1;
- }
if (!forked)
if (continue_via_systemd(container ?: sra->sys_name,
@@ -3688,7 +3680,7 @@ int reshape_container(char *container, char *devname,
*/
ping_monitor(container);
- if (!forked && !c->freeze_reshape)
+ if (!forked)
if (continue_via_systemd(container, GROW_SERVICE, NULL))
return 0;
@@ -3698,8 +3690,7 @@ int reshape_container(char *container, char *devname,
unfreeze(st);
return 1;
default: /* parent */
- if (!c->freeze_reshape)
- printf("%s: multi-array reshape continues in background\n", Name);
+ printf("%s: multi-array reshape continues in background\n", Name);
return 0;
case 0: /* child */
manage_fork_fds(0);
@@ -3797,15 +3788,9 @@ int reshape_container(char *container, char *devname,
rv = reshape_array(container, fd, adev, st,
content, c->force, NULL, INVALID_SECTORS,
- c->backup_file, c->verbose, 1, restart,
- c->freeze_reshape);
+ c->backup_file, c->verbose, 1, restart);
close(fd);
- if (c->freeze_reshape) {
- sysfs_free(cc);
- exit(0);
- }
-
restart = 0;
if (rv)
break;
@@ -5220,8 +5205,7 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
} else
ret_val = reshape_array(NULL, mdfd, "array", st, info, 1,
NULL, INVALID_SECTORS, c->backup_file,
- 0, forked, 1 | info->reshape_active,
- c->freeze_reshape);
+ 0, forked, 1 | info->reshape_active);
return ret_val;
}
diff --git a/ReadMe.c b/ReadMe.c
index 9c29723f..c2415c26 100644
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -158,7 +158,6 @@ struct option long_options[] = {
{"scan", 0, 0, 's'},
{"force", 0, 0, Force},
{"update", 1, 0, 'U'},
- {"freeze-reshape", 0, 0, FreezeReshape},
/* Management */
{"add", 0, 0, Add},
diff --git a/mdadm.8.in b/mdadm.8.in
index 83c0689f..45255521 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -880,31 +880,6 @@ different versions of
.I mdadm
are used to add different devices).
-.TP
-.BR \-\-continue
-This option is complementary to the
-.B \-\-freeze-reshape
-option for assembly. It is needed when
-.B \-\-grow
-operation is interrupted and it is not restarted automatically due to
-.B \-\-freeze-reshape
-usage during array assembly. This option is used together with
-.BR \-G
-, (
-.BR \-\-grow
-) command and device for a pending reshape to be continued.
-All parameters required for reshape continuation will be read from array metadata.
-If initial
-.BR \-\-grow
-command had required
-.BR \-\-backup\-file=
-option to be set, continuation option will require to have exactly the same
-backup file given as well.
-.IP
-Any other parameter passed together with
-.BR \-\-continue
-option will be ignored.
-
.TP
.BR \-N ", " \-\-name=
Set a
@@ -1302,18 +1277,6 @@ or
and allows the array to be again used on a kernel prior to Linux 5.3.
This option should be used with great caution.
-.TP
-.BR \-\-freeze\-reshape
-This option is intended to be used in start-up scripts during the initrd boot phase.
-When the array under reshape is assembled during the initrd phase, this option
-stops the reshape after the reshape-critical section has been restored. This happens
-before the file system pivot operation and avoids loss of filesystem context.
-Losing file system context would cause reshape to be broken.
-
-Reshape can be continued later using the
-.B \-\-continue
-option for the grow command.
-
.SH For Manage mode:
.TP
diff --git a/mdadm.c b/mdadm.c
index 7d3b656b..a72058b4 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -710,12 +710,6 @@ int main(int argc, char *argv[])
case O(MANAGE,Force): /* add device which is too large */
c.force = 1;
continue;
- /* now for the Assemble options */
- case O(ASSEMBLE, FreezeReshape): /* Freeze reshape during
- * initrd phase */
- case O(INCREMENTAL, FreezeReshape):
- c.freeze_reshape = 1;
- continue;
case O(CREATE,'u'): /* uuid of array */
case O(ASSEMBLE,'u'): /* uuid of array */
if (ident.uuid_set) {
diff --git a/mdadm.h b/mdadm.h
index 77705b11..6062e167 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -530,7 +530,6 @@ enum special_options {
RebuildMapOpt,
InvalidBackup,
UdevRules,
- FreezeReshape,
Continue,
OffRootOpt,
Prefer,
@@ -680,7 +679,6 @@ struct context {
int scan;
int SparcAdjust;
int delay;
- int freeze_reshape;
char *backup_file;
int invalid_backup;
char *action;
--
2.41.0

View File

@ -0,0 +1,33 @@
From 25267bcc1eb403b2d837069289990afdc097031f Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Wed, 9 Oct 2024 11:24:13 +0000
Subject: [PATCH 09/37] Detail: Export reshape status
Display if there's an ongoing reshape happening in mdadm --detail
--export output.
This change is needed for incoming patches that will change "grow
continue" udev rules, to be based on actual array state.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
---
Detail.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Detail.c b/Detail.c
index 5819ced9..b804a624 100644
--- a/Detail.c
+++ b/Detail.c
@@ -290,6 +290,9 @@ int Detail(char *dev, struct context *c)
map_free(map);
if (st && st->sb) {
+ if (info)
+ printf("MD_RESHAPE_ACTIVE=%s\n",
+ info->reshape_active ? "True" : "False");
if (st->ss->export_detail_super)
st->ss->export_detail_super(st);
}
--
2.41.0

View File

@ -0,0 +1,217 @@
From 8a0d3fea424c1c19c51993c0849ea76ea41e8003 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Thu, 10 Oct 2024 10:31:06 +0000
Subject: [PATCH 10/37] mdadm: Do not start reshape before switchroot
There are numerous issues for --grow --continue in switchroot phrase,
they include:
* Events being missed for restarting grow-continue service. This is
apparent mostly on OS on RAID scenarios. When a checkpoint (next step)
is committed, we have no reliable way to gracefully stop reshape until
it reaches that checkpoint. During boot, there's heavy I/O utilisation,
which causes sync speed drop, and naturally checkpoint takes longer to
reach. This further causes systemd to forcefully kill grow-continue
service due to timeouts, which results in udev event being missed for
grow-continue service restart.
* Grow-continue (seemingly) was not designed to be restarted without
reassembly, some things like stopping chunksize (to lower) migration
were straight up not working until recently.
This patch makes grow-continue (actual reshape) start after switchroot
phrase. This way we should not encounter issues related to restarting
the service.
Add checks not start a reshape if in initrd, let it initialise only.
Change grow-continue udev rule to be triggered whenever there's a
reshape happening in metadata, rely on udev event to kick reshape after
switchroot. Add handle_forking helper function for reshapes to avoid
duplicating code.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
---
Grow.c | 81 +++++++++++++++++++++++++++------------
mdadm_status.h | 3 +-
udev-md-raid-arrays.rules | 3 +-
util.c | 1 +
4 files changed, 61 insertions(+), 27 deletions(-)
diff --git a/Grow.c b/Grow.c
index 0d9e3b53..2719346c 100644
--- a/Grow.c
+++ b/Grow.c
@@ -2995,6 +2995,34 @@ static void catch_term(int sig)
sigterm = 1;
}
+
+/**
+ * handle_forking() - Handle reshape forking.
+ *
+ * @forked: if already forked.
+ * @devname: device name.
+ * Returns: -1 if fork() failed,
+ * 0 if child process,
+ * 1 if job delegated to forked process or systemd.
+ *
+ * This function is a helper function for reshapes for fork handling.
+ */
+static mdadm_status_t handle_forking(bool forked, char *devname)
+{
+ if (forked)
+ return MDADM_STATUS_FORKED;
+
+ if (devname && continue_via_systemd(devname, GROW_SERVICE, NULL))
+ return MDADM_STATUS_SUCCESS;
+
+ switch (fork()) {
+ case -1: return MDADM_STATUS_ERROR; /* error */
+ case 0: return MDADM_STATUS_FORKED; /* child */
+ default: return MDADM_STATUS_SUCCESS; /* parent */
+ }
+
+}
+
static int reshape_array(char *container, int fd, char *devname,
struct supertype *st, struct mdinfo *info,
int force, struct mddev_dev *devlist,
@@ -3485,33 +3513,35 @@ started:
if (restart)
sysfs_set_str(sra, NULL, "array_state", "active");
- if (!forked)
- if (continue_via_systemd(container ?: sra->sys_name,
- GROW_SERVICE, NULL)) {
- free(fdlist);
- free(offsets);
- sysfs_free(sra);
- return 0;
- }
+ /* Do not run in initrd */
+ if (in_initrd()) {
+ free(fdlist);
+ free(offsets);
+ sysfs_free(sra);
+ pr_info("Reshape has to be continued from location %llu when root filesystem has been mounted.\n",
+ sra->reshape_progress);
+ return 1;
+ }
/* Now we just need to kick off the reshape and watch, while
* handling backups of the data...
* This is all done by a forked background process.
*/
- switch(forked ? 0 : fork()) {
- case -1:
+ switch (handle_forking(forked, container ? container : sra->sys_name)) {
+ default: /* Unused, only to satisfy compiler. */
+ case MDADM_STATUS_ERROR: /* error */
pr_err("Cannot run child to monitor reshape: %s\n",
strerror(errno));
abort_reshape(sra);
goto release;
- default:
+ case MDADM_STATUS_FORKED: /* child */
+ map_fork();
+ break;
+ case MDADM_STATUS_SUCCESS: /* parent */
free(fdlist);
free(offsets);
sysfs_free(sra);
return 0;
- case 0:
- map_fork();
- break;
}
/* Close unused file descriptor in the forked process */
@@ -3680,22 +3710,19 @@ int reshape_container(char *container, char *devname,
*/
ping_monitor(container);
- if (!forked)
- if (continue_via_systemd(container, GROW_SERVICE, NULL))
- return 0;
-
- switch (forked ? 0 : fork()) {
- case -1: /* error */
+ switch (handle_forking(forked, container)) {
+ default: /* Unused, only to satisfy compiler. */
+ case MDADM_STATUS_ERROR: /* error */
perror("Cannot fork to complete reshape\n");
unfreeze(st);
return 1;
- default: /* parent */
- printf("%s: multi-array reshape continues in background\n", Name);
- return 0;
- case 0: /* child */
+ case MDADM_STATUS_FORKED: /* child */
manage_fork_fds(0);
map_fork();
break;
+ case MDADM_STATUS_SUCCESS: /* parent */
+ printf("%s: multi-array reshape continues in background\n", Name);
+ return 0;
}
/* close unused handle in child process
@@ -3791,6 +3818,12 @@ int reshape_container(char *container, char *devname,
c->backup_file, c->verbose, 1, restart);
close(fd);
+ /* Do not run reshape in initrd but let it initialize.*/
+ if (in_initrd()) {
+ sysfs_free(cc);
+ exit(0);
+ }
+
restart = 0;
if (rv)
break;
diff --git a/mdadm_status.h b/mdadm_status.h
index 905105e2..e244127c 100644
--- a/mdadm_status.h
+++ b/mdadm_status.h
@@ -7,7 +7,8 @@ typedef enum mdadm_status {
MDADM_STATUS_SUCCESS = 0,
MDADM_STATUS_ERROR,
MDADM_STATUS_UNDEF,
- MDADM_STATUS_MEM_FAIL
+ MDADM_STATUS_MEM_FAIL,
+ MDADM_STATUS_FORKED
} mdadm_status_t;
#endif
diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules
index 4e64b249..d8de6d00 100644
--- a/udev-md-raid-arrays.rules
+++ b/udev-md-raid-arrays.rules
@@ -15,7 +15,6 @@ ENV{DEVTYPE}=="partition", GOTO="md_ignore_state"
ATTR{md/metadata_version}=="external:[A-Za-z]*", ATTR{md/array_state}=="inactive", GOTO="md_ignore_state"
TEST!="md/array_state", ENV{SYSTEMD_READY}="0", GOTO="md_end"
ATTR{md/array_state}=="clear*|inactive", ENV{SYSTEMD_READY}="0", GOTO="md_end"
-ATTR{md/sync_action}=="reshape", ENV{RESHAPE_ACTIVE}="yes"
LABEL="md_ignore_state"
IMPORT{program}="BINDIR/mdadm --detail --no-devices --export $devnode"
@@ -40,6 +39,6 @@ ENV{MD_LEVEL}=="raid[1-9]*", ENV{SYSTEMD_WANTS}+="mdmonitor.service"
ENV{MD_LEVEL}=="raid[1-9]*", ENV{MD_CONTAINER}=="?*", PROGRAM="/usr/bin/readlink $env{MD_CONTAINER}", ENV{MD_MON_THIS}="%c"
ENV{MD_MON_THIS}=="?*", TEST=="/etc/initrd-release", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@initrd-%c.service"
ENV{MD_MON_THIS}=="?*", TEST!="/etc/initrd-release", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service"
-ENV{RESHAPE_ACTIVE}=="yes", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdadm-grow-continue@%c.service"
+ENV{MD_RESHAPE_ACTIVE}=="True", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdadm-grow-continue@%c.service"
LABEL="md_end"
diff --git a/util.c b/util.c
index 6aa44a80..8099852f 100644
--- a/util.c
+++ b/util.c
@@ -2307,6 +2307,7 @@ int continue_via_systemd(char *devnm, char *service_name, char *prefix)
int pid, status;
char pathbuf[1024];
+ dprintf("Start %s service\n", service_name);
/* Simply return that service cannot be started */
if (check_env("MDADM_NO_SYSTEMCTL"))
return 0;
--
2.41.0

View File

@ -0,0 +1,48 @@
From 70cba6ba8e83f2971d17ce6e36076d46191766d9 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Thu, 10 Oct 2024 12:45:11 +0000
Subject: [PATCH 11/37] Better error messages for broken reshape
mdadm --grow --continue has no functionality to restore critical sectors
if reshape was stopped during operation. This functionality belongs to
assemble or incremental.
This patch adds hints to error messages, to try to reassemble array in
case of reshape failure to restore critical sector, so assemble can
handle restoration.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
---
Grow.c | 1 +
super-intel.c | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/Grow.c b/Grow.c
index 2719346c..818eb6a4 100644
--- a/Grow.c
+++ b/Grow.c
@@ -2387,6 +2387,7 @@ static int verify_reshape_position(struct mdinfo *info, int level)
} else if (info->reshape_progress > position) {
pr_err("Fatal error: array reshape was not properly frozen (expected reshape position is %llu, but reshape progress is %llu.\n",
position, info->reshape_progress);
+ pr_err("Reassemble array to try to restore critical sector.\n");
ret_val = -1;
} else {
dprintf("Reshape position in md and metadata are the same;");
diff --git a/super-intel.c b/super-intel.c
index 7e3c5f2b..cab84198 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -12596,7 +12596,8 @@ static int imsm_manage_reshape(
init_migr_record_imsm(st, dev, sra);
else {
if (__le32_to_cpu(migr_rec->rec_status) != UNIT_SRC_NORMAL) {
- dprintf("imsm: cannot restart migration when data are present in copy area.\n");
+ pr_err("imsm: Cannot restart migration when data are present in copy area.\n"
+ " Reassemble array to try to restore critical sector.\n");
goto abort;
}
/* Save checkpoint to update migration record for current
--
2.41.0

View File

@ -0,0 +1,117 @@
From 82ccad68d46d4b10a928bc860c0feedf26e483e3 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Wed, 20 Nov 2024 19:01:30 +0000
Subject: [PATCH 12/37] Refactor continue_via_systemd()
Refactor continue_via_systemd() and it's calls to make it more readable.
No functional changes.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
---
Grow.c | 2 +-
mdadm.h | 2 +-
util.c | 43 ++++++++++++++++++++++++-------------------
3 files changed, 26 insertions(+), 21 deletions(-)
diff --git a/Grow.c b/Grow.c
index 818eb6a4..53b0b387 100644
--- a/Grow.c
+++ b/Grow.c
@@ -3013,7 +3013,7 @@ static mdadm_status_t handle_forking(bool forked, char *devname)
if (forked)
return MDADM_STATUS_FORKED;
- if (devname && continue_via_systemd(devname, GROW_SERVICE, NULL))
+ if (devname && continue_via_systemd(devname, GROW_SERVICE, NULL) == MDADM_STATUS_SUCCESS)
return MDADM_STATUS_SUCCESS;
switch (fork()) {
diff --git a/mdadm.h b/mdadm.h
index 6062e167..e84c341c 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1694,7 +1694,7 @@ extern int same_dev(char *one, char *two);
extern int compare_paths (char* path1,char* path2);
extern void enable_fds(int devices);
extern void manage_fork_fds(int close_all);
-extern int continue_via_systemd(char *devnm, char *service_name, char *prefix);
+extern mdadm_status_t continue_via_systemd(char *devnm, char *service_name, char *prefix);
extern void ident_init(struct mddev_ident *ident);
extern mdadm_status_t ident_set_devname(struct mddev_ident *ident, const char *devname);
diff --git a/util.c b/util.c
index 8099852f..8c45f0e1 100644
--- a/util.c
+++ b/util.c
@@ -1982,7 +1982,7 @@ int start_mdmon(char *devnm)
if (check_env("MDADM_NO_MDMON"))
return 0;
- if (continue_via_systemd(devnm, MDMON_SERVICE, prefix))
+ if (continue_via_systemd(devnm, MDMON_SERVICE, prefix) == MDADM_STATUS_SUCCESS)
return 0;
/* That failed, try running mdmon directly */
@@ -2299,36 +2299,41 @@ void manage_fork_fds(int close_all)
/* In a systemd/udev world, it is best to get systemd to
* run daemon rather than running in the background.
* Returns:
- * 1- if systemd service has been started
- * 0- otherwise
+ * MDADM_STATUS_SUCCESS - if systemd service has been started.
+ * MDADM_STATUS_ERROR - otherwise.
*/
-int continue_via_systemd(char *devnm, char *service_name, char *prefix)
+mdadm_status_t continue_via_systemd(char *devnm, char *service_name, char *prefix)
{
int pid, status;
- char pathbuf[1024];
+ char pathbuf[PATH_MAX];
dprintf("Start %s service\n", service_name);
/* Simply return that service cannot be started */
if (check_env("MDADM_NO_SYSTEMCTL"))
- return 0;
+ return MDADM_STATUS_SUCCESS;
+
+ /* Fork in attempt to start services */
switch (fork()) {
- case 0:
- manage_fork_fds(1);
- snprintf(pathbuf, sizeof(pathbuf),
- "%s@%s%s.service", service_name, prefix ?: "", devnm);
- status = execl("/usr/bin/systemctl", "systemctl", "restart",
- pathbuf, NULL);
- status = execl("/bin/systemctl", "systemctl", "restart",
- pathbuf, NULL);
- exit(1);
- case -1: /* Just do it ourselves. */
+ case -1: /* Fork failed, just do it ourselves. */
break;
- default: /* parent - good */
+ case 0: /* child */
+ manage_fork_fds(1);
+ snprintf(pathbuf, sizeof(pathbuf), "%s@%s%s.service",
+ service_name, prefix ? prefix : "", devnm);
+
+ /* Attempt to start service.
+ * On success execl() will "kill" the fork, and return status of systemctl call.
+ */
+ execl("/usr/bin/systemctl", "systemctl", "restart", pathbuf, NULL);
+ execl("/bin/systemctl", "systemctl", "restart", pathbuf, NULL);
+ exit(MDADM_STATUS_ERROR);
+ default: /* parent */
+ /* Check if forked process successfully trigered service */
pid = wait(&status);
if (pid >= 0 && status == 0)
- return 1;
+ return MDADM_STATUS_SUCCESS;
}
- return 0;
+ return MDADM_STATUS_ERROR;
}
int in_initrd(void)
--
2.41.0

View File

@ -0,0 +1,32 @@
From e0df6c4c984d564e9e40913727e916a6cd8f466e Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 17 Jan 2025 15:15:40 +0800
Subject: [PATCH 13/37] mdadm/raid6check: add xmalloc.h to raid6check.c
It reports building error:
raid6check.c:324:26: error: implicit declaration of function xmalloc
Add xmalloc.h to raid6check.c file to fix this.
Signed-off-by: Xiao Ni <xni@redhat.com>
Link: https://lore.kernel.org/r/20250117071540.4094-1-xni@redhat.com
Signed-off-by: Song Liu <song@kernel.org>
---
raid6check.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/raid6check.c b/raid6check.c
index 99477761..95533f7d 100644
--- a/raid6check.c
+++ b/raid6check.c
@@ -23,6 +23,7 @@
*/
#include "mdadm.h"
+#include "xmalloc.h"
#include <stdint.h>
#include <sys/mman.h>
--
2.41.0

View File

@ -0,0 +1,56 @@
From b1ee932b89a16c881a3336f9fd728d46c1f8c65d Mon Sep 17 00:00:00 2001
From: Coly Li <colyli@suse.de>
Date: Wed, 22 Jan 2025 23:18:59 +0800
Subject: [PATCH 14/37] mdopen: add sbin path to env PATH when call
system("modprobe md_mod")
During the boot process if mdadm is called in udev context, sbin paths
like /sbin, /usr/sbin, /usr/local/sbin normally not defined in PATH env
variable, calling system("modprobe md_mod") in create_named_array() may
fail with 'sh: modprobe: command not found' error message.
We don't want to move modprobe binary into udev private directory, so
setting the PATH env is a more proper method to avoid the above issue.
This patch sets PATH env variable with "/sbin:/usr/sbin:/usr/local/sbin"
before calling system("modprobe md_mod"). The change only takes effect
within the udev worker context, not seen by global udev environment.
Signed-off-by: Coly Li <colyli@suse.de>
Signed-off-by: Mariusz Tkaczyk <mtkaczyk@kernel.org>
---
mdopen.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/mdopen.c b/mdopen.c
index 26f0c716..57252b64 100644
--- a/mdopen.c
+++ b/mdopen.c
@@ -39,6 +39,24 @@ int create_named_array(char *devnm)
fd = open(new_array_file, O_WRONLY);
if (fd < 0 && errno == ENOENT) {
+ char buf[PATH_MAX] = {0};
+ char *env_ptr;
+
+ env_ptr = getenv("PATH");
+ /*
+ * When called by udev worker context, path of modprobe
+ * might not be in env PATH. Set sbin paths into PATH
+ * env to avoid potential failure when run modprobe here.
+ */
+ if (env_ptr)
+ snprintf(buf, PATH_MAX - 1, "%s:%s", env_ptr,
+ "/sbin:/usr/sbin:/usr/local/sbin");
+ else
+ snprintf(buf, PATH_MAX - 1, "%s",
+ "/sbin:/usr/sbin:/usr/local/sbin");
+
+ setenv("PATH", buf, 1);
+
if (system("modprobe md_mod") == 0)
fd = open(new_array_file, O_WRONLY);
}
--
2.41.0

View File

@ -0,0 +1,40 @@
From 21e4efb1cd15c4de4a57de26b0ea2e4234aa8ce5 Mon Sep 17 00:00:00 2001
From: Antonio Alvarez Feijoo <antonio.feijoo@suse.com>
Date: Thu, 23 Jan 2025 19:46:38 +0100
Subject: [PATCH 15/37] udev: persist properties of MD devices after
switch_root
dracut installs in the initrd a custom udev rule for MD devices
(59-persistent-storage-md.rules) only to set the db_persist option (see
[1]). The main purpose is that if an MD device is activated in the initrd,
its properties are kept on the udev database after the transition from the
initrd to the rootfs. This was added to fix detection issues when LVM is
on top.
This patch would allow to remove the custom udev rule shipped by dracut
(63-md-raid-arrays.rules is already being installed in the initrd), and it
will also benefit other initrd generators that do not want to create
custom udev rules.
[1] https://github.com/dracutdevs/dracut/blob/master/modules.d/90mdraid
Signed-off-by: Antonio Alvarez Feijoo <antonio.feijoo@suse.com>
---
udev-md-raid-arrays.rules | 1 +
1 file changed, 1 insertion(+)
diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules
index d8de6d00..a8098dc5 100644
--- a/udev-md-raid-arrays.rules
+++ b/udev-md-raid-arrays.rules
@@ -29,6 +29,7 @@ ENV{DEVTYPE}=="partition", ENV{MD_DEVNAME}=="*[0-9]", SYMLINK+="md/$env{MD_DEVNA
IMPORT{builtin}="blkid"
OPTIONS+="link_priority=100"
OPTIONS+="watch"
+OPTIONS+="db_persist"
ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}"
ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_PART_ENTRY_UUID}=="?*", SYMLINK+="disk/by-partuuid/$env{ID_PART_ENTRY_UUID}"
ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}"
--
2.41.0

View File

@ -0,0 +1,36 @@
From c09ae8417dc9e11da1d5bf2867c6498050c6ddb9 Mon Sep 17 00:00:00 2001
From: Yu Kuai <yukuai3@huawei.com>
Date: Fri, 27 Dec 2024 14:07:02 +0800
Subject: [PATCH 16/37] mdadm: fix --grow with --add for linear
For the case mdadm --grow with --add, the s.btype should not be
initialized yet, hence BitmapUnknown should be checked instead of
BitmapNone.
Noted that this behaviour should only support by md-linear, which is
removed from kernel, howerver, it turns out md-linear is used widely
in home NAS and we're planning to reintroduce it soon.
Fixes: 581ba1341017 ("mdadm: remove bitmap file support")
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Signed-off-by: Mariusz Tkaczyk <mtkaczyk@kernel.org>
---
mdadm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mdadm.c b/mdadm.c
index a72058b4..6200cd0e 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -1619,7 +1619,7 @@ int main(int argc, char *argv[])
if (devs_found > 1 && s.raiddisks == 0 && s.level == UnSet) {
/* must be '-a'. */
if (s.size > 0 || s.chunk ||
- s.layout_str || s.btype != BitmapNone) {
+ s.layout_str || s.btype != BitmapUnknown) {
pr_err("--add cannot be used with other geometry changes in --grow mode\n");
rv = 1;
break;
--
2.41.0

View File

@ -0,0 +1,41 @@
From 1fc0f290caeb0720aa6c97177ab429953f5bf10f Mon Sep 17 00:00:00 2001
From: Ross Lagerwall <ross.lagerwall@citrix.com>
Date: Wed, 29 Jan 2025 13:31:11 +0000
Subject: [PATCH 17/37] platform-intel: Disable legacy option ROM scan on UEFI
machines
The legacy option ROM memory range from 0xc0000-0xeffff is not defined
on UEFI machines so don't attempt to scan it. This avoids lockdown log
spam when Secure Boot is enabled (avoids use of /dev/mem).
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
---
platform-intel.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/platform-intel.c b/platform-intel.c
index 95bc4929..270aef36 100644
--- a/platform-intel.c
+++ b/platform-intel.c
@@ -607,6 +607,7 @@ const struct imsm_orom *imsm_platform_test(struct sys_dev *hba)
static const struct imsm_orom *find_imsm_hba_orom(struct sys_dev *hba)
{
+ struct stat st;
unsigned long align;
if (check_env("IMSM_TEST_OROM"))
@@ -616,6 +617,10 @@ static const struct imsm_orom *find_imsm_hba_orom(struct sys_dev *hba)
if (check_env("IMSM_TEST_AHCI_EFI") || check_env("IMSM_TEST_SCU_EFI"))
return NULL;
+ /* Skip legacy option ROM scan when EFI booted */
+ if (stat("/sys/firmware/efi", &st) == 0 && S_ISDIR(st.st_mode))
+ return NULL;
+
find_intel_devices();
if (intel_devices == NULL)
--
2.41.0

View File

@ -0,0 +1,61 @@
From 9e8b3b1492cff63dafb759382c74a479460f49e6 Mon Sep 17 00:00:00 2001
From: lilinzhe <llz@antiy.cn>
Date: Mon, 16 Dec 2024 12:00:02 +0800
Subject: [PATCH 18/37] super-ddf: Prevent crash when handling DDF metadata
A dummy function is defined because availability of ss->update_super is
not always verified.
This fix addresses a crash reported when assembling a RAID array using
mdadm with DDF metadata. For more details, see the discussion at:
https://lore.kernel.org/all/
CALHdMH30LuxR4tz9jP2ykDaDJtZ3P7L3LrZ+9e4Fq=Q6NwSM=Q@mail.gmail.com/
The discussion centers on an issue with mdadm where attempting to
assemble a RAID array caused a null pointer dereference. The problem
was traced to a missing update_super() function in super-ddf.c, which
led to a crash in Assemble.c.
Signed-off-by: lilinzhe <llz@antiy.cn>
---
super-ddf.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/super-ddf.c b/super-ddf.c
index 6cd099ab..a06ed435 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -5195,6 +5195,21 @@ static void default_geometry_ddf(struct supertype *st, int *level, int *layout,
*layout = ddf_level_to_layout(*level);
}
+static int update_super_ddf_dummy(struct supertype *st, struct mdinfo *info,
+ enum update_opt update,
+ char *devname, int verbose,
+ int uuid_set, char *homehost)
+{
+ /*
+ * A dummy update_super function is required to ensure
+ * reliable handling of DDF metadata in mdadm.
+ * This implementation acts as a placeholder for cases
+ * where ss->update_super is not verified.
+ */
+ dprintf("update_super is not implemented in DDF\n");
+ return 0;
+}
+
struct superswitch super_ddf = {
.examine_super = examine_super_ddf,
.brief_examine_super = brief_examine_super_ddf,
@@ -5213,6 +5228,8 @@ struct superswitch super_ddf = {
.uuid_from_super= uuid_from_super_ddf,
.getinfo_super = getinfo_super_ddf,
+ .update_super = update_super_ddf_dummy,
+
.avail_size = avail_size_ddf,
.compare_super = compare_super_ddf,
--
2.41.0

View File

@ -0,0 +1,297 @@
From f2197b6b6c14af6c788c628acd1fc6d92c268c53 Mon Sep 17 00:00:00 2001
From: lilinzhe <llz@antiy.cn>
Date: Mon, 16 Dec 2024 12:11:41 +0800
Subject: [PATCH 19/37] super-ddf: optimize DDF header search for widely used
RAID controllers
Implemented fallback logic to search the last 32MB of the device
for the DDF header (magic). If found, proceeds to load the DDF metadata
from the located position.
When clearing metadata as required by the mdadm --zero (function Kill),
also erase the last 32MB of data; otherwise, it may result in an
infinite loop.
According to the specification, the Anchor Header should be placed at
the end of the disk. However,some widely used RAID hardware, such as
LSI and PERC, do not position it within the last 512 bytes of the disk.
Signed-off-by: lilinzhe <llz@antiy.cn>
---
super-ddf.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++-----
xmalloc.c | 11 +++
xmalloc.h | 1 +
3 files changed, 185 insertions(+), 17 deletions(-)
diff --git a/super-ddf.c b/super-ddf.c
index a06ed435..6e7db924 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -272,6 +272,10 @@ struct phys_disk {
#define DDF_ReadErrors 32
#define DDF_Missing 64
+
+#define SEARCH_BLOCK_SIZE 4096
+#define SEARCH_REGION_SIZE (32 * 1024 * 1024)
+
/* The content of the virt_section global scope */
struct virtual_disk {
be32 magic; /* DDF_VIRT_RECORDS_MAGIC */
@@ -877,30 +881,180 @@ static void *load_section(int fd, struct ddf_super *super, void *buf,
return buf;
}
-static int load_ddf_headers(int fd, struct ddf_super *super, char *devname)
+
+/*
+ * Search for DDF_HEADER_MAGIC in the last 32MB of the device
+ *
+ * According to the specification, the Anchor Header should be placed at
+ * the end of the disk. However,some widely used RAID hardware, such as
+ * LSI and PERC, do not position it within the last 512 bytes of the disk.
+ *
+ */
+static int search_for_ddf_headers(int fd, char *devname,
+ unsigned long long *out)
{
+ unsigned long long search_start;
+ unsigned long long search_end;
+ size_t bytes_block_to_read;
unsigned long long dsize;
+ unsigned long long pos;
+ int bytes_current_read;
+ size_t offset;
+
+ void *buffer = NULL;
+ be32 *magic_ptr = NULL;
+
+ int result = 0;
get_dev_size(fd, NULL, &dsize);
- if (lseek64(fd, dsize - 512, 0) == -1L) {
- if (devname)
- pr_err("Cannot seek to anchor block on %s: %s\n",
+
+ /* Determine the search range */
+ if (dsize > SEARCH_REGION_SIZE)
+ search_start = dsize - SEARCH_REGION_SIZE;
+ else
+ search_start = 0;
+
+ search_end = dsize;
+ pos = search_start;
+
+
+ buffer = xmemalign(SEARCH_BLOCK_SIZE, SEARCH_BLOCK_SIZE);
+
+ if (buffer == NULL) {
+ result = 1;
+ goto cleanup;
+ }
+
+ while (pos < search_end) {
+ /* Calculate the number of bytes to read in the current block */
+ bytes_block_to_read = SEARCH_BLOCK_SIZE;
+ if (search_end - pos < SEARCH_BLOCK_SIZE)
+ bytes_block_to_read = search_end - pos;
+
+ if (lseek64(fd, pos, SEEK_SET) < 0) {
+ pr_err("lseek64 for %s failed %d:%s\n",
+ fd2devnm(fd), errno, strerror(errno));
+ result = 2;
+ goto cleanup;
+ }
+
+ /*Read data from the device */
+ bytes_current_read = read(fd, buffer, bytes_block_to_read);
+
+ if (bytes_current_read <= 0) {
+ pr_err("Failed to read %s. %d:%s, Position=%llu, Bytes to read=%zu. Skipping.\n",
+ fd2devnm(fd), errno, strerror(errno), pos, bytes_block_to_read);
+ pos += SEARCH_BLOCK_SIZE; /* Skip to the next block */
+ continue;
+ }
+
+ /* Search for the magic value within the read block */
+ for (offset = 0;
+ offset + sizeof(be32) <= (size_t)bytes_current_read;
+ offset += sizeof(be32)) {
+
+ magic_ptr = (be32 *) ((char *)buffer + offset);
+ if (be32_eq(*magic_ptr, DDF_HEADER_MAGIC)) {
+ *out = pos + offset;
+ result = 0;
+ goto cleanup;
+ }
+ }
+
+ pos += SEARCH_BLOCK_SIZE;
+ }
+
+cleanup:
+ free(buffer);
+ return result;
+}
+
+static int load_ddf_headers(int fd, struct ddf_super *super, char *devname)
+{
+ /*
+ * Load DDF headers from a device.
+ * First, check at dsize - 512, and if not found, search for it.
+ */
+ unsigned long long dsize = 0;
+ unsigned long long ddfpos = 0;
+ unsigned long long ddffound = 0;
+ bool found_anchor = false;
+
+ get_dev_size(fd, NULL, &dsize);
+
+ /* Check the last 512 bytes for the DDF header. */
+ if (lseek64(fd, dsize - 512, SEEK_SET) == -1L) {
+ if (devname) {
+ pr_err("Cannot seek to last 512 bytes on %s: %s\n",
devname, strerror(errno));
+ }
return 1;
}
- if (read(fd, &super->anchor, 512) != 512) {
- if (devname)
- pr_err("Cannot read anchor block on %s: %s\n",
+
+
+ /* Read the last 512 bytes into the anchor block */
+ if (read(fd, &super->anchor, 512) == 512) {
+ /* Check if the magic value matches */
+ if (be32_eq(super->anchor.magic, DDF_HEADER_MAGIC))
+ found_anchor = true;
+
+ } else {
+ if (devname) {
+ pr_err("Cannot read last 512 bytes on %s: %s\n",
devname, strerror(errno));
- return 1;
+ }
}
- if (!be32_eq(super->anchor.magic, DDF_HEADER_MAGIC)) {
+
+ if (!found_anchor) {
+ /* If not found, perform a full search for DDF headers */
+ ddffound = search_for_ddf_headers(fd, devname, &ddfpos);
+ if (ddffound != 0) {
+ if (devname) {
+ pr_err
+ ("DDF headers not found during search on %s\n",
+ devname);
+ }
+ return 2;
+ }
+
+ /* Seek to the found position */
+ if (lseek64(fd, ddfpos, SEEK_SET) == -1L) {
+ if (devname) {
+ pr_err("Cannot seek to anchor block on %s\n",
+ devname);
+ }
+ return 1;
+ }
+
+ /* Read the header from the found position */
+ if (read(fd, &super->anchor, 512) != 512) {
+ if (devname) {
+ pr_err
+ ("Cannot read DDF header at found position on %s: %s\n",
+ devname, strerror(errno));
+ }
+ return 1;
+ }
+
+ /* Verify the magic value again */
+ if (!be32_eq(super->anchor.magic, DDF_HEADER_MAGIC)) {
+ if (devname) {
+ pr_err("Invalid DDF header magic value on %s\n",
+ devname);
+ }
+ return 2;
+ }
+ found_anchor = true;
+ }
+ if (!found_anchor) {
+
if (devname)
- pr_err("no DDF anchor found on %s\n",
- devname);
+ pr_err("DDF headers not found on %s\n", devname);
+
return 2;
}
+
if (!be32_eq(calc_crc(&super->anchor, 512), super->anchor.crc)) {
if (devname)
pr_err("bad CRC on anchor on %s\n",
@@ -3889,16 +4043,17 @@ static int store_super_ddf(struct supertype *st, int fd)
dl->fd = ofd;
return ret;
}
+ // this is used for cleanup (Kill). to clean up 512 bytes
+ // at the end of the disk is not enough.
+ // clears SEARCH_REGION_SIZE bytes at the end of the disk.
- if (posix_memalign(&buf, 512, 512) != 0)
- return 1;
- memset(buf, 0, 512);
-
- if (lseek64(fd, dsize - 512, 0) == -1L) {
+ buf = xmemalign(SEARCH_BLOCK_SIZE, SEARCH_REGION_SIZE);
+ memset(buf, 0, SEARCH_REGION_SIZE);
+ if (lseek64(fd, dsize - SEARCH_REGION_SIZE, 0) == -1L) {
free(buf);
return 1;
}
- rc = write(fd, buf, 512);
+ rc = write(fd, buf, SEARCH_REGION_SIZE);
free(buf);
if (rc < 0)
return 1;
@@ -5208,6 +5363,7 @@ static int update_super_ddf_dummy(struct supertype *st, struct mdinfo *info,
*/
dprintf("update_super is not implemented in DDF\n");
return 0;
+
}
struct superswitch super_ddf = {
diff --git a/xmalloc.c b/xmalloc.c
index e28d3bd6..9472005e 100644
--- a/xmalloc.c
+++ b/xmalloc.c
@@ -75,3 +75,14 @@ char *xstrdup(const char *str)
return exit_memory_alloc_failure();
}
+
+void *xmemalign(size_t alignment, size_t size)
+{
+ void *ptr = NULL;
+ int result = posix_memalign(&ptr, alignment, size);
+
+ if (result == 0)
+ return ptr;
+
+ return exit_memory_alloc_failure();
+}
diff --git a/xmalloc.h b/xmalloc.h
index 0904b0ab..789948ae 100644
--- a/xmalloc.h
+++ b/xmalloc.h
@@ -9,5 +9,6 @@ void *xmalloc(size_t len);
void *xrealloc(void *ptr, size_t len);
void *xcalloc(size_t num, size_t size);
char *xstrdup(const char *str);
+void *xmemalign(size_t alignment, size_t size);
#endif
--
2.41.0

View File

@ -0,0 +1,200 @@
From eb9876f58658a107705a689852110903723e4d3b Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mtkaczyk@kernel.org>
Date: Mon, 3 Feb 2025 11:36:01 +0100
Subject: [PATCH 20/37] bitmap.h - clear __KERNEL__ based headers
It is unused for years. Clear it.
Signed-off-by: Mariusz Tkaczyk <mtkaczyk@kernel.org>
---
bitmap.h | 169 -------------------------------------------------------
1 file changed, 169 deletions(-)
diff --git a/bitmap.h b/bitmap.h
index 7b1f80f2..2614a14e 100644
--- a/bitmap.h
+++ b/bitmap.h
@@ -78,63 +78,6 @@
*
*/
-#ifdef __KERNEL__
-
-#define PAGE_BITS (PAGE_SIZE << 3)
-#define PAGE_BIT_SHIFT (PAGE_SHIFT + 3)
-
-typedef __u16 bitmap_counter_t;
-#define COUNTER_BITS 16
-#define COUNTER_BIT_SHIFT 4
-#define COUNTER_BYTE_RATIO (COUNTER_BITS / 8)
-#define COUNTER_BYTE_SHIFT (COUNTER_BIT_SHIFT - 3)
-
-#define NEEDED_MASK ((bitmap_counter_t) (1 << (COUNTER_BITS - 1)))
-#define RESYNC_MASK ((bitmap_counter_t) (1 << (COUNTER_BITS - 2)))
-#define COUNTER_MAX ((bitmap_counter_t) RESYNC_MASK - 1)
-#define NEEDED(x) (((bitmap_counter_t) x) & NEEDED_MASK)
-#define RESYNC(x) (((bitmap_counter_t) x) & RESYNC_MASK)
-#define COUNTER(x) (((bitmap_counter_t) x) & COUNTER_MAX)
-
-/* how many counters per page? */
-#define PAGE_COUNTER_RATIO (PAGE_BITS / COUNTER_BITS)
-/* same, except a shift value for more efficient bitops */
-#define PAGE_COUNTER_SHIFT (PAGE_BIT_SHIFT - COUNTER_BIT_SHIFT)
-/* same, except a mask value for more efficient bitops */
-#define PAGE_COUNTER_MASK (PAGE_COUNTER_RATIO - 1)
-
-#define BITMAP_BLOCK_SIZE 512
-#define BITMAP_BLOCK_SHIFT 9
-
-/* how many blocks per chunk? (this is variable) */
-#define CHUNK_BLOCK_RATIO(bitmap) ((bitmap)->chunksize >> BITMAP_BLOCK_SHIFT)
-#define CHUNK_BLOCK_SHIFT(bitmap) ((bitmap)->chunkshift - BITMAP_BLOCK_SHIFT)
-#define CHUNK_BLOCK_MASK(bitmap) (CHUNK_BLOCK_RATIO(bitmap) - 1)
-
-/* when hijacked, the counters and bits represent even larger "chunks" */
-/* there will be 1024 chunks represented by each counter in the page pointers */
-#define PAGEPTR_BLOCK_RATIO(bitmap) \
- (CHUNK_BLOCK_RATIO(bitmap) << PAGE_COUNTER_SHIFT >> 1)
-#define PAGEPTR_BLOCK_SHIFT(bitmap) \
- (CHUNK_BLOCK_SHIFT(bitmap) + PAGE_COUNTER_SHIFT - 1)
-#define PAGEPTR_BLOCK_MASK(bitmap) (PAGEPTR_BLOCK_RATIO(bitmap) - 1)
-
-/*
- * on-disk bitmap:
- *
- * Use one bit per "chunk" (block set). We do the disk I/O on the bitmap
- * file a page at a time. There's a superblock at the start of the file.
- */
-
-/* map chunks (bits) to file pages - offset by the size of the superblock */
-#define CHUNK_BIT_OFFSET(chunk) ((chunk) + (sizeof(bitmap_super_t) << 3))
-
-#endif
-
-/*
- * bitmap structures:
- */
-
#define BITMAP_MAGIC 0x6d746962
/* use these for bitmap->flags and bitmap->sb->state bit-fields */
@@ -176,116 +119,4 @@ typedef struct bitmap_super_s {
* devices. For raid10 it is the size of the array.
*/
-#ifdef __KERNEL__
-
-/* the in-memory bitmap is represented by bitmap_pages */
-struct bitmap_page {
- /*
- * map points to the actual memory page
- */
- char *map;
- /*
- * in emergencies (when map cannot be allocated), hijack the map
- * pointer and use it as two counters itself
- */
- unsigned int hijacked;
- /*
- * count of dirty bits on the page
- */
- int count;
-};
-
-/* keep track of bitmap file pages that have pending writes on them */
-struct page_list {
- struct list_head list;
- struct page *page;
-};
-
-/* the main bitmap structure - one per mddev */
-struct bitmap {
- struct bitmap_page *bp;
- unsigned long pages; /* total number of pages in the bitmap */
- unsigned long missing_pages; /* number of pages not yet allocated */
-
- mddev_t *mddev; /* the md device that the bitmap is for */
-
- int counter_bits; /* how many bits per block counter */
-
- /* bitmap chunksize -- how much data does each bit represent? */
- unsigned long chunksize;
- unsigned long chunkshift; /* chunksize = 2^chunkshift (for bitops) */
- unsigned long chunks; /* total number of data chunks for the array */
-
- /* We hold a count on the chunk currently being synced, and drop
- * it when the last block is started. If the resync is aborted
- * midway, we need to be able to drop that count, so we remember
- * the counted chunk..
- */
- unsigned long syncchunk;
-
- __u64 events_cleared;
-
- /* bitmap spinlock */
- spinlock_t lock;
-
- struct file *file; /* backing disk file */
- struct page *sb_page; /* cached copy of the bitmap file superblock */
- struct page **filemap; /* list of cache pages for the file */
- unsigned long *filemap_attr; /* attributes associated w/ filemap pages */
- unsigned long file_pages; /* number of pages in the file */
-
- unsigned long flags;
-
- /*
- * the bitmap daemon - periodically wakes up and sweeps the bitmap
- * file, cleaning up bits and flushing out pages to disk as necessary
- */
- mdk_thread_t *daemon;
- unsigned long daemon_sleep; /* how many seconds between updates? */
-
- /*
- * bitmap write daemon - this daemon performs writes to the bitmap file
- * this thread is only needed because of a limitation in ext3 (jbd)
- * that does not allow a task to have two journal transactions ongoing
- * simultaneously (even if the transactions are for two different
- * filesystems) -- in the case of bitmap, that would be the filesystem
- * that the bitmap file resides on and the filesystem that is mounted
- * on the md device -- see current->journal_info in jbd/transaction.c
- */
- mdk_thread_t *write_daemon;
- mdk_thread_t *writeback_daemon;
- spinlock_t write_lock;
- struct semaphore write_ready;
- struct semaphore write_done;
- unsigned long writes_pending;
- wait_queue_head_t write_wait;
- struct list_head write_pages;
- struct list_head complete_pages;
- mempool_t *write_pool;
-};
-
-/* the bitmap API */
-
-/* these are used only by md/bitmap */
-int bitmap_create(mddev_t *mddev);
-void bitmap_destroy(mddev_t *mddev);
-int bitmap_active(struct bitmap *bitmap);
-
-char *file_path(struct file *file, char *buf, int count);
-void bitmap_print_sb(struct bitmap *bitmap);
-int bitmap_update_sb(struct bitmap *bitmap);
-
-int bitmap_setallbits(struct bitmap *bitmap);
-
-/* these are exported */
-void bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors);
-void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors,
- int success);
-int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks);
-void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted);
-void bitmap_close_sync(struct bitmap *bitmap);
-
-int bitmap_unplug(struct bitmap *bitmap);
-#endif
-
#endif
--
2.41.0

View File

@ -0,0 +1,206 @@
From 17fed47a64e1890df9820b93548c396b7de54e31 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mtkaczyk@kernel.org>
Date: Wed, 5 Feb 2025 11:34:45 +0100
Subject: [PATCH 21/37] bitmap.h: Minor fixes
Move documentation to documentation/bitmap.md. Add Neil's copyrights,
add missing license. Remove unused macros.
Signed-off-by: Mariusz Tkaczyk <mtkaczyk@kernel.org>
---
bitmap.h | 94 ++++-------------------------------------
documentation/bitmap.md | 67 +++++++++++++++++++++++++++++
2 files changed, 75 insertions(+), 86 deletions(-)
create mode 100644 documentation/bitmap.md
diff --git a/bitmap.h b/bitmap.h
index 2614a14e..9f3d4f3e 100644
--- a/bitmap.h
+++ b/bitmap.h
@@ -1,83 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
/*
- * bitmap.h: Copyright (C) Peter T. Breuer (ptb@ot.uc3m.es) 2003
- *
- * additions: Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, Inc.
+ * Copyright (C) Peter T. Breuer (ptb@ot.uc3m.es) 2003
+ * Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, Inc.
+ * Copyright (C) 2005 Neil Brown <neilb@suse.com>
*/
+
+/* See documentation/bitmap.md */
+
#ifndef BITMAP_H
#define BITMAP_H 1
#define BITMAP_MAJOR_LO 3
-/* version 4 insists the bitmap is in little-endian order
- * with version 3, it is host-endian which is non-portable
- */
#define BITMAP_MAJOR_HI 4
-#define BITMAP_MAJOR_HOSTENDIAN 3
#define BITMAP_MAJOR_CLUSTERED 5
-
-#define BITMAP_MINOR 39
-
-/*
- * in-memory bitmap:
- *
- * Use 16 bit block counters to track pending writes to each "chunk".
- * The 2 high order bits are special-purpose, the first is a flag indicating
- * whether a resync is needed. The second is a flag indicating whether a
- * resync is active.
- * This means that the counter is actually 14 bits:
- *
- * +--------+--------+------------------------------------------------+
- * | resync | resync | counter |
- * | needed | active | |
- * | (0-1) | (0-1) | (0-16383) |
- * +--------+--------+------------------------------------------------+
- *
- * The "resync needed" bit is set when:
- * a '1' bit is read from storage at startup.
- * a write request fails on some drives
- * a resync is aborted on a chunk with 'resync active' set
- * It is cleared (and resync-active set) when a resync starts across all drives
- * of the chunk.
- *
- *
- * The "resync active" bit is set when:
- * a resync is started on all drives, and resync_needed is set.
- * resync_needed will be cleared (as long as resync_active wasn't already set).
- * It is cleared when a resync completes.
- *
- * The counter counts pending write requests, plus the on-disk bit.
- * When the counter is '1' and the resync bits are clear, the on-disk
- * bit can be cleared as well, thus setting the counter to 0.
- * When we set a bit, or in the counter (to start a write), if the fields is
- * 0, we first set the disk bit and set the counter to 1.
- *
- * If the counter is 0, the on-disk bit is clear and the stipe is clean
- * Anything that dirties the stipe pushes the counter to 2 (at least)
- * and sets the on-disk bit (lazily).
- * If a periodic sweep find the counter at 2, it is decremented to 1.
- * If the sweep find the counter at 1, the on-disk bit is cleared and the
- * counter goes to zero.
- *
- * Also, we'll hijack the "map" pointer itself and use it as two 16 bit block
- * counters as a fallback when "page" memory cannot be allocated:
- *
- * Normal case (page memory allocated):
- *
- * page pointer (32-bit)
- *
- * [ ] ------+
- * |
- * +-------> [ ][ ]..[ ] (4096 byte page == 2048 counters)
- * c1 c2 c2048
- *
- * Hijacked case (page memory allocation failed):
- *
- * hijacked page pointer (32-bit)
- *
- * [ ][ ] (no page memory allocated)
- * counter #1 (16-bit) counter #2 (16-bit)
- *
- */
-
#define BITMAP_MAGIC 0x6d746962
/* use these for bitmap->flags and bitmap->sb->state bit-fields */
@@ -105,18 +41,4 @@ typedef struct bitmap_super_s {
__u8 pad[256 - 136]; /* set to zero */
} bitmap_super_t;
-/* notes:
- * (1) This event counter is updated before the eventcounter in the md superblock
- * When a bitmap is loaded, it is only accepted if this event counter is equal
- * to, or one greater than, the event counter in the superblock.
- * (2) This event counter is updated when the other one is *if*and*only*if* the
- * array is not degraded. As bits are not cleared when the array is degraded,
- * this represents the last time that any bits were cleared.
- * If a device is being added that has an event count with this value or
- * higher, it is accepted as conforming to the bitmap.
- * (3)This is the number of sectors represented by the bitmap, and is the range that
- * resync happens across. For raid1 and raid5/6 it is the size of individual
- * devices. For raid10 it is the size of the array.
- */
-
#endif
diff --git a/documentation/bitmap.md b/documentation/bitmap.md
new file mode 100644
index 00000000..bdc146e5
--- /dev/null
+++ b/documentation/bitmap.md
@@ -0,0 +1,67 @@
+# Internal bitmap block design
+
+Use 16 bit block counters to track pending writes to each "chunk".
+The 2 high order bits are special-purpose, the first is a flag indicating
+whether a resync is needed. The second is a flag indicating whether a
+resync is active. This means that the counter is actually 14 bits:
+
+| resync_needed | resync_active | counter |
+| :----: | :----: | :----: |
+| (0-1) | (0-1) | (0-16383) |
+
+The `resync_needed` bit is set when:
+- a `1` bit is read from storage at startup;
+- a write request fails on some drives;
+- a resync is aborted on a chunk with `resync_active` set;
+- It is cleared (and `resync_active` set) when a resync starts across all drives of the chunk.
+
+The `resync_active` bit is set when:
+- a resync is started on all drives, and `resync_needed` is set.
+- `resync_needed` will be cleared (as long as `resync_active` wasn't already set).
+- It is cleared when a resync completes.
+
+The counter counts pending write requests, plus the on-disk bit.
+When the counter is `1` and the resync bits are clear, the on-disk
+bit can be cleared as well, thus setting the counter to `0`.
+When we set a bit, or in the counter (to start a write), if the fields is
+`0`, we first set the disk bit and set the counter to `1`.
+
+If the counter is `0`, the on-disk bit is clear and the stipe is clean
+Anything that dirties the stipe pushes the counter to `2` (at least)
+and sets the on-disk bit (lazily).
+If a periodic sweep find the counter at `2`, it is decremented to `1`.
+If the sweep find the counter at `1`, the on-disk bit is cleared and the
+counter goes to `0`.
+
+Also, we'll hijack the "map" pointer itself and use it as two 16 bit block
+counters as a fallback when "page" memory cannot be allocated:
+
+Normal case (page memory allocated):
+
+page pointer (32-bit)
+
+ [ ] ------+
+ |
+ +-------> [ ][ ]..[ ] (4096 byte page == 2048 counters)
+ c1 c2 c2048
+
+ Hijacked case (page memory allocation failed):
+
+ hijacked page pointer (32-bit)
+
+ [ ][ ] (no page memory allocated)
+ counter #1 (16-bit) counter #2 (16-bit)
+
+
+## Notes:
+1. bitmap_super_s->events counter is updated before the event counter in the md superblock;
+ When a bitmap is loaded, it is only accepted if this event counter is equal
+ to, or one greater than, the event counter in the superblock.
+2. bitmap_super_s->events is updated when the other one is `if` and `only if` the
+ array is not degraded. As bits are not cleared when the array is degraded,
+ this represents the last time that any bits were cleared. If a device is being
+ added that has an event count with this value or higher, it is accepted
+ as conforming to the bitmap.
+3. bitmap_super_s->chunksize is the number of sectors represented by the bitmap,
+ and is the range that resync happens across. For raid1 and raid5/6 it is the
+ size of individual devices. For raid10 it is the size of the array.
--
2.41.0

View File

@ -0,0 +1,20 @@
From 4b3932487a8dc2e87530e595ccabe48c79446f30 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mtkaczyk@kernel.org>
Date: Wed, 12 Feb 2025 11:29:05 +0100
Subject: [PATCH 22/37] Move release steps to documentation/
Make a room for release MAINTAINERS file.
Signed-off-by: Mariusz Tkaczyk <mtkaczyk@kernel.org>
---
MAINTAINERS.md => documentation/HOW_TO_RELEASE.md | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename MAINTAINERS.md => documentation/HOW_TO_RELEASE.md (100%)
diff --git a/MAINTAINERS.md b/documentation/HOW_TO_RELEASE.md
similarity index 100%
rename from MAINTAINERS.md
rename to documentation/HOW_TO_RELEASE.md
--
2.41.0

View File

@ -0,0 +1,102 @@
From dacce2a0009f3506a5accf91f8fa9956eb36218e Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mtkaczyk@kernel.org>
Date: Wed, 12 Feb 2025 12:41:58 +0100
Subject: [PATCH 23/37] Rework MAINTAINERS file
Remove Mateusz. Intergrate it with README.md
Signed-off-by: Mariusz Tkaczyk <mtkaczyk@kernel.org>
---
MAINTAINERS | 32 --------------------------------
MAINTAINERS.md | 23 +++++++++++++++++++++++
README.md | 5 +----
3 files changed, 24 insertions(+), 36 deletions(-)
delete mode 100644 MAINTAINERS
create mode 100644 MAINTAINERS.md
diff --git a/MAINTAINERS b/MAINTAINERS
deleted file mode 100644
index 0a1229fd..00000000
--- a/MAINTAINERS
+++ /dev/null
@@ -1,32 +0,0 @@
-
-# List of maintainers for mdadm
-
-
-Descriptions of section entries:
-
-M: Mail patches to: FullName <address@domain>
-L: Mailing list that is relevant to mdadm
-
-
-Alphabetical Order:
-
-M: Blazej Kucman <blazej.kucman@linux.intel.com>
-L: linux-raid@vger.kernel.org
-
-M: Mateusz Kusiak <mateusz.kusiak@intel.com>
-L: linux-raid@vger.kernel.org
-
-M: Mariusz Tkaczyk <mtkaczyk@kernel.org>
-L: linux-raid@vger.kernel.org
-
-M: Nigel Croxon <ncroxon@redhat.com>
-L: linux-raid@vger.kernel.org
-
-M: Song Liu <song@kernel.org>
-L: linux-raid@vger.kernel.org
-
-M: Xiao Ni <xni@redhat.com>
-L: linux-raid@vger.kernel.org
-
-M: Yu Kuai <yukuai@kernel.org>
-L: linux-raid@vger.kernel.org
diff --git a/MAINTAINERS.md b/MAINTAINERS.md
new file mode 100644
index 00000000..00587484
--- /dev/null
+++ b/MAINTAINERS.md
@@ -0,0 +1,23 @@
+If you are sending patch through mailing list, please include everyone listed
+in this file.
+
+## Github maintainers team
+
+Github Pull Request must be `approved` by at least 2 maintainers team members:
+
+ Name | Github Profile | Email address |
+| -- |----------------|---------------|
+| Blazej Kucman | [bkucman](https://github.com/bkucman) | <blazej.kucman@linux.intel.com> |
+| Mariusz Tkaczyk | [mtkaczyk](https://github.com/mtkaczyk) | <mtkaczyk@kernel.org> |
+| Nigel Croxon | [ncroxon](https://github.com/ncroxon) | <ncroxon@redhat.com> |
+| Xiao Ni | [XiaoNi87](https://github.com/XiaoNi87) | <xni@redhat.com> |
+
+## Kernel.org maintainers
+Reach this team specifically if you are observing differences
+between kernel.org and Github.
+
+| Name | Email address |
+|------|----------------|
+| Mariusz Tkaczyk | <mtkaczyk@kernel.org> |
+| Song Liu | <song@kernel.org> |
+| Yu Kuai | <yukuai@kernel.org> |
diff --git a/README.md b/README.md
index 0c299a9a..029e0ee2 100644
--- a/README.md
+++ b/README.md
@@ -77,10 +77,7 @@ to the chosen branch, then Pull Request will be automatically updated.
# Maintainers of mdadm repository on kernel.org
-If there are differences between github and kernel.org, please contact kernel.org mdadm maintainers:
-
-- Jes Sorensen <jes@trained-monkey.org>;
-- Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>;
+See [Maintainers File](MAINTAINERS.md).
# Minimal supported kernel version
--
2.41.0

View File

@ -0,0 +1,122 @@
From 7d29b3823c18a24d6efbb502f08638788f97e04b Mon Sep 17 00:00:00 2001
From: Junxiao Bi <junxiao.bi@oracle.com>
Date: Tue, 18 Feb 2025 10:48:31 -0800
Subject: [PATCH 24/37] mdmon: imsm: fix metadata corruption when managing new
array
When manager thread detects new array, it will invoke manage_new().
For imsm array, it will further invoke imsm_open_new(). Since
commit bbab0940fa75("imsm: write bad block log on metadata sync"),
it preallocates bad block log when opening the array, that requires
increasing the mpb buffer size.
For that, imsm_open_new() invokes function imsm_update_metadata_locally(),
which first uses imsm_prepare_update() to allocate a larger mpb buffer
and store it at "mpb->next_buf", and then invoke imsm_process_update()
to copy the content from current mpb buffer "mpb->buf" to "mpb->next_buf",
and then free the current mpb buffer and set the new buffer as current.
There is a small race window, when monitor thread is syncing metadata,
it gets current buffer pointer in imsm_sync_metadata()->write_super_imsm(),
but before flushing the buffer to disk, manager thread does above switching
buffer which frees current buffer, then monitor thread will run into
use-after-free issue and could cause on-disk metadata corruption.
If system keeps running, further metadata update could fix the corruption,
because after switching buffer, the new buffer will contain good metadata,
but if panic/power cycle happens while disk metadata is corrupted,
the system will run into bootup failure if array is used as root,
otherwise the array can not be assembled after boot if not used as root.
This issue will not happen for imsm array with only one member array,
because the memory array has not be opened yet, monitor thread will not
do any metadata updates.
This can happen for imsm array with at lease two member array, in the
following two scenarios:
1. Restarting mdmon process with at least two member array
This will happen during system boot up or user restart mdmon after mdadm
upgrade
2. Adding new member array to exist imsm array with at least one member
array.
To fix this, delay the switching buffer operation to monitor thread.
Fixes: bbab0940fa75 ("imsm: write bad block log on metadata sync")
Signed-off-by: Junxiao Bi <junxiao.bi@oracle.com>
---
managemon.c | 10 ++++++++--
super-intel.c | 14 +++++++++++---
2 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/managemon.c b/managemon.c
index d7981328..74b64bfc 100644
--- a/managemon.c
+++ b/managemon.c
@@ -721,11 +721,12 @@ static void manage_new(struct mdstat_ent *mdstat,
* the monitor.
*/
+ struct metadata_update *update = NULL;
struct active_array *new = NULL;
struct mdinfo *mdi = NULL, *di;
- int i, inst;
- int failed = 0;
char buf[SYSFS_MAX_BUF_SIZE];
+ int failed = 0;
+ int i, inst;
/* check if array is ready to be monitored */
if (!mdstat->active || !mdstat->level)
@@ -824,9 +825,14 @@ static void manage_new(struct mdstat_ent *mdstat,
/* if everything checks out tell the metadata handler we want to
* manage this instance
*/
+ container->update_tail = &update;
if (!aa_ready(new) || container->ss->open_new(container, new, inst) < 0) {
+ container->update_tail = NULL;
goto error;
} else {
+ if (update)
+ queue_metadata_update(update);
+ container->update_tail = NULL;
replace_array(container, victim, new);
if (failed) {
new->check_degraded = 1;
diff --git a/super-intel.c b/super-intel.c
index cab84198..4988eef1 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -8467,12 +8467,15 @@ static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev,
return failed;
}
+static int imsm_prepare_update(struct supertype *st,
+ struct metadata_update *update);
static int imsm_open_new(struct supertype *c, struct active_array *a,
int inst)
{
struct intel_super *super = c->sb;
struct imsm_super *mpb = super->anchor;
- struct imsm_update_prealloc_bb_mem u;
+ struct imsm_update_prealloc_bb_mem *u;
+ struct metadata_update mu;
if (inst >= mpb->num_raid_devs) {
pr_err("subarry index %d, out of range\n", inst);
@@ -8482,8 +8485,13 @@ static int imsm_open_new(struct supertype *c, struct active_array *a,
dprintf("imsm: open_new %d\n", inst);
a->info.container_member = inst;
- u.type = update_prealloc_badblocks_mem;
- imsm_update_metadata_locally(c, &u, sizeof(u));
+ u = xmalloc(sizeof(*u));
+ u->type = update_prealloc_badblocks_mem;
+ mu.len = sizeof(*u);
+ mu.buf = (char *)u;
+ imsm_prepare_update(c, &mu);
+ if (c->update_tail)
+ append_metadata_update(c, u, sizeof(*u));
return 0;
}
--
2.41.0

View File

@ -0,0 +1,217 @@
From c2fbf66ba0243f499f78ed43fa1207a9bd9361b5 Mon Sep 17 00:00:00 2001
From: XiaoNi87 <xni@redhat.com>
Date: Tue, 18 Mar 2025 08:18:04 +0800
Subject: [PATCH 25/37] Regression fix (#156)
Signed-off-by: Xiao Ni <xni@redhat.com>
---
.github/tools/run_mdadm_tests.sh | 2 +-
test | 22 +++++++++++++++++++---
tests/05r6tor0.broken | 15 +++++++++++++++
tests/07revert-inplace.broken | 8 ++++++++
tests/10ddf-create.broken | 5 -----
tests/10ddf-fail-two-spares.broken | 5 -----
tests/20raid5journal.broken | 17 +++++++++++++++++
tests/env-ddf-template | 3 +--
tests/skiptests | 9 +++++++++
util.c | 2 +-
10 files changed, 71 insertions(+), 17 deletions(-)
create mode 100644 tests/05r6tor0.broken
create mode 100644 tests/07revert-inplace.broken
delete mode 100644 tests/10ddf-create.broken
delete mode 100644 tests/10ddf-fail-two-spares.broken
create mode 100644 tests/20raid5journal.broken
create mode 100644 tests/skiptests
diff --git a/.github/tools/run_mdadm_tests.sh b/.github/tools/run_mdadm_tests.sh
index 456874b5..22d89a8c 100755
--- a/.github/tools/run_mdadm_tests.sh
+++ b/.github/tools/run_mdadm_tests.sh
@@ -11,7 +11,7 @@ sudo ./test setup
#sudo ./test --tests=00createnames
-sudo ./test --skip-broken --no-error --disable-integrity --disable-multipath --disable-linear --keep-going
+sudo ./test --skip-broken --no-error --disable-integrity --disable-multipath --disable-linear --keep-going --skip-bigcase
ret=$?
sudo ./test cleanup
diff --git a/test b/test
index 88e44f18..7fa68177 100755
--- a/test
+++ b/test
@@ -26,6 +26,10 @@ savelogs=0
exitonerror=1
ctrl_c_error=0
skipbroken=0
+skipbigcase=0
+skipfile="skiptests"
+skipcheckfile=$testdir/$skipfile
+checkscript=""
loop=1
prefix='[0-9][0-9]'
@@ -192,6 +196,7 @@ do_help() {
--loop=N Run tests N times (0 to run forever)
--skip-broken Skip tests that are known to be broken
--skip-always-broken Skip tests that are known to always fail
+ --skip-bigcase Skip tests that need time than 200 seconds
--dev=loop|lvm|ram|disk Use loop devices (default), LVM, RAM or disk
--disks= Provide a bunch of physical devices for test
--volgroup=name LVM volume group for LVM test
@@ -295,6 +300,9 @@ parse_args() {
--skip-always-broken )
skipbroken=always
;;
+ --skip-bigcase )
+ skipbigcase=all
+ ;;
--disable-multipath )
unset MULTIPATH
;;
@@ -369,9 +377,17 @@ main() {
else
for script in $testdir/$prefix $testdir/$prefix*[^~]
do
- case $script in *.broken) ;;
- *)
- do_test $script
+ checkscript="${script##*/}"
+ case $script in
+ *.broken)
+ ;;
+ *)
+ if grep -q "$checkscript" "$skipcheckfile"; then
+ if [ "$skipbigcase" == "all" ]; then
+ continue
+ fi
+ fi
+ do_test $script
esac
done
fi
diff --git a/tests/05r6tor0.broken b/tests/05r6tor0.broken
new file mode 100644
index 00000000..930a0941
--- /dev/null
+++ b/tests/05r6tor0.broken
@@ -0,0 +1,15 @@
+Sometimes
+
++++ pgrep -f 'mdadm --grow --continue'
+++ [[ '' != '' ]]
+++ break
+++ echo 100
+++ echo 500
+++ sleep 2
+++ check raid5
+++ case $1 in
+++ grep -sq 'active raid5 ' /proc/mdstat
+++ die 'active raid5 not found'
+++ echo -e '\n\tERROR: active raid5 not found \n'
+
+ ERROR: active raid5 not found
diff --git a/tests/07revert-inplace.broken b/tests/07revert-inplace.broken
new file mode 100644
index 00000000..73d98a04
--- /dev/null
+++ b/tests/07revert-inplace.broken
@@ -0,0 +1,8 @@
+always fails
+
+Fails with errors:
+ ++ /usr/sbin/mdadm -A /dev/md0 --update=revert-reshape /dev/loop0 /dev/loop1 /dev/loop2 /dev/loop3 /dev/loop4 --backup-file=/tmp/md-backup
+++ rv=1
+++ case $* in
+++ cat /var/tmp/stderr
+mdadm: failed to RUN_ARRAY /dev/md0: Invalid argument
diff --git a/tests/10ddf-create.broken b/tests/10ddf-create.broken
deleted file mode 100644
index 0f7d25e5..00000000
--- a/tests/10ddf-create.broken
+++ /dev/null
@@ -1,5 +0,0 @@
-Fails due to segmentation fault at assemble.
-
-Too much effort to diagnose this now, marking as broken to make CI clear.
- ++ /usr/sbin/mdadm -A /dev/md/ddf0 /dev/loop8 /dev/loop9 /dev/loop10 /dev/loop11 /dev/loop12
- ./test: line 76: 101955 Segmentation fault (core dumped) $mdadm "$@" 2> $targetdir/stderr
diff --git a/tests/10ddf-fail-two-spares.broken b/tests/10ddf-fail-two-spares.broken
deleted file mode 100644
index eeea56d9..00000000
--- a/tests/10ddf-fail-two-spares.broken
+++ /dev/null
@@ -1,5 +0,0 @@
-fails infrequently
-
-Fails roughly 1 in 3 with error:
-
- ERROR: /dev/md/vol1 should be optimal in meta data
diff --git a/tests/20raid5journal.broken b/tests/20raid5journal.broken
new file mode 100644
index 00000000..c7b214af
--- /dev/null
+++ b/tests/20raid5journal.broken
@@ -0,0 +1,17 @@
+always fail
+
+++ /usr/sbin/mdadm -I /dev/loop4
+++ rv=0
+++ case $* in
+++ cat /var/tmp/stderr
+mdadm: /dev/loop4 attached to /dev/md/0_0, which has been started.
+++ return 0
+++ check raid5
+++ case $1 in
+++ grep -sq 'active raid5 ' /proc/mdstat
+++ die 'active raid5 not found'
+++ echo -e '\n\tERROR: active raid5 not found \n'
+
+ ERROR: active raid5 not found
+
+++ save_log fail
diff --git a/tests/env-ddf-template b/tests/env-ddf-template
index 4f4ad0f3..ebc0ebf3 100644
--- a/tests/env-ddf-template
+++ b/tests/env-ddf-template
@@ -3,8 +3,7 @@ sha1_sum() {
}
get_rootdev() {
- local part=$(grep ' / ' /proc/mounts | awk '{print $1}')
- local bd=/dev/$(lsblk -no PKNAME $part)
+ local bd=$(grep ' / ' /proc/mounts | awk '{print $1}')
[ -b $bd ] || exit 1
echo $bd
}
diff --git a/tests/skiptests b/tests/skiptests
new file mode 100644
index 00000000..fd0893f1
--- /dev/null
+++ b/tests/skiptests
@@ -0,0 +1,9 @@
+casename:seconds
+01raid6integ:1732
+01replace:396
+07layouts:836
+11spare-migration:1140
+12imsm-r0_2d-grow-r0_5d:218
+13imsm-r0_r0_2d-grow-r0_r0_4d:218
+13imsm-r0_r0_2d-grow-r0_r0_5d:246
+19raid6check:268
diff --git a/util.c b/util.c
index 8c45f0e1..9fe2d227 100644
--- a/util.c
+++ b/util.c
@@ -2310,7 +2310,7 @@ mdadm_status_t continue_via_systemd(char *devnm, char *service_name, char *prefi
dprintf("Start %s service\n", service_name);
/* Simply return that service cannot be started */
if (check_env("MDADM_NO_SYSTEMCTL"))
- return MDADM_STATUS_SUCCESS;
+ return MDADM_STATUS_ERROR;
/* Fork in attempt to start services */
switch (fork()) {
--
2.41.0

View File

@ -0,0 +1,72 @@
From 4e2e208c8d3e9ba0fae88136d7c4cd0292af73b0 Mon Sep 17 00:00:00 2001
From: Wu Guanghao <wuguanghao3@huawei.com>
Date: Tue, 11 Mar 2025 03:11:55 +0000
Subject: [PATCH 26/37] super1: Clear extra flags when initializing metadata
When adding a disk to a RAID1 array, the metadata is read from the
existing member disks for sync. However, only the bad_blocks flag are
copied, the bad_blocks records are not copied, so the bad_blocks
records are all zeros. The kernel function super_1_load() detects
bad_blocks flag and reads the bad_blocks record, then sets the bad
block using badblocks_set().
After the kernel commit 1726c7746783 (badblocks: improve badblocks_set()
for multiple ranges handling) if the length of a bad_blocks record is 0,
it will return a failure. Therefore the device addition will fail.
So when adding a new disk, some flags cannot be sync and need to be clead.
Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
---
super1.c | 3 +++
tests/05r1-add-badblocks | 24 ++++++++++++++++++++++++
2 files changed, 27 insertions(+)
create mode 100644 tests/05r1-add-badblocks
diff --git a/super1.c b/super1.c
index fe3c4c64..c828b682 100644
--- a/super1.c
+++ b/super1.c
@@ -1971,6 +1971,9 @@ static int write_init_super1(struct supertype *st)
long bm_offset;
bool raid0_need_layout = false;
+ /* Clear extra flags */
+ sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_BAD_BLOCKS | MD_FEATURE_REPLACEMENT);
+
/* Since linux kernel v5.4, raid0 always has a layout */
if (has_raid0_layout(sb) && get_linux_version() >= 5004000)
raid0_need_layout = true;
diff --git a/tests/05r1-add-badblocks b/tests/05r1-add-badblocks
new file mode 100644
index 00000000..6192327a
--- /dev/null
+++ b/tests/05r1-add-badblocks
@@ -0,0 +1,24 @@
+#
+# create a raid1 with a drive and set badblocks for the drive.
+# add a new drive does not cause an error.
+#
+
+# create raid1
+mdadm -CR $md0 -l1 -n2 -e1.0 $dev1 missing
+testdev $md0 1 $mdsize1a 64
+sleep 3
+
+# set badblocks for the drive
+dev1_name=$(basename $dev1)
+echo "100 100" > /sys/block/md0/md/dev-$dev1_name/bad_blocks
+echo "write_error" > /sys/block/md0/md/dev-$dev1_name/state
+
+# write badblocks to metadata
+dd if=/dev/zero of=$md0 bs=512 count=200 oflag=direct
+
+# re-add and recovery
+mdadm $md0 -a $dev2
+check recovery
+
+mdadm -S $md0
+
--
2.41.0

View File

@ -0,0 +1,74 @@
From 127e38b59cbdf717d1569bcdc75b8d823d8485f3 Mon Sep 17 00:00:00 2001
From: Blazej Kucman <blazej.kucman@intel.com>
Date: Mon, 31 Mar 2025 12:46:52 +0200
Subject: [PATCH 27/37] imsm: Fix RAID0 to RAID10 migration
Support for RAID10 with +4 disks in IMSM introduced an inconsistency
between the VROC UEFI driver and Linux IMSM. VROC UEFI does not
support RAID10 with +4 disks, therefore appropriate protections were
added to the mdadm IMSM code that results in skipping processing of
such RAID in the UEFI phase. Unfortunately the case of migration
RAID0 2 disks to RAID10 4 disks was omitted, this case requires
maintaining compatibility with the VROC UEFI driver because it is
supported.
For RAID10 +4 disk the MPB_ATTRIB_RAID10_EXT attribute is set in the
metadata, thanks to which the UEFI driver does not process such RAID.
In the series adding support, a new metadata raid level value
IMSM_T_RAID10 was also introduced. It is not recognized by VROC UEFI.
The issue is caused by the fact that in the case of the mentioned
migration, IMSM_T_RAID10 is entered into the metadata but attribute
MPB_ATTRIB_RAID10_EXT is not entered, which causes an attempt to
process such RAID in the UEFI phase. This situation results in
the platform hang during booting in UEFI phase, this also results in
data loss after failed and interrupted RAID processing in VROC UEFI.
The above situation is result of the update_imsm_raid_level()
function, for the mentioned migration function is executed on a map
with a not yet updated number of disks.
The fix is to explicitly handle migration in the function mentioned
above to maintain compatibility with VROC UEFI driver.
Steps to reproduce:
mdadm -C /dev/md/imsm0 -e imsm -n 2 /dev/nvme[1,2]n1 -R
mdadm -C /dev/md/vol -l 0 -n 2 /dev/nvme[1,2]n1 --assume-clean -R
mdadm -a /dev/md127 /dev/nvme3n1
mdadm -a /dev/md127 /dev/nvme4n1
mdadm -G /dev/md126 -l 10
reboot
Fixes: 27550b13297a ("imsm: add support for literal RAID 10")
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
---
super-intel.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/super-intel.c b/super-intel.c
index 4988eef1..b7b030a2 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -1327,6 +1327,19 @@ static void update_imsm_raid_level(struct imsm_map *map, int new_level)
return;
}
+ /*
+ * RAID0 to RAID10 migration.
+ * Due to the compatibility with VROC UEFI must be maintained, this case must be handled
+ * separately, because the map does not have an updated number of disks.
+ */
+ if (map->raid_level == IMSM_T_RAID0) {
+ if (map->num_members == 2)
+ map->raid_level = IMSM_T_RAID1;
+ else
+ map->raid_level = IMSM_T_RAID10;
+ return;
+ }
+
if (map->num_members == 4) {
if (map->raid_level == IMSM_T_RAID10 || map->raid_level == IMSM_T_RAID1)
return;
--
2.41.0

View File

@ -0,0 +1,193 @@
From 6ce7f21bb822fd0125f78434d9fbf6c3db524892 Mon Sep 17 00:00:00 2001
From: NeilBrown <neil@brown.name>
Date: Fri, 4 Apr 2025 11:56:04 +1100
Subject: [PATCH 28/37] Allow RAID0 to be created with v0.90 metadata #161
It is not currently possible to create a RAID0 with 0.90 metadata.
This is because 0.90 cannot specify the layout of RAID0 (it is
traditionally ignored) and different kernels do different things with
RAID0 layouts.
However it should be possible to use --layout=dangerous as that
acknowledges the risk.
It also should be possible to create a RAID0 with all devices the same
size because in that case all layouts are identical.
The metadata handler can only check that all devices are the same size
quite late - in write_init_super(). By that time the default is
currently set - set to a value that super0 cannot handle.
So this patch delays the setting of the default value and leave it for
the metadata handler (or for the Build handler).
super1 selects ORIG in that case.
intel and ddf don't support non-uniform RAID0 so they don't need any
change.
super0 now checks the sizes of devices if the default RAID0 layout was
requested and rejects the request in they are not the same.
validiate_geometry0 now allows "dangerous" layouts for raid0.
Signed-off-by: NeilBrown <neil@brown.name>
---
Build.c | 4 ++++
Create.c | 2 +-
maps.c | 2 +-
mdadm.h | 1 +
super0.c | 34 +++++++++++++++++++++++++++++++++-
super1.c | 4 ++++
tests/00raid0 | 4 ++--
7 files changed, 46 insertions(+), 5 deletions(-)
diff --git a/Build.c b/Build.c
index 70aab7a0..9eb85a13 100644
--- a/Build.c
+++ b/Build.c
@@ -103,6 +103,10 @@ int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s,
s->chunk = 64;
array.chunk_size = s->chunk*1024;
array.layout = s->layout;
+
+ if (array.level == 0 && array.layout == UnSet)
+ /* Raid0 leaves default to metadata handler. That is us. */
+ array.layout = RAID0_ORIG_LAYOUT;
if (md_set_array_info(mdfd, &array)) {
pr_err("md_set_array_info() failed for %s: %s\n", chosen_name, strerror(errno));
goto abort;
diff --git a/Create.c b/Create.c
index fd6c9215..2b181dbf 100644
--- a/Create.c
+++ b/Create.c
@@ -77,7 +77,7 @@ int default_layout(struct supertype *st, int level, int verbose)
layout = 0;
break;
case 0:
- layout = RAID0_ORIG_LAYOUT;
+ /* Leave unset - metadata handlers choose default */
break;
case 10:
layout = 0x102; /* near=2, far=1 */
diff --git a/maps.c b/maps.c
index 17f8b54d..2181b4ac 100644
--- a/maps.c
+++ b/maps.c
@@ -81,7 +81,7 @@ mapping_t r0layout[] = {
{ "alternate", RAID0_ALT_MULTIZONE_LAYOUT},
{ "1", 1}, /* aka ORIG */
{ "2", 2}, /* aka ALT */
- { "dangerous", 0},
+ { "dangerous", RAID0_DANGEROUS_LAYOUT},
{ NULL, UnSet},
};
diff --git a/mdadm.h b/mdadm.h
index e84c341c..0ea83ad3 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -2003,6 +2003,7 @@ static inline int xasprintf(char **strp, const char *fmt, ...) {
#endif
enum r0layout {
+ RAID0_DANGEROUS_LAYOUT = 0, /* layout depends on kernel version */
RAID0_ORIG_LAYOUT = 1,
RAID0_ALT_MULTIZONE_LAYOUT = 2,
};
diff --git a/super0.c b/super0.c
index ff4905b9..4a462bdc 100644
--- a/super0.c
+++ b/super0.c
@@ -837,6 +837,7 @@ struct devinfo {
int fd;
char *devname;
mdu_disk_info_t disk;
+ unsigned long long dev_size;
struct devinfo *next;
};
@@ -866,6 +867,10 @@ static int add_to_super0(struct supertype *st, mdu_disk_info_t *dinfo,
di->devname = devname;
di->disk = *dinfo;
di->next = NULL;
+
+ if (is_fd_valid(fd))
+ get_dev_size(fd, NULL, &di->dev_size);
+
*dip = di;
return 0;
@@ -929,6 +934,33 @@ static int write_init_super0(struct supertype *st)
int rv = 0;
struct devinfo *di;
+ if (sb->level == 0 && sb->layout == UnSet) {
+ /* Without requesting a dangerous (0) layout
+ * we can only allow this RAID0 if all devices are
+ * the same size
+ */
+ unsigned long long chunks = 0;
+ unsigned long chunk_sectors = sb->chunk_size >> 9;
+
+ for (di = st->info; di; di = di->next) {
+ unsigned long long this_chunks;
+
+ this_chunks = st->ss->avail_size(st, di->dev_size, 0) / chunk_sectors;
+
+ if (chunks == 0) {
+ chunks = this_chunks;
+ continue;
+ }
+
+ if (this_chunks != chunks) {
+ pr_err("Need explicit layout=dangerous to create 0.90 raid0 on non-uniform sized devices\n");
+ return 1;
+ }
+ }
+ /* looks safe */
+ sb->layout = 0;
+ }
+
for (di = st->info ; di && ! rv ; di = di->next) {
if (di->disk.state & (1 << MD_DISK_FAULTY))
@@ -1321,7 +1353,7 @@ static int validate_geometry0(struct supertype *st, int level,
if (*chunk == UnSet)
*chunk = DEFAULT_CHUNK;
- if (level == 0 && layout != UnSet) {
+ if (level == 0 && layout != UnSet && layout != RAID0_DANGEROUS_LAYOUT) {
if (verbose)
pr_err("0.90 metadata does not support layouts for RAID0\n");
return 0;
diff --git a/super1.c b/super1.c
index c828b682..fb93f462 100644
--- a/super1.c
+++ b/super1.c
@@ -1677,6 +1677,10 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info,
sizeof(sb->set_name) - namelen);
}
+ if (info->level == 0 && info->layout == UnSet)
+ /* Metadata chooses default layout for RAID0 */
+ info->layout = RAID0_ORIG_LAYOUT;
+
sb->ctime = __cpu_to_le64((unsigned long long)time(0));
sb->level = __cpu_to_le32(info->level);
sb->layout = __cpu_to_le32(info->layout);
diff --git a/tests/00raid0 b/tests/00raid0
index 6407c320..94abcd49 100644
--- a/tests/00raid0
+++ b/tests/00raid0
@@ -6,8 +6,8 @@ check raid0
testdev $md0 3 $mdsize2_l 512
mdadm -S $md0
-# verify raid0 with layouts fail for 0.90
-mdadm -CR $md0 -e0.90 -l0 -n4 $dev0 $dev1 $dev2 $dev3
+# verify raid0 with explicit layouts fail for 0.90
+mdadm -CR $md0 -e0.90 -l0 --layout=original -n4 $dev0 $dev1 $dev2 $dev3
check opposite_result
# now with no superblock
--
2.41.0

View File

@ -0,0 +1,45 @@
From b532421e747d75223c6f7a065fb643d2d318011c Mon Sep 17 00:00:00 2001
From: Paul Luse <paul.e.luse@intel.com>
Date: Thu, 24 Apr 2025 07:30:10 -0700
Subject: [PATCH 29/37] Update tests.yml
Signed-off-by: Paul Luse <paul.e.luse@intel.com>
---
.github/workflows/tests.yml | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index ce940108..6f8e2b8e 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -31,9 +31,15 @@ jobs:
- name: 'Prepare machine'
run: |
cd ..
- vagrant halt
+ vagrant snapshot restore clean_vm_v42
+ echo "FYI vagrant restore command finished with exit code: $?"
+ sleep 2
vagrant status
vagrant up
+ sleep 2
+ vagrant ssh -c "sudo timedatectl set-timezone UTC && \
+ sudo systemctl restart chronyd && sudo chronyc -a makestep && sleep 1"
+ echo "FYI vagrant time command finished with exit code: $?"
- name: 'Run tests'
id: testing
@@ -69,9 +75,7 @@ jobs:
runs-on: self-hosted
needs: [upstream_tests]
steps:
- - name: Restore clean VM
+ - name: Halt VM
run: |
cd ..
- vagrant up
- vagrant ssh -c "sudo mdadm -Ss"
vagrant halt
--
2.41.0

View File

@ -0,0 +1,26 @@
From 07bde560b71a2f6e36de5bc6f24e07e761c1c83b Mon Sep 17 00:00:00 2001
From: Paul Luse <paul.e.luse@intel.com>
Date: Thu, 24 Apr 2025 08:38:29 -0700
Subject: [PATCH 30/37] Update tests.yml
Signed-off-by: Paul Luse <paul.e.luse@intel.com>
---
.github/workflows/tests.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 6f8e2b8e..b4c156c0 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -65,7 +65,7 @@ jobs:
if: ${{ steps.testing.outcome == 'failure' }}
run: |
cd ..
- sudo rm /home/ci/actions-runner/_work/mdadm/logs/*.log
+ sudo rm -rf /home/ci/actions-runner/_work/mdadm/logs/*.log
- name: "Set failed"
if: ${{ steps.testing.outcome == 'failure' }}
--
2.41.0

View File

@ -0,0 +1,26 @@
From affe2168b807ccd48f00dc9e021196a5e2e83870 Mon Sep 17 00:00:00 2001
From: Paul Luse <paul.e.luse@intel.com>
Date: Thu, 24 Apr 2025 08:41:15 -0700
Subject: [PATCH 31/37] Update tests.yml
Signed-off-by: Paul Luse <paul.e.luse@intel.com>
---
.github/workflows/tests.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index b4c156c0..9b361571 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -37,7 +37,7 @@ jobs:
vagrant status
vagrant up
sleep 2
- vagrant ssh -c "sudo timedatectl set-timezone UTC && \
+ vagrant ssh -c "uname -r && sudo timedatectl set-timezone UTC && \
sudo systemctl restart chronyd && sudo chronyc -a makestep && sleep 1"
echo "FYI vagrant time command finished with exit code: $?"
--
2.41.0

View File

@ -0,0 +1,29 @@
From 5fd2f5da6fe7995190627f8a7bd9f6ff90aad1d4 Mon Sep 17 00:00:00 2001
From: Paul Luse <paul.e.luse@intel.com>
Date: Thu, 24 Apr 2025 09:03:32 -0700
Subject: [PATCH 32/37] Update tests.yml
Signed-off-by: Paul Luse <paul.e.luse@intel.com>
---
.github/workflows/tests.yml | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 9b361571..2556fccf 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -37,9 +37,8 @@ jobs:
vagrant status
vagrant up
sleep 2
- vagrant ssh -c "uname -r && sudo timedatectl set-timezone UTC && \
- sudo systemctl restart chronyd && sudo chronyc -a makestep && sleep 1"
- echo "FYI vagrant time command finished with exit code: $?"
+ vagrant ssh -c "uname -r"
+ echo "FYI vagrant uname command finished with exit code: $?"
- name: 'Run tests'
id: testing
--
2.41.0

View File

@ -0,0 +1,22 @@
From 97ee409451a7191d3d2861b6718f79116f80b4ec Mon Sep 17 00:00:00 2001
From: Paul E Luse <paul.e.luse@intel.com>
Date: Thu, 24 Apr 2025 18:22:54 +0200
Subject: [PATCH 33/37] This is a test for CI, do not merge
Signed-off-by: Paul E Luse <paul.e.luse@intel.com>
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index 029e0ee2..426e3512 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
+test
**mdadm** is a utility used to create and manage **software RAID** devices implemented through
**Multiple devices driver (MD)** in kernel. It supports following RAID metadata formats:
--
2.41.0

View File

@ -0,0 +1,24 @@
From f5ff81d14fdd34f770120a057804d6067fd5035b Mon Sep 17 00:00:00 2001
From: Paul Luse <paul.e.luse@intel.com>
Date: Thu, 24 Apr 2025 09:48:56 -0700
Subject: [PATCH 34/37] Update README.md
Needed to remove the word "test" as part of testing updated CI workflow.
Signed-off-by: Paul Luse <paul.e.luse@intel.com>
---
README.md | 1 -
1 file changed, 1 deletion(-)
diff --git a/README.md b/README.md
index 426e3512..029e0ee2 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,3 @@
-test
**mdadm** is a utility used to create and manage **software RAID** devices implemented through
**Multiple devices driver (MD)** in kernel. It supports following RAID metadata formats:
--
2.41.0

View File

@ -0,0 +1,183 @@
From bd648e3bec3d883d2f4addea84ac1ac8790c75e9 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mtkaczyk@kernel.org>
Date: Fri, 7 Mar 2025 11:38:48 +0100
Subject: [PATCH 35/37] mdadm: Remove klibc and uclibc support
Klibc compilation is not working for at least 3 years because of
following error:
mdadm.h:1912:15: error: unknown type name 'sighandler_t'
It will have a conflict with le/be_to_cpu() functions family provided by
asm/byteorder.h which will be included with raid/md_p.h. Therefore we
need to remove support for it. Also, remove uclibc because it is not actively
maintained.
Remove klibc and uclibc targets from Makefile and special klibc code.
Targets can be removed safely because using CC is recommended.
Signed-off-by: Mariusz Tkaczyk <mtkaczyk@kernel.org>
---
Makefile | 34 +++-------------------------------
README.md | 3 ---
mdadm.h | 37 +------------------------------------
3 files changed, 4 insertions(+), 70 deletions(-)
diff --git a/Makefile b/Makefile
index bcd092de..387e4a56 100644
--- a/Makefile
+++ b/Makefile
@@ -31,16 +31,6 @@
# define "CXFLAGS" to give extra flags to CC.
# e.g. make CXFLAGS=-O to optimise
CXFLAGS ?=-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE
-TCC = tcc
-UCLIBC_GCC = $(shell for nm in i386-uclibc-linux-gcc i386-uclibc-gcc; do which $$nm > /dev/null && { echo $$nm ; exit; } ; done; echo false No uclibc found )
-#DIET_GCC = diet gcc
-# sorry, but diet-libc doesn't know about posix_memalign,
-# so we cannot use it any more.
-DIET_GCC = gcc -DHAVE_STDINT_H
-
-KLIBC=/home/src/klibc/klibc-0.77
-
-KLIBC_GCC = gcc -nostdinc -iwithprefix include -I$(KLIBC)/klibc/include -I$(KLIBC)/linux/include -I$(KLIBC)/klibc/arch/i386/include -I$(KLIBC)/klibc/include/bits32
ifdef COVERITY
COVERITY_FLAGS=-include coverity-gcc-hack.h
@@ -225,8 +215,6 @@ everything: all swap_super test_stripe raid6check \
mdadm.Os mdadm.O2 man
everything-test: all swap_super test_stripe \
mdadm.Os mdadm.O2 man
-# mdadm.uclibc doesn't work on x86-64
-# mdadm.tcc doesn't work..
%.o: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) $(COVERITY_FLAGS) -o $@ -c $<
@@ -237,13 +225,6 @@ mdadm : $(OBJS) | check_rundir
mdadm.static : $(OBJS) $(STATICOBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -static -o mdadm.static $(OBJS) $(STATICOBJS) $(LDLIBS)
-mdadm.tcc : $(SRCS) $(INCL)
- $(TCC) -o mdadm.tcc $(SRCS)
-
-mdadm.klibc : $(SRCS) $(INCL)
- rm -f $(OBJS)
- $(CC) -nostdinc -iwithprefix include -I$(KLIBC)/klibc/include -I$(KLIBC)/linux/include -I$(KLIBC)/klibc/arch/i386/include -I$(KLIBC)/klibc/include/bits32 $(CFLAGS) $(SRCS)
-
mdadm.Os : $(SRCS) $(INCL)
$(CC) -o mdadm.Os $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -DHAVE_STDINT_H -Os $(SRCS) $(LDLIBS)
@@ -298,15 +279,6 @@ install : install-bin install-man install-udev
install-static : mdadm.static install-man
$(INSTALL) -D $(STRIP) -m 755 mdadm.static $(DESTDIR)$(BINDIR)/mdadm
-install-tcc : mdadm.tcc install-man
- $(INSTALL) -D $(STRIP) -m 755 mdadm.tcc $(DESTDIR)$(BINDIR)/mdadm
-
-install-uclibc : mdadm.uclibc install-man
- $(INSTALL) -D $(STRIP) -m 755 mdadm.uclibc $(DESTDIR)$(BINDIR)/mdadm
-
-install-klibc : mdadm.klibc install-man
- $(INSTALL) -D $(STRIP) -m 755 mdadm.klibc $(DESTDIR)$(BINDIR)/mdadm
-
install-man: mdadm.8 md.4 mdadm.conf.5 mdmon.8
$(INSTALL) -D -m 644 mdadm.8 $(DESTDIR)$(MAN8DIR)/mdadm.8
$(INSTALL) -D -m 644 mdmon.8 $(DESTDIR)$(MAN8DIR)/mdmon.8
@@ -354,9 +326,9 @@ test: mdadm mdmon test_stripe swap_super raid6check
clean :
rm -f mdadm mdmon $(OBJS) $(MON_OBJS) $(STATICOBJS) core *.man \
- mdadm.tcc mdadm.uclibc mdadm.static *.orig *.porig *.rej *.alt \
- .merge_file_* mdadm.Os mdadm.O2 mdmon.O2 swap_super init.cpio.gz \
- mdadm.uclibc.static test_stripe raid6check raid6check.o mdmon mdadm.8
+ mdadm.static *.orig *.porig *.rej *.alt merge_file_* \
+ mdadm.Os mdadm.O2 mdmon.O2 swap_super init.cpio.gz \
+ test_stripe raid6check raid6check.o mdmon mdadm.8
rm -rf cov-int
dist : clean
diff --git a/README.md b/README.md
index 029e0ee2..ba611ec5 100644
--- a/README.md
+++ b/README.md
@@ -135,9 +135,6 @@ List of installation targets:
The following targets are deprecated and should not be used:
- `install-static`
-- `install-tcc`
-- `install-uclibc`
-- `install-klibc`
# License
diff --git a/mdadm.h b/mdadm.h
index 0ea83ad3..592bd1ba 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -43,6 +43,7 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence));
#include <sys/time.h>
#include <getopt.h>
#include <fcntl.h>
+#include <ftw.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
@@ -189,7 +190,6 @@ struct dlm_lksb {
((x) & 0x00000000ff000000ULL) << 8 | \
((x) & 0x000000ff00000000ULL) >> 8)
-#if !defined(__KLIBC__)
#if BYTE_ORDER == LITTLE_ENDIAN
#define __cpu_to_le16(_x) (unsigned int)(_x)
#define __cpu_to_le32(_x) (unsigned int)(_x)
@@ -221,7 +221,6 @@ struct dlm_lksb {
#else
# error "unknown endianness."
#endif
-#endif /* __KLIBC__ */
/*
* Partially stolen from include/linux/unaligned/packed_struct.h
@@ -1530,40 +1529,6 @@ extern void sysfsline(char *line);
struct stat64;
#endif
-#define HAVE_NFTW we assume
-#define HAVE_FTW
-
-#ifdef __UCLIBC__
-# include <features.h>
-# ifndef __UCLIBC_HAS_LFS__
-# define lseek64 lseek
-# endif
-# ifndef __UCLIBC_HAS_FTW__
-# undef HAVE_FTW
-# undef HAVE_NFTW
-# endif
-#endif
-
-#ifdef __dietlibc__
-# undef HAVE_NFTW
-#endif
-
-#if defined(__KLIBC__)
-# undef HAVE_NFTW
-# undef HAVE_FTW
-#endif
-
-#ifndef HAVE_NFTW
-# define FTW_PHYS 1
-# ifndef HAVE_FTW
- struct FTW {};
-# endif
-#endif
-
-#ifdef HAVE_FTW
-# include <ftw.h>
-#endif
-
extern int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s);
extern int Manage_ro(char *devname, int fd, int readonly);
--
2.41.0

View File

@ -0,0 +1,96 @@
From 696207860f408534651db89c5b40133f5903fa25 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mtkaczyk@kernel.org>
Date: Fri, 7 Mar 2025 12:10:58 +0100
Subject: [PATCH 36/37] mdadm: include asm/byteorder.h
It will be included by raid/md_p.h anyway. Include it directly and
remove custom functions. It is not a problem now.
Signed-off-by: Mariusz Tkaczyk <mtkaczyk@kernel.org>
---
mdadm.h | 55 +------------------------------------------------------
1 file changed, 1 insertion(+), 54 deletions(-)
diff --git a/mdadm.h b/mdadm.h
index 592bd1ba..7471cedc 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -34,6 +34,7 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence));
#endif
#include <assert.h>
+#include <asm/byteorder.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdarg.h>
@@ -85,7 +86,6 @@ struct dlm_lksb {
#endif
#include <linux/kdev_t.h>
-/*#include <linux/fs.h> */
#include <sys/mount.h>
#include <asm/types.h>
#include <sys/ioctl.h>
@@ -169,59 +169,6 @@ struct dlm_lksb {
#include "msg.h"
#include "mdadm_status.h"
-#include <endian.h>
-/* Redhat don't like to #include <asm/byteorder.h>, and
- * some time include <linux/byteorder/xxx_endian.h> isn't enough,
- * and there is no standard conversion function so... */
-/* And dietlibc doesn't think byteswap is ok, so.. */
-/* #include <byteswap.h> */
-#define __mdadm_bswap_16(x) (((x) & 0x00ffU) << 8 | \
- ((x) & 0xff00U) >> 8)
-#define __mdadm_bswap_32(x) (((x) & 0x000000ffU) << 24 | \
- ((x) & 0xff000000U) >> 24 | \
- ((x) & 0x0000ff00U) << 8 | \
- ((x) & 0x00ff0000U) >> 8)
-#define __mdadm_bswap_64(x) (((x) & 0x00000000000000ffULL) << 56 | \
- ((x) & 0xff00000000000000ULL) >> 56 | \
- ((x) & 0x000000000000ff00ULL) << 40 | \
- ((x) & 0x00ff000000000000ULL) >> 40 | \
- ((x) & 0x0000000000ff0000ULL) << 24 | \
- ((x) & 0x0000ff0000000000ULL) >> 24 | \
- ((x) & 0x00000000ff000000ULL) << 8 | \
- ((x) & 0x000000ff00000000ULL) >> 8)
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define __cpu_to_le16(_x) (unsigned int)(_x)
-#define __cpu_to_le32(_x) (unsigned int)(_x)
-#define __cpu_to_le64(_x) (unsigned long long)(_x)
-#define __le16_to_cpu(_x) (unsigned int)(_x)
-#define __le32_to_cpu(_x) (unsigned int)(_x)
-#define __le64_to_cpu(_x) (unsigned long long)(_x)
-
-#define __cpu_to_be16(_x) __mdadm_bswap_16(_x)
-#define __cpu_to_be32(_x) __mdadm_bswap_32(_x)
-#define __cpu_to_be64(_x) __mdadm_bswap_64(_x)
-#define __be16_to_cpu(_x) __mdadm_bswap_16(_x)
-#define __be32_to_cpu(_x) __mdadm_bswap_32(_x)
-#define __be64_to_cpu(_x) __mdadm_bswap_64(_x)
-#elif BYTE_ORDER == BIG_ENDIAN
-#define __cpu_to_le16(_x) __mdadm_bswap_16(_x)
-#define __cpu_to_le32(_x) __mdadm_bswap_32(_x)
-#define __cpu_to_le64(_x) __mdadm_bswap_64(_x)
-#define __le16_to_cpu(_x) __mdadm_bswap_16(_x)
-#define __le32_to_cpu(_x) __mdadm_bswap_32(_x)
-#define __le64_to_cpu(_x) __mdadm_bswap_64(_x)
-
-#define __cpu_to_be16(_x) (unsigned int)(_x)
-#define __cpu_to_be32(_x) (unsigned int)(_x)
-#define __cpu_to_be64(_x) (unsigned long long)(_x)
-#define __be16_to_cpu(_x) (unsigned int)(_x)
-#define __be32_to_cpu(_x) (unsigned int)(_x)
-#define __be64_to_cpu(_x) (unsigned long long)(_x)
-#else
-# error "unknown endianness."
-#endif
-
/*
* Partially stolen from include/linux/unaligned/packed_struct.h
*/
--
2.41.0

View File

@ -0,0 +1,346 @@
From f5889f9a1b8753a1472dfef9d025da2bae395239 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mtkaczyk@kernel.org>
Date: Mon, 10 Mar 2025 11:16:28 +0100
Subject: [PATCH 37/37] mdadm: use kernel raid headers
For a years we redefined these headers in mdadm. We should reuse headers
exported by kernel to integrate driver and mdadm better.
Include them and remove mdadm owned headers.
There are 3 defines not available in kernel headers, so define them
directly but put them in ifndef guard to make them transparent later.
Use MD_FEATURE_CLUSTERED instead of MD_FEATURE_BITMAP_VERSIONED. The
value is same, kernel define has different name.
Signed-off-by: Mariusz Tkaczyk <mtkaczyk@kernel.org>
---
Create.c | 2 -
Detail.c | 2 -
Examine.c | 2 -
Grow.c | 6 ---
Kill.c | 2 -
Manage.c | 2 -
Query.c | 2 -
mdadm.h | 16 ++++++-
mdmonitor.c | 2 -
super1.c | 126 ++--------------------------------------------------
udev.c | 2 -
11 files changed, 17 insertions(+), 147 deletions(-)
diff --git a/Create.c b/Create.c
index 2b181dbf..de90b0b8 100644
--- a/Create.c
+++ b/Create.c
@@ -23,8 +23,6 @@
*/
#include "mdadm.h"
-#include "md_u.h"
-#include "md_p.h"
#include "udev.h"
#include "xmalloc.h"
diff --git a/Detail.c b/Detail.c
index b804a624..3802ef8f 100644
--- a/Detail.c
+++ b/Detail.c
@@ -23,8 +23,6 @@
*/
#include "mdadm.h"
-#include "md_p.h"
-#include "md_u.h"
#include "xmalloc.h"
#include <ctype.h>
diff --git a/Examine.c b/Examine.c
index 036b7a56..9c8564be 100644
--- a/Examine.c
+++ b/Examine.c
@@ -24,8 +24,6 @@
#include "dlink.h"
#include "mdadm.h"
-#include "md_u.h"
-#include "md_p.h"
#include "xmalloc.h"
#if ! defined(__BIG_ENDIAN) && ! defined(__LITTLE_ENDIAN)
diff --git a/Grow.c b/Grow.c
index 53b0b387..30eaa3c6 100644
--- a/Grow.c
+++ b/Grow.c
@@ -30,12 +30,6 @@
#include <stdint.h>
#include <sys/wait.h>
-#if ! defined(__BIG_ENDIAN) && ! defined(__LITTLE_ENDIAN)
-#error no endian defined
-#endif
-#include "md_u.h"
-#include "md_p.h"
-
int restore_backup(struct supertype *st,
struct mdinfo *content,
int working_disks,
diff --git a/Kill.c b/Kill.c
index 43c9abed..9f05a1ac 100644
--- a/Kill.c
+++ b/Kill.c
@@ -26,8 +26,6 @@
*/
#include "mdadm.h"
-#include "md_u.h"
-#include "md_p.h"
int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl)
{
diff --git a/Manage.c b/Manage.c
index 034eb00c..22b1f52b 100644
--- a/Manage.c
+++ b/Manage.c
@@ -23,8 +23,6 @@
*/
#include "mdadm.h"
-#include "md_u.h"
-#include "md_p.h"
#include "udev.h"
#include "xmalloc.h"
diff --git a/Query.c b/Query.c
index aedb4ce7..72f49a4e 100644
--- a/Query.c
+++ b/Query.c
@@ -23,8 +23,6 @@
*/
#include "mdadm.h"
-#include "md_p.h"
-#include "md_u.h"
int Query(char *dev)
{
diff --git a/mdadm.h b/mdadm.h
index 7471cedc..ce9c216b 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -163,8 +163,20 @@ struct dlm_lksb {
#define GROW_SERVICE "mdadm-grow-continue"
#endif /* GROW_SERVICE */
-#include "md_u.h"
-#include "md_p.h"
+#include <linux/raid/md_u.h>
+#include <linux/raid/md_p.h>
+
+/* These defines might be missing in raid headers*/
+#ifndef MD_SB_BLOCK_CONTAINER_RESHAPE
+#define MD_SB_BLOCK_CONTAINER_RESHAPE 3
+#endif
+#ifndef MD_SB_BLOCK_VOLUME
+#define MD_SB_BLOCK_VOLUME 4
+#endif
+#ifndef MD_DISK_REPLACEMENT
+#define MD_DISK_REPLACEMENT 17
+#endif
+
#include "bitmap.h"
#include "msg.h"
#include "mdadm_status.h"
diff --git a/mdmonitor.c b/mdmonitor.c
index d1cfbf94..d51617cd 100644
--- a/mdmonitor.c
+++ b/mdmonitor.c
@@ -23,8 +23,6 @@
*/
#include "mdadm.h"
-#include "md_p.h"
-#include "md_u.h"
#include "udev.h"
#include "xmalloc.h"
diff --git a/super1.c b/super1.c
index fb93f462..84d73573 100644
--- a/super1.c
+++ b/super1.c
@@ -26,92 +26,6 @@
#include "mdadm.h"
#include "xmalloc.h"
-/*
- * The version-1 superblock :
- * All numeric fields are little-endian.
- *
- * total size: 256 bytes plus 2 per device.
- * 1K allows 384 devices.
- */
-struct mdp_superblock_1 {
- /* constant array information - 128 bytes */
- __u32 magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian */
- __u32 major_version; /* 1 */
- __u32 feature_map; /* 0 for now */
- __u32 pad0; /* always set to 0 when writing */
-
- __u8 set_uuid[16]; /* user-space generated. */
- char set_name[32]; /* set and interpreted by user-space */
-
- __u64 ctime; /* lo 40 bits are seconds, top 24 are microseconds or 0*/
- __u32 level; /* -4 (multipath), -1 (linear), 0,1,4,5 */
- __u32 layout; /* used for raid5, raid6, raid10, and raid0 */
- __u64 size; /* used size of component devices, in 512byte sectors */
-
- __u32 chunksize; /* in 512byte sectors */
- __u32 raid_disks;
- union {
- __u32 bitmap_offset; /* sectors after start of superblock that bitmap starts
- * NOTE: signed, so bitmap can be before superblock
- * only meaningful of feature_map[0] is set.
- */
-
- /* only meaningful when feature_map[MD_FEATURE_PPL] is set */
- struct {
- __s16 offset; /* sectors from start of superblock that ppl starts */
- __u16 size; /* ppl size in sectors */
- } ppl;
- };
-
- /* These are only valid with feature bit '4' */
- __u32 new_level; /* new level we are reshaping to */
- __u64 reshape_position; /* next address in array-space for reshape */
- __u32 delta_disks; /* change in number of raid_disks */
- __u32 new_layout; /* new layout */
- __u32 new_chunk; /* new chunk size (sectors) */
- __u32 new_offset; /* signed number to add to data_offset in new
- * layout. 0 == no-change. This can be
- * different on each device in the array.
- */
-
- /* constant this-device information - 64 bytes */
- __u64 data_offset; /* sector start of data, often 0 */
- __u64 data_size; /* sectors in this device that can be used for data */
- __u64 super_offset; /* sector start of this superblock */
- union {
- __u64 recovery_offset;/* sectors before this offset (from data_offset) have been recovered */
- __u64 journal_tail;/* journal tail of journal device (from data_offset) */
- };
- __u32 dev_number; /* permanent identifier of this device - not role in raid */
- __u32 cnt_corrected_read; /* number of read errors that were corrected by re-writing */
- __u8 device_uuid[16]; /* user-space setable, ignored by kernel */
- __u8 devflags; /* per-device flags. Only one defined...*/
-#define WriteMostly1 1 /* mask for writemostly flag in above */
-#define FailFast1 2 /* Device should get FailFast requests */
- /* bad block log. If there are any bad blocks the feature flag is set.
- * if offset and size are non-zero, that space is reserved and available.
- */
- __u8 bblog_shift; /* shift from sectors to block size for badblock list */
- __u16 bblog_size; /* number of sectors reserved for badblock list */
- __u32 bblog_offset; /* sector offset from superblock to bblog, signed */
-
- /* array state information - 64 bytes */
- __u64 utime; /* 40 bits second, 24 bits microseconds */
- __u64 events; /* incremented when superblock updated */
- __u64 resync_offset; /* data before this offset (from data_offset) known to be in sync */
- __u32 sb_csum; /* checksum upto dev_roles[max_dev] */
- __u32 max_dev; /* size of dev_roles[] array to consider */
- __u8 pad3[64-32]; /* set to 0 when writing */
-
- /* device state information. Indexed by dev_number.
- * 2 bytes per device
- * Note there are no per-device state flags. State information is rolled
- * into the 'roles' value. If a device is spare or faulty, then it doesn't
- * have a meaningful role.
- */
- __u16 dev_roles[0]; /* role in array, or 0xffff for a spare, or 0xfffe for faulty */
-};
-
#define MAX_SB_SIZE 4096
/* bitmap super size is 256, but we round up to a sector for alignment */
#define BM_SUPER_SIZE 512
@@ -126,40 +40,6 @@ struct misc_dev_info {
#define MULTIPLE_PPL_AREA_SIZE_SUPER1 (1024 * 1024) /* Size of the whole
* mutliple PPL area
*/
-/* feature_map bits */
-#define MD_FEATURE_BITMAP_OFFSET 1
-#define MD_FEATURE_RECOVERY_OFFSET 2 /* recovery_offset is present and
- * must be honoured
- */
-#define MD_FEATURE_RESHAPE_ACTIVE 4
-#define MD_FEATURE_BAD_BLOCKS 8 /* badblock list is not empty */
-#define MD_FEATURE_REPLACEMENT 16 /* This device is replacing an
- * active device with same 'role'.
- * 'recovery_offset' is also set.
- */
-#define MD_FEATURE_RESHAPE_BACKWARDS 32 /* Reshape doesn't change number
- * of devices, but is going
- * backwards anyway.
- */
-#define MD_FEATURE_NEW_OFFSET 64 /* new_offset must be honoured */
-#define MD_FEATURE_BITMAP_VERSIONED 256 /* bitmap version number checked properly */
-#define MD_FEATURE_JOURNAL 512 /* support write journal */
-#define MD_FEATURE_PPL 1024 /* support PPL */
-#define MD_FEATURE_MUTLIPLE_PPLS 2048 /* support for multiple PPLs */
-#define MD_FEATURE_RAID0_LAYOUT 4096 /* layout is meaningful in RAID0 */
-#define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET \
- |MD_FEATURE_RECOVERY_OFFSET \
- |MD_FEATURE_RESHAPE_ACTIVE \
- |MD_FEATURE_BAD_BLOCKS \
- |MD_FEATURE_REPLACEMENT \
- |MD_FEATURE_RESHAPE_BACKWARDS \
- |MD_FEATURE_NEW_OFFSET \
- |MD_FEATURE_BITMAP_VERSIONED \
- |MD_FEATURE_JOURNAL \
- |MD_FEATURE_PPL \
- |MD_FEATURE_MULTIPLE_PPLS \
- |MD_FEATURE_RAID0_LAYOUT \
- )
static int role_from_sb(struct mdp_superblock_1 *sb)
{
@@ -319,7 +199,7 @@ static int awrite(struct align_fd *afd, void *buf, int len)
static inline unsigned int md_feature_any_ppl_on(__u32 feature_map)
{
return ((__cpu_to_le32(feature_map) &
- (MD_FEATURE_PPL | MD_FEATURE_MUTLIPLE_PPLS)));
+ (MD_FEATURE_PPL | MD_FEATURE_MULTIPLE_PPLS)));
}
static inline unsigned int choose_ppl_space(int chunk)
@@ -1483,7 +1363,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
}
case UOPT_NO_PPL:
sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_PPL |
- MD_FEATURE_MUTLIPLE_PPLS);
+ MD_FEATURE_MULTIPLE_PPLS);
break;
case UOPT_DEVICESIZE:
if (__le64_to_cpu(sb->super_offset) >=
@@ -2650,7 +2530,7 @@ add_internal_bitmap1(struct supertype *st,
bms->nodes = __cpu_to_le32(st->nodes);
if (st->nodes)
sb->feature_map = __cpu_to_le32(__le32_to_cpu(sb->feature_map) |
- MD_FEATURE_BITMAP_VERSIONED);
+ MD_FEATURE_CLUSTERED);
if (st->cluster_name) {
len = sizeof(bms->cluster_name);
strncpy((char *)bms->cluster_name, st->cluster_name, len);
diff --git a/udev.c b/udev.c
index 88a99781..961ca970 100644
--- a/udev.c
+++ b/udev.c
@@ -20,8 +20,6 @@
#include "mdadm.h"
#include "udev.h"
-#include "md_p.h"
-#include "md_u.h"
#include "xmalloc.h"
#include <sys/wait.h>
--
2.41.0

View File

@ -0,0 +1,30 @@
From 32ab389711c718e1690e6f63c21adbd8b84b010a Mon Sep 17 00:00:00 2001
From: Paul Luse <paul.e.luse@intel.com>
Date: Wed, 30 Apr 2025 14:04:14 -0700
Subject: [PATCH 38/74] Update tests.yml
Signed-off-by: Paul Luse <paul.e.luse@intel.com>
---
.github/workflows/tests.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 2556fccfb99b..73082fd2ef15 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -37,9 +37,9 @@ jobs:
vagrant status
vagrant up
sleep 2
- vagrant ssh -c "uname -r"
- echo "FYI vagrant uname command finished with exit code: $?"
-
+ vagrant ssh -c "sudo timedatectl set-timezone UTC && \
+ sudo systemctl restart chronyd && sudo chronyc -a makestep && sleep 1 && uname -r"
+ echo "FYI vagrant time command finished with exit code: $?"
- name: 'Run tests'
id: testing
continue-on-error: true
--
2.50.1

View File

@ -0,0 +1,28 @@
From 02b7cacefe080c7c0f55b942b26bfcae9297587b Mon Sep 17 00:00:00 2001
From: Paul Luse <paul.e.luse@intel.com>
Date: Wed, 30 Apr 2025 17:45:32 -0700
Subject: [PATCH 39/74] Update tests.yml
Signed-off-by: Paul Luse <paul.e.luse@intel.com>
---
.github/workflows/tests.yml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 73082fd2ef15..ddba632dc13c 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -31,7 +31,9 @@ jobs:
- name: 'Prepare machine'
run: |
cd ..
- vagrant snapshot restore clean_vm_v42
+ # to upgrade the VMs to Fed42, comment the next line out and uncomment the one below that.
+ vagrant snapshot restore clean_vm_v1
+ # vagrant snapshot restore clean_vm_v42
echo "FYI vagrant restore command finished with exit code: $?"
sleep 2
vagrant status
--
2.50.1

View File

@ -0,0 +1,33 @@
From e05b13f97db18dfa98814fcebd9d1b58b9fcb8cd Mon Sep 17 00:00:00 2001
From: Paul Luse <paul.e.luse@intel.com>
Date: Thu, 1 May 2025 12:18:17 -0700
Subject: [PATCH 40/74] Update run_mdadm_tests.sh
Signed-off-by: Paul Luse <paul.e.luse@intel.com>
---
.github/tools/run_mdadm_tests.sh | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/.github/tools/run_mdadm_tests.sh b/.github/tools/run_mdadm_tests.sh
index 22d89a8c371a..8c287bde860e 100755
--- a/.github/tools/run_mdadm_tests.sh
+++ b/.github/tools/run_mdadm_tests.sh
@@ -2,7 +2,15 @@
sudo make clean
sudo make -j$(nproc)
+if [ $? -ne 0 ]; then
+ echo "Error: make command failed."
+ exit 1
+fi
sudo make install
+if [ $? -ne 0 ]; then
+ echo "Error: make install command failed."
+ exit 1
+fi
sudo mdadm -Ss
sudo ./test setup
--
2.50.1

View File

@ -0,0 +1,65 @@
From 4aa30f1beafc1fed844a0f335e196400adeb1840 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mtkaczyk@kernel.org>
Date: Fri, 11 Apr 2025 14:36:12 +0200
Subject: [PATCH 41/74] tests: support second runner
Second runner has different VM name. Honor that when coping
and removing logs.
Signed-off-by: Mariusz Tkaczyk <mtkaczyk@kernel.org>
---
.github/workflows/tests.yml | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index ddba632dc13c..a07e320b03c4 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -42,6 +42,10 @@ jobs:
vagrant ssh -c "sudo timedatectl set-timezone UTC && \
sudo systemctl restart chronyd && sudo chronyc -a makestep && sleep 1 && uname -r"
echo "FYI vagrant time command finished with exit code: $?"
+
+ - name: Export RUNNER_NAME
+ run: echo "RUNNER_NAME=$RUNNER_NAME" >> $GITHUB_ENV
+
- name: 'Run tests'
id: testing
continue-on-error: true
@@ -55,18 +59,30 @@ jobs:
cd ..
vagrant ssh -c "sudo mkdir -p /home/vagrant/host/logs && sudo mv /var/tmp/*.log /home/vagrant/host/logs"
- - name: "Save artifacts"
- if: ${{ steps.testing.outcome == 'failure' }}
+ - name: "Save artifacts inspur5"
+ if: ${{ steps.testing.outcome == 'failure' && env.RUNNER_NAME == 'inspur5' }}
uses: actions/upload-artifact@v4
with:
name: "Logs from failed tests"
path: /home/ci/actions-runner/_work/mdadm/logs/*.log
+ - name: "Save artifacts inspur5-2"
+ if: ${{ steps.testing.outcome == 'failure' && env.RUNNER_NAME == 'inspur5-2'}}
+ uses: actions/upload-artifact@v4
+ with:
+ name: "Logs from failed tests"
+ path: /home/ci/actions-runner-2/_work/mdadm/logs/*.log
+
- name: "Clean logs"
if: ${{ steps.testing.outcome == 'failure' }}
run: |
cd ..
- sudo rm -rf /home/ci/actions-runner/_work/mdadm/logs/*.log
+
+ if [ "$RUNNER_NAME" == "inspur5" ]; then
+ sudo rm /home/ci/actions-runner/_work/mdadm/logs/*.log
+ else
+ sudo rm /home/ci/actions-runner-2/_work/mdadm/logs/*.log
+ fi
- name: "Set failed"
if: ${{ steps.testing.outcome == 'failure' }}
--
2.50.1

View File

@ -0,0 +1,41 @@
From e270c8f99e90cf89e0c1a0534547e7b4bf285041 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Wed, 30 Apr 2025 21:18:36 +0200
Subject: [PATCH 42/74] mdadm: allow any valid minor number in md device name
Since 25aa732 ("mdadm: numbered names verification"), it is not possible
any more to create arrays /dev/md${N} with N >= 127. The limit has later
been increased to 1024, which is also artificial. The error message printed
by mdadm is misleading, as the problem is not POSIX compatibility here.
# mdadm -C -v /dev/md9999 --name=foo -l1 -n2 /dev/loop0 /dev/loop1
mdadm: Value "/dev/md9999" cannot be set as devname. Reason: Not POSIX compatible.
Given that mdadm creates an array with minor number ${N} if the argument is
/dev/md${N}, the natural limit for the number is the highest minor number
available, which is (1 << MINORBITS) with MINORBITS=20 on Linux.
Fixes: 25aa732 ("mdadm: numbered names verification")
Fixes: f786072 ("mdadm: Increase number limit in md device name to 1024.")
Signed-off-by: Martin Wilck <mwilck@suse.com>
---
util.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/util.c b/util.c
index 9fe2d2276712..0f77521149f8 100644
--- a/util.c
+++ b/util.c
@@ -972,7 +972,8 @@ static bool is_devname_numbered(const char *devname, const char *pref, const int
if (parse_num(&val, devname + pref_len) != 0)
return false;
- if (val > 1024)
+ /* Allow any number that represents a valid minor number */
+ if (val >= (1 << 20))
return false;
return true;
--
2.50.1

View File

@ -0,0 +1,58 @@
From e549ac6ab2ce5e7ec182310f8f5f2e41c6ac9233 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 7 May 2025 18:06:59 +0800
Subject: [PATCH 43/74] mdadm: use standard libc nftw
commit bd648e3bec3d ("mdadm: Remove klibc and uclibc support") removes
macro HAVE_NFTW/HAVE_FTW and uses libc header ftw.h. But it leaves the
codes in lib.c which let mdadm command call nftw defined in lib.c. It
needs to remove these codes.
The bug can be reproduced by:
mdadm -CR /dev/md0 --level raid5 --metadata=1.1 --chunk=32 --raid-disks 3
--size 10000 /dev/loop1 /dev/loop2 /dev/loop3
mdadm /dev/md0 --grow --chunk=64
mdadm: /dev/md0: cannot open component -unknown-
Fixes: bd648e3bec3d ("mdadm: Remove klibc and uclibc support")
Signed-off-by: Xiao Ni <xni@redhat.com>
---
lib.c | 22 ----------------------
1 file changed, 22 deletions(-)
diff --git a/lib.c b/lib.c
index f36ae03a3fa0..eb6cc1194cab 100644
--- a/lib.c
+++ b/lib.c
@@ -245,28 +245,6 @@ int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s)
return 0;
}
-#ifndef HAVE_NFTW
-#ifdef HAVE_FTW
-int add_dev_1(const char *name, const struct stat *stb, int flag)
-{
- return add_dev(name, stb, flag, NULL);
-}
-int nftw(const char *path,
- int (*han)(const char *name, const struct stat *stb,
- int flag, struct FTW *s), int nopenfd, int flags)
-{
- return ftw(path, add_dev_1, nopenfd);
-}
-#else
-int nftw(const char *path,
- int (*han)(const char *name, const struct stat *stb,
- int flag, struct FTW *s), int nopenfd, int flags)
-{
- return 0;
-}
-#endif /* HAVE_FTW */
-#endif /* HAVE_NFTW */
-
/*
* Find a block device with the right major/minor number.
* If we find multiple names, choose the shortest.
--
2.50.1

View File

@ -0,0 +1,67 @@
From f815615ebf74a71064ba480ba773ef4bf98b53b0 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 7 May 2025 18:26:08 +0800
Subject: [PATCH 44/74] mdadm: fix building errors
Some building errors are found in ppc64le platform:
format '%llu' expects argument of type 'long long unsigned int', but
argument 3 has type 'long unsigned int' [-Werror=format=]
Signed-off-by: Xiao Ni <xni@redhat.com>
---
super-ddf.c | 9 +++++----
super-intel.c | 3 ++-
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/super-ddf.c b/super-ddf.c
index 6e7db924d2b1..dda8b7fedd64 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -1606,9 +1606,9 @@ static void examine_vd(int n, struct ddf_super *sb, char *guid)
map_num(ddf_sec_level, vc->srl) ?: "-unknown-");
}
printf(" Device Size[%d] : %llu\n", n,
- be64_to_cpu(vc->blocks)/2);
+ (unsigned long long)(be64_to_cpu(vc->blocks)/2));
printf(" Array Size[%d] : %llu\n", n,
- be64_to_cpu(vc->array_blocks)/2);
+ (unsigned long long)(be64_to_cpu(vc->array_blocks)/2));
}
}
@@ -1665,7 +1665,7 @@ static void examine_pds(struct ddf_super *sb)
printf(" %3d %08x ", i,
be32_to_cpu(pd->refnum));
printf("%8lluK ",
- be64_to_cpu(pd->config_size)>>1);
+ (unsigned long long)be64_to_cpu(pd->config_size)>>1);
for (dl = sb->dlist; dl ; dl = dl->next) {
if (be32_eq(dl->disk.refnum, pd->refnum)) {
char *dv = map_dev(dl->major, dl->minor, 0);
@@ -2901,7 +2901,8 @@ static unsigned int find_unused_pde(const struct ddf_super *ddf)
static void _set_config_size(struct phys_disk_entry *pde, const struct dl *dl)
{
__u64 cfs, t;
- cfs = min(dl->size - 32*1024*2ULL, be64_to_cpu(dl->primary_lba));
+ cfs = min((unsigned long long)dl->size - 32*1024*2ULL,
+ (unsigned long long)(be64_to_cpu(dl->primary_lba)));
t = be64_to_cpu(dl->secondary_lba);
if (t != ~(__u64)0)
cfs = min(cfs, t);
diff --git a/super-intel.c b/super-intel.c
index b7b030a20432..4fbbc98d915c 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -2325,7 +2325,8 @@ static void export_examine_super_imsm(struct supertype *st)
printf("MD_LEVEL=container\n");
printf("MD_UUID=%s\n", nbuf+5);
printf("MD_DEVICES=%u\n", mpb->num_disks);
- printf("MD_CREATION_TIME=%llu\n", __le64_to_cpu(mpb->creation_time));
+ printf("MD_CREATION_TIME=%llu\n",
+ (unsigned long long)__le64_to_cpu(mpb->creation_time));
}
static void detail_super_imsm(struct supertype *st, char *homehost,
--
2.50.1

View File

@ -0,0 +1,34 @@
From a83ecaf17c75734aead366c6de71b6dd42a4a63d Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Wed, 7 May 2025 18:34:20 +0800
Subject: [PATCH 45/74] mdadm: add attribute nonstring for signature
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
It reports building error in f42:
error: initializer-string for array of unsigned char truncates NULL
terminator but destination lacks nonstring attribute (5 chars into 4
available) [-Werror=unterminated-string-initialization]
Signed-off-by: Xiao Ni <xni@redhat.com>
---
platform-intel.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/platform-intel.h b/platform-intel.h
index 63d416826118..f92a9a11c3a0 100644
--- a/platform-intel.h
+++ b/platform-intel.h
@@ -24,7 +24,7 @@
/* The IMSM Capability (IMSM AHCI and ISCU OROM/EFI variable) Version Table definition */
struct imsm_orom {
- __u8 signature[4];
+ __u8 signature[4] __attribute__((nonstring));
#define IMSM_OROM_SIGNATURE "$VER"
#define IMSM_NVME_OROM_COMPAT_SIGNATURE "$NVM"
#define IMSM_VMD_OROM_COMPAT_SIGNATURE "$VMD"
--
2.50.1

View File

@ -0,0 +1,39 @@
From 1640b5c37bb870a9ae36d6e72e09dd8a47aeac43 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Thu, 8 May 2025 11:45:50 +0800
Subject: [PATCH 46/74] mdadm: give more time to wait sync thread to reap
01r5fail case reports error sometimes:
++ '[' -n '2248 / 35840' ']'
++ die 'resync or recovery is happening!'
++ echo -e '\n\tERROR: resync or recovery is happening! \n'
ERROR: resync or recovery is happening!
sync thread is reapped in md_thread. So we need to give more time to
wait sync thread to reap.
Signed-off-by: Xiao Ni <xni@redhat.com>
---
tests/func.sh | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/tests/func.sh b/tests/func.sh
index e42c7d56d9a2..19ad8b3211e3 100644
--- a/tests/func.sh
+++ b/tests/func.sh
@@ -357,7 +357,10 @@ check() {
done
;;
nosync )
- sleep 0.5
+ # sync thread is reapped in md_thread, give it more time to wait sync thread
+ # to reap. Before this change, it gives 0.5s which is too small. Sometimes
+ # the sync thread can't be reapped and error happens
+ sleep 3
# Since 4.2 we delay the close of recovery until there has been a chance for
# spares to be activated. That means that a recovery that finds nothing
# to do can still take a little longer than expected.
--
2.50.1

View File

@ -0,0 +1,38 @@
From 882c8fda76772573acf2000a850106a09413d2e9 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Thu, 8 May 2025 12:45:32 +0800
Subject: [PATCH 47/74] mdadm/tests: mark 10ddf-fail-two-spares broken
Sometimes 10ddf-fail-two-spares fail because:
++ grep -q 'state\[1\] : Optimal, Consistent' /tmp/mdtest-5k3MzO
++ echo ERROR: /dev/md/vol1 should be optimal in meta data
ERROR: /dev/md/vol1 should be optimal in meta data
Mark this as broken.
Signed-off-by: Xiao Ni <xni@redhat.com>
---
tests/10ddf-fail-two-spares.broken | 11 +++++++++++
1 file changed, 11 insertions(+)
create mode 100644 tests/10ddf-fail-two-spares.broken
diff --git a/tests/10ddf-fail-two-spares.broken b/tests/10ddf-fail-two-spares.broken
new file mode 100644
index 000000000000..d0158c042f22
--- /dev/null
+++ b/tests/10ddf-fail-two-spares.broken
@@ -0,0 +1,11 @@
+Sometimes
+
+++ grep -q 'state\[0\] : Optimal, Consistent' /tmp/mdtest-5k3MzO
+++ grep -q 'state\[1\] : Optimal, Consistent' /tmp/mdtest-5k3MzO
+++ echo ERROR: /dev/md/vol1 should be optimal in meta data
+ERROR: /dev/md/vol1 should be optimal in meta data
+
+if ! grep -q 'state\[1\] : Optimal, Consistent' $tmp; then
+ echo ERROR: $member1 should be optimal in meta data
+ ret=1
+fi
--
2.50.1

View File

@ -0,0 +1,52 @@
From 5d4c31e8c1ed273636aa9d9f36d8b6f0ebc9713e Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Thu, 8 May 2025 17:02:13 +0800
Subject: [PATCH 48/74] mdadm/tests: mark 09imsm-assemble broken
09imsm-assemble fails sometimes. So mark it as broken.
Signed-off-by: Xiao Ni <xni@redhat.com>
---
tests/09imsm-assemble.broken | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
create mode 100644 tests/09imsm-assemble.broken
diff --git a/tests/09imsm-assemble.broken b/tests/09imsm-assemble.broken
new file mode 100644
index 000000000000..a139042c99a0
--- /dev/null
+++ b/tests/09imsm-assemble.broken
@@ -0,0 +1,30 @@
+Sometimes
+
+Sometimes it fails:
+++ /usr/sbin/mdadm --remove /dev/md/container /dev/loop2
+++ rv=1
+++ case $* in
+++ cat /var/tmp/stderr
+mdadm: /dev/loop2 is still in use, cannot remove.
+++ return 1
+++ sleep 2
+++ (( i++ ))
+++ (( i<=ret ))
+++ '[' 0 -ne 1 ']'
+++ echo '/dev/loop2 removal from /dev/md/container should have succeeded'
+/dev/loop2 removal from /dev/md/container should have succeeded
+
+Sometimes it fails:
+++ imsm_check_hold /dev/md/container /dev/loop1
+++ mdadm --remove /dev/md/container /dev/loop1
+++ rm -f /var/tmp/stderr
+++ case $* in
+++ case $* in
+++ /usr/sbin/mdadm --remove /dev/md/container /dev/loop1
+++ rv=0
+++ case $* in
+++ cat /var/tmp/stderr
+mdadm: hot removed /dev/loop1 from /dev/md/container
+++ return 0
+++ echo '/dev/loop1 removal from /dev/md/container should have been blocked'
+/dev/loop1 removal from /dev/md/container should have been blocked
--
2.50.1

View File

@ -0,0 +1,44 @@
From 7ecd1fe2d709ad84fbed29b1594f02fad52592cc Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Thu, 8 May 2025 17:56:08 +0800
Subject: [PATCH 49/74] mdadm/tests: mark 10ddf-fail-readd-readonly broken
10ddf-fail-readd-readonly fails sometimes. Mark this case broken.
Signed-off-by: Xiao Ni <xni@redhat.com>
---
tests/10ddf-fail-readd-readonly.broken | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 tests/10ddf-fail-readd-readonly.broken
diff --git a/tests/10ddf-fail-readd-readonly.broken b/tests/10ddf-fail-readd-readonly.broken
new file mode 100644
index 000000000000..500343cd9814
--- /dev/null
+++ b/tests/10ddf-fail-readd-readonly.broken
@@ -0,0 +1,22 @@
+Sometimes
+
+This case fails sometimes like:
+mdadm: cannot open MISSING: No such file or directory
+++ return 1
+++ grep -q 'state\[0\] : Optimal, Consistent' /tmp/mdtest-bDoaoB
+++ echo ERROR: member 0 should be optimal in meta data on MISSING
+ERROR: member 0 should be optimal in meta data on MISSING
+++ ret=1
+++ for x in $@
+++ mdadm -E /dev/loop9
+++ rm -f /var/tmp/stderr
+++ case $* in
+++ case $* in
+++ /usr/sbin/mdadm -E /dev/loop9
+++ rv=0
+++ case $* in
+++ cat /var/tmp/stderr
+++ return 0
+++ grep -q 'state\[0\] : Optimal, Consistent' /tmp/mdtest-bDoaoB
+++ echo ERROR: member 0 should be optimal in meta data on /dev/loop9
+ERROR: member 0 should be optimal in meta data on /dev/loop9
--
2.50.1

View File

@ -0,0 +1,31 @@
From f0667a39f889395f40d8b6c41730e89ac5434c21 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= <nabijaczleweli@nabijaczleweli.xyz>
Date: Tue, 6 May 2025 20:59:29 +0200
Subject: [PATCH 50/74] optim[al]ize; write-indent -> write-intent
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Former is highly non-standard, latter is wrong
Signed-off-by: наб <nabijaczleweli@nabijaczleweli.xyz>
---
mdadm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mdadm.c b/mdadm.c
index 6200cd0e7f9b..14649a40c236 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -1522,7 +1522,7 @@ int main(int argc, char *argv[])
if (s.btype == BitmapUnknown) {
if (c.runstop != 1 && s.level >= 1 &&
- ask("To optimalize recovery speed, it is recommended to enable write-indent bitmap, do you want to enable it now?"))
+ ask("To optimize recovery speed, it is recommended to enable write-intent bitmap, do you want to enable it now?"))
s.btype = BitmapInternal;
else
s.btype = BitmapNone;
--
2.50.1

View File

@ -1,7 +1,7 @@
From 8da27191aa62b08075d8e7ec36c14083f528eb89 Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Fri, 4 Apr 2025 08:44:47 -0400
Subject: [PATCH 1/1] mdadm: enable sync file for udev rules
Subject: [PATCH 51/74] mdadm: enable sync file for udev rules
Mounting an md device may fail during boot from mdadm's claim
on the device not being released before systemd attempts to mount.
@ -97,10 +97,11 @@ Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
Incremental.c | 20 +++++++++++++++-----
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git mdadm-4.2/Create.c mdadm-4.2-fix/Create.c
--- mdadm-4.2/Create.c 2025-06-05 06:17:32.656879914 -0400
+++ mdadm-4.2-fix/Create.c 2025-06-05 07:40:05.583074551 -0400
@@ -1321,8 +1321,8 @@
diff --git a/Create.c b/Create.c
index de90b0b8e781..420b9136c2c2 100644
--- a/Create.c
+++ b/Create.c
@@ -1316,8 +1316,8 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
} else {
pr_err("not starting array - not enough devices.\n");
}
@ -108,29 +109,38 @@ diff --git mdadm-4.2/Create.c mdadm-4.2-fix/Create.c
close(mdfd);
+ udev_unblock();
sysfs_uevent(&info, "change");
return 0;
dev_policy_free(custom_pols);
diff --git mdadm-4.2/Incremental.c mdadm-4.2-fix/Incremental.c
--- mdadm-4.2/Incremental.c 2025-06-05 06:17:32.789874082 -0400
+++ mdadm-4.2-fix/Incremental.c 2025-06-05 07:44:27.126170772 -0400
@@ -29,6 +29,7 @@
*/
diff --git a/Incremental.c b/Incremental.c
index 228d2bdd5de2..ba3810e6157f 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -30,6 +30,7 @@
#include "mdadm.h"
#include "xmalloc.h"
+#include "udev.h"
#include <sys/wait.h>
#include <dirent.h>
#include <ctype.h>
@@ -296,7 +297,7 @@
@@ -286,7 +287,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
/* Couldn't find an existing array, maybe make a new one */
mdfd = create_mddev(match ? match->devname : NULL,
- name_to_use, c->autof, trustworthy, chosen_name, 0);
+ name_to_use, c->autof, trustworthy, chosen_name, 1);
mdfd = create_mddev(match ? match->devname : NULL, name_to_use, trustworthy,
- chosen_name, 0);
+ chosen_name, 1);
if (mdfd < 0)
goto out_unlock;
@@ -474,7 +475,6 @@
@@ -447,7 +448,6 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
info.array.working_disks = 0;
for (d = sra->devs; d; d=d->next)
info.array.working_disks ++;
-
}
if (strncmp(chosen_name, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0)
md_devname = chosen_name + DEV_MD_DIR_LEN;
@@ -464,7 +464,6 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
if (is_container(info.array.level)) {
char devnm[32];
/* Try to assemble within the container */
@ -138,7 +148,7 @@ diff --git mdadm-4.2/Incremental.c mdadm-4.2-fix/Incremental.c
if (!c->export && c->verbose >= 0)
pr_err("container %s now has %d device%s\n",
chosen_name, info.array.working_disks,
@@ -486,6 +486,8 @@
@@ -476,6 +475,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
if (st->ss->load_container)
rv = st->ss->load_container(st, mdfd, NULL);
close(mdfd);
@ -147,7 +157,7 @@ diff --git mdadm-4.2/Incremental.c mdadm-4.2-fix/Incremental.c
sysfs_free(sra);
if (!rv)
rv = Incremental_container(st, chosen_name, c, NULL);
@@ -494,6 +496,7 @@
@@ -484,6 +485,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
* so that it can eg. try to rebuild degraded array */
if (st->ss->external)
ping_monitor(devnm);
@ -155,7 +165,7 @@ diff --git mdadm-4.2/Incremental.c mdadm-4.2-fix/Incremental.c
return rv;
}
@@ -630,7 +633,11 @@
@@ -606,7 +608,11 @@ out:
close(mdfd);
if (policy)
dev_policy_free(policy);
@ -168,16 +178,16 @@ diff --git mdadm-4.2/Incremental.c mdadm-4.2-fix/Incremental.c
return rv;
out_unlock:
map_unlock(&map);
@@ -1577,7 +1584,7 @@
ra->name,
c->autof,
trustworthy,
@@ -1561,7 +1567,7 @@ static int Incremental_container(struct supertype *st, char *devname,
trustworthy = LOCAL;
mdfd = create_mddev(match ? match->devname : NULL, ra->name, trustworthy,
- chosen_name, 0);
+ chosen_name, 1);
if (!is_fd_valid(mdfd)) {
pr_err("create_mddev failed with chosen name %s: %s.\n",
@@ -1597,6 +1604,8 @@
@@ -1581,6 +1587,8 @@ static int Incremental_container(struct supertype *st, char *devname,
map_free(map);
map = NULL;
close_fd(&mdfd);
@ -186,7 +196,7 @@ diff --git mdadm-4.2/Incremental.c mdadm-4.2-fix/Incremental.c
}
if (c->export && result) {
char sep = '=';
@@ -1623,6 +1632,8 @@
@@ -1607,6 +1615,8 @@ static int Incremental_container(struct supertype *st, char *devname,
release:
map_free(map);
sysfs_free(list);
@ -195,3 +205,6 @@ diff --git mdadm-4.2/Incremental.c mdadm-4.2-fix/Incremental.c
return rv;
}
--
2.50.1

View File

@ -0,0 +1,219 @@
From 0550fb37839866bb11ec139780d75f97d0765cfb Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mtkaczyk@kernel.org>
Date: Sat, 5 Apr 2025 19:47:18 +0200
Subject: [PATCH 52/74] mdadm: remove POSIX check
Neil Brown in #159 pointed that mdadm should been keep in base utility
style, allowing much more with no strict limitations until absolutely
necessary to prevent crashes.
This view, supported with regression #160 caused by POSIX portable
character set requirement leads me to revert it.
Revert the POSIX portable character set verification of name and
devname. Make it IMSM only.
Fixes: e2eb503bd797 ("mdadm: Follow POSIX Portable Character Set")
Signed-off-by: Mariusz Tkaczyk <mtkaczyk@kernel.org>
---
config.c | 45 +++++++++------------------------------------
mdadm.8.in | 24 ++++++++----------------
super-intel.c | 11 +++++++++++
tests/00confnames | 13 +++++--------
4 files changed, 33 insertions(+), 60 deletions(-)
diff --git a/config.c b/config.c
index 8a8ae5e48c41..e6ede3bbe45d 100644
--- a/config.c
+++ b/config.c
@@ -188,34 +188,6 @@ inline void ident_init(struct mddev_ident *ident)
ident->uuid_set = 0;
}
-/** ident_check_name() - helper function to verify name.
- * @name: name to check.
- * @prop_name: the name of the property it is validated against, used for logging.
- * @cmdline: context dependent actions.
- *
- * @name must follow name's criteria, be POSIX compatible and does not have leading dot.
- */
-static mdadm_status_t ident_check_name(const char *name, const char *prop_name, const bool cmdline)
-{
- if (!is_string_lq(name, MD_NAME_MAX + 1)) {
- ident_log(prop_name, name, "Too long or empty", cmdline);
- return MDADM_STATUS_ERROR;
- }
-
- if (*name == '.') {
- /* MD device should not be considered as hidden. */
- ident_log(prop_name, name, "Leading dot forbidden", cmdline);
- return MDADM_STATUS_ERROR;
- }
-
- if (!is_name_posix_compatible(name)) {
- ident_log(prop_name, name, "Not POSIX compatible", cmdline);
- return MDADM_STATUS_ERROR;
- }
-
- return MDADM_STATUS_SUCCESS;
-}
-
/**
* _ident_set_devname() - verify devname and set it in &mddev_ident.
* @ident: pointer to &mddev_ident.
@@ -243,7 +215,6 @@ mdadm_status_t _ident_set_devname(struct mddev_ident *ident, const char *devname
static const char named_dev_pref[] = DEV_NUM_PREF "_";
static const int named_dev_pref_size = sizeof(named_dev_pref) - 1;
const char *prop_name = "devname";
- mdadm_status_t ret;
const char *name;
if (ident->devname) {
@@ -270,9 +241,11 @@ mdadm_status_t _ident_set_devname(struct mddev_ident *ident, const char *devname
else
name = devname;
- ret = ident_check_name(name, prop_name, cmdline);
- if (ret)
- return ret;
+ if (!is_string_lq(name, MD_NAME_MAX + 1)) {
+ ident_log(prop_name, name, "Too long or empty", cmdline);
+ return MDADM_STATUS_ERROR;
+ }
+
pass:
ident->devname = xstrdup(devname);
return MDADM_STATUS_SUCCESS;
@@ -294,16 +267,16 @@ mdadm_status_t ident_set_name(struct mddev_ident *ident, const char *name)
assert(ident);
const char *prop_name = "name";
- mdadm_status_t ret;
if (ident->name[0]) {
ident_log(prop_name, name, "Already defined", true);
return MDADM_STATUS_ERROR;
}
- ret = ident_check_name(name, prop_name, true);
- if (ret)
- return ret;
+ if (!is_string_lq(name, MD_NAME_MAX + 1)) {
+ ident_log(prop_name, name, "Too long or empty", true);
+ return MDADM_STATUS_ERROR;
+ }
snprintf(ident->name, MD_NAME_MAX + 1, "%s", name);
return MDADM_STATUS_SUCCESS;
diff --git a/mdadm.8.in b/mdadm.8.in
index 452555216644..2a71e32237d4 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -884,10 +884,8 @@ are used to add different devices).
.BR \-N ", " \-\-name=
Set a
.B name
-for the array. It must be
-.BR "POSIX PORTABLE NAME"
-compatible and cannot be longer than 32 chars. This is effective when creating an array
-with a v1 metadata, or an external array.
+for the array. It cannot be longer than 32 chars. This is effective when
+creating an array with a v1 metadata, or an external array.
If name is needed but not specified, it is taken from the basename of the device
that is being created. See
@@ -1024,11 +1022,9 @@ is much safer.
.TP
.BR \-N ", " \-\-name=
-Specify the name of the array to assemble. It must be
-.BR "POSIX PORTABLE NAME"
-compatible and cannot be longer than 32 chars. This must be the name
-that was specified when creating the array. It must either match
-the name stored in the superblock exactly, or it must match
+Specify the name of the array to assemble. It cannot be longer than 32 chars.
+This must be the name that was specified when creating the array. It must
+either match the name stored in the superblock exactly, or it must match
with the current
.I homehost
prefixed to the start of the given name.
@@ -2236,10 +2232,8 @@ and
The
.B name
-option updates the subarray name in the metadata. It must be
-.BR "POSIX PORTABLE NAME"
-compatible and cannot be longer than 32 chars. If successes, new value will be respected after
-next assembly.
+option updates the subarray name in the metadata. It cannot be longer than
+32 chars. If successes, new value will be respected after next assembly.
The
.B ppl
@@ -3214,9 +3208,7 @@ can be given, or just the suffix of the second sort of name, such as
.I home
can be given.
-In every style, raw name must be compatible with
-.BR "POSIX PORTABLE NAME"
-and has to be no longer than 32 chars.
+In every style, raw name has to be no longer than 32 chars.
When
.I mdadm
diff --git a/super-intel.c b/super-intel.c
index 4fbbc98d915c..40519f8fce2a 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -5630,6 +5630,17 @@ static bool imsm_is_name_allowed(struct intel_super *super, const char * const n
return false;
}
+ if (name[0] == '.') {
+ pr_vrb("imsm: Name \"%s\" has forbidden leading dot", name);
+ return false;
+ }
+
+ if (is_name_posix_compatible(name) == false) {
+ pr_vrb("imsm: Name \"%s\" doesn't follow POSIX portable file name character set",
+ name);
+ return false;
+ }
+
for (i = 0; i < mpb->num_raid_devs; i++) {
struct imsm_dev *dev = get_imsm_dev(super, i);
diff --git a/tests/00confnames b/tests/00confnames
index 191a905f3379..db22fa1a5035 100644
--- a/tests/00confnames
+++ b/tests/00confnames
@@ -4,6 +4,10 @@ set -x -e
# Test how <devname> is handled during Incremental assemblation with
# config file and ARRAYLINE specified.
+# for native, mdadm is not limiting or checking the set of ASCI symbols that
+# can be used. It is up to user to use symbols that are not conflicting with
+# system utilities. Any problem is this area is not mdadm issue.
+
names_create "/dev/md/name"
local _UUID="$(mdadm -D --export /dev/md127 | grep MD_UUID | cut -d'=' -f2)"
[[ "$_UUID" == "" ]] && echo "Cannot obtain UUID for $DEVNODE_NAME" && exit 1
@@ -41,14 +45,7 @@ mdadm -I $dev0 --config=$config
names_verify "/dev/md4" "empty" "name"
mdadm -S "/dev/md4"
-# 6. <devname> with some special symbols and locales.
-# <devname> should be ignored.
-names_make_conf $_UUID "tźż-\.,<>st+-" $config
-mdadm -I $dev0 --config=$config
-names_verify "/dev/md127" "name" "name"
-mdadm -S "/dev/md127"
-
-# 7. No <devname> set.
+# 6. No <devname> set.
# Metadata name and default node used.
names_make_conf $_UUID "empty" $config
mdadm -I $dev0 --config=$config
--
2.50.1

View File

@ -0,0 +1,30 @@
From ea4cdaea1a553685444a3fb39aae6b2cfee387ef Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Tue, 3 Jun 2025 08:49:29 +0800
Subject: [PATCH 53/74] mdadm/assemble: Don't stop array after creating it
It stops the array which is just created. From the comment it wants to
stop the array if it has no content. But it hasn't added member disks,
so it's a clean array. It's meaningless to do it.
Signed-off-by: Xiao Ni <xni@redhat.com>
---
Assemble.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index f8099cd32aa3..1949bf96c478 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1570,8 +1570,6 @@ try_again:
goto try_again;
goto out;
}
- /* just incase it was started but has no content */
- ioctl(mdfd, STOP_ARRAY, NULL);
}
if (content != &info) {
--
2.50.1

View File

@ -0,0 +1,47 @@
From 34f21b7acea8afbea9348d0f421beeeedca7a136 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Wed, 7 May 2025 17:49:05 +0200
Subject: [PATCH 54/74] mdmonitor: use MAILFROM to set sendmail envelope sender
address
Modern mail relays may reject emails with unknown envelope sender
address.
Use the MAILFROM address also as envelope sender address to work
around this issue.
Signed-off-by: Martin Wilck <mwilck@suse.com>
---
mdmonitor.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/mdmonitor.c b/mdmonitor.c
index d51617cd0981..ea35d98ede30 100644
--- a/mdmonitor.c
+++ b/mdmonitor.c
@@ -639,11 +639,20 @@ static void execute_alert_cmd(const struct event_data *data)
*/
static void send_event_email(const struct event_data *data)
{
- FILE *mp, *mdstat;
+ FILE *mp = NULL, *mdstat;
char buf[BUFSIZ];
int n;
- mp = popen(Sendmail, "w");
+ if (info.mailfrom) {
+ char cmd[1024];
+ int rc = snprintf(cmd, sizeof(cmd), "%s -f%s",
+ Sendmail, info.mailfrom);
+
+ if (rc >= 0 && (unsigned int)rc < sizeof(cmd))
+ mp = popen(cmd, "w");
+ }
+ if (mp == NULL)
+ mp = popen(Sendmail, "w");
if (!mp) {
pr_err("Cannot open pipe stream for sendmail.\n");
return;
--
2.50.1

View File

@ -0,0 +1,749 @@
From 787cc1b60130b8031be59e49d54463c58cd8cf74 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@dell.com>
Date: Thu, 26 Jun 2025 06:29:37 +0100
Subject: [PATCH 55/74] mdadm: use lseek consistently
mdadm used both lseek and lseek64 for legacy reasons. These days, we just
need to configure __USE_LARGEFILE64 macro. Fixing this issue enables
musl compilation.
Add macro, and change all lseek64 to lseek. Fix style issues in these
lines.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@dell.com>
---
Grow.c | 52 +++++++++++++++++++++++++--------------------------
mdadm.h | 10 ++--------
raid6check.c | 15 ++++++++-------
restripe.c | 10 ++++------
super-ddf.c | 24 ++++++++++++------------
super-intel.c | 32 +++++++++++++++----------------
super0.c | 14 +++++++-------
super1.c | 24 ++++++++++++------------
swap_super.c | 12 +++++-------
util.c | 2 +-
10 files changed, 93 insertions(+), 102 deletions(-)
diff --git a/Grow.c b/Grow.c
index 30eaa3c6a654..fbf56156a7c4 100644
--- a/Grow.c
+++ b/Grow.c
@@ -4280,10 +4280,10 @@ static int grow_backup(struct mdinfo *sra,
bsb.magic[15] = '2';
for (i = 0; i < dests; i++)
if (part)
- lseek64(destfd[i], destoffsets[i] +
- __le64_to_cpu(bsb.devstart2)*512, 0);
+ lseek(destfd[i], destoffsets[i] +
+ __le64_to_cpu(bsb.devstart2) * 512, 0);
else
- lseek64(destfd[i], destoffsets[i], 0);
+ lseek(destfd[i], destoffsets[i], 0);
rv = save_stripes(sources, offsets, disks, chunk, level, layout,
dests, destfd, offset * 512 * odata,
@@ -4293,24 +4293,24 @@ static int grow_backup(struct mdinfo *sra,
return rv;
bsb.mtime = __cpu_to_le64(time(0));
for (i = 0; i < dests; i++) {
- bsb.devstart = __cpu_to_le64(destoffsets[i]/512);
+ unsigned long long seek = destoffsets[i] + stripes * chunk * odata;
- bsb.sb_csum = bsb_csum((char*)&bsb,
- ((char*)&bsb.sb_csum)-((char*)&bsb));
+ bsb.devstart = __cpu_to_le64(destoffsets[i] / 512);
+
+ bsb.sb_csum = bsb_csum((char *)&bsb, ((char *)&bsb.sb_csum) - ((char *)&bsb));
if (memcmp(bsb.magic, "md_backup_data-2", 16) == 0)
- bsb.sb_csum2 = bsb_csum((char*)&bsb,
- ((char*)&bsb.sb_csum2)-((char*)&bsb));
+ bsb.sb_csum2 = bsb_csum((char *)&bsb,
+ ((char *)&bsb.sb_csum2) - ((char *)&bsb));
rv = -1;
- if ((unsigned long long)lseek64(destfd[i],
- destoffsets[i] - 4096, 0) !=
+
+ if ((unsigned long long)lseek(destfd[i], destoffsets[i] - 4096, 0) !=
destoffsets[i] - 4096)
break;
if (write(destfd[i], &bsb, 512) != 512)
break;
if (destoffsets[i] > 4096) {
- if ((unsigned long long)lseek64(destfd[i], destoffsets[i]+stripes*chunk*odata, 0) !=
- destoffsets[i]+stripes*chunk*odata)
+ if ((unsigned long long)lseek(destfd[i], seek, 0) != seek)
break;
if (write(destfd[i], &bsb, 512) != 512)
break;
@@ -4359,7 +4359,7 @@ static int forget_backup(int dests, int *destfd,
if (memcmp(bsb.magic, "md_backup_data-2", 16) == 0)
bsb.sb_csum2 = bsb_csum((char*)&bsb,
((char*)&bsb.sb_csum2)-((char*)&bsb));
- if ((unsigned long long)lseek64(destfd[i], destoffsets[i]-4096, 0) !=
+ if ((unsigned long long)lseek(destfd[i], destoffsets[i]-4096, 0) !=
destoffsets[i]-4096)
rv = -1;
if (rv == 0 && write(destfd[i], &bsb, 512) != 512)
@@ -4387,8 +4387,8 @@ static void validate(int afd, int bfd, unsigned long long offset)
*/
if (afd < 0)
return;
- if (lseek64(bfd, offset - 4096, 0) < 0) {
- pr_err("lseek64 fails %d:%s\n", errno, strerror(errno));
+ if (lseek(bfd, offset - 4096, 0) < 0) {
+ pr_err("lseek fails %d:%s\n", errno, strerror(errno));
return;
}
if (read(bfd, &bsb2, 512) != 512)
@@ -4421,8 +4421,8 @@ static void validate(int afd, int bfd, unsigned long long offset)
}
}
- if (lseek64(bfd, offset, 0) < 0) {
- pr_err("lseek64 fails %d:%s\n", errno, strerror(errno));
+ if (lseek(bfd, offset, 0) < 0) {
+ pr_err("lseek fails %d:%s\n", errno, strerror(errno));
goto out;
}
if ((unsigned long long)read(bfd, bbuf, len) != len) {
@@ -4430,8 +4430,8 @@ static void validate(int afd, int bfd, unsigned long long offset)
fail("read first backup failed");
}
- if (lseek64(afd, __le64_to_cpu(bsb2.arraystart)*512, 0) < 0) {
- pr_err("lseek64 fails %d:%s\n", errno, strerror(errno));
+ if (lseek(afd, __le64_to_cpu(bsb2.arraystart)*512, 0) < 0) {
+ pr_err("lseek fails %d:%s\n", errno, strerror(errno));
goto out;
}
if ((unsigned long long)read(afd, abuf, len) != len)
@@ -4450,14 +4450,14 @@ static void validate(int afd, int bfd, unsigned long long offset)
bbuf = xmalloc(abuflen);
}
- if (lseek64(bfd, offset+__le64_to_cpu(bsb2.devstart2)*512, 0) < 0) {
- pr_err("lseek64 fails %d:%s\n", errno, strerror(errno));
+ if (lseek(bfd, offset+__le64_to_cpu(bsb2.devstart2)*512, 0) < 0) {
+ pr_err("lseek fails %d:%s\n", errno, strerror(errno));
goto out;
}
if ((unsigned long long)read(bfd, bbuf, len) != len)
fail("read second backup failed");
- if (lseek64(afd, __le64_to_cpu(bsb2.arraystart2)*512, 0) < 0) {
- pr_err("lseek64 fails %d:%s\n", errno, strerror(errno));
+ if (lseek(afd, __le64_to_cpu(bsb2.arraystart2)*512, 0) < 0) {
+ pr_err("lseek fails %d:%s\n", errno, strerror(errno));
goto out;
}
if ((unsigned long long)read(afd, abuf, len) != len)
@@ -4740,7 +4740,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist,
st->ss->getinfo_super(st, &dinfo, NULL);
st->ss->free_super(st);
- if (lseek64(fd,
+ if (lseek(fd,
(dinfo.data_offset + dinfo.component_size - 8) <<9,
0) < 0) {
pr_err("Cannot seek on device %d\n", i);
@@ -4840,7 +4840,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist,
goto nonew; /* No new data here */
}
}
- if (lseek64(fd, __le64_to_cpu(bsb.devstart)*512, 0)< 0) {
+ if (lseek(fd, __le64_to_cpu(bsb.devstart) * 512, 0) < 0) {
second_fail:
if (verbose)
pr_err("Failed to verify secondary backup-metadata block on %s\n",
@@ -4848,7 +4848,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist,
continue; /* Cannot seek */
}
/* There should be a duplicate backup superblock 4k before here */
- if (lseek64(fd, -4096, 1) < 0 ||
+ if (lseek(fd, -4096, 1) < 0 ||
read(fd, &bsb2, sizeof(bsb2)) != sizeof(bsb2))
goto second_fail; /* Cannot find leading superblock */
if (bsb.magic[15] == '1')
diff --git a/mdadm.h b/mdadm.h
index ce9c216bf74d..84bd2c915fc2 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -24,15 +24,9 @@
#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
-#include <unistd.h>
-#ifdef __GLIBC__
-extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence));
-#elif !defined(lseek64)
-# if defined(__NO_STAT64) || __WORDSIZE != 32
-# define lseek64 lseek
-# endif
-#endif
+#define __USE_LARGEFILE64 1
+#include <unistd.h>
#include <assert.h>
#include <asm/byteorder.h>
#include <sys/types.h>
diff --git a/raid6check.c b/raid6check.c
index 95533f7d0836..4469dc8fac5a 100644
--- a/raid6check.c
+++ b/raid6check.c
@@ -212,9 +212,12 @@ int autorepair(int *disk, unsigned long long start, int chunk_size,
for(j = 0; j < (chunk_size >> CHECK_PAGE_BITS); j++) {
if(page_to_write[j] == 1) {
int slot = block_index_for_slot[disk[j]];
- lseek64(source[slot], offsets[slot] + start * chunk_size + j * CHECK_PAGE_SIZE, SEEK_SET);
+ lseek(source[slot],
+ offsets[slot] + start * chunk_size +
+ j * CHECK_PAGE_SIZE, SEEK_SET);
write_res += write(source[slot],
- blocks[disk[j]] + j * CHECK_PAGE_SIZE,
+ blocks[disk[j]] +
+ j * CHECK_PAGE_SIZE,
CHECK_PAGE_SIZE);
}
}
@@ -287,16 +290,14 @@ int manual_repair(int chunk_size, int syndrome_disks,
int write_res1, write_res2;
off64_t seek_res;
- seek_res = lseek64(source[fd1],
- offsets[fd1] + start * chunk_size, SEEK_SET);
+ seek_res = lseek(source[fd1], offsets[fd1] + start * chunk_size, SEEK_SET);
if (seek_res < 0) {
fprintf(stderr, "lseek failed for failed_disk1\n");
return -1;
}
write_res1 = write(source[fd1], blocks[failed_slot1], chunk_size);
- seek_res = lseek64(source[fd2],
- offsets[fd2] + start * chunk_size, SEEK_SET);
+ seek_res = lseek(source[fd2], offsets[fd2] + start * chunk_size, SEEK_SET);
if (seek_res < 0) {
fprintf(stderr, "lseek failed for failed_disk2\n");
return -1;
@@ -380,7 +381,7 @@ int check_stripes(struct mdinfo *info, int *source, unsigned long long *offsets,
goto exitCheck;
}
for (i = 0 ; i < raid_disks ; i++) {
- off64_t seek_res = lseek64(source[i], offsets[i] + start * chunk_size,
+ off64_t seek_res = lseek(source[i], offsets[i] + start * chunk_size,
SEEK_SET);
if (seek_res < 0) {
fprintf(stderr, "lseek to source %d failed\n", i);
diff --git a/restripe.c b/restripe.c
index 5e126eb7bfa5..ec8d6275c407 100644
--- a/restripe.c
+++ b/restripe.c
@@ -583,8 +583,7 @@ int save_stripes(int *source, unsigned long long *offsets,
raid_disks, level, layout);
if (dnum < 0) abort();
if (source[dnum] < 0 ||
- lseek64(source[dnum],
- offsets[dnum] + offset, 0) < 0 ||
+ lseek(source[dnum], offsets[dnum] + offset, 0) < 0 ||
read(source[dnum], buf+disk * chunk_size,
chunk_size) != chunk_size) {
if (failed <= 2) {
@@ -756,7 +755,7 @@ int restore_stripes(int *dest, unsigned long long *offsets,
raid_disks, level, layout);
if (src_buf == NULL) {
/* read from file */
- if (lseek64(source, read_offset, 0) !=
+ if (lseek(source, read_offset, 0) !=
(off64_t)read_offset) {
rv = -1;
goto abort;
@@ -818,8 +817,7 @@ int restore_stripes(int *dest, unsigned long long *offsets,
}
for (i=0; i < raid_disks ; i++)
if (dest[i] >= 0) {
- if (lseek64(dest[i],
- offsets[i]+offset, 0) < 0) {
+ if (lseek(dest[i], offsets[i]+offset, 0) < 0) {
rv = -1;
goto abort;
}
@@ -868,7 +866,7 @@ int test_stripes(int *source, unsigned long long *offsets,
int disk;
for (i = 0 ; i < raid_disks ; i++) {
- if ((lseek64(source[i], offsets[i]+start, 0) < 0) ||
+ if ((lseek(source[i], offsets[i]+start, 0) < 0) ||
(read(source[i], stripes[i], chunk_size) !=
chunk_size)) {
free(q);
diff --git a/super-ddf.c b/super-ddf.c
index dda8b7fedd64..f46217206437 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -815,7 +815,7 @@ static int load_ddf_header(int fd, unsigned long long lba,
if (lba >= size-1)
return 0;
- if (lseek64(fd, lba << 9, 0) == -1L)
+ if (lseek(fd, lba << 9, 0) == -1L)
return 0;
if (read(fd, hdr, 512) != 512)
@@ -868,7 +868,7 @@ static void *load_section(int fd, struct ddf_super *super, void *buf,
else
offset += be64_to_cpu(super->active->secondary_lba);
- if ((unsigned long long)lseek64(fd, offset << 9, 0) != (offset << 9)) {
+ if ((unsigned long long)lseek(fd, offset << 9, 0) != (offset << 9)) {
if (dofree)
free(buf);
return NULL;
@@ -932,8 +932,8 @@ static int search_for_ddf_headers(int fd, char *devname,
if (search_end - pos < SEARCH_BLOCK_SIZE)
bytes_block_to_read = search_end - pos;
- if (lseek64(fd, pos, SEEK_SET) < 0) {
- pr_err("lseek64 for %s failed %d:%s\n",
+ if (lseek(fd, pos, SEEK_SET) < 0) {
+ pr_err("lseek for %s failed %d:%s\n",
fd2devnm(fd), errno, strerror(errno));
result = 2;
goto cleanup;
@@ -984,7 +984,7 @@ static int load_ddf_headers(int fd, struct ddf_super *super, char *devname)
get_dev_size(fd, NULL, &dsize);
/* Check the last 512 bytes for the DDF header. */
- if (lseek64(fd, dsize - 512, SEEK_SET) == -1L) {
+ if (lseek(fd, dsize - 512, SEEK_SET) == -1L) {
if (devname) {
pr_err("Cannot seek to last 512 bytes on %s: %s\n",
devname, strerror(errno));
@@ -1019,7 +1019,7 @@ static int load_ddf_headers(int fd, struct ddf_super *super, char *devname)
}
/* Seek to the found position */
- if (lseek64(fd, ddfpos, SEEK_SET) == -1L) {
+ if (lseek(fd, ddfpos, SEEK_SET) == -1L) {
if (devname) {
pr_err("Cannot seek to anchor block on %s\n",
devname);
@@ -1849,7 +1849,7 @@ static int copy_metadata_ddf(struct supertype *st, int from, int to)
if (!get_dev_size(from, NULL, &dsize))
goto err;
- if (lseek64(from, dsize - 512, 0) == -1L)
+ if (lseek(from, dsize - 512, 0) == -1L)
goto err;
if (read(from, buf, 512) != 512)
@@ -1870,7 +1870,7 @@ static int copy_metadata_ddf(struct supertype *st, int from, int to)
bytes = dsize - offset;
- if (lseek64(from, offset, 0) == -1L || lseek64(to, offset, 0) == -1L)
+ if (lseek(from, offset, 0) == -1L || lseek(to, offset, 0) == -1L)
goto err;
while (written < bytes) {
@@ -3132,7 +3132,7 @@ static int __write_ddf_structure(struct dl *d, struct ddf_super *ddf, __u8 type)
header->openflag = 1;
header->crc = calc_crc(header, 512);
- if (lseek64(fd, sector << 9, 0) == -1L)
+ if (lseek(fd, sector << 9, 0) == -1L)
goto out;
if (write(fd, header, 512) < 0)
@@ -3199,7 +3199,7 @@ out:
header->openflag = 0;
header->crc = calc_crc(header, 512);
- if (lseek64(fd, sector << 9, 0) == -1L)
+ if (lseek(fd, sector << 9, 0) == -1L)
return 0;
if (write(fd, header, 512) < 0)
@@ -3254,7 +3254,7 @@ static int _write_super_to_disk(struct ddf_super *ddf, struct dl *d)
if (!__write_ddf_structure(d, ddf, DDF_HEADER_SECONDARY))
return 0;
- if (lseek64(fd, (size - 1) * 512, SEEK_SET) == -1L)
+ if (lseek(fd, (size - 1) * 512, SEEK_SET) == -1L)
return 0;
if (write(fd, &ddf->anchor, 512) < 0)
@@ -4050,7 +4050,7 @@ static int store_super_ddf(struct supertype *st, int fd)
buf = xmemalign(SEARCH_BLOCK_SIZE, SEARCH_REGION_SIZE);
memset(buf, 0, SEARCH_REGION_SIZE);
- if (lseek64(fd, dsize - SEARCH_REGION_SIZE, 0) == -1L) {
+ if (lseek(fd, dsize - SEARCH_REGION_SIZE, 0) == -1L) {
free(buf);
return 1;
}
diff --git a/super-intel.c b/super-intel.c
index 40519f8fce2a..7162327ecdf2 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -3230,7 +3230,7 @@ static int read_imsm_migr_rec(int fd, struct intel_super *super)
unsigned long long dsize;
get_dev_size(fd, NULL, &dsize);
- if (lseek64(fd, dsize - (sector_size*MIGR_REC_SECTOR_POSITION),
+ if (lseek(fd, dsize - (sector_size*MIGR_REC_SECTOR_POSITION),
SEEK_SET) < 0) {
pr_err("Cannot seek to anchor block: %s\n",
strerror(errno));
@@ -3421,7 +3421,7 @@ static int write_imsm_migr_rec(struct supertype *st)
continue;
get_dev_size(sd->fd, NULL, &dsize);
- if (lseek64(sd->fd, dsize - (MIGR_REC_SECTOR_POSITION *
+ if (lseek(sd->fd, dsize - (MIGR_REC_SECTOR_POSITION *
sector_size),
SEEK_SET) < 0) {
pr_err("Cannot seek to anchor block: %s\n",
@@ -4591,7 +4591,7 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname)
return 1;
}
- if (lseek64(fd, dsize - (sector_size * 2), SEEK_SET) < 0) {
+ if (lseek(fd, dsize - (sector_size * 2), SEEK_SET) < 0) {
if (devname)
pr_err("Cannot seek to anchor block on %s: %s\n",
devname, strerror(errno));
@@ -4660,7 +4660,7 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname)
}
/* read the extended mpb */
- if (lseek64(fd, dsize - (sector_size * (2 + sectors)), SEEK_SET) < 0) {
+ if (lseek(fd, dsize - (sector_size * (2 + sectors)), SEEK_SET) < 0) {
if (devname)
pr_err("Cannot seek to extended mpb on %s: %s\n",
devname, strerror(errno));
@@ -6164,7 +6164,7 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
/* clear migr_rec when adding disk to container */
memset(super->migr_rec_buf, 0, MIGR_REC_BUF_SECTORS * MAX_SECTOR_SIZE);
- if (lseek64(fd, (size - MIGR_REC_SECTOR_POSITION * member_sector_size), SEEK_SET) >= 0) {
+ if (lseek(fd, (size - MIGR_REC_SECTOR_POSITION * member_sector_size), SEEK_SET) >= 0) {
unsigned int nbytes = MIGR_REC_BUF_SECTORS * member_sector_size;
if ((unsigned int)write(fd, super->migr_rec_buf, nbytes) != nbytes)
@@ -6387,7 +6387,7 @@ static int write_super_imsm(struct supertype *st, int doclose)
unsigned long long dsize;
get_dev_size(d->fd, NULL, &dsize);
- if (lseek64(d->fd, dsize - sector_size,
+ if (lseek(d->fd, dsize - sector_size,
SEEK_SET) >= 0) {
if ((unsigned int)write(d->fd,
super->migr_rec_buf,
@@ -6470,7 +6470,7 @@ static int write_ppl_header(unsigned long long ppl_sector, int fd, void *buf)
ppl_hdr->checksum = __cpu_to_le32(~crc32c_le(~0, buf, PPL_HEADER_SIZE));
- if (lseek64(fd, ppl_sector * 512, SEEK_SET) < 0) {
+ if (lseek(fd, ppl_sector * 512, SEEK_SET) < 0) {
ret = -errno;
perror("Failed to seek to PPL header location");
return ret;
@@ -6564,7 +6564,7 @@ static int validate_ppl_imsm(struct supertype *st, struct mdinfo *info,
dprintf("Checking potential PPL at offset: %llu\n", ppl_offset);
- if (lseek64(d->fd, info->ppl_sector * 512 + ppl_offset,
+ if (lseek(d->fd, info->ppl_sector * 512 + ppl_offset,
SEEK_SET) < 0) {
perror("Failed to seek to PPL header location");
ret = -1;
@@ -9089,7 +9089,7 @@ static int store_imsm_mpb(int fd, struct imsm_super *mpb)
sectors = mpb_sectors(mpb, sector_size) - 1;
/* write the extended mpb to the sectors preceeding the anchor */
- if (lseek64(fd, dsize - (sector_size * (2 + sectors)),
+ if (lseek(fd, dsize - (sector_size * (2 + sectors)),
SEEK_SET) < 0)
return 1;
@@ -9099,7 +9099,7 @@ static int store_imsm_mpb(int fd, struct imsm_super *mpb)
}
/* first block is stored on second to last sector of the disk */
- if (lseek64(fd, dsize - (sector_size * 2), SEEK_SET) < 0)
+ if (lseek(fd, dsize - (sector_size * 2), SEEK_SET) < 0)
return 1;
if ((unsigned int)write(fd, buf, sector_size) != sector_size)
@@ -11282,7 +11282,7 @@ int recover_backup_imsm(struct supertype *st, struct mdinfo *info)
skipped_disks++;
continue;
}
- if (lseek64(dl_disk->fd, read_offset, SEEK_SET) < 0) {
+ if (lseek(dl_disk->fd, read_offset, SEEK_SET) < 0) {
pr_err("Cannot seek to block: %s\n",
strerror(errno));
skipped_disks++;
@@ -11294,7 +11294,7 @@ int recover_backup_imsm(struct supertype *st, struct mdinfo *info)
skipped_disks++;
continue;
}
- if (lseek64(dl_disk->fd, write_offset, SEEK_SET) < 0) {
+ if (lseek(dl_disk->fd, write_offset, SEEK_SET) < 0) {
pr_err("Cannot seek to block: %s\n",
strerror(errno));
skipped_disks++;
@@ -12776,7 +12776,7 @@ static int imsm_manage_reshape(
unsigned long long dsize;
get_dev_size(d->fd, NULL, &dsize);
- if (lseek64(d->fd, dsize - MIGR_REC_SECTOR_POSITION*sector_size,
+ if (lseek(d->fd, dsize - MIGR_REC_SECTOR_POSITION*sector_size,
SEEK_SET) >= 0) {
if ((unsigned int)write(d->fd, super->migr_rec_buf,
MIGR_REC_BUF_SECTORS*sector_size) !=
@@ -12932,7 +12932,7 @@ static int validate_internal_bitmap_for_drive(struct supertype *st,
}
}
- if (lseek64(fd, offset * super->sector_size, SEEK_SET) < 0)
+ if (lseek(fd, offset * super->sector_size, SEEK_SET) < 0)
goto abort;
if (read(fd, read_buf, IMSM_BITMAP_HEADER_SIZE) !=
IMSM_BITMAP_HEADER_SIZE)
@@ -13050,7 +13050,7 @@ static int locate_bitmap_imsm(struct supertype *st, int fd, int node_num)
offset = get_bitmap_header_sector(super, super->current_vol);
dprintf("bitmap header offset is %llu\n", offset);
- lseek64(fd, offset << 9, 0);
+ lseek(fd, offset << 9, 0);
return 0;
}
@@ -13104,7 +13104,7 @@ static int write_init_bitmap_imsm(struct supertype *st, int fd,
return -1;
memset(buf, 0xFF, MAX_SECTOR_SIZE);
offset = get_bitmap_sector(super, vol_idx);
- lseek64(fd, offset << 9, 0);
+ lseek(fd, offset << 9, 0);
while (written < IMSM_BITMAP_AREA_SIZE) {
to_write = IMSM_BITMAP_AREA_SIZE - written;
if (to_write > MAX_SECTOR_SIZE)
diff --git a/super0.c b/super0.c
index 4a462bdca9c8..def553c63c80 100644
--- a/super0.c
+++ b/super0.c
@@ -332,12 +332,12 @@ static int copy_metadata0(struct supertype *st, int from, int to)
offset *= 512;
- if (lseek64(from, offset, 0) < 0LL)
+ if (lseek(from, offset, 0) < 0LL)
goto err;
if (read(from, buf, bufsize) != bufsize)
goto err;
- if (lseek64(to, offset, 0) < 0LL)
+ if (lseek(to, offset, 0) < 0LL)
goto err;
super = buf;
if (super->md_magic != MD_SB_MAGIC ||
@@ -895,7 +895,7 @@ static int store_super0(struct supertype *st, int fd)
offset = dsize/512 - 8*2;
offset &= ~(4*2-1);
offset *= 512;
- if (lseek64(fd, offset, 0)< 0LL)
+ if (lseek(fd, offset, 0) < 0LL)
ret = 3;
else if (write(fd, st->other, 1024) != 1024)
ret = 4;
@@ -910,7 +910,7 @@ static int store_super0(struct supertype *st, int fd)
offset *= 512;
- if (lseek64(fd, offset, 0)< 0LL)
+ if (lseek(fd, offset, 0) < 0LL)
return 3;
if (write(fd, super, sizeof(*super)) != sizeof(*super))
@@ -1064,7 +1064,7 @@ static int load_super0(struct supertype *st, int fd, char *devname)
offset *= 512;
- if (lseek64(fd, offset, 0)< 0LL) {
+ if (lseek(fd, offset, 0) < 0LL) {
if (devname)
pr_err("Cannot seek to superblock on %s: %s\n",
devname, strerror(errno));
@@ -1249,7 +1249,7 @@ static int locate_bitmap0(struct supertype *st, int fd, int node_num)
offset += MD_SB_BYTES;
- if (lseek64(fd, offset, 0) < 0)
+ if (lseek(fd, offset, 0) < 0)
return -1;
return 0;
}
@@ -1275,7 +1275,7 @@ static int write_bitmap0(struct supertype *st, int fd, enum bitmap_update update
offset *= 512;
- if (lseek64(fd, offset + 4096, 0)< 0LL)
+ if (lseek(fd, offset + 4096, 0) < 0LL)
return 3;
if (posix_memalign(&buf, 4096, 4096))
diff --git a/super1.c b/super1.c
index 84d735738401..a8081a441009 100644
--- a/super1.c
+++ b/super1.c
@@ -628,7 +628,7 @@ static int copy_metadata1(struct supertype *st, int from, int to)
goto err;
}
- if (lseek64(from, sb_offset << 9, 0) < 0LL)
+ if (lseek(from, sb_offset << 9, 0) < 0LL)
goto err;
if (read(from, buf, bufsize) != bufsize)
goto err;
@@ -642,7 +642,7 @@ static int copy_metadata1(struct supertype *st, int from, int to)
calc_sb_1_csum(sb) != super.sb_csum)
goto err;
- if (lseek64(to, sb_offset << 9, 0) < 0LL)
+ if (lseek(to, sb_offset << 9, 0) < 0LL)
goto err;
if (write(to, buf, bufsize) != bufsize)
goto err;
@@ -658,9 +658,9 @@ static int copy_metadata1(struct supertype *st, int from, int to)
bitmap_offset += (int32_t)__le32_to_cpu(super.bitmap_offset);
- if (lseek64(from, bitmap_offset<<9, 0) < 0)
+ if (lseek(from, bitmap_offset<<9, 0) < 0)
goto err;
- if (lseek64(to, bitmap_offset<<9, 0) < 0)
+ if (lseek(to, bitmap_offset<<9, 0) < 0)
goto err;
for (written = 0; written < bytes ; ) {
@@ -699,9 +699,9 @@ static int copy_metadata1(struct supertype *st, int from, int to)
bb_offset += (int32_t)__le32_to_cpu(super.bblog_offset);
- if (lseek64(from, bb_offset<<9, 0) < 0)
+ if (lseek(from, bb_offset<<9, 0) < 0)
goto err;
- if (lseek64(to, bb_offset<<9, 0) < 0)
+ if (lseek(to, bb_offset<<9, 0) < 0)
goto err;
for (written = 0; written < bytes ; ) {
@@ -803,7 +803,7 @@ static int examine_badblocks_super1(struct supertype *st, int fd, char *devname)
offset = __le64_to_cpu(sb->super_offset) +
(int)__le32_to_cpu(sb->bblog_offset);
offset <<= 9;
- if (lseek64(fd, offset, 0) < 0) {
+ if (lseek(fd, offset, 0) < 0) {
pr_err("Cannot seek to bad-blocks list\n");
free(bbl);
return 1;
@@ -1701,7 +1701,7 @@ static int store_super1(struct supertype *st, int fd)
abort();
}
- if (lseek64(fd, sb_offset << 9, 0)< 0LL)
+ if (lseek(fd, sb_offset << 9, 0) < 0LL)
return 3;
sbsize = ROUND_UP(sizeof(*sb) + 2 * __le32_to_cpu(sb->max_dev), 512);
@@ -1770,7 +1770,7 @@ static int write_init_ppl1(struct supertype *st, struct mdinfo *info, int fd)
sizeof(sb->set_uuid)));
ppl_hdr->checksum = __cpu_to_le32(~crc32c_le(~0, buf, PPL_HEADER_SIZE));
- if (lseek64(fd, info->ppl_sector * 512, SEEK_SET) < 0) {
+ if (lseek(fd, info->ppl_sector * 512, SEEK_SET) < 0) {
ret = errno;
perror("Failed to seek to PPL header location");
}
@@ -1815,7 +1815,7 @@ static int write_empty_r5l_meta_block(struct supertype *st, int fd)
crc = crc32c_le(crc, (void *)mb, META_BLOCK_SIZE);
mb->checksum = crc;
- if (lseek64(fd, __le64_to_cpu(sb->data_offset) * 512, 0) < 0LL) {
+ if (lseek(fd, __le64_to_cpu(sb->data_offset) * 512, 0) < 0LL) {
pr_err("cannot seek to offset of the meta block\n");
goto fail_to_write;
}
@@ -2184,7 +2184,7 @@ static int load_super1(struct supertype *st, int fd, char *devname)
return -EINVAL;
}
- if (lseek64(fd, sb_offset << 9, 0)< 0LL) {
+ if (lseek(fd, sb_offset << 9, 0) < 0LL) {
if (devname)
pr_err("Cannot seek to superblock on %s: %s\n",
devname, strerror(errno));
@@ -2569,7 +2569,7 @@ static int locate_bitmap1(struct supertype *st, int fd, int node_num)
}
if (mustfree)
free(sb);
- if (lseek64(fd, offset<<9, 0) < 0) {
+ if (lseek(fd, offset<<9, 0) < 0) {
pr_err("lseek fails\n");
ret = -1;
}
diff --git a/swap_super.c b/swap_super.c
index b6db5743d572..15021bd18083 100644
--- a/swap_super.c
+++ b/swap_super.c
@@ -16,7 +16,7 @@
#define MD_NEW_SIZE_SECTORS(x) ((x & ~(MD_RESERVED_SECTORS - 1)) - MD_RESERVED_SECTORS)
-extern long long lseek64(int, long long, int);
+#define __USE_LARGEFILE64 1
int main(int argc, char *argv[])
{
@@ -38,10 +38,9 @@ int main(int argc, char *argv[])
exit(1);
}
offset = MD_NEW_SIZE_SECTORS(size) * 512LL;
- if (lseek64(fd, offset, 0) < 0LL) {
- perror("lseek64");
+ if (lseek(fd, offset, 0) < 0LL)
exit(1);
- }
+
if (read(fd, super, 4096) != 4096) {
perror("read");
exit(1);
@@ -68,10 +67,9 @@ int main(int argc, char *argv[])
super[32*4+10*4 +i] = t;
}
- if (lseek64(fd, offset, 0) < 0LL) {
- perror("lseek64");
+ if (lseek(fd, offset, 0) < 0LL)
exit(1);
- }
+
if (write(fd, super, 4096) != 4096) {
perror("write");
exit(1);
diff --git a/util.c b/util.c
index 0f77521149f8..43d1c119d013 100644
--- a/util.c
+++ b/util.c
@@ -2456,7 +2456,7 @@ int zero_disk_range(int fd, unsigned long long sector, size_t count)
return -1;
}
- if (lseek64(fd, sector * 512, SEEK_SET) < 0) {
+ if (lseek(fd, sector * 512, SEEK_SET) < 0) {
ret = -errno;
pr_err("Failed to seek offset for zeroing\n");
goto out;
--
2.50.1

View File

@ -0,0 +1,68 @@
From d764c4829947923142a83251296d04edaee7d2f7 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 12 Aug 2025 21:18:44 +0000
Subject: [PATCH 56/74] build(deps): bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)
---
updated-dependencies:
- dependency-name: actions/checkout
dependency-version: '5'
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
---
.github/workflows/review.yml | 4 ++--
.github/workflows/tests.yml | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/review.yml b/.github/workflows/review.yml
index e5fbf4eef4c5..098798b1b4e8 100644
--- a/.github/workflows/review.yml
+++ b/.github/workflows/review.yml
@@ -12,7 +12,7 @@ jobs:
# gcc-versions are used to test up to 5 years old
gcc-version: [9, 10, 11, 12, 13, 14]
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
- name: 'Add ubuntu repository and install dependencies'
run: .github/tools/install_ubuntu_packages.sh ${{ matrix.gcc-version }}
- name: 'Check if gcc was installed correctly'
@@ -35,7 +35,7 @@ jobs:
runs-on: ubuntu-latest
name: checkpatch review
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index a07e320b03c4..3892e56d4127 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -18,12 +18,12 @@ jobs:
timeout-minutes: 150
name: upstream tests
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
if: ${{ github.event_name == 'pull_request' }}
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
if: ${{ github.event_name == 'schedule' }}
with:
ref: main
--
2.50.1

View File

@ -0,0 +1,48 @@
From 191957c3e4f8bcc3fdc251067e523732749f75cd Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Wed, 13 Aug 2025 19:28:08 +0200
Subject: [PATCH 57/74] systemd: use "Type=simple" for mdcheck services
"Type=oneshot" means that systemd considers the unit as started when the
started process exits. But the "mdcheck" script may run for several
hours. Thus systemd will regard the unit as "activating" all the
time. This can be easily tested by running "systemctl start
mdcheck_start.service" manually. The systemctl command will not finish
until the mdcheck utility has finished or Ctrl-C is typed, which is
broken.
Use "Type=simple" instead.
Signed-off-by: Martin Wilck <mwilck@suse.com>
---
systemd/mdcheck_continue.service | 2 +-
systemd/mdcheck_start.service | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service
index 70892a1f6018..cd12db850e42 100644
--- a/systemd/mdcheck_continue.service
+++ b/systemd/mdcheck_continue.service
@@ -11,6 +11,6 @@ ConditionPathExistsGlob=/var/lib/mdcheck/MD_UUID_*
Documentation=man:mdadm(8)
[Service]
-Type=oneshot
+Type=simple
Environment="MDADM_CHECK_DURATION=6 hours"
ExecStart=/usr/share/mdadm/mdcheck --continue --duration ${MDADM_CHECK_DURATION}
diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service
index fc4fc4388c6c..16ba6b67a1ce 100644
--- a/systemd/mdcheck_start.service
+++ b/systemd/mdcheck_start.service
@@ -11,6 +11,6 @@ Wants=mdcheck_continue.timer
Documentation=man:mdadm(8)
[Service]
-Type=oneshot
+Type=simple
Environment="MDADM_CHECK_DURATION=6 hours"
ExecStart=/usr/share/mdadm/mdcheck --duration ${MDADM_CHECK_DURATION}
--
2.50.1

View File

@ -0,0 +1,95 @@
From 303362bee868049959a0a3421080e685ff7cc4b2 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Wed, 13 Aug 2025 21:01:30 +0200
Subject: [PATCH 58/74] mdcheck: reset sync_action to "idle" when stopped
When the mdcheck script stops because the pre-set duration is exceeded, it
will also set the sync action in the kernel to "idle". But when it is
stopped by a signal (e.g. when the systemd service running it is stopped),
it doesn't. This is inconsistent behavior.
Move the code that switches the sync_action to "idle" into a cleanup
function that is always executed on exit. This requires separate "trap"
statements for EXIT(0) and signals, because otherwise a race condition may
arise between the cleanup code and the script body.
Signed-off-by: Martin Wilck <mwilck@suse.com>
---
misc/mdcheck | 50 +++++++++++++++++++++++++++-----------------------
1 file changed, 27 insertions(+), 23 deletions(-)
diff --git a/misc/mdcheck b/misc/mdcheck
index 5f068121b924..aa2096612e56 100644
--- a/misc/mdcheck
+++ b/misc/mdcheck
@@ -66,15 +66,40 @@ shift
# We need a temp file occasionally...
tmp=/var/lib/mdcheck/.md-check-$$
-trap 'rm -f "$tmp"' 0 2 3 15
+cnt=0
+
+cleanup() {
+ # We've waited, and there are still checks running.
+ # Time to stop them.
+ for i in `eval echo {1..$cnt}`
+ do
+ eval fl=\$MD_${i}_fl
+ eval sys=\$MD_${i}_sys
+ eval dev=\$MD_${i}_dev
+
+ if [ -z "$fl" ]; then continue; fi
+
+ if [ "`cat $sys/md/sync_action`" != 'check' ]
+ then
+ eval MD_${i}_fl=
+ rm -f $fl
+ continue;
+ fi
+ echo idle > $sys/md/sync_action
+ cat $sys/md/sync_min > $fl
+ logger -p daemon.info pause checking $dev at `cat $fl`
+ done
+ rm -f "$tmp"
+}
+trap 'exit 129' 2 3 15
+trap 'cleanup' 0
# firstly, clean out really old state files
mkdir -p /var/lib/mdcheck
find /var/lib/mdcheck -name "MD_UUID*" -type f -mtime +180 -exec rm {} \;
# Now look at each md device.
-cnt=0
for dev in /dev/md?*
do
[ -e "$dev" ] || continue
@@ -149,24 +174,3 @@ do
fi
sleep 220
done
-
-# We've waited, and there are still checks running.
-# Time to stop them.
-for i in `eval echo {1..$cnt}`
-do
- eval fl=\$MD_${i}_fl
- eval sys=\$MD_${i}_sys
- eval dev=\$MD_${i}_dev
-
- if [ -z "$fl" ]; then continue; fi
-
- if [ "`cat $sys/md/sync_action`" != 'check' ]
- then
- eval MD_${i}_fl=
- rm -f $fl
- continue;
- fi
- echo idle > $sys/md/sync_action
- cat $sys/md/sync_min > $fl
- logger -p daemon.info pause checking $dev at `cat $fl`
-done
--
2.50.1

View File

@ -0,0 +1,30 @@
From a40a6a7e57095ad3ed20f827c2ad992cf7658699 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Wed, 13 Aug 2025 21:07:36 +0200
Subject: [PATCH 59/74] mdcheck: make sure signals are processed immediately
"systemctl stop mdcheck_start.service" may hang for a long time,
because the shell doesn't handle signals until the sleep process in
the foreground returns. Fix this by starting sleep in the background
and waiting for it (the built-in "wait" receives the signal).
Signed-off-by: Martin Wilck <mwilck@suse.com>
---
misc/mdcheck | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/misc/mdcheck b/misc/mdcheck
index aa2096612e56..398a1ea607ca 100644
--- a/misc/mdcheck
+++ b/misc/mdcheck
@@ -172,5 +172,6 @@ do
systemctl stop mdcheck_continue.timer
exit 0;
fi
- sleep 220
+ sleep 220 &
+ wait $!
done
--
2.50.1

View File

@ -0,0 +1,50 @@
From 8aa4ea95db3525c2d381ddf65da69ab549c814d4 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@suse.com>
Date: Wed, 13 Aug 2025 22:12:53 +0200
Subject: [PATCH 60/74] systemd: start mdcheck_continue.timer before
mdcheck_start.timer
In the (unlikely but possible) case that a previously started md check
hasn't finished on the first Sunday of the following month,
mdcheck_start.service will start the scan from position 0, which is
probably not desired.
Have mdcheck_continue.service start first, so that it will pick up the
check where it left off, and that the subsequent mdcheck_start.service will
do nothing.
Signed-off-by: Martin Wilck <mwilck@suse.com>
---
systemd/mdcheck_continue.timer | 2 +-
systemd/mdcheck_start.timer | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/systemd/mdcheck_continue.timer b/systemd/mdcheck_continue.timer
index dba1074c1f44..0ab5d2ebecb5 100644
--- a/systemd/mdcheck_continue.timer
+++ b/systemd/mdcheck_continue.timer
@@ -9,7 +9,7 @@
Description=MD array scrubbing - continuation
[Timer]
-OnCalendar= 1:05:00
+OnCalendar= 1:00:00
[Install]
WantedBy= mdmonitor.service
diff --git a/systemd/mdcheck_start.timer b/systemd/mdcheck_start.timer
index 9e7e02ab7333..1b8f3f20878b 100644
--- a/systemd/mdcheck_start.timer
+++ b/systemd/mdcheck_start.timer
@@ -9,7 +9,7 @@
Description=MD array scrubbing
[Timer]
-OnCalendar=Sun *-*-1..7 1:00:00
+OnCalendar=Sun *-*-1..7 1:05:00
[Install]
WantedBy= mdmonitor.service
--
2.50.1

View File

@ -0,0 +1,39 @@
From 574b11602fb210c5b3e5f6fe460ab21e7c7d998c Mon Sep 17 00:00:00 2001
From: QRPp <awesome.walrus+github@gmail.com>
Date: Mon, 1 Sep 2025 21:33:57 +0100
Subject: [PATCH 61/74] Fix --monitor --scan with relative ARRAY devnames
Since commit e702f392959d ("Mdmonitor: Fix segfault"), when configuration
files used non-absolute ARRAY device names, commands like `mdadm --monitor
--scan` failed with `mdadm: error opening devname: No such file or
directory` unless run from the `/dev/md` directory.
Signed-off-by: QRPp <awesome.walrus+github@gmail.com>
---
mdmonitor.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/mdmonitor.c b/mdmonitor.c
index ea35d98ede30..22b0a818f9bd 100644
--- a/mdmonitor.c
+++ b/mdmonitor.c
@@ -254,12 +254,14 @@ int Monitor(struct mddev_dev *devlist,
continue;
if (is_devname_ignore(mdlist->devname) == true)
continue;
- if (!is_mddev(mdlist->devname))
- continue;
st = xcalloc(1, sizeof *st);
snprintf(st->devname, MD_NAME_MAX + sizeof(DEV_MD_DIR), DEV_MD_DIR "%s",
basename(mdlist->devname));
+ if (!is_mddev(st->devname)) {
+ free(st);
+ continue;
+ }
st->next = statelist;
st->devnm[0] = 0;
st->percent = RESYNC_UNKNOWN;
--
2.50.1

View File

@ -0,0 +1,108 @@
From 456c6bed0b9e0866c75f0f7c8579d5f4f3f3e966 Mon Sep 17 00:00:00 2001
From: "Dr. Joachim Schneider" <jesmx@hal.rhein-neckar.de>
Date: Sat, 6 Sep 2025 20:28:07 +0200
Subject: [PATCH 62/74] Re-enable mdadm --monitor ... for /dev/mdX
This fixes a regression introduced with
commit 84d969be8f6d ("Monitor: use snprintf to fill device name"):
With this fix
mdadm --monitor --scan -1 -p <pgm>
is possible again for /dev/mdX without symlink in /dev/md/.
The bug can be reproduced by these steps:
(a) Create block devices for testing:
$ dd if=/dev/zero of=/tmp/d0.bin bs=1M count=16
$ dd if=/dev/zero of=/tmp/d1.bin bs=1M count=16
$ losetup -f /tmp/d0.bin
$ losetup -f /tmp/d1.bin
$ losetup
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO LOG-SEC
/dev/loop1 0 0 0 0 /tmp/d1.bin 0 512
/dev/loop0 0 0 0 0 /tmp/d0.bin 0 512
(b) Create RAID-1 array '/dev/md0':
$ mdadm --create /dev/md0 --level=1 --raid-devices=2 \
/dev/loop0 /dev/loop1
...
mdadm: array /dev/md0 started.
(c) Check:
$ cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 loop1[1] loop0[0]
15360 blocks super 1.2 [2/2] [UU]
unused devices: <none>
(d) Create 'mdadm.conf':
$ mdadm --detail --scan > /tmp/mdadm.conf
$ cat /tmp/mdadm.conf
ARRAY /dev/md0 metadata=1.2 UUID=c0280f55:9c32e4ff:34f85ea3:08d1331b
(e) Use this bash script ('/tmp/report') for 'mdadm --monitor':
[[ $# -lt 2 ]] && exit 0
problem="$1"
shift
array="$1"
shift
args="$*"
echo "MD REPORT: ${problem} with ${array}: ${args}"
(f) Call mdamd in monitor mode:
$ mdadm --monitor -c /tmp/mdadm.conf --scan -1 -p /tmp/report
Without the fix one gets this output:
mdadm: DeviceDisappeared event detected on md device /dev/md/md0
MD REPORT: DeviceDisappeared with /dev/md/md0:
mdadm: NewArray event detected on md device /dev/md0
MD REPORT: NewArray with /dev/md0:
Only the output of the 'report'-script:
$ mdadm --monitor -c /tmp/mdadm.conf --scan -1 \
-p /tmp/report 2>/dev/null
MD REPORT: DeviceDisappeared with /dev/md/md0:
MD REPORT: NewArray with /dev/md0:
With the fix no (warning) output is produced:
$ /tmp/mdadm-FIXED --monitor -c /tmp/mdadm.conf --scan -1 \
-p /tmp/report
Signed-off-by: Dr. Joachim Schneider <jesmx@hal.rhein-neckar.de>
---
mdmonitor.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mdmonitor.c b/mdmonitor.c
index 22b0a818f9bd..314dafb4588b 100644
--- a/mdmonitor.c
+++ b/mdmonitor.c
@@ -256,8 +256,8 @@ int Monitor(struct mddev_dev *devlist,
continue;
st = xcalloc(1, sizeof *st);
- snprintf(st->devname, MD_NAME_MAX + sizeof(DEV_MD_DIR), DEV_MD_DIR "%s",
- basename(mdlist->devname));
+ snprintf(st->devname, sizeof(st->devname), "%s%s",
+ '/' == *mdlist->devname ? "" : DEV_MD_DIR, mdlist->devname);
if (!is_mddev(st->devname)) {
free(st);
continue;
--
2.50.1

View File

@ -0,0 +1,28 @@
From 388ef731dccff3b8da369c1968af7daf9b32fe1d Mon Sep 17 00:00:00 2001
From: Amon Bune <admin@full-stack.ninja>
Date: Mon, 29 Sep 2025 19:16:00 +0200
Subject: [PATCH 63/74] Fix 'meaing' typo in mdadm.conf-example
Fix typo in mdadm.conf example file
Signed-off-by: Amon Bune <admin@full-stack.ninja>
---
documentation/mdadm.conf-example | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/documentation/mdadm.conf-example b/documentation/mdadm.conf-example
index 35a75d128a69..29dd55ab3148 100644
--- a/documentation/mdadm.conf-example
+++ b/documentation/mdadm.conf-example
@@ -28,7 +28,7 @@
#
#
# The AUTO line can control which arrays get assembled by auto-assembly,
-# meaing either "mdadm -As" when there are no 'ARRAY' lines in this file,
+# meaning either "mdadm -As" when there are no 'ARRAY' lines in this file,
# or "mdadm --incremental" when the array found is not listed in this file.
# By default, all arrays that are found are assembled.
# If you want to ignore all DDF arrays (maybe they are managed by dmraid),
--
2.50.1

View File

@ -0,0 +1,121 @@
From 2a63857e9506324ec3ef69746344de08f55e6d77 Mon Sep 17 00:00:00 2001
From: Mingye Wang <arthur200126@gmail.com>
Date: Sat, 20 Sep 2025 14:21:40 +0800
Subject: [PATCH 64/74] Update raid6check man page
This adds autorepair and manual repair modes, which have been here for about 12 years. The description of the manual repair mode can probably use more work.
Signed-off-by: Mingye Wang <arthur200126@gmail.com>
---
raid6check.8 | 61 +++++++++++++++++++++++++++++++++++++---------------
1 file changed, 44 insertions(+), 17 deletions(-)
diff --git a/raid6check.8 b/raid6check.8
index 8999ca89e951..f6acb288834b 100644
--- a/raid6check.8
+++ b/raid6check.8
@@ -13,48 +13,72 @@ Linux Software RAID
.SH SYNOPSIS
-.BI raid6check " <raid6 device> <start stripe> <number of stripes>"
+.BI raid6check " <raid6_device> <start_stripe> <number_of_stripes>"
+.RB [ autorepair ]
+
+.BI raid6check " <raid6_device> " repair " <stripe> <failed_slot_1>"
+.I "<failed_slot_2>"
.SH DESCRIPTION
RAID6 devices in which one single component drive has errors can use
the double parity in order to find out which component drive.
-The "raid6check" tool checks, for each stripe, the double parity
-consistency, reports mismatches and, if possible, which
+The "raid6check" tool has two modes: check mode and repair mode.
+
+"raid6check" requires a non-degraded RAID6 MD device as first
+parameter. If the given MD device is not a RAID6, "raid6check" will,
+of course, not continue.
+
+If the RAID6 MD device is degraded, "raid6check" will report
+an error and it will not proceed further.
+
+.SS Check mode
+In the check mode, the "raid6check" tool checks, for each stripe, the
+double parity consistency, reports mismatches and, if possible, which
component drive has the mismatch.
Since it works at stripe level, it can report different drives with
mismatches at different stripes.
-"raid6check" requires a non-degraded RAID6 MD device as first
-parameter, a starting stripe (usually 0) and the number of stripes
-to be checked.
+In addition to the MD device, "raid6check" requries a starting stripe
+(usually 0) and the number of stripes to be checked.
If this third parameter is also 0, it will check the array up to
the end.
+If the fourth parameter is "autorepair", it will overwrite single-slot
+errors.
"raid6check" will start printing information about the RAID6, then
for each stripe, it will report the parity rotation status.
In case of parity mismatches, "raid6check" reports, if possible,
-which component drive could be responsible. Otherwise it reports
-that it is not possible to find the component drive.
-
-If the given MD device is not a RAID6, "raid6check" will, of
-course, not continue.
+which component drive could be responsible.
+Otherwise it reports that it is not possible to find the component drive.
-If the RAID6 MD device is degraded, "raid6check" will report
-an error and it will not proceed further.
-
-No write operations are performed on the array or the components.
+No write operations are performed on the array or the components,
+unless "autorepair" is specified.
Furthermore, the checked array can be online and in use during
the operation of "raid6check".
+.SS Repair mode
+In the repair mode, the "raid6check" tool checks the given stripe.
+If inconsistencies are found, it attempts to repair the strip assuming
+that the two given slots are incorrect.
+
+-1 may be used to specify parity P and -2 parity Q.
+
.SH EXAMPLES
.B " raid6check /dev/md0 0 0"
.br
This will check /dev/md0 from start to end.
-.B " raid6check /dev/md3 0 1"
+.B " raid6check /dev/md3 0 1 autorepair"
+.br
+This will check the first stripe of /dev/md3.
+Any error will be reported, and if single-slot, repaired.
+
+.B " raid6check /dev/md3 0 repair 1 -1 -2"
.br
This will check the first stripe of /dev/md3.
+If any inconsistencies are found, repair is performed assuming
+the two parities are incorrect.
.B " raid6check /dev/md1 1000 0"
.br
@@ -76,7 +100,10 @@ Furthermore, the sysfs interface is needed in order to find out
the RAID6 parameters.
.SH BUGS
-Negative parameters can lead to unexpected results.
+Negative stripe parameters can lead to unexpected results due to
+strtoull.
+(Negative slot numbers should work for Q [-1] and P [-2] but
+currently involve compiler-defined behavior.)
It is not clear what will happen if the RAID6 MD device gets
degraded during the check.
--
2.50.1

View File

@ -0,0 +1,41 @@
From d478aff31f466d126eaa5b018c93654b58047b40 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@dell.com>
Date: Tue, 23 Sep 2025 08:06:12 +0200
Subject: [PATCH 65/74] udev: Fix memleak
According to manual:
On success, udev_monitor_receive_device() returns a pointer to a newly
referenced device that was received via the monitor. The caller is
responsible to drop this reference when done.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@dell.com>
---
udev.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/udev.c b/udev.c
index 961ca970d460..f857c723e4a1 100644
--- a/udev.c
+++ b/udev.c
@@ -147,9 +147,16 @@ enum udev_status udev_wait_for_events(int seconds)
tv.tv_sec = seconds;
tv.tv_usec = 0;
- if (select(fd + 1, &readfds, NULL, NULL, &tv) > 0 && FD_ISSET(fd, &readfds))
- if (udev_monitor_receive_device(udev_monitor))
+ if (select(fd + 1, &readfds, NULL, NULL, &tv) > 0 && FD_ISSET(fd, &readfds)) {
+ struct udev_device *dev = udev_monitor_receive_device(udev_monitor);
+
+ if (dev) {
+ udev_device_unref(dev);
return UDEV_STATUS_SUCCESS; /* event detected */
+ } else {
+ return UDEV_STATUS_ERROR;
+ }
+ }
return UDEV_STATUS_TIMEOUT;
}
#endif
--
2.50.1

View File

@ -0,0 +1,60 @@
From c425cdc9297a1f27f664b19a9d9386b43d92f7b3 Mon Sep 17 00:00:00 2001
From: Wu Guanghao <wuguanghao3@huawei.com>
Date: Tue, 14 Oct 2025 10:23:46 +0800
Subject: [PATCH 66/74] mdadm: modify the order of free_super_xxx() to avoid
memory leak
free_super_xx() should be executed at the load_super_xx() entry.
When there are additional checks, it may lead to supertype not being
released, resulting in a memory leak.
Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
---
super-ddf.c | 4 ++--
super-intel.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/super-ddf.c b/super-ddf.c
index f46217206437..7b38f9125134 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -1324,6 +1324,8 @@ static int load_super_ddf(struct supertype *st, int fd,
struct ddf_super *super;
int rv;
+ free_super_ddf(st);
+
if (get_dev_size(fd, devname, &dsize) == 0)
return 1;
@@ -1345,8 +1347,6 @@ static int load_super_ddf(struct supertype *st, int fd,
return 1;
}
- free_super_ddf(st);
-
if (posix_memalign((void**)&super, 512, sizeof(*super))!= 0) {
pr_err("malloc of %zu failed.\n",
sizeof(*super));
diff --git a/super-intel.c b/super-intel.c
index 7162327ecdf2..5a4a2eb1c949 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -5471,12 +5471,12 @@ static int load_super_imsm(struct supertype *st, int fd, char *devname)
int rv;
int retry;
+ free_super_imsm(st);
+
if (test_partition(fd))
/* IMSM not allowed on partitions */
return 1;
- free_super_imsm(st);
-
super = alloc_super();
if (!super)
return 1;
--
2.50.1

View File

@ -0,0 +1,28 @@
From 7cb225b4949ca63f9e8298a7feb00e04c71c7e9e Mon Sep 17 00:00:00 2001
From: Wu Guanghao <wuguanghao3@huawei.com>
Date: Tue, 14 Oct 2025 10:50:18 +0800
Subject: [PATCH 67/74] mdadm: Fix memory leak issue in check_raid()
check_raid() alloc for st, but did not release it when exiting.
Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
---
util.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/util.c b/util.c
index 43d1c119d013..5d6fe800d666 100644
--- a/util.c
+++ b/util.c
@@ -693,6 +693,8 @@ int check_raid(int fd, char *name)
/* Looks like GPT or MBR */
pr_err("partition table exists on %s\n", name);
}
+
+ free(st);
return 1;
}
--
2.50.1

View File

@ -0,0 +1,29 @@
From b67f6f01c8c1638bca5c2c9327720b2b8197768f Mon Sep 17 00:00:00 2001
From: Wu Guanghao <wuguanghao3@huawei.com>
Date: Tue, 14 Oct 2025 11:29:37 +0800
Subject: [PATCH 68/74] mdadm: Fix memory leak issue in Manage_stop()
The local variable 'mds' allocated in Manage_stop() is only released
under specific conditions in the for loop. This can lead to memory leak
when under othe conditions.
Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
---
Manage.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/Manage.c b/Manage.c
index 22b1f52b7dc7..b53e65e9cea2 100644
--- a/Manage.c
+++ b/Manage.c
@@ -286,6 +286,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
rv = 1;
goto out;
}
+ free_mdstat(mds);
}
/* If the array is undergoing a reshape which changes the number
--
2.50.1

View File

@ -0,0 +1,29 @@
From ca10248139610ffb53fe90224333513dcc3ca155 Mon Sep 17 00:00:00 2001
From: Wu Guanghao <wuguanghao3@huawei.com>
Date: Tue, 14 Oct 2025 11:49:11 +0800
Subject: [PATCH 69/74] mdadm: Fix memory leak issue in load_ddf_local()
dl->devname might be allocated space through xstrdup(). Before an
abnormal exit, it needs to be checked and released.
Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
---
super-ddf.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/super-ddf.c b/super-ddf.c
index 7b38f9125134..657c53abe729 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -1208,6 +1208,8 @@ static int load_ddf_local(int fd, struct ddf_super *super,
dl->devname = devname ? xstrdup(devname) : NULL;
if (fstat(fd, &stb) != 0) {
+ if (dl->devname)
+ free(dl->devname);
free(dl);
return 1;
}
--
2.50.1

View File

@ -0,0 +1,67 @@
From 804a6a6b5747eed8794a6b007279dc8e09432270 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 17 Oct 2025 17:04:25 +0800
Subject: [PATCH 70/74] mdadm/Incremental: wait a while before removing a
member
We encountered a regression that member disk can't be removed in
incremental remove mode:
mdadm -If /dev/loop0
mdadm: Cannot remove member device loop0 from md127
It doesn't allow to remove a member if sync thread is running. mdadm -If
sets member disk faulty first, then it removes the disk. If sync thread
is running, it will be interrupted by setting a member faulty. But the sync
thread hasn't been reapped. So it needs to wait a while to let kernel to
reap sync thread.
Signed-off-by: Xiao Ni <xni@redhat.com>
---
Incremental.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/Incremental.c b/Incremental.c
index ba3810e6157f..f30697fa684f 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -1715,6 +1715,7 @@ int Incremental_remove(char *devname, char *id_path, int verbose)
struct mdstat_ent *ent;
struct mdinfo mdi;
int mdfd = -1;
+ int retry = 25;
if (strcmp(devnm, devname) != 0)
if (!is_devnode_path(devname)) {
@@ -1790,11 +1791,26 @@ int Incremental_remove(char *devname, char *id_path, int verbose)
/* Native arrays are handled separatelly to provide more detailed error handling */
rv = sysfs_set_memb_state(ent->devnm, devnm, MEMB_STATE_FAULTY);
- if (rv && verbose >= 0)
- pr_err("Cannot fail member device %s in array %s.\n", devnm, ent->devnm);
+ if (rv) {
+ if (verbose >= 0)
+ pr_err("Cannot fail member device %s in array %s.\n", devnm, ent->devnm);
+ goto out;
+ }
- if (rv == MDADM_STATUS_SUCCESS)
+ /*
+ * If resync/recovery is running, sync thread is interrupted by setting member faulty.
+ * And it needs to wait some time to let kernel to reap sync thread. If not, it will
+ * fail to remove it.
+ */
+ while (retry) {
rv = sysfs_set_memb_state(ent->devnm, devnm, MEMB_STATE_REMOVE);
+ if (rv) {
+ sleep_for(0, MSEC_TO_NSEC(200), true);
+ retry--;
+ continue;
+ }
+ break;
+ }
if (rv && verbose >= 0)
pr_err("Cannot remove member device %s from %s.\n", devnm, ent->devnm);
--
2.50.1

View File

@ -0,0 +1,39 @@
From abb9a2b097c940251673eba5f074638b10ceb26e Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 17 Oct 2025 17:06:13 +0800
Subject: [PATCH 71/74] mdadm/sysfs: close fd before return
It needs to close fd before returning the function.
Signed-off-by: Xiao Ni <xni@redhat.com>
---
sysfs.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/sysfs.c b/sysfs.c
index c030d634b155..e60adc9f549f 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -160,6 +160,7 @@ mdadm_status_t sysfs_set_memb_state_fd(int fd, memb_state_t state, int *err)
mdadm_status_t sysfs_set_memb_state(char *array_devnm, char *memb_devnm, memb_state_t state)
{
int state_fd = sysfs_open_memb_attr(array_devnm, memb_devnm, "state", O_RDWR);
+ mdadm_status_t status;
if (!is_fd_valid(state_fd)) {
pr_err("Cannot open file descriptor to %s in array %s, aborting.\n",
@@ -167,9 +168,9 @@ mdadm_status_t sysfs_set_memb_state(char *array_devnm, char *memb_devnm, memb_st
return MDADM_STATUS_ERROR;
}
- return sysfs_set_memb_state_fd(state_fd, state, NULL);
-
+ status = sysfs_set_memb_state_fd(state_fd, state, NULL);
close_fd(&state_fd);
+ return status;
}
/**
--
2.50.1

View File

@ -0,0 +1,28 @@
From 868376e030349417bc6c858dec565ae0d9808b60 Mon Sep 17 00:00:00 2001
From: Guilherme Ferreira <16529503+piradata@users.noreply.github.com>
Date: Sat, 25 Oct 2025 20:15:53 -0300
Subject: [PATCH 72/74] Update README.md
just updated the link to the new one, the old pointed to an archive page
Signed-off-by: Guilherme Ferreira <16529503+piradata@users.noreply.github.com>
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index ba611ec5fb7b..9289f50ac776 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
**mdadm** is a utility used to create and manage **software RAID** devices implemented through
**Multiple devices driver (MD)** in kernel. It supports following RAID metadata formats:
-* [Linux native RAID](https://raid.wiki.kernel.org/index.php/RAID_superblock_formats):
+* [Linux native RAID](https://docs.kernel.org/admin-guide/md.html#superblock-formats):
Known as **native** or **native RAID**. First and default metadata format. Metadata management
is implemented in **MD driver**.
--
2.50.1

View File

@ -0,0 +1,120 @@
From d354d314db86379f18a4ccd35af9f6e56635b61d Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Fri, 24 Oct 2025 15:17:29 +0800
Subject: [PATCH 73/74] mdadm: Create array with sync del gendisk mode
kernel patch 9e59d609763f ('md: call del_gendisk in control path') calls
del_gendisk in sync way. After the patch mentioned just now, device node
(/dev/md0 .e.g) will disappear after mdadm --stop command. It resolves the
problem raid can be created again because raid can be created when opening
device node. Then regression tests will be interrupted.
But it causes an error when assembling array which has been fixed by pr182.
So people can't assemble array if they use new kernel and old mdadm. So
in kernel space, 25db5f284fb8 ('md: add legacy_async_del_gendisk mod') is
used to fix this problem. The default is async mode.
async del mode will be removed in future. We'll start use sync del mode in
new mdadm version. So people will not see failure when upgrading to the
new mdadm version with sync del mode.
Signed-off-by: Xiao Ni <xni@redhat.com>
---
mdadm.h | 3 +++
mdopen.c | 5 +++++
util.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 53 insertions(+)
diff --git a/mdadm.h b/mdadm.h
index 84bd2c915fc2..7dcb20ed1f34 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -141,6 +141,8 @@ struct dlm_lksb {
#define MDMON_DIR "/run/mdadm"
#endif /* MDMON_DIR */
+#define MD_MOD_ASYNC_DEL_GENDISK "legacy_async_del_gendisk"
+
/* FAILED_SLOTS is where to save files storing recent removal of array
* member in order to allow future reuse of disk inserted in the same
* slot for array recovery
@@ -855,6 +857,7 @@ extern int restore_stripes(int *dest, unsigned long long *offsets,
unsigned long long start, unsigned long long length,
char *src_buf);
extern bool sysfs_is_libata_allow_tpm_enabled(const int verbose);
+extern bool init_md_mod_param(void);
#ifndef Sendmail
#define Sendmail "/usr/lib/sendmail -t"
diff --git a/mdopen.c b/mdopen.c
index 57252b646137..b685603d6de5 100644
--- a/mdopen.c
+++ b/mdopen.c
@@ -148,6 +148,11 @@ int create_mddev(char *dev, char *name, int trustworthy,
char devnm[32];
char cbuf[400];
+ if (!init_md_mod_param()) {
+ pr_err("init md module parameters fail\n");
+ return -1;
+ }
+
if (!udev_is_available())
block_udev = 0;
diff --git a/util.c b/util.c
index 5d6fe800d666..146f38fddd82 100644
--- a/util.c
+++ b/util.c
@@ -2559,3 +2559,48 @@ bool is_file(const char *path)
return true;
}
+
+bool set_md_mod_parameter(const char *name, const char *value)
+{
+ char path[256];
+ int fd;
+ bool ret = true;
+
+ snprintf(path, sizeof(path), "/sys/module/md_mod/parameters/%s", name);
+
+ fd = open(path, O_WRONLY);
+ if (fd < 0) {
+ pr_err("Can't open %s\n", path);
+ return false;
+ }
+
+ if (write(fd, value, strlen(value)) != (ssize_t)strlen(value)) {
+ pr_err("Failed to write to %s\n", path);
+ ret = false;
+ }
+
+ close(fd);
+ return ret;
+}
+
+/* Init kernel md_mod parameters here if needed */
+bool init_md_mod_param(void)
+{
+ bool ret = true;
+
+ /*
+ * In kernel 9e59d609763f calls del_gendisk in sync way. So device
+ * node can be removed after stop command. But it can introduce a
+ * regression which can be fixed by github pr182. New mdadm version
+ * with pr182 can work well with new kernel. But users who don't
+ * update mdadm and update to new kernel, they can't assemble array
+ * anymore. So kernel adds a kernel parameter legacy_async_del_gendisk
+ * and uses async as default.
+ * We'll use sync mode since 6.18 rather than async mode. So in future
+ * the kernel parameter will be removed.
+ */
+ if (get_linux_version() >= 6018000)
+ ret = set_md_mod_parameter(MD_MOD_ASYNC_DEL_GENDISK, "N");
+
+ return ret;
+}
--
2.50.1

View File

@ -1,7 +1,31 @@
diff -Naur mdadm-4.2/Assemble.c mdadm-4.2-fix/Assemble.c
--- mdadm-4.2/Assemble.c 2025-10-25 11:46:59.647889913 +0800
+++ mdadm-4.2-fix/Assemble.c 2025-10-25 11:37:18.437758159 +0800
@@ -1337,10 +1337,8 @@
From 6fa6c4b915f6bc024cf481d137569a255001a84a Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Mon, 27 Oct 2025 08:15:38 +0800
Subject: [PATCH 74/74] mdadm/Assemble: alloc superblock in Assemble
Now it allocs superblock outside Assemble and frees the memory outside
Assemble. But the memory can be freed and realloc in Assemble. So freed
memory will be dereferenced outside Assemble. This patch moves the memory
management into Assemble. So it's more safe and the input arguments is
less.
This can be reproduced by:
mdadm -CR /dev/md0 -l1 -n2 /dev/loop0 /dev/loop1 --assume-clean
mdadm -Ss
mdadm -A -e 1.2 /dev/md0 /dev/loop0 /dev/loop1
Signed-off-by: Xiao Ni <xni@redhat.com>
---
Assemble.c | 47 ++++++++++++++++++++++++++++++++++-------------
mdadm.c | 12 +++++++-----
mdadm.h | 7 +++----
3 files changed, 44 insertions(+), 22 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index 1949bf96c478..cfe01ee237bb 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1308,10 +1308,8 @@ static int start_array(int mdfd,
return 1;
}
@ -14,7 +38,7 @@ diff -Naur mdadm-4.2/Assemble.c mdadm-4.2-fix/Assemble.c
{
/*
* The task of Assemble is to find a collection of
@@ -1427,6 +1425,7 @@
@@ -1398,6 +1396,7 @@ int Assemble(struct supertype *st, char *mddev,
char chosen_name[1024];
struct map_ent *map = NULL;
struct map_ent *mp;
@ -22,7 +46,7 @@ diff -Naur mdadm-4.2/Assemble.c mdadm-4.2-fix/Assemble.c
/*
* If any subdevs are listed, then any that don't
@@ -1447,6 +1446,15 @@
@@ -1418,6 +1417,15 @@ int Assemble(struct supertype *st, char *mddev,
return 1;
}
@ -38,7 +62,7 @@ diff -Naur mdadm-4.2/Assemble.c mdadm-4.2-fix/Assemble.c
if (devlist == NULL)
devlist = conf_get_devs();
else if (mddev)
@@ -1468,11 +1476,15 @@
@@ -1439,11 +1447,15 @@ try_again:
st->ignore_hw_compat = 1;
num_devs = select_devices(devlist, ident, &st, &content, c,
inargv, auto_assem);
@ -58,7 +82,7 @@ diff -Naur mdadm-4.2/Assemble.c mdadm-4.2-fix/Assemble.c
/* We have a full set of devices - we now need to find the
* array device.
@@ -1603,11 +1615,10 @@
@@ -1574,12 +1586,11 @@ try_again:
if (content != &info) {
/* This is a member of a container. Try starting the array. */
@ -67,12 +91,13 @@ diff -Naur mdadm-4.2/Assemble.c mdadm-4.2-fix/Assemble.c
+ rv = assemble_container_content(st, mdfd, content, c,
chosen_name, NULL);
close(mdfd);
sysfs_free(pre_exist);
- return err;
+ goto free_st;
}
/* Ok, no bad inconsistancy, we can try updating etc */
@@ -1961,9 +1972,19 @@
@@ -1937,10 +1948,20 @@ out:
/* '2' means 'OK, but not started yet' */
if (rv == -1) {
free(devices);
@ -80,6 +105,7 @@ diff -Naur mdadm-4.2/Assemble.c mdadm-4.2-fix/Assemble.c
+ rv = 1;
+ goto free_st;
}
close(mdfd);
- return rv == 2 ? 0 : rv;
+
+ if (rv == 2)
@ -94,18 +120,19 @@ diff -Naur mdadm-4.2/Assemble.c mdadm-4.2-fix/Assemble.c
}
int assemble_container_content(struct supertype *st, int mdfd,
diff -Naur mdadm-4.2/mdadm.c mdadm-4.2-fix/mdadm.c
--- mdadm-4.2/mdadm.c 2025-10-25 11:46:59.527825090 +0800
+++ mdadm-4.2-fix/mdadm.c 2025-10-25 11:42:17.331226086 +0800
@@ -71,6 +71,7 @@
*/
diff --git a/mdadm.c b/mdadm.c
index 14649a40c236..18ded25ee79d 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -107,6 +107,7 @@ int main(int argc, char *argv[])
int grow_continue = 0;
struct context c = {
.require_homehost = 1,
+ .metadata = NULL,
};
struct shape s = {
.journaldisks = 0,
@@ -402,6 +403,7 @@
@@ -445,6 +446,7 @@ int main(int argc, char *argv[])
pr_err("unrecognised metadata identifier: %s\n", optarg);
exit(2);
}
@ -113,10 +140,10 @@ diff -Naur mdadm-4.2/mdadm.c mdadm-4.2-fix/mdadm.c
continue;
case O(MANAGE,'W'):
@@ -1427,10 +1429,10 @@
@@ -1424,10 +1426,10 @@ int main(int argc, char *argv[])
if (mdfd >= 0)
close(mdfd);
} else {
if (array_ident->autof == 0)
array_ident->autof = c.autof;
- rv |= Assemble(ss, ident.devname, array_ident, NULL, &c);
+ rv |= Assemble(ident.devname, array_ident, NULL, &c);
}
@ -126,41 +153,38 @@ diff -Naur mdadm-4.2/mdadm.c mdadm-4.2-fix/mdadm.c
else if (devs_found > 0) {
if (c.update && devs_found > 1) {
pr_err("can only update a single array at a time\n");
@@ -1450,8 +1452,7 @@
@@ -1445,7 +1447,7 @@ int main(int argc, char *argv[])
rv |= 1;
continue;
}
if (array_ident->autof == 0)
array_ident->autof = c.autof;
- rv |= Assemble(ss, dv->devname, array_ident,
- NULL, &c);
- rv |= Assemble(ss, dv->devname, array_ident, NULL, &c);
+ rv |= Assemble(dv->devname, array_ident, NULL, &c);
}
} else {
if (c.update) {
@@ -1736,8 +1737,7 @@
@@ -1737,7 +1739,7 @@ static int scan_assemble(struct supertype *ss,
if (a->devname && is_devname_ignore(a->devname) == true)
continue;
- r = Assemble(ss, a->devname,
- a, NULL, c);
+ r = Assemble(a->devname, a, NULL, c);
+ r = Assemble(a->devname,
a, NULL, c);
if (r == 0) {
a->assembled = 1;
successes++;
@@ -1759,9 +1759,7 @@
@@ -1760,7 +1762,7 @@ static int scan_assemble(struct supertype *ss,
struct mddev_dev *devlist = conf_get_devs();
acnt = 0;
do {
- rv2 = Assemble(ss, NULL,
- ident,
- devlist, c);
+ rv2 = Assemble(NULL, ident, devlist, c);
+ rv2 = Assemble(NULL,
ident,
devlist, c);
if (rv2 == 0) {
cnt++;
acnt++;
diff -Naur mdadm-4.2/mdadm.h mdadm-4.2-fix/mdadm.h
--- mdadm-4.2/mdadm.h 2025-10-25 11:46:59.716186280 +0800
+++ mdadm-4.2-fix/mdadm.h 2025-10-25 11:43:13.999603357 +0800
@@ -662,6 +662,7 @@
diff --git a/mdadm.h b/mdadm.h
index 7dcb20ed1f34..56925cf863f1 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -638,6 +638,7 @@ struct context {
char *action;
int nodes;
char *homecluster;
@ -168,9 +192,9 @@ diff -Naur mdadm-4.2/mdadm.h mdadm-4.2-fix/mdadm.h
};
struct shape {
@@ -1541,10 +1542,8 @@
extern int Grow_continue_command(char *devname, int fd,
char *backup_file, int verbose);
@@ -1516,10 +1517,8 @@ extern int restore_backup(struct supertype *st,
int verbose);
extern int Grow_continue_command(char *devname, int fd, struct context *c);
-extern int Assemble(struct supertype *st, char *mddev,
- struct mddev_ident *ident,
@ -181,3 +205,6 @@ diff -Naur mdadm-4.2/mdadm.h mdadm-4.2-fix/mdadm.h
extern int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s,
struct context *c);
--
2.50.1

View File

@ -1,47 +0,0 @@
From f1cc8ab9ab6a92c3cd94ab7590b46285e214681e Mon Sep 17 00:00:00 2001
From: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Date: Tue, 15 Mar 2022 09:30:30 +0100
Subject: [PATCH 01/83] Unify error message.
Provide the same error message for the same error that can occur in Grow.c and super-intel.c.
Signed-off-by: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Grow.c | 4 ++--
super-intel.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Grow.c b/Grow.c
index 9c6fc95e..9a947204 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1001,8 +1001,8 @@ int remove_disks_for_takeover(struct supertype *st,
rv = 1;
sysfs_free(arrays);
if (rv) {
- pr_err("Error. Cannot perform operation on /dev/%s\n", st->devnm);
- pr_err("For this operation it MUST be single array in container\n");
+ pr_err("Error. Cannot perform operation on %s- for this operation "
+ "it MUST be single array in container\n", st->devnm);
return rv;
}
}
diff --git a/super-intel.c b/super-intel.c
index d5fad102..5ffa7636 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -11683,8 +11683,8 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
struct imsm_super *mpb = super->anchor;
if (mpb->num_raid_devs > 1) {
- pr_err("Error. Cannot perform operation on %s- for this operation it MUST be single array in container\n",
- geo->dev_name);
+ pr_err("Error. Cannot perform operation on %s- for this operation "
+ "it MUST be single array in container\n", geo->dev_name);
change = -1;
}
}
--
2.38.1

View File

@ -1,33 +0,0 @@
From 5ce5a15f0bf007e850e15259bba4f53736605fb2 Mon Sep 17 00:00:00 2001
From: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Date: Fri, 25 Mar 2022 12:48:59 +0100
Subject: [PATCH 02/83] mdadm: Fix double free
If there was a size mismatch after creation it would get fixed on grow
in imsm_fix_size_mismatch(), but due to double free "double free or corruption (fasttop)"
error occurs and grow cannot proceed.
Signed-off-by: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-intel.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index 5ffa7636..6ff336ee 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -11783,9 +11783,8 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index)
st->update_tail = &st->updates;
} else {
imsm_sync_metadata(st);
+ free(update);
}
-
- free(update);
}
ret_val = 0;
exit:
--
2.38.1

View File

@ -1,83 +0,0 @@
From fea026b4849182fc8413014c81456e7215af28d9 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Wed, 23 Mar 2022 15:05:19 +0100
Subject: [PATCH 03/83] Grow_reshape: Add r0 grow size error message and update
man
Grow size on r0 is not supported for imsm and native metadata.
Add proper error message.
Update man for proper use of --size.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Grow.c | 6 ++++++
mdadm.8.in | 19 ++++++++++++-------
2 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/Grow.c b/Grow.c
index 9a947204..aa72490b 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1998,6 +1998,12 @@ int Grow_reshape(char *devname, int fd,
goto release;
}
+ if (array.level == 0) {
+ pr_err("Component size change is not supported for RAID0\n");
+ rv = 1;
+ goto release;
+ }
+
if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet, NULL,
devname, APPLY_METADATA_CHANGES,
c->verbose > 0)) {
diff --git a/mdadm.8.in b/mdadm.8.in
index be902dba..e2a42425 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -459,7 +459,8 @@ number of spare devices.
.TP
.BR \-z ", " \-\-size=
-Amount (in Kilobytes) of space to use from each drive in RAID levels 1/4/5/6.
+Amount (in Kilobytes) of space to use from each drive in RAID levels 1/4/5/6/10
+and for RAID 0 on external metadata.
This must be a multiple of the chunk size, and must leave about 128Kb
of space at the end of the drive for the RAID superblock.
If this is not specified
@@ -478,10 +479,19 @@ To guard against this it can be useful to set the initial size
slightly smaller than the smaller device with the aim that it will
still be larger than any replacement.
+This option can be used with
+.B \-\-create
+for determining initial size of an array. For external metadata,
+it can be used on a volume, but not on a container itself.
+Setting initial size of
+.B RAID 0
+array is only valid for external metadata.
+
This value can be set with
.B \-\-grow
-for RAID level 1/4/5/6 though
+for RAID level 1/4/5/6/10 though
DDF arrays may not be able to support this.
+RAID 0 array size cannot be changed.
If the array was created with a size smaller than the currently
active drives, the extra space can be accessed using
.BR \-\-grow .
@@ -501,11 +511,6 @@ problems the array can be made bigger again with no loss with another
.B "\-\-grow \-\-size="
command.
-This value cannot be used when creating a
-.B CONTAINER
-such as with DDF and IMSM metadata, though it perfectly valid when
-creating an array inside a container.
-
.TP
.BR \-Z ", " \-\-array\-size=
This is only meaningful with
--
2.38.1

View File

@ -1,67 +0,0 @@
From cf9a109209aad285372b67306d54118af6fc522b Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Fri, 14 Jan 2022 16:44:33 +0100
Subject: [PATCH 04/83] udev: adapt rules to systemd v247
New events have been added in kernel 4.14 ("bind" and "unbind").
Systemd maintainer suggests to modify "add|change" branches.
This patches implements their suggestions. There is no issue yet because
new event types are not used in md.
Please see systemd announcement for details[1].
[1] https://lists.freedesktop.org/archives/systemd-devel/2020-November/045646.html
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
udev-md-raid-arrays.rules | 2 +-
udev-md-raid-assembly.rules | 5 +++--
udev-md-raid-safe-timeouts.rules | 2 +-
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules
index 13c9076e..2967ace1 100644
--- a/udev-md-raid-arrays.rules
+++ b/udev-md-raid-arrays.rules
@@ -3,7 +3,7 @@
SUBSYSTEM!="block", GOTO="md_end"
# handle md arrays
-ACTION!="add|change", GOTO="md_end"
+ACTION=="remove", GOTO="md_end"
KERNEL!="md*", GOTO="md_end"
# partitions have no md/{array_state,metadata_version}, but should not
diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules
index d668cddd..39b4344b 100644
--- a/udev-md-raid-assembly.rules
+++ b/udev-md-raid-assembly.rules
@@ -30,8 +30,9 @@ LABEL="md_inc"
# remember you can limit what gets auto/incrementally assembled by
# mdadm.conf(5)'s 'AUTO' and selectively whitelist using 'ARRAY'
-ACTION=="add|change", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}"
-ACTION=="add|change", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer"
+ACTION!="remove", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot $env{DEVLINKS}"
+ACTION!="remove", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer"
+
ACTION=="remove", ENV{ID_PATH}=="?*", RUN+="BINDIR/mdadm -If $name --path $env{ID_PATH}"
ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="BINDIR/mdadm -If $name"
diff --git a/udev-md-raid-safe-timeouts.rules b/udev-md-raid-safe-timeouts.rules
index 12bdcaa8..2e185cee 100644
--- a/udev-md-raid-safe-timeouts.rules
+++ b/udev-md-raid-safe-timeouts.rules
@@ -50,7 +50,7 @@ ENV{DEVTYPE}!="partition", GOTO="md_timeouts_end"
IMPORT{program}="/sbin/mdadm --examine --export $devnode"
-ACTION=="add|change", \
+ACTION!="remove", \
ENV{ID_FS_TYPE}=="linux_raid_member", \
ENV{MD_LEVEL}=="raid[1-9]*", \
TEST=="/sys/block/$parent/device/timeout", \
--
2.38.1

View File

@ -1,252 +0,0 @@
From 83a379cfbd283b387919fe05d44eb4c49e155ad6 Mon Sep 17 00:00:00 2001
From: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Date: Mon, 21 Feb 2022 13:05:20 +0100
Subject: [PATCH 05/83] Replace error prone signal() with sigaction()
Up to this date signal() was used which implementation could vary [1].
Sigaction() call is preferred. This commit introduces replacement
from signal() to sigaction() by the use of signal_s() wrapper.
Also remove redundant signal.h header includes.
[1] https://man7.org/linux/man-pages/man2/signal.2.html
Signed-off-by: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Grow.c | 4 ++--
Monitor.c | 5 +++--
managemon.c | 1 -
mdadm.h | 22 ++++++++++++++++++++++
mdmon.c | 1 -
monitor.c | 1 -
probe_roms.c | 6 +++---
raid6check.c | 25 +++++++++++++++----------
util.c | 1 -
9 files changed, 45 insertions(+), 21 deletions(-)
diff --git a/Grow.c b/Grow.c
index aa72490b..18c5719b 100644
--- a/Grow.c
+++ b/Grow.c
@@ -26,7 +26,6 @@
#include <sys/mman.h>
#include <stddef.h>
#include <stdint.h>
-#include <signal.h>
#include <sys/wait.h>
#if ! defined(__BIG_ENDIAN) && ! defined(__LITTLE_ENDIAN)
@@ -3566,7 +3565,8 @@ started:
fd = -1;
mlockall(MCL_FUTURE);
- signal(SIGTERM, catch_term);
+ if (signal_s(SIGTERM, catch_term) == SIG_ERR)
+ goto release;
if (st->ss->external) {
/* metadata handler takes it from here */
diff --git a/Monitor.c b/Monitor.c
index 30c031a2..c0ab5412 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -26,7 +26,6 @@
#include "md_p.h"
#include "md_u.h"
#include <sys/wait.h>
-#include <signal.h>
#include <limits.h>
#include <syslog.h>
#ifndef NO_LIBUDEV
@@ -435,8 +434,10 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info)
if (mp) {
FILE *mdstat;
char hname[256];
+
gethostname(hname, sizeof(hname));
- signal(SIGPIPE, SIG_IGN);
+ signal_s(SIGPIPE, SIG_IGN);
+
if (info->mailfrom)
fprintf(mp, "From: %s\n", info->mailfrom);
else
diff --git a/managemon.c b/managemon.c
index bb7334cf..0e9bdf00 100644
--- a/managemon.c
+++ b/managemon.c
@@ -106,7 +106,6 @@
#include "mdmon.h"
#include <sys/syscall.h>
#include <sys/socket.h>
-#include <signal.h>
static void close_aa(struct active_array *aa)
{
diff --git a/mdadm.h b/mdadm.h
index c7268a71..26e7e5cd 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -46,6 +46,7 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence));
#include <string.h>
#include <syslog.h>
#include <stdbool.h>
+#include <signal.h>
/* Newer glibc requires sys/sysmacros.h directly for makedev() */
#include <sys/sysmacros.h>
#ifdef __dietlibc__
@@ -1729,6 +1730,27 @@ static inline char *to_subarray(struct mdstat_ent *ent, char *container)
return &ent->metadata_version[10+strlen(container)+1];
}
+/**
+ * signal_s() - Wrapper for sigaction() with signal()-like interface.
+ * @sig: The signal to set the signal handler to.
+ * @handler: The signal handler.
+ *
+ * Return: previous handler or SIG_ERR on failure.
+ */
+static inline sighandler_t signal_s(int sig, sighandler_t handler)
+{
+ struct sigaction new_act;
+ struct sigaction old_act;
+
+ new_act.sa_handler = handler;
+ new_act.sa_flags = 0;
+
+ if (sigaction(sig, &new_act, &old_act) == 0)
+ return old_act.sa_handler;
+
+ return SIG_ERR;
+}
+
#ifdef DEBUG
#define dprintf(fmt, arg...) \
fprintf(stderr, "%s: %s: "fmt, Name, __func__, ##arg)
diff --git a/mdmon.c b/mdmon.c
index c71e62c6..5570574b 100644
--- a/mdmon.c
+++ b/mdmon.c
@@ -56,7 +56,6 @@
#include <errno.h>
#include <string.h>
#include <fcntl.h>
-#include <signal.h>
#include <dirent.h>
#ifdef USE_PTHREADS
#include <pthread.h>
diff --git a/monitor.c b/monitor.c
index e0d3be67..b877e595 100644
--- a/monitor.c
+++ b/monitor.c
@@ -22,7 +22,6 @@
#include "mdmon.h"
#include <sys/syscall.h>
#include <sys/select.h>
-#include <signal.h>
static char *array_states[] = {
"clear", "inactive", "suspended", "readonly", "read-auto",
diff --git a/probe_roms.c b/probe_roms.c
index 7ea04c7a..94c80c2c 100644
--- a/probe_roms.c
+++ b/probe_roms.c
@@ -22,7 +22,6 @@
#include "probe_roms.h"
#include "mdadm.h"
#include <unistd.h>
-#include <signal.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
@@ -69,7 +68,8 @@ static int probe_address16(const __u16 *ptr, __u16 *val)
void probe_roms_exit(void)
{
- signal(SIGBUS, SIG_DFL);
+ signal_s(SIGBUS, SIG_DFL);
+
if (rom_fd >= 0) {
close(rom_fd);
rom_fd = -1;
@@ -98,7 +98,7 @@ int probe_roms_init(unsigned long align)
if (roms_init())
return -1;
- if (signal(SIGBUS, sigbus) == SIG_ERR)
+ if (signal_s(SIGBUS, sigbus) == SIG_ERR)
rc = -1;
if (rc == 0) {
fd = open("/dev/mem", O_RDONLY);
diff --git a/raid6check.c b/raid6check.c
index a8e6005b..99477761 100644
--- a/raid6check.c
+++ b/raid6check.c
@@ -24,7 +24,6 @@
#include "mdadm.h"
#include <stdint.h>
-#include <signal.h>
#include <sys/mman.h>
#define CHECK_PAGE_BITS (12)
@@ -130,30 +129,36 @@ void raid6_stats(int *disk, int *results, int raid_disks, int chunk_size)
}
int lock_stripe(struct mdinfo *info, unsigned long long start,
- int chunk_size, int data_disks, sighandler_t *sig) {
+ int chunk_size, int data_disks, sighandler_t *sig)
+{
int rv;
+
+ sig[0] = signal_s(SIGTERM, SIG_IGN);
+ sig[1] = signal_s(SIGINT, SIG_IGN);
+ sig[2] = signal_s(SIGQUIT, SIG_IGN);
+
+ if (sig[0] == SIG_ERR || sig[1] == SIG_ERR || sig[2] == SIG_ERR)
+ return 1;
+
if(mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {
return 2;
}
- sig[0] = signal(SIGTERM, SIG_IGN);
- sig[1] = signal(SIGINT, SIG_IGN);
- sig[2] = signal(SIGQUIT, SIG_IGN);
-
rv = sysfs_set_num(info, NULL, "suspend_lo", start * chunk_size * data_disks);
rv |= sysfs_set_num(info, NULL, "suspend_hi", (start + 1) * chunk_size * data_disks);
return rv * 256;
}
-int unlock_all_stripes(struct mdinfo *info, sighandler_t *sig) {
+int unlock_all_stripes(struct mdinfo *info, sighandler_t *sig)
+{
int rv;
rv = sysfs_set_num(info, NULL, "suspend_lo", 0x7FFFFFFFFFFFFFFFULL);
rv |= sysfs_set_num(info, NULL, "suspend_hi", 0);
rv |= sysfs_set_num(info, NULL, "suspend_lo", 0);
- signal(SIGQUIT, sig[2]);
- signal(SIGINT, sig[1]);
- signal(SIGTERM, sig[0]);
+ signal_s(SIGQUIT, sig[2]);
+ signal_s(SIGINT, sig[1]);
+ signal_s(SIGTERM, sig[0]);
if(munlockall() != 0)
return 3;
diff --git a/util.c b/util.c
index 3d05d074..cc94f96e 100644
--- a/util.c
+++ b/util.c
@@ -35,7 +35,6 @@
#include <poll.h>
#include <ctype.h>
#include <dirent.h>
-#include <signal.h>
#include <dlfcn.h>
--
2.38.1

File diff suppressed because it is too large Load Diff

View File

@ -1,48 +0,0 @@
From c23400377bb3d8e98e810cd92dba478dac1dff82 Mon Sep 17 00:00:00 2001
From: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Date: Fri, 18 Mar 2022 09:26:05 +0100
Subject: [PATCH 07/83] mdadm: Update ReadMe
Instead of hardcoded config file path give reference to config manual.
Add missing monitordelay and homecluster parameters.
Signed-off-by: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Acked-by: Coly Li <colyli@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
ReadMe.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/ReadMe.c b/ReadMe.c
index 81399765..8f873c48 100644
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -613,7 +613,6 @@ char Help_incr[] =
;
char Help_config[] =
-"The /etc/mdadm.conf config file:\n\n"
" The config file contains, apart from blank lines and comment lines that\n"
" start with a hash(#), array lines, device lines, and various\n"
" configuration lines.\n"
@@ -636,10 +635,12 @@ char Help_config[] =
" than a device must match all of them to be considered.\n"
"\n"
" Other configuration lines include:\n"
-" mailaddr, mailfrom, program used for --monitor mode\n"
-" create, auto used when creating device names in /dev\n"
-" homehost, policy, part-policy used to guide policy in various\n"
-" situations\n"
+" mailaddr, mailfrom, program, monitordelay used for --monitor mode\n"
+" create, auto used when creating device names in /dev\n"
+" homehost, homecluster, policy, part-policy used to guide policy in various\n"
+" situations\n"
+"\n"
+"For more details see mdadm.conf(5).\n"
"\n"
;
--
2.38.1

View File

@ -1,203 +0,0 @@
From 24e075c659d0a8718aabefe5af4c97195a188af7 Mon Sep 17 00:00:00 2001
From: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Date: Fri, 18 Mar 2022 09:26:06 +0100
Subject: [PATCH 08/83] mdadm: Update config man regarding default files and
multi-keyword behavior
Simplify default and alternative config file and directory location references
from mdadm(8) as references to mdadm.conf(5). Add FILE section in config man
and explain order and conditions in which default and alternative config files
and directories are used.
Update config man behavior regarding parsing order when multiple keywords/config
files are involved.
Signed-off-by: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Acked-by: Coly Li <colyli@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
mdadm.8.in | 30 +++++++++--------------
mdadm.conf.5.in | 65 ++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 71 insertions(+), 24 deletions(-)
diff --git a/mdadm.8.in b/mdadm.8.in
index 8b21ffd4..0be02e4a 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -266,14 +266,11 @@ the exact meaning of this option in different contexts.
.TP
.BR \-c ", " \-\-config=
-Specify the config file or directory. Default is to use
-.B {CONFFILE}
-and
-.BR {CONFFILE}.d ,
-or if those are missing then
-.B {CONFFILE2}
-and
-.BR {CONFFILE2}.d .
+Specify the config file or directory. If not specified, default config file
+and default conf.d directory will be used. See
+.BR mdadm.conf (5)
+for more details.
+
If the config file given is
.B "partitions"
then nothing will be read, but
@@ -2013,11 +2010,9 @@ The config file is only used if explicitly named with
.B \-\-config
or requested with (a possibly implicit)
.BR \-\-scan .
-In the later case,
-.B {CONFFILE}
-or
-.B {CONFFILE2}
-is used.
+In the later case, default config file is used. See
+.BR mdadm.conf (5)
+for more details.
If
.B \-\-scan
@@ -3346,16 +3341,15 @@ on Monitor mode.
.SS {CONFFILE} (or {CONFFILE2})
-The config file lists which devices may be scanned to see if
-they contain MD super block, and gives identifying information
-(e.g. UUID) about known MD arrays. See
+Default config file. See
.BR mdadm.conf (5)
for more details.
.SS {CONFFILE}.d (or {CONFFILE2}.d)
-A directory containing configuration files which are read in lexical
-order.
+Default directory containing configuration files. See
+.BR mdadm.conf (5)
+for more details.
.SS {MAP_PATH}
When
diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in
index 83edd008..dd331a6a 100644
--- a/mdadm.conf.5.in
+++ b/mdadm.conf.5.in
@@ -88,7 +88,8 @@ but only the major and minor device numbers. It scans
.I /dev
to find the name that matches the numbers.
-If no DEVICE line is present, then "DEVICE partitions containers" is assumed.
+If no DEVICE line is present in any config file,
+then "DEVICE partitions containers" is assumed.
For example:
.IP
@@ -272,6 +273,10 @@ catenated with spaces to form the address.
Note that this value cannot be set via the
.I mdadm
commandline. It is only settable via the config file.
+There should only be one
+.B MAILADDR
+line and it should have only one address. Any subsequent addresses
+are silently ignored.
.TP
.B PROGRAM
@@ -286,7 +291,8 @@ device.
There should only be one
.B program
-line and it should be give only one program.
+line and it should be given only one program. Any subsequent programs
+are silently ignored.
.TP
@@ -295,7 +301,14 @@ The
.B create
line gives default values to be used when creating arrays, new members
of arrays, and device entries for arrays.
-These include:
+
+There should only be one
+.B create
+line. Any subsequent lines will override the previous settings.
+
+Keywords used in the
+.I CREATE
+line and supported values are:
.RS 4
.TP
@@ -475,8 +488,8 @@ The known metadata types are
.B AUTO
should be given at most once. Subsequent lines are silently ignored.
-Thus an earlier config file in a config directory will over-ride
-the setting in a later config file.
+Thus a later config file in a config directory will not overwrite
+the setting in an earlier config file.
.TP
.B POLICY
@@ -594,6 +607,7 @@ The
line lists custom values of MD device's sysfs attributes which will be
stored in sysfs after the array is assembled. Multiple lines are allowed and each
line has to contain the uuid or the name of the device to which it relates.
+Lines are applied in reverse order.
.RS 4
.TP
.B uuid=
@@ -621,7 +635,46 @@ is running in
.B \-\-monitor
mode.
.B \-d/\-\-delay
-command line argument takes precedence over the config file
+command line argument takes precedence over the config file.
+
+If multiple
+.B MINITORDELAY
+lines are provided, only first non-zero value is considered.
+
+.SH FILES
+
+.SS {CONFFILE}
+
+The default config file location, used when
+.I mdadm
+is running without --config option.
+
+.SS {CONFFILE}.d
+
+The default directory with config files. Used when
+.I mdadm
+is running without --config option, after successful reading of the
+.B {CONFFILE}
+default config file. Files in that directory
+are read in lexical order.
+
+
+.SS {CONFFILE2}
+
+Alternative config file that is read, when
+.I mdadm
+is running without --config option and the
+.B {CONFFILE}
+default config file was not opened successfully.
+
+.SS {CONFFILE2}.d
+
+The alternative directory with config files. Used when
+.I mdadm
+is runninng without --config option, after reading the
+.B {CONFFILE2}
+alternative config file whether it was successful or not. Files in
+that directory are read in lexical order.
.SH EXAMPLE
DEVICE /dev/sd[bcdjkl]1
--
2.38.1

View File

@ -1,45 +0,0 @@
From c33bbda5b0e127bb161fd4ad44bcfaa2a5daf153 Mon Sep 17 00:00:00 2001
From: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Date: Fri, 18 Mar 2022 09:26:07 +0100
Subject: [PATCH 09/83] mdadm: Update config manual
Add missing HOMECLUSTER keyword description.
Signed-off-by: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Acked-by: Coly Li <colyli@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
mdadm.conf.5.in | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in
index dd331a6a..cd4e6a9d 100644
--- a/mdadm.conf.5.in
+++ b/mdadm.conf.5.in
@@ -439,6 +439,23 @@ from any possible local name. e.g.
.B /dev/md/1_1
or
.BR /dev/md/home_0 .
+
+.TP
+.B HOMECLUSTER
+The
+.B homcluster
+line gives a default value for the
+.B \-\-homecluster=
+option to mdadm. It specifies the cluster name for the md device.
+The md device can be assembled only on the cluster which matches
+the name specified. If
+.B homcluster
+is not provided, mdadm tries to detect the cluster name automatically.
+
+There should only be one
+.B homecluster
+line. Any subsequent lines will be silently ignored.
+
.TP
.B AUTO
A list of names of metadata format can be given, each preceded by a
--
2.38.1

View File

@ -1,153 +0,0 @@
From 913f07d1db4a0078acc26d6ccabe1c315cf9273c Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 20 Jan 2022 13:18:32 +0100
Subject: [PATCH 10/83] Create, Build: use default_layout()
This code is duplicated for Build mode so make default_layout() extern
and use it. Simplify the function structure.
It introduced change for Build mode, now for raid0 RAID0_ORIG_LAYOUT
will be returned same as for Create.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Build.c | 23 +------------------
Create.c | 67 ++++++++++++++++++++++++++++++++++----------------------
mdadm.h | 1 +
3 files changed, 43 insertions(+), 48 deletions(-)
diff --git a/Build.c b/Build.c
index 962c2e37..8d6f6f58 100644
--- a/Build.c
+++ b/Build.c
@@ -71,28 +71,7 @@ int Build(char *mddev, struct mddev_dev *devlist,
}
if (s->layout == UnSet)
- switch(s->level) {
- default: /* no layout */
- s->layout = 0;
- break;
- case 10:
- s->layout = 0x102; /* near=2, far=1 */
- if (c->verbose > 0)
- pr_err("layout defaults to n1\n");
- break;
- case 5:
- case 6:
- s->layout = map_name(r5layout, "default");
- if (c->verbose > 0)
- pr_err("layout defaults to %s\n", map_num(r5layout, s->layout));
- break;
- case LEVEL_FAULTY:
- s->layout = map_name(faultylayout, "default");
-
- if (c->verbose > 0)
- pr_err("layout defaults to %s\n", map_num(faultylayout, s->layout));
- break;
- }
+ s->layout = default_layout(NULL, s->level, c->verbose);
/* We need to create the device. It can have no name. */
map_lock(&map);
diff --git a/Create.c b/Create.c
index 0ff1922d..9ea19de0 100644
--- a/Create.c
+++ b/Create.c
@@ -39,39 +39,54 @@ static int round_size_and_verify(unsigned long long *size, int chunk)
return 0;
}
-static int default_layout(struct supertype *st, int level, int verbose)
+/**
+ * default_layout() - Get default layout for level.
+ * @st: metadata requested, could be NULL.
+ * @level: raid level requested.
+ * @verbose: verbose level.
+ *
+ * Try to ask metadata handler first, otherwise use global defaults.
+ *
+ * Return: Layout or &UnSet, return value meaning depends of level used.
+ */
+int default_layout(struct supertype *st, int level, int verbose)
{
int layout = UnSet;
+ mapping_t *layout_map = NULL;
+ char *layout_name = NULL;
if (st && st->ss->default_geometry)
st->ss->default_geometry(st, &level, &layout, NULL);
- if (layout == UnSet)
- switch(level) {
- default: /* no layout */
- layout = 0;
- break;
- case 0:
- layout = RAID0_ORIG_LAYOUT;
- break;
- case 10:
- layout = 0x102; /* near=2, far=1 */
- if (verbose > 0)
- pr_err("layout defaults to n2\n");
- break;
- case 5:
- case 6:
- layout = map_name(r5layout, "default");
- if (verbose > 0)
- pr_err("layout defaults to %s\n", map_num(r5layout, layout));
- break;
- case LEVEL_FAULTY:
- layout = map_name(faultylayout, "default");
+ if (layout != UnSet)
+ return layout;
- if (verbose > 0)
- pr_err("layout defaults to %s\n", map_num(faultylayout, layout));
- break;
- }
+ switch (level) {
+ default: /* no layout */
+ layout = 0;
+ break;
+ case 0:
+ layout = RAID0_ORIG_LAYOUT;
+ break;
+ case 10:
+ layout = 0x102; /* near=2, far=1 */
+ layout_name = "n2";
+ break;
+ case 5:
+ case 6:
+ layout_map = r5layout;
+ break;
+ case LEVEL_FAULTY:
+ layout_map = faultylayout;
+ break;
+ }
+
+ if (layout_map) {
+ layout = map_name(layout_map, "default");
+ layout_name = map_num(layout_map, layout);
+ }
+ if (layout_name && verbose > 0)
+ pr_err("layout defaults to %s\n", layout_name);
return layout;
}
diff --git a/mdadm.h b/mdadm.h
index 26e7e5cd..cd72e711 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1512,6 +1512,7 @@ extern int get_linux_version(void);
extern int mdadm_version(char *version);
extern unsigned long long parse_size(char *size);
extern int parse_uuid(char *str, int uuid[4]);
+int default_layout(struct supertype *st, int level, int verbose);
extern int is_near_layout_10(int layout);
extern int parse_layout_10(char *layout);
extern int parse_layout_faulty(char *layout);
--
2.38.1

View File

@ -1,382 +0,0 @@
From 5f21d67472ad08c1e96b4385254adba79aa1c467 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 20 Jan 2022 13:18:33 +0100
Subject: [PATCH 11/83] mdadm: add map_num_s()
map_num() returns NULL if key is not defined. This patch adds
alternative, non NULL version for cases where NULL is not expected.
There are many printf() calls where map_num() is called on variable
without NULL verification. It works, even if NULL is passed because
gcc is able to ignore NULL argument quietly but the behavior is
undefined. For safety reasons such usages will use map_num_s() now.
It is a potential point of regression.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Assemble.c | 6 ++----
Create.c | 2 +-
Detail.c | 4 ++--
Grow.c | 16 ++++++++--------
Query.c | 4 ++--
maps.c | 24 ++++++++++++++++++++++++
mdadm.c | 20 ++++++++++----------
mdadm.h | 2 +-
super-ddf.c | 6 +++---
super-intel.c | 2 +-
super0.c | 2 +-
super1.c | 2 +-
sysfs.c | 9 +++++----
13 files changed, 61 insertions(+), 38 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index 704b8293..9eac9ce0 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -63,7 +63,7 @@ static void set_array_assembly_status(struct context *c,
struct assembly_array_info *arr)
{
int raid_disks = arr->preexist_cnt + arr->new_cnt;
- char *status_msg = map_num(assemble_statuses, status);
+ char *status_msg = map_num_s(assemble_statuses, status);
if (c->export && result)
*result |= status;
@@ -77,9 +77,7 @@ static void set_array_assembly_status(struct context *c,
fprintf(stderr, " (%d new)", arr->new_cnt);
if (arr->exp_cnt)
fprintf(stderr, " ( + %d for expansion)", arr->exp_cnt);
- if (status_msg)
- fprintf(stderr, " %s", status_msg);
- fprintf(stderr, ".\n");
+ fprintf(stderr, " %s.\n", status_msg);
}
static int name_matches(char *found, char *required, char *homehost, int require_homehost)
diff --git a/Create.c b/Create.c
index 9ea19de0..c84c1ac8 100644
--- a/Create.c
+++ b/Create.c
@@ -83,7 +83,7 @@ int default_layout(struct supertype *st, int level, int verbose)
if (layout_map) {
layout = map_name(layout_map, "default");
- layout_name = map_num(layout_map, layout);
+ layout_name = map_num_s(layout_map, layout);
}
if (layout_name && verbose > 0)
pr_err("layout defaults to %s\n", layout_name);
diff --git a/Detail.c b/Detail.c
index 95d4cc70..ce7a8445 100644
--- a/Detail.c
+++ b/Detail.c
@@ -495,8 +495,8 @@ int Detail(char *dev, struct context *c)
if (array.state & (1 << MD_SB_CLEAN)) {
if ((array.level == 0) ||
(array.level == LEVEL_LINEAR))
- arrayst = map_num(sysfs_array_states,
- sra->array_state);
+ arrayst = map_num_s(sysfs_array_states,
+ sra->array_state);
else
arrayst = "clean";
} else {
diff --git a/Grow.c b/Grow.c
index 18c5719b..8a242b0f 100644
--- a/Grow.c
+++ b/Grow.c
@@ -547,7 +547,7 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha
if (s->consistency_policy != CONSISTENCY_POLICY_RESYNC &&
s->consistency_policy != CONSISTENCY_POLICY_PPL) {
pr_err("Operation not supported for consistency policy %s\n",
- map_num(consistency_policies, s->consistency_policy));
+ map_num_s(consistency_policies, s->consistency_policy));
return 1;
}
@@ -578,14 +578,14 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha
if (sra->consistency_policy == (unsigned)s->consistency_policy) {
pr_err("Consistency policy is already %s\n",
- map_num(consistency_policies, s->consistency_policy));
+ map_num_s(consistency_policies, s->consistency_policy));
ret = 1;
goto free_info;
} else if (sra->consistency_policy != CONSISTENCY_POLICY_RESYNC &&
sra->consistency_policy != CONSISTENCY_POLICY_PPL) {
pr_err("Current consistency policy is %s, cannot change to %s\n",
- map_num(consistency_policies, sra->consistency_policy),
- map_num(consistency_policies, s->consistency_policy));
+ map_num_s(consistency_policies, sra->consistency_policy),
+ map_num_s(consistency_policies, s->consistency_policy));
ret = 1;
goto free_info;
}
@@ -704,8 +704,8 @@ int Grow_consistency_policy(char *devname, int fd, struct context *c, struct sha
}
ret = sysfs_set_str(sra, NULL, "consistency_policy",
- map_num(consistency_policies,
- s->consistency_policy));
+ map_num_s(consistency_policies,
+ s->consistency_policy));
if (ret)
pr_err("Failed to change array consistency policy\n");
@@ -2241,7 +2241,7 @@ size_change_error:
info.new_layout = UnSet;
if (info.array.level == 6 && info.new_level == UnSet) {
char l[40], *h;
- strcpy(l, map_num(r6layout, info.array.layout));
+ strcpy(l, map_num_s(r6layout, info.array.layout));
h = strrchr(l, '-');
if (h && strcmp(h, "-6") == 0) {
*h = 0;
@@ -2266,7 +2266,7 @@ size_change_error:
info.new_layout = info.array.layout;
else if (info.array.level == 5 && info.new_level == 6) {
char l[40];
- strcpy(l, map_num(r5layout, info.array.layout));
+ strcpy(l, map_num_s(r5layout, info.array.layout));
strcat(l, "-6");
info.new_layout = map_name(r6layout, l);
} else {
diff --git a/Query.c b/Query.c
index 23fbf8aa..adcd231e 100644
--- a/Query.c
+++ b/Query.c
@@ -93,7 +93,7 @@ int Query(char *dev)
else {
printf("%s: %s %s %d devices, %d spare%s. Use mdadm --detail for more detail.\n",
dev, human_size_brief(larray_size,IEC),
- map_num(pers, level), raid_disks,
+ map_num_s(pers, level), raid_disks,
spare_disks, spare_disks == 1 ? "" : "s");
}
st = guess_super(fd);
@@ -131,7 +131,7 @@ int Query(char *dev)
dev,
info.disk.number, info.array.raid_disks,
activity,
- map_num(pers, info.array.level),
+ map_num_s(pers, info.array.level),
mddev);
if (st->ss == &super0)
put_md_name(mddev);
diff --git a/maps.c b/maps.c
index a4fd2797..20fcf719 100644
--- a/maps.c
+++ b/maps.c
@@ -166,6 +166,30 @@ mapping_t sysfs_array_states[] = {
{ NULL, ARRAY_UNKNOWN_STATE }
};
+/**
+ * map_num_s() - Safer alternative of map_num() function.
+ * @map: map to search.
+ * @num: key to match.
+ *
+ * Shall be used only if key existence is quaranted.
+ *
+ * Return: Pointer to name of the element.
+ */
+char *map_num_s(mapping_t *map, int num)
+{
+ char *ret = map_num(map, num);
+
+ assert(ret);
+ return ret;
+}
+
+/**
+ * map_num() - get element name by key.
+ * @map: map to search.
+ * @num: key to match.
+ *
+ * Return: Pointer to name of the element or NULL.
+ */
char *map_num(mapping_t *map, int num)
{
while (map->name) {
diff --git a/mdadm.c b/mdadm.c
index 26299b2e..be40686c 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -280,8 +280,8 @@ int main(int argc, char *argv[])
else
fprintf(stderr, "-%c", opt);
fprintf(stderr, " would set mdadm mode to \"%s\", but it is already set to \"%s\".\n",
- map_num(modes, newmode),
- map_num(modes, mode));
+ map_num_s(modes, newmode),
+ map_num_s(modes, mode));
exit(2);
} else if (!mode && newmode) {
mode = newmode;
@@ -544,7 +544,7 @@ int main(int argc, char *argv[])
switch(s.level) {
default:
pr_err("layout not meaningful for %s arrays.\n",
- map_num(pers, s.level));
+ map_num_s(pers, s.level));
exit(2);
case UnSet:
pr_err("raid level must be given before layout.\n");
@@ -1248,10 +1248,10 @@ int main(int argc, char *argv[])
if (option_index > 0)
pr_err(":option --%s not valid in %s mode\n",
long_options[option_index].name,
- map_num(modes, mode));
+ map_num_s(modes, mode));
else
pr_err("option -%c not valid in %s mode\n",
- opt, map_num(modes, mode));
+ opt, map_num_s(modes, mode));
exit(2);
}
@@ -1276,7 +1276,7 @@ int main(int argc, char *argv[])
if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN &&
s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) {
pr_err("--write-journal is not supported with consistency policy: %s\n",
- map_num(consistency_policies, s.consistency_policy));
+ map_num_s(consistency_policies, s.consistency_policy));
exit(2);
}
}
@@ -1285,12 +1285,12 @@ int main(int argc, char *argv[])
s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) {
if (s.level <= 0) {
pr_err("--consistency-policy not meaningful with level %s.\n",
- map_num(pers, s.level));
+ map_num_s(pers, s.level));
exit(2);
} else if (s.consistency_policy == CONSISTENCY_POLICY_JOURNAL &&
!s.journaldisks) {
pr_err("--write-journal is required for consistency policy: %s\n",
- map_num(consistency_policies, s.consistency_policy));
+ map_num_s(consistency_policies, s.consistency_policy));
exit(2);
} else if (s.consistency_policy == CONSISTENCY_POLICY_PPL &&
s.level != 5) {
@@ -1300,14 +1300,14 @@ int main(int argc, char *argv[])
(!s.bitmap_file ||
strcmp(s.bitmap_file, "none") == 0)) {
pr_err("--bitmap is required for consistency policy: %s\n",
- map_num(consistency_policies, s.consistency_policy));
+ map_num_s(consistency_policies, s.consistency_policy));
exit(2);
} else if (s.bitmap_file &&
strcmp(s.bitmap_file, "none") != 0 &&
s.consistency_policy != CONSISTENCY_POLICY_BITMAP &&
s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) {
pr_err("--bitmap is not compatible with consistency policy: %s\n",
- map_num(consistency_policies, s.consistency_policy));
+ map_num_s(consistency_policies, s.consistency_policy));
exit(2);
}
}
diff --git a/mdadm.h b/mdadm.h
index cd72e711..09915a00 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -770,7 +770,7 @@ extern int restore_stripes(int *dest, unsigned long long *offsets,
#endif
#define SYSLOG_FACILITY LOG_DAEMON
-
+extern char *map_num_s(mapping_t *map, int num);
extern char *map_num(mapping_t *map, int num);
extern int map_name(mapping_t *map, char *name);
extern mapping_t r0layout[], r5layout[], r6layout[],
diff --git a/super-ddf.c b/super-ddf.c
index 3f304cdc..8cda23a7 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -1477,13 +1477,13 @@ static void examine_vds(struct ddf_super *sb)
printf("\n");
printf(" unit[%d] : %d\n", i, be16_to_cpu(ve->unit));
printf(" state[%d] : %s, %s%s\n", i,
- map_num(ddf_state, ve->state & 7),
+ map_num_s(ddf_state, ve->state & 7),
(ve->state & DDF_state_morphing) ? "Morphing, ": "",
(ve->state & DDF_state_inconsistent)? "Not Consistent" : "Consistent");
printf(" init state[%d] : %s\n", i,
- map_num(ddf_init_state, ve->init_state&DDF_initstate_mask));
+ map_num_s(ddf_init_state, ve->init_state & DDF_initstate_mask));
printf(" access[%d] : %s\n", i,
- map_num(ddf_access, (ve->init_state & DDF_access_mask) >> 6));
+ map_num_s(ddf_access, (ve->init_state & DDF_access_mask) >> 6));
printf(" Name[%d] : %.16s\n", i, ve->name);
examine_vd(i, sb, ve->guid);
}
diff --git a/super-intel.c b/super-intel.c
index 6ff336ee..ba3bd41f 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -5625,7 +5625,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
free(dev);
free(dv);
pr_err("imsm does not support consistency policy %s\n",
- map_num(consistency_policies, s->consistency_policy));
+ map_num_s(consistency_policies, s->consistency_policy));
return 0;
}
diff --git a/super0.c b/super0.c
index b79b97a9..61c9ec1d 100644
--- a/super0.c
+++ b/super0.c
@@ -288,7 +288,7 @@ static void export_examine_super0(struct supertype *st)
{
mdp_super_t *sb = st->sb;
- printf("MD_LEVEL=%s\n", map_num(pers, sb->level));
+ printf("MD_LEVEL=%s\n", map_num_s(pers, sb->level));
printf("MD_DEVICES=%d\n", sb->raid_disks);
if (sb->minor_version >= 90)
printf("MD_UUID=%08x:%08x:%08x:%08x\n",
diff --git a/super1.c b/super1.c
index a12a5bc8..e3e2f954 100644
--- a/super1.c
+++ b/super1.c
@@ -671,7 +671,7 @@ static void export_examine_super1(struct supertype *st)
int len = 32;
int layout;
- printf("MD_LEVEL=%s\n", map_num(pers, __le32_to_cpu(sb->level)));
+ printf("MD_LEVEL=%s\n", map_num_s(pers, __le32_to_cpu(sb->level)));
printf("MD_DEVICES=%d\n", __le32_to_cpu(sb->raid_disks));
for (i = 0; i < 32; i++)
if (sb->set_name[i] == '\n' || sb->set_name[i] == '\0') {
diff --git a/sysfs.c b/sysfs.c
index 2995713d..0d98a65f 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -689,7 +689,7 @@ int sysfs_set_array(struct mdinfo *info, int vers)
if (info->array.level < 0)
return 0; /* FIXME */
rv |= sysfs_set_str(info, NULL, "level",
- map_num(pers, info->array.level));
+ map_num_s(pers, info->array.level));
if (info->reshape_active && info->delta_disks != UnSet)
raid_disks -= info->delta_disks;
rv |= sysfs_set_num(info, NULL, "raid_disks", raid_disks);
@@ -724,9 +724,10 @@ int sysfs_set_array(struct mdinfo *info, int vers)
}
if (info->consistency_policy == CONSISTENCY_POLICY_PPL) {
- if (sysfs_set_str(info, NULL, "consistency_policy",
- map_num(consistency_policies,
- info->consistency_policy))) {
+ char *policy = map_num_s(consistency_policies,
+ info->consistency_policy);
+
+ if (sysfs_set_str(info, NULL, "consistency_policy", policy)) {
pr_err("This kernel does not support PPL. Falling back to consistency-policy=resync.\n");
info->consistency_policy = CONSISTENCY_POLICY_RESYNC;
}
--
2.38.1

View File

@ -1,69 +0,0 @@
From 52c67fcdd6dadc4138ecad73e65599551804d445 Mon Sep 17 00:00:00 2001
From: Coly Li <colyli@suse.de>
Date: Tue, 15 Feb 2022 21:34:15 +0800
Subject: [PATCH 012/125] mdadm/systemd: remove KillMode=none from service file
For mdadm's systemd configuration, current systemd KillMode is "none" in
following service files,
- mdadm-grow-continue@.service
- mdmon@.service
This "none" mode is strongly againsted by systemd developers (see man 5
systemd.kill for "KillMode=" section), and is considering to remove in
future systemd version.
As systemd developer explained in disuccsion, the systemd kill process
is,
1. send the signal specified by KillSignal= to the list of processes (if
any), TERM is the default
2. wait until either the target of process(es) exit or a timeout expires
3. if the timeout expires send the signal specified by FinalKillSignal=,
KILL is the default
For "control-group", all remaining processes will receive the SIGTERM
signal (by default) and if there are still processes after a period f
time, they will get the SIGKILL signal.
For "mixed", only the main process will receive the SIGTERM signal, and
if there are still processes after a period of time, all remaining
processes (including the main one) will receive the SIGKILL signal.
From the above comment, currently KillMode=control-group is a proper
kill mode. Since control-gropu is the default kill mode, the fix can be
simply removing KillMode=none line from the service file, then the
default mode will take effect.
Signed-off-by: Coly Li <colyli@suse.de>
Cc: Benjamin Brunner <bbrunner@suse.com>
Cc: Franck Bui <fbui@suse.de>
Cc: Jes Sorensen <jes@trained-monkey.org>
Cc: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Cc: Neil Brown <neilb@suse.de>
Cc: Xiao Ni <xni@redhat.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
systemd/mdadm-grow-continue@.service | 1 -
systemd/mdmon@.service | 1 -
2 files changed, 2 deletions(-)
diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service
index 5c667d2a..9fdc8ec7 100644
--- a/systemd/mdadm-grow-continue@.service
+++ b/systemd/mdadm-grow-continue@.service
@@ -14,4 +14,3 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I
StandardInput=null
StandardOutput=null
StandardError=null
-KillMode=none
diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service
index 85a3a7c5..77533958 100644
--- a/systemd/mdmon@.service
+++ b/systemd/mdmon@.service
@@ -25,4 +25,3 @@ Type=forking
# it out) and systemd will remove it when transitioning from
# initramfs to rootfs.
#PIDFile=/run/mdadm/%I.pid
-KillMode=none
--
2.38.1

View File

@ -1,122 +0,0 @@
From 1066ab83dbe9a4cc20f7db44a40aa2cbb9d5eed6 Mon Sep 17 00:00:00 2001
From: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Date: Fri, 13 May 2022 09:19:42 +0200
Subject: [PATCH 13/83] mdmon: Stop parsing duplicate options
Introduce new function is_duplicate_opt() to check if given option
was already used and prevent setting it again along with an error
message.
Move parsing above in_initrd() check to be able to detect --offroot
option duplicates.
Now help option is executed after parsing to prevent executing commands
like: 'mdmon --help --ndlksnlksajndfjksndafasj'.
Signed-off-by: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
mdmon.c | 44 +++++++++++++++++++++++++++++++++++---------
1 file changed, 35 insertions(+), 9 deletions(-)
diff --git a/mdmon.c b/mdmon.c
index 5570574b..c057da63 100644
--- a/mdmon.c
+++ b/mdmon.c
@@ -288,6 +288,15 @@ void usage(void)
exit(2);
}
+static bool is_duplicate_opt(const int opt, const int set_val, const char *long_name)
+{
+ if (opt == set_val) {
+ pr_err("--%s option duplicated!\n", long_name);
+ return true;
+ }
+ return false;
+}
+
static int mdmon(char *devnm, int must_fork, int takeover);
int main(int argc, char *argv[])
@@ -299,6 +308,7 @@ int main(int argc, char *argv[])
int all = 0;
int takeover = 0;
int dofork = 1;
+ bool help = false;
static struct option options[] = {
{"all", 0, NULL, 'a'},
{"takeover", 0, NULL, 't'},
@@ -308,37 +318,50 @@ int main(int argc, char *argv[])
{NULL, 0, NULL, 0}
};
- if (in_initrd()) {
- /*
- * set first char of argv[0] to @. This is used by
- * systemd to signal that the task was launched from
- * initrd/initramfs and should be preserved during shutdown
- */
- argv[0][0] = '@';
- }
-
while ((opt = getopt_long(argc, argv, "thaF", options, NULL)) != -1) {
switch (opt) {
case 'a':
+ if (is_duplicate_opt(all, 1, "all"))
+ exit(1);
container_name = argv[optind-1];
all = 1;
break;
case 't':
+ if (is_duplicate_opt(takeover, 1, "takeover"))
+ exit(1);
takeover = 1;
break;
case 'F':
+ if (is_duplicate_opt(dofork, 0, "foreground"))
+ exit(1);
dofork = 0;
break;
case OffRootOpt:
+ if (is_duplicate_opt(argv[0][0], '@', "offroot"))
+ exit(1);
argv[0][0] = '@';
break;
case 'h':
+ if (is_duplicate_opt(help, true, "help"))
+ exit(1);
+ help = true;
+ break;
default:
usage();
break;
}
}
+
+ if (in_initrd()) {
+ /*
+ * set first char of argv[0] to @. This is used by
+ * systemd to signal that the task was launched from
+ * initrd/initramfs and should be preserved during shutdown
+ */
+ argv[0][0] = '@';
+ }
+
if (all == 0 && container_name == NULL) {
if (argv[optind])
container_name = argv[optind];
@@ -353,6 +376,9 @@ int main(int argc, char *argv[])
if (strcmp(container_name, "/proc/mdstat") == 0)
all = 1;
+ if (help)
+ usage();
+
if (all) {
struct mdstat_ent *mdstat, *e;
int container_len = strlen(container_name);
--
2.38.1

View File

@ -1,41 +0,0 @@
From 20e114e334ed6ed3280c37a9a08fb95578393d1a Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Thu, 19 May 2022 09:16:08 +0200
Subject: [PATCH 14/83] Grow: block -n on external volumes.
Performing --raid-devices on external metadata volume should be blocked
as it causes unwanted behaviour.
Eg. Performing
mdadm -G /dev/md/volume -l10 -n4
on r0_d2 inside 4 disk container, returns
mdadm: Need 2 spares to avoid degraded array, only have 0.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Grow.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Grow.c b/Grow.c
index 8a242b0f..f6efbc48 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1892,6 +1892,14 @@ int Grow_reshape(char *devname, int fd,
if (retval) {
pr_err("Cannot read superblock for %s\n", devname);
+ close(cfd);
+ free(subarray);
+ return 1;
+ }
+
+ if (s->raiddisks && subarray) {
+ pr_err("--raid-devices operation can be performed on a container only\n");
+ close(cfd);
free(subarray);
return 1;
}
--
2.38.1

View File

@ -1,90 +0,0 @@
From de064c93e3819d72720e4fba6575265ba10e1553 Mon Sep 17 00:00:00 2001
From: Mateusz Grzonka <mateusz.grzonka@intel.com>
Date: Mon, 13 Jun 2022 12:11:25 +0200
Subject: [PATCH 15/83] Incremental: Fix possible memory and resource leaks
map allocated through map_by_uuid() is not freed if mdfd is invalid.
In addition mdfd is not closed, and mdinfo list is not freed too.
Signed-off-by: Mateusz Grzonka <mateusz.grzonka@intel.com>
Change-Id: I25e726f0e2502cf7e8ce80c2bd7944b3b1e2b9dc
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Incremental.c | 32 +++++++++++++++++++++++---------
1 file changed, 23 insertions(+), 9 deletions(-)
diff --git a/Incremental.c b/Incremental.c
index a57fc323..4d0cd9d6 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -1499,7 +1499,7 @@ static int Incremental_container(struct supertype *st, char *devname,
return 0;
}
for (ra = list ; ra ; ra = ra->next) {
- int mdfd;
+ int mdfd = -1;
char chosen_name[1024];
struct map_ent *mp;
struct mddev_ident *match = NULL;
@@ -1514,6 +1514,12 @@ static int Incremental_container(struct supertype *st, char *devname,
if (mp) {
mdfd = open_dev(mp->devnm);
+ if (!is_fd_valid(mdfd)) {
+ pr_err("failed to open %s: %s.\n",
+ mp->devnm, strerror(errno));
+ rv = 2;
+ goto release;
+ }
if (mp->path)
strcpy(chosen_name, mp->path);
else
@@ -1573,21 +1579,25 @@ static int Incremental_container(struct supertype *st, char *devname,
c->autof,
trustworthy,
chosen_name, 0);
+
+ if (!is_fd_valid(mdfd)) {
+ pr_err("create_mddev failed with chosen name %s: %s.\n",
+ chosen_name, strerror(errno));
+ rv = 2;
+ goto release;
+ }
}
- if (only && (!mp || strcmp(mp->devnm, only) != 0))
- continue;
- if (mdfd < 0) {
- pr_err("failed to open %s: %s.\n",
- chosen_name, strerror(errno));
- return 2;
+ if (only && (!mp || strcmp(mp->devnm, only) != 0)) {
+ close_fd(&mdfd);
+ continue;
}
assemble_container_content(st, mdfd, ra, c,
chosen_name, &result);
map_free(map);
map = NULL;
- close(mdfd);
+ close_fd(&mdfd);
}
if (c->export && result) {
char sep = '=';
@@ -1610,7 +1620,11 @@ static int Incremental_container(struct supertype *st, char *devname,
}
printf("\n");
}
- return 0;
+
+release:
+ map_free(map);
+ sysfs_free(list);
+ return rv;
}
static void run_udisks(char *arg1, char *arg2)
--
2.38.1

View File

@ -1,98 +0,0 @@
From e702f392959d1c2ad2089e595b52235ed97b4e18 Mon Sep 17 00:00:00 2001
From: Kinga Tanska <kinga.tanska@intel.com>
Date: Mon, 6 Jun 2022 12:32:12 +0200
Subject: [PATCH 16/83] Mdmonitor: Fix segfault
Mdadm with "--monitor" parameter requires md device
as an argument to be monitored. If given argument is
not a md device, error shall be returned. Previously
it was not checked and invalid argument caused
segmentation fault. This commit adds checking
that devices passed to mdmonitor are md devices.
Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 10 +++++++++-
mdadm.h | 1 +
mdopen.c | 17 +++++++++++++++++
3 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/Monitor.c b/Monitor.c
index c0ab5412..4e5802b5 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -182,6 +182,7 @@ int Monitor(struct mddev_dev *devlist,
continue;
if (strcasecmp(mdlist->devname, "<ignore>") == 0)
continue;
+
st = xcalloc(1, sizeof *st);
if (mdlist->devname[0] == '/')
st->devname = xstrdup(mdlist->devname);
@@ -190,6 +191,8 @@ int Monitor(struct mddev_dev *devlist,
strcpy(strcpy(st->devname, "/dev/md/"),
mdlist->devname);
}
+ if (!is_mddev(mdlist->devname))
+ return 1;
st->next = statelist;
st->devnm[0] = 0;
st->percent = RESYNC_UNKNOWN;
@@ -203,7 +206,12 @@ int Monitor(struct mddev_dev *devlist,
struct mddev_dev *dv;
for (dv = devlist; dv; dv = dv->next) {
- struct state *st = xcalloc(1, sizeof *st);
+ struct state *st;
+
+ if (!is_mddev(dv->devname))
+ return 1;
+
+ st = xcalloc(1, sizeof *st);
mdlist = conf_get_ident(dv->devname);
st->devname = xstrdup(dv->devname);
st->next = statelist;
diff --git a/mdadm.h b/mdadm.h
index 09915a00..d53df169 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1636,6 +1636,7 @@ extern int create_mddev(char *dev, char *name, int autof, int trustworthy,
#define FOREIGN 2
#define METADATA 3
extern int open_mddev(char *dev, int report_errors);
+extern int is_mddev(char *dev);
extern int open_container(int fd);
extern int metadata_container_matches(char *metadata, char *devnm);
extern int metadata_subdev_matches(char *metadata, char *devnm);
diff --git a/mdopen.c b/mdopen.c
index 245be537..d18c9319 100644
--- a/mdopen.c
+++ b/mdopen.c
@@ -475,6 +475,23 @@ int open_mddev(char *dev, int report_errors)
return mdfd;
}
+/**
+ * is_mddev() - check that file name passed is an md device.
+ * @dev: file name that has to be checked.
+ * Return: 1 if file passed is an md device, 0 if not.
+ */
+int is_mddev(char *dev)
+{
+ int fd = open_mddev(dev, 1);
+
+ if (fd >= 0) {
+ close(fd);
+ return 1;
+ }
+
+ return 0;
+}
+
char *find_free_devnm(int use_partitions)
{
static char devnm[32];
--
2.38.1

View File

@ -1,61 +0,0 @@
From f5ff2988761625b43eb15555993f2797af29f166 Mon Sep 17 00:00:00 2001
From: Kinga Tanska <kinga.tanska@intel.com>
Date: Mon, 6 Jun 2022 12:32:13 +0200
Subject: [PATCH 17/83] Mdmonitor: Improve logging method
Change logging, and as a result, mdmonitor in verbose
mode will report its configuration.
Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
Signed-off-by: Oleksandr Shchirskyi <oleksandr.shchirskyi@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/Monitor.c b/Monitor.c
index 4e5802b5..6ca1ebe5 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -136,24 +136,27 @@ int Monitor(struct mddev_dev *devlist,
struct mddev_ident *mdlist;
int delay_for_event = c->delay;
- if (!mailaddr) {
+ if (!mailaddr)
mailaddr = conf_get_mailaddr();
- if (mailaddr && ! c->scan)
- pr_err("Monitor using email address \"%s\" from config file\n",
- mailaddr);
- }
- mailfrom = conf_get_mailfrom();
- if (!alert_cmd) {
+ if (!alert_cmd)
alert_cmd = conf_get_program();
- if (alert_cmd && !c->scan)
- pr_err("Monitor using program \"%s\" from config file\n",
- alert_cmd);
- }
+
+ mailfrom = conf_get_mailfrom();
+
if (c->scan && !mailaddr && !alert_cmd && !dosyslog) {
pr_err("No mail address or alert command - not monitoring.\n");
return 1;
}
+
+ if (c->verbose) {
+ pr_err("Monitor is started with delay %ds\n", c->delay);
+ if (mailaddr)
+ pr_err("Monitor using email address %s\n", mailaddr);
+ if (alert_cmd)
+ pr_err("Monitor using program %s\n", alert_cmd);
+ }
+
info.alert_cmd = alert_cmd;
info.mailaddr = mailaddr;
info.mailfrom = mailfrom;
--
2.38.1

View File

@ -1,73 +0,0 @@
From 626bc45396c4959f2c4685c2faa7c4f553f4efdf Mon Sep 17 00:00:00 2001
From: Mateusz Grzonka <mateusz.grzonka@intel.com>
Date: Mon, 13 Jun 2022 11:59:34 +0200
Subject: [PATCH 18/83] Fix possible NULL ptr dereferences and memory leaks
In Assemble there was a NULL check for sra variable,
which effectively didn't stop the execution in every case.
That might have resulted in a NULL pointer dereference.
Also in super-ddf, mu variable was set to NULL for some condition,
and then immidiately dereferenced.
Additionally some memory wasn't freed as well.
Signed-off-by: Mateusz Grzonka <mateusz.grzonka@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Assemble.c | 7 ++++++-
super-ddf.c | 9 +++++++--
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index 9eac9ce0..4b213560 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1982,7 +1982,12 @@ int assemble_container_content(struct supertype *st, int mdfd,
}
sra = sysfs_read(mdfd, NULL, GET_VERSION|GET_DEVS);
- if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0) {
+ if (sra == NULL) {
+ pr_err("Failed to read sysfs parameters\n");
+ return 1;
+ }
+
+ if (strcmp(sra->text_version, content->text_version) != 0) {
if (content->array.major_version == -1 &&
content->array.minor_version == -2 &&
c->readonly &&
diff --git a/super-ddf.c b/super-ddf.c
index 8cda23a7..abbc8b09 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -5125,13 +5125,16 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a,
*/
vc = find_vdcr(ddf, a->info.container_member, rv->disk.raid_disk,
&n_bvd, &vcl);
- if (vc == NULL)
+ if (vc == NULL) {
+ free(rv);
return NULL;
+ }
mu = xmalloc(sizeof(*mu));
if (posix_memalign(&mu->space, 512, sizeof(struct vcl)) != 0) {
free(mu);
- mu = NULL;
+ free(rv);
+ return NULL;
}
mu->len = ddf->conf_rec_len * 512 * vcl->conf.sec_elmnt_count;
@@ -5161,6 +5164,8 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a,
pr_err("BUG: can't find disk %d (%d/%d)\n",
di->disk.raid_disk,
di->disk.major, di->disk.minor);
+ free(mu);
+ free(rv);
return NULL;
}
vc->phys_refnum[i_prim] = ddf->phys->entries[dl->pdnum].refnum;
--
2.38.1

View File

@ -1,301 +0,0 @@
From 756a15f32338fdf0c562678694bc8991ad6afb90 Mon Sep 17 00:00:00 2001
From: Mateusz Grzonka <mateusz.grzonka@intel.com>
Date: Mon, 13 Jun 2022 12:00:09 +0200
Subject: [PATCH 19/83] imsm: Remove possibility for get_imsm_dev to return
NULL
Returning NULL from get_imsm_dev or __get_imsm_dev will cause segfault.
Guarantee that it never happens.
Signed-off-by: Mateusz Grzonka <mateusz.grzonka@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-intel.c | 153 +++++++++++++++++++++++++-------------------------
1 file changed, 78 insertions(+), 75 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index ba3bd41f..3788feb9 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -851,6 +851,21 @@ static struct disk_info *get_disk_info(struct imsm_update_create_array *update)
return inf;
}
+/**
+ * __get_imsm_dev() - Get device with index from imsm_super.
+ * @mpb: &imsm_super pointer, not NULL.
+ * @index: Device index.
+ *
+ * Function works as non-NULL, aborting in such a case,
+ * when NULL would be returned.
+ *
+ * Device index should be in range 0 up to num_raid_devs.
+ * Function assumes the index was already verified.
+ * Index must be valid, otherwise abort() is called.
+ *
+ * Return: Pointer to corresponding imsm_dev.
+ *
+ */
static struct imsm_dev *__get_imsm_dev(struct imsm_super *mpb, __u8 index)
{
int offset;
@@ -858,30 +873,47 @@ static struct imsm_dev *__get_imsm_dev(struct imsm_super *mpb, __u8 index)
void *_mpb = mpb;
if (index >= mpb->num_raid_devs)
- return NULL;
+ goto error;
/* devices start after all disks */
offset = ((void *) &mpb->disk[mpb->num_disks]) - _mpb;
- for (i = 0; i <= index; i++)
+ for (i = 0; i <= index; i++, offset += sizeof_imsm_dev(_mpb + offset, 0))
if (i == index)
return _mpb + offset;
- else
- offset += sizeof_imsm_dev(_mpb + offset, 0);
-
- return NULL;
+error:
+ pr_err("cannot find imsm_dev with index %u in imsm_super\n", index);
+ abort();
}
+/**
+ * get_imsm_dev() - Get device with index from intel_super.
+ * @super: &intel_super pointer, not NULL.
+ * @index: Device index.
+ *
+ * Function works as non-NULL, aborting in such a case,
+ * when NULL would be returned.
+ *
+ * Device index should be in range 0 up to num_raid_devs.
+ * Function assumes the index was already verified.
+ * Index must be valid, otherwise abort() is called.
+ *
+ * Return: Pointer to corresponding imsm_dev.
+ *
+ */
static struct imsm_dev *get_imsm_dev(struct intel_super *super, __u8 index)
{
struct intel_dev *dv;
if (index >= super->anchor->num_raid_devs)
- return NULL;
+ goto error;
+
for (dv = super->devlist; dv; dv = dv->next)
if (dv->index == index)
return dv->dev;
- return NULL;
+error:
+ pr_err("cannot find imsm_dev with index %u in intel_super\n", index);
+ abort();
}
static inline unsigned long long __le48_to_cpu(const struct bbm_log_block_addr
@@ -4364,8 +4396,7 @@ int check_mpb_migr_compatibility(struct intel_super *super)
for (i = 0; i < super->anchor->num_raid_devs; i++) {
struct imsm_dev *dev_iter = __get_imsm_dev(super->anchor, i);
- if (dev_iter &&
- dev_iter->vol.migr_state == 1 &&
+ if (dev_iter->vol.migr_state == 1 &&
dev_iter->vol.migr_type == MIGR_GEN_MIGR) {
/* This device is migrating */
map0 = get_imsm_map(dev_iter, MAP_0);
@@ -4514,8 +4545,6 @@ static void clear_hi(struct intel_super *super)
}
for (i = 0; i < mpb->num_raid_devs; ++i) {
struct imsm_dev *dev = get_imsm_dev(super, i);
- if (!dev)
- return;
for (n = 0; n < 2; ++n) {
struct imsm_map *map = get_imsm_map(dev, n);
if (!map)
@@ -5836,7 +5865,7 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
struct imsm_dev *_dev = __get_imsm_dev(mpb, 0);
_disk = __get_imsm_disk(mpb, dl->index);
- if (!_dev || !_disk) {
+ if (!_disk) {
pr_err("BUG mpb setup error\n");
return 1;
}
@@ -6171,10 +6200,10 @@ static int write_super_imsm(struct supertype *st, int doclose)
for (i = 0; i < mpb->num_raid_devs; i++) {
struct imsm_dev *dev = __get_imsm_dev(mpb, i);
struct imsm_dev *dev2 = get_imsm_dev(super, i);
- if (dev && dev2) {
- imsm_copy_dev(dev, dev2);
- mpb_size += sizeof_imsm_dev(dev, 0);
- }
+
+ imsm_copy_dev(dev, dev2);
+ mpb_size += sizeof_imsm_dev(dev, 0);
+
if (is_gen_migration(dev2))
clear_migration_record = 0;
}
@@ -9033,29 +9062,26 @@ static int imsm_rebuild_allowed(struct supertype *cont, int dev_idx, int failed)
__u8 state;
dev2 = get_imsm_dev(cont->sb, dev_idx);
- if (dev2) {
- state = imsm_check_degraded(cont->sb, dev2, failed, MAP_0);
- if (state == IMSM_T_STATE_FAILED) {
- map = get_imsm_map(dev2, MAP_0);
- if (!map)
- return 1;
- for (slot = 0; slot < map->num_members; slot++) {
- /*
- * Check if failed disks are deleted from intel
- * disk list or are marked to be deleted
- */
- idx = get_imsm_disk_idx(dev2, slot, MAP_X);
- idisk = get_imsm_dl_disk(cont->sb, idx);
- /*
- * Do not rebuild the array if failed disks
- * from failed sub-array are not removed from
- * container.
- */
- if (idisk &&
- is_failed(&idisk->disk) &&
- (idisk->action != DISK_REMOVE))
- return 0;
- }
+
+ state = imsm_check_degraded(cont->sb, dev2, failed, MAP_0);
+ if (state == IMSM_T_STATE_FAILED) {
+ map = get_imsm_map(dev2, MAP_0);
+ for (slot = 0; slot < map->num_members; slot++) {
+ /*
+ * Check if failed disks are deleted from intel
+ * disk list or are marked to be deleted
+ */
+ idx = get_imsm_disk_idx(dev2, slot, MAP_X);
+ idisk = get_imsm_dl_disk(cont->sb, idx);
+ /*
+ * Do not rebuild the array if failed disks
+ * from failed sub-array are not removed from
+ * container.
+ */
+ if (idisk &&
+ is_failed(&idisk->disk) &&
+ (idisk->action != DISK_REMOVE))
+ return 0;
}
}
return 1;
@@ -10089,7 +10115,6 @@ static void imsm_process_update(struct supertype *st,
int victim = u->dev_idx;
struct active_array *a;
struct intel_dev **dp;
- struct imsm_dev *dev;
/* sanity check that we are not affecting the uuid of
* active arrays, or deleting an active array
@@ -10105,8 +10130,7 @@ static void imsm_process_update(struct supertype *st,
* is active in the container, so checking
* mpb->num_raid_devs is just extra paranoia
*/
- dev = get_imsm_dev(super, victim);
- if (a || !dev || mpb->num_raid_devs == 1) {
+ if (a || mpb->num_raid_devs == 1 || victim >= super->anchor->num_raid_devs) {
dprintf("failed to delete subarray-%d\n", victim);
break;
}
@@ -10140,7 +10164,7 @@ static void imsm_process_update(struct supertype *st,
if (a->info.container_member == target)
break;
dev = get_imsm_dev(super, u->dev_idx);
- if (a || !dev || !check_name(super, name, 1)) {
+ if (a || !check_name(super, name, 1)) {
dprintf("failed to rename subarray-%d\n", target);
break;
}
@@ -10169,10 +10193,6 @@ static void imsm_process_update(struct supertype *st,
struct imsm_update_rwh_policy *u = (void *)update->buf;
int target = u->dev_idx;
struct imsm_dev *dev = get_imsm_dev(super, target);
- if (!dev) {
- dprintf("could not find subarray-%d\n", target);
- break;
- }
if (dev->rwh_policy != u->new_policy) {
dev->rwh_policy = u->new_policy;
@@ -11397,8 +11417,10 @@ static int imsm_create_metadata_update_for_migration(
{
struct intel_super *super = st->sb;
int update_memory_size;
+ int current_chunk_size;
struct imsm_update_reshape_migration *u;
- struct imsm_dev *dev;
+ struct imsm_dev *dev = get_imsm_dev(super, super->current_vol);
+ struct imsm_map *map = get_imsm_map(dev, MAP_0);
int previous_level = -1;
dprintf("(enter) New Level = %i\n", geo->level);
@@ -11415,23 +11437,15 @@ static int imsm_create_metadata_update_for_migration(
u->new_disks[0] = -1;
u->new_chunksize = -1;
- dev = get_imsm_dev(super, u->subdev);
- if (dev) {
- struct imsm_map *map;
+ current_chunk_size = __le16_to_cpu(map->blocks_per_strip) / 2;
- map = get_imsm_map(dev, MAP_0);
- if (map) {
- int current_chunk_size =
- __le16_to_cpu(map->blocks_per_strip) / 2;
-
- if (geo->chunksize != current_chunk_size) {
- u->new_chunksize = geo->chunksize / 1024;
- dprintf("imsm: chunk size change from %i to %i\n",
- current_chunk_size, u->new_chunksize);
- }
- previous_level = map->raid_level;
- }
+ if (geo->chunksize != current_chunk_size) {
+ u->new_chunksize = geo->chunksize / 1024;
+ dprintf("imsm: chunk size change from %i to %i\n",
+ current_chunk_size, u->new_chunksize);
}
+ previous_level = map->raid_level;
+
if (geo->level == 5 && previous_level == 0) {
struct mdinfo *spares = NULL;
@@ -12519,9 +12533,6 @@ static int validate_internal_bitmap_imsm(struct supertype *st)
unsigned long long offset;
struct dl *d;
- if (!dev)
- return -1;
-
if (dev->rwh_policy != RWH_BITMAP)
return 0;
@@ -12567,16 +12578,8 @@ static int add_internal_bitmap_imsm(struct supertype *st, int *chunkp,
return -1;
dev = get_imsm_dev(super, vol_idx);
-
- if (!dev) {
- dprintf("cannot find the device for volume index %d\n",
- vol_idx);
- return -1;
- }
dev->rwh_policy = RWH_BITMAP;
-
*chunkp = calculate_bitmap_chunksize(st, dev);
-
return 0;
}
--
2.38.1

View File

@ -1,85 +0,0 @@
From 190dc029b141c423e724566cbed5d5afbb10b05a Mon Sep 17 00:00:00 2001
From: Nigel Croxon <ncroxon@redhat.com>
Date: Mon, 18 Apr 2022 13:44:23 -0400
Subject: [PATCH 20/83] Revert "mdadm: fix coredump of mdadm --monitor -r"
This reverts commit 546047688e1c64638f462147c755b58119cabdc8.
The change from commit mdadm: fix coredump of mdadm
--monitor -r broke the printing of the return message when
passing -r to mdadm --manage, the removal of a device from
an array.
If the current code reverts this commit, both issues are
still fixed.
The original problem reported that the fix tried to address
was: The --monitor -r option requires a parameter,
otherwise a null pointer will be manipulated when
converting to integer data, and a core dump will appear.
The original problem was really fixed with:
60815698c0a Refactor parse_num and use it to parse optarg.
Which added a check for NULL in 'optarg' before moving it
to the 'increments' variable.
New issue: When trying to remove a device using the short
argument -r, instead of the long argument --remove, the
output is empty. The problem started when commit
546047688e1c was added.
Steps to Reproduce:
1. create/assemble /dev/md0 device
2. mdadm --manage /dev/md0 -r /dev/vdxx
Actual results:
Nothing, empty output, nothing happens, the device is still
connected to the array.
The output should have stated "mdadm: hot remove failed
for /dev/vdxx: Device or resource busy", if the device was
still active. Or it should remove the device and print
a message:
mdadm: set /dev/vdd faulty in /dev/md0
mdadm: hot removed /dev/vdd from /dev/md0
The following commit should be reverted as it breaks
mdadm --manage -r.
commit 546047688e1c64638f462147c755b58119cabdc8
Author: Wu Guanghao <wuguanghao3@huawei.com>
Date: Mon Aug 16 15:24:51 2021 +0800
mdadm: fix coredump of mdadm --monitor -r
-Nigel
Signed-off-by: Nigel Croxon <ncroxon@redhat.com>
Acked-by: Coly Li <colyli@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
ReadMe.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/ReadMe.c b/ReadMe.c
index 8f873c48..bec1be9a 100644
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -81,11 +81,11 @@ char Version[] = "mdadm - v" VERSION " - " VERS_DATE EXTRAVERSION "\n";
* found, it is started.
*/
-char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:r:n:x:u:c:d:z:U:N:safRSow1tye:k";
+char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:";
char short_bitmap_options[]=
- "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:r:n:x:u:c:d:z:U:N:sarfRSow1tye:k:";
+ "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:";
char short_bitmap_auto_options[]=
- "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:r:n:x:u:c:d:z:U:N:sa:rfRSow1tye:k:";
+ "-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sa:rfRSow1tye:k:";
struct option long_options[] = {
{"manage", 0, 0, ManageOpt},
--
2.38.1

View File

@ -1,31 +0,0 @@
From 953cc7e5a485a91ddec7312c7a5d7779749fad5f Mon Sep 17 00:00:00 2001
From: Kinga Tanska <kinga.tanska@intel.com>
Date: Tue, 21 Jun 2022 00:10:39 +0800
Subject: [PATCH 21/83] util: replace ioctl use with function
Replace using of ioctl calling to get md array info with
special function prepared to it.
Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
Acked-by: Coly Li <colyli@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
util.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/util.c b/util.c
index cc94f96e..38f0420e 100644
--- a/util.c
+++ b/util.c
@@ -267,7 +267,7 @@ int md_array_active(int fd)
* GET_ARRAY_INFO doesn't provide access to the proper state
* information, so fallback to a basic check for raid_disks != 0
*/
- ret = ioctl(fd, GET_ARRAY_INFO, &array);
+ ret = md_get_array_info(fd, &array);
}
return !ret;
--
2.38.1

View File

@ -1,110 +0,0 @@
From 63902857b98c37c8ac4b837bb01d006b327a4532 Mon Sep 17 00:00:00 2001
From: Heming Zhao <heming.zhao@suse.com>
Date: Tue, 21 Jun 2022 00:10:40 +0800
Subject: [PATCH 22/83] mdadm/super1: restore commit 45a87c2f31335 to fix
clustered slot issue
Commit 9d67f6496c71 ("mdadm:check the nodes when operate clustered
array") modified assignment logic for st->nodes in write_bitmap1(),
which introduced bitmap slot issue:
load_super1 didn't set up supertype.nodes, which made spare disk only
have one slot info. Then it triggered kernel md_bitmap_load_sb to get
wrong bitmap slot data.
For fixing this issue, there are two methods:
1> revert the related code of commit 9d67f6496c71. and restore the code
from former commit 45a87c2f31335 ("super1: add more checks for
NodeNumUpdate option").
st->nodes value would be 0 & 1 under current code logic. i.e.
When adding a spare disk, there is no place to init st->nodes, and
the value is ZERO.
2> keep 9d67f6496c71, add additional ->nodes handling in load_super1(),
let load_super1 to set st->nodes when bitmap is BITMAP_MAJOR_CLUSTERED.
Under current mdadm code logic, load_super1 will be called many
times, any new code in load_super1 will cost mdadm running more time.
And more reason is I prefer as much as possible to limit clustered
code spreading in every corner.
So I used method <1> to fix this issue.
How to trigger:
dd if=/dev/zero bs=1M count=1 oflag=direct of=/dev/sda
dd if=/dev/zero bs=1M count=1 oflag=direct of=/dev/sdb
dd if=/dev/zero bs=1M count=1 oflag=direct of=/dev/sdc
mdadm -C /dev/md0 -b clustered -e 1.2 -n 2 -l mirror /dev/sda /dev/sdb
mdadm -a /dev/md0 /dev/sdc
mdadm /dev/md0 --fail /dev/sda
mdadm /dev/md0 --remove /dev/sda
mdadm -Ss
mdadm -A /dev/md0 /dev/sdb /dev/sdc
the output of current "mdadm -X /dev/sdc":
(there should be (by default) 4 slot info for correct output)
```
Filename : /dev/sdc
Magic : 6d746962
Version : 5
UUID : a74642f8:a6b1fba8:58e1f8db:cfe7b082
Events : 29
Events Cleared : 0
State : OK
Chunksize : 64 MB
Daemon : 5s flush period
Write Mode : Normal
Sync Size : 306176 (299.00 MiB 313.52 MB)
Bitmap : 5 bits (chunks), 5 dirty (100.0%)
```
And mdadm later operations will trigger kernel output error message:
(triggered by "mdadm -A /dev/md0 /dev/sdb /dev/sdc")
```
kernel: md0: invalid bitmap file superblock: bad magic
kernel: md_bitmap_copy_from_slot can't get bitmap from slot 1
kernel: md-cluster: Could not gather bitmaps from slot 1
kernel: md0: invalid bitmap file superblock: bad magic
kernel: md_bitmap_copy_from_slot can't get bitmap from slot 2
kernel: md-cluster: Could not gather bitmaps from slot 2
kernel: md0: invalid bitmap file superblock: bad magic
kernel: md_bitmap_copy_from_slot can't get bitmap from slot 3
kernel: md-cluster: Could not gather bitmaps from slot 3
kernel: md-cluster: failed to gather all resyn infos
kernel: md0: detected capacity change from 0 to 612352
```
Acked-by: Coly Li <colyli@suse.de>
Signed-off-by: Heming Zhao <heming.zhao@suse.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super1.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/super1.c b/super1.c
index e3e2f954..3a0c69fd 100644
--- a/super1.c
+++ b/super1.c
@@ -2674,7 +2674,17 @@ static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update
}
if (bms->version == BITMAP_MAJOR_CLUSTERED) {
- if (__cpu_to_le32(st->nodes) < bms->nodes) {
+ if (st->nodes == 1) {
+ /* the parameter for nodes is not valid */
+ pr_err("Warning: cluster-md at least needs two nodes\n");
+ return -EINVAL;
+ } else if (st->nodes == 0) {
+ /*
+ * parameter "--nodes" is not specified, (eg, add a disk to
+ * clustered raid)
+ */
+ break;
+ } else if (__cpu_to_le32(st->nodes) < bms->nodes) {
/*
* Since the nodes num is not increased, no
* need to check the space enough or not,
--
2.38.1

View File

@ -1,122 +0,0 @@
From 76c152ca9851e9fcdf52e8f6e7e6c09b936bdd14 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Tue, 21 Jun 2022 00:10:41 +0800
Subject: [PATCH 23/83] imsm: introduce get_disk_slot_in_dev()
The routine was added to remove unnecessary get_imsm_dev() and
get_imsm_map() calls, used only to determine disk slot.
Additionally, enum for IMSM return statues was added for further usage.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Acked-by: Coly Li <colyli@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-intel.c | 47 ++++++++++++++++++++++++++++++++++++-----------
1 file changed, 36 insertions(+), 11 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index 3788feb9..cd1f1e3d 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -366,6 +366,18 @@ struct migr_record {
};
ASSERT_SIZE(migr_record, 128)
+/**
+ * enum imsm_status - internal IMSM return values representation.
+ * @STATUS_OK: function succeeded.
+ * @STATUS_ERROR: General error ocurred (not specified).
+ *
+ * Typedefed to imsm_status_t.
+ */
+typedef enum imsm_status {
+ IMSM_STATUS_ERROR = -1,
+ IMSM_STATUS_OK = 0,
+} imsm_status_t;
+
struct md_list {
/* usage marker:
* 1: load metadata
@@ -1183,7 +1195,7 @@ static void set_imsm_ord_tbl_ent(struct imsm_map *map, int slot, __u32 ord)
map->disk_ord_tbl[slot] = __cpu_to_le32(ord);
}
-static int get_imsm_disk_slot(struct imsm_map *map, unsigned idx)
+static int get_imsm_disk_slot(struct imsm_map *map, const unsigned int idx)
{
int slot;
__u32 ord;
@@ -1194,7 +1206,7 @@ static int get_imsm_disk_slot(struct imsm_map *map, unsigned idx)
return slot;
}
- return -1;
+ return IMSM_STATUS_ERROR;
}
static int get_imsm_raid_level(struct imsm_map *map)
@@ -1209,6 +1221,23 @@ static int get_imsm_raid_level(struct imsm_map *map)
return map->raid_level;
}
+/**
+ * get_disk_slot_in_dev() - retrieve disk slot from &imsm_dev.
+ * @super: &intel_super pointer, not NULL.
+ * @dev_idx: imsm device index.
+ * @idx: disk index.
+ *
+ * Return: Slot on success, IMSM_STATUS_ERROR otherwise.
+ */
+static int get_disk_slot_in_dev(struct intel_super *super, const __u8 dev_idx,
+ const unsigned int idx)
+{
+ struct imsm_dev *dev = get_imsm_dev(super, dev_idx);
+ struct imsm_map *map = get_imsm_map(dev, MAP_0);
+
+ return get_imsm_disk_slot(map, idx);
+}
+
static int cmp_extent(const void *av, const void *bv)
{
const struct extent *a = av;
@@ -1225,13 +1254,9 @@ static int count_memberships(struct dl *dl, struct intel_super *super)
int memberships = 0;
int i;
- for (i = 0; i < super->anchor->num_raid_devs; i++) {
- struct imsm_dev *dev = get_imsm_dev(super, i);
- struct imsm_map *map = get_imsm_map(dev, MAP_0);
-
- if (get_imsm_disk_slot(map, dl->index) >= 0)
+ for (i = 0; i < super->anchor->num_raid_devs; i++)
+ if (get_disk_slot_in_dev(super, i, dl->index) >= 0)
memberships++;
- }
return memberships;
}
@@ -1941,6 +1966,7 @@ void examine_migr_rec_imsm(struct intel_super *super)
/* first map under migration */
map = get_imsm_map(dev, MAP_0);
+
if (map)
slot = get_imsm_disk_slot(map, super->disks->index);
if (map == NULL || slot > 1 || slot < 0) {
@@ -9655,10 +9681,9 @@ static int apply_update_activate_spare(struct imsm_update_activate_spare *u,
/* count arrays using the victim in the metadata */
found = 0;
for (a = active_array; a ; a = a->next) {
- dev = get_imsm_dev(super, a->info.container_member);
- map = get_imsm_map(dev, MAP_0);
+ int dev_idx = a->info.container_member;
- if (get_imsm_disk_slot(map, victim) >= 0)
+ if (get_disk_slot_in_dev(super, dev_idx, victim) >= 0)
found++;
}
--
2.38.1

View File

@ -1,252 +0,0 @@
From 6d4d9ab295de165e57b5c30e044028dbffb8f297 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Tue, 21 Jun 2022 00:10:42 +0800
Subject: [PATCH 24/83] imsm: use same slot across container
Autolayout relies on drives order on super->disks list, but
it is not quaranted by readdir() in sysfs_read(). As a result
drive could be put in different slot in second volume.
Make it consistent by reffering to first volume, if exists.
Use enum imsm_status to unify error handling.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Acked-by: Coly Li <colyli@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-intel.c | 169 ++++++++++++++++++++++++++++++++------------------
1 file changed, 108 insertions(+), 61 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index cd1f1e3d..deef7c87 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -7522,11 +7522,27 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
return 1;
}
-static int imsm_get_free_size(struct supertype *st, int raiddisks,
- unsigned long long size, int chunk,
- unsigned long long *freesize)
+/**
+ * imsm_get_free_size() - get the biggest, common free space from members.
+ * @super: &intel_super pointer, not NULL.
+ * @raiddisks: number of raid disks.
+ * @size: requested size, could be 0 (means max size).
+ * @chunk: requested chunk.
+ * @freesize: pointer for returned size value.
+ *
+ * Return: &IMSM_STATUS_OK or &IMSM_STATUS_ERROR.
+ *
+ * @freesize is set to meaningful value, this can be @size, or calculated
+ * max free size.
+ * super->create_offset value is modified and set appropriately in
+ * merge_extends() for further creation.
+ */
+static imsm_status_t imsm_get_free_size(struct intel_super *super,
+ const int raiddisks,
+ unsigned long long size,
+ const int chunk,
+ unsigned long long *freesize)
{
- struct intel_super *super = st->sb;
struct imsm_super *mpb = super->anchor;
struct dl *dl;
int i;
@@ -7570,12 +7586,10 @@ static int imsm_get_free_size(struct supertype *st, int raiddisks,
/* chunk is in K */
minsize = chunk * 2;
- if (cnt < raiddisks ||
- (super->orom && used && used != raiddisks) ||
- maxsize < minsize ||
- maxsize == 0) {
+ if (cnt < raiddisks || (super->orom && used && used != raiddisks) ||
+ maxsize < minsize || maxsize == 0) {
pr_err("not enough devices with space to create array.\n");
- return 0; /* No enough free spaces large enough */
+ return IMSM_STATUS_ERROR;
}
if (size == 0) {
@@ -7588,37 +7602,69 @@ static int imsm_get_free_size(struct supertype *st, int raiddisks,
}
if (mpb->num_raid_devs > 0 && size && size != maxsize)
pr_err("attempting to create a second volume with size less then remaining space.\n");
- cnt = 0;
- for (dl = super->disks; dl; dl = dl->next)
- if (dl->e)
- dl->raiddisk = cnt++;
-
*freesize = size;
dprintf("imsm: imsm_get_free_size() returns : %llu\n", size);
- return 1;
+ return IMSM_STATUS_OK;
}
-static int reserve_space(struct supertype *st, int raiddisks,
- unsigned long long size, int chunk,
- unsigned long long *freesize)
+/**
+ * autolayout_imsm() - automatically layout a new volume.
+ * @super: &intel_super pointer, not NULL.
+ * @raiddisks: number of raid disks.
+ * @size: requested size, could be 0 (means max size).
+ * @chunk: requested chunk.
+ * @freesize: pointer for returned size value.
+ *
+ * We are being asked to automatically layout a new volume based on the current
+ * contents of the container. If the parameters can be satisfied autolayout_imsm
+ * will record the disks, start offset, and will return size of the volume to
+ * be created. See imsm_get_free_size() for details.
+ * add_to_super() and getinfo_super() detect when autolayout is in progress.
+ * If first volume exists, slots are set consistently to it.
+ *
+ * Return: &IMSM_STATUS_OK on success, &IMSM_STATUS_ERROR otherwise.
+ *
+ * Disks are marked for creation via dl->raiddisk.
+ */
+static imsm_status_t autolayout_imsm(struct intel_super *super,
+ const int raiddisks,
+ unsigned long long size, const int chunk,
+ unsigned long long *freesize)
{
- struct intel_super *super = st->sb;
- struct dl *dl;
- int cnt;
- int rv = 0;
+ int curr_slot = 0;
+ struct dl *disk;
+ int vol_cnt = super->anchor->num_raid_devs;
+ imsm_status_t rv;
- rv = imsm_get_free_size(st, raiddisks, size, chunk, freesize);
- if (rv) {
- cnt = 0;
- for (dl = super->disks; dl; dl = dl->next)
- if (dl->e)
- dl->raiddisk = cnt++;
- rv = 1;
+ rv = imsm_get_free_size(super, raiddisks, size, chunk, freesize);
+ if (rv != IMSM_STATUS_OK)
+ return IMSM_STATUS_ERROR;
+
+ for (disk = super->disks; disk; disk = disk->next) {
+ if (!disk->e)
+ continue;
+
+ if (curr_slot == raiddisks)
+ break;
+
+ if (vol_cnt == 0) {
+ disk->raiddisk = curr_slot;
+ } else {
+ int _slot = get_disk_slot_in_dev(super, 0, disk->index);
+
+ if (_slot == -1) {
+ pr_err("Disk %s is not used in first volume, aborting\n",
+ disk->devname);
+ return IMSM_STATUS_ERROR;
+ }
+ disk->raiddisk = _slot;
+ }
+ curr_slot++;
}
- return rv;
+ return IMSM_STATUS_OK;
}
static int validate_geometry_imsm(struct supertype *st, int level, int layout,
@@ -7654,35 +7700,35 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
}
if (!dev) {
- if (st->sb) {
- struct intel_super *super = st->sb;
- if (!validate_geometry_imsm_orom(st->sb, level, layout,
- raiddisks, chunk, size,
- verbose))
+ struct intel_super *super = st->sb;
+
+ /*
+ * Autolayout mode, st->sb and freesize must be set.
+ */
+ if (!super || !freesize) {
+ pr_vrb("freesize and superblock must be set for autolayout, aborting\n");
+ return 1;
+ }
+
+ if (!validate_geometry_imsm_orom(st->sb, level, layout,
+ raiddisks, chunk, size,
+ verbose))
+ return 0;
+
+ if (super->orom) {
+ imsm_status_t rv;
+ int count = count_volumes(super->hba, super->orom->dpa,
+ verbose);
+ if (super->orom->vphba <= count) {
+ pr_vrb("platform does not support more than %d raid volumes.\n",
+ super->orom->vphba);
return 0;
- /* we are being asked to automatically layout a
- * new volume based on the current contents of
- * the container. If the the parameters can be
- * satisfied reserve_space will record the disks,
- * start offset, and size of the volume to be
- * created. add_to_super and getinfo_super
- * detect when autolayout is in progress.
- */
- /* assuming that freesize is always given when array is
- created */
- if (super->orom && freesize) {
- int count;
- count = count_volumes(super->hba,
- super->orom->dpa, verbose);
- if (super->orom->vphba <= count) {
- pr_vrb("platform does not support more than %d raid volumes.\n",
- super->orom->vphba);
- return 0;
- }
}
- if (freesize)
- return reserve_space(st, raiddisks, size,
- *chunk, freesize);
+
+ rv = autolayout_imsm(super, raiddisks, size, *chunk,
+ freesize);
+ if (rv != IMSM_STATUS_OK)
+ return 0;
}
return 1;
}
@@ -11538,7 +11584,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
unsigned long long current_size;
unsigned long long free_size;
unsigned long long max_size;
- int rv;
+ imsm_status_t rv;
getinfo_super_imsm_volume(st, &info, NULL);
if (geo->level != info.array.level && geo->level >= 0 &&
@@ -11657,9 +11703,10 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
}
/* check the maximum available size
*/
- rv = imsm_get_free_size(st, dev->vol.map->num_members,
- 0, chunk, &free_size);
- if (rv == 0)
+ rv = imsm_get_free_size(super, dev->vol.map->num_members,
+ 0, chunk, &free_size);
+
+ if (rv != IMSM_STATUS_OK)
/* Cannot find maximum available space
*/
max_size = 0;
--
2.38.1

Some files were not shown because too many files have changed in this diff Show More