Compare commits

...

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

159 changed files with 9241 additions and 12590 deletions

6
.gitignore vendored
View File

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

View File

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

View File

@ -0,0 +1,64 @@
From aec3b907de48be54106600a1ecb69d1231f4801d Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Thu, 18 Jan 2024 11:30:15 +0100
Subject: [PATCH 01/41] Remove hardcoded checkpoint interval checking
Mdmon assumes that kernel marks checkpoint every 1/16 of the volume size
and that the checkpoints are equal in size. This is not true, kernel may
mark checkpoints more frequently depending on several factors, including
sync speed. This results in checkpoints reported by mdadm --examine
falling behind the one reported by kernel.
Remove hardcoded checkpoint interval checking.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
monitor.c | 22 ++++++----------------
1 file changed, 6 insertions(+), 16 deletions(-)
diff --git a/monitor.c b/monitor.c
index 4acec678..b8d9e881 100644
--- a/monitor.c
+++ b/monitor.c
@@ -564,22 +564,10 @@ static int read_and_act(struct active_array *a, fd_set *fds)
}
}
- /* Check for recovery checkpoint notifications. We need to be a
- * minimum distance away from the last checkpoint to prevent
- * over checkpointing. Note reshape checkpointing is handled
- * in the second branch.
+ /* Handle reshape checkpointing
*/
- if (sync_completed > a->last_checkpoint &&
- sync_completed - a->last_checkpoint > a->info.component_size >> 4 &&
- a->curr_action > reshape) {
- /* A (non-reshape) sync_action has reached a checkpoint.
- * Record the updated position in the metadata
- */
- a->last_checkpoint = sync_completed;
- a->container->ss->set_array_state(a, a->curr_state <= clean);
- } else if ((a->curr_action == idle && a->prev_action == reshape) ||
- (a->curr_action == reshape &&
- sync_completed > a->last_checkpoint)) {
+ if ((a->curr_action == idle && a->prev_action == reshape) ||
+ (a->curr_action == reshape && sync_completed > a->last_checkpoint)) {
/* Reshape has progressed or completed so we need to
* update the array state - and possibly the array size
*/
@@ -607,8 +595,10 @@ static int read_and_act(struct active_array *a, fd_set *fds)
a->last_checkpoint = sync_completed;
}
- if (sync_completed > a->last_checkpoint)
+ if (sync_completed > a->last_checkpoint) {
a->last_checkpoint = sync_completed;
+ a->container->ss->set_array_state(a, a->curr_state <= clean);
+ }
if (sync_completed >= a->info.component_size)
a->last_checkpoint = 0;
--
2.40.1

View File

@ -0,0 +1,96 @@
From cf87fe75fd83dac008ea116c2c52ec69783fdf6a Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Thu, 18 Jan 2024 11:30:16 +0100
Subject: [PATCH 02/41] monitor: refactor checkpoint update
"if" statements of checkpoint updates have too many responsibilties.
This results in unclear code flow and duplicated code.
Refactor checkpoint update code and simplify "if" statements.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
monitor.c | 51 +++++++++++++++++++++++++--------------------------
1 file changed, 25 insertions(+), 26 deletions(-)
diff --git a/monitor.c b/monitor.c
index b8d9e881..be0bec78 100644
--- a/monitor.c
+++ b/monitor.c
@@ -412,6 +412,7 @@ static int read_and_act(struct active_array *a, fd_set *fds)
int ret = 0;
int count = 0;
struct timeval tv;
+ bool write_checkpoint = false;
a->next_state = bad_word;
a->next_action = bad_action;
@@ -564,40 +565,38 @@ static int read_and_act(struct active_array *a, fd_set *fds)
}
}
- /* Handle reshape checkpointing
- */
- if ((a->curr_action == idle && a->prev_action == reshape) ||
- (a->curr_action == reshape && sync_completed > a->last_checkpoint)) {
- /* Reshape has progressed or completed so we need to
- * update the array state - and possibly the array size
- */
+ /* Update reshape checkpoint, depending if it finished or progressed */
+ if (a->curr_action == idle && a->prev_action == reshape) {
+ char buf[SYSFS_MAX_BUF_SIZE];
+
if (sync_completed != 0)
a->last_checkpoint = sync_completed;
- /* We might need to update last_checkpoint depending on
- * the reason that reshape finished.
- * if array reshape is really finished:
- * set check point to the end, this allows
- * set_array_state() to finalize reshape in metadata
- * if reshape if broken: do not set checkpoint to the end
- * this allows for reshape restart from checkpoint
+
+ /*
+ * If reshape really finished, set checkpoint to the end to finalize it.
+ * Do not set checkpoint if reshape is broken.
+ * Reshape will restart from last checkpoint.
*/
- if ((a->curr_action != reshape) &&
- (a->prev_action == reshape)) {
- char buf[SYSFS_MAX_BUF_SIZE];
- if ((sysfs_get_str(&a->info, NULL,
- "reshape_position",
- buf,
- sizeof(buf)) >= 0) &&
- str_is_none(buf) == true)
+ if (sysfs_get_str(&a->info, NULL, "reshape_position", buf, sizeof(buf)) >= 0)
+ if (str_is_none(buf) == true)
a->last_checkpoint = a->info.component_size;
- }
- a->container->ss->set_array_state(a, a->curr_state <= clean);
- a->last_checkpoint = sync_completed;
+
+ write_checkpoint = true;
}
- if (sync_completed > a->last_checkpoint) {
+ if (a->curr_action >= reshape && sync_completed > a->last_checkpoint) {
+ /* Update checkpoint if neither reshape nor idle action */
a->last_checkpoint = sync_completed;
+
+ write_checkpoint = true;
+ }
+
+ /* Save checkpoint */
+ if (write_checkpoint) {
a->container->ss->set_array_state(a, a->curr_state <= clean);
+
+ if (a->curr_action <= reshape)
+ a->last_checkpoint = sync_completed;
}
if (sync_completed >= a->info.component_size)
--
2.40.1

View File

@ -0,0 +1,47 @@
From fdb7e802f4cf64d067c3abaafa35056e2bc1ed43 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Thu, 18 Jan 2024 11:30:17 +0100
Subject: [PATCH 03/41] Super-intel: Fix first checkpoint restart
When imsm based array is stopped after reaching first checkpoint and
then assembled, first checkpoint is reported as 0.
This behaviour is valid only for initial checkpoint, if the array was
stopped while performing some action.
Last checkpoint value is not taken from metadata but always starts
with 0 and it's incremented when sync_completed in sysfs changes.
In simplification, read_and_act() is responsible for checkpoint updates
and is executed each time sysfs checkpoint update happens. For first
checkpoint it is executed twice and due to marking checkpoint before
triggering any action on the array, it is impossible to read
sync_completed from sysfs in just two iterations.
The workaround to this is not marking any checkpoint for first
sysfs checkpoint after RAID assembly, to preserve checkpoint value
stored in metadata.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
super-intel.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/super-intel.c b/super-intel.c
index dbea235d..e61f3f6f 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -8771,6 +8771,9 @@ static int imsm_set_array_state(struct active_array *a, int consistent)
super->updates_pending++;
}
+ if (a->prev_action == idle)
+ goto skip_mark_checkpoint;
+
mark_checkpoint:
/* skip checkpointing for general migration,
* it is controlled in mdadm
--
2.40.1

View File

@ -0,0 +1,61 @@
From ea2ca7ed3dbbf881ce08d80fe371f2aaf05011c3 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Thu, 18 Jan 2024 11:30:18 +0100
Subject: [PATCH 04/41] Grow: Move update_tail assign to Grow_reshape()
Due to e919fb0af245 ("FIX: Enable metadata updates for raid0") code
can't enter super-intel.c:3415, resulting in checkpoint not being
saved to metadata for second volume in matrix raid array.
This results in checkpoint being stuck at last value for the
first volume.
Move st->update_tail to Grow_reshape() so it is assigned for each
volume.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Grow.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/Grow.c b/Grow.c
index f95dae82..5498e54f 100644
--- a/Grow.c
+++ b/Grow.c
@@ -2085,9 +2085,10 @@ int Grow_reshape(char *devname, int fd,
if (!mdmon_running(st->container_devnm))
start_mdmon(st->container_devnm);
ping_monitor(container);
- if (mdmon_running(st->container_devnm) &&
- st->update_tail == NULL)
- st->update_tail = &st->updates;
+ if (mdmon_running(st->container_devnm) == false) {
+ pr_err("No mdmon found. Grow cannot continue.\n");
+ goto release;
+ }
}
if (s->size == MAX_SIZE)
@@ -3048,6 +3049,8 @@ static int reshape_array(char *container, int fd, char *devname,
dprintf("Cannot get array information.\n");
goto release;
}
+ if (st->update_tail == NULL)
+ st->update_tail = &st->updates;
if (array.level == 0 && info->component_size == 0) {
get_dev_size(fd, NULL, &array_size);
info->component_size = array_size / array.raid_disks;
@@ -5152,9 +5155,7 @@ int Grow_continue_command(char *devname, int fd,
start_mdmon(container);
ping_monitor(container);
- if (mdmon_running(container))
- st->update_tail = &st->updates;
- else {
+ if (mdmon_running(container) == false) {
pr_err("No mdmon found. Grow cannot continue.\n");
ret_val = 1;
goto Grow_continue_command_exit;
--
2.40.1

View File

@ -0,0 +1,56 @@
From 37eeae381a8ed07a1fabb64184fe45d95a861496 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Thu, 18 Jan 2024 11:30:19 +0100
Subject: [PATCH 05/41] Add understanding output section in man
Add new section in man for explaining mdadm outputs.
Describe checkpoint entry.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
mdadm.8.in | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/mdadm.8.in b/mdadm.8.in
index 96a4a08e..9ba66825 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -3179,7 +3179,7 @@ environment. This can be useful for testing or for disaster
recovery. You should be aware that interoperability may be
compromised by setting this value.
-These change can also be suppressed by adding
+These change can also be suppressed by adding
.B mdadm.imsm.test=1
to the kernel command line. This makes it easy to test IMSM
code in a virtual machine that doesn't have IMSM virtual hardware.
@@ -3454,6 +3454,25 @@ is any string. These names are supported by
since version 3.3 provided they are enabled in
.IR mdadm.conf .
+.SH UNDERSTANDING OUTPUT
+
+.TP
+EXAMINE
+
+.TP
+.B checkpoint
+Checkpoint value is reported when array is performing some action including
+resync, recovery or reshape. Checkpoints allow resuming action from certain
+point if it was interrupted.
+
+Checkpoint is reported as combination of two values: current migration unit
+and number of blocks per unit. By multiplying those values and dividing by
+array size checkpoint progress percentage can be obtained in relation to
+current progress reported in /proc/mdstat. Checkpoint is also related to (and
+sometimes based on) sysfs entry sync_completed but depending on action units
+may differ. Even if units are the same, it should not be expected that
+checkpoint and sync_completed will be exact match nor updated simultaneously.
+
.SH NOTE
.I mdadm
was previously known as
--
2.40.1

View File

@ -0,0 +1,48 @@
From b8f5523a795b8f7e56dfbc139ce7f64728b67726 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Tue, 20 Feb 2024 11:56:07 +0100
Subject: [PATCH 06/41] Create: add_disk_to_super() fix resource leak
Fixes resource leak in add_disk_to_super().
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Create.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/Create.c b/Create.c
index 8082f54a..7e9170b6 100644
--- a/Create.c
+++ b/Create.c
@@ -279,8 +279,10 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c,
dv->devname);
return 1;
}
- if (!fstat_is_blkdev(fd, dv->devname, &rdev))
+ if (!fstat_is_blkdev(fd, dv->devname, &rdev)) {
+ close(fd);
return 1;
+ }
info->disk.major = major(rdev);
info->disk.minor = minor(rdev);
}
@@ -289,6 +291,7 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c,
if (st->ss->add_to_super(st, &info->disk, fd, dv->devname,
dv->data_offset)) {
ioctl(mdfd, STOP_ARRAY, NULL);
+ close(fd);
return 1;
}
st->ss->getinfo_super(st, info, NULL);
@@ -297,6 +300,7 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c,
*zero_pid = write_zeroes_fork(fd, s, st, dv);
if (*zero_pid <= 0) {
ioctl(mdfd, STOP_ARRAY, NULL);
+ close(fd);
return 1;
}
}
--
2.40.1

View File

@ -0,0 +1,35 @@
From 38cb95dd28fa790ae6d90b169f1fd2b1d09a02f2 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Tue, 20 Feb 2024 11:56:08 +0100
Subject: [PATCH 07/41] mdadm: signal_s() init variables
Init sigaction structs in signal_s().
This approach might throw warnings for GCC 4.x and lower.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
mdadm.h | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/mdadm.h b/mdadm.h
index 1f28b3e7..75c887e4 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1856,11 +1856,10 @@ static inline char *to_subarray(struct mdstat_ent *ent, char *container)
*/
static inline sighandler_t signal_s(int sig, sighandler_t handler)
{
- struct sigaction new_act;
- struct sigaction old_act;
+ struct sigaction new_act = {0};
+ struct sigaction old_act = {0};
new_act.sa_handler = handler;
- new_act.sa_flags = 0;
if (sigaction(sig, &new_act, &old_act) == 0)
return old_act.sa_handler;
--
2.40.1

View File

@ -0,0 +1,48 @@
From b7d7837128e90c8b496ebc3d88eda1a8ff477392 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Tue, 20 Feb 2024 11:56:09 +0100
Subject: [PATCH 08/41] Monitor: open file before check in check_one_sharer()
Open file before performing checks in check_one_sharer() to avoid
file tampering.
Remove redundant access check.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Monitor.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/Monitor.c b/Monitor.c
index 824a69fc..7cee95d4 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -451,20 +451,17 @@ static int check_one_sharer(int scan)
return 2;
}
- if (access(AUTOREBUILD_PID_PATH, F_OK) != 0)
- return 0;
-
- if (!is_file(AUTOREBUILD_PID_PATH)) {
- pr_err("%s is not a regular file.\n", AUTOREBUILD_PID_PATH);
- return 2;
- }
-
fp = fopen(AUTOREBUILD_PID_PATH, "r");
if (!fp) {
pr_err("Cannot open %s file.\n", AUTOREBUILD_PID_PATH);
return 2;
}
+ if (!is_file(AUTOREBUILD_PID_PATH)) {
+ pr_err("%s is not a regular file.\n", AUTOREBUILD_PID_PATH);
+ return 2;
+ }
+
if (fscanf(fp, "%d", &pid) != 1) {
pr_err("Cannot read pid from %s file.\n", AUTOREBUILD_PID_PATH);
fclose(fp);
--
2.40.1

View File

@ -0,0 +1,34 @@
From e44d13f466e30c018887cd5aaf1212ed9f510813 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Tue, 20 Feb 2024 11:56:10 +0100
Subject: [PATCH 09/41] Grow: remove dead condition in Grow_reshape()
Remove dead "if" condition from Grow_reshape(). Sysfs read check is
performed earlier in the code.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Grow.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/Grow.c b/Grow.c
index 5498e54f..c69a342d 100644
--- a/Grow.c
+++ b/Grow.c
@@ -2098,11 +2098,7 @@ int Grow_reshape(char *devname, int fd,
/* got truncated to 32bit, write to
* component_size instead
*/
- if (sra)
- rv = sysfs_set_num(sra, NULL,
- "component_size", s->size);
- else
- rv = -1;
+ rv = sysfs_set_num(sra, NULL, "component_size", s->size);
} else {
rv = md_set_array_info(fd, &array);
--
2.40.1

View File

@ -0,0 +1,34 @@
From 7ccf947eb595c1bb729c32ba18ce171dada76a68 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Tue, 20 Feb 2024 11:56:11 +0100
Subject: [PATCH 10/41] super1: check fd before passing to get_dev_size() in
add_to_super1()
Check if file descriptor is valid before passing it to get_dev_size() in
add_to_super().
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
super1.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/super1.c b/super1.c
index 871d19f0..5439b7bb 100644
--- a/super1.c
+++ b/super1.c
@@ -1752,7 +1752,10 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
di->devname = devname;
di->disk = *dk;
di->data_offset = data_offset;
- get_dev_size(fd, NULL, &di->dev_size);
+
+ if (is_fd_valid(fd))
+ get_dev_size(fd, NULL, &di->dev_size);
+
di->next = NULL;
*dip = di;
--
2.40.1

View File

@ -0,0 +1,66 @@
From c8772da4b53307546a9a374507bcec3398fc82c4 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Tue, 20 Feb 2024 11:56:12 +0100
Subject: [PATCH 11/41] mdmon: refactor md device name check in main()
Refactor mdmon main function to verify if fd is valid prior to checking
device name. This is due to static code analysis complaining after
change b938519e7719 ("util: remove obsolete code from get_md_name").
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
mdmon.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/mdmon.c b/mdmon.c
index a2038fe6..5fdb5cdb 100644
--- a/mdmon.c
+++ b/mdmon.c
@@ -302,12 +302,12 @@ static int mdmon(char *devnm, int must_fork, int takeover);
int main(int argc, char *argv[])
{
char *container_name = NULL;
- char *devnm = NULL;
int status = 0;
int opt;
int all = 0;
int takeover = 0;
int dofork = 1;
+ int mdfd = -1;
bool help = false;
static struct option options[] = {
{"all", 0, NULL, 'a'},
@@ -410,19 +410,20 @@ int main(int argc, char *argv[])
free_mdstat(mdstat);
return status;
- } else {
- int mdfd = open_mddev(container_name, 0);
- devnm = fd2devnm(mdfd);
+ }
+
+ mdfd = open_mddev(container_name, 0);
+ if (is_fd_valid(mdfd)) {
+ char *devnm = fd2devnm(mdfd);
close(mdfd);
- }
- if (!devnm) {
- pr_err("%s is not a valid md device name\n",
- container_name);
- return 1;
+ if (devnm)
+ return mdmon(devnm, dofork && do_fork(), takeover);
}
- return mdmon(devnm, dofork && do_fork(), takeover);
+
+ pr_err("%s is not a valid md device name\n", container_name);
+ return 1;
}
static int mdmon(char *devnm, int must_fork, int takeover)
--
2.40.1

View File

@ -0,0 +1,138 @@
From 4c12714d1ca06533fe7a887966df2558fd2f96b2 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Tue, 20 Feb 2024 17:04:44 +0100
Subject: [PATCH 12/41] test: run tests on system level mdadm
The tests run with MDADM_NO_SYSTEMCTL flag by default, however it has
no effect on udev. In case of external metadata, even if flag is set,
udev will trigger systemd to launch mdmon.
This commit changes test execution level, so the tests are run on system
level mdadm, meaning local build must be installed prior to running
tests.
Add warning that the tests are run on system level mdadm and local
build must be installed first.
Do not call mdadm with "quiet" as it makes it not display critical
messages necessary for debug.
Remove forcing speed_limit and add restoring system speed_limit_max
after test execution.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
test | 27 ++++++++++++++++++---------
tests/func.sh | 1 -
2 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/test b/test
index 49a36c3b..338c2db4 100755
--- a/test
+++ b/test
@@ -1,11 +1,12 @@
#!/bin/bash
#
# run test suite for mdadm
-mdadm=$PWD/mdadm
+mdadm=`which mdadm`
targetdir="/var/tmp"
logdir="$targetdir"
config=/tmp/mdadm.conf
testdir=$PWD/tests
+system_speed_limit=`cat /proc/sys/dev/raid/speed_limit_max`
devlist=
savelogs=0
@@ -20,9 +21,6 @@ DEVTYPE=loop
INTEGRITY=yes
LVM_VOLGROUP=mdtest
-# make sure to test local mdmon, not system one
-export MDADM_NO_SYSTEMCTL=1
-
# assume md0, md1, md2 exist in /dev
md0=/dev/md0
md1=/dev/md1
@@ -41,7 +39,10 @@ ctrl_c() {
ctrl_c_error=1
}
-# mdadm always adds --quiet, and we want to see any unexpected messages
+restore_system_speed_limit() {
+ echo $system_speed_limit > /proc/sys/dev/raid/speed_limit_max
+}
+
mdadm() {
rm -f $targetdir/stderr
case $* in
@@ -63,10 +64,10 @@ mdadm() {
$mdadm --zero $args > /dev/null
}
done
- $mdadm 2> $targetdir/stderr --quiet "$@" --auto=yes
+ $mdadm 2> $targetdir/stderr "$@" --auto=yes
;;
* )
- $mdadm 2> $targetdir/stderr --quiet "$@"
+ $mdadm 2> $targetdir/stderr "$@"
;;
esac
rv=$?
@@ -99,8 +100,6 @@ do_test() {
fi
rm -f $targetdir/stderr
- # this might have been reset: restore the default.
- echo 2000 > /proc/sys/dev/raid/speed_limit_max
do_clean
# source script in a subshell, so it has access to our
# namespace, but cannot change it.
@@ -122,6 +121,7 @@ do_test() {
echo " (KNOWN BROKEN TEST: $_broken_msg)"
fi
fi
+ restore_system_speed_limit
[ "$savelogs" == "1" ] &&
mv -f $targetdir/log $logdir/$_basename.log
[ "$ctrl_c_error" == "1" ] && exit 1
@@ -299,7 +299,15 @@ parse_args() {
done
}
+print_warning() {
+ cat <<-EOF
+ Warning! Tests are performed on system level mdadm!
+ If you want to test local build, you need to install it first!
+ EOF
+}
+
main() {
+ print_warning
do_setup
echo "Testing on linux-$(uname -r) kernel"
@@ -329,6 +337,7 @@ main() {
break
fi
done
+
exit 0
}
diff --git a/tests/func.sh b/tests/func.sh
index 1c1a28a2..b474442b 100644
--- a/tests/func.sh
+++ b/tests/func.sh
@@ -213,7 +213,6 @@ do_setup() {
path1=$dev7
ulimit -c unlimited
[ -f /proc/mdstat ] || modprobe md_mod
- echo 2000 > /proc/sys/dev/raid/speed_limit_max
echo 0 > /sys/module/md_mod/parameters/start_ro
}
--
2.40.1

View File

@ -0,0 +1,43 @@
From 3c3ddeeccc1eb4accb62ce9920de430a564be806 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Wed, 28 Feb 2024 16:37:20 +0100
Subject: [PATCH 13/41] Monitor: Allow no PID in check_one_sharer()
Commit 5fb5479ad100 ("Monitor: open file before check in
check_one_sharer()") introduced a regression that prohibits monitor
from starting if PID file does not exist.
Add check for no PID file.
Add missing fclose().
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Monitor.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Monitor.c b/Monitor.c
index 7cee95d4..9be2b528 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -453,12 +453,17 @@ static int check_one_sharer(int scan)
fp = fopen(AUTOREBUILD_PID_PATH, "r");
if (!fp) {
+ /* PID file does not exist */
+ if (errno == ENOENT)
+ return 0;
+
pr_err("Cannot open %s file.\n", AUTOREBUILD_PID_PATH);
return 2;
}
if (!is_file(AUTOREBUILD_PID_PATH)) {
pr_err("%s is not a regular file.\n", AUTOREBUILD_PID_PATH);
+ fclose(fp);
return 2;
}
--
2.40.1

View File

@ -0,0 +1,47 @@
From d1cd231ae41d98b2555dbff08d0c79876b5059fe Mon Sep 17 00:00:00 2001
From: Kinga Tanska <kinga.tanska@intel.com>
Date: Tue, 27 Feb 2024 07:36:39 +0100
Subject: [PATCH 14/41] super-intel: respect IMSM_DEVNAME_AS_SERIAL flag
IMSM_DEVNAME_AS_SERIAL flag was respected only when searching
serial using nvme or scsi device wasn't successful. This
flag shall be applied first, to have user settings with
the highest priority.
Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
super-intel.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index e61f3f6f..4babec9f 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -4174,17 +4174,17 @@ static int imsm_read_serial(int fd, char *devname,
memset(buf, 0, sizeof(buf));
+ if (check_env("IMSM_DEVNAME_AS_SERIAL")) {
+ memset(serial, 0, serial_buf_len);
+ fd2devname(fd, (char *) serial);
+ return 0;
+ }
+
rv = nvme_get_serial(fd, buf, sizeof(buf));
if (rv)
rv = scsi_get_serial(fd, buf, sizeof(buf));
- if (rv && check_env("IMSM_DEVNAME_AS_SERIAL")) {
- memset(serial, 0, MAX_RAID_SERIAL_LEN);
- fd2devname(fd, (char *) serial);
- return 0;
- }
-
if (rv != 0) {
if (devname)
pr_err("Failed to retrieve serial for %s\n",
--
2.40.1

View File

@ -0,0 +1,236 @@
From a944da4e1a56cd926e6b21f5aaebc13198265419 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Fri, 23 Feb 2024 15:51:42 +0100
Subject: [PATCH 15/41] mdadm: remove TODO
This file is not updated in 16 years.
No reasons to keep it. Remove it.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
TODO | 213 -----------------------------------------------------------
1 file changed, 213 deletions(-)
delete mode 100644 TODO
diff --git a/TODO b/TODO
deleted file mode 100644
index 279d20db..00000000
--- a/TODO
+++ /dev/null
@@ -1,213 +0,0 @@
- - add 'name' field to metadata type and use it.
- - use validate_geometry more
- - metadata should be able to check/reject bitmap stuff.
-
-DDF:
- Three new metadata types:
- ddf - used only to create a container.
- ddf-bvd - used to create an array in a container
- ddf-svd - used to create a secondary array from bvds.
-
- Usage:
- mdadm -C /dev/ddf1 /dev/sd[abcdef]
- mdadm -C /dev/md1 -e ddf /dev/sd[a-f]
- mdadm -C /dev/md1 -l container /dev/sd[a-f]
-
- Each of these create a new ddf container using all those
- devices. The name 'ddf*' signals that ddf metadata should be used.
- '-e ddf' only supports one level - 'container'. 'container' is only
- supported by ddf.
-
- mdadm -C /dev/md1 -l0 -n4 /dev/ddf1 # or maybe not ???
- mdadm -C /dev/md1 -l1 -n2 /dev/sda /dev/sdb
- If exactly one device is given, and it is a container, we select
- devices from that container.
- If devices are given that are already in use, they must be in use by
- a container, and the array is created in the container.
- If devices given are bvds, we slip under the hood to make
- the svd arrays.
-
- mdadm -A /dev/ddf ......
- base drives make a container. Anything in that container is started
- auto-read-only.
- if /dev/ddf is already assembled, we assemble bvds and svds inside it.
-
-
-2005-dec-20
- Want an incremental assembly mode to work nicely with udev.
- Core usage would be something like
- mdadm --incr-assemble /dev/newdevice
- This would
- - examine the device to determine uuid etc.
- - look for a match in /etc/mdadm.conf, abort if not found
- - find that device and collect current contents
- - perform an 'assemble' analysis to make sure we have the best set of devices.
- - remove or add devices as appropriate
- - possibly start the array if it was complete
-
- Other usages could involve
- - specify which array to auto-add to.
- This requires an existing array for uuid matching... is there any point?
-
- -
-
-
-2004-june-02
- * Don't print 'errors' flag, it is meaningless. DONE
- * Handle new superblock format
- * create device file on demand, particularly partitionable devices. DONE
- BUT figure a way to create the partition devices.
- auto=partN
- * Use Event: interface to listen for events. DONE, untested
- * Make sure mdadm -As can assemble multi-level RAIDs ok.
- * --build to build raid1 or multipath arrays
- clean or not ???
-
-----------------------------------------------------------------------------
-* mdadm --monitor to monitor failed multipath paths and re-instate them.
-
-* Maybe make "--help" fit in 80x24 and have a --long-help with more info. DONE
-
-
-* maybe "missing" instead of <bold>missing</> in doco DONE
-* possibly wait for resync to start, or even finish while assembling.- NO
-
-* -Db should have a devices= entry if possible. - DONE
-* when assembling multipath arrays, ignore any error indicators. - DONE
-* rationalise --monitor usage:
- mdadm --monitor
- doesn't do as expected. DONE
-
-* --assemble could have a --update option. - DONE
- following word can be:
- sparc2.2
- super-minor
-
-* mdadm /dev/md11, where md11 is raid0 can segfault, particularly when looking in the
- [UU_UUU] string ... which doesn't exist !
-It should be more sensible. DONE
-
-Example:
-
-from Raimund Sacherer <raimund.sacherer@ngit.at>
-
-mke2fs -m0 -q /dev/ram1 300
-mount -n -t ext2 /dev/ram1 /tmp
-echo DEVICE /dev/[sh]* >> /tmp/mdadm.conf
-mdadm -Esb /dev/[sh]* 2>/dev/null >> /tmp/mdadm.conf
-mdadm -ARsc /tmp/mdadm.conf
-umount /tmp
-
-
-?? Allow -S /dev/md? - current complains subsequent not a/d/r - DONE
-
-* new "Query" mode to subsume --detail and --examine.
- --query or -Q, takes a device and tells if it is an MD device,
- and also tells in a raid superblock is found.
- DONE
-
-* write mdstat.c to parse /proc/mdstat file
- Build list of arrays: name, rebuild-percent
- DONE
-
-* parse /proc/partitions and map major/minor into /dev/* names,
- and use that for default DEVICE list ????
-
-* --detail --scan to read /proc/mdstat, and then iterate over these,
- but assume --brief. --verbose can override
- check each subdevice to see if it is in conf_get_devs.
- Warn if not.
- DONE, but don't warn yet...
-
-* Support multipath ... maybe...
- maybe DONE
-
-* --follow to syslog
-
-* --follow to move spares around DONE
-
-* --follow to notice other events: DONE
- rebuild started
- spare activated
- spare removed
- spare added
-
-------------------------------------
-- --examine --scan scans all drives and build an mdadm.conf file DONE
-
-- check superblock checksum in examine DONE
-- report "chunk" or "rounding" depending on raid level DONE
-- report "linear" instead of "-1" for raid level DONE
-- decode ayout depending on raid level DONE
-- --verbose and --force flags. DONE
-
-- set md_minor, *_disks for Create - DONE
-- for create raid5, how to choose between
- all working, but not insync
- one missing, one spare, insync DONE (--force)
-- and for raid1 - some failed drives... (missing)
-
-- when RUN_ARRAY, make sure *_disks counts are right
-
-- get --detail to extract extra stuff from superblock,
- like uuid DONE
-- --detail --brief to give a config file line DONE
-- parse config file. DONE
-- test...
-
-- when --assemble --scan, if an underlying device is an md device,
- then try to assemble that device first.
-
-
-- mdadm -S /dev/md0 /dev/md1 gives internal error FIXED
-
-- mdadm --detail --scan print summary of what it can find? DONE
-
-
----------
-Assemble doesn't add spares. - DONE
-Create to allow "missing" name for devices.
-Create to accept "--force" for do exactly what is requested
-- get Assemble to upgrade devices if force flag.
-ARRAY lines in config file to have super_minor=n
-ARRAY lines in config file to have device=pattern, and only accept
- those devices
- If UUID given, insist on that
- If not, but super_minor given, require all found with that minor
- to have same uuid
- If only device given, all valid supers on those devices must have
- same uuid
-allow /dev/mdX as first argument before any options
-Possible --dry-run option for create and assemble--force
-
-Assemble to check that all devices mentioned in superblock
- are present.
-
-New mode: --Monitor (or --Follow)
- Periodically check status of all arrays (listed in config file).
- Log every event and apparent cause - or differences
- Email and alert - or run a program - for important events
- Move spares around if necessary.
-
- An Array line can have a spare-group= field that indicates that
- the array shares spares with other arrays with the same
- spare-group name.
- If an array has a failed and no spares, then check all other
- arrays in the spare group. If one has no failures and a spare,
- then consider that spare.
- Choose the smallest considered spare that is large enough.
- If there is one, then hot-remove it from it's home, and
- hot-add it to the array in question.
-
- --mail-to address
- --alert-handler program
-
- Will also extract information from /proc/mdstat if present,
- and consider 20% marks in rebuild as events.
-
- Events are:
- drive fails - causes mail to be sent
- rebuild started
- spare activated
- spare removed
- spare added
--
2.40.1

View File

@ -0,0 +1,119 @@
From 84d5e05d6fa6bbe6f4a3bdbdb1165dcc463b5207 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Fri, 23 Feb 2024 15:51:43 +0100
Subject: [PATCH 16/41] mdadm: remove makedist
Archives are generated kernel.org automation, no need to submit
them manually, so remove legacy solution.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
makedist | 96 --------------------------------------------------------
1 file changed, 96 deletions(-)
delete mode 100755 makedist
diff --git a/makedist b/makedist
deleted file mode 100755
index 0c4b39eb..00000000
--- a/makedist
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/bin/sh
-# avoid silly sorting
-export LANG=C
-arg=$1
-target=~/public_html/source/mdadm
-if [ " $arg" = " test" ]
-then
- target=/tmp/mdadm-test
- rm -rf $target
- mkdir -p $target
-fi
-if [ -d $target ]
-then :
-else echo $target is not a directory
- exit 2
-fi
-set `grep '^#define VERSION' ReadMe.c `
-version=`echo $3 | sed -e 's/"//g'`
-grep "^.TH MDADM 8 .. v$version" mdadm.8.in > /dev/null 2>&1 ||
- {
- echo mdadm.8.in does not mention version $version.
- exit 1
- }
-grep "^.TH MDMON 8 .. v$version" mdmon.8 > /dev/null 2>&1 ||
- {
- echo mdmon.8 does not mention version $version.
- exit 1
- }
-rpmv=`echo $version | tr - _`
-grep "^Version: *$rpmv$" mdadm.spec > /dev/null 2>&1 ||
- {
- echo mdadm.spec does not mention version $version.
- exit 1
- }
-if [ -f ANNOUNCE-$version ]
-then :
-else
- echo ANNOUNCE-$version does not exist
- exit 1
-fi
-if grep "^ANNOUNCE-$version\$" inventory
-then :
-else { cat inventory ; echo ANNOUNCE-$version ; } | sort -o inventory
-fi
-
-echo version = $version
-base=mdadm-$rpmv.tar.gz
-if [ " $arg" != " diff" ]
-then
- if [ -f $target/$base ]
- then
- echo $target/$base exists.
- exit 1
- fi
- trap "rm $target/$base; exit" 1 2 3
- git archive --prefix=mdadm-$rpmv/ HEAD | gzip --best > $target/$base
- chmod a+r $target/$base
- ls -l $target/$base
- if tar tzf $target/$base | sed 's,[^/]*/,,' | sort | diff -u inventory -
- then : correct files found
- else echo "Extra files, or inventory is out-of-date"
- rm $target/$base
- exit 1
- fi
- rpmbuild -ta $target/$base || exit 1
- find ~/rpmbuild/RPMS -name "*mdadm-$version-*" \
- -exec cp {} $target/RPM \;
- cp ANNOUNCE-$version $target/ANNOUNCE
- cp ChangeLog $target/ChangeLog
- if [ " $arg" != " test" ]
- then
- echo -n "Confirm signing this release? "
- read a
- if [ " $a" != " y" ]; then echo OK - bye. ; exit 1; fi
- if zcat $target/$base | gpg -ba > $target/$base.sign && gpg -ba $target/ANNOUNCE
- then
- kup put $target/$base $target/$base.sign \
- /pub/linux/utils/raid/mdadm/mdadm-$version.tar.gz
- kup put $target/ANNOUNCE $target/ANNOUNCE.asc /pub/linux/utils/raid/mdadm/ANNOUNCE
- else
- echo signing failed
- exit 1
- fi
- fi
-else
- if [ ! -f $target/$base ]
- then
- echo $target/$base does not exist.
- exit 1
- fi
- ( cd .. ; ln -s mdadm.v2 mdadm-$version ; tar chf - --exclude=.git --exclude="TAGS" --exclude='*,v' --exclude='*~' --exclude='*.o' --exclude mdadm --exclude=mdadm'.[^ch0-9]' --exclude=RCS mdadm-$version ; rm mdadm-$version ) | gzip --best > /var/tmp/mdadm-new.tgz
- mkdir /var/tmp/mdadm-old ; zcat $target/$base | ( cd /var/tmp/mdadm-old ; tar xf - )
- mkdir /var/tmp/mdadm-new ; zcat /var/tmp/mdadm-new.tgz | ( cd /var/tmp/mdadm-new ; tar xf - )
- diff -ru /var/tmp/mdadm-old /var/tmp/mdadm-new
- rm -rf /var/tmp/mdadm-old /var/tmp/mdadm-new /var/tmp/mdadm-new.tgz
-fi
--
2.40.1

View File

@ -0,0 +1,69 @@
From 9cdcc193cec92c624841d5b70f1b96daafdc4314 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Fri, 23 Feb 2024 15:51:44 +0100
Subject: [PATCH 17/41] mdadm: remove mdadm.spec
This file is outdated, distributions have their own specs.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
mdadm.spec | 47 -----------------------------------------------
1 file changed, 47 deletions(-)
delete mode 100644 mdadm.spec
diff --git a/mdadm.spec b/mdadm.spec
deleted file mode 100644
index 12e7859a..00000000
--- a/mdadm.spec
+++ /dev/null
@@ -1,47 +0,0 @@
-Summary: mdadm is used for controlling Linux md devices (aka RAID arrays)
-Name: mdadm
-Version: 4.3
-Release: 1
-Source: https://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.gz
-URL: https://neil.brown.name/blog/mdadm
-License: GPL
-Group: Utilities/System
-BuildRoot: %{_tmppath}/%{name}-root
-Obsoletes: mdctl
-
-%description
-mdadm is a program that can be used to create, manage, and monitor
-Linux MD (Software RAID) devices.
-
-%prep
-%setup -q
-# we want to install in /sbin, not /usr/sbin...
-%define _exec_prefix %{nil}
-
-%build
-# This is a debatable issue. The author of this RPM spec file feels that
-# people who install RPMs (especially given that the default RPM options
-# will strip the binary) are not going to be running gdb against the
-# program.
-make CXFLAGS="$RPM_OPT_FLAGS" SYSCONFDIR="%{_sysconfdir}"
-
-%install
-make DESTDIR=$RPM_BUILD_ROOT MANDIR=%{_mandir} BINDIR=%{_sbindir} install
-install -D -m644 mdadm.conf-example $RPM_BUILD_ROOT/%{_sysconfdir}/mdadm.conf
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%defattr(-,root,root)
-%doc TODO ChangeLog mdadm.conf-example COPYING
-%{_sbindir}/mdadm
-%{_sbindir}/mdmon
-/usr/lib/udev/rules.d/01-md-raid-creating.rules
-/usr/lib/udev/rules.d/63-md-raid-arrays.rules
-/usr/lib/udev/rules.d/64-md-raid-assembly.rules
-/usr/lib/udev/rules.d/69-md-clustered-confirm-device.rules
-%config(noreplace,missingok)/%{_sysconfdir}/mdadm.conf
-%{_mandir}/man*/md*
-
-%changelog
--
2.40.1

View File

@ -0,0 +1,209 @@
From 9282e1169f19676553a82dd49f780285a16e3b9a Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Fri, 23 Feb 2024 15:51:45 +0100
Subject: [PATCH 18/41] mdadm: remove mkinitramfs stuff
This script uses mdadm.static which is known to not be abandoned
(probably not working) from years. Mdadm is integrated with dracut
and mkinitramfs these days.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
README.initramfs | 122 -----------------------------------------------
mkinitramfs | 55 ---------------------
2 files changed, 177 deletions(-)
delete mode 100644 README.initramfs
delete mode 100644 mkinitramfs
diff --git a/README.initramfs b/README.initramfs
deleted file mode 100644
index c5fa6680..00000000
--- a/README.initramfs
+++ /dev/null
@@ -1,122 +0,0 @@
-Assembling md arrays at boot time.
----------------------------------
-December 2005
-
-These notes apply to 2.6 kernels only and, in some cases,
-to 2.6.15 or later.
-
-Md arrays can be assembled at boot time using the 'autodetect' functionality
-which is triggered by storing components of an array in partitions of type
-'fd' - Linux Raid Autodetect.
-They can also be assembled by specifying the component devices in a
-kernel parameter such as
- md=0,/dev/sda,/dev/sdb
-In this case, /dev/md0 will be assembled (because of the 0) from the listed
-devices.
-
-These mechanisms, while useful, do not provide complete functionality
-and are unlikely to be extended. The preferred way to assemble md
-arrays at boot time is using 'mdadm'. To assemble an array which
-contains the root filesystem, mdadm needs to be run before that
-filesystem is mounted, and so needs to be run from an initial-ram-fs.
-It is how this can work that is the primary focus of this document.
-
-It should be noted up front that only the array containing the root
-filesystem should be assembled from the initramfs. Any other arrays
-should be assembled under the control of files on the main filesystem
-as this enhanced flexibility and maintainability.
-
-A minimal initramfs for assembling md arrays can be created using 3
-files and one directory. These are:
-
-/bin Directory
-/bin/mdadm statically linked mdadm binary
-/bin/busybox statically linked busybox binary
-/bin/sh hard link to /bin/busybox
-/init a shell script which call mdadm appropriately.
-
-An example init script is:
-
-==============================================
-#!/bin/sh
-
-echo 'Auto-assembling boot md array'
-mkdir /proc
-mount -t proc proc /proc
-if [ -n "$rootuuid" ]
-then arg=--uuid=$rootuuid
-elif [ -n "$mdminor" ]
-then arg=--super-minor=$mdminor
-else arg=--super-minor=0
-fi
-echo "Using $arg"
-mdadm -Acpartitions $arg --auto=part /dev/mda
-cd /
-mount /dev/mda1 /root || mount /dev/mda /root
-umount /proc
-cd /root
-exec chroot . /sbin/init < /dev/console > /dev/console 2>&1
-=============================================
-
-This could certainly be extended, or merged into a larger init script.
-Though tested and in production use, it is not presented here as
-"The Right Way" to do it, but as a useful example.
-Some key points are:
-
- /proc needs to be mounted so that /proc/partitions can be accessed
- by mdadm, and so that /proc/filesystems can be accessed by mount.
-
- The uuid of the array can be passed in as a kernel parameter
- (rootuuid). As the kernel doesn't use this value, it is made available
- in the environment for /init
-
- If no uuid is given, we default to md0, (--super-minor=0) which is a
- commonly used to store the root filesystem. This may not work in
- all situations.
-
- We assemble the array as a partitionable array (/dev/mda) even if we
- end up using the whole array. There is no cost in using the partitionable
- interface, and in this context it is simpler.
-
- We try mounting both /dev/mda1 and /dev/mda as they are the most like
- part of the array to contain the root filesystem.
-
- The --auto flag is given to mdadm so that it will create /dev/md*
- files automatically. This is needed as /dev will not contain
- and md files, and udev will not create them (as udev only created device
- files after the device exists, and mdadm need the device file to create
- the device). Note that the created md files may not exist in /dev
- of the mounted root filesystem. This needs to be deal with separately
- from mdadm - possibly using udev.
-
- We do not need to create device files for the components which will
- be assembled into /dev/mda. mdadm finds the major/minor numbers from
- /proc/partitions and creates a temporary /dev file if one doesn't already
- exist.
-
-The script "mkinitramfs" which is included with the mdadm distribution
-can be used to create a minimal initramfs. It creates a file called
-'init.cpio.gz' which can be specified as an 'initrd' to lilo or grub
-(or whatever boot loader is being used).
-
-
-
-
-Resume from an md array
------------------------
-
-If you want to make use of the suspend-to-disk/resume functionality in Linux,
-and want to have swap on an md array, you will need to assemble the array
-before resume is possible.
-However, because the array is active in the resumed image, you do not want
-anything written to any drives during the resume process, such as superblock
-updates or array resync.
-
-This can be achieved in 2.6.15-rc1 and later kernels using the
-'start_readonly' module parameter.
-Simply include the command
- echo 1 > /sys/module/md_mod/parameters/start_ro
-before assembling the array with 'mdadm'.
-You can then echo
- 9:0
-or whatever is appropriate to /sys/power/resume to trigger the resume.
diff --git a/mkinitramfs b/mkinitramfs
deleted file mode 100644
index c6275ddb..00000000
--- a/mkinitramfs
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/sh
-
-# make sure we are being run in the right directory...
-if [ -f mkinitramfs ]
-then :
-else
- echo >&2 mkinitramfs must be run from the mdadm source directory.
- exit 1
-fi
-if [ -f /bin/busybox ]
-then : good, it exists
- case `file /bin/busybox` in
- *statically* ) : good ;;
- * ) echo >&2 mkinitramfs: /bin/busybox is not statically linked: cannot proceed.
- exit 1
- esac
-else
- echo >&2 "mkinitramfs: /bin/busybox doesn't exist - please install it statically linked."
- exit 1
-fi
-
-rm -rf initramfs
-mkdir initramfs
-mkdir initramfs/bin
-make mdadm.static
-cp mdadm.static initramfs/bin/mdadm
-cp /bin/busybox initramfs/bin/busybox
-ln initramfs/bin/busybox initramfs/bin/sh
-cat <<- END > initramfs/init
- #!/bin/sh
-
- echo 'Auto-assembling boot md array'
- mkdir /proc
- mount -t proc proc /proc
- if [ -n "$rootuuid" ]
- then arg=--uuid=$rootuuid
- elif [ -n "$mdminor" ]
- then arg=--super-minor=$mdminor
- else arg=--super-minor=0
- fi
- echo "Using $arg"
- mdadm -Acpartitions $arg --auto=part /dev/mda
- cd /
- mount /dev/mda1 /root || mount /dev/mda /root
- umount /proc
- cd /root
- exec chroot . /sbin/init < /dev/console > /dev/console 2>&1
-END
-chmod +x initramfs/init
-
-(cd initramfs
- find init bin | cpio -o -H newc | gzip --best
-) > init.cpio.gz
-rm -rf initramfs
-ls -l init.cpio.gz
--
2.40.1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,75 @@
From 60c19530dd7cc6b38a75695a0a3d004bbe60d430 Mon Sep 17 00:00:00 2001
From: Kinga Tanska <kinga.tanska@intel.com>
Date: Tue, 27 Feb 2024 03:36:14 +0100
Subject: [PATCH 20/41] Detail: remove duplicated code
Remove duplicated code from Detail(), where MD_UUID and MD_DEVNAME
are being set. Superblock is no longer required to print system
properties. Now it tries to obtain map in two ways.
Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Detail.c | 33 +++++++++++++--------------------
1 file changed, 13 insertions(+), 20 deletions(-)
diff --git a/Detail.c b/Detail.c
index aaa3dd6e..f23ec16f 100644
--- a/Detail.c
+++ b/Detail.c
@@ -226,6 +226,9 @@ int Detail(char *dev, struct context *c)
str = map_num(pers, array.level);
if (c->export) {
+ char nbuf[64];
+ struct map_ent *mp = NULL, *map = NULL;
+
if (array.raid_disks) {
if (str)
printf("MD_LEVEL=%s\n", str);
@@ -247,32 +250,22 @@ int Detail(char *dev, struct context *c)
array.minor_version);
}
- if (st && st->sb && info) {
- char nbuf[64];
- struct map_ent *mp, *map = NULL;
-
- fname_from_uuid(st, info, nbuf, ':');
- printf("MD_UUID=%s\n", nbuf + 5);
+ if (info)
mp = map_by_uuid(&map, info->uuid);
+ if (!mp)
+ mp = map_by_devnm(&map, fd2devnm(fd));
- if (mp && mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0)
+ if (mp) {
+ __fname_from_uuid(mp->uuid, 0, nbuf, ':');
+ printf("MD_UUID=%s\n", nbuf + 5);
+ if (mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0)
printf("MD_DEVNAME=%s\n", mp->path + DEV_MD_DIR_LEN);
+ }
+ map_free(map);
+ if (st && st->sb) {
if (st->ss->export_detail_super)
st->ss->export_detail_super(st);
- map_free(map);
- } else {
- struct map_ent *mp, *map = NULL;
- char nbuf[64];
- mp = map_by_devnm(&map, fd2devnm(fd));
- if (mp) {
- __fname_from_uuid(mp->uuid, 0, nbuf, ':');
- printf("MD_UUID=%s\n", nbuf+5);
- }
- if (mp && mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0)
- printf("MD_DEVNAME=%s\n", mp->path + DEV_MD_DIR_LEN);
-
- map_free(map);
}
if (!c->no_devices && sra) {
struct mdinfo *mdi;
--
2.40.1

View File

@ -0,0 +1,286 @@
From 0c0f09cb035b6a27a1d11c54836742a9945a5014 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 29 Feb 2024 12:52:05 +0100
Subject: [PATCH 21/41] mdadm: Add functions for spare criteria verification
It is done similar way in few places. As a result, two almost identical
functions (dev_size_from_id() and dev_sector_size_from_id()) are
removed. Now, it uses same file descriptor to send two ioctls.
Two extern functions are added, in next patches
disk_fd_matches_criteria() is used.
Next optimization is inline zeroing struct spare_criteria. With that,
we don't need to reset values in get_spare_criteria_imsm().
Dedicated boolean field for checking if criteria are filled is added.
We don't need to execute the code if it is not set.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Incremental.c | 2 +-
Monitor.c | 14 +------
mdadm.h | 6 ++-
super-intel.c | 4 +-
util.c | 112 ++++++++++++++++++++++++++------------------------
5 files changed, 67 insertions(+), 71 deletions(-)
diff --git a/Incremental.c b/Incremental.c
index 30c07c03..2b5a5859 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -874,7 +874,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
struct domainlist *dl = NULL;
struct mdinfo *sra;
unsigned long long devsize, freesize = 0;
- struct spare_criteria sc = {0, 0};
+ struct spare_criteria sc = {0};
if (is_subarray(mp->metadata))
continue;
diff --git a/Monitor.c b/Monitor.c
index 9be2b528..1ece8712 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -1070,22 +1070,12 @@ static dev_t choose_spare(struct state *from, struct state *to,
for (d = from->raid; !dev && d < MAX_DISKS; d++) {
if (from->devid[d] > 0 && from->devstate[d] == 0) {
struct dev_policy *pol;
- unsigned long long dev_size;
- unsigned int dev_sector_size;
if (to->metadata->ss->external &&
test_partition_from_id(from->devid[d]))
continue;
- if (sc->min_size &&
- dev_size_from_id(from->devid[d], &dev_size) &&
- dev_size < sc->min_size)
- continue;
-
- if (sc->sector_size &&
- dev_sector_size_from_id(from->devid[d],
- &dev_sector_size) &&
- sc->sector_size != dev_sector_size)
+ if (devid_matches_criteria(from->devid[d], sc) == false)
continue;
pol = devid_policy(from->devid[d]);
@@ -1170,12 +1160,12 @@ static void try_spare_migration(struct state *statelist)
{
struct state *from;
struct state *st;
- struct spare_criteria sc;
link_containers_with_subarrays(statelist);
for (st = statelist; st; st = st->next)
if (st->active < st->raid && st->spare == 0 && !st->err) {
struct domainlist *domlist = NULL;
+ struct spare_criteria sc = {0};
int d;
struct state *to = st;
diff --git a/mdadm.h b/mdadm.h
index 75c887e4..e8abd730 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -430,6 +430,7 @@ struct createinfo {
};
struct spare_criteria {
+ bool criteria_set;
unsigned long long min_size;
unsigned int sector_size;
};
@@ -1368,8 +1369,6 @@ extern struct supertype *dup_super(struct supertype *st);
extern int get_dev_size(int fd, char *dname, unsigned long long *sizep);
extern int get_dev_sector_size(int fd, char *dname, unsigned int *sectsizep);
extern int must_be_container(int fd);
-extern int dev_size_from_id(dev_t id, unsigned long long *size);
-extern int dev_sector_size_from_id(dev_t id, unsigned int *size);
void wait_for(char *dev, int fd);
/*
@@ -1708,6 +1707,9 @@ extern int assemble_container_content(struct supertype *st, int mdfd,
#define INCR_UNSAFE 2
#define INCR_ALREADY 4
#define INCR_YES 8
+
+extern bool devid_matches_criteria(dev_t devid, struct spare_criteria *sc);
+extern bool disk_fd_matches_criteria(int disk_fd, struct spare_criteria *sc);
extern struct mdinfo *container_choose_spares(struct supertype *st,
struct spare_criteria *criteria,
struct domainlist *domlist,
diff --git a/super-intel.c b/super-intel.c
index 4babec9f..39ec4754 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -1748,9 +1748,6 @@ int get_spare_criteria_imsm(struct supertype *st, struct spare_criteria *c)
int i;
unsigned long long size = 0;
- c->min_size = 0;
- c->sector_size = 0;
-
if (!super)
return -EINVAL;
/* find first active disk in array */
@@ -1774,6 +1771,7 @@ int get_spare_criteria_imsm(struct supertype *st, struct spare_criteria *c)
c->min_size = size * 512;
c->sector_size = super->sector_size;
+ c->criteria_set = true;
return 0;
}
diff --git a/util.c b/util.c
index b1454473..041e78cf 100644
--- a/util.c
+++ b/util.c
@@ -1266,40 +1266,6 @@ struct supertype *super_by_fd(int fd, char **subarrayp)
return st;
}
-int dev_size_from_id(dev_t id, unsigned long long *size)
-{
- char buf[20];
- int fd;
-
- sprintf(buf, "%d:%d", major(id), minor(id));
- fd = dev_open(buf, O_RDONLY);
- if (fd < 0)
- return 0;
- if (get_dev_size(fd, NULL, size)) {
- close(fd);
- return 1;
- }
- close(fd);
- return 0;
-}
-
-int dev_sector_size_from_id(dev_t id, unsigned int *size)
-{
- char buf[20];
- int fd;
-
- sprintf(buf, "%d:%d", major(id), minor(id));
- fd = dev_open(buf, O_RDONLY);
- if (fd < 0)
- return 0;
- if (get_dev_sector_size(fd, NULL, size)) {
- close(fd);
- return 1;
- }
- close(fd);
- return 0;
-}
-
struct supertype *dup_super(struct supertype *orig)
{
struct supertype *st;
@@ -2088,6 +2054,60 @@ void append_metadata_update(struct supertype *st, void *buf, int len)
unsigned int __invalid_size_argument_for_IOC = 0;
#endif
+/**
+ * disk_fd_matches_criteria() - check if device matches spare criteria.
+ * @disk_fd: file descriptor of the disk.
+ * @sc: criteria to test.
+ *
+ * Return: true if disk matches criteria, false otherwise.
+ */
+bool disk_fd_matches_criteria(int disk_fd, struct spare_criteria *sc)
+{
+ unsigned int dev_sector_size = 0;
+ unsigned long long dev_size = 0;
+
+ if (!sc->criteria_set)
+ return true;
+
+ if (!get_dev_size(disk_fd, NULL, &dev_size) || dev_size < sc->min_size)
+ return false;
+
+ if (!get_dev_sector_size(disk_fd, NULL, &dev_sector_size) ||
+ sc->sector_size != dev_sector_size)
+ return false;
+
+ return true;
+}
+
+/**
+ * devid_matches_criteria() - check if device referenced by devid matches spare criteria.
+ * @devid: devid of the device to check.
+ * @sc: criteria to test.
+ *
+ * Return: true if disk matches criteria, false otherwise.
+ */
+bool devid_matches_criteria(dev_t devid, struct spare_criteria *sc)
+{
+ char buf[NAME_MAX];
+ bool ret;
+ int fd;
+
+ if (!sc->criteria_set)
+ return true;
+
+ snprintf(buf, NAME_MAX, "%d:%d", major(devid), minor(devid));
+
+ fd = dev_open(buf, O_RDONLY);
+ if (!is_fd_valid(fd))
+ return false;
+
+ /* Error code inherited */
+ ret = disk_fd_matches_criteria(fd, sc);
+
+ close(fd);
+ return ret;
+}
+
/* Pick all spares matching given criteria from a container
* if min_size == 0 do not check size
* if domlist == NULL do not check domains
@@ -2111,28 +2131,13 @@ struct mdinfo *container_choose_spares(struct supertype *st,
dp = &disks->devs;
disks->array.spare_disks = 0;
while (*dp) {
- int found = 0;
+ bool found = false;
+
d = *dp;
if (d->disk.state == 0) {
- /* check if size is acceptable */
- unsigned long long dev_size;
- unsigned int dev_sector_size;
- int size_valid = 0;
- int sector_size_valid = 0;
-
dev_t dev = makedev(d->disk.major,d->disk.minor);
- if (!criteria->min_size ||
- (dev_size_from_id(dev, &dev_size) &&
- dev_size >= criteria->min_size))
- size_valid = 1;
-
- if (!criteria->sector_size ||
- (dev_sector_size_from_id(dev, &dev_sector_size) &&
- criteria->sector_size == dev_sector_size))
- sector_size_valid = 1;
-
- found = size_valid && sector_size_valid;
+ found = devid_matches_criteria(dev, criteria);
/* check if domain matches */
if (found && domlist) {
@@ -2141,7 +2146,8 @@ struct mdinfo *container_choose_spares(struct supertype *st,
pol_add(&pol, pol_domain,
spare_group, NULL);
if (domain_test(domlist, pol, metadata) != 1)
- found = 0;
+ found = false;
+
dev_policy_free(pol);
}
}
--
2.40.1

View File

@ -0,0 +1,357 @@
From f656201188d73cdc2726265f1348f8ffbf7587be Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 29 Feb 2024 12:52:06 +0100
Subject: [PATCH 22/41] mdadm: drop get_required_spare_criteria()
Only IMSM implements get_spare_criteria, so load_super() in
get_required_spare_criteria() is dead code. It is moved inside
metadata handler, because only IMSM implements it.
Give possibility to provide devnode to be opened. With that we can hide
load_container() used only to fill spare criteria inside handler
and simplify implementation in generic code.
Add helper function for testing spare criteria in Incremental and
error messages.
File descriptor in get_spare_criteria_imsm() is always opened on purpose.
New functionality added in next patches will require it. For the same
reason, function is moved to other place.
No functional changes.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Incremental.c | 77 ++++++++++++++++++++++----------
Monitor.c | 35 +++------------
mdadm.h | 5 +--
super-intel.c | 120 +++++++++++++++++++++++++++++++++-----------------
4 files changed, 140 insertions(+), 97 deletions(-)
diff --git a/Incremental.c b/Incremental.c
index 2b5a5859..66c2cc86 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -833,6 +833,53 @@ container_members_max_degradation(struct map_ent *map, struct map_ent *me)
return max_degraded;
}
+/**
+ * incremental_external_test_spare_criteria() - helper to test spare criteria.
+ * @st: supertype, must be not NULL, it is duplicated here.
+ * @container_devnm: devnm of the container.
+ * @disk_fd: file descriptor of device to tested.
+ * @verbose: verbose flag.
+ *
+ * The function is used on new drive verification path to check if it can be added to external
+ * container. To test spare criteria, metadata must be loaded. It duplicates super to not mess in
+ * original one.
+ * Function is executed if superblock supports get_spare_criteria(), otherwise success is returned.
+ */
+mdadm_status_t incremental_external_test_spare_criteria(struct supertype *st, char *container_devnm,
+ int disk_fd, int verbose)
+{
+ mdadm_status_t rv = MDADM_STATUS_ERROR;
+ char container_devname[PATH_MAX];
+ struct spare_criteria sc = {0};
+ struct supertype *dup;
+
+ if (!st->ss->get_spare_criteria)
+ return MDADM_STATUS_SUCCESS;
+
+ dup = dup_super(st);
+ snprintf(container_devname, PATH_MAX, "/dev/%s", container_devnm);
+
+ if (dup->ss->get_spare_criteria(dup, container_devname, &sc) != 0) {
+ if (verbose > 1)
+ pr_err("Failed to get spare criteria for %s\n", container_devname);
+ goto out;
+ }
+
+ if (!disk_fd_matches_criteria(disk_fd, &sc)) {
+ if (verbose > 1)
+ pr_err("Disk does not match spare criteria for %s\n", container_devname);
+ goto out;
+ }
+
+ rv = MDADM_STATUS_SUCCESS;
+
+out:
+ dup->ss->free_super(dup);
+ free(dup);
+
+ return rv;
+}
+
static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
struct map_ent *target, int bare,
struct supertype *st, int verbose)
@@ -873,8 +920,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
struct supertype *st2;
struct domainlist *dl = NULL;
struct mdinfo *sra;
- unsigned long long devsize, freesize = 0;
- struct spare_criteria sc = {0};
+ unsigned long long freesize = 0;
if (is_subarray(mp->metadata))
continue;
@@ -925,34 +971,19 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
if (sra->array.failed_disks == -1)
sra->array.failed_disks = container_members_max_degradation(map, mp);
- get_dev_size(dfd, NULL, &devsize);
if (sra->component_size == 0) {
- /* true for containers, here we must read superblock
- * to obtain minimum spare size */
- struct supertype *st3 = dup_super(st2);
- int mdfd = open_dev(mp->devnm);
- if (mdfd < 0) {
- free(st3);
+ /* true for containers */
+ if (incremental_external_test_spare_criteria(st2, mp->devnm, dfd, verbose))
goto next;
- }
- if (st3->ss->load_container &&
- !st3->ss->load_container(st3, mdfd, mp->path)) {
- if (st3->ss->get_spare_criteria)
- st3->ss->get_spare_criteria(st3, &sc);
- st3->ss->free_super(st3);
- }
- free(st3);
- close(mdfd);
}
- if ((sra->component_size > 0 &&
- st2->ss->validate_geometry(st2, sra->array.level, sra->array.layout,
+
+ if (sra->component_size > 0 &&
+ st2->ss->validate_geometry(st2, sra->array.level, sra->array.layout,
sra->array.raid_disks, &sra->array.chunk_size,
sra->component_size,
sra->devs ? sra->devs->data_offset : INVALID_SECTORS,
devname, &freesize, sra->consistency_policy,
- 0) &&
- freesize < sra->component_size) ||
- (sra->component_size == 0 && devsize < sc.min_size)) {
+ 0) && freesize < sra->component_size) {
if (verbose > 1)
pr_err("not adding %s to %s as it is too small\n",
devname, mp->path);
diff --git a/Monitor.c b/Monitor.c
index 1ece8712..6b4560ae 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -1008,34 +1008,6 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist)
return new_found;
}
-static int get_required_spare_criteria(struct state *st,
- struct spare_criteria *sc)
-{
- int fd;
-
- if (!st->metadata || !st->metadata->ss->get_spare_criteria) {
- sc->min_size = 0;
- sc->sector_size = 0;
- return 0;
- }
-
- fd = open(st->devname, O_RDONLY);
- if (fd < 0)
- return 1;
- if (st->metadata->ss->external)
- st->metadata->ss->load_container(st->metadata, fd, st->devname);
- else
- st->metadata->ss->load_super(st->metadata, fd, st->devname);
- close(fd);
- if (!st->metadata->sb)
- return 1;
-
- st->metadata->ss->get_spare_criteria(st->metadata, sc);
- st->metadata->ss->free_super(st->metadata);
-
- return 0;
-}
-
static int check_donor(struct state *from, struct state *to)
{
struct state *sub;
@@ -1178,8 +1150,11 @@ static void try_spare_migration(struct state *statelist)
/* member of a container */
to = to->parent;
- if (get_required_spare_criteria(to, &sc))
- continue;
+ if (to->metadata->ss->get_spare_criteria)
+ if (to->metadata->ss->get_spare_criteria(to->metadata, to->devname,
+ &sc))
+ continue;
+
if (to->metadata->ss->external) {
/* We must make sure there is
* no suitable spare in container already.
diff --git a/mdadm.h b/mdadm.h
index e8abd730..cbc586f5 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1116,10 +1116,9 @@ extern struct superswitch {
* Return spare criteria for array:
* - minimum disk size can be used in array;
* - sector size can be used in array.
- * Return values: 0 - for success and -EINVAL on error.
*/
- int (*get_spare_criteria)(struct supertype *st,
- struct spare_criteria *sc);
+ mdadm_status_t (*get_spare_criteria)(struct supertype *st, char *mddev_path,
+ struct spare_criteria *sc);
/* Find somewhere to put a bitmap - possibly auto-size it - and
* update the metadata to record this. The array may be newly
* created, in which case data_size may be updated, or it might
diff --git a/super-intel.c b/super-intel.c
index 39ec4754..7ad391ac 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -1736,46 +1736,6 @@ static __u32 imsm_min_reserved_sectors(struct intel_super *super)
return (remainder < rv) ? remainder : rv;
}
-/*
- * Return minimum size of a spare and sector size
- * that can be used in this array
- */
-int get_spare_criteria_imsm(struct supertype *st, struct spare_criteria *c)
-{
- struct intel_super *super = st->sb;
- struct dl *dl;
- struct extent *e;
- int i;
- unsigned long long size = 0;
-
- if (!super)
- return -EINVAL;
- /* find first active disk in array */
- dl = super->disks;
- while (dl && (is_failed(&dl->disk) || dl->index == -1))
- dl = dl->next;
- if (!dl)
- return -EINVAL;
- /* find last lba used by subarrays */
- e = get_extents(super, dl, 0);
- if (!e)
- return -EINVAL;
- for (i = 0; e[i].size; i++)
- continue;
- if (i > 0)
- size = e[i-1].start + e[i-1].size;
- free(e);
-
- /* add the amount of space needed for metadata */
- size += imsm_min_reserved_sectors(super);
-
- c->min_size = size * 512;
- c->sector_size = super->sector_size;
- c->criteria_set = true;
-
- return 0;
-}
-
static bool is_gen_migration(struct imsm_dev *dev);
#define IMSM_4K_DIV 8
@@ -11295,6 +11255,84 @@ static const char *imsm_get_disk_controller_domain(const char *path)
return drv;
}
+/**
+ * get_spare_criteria_imsm() - set spare criteria.
+ * @st: supertype.
+ * @mddev_path: path to md device devnode, it must be container.
+ * @c: spare_criteria struct to fill, not NULL.
+ *
+ * If superblock is not loaded, use mddev_path to load_container. It must be given in this case.
+ * Filles size and sector size accordingly to superblock.
+ */
+mdadm_status_t get_spare_criteria_imsm(struct supertype *st, char *mddev_path,
+ struct spare_criteria *c)
+{
+ mdadm_status_t ret = MDADM_STATUS_ERROR;
+ bool free_superblock = false;
+ unsigned long long size = 0;
+ struct intel_super *super;
+ struct extent *e;
+ struct dl *dl;
+ int i;
+
+ /* If no superblock and no mddev_path, we cannot load superblock. */
+ assert(st->sb || mddev_path);
+
+ if (mddev_path) {
+ int fd = open(mddev_path, O_RDONLY);
+
+ if (!is_fd_valid(fd))
+ return MDADM_STATUS_ERROR;
+
+ if (!st->sb) {
+ if (load_container_imsm(st, fd, st->devnm)) {
+ close(fd);
+ return MDADM_STATUS_ERROR;
+ }
+ free_superblock = true;
+ }
+ close(fd);
+ }
+
+ super = st->sb;
+
+ /* find first active disk in array */
+ dl = super->disks;
+ while (dl && (is_failed(&dl->disk) || dl->index == -1))
+ dl = dl->next;
+
+ if (!dl)
+ goto out;
+
+ /* find last lba used by subarrays */
+ e = get_extents(super, dl, 0);
+ if (!e)
+ goto out;
+
+ for (i = 0; e[i].size; i++)
+ continue;
+ if (i > 0)
+ size = e[i - 1].start + e[i - 1].size;
+ free(e);
+
+ /* add the amount of space needed for metadata */
+ size += imsm_min_reserved_sectors(super);
+
+ c->min_size = size * 512;
+ c->sector_size = super->sector_size;
+ c->criteria_set = true;
+ ret = MDADM_STATUS_SUCCESS;
+
+out:
+ if (free_superblock)
+ free_super_imsm(st);
+
+ if (ret != MDADM_STATUS_SUCCESS)
+ c->criteria_set = false;
+
+ return ret;
+}
+
static char *imsm_find_array_devnm_by_subdev(int subdev, char *container)
{
static char devnm[32];
@@ -11425,7 +11463,7 @@ static struct mdinfo *get_spares_for_grow(struct supertype *st)
{
struct spare_criteria sc;
- get_spare_criteria_imsm(st, &sc);
+ get_spare_criteria_imsm(st, NULL, &sc);
return container_choose_spares(st, &sc, NULL, NULL, NULL, 0);
}
--
2.40.1

View File

@ -0,0 +1,64 @@
From e97ca3583c96591af0e4863c12c394074a51c84d Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 29 Feb 2024 12:52:07 +0100
Subject: [PATCH 23/41] Manage: fix check after dereference issue
The code dereferences dev_st earlier without checking, it gives SAST
problem.
dev_st is needed for attempt_re_add(), but it is executed only if
dv->disposition != 'S', so move disposition check up.
tst is a must to reach this place, dup_super() have to return valid
pointer, all it needs to check is if load_super() returns superblock.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Manage.c | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/Manage.c b/Manage.c
index 30302ac8..77b79cf5 100644
--- a/Manage.c
+++ b/Manage.c
@@ -794,25 +794,23 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
* simply re-add it.
*/
- if (array->not_persistent == 0) {
+ if (array->not_persistent == 0 && dv->disposition != 'S') {
+ int rv = 0;
+
dev_st = dup_super(tst);
dev_st->ss->load_super(dev_st, tfd, NULL);
- if (dev_st->sb && dv->disposition != 'S') {
- int rv;
- rv = attempt_re_add(fd, tfd, dv, dev_st, tst,
- rdev, update, devname,
- verbose, array);
- dev_st->ss->free_super(dev_st);
- if (rv) {
- free(dev_st);
- return rv;
- }
- }
- if (dev_st) {
+ if (dev_st->sb) {
+ rv = attempt_re_add(fd, tfd, dv, dev_st, tst, rdev, update,
+ devname, verbose, array);
+
dev_st->ss->free_super(dev_st);
- free(dev_st);
}
+
+ free(dev_st);
+
+ if (rv)
+ return rv;
}
if (dv->disposition == 'M') {
if (verbose > 0)
--
2.40.1

View File

@ -0,0 +1,184 @@
From 29273f606542d915a3ddf37bb084f4eff54fcc3b Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 29 Feb 2024 12:52:08 +0100
Subject: [PATCH 24/41] Manage: implement manage_add_external()
Move external add code to separate function. It is easier to control
error path now. Error messages are adjusted.
No functional changes.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Manage.c | 147 ++++++++++++++++++++++++++++++++-----------------------
1 file changed, 86 insertions(+), 61 deletions(-)
diff --git a/Manage.c b/Manage.c
index 77b79cf5..b3e216cb 100644
--- a/Manage.c
+++ b/Manage.c
@@ -695,6 +695,91 @@ skip_re_add:
return 0;
}
+/**
+ * manage_add_external() - Add disk to external container.
+ * @st: external supertype pointer, must not be NULL, superblock is released here.
+ * @fd: container file descriptor, must not have O_EXCL mode.
+ * @disk_fd: device to add file descriptor.
+ * @disk_name: name of the device to add.
+ * @disc: disk info.
+ *
+ * Superblock is released here because any open fd with O_EXCL will block sysfs_add_disk().
+ */
+mdadm_status_t manage_add_external(struct supertype *st, int fd, char *disk_name,
+ mdu_disk_info_t *disc)
+{
+ mdadm_status_t rv = MDADM_STATUS_ERROR;
+ char container_devpath[MD_NAME_MAX];
+ struct mdinfo new_mdi;
+ struct mdinfo *sra = NULL;
+ int container_fd;
+ int disk_fd = -1;
+
+ snprintf(container_devpath, MD_NAME_MAX, "%s", fd2devnm(fd));
+
+ container_fd = open_dev_excl(container_devpath);
+ if (!is_fd_valid(container_fd)) {
+ pr_err("Failed to get exclusive access to container %s\n", container_devpath);
+ return MDADM_STATUS_ERROR;
+ }
+
+ /* Check if metadata handler is able to accept the drive */
+ if (!st->ss->validate_geometry(st, LEVEL_CONTAINER, 0, 1, NULL, 0, 0, disk_name, NULL,
+ 0, 1))
+ goto out;
+
+ Kill(disk_name, NULL, 0, -1, 0);
+
+ disk_fd = dev_open(disk_name, O_RDWR | O_EXCL | O_DIRECT);
+ if (!is_fd_valid(disk_fd)) {
+ pr_err("Failed to exclusively open %s\n", disk_name);
+ goto out;
+ }
+
+ if (st->ss->add_to_super(st, disc, disk_fd, disk_name, INVALID_SECTORS))
+ goto out;
+
+ if (!mdmon_running(st->container_devnm))
+ st->ss->sync_metadata(st);
+
+ sra = sysfs_read(container_fd, NULL, 0);
+ if (!sra) {
+ pr_err("Failed to read sysfs for %s\n", disk_name);
+ goto out;
+ }
+
+ sra->array.level = LEVEL_CONTAINER;
+ /* Need to set data_offset and component_size */
+ st->ss->getinfo_super(st, &new_mdi, NULL);
+ new_mdi.disk.major = disc->major;
+ new_mdi.disk.minor = disc->minor;
+ new_mdi.recovery_start = 0;
+
+ st->ss->free_super(st);
+
+ if (sysfs_add_disk(sra, &new_mdi, 0) != 0) {
+ pr_err("Failed to add %s to container %s\n", disk_name, container_devpath);
+ goto out;
+ }
+ ping_monitor(container_devpath);
+ rv = MDADM_STATUS_SUCCESS;
+
+out:
+ close(container_fd);
+
+ if (sra)
+ sysfs_free(sra);
+
+ if (rv != MDADM_STATUS_SUCCESS && is_fd_valid(disk_fd))
+ /* Metadata handler records this descriptor, so release it only on failure. */
+ close(disk_fd);
+
+ if (st->sb)
+ st->ss->free_super(st);
+
+ return rv;
+}
+
int Manage_add(int fd, int tfd, struct mddev_dev *dv,
struct supertype *tst, mdu_array_info_t *array,
int force, int verbose, char *devname,
@@ -966,68 +1051,8 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
if (dv->failfast == FlagSet)
disc.state |= (1 << MD_DISK_FAILFAST);
if (tst->ss->external) {
- /* add a disk
- * to an external metadata container */
- struct mdinfo new_mdi;
- struct mdinfo *sra;
- int container_fd;
- char devnm[32];
- int dfd;
-
- strcpy(devnm, fd2devnm(fd));
-
- container_fd = open_dev_excl(devnm);
- if (container_fd < 0) {
- pr_err("add failed for %s: could not get exclusive access to container\n",
- dv->devname);
- tst->ss->free_super(tst);
+ if (manage_add_external(tst, fd, dv->devname, &disc) != MDADM_STATUS_SUCCESS)
goto unlock;
- }
-
- /* Check if metadata handler is able to accept the drive */
- if (!tst->ss->validate_geometry(tst, LEVEL_CONTAINER, 0, 1, NULL,
- 0, 0, dv->devname, NULL, 0, 1)) {
- close(container_fd);
- goto unlock;
- }
-
- Kill(dv->devname, NULL, 0, -1, 0);
- dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT);
- if (tst->ss->add_to_super(tst, &disc, dfd,
- dv->devname, INVALID_SECTORS)) {
- close(dfd);
- close(container_fd);
- goto unlock;
- }
- if (!mdmon_running(tst->container_devnm))
- tst->ss->sync_metadata(tst);
-
- sra = sysfs_read(container_fd, NULL, 0);
- if (!sra) {
- pr_err("add failed for %s: sysfs_read failed\n",
- dv->devname);
- close(container_fd);
- tst->ss->free_super(tst);
- goto unlock;
- }
- sra->array.level = LEVEL_CONTAINER;
- /* Need to set data_offset and component_size */
- tst->ss->getinfo_super(tst, &new_mdi, NULL);
- new_mdi.disk.major = disc.major;
- new_mdi.disk.minor = disc.minor;
- new_mdi.recovery_start = 0;
- /* Make sure fds are closed as they are O_EXCL which
- * would block add_disk */
- tst->ss->free_super(tst);
- if (sysfs_add_disk(sra, &new_mdi, 0) != 0) {
- pr_err("add new device to external metadata failed for %s\n", dv->devname);
- close(container_fd);
- sysfs_free(sra);
- goto unlock;
- }
- ping_monitor(devnm);
- sysfs_free(sra);
- close(container_fd);
} else {
tst->ss->free_super(tst);
if (ioctl(fd, ADD_NEW_DISK, &disc)) {
--
2.40.1

View File

@ -0,0 +1,138 @@
From 14a8657940be34a781222b4b715bd09eb80d1057 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 29 Feb 2024 12:52:09 +0100
Subject: [PATCH 25/41] mdadm: introduce sysfs_get_container_devnm()
There at least two places where it is done directly, so replace them
with function. Print message about creating external array, add "/dev/"
prefix to refer directly to devnode.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Create.c | 21 ++++++++++-----------
Manage.c | 14 ++++----------
mdadm.h | 2 ++
sysfs.c | 23 +++++++++++++++++++++++
4 files changed, 39 insertions(+), 21 deletions(-)
diff --git a/Create.c b/Create.c
index 7e9170b6..0b776266 100644
--- a/Create.c
+++ b/Create.c
@@ -1142,24 +1142,23 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
if (did_default && c->verbose >= 0) {
if (is_subarray(info.text_version)) {
- char devnm[32];
- char *ep;
+ char devnm[MD_NAME_MAX];
struct mdinfo *mdi;
- strncpy(devnm, info.text_version+1, 32);
- devnm[31] = 0;
- ep = strchr(devnm, '/');
- if (ep)
- *ep = 0;
+ sysfs_get_container_devnm(&info, devnm);
mdi = sysfs_read(-1, devnm, GET_VERSION);
+ if (!mdi) {
+ pr_err("Cannot open sysfs for container %s\n", devnm);
+ goto abort_locked;
+ }
+
+ pr_info("Creating array inside %s container /dev/%s\n", mdi->text_version,
+ devnm);
- pr_info("Creating array inside %s container %s\n",
- mdi?mdi->text_version:"managed", devnm);
sysfs_free(mdi);
} else
- pr_info("Defaulting to version %s metadata\n",
- info.text_version);
+ pr_info("Defaulting to version %s metadata\n", info.text_version);
}
map_update(&map, fd2devnm(mdfd), info.text_version,
diff --git a/Manage.c b/Manage.c
index b3e216cb..969d0ea9 100644
--- a/Manage.c
+++ b/Manage.c
@@ -178,7 +178,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
struct map_ent *map = NULL;
struct mdinfo *mdi;
char devnm[32];
- char container[32];
+ char container[MD_NAME_MAX] = {0};
int err;
int count;
char buf[SYSFS_MAX_BUF_SIZE];
@@ -192,15 +192,9 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
* to stop is probably a bad idea.
*/
mdi = sysfs_read(fd, NULL, GET_LEVEL|GET_COMPONENT|GET_VERSION);
- if (mdi && is_subarray(mdi->text_version)) {
- char *sl;
- strncpy(container, mdi->text_version+1, sizeof(container));
- container[sizeof(container)-1] = 0;
- sl = strchr(container, '/');
- if (sl)
- *sl = 0;
- } else
- container[0] = 0;
+ if (mdi && is_subarray(mdi->text_version))
+ sysfs_get_container_devnm(mdi, container);
+
close(fd);
count = 5;
while (((fd = ((devname[0] == '/')
diff --git a/mdadm.h b/mdadm.h
index cbc586f5..39b86bd0 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -777,6 +777,8 @@ enum sysfs_read_flags {
#define SYSFS_MAX_BUF_SIZE 64
+extern void sysfs_get_container_devnm(struct mdinfo *mdi, char *buf);
+
/* If fd >= 0, get the array it is open on,
* else use devnm.
*/
diff --git a/sysfs.c b/sysfs.c
index f95ef701..230b842e 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -74,6 +74,29 @@ void sysfs_free(struct mdinfo *sra)
}
}
+/**
+ * sysfs_get_container_devnm() - extract container device name.
+ * @mdi: md_info describes member array, with GET_VERSION option.
+ * @buf: buf to fill, must be MD_NAME_MAX.
+ *
+ * External array version is in format {/,-}<container_devnm>/<array_index>
+ * Extract container_devnm from it and safe it in @buf.
+ */
+void sysfs_get_container_devnm(struct mdinfo *mdi, char *buf)
+{
+ char *p;
+
+ assert(is_subarray(mdi->text_version));
+
+ /* Skip first special sign */
+ snprintf(buf, MD_NAME_MAX, "%s", mdi->text_version + 1);
+
+ /* Remove array index */
+ p = strchr(buf, '/');
+ if (p)
+ *p = 0;
+}
+
int sysfs_open(char *devnm, char *devname, char *attr)
{
char fname[MAX_SYSFS_PATH_LEN];
--
2.40.1

View File

@ -0,0 +1,115 @@
From 1fef0c6ff54c2710f75a239dd8a5e0ffb0068e86 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 29 Feb 2024 12:52:10 +0100
Subject: [PATCH 26/41] mdadm.h: Introduce custom device policies
The approach proposed here is to test drive policies outside
validate_geometry() separately per every drive and add determined
policies to list. The implementation reuses dev_policy we have in
mdadm.
This concept addresses following problems:
- test drives if they fit together to criteria required by metadata
handler,
- test all drives assigned to the container even if some of them are not
target of the request, mdmon is free to use any drive in the same
container,
- extensibility, new policies can be added to handler easy,
- fix issues related to imsm controller domain verifying.
Add superswitch function. It is used in next patches.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
mdadm.h | 54 ++++++++++++++++++++++++++++++++++++------------------
1 file changed, 36 insertions(+), 18 deletions(-)
diff --git a/mdadm.h b/mdadm.h
index 39b86bd0..889f4a0f 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -940,6 +940,23 @@ struct reshape {
unsigned long long new_size; /* New size of array in sectors */
};
+/**
+ * struct dev_policy - Data structure for policy management.
+ * @next: pointer to next dev_policy.
+ * @name: policy name, category.
+ * @metadata: the metadata type it affects.
+ * @value: value of the policy.
+ *
+ * The functions to manipulate dev_policy lists do not free elements, so they must be statically
+ * allocated. @name and @metadata can be compared by address.
+ */
+typedef struct dev_policy {
+ struct dev_policy *next;
+ char *name;
+ const char *metadata;
+ const char *value;
+} dev_policy_t;
+
/* A superswitch provides entry point to a metadata handler.
*
* The superswitch primarily operates on some "metadata" that
@@ -1168,6 +1185,25 @@ extern struct superswitch {
char *subdev, unsigned long long *freesize,
int consistency_policy, int verbose);
+ /**
+ * test_and_add_drive_policies() - test new and add custom policies from metadata handler.
+ * @pols: list of currently recorded policies.
+ * @disk_fd: file descriptor of the device to check.
+ * @verbose: verbose flag.
+ *
+ * Used by IMSM to verify all drives in container/array, against requirements not recored
+ * in superblock, like controller type for IMSM. It should check all drives even if
+ * they are not actually used, because mdmon or kernel are free to use any drive assigned to
+ * container automatically.
+ *
+ * Generating and comparison methods belong to metadata handler. It is not mandatory to be
+ * implemented.
+ *
+ * Return: MDADM_STATUS_SUCCESS is expected on success.
+ */
+ mdadm_status_t (*test_and_add_drive_policies)(dev_policy_t **pols, int disk_fd,
+ const int verbose);
+
/* Return a linked list of 'mdinfo' structures for all arrays
* in the container. For non-containers, it is like
* getinfo_super with an allocated mdinfo.*/
@@ -1372,23 +1408,6 @@ extern int get_dev_sector_size(int fd, char *dname, unsigned int *sectsizep);
extern int must_be_container(int fd);
void wait_for(char *dev, int fd);
-/*
- * Data structures for policy management.
- * Each device can have a policy structure that lists
- * various name/value pairs each possibly with a metadata associated.
- * The policy list is sorted by name/value/metadata
- */
-struct dev_policy {
- struct dev_policy *next;
- char *name; /* None of these strings are allocated. They are
- * all just references to strings which are known
- * to exist elsewhere.
- * name and metadata can be compared by address equality.
- */
- const char *metadata;
- const char *value;
-};
-
extern char pol_act[], pol_domain[], pol_metadata[], pol_auto[];
/* iterate over the sublist starting at list, having the same
@@ -1430,7 +1449,6 @@ extern struct dev_policy *disk_policy(struct mdinfo *disk);
extern struct dev_policy *devid_policy(int devid);
extern void dev_policy_free(struct dev_policy *p);
-//extern void pol_new(struct dev_policy **pol, char *name, char *val, char *metadata);
extern void pol_add(struct dev_policy **pol, char *name, char *val, char *metadata);
extern struct dev_policy *pol_find(struct dev_policy *pol, char *name);
--
2.40.1

View File

@ -0,0 +1,144 @@
From 5a2e194cb31569880a26356b8594ddca6e3b3828 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 29 Feb 2024 12:52:11 +0100
Subject: [PATCH 27/41] mdadm: test_and_add device policies implementation
Add support for three scenarios:
- obtaining array wide policies via fd,
- obtaining array wide policies via struct mdinfo,
- getting policies for particular drive from the request.
Add proper functions and make them extern. These functions are used
in next patches.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
mdadm.h | 7 +++++
policy.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 100 insertions(+)
diff --git a/mdadm.h b/mdadm.h
index 889f4a0f..af2bc714 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1452,6 +1452,13 @@ extern void dev_policy_free(struct dev_policy *p);
extern void pol_add(struct dev_policy **pol, char *name, char *val, char *metadata);
extern struct dev_policy *pol_find(struct dev_policy *pol, char *name);
+extern mdadm_status_t drive_test_and_add_policies(struct supertype *st, dev_policy_t **pols,
+ int fd, const int verbose);
+extern mdadm_status_t sysfs_test_and_add_drive_policies(struct supertype *st, dev_policy_t **pols,
+ struct mdinfo *mdi, const int verbose);
+extern mdadm_status_t mddev_test_and_add_drive_policies(struct supertype *st, dev_policy_t **pols,
+ int array_fd, const int verbose);
+
enum policy_action {
act_default,
act_include,
diff --git a/policy.c b/policy.c
index eee9ef63..4b85f62d 100644
--- a/policy.c
+++ b/policy.c
@@ -397,6 +397,99 @@ struct dev_policy *path_policy(char **paths, char *type)
return pol;
}
+/**
+ * drive_test_and_add_policies() - get policies for drive and add them to pols.
+ * @st: supertype.
+ * @pols: pointer to pointer of first list entry, cannot be NULL, may point to NULL.
+ * @fd: device descriptor.
+ * @verbose: verbose flag.
+ *
+ * If supertype doesn't support this functionality return success. Use metadata handler to get
+ * policies.
+ */
+mdadm_status_t drive_test_and_add_policies(struct supertype *st, dev_policy_t **pols, int fd,
+ const int verbose)
+{
+ if (!st->ss->test_and_add_drive_policies)
+ return MDADM_STATUS_SUCCESS;
+
+ if (st->ss->test_and_add_drive_policies(pols, fd, verbose) == MDADM_STATUS_SUCCESS) {
+ /* After successful call list cannot be empty */
+ assert(*pols);
+ return MDADM_STATUS_SUCCESS;
+ }
+
+ return MDADM_STATUS_ERROR;
+}
+
+/**
+ * sysfs_test_and_add_policies() - get policies for mddev and add them to pols.
+ * @st: supertype.
+ * @pols: pointer to pointer of first list entry, cannot be NULL, may point to NULL.
+ * @mdi: mdinfo describes the MD array, must have GET_DISKS option.
+ * @verbose: verbose flag.
+ *
+ * If supertype doesn't support this functionality return success. To get policies, all disks
+ * connected to mddev are analyzed.
+ */
+mdadm_status_t sysfs_test_and_add_drive_policies(struct supertype *st, dev_policy_t **pols,
+ struct mdinfo *mdi, const int verbose)
+{
+ struct mdinfo *sd;
+
+ if (!st->ss->test_and_add_drive_policies)
+ return MDADM_STATUS_SUCCESS;
+
+ for (sd = mdi->devs; sd; sd = sd->next) {
+ char *devpath = map_dev(sd->disk.major, sd->disk.minor, 0);
+ int fd = dev_open(devpath, O_RDONLY);
+ int rv;
+
+ if (!is_fd_valid(fd)) {
+ pr_err("Cannot open fd for %s\n", devpath);
+ return MDADM_STATUS_ERROR;
+ }
+
+ rv = drive_test_and_add_policies(st, pols, fd, verbose);
+ close(fd);
+
+ if (rv)
+ return MDADM_STATUS_ERROR;
+ }
+
+ return MDADM_STATUS_SUCCESS;
+}
+
+/**
+ * mddev_test_and_add_policies() - get policies for mddev and add them to pols.
+ * @st: supertype.
+ * @pols: pointer to pointer of first list entry, cannot be NULL, may point to NULL.
+ * @array_fd: MD device descriptor.
+ * @verbose: verbose flag.
+ *
+ * If supertype doesn't support this functionality return success. Use fd to extract disks.
+ */
+mdadm_status_t mddev_test_and_add_drive_policies(struct supertype *st, dev_policy_t **pols,
+ int array_fd, const int verbose)
+{
+ struct mdinfo *sra;
+ int ret;
+
+ if (!st->ss->test_and_add_drive_policies)
+ return MDADM_STATUS_SUCCESS;
+
+ sra = sysfs_read(array_fd, NULL, GET_DEVS);
+ if (!sra) {
+ pr_err("Cannot load sysfs for %s\n", fd2devnm(array_fd));
+ return MDADM_STATUS_ERROR;
+ }
+
+ ret = sysfs_test_and_add_drive_policies(st, pols, sra, verbose);
+
+ sysfs_free(sra);
+ return ret;
+}
+
void pol_add(struct dev_policy **pol,
char *name, char *val,
char *metadata)
--
2.40.1

View File

@ -0,0 +1,124 @@
From f5a39b66f794322f30828389ddd488d17f578ad5 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 29 Feb 2024 12:52:12 +0100
Subject: [PATCH 28/41] Create: Use device policies
Generate and compare policies, abort if policies do not match.
It is tested for both create modes, with container and disk list
specified directly. It is used if supertype supports it.
For a case when disk list is specified, container may contain more
devices, so additional check on container is done to analyze all disks.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Create.c | 31 +++++++++++++++++++++++++------
1 file changed, 25 insertions(+), 6 deletions(-)
diff --git a/Create.c b/Create.c
index 0b776266..4397ff49 100644
--- a/Create.c
+++ b/Create.c
@@ -497,6 +497,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
*/
int mdfd;
unsigned long long minsize = 0, maxsize = 0;
+ dev_policy_t *custom_pols = NULL;
char *mindisc = NULL;
char *maxdisc = NULL;
char *name = ident->name;
@@ -588,6 +589,9 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
first_missing = subdevs * 2;
second_missing = subdevs * 2;
insert_point = subdevs * 2;
+
+ if (mddev_test_and_add_drive_policies(st, &custom_pols, fd, 1))
+ exit(1);
}
}
if (fd >= 0)
@@ -739,7 +743,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
close(dfd);
exit(2);
}
- close(dfd);
+
info.array.working_disks++;
if (dnum < s->raiddisks && dv->disposition != 'j')
info.array.active_disks++;
@@ -812,6 +816,11 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
}
}
+ if (drive_test_and_add_policies(st, &custom_pols, dfd, 1))
+ exit(1);
+
+ close(dfd);
+
if (dv->disposition == 'j')
goto skip_size_check; /* skip write journal for size check */
@@ -886,6 +895,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
close(fd);
}
}
+
if (missing_disks == dnum && !have_container) {
pr_err("Subdevs can't be all missing\n");
return 1;
@@ -1140,25 +1150,30 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
goto abort_locked;
}
- if (did_default && c->verbose >= 0) {
+ if (did_default) {
if (is_subarray(info.text_version)) {
char devnm[MD_NAME_MAX];
struct mdinfo *mdi;
sysfs_get_container_devnm(&info, devnm);
- mdi = sysfs_read(-1, devnm, GET_VERSION);
+ mdi = sysfs_read(-1, devnm, GET_VERSION | GET_DEVS);
if (!mdi) {
pr_err("Cannot open sysfs for container %s\n", devnm);
goto abort_locked;
}
- pr_info("Creating array inside %s container /dev/%s\n", mdi->text_version,
- devnm);
+ if (sysfs_test_and_add_drive_policies(st, &custom_pols, mdi, 1))
+ goto abort_locked;
+
+ if (c->verbose >= 0)
+ pr_info("Creating array inside %s container /dev/%s\n",
+ mdi->text_version, devnm);
sysfs_free(mdi);
- } else
+ } else if (c->verbose >= 0) {
pr_info("Defaulting to version %s metadata\n", info.text_version);
+ }
}
map_update(&map, fd2devnm(mdfd), info.text_version,
@@ -1328,6 +1343,8 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
udev_unblock();
close(mdfd);
sysfs_uevent(&info, "change");
+ dev_policy_free(custom_pols);
+
return 0;
abort:
@@ -1339,5 +1356,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
if (mdfd >= 0)
close(mdfd);
+
+ dev_policy_free(custom_pols);
return 1;
}
--
2.40.1

View File

@ -0,0 +1,60 @@
From 1251db34616bf4890d86664abc5186e9106e9073 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 29 Feb 2024 12:52:13 +0100
Subject: [PATCH 29/41] Manage: check device policies in manage_add_external()
Only IMSM is going to use device policies so it is added to
manage_add_external(). Test policies before adding the drive to
container.
The change blocks adding new device to the container which already
contains not matching devices
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Manage.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Manage.c b/Manage.c
index 969d0ea9..96e5ee54 100644
--- a/Manage.c
+++ b/Manage.c
@@ -704,6 +704,7 @@ mdadm_status_t manage_add_external(struct supertype *st, int fd, char *disk_name
{
mdadm_status_t rv = MDADM_STATUS_ERROR;
char container_devpath[MD_NAME_MAX];
+ struct dev_policy *pols = NULL;
struct mdinfo new_mdi;
struct mdinfo *sra = NULL;
int container_fd;
@@ -722,6 +723,9 @@ mdadm_status_t manage_add_external(struct supertype *st, int fd, char *disk_name
0, 1))
goto out;
+ if (mddev_test_and_add_drive_policies(st, &pols, container_fd, 1))
+ goto out;
+
Kill(disk_name, NULL, 0, -1, 0);
disk_fd = dev_open(disk_name, O_RDWR | O_EXCL | O_DIRECT);
@@ -730,6 +734,9 @@ mdadm_status_t manage_add_external(struct supertype *st, int fd, char *disk_name
goto out;
}
+ if (drive_test_and_add_policies(st, &pols, disk_fd, 1))
+ goto out;
+
if (st->ss->add_to_super(st, disc, disk_fd, disk_name, INVALID_SECTORS))
goto out;
@@ -760,6 +767,7 @@ mdadm_status_t manage_add_external(struct supertype *st, int fd, char *disk_name
out:
close(container_fd);
+ dev_policy_free(pols);
if (sra)
sysfs_free(sra);
--
2.40.1

View File

@ -0,0 +1,142 @@
From 51a9f2fc5e982f3bcbf88fe1bf30c0bf55bfd49c Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 29 Feb 2024 12:52:14 +0100
Subject: [PATCH 30/41] Monitor, Incremental: use device policies
spare_criteria is expanded to contain policies which will be generated
by handler's get_spare_criteria() function. It provides a way to
test device for metadata specific policies earlier than during
add_do_super(), when device is already removed from previous
array/container for Monitor.
For Incremental, it ensures that all criteria are tested when trying
spare. It is not tested when device contains valid metadata.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Incremental.c | 2 +-
Monitor.c | 3 ++-
mdadm.h | 5 +++--
util.c | 13 +++++++++----
4 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/Incremental.c b/Incremental.c
index 66c2cc86..958ba9ba 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -865,7 +865,7 @@ mdadm_status_t incremental_external_test_spare_criteria(struct supertype *st, ch
goto out;
}
- if (!disk_fd_matches_criteria(disk_fd, &sc)) {
+ if (!disk_fd_matches_criteria(dup, disk_fd, &sc)) {
if (verbose > 1)
pr_err("Disk does not match spare criteria for %s\n", container_devname);
goto out;
diff --git a/Monitor.c b/Monitor.c
index 6b4560ae..9b016bc3 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -1047,7 +1047,7 @@ static dev_t choose_spare(struct state *from, struct state *to,
test_partition_from_id(from->devid[d]))
continue;
- if (devid_matches_criteria(from->devid[d], sc) == false)
+ if (devid_matches_criteria(to->metadata, from->devid[d], sc) == false)
continue;
pol = devid_policy(from->devid[d]);
@@ -1195,6 +1195,7 @@ static void try_spare_migration(struct state *statelist)
}
}
domain_free(domlist);
+ dev_policy_free(sc.pols);
}
}
diff --git a/mdadm.h b/mdadm.h
index af2bc714..cfa11391 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -433,6 +433,7 @@ struct spare_criteria {
bool criteria_set;
unsigned long long min_size;
unsigned int sector_size;
+ struct dev_policy *pols;
};
typedef enum mdadm_status {
@@ -1734,8 +1735,8 @@ extern int assemble_container_content(struct supertype *st, int mdfd,
#define INCR_ALREADY 4
#define INCR_YES 8
-extern bool devid_matches_criteria(dev_t devid, struct spare_criteria *sc);
-extern bool disk_fd_matches_criteria(int disk_fd, struct spare_criteria *sc);
+extern bool devid_matches_criteria(struct supertype *st, dev_t devid, struct spare_criteria *sc);
+extern bool disk_fd_matches_criteria(struct supertype *st, int disk_fd, struct spare_criteria *sc);
extern struct mdinfo *container_choose_spares(struct supertype *st,
struct spare_criteria *criteria,
struct domainlist *domlist,
diff --git a/util.c b/util.c
index 041e78cf..05ad3343 100644
--- a/util.c
+++ b/util.c
@@ -2056,12 +2056,13 @@ unsigned int __invalid_size_argument_for_IOC = 0;
/**
* disk_fd_matches_criteria() - check if device matches spare criteria.
+ * @st: supertype, not NULL.
* @disk_fd: file descriptor of the disk.
* @sc: criteria to test.
*
* Return: true if disk matches criteria, false otherwise.
*/
-bool disk_fd_matches_criteria(int disk_fd, struct spare_criteria *sc)
+bool disk_fd_matches_criteria(struct supertype *st, int disk_fd, struct spare_criteria *sc)
{
unsigned int dev_sector_size = 0;
unsigned long long dev_size = 0;
@@ -2076,17 +2077,21 @@ bool disk_fd_matches_criteria(int disk_fd, struct spare_criteria *sc)
sc->sector_size != dev_sector_size)
return false;
+ if (drive_test_and_add_policies(st, &sc->pols, disk_fd, 0))
+ return false;
+
return true;
}
/**
* devid_matches_criteria() - check if device referenced by devid matches spare criteria.
+ * @st: supertype, not NULL.
* @devid: devid of the device to check.
* @sc: criteria to test.
*
* Return: true if disk matches criteria, false otherwise.
*/
-bool devid_matches_criteria(dev_t devid, struct spare_criteria *sc)
+bool devid_matches_criteria(struct supertype *st, dev_t devid, struct spare_criteria *sc)
{
char buf[NAME_MAX];
bool ret;
@@ -2102,7 +2107,7 @@ bool devid_matches_criteria(dev_t devid, struct spare_criteria *sc)
return false;
/* Error code inherited */
- ret = disk_fd_matches_criteria(fd, sc);
+ ret = disk_fd_matches_criteria(st, fd, sc);
close(fd);
return ret;
@@ -2137,7 +2142,7 @@ struct mdinfo *container_choose_spares(struct supertype *st,
if (d->disk.state == 0) {
dev_t dev = makedev(d->disk.major,d->disk.minor);
- found = devid_matches_criteria(dev, criteria);
+ found = devid_matches_criteria(st, dev, criteria);
/* check if domain matches */
if (found && domlist) {
--
2.40.1

View File

@ -0,0 +1,187 @@
From e21aea08eb706939a38f7dc5cf9509a9afd45f8a Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 29 Feb 2024 12:52:15 +0100
Subject: [PATCH 31/41] imsm: test_and_add_device_policies() implementation
This patch removes get_disk_controller_domain_imsm() in favour of
test_and_add_device_policies_imsm(). It is used by
create, add and mdmonitor.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
platform-intel.h | 1 -
super-intel.c | 123 ++++++++++++++++++++++++++++++++++-------------
2 files changed, 90 insertions(+), 34 deletions(-)
diff --git a/platform-intel.h b/platform-intel.h
index ce29d3da..3c2bc595 100644
--- a/platform-intel.h
+++ b/platform-intel.h
@@ -262,7 +262,6 @@ int disk_attached_to_hba(int fd, const char *hba_path);
int devt_attached_to_hba(dev_t dev, const char *hba_path);
char *devt_to_devpath(dev_t dev, int dev_level, char *buf);
int path_attached_to_hba(const char *disk_path, const char *hba_path);
-const char *get_sys_dev_type(enum sys_dev_type);
const struct orom_entry *get_orom_entry_by_device_id(__u16 dev_id);
const struct imsm_orom *get_orom_by_device_id(__u16 device_id);
struct sys_dev *device_by_id(__u16 device_id);
diff --git a/super-intel.c b/super-intel.c
index 7ad391ac..77140455 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -11220,39 +11220,90 @@ abort:
return retval;
}
-static char disk_by_path[] = "/dev/disk/by-path/";
-
-static const char *imsm_get_disk_controller_domain(const char *path)
-{
- char disk_path[PATH_MAX];
- char *drv=NULL;
- struct stat st;
-
- strncpy(disk_path, disk_by_path, PATH_MAX);
- strncat(disk_path, path, PATH_MAX - strlen(disk_path) - 1);
- if (stat(disk_path, &st) == 0) {
- struct sys_dev* hba;
- char *path;
-
- path = devt_to_devpath(st.st_rdev, 1, NULL);
- if (path == NULL)
- return "unknown";
- hba = find_disk_attached_hba(-1, path);
- if (hba && hba->type == SYS_DEV_SAS)
- drv = "isci";
- else if (hba && (hba->type == SYS_DEV_SATA || hba->type == SYS_DEV_SATA_VMD))
- drv = "ahci";
- else if (hba && hba->type == SYS_DEV_VMD)
- drv = "vmd";
- else if (hba && hba->type == SYS_DEV_NVME)
- drv = "nvme";
- else
- drv = "unknown";
- dprintf("path: %s hba: %s attached: %s\n",
- path, (hba) ? hba->path : "NULL", drv);
- free(path);
+/**
+ * test_and_add_drive_controller_policy_imsm() - add disk controller to policies list.
+ * @type: Policy type to search on list.
+ * @pols: List of currently recorded policies.
+ * @disk_fd: File descriptor of the device to check.
+ * @hba: The hba disk is attached, could be NULL if verification is disabled.
+ * @verbose: verbose flag.
+ *
+ * IMSM cares about drive physical placement. If @hba is not set, it adds unknown policy.
+ * If there is no controller policy on pols we are free to add first one. If there is a policy then,
+ * new must be the same - no controller mixing allowed.
+ */
+static mdadm_status_t
+test_and_add_drive_controller_policy_imsm(const char * const type, dev_policy_t **pols, int disk_fd,
+ struct sys_dev *hba, const int verbose)
+{
+ const char *controller_policy = get_sys_dev_type(SYS_DEV_UNKNOWN);
+ struct dev_policy *pol = pol_find(*pols, (char *)type);
+ char devname[MAX_RAID_SERIAL_LEN];
+
+ if (hba)
+ controller_policy = get_sys_dev_type(hba->type);
+
+ if (!pol) {
+ pol_add(pols, (char *)type, (char *)controller_policy, "imsm");
+ return MDADM_STATUS_SUCCESS;
}
- return drv;
+
+ if (strcmp(pol->value, controller_policy) == 0)
+ return MDADM_STATUS_SUCCESS;
+
+ fd2devname(disk_fd, devname);
+ pr_vrb("Intel(R) raid controller \"%s\" found for %s, but \"%s\" was detected earlier\n",
+ controller_policy, devname, pol->value);
+ pr_vrb("Disks under different controllers cannot be used, aborting\n");
+
+ return MDADM_STATUS_ERROR;
+}
+
+struct imsm_drive_policy {
+ char *type;
+ mdadm_status_t (*test_and_add_drive_policy)(const char * const type,
+ struct dev_policy **pols, int disk_fd,
+ struct sys_dev *hba, const int verbose);
+};
+
+struct imsm_drive_policy imsm_policies[] = {
+ {"controller", test_and_add_drive_controller_policy_imsm},
+};
+
+mdadm_status_t test_and_add_drive_policies_imsm(struct dev_policy **pols, int disk_fd,
+ const int verbose)
+{
+ struct imsm_drive_policy *imsm_pol;
+ struct sys_dev *hba = NULL;
+ char path[PATH_MAX];
+ mdadm_status_t ret;
+ unsigned int i;
+
+ /* If imsm platform verification is disabled, do not search for hba. */
+ if (check_no_platform() != 1) {
+ if (!diskfd_to_devpath(disk_fd, 1, path)) {
+ pr_vrb("IMSM: Failed to retrieve device path by file descriptor.\n");
+ return MDADM_STATUS_ERROR;
+ }
+
+ hba = find_disk_attached_hba(disk_fd, path);
+ if (!hba) {
+ pr_vrb("IMSM: Failed to find hba for %s\n", path);
+ return MDADM_STATUS_ERROR;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(imsm_policies); i++) {
+ imsm_pol = &imsm_policies[i];
+
+ ret = imsm_pol->test_and_add_drive_policy(imsm_pol->type, pols, disk_fd, hba,
+ verbose);
+ if (ret != MDADM_STATUS_SUCCESS)
+ /* Inherit error code */
+ return ret;
+ }
+
+ return MDADM_STATUS_SUCCESS;
}
/**
@@ -11280,6 +11331,7 @@ mdadm_status_t get_spare_criteria_imsm(struct supertype *st, char *mddev_path,
if (mddev_path) {
int fd = open(mddev_path, O_RDONLY);
+ mdadm_status_t rv;
if (!is_fd_valid(fd))
return MDADM_STATUS_ERROR;
@@ -11291,7 +11343,12 @@ mdadm_status_t get_spare_criteria_imsm(struct supertype *st, char *mddev_path,
}
free_superblock = true;
}
+
+ rv = mddev_test_and_add_drive_policies(st, &c->pols, fd, 0);
close(fd);
+
+ if (rv != MDADM_STATUS_SUCCESS)
+ goto out;
}
super = st->sb;
@@ -13026,7 +13083,7 @@ struct superswitch super_imsm = {
.update_subarray = update_subarray_imsm,
.load_container = load_container_imsm,
.default_geometry = default_geometry_imsm,
- .get_disk_controller_domain = imsm_get_disk_controller_domain,
+ .test_and_add_drive_policies = test_and_add_drive_policies_imsm,
.reshape_super = imsm_reshape_super,
.manage_reshape = imsm_manage_reshape,
.recover_backup = recover_backup_imsm,
--
2.40.1

View File

@ -0,0 +1,75 @@
From e492d2ac143e7f02d6c262130d42a4422e8295d5 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 29 Feb 2024 12:52:16 +0100
Subject: [PATCH 32/41] mdadm: drop get_disk_controller_domain()
This function is unused now. Drop it.
Controller for IMSM is a device policy and is separated from user defined
domains.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
mdadm.h | 15 ---------------
policy.c | 13 -------------
2 files changed, 28 deletions(-)
diff --git a/mdadm.h b/mdadm.h
index cfa11391..3fedca48 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1286,21 +1286,6 @@ extern struct superswitch {
*/
struct mdinfo *(*activate_spare)(struct active_array *a,
struct metadata_update **updates);
- /*
- * Return statically allocated string that represents metadata specific
- * controller domain of the disk. The domain is used in disk domain
- * matching functions. Disks belong to the same domain if the they have
- * the same domain from mdadm.conf and belong the same metadata domain.
- * Returning NULL or not providing this handler means that metadata
- * does not distinguish the differences between disks that belong to
- * different controllers. They are in the domain specified by
- * configuration file (mdadm.conf).
- * In case when the metadata has the notion of domains based on disk
- * it shall return NULL for disks that do not belong to the controller
- * the supported domains. Such disks will form another domain and won't
- * be mixed with supported ones.
- */
- const char *(*get_disk_controller_domain)(const char *path);
/* for external backup area */
int (*recover_backup)(struct supertype *st, struct mdinfo *info);
diff --git a/policy.c b/policy.c
index 4b85f62d..404f9b5d 100644
--- a/policy.c
+++ b/policy.c
@@ -365,7 +365,6 @@ struct dev_policy *path_policy(char **paths, char *type)
{
struct pol_rule *rules;
struct dev_policy *pol = NULL;
- int i;
rules = config_rules;
@@ -380,18 +379,6 @@ struct dev_policy *path_policy(char **paths, char *type)
rules = rules->next;
}
- /* Now add any metadata-specific internal knowledge
- * about this path
- */
- for (i=0; paths && paths[0] && superlist[i]; i++)
- if (superlist[i]->get_disk_controller_domain) {
- const char *d =
- superlist[i]->get_disk_controller_domain(
- paths[0]);
- if (d)
- pol_new(&pol, pol_domain, d, superlist[i]->name);
- }
-
pol_sort(&pol);
pol_dedup(pol);
return pol;
--
2.40.1

View File

@ -0,0 +1,42 @@
From 933bb500b80cca6f4e9237382f7d8ac852978471 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Thu, 29 Feb 2024 12:52:17 +0100
Subject: [PATCH 33/41] Revert "policy.c: Avoid to take spare without defined
domain by imsm"
This reverts commit 3bf9495270d7 ("policy.c: Avoid to take spare without
defined domain by imsm").
IMSM does not require to be special now because it doesn't create disk
controller domain.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
policy.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/policy.c b/policy.c
index 404f9b5d..dfaafdc0 100644
--- a/policy.c
+++ b/policy.c
@@ -759,7 +759,6 @@ int domain_test(struct domainlist *dom, struct dev_policy *pol,
* 1: has domains, all match
*/
int found_any = -1;
- int has_one_domain = 1;
struct dev_policy *p;
pol = pol_find(pol, pol_domain);
@@ -769,9 +768,6 @@ int domain_test(struct domainlist *dom, struct dev_policy *pol,
dom = dom->next;
if (!dom || strcmp(dom->dom, p->value) != 0)
return 0;
- if (has_one_domain && metadata && strcmp(metadata, "imsm") == 0)
- found_any = -1;
- has_one_domain = 0;
}
return found_any;
}
--
2.40.1

View File

@ -0,0 +1,307 @@
From 9c63130e8974033969569fb9d0b373d1d1478cf7 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Wed, 6 Mar 2024 13:45:53 +0100
Subject: [PATCH 34/41] mdadm: remove inventory file
It is a file with repo content list. It is outdated already.
Remove it.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
inventory | 284 ------------------------------------------------------
1 file changed, 284 deletions(-)
delete mode 100755 inventory
diff --git a/inventory b/inventory
deleted file mode 100755
index c4801b49..00000000
--- a/inventory
+++ /dev/null
@@ -1,284 +0,0 @@
-
-.gitignore
-ANNOUNCE-3.0
-ANNOUNCE-3.0.1
-ANNOUNCE-3.0.2
-ANNOUNCE-3.0.3
-ANNOUNCE-3.1
-ANNOUNCE-3.1.1
-ANNOUNCE-3.1.2
-ANNOUNCE-3.1.3
-ANNOUNCE-3.1.4
-ANNOUNCE-3.1.5
-ANNOUNCE-3.2
-ANNOUNCE-3.2.1
-ANNOUNCE-3.2.2
-ANNOUNCE-3.2.3
-ANNOUNCE-3.2.4
-ANNOUNCE-3.2.5
-ANNOUNCE-3.2.6
-ANNOUNCE-3.3
-ANNOUNCE-3.3.1
-ANNOUNCE-3.3.2
-ANNOUNCE-3.3.3
-ANNOUNCE-3.3.4
-ANNOUNCE-3.4
-ANNOUNCE-4.0
-ANNOUNCE-4.1
-ANNOUNCE-4.2
-Assemble.c
-Build.c
-COPYING
-ChangeLog
-Create.c
-Detail.c
-Dump.c
-Examine.c
-Grow.c
-INSTALL
-Incremental.c
-Kill.c
-Makefile
-Manage.c
-Monitor.c
-Query.c
-README.initramfs
-ReadMe.c
-TODO
-bitmap.c
-bitmap.h
-clustermd_tests/
-clustermd_tests/00r10_Create
-clustermd_tests/00r1_Create
-clustermd_tests/01r10_Grow_bitmap-switch
-clustermd_tests/01r10_Grow_resize
-clustermd_tests/01r1_Grow_add
-clustermd_tests/01r1_Grow_bitmap-switch
-clustermd_tests/01r1_Grow_resize
-clustermd_tests/02r10_Manage_add
-clustermd_tests/02r10_Manage_add-spare
-clustermd_tests/02r10_Manage_re-add
-clustermd_tests/02r1_Manage_add
-clustermd_tests/02r1_Manage_add-spare
-clustermd_tests/02r1_Manage_re-add
-clustermd_tests/03r10_switch-recovery
-clustermd_tests/03r10_switch-resync
-clustermd_tests/03r1_switch-recovery
-clustermd_tests/03r1_switch-resync
-clustermd_tests/cluster_conf
-clustermd_tests/func.sh
-config.c
-coverity-gcc-hack.h
-crc32.c
-crc32.h
-crc32c.c
-dlink.c
-dlink.h
-external-reshape-design.txt
-inventory
-lib.c
-makedist
-managemon.c
-mapfile.c
-maps.c
-md.4
-md5.h
-md_p.h
-md_u.h
-mdadm.8.in
-mdadm.c
-mdadm.conf-example
-mdadm.conf.5
-mdadm.h
-mdadm.spec
-mdmon-design.txt
-mdmon.8
-mdmon.c
-mdmon.h
-mdopen.c
-mdstat.c
-misc/
-misc/mdcheck
-misc/syslog-events
-mkinitramfs
-monitor.c
-msg.c
-msg.h
-part.h
-platform-intel.c
-platform-intel.h
-policy.c
-probe_roms.c
-probe_roms.h
-pwgr.c
-raid5extend.c
-raid6check.8
-raid6check.c
-restripe.c
-sg_io.c
-sha1.c
-sha1.h
-super-ddf.c
-super-gpt.c
-super-intel.c
-super-mbr.c
-super0.c
-super1.c
-swap_super.c
-sysfs.c
-systemd/
-systemd/SUSE-mdadm_env.sh
-systemd/mdadm-grow-continue@.service
-systemd/mdadm-last-resort@.service
-systemd/mdadm-last-resort@.timer
-systemd/mdadm.shutdown
-systemd/mdcheck_continue.service
-systemd/mdcheck_continue.timer
-systemd/mdcheck_start.service
-systemd/mdcheck_start.timer
-systemd/mdmon@.service
-systemd/mdmonitor-oneshot.service
-systemd/mdmonitor-oneshot.timer
-systemd/mdmonitor.service
-test
-tests/
-tests/00linear
-tests/00multipath
-tests/00names
-tests/00raid0
-tests/00raid1
-tests/00raid10
-tests/00raid4
-tests/00raid5
-tests/00raid6
-tests/00readonly
-tests/01r1fail
-tests/01r5fail
-tests/01r5integ
-tests/01raid6integ
-tests/01replace
-tests/02lineargrow
-tests/02r1add
-tests/02r1grow
-tests/02r5grow
-tests/02r6grow
-tests/03assem-incr
-tests/03r0assem
-tests/03r5assem
-tests/03r5assem-failed
-tests/03r5assemV1
-tests/04r0update
-tests/04r1update
-tests/04r5swap
-tests/04update-metadata
-tests/04update-uuid
-tests/05r1-add-internalbitmap
-tests/05r1-add-internalbitmap-v1a
-tests/05r1-add-internalbitmap-v1b
-tests/05r1-add-internalbitmap-v1c
-tests/05r1-bitmapfile
-tests/05r1-failfast
-tests/05r1-grow-external
-tests/05r1-grow-internal
-tests/05r1-grow-internal-1
-tests/05r1-internalbitmap
-tests/05r1-internalbitmap-v1a
-tests/05r1-internalbitmap-v1b
-tests/05r1-internalbitmap-v1c
-tests/05r1-n3-bitmapfile
-tests/05r1-re-add
-tests/05r1-re-add-nosuper
-tests/05r1-remove-internalbitmap
-tests/05r1-remove-internalbitmap-v1a
-tests/05r1-remove-internalbitmap-v1b
-tests/05r1-remove-internalbitmap-v1c
-tests/05r5-bitmapfile
-tests/05r5-internalbitmap
-tests/05r6-bitmapfile
-tests/05r6tor0
-tests/06name
-tests/06sysfs
-tests/06wrmostly
-tests/07autoassemble
-tests/07autodetect
-tests/07changelevelintr
-tests/07changelevels
-tests/07layouts
-tests/07reshape5intr
-tests/07revert-grow
-tests/07revert-inplace
-tests/07revert-shrink
-tests/07testreshape5
-tests/09imsm-assemble
-tests/09imsm-create-fail-rebuild
-tests/09imsm-overlap
-tests/10ddf-assemble-missing
-tests/10ddf-create
-tests/10ddf-create-fail-rebuild
-tests/10ddf-fail-create-race
-tests/10ddf-fail-readd
-tests/10ddf-fail-readd-readonly
-tests/10ddf-fail-spare
-tests/10ddf-fail-stop-readd
-tests/10ddf-fail-twice
-tests/10ddf-fail-two-spares
-tests/10ddf-geometry
-tests/10ddf-incremental-wrong-order
-tests/10ddf-sudden-degraded
-tests/11spare-migration
-tests/12imsm-r0_2d-grow-r0_3d
-tests/12imsm-r0_2d-grow-r0_4d
-tests/12imsm-r0_2d-grow-r0_5d
-tests/12imsm-r0_3d-grow-r0_4d
-tests/12imsm-r5_3d-grow-r5_4d
-tests/12imsm-r5_3d-grow-r5_5d
-tests/13imsm-r0_r0_2d-grow-r0_r0_4d
-tests/13imsm-r0_r0_2d-grow-r0_r0_5d
-tests/13imsm-r0_r0_3d-grow-r0_r0_4d
-tests/13imsm-r0_r5_3d-grow-r0_r5_4d
-tests/13imsm-r0_r5_3d-grow-r0_r5_5d
-tests/13imsm-r5_r0_3d-grow-r5_r0_4d
-tests/13imsm-r5_r0_3d-grow-r5_r0_5d
-tests/14imsm-r0_3d-r5_3d-migrate-r5_4d-r5_4d
-tests/14imsm-r0_3d_no_spares-migrate-r5_3d
-tests/14imsm-r0_r0_2d-takeover-r10_4d
-tests/14imsm-r10_4d-grow-r10_5d
-tests/14imsm-r10_r5_4d-takeover-r0_2d
-tests/14imsm-r1_2d-grow-r1_3d
-tests/14imsm-r1_2d-takeover-r0_2d
-tests/14imsm-r5_3d-grow-r5_5d-no-spares
-tests/14imsm-r5_3d-migrate-r4_3d
-tests/15imsm-r0_3d_64k-migrate-r0_3d_256k
-tests/15imsm-r5_3d_4k-migrate-r5_3d_256k
-tests/15imsm-r5_3d_64k-migrate-r5_3d_256k
-tests/15imsm-r5_6d_4k-migrate-r5_6d_256k
-tests/15imsm-r5_r0_3d_64k-migrate-r5_r0_3d_256k
-tests/16imsm-r0_3d-migrate-r5_4d
-tests/16imsm-r0_5d-migrate-r5_6d
-tests/16imsm-r5_3d-migrate-r0_3d
-tests/16imsm-r5_5d-migrate-r0_5d
-tests/18imsm-1d-takeover-r0_1d
-tests/18imsm-1d-takeover-r1_2d
-tests/18imsm-r0_2d-takeover-r10_4d
-tests/18imsm-r10_4d-takeover-r0_2d
-tests/18imsm-r1_2d-takeover-r0_1d
-tests/19raid6auto-repair
-tests/19raid6check
-tests/19raid6repair
-tests/19repair-does-not-destroy
-tests/20raid5journal
-tests/21raid5cache
-tests/ToTest
-tests/env-ddf-template
-tests/env-imsm-template
-tests/func.sh
-tests/imsm-grow-template
-tests/utils
-udev-md-clustered-confirm-device.rules
-udev-md-raid-arrays.rules
-udev-md-raid-assembly.rules
-udev-md-raid-creating.rules
-udev-md-raid-safe-timeouts.rules
-util.c
-uuid.c
-xmalloc.c
--
2.40.1

View File

@ -0,0 +1,31 @@
From 1750758c7ff526e3560433f6235e5cfa35cf646a Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Wed, 6 Mar 2024 15:50:55 +0100
Subject: [PATCH 35/41] udev.c: Do not require libudev.h if DNO_LIBUDEV
libudev may not be presented at all, do not require it.
Reported-by: Boian Bonev <bbonev@ipacct.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
udev.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/udev.c b/udev.c
index bc4722b0..066e6ab1 100644
--- a/udev.c
+++ b/udev.c
@@ -26,7 +26,10 @@
#include <signal.h>
#include <limits.h>
#include <syslog.h>
+
+#ifndef NO_LIBUDEV
#include <libudev.h>
+#endif
static char *unblock_path;
--
2.40.1

View File

@ -0,0 +1,29 @@
From 8bda86099089b44129ef6206764f9de47a45f0db Mon Sep 17 00:00:00 2001
From: Alexander Kanavin <alex@linutronix.de>
Date: Tue, 12 Mar 2024 11:01:50 +0100
Subject: [PATCH 36/41] util.c: add limits.h include for NAME_MAX definition
Add limits.h include for NAME_MAX definition.
Signed-off-by: Alexander Kanavin <alex@linutronix.de>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
util.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/util.c b/util.c
index 05ad3343..49a9c6e2 100644
--- a/util.c
+++ b/util.c
@@ -36,7 +36,7 @@
#include <ctype.h>
#include <dirent.h>
#include <dlfcn.h>
-
+#include <limits.h>
/*
* following taken from linux/blkpg.h because they aren't
--
2.40.1

View File

@ -0,0 +1,59 @@
From 1c8327950566449e206e613c11c8232032f26787 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Mon, 18 Mar 2024 16:19:29 +0100
Subject: [PATCH 37/41] mdadm: set swapuuid in all handlers
It is not set, so it should be 0 but it may vary on compilation
settings. Set it always to 0.
metadata should care to set UUID and read in proper endianness so it
doesn't follow super1 concept of swapuuid to depend on endianness.
It is not an attempt to fix endianness issues.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
super-ddf.c | 1 +
super-intel.c | 1 +
super0.c | 2 ++
3 files changed, 4 insertions(+)
diff --git a/super-ddf.c b/super-ddf.c
index 7571e3b7..94ac5ff3 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -5162,6 +5162,7 @@ struct superswitch super_ddf = {
.default_geometry = default_geometry_ddf,
.external = 1,
+ .swapuuid = 0,
/* for mdmon */
.open_new = ddf_open_new,
diff --git a/super-intel.c b/super-intel.c
index 77140455..e1754f29 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -13116,6 +13116,7 @@ struct superswitch super_imsm = {
.validate_ppl = validate_ppl_imsm,
.external = 1,
+ .swapuuid = 0,
.name = "imsm",
/* for mdmon */
diff --git a/super0.c b/super0.c
index a7c5f813..9b8a1bd6 100644
--- a/super0.c
+++ b/super0.c
@@ -1369,5 +1369,7 @@ struct superswitch super0 = {
.locate_bitmap = locate_bitmap0,
.write_bitmap = write_bitmap0,
.free_super = free_super0,
+
+ .swapuuid = 0,
.name = "0.90",
};
--
2.40.1

View File

@ -0,0 +1,247 @@
From ba65d917d121dfb9876053e6f62dbd4ebf2e028c Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Mon, 18 Mar 2024 16:19:30 +0100
Subject: [PATCH 38/41] mdadm: Fix native --detail --export
Mentioned commit (see Fixes) causes that UUID is not swapped as expected
for native superblock. Fix this problem.
For detail, we should avoid superblock calls, we can have information
about supertype from map, use that.
Simplify fname_from_uuid() by removing dependencies to metadata
handler, it is not needed. Decision is taken at compile time, expect
super1 but this function is not used by super1. Add warning about that.
Remove separator, it is always ':'.
Fixes: 60c19530dd7c ("Detail: remove duplicated code")
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Detail.c | 26 +++++++++++++++++++++++++-
mdadm.h | 3 +--
super-ddf.c | 10 +++++-----
super-intel.c | 16 ++++++++--------
util.c | 24 +++++++++++++-----------
5 files changed, 52 insertions(+), 27 deletions(-)
diff --git a/Detail.c b/Detail.c
index f23ec16f..55a086d3 100644
--- a/Detail.c
+++ b/Detail.c
@@ -49,6 +49,30 @@ static int add_device(const char *dev, char ***p_devices,
return n_devices + 1;
}
+/**
+ * detail_fname_from_uuid() - generate uuid string with special super1 handling.
+ * @mp: map entry to parse.
+ * @buf: buf to write.
+ *
+ * Hack to workaround an issue with super1 superblocks. It swapuuid set in order for assembly
+ * to work, but can't have it set if we want this printout to match all the other uuid printouts
+ * in super1.c, so we force swapuuid to 1 to make our printout match the rest of super1.
+ *
+ * Always convert uuid if host is big endian.
+ */
+char *detail_fname_from_uuid(struct map_ent *mp, char *buf)
+{
+#if __BYTE_ORDER == BIG_ENDIAN
+ bool swap = true;
+#else
+ bool swap = false;
+#endif
+ if (strncmp(mp->metadata, "1.", 2) == 0)
+ swap = true;
+
+ return __fname_from_uuid(mp->uuid, swap, buf, ':');
+}
+
int Detail(char *dev, struct context *c)
{
/*
@@ -256,7 +280,7 @@ int Detail(char *dev, struct context *c)
mp = map_by_devnm(&map, fd2devnm(fd));
if (mp) {
- __fname_from_uuid(mp->uuid, 0, nbuf, ':');
+ detail_fname_from_uuid(mp, nbuf);
printf("MD_UUID=%s\n", nbuf + 5);
if (mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0)
printf("MD_DEVNAME=%s\n", mp->path + DEV_MD_DIR_LEN);
diff --git a/mdadm.h b/mdadm.h
index 3fedca48..a363708a 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1696,8 +1696,7 @@ extern const int uuid_zero[4];
extern int same_uuid(int a[4], int b[4], int swapuuid);
extern void copy_uuid(void *a, int b[4], int swapuuid);
extern char *__fname_from_uuid(int id[4], int swap, char *buf, char sep);
-extern char *fname_from_uuid(struct supertype *st,
- struct mdinfo *info, char *buf, char sep);
+extern char *fname_from_uuid(struct mdinfo *info, char *buf);
extern unsigned long calc_csum(void *super, int bytes);
extern int enough(int level, int raid_disks, int layout, int clean,
char *avail);
diff --git a/super-ddf.c b/super-ddf.c
index 94ac5ff3..21426c75 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -1617,7 +1617,7 @@ static void brief_examine_super_ddf(struct supertype *st, int verbose)
struct mdinfo info;
char nbuf[64];
getinfo_super_ddf(st, &info, NULL);
- fname_from_uuid(st, &info, nbuf, ':');
+ fname_from_uuid(&info, nbuf);
printf("ARRAY metadata=ddf UUID=%s\n", nbuf + 5);
}
@@ -1632,7 +1632,7 @@ static void brief_examine_subarrays_ddf(struct supertype *st, int verbose)
unsigned int i;
char nbuf[64];
getinfo_super_ddf(st, &info, NULL);
- fname_from_uuid(st, &info, nbuf, ':');
+ fname_from_uuid(&info, nbuf);
for (i = 0; i < be16_to_cpu(ddf->virt->max_vdes); i++) {
struct virtual_entry *ve = &ddf->virt->entries[i];
@@ -1645,7 +1645,7 @@ static void brief_examine_subarrays_ddf(struct supertype *st, int verbose)
ddf->currentconf =&vcl;
vcl.vcnum = i;
uuid_from_super_ddf(st, info.uuid);
- fname_from_uuid(st, &info, nbuf1, ':');
+ fname_from_uuid(&info, nbuf1);
_ddf_array_name(namebuf, ddf, i);
printf("ARRAY%s%s container=%s member=%d UUID=%s\n",
namebuf[0] == '\0' ? "" : " " DEV_MD_DIR, namebuf,
@@ -1658,7 +1658,7 @@ static void export_examine_super_ddf(struct supertype *st)
struct mdinfo info;
char nbuf[64];
getinfo_super_ddf(st, &info, NULL);
- fname_from_uuid(st, &info, nbuf, ':');
+ fname_from_uuid(&info, nbuf);
printf("MD_METADATA=ddf\n");
printf("MD_LEVEL=container\n");
printf("MD_UUID=%s\n", nbuf+5);
@@ -1798,7 +1798,7 @@ static void brief_detail_super_ddf(struct supertype *st, char *subarray)
return;
else
uuid_of_ddf_subarray(ddf, vcnum, info.uuid);
- fname_from_uuid(st, &info, nbuf,':');
+ fname_from_uuid(&info, nbuf);
printf(" UUID=%s", nbuf + 5);
}
diff --git a/super-intel.c b/super-intel.c
index e1754f29..ff2590fe 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -2217,7 +2217,7 @@ static void examine_super_imsm(struct supertype *st, char *homehost)
else
printf("not supported\n");
getinfo_super_imsm(st, &info, NULL);
- fname_from_uuid(st, &info, nbuf, ':');
+ fname_from_uuid(&info, nbuf);
printf(" UUID : %s\n", nbuf + 5);
sum = __le32_to_cpu(mpb->check_sum);
printf(" Checksum : %08x %s\n", sum,
@@ -2242,7 +2242,7 @@ static void examine_super_imsm(struct supertype *st, char *homehost)
super->current_vol = i;
getinfo_super_imsm(st, &info, NULL);
- fname_from_uuid(st, &info, nbuf, ':');
+ fname_from_uuid(&info, nbuf);
print_imsm_dev(super, dev, nbuf + 5, super->disks->index);
}
for (i = 0; i < mpb->num_disks; i++) {
@@ -2267,7 +2267,7 @@ static void brief_examine_super_imsm(struct supertype *st, int verbose)
char nbuf[64];
getinfo_super_imsm(st, &info, NULL);
- fname_from_uuid(st, &info, nbuf, ':');
+ fname_from_uuid(&info, nbuf);
printf("ARRAY metadata=imsm UUID=%s\n", nbuf + 5);
}
@@ -2284,13 +2284,13 @@ static void brief_examine_subarrays_imsm(struct supertype *st, int verbose)
return;
getinfo_super_imsm(st, &info, NULL);
- fname_from_uuid(st, &info, nbuf, ':');
+ fname_from_uuid(&info, nbuf);
for (i = 0; i < super->anchor->num_raid_devs; i++) {
struct imsm_dev *dev = get_imsm_dev(super, i);
super->current_vol = i;
getinfo_super_imsm(st, &info, NULL);
- fname_from_uuid(st, &info, nbuf1, ':');
+ fname_from_uuid(&info, nbuf1);
printf("ARRAY " DEV_MD_DIR "%.16s container=%s member=%d UUID=%s\n",
dev->volume, nbuf + 5, i, nbuf1 + 5);
}
@@ -2304,7 +2304,7 @@ static void export_examine_super_imsm(struct supertype *st)
char nbuf[64];
getinfo_super_imsm(st, &info, NULL);
- fname_from_uuid(st, &info, nbuf, ':');
+ fname_from_uuid(&info, nbuf);
printf("MD_METADATA=imsm\n");
printf("MD_LEVEL=container\n");
printf("MD_UUID=%s\n", nbuf+5);
@@ -2324,7 +2324,7 @@ static void detail_super_imsm(struct supertype *st, char *homehost,
super->current_vol = strtoul(subarray, NULL, 10);
getinfo_super_imsm(st, &info, NULL);
- fname_from_uuid(st, &info, nbuf, ':');
+ fname_from_uuid(&info, nbuf);
printf("\n UUID : %s\n", nbuf + 5);
super->current_vol = temp_vol;
@@ -2341,7 +2341,7 @@ static void brief_detail_super_imsm(struct supertype *st, char *subarray)
super->current_vol = strtoul(subarray, NULL, 10);
getinfo_super_imsm(st, &info, NULL);
- fname_from_uuid(st, &info, nbuf, ':');
+ fname_from_uuid(&info, nbuf);
printf(" UUID=%s", nbuf + 5);
super->current_vol = temp_vol;
diff --git a/util.c b/util.c
index 49a9c6e2..03336d6f 100644
--- a/util.c
+++ b/util.c
@@ -589,19 +589,21 @@ char *__fname_from_uuid(int id[4], int swap, char *buf, char sep)
}
-char *fname_from_uuid(struct supertype *st, struct mdinfo *info,
- char *buf, char sep)
-{
- // dirty hack to work around an issue with super1 superblocks...
- // super1 superblocks need swapuuid set in order for assembly to
- // work, but can't have it set if we want this printout to match
- // all the other uuid printouts in super1.c, so we force swapuuid
- // to 1 to make our printout match the rest of super1
+/**
+ * fname_from_uuid() - generate uuid string. Should not be used with super1.
+ * @info: info with uuid
+ * @buf: buf to fill.
+ *
+ * This routine should not be used with super1. See detail_fname_from_uuid() for details. It does
+ * not use superswitch swapuuid as it should be 0 but it has to do UUID conversion if host is big
+ * endian- left for backward compatibility.
+ */
+char *fname_from_uuid(struct mdinfo *info, char *buf)
+{
#if __BYTE_ORDER == BIG_ENDIAN
- return __fname_from_uuid(info->uuid, 1, buf, sep);
+ return __fname_from_uuid(info->uuid, true, buf, ':');
#else
- return __fname_from_uuid(info->uuid, (st->ss == &super1) ? 1 :
- st->ss->swapuuid, buf, sep);
+ return __fname_from_uuid(info->uuid, false, buf, ':');
#endif
}
--
2.40.1

View File

@ -0,0 +1,87 @@
From de23e12a39cfc94575e1173293fe9e15337ee999 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Mon, 18 Mar 2024 16:53:31 +0100
Subject: [PATCH 39/41] sysfs: remove vers parameter from sysfs_set_array
9003 was passed directly to sysfs_set_array() since md_get_version()
always returned this value. md_get_version() was removed long ago.
Remove dead version check from sysfs_set_array().
Remove "vers" argument and fix function calls.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Assemble.c | 2 +-
mdadm.h | 2 +-
sysfs.c | 6 ++----
util.c | 3 +--
4 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index 9d042055..f6c5b99e 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1988,7 +1988,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
* and ignoring special character on the first place.
*/
if (strcmp(sra->text_version + 1, content->text_version + 1) != 0) {
- if (sysfs_set_array(content, 9003) != 0) {
+ if (sysfs_set_array(content) != 0) {
sysfs_free(sra);
return 1;
}
diff --git a/mdadm.h b/mdadm.h
index a363708a..ae2106a2 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -811,7 +811,7 @@ extern int sysfs_attribute_available(struct mdinfo *sra, struct mdinfo *dev,
extern int sysfs_get_str(struct mdinfo *sra, struct mdinfo *dev,
char *name, char *val, int size);
extern int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms);
-extern int sysfs_set_array(struct mdinfo *info, int vers);
+extern int sysfs_set_array(struct mdinfo *info);
extern int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume);
extern int sysfs_disk_to_scsi_id(int fd, __u32 *id);
extern int sysfs_unique_holder(char *devnm, long rdev);
diff --git a/sysfs.c b/sysfs.c
index 230b842e..4ded1672 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -678,7 +678,7 @@ int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms)
return sysfs_set_str(sra, NULL, "safe_mode_delay", delay);
}
-int sysfs_set_array(struct mdinfo *info, int vers)
+int sysfs_set_array(struct mdinfo *info)
{
int rv = 0;
char ver[100];
@@ -702,9 +702,7 @@ int sysfs_set_array(struct mdinfo *info, int vers)
if (strlen(buf) >= 9 && buf[9] == '-')
ver[9] = '-';
- if ((vers % 100) < 2 ||
- sysfs_set_str(info, NULL, "metadata_version",
- ver) < 0) {
+ if (sysfs_set_str(info, NULL, "metadata_version", ver) < 0) {
pr_err("This kernel does not support external metadata.\n");
return 1;
}
diff --git a/util.c b/util.c
index 03336d6f..9e837045 100644
--- a/util.c
+++ b/util.c
@@ -1867,8 +1867,7 @@ int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info)
int rv;
if (st->ss->external)
- return sysfs_set_array(info, 9003);
-
+ return sysfs_set_array(info);
memset(&inf, 0, sizeof(inf));
inf.major_version = info->array.major_version;
inf.minor_version = info->array.minor_version;
--
2.40.1

View File

@ -0,0 +1,55 @@
From ae996e81232b8ba991e763dfa15577a0af358358 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Mon, 18 Mar 2024 17:28:42 +0100
Subject: [PATCH 40/41] mdadm: fix grow segfault for IMSM
If sc is not initialized, there is possibility that sc.pols is not zeroed
and it causes segfault.
Add missing initialization.
Add missing dev_policy_free() in two places.
Fixes: f656201188d7 ("mdadm: drop get_required_spare_criteria()")
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Incremental.c | 1 +
super-intel.c | 9 +++++++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/Incremental.c b/Incremental.c
index 958ba9ba..83db0712 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -874,6 +874,7 @@ mdadm_status_t incremental_external_test_spare_criteria(struct supertype *st, ch
rv = MDADM_STATUS_SUCCESS;
out:
+ dev_policy_free(sc.pols);
dup->ss->free_super(dup);
free(dup);
diff --git a/super-intel.c b/super-intel.c
index ff2590fe..70f3c4ef 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -11518,10 +11518,15 @@ static int imsm_reshape_is_allowed_on_container(struct supertype *st,
*/
static struct mdinfo *get_spares_for_grow(struct supertype *st)
{
- struct spare_criteria sc;
+ struct spare_criteria sc = {0};
+ struct mdinfo *spares;
get_spare_criteria_imsm(st, NULL, &sc);
- return container_choose_spares(st, &sc, NULL, NULL, NULL, 0);
+ spares = container_choose_spares(st, &sc, NULL, NULL, NULL, 0);
+
+ dev_policy_free(sc.pols);
+
+ return spares;
}
/******************************************************************************
--
2.40.1

View File

@ -0,0 +1,85 @@
From da4d58b6d01ed8b0149b777eba7818861fde8c80 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Tue, 19 Mar 2024 11:15:29 +0100
Subject: [PATCH 41/41] Remove all "if zeros" pt.2
Commit e15e8b00cbce ("Remove all "if zeros"") did not remove all "if 0"
code blocks.
This commit is cleanup for that commit.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
Build.c | 6 ------
Grow.c | 13 +------------
super1.c | 11 -----------
3 files changed, 1 insertion(+), 29 deletions(-)
diff --git a/Build.c b/Build.c
index 1fbf8596..1be90e41 100644
--- a/Build.c
+++ b/Build.c
@@ -156,12 +156,6 @@ int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s,
bitmap_fd = open(s->bitmap_file, O_RDWR);
if (bitmap_fd < 0) {
int major = BITMAP_MAJOR_HI;
-#if 0
- if (s->bitmap_chunk == UnSet) {
- pr_err("%s cannot be opened.\n", s->bitmap_file);
- goto abort;
- }
-#endif
bitmapsize = s->size >> 9; /* FIXME wrong for RAID10 */
if (CreateBitmap(s->bitmap_file, 1, NULL,
s->bitmap_chunk, c->delay,
diff --git a/Grow.c b/Grow.c
index c69a342d..074f1995 100644
--- a/Grow.c
+++ b/Grow.c
@@ -4413,19 +4413,8 @@ static void validate(int afd, int bfd, unsigned long long offset)
lseek64(afd, __le64_to_cpu(bsb2.arraystart)*512, 0);
if ((unsigned long long)read(afd, abuf, len) != len)
fail("read first from array failed");
- if (memcmp(bbuf, abuf, len) != 0) {
-#if 0
- int i;
- printf("offset=%llu len=%llu\n",
- (unsigned long long)__le64_to_cpu(bsb2.arraystart)*512, len);
- for (i=0; i<len; i++)
- if (bbuf[i] != abuf[i]) {
- printf("first diff byte %d\n", i);
- break;
- }
-#endif
+ if (memcmp(bbuf, abuf, len) != 0)
fail("data1 compare failed");
- }
}
if (bsb2.length2) {
unsigned long long len = __le64_to_cpu(bsb2.length2)*512;
diff --git a/super1.c b/super1.c
index 5439b7bb..81d29a65 100644
--- a/super1.c
+++ b/super1.c
@@ -575,17 +575,6 @@ static void examine_super1(struct supertype *st, char *homehost)
inconsistent = 1;
}
}
-#if 0
- /* This is confusing too */
- faulty = 0;
- for (i = 0; i < __le32_to_cpu(sb->max_dev); i++) {
- int role = __le16_to_cpu(sb->dev_roles[i]);
- if (role == MD_DISK_ROLE_FAULTY)
- faulty++;
- }
- if (faulty)
- printf(" %d failed", faulty);
-#endif
printf(" ('A' == active, '.' == missing, 'R' == replacing)");
printf("\n");
for (d = 0; d < __le32_to_cpu(sb->max_dev); d++) {
--
2.40.1

View File

@ -0,0 +1,38 @@
From 7e92ef334af165a5e50b33ddff98e18f1c8a18d0 Mon Sep 17 00:00:00 2001
From: Xiao Ni <xni@redhat.com>
Date: Thu, 24 Feb 2022 11:37:34 +0800
Subject: [PATCH 1/1] Revert "mdadm: fix coredump of mdadm --monitor -r"
This reverts commit 546047688e1c64638f462147c755b58119cabdc8.
This is a rhel ony patch. We have sent patch to upstream. But
it hasn't been merged. We will remove this patch once upstream
merges our patch.
Signed-off-by: Xiao Ni <xni@redhat.com>
---
ReadMe.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/ReadMe.c b/ReadMe.c
index 81399765..ee457a54 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.31.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,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

View File

@ -1,122 +0,0 @@
From 9a7df595bbe360132cb37c8b39aa1fd9ac24b43f Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Tue, 21 Jun 2022 00:10:43 +0800
Subject: [PATCH 25/83] imsm: block changing slots during creation
If user specifies drives for array creation, then slot order across
volumes is not preserved.
Ideally, it should be checked in validate_geometry() but it is not
possible in current implementation (order is determined later).
Add verification in add_to_super_imsm_volume() and throw error if
mismatch is detected.
IMSM allows to use only same members within container.
This is not hardware dependency but metadata limitation.
Therefore, 09-imsm-overlap test is removed. Testing it is pointless.
After this patch, creation in this scenario is blocked. Offset
verification is covered in other tests.
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 | 33 ++++++++++++++++++++++-----------
tests/09imsm-overlap | 28 ----------------------------
2 files changed, 22 insertions(+), 39 deletions(-)
delete mode 100644 tests/09imsm-overlap
diff --git a/super-intel.c b/super-intel.c
index deef7c87..8ffe485c 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -5789,6 +5789,10 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
struct imsm_map *map;
struct dl *dl, *df;
int slot;
+ int autolayout = 0;
+
+ if (!is_fd_valid(fd))
+ autolayout = 1;
dev = get_imsm_dev(super, super->current_vol);
map = get_imsm_map(dev, MAP_0);
@@ -5799,25 +5803,32 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
return 1;
}
- if (!is_fd_valid(fd)) {
- /* we're doing autolayout so grab the pre-marked (in
- * validate_geometry) raid_disk
- */
- for (dl = super->disks; dl; dl = dl->next)
+ for (dl = super->disks; dl ; dl = dl->next) {
+ if (autolayout) {
if (dl->raiddisk == dk->raid_disk)
break;
- } else {
- for (dl = super->disks; dl ; dl = dl->next)
- if (dl->major == dk->major &&
- dl->minor == dk->minor)
- break;
+ } else if (dl->major == dk->major && dl->minor == dk->minor)
+ break;
}
if (!dl) {
- pr_err("%s is not a member of the same container\n", devname);
+ if (!autolayout)
+ pr_err("%s is not a member of the same container.\n",
+ devname);
return 1;
}
+ if (!autolayout && super->current_vol > 0) {
+ int _slot = get_disk_slot_in_dev(super, 0, dl->index);
+
+ if (_slot != dk->raid_disk) {
+ pr_err("Member %s is in %d slot for the first volume, but is in %d slot for a new volume.\n",
+ dl->devname, _slot, dk->raid_disk);
+ pr_err("Raid members are in different order than for the first volume, aborting.\n");
+ return 1;
+ }
+ }
+
if (mpb->num_disks == 0)
if (!get_dev_sector_size(dl->fd, dl->devname,
&super->sector_size))
diff --git a/tests/09imsm-overlap b/tests/09imsm-overlap
deleted file mode 100644
index ff5d2093..00000000
--- a/tests/09imsm-overlap
+++ /dev/null
@@ -1,28 +0,0 @@
-
-. tests/env-imsm-template
-
-# create raid arrays with varying degress of overlap
-mdadm -CR $container -e imsm -n 6 $dev0 $dev1 $dev2 $dev3 $dev4 $dev5
-imsm_check container 6
-
-size=1024
-level=1
-num_disks=2
-mdadm -CR $member0 $dev0 $dev1 -n $num_disks -l $level -z $size
-mdadm -CR $member1 $dev1 $dev2 -n $num_disks -l $level -z $size
-mdadm -CR $member2 $dev2 $dev3 -n $num_disks -l $level -z $size
-mdadm -CR $member3 $dev3 $dev4 -n $num_disks -l $level -z $size
-mdadm -CR $member4 $dev4 $dev5 -n $num_disks -l $level -z $size
-
-udevadm settle
-
-offset=0
-imsm_check member $member0 $num_disks $level $size 1024 $offset
-offset=$((offset+size+4096))
-imsm_check member $member1 $num_disks $level $size 1024 $offset
-offset=$((offset+size+4096))
-imsm_check member $member2 $num_disks $level $size 1024 $offset
-offset=$((offset+size+4096))
-imsm_check member $member3 $num_disks $level $size 1024 $offset
-offset=$((offset+size+4096))
-imsm_check member $member4 $num_disks $level $size 1024 $offset
--
2.38.1

View File

@ -1,177 +0,0 @@
From 70f1ff4291b0388adca1f4c91918ce1175e8b360 Mon Sep 17 00:00:00 2001
From: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Date: Wed, 15 Jun 2022 14:28:39 +0200
Subject: [PATCH 26/83] mdadm: block update=ppl for non raid456 levels
Option ppl should be used only for raid levels 4, 5 and 6. Cancel update
for other levels.
Applied globally for imsm and ddf format.
Additionally introduce is_level456() helper function.
Signed-off-by: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Assemble.c | 11 +++++------
Grow.c | 2 +-
Manage.c | 14 ++++++++++++--
mdadm.h | 11 +++++++++++
super0.c | 2 +-
super1.c | 3 +--
6 files changed, 31 insertions(+), 12 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index 4b213560..6df6bfbc 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -906,8 +906,7 @@ static int force_array(struct mdinfo *content,
* devices in RAID4 or last devices in RAID4/5/6.
*/
delta = devices[j].i.delta_disks;
- if (devices[j].i.array.level >= 4 &&
- devices[j].i.array.level <= 6 &&
+ if (is_level456(devices[j].i.array.level) &&
i/2 >= content->array.raid_disks - delta)
/* OK */;
else if (devices[j].i.array.level == 4 &&
@@ -1226,8 +1225,7 @@ static int start_array(int mdfd,
fprintf(stderr, ".\n");
}
if (content->reshape_active &&
- content->array.level >= 4 &&
- content->array.level <= 6) {
+ is_level456(content->array.level)) {
/* might need to increase the size
* of the stripe cache - default is 256
*/
@@ -1974,7 +1972,8 @@ int assemble_container_content(struct supertype *st, int mdfd,
int start_reshape;
char *avail;
int err;
- int is_raid456, is_clean, all_disks;
+ int is_clean, all_disks;
+ bool is_raid456;
if (sysfs_init(content, mdfd, NULL)) {
pr_err("Unable to initialize sysfs\n");
@@ -2107,7 +2106,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
content->array.state |= 1;
}
- is_raid456 = (content->array.level >= 4 && content->array.level <= 6);
+ is_raid456 = is_level456(content->array.level);
is_clean = content->array.state & 1;
if (enough(content->array.level, content->array.raid_disks,
diff --git a/Grow.c b/Grow.c
index f6efbc48..8c520d42 100644
--- a/Grow.c
+++ b/Grow.c
@@ -2944,7 +2944,7 @@ static int impose_level(int fd, int level, char *devname, int verbose)
}
md_get_array_info(fd, &array);
- if (level == 0 && (array.level >= 4 && array.level <= 6)) {
+ if (level == 0 && is_level456(array.level)) {
/* To convert to RAID0 we need to fail and
* remove any non-data devices. */
int found = 0;
diff --git a/Manage.c b/Manage.c
index f789e0c1..e5e6abe4 100644
--- a/Manage.c
+++ b/Manage.c
@@ -307,7 +307,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
* - unfreeze reshape
* - wait on 'sync_completed' for that point to be reached.
*/
- if (mdi && (mdi->array.level >= 4 && mdi->array.level <= 6) &&
+ if (mdi && is_level456(mdi->array.level) &&
sysfs_attribute_available(mdi, NULL, "sync_action") &&
sysfs_attribute_available(mdi, NULL, "reshape_direction") &&
sysfs_get_str(mdi, NULL, "sync_action", buf, 20) > 0 &&
@@ -1679,6 +1679,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident
{
struct supertype supertype, *st = &supertype;
int fd, rv = 2;
+ struct mdinfo *info = NULL;
memset(st, 0, sizeof(*st));
@@ -1696,6 +1697,13 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident
if (mdmon_running(st->devnm))
st->update_tail = &st->updates;
+ info = st->ss->container_content(st, subarray);
+
+ if (strncmp(update, "ppl", 3) == 0 && !is_level456(info->array.level)) {
+ pr_err("RWH policy ppl is supported only for raid4, raid5 and raid6.\n");
+ goto free_super;
+ }
+
rv = st->ss->update_subarray(st, subarray, update, ident);
if (rv) {
@@ -1711,7 +1719,9 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident
pr_err("Updated subarray-%s name from %s, UUIDs may have changed\n",
subarray, dev);
- free_super:
+free_super:
+ if (info)
+ free(info);
st->ss->free_super(st);
close(fd);
diff --git a/mdadm.h b/mdadm.h
index d53df169..974415b9 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -796,6 +796,17 @@ static inline int is_fd_valid(int fd)
return (fd > -1);
}
+/**
+ * is_level456() - check whether given level is between inclusive 4 and 6.
+ * @level: level to check.
+ *
+ * Return: true if condition is met, false otherwise
+ */
+static inline bool is_level456(int level)
+{
+ return (level >= 4 && level <= 6);
+}
+
/**
* close_fd() - verify, close and unset file descriptor.
* @fd: pointer to file descriptor.
diff --git a/super0.c b/super0.c
index 61c9ec1d..37f595ed 100644
--- a/super0.c
+++ b/super0.c
@@ -683,7 +683,7 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
int parity = sb->level == 6 ? 2 : 1;
rv = 0;
- if (sb->level >= 4 && sb->level <= 6 &&
+ if (is_level456(sb->level) &&
sb->reshape_position % (
sb->new_chunk/512 *
(sb->raid_disks - sb->delta_disks - parity))) {
diff --git a/super1.c b/super1.c
index 3a0c69fd..71af860c 100644
--- a/super1.c
+++ b/super1.c
@@ -1530,8 +1530,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
* So we reject a revert-reshape unless the
* alignment is good.
*/
- if (__le32_to_cpu(sb->level) >= 4 &&
- __le32_to_cpu(sb->level) <= 6) {
+ if (is_level456(__le32_to_cpu(sb->level))) {
reshape_sectors =
__le64_to_cpu(sb->reshape_position);
reshape_chunk = __le32_to_cpu(sb->new_chunk);
--
2.38.1

View File

@ -1,30 +0,0 @@
From 42e02e613fb0b4a2c0c0d984b9e6e2933875bb44 Mon Sep 17 00:00:00 2001
From: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Date: Fri, 22 Jul 2022 08:43:47 +0200
Subject: [PATCH 27/83] mdadm: Fix array size mismatch after grow
imsm_fix_size_mismatch() is invoked to fix the problem, but it couldn't
proceed due to migration check. This patch allows for intended behavior.
Signed-off-by: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-intel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/super-intel.c b/super-intel.c
index 8ffe485c..76b947f5 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -11854,7 +11854,7 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index)
unsigned long long d_size = imsm_dev_size(dev);
int u_size;
- if (calc_size == d_size || dev->vol.migr_type == MIGR_GEN_MIGR)
+ if (calc_size == d_size)
continue;
/* There is a difference, confirm that imsm_dev_size is
--
2.38.1

View File

@ -1,34 +0,0 @@
From 751757620afb25a4c02746bf8368a7b5f22352ec Mon Sep 17 00:00:00 2001
From: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Date: Fri, 22 Jul 2022 08:43:48 +0200
Subject: [PATCH 28/83] mdadm: Remove dead code in imsm_fix_size_mismatch
imsm_create_metadata_update_for_size_change() that returns u_size value
could return 0 in the past. As its behavior changed, and returned value
is always the size of imsm_update_size_change structure, check for
u_size is no longer needed.
Signed-off-by: Lukasz Florczak <lukasz.florczak@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super-intel.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/super-intel.c b/super-intel.c
index 76b947f5..4ddfcf94 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -11869,10 +11869,6 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index)
geo.size = d_size;
u_size = imsm_create_metadata_update_for_size_change(st, &geo,
&update);
- if (u_size < 1) {
- dprintf("imsm: Cannot prepare size change update\n");
- goto exit;
- }
imsm_update_metadata_locally(st, update, u_size);
if (st->update_tail) {
append_metadata_update(st, update, u_size);
--
2.38.1

View File

@ -1,40 +0,0 @@
From c8d1c398505b62d9129a4e711f17e4469f4327ff Mon Sep 17 00:00:00 2001
From: Kinga Tanska <kinga.tanska@intel.com>
Date: Thu, 14 Jul 2022 09:02:10 +0200
Subject: [PATCH 29/83] Monitor: use devname as char array instead of pointer
Device name wasn't filled properly due to incorrect use of strcpy.
Strcpy was used twice. Firstly to fill devname with "/dev/md/"
and then to add chosen name. First strcpy result was overwritten by
second one (as a result <device_name> instead of "/dev/md/<device_name>"
was assigned). This commit changes this implementation to use snprintf
and devname with fixed size.
Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/Monitor.c b/Monitor.c
index 6ca1ebe5..a5b11ae2 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -190,9 +190,11 @@ int Monitor(struct mddev_dev *devlist,
if (mdlist->devname[0] == '/')
st->devname = xstrdup(mdlist->devname);
else {
- st->devname = xmalloc(8+strlen(mdlist->devname)+1);
- strcpy(strcpy(st->devname, "/dev/md/"),
- mdlist->devname);
+ /* length of "/dev/md/" + device name + terminating byte */
+ size_t _len = sizeof("/dev/md/") + strnlen(mdlist->devname, PATH_MAX);
+
+ st->devname = xcalloc(_len, sizeof(char));
+ snprintf(st->devname, _len, "/dev/md/%s", mdlist->devname);
}
if (!is_mddev(mdlist->devname))
return 1;
--
2.38.1

View File

@ -1,133 +0,0 @@
From 84d969be8f6d8a345b75f558fad26e4f62a558f6 Mon Sep 17 00:00:00 2001
From: Kinga Tanska <kinga.tanska@intel.com>
Date: Thu, 14 Jul 2022 09:02:11 +0200
Subject: [PATCH 30/83] Monitor: use snprintf to fill device name
Safe string functions are propagated in Monitor.c.
Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 37 ++++++++++++++-----------------------
1 file changed, 14 insertions(+), 23 deletions(-)
diff --git a/Monitor.c b/Monitor.c
index a5b11ae2..93f36ac0 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -33,8 +33,8 @@
#endif
struct state {
- char *devname;
- char devnm[32]; /* to sync with mdstat info */
+ char devname[MD_NAME_MAX + sizeof("/dev/md/")]; /* length of "/dev/md/" + device name + terminating byte*/
+ char devnm[MD_NAME_MAX]; /* to sync with mdstat info */
unsigned int utime;
int err;
char *spare_group;
@@ -45,9 +45,9 @@ struct state {
int devstate[MAX_DISKS];
dev_t devid[MAX_DISKS];
int percent;
- char parent_devnm[32]; /* For subarray, devnm of parent.
- * For others, ""
- */
+ char parent_devnm[MD_NAME_MAX]; /* For subarray, devnm of parent.
+ * For others, ""
+ */
struct supertype *metadata;
struct state *subarray;/* for a container it is a link to first subarray
* for a subarray it is a link to next subarray
@@ -187,15 +187,8 @@ int Monitor(struct mddev_dev *devlist,
continue;
st = xcalloc(1, sizeof *st);
- if (mdlist->devname[0] == '/')
- st->devname = xstrdup(mdlist->devname);
- else {
- /* length of "/dev/md/" + device name + terminating byte */
- size_t _len = sizeof("/dev/md/") + strnlen(mdlist->devname, PATH_MAX);
-
- st->devname = xcalloc(_len, sizeof(char));
- snprintf(st->devname, _len, "/dev/md/%s", mdlist->devname);
- }
+ snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"),
+ "/dev/md/%s", basename(mdlist->devname));
if (!is_mddev(mdlist->devname))
return 1;
st->next = statelist;
@@ -218,7 +211,7 @@ int Monitor(struct mddev_dev *devlist,
st = xcalloc(1, sizeof *st);
mdlist = conf_get_ident(dv->devname);
- st->devname = xstrdup(dv->devname);
+ snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "%s", dv->devname);
st->next = statelist;
st->devnm[0] = 0;
st->percent = RESYNC_UNKNOWN;
@@ -301,7 +294,6 @@ int Monitor(struct mddev_dev *devlist,
for (stp = &statelist; (st = *stp) != NULL; ) {
if (st->from_auto && st->err > 5) {
*stp = st->next;
- free(st->devname);
free(st->spare_group);
free(st);
} else
@@ -554,7 +546,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
goto disappeared;
if (st->devnm[0] == 0)
- strcpy(st->devnm, fd2devnm(fd));
+ snprintf(st->devnm, MD_NAME_MAX, "%s", fd2devnm(fd));
for (mse2 = mdstat; mse2; mse2 = mse2->next)
if (strcmp(mse2->devnm, st->devnm) == 0) {
@@ -684,7 +676,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
strncmp(mse->metadata_version, "external:", 9) == 0 &&
is_subarray(mse->metadata_version+9)) {
char *sl;
- strcpy(st->parent_devnm, mse->metadata_version + 10);
+ snprintf(st->parent_devnm, MD_NAME_MAX, "%s", mse->metadata_version + 10);
sl = strchr(st->parent_devnm, '/');
if (sl)
*sl = 0;
@@ -772,14 +764,13 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
continue;
}
- st->devname = xstrdup(name);
+ snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "%s", name);
if ((fd = open(st->devname, O_RDONLY)) < 0 ||
md_get_array_info(fd, &array) < 0) {
/* no such array */
if (fd >= 0)
close(fd);
put_md_name(st->devname);
- free(st->devname);
if (st->metadata) {
st->metadata->ss->free_super(st->metadata);
free(st->metadata);
@@ -791,7 +782,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
st->next = *statelist;
st->err = 1;
st->from_auto = 1;
- strcpy(st->devnm, mse->devnm);
+ snprintf(st->devnm, MD_NAME_MAX, "%s", mse->devnm);
st->percent = RESYNC_UNKNOWN;
st->expected_spares = -1;
if (mse->metadata_version &&
@@ -799,8 +790,8 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
"external:", 9) == 0 &&
is_subarray(mse->metadata_version+9)) {
char *sl;
- strcpy(st->parent_devnm,
- mse->metadata_version+10);
+ snprintf(st->parent_devnm, MD_NAME_MAX,
+ "%s", mse->metadata_version + 10);
sl = strchr(st->parent_devnm, '/');
*sl = 0;
} else
--
2.38.1

View File

@ -1,42 +0,0 @@
From 14ae4c37bce9a53da08d59d6c2d7e0946e9c9f47 Mon Sep 17 00:00:00 2001
From: Logan Gunthorpe <logang@deltatee.com>
Date: Wed, 22 Jun 2022 14:25:06 -0600
Subject: [PATCH 31/83] Makefile: Don't build static build with everything and
everything-test
Running the test suite requires building everything, but it seems to be
difficult to build the static version of mdadm now seeing there
is no readily available static udev library.
The test suite doesn't need the static binary so just don't build it
with the everything or everything-test targets.
Leave the mdadm.static and install-static targets in place in case
someone still has a use case for the static binary.
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
---
Makefile | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index bf126033..ec1f99ed 100644
--- a/Makefile
+++ b/Makefile
@@ -182,9 +182,9 @@ check_rundir:
echo "***** or set CHECK_RUN_DIR=0"; exit 1; \
fi
-everything: all mdadm.static swap_super test_stripe raid6check \
+everything: all swap_super test_stripe raid6check \
mdadm.Os mdadm.O2 man
-everything-test: all mdadm.static swap_super test_stripe \
+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..
--
2.38.1

View File

@ -1,141 +0,0 @@
From 679bd9508a30b2a0a1baecc9a21dd6c7d8d8d7dc Mon Sep 17 00:00:00 2001
From: Logan Gunthorpe <logang@deltatee.com>
Date: Wed, 22 Jun 2022 14:25:07 -0600
Subject: [PATCH 32/83] DDF: Cleanup validate_geometry_ddf_container()
Move the function up so that the function declaration is not necessary
and remove the unused arguments to the function.
No functional changes are intended but will help with a bug fix in the
next patch.
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
---
super-ddf.c | 88 ++++++++++++++++++++++++-----------------------------
1 file changed, 39 insertions(+), 49 deletions(-)
diff --git a/super-ddf.c b/super-ddf.c
index abbc8b09..9d867f69 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -503,13 +503,6 @@ struct ddf_super {
static int load_super_ddf_all(struct supertype *st, int fd,
void **sbp, char *devname);
static int get_svd_state(const struct ddf_super *, const struct vcl *);
-static int
-validate_geometry_ddf_container(struct supertype *st,
- int level, int layout, int raiddisks,
- int chunk, unsigned long long size,
- unsigned long long data_offset,
- char *dev, unsigned long long *freesize,
- int verbose);
static int validate_geometry_ddf_bvd(struct supertype *st,
int level, int layout, int raiddisks,
@@ -3322,6 +3315,42 @@ static int reserve_space(struct supertype *st, int raiddisks,
return 1;
}
+static int
+validate_geometry_ddf_container(struct supertype *st,
+ int level, int raiddisks,
+ unsigned long long data_offset,
+ char *dev, unsigned long long *freesize,
+ int verbose)
+{
+ int fd;
+ unsigned long long ldsize;
+
+ if (level != LEVEL_CONTAINER)
+ return 0;
+ if (!dev)
+ return 1;
+
+ fd = dev_open(dev, O_RDONLY|O_EXCL);
+ if (fd < 0) {
+ if (verbose)
+ pr_err("ddf: Cannot open %s: %s\n",
+ dev, strerror(errno));
+ return 0;
+ }
+ if (!get_dev_size(fd, dev, &ldsize)) {
+ close(fd);
+ return 0;
+ }
+ close(fd);
+ if (freesize) {
+ *freesize = avail_size_ddf(st, ldsize >> 9, INVALID_SECTORS);
+ if (*freesize == 0)
+ return 0;
+ }
+
+ return 1;
+}
+
static int validate_geometry_ddf(struct supertype *st,
int level, int layout, int raiddisks,
int *chunk, unsigned long long size,
@@ -3347,11 +3376,9 @@ static int validate_geometry_ddf(struct supertype *st,
level = LEVEL_CONTAINER;
if (level == LEVEL_CONTAINER) {
/* Must be a fresh device to add to a container */
- return validate_geometry_ddf_container(st, level, layout,
- raiddisks, *chunk,
- size, data_offset, dev,
- freesize,
- verbose);
+ return validate_geometry_ddf_container(st, level, raiddisks,
+ data_offset, dev,
+ freesize, verbose);
}
if (!dev) {
@@ -3449,43 +3476,6 @@ static int validate_geometry_ddf(struct supertype *st,
return 1;
}
-static int
-validate_geometry_ddf_container(struct supertype *st,
- int level, int layout, int raiddisks,
- int chunk, unsigned long long size,
- unsigned long long data_offset,
- char *dev, unsigned long long *freesize,
- int verbose)
-{
- int fd;
- unsigned long long ldsize;
-
- if (level != LEVEL_CONTAINER)
- return 0;
- if (!dev)
- return 1;
-
- fd = dev_open(dev, O_RDONLY|O_EXCL);
- if (fd < 0) {
- if (verbose)
- pr_err("ddf: Cannot open %s: %s\n",
- dev, strerror(errno));
- return 0;
- }
- if (!get_dev_size(fd, dev, &ldsize)) {
- close(fd);
- return 0;
- }
- close(fd);
- if (freesize) {
- *freesize = avail_size_ddf(st, ldsize >> 9, INVALID_SECTORS);
- if (*freesize == 0)
- return 0;
- }
-
- return 1;
-}
-
static int validate_geometry_ddf_bvd(struct supertype *st,
int level, int layout, int raiddisks,
int *chunk, unsigned long long size,
--
2.38.1

View File

@ -1,49 +0,0 @@
From 2b93288a5650bb811932836f67f30d63c5ddcfbd Mon Sep 17 00:00:00 2001
From: Logan Gunthorpe <logang@deltatee.com>
Date: Wed, 22 Jun 2022 14:25:08 -0600
Subject: [PATCH 33/83] DDF: Fix NULL pointer dereference in
validate_geometry_ddf()
A relatively recent patch added a call to validate_geometry() in
Manage_add() that has level=LEVEL_CONTAINER and chunk=NULL.
This causes some ddf tests to segfault which aborts the test suite.
To fix this, avoid dereferencing chunk when the level is
LEVEL_CONTAINER or LEVEL_NONE.
Fixes: 1f5d54a06df0 ("Manage: Call validate_geometry when adding drive to external container")
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
---
super-ddf.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/super-ddf.c b/super-ddf.c
index 9d867f69..949e7d15 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -3369,9 +3369,6 @@ static int validate_geometry_ddf(struct supertype *st,
* If given BVDs, we make an SVD, changing all the GUIDs in the process.
*/
- if (*chunk == UnSet)
- *chunk = DEFAULT_CHUNK;
-
if (level == LEVEL_NONE)
level = LEVEL_CONTAINER;
if (level == LEVEL_CONTAINER) {
@@ -3381,6 +3378,9 @@ static int validate_geometry_ddf(struct supertype *st,
freesize, verbose);
}
+ if (*chunk == UnSet)
+ *chunk = DEFAULT_CHUNK;
+
if (!dev) {
mdu_array_info_t array = {
.level = level,
--
2.38.1

View File

@ -1,85 +0,0 @@
From 548e9b916f86c06e2cdb50d8f49633f9bec66c7e Mon Sep 17 00:00:00 2001
From: Logan Gunthorpe <logang@deltatee.com>
Date: Wed, 22 Jun 2022 14:25:09 -0600
Subject: [PATCH 34/83] mdadm/Grow: Fix use after close bug by closing after
fork
The test 07reshape-grow fails most of the time. But it succeeds around
1 in 5 times. When it does succeed, it causes the tests to die because
mdadm has segfaulted.
The segfault was caused by mdadm attempting to repoen a file
descriptor that was already closed. The backtrace of the segfault
was:
#0 __strncmp_avx2 () at ../sysdeps/x86_64/multiarch/strcmp-avx2.S:101
#1 0x000056146e31d44b in devnm2devid (devnm=0x0) at util.c:956
#2 0x000056146e31dab4 in open_dev_flags (devnm=0x0, flags=0)
at util.c:1072
#3 0x000056146e31db22 in open_dev (devnm=0x0) at util.c:1079
#4 0x000056146e3202e8 in reopen_mddev (mdfd=4) at util.c:2244
#5 0x000056146e329f36 in start_array (mdfd=4,
mddev=0x7ffc55342450 "/dev/md0", content=0x7ffc55342860,
st=0x56146fc78660, ident=0x7ffc55342f70, best=0x56146fc6f5d0,
bestcnt=10, chosen_drive=0, devices=0x56146fc706b0, okcnt=5,
sparecnt=0, rebuilding_cnt=0, journalcnt=0, c=0x7ffc55342e90,
clean=1, avail=0x56146fc78720 "\001\001\001\001\001",
start_partial_ok=0, err_ok=0, was_forced=0)
at Assemble.c:1206
#6 0x000056146e32c36e in Assemble (st=0x56146fc78660,
mddev=0x7ffc55342450 "/dev/md0", ident=0x7ffc55342f70,
devlist=0x56146fc6e2d0, c=0x7ffc55342e90)
at Assemble.c:1914
#7 0x000056146e312ac9 in main (argc=11, argv=0x7ffc55343238)
at mdadm.c:1510
The file descriptor was closed early in Grow_continue(). The noted commit
moved the close() call to close the fd above the fork which caused the
parent process to return with a closed fd.
This meant reshape_array() and Grow_continue() would return in the parent
with the fd forked. The fd would eventually be passed to reopen_mddev()
which returned an unhandled NULL from fd2devnm() which would then be
dereferenced in devnm2devid.
Fix this by moving the close() call below the fork. This appears to
fix the 07revert-grow test. While we're at it, switch to using
close_fd() to invalidate the file descriptor.
Fixes: 77b72fa82813 ("mdadm/Grow: prevent md's fd from being occupied during delayed time")
Cc: Alex Wu <alexwu@synology.com>
Cc: BingJing Chang <bingjingc@synology.com>
Cc: Danny Shih <dannyshih@synology.com>
Cc: ChangSyun Peng <allenpeng@synology.com>
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
---
Grow.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Grow.c b/Grow.c
index 8c520d42..97f22c75 100644
--- a/Grow.c
+++ b/Grow.c
@@ -3514,7 +3514,6 @@ started:
return 0;
}
- close(fd);
/* 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.
@@ -3535,6 +3534,9 @@ started:
break;
}
+ /* Close unused file descriptor in the forked process */
+ close_fd(&fd);
+
/* If another array on the same devices is busy, the
* reshape will wait for them. This would mean that
* the first section that we suspend will stay suspended
--
2.38.1

View File

@ -1,36 +0,0 @@
From 9ae62977b51dab0f4bb46b1c8ea5ebd1705b2f4d Mon Sep 17 00:00:00 2001
From: Logan Gunthorpe <logang@deltatee.com>
Date: Wed, 22 Jun 2022 14:25:10 -0600
Subject: [PATCH 35/83] monitor: Avoid segfault when calling NULL
get_bad_blocks
Not all struct superswitch implement a get_bad_blocks() function,
yet mdmon seems to call it without checking for NULL and thus
occasionally segfaults in the test 10ddf-geometry.
Fix this by checking for NULL before calling it.
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
---
monitor.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/monitor.c b/monitor.c
index b877e595..820a93d0 100644
--- a/monitor.c
+++ b/monitor.c
@@ -311,6 +311,9 @@ static int check_for_cleared_bb(struct active_array *a, struct mdinfo *mdi)
struct md_bb *bb;
int i;
+ if (!ss->get_bad_blocks)
+ return -1;
+
/*
* Get a list of bad blocks for an array, then read list of
* acknowledged bad blocks from kernel and compare it against metadata
--
2.38.1

View File

@ -1,78 +0,0 @@
From 6c9d9260633f2c8491985b0782cf0fbd7e51651b Mon Sep 17 00:00:00 2001
From: Logan Gunthorpe <logang@deltatee.com>
Date: Wed, 22 Jun 2022 14:25:11 -0600
Subject: [PATCH 36/83] mdadm: Fix mdadm -r remove option regression
The commit noted below globally adds a parameter to the -r option but missed
the fact that -r is used for another purpose: --remove.
After that commit, a command such as:
mdadm /dev/md0 -r /dev/loop0
will do nothing seeing the device parameter will be consumed as a
argument to the -r option; thus, there will only be one device
seen one the command line, devs_found will only be 1 and nothing will
happen.
This caused the 01r5integ and 01raid6integ tests to hang indefinitely
as mdadm did not remove the failed device. With the device not removed,
it would not be readded. Then the loop waiting for the array status to
change would loop forever.
This commit was recently reverted, but the legitimate fix for the
monitor operations was still not fixed. So add specific monitor
short ops to re-fix the --monitor -r option.
Fixes: 546047688e1c ("mdadm: fix coredump of mdadm --monitor -r")
Fixes: 190dc029b141 ("Revert "mdadm: fix coredump of mdadm --monitor -r"")
Cc: Wu Guanghao <wuguanghao3@huawei.com>
Cc: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
---
ReadMe.c | 1 +
mdadm.c | 1 +
mdadm.h | 1 +
3 files changed, 3 insertions(+)
diff --git a/ReadMe.c b/ReadMe.c
index bec1be9a..7518a32a 100644
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -82,6 +82,7 @@ char Version[] = "mdadm - v" VERSION " - " VERS_DATE EXTRAVERSION "\n";
*/
char short_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:";
+char short_monitor_options[]="-ABCDEFGIQhVXYWZ:vqbc:i:l:p:m:r:n:x:u:c:d:z:U:N:safRSow1tye:k:";
char short_bitmap_options[]=
"-ABCDEFGIQhVXYWZ:vqb:c:i:l:p:m:n:x:u:c:d:z:U:N:sarfRSow1tye:k:";
char short_bitmap_auto_options[]=
diff --git a/mdadm.c b/mdadm.c
index be40686c..d0c5e6de 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -227,6 +227,7 @@ int main(int argc, char *argv[])
shortopt = short_bitmap_auto_options;
break;
case 'F': newmode = MONITOR;
+ shortopt = short_monitor_options;
break;
case 'G': newmode = GROW;
shortopt = short_bitmap_options;
diff --git a/mdadm.h b/mdadm.h
index 974415b9..163f4a49 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -419,6 +419,7 @@ enum mode {
};
extern char short_options[];
+extern char short_monitor_options[];
extern char short_bitmap_options[];
extern char short_bitmap_auto_options[];
extern struct option long_options[];
--
2.38.1

View File

@ -1,42 +0,0 @@
From 41edf6f45895193f4a523cb0a08d639c9ff9ccc9 Mon Sep 17 00:00:00 2001
From: Logan Gunthorpe <logang@deltatee.com>
Date: Wed, 22 Jun 2022 14:25:12 -0600
Subject: [PATCH 37/83] mdadm: Fix optional --write-behind parameter
The commit noted below changed the behaviour of --write-behind to
require an argument. This broke the 06wrmostly test with the error:
mdadm: Invalid value for maximum outstanding write-behind writes: (null).
Must be between 0 and 16383.
To fix this, check if optarg is NULL before parising it, as the origial
code did.
Fixes: 60815698c0ac ("Refactor parse_num and use it to parse optarg.")
Cc: Mateusz Grzonka <mateusz.grzonka@intel.com>
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
---
mdadm.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/mdadm.c b/mdadm.c
index d0c5e6de..56722ed9 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -1201,8 +1201,9 @@ int main(int argc, char *argv[])
case O(BUILD, WriteBehind):
case O(CREATE, WriteBehind):
s.write_behind = DEFAULT_MAX_WRITE_BEHIND;
- if (parse_num(&s.write_behind, optarg) != 0 ||
- s.write_behind < 0 || s.write_behind > 16383) {
+ if (optarg &&
+ (parse_num(&s.write_behind, optarg) != 0 ||
+ s.write_behind < 0 || s.write_behind > 16383)) {
pr_err("Invalid value for maximum outstanding write-behind writes: %s.\n\tMust be between 0 and 16383.\n",
optarg);
exit(2);
--
2.38.1

View File

@ -1,38 +0,0 @@
From 7539254342bc591717b0051734cc6c09c1b88640 Mon Sep 17 00:00:00 2001
From: Sudhakar Panneerselvam <sudhakar.panneerselvam@oracle.com>
Date: Wed, 22 Jun 2022 14:25:13 -0600
Subject: [PATCH 38/83] tests/00raid0: add a test that validates raid0 with
layout fails for 0.9
329dfc28debb disallows the creation of raid0 with layouts for 0.9
metadata. This test confirms the new behavior.
Signed-off-by: Sudhakar Panneerselvam <sudhakar.panneerselvam@oracle.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
---
tests/00raid0 | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/tests/00raid0 b/tests/00raid0
index 8bc18985..e6b21cc4 100644
--- a/tests/00raid0
+++ b/tests/00raid0
@@ -6,11 +6,9 @@ check raid0
testdev $md0 3 $mdsize2_l 512
mdadm -S $md0
-# now with version-0.90 superblock
+# verify raid0 with layouts fail for 0.90
mdadm -CR $md0 -e0.90 -l0 -n4 $dev0 $dev1 $dev2 $dev3
-check raid0
-testdev $md0 4 $mdsize0 512
-mdadm -S $md0
+check opposite_result
# now with no superblock
mdadm -B $md0 -l0 -n5 $dev0 $dev1 $dev2 $dev3 $dev4
--
2.38.1

View File

@ -1,99 +0,0 @@
From 14c2161edb77d7294199e8aa7daa9f9d1d0ad5d7 Mon Sep 17 00:00:00 2001
From: Sudhakar Panneerselvam <sudhakar.panneerselvam@oracle.com>
Date: Wed, 22 Jun 2022 14:25:14 -0600
Subject: [PATCH 39/83] tests: fix raid0 tests for 0.90 metadata
Some of the test cases fail because raid0 creation fails with the error,
"0.90 metadata does not support layouts for RAID0" added by commit,
329dfc28debb. Fix some of the test cases by switching from raid0 to
linear level for 0.9 metadata where possible.
Signed-off-by: Sudhakar Panneerselvam <sudhakar.panneerselvam@oracle.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
---
tests/00raid0 | 4 ++--
tests/00readonly | 4 ++++
tests/03r0assem | 6 +++---
tests/04r0update | 4 ++--
tests/04update-metadata | 2 +-
5 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/tests/00raid0 b/tests/00raid0
index e6b21cc4..9b8896cb 100644
--- a/tests/00raid0
+++ b/tests/00raid0
@@ -20,8 +20,8 @@ mdadm -S $md0
# now same again with different chunk size
for chunk in 4 32 256
do
- mdadm -CR $md0 -e0.90 -l raid0 --chunk $chunk -n3 $dev0 $dev1 $dev2
- check raid0
+ mdadm -CR $md0 -e0.90 -l linear --chunk $chunk -n3 $dev0 $dev1 $dev2
+ check linear
testdev $md0 3 $mdsize0 $chunk
mdadm -S $md0
diff --git a/tests/00readonly b/tests/00readonly
index 28b0fa13..39202487 100644
--- a/tests/00readonly
+++ b/tests/00readonly
@@ -4,6 +4,10 @@ for metadata in 0.9 1.0 1.1 1.2
do
for level in linear raid0 raid1 raid4 raid5 raid6 raid10
do
+ if [[ $metadata == "0.9" && $level == "raid0" ]];
+ then
+ continue
+ fi
mdadm -CR $md0 -l $level -n 4 --metadata=$metadata \
$dev1 $dev2 $dev3 $dev4 --assume-clean
check nosync
diff --git a/tests/03r0assem b/tests/03r0assem
index 6744e322..44df0645 100644
--- a/tests/03r0assem
+++ b/tests/03r0assem
@@ -68,9 +68,9 @@ mdadm -S $md2
### Now for version 0...
mdadm --zero-superblock $dev0 $dev1 $dev2
-mdadm -CR $md2 -l0 --metadata=0.90 -n3 $dev0 $dev1 $dev2
-check raid0
-tst="testdev $md2 3 $mdsize0 512"
+mdadm -CR $md2 -llinear --metadata=0.90 -n3 $dev0 $dev1 $dev2
+check linear
+tst="testdev $md2 3 $mdsize0 1"
$tst
uuid=`mdadm -Db $md2 | sed 's/.*UUID=//'`
diff --git a/tests/04r0update b/tests/04r0update
index 73ee3b9f..b95efb06 100644
--- a/tests/04r0update
+++ b/tests/04r0update
@@ -1,7 +1,7 @@
# create a raid0, re-assemble with a different super-minor
-mdadm -CR -e 0.90 $md0 -l0 -n3 $dev0 $dev1 $dev2
-testdev $md0 3 $mdsize0 512
+mdadm -CR -e 0.90 $md0 -llinear -n3 $dev0 $dev1 $dev2
+testdev $md0 3 $mdsize0 1
minor1=`mdadm -E $dev0 | sed -n -e 's/.*Preferred Minor : //p'`
mdadm -S /dev/md0
diff --git a/tests/04update-metadata b/tests/04update-metadata
index 232fc1ff..08c14af7 100644
--- a/tests/04update-metadata
+++ b/tests/04update-metadata
@@ -8,7 +8,7 @@ set -xe
dlist="$dev0 $dev1 $dev2 $dev3"
-for ls in raid0/4 linear/4 raid1/1 raid5/3 raid6/2
+for ls in linear/4 raid1/1 raid5/3 raid6/2
do
s=${ls#*/} l=${ls%/*}
mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 -c 64 $dlist
--
2.38.1

View File

@ -1,39 +0,0 @@
From de045db607b1ac4b70fc2a8878463e029c2ab1dc Mon Sep 17 00:00:00 2001
From: Sudhakar Panneerselvam <sudhakar.panneerselvam@oracle.com>
Date: Wed, 22 Jun 2022 14:25:15 -0600
Subject: [PATCH 40/83] tests/04update-metadata: avoid passing chunk size to
raid1
'04update-metadata' test fails with error, "specifying chunk size is
forbidden for this level" added by commit, 5b30a34aa4b5e. Hence,
correcting the test to ignore passing chunk size to raid1.
Signed-off-by: Sudhakar Panneerselvam <sudhakar.panneerselvam@oracle.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@oracle.com>
[logang@deltatee.com: fix if/then style and dropped unrelated hunk]
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
---
tests/04update-metadata | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/tests/04update-metadata b/tests/04update-metadata
index 08c14af7..2b72a303 100644
--- a/tests/04update-metadata
+++ b/tests/04update-metadata
@@ -11,7 +11,11 @@ dlist="$dev0 $dev1 $dev2 $dev3"
for ls in linear/4 raid1/1 raid5/3 raid6/2
do
s=${ls#*/} l=${ls%/*}
- mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 -c 64 $dlist
+ if [[ $l == 'raid1' ]]; then
+ mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 $dlist
+ else
+ mdadm -CR --assume-clean -e 0.90 $md0 --level $l -n 4 -c 64 $dlist
+ fi
testdev $md0 $s 19904 64
mdadm -S $md0
mdadm -A $md0 --update=metadata $dlist
--
2.38.1

View File

@ -1,31 +0,0 @@
From a2c832465fc75202e244327b2081231dfa974617 Mon Sep 17 00:00:00 2001
From: Sudhakar Panneerselvam <sudhakar.panneerselvam@oracle.com>
Date: Wed, 22 Jun 2022 14:25:16 -0600
Subject: [PATCH 41/83] tests/02lineargrow: clear the superblock at every
iteration
This fixes 02lineargrow test as prior metadata causes --add operation
to misbehave.
Signed-off-by: Sudhakar Panneerselvam <sudhakar.panneerselvam@oracle.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
---
tests/02lineargrow | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tests/02lineargrow b/tests/02lineargrow
index e05c219d..595bf9f2 100644
--- a/tests/02lineargrow
+++ b/tests/02lineargrow
@@ -20,4 +20,6 @@ do
testdev $md0 3 $sz 1
mdadm -S $md0
+ mdadm --zero /dev/loop2
+ mdadm --zero /dev/loop3
done
--
2.38.1

View File

@ -1,88 +0,0 @@
From a7bfcc716e235664dfb3b6c5a9590273e611ac72 Mon Sep 17 00:00:00 2001
From: Logan Gunthorpe <logang@deltatee.com>
Date: Wed, 22 Jun 2022 14:25:17 -0600
Subject: [PATCH 42/83] mdadm/test: Add a mode to repeat specified tests
Many tests fail infrequently or rarely. To help find these, add
an option to run the tests multiple times by specifying --loop=N.
If --loop=0 is specified, the test will be looped forever.
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
---
test | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/test b/test
index 711a3c7a..da6db5e0 100755
--- a/test
+++ b/test
@@ -10,6 +10,7 @@ devlist=
savelogs=0
exitonerror=1
+loop=1
prefix='[0-9][0-9]'
# use loop devices by default if doesn't specify --dev
@@ -117,6 +118,7 @@ do_help() {
--logdir=directory Directory to save all logfiles in
--save-logs Usually use with --logdir together
--keep-going | --no-error Don't stop on error, ie. run all tests
+ --loop=N Run tests N times (0 to run forever)
--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
@@ -211,6 +213,9 @@ parse_args() {
--keep-going | --no-error )
exitonerror=0
;;
+ --loop=* )
+ loop="${i##*=}"
+ ;;
--disable-multipath )
unset MULTIPATH
;;
@@ -263,19 +268,26 @@ main() {
echo "Testing on linux-$(uname -r) kernel"
[ "$savelogs" == "1" ] &&
echo "Saving logs to $logdir"
- if [ "x$TESTLIST" != "x" ]
- then
- for script in ${TESTLIST[@]}
- do
- do_test $testdir/$script
- done
- else
- for script in $testdir/$prefix $testdir/$prefix*[^~]
- do
- do_test $script
- done
- fi
+ while true; do
+ if [ "x$TESTLIST" != "x" ]
+ then
+ for script in ${TESTLIST[@]}
+ do
+ do_test $testdir/$script
+ done
+ else
+ for script in $testdir/$prefix $testdir/$prefix*[^~]
+ do
+ do_test $script
+ done
+ fi
+
+ let loop=$loop-1
+ if [ "$loop" == "0" ]; then
+ break
+ fi
+ done
exit 0
}
--
2.38.1

View File

@ -1,120 +0,0 @@
From 28520bf114b3b0515a48ff44fff4ecbe9ed6dfad Mon Sep 17 00:00:00 2001
From: Logan Gunthorpe <logang@deltatee.com>
Date: Wed, 22 Jun 2022 14:25:18 -0600
Subject: [PATCH 43/83] mdadm/test: Mark and ignore broken test failures
Add functionality to continue if a test marked as broken fails.
To mark a test as broken, a file with the same name but with the suffix
'.broken' should exist. The first line in the file will be printed with
a KNOWN BROKEN message; the rest of the file can describe the how the
test is broken.
Also adds --skip-broken and --skip-always-broken to skip all the tests
that have a .broken file or to skip all tests whose .broken file's first
line contains the keyword always.
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
---
test | 37 +++++++++++++++++++++++++++++++++++--
1 file changed, 35 insertions(+), 2 deletions(-)
diff --git a/test b/test
index da6db5e0..61d9ee83 100755
--- a/test
+++ b/test
@@ -10,6 +10,8 @@ devlist=
savelogs=0
exitonerror=1
+ctrl_c_error=0
+skipbroken=0
loop=1
prefix='[0-9][0-9]'
@@ -36,6 +38,7 @@ die() {
ctrl_c() {
exitonerror=1
+ ctrl_c_error=1
}
# mdadm always adds --quiet, and we want to see any unexpected messages
@@ -80,8 +83,21 @@ mdadm() {
do_test() {
_script=$1
_basename=`basename $_script`
+ _broken=0
+
if [ -f "$_script" ]
then
+ if [ -f "${_script}.broken" ]; then
+ _broken=1
+ _broken_msg=$(head -n1 "${_script}.broken" | tr -d '\n')
+ if [ "$skipbroken" == "all" ]; then
+ return
+ elif [ "$skipbroken" == "always" ] &&
+ [[ "$_broken_msg" == *always* ]]; then
+ return
+ fi
+ fi
+
rm -f $targetdir/stderr
# this might have been reset: restore the default.
echo 2000 > /proc/sys/dev/raid/speed_limit_max
@@ -98,10 +114,15 @@ do_test() {
else
save_log fail
_fail=1
+ if [ "$_broken" == "1" ]; then
+ echo " (KNOWN BROKEN TEST: $_broken_msg)"
+ fi
fi
[ "$savelogs" == "1" ] &&
mv -f $targetdir/log $logdir/$_basename.log
- [ "$_fail" == "1" -a "$exitonerror" == "1" ] && exit 1
+ [ "$ctrl_c_error" == "1" ] && exit 1
+ [ "$_fail" == "1" -a "$exitonerror" == "1" \
+ -a "$_broken" == "0" ] && exit 1
fi
}
@@ -119,6 +140,8 @@ do_help() {
--save-logs Usually use with --logdir together
--keep-going | --no-error Don't stop on error, ie. run all tests
--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
--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
@@ -216,6 +239,12 @@ parse_args() {
--loop=* )
loop="${i##*=}"
;;
+ --skip-broken )
+ skipbroken=all
+ ;;
+ --skip-always-broken )
+ skipbroken=always
+ ;;
--disable-multipath )
unset MULTIPATH
;;
@@ -279,7 +308,11 @@ main() {
else
for script in $testdir/$prefix $testdir/$prefix*[^~]
do
- do_test $script
+ case $script in
+ *.broken) ;;
+ *)
+ do_test $script
+ esac
done
fi
--
2.38.1

View File

@ -1,447 +0,0 @@
From daa86d6634761796ada1f535c13e47fdd3cc95eb Mon Sep 17 00:00:00 2001
From: Logan Gunthorpe <logang@deltatee.com>
Date: Wed, 22 Jun 2022 14:25:19 -0600
Subject: [PATCH 44/83] tests: Add broken files for all broken tests
Each broken file contains the rough frequency of brokeness as well
as a brief explanation of what happens when it breaks. Estimates
of failure rates are not statistically significant and can vary
run to run.
This is really just a view from my window. Tests were done on a
small VM with the default loop devices, not real hardware. We've
seen different kernel configurations can cause bugs to appear as well
(ie. different block schedulers). It may also be that different race
conditions will be seen on machines with different performance
characteristics.
These annotations were done with the kernel currently in md/md-next:
facef3b96c5b ("md: Notify sysfs sync_completed in md_reap_sync_thread()")
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
---
tests/01r5integ.broken | 7 ++++
tests/01raid6integ.broken | 7 ++++
tests/04r5swap.broken | 7 ++++
tests/07autoassemble.broken | 8 ++++
tests/07autodetect.broken | 5 +++
tests/07changelevelintr.broken | 9 +++++
tests/07changelevels.broken | 9 +++++
tests/07reshape5intr.broken | 45 ++++++++++++++++++++++
tests/07revert-grow.broken | 31 +++++++++++++++
tests/07revert-shrink.broken | 9 +++++
tests/07testreshape5.broken | 12 ++++++
tests/09imsm-assemble.broken | 6 +++
tests/09imsm-create-fail-rebuild.broken | 5 +++
tests/09imsm-overlap.broken | 7 ++++
tests/10ddf-assemble-missing.broken | 6 +++
tests/10ddf-fail-create-race.broken | 7 ++++
tests/10ddf-fail-two-spares.broken | 5 +++
tests/10ddf-incremental-wrong-order.broken | 9 +++++
tests/14imsm-r1_2d-grow-r1_3d.broken | 5 +++
tests/14imsm-r1_2d-takeover-r0_2d.broken | 6 +++
tests/18imsm-r10_4d-takeover-r0_2d.broken | 5 +++
tests/18imsm-r1_2d-takeover-r0_1d.broken | 6 +++
tests/19raid6auto-repair.broken | 5 +++
tests/19raid6repair.broken | 5 +++
24 files changed, 226 insertions(+)
create mode 100644 tests/01r5integ.broken
create mode 100644 tests/01raid6integ.broken
create mode 100644 tests/04r5swap.broken
create mode 100644 tests/07autoassemble.broken
create mode 100644 tests/07autodetect.broken
create mode 100644 tests/07changelevelintr.broken
create mode 100644 tests/07changelevels.broken
create mode 100644 tests/07reshape5intr.broken
create mode 100644 tests/07revert-grow.broken
create mode 100644 tests/07revert-shrink.broken
create mode 100644 tests/07testreshape5.broken
create mode 100644 tests/09imsm-assemble.broken
create mode 100644 tests/09imsm-create-fail-rebuild.broken
create mode 100644 tests/09imsm-overlap.broken
create mode 100644 tests/10ddf-assemble-missing.broken
create mode 100644 tests/10ddf-fail-create-race.broken
create mode 100644 tests/10ddf-fail-two-spares.broken
create mode 100644 tests/10ddf-incremental-wrong-order.broken
create mode 100644 tests/14imsm-r1_2d-grow-r1_3d.broken
create mode 100644 tests/14imsm-r1_2d-takeover-r0_2d.broken
create mode 100644 tests/18imsm-r10_4d-takeover-r0_2d.broken
create mode 100644 tests/18imsm-r1_2d-takeover-r0_1d.broken
create mode 100644 tests/19raid6auto-repair.broken
create mode 100644 tests/19raid6repair.broken
diff --git a/tests/01r5integ.broken b/tests/01r5integ.broken
new file mode 100644
index 00000000..20737637
--- /dev/null
+++ b/tests/01r5integ.broken
@@ -0,0 +1,7 @@
+fails rarely
+
+Fails about 1 in every 30 runs with a sha mismatch error:
+
+ c49ab26e1b01def7874af9b8a6d6d0c29fdfafe6 /dev/md0 does not match
+ 15dc2f73262f811ada53c65e505ceec9cf025cb9 /dev/md0 with /dev/loop3
+ missing
diff --git a/tests/01raid6integ.broken b/tests/01raid6integ.broken
new file mode 100644
index 00000000..1df735f0
--- /dev/null
+++ b/tests/01raid6integ.broken
@@ -0,0 +1,7 @@
+fails infrequently
+
+Fails about 1 in 5 with a sha mismatch:
+
+ 8286c2bc045ae2cfe9f8b7ae3a898fa25db6926f /dev/md0 does not match
+ a083a0738b58caab37fd568b91b177035ded37df /dev/md0 with /dev/loop2 and
+ /dev/loop3 missing
diff --git a/tests/04r5swap.broken b/tests/04r5swap.broken
new file mode 100644
index 00000000..e38987db
--- /dev/null
+++ b/tests/04r5swap.broken
@@ -0,0 +1,7 @@
+always fails
+
+Fails with errors:
+
+ mdadm: /dev/loop0 has no superblock - assembly aborted
+
+ ERROR: no recovery happening
diff --git a/tests/07autoassemble.broken b/tests/07autoassemble.broken
new file mode 100644
index 00000000..8be09407
--- /dev/null
+++ b/tests/07autoassemble.broken
@@ -0,0 +1,8 @@
+always fails
+
+Prints lots of messages, but the array doesn't assemble. Error
+possibly related to:
+
+ mdadm: /dev/md/1 is busy - skipping
+ mdadm: no recogniseable superblock on /dev/md/testing:0
+ mdadm: /dev/md/2 is busy - skipping
diff --git a/tests/07autodetect.broken b/tests/07autodetect.broken
new file mode 100644
index 00000000..294954a1
--- /dev/null
+++ b/tests/07autodetect.broken
@@ -0,0 +1,5 @@
+always fails
+
+Fails with error:
+
+ ERROR: no resync happening
diff --git a/tests/07changelevelintr.broken b/tests/07changelevelintr.broken
new file mode 100644
index 00000000..284b4906
--- /dev/null
+++ b/tests/07changelevelintr.broken
@@ -0,0 +1,9 @@
+always fails
+
+Fails with errors:
+
+ mdadm: this change will reduce the size of the array.
+ use --grow --array-size first to truncate array.
+ e.g. mdadm --grow /dev/md0 --array-size 56832
+
+ ERROR: no reshape happening
diff --git a/tests/07changelevels.broken b/tests/07changelevels.broken
new file mode 100644
index 00000000..9b930d93
--- /dev/null
+++ b/tests/07changelevels.broken
@@ -0,0 +1,9 @@
+always fails
+
+Fails with errors:
+
+ mdadm: /dev/loop0 is smaller than given size. 18976K < 19968K + metadata
+ mdadm: /dev/loop1 is smaller than given size. 18976K < 19968K + metadata
+ mdadm: /dev/loop2 is smaller than given size. 18976K < 19968K + metadata
+
+ ERROR: /dev/md0 isn't a block device.
diff --git a/tests/07reshape5intr.broken b/tests/07reshape5intr.broken
new file mode 100644
index 00000000..efe52a66
--- /dev/null
+++ b/tests/07reshape5intr.broken
@@ -0,0 +1,45 @@
+always fails
+
+This patch, recently added to md-next causes the test to always fail:
+
+7e6ba434cc60 ("md: don't unregister sync_thread with reconfig_mutex
+held")
+
+The new error is simply:
+
+ ERROR: no reshape happening
+
+Before the patch, the error seen is below.
+
+--
+
+fails infrequently
+
+Fails roughly 1 in 4 runs with errors:
+
+ mdadm: Merging with already-assembled /dev/md/0
+ mdadm: cannot re-read metadata from /dev/loop6 - aborting
+
+ ERROR: no reshape happening
+
+Also have seen a random deadlock:
+
+ INFO: task mdadm:109702 blocked for more than 30 seconds.
+ Not tainted 5.18.0-rc3-eid-vmlocalyes-dbg-00095-g3c2b5427979d #2040
+ "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+ task:mdadm state:D stack: 0 pid:109702 ppid: 1 flags:0x00004000
+ Call Trace:
+ <TASK>
+ __schedule+0x67e/0x13b0
+ schedule+0x82/0x110
+ mddev_suspend+0x2e1/0x330
+ suspend_lo_store+0xbd/0x140
+ md_attr_store+0xcb/0x130
+ sysfs_kf_write+0x89/0xb0
+ kernfs_fop_write_iter+0x202/0x2c0
+ new_sync_write+0x222/0x330
+ vfs_write+0x3bc/0x4d0
+ ksys_write+0xd9/0x180
+ __x64_sys_write+0x43/0x50
+ do_syscall_64+0x3b/0x90
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
diff --git a/tests/07revert-grow.broken b/tests/07revert-grow.broken
new file mode 100644
index 00000000..9b6db86f
--- /dev/null
+++ b/tests/07revert-grow.broken
@@ -0,0 +1,31 @@
+always fails
+
+This patch, recently added to md-next causes the test to always fail:
+
+7e6ba434cc60 ("md: don't unregister sync_thread with reconfig_mutex held")
+
+The errors are:
+
+ mdadm: No active reshape to revert on /dev/loop0
+ ERROR: active raid5 not found
+
+Before the patch, the error seen is below.
+
+--
+
+fails rarely
+
+Fails about 1 in every 30 runs with errors:
+
+ mdadm: Merging with already-assembled /dev/md/0
+ mdadm: backup file /tmp/md-backup inaccessible: No such file or directory
+ mdadm: failed to add /dev/loop1 to /dev/md/0: Invalid argument
+ mdadm: failed to add /dev/loop2 to /dev/md/0: Invalid argument
+ mdadm: failed to add /dev/loop3 to /dev/md/0: Invalid argument
+ mdadm: failed to add /dev/loop0 to /dev/md/0: Invalid argument
+ mdadm: /dev/md/0 assembled from 1 drive - need all 5 to start it
+ (use --run to insist).
+
+ grep: /sys/block/md*/md/sync_action: No such file or directory
+
+ ERROR: active raid5 not found
diff --git a/tests/07revert-shrink.broken b/tests/07revert-shrink.broken
new file mode 100644
index 00000000..c33c39ec
--- /dev/null
+++ b/tests/07revert-shrink.broken
@@ -0,0 +1,9 @@
+always fails
+
+Fails with errors:
+
+ mdadm: this change will reduce the size of the array.
+ use --grow --array-size first to truncate array.
+ e.g. mdadm --grow /dev/md0 --array-size 53760
+
+ ERROR: active raid5 not found
diff --git a/tests/07testreshape5.broken b/tests/07testreshape5.broken
new file mode 100644
index 00000000..a8ce03e4
--- /dev/null
+++ b/tests/07testreshape5.broken
@@ -0,0 +1,12 @@
+always fails
+
+Test seems to run 'test_stripe' at $dir directory, but $dir is never
+set. If $dir is adjusted to $PWD, the test still fails with:
+
+ mdadm: /dev/loop2 is not suitable for this array.
+ mdadm: create aborted
+ ++ return 1
+ ++ cmp -s -n 8192 /dev/md0 /tmp/RandFile
+ ++ echo cmp failed
+ cmp failed
+ ++ exit 2
diff --git a/tests/09imsm-assemble.broken b/tests/09imsm-assemble.broken
new file mode 100644
index 00000000..a6d4d5cf
--- /dev/null
+++ b/tests/09imsm-assemble.broken
@@ -0,0 +1,6 @@
+fails infrequently
+
+Fails roughly 1 in 10 runs with errors:
+
+ mdadm: /dev/loop2 is still in use, cannot remove.
+ /dev/loop2 removal from /dev/md/container should have succeeded
diff --git a/tests/09imsm-create-fail-rebuild.broken b/tests/09imsm-create-fail-rebuild.broken
new file mode 100644
index 00000000..40c4b294
--- /dev/null
+++ b/tests/09imsm-create-fail-rebuild.broken
@@ -0,0 +1,5 @@
+always fails
+
+Fails with error:
+
+ **Error**: Array size mismatch - expected 3072, actual 16384
diff --git a/tests/09imsm-overlap.broken b/tests/09imsm-overlap.broken
new file mode 100644
index 00000000..e7ccab76
--- /dev/null
+++ b/tests/09imsm-overlap.broken
@@ -0,0 +1,7 @@
+always fails
+
+Fails with errors:
+
+ **Error**: Offset mismatch - expected 15360, actual 0
+ **Error**: Offset mismatch - expected 15360, actual 0
+ /dev/md/vol3 failed check
diff --git a/tests/10ddf-assemble-missing.broken b/tests/10ddf-assemble-missing.broken
new file mode 100644
index 00000000..bfd8d103
--- /dev/null
+++ b/tests/10ddf-assemble-missing.broken
@@ -0,0 +1,6 @@
+always fails
+
+Fails with errors:
+
+ ERROR: /dev/md/vol0 has unexpected state on /dev/loop10
+ ERROR: unexpected number of online disks on /dev/loop10
diff --git a/tests/10ddf-fail-create-race.broken b/tests/10ddf-fail-create-race.broken
new file mode 100644
index 00000000..6c0df023
--- /dev/null
+++ b/tests/10ddf-fail-create-race.broken
@@ -0,0 +1,7 @@
+usually fails
+
+Fails about 9 out of 10 times with many errors:
+
+ mdadm: cannot open MISSING: No such file or directory
+ ERROR: non-degraded array found
+ ERROR: disk 0 not marked as failed in meta data
diff --git a/tests/10ddf-fail-two-spares.broken b/tests/10ddf-fail-two-spares.broken
new file mode 100644
index 00000000..eeea56d9
--- /dev/null
+++ b/tests/10ddf-fail-two-spares.broken
@@ -0,0 +1,5 @@
+fails infrequently
+
+Fails roughly 1 in 3 with error:
+
+ ERROR: /dev/md/vol1 should be optimal in meta data
diff --git a/tests/10ddf-incremental-wrong-order.broken b/tests/10ddf-incremental-wrong-order.broken
new file mode 100644
index 00000000..a5af3bab
--- /dev/null
+++ b/tests/10ddf-incremental-wrong-order.broken
@@ -0,0 +1,9 @@
+always fails
+
+Fails with errors:
+ ERROR: sha1sum of /dev/md/vol0 has changed
+ ERROR: /dev/md/vol0 has unexpected state on /dev/loop10
+ ERROR: unexpected number of online disks on /dev/loop10
+ ERROR: /dev/md/vol0 has unexpected state on /dev/loop8
+ ERROR: unexpected number of online disks on /dev/loop8
+ ERROR: sha1sum of /dev/md/vol0 has changed
diff --git a/tests/14imsm-r1_2d-grow-r1_3d.broken b/tests/14imsm-r1_2d-grow-r1_3d.broken
new file mode 100644
index 00000000..4ef1d406
--- /dev/null
+++ b/tests/14imsm-r1_2d-grow-r1_3d.broken
@@ -0,0 +1,5 @@
+always fails
+
+Fails with error:
+
+ mdadm/tests/func.sh: line 325: dvsize/chunk: division by 0 (error token is "chunk")
diff --git a/tests/14imsm-r1_2d-takeover-r0_2d.broken b/tests/14imsm-r1_2d-takeover-r0_2d.broken
new file mode 100644
index 00000000..89cd4e57
--- /dev/null
+++ b/tests/14imsm-r1_2d-takeover-r0_2d.broken
@@ -0,0 +1,6 @@
+always fails
+
+Fails with error:
+
+ tests/func.sh: line 325: dvsize/chunk: division by 0 (error token
+ is "chunk")
diff --git a/tests/18imsm-r10_4d-takeover-r0_2d.broken b/tests/18imsm-r10_4d-takeover-r0_2d.broken
new file mode 100644
index 00000000..a27399f5
--- /dev/null
+++ b/tests/18imsm-r10_4d-takeover-r0_2d.broken
@@ -0,0 +1,5 @@
+fails rarely
+
+Fails about 1 run in 100 with message:
+
+ ERROR: size is wrong for /dev/md/vol0: 2 * 5120 (chunk=128) = 20480, not 0
diff --git a/tests/18imsm-r1_2d-takeover-r0_1d.broken b/tests/18imsm-r1_2d-takeover-r0_1d.broken
new file mode 100644
index 00000000..aa1982e6
--- /dev/null
+++ b/tests/18imsm-r1_2d-takeover-r0_1d.broken
@@ -0,0 +1,6 @@
+always fails
+
+Fails with error:
+
+ tests/func.sh: line 325: dvsize/chunk: division by 0 (error token
+ is "chunk")
diff --git a/tests/19raid6auto-repair.broken b/tests/19raid6auto-repair.broken
new file mode 100644
index 00000000..e91a1425
--- /dev/null
+++ b/tests/19raid6auto-repair.broken
@@ -0,0 +1,5 @@
+always fails
+
+Fails with:
+
+ "should detect errors"
diff --git a/tests/19raid6repair.broken b/tests/19raid6repair.broken
new file mode 100644
index 00000000..e91a1425
--- /dev/null
+++ b/tests/19raid6repair.broken
@@ -0,0 +1,5 @@
+always fails
+
+Fails with:
+
+ "should detect errors"
--
2.38.1

View File

@ -1,316 +0,0 @@
From 239b3cc0b5da87e966746533b1873c439db54b16 Mon Sep 17 00:00:00 2001
From: Mateusz Grzonka <mateusz.grzonka@intel.com>
Date: Fri, 12 Aug 2022 16:36:02 +0200
Subject: [PATCH 45/83] mdadm: Replace obsolete usleep with nanosleep
According to POSIX.1-2001, usleep is considered obsolete.
Replace it with a wrapper that uses nanosleep, as recommended in man.
Add handy macros for conversions between msec, usec and nsec.
Signed-off-by: Mateusz Grzonka <mateusz.grzonka@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Assemble.c | 2 +-
Grow.c | 4 ++--
Manage.c | 10 +++++-----
managemon.c | 8 ++++----
mdadm.h | 4 ++++
mdmon.c | 4 ++--
super-intel.c | 6 +++---
util.c | 42 +++++++++++++++++++++++++++++++++---------
8 files changed, 54 insertions(+), 26 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index 6df6bfbc..be2160b4 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1947,7 +1947,7 @@ out:
break;
close(mdfd);
}
- usleep(usecs);
+ sleep_for(0, USEC_TO_NSEC(usecs), true);
usecs <<= 1;
}
}
diff --git a/Grow.c b/Grow.c
index 97f22c75..5780635a 100644
--- a/Grow.c
+++ b/Grow.c
@@ -954,7 +954,7 @@ int start_reshape(struct mdinfo *sra, int already_running,
err = sysfs_set_str(sra, NULL, "sync_action",
"reshape");
if (err)
- sleep(1);
+ sleep_for(1, 0, true);
} while (err && errno == EBUSY && cnt-- > 0);
}
return err;
@@ -5058,7 +5058,7 @@ int Grow_continue_command(char *devname, int fd,
}
st->ss->getinfo_super(st, content, NULL);
if (!content->reshape_active)
- sleep(3);
+ sleep_for(3, 0, true);
else
break;
} while (cnt-- > 0);
diff --git a/Manage.c b/Manage.c
index e5e6abe4..a142f8bd 100644
--- a/Manage.c
+++ b/Manage.c
@@ -244,7 +244,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
"array_state",
"inactive")) < 0 &&
errno == EBUSY) {
- usleep(200000);
+ sleep_for(0, MSEC_TO_NSEC(200), true);
count--;
}
if (err) {
@@ -328,7 +328,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
sysfs_get_ll(mdi, NULL, "sync_max", &old_sync_max) == 0) {
/* must be in the critical section - wait a bit */
delay -= 1;
- usleep(100000);
+ sleep_for(0, MSEC_TO_NSEC(100), true);
}
if (sysfs_set_str(mdi, NULL, "sync_action", "frozen") != 0)
@@ -405,7 +405,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
* quite started yet. Wait a bit and
* check 'sync_action' to see.
*/
- usleep(10000);
+ sleep_for(0, MSEC_TO_NSEC(10), true);
sysfs_get_str(mdi, NULL, "sync_action", buf, sizeof(buf));
if (strncmp(buf, "reshape", 7) != 0)
break;
@@ -447,7 +447,7 @@ done:
count = 25; err = 0;
while (count && fd >= 0 &&
(err = ioctl(fd, STOP_ARRAY, NULL)) < 0 && errno == EBUSY) {
- usleep(200000);
+ sleep_for(0, MSEC_TO_NSEC(200), true);
count --;
}
if (fd >= 0 && err) {
@@ -1105,7 +1105,7 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
ret = sysfs_unique_holder(devnm, rdev);
if (ret < 2)
break;
- usleep(100 * 1000); /* 100ms */
+ sleep_for(0, MSEC_TO_NSEC(100), true);
} while (--count > 0);
if (ret == 0) {
diff --git a/managemon.c b/managemon.c
index 0e9bdf00..a7bfa8f6 100644
--- a/managemon.c
+++ b/managemon.c
@@ -207,7 +207,7 @@ static void replace_array(struct supertype *container,
remove_old();
while (pending_discard) {
while (discard_this == NULL)
- sleep(1);
+ sleep_for(1, 0, true);
remove_old();
}
pending_discard = old;
@@ -568,7 +568,7 @@ static void manage_member(struct mdstat_ent *mdstat,
updates = NULL;
while (update_queue_pending || update_queue) {
check_update_queue(container);
- usleep(15*1000);
+ sleep_for(0, MSEC_TO_NSEC(15), true);
}
replace_array(container, a, newa);
if (sysfs_set_str(&a->info, NULL,
@@ -822,7 +822,7 @@ static void handle_message(struct supertype *container, struct metadata_update *
if (msg->len <= 0)
while (update_queue_pending || update_queue) {
check_update_queue(container);
- usleep(15*1000);
+ sleep_for(0, MSEC_TO_NSEC(15), true);
}
if (msg->len == 0) { /* ping_monitor */
@@ -836,7 +836,7 @@ static void handle_message(struct supertype *container, struct metadata_update *
wakeup_monitor();
while (monitor_loop_cnt - cnt < 0)
- usleep(10 * 1000);
+ sleep_for(0, MSEC_TO_NSEC(10), true);
} else if (msg->len == -1) { /* ping_manager */
struct mdstat_ent *mdstat = mdstat_read(1, 0);
diff --git a/mdadm.h b/mdadm.h
index 163f4a49..add9c0b6 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1720,6 +1720,10 @@ extern int cluster_get_dlmlock(void);
extern int cluster_release_dlmlock(void);
extern void set_dlm_hooks(void);
+#define MSEC_TO_NSEC(msec) ((msec) * 1000000)
+#define USEC_TO_NSEC(usec) ((usec) * 1000)
+extern void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt);
+
#define _ROUND_UP(val, base) (((val) + (base) - 1) & ~(base - 1))
#define ROUND_UP(val, base) _ROUND_UP(val, (typeof(val))(base))
#define ROUND_UP_PTR(ptr, base) ((typeof(ptr)) \
diff --git a/mdmon.c b/mdmon.c
index c057da63..e9d035eb 100644
--- a/mdmon.c
+++ b/mdmon.c
@@ -99,7 +99,7 @@ static int clone_monitor(struct supertype *container)
if (rc)
return rc;
while (mon_tid == -1)
- usleep(10);
+ sleep_for(0, USEC_TO_NSEC(10), true);
pthread_attr_destroy(&attr);
mgr_tid = syscall(SYS_gettid);
@@ -209,7 +209,7 @@ static void try_kill_monitor(pid_t pid, char *devname, int sock)
rv = kill(pid, SIGUSR1);
if (rv < 0)
break;
- usleep(200000);
+ sleep_for(0, MSEC_TO_NSEC(200), true);
}
}
diff --git a/super-intel.c b/super-intel.c
index 4ddfcf94..4d82af3d 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -5275,7 +5275,7 @@ static int get_super_block(struct intel_super **super_list, char *devnm, char *d
/* retry the load if we might have raced against mdmon */
if (err == 3 && devnm && mdmon_running(devnm))
for (retry = 0; retry < 3; retry++) {
- usleep(3000);
+ sleep_for(0, MSEC_TO_NSEC(3), true);
err = load_and_parse_mpb(dfd, s, NULL, keep_fd);
if (err != 3)
break;
@@ -5377,7 +5377,7 @@ static int load_super_imsm(struct supertype *st, int fd, char *devname)
if (mdstat && mdmon_running(mdstat->devnm) && getpid() != mdmon_pid(mdstat->devnm)) {
for (retry = 0; retry < 3; retry++) {
- usleep(3000);
+ sleep_for(0, MSEC_TO_NSEC(3), true);
rv = load_and_parse_mpb(fd, super, devname, 0);
if (rv != 3)
break;
@@ -12084,7 +12084,7 @@ int wait_for_reshape_imsm(struct mdinfo *sra, int ndata)
close(fd);
return 1;
}
- usleep(30000);
+ sleep_for(0, MSEC_TO_NSEC(30), true);
} else
break;
} while (retry--);
diff --git a/util.c b/util.c
index 38f0420e..ca48d976 100644
--- a/util.c
+++ b/util.c
@@ -166,7 +166,7 @@ retry:
pr_err("error %d when get PW mode on lock %s\n", errno, str);
/* let's try several times if EAGAIN happened */
if (dlm_lock_res->lksb.sb_status == EAGAIN && retry_count < 10) {
- sleep(10);
+ sleep_for(10, 0, true);
retry_count++;
goto retry;
}
@@ -1085,7 +1085,7 @@ int open_dev_excl(char *devnm)
int i;
int flags = O_RDWR;
dev_t devid = devnm2devid(devnm);
- long delay = 1000;
+ unsigned int delay = 1; // miliseconds
sprintf(buf, "%d:%d", major(devid), minor(devid));
for (i = 0; i < 25; i++) {
@@ -1098,8 +1098,8 @@ int open_dev_excl(char *devnm)
}
if (errno != EBUSY)
return fd;
- usleep(delay);
- if (delay < 200000)
+ sleep_for(0, MSEC_TO_NSEC(delay), true);
+ if (delay < 200)
delay *= 2;
}
return -1;
@@ -1123,7 +1123,7 @@ void wait_for(char *dev, int fd)
{
int i;
struct stat stb_want;
- long delay = 1000;
+ unsigned int delay = 1; // miliseconds
if (fstat(fd, &stb_want) != 0 ||
(stb_want.st_mode & S_IFMT) != S_IFBLK)
@@ -1135,8 +1135,8 @@ void wait_for(char *dev, int fd)
(stb.st_mode & S_IFMT) == S_IFBLK &&
(stb.st_rdev == stb_want.st_rdev))
return;
- usleep(delay);
- if (delay < 200000)
+ sleep_for(0, MSEC_TO_NSEC(delay), true);
+ if (delay < 200)
delay *= 2;
}
if (i == 25)
@@ -1821,7 +1821,7 @@ int hot_remove_disk(int mdfd, unsigned long dev, int force)
while ((ret = ioctl(mdfd, HOT_REMOVE_DISK, dev)) == -1 &&
errno == EBUSY &&
cnt-- > 0)
- usleep(10000);
+ sleep_for(0, MSEC_TO_NSEC(10), true);
return ret;
}
@@ -1834,7 +1834,7 @@ int sys_hot_remove_disk(int statefd, int force)
while ((ret = write(statefd, "remove", 6)) == -1 &&
errno == EBUSY &&
cnt-- > 0)
- usleep(10000);
+ sleep_for(0, MSEC_TO_NSEC(10), true);
return ret == 6 ? 0 : -1;
}
@@ -2375,3 +2375,27 @@ out:
close(fd_zero);
return ret;
}
+
+/**
+ * sleep_for() - Sleeps for specified time.
+ * @sec: Seconds to sleep for.
+ * @nsec: Nanoseconds to sleep for, has to be less than one second.
+ * @wake_after_interrupt: If set, wake up if interrupted.
+ *
+ * Function immediately returns if error different than EINTR occurs.
+ */
+void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt)
+{
+ struct timespec delay = {.tv_sec = sec, .tv_nsec = nsec};
+
+ assert(nsec < MSEC_TO_NSEC(1000));
+
+ do {
+ errno = 0;
+ nanosleep(&delay, &delay);
+ if (errno != 0 && errno != EINTR) {
+ pr_err("Error sleeping for %us %ldns: %s\n", sec, nsec, strerror(errno));
+ return;
+ }
+ } while (!wake_after_interrupt && errno == EINTR);
+}
--
2.38.1

View File

@ -1,36 +0,0 @@
From 39b381252c32275079344d30de18b76fda4bba26 Mon Sep 17 00:00:00 2001
From: Logan Gunthorpe <logang@deltatee.com>
Date: Wed, 27 Jul 2022 15:52:45 -0600
Subject: [PATCH 46/83] tests/00readonly: Run udevadm settle before setting ro
In some recent kernel versions, 00readonly fails with:
mdadm: failed to set readonly for /dev/md0: Device or resource busy
ERROR: array is not read-only!
This was traced down to a race condition with udev holding a reference
to the block device at the same time as trying to set it read only.
To fix this, call udevadm settle before setting the array read only.
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
tests/00readonly | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/00readonly b/tests/00readonly
index 39202487..afe243b3 100644
--- a/tests/00readonly
+++ b/tests/00readonly
@@ -12,6 +12,7 @@ do
$dev1 $dev2 $dev3 $dev4 --assume-clean
check nosync
check $level
+ udevadm settle
mdadm -ro $md0
check readonly
state=$(cat /sys/block/md0/md/array_state)
--
2.38.1

View File

@ -1,119 +0,0 @@
From b7671c82010ffc04dfaecff2dd19ef8b2283e2b6 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Tue, 19 Jul 2022 14:48:21 +0200
Subject: [PATCH 47/83] tests: add test for names
Current behavior is not documented and tested. This test is a base for
future improvements. It is enough to test it only with native metadata,
because it is generic code. Generated properties are passed to metadata
handler.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
tests/00createnames | 93 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 93 insertions(+)
create mode 100644 tests/00createnames
diff --git a/tests/00createnames b/tests/00createnames
new file mode 100644
index 00000000..64b81b92
--- /dev/null
+++ b/tests/00createnames
@@ -0,0 +1,93 @@
+set -x -e
+
+# Test how <devname> and --name= are handled for create mode.
+# We need to check three properties, generated from those parameters:
+# - devnode name
+# - link in /dev/md/ (MD_DEVNAME property from --detail --export)
+# - name in metadata (MD_NAME property from --examine --export)
+
+function _verify() {
+ local DEVNODE_NAME="$1"
+ local WANTED_LINK="$2"
+ local WANTED_NAME="$3"
+
+ local RES="$(mdadm -D --export $DEVNODE_NAME | grep MD_DEVNAME)"
+ if [[ "$?" != "0" ]]; then
+ echo "Cannot get details for $DEVNODE_NAME - unexpected devnode."
+ exit 1
+ fi
+
+ if [[ "$WANTED_LINK" != "empty" ]]; then
+ local EXPECTED="MD_DEVNAME=$WANTED_LINK"
+ if [[ "$RES" != "$EXPECTED" ]]; then
+ echo "$RES doesn't match $EXPECTED."
+ exit 1
+ fi
+ fi
+
+
+ local RES="$(mdadm -E --export $dev0 | grep MD_NAME)"
+ if [[ "$?" != "0" ]]; then
+ echo "Cannot get metadata from $dev0."
+ exit 1
+ fi
+
+ local EXPECTED="MD_NAME=$(hostname):$WANTED_NAME"
+ if [[ "$RES" != "$EXPECTED" ]]; then
+ echo "$RES doesn't match $EXPECTED."
+ exit 1
+ fi
+}
+
+function _create() {
+ local DEVNAME=$1
+ local NAME=$2
+
+ if [[ -z "$NAME" ]]; then
+ mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force
+ else
+ mdadm -CR "$DEVNAME" --name="$NAME" -l0 -n 1 $dev0 --force
+ fi
+
+ if [[ "$?" != "0" ]]; then
+ echo "Cannot create device."
+ exit 1
+ fi
+}
+
+# The most trivial case.
+_create "/dev/md/name"
+_verify "/dev/md127" "name" "name"
+mdadm -S "/dev/md127"
+
+_create "name"
+_verify "/dev/md127" "name" "name"
+mdadm -S "/dev/md127"
+
+# Use 'mdX' as name.
+_create "/dev/md/md0"
+_verify "/dev/md127" "md0" "md0"
+mdadm -S "/dev/md127"
+
+_create "md0"
+_verify "/dev/md127" "md0" "md0"
+mdadm -S "/dev/md127"
+
+# <devnode> is used to create MD_DEVNAME but, name is used to create MD_NAME.
+_create "/dev/md/devnode" "name"
+_verify "/dev/md127" "devnode" "name"
+mdadm -S "/dev/md127"
+
+_create "devnode" "name"
+_verify "/dev/md127" "devnode" "name"
+mdadm -S "/dev/md127"
+
+# Devnode points to /dev/ directory. MD_DEVNAME doesn't exist.
+_create "/dev/md0"
+_verify "/dev/md0" "empty" "0"
+mdadm -S "/dev/md0"
+
+# Devnode points to /dev/ directory and name is set.
+_create "/dev/md0" "name"
+_verify "/dev/md0" "empty" "name"
+mdadm -S "/dev/md0"
--
2.38.1

View File

@ -1,176 +0,0 @@
From e4a030a0d3a953b8e74c118200e58dc83c2fc608 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Tue, 19 Jul 2022 14:48:22 +0200
Subject: [PATCH 48/83] mdadm: remove symlink option
The option is not used. Remove it from code.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
ReadMe.c | 1 -
config.c | 7 +------
mdadm.8.in | 9 ---------
mdadm.c | 20 --------------------
mdadm.conf.5.in | 15 ---------------
mdadm.h | 2 --
6 files changed, 1 insertion(+), 53 deletions(-)
diff --git a/ReadMe.c b/ReadMe.c
index 7518a32a..7f94847e 100644
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -147,7 +147,6 @@ struct option long_options[] = {
{"nofailfast",0, 0, NoFailFast},
{"re-add", 0, 0, ReAdd},
{"homehost", 1, 0, HomeHost},
- {"symlinks", 1, 0, Symlinks},
{"data-offset",1, 0, DataOffset},
{"nodes",1, 0, Nodes}, /* also for --assemble */
{"home-cluster",1, 0, ClusterName},
diff --git a/config.c b/config.c
index 9c725457..dc1620c1 100644
--- a/config.c
+++ b/config.c
@@ -194,7 +194,6 @@ struct mddev_dev *load_containers(void)
struct createinfo createinfo = {
.autof = 2, /* by default, create devices with standard names */
- .symlinks = 1,
.names = 0, /* By default, stick with numbered md devices. */
.bblist = 1, /* Use a bad block list by default */
#ifdef DEBIAN
@@ -310,11 +309,7 @@ static void createline(char *line)
if (!createinfo.supertype)
pr_err("metadata format %s unknown, ignoring\n",
w+9);
- } else if (strncasecmp(w, "symlinks=yes", 12) == 0)
- createinfo.symlinks = 1;
- else if (strncasecmp(w, "symlinks=no", 11) == 0)
- createinfo.symlinks = 0;
- else if (strncasecmp(w, "names=yes", 12) == 0)
+ } else if (strncasecmp(w, "names=yes", 12) == 0)
createinfo.names = 1;
else if (strncasecmp(w, "names=no", 11) == 0)
createinfo.names = 0;
diff --git a/mdadm.8.in b/mdadm.8.in
index 0be02e4a..f2736226 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -1048,11 +1048,6 @@ simultaneously. If not specified, this defaults to 4.
Specify journal device for the RAID-4/5/6 array. The journal device
should be a SSD with reasonable lifetime.
-.TP
-.BR \-\-symlinks
-Auto creation of symlinks in /dev to /dev/md, option --symlinks must
-be 'no' or 'yes' and work with --create and --build.
-
.TP
.BR \-k ", " \-\-consistency\-policy=
Specify how the array maintains consistency in case of unexpected shutdown.
@@ -1405,10 +1400,6 @@ Reshape can be continued later using the
.B \-\-continue
option for the grow command.
-.TP
-.BR \-\-symlinks
-See this option under Create and Build options.
-
.SH For Manage mode:
.TP
diff --git a/mdadm.c b/mdadm.c
index 56722ed9..180f7a9c 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -59,7 +59,6 @@ int main(int argc, char *argv[])
struct mddev_dev *dv;
mdu_array_info_t array;
int devs_found = 0;
- char *symlinks = NULL;
int grow_continue = 0;
/* autof indicates whether and how to create device node.
* bottom 3 bits are style. Rest (when shifted) are number of parts
@@ -663,13 +662,6 @@ int main(int argc, char *argv[])
case O(ASSEMBLE,Auto): /* auto-creation of device node */
c.autof = parse_auto(optarg, "--auto flag", 0);
continue;
-
- case O(CREATE,Symlinks):
- case O(BUILD,Symlinks):
- case O(ASSEMBLE,Symlinks): /* auto creation of symlinks in /dev to /dev/md */
- symlinks = optarg;
- continue;
-
case O(BUILD,'f'): /* force honouring '-n 1' */
case O(BUILD,Force): /* force honouring '-n 1' */
case O(GROW,'f'): /* ditto */
@@ -1325,18 +1317,6 @@ int main(int argc, char *argv[])
exit(2);
}
- if (symlinks) {
- struct createinfo *ci = conf_get_create_info();
-
- if (strcasecmp(symlinks, "yes") == 0)
- ci->symlinks = 1;
- else if (strcasecmp(symlinks, "no") == 0)
- ci->symlinks = 0;
- else {
- pr_err("option --symlinks must be 'no' or 'yes'\n");
- exit(2);
- }
- }
/* Ok, got the option parsing out of the way
* hopefully it's mostly right but there might be some stuff
* missing
diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in
index cd4e6a9d..bc2295c2 100644
--- a/mdadm.conf.5.in
+++ b/mdadm.conf.5.in
@@ -338,21 +338,6 @@ missing device entries should be created.
The name of the metadata format to use if none is explicitly given.
This can be useful to impose a system-wide default of version-1 superblocks.
-.TP
-.B symlinks=no
-Normally when creating devices in
-.B /dev/md/
-.I mdadm
-will create a matching symlink from
-.B /dev/
-with a name starting
-.B md
-or
-.BR md_ .
-Give
-.B symlinks=no
-to suppress this symlink creation.
-
.TP
.B names=yes
Since Linux 2.6.29 it has been possible to create
diff --git a/mdadm.h b/mdadm.h
index add9c0b6..93e72786 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -394,7 +394,6 @@ struct createinfo {
int gid;
int autof;
int mode;
- int symlinks;
int names;
int bblist;
struct supertype *supertype;
@@ -442,7 +441,6 @@ enum special_options {
BackupFile,
HomeHost,
AutoHomeHost,
- Symlinks,
AutoDetect,
Waitclean,
DetailPlatform,
--
2.38.1

View File

@ -1,232 +0,0 @@
From ae5dfc56b7a96805d5a0b50eaf93b9fec8604298 Mon Sep 17 00:00:00 2001
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Date: Tue, 19 Jul 2022 14:48:23 +0200
Subject: [PATCH 49/83] mdadm: move data_offset to struct shape
Data offset is a shape property so move it there to remove additional
parameter from some functions.
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Create.c | 16 ++++++++--------
Grow.c | 7 +++----
mdadm.c | 20 +++++++++-----------
mdadm.h | 5 ++---
4 files changed, 22 insertions(+), 26 deletions(-)
diff --git a/Create.c b/Create.c
index c84c1ac8..e06ec2ae 100644
--- a/Create.c
+++ b/Create.c
@@ -95,7 +95,7 @@ int Create(struct supertype *st, char *mddev,
char *name, int *uuid,
int subdevs, struct mddev_dev *devlist,
struct shape *s,
- struct context *c, unsigned long long data_offset)
+ struct context *c)
{
/*
* Create a new raid array.
@@ -288,7 +288,7 @@ int Create(struct supertype *st, char *mddev,
newsize = s->size * 2;
if (st && ! st->ss->validate_geometry(st, s->level, s->layout, s->raiddisks,
&s->chunk, s->size*2,
- data_offset, NULL,
+ s->data_offset, NULL,
&newsize, s->consistency_policy,
c->verbose >= 0))
return 1;
@@ -323,10 +323,10 @@ int Create(struct supertype *st, char *mddev,
info.array.working_disks = 0;
dnum = 0;
for (dv = devlist; dv; dv = dv->next)
- if (data_offset == VARIABLE_OFFSET)
+ if (s->data_offset == VARIABLE_OFFSET)
dv->data_offset = INVALID_SECTORS;
else
- dv->data_offset = data_offset;
+ dv->data_offset = s->data_offset;
for (dv=devlist; dv && !have_container; dv=dv->next, dnum++) {
char *dname = dv->devname;
@@ -342,7 +342,7 @@ int Create(struct supertype *st, char *mddev,
missing_disks ++;
continue;
}
- if (data_offset == VARIABLE_OFFSET) {
+ if (s->data_offset == VARIABLE_OFFSET) {
doff = strchr(dname, ':');
if (doff) {
*doff++ = 0;
@@ -350,7 +350,7 @@ int Create(struct supertype *st, char *mddev,
} else
dv->data_offset = INVALID_SECTORS;
} else
- dv->data_offset = data_offset;
+ dv->data_offset = s->data_offset;
dfd = open(dname, O_RDONLY);
if (dfd < 0) {
@@ -535,7 +535,7 @@ int Create(struct supertype *st, char *mddev,
if (!st->ss->validate_geometry(st, s->level, s->layout,
s->raiddisks,
&s->chunk, minsize*2,
- data_offset,
+ s->data_offset,
NULL, NULL,
s->consistency_policy, 0)) {
pr_err("devices too large for RAID level %d\n", s->level);
@@ -754,7 +754,7 @@ int Create(struct supertype *st, char *mddev,
}
}
if (!st->ss->init_super(st, &info.array, s, name, c->homehost, uuid,
- data_offset))
+ s->data_offset))
goto abort_locked;
total_slots = info.array.nr_disks;
diff --git a/Grow.c b/Grow.c
index 5780635a..868bdc3a 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1775,7 +1775,6 @@ static int reshape_container(char *container, char *devname,
int Grow_reshape(char *devname, int fd,
struct mddev_dev *devlist,
- unsigned long long data_offset,
struct context *c, struct shape *s)
{
/* Make some changes in the shape of an array.
@@ -1821,7 +1820,7 @@ int Grow_reshape(char *devname, int fd,
return 1;
}
- if (data_offset != INVALID_SECTORS && array.level != 10 &&
+ if (s->data_offset != INVALID_SECTORS && array.level != 10 &&
(array.level < 4 || array.level > 6)) {
pr_err("--grow --data-offset not yet supported\n");
return 1;
@@ -2179,7 +2178,7 @@ size_change_error:
if ((s->level == UnSet || s->level == array.level) &&
(s->layout_str == NULL) &&
(s->chunk == 0 || s->chunk == array.chunk_size) &&
- data_offset == INVALID_SECTORS &&
+ s->data_offset == INVALID_SECTORS &&
(s->raiddisks == 0 || s->raiddisks == array.raid_disks)) {
/* Nothing more to do */
if (!changed && c->verbose >= 0)
@@ -2379,7 +2378,7 @@ size_change_error:
}
sync_metadata(st);
rv = reshape_array(container, fd, devname, st, &info, c->force,
- devlist, data_offset, c->backup_file,
+ devlist, s->data_offset, c->backup_file,
c->verbose, 0, 0, 0);
frozen = 0;
}
diff --git a/mdadm.c b/mdadm.c
index 180f7a9c..845e4466 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -49,7 +49,6 @@ int main(int argc, char *argv[])
int i;
unsigned long long array_size = 0;
- unsigned long long data_offset = INVALID_SECTORS;
struct mddev_ident ident;
char *configfile = NULL;
int devmode = 0;
@@ -79,6 +78,7 @@ int main(int argc, char *argv[])
.layout = UnSet,
.bitmap_chunk = UnSet,
.consistency_policy = CONSISTENCY_POLICY_UNKNOWN,
+ .data_offset = INVALID_SECTORS,
};
char sys_hostname[256];
@@ -479,15 +479,15 @@ int main(int argc, char *argv[])
case O(CREATE,DataOffset):
case O(GROW,DataOffset):
- if (data_offset != INVALID_SECTORS) {
+ if (s.data_offset != INVALID_SECTORS) {
pr_err("data-offset may only be specified one. Second value is %s.\n", optarg);
exit(2);
}
if (mode == CREATE && strcmp(optarg, "variable") == 0)
- data_offset = VARIABLE_OFFSET;
+ s.data_offset = VARIABLE_OFFSET;
else
- data_offset = parse_size(optarg);
- if (data_offset == INVALID_SECTORS) {
+ s.data_offset = parse_size(optarg);
+ if (s.data_offset == INVALID_SECTORS) {
pr_err("invalid data-offset: %s\n",
optarg);
exit(2);
@@ -1416,7 +1416,7 @@ int main(int argc, char *argv[])
exit(1);
}
- if (c.backup_file && data_offset != INVALID_SECTORS) {
+ if (c.backup_file && s.data_offset != INVALID_SECTORS) {
pr_err("--backup-file and --data-offset are incompatible\n");
exit(2);
}
@@ -1587,8 +1587,7 @@ int main(int argc, char *argv[])
rv = Create(ss, devlist->devname,
ident.name, ident.uuid_set ? ident.uuid : NULL,
- devs_found-1, devlist->next,
- &s, &c, data_offset);
+ devs_found - 1, devlist->next, &s, &c);
break;
case MISC:
if (devmode == 'E') {
@@ -1706,10 +1705,9 @@ int main(int argc, char *argv[])
c.verbose);
else if (s.size > 0 || s.raiddisks || s.layout_str ||
s.chunk != 0 || s.level != UnSet ||
- data_offset != INVALID_SECTORS) {
+ s.data_offset != INVALID_SECTORS) {
rv = Grow_reshape(devlist->devname, mdfd,
- devlist->next,
- data_offset, &c, &s);
+ devlist->next, &c, &s);
} else if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) {
rv = Grow_consistency_policy(devlist->devname, mdfd, &c, &s);
} else if (array_size == 0)
diff --git a/mdadm.h b/mdadm.h
index 93e72786..adb7cdaa 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -595,6 +595,7 @@ struct shape {
int assume_clean;
int write_behind;
unsigned long long size;
+ unsigned long long data_offset;
int consistency_policy;
};
@@ -1431,7 +1432,6 @@ extern int Grow_addbitmap(char *devname, int fd,
struct context *c, struct shape *s);
extern int Grow_reshape(char *devname, int fd,
struct mddev_dev *devlist,
- unsigned long long data_offset,
struct context *c, struct shape *s);
extern int Grow_restart(struct supertype *st, struct mdinfo *info,
int *fdlist, int cnt, char *backup_file, int verbose);
@@ -1462,8 +1462,7 @@ extern int Create(struct supertype *st, char *mddev,
char *name, int *uuid,
int subdevs, struct mddev_dev *devlist,
struct shape *s,
- struct context *c,
- unsigned long long data_offset);
+ struct context *c);
extern int Detail(char *dev, struct context *c);
extern int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export, char *controller_path);
--
2.38.1

View File

@ -1,162 +0,0 @@
From 27ad4900501c615b7c6b266bf23948e5606dba53 Mon Sep 17 00:00:00 2001
From: Logan Gunthorpe <logang@deltatee.com>
Date: Wed, 27 Jul 2022 15:52:46 -0600
Subject: [PATCH 50/83] mdadm: Don't open md device for CREATE and ASSEMBLE
The mdadm command tries to open the md device for most modes, first
thing, no matter what. When running to create or assemble an array,
in most cases, the md device will not exist, the open call will fail
and everything will proceed correctly.
However, when running tests, a create or assembly command may be run
shortly after stopping an array and the old md device file may still
be around. Then, if create_on_open is set in the kernel, a new md
device will be created when mdadm does its initial open.
When mdadm gets around to creating the new device with the new_array
parameter it issues this error:
mdadm: Fail to create md0 when using
/sys/module/md_mod/parameters/new_array, fallback to creation via node
This is because an mddev was already created by the kernel with the
earlier open() call and thus the new one being created will fail with
EEXIST. The mdadm command will still successfully be created due to
falling back to the node creation method. However, the error message
itself will fail any test that's running it.
This issue is a race condition that is very rare, but a recent change
in the kernel caused this to happen more frequently: about 1 in 50
times.
To fix this, don't bother trying to open the md device for CREATE,
ASSEMBLE and BUILD commands, as the file descriptor will never be used
anyway even if it is successfully openned. The mdfd has not been used
for these commands since:
7f91af49ad09 ("Delay creation of array devices for assemble/build/create")
The checks that were done on the open device can be changed to being
done with stat.
Side note: it would be nice to disable create_on_open as well to help
solve this, but it seems the work for this was never finished. By default,
mdadm will create using the old node interface when a name is specified
unless the user specifically puts names=yes in a config file, which
doesn't seem to be common or desirable to require this..
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
lib.c | 12 ++++++++++++
mdadm.c | 40 ++++++++++++++++++++--------------------
mdadm.h | 1 +
3 files changed, 33 insertions(+), 20 deletions(-)
diff --git a/lib.c b/lib.c
index 7e3e3d47..e395b28d 100644
--- a/lib.c
+++ b/lib.c
@@ -164,6 +164,18 @@ char *stat2devnm(struct stat *st)
return devid2devnm(st->st_rdev);
}
+bool stat_is_md_dev(struct stat *st)
+{
+ if ((S_IFMT & st->st_mode) != S_IFBLK)
+ return false;
+ if (major(st->st_rdev) == MD_MAJOR)
+ return true;
+ if (major(st->st_rdev) == (unsigned)get_mdp_major())
+ return true;
+
+ return false;
+}
+
char *fd2devnm(int fd)
{
struct stat stb;
diff --git a/mdadm.c b/mdadm.c
index 845e4466..972adb52 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -1329,6 +1329,9 @@ int main(int argc, char *argv[])
if (mode == MANAGE || mode == BUILD || mode == CREATE ||
mode == GROW || (mode == ASSEMBLE && ! c.scan)) {
+ struct stat stb;
+ int ret;
+
if (devs_found < 1) {
pr_err("an md device must be given in this mode\n");
exit(2);
@@ -1341,6 +1344,12 @@ int main(int argc, char *argv[])
mdfd = open_mddev(devlist->devname, 1);
if (mdfd < 0)
exit(1);
+
+ ret = fstat(mdfd, &stb);
+ if (ret) {
+ pr_err("fstat failed on %s.\n", devlist->devname);
+ exit(1);
+ }
} else {
char *bname = basename(devlist->devname);
@@ -1348,30 +1357,21 @@ int main(int argc, char *argv[])
pr_err("Name %s is too long.\n", devlist->devname);
exit(1);
}
- /* non-existent device is OK */
- mdfd = open_mddev(devlist->devname, 0);
- }
- if (mdfd == -2) {
- pr_err("device %s exists but is not an md array.\n", devlist->devname);
- exit(1);
- }
- if ((int)ident.super_minor == -2) {
- struct stat stb;
- if (mdfd < 0) {
+
+ ret = stat(devlist->devname, &stb);
+ if (ident.super_minor == -2 && ret != 0) {
pr_err("--super-minor=dev given, and listed device %s doesn't exist.\n",
- devlist->devname);
+ devlist->devname);
+ exit(1);
+ }
+
+ if (!ret && !stat_is_md_dev(&stb)) {
+ pr_err("device %s exists but is not an md array.\n", devlist->devname);
exit(1);
}
- fstat(mdfd, &stb);
- ident.super_minor = minor(stb.st_rdev);
- }
- if (mdfd >= 0 && mode != MANAGE && mode != GROW) {
- /* We don't really want this open yet, we just might
- * have wanted to check some things
- */
- close(mdfd);
- mdfd = -1;
}
+ if (ident.super_minor == -2)
+ ident.super_minor = minor(stb.st_rdev);
}
if (s.raiddisks) {
diff --git a/mdadm.h b/mdadm.h
index adb7cdaa..8208b81e 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1672,6 +1672,7 @@ void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0
extern char *stat2kname(struct stat *st);
extern char *fd2kname(int fd);
extern char *stat2devnm(struct stat *st);
+bool stat_is_md_dev(struct stat *st);
extern char *fd2devnm(int fd);
extern void udev_block(char *devnm);
extern void udev_unblock(void);
--
2.38.1

View File

@ -1,231 +0,0 @@
From 7211116c295ba1f9e1fcbdc2dd2d3762855062e1 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Thu, 28 Jul 2022 20:20:53 +0800
Subject: [PATCH 51/83] Grow: Split Grow_reshape into helper function
Grow_reshape should be split into helper functions given its size.
- Add helper function for preparing reshape on external metadata.
- Close cfd file descriptor.
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Acked-by: Coly Li <colyli@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Grow.c | 125 ++++++++++++++++++++++++++++++--------------------------
mdadm.h | 1 +
util.c | 14 +++++++
3 files changed, 81 insertions(+), 59 deletions(-)
diff --git a/Grow.c b/Grow.c
index 868bdc3a..0f07a894 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1773,6 +1773,65 @@ static int reshape_container(char *container, char *devname,
char *backup_file, int verbose,
int forked, int restart, int freeze_reshape);
+/**
+ * prepare_external_reshape() - prepares update on external metadata if supported.
+ * @devname: Device name.
+ * @subarray: Subarray.
+ * @st: Supertype.
+ * @container: Container.
+ * @cfd: Container file descriptor.
+ *
+ * Function checks that the requested reshape is supported on external metadata,
+ * and performs an initial check that the container holds the pre-requisite
+ * spare devices (mdmon owns final validation).
+ *
+ * Return: 0 on success, else 1
+ */
+static int prepare_external_reshape(char *devname, char *subarray,
+ struct supertype *st, char *container,
+ const int cfd)
+{
+ struct mdinfo *cc = NULL;
+ struct mdinfo *content = NULL;
+
+ if (st->ss->load_container(st, cfd, NULL)) {
+ pr_err("Cannot read superblock for %s\n", devname);
+ return 1;
+ }
+
+ if (!st->ss->container_content)
+ return 1;
+
+ cc = st->ss->container_content(st, subarray);
+ for (content = cc; content ; content = content->next) {
+ /*
+ * check if reshape is allowed based on metadata
+ * indications stored in content.array.status
+ */
+ if (is_bit_set(&content->array.state, MD_SB_BLOCK_VOLUME) ||
+ is_bit_set(&content->array.state, MD_SB_BLOCK_CONTAINER_RESHAPE)) {
+ pr_err("Cannot reshape arrays in container with unsupported metadata: %s(%s)\n",
+ devname, container);
+ goto error;
+ }
+ if (content->consistency_policy == CONSISTENCY_POLICY_PPL) {
+ pr_err("Operation not supported when ppl consistency policy is enabled\n");
+ goto error;
+ }
+ if (content->consistency_policy == CONSISTENCY_POLICY_BITMAP) {
+ pr_err("Operation not supported when write-intent bitmap consistency policy is enabled\n");
+ goto error;
+ }
+ }
+ sysfs_free(cc);
+ if (mdmon_running(container))
+ st->update_tail = &st->updates;
+ return 0;
+error:
+ sysfs_free(cc);
+ return 1;
+}
+
int Grow_reshape(char *devname, int fd,
struct mddev_dev *devlist,
struct context *c, struct shape *s)
@@ -1799,7 +1858,7 @@ int Grow_reshape(char *devname, int fd,
struct supertype *st;
char *subarray = NULL;
- int frozen;
+ int frozen = 0;
int changed = 0;
char *container = NULL;
int cfd = -1;
@@ -1808,7 +1867,7 @@ int Grow_reshape(char *devname, int fd,
int added_disks;
struct mdinfo info;
- struct mdinfo *sra;
+ struct mdinfo *sra = NULL;
if (md_get_array_info(fd, &array) < 0) {
pr_err("%s is not an active md array - aborting\n",
@@ -1865,13 +1924,7 @@ int Grow_reshape(char *devname, int fd,
}
}
- /* in the external case we need to check that the requested reshape is
- * supported, and perform an initial check that the container holds the
- * pre-requisite spare devices (mdmon owns final validation)
- */
if (st->ss->external) {
- int retval;
-
if (subarray) {
container = st->container_devnm;
cfd = open_dev_excl(st->container_devnm);
@@ -1887,13 +1940,12 @@ int Grow_reshape(char *devname, int fd,
return 1;
}
- retval = st->ss->load_container(st, cfd, NULL);
-
- if (retval) {
- pr_err("Cannot read superblock for %s\n", devname);
- close(cfd);
+ rv = prepare_external_reshape(devname, subarray, st,
+ container, cfd);
+ if (rv > 0) {
free(subarray);
- return 1;
+ close(cfd);
+ goto release;
}
if (s->raiddisks && subarray) {
@@ -1902,51 +1954,6 @@ int Grow_reshape(char *devname, int fd,
free(subarray);
return 1;
}
-
- /* check if operation is supported for metadata handler */
- if (st->ss->container_content) {
- struct mdinfo *cc = NULL;
- struct mdinfo *content = NULL;
-
- cc = st->ss->container_content(st, subarray);
- for (content = cc; content ; content = content->next) {
- int allow_reshape = 1;
-
- /* check if reshape is allowed based on metadata
- * indications stored in content.array.status
- */
- if (content->array.state &
- (1 << MD_SB_BLOCK_VOLUME))
- allow_reshape = 0;
- if (content->array.state &
- (1 << MD_SB_BLOCK_CONTAINER_RESHAPE))
- allow_reshape = 0;
- if (!allow_reshape) {
- pr_err("cannot reshape arrays in container with unsupported metadata: %s(%s)\n",
- devname, container);
- sysfs_free(cc);
- free(subarray);
- return 1;
- }
- if (content->consistency_policy ==
- CONSISTENCY_POLICY_PPL) {
- pr_err("Operation not supported when ppl consistency policy is enabled\n");
- sysfs_free(cc);
- free(subarray);
- return 1;
- }
- if (content->consistency_policy ==
- CONSISTENCY_POLICY_BITMAP) {
- pr_err("Operation not supported when write-intent bitmap is enabled\n");
- sysfs_free(cc);
- free(subarray);
- return 1;
- }
- }
- sysfs_free(cc);
- }
- if (mdmon_running(container))
- st->update_tail = &st->updates;
}
added_disks = 0;
diff --git a/mdadm.h b/mdadm.h
index 8208b81e..941a5f38 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -1539,6 +1539,7 @@ extern int stat_is_blkdev(char *devname, dev_t *rdev);
extern bool is_dev_alive(char *path);
extern int get_mdp_major(void);
extern int get_maj_min(char *dev, int *major, int *minor);
+extern bool is_bit_set(int *val, unsigned char index);
extern int dev_open(char *dev, int flags);
extern int open_dev(char *devnm);
extern void reopen_mddev(int mdfd);
diff --git a/util.c b/util.c
index ca48d976..26ffdcea 100644
--- a/util.c
+++ b/util.c
@@ -1027,6 +1027,20 @@ int get_maj_min(char *dev, int *major, int *minor)
*e == 0);
}
+/**
+ * is_bit_set() - get bit value by index.
+ * @val: value.
+ * @index: index of the bit (LSB numbering).
+ *
+ * Return: bit value.
+ */
+bool is_bit_set(int *val, unsigned char index)
+{
+ if ((*val) & (1 << index))
+ return true;
+ return false;
+}
+
int dev_open(char *dev, int flags)
{
/* like 'open', but if 'dev' matches %d:%d, create a temp
--
2.38.1

View File

@ -1,36 +0,0 @@
From 5c3c3df646dd3b7e8df81152f08e9ac4ddccc671 Mon Sep 17 00:00:00 2001
From: Kinga Tanska <kinga.tanska@intel.com>
Date: Fri, 19 Aug 2022 02:55:46 +0200
Subject: [PATCH 52/83] Assemble: check if device is container before
scheduling force-clean update
Up to now using assemble with force flag making each array as clean.
Force-clean should not be done for the container. This commit add
check if device is different than container before cleaning.
Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Assemble.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/Assemble.c b/Assemble.c
index be2160b4..1dd82a8c 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1809,10 +1809,9 @@ try_again:
}
#endif
}
- if (c->force && !clean &&
+ if (c->force && !clean && content->array.level != LEVEL_CONTAINER &&
!enough(content->array.level, content->array.raid_disks,
- content->array.layout, clean,
- avail)) {
+ content->array.layout, clean, avail)) {
change += st->ss->update_super(st, content, "force-array",
devices[chosen_drive].devname, c->verbose,
0, NULL);
--
2.38.1

View File

@ -1,112 +0,0 @@
From 171e9743881edf2dfb163ddff483566fbf913ccd Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Fri, 26 Aug 2022 08:55:56 +1000
Subject: [PATCH 53/83] super1: report truncated device
When the metadata is at the start of the device, it is possible that it
describes a device large than the one it is actually stored on. When
this happens, report it loudly in --examine.
....
Unused Space : before=1968 sectors, after=-2047 sectors DEVICE TOO SMALL
State : clean TRUNCATED DEVICE
....
Also report in --assemble so that the failure which the kernel will
report will be explained.
mdadm: Device /dev/sdb is not large enough for data described in superblock
mdadm: no RAID superblock on /dev/sdb
mdadm: /dev/sdb has no superblock - assembly aborted
Scenario can be demonstrated as follows:
mdadm: Note: this array has metadata at the start and
may not be suitable as a boot device. If you plan to
store '/boot' on this device please ensure that
your boot-loader understands md/v1.x metadata, or use
--metadata=0.90
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md/test started.
mdadm: stopped /dev/md/test
Unused Space : before=1968 sectors, after=-2047 sectors DEVICE TOO SMALL
State : clean TRUNCATED DEVICE
Unused Space : before=1968 sectors, after=-2047 sectors DEVICE TOO SMALL
State : clean TRUNCATED DEVICE
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
super1.c | 35 ++++++++++++++++++++++++++++-------
1 file changed, 28 insertions(+), 7 deletions(-)
diff --git a/super1.c b/super1.c
index 71af860c..58345e68 100644
--- a/super1.c
+++ b/super1.c
@@ -406,12 +406,18 @@ static void examine_super1(struct supertype *st, char *homehost)
st->ss->getinfo_super(st, &info, NULL);
if (info.space_after != 1 &&
- !(__le32_to_cpu(sb->feature_map) & MD_FEATURE_NEW_OFFSET))
- printf(" Unused Space : before=%llu sectors, after=%llu sectors\n",
- info.space_before, info.space_after);
-
- printf(" State : %s\n",
- (__le64_to_cpu(sb->resync_offset)+1)? "active":"clean");
+ !(__le32_to_cpu(sb->feature_map) & MD_FEATURE_NEW_OFFSET)) {
+ printf(" Unused Space : before=%llu sectors, ",
+ info.space_before);
+ if (info.space_after < INT64_MAX)
+ printf("after=%llu sectors\n", info.space_after);
+ else
+ printf("after=-%llu sectors DEVICE TOO SMALL\n",
+ UINT64_MAX - info.space_after);
+ }
+ printf(" State : %s%s\n",
+ (__le64_to_cpu(sb->resync_offset)+1) ? "active":"clean",
+ (info.space_after > INT64_MAX) ? " TRUNCATED DEVICE" : "");
printf(" Device UUID : ");
for (i=0; i<16; i++) {
if ((i&3)==0 && i != 0)
@@ -2206,6 +2212,7 @@ static int load_super1(struct supertype *st, int fd, char *devname)
tst.ss = &super1;
for (tst.minor_version = 0; tst.minor_version <= 2;
tst.minor_version++) {
+ tst.ignore_hw_compat = st->ignore_hw_compat;
switch(load_super1(&tst, fd, devname)) {
case 0: super = tst.sb;
if (bestvers == -1 ||
@@ -2312,7 +2319,6 @@ static int load_super1(struct supertype *st, int fd, char *devname)
free(super);
return 2;
}
- st->sb = super;
bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE);
@@ -2322,6 +2328,21 @@ static int load_super1(struct supertype *st, int fd, char *devname)
if (st->data_offset == INVALID_SECTORS)
st->data_offset = __le64_to_cpu(super->data_offset);
+ if (st->minor_version >= 1 &&
+ st->ignore_hw_compat == 0 &&
+ (dsize < (__le64_to_cpu(super->data_offset) +
+ __le64_to_cpu(super->size))
+ ||
+ dsize < (__le64_to_cpu(super->data_offset) +
+ __le64_to_cpu(super->data_size)))) {
+ if (devname)
+ pr_err("Device %s is not large enough for data described in superblock\n",
+ devname);
+ free(super);
+ return 2;
+ }
+ st->sb = super;
+
/* Now check on the bitmap superblock */
if ((__le32_to_cpu(super->feature_map)&MD_FEATURE_BITMAP_OFFSET) == 0)
return 0;
--
2.38.1

View File

@ -1,616 +0,0 @@
From 1a386f804d8392b849b3362da6b0157b0db83091 Mon Sep 17 00:00:00 2001
From: Mateusz Grzonka <mateusz.grzonka@intel.com>
Date: Fri, 12 Aug 2022 16:52:12 +0200
Subject: [PATCH 54/83] mdadm: Correct typos, punctuation and grammar in man
Signed-off-by: Mateusz Grzonka <mateusz.grzonka@intel.com>
Reviewed-by: Wol <anthony@youngman.org.uk>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
mdadm.8.in | 178 ++++++++++++++++++++++++++---------------------------
1 file changed, 88 insertions(+), 90 deletions(-)
diff --git a/mdadm.8.in b/mdadm.8.in
index f2736226..70c79d1e 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -158,7 +158,7 @@ adding new spares and removing faulty devices.
.B Misc
This is an 'everything else' mode that supports operations on active
arrays, operations on component devices such as erasing old superblocks, and
-information gathering operations.
+information-gathering operations.
.\"This mode allows operations on independent devices such as examine MD
.\"superblocks, erasing old superblocks and stopping active arrays.
@@ -231,12 +231,12 @@ mode to be assumed.
.TP
.BR \-h ", " \-\-help
-Display general help message or, after one of the above options, a
+Display a general help message or, after one of the above options, a
mode-specific help message.
.TP
.B \-\-help\-options
-Display more detailed help about command line parsing and some commonly
+Display more detailed help about command-line parsing and some commonly
used options.
.TP
@@ -266,7 +266,7 @@ the exact meaning of this option in different contexts.
.TP
.BR \-c ", " \-\-config=
-Specify the config file or directory. If not specified, default config file
+Specify the config file or directory. If not specified, the default config file
and default conf.d directory will be used. See
.BR mdadm.conf (5)
for more details.
@@ -379,7 +379,7 @@ When creating an array, the
.B homehost
will be recorded in the metadata. For version-1 superblocks, it will
be prefixed to the array name. For version-0.90 superblocks, part of
-the SHA1 hash of the hostname will be stored in the later half of the
+the SHA1 hash of the hostname will be stored in the latter half of the
UUID.
When reporting information about an array, any array which is tagged
@@ -388,7 +388,7 @@ for the given homehost will be reported as such.
When using Auto-Assemble, only arrays tagged for the given homehost
will be allowed to use 'local' names (i.e. not ending in '_' followed
by a digit string). See below under
-.BR "Auto Assembly" .
+.BR "Auto-Assembly" .
The special name "\fBany\fP" can be used as a wild card. If an array
is created with
@@ -403,7 +403,7 @@ When
.I mdadm
needs to print the name for a device it normally finds the name in
.B /dev
-which refers to the device and is shortest. When a path component is
+which refers to the device and is the shortest. When a path component is
given with
.B \-\-prefer
.I mdadm
@@ -478,9 +478,9 @@ still be larger than any replacement.
This option can be used with
.B \-\-create
-for determining initial size of an array. For external metadata,
+for determining the 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
+Setting the initial size of
.B RAID 0
array is only valid for external metadata.
@@ -545,20 +545,20 @@ Clustered arrays do not support this parameter yet.
.TP
.BR \-c ", " \-\-chunk=
-Specify chunk size of kilobytes. The default when creating an
+Specify chunk size in kilobytes. The default when creating an
array is 512KB. To ensure compatibility with earlier versions, the
default when building an array with no persistent metadata is 64KB.
This is only meaningful for RAID0, RAID4, RAID5, RAID6, and RAID10.
RAID4, RAID5, RAID6, and RAID10 require the chunk size to be a power
-of 2. In any case it must be a multiple of 4KB.
+of 2, with minimal chunk size being 4KB.
A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes,
Megabytes, Gigabytes or Terabytes respectively.
.TP
.BR \-\-rounding=
-Specify rounding factor for a Linear array. The size of each
+Specify the rounding factor for a Linear array. The size of each
component will be rounded down to a multiple of this size.
This is a synonym for
.B \-\-chunk
@@ -655,7 +655,8 @@ option to set subsequent failure modes.
and "flush" will clear any persistent faults.
The layout options for RAID10 are one of 'n', 'o' or 'f' followed
-by a small number. The default is 'n2'. The supported options are:
+by a small number signifying the number of copies of each datablock.
+The default is 'n2'. The supported options are:
.I 'n'
signals 'near' copies. Multiple copies of one data block are at
@@ -673,7 +674,7 @@ signals 'far' copies
(multiple copies have very different offsets).
See md(4) for more detail about 'near', 'offset', and 'far'.
-The number is the number of copies of each datablock. 2 is normal, 3
+As for the number of copies of each data block, 2 is normal, 3
can be useful. This number can be at most equal to the number of
devices in the array. It does not need to divide evenly into that
number (e.g. it is perfectly legal to have an 'n2' layout for an array
@@ -684,7 +685,7 @@ A bug introduced in Linux 3.14 means that RAID0 arrays
started using a different layout. This could lead to
data corruption. Since Linux 5.4 (and various stable releases that received
backports), the kernel will not accept such an array unless
-a layout is explictly set. It can be set to
+a layout is explicitly set. It can be set to
.RB ' original '
or
.RB ' alternate '.
@@ -760,13 +761,13 @@ or by selecting a different consistency policy with
.TP
.BR \-\-bitmap\-chunk=
-Set the chunksize of the bitmap. Each bit corresponds to that many
+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 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 chunksize defaults to 64Meg, or larger if necessary to
+bitmap, the chunk size defaults to 64Meg, or larger if necessary to
fit the bitmap into the available space.
A suffix of 'K', 'M', 'G' or 'T' can be given to indicate Kilobytes,
@@ -840,7 +841,7 @@ can be used with that command to avoid the automatic resync.
.BR \-\-backup\-file=
This is needed when
.B \-\-grow
-is used to increase the number of raid-devices in a RAID5 or RAID6 if
+is used to increase the number of raid devices in a RAID5 or RAID6 if
there are no spare devices available, or to shrink, change RAID level
or layout. See the GROW MODE section below on RAID\-DEVICES CHANGES.
The file must be stored on a separate device, not on the RAID array
@@ -879,7 +880,7 @@ When creating an array,
.B \-\-data\-offset
can be specified as
.BR variable .
-In the case each member device is expected to have a offset appended
+In the case each member device is expected to have an offset appended
to the name, separated by a colon. This makes it possible to recreate
exactly an array which has varying data offsets (as can happen when
different versions of
@@ -943,7 +944,7 @@ Insist that
.I mdadm
accept the geometry and layout specified without question. Normally
.I mdadm
-will not allow creation of an array with only one device, and will try
+will not allow the creation of an array with only one device, and will try
to create a RAID5 array with one missing drive (as this makes the
initial resync work faster). With
.BR \-\-force ,
@@ -1004,7 +1005,7 @@ number added, e.g.
If the md device name is in a 'standard' format as described in DEVICE
NAMES, then it will be created, if necessary, with the appropriate
device number based on that name. If the device name is not in one of these
-formats, then a unused device number will be allocated. The device
+formats, then an unused device number will be allocated. The device
number will be considered unused if there is no active array for that
number, and there is no entry in /dev for that number and with a
non-standard name. Names that are not in 'standard' format are only
@@ -1032,25 +1033,25 @@ then
.B \-\-add
can be used to add some extra devices to be included in the array.
In most cases this is not needed as the extra devices can be added as
-spares first, and then the number of raid-disks can be changed.
-However for RAID0, it is not possible to add spares. So to increase
+spares first, and then the number of raid disks can be changed.
+However, for RAID0 it is not possible to add spares. So to increase
the number of devices in a RAID0, it is necessary to set the new
number of devices, and to add the new devices, in the same command.
.TP
.BR \-\-nodes
-Only works when the array is for clustered environment. It specifies
+Only works when the array is created for a clustered environment. It specifies
the maximum number of nodes in the cluster that will use this device
simultaneously. If not specified, this defaults to 4.
.TP
.BR \-\-write-journal
Specify journal device for the RAID-4/5/6 array. The journal device
-should be a SSD with reasonable lifetime.
+should be an SSD with a reasonable lifetime.
.TP
.BR \-k ", " \-\-consistency\-policy=
-Specify how the array maintains consistency in case of unexpected shutdown.
+Specify how the array maintains consistency in the case of an unexpected shutdown.
Only relevant for RAID levels with redundancy.
Currently supported options are:
.RS
@@ -1058,7 +1059,7 @@ Currently supported options are:
.TP
.B resync
Full resync is performed and all redundancy is regenerated when the array is
-started after unclean shutdown.
+started after an unclean shutdown.
.TP
.B bitmap
@@ -1067,8 +1068,8 @@ Resync assisted by a write-intent bitmap. Implicitly selected when using
.TP
.B journal
-For RAID levels 4/5/6, journal device is used to log transactions and replay
-after unclean shutdown. Implicitly selected when using
+For RAID levels 4/5/6, the journal device is used to log transactions and replay
+after an unclean shutdown. Implicitly selected when using
.BR \-\-write\-journal .
.TP
@@ -1237,7 +1238,7 @@ This can be useful if
reports a different "Preferred Minor" to
.BR \-\-detail .
In some cases this update will be performed automatically
-by the kernel driver. In particular the update happens automatically
+by the kernel driver. In particular, the update happens automatically
at the first write to an array with redundancy (RAID level 1 or
greater) on a 2.6 (or later) kernel.
@@ -1277,7 +1278,7 @@ For version-1 superblocks, this involves updating the name.
The
.B home\-cluster
option will change the cluster name as recorded in the superblock and
-bitmap. This option only works for clustered environment.
+bitmap. This option only works for a clustered environment.
The
.B resync
@@ -1390,10 +1391,10 @@ This option should be used with great caution.
.TP
.BR \-\-freeze\-reshape
-Option is intended to be used in start-up scripts during initrd boot phase.
-When array under reshape is assembled during initrd phase, this option
-stops reshape after reshape critical section is being restored. This happens
-before file system pivot operation and avoids loss of file system context.
+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
@@ -1437,9 +1438,9 @@ re\-add a device that was previously removed from an array.
If the metadata on the device reports that it is a member of the
array, and the slot that it used is still vacant, then the device will
be added back to the array in the same position. This will normally
-cause the data for that device to be recovered. However based on the
+cause the data for that device to be recovered. However, based on the
event count on the device, the recovery may only require sections that
-are flagged a write-intent bitmap to be recovered or may not require
+are flagged by a write-intent bitmap to be recovered or may not require
any recovery at all.
When used on an array that has no metadata (i.e. it was built with
@@ -1447,13 +1448,12 @@ When used on an array that has no metadata (i.e. it was built with
it will be assumed that bitmap-based recovery is enough to make the
device fully consistent with the array.
-When used with v1.x metadata,
.B \-\-re\-add
-can be accompanied by
+can also be accompanied by
.BR \-\-update=devicesize ,
.BR \-\-update=bbl ", or"
.BR \-\-update=no\-bbl .
-See the description of these option when used in Assemble mode for an
+See descriptions of these options when used in Assemble mode for an
explanation of their use.
If the device name given is
@@ -1480,7 +1480,7 @@ Add a device as a spare. This is similar to
except that it does not attempt
.B \-\-re\-add
first. The device will be added as a spare even if it looks like it
-could be an recent member of the array.
+could be a recent member of the array.
.TP
.BR \-r ", " \-\-remove
@@ -1497,12 +1497,12 @@ and names like
.B set-A
can be given to
.BR \-\-remove .
-The first causes all failed device to be removed. The second causes
+The first causes all failed devices to be removed. The second causes
any device which is no longer connected to the system (i.e an 'open'
returns
.BR ENXIO )
to be removed.
-The third will remove a set as describe below under
+The third will remove a set as described below under
.BR \-\-fail .
.TP
@@ -1519,7 +1519,7 @@ For RAID10 arrays where the number of copies evenly divides the number
of devices, the devices can be conceptually divided into sets where
each set contains a single complete copy of the data on the array.
Sometimes a RAID10 array will be configured so that these sets are on
-separate controllers. In this case all the devices in one set can be
+separate controllers. In this case, all the devices in one set can be
failed by giving a name like
.B set\-A
or
@@ -1549,9 +1549,9 @@ This can follow a list of
.B \-\-replace
devices. The devices listed after
.B \-\-with
-will be preferentially used to replace the devices listed after
+will preferentially be used to replace the devices listed after
.BR \-\-replace .
-These device must already be spare devices in the array.
+These devices must already be spare devices in the array.
.TP
.BR \-\-write\-mostly
@@ -1574,8 +1574,8 @@ the device is found or <slot>:missing in case the device is not found.
.TP
.BR \-\-add-journal
-Add journal to an existing array, or recreate journal for RAID-4/5/6 array
-that lost a journal device. To avoid interrupting on-going write opertions,
+Add a journal to an existing array, or recreate journal for a RAID-4/5/6 array
+that lost a journal device. To avoid interrupting ongoing write operations,
.B \-\-add-journal
only works for array in Read-Only state.
@@ -1631,9 +1631,9 @@ Print details of one or more md devices.
.TP
.BR \-\-detail\-platform
Print details of the platform's RAID capabilities (firmware / hardware
-topology) for a given metadata format. If used without argument, mdadm
+topology) for a given metadata format. If used without an argument, mdadm
will scan all controllers looking for their capabilities. Otherwise, mdadm
-will only look at the controller specified by the argument in form of an
+will only look at the controller specified by the argument in the form of an
absolute filepath or a link, e.g.
.IR /sys/devices/pci0000:00/0000:00:1f.2 .
@@ -1742,8 +1742,8 @@ the block where the superblock would be is overwritten even if it
doesn't appear to be valid.
.B Note:
-Be careful to call \-\-zero\-superblock with clustered raid, make sure
-array isn't used or assembled in other cluster node before execute it.
+Be careful when calling \-\-zero\-superblock with clustered raid. Make sure
+the array isn't used or assembled in another cluster node before executing it.
.TP
.B \-\-kill\-subarray=
@@ -1790,7 +1790,7 @@ For each md device given, or each device in /proc/mdstat if
is given, arrange for the array to be marked clean as soon as possible.
.I mdadm
will return with success if the array uses external metadata and we
-successfully waited. For native arrays this returns immediately as the
+successfully waited. For native arrays, this returns immediately as the
kernel handles dirty-clean transitions at shutdown. No action is taken
if safe-mode handling is disabled.
@@ -1830,7 +1830,7 @@ uses to help track which arrays are currently being assembled.
.TP
.BR \-\-run ", " \-R
-Run any array assembled as soon as a minimal number of devices are
+Run any array assembled as soon as a minimal number of devices is
available, rather than waiting until all expected devices are present.
.TP
@@ -1860,7 +1860,7 @@ Only used with \-\-fail. The 'path' given will be recorded so that if
a new device appears at the same location it can be automatically
added to the same array. This allows the failed device to be
automatically replaced by a new device without metadata if it appears
-at specified path. This option is normally only set by a
+at specified path. This option is normally only set by an
.I udev
script.
@@ -1961,7 +1961,7 @@ Usage:
.PP
This usage assembles one or more RAID arrays from pre-existing components.
For each array, mdadm needs to know the md device, the identity of the
-array, and a number of component-devices. These can be found in a number of ways.
+array, and the number of component devices. These can be found in a number of ways.
In the first usage example (without the
.BR \-\-scan )
@@ -2001,7 +2001,7 @@ The config file is only used if explicitly named with
.B \-\-config
or requested with (a possibly implicit)
.BR \-\-scan .
-In the later case, default config file is used. See
+In the latter case, the default config file is used. See
.BR mdadm.conf (5)
for more details.
@@ -2039,14 +2039,14 @@ detects that udev is not configured, it will create the devices in
.B /dev
itself.
-In Linux kernels prior to version 2.6.28 there were two distinctly
-different types of md devices that could be created: one that could be
+In Linux kernels prior to version 2.6.28 there were two distinct
+types of md devices that could be created: one that could be
partitioned using standard partitioning tools and one that could not.
-Since 2.6.28 that distinction is no longer relevant as both type of
+Since 2.6.28 that distinction is no longer relevant as both types of
devices can be partitioned.
.I mdadm
will normally create the type that originally could not be partitioned
-as it has a well defined major number (9).
+as it has a well-defined major number (9).
Prior to 2.6.28, it is important that mdadm chooses the correct type
of array device to use. This can be controlled with the
@@ -2066,7 +2066,7 @@ can also be given in the configuration file as a word starting
.B auto=
on the ARRAY line for the relevant array.
-.SS Auto Assembly
+.SS Auto-Assembly
When
.B \-\-assemble
is used with
@@ -2122,11 +2122,11 @@ See
.IR mdadm.conf (5)
for further details.
-Note: Auto assembly cannot be used for assembling and activating some
+Note: Auto-assembly cannot be used for assembling and activating some
arrays which are undergoing reshape. In particular as the
.B backup\-file
-cannot be given, any reshape which requires a backup-file to continue
-cannot be started by auto assembly. An array which is growing to more
+cannot be given, any reshape which requires a backup file to continue
+cannot be started by auto-assembly. An array which is growing to more
devices and has passed the critical section can be assembled using
auto-assembly.
@@ -2233,7 +2233,7 @@ When creating a partition based array, using
.I mdadm
with version-1.x metadata, the partition type should be set to
.B 0xDA
-(non fs-data). This type selection allows for greater precision since
+(non fs-data). This type of selection allows for greater precision since
using any other [RAID auto-detect (0xFD) or a GNU/Linux partition (0x83)],
might create problems in the event of array recovery through a live cdrom.
@@ -2249,7 +2249,7 @@ when creating a v0.90 array will silently override any
setting.
.\"If the
.\".B \-\-size
-.\"option is given, it is not necessary to list any component-devices in this command.
+.\"option is given, it is not necessary to list any component devices in this command.
.\"They can be added later, before a
.\".B \-\-run.
.\"If no
@@ -2263,7 +2263,7 @@ 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
+option. In any case, space for a bitmap will be reserved so that one
can be added later with
.BR "\-\-grow \-\-bitmap=internal" .
@@ -2313,7 +2313,7 @@ will firstly mark
as faulty in
.B /dev/md0
and will then remove it from the array and finally add it back
-in as a spare. However only one md array can be affected by a single
+in as a spare. However, only one md array can be affected by a single
command.
When a device is added to an active array, mdadm checks to see if it
@@ -2458,14 +2458,14 @@ config file to be examined.
If the device contains RAID metadata, a file will be created in the
.I directory
and the metadata will be written to it. The file will be the same
-size as the device and have the metadata written in the file at the
-same locate that it exists in the device. However the file will be "sparse" so
+size as the device and will have the metadata written at the
+same location as it exists in the device. However, the file will be "sparse" so
that only those blocks containing metadata will be allocated. The
total space used will be small.
-The file name used in the
+The filename used in the
.I directory
-will be the base name of the device. Further if any links appear in
+will be the base name of the device. Further, if any links appear in
.I /dev/disk/by-id
which point to the device, then hard links to the file will be created
in
@@ -2567,7 +2567,7 @@ and if the destination array has a failed drive but no spares.
If any devices are listed on the command line,
.I mdadm
-will only monitor those devices. Otherwise all arrays listed in the
+will only monitor those devices, otherwise, all arrays listed in the
configuration file will be monitored. Further, if
.B \-\-scan
is given, then any other md devices that appear in
@@ -2624,10 +2624,10 @@ check, repair). (syslog priority: Warning)
.BI Rebuild NN
Where
.I NN
-is a two-digit number (ie. 05, 48). This indicates that rebuild
-has passed that many percent of the total. The events are generated
-with fixed increment since 0. Increment size may be specified with
-a commandline option (default is 20). (syslog priority: Warning)
+is a two-digit number (eg. 05, 48). This indicates that the rebuild
+has reached that percentage of the total. The events are generated
+at a fixed increment from 0. The increment size may be specified with
+a command-line option (the default is 20). (syslog priority: Warning)
.TP
.B RebuildFinished
@@ -2735,8 +2735,8 @@ When
detects that an array in a spare group has fewer active
devices than necessary for the complete array, and has no spare
devices, it will look for another array in the same spare group that
-has a full complement of working drive and a spare. It will then
-attempt to remove the spare from the second drive and add it to the
+has a full complement of working drives and a spare. It will then
+attempt to remove the spare from the second array and add it to the
first.
If the removal succeeds but the adding fails, then it is added back to
the original array.
@@ -2750,10 +2750,8 @@ and then follow similar steps as above if a matching spare is found.
.SH GROW MODE
The GROW mode is used for changing the size or shape of an active
array.
-For this to work, the kernel must support the necessary change.
-Various types of growth are being added during 2.6 development.
-Currently the supported changes include
+During the kernel 2.6 era the following changes were added:
.IP \(bu 4
change the "size" attribute for RAID1, RAID4, RAID5 and RAID6.
.IP \(bu 4
@@ -2796,8 +2794,8 @@ use more than half of a spare device for backup space.
.SS SIZE CHANGES
Normally when an array is built the "size" is taken from the smallest
-of the drives. If all the small drives in an arrays are, one at a
-time, removed and replaced with larger drives, then you could have an
+of the drives. If all the small drives in an arrays are, over time,
+removed and replaced with larger drives, then you could have an
array of large drives with only a small amount used. In this
situation, changing the "size" with "GROW" mode will allow the extra
space to start being used. If the size is increased in this way, a
@@ -2812,7 +2810,7 @@ after growing, or to reduce its size
.B prior
to shrinking the array.
-Also the size of an array cannot be changed while it has an active
+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.
@@ -2892,7 +2890,7 @@ long time. A
is required. If the array is not simultaneously being grown or
shrunk, so that the array size will remain the same - for example,
reshaping a 3-drive RAID5 into a 4-drive RAID6 - the backup file will
-be used not just for a "cricital section" but throughout the reshape
+be used not just for a "critical section" but throughout the reshape
operation, as described below under LAYOUT CHANGES.
.SS CHUNK-SIZE AND LAYOUT CHANGES
@@ -2910,7 +2908,7 @@ slowly.
If the reshape is interrupted for any reason, this backup file must be
made available to
.B "mdadm --assemble"
-so the array can be reassembled. Consequently the file cannot be
+so the array can be reassembled. Consequently, the file cannot be
stored on the device being reshaped.
--
2.38.1

View File

@ -1,91 +0,0 @@
From fc6fd4063769f4194c3fb8f77b32b2819e140fb9 Mon Sep 17 00:00:00 2001
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
Date: Thu, 18 Aug 2022 11:47:21 +0200
Subject: [PATCH 55/83] Manage: Block unsafe member failing
Kernel may or may not block mdadm from removing member device if it
will cause arrays failed state. It depends on raid personality
implementation in kernel.
Add verification on requested removal path (#mdadm --set-faulty
command).
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Manage.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 52 insertions(+), 1 deletion(-)
diff --git a/Manage.c b/Manage.c
index a142f8bd..b1d0e630 100644
--- a/Manage.c
+++ b/Manage.c
@@ -1285,6 +1285,50 @@ int Manage_with(struct supertype *tst, int fd, struct mddev_dev *dv,
return -1;
}
+/**
+ * is_remove_safe() - Check if remove is safe.
+ * @array: Array info.
+ * @fd: Array file descriptor.
+ * @devname: Name of device to remove.
+ * @verbose: Verbose.
+ *
+ * The function determines if array will be operational
+ * after removing &devname.
+ *
+ * Return: True if array will be operational, false otherwise.
+ */
+bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const int verbose)
+{
+ dev_t devid = devnm2devid(devname + 5);
+ struct mdinfo *mdi = sysfs_read(fd, NULL, GET_DEVS | GET_DISKS | GET_STATE);
+
+ if (!mdi) {
+ if (verbose)
+ pr_err("Failed to read sysfs attributes for %s\n", devname);
+ return false;
+ }
+
+ char *avail = xcalloc(array->raid_disks, sizeof(char));
+
+ for (mdi = mdi->devs; mdi; mdi = mdi->next) {
+ if (mdi->disk.raid_disk < 0)
+ continue;
+ if (!(mdi->disk.state & (1 << MD_DISK_SYNC)))
+ continue;
+ if (makedev(mdi->disk.major, mdi->disk.minor) == devid)
+ continue;
+ avail[mdi->disk.raid_disk] = 1;
+ }
+ sysfs_free(mdi);
+
+ bool is_enough = enough(array->level, array->raid_disks,
+ array->layout, (array->state & 1),
+ avail);
+
+ free(avail);
+ return is_enough;
+}
+
int Manage_subdevs(char *devname, int fd,
struct mddev_dev *devlist, int verbose, int test,
char *update, int force)
@@ -1598,7 +1642,14 @@ int Manage_subdevs(char *devname, int fd,
break;
case 'f': /* set faulty */
- /* FIXME check current member */
+ if (!is_remove_safe(&array, fd, dv->devname, verbose)) {
+ pr_err("Cannot remove %s from %s, array will be failed.\n",
+ dv->devname, devname);
+ if (sysfd >= 0)
+ close(sysfd);
+ goto abort;
+ }
+
if ((sysfd >= 0 && write(sysfd, "faulty", 6) != 6) ||
(sysfd < 0 && ioctl(fd, SET_DISK_FAULTY,
rdev))) {
--
2.38.1

View File

@ -1,112 +0,0 @@
From 55c10e4de13abe3e6934895e1fff7d2d20d0b2c2 Mon Sep 17 00:00:00 2001
From: Pawel Baldysiak <pawel.baldysiak@intel.com>
Date: Thu, 1 Sep 2022 11:20:31 +0200
Subject: [PATCH 56/83] Monitor: Fix statelist memory leaks
Free statelist in error path in Monitor initialization.
Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
Monitor.c | 40 +++++++++++++++++++++++++++++++---------
1 file changed, 31 insertions(+), 9 deletions(-)
diff --git a/Monitor.c b/Monitor.c
index 93f36ac0..b4e954c6 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -74,6 +74,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
int test, struct alert_info *info);
static void try_spare_migration(struct state *statelist, struct alert_info *info);
static void link_containers_with_subarrays(struct state *list);
+static void free_statelist(struct state *statelist);
#ifndef NO_LIBUDEV
static int check_udev_activity(void);
#endif
@@ -128,7 +129,6 @@ int Monitor(struct mddev_dev *devlist,
*/
struct state *statelist = NULL;
- struct state *st2;
int finished = 0;
struct mdstat_ent *mdstat = NULL;
char *mailfrom;
@@ -185,12 +185,14 @@ int Monitor(struct mddev_dev *devlist,
continue;
if (strcasecmp(mdlist->devname, "<ignore>") == 0)
continue;
+ if (!is_mddev(mdlist->devname)) {
+ free_statelist(statelist);
+ return 1;
+ }
st = xcalloc(1, sizeof *st);
snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"),
"/dev/md/%s", basename(mdlist->devname));
- if (!is_mddev(mdlist->devname))
- return 1;
st->next = statelist;
st->devnm[0] = 0;
st->percent = RESYNC_UNKNOWN;
@@ -206,8 +208,10 @@ int Monitor(struct mddev_dev *devlist,
for (dv = devlist; dv; dv = dv->next) {
struct state *st;
- if (!is_mddev(dv->devname))
+ if (!is_mddev(dv->devname)) {
+ free_statelist(statelist);
return 1;
+ }
st = xcalloc(1, sizeof *st);
mdlist = conf_get_ident(dv->devname);
@@ -294,16 +298,16 @@ int Monitor(struct mddev_dev *devlist,
for (stp = &statelist; (st = *stp) != NULL; ) {
if (st->from_auto && st->err > 5) {
*stp = st->next;
- free(st->spare_group);
+ if (st->spare_group)
+ free(st->spare_group);
+
free(st);
} else
stp = &st->next;
}
}
- for (st2 = statelist; st2; st2 = statelist) {
- statelist = st2->next;
- free(st2);
- }
+
+ free_statelist(statelist);
if (pidfile)
unlink(pidfile);
@@ -1056,6 +1060,24 @@ static void link_containers_with_subarrays(struct state *list)
}
}
+/**
+ * free_statelist() - Frees statelist.
+ * @statelist: statelist to free
+ */
+static void free_statelist(struct state *statelist)
+{
+ struct state *tmp = NULL;
+
+ while (statelist) {
+ if (statelist->spare_group)
+ free(statelist->spare_group);
+
+ tmp = statelist;
+ statelist = statelist->next;
+ free(tmp);
+ }
+}
+
#ifndef NO_LIBUDEV
/* function: check_udev_activity
* Description: Function waits for udev to finish
--
2.38.1

View File

@ -1,64 +0,0 @@
From ea7a02a3294aae223e1329aed5da7f4aa3ac05c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Old=C5=99ich=20Jedli=C4=8Dka?= <oldium.pro@gmail.com>
Date: Wed, 31 Aug 2022 19:57:29 +0200
Subject: [PATCH 57/83] mdadm: added support for Intel Alderlake RST on VMD
platform
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Alderlake RST on VMD uses RstVmdV UEFI variable name, so detect it.
Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
Reviewed-by: Kinga Tanska <kinga.tanska@linux.intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
---
platform-intel.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/platform-intel.c b/platform-intel.c
index 5a8729e7..757f0b1b 100644
--- a/platform-intel.c
+++ b/platform-intel.c
@@ -512,7 +512,8 @@ static const struct imsm_orom *find_imsm_hba_orom(struct sys_dev *hba)
#define AHCI_PROP "RstSataV"
#define AHCI_SSATA_PROP "RstsSatV"
#define AHCI_TSATA_PROP "RsttSatV"
-#define VMD_PROP "RstUefiV"
+#define VROC_VMD_PROP "RstUefiV"
+#define RST_VMD_PROP "RstVmdV"
#define VENDOR_GUID \
EFI_GUID(0x193dfefa, 0xa445, 0x4302, 0x99, 0xd8, 0xef, 0x3a, 0xad, 0x1a, 0x04, 0xc6)
@@ -605,6 +606,7 @@ const struct imsm_orom *find_imsm_efi(struct sys_dev *hba)
struct orom_entry *ret;
static const char * const sata_efivars[] = {AHCI_PROP, AHCI_SSATA_PROP,
AHCI_TSATA_PROP};
+ static const char * const vmd_efivars[] = {VROC_VMD_PROP, RST_VMD_PROP};
unsigned long i;
if (check_env("IMSM_TEST_AHCI_EFI") || check_env("IMSM_TEST_SCU_EFI"))
@@ -636,10 +638,16 @@ const struct imsm_orom *find_imsm_efi(struct sys_dev *hba)
break;
case SYS_DEV_VMD:
- if (!read_efi_variable(&orom, sizeof(orom), VMD_PROP,
- VENDOR_GUID))
- break;
- return NULL;
+ for (i = 0; i < ARRAY_SIZE(vmd_efivars); i++) {
+ if (!read_efi_variable(&orom, sizeof(orom),
+ vmd_efivars[i], VENDOR_GUID))
+ break;
+ }
+
+ if (i == ARRAY_SIZE(vmd_efivars))
+ return NULL;
+
+ break;
default:
return NULL;
}
--
2.38.1

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