import CS mdadm-4.2-12.el9_3
This commit is contained in:
parent
9da1d1df7a
commit
7f41642fd6
@ -0,0 +1,69 @@
|
|||||||
|
From 52c67fcdd6dadc4138ecad73e65599551804d445 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Coly Li <colyli@suse.de>
|
||||||
|
Date: Tue, 15 Feb 2022 21:34:15 +0800
|
||||||
|
Subject: [PATCH 012/125] mdadm/systemd: remove KillMode=none from service file
|
||||||
|
|
||||||
|
For mdadm's systemd configuration, current systemd KillMode is "none" in
|
||||||
|
following service files,
|
||||||
|
- mdadm-grow-continue@.service
|
||||||
|
- mdmon@.service
|
||||||
|
|
||||||
|
This "none" mode is strongly againsted by systemd developers (see man 5
|
||||||
|
systemd.kill for "KillMode=" section), and is considering to remove in
|
||||||
|
future systemd version.
|
||||||
|
|
||||||
|
As systemd developer explained in disuccsion, the systemd kill process
|
||||||
|
is,
|
||||||
|
1. send the signal specified by KillSignal= to the list of processes (if
|
||||||
|
any), TERM is the default
|
||||||
|
2. wait until either the target of process(es) exit or a timeout expires
|
||||||
|
3. if the timeout expires send the signal specified by FinalKillSignal=,
|
||||||
|
KILL is the default
|
||||||
|
|
||||||
|
For "control-group", all remaining processes will receive the SIGTERM
|
||||||
|
signal (by default) and if there are still processes after a period f
|
||||||
|
time, they will get the SIGKILL signal.
|
||||||
|
|
||||||
|
For "mixed", only the main process will receive the SIGTERM signal, and
|
||||||
|
if there are still processes after a period of time, all remaining
|
||||||
|
processes (including the main one) will receive the SIGKILL signal.
|
||||||
|
|
||||||
|
From the above comment, currently KillMode=control-group is a proper
|
||||||
|
kill mode. Since control-gropu is the default kill mode, the fix can be
|
||||||
|
simply removing KillMode=none line from the service file, then the
|
||||||
|
default mode will take effect.
|
||||||
|
|
||||||
|
Signed-off-by: Coly Li <colyli@suse.de>
|
||||||
|
Cc: Benjamin Brunner <bbrunner@suse.com>
|
||||||
|
Cc: Franck Bui <fbui@suse.de>
|
||||||
|
Cc: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
Cc: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Cc: Neil Brown <neilb@suse.de>
|
||||||
|
Cc: Xiao Ni <xni@redhat.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
|
||||||
|
---
|
||||||
|
systemd/mdadm-grow-continue@.service | 1 -
|
||||||
|
systemd/mdmon@.service | 1 -
|
||||||
|
2 files changed, 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service
|
||||||
|
index 5c667d2a..9fdc8ec7 100644
|
||||||
|
--- a/systemd/mdadm-grow-continue@.service
|
||||||
|
+++ b/systemd/mdadm-grow-continue@.service
|
||||||
|
@@ -14,4 +14,3 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I
|
||||||
|
StandardInput=null
|
||||||
|
StandardOutput=null
|
||||||
|
StandardError=null
|
||||||
|
-KillMode=none
|
||||||
|
diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service
|
||||||
|
index 85a3a7c5..77533958 100644
|
||||||
|
--- a/systemd/mdmon@.service
|
||||||
|
+++ b/systemd/mdmon@.service
|
||||||
|
@@ -25,4 +25,3 @@ Type=forking
|
||||||
|
# it out) and systemd will remove it when transitioning from
|
||||||
|
# initramfs to rootfs.
|
||||||
|
#PIDFile=/run/mdadm/%I.pid
|
||||||
|
-KillMode=none
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,54 @@
|
|||||||
|
From 28a083955c6f58f8e582734c8c82aff909a7d461 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Thu, 2 Feb 2023 08:56:31 +0100
|
||||||
|
Subject: [PATCH 084/125] Revert "mdadm/systemd: remove KillMode=none from
|
||||||
|
service file"
|
||||||
|
|
||||||
|
This reverts commit 52c67fcdd6dadc4138ecad73e65599551804d445.
|
||||||
|
|
||||||
|
The functionality is marked as deprecated but we don't have alternative
|
||||||
|
solution yet. Shutdown hangs if OS is installed on external array:
|
||||||
|
|
||||||
|
task:umount state:D stack: 0 pid: 6285 ppid: flags:0x00004084
|
||||||
|
Call Trace:
|
||||||
|
__schedule+0x2d1/0x830
|
||||||
|
? finish_wait+0x80/0x80
|
||||||
|
schedule+0x35/0xa0
|
||||||
|
md_write_start+0x14b/0x220
|
||||||
|
? finish_wait+0x80/0x80
|
||||||
|
raid1_make_request+0x3c/0x90 [raid1]
|
||||||
|
md_handle_request+0x128/0x1b0
|
||||||
|
md_make_request+0x5b/0xb0
|
||||||
|
generic_make_request_no_check+0x202/0x330
|
||||||
|
submit_bio+0x3c/0x160
|
||||||
|
|
||||||
|
Use it until new solution is implemented.
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
systemd/mdadm-grow-continue@.service | 1 +
|
||||||
|
systemd/mdmon@.service | 1 +
|
||||||
|
2 files changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service
|
||||||
|
index 64b8254a..9ccadca3 100644
|
||||||
|
--- a/systemd/mdadm-grow-continue@.service
|
||||||
|
+++ b/systemd/mdadm-grow-continue@.service
|
||||||
|
@@ -15,3 +15,4 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I
|
||||||
|
StandardInput=null
|
||||||
|
StandardOutput=null
|
||||||
|
StandardError=null
|
||||||
|
+KillMode=none
|
||||||
|
diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service
|
||||||
|
index 97a1acd9..cb6482d9 100644
|
||||||
|
--- a/systemd/mdmon@.service
|
||||||
|
+++ b/systemd/mdmon@.service
|
||||||
|
@@ -26,3 +26,4 @@ Type=forking
|
||||||
|
# it out) and systemd will remove it when transitioning from
|
||||||
|
# initramfs to rootfs.
|
||||||
|
#PIDFile=/run/mdadm/%I.pid
|
||||||
|
+KillMode=none
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
From d07e561810a2e33b667a8a9476edaff42eb119b9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Heming Zhao <heming.zhao@suse.com>
|
||||||
|
Date: Thu, 23 Feb 2023 22:39:39 +0800
|
||||||
|
Subject: [PATCH 085/125] Grow: fix can't change bitmap type from none to
|
||||||
|
clustered.
|
||||||
|
|
||||||
|
Commit a042210648ed ("disallow create or grow clustered bitmap with
|
||||||
|
writemostly set") introduced this bug. We should use 'true' logic not
|
||||||
|
'== 0' to deny setting up clustered array under WRITEMOSTLY condition.
|
||||||
|
|
||||||
|
How to trigger
|
||||||
|
|
||||||
|
```
|
||||||
|
~/mdadm # ./mdadm -Ss && ./mdadm --zero-superblock /dev/sd{a,b}
|
||||||
|
~/mdadm # ./mdadm -C /dev/md0 -l mirror -b clustered -e 1.2 -n 2 \
|
||||||
|
/dev/sda /dev/sdb --assume-clean
|
||||||
|
mdadm: array /dev/md0 started.
|
||||||
|
~/mdadm # ./mdadm --grow /dev/md0 --bitmap=none
|
||||||
|
~/mdadm # ./mdadm --grow /dev/md0 --bitmap=clustered
|
||||||
|
mdadm: /dev/md0 disks marked write-mostly are not supported with clustered bitmap
|
||||||
|
```
|
||||||
|
|
||||||
|
Signed-off-by: Heming Zhao <heming.zhao@suse.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Grow.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/Grow.c b/Grow.c
|
||||||
|
index 8f5cf07d..bb5fe45c 100644
|
||||||
|
--- a/Grow.c
|
||||||
|
+++ b/Grow.c
|
||||||
|
@@ -429,7 +429,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
|
||||||
|
dv = map_dev(disk.major, disk.minor, 1);
|
||||||
|
if (!dv)
|
||||||
|
continue;
|
||||||
|
- if (((disk.state & (1 << MD_DISK_WRITEMOSTLY)) == 0) &&
|
||||||
|
+ if ((disk.state & (1 << MD_DISK_WRITEMOSTLY)) &&
|
||||||
|
(strcmp(s->bitmap_file, "clustered") == 0)) {
|
||||||
|
pr_err("%s disks marked write-mostly are not supported with clustered bitmap\n",devname);
|
||||||
|
free(mdi);
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
76
SOURCES/0086-Fix-NULL-dereference-in-super_by_fd.patch
Normal file
76
SOURCES/0086-Fix-NULL-dereference-in-super_by_fd.patch
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
From f1f3ef7d2de5e3a726c27b9f9bb20e270a100dab Mon Sep 17 00:00:00 2001
|
||||||
|
From: Li Xiao Keng <lixiaokeng@huawei.com>
|
||||||
|
Date: Mon, 27 Feb 2023 11:12:07 +0800
|
||||||
|
Subject: [PATCH 086/125] Fix NULL dereference in super_by_fd
|
||||||
|
|
||||||
|
When we create 100 partitions (major is 259 not 254) in a raid device,
|
||||||
|
mdadm may coredump:
|
||||||
|
|
||||||
|
Core was generated by `/usr/sbin/mdadm --detail --export /dev/md1p7'.
|
||||||
|
Program terminated with signal SIGSEGV, Segmentation fault.
|
||||||
|
#0 __strlen_avx2_rtm () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:74
|
||||||
|
74 VPCMPEQ (%rdi), %ymm0, %ymm1
|
||||||
|
(gdb) bt
|
||||||
|
#0 __strlen_avx2_rtm () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:74
|
||||||
|
#1 0x00007fbb9a7e4139 in __strcpy_chk (dest=dest@entry=0x55d55d6a13ac "", src=0x0, destlen=destlen@entry=32) at strcpy_chk.c:28
|
||||||
|
#2 0x000055d55ba1766d in strcpy (__src=<optimized out>, __dest=0x55d55d6a13ac "") at /usr/include/bits/string_fortified.h:79
|
||||||
|
#3 super_by_fd (fd=fd@entry=3, subarrayp=subarrayp@entry=0x7fff44dfcc48) at util.c:1289
|
||||||
|
#4 0x000055d55ba273a6 in Detail (dev=0x7fff44dfef0b "/dev/md1p7", c=0x7fff44dfe440) at Detail.c:101
|
||||||
|
#5 0x000055d55ba0de61 in misc_list (c=<optimized out>, ss=<optimized out>, dump_directory=<optimized out>, ident=<optimized out>, devlist=<optimized out>) at mdadm.c:1959
|
||||||
|
#6 main (argc=<optimized out>, argv=<optimized out>) at mdadm.c:1629
|
||||||
|
|
||||||
|
The direct cause is fd2devnm returning NULL, so add a check.
|
||||||
|
|
||||||
|
Signed-off-by: Li Xiao Keng <lixiaokeng@huawei.com>
|
||||||
|
Signed-off-by: Wu Guang Hao <wuguanghao3@huawei.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de <mailto:colyli@suse.de>>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
mapfile.c | 4 ++++
|
||||||
|
util.c | 7 ++++++-
|
||||||
|
2 files changed, 10 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/mapfile.c b/mapfile.c
|
||||||
|
index 6b2207dd..ac351768 100644
|
||||||
|
--- a/mapfile.c
|
||||||
|
+++ b/mapfile.c
|
||||||
|
@@ -292,6 +292,10 @@ struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4])
|
||||||
|
struct map_ent *map_by_devnm(struct map_ent **map, char *devnm)
|
||||||
|
{
|
||||||
|
struct map_ent *mp;
|
||||||
|
+
|
||||||
|
+ if (!devnm)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
if (!*map)
|
||||||
|
map_read(map);
|
||||||
|
|
||||||
|
diff --git a/util.c b/util.c
|
||||||
|
index 9cd89fa4..8c7f3fd5 100644
|
||||||
|
--- a/util.c
|
||||||
|
+++ b/util.c
|
||||||
|
@@ -1160,6 +1160,11 @@ struct supertype *super_by_fd(int fd, char **subarrayp)
|
||||||
|
int i;
|
||||||
|
char *subarray = NULL;
|
||||||
|
char container[32] = "";
|
||||||
|
+ char *devnm = NULL;
|
||||||
|
+
|
||||||
|
+ devnm = fd2devnm(fd);
|
||||||
|
+ if (!devnm)
|
||||||
|
+ return NULL;
|
||||||
|
|
||||||
|
sra = sysfs_read(fd, NULL, GET_VERSION);
|
||||||
|
|
||||||
|
@@ -1205,7 +1210,7 @@ struct supertype *super_by_fd(int fd, char **subarrayp)
|
||||||
|
if (subarrayp)
|
||||||
|
*subarrayp = subarray;
|
||||||
|
strcpy(st->container_devnm, container);
|
||||||
|
- strcpy(st->devnm, fd2devnm(fd));
|
||||||
|
+ strncpy(st->devnm, devnm, MD_NAME_MAX - 1);
|
||||||
|
} else
|
||||||
|
free(subarray);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
369
SOURCES/0087-Mdmonitor-Make-alert_info-global.patch
Normal file
369
SOURCES/0087-Mdmonitor-Make-alert_info-global.patch
Normal file
@ -0,0 +1,369 @@
|
|||||||
|
From b301516615c441bd3cc4b512fae73fc066d227f1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Date: Thu, 2 Feb 2023 12:26:59 +0100
|
||||||
|
Subject: [PATCH 087/125] Mdmonitor: Make alert_info global
|
||||||
|
|
||||||
|
Move information about --test flag and hostname into alert_info.
|
||||||
|
|
||||||
|
Signed-off-by: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Monitor.c | 124 +++++++++++++++++++++++++++---------------------------
|
||||||
|
1 file changed, 61 insertions(+), 63 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Monitor.c b/Monitor.c
|
||||||
|
index 188cb8be..9ef4dab8 100644
|
||||||
|
--- a/Monitor.c
|
||||||
|
+++ b/Monitor.c
|
||||||
|
@@ -58,21 +58,20 @@ struct state {
|
||||||
|
};
|
||||||
|
|
||||||
|
struct alert_info {
|
||||||
|
+ char hostname[HOST_NAME_MAX];
|
||||||
|
char *mailaddr;
|
||||||
|
char *mailfrom;
|
||||||
|
char *alert_cmd;
|
||||||
|
int dosyslog;
|
||||||
|
-};
|
||||||
|
+ int test;
|
||||||
|
+} info;
|
||||||
|
static int make_daemon(char *pidfile);
|
||||||
|
static int check_one_sharer(int scan);
|
||||||
|
static void write_autorebuild_pid(void);
|
||||||
|
-static void alert(const char *event, const char *dev, const char *disc, struct alert_info *info);
|
||||||
|
-static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
- int test, struct alert_info *info,
|
||||||
|
- int increments, char *prefer);
|
||||||
|
-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 alert(const char *event, const char *dev, const char *disc);
|
||||||
|
+static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer);
|
||||||
|
+static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist);
|
||||||
|
+static void try_spare_migration(struct state *statelist);
|
||||||
|
static void link_containers_with_subarrays(struct state *list);
|
||||||
|
static void free_statelist(struct state *statelist);
|
||||||
|
#ifndef NO_LIBUDEV
|
||||||
|
@@ -132,7 +131,6 @@ int Monitor(struct mddev_dev *devlist,
|
||||||
|
int finished = 0;
|
||||||
|
struct mdstat_ent *mdstat = NULL;
|
||||||
|
char *mailfrom;
|
||||||
|
- struct alert_info info;
|
||||||
|
struct mddev_ident *mdlist;
|
||||||
|
int delay_for_event = c->delay;
|
||||||
|
|
||||||
|
@@ -166,6 +164,13 @@ int Monitor(struct mddev_dev *devlist,
|
||||||
|
info.mailaddr = mailaddr;
|
||||||
|
info.mailfrom = mailfrom;
|
||||||
|
info.dosyslog = dosyslog;
|
||||||
|
+ info.test = c->test;
|
||||||
|
+
|
||||||
|
+ if (gethostname(info.hostname, sizeof(info.hostname)) != 0) {
|
||||||
|
+ pr_err("Cannot get hostname.\n");
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ info.hostname[sizeof(info.hostname) - 1] = '\0';
|
||||||
|
|
||||||
|
if (share){
|
||||||
|
if (check_one_sharer(c->scan))
|
||||||
|
@@ -241,8 +246,7 @@ int Monitor(struct mddev_dev *devlist,
|
||||||
|
mdstat = mdstat_read(oneshot ? 0 : 1, 0);
|
||||||
|
|
||||||
|
for (st = statelist; st; st = st->next) {
|
||||||
|
- if (check_array(st, mdstat, c->test, &info,
|
||||||
|
- increments, c->prefer))
|
||||||
|
+ if (check_array(st, mdstat, increments, c->prefer))
|
||||||
|
anydegraded = 1;
|
||||||
|
/* for external arrays, metadata is filled for
|
||||||
|
* containers only
|
||||||
|
@@ -255,15 +259,14 @@ int Monitor(struct mddev_dev *devlist,
|
||||||
|
|
||||||
|
/* now check if there are any new devices found in mdstat */
|
||||||
|
if (c->scan)
|
||||||
|
- new_found = add_new_arrays(mdstat, &statelist, c->test,
|
||||||
|
- &info);
|
||||||
|
+ new_found = add_new_arrays(mdstat, &statelist);
|
||||||
|
|
||||||
|
/* If an array has active < raid && spare == 0 && spare_group != NULL
|
||||||
|
* Look for another array with spare > 0 and active == raid and same spare_group
|
||||||
|
* if found, choose a device and hotremove/hotadd
|
||||||
|
*/
|
||||||
|
if (share && anydegraded)
|
||||||
|
- try_spare_migration(statelist, &info);
|
||||||
|
+ try_spare_migration(statelist);
|
||||||
|
if (!new_found) {
|
||||||
|
if (oneshot)
|
||||||
|
break;
|
||||||
|
@@ -294,7 +297,7 @@ int Monitor(struct mddev_dev *devlist,
|
||||||
|
mdstat_close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- c->test = 0;
|
||||||
|
+ info.test = 0;
|
||||||
|
|
||||||
|
for (stp = &statelist; (st = *stp) != NULL; ) {
|
||||||
|
if (st->from_auto && st->err > 5) {
|
||||||
|
@@ -412,7 +415,7 @@ static void write_autorebuild_pid()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void execute_alert_cmd(const char *event, const char *dev, const char *disc, struct alert_info *info)
|
||||||
|
+static void execute_alert_cmd(const char *event, const char *dev, const char *disc)
|
||||||
|
{
|
||||||
|
int pid = fork();
|
||||||
|
|
||||||
|
@@ -424,15 +427,14 @@ static void execute_alert_cmd(const char *event, const char *dev, const char *di
|
||||||
|
pr_err("Cannot fork to execute alert command");
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
- execl(info->alert_cmd, info->alert_cmd, event, dev, disc, NULL);
|
||||||
|
+ execl(info.alert_cmd, info.alert_cmd, event, dev, disc, NULL);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void send_event_email(const char *event, const char *dev, const char *disc, struct alert_info *info)
|
||||||
|
+static void send_event_email(const char *event, const char *dev, const char *disc)
|
||||||
|
{
|
||||||
|
FILE *mp, *mdstat;
|
||||||
|
- char hname[256];
|
||||||
|
char buf[BUFSIZ];
|
||||||
|
int n;
|
||||||
|
|
||||||
|
@@ -442,14 +444,13 @@ static void send_event_email(const char *event, const char *dev, const char *dis
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- gethostname(hname, sizeof(hname));
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
- if (info->mailfrom)
|
||||||
|
- fprintf(mp, "From: %s\n", info->mailfrom);
|
||||||
|
+ if (info.mailfrom)
|
||||||
|
+ fprintf(mp, "From: %s\n", info.mailfrom);
|
||||||
|
else
|
||||||
|
fprintf(mp, "From: %s monitoring <root>\n", Name);
|
||||||
|
- fprintf(mp, "To: %s\n", info->mailaddr);
|
||||||
|
- fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, hname);
|
||||||
|
+ fprintf(mp, "To: %s\n", info.mailaddr);
|
||||||
|
+ fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, info.hostname);
|
||||||
|
fprintf(mp, "This is an automatically generated mail message. \n");
|
||||||
|
fprintf(mp, "A %s event had been detected on md device %s.\n\n", event, dev);
|
||||||
|
|
||||||
|
@@ -501,37 +502,36 @@ static void log_event_to_syslog(const char *event, const char *dev, const char *
|
||||||
|
syslog(priority, "%s event detected on md device %s", event, dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void alert(const char *event, const char *dev, const char *disc, struct alert_info *info)
|
||||||
|
+static void alert(const char *event, const char *dev, const char *disc)
|
||||||
|
{
|
||||||
|
- if (!info->alert_cmd && !info->mailaddr && !info->dosyslog) {
|
||||||
|
+ if (!info.alert_cmd && !info.mailaddr && !info.dosyslog) {
|
||||||
|
time_t now = time(0);
|
||||||
|
|
||||||
|
printf("%1.15s: %s on %s %s\n", ctime(&now) + 4,
|
||||||
|
event, dev, disc?disc:"unknown device");
|
||||||
|
}
|
||||||
|
- if (info->alert_cmd)
|
||||||
|
- execute_alert_cmd(event, dev, disc, info);
|
||||||
|
+ if (info.alert_cmd)
|
||||||
|
+ execute_alert_cmd(event, dev, disc);
|
||||||
|
|
||||||
|
- if (info->mailaddr && (strncmp(event, "Fail", 4) == 0 ||
|
||||||
|
+ if (info.mailaddr && (strncmp(event, "Fail", 4) == 0 ||
|
||||||
|
strncmp(event, "Test", 4) == 0 ||
|
||||||
|
strncmp(event, "Spares", 6) == 0 ||
|
||||||
|
strncmp(event, "Degrade", 7) == 0)) {
|
||||||
|
- send_event_email(event, dev, disc, info);
|
||||||
|
+ send_event_email(event, dev, disc);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (info->dosyslog)
|
||||||
|
+ if (info.dosyslog)
|
||||||
|
log_event_to_syslog(event, dev, disc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
- int test, struct alert_info *ainfo,
|
||||||
|
int increments, char *prefer)
|
||||||
|
{
|
||||||
|
/* Update the state 'st' to reflect any changes shown in mdstat,
|
||||||
|
* or found by directly examining the array, and return
|
||||||
|
* '1' if the array is degraded, or '0' if it is optimal (or dead).
|
||||||
|
*/
|
||||||
|
- struct { int state, major, minor; } info[MAX_DISKS];
|
||||||
|
+ struct { int state, major, minor; } disks_info[MAX_DISKS];
|
||||||
|
struct mdinfo *sra = NULL;
|
||||||
|
mdu_array_info_t array;
|
||||||
|
struct mdstat_ent *mse = NULL, *mse2;
|
||||||
|
@@ -545,8 +545,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
int is_container = 0;
|
||||||
|
unsigned long redundancy_only_flags = 0;
|
||||||
|
|
||||||
|
- if (test)
|
||||||
|
- alert("TestMessage", dev, NULL, ainfo);
|
||||||
|
+ if (info.test)
|
||||||
|
+ alert("TestMessage", dev, NULL);
|
||||||
|
|
||||||
|
retval = 0;
|
||||||
|
|
||||||
|
@@ -595,7 +595,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
*/
|
||||||
|
if (sra->array.level == 0 || sra->array.level == -1) {
|
||||||
|
if (!st->err && !st->from_config)
|
||||||
|
- alert("DeviceDisappeared", dev, " Wrong-Level", ainfo);
|
||||||
|
+ alert("DeviceDisappeared", dev, " Wrong-Level");
|
||||||
|
st->err++;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
@@ -612,7 +612,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
st->percent = RESYNC_NONE;
|
||||||
|
new_array = 1;
|
||||||
|
if (!is_container)
|
||||||
|
- alert("NewArray", st->devname, NULL, ainfo);
|
||||||
|
+ alert("NewArray", st->devname, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (st->utime == array.utime && st->failed == sra->array.failed_disks &&
|
||||||
|
@@ -625,14 +625,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
}
|
||||||
|
if (st->utime == 0 && /* new array */
|
||||||
|
mse->pattern && strchr(mse->pattern, '_') /* degraded */)
|
||||||
|
- alert("DegradedArray", dev, NULL, ainfo);
|
||||||
|
+ alert("DegradedArray", dev, NULL);
|
||||||
|
|
||||||
|
if (st->utime == 0 && /* new array */ st->expected_spares > 0 &&
|
||||||
|
sra->array.spare_disks < st->expected_spares)
|
||||||
|
- alert("SparesMissing", dev, NULL, ainfo);
|
||||||
|
+ alert("SparesMissing", dev, NULL);
|
||||||
|
if (st->percent < 0 && st->percent != RESYNC_UNKNOWN &&
|
||||||
|
mse->percent >= 0)
|
||||||
|
- alert("RebuildStarted", dev, NULL, ainfo);
|
||||||
|
+ alert("RebuildStarted", dev, NULL);
|
||||||
|
if (st->percent >= 0 && mse->percent >= 0 &&
|
||||||
|
(mse->percent / increments) > (st->percent / increments)) {
|
||||||
|
char percentalert[18];
|
||||||
|
@@ -647,7 +647,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
snprintf(percentalert, sizeof(percentalert),
|
||||||
|
"Rebuild%02d", mse->percent);
|
||||||
|
|
||||||
|
- alert(percentalert, dev, NULL, ainfo);
|
||||||
|
+ alert(percentalert, dev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mse->percent == RESYNC_NONE && st->percent >= 0) {
|
||||||
|
@@ -660,9 +660,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
snprintf(cnt, sizeof(cnt),
|
||||||
|
" mismatches found: %d (on raid level %d)",
|
||||||
|
sra->mismatch_cnt, sra->array.level);
|
||||||
|
- alert("RebuildFinished", dev, cnt, ainfo);
|
||||||
|
+ alert("RebuildFinished", dev, cnt);
|
||||||
|
} else
|
||||||
|
- alert("RebuildFinished", dev, NULL, ainfo);
|
||||||
|
+ alert("RebuildFinished", dev, NULL);
|
||||||
|
}
|
||||||
|
st->percent = mse->percent;
|
||||||
|
|
||||||
|
@@ -671,13 +671,13 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
mdu_disk_info_t disc;
|
||||||
|
disc.number = i;
|
||||||
|
if (md_get_disk_info(fd, &disc) >= 0) {
|
||||||
|
- info[i].state = disc.state;
|
||||||
|
- info[i].major = disc.major;
|
||||||
|
- info[i].minor = disc.minor;
|
||||||
|
+ disks_info[i].state = disc.state;
|
||||||
|
+ disks_info[i].major = disc.major;
|
||||||
|
+ disks_info[i].minor = disc.minor;
|
||||||
|
if (disc.major || disc.minor)
|
||||||
|
remaining_disks --;
|
||||||
|
} else
|
||||||
|
- info[i].major = info[i].minor = 0;
|
||||||
|
+ disks_info[i].major = disks_info[i].minor = 0;
|
||||||
|
}
|
||||||
|
last_disk = i;
|
||||||
|
|
||||||
|
@@ -700,13 +700,13 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
int change;
|
||||||
|
char *dv = NULL;
|
||||||
|
disc.number = i;
|
||||||
|
- if (i < last_disk && (info[i].major || info[i].minor)) {
|
||||||
|
- newstate = info[i].state;
|
||||||
|
- dv = map_dev_preferred(info[i].major, info[i].minor, 1,
|
||||||
|
+ if (i < last_disk && (disks_info[i].major || disks_info[i].minor)) {
|
||||||
|
+ newstate = disks_info[i].state;
|
||||||
|
+ dv = map_dev_preferred(disks_info[i].major, disks_info[i].minor, 1,
|
||||||
|
prefer);
|
||||||
|
disc.state = newstate;
|
||||||
|
- disc.major = info[i].major;
|
||||||
|
- disc.minor = info[i].minor;
|
||||||
|
+ disc.major = disks_info[i].major;
|
||||||
|
+ disc.minor = disks_info[i].minor;
|
||||||
|
} else
|
||||||
|
newstate = (1 << MD_DISK_REMOVED);
|
||||||
|
|
||||||
|
@@ -716,14 +716,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
change = newstate ^ st->devstate[i];
|
||||||
|
if (st->utime && change && !st->err && !new_array) {
|
||||||
|
if ((st->devstate[i]&change) & (1 << MD_DISK_SYNC))
|
||||||
|
- alert("Fail", dev, dv, ainfo);
|
||||||
|
+ alert("Fail", dev, dv);
|
||||||
|
else if ((newstate & (1 << MD_DISK_FAULTY)) &&
|
||||||
|
(disc.major || disc.minor) &&
|
||||||
|
st->devid[i] == makedev(disc.major,
|
||||||
|
disc.minor))
|
||||||
|
- alert("FailSpare", dev, dv, ainfo);
|
||||||
|
+ alert("FailSpare", dev, dv);
|
||||||
|
else if ((newstate&change) & (1 << MD_DISK_SYNC))
|
||||||
|
- alert("SpareActive", dev, dv, ainfo);
|
||||||
|
+ alert("SpareActive", dev, dv);
|
||||||
|
}
|
||||||
|
st->devstate[i] = newstate;
|
||||||
|
st->devid[i] = makedev(disc.major, disc.minor);
|
||||||
|
@@ -747,13 +747,12 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
|
||||||
|
disappeared:
|
||||||
|
if (!st->err && !is_container)
|
||||||
|
- alert("DeviceDisappeared", dev, NULL, ainfo);
|
||||||
|
+ alert("DeviceDisappeared", dev, NULL);
|
||||||
|
st->err++;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
|
||||||
|
- int test, struct alert_info *info)
|
||||||
|
+static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist)
|
||||||
|
{
|
||||||
|
struct mdstat_ent *mse;
|
||||||
|
int new_found = 0;
|
||||||
|
@@ -806,8 +805,8 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
|
||||||
|
} else
|
||||||
|
st->parent_devnm[0] = 0;
|
||||||
|
*statelist = st;
|
||||||
|
- if (test)
|
||||||
|
- alert("TestMessage", st->devname, NULL, info);
|
||||||
|
+ if (info.test)
|
||||||
|
+ alert("TestMessage", st->devname, NULL);
|
||||||
|
new_found = 1;
|
||||||
|
}
|
||||||
|
return new_found;
|
||||||
|
@@ -971,7 +970,7 @@ static dev_t container_choose_spare(struct state *from, struct state *to,
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void try_spare_migration(struct state *statelist, struct alert_info *info)
|
||||||
|
+static void try_spare_migration(struct state *statelist)
|
||||||
|
{
|
||||||
|
struct state *from;
|
||||||
|
struct state *st;
|
||||||
|
@@ -1030,8 +1029,7 @@ static void try_spare_migration(struct state *statelist, struct alert_info *info
|
||||||
|
if (devid > 0 &&
|
||||||
|
move_spare(from->devname, to->devname,
|
||||||
|
devid)) {
|
||||||
|
- alert("MoveSpare", to->devname,
|
||||||
|
- from->devname, info);
|
||||||
|
+ alert("MoveSpare", to->devname, from->devname);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,313 @@
|
|||||||
|
From 50232a6ec4a5c46c608181d72d0c633831a03134 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Date: Thu, 2 Feb 2023 12:27:00 +0100
|
||||||
|
Subject: [PATCH 088/125] Mdmonitor: Pass events to alert() using enums instead
|
||||||
|
of strings
|
||||||
|
|
||||||
|
Add events enum, and mapping_t struct, that maps them to strings, so
|
||||||
|
that enums are passed around instead of strings.
|
||||||
|
|
||||||
|
Signed-off-by: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Monitor.c | 136 +++++++++++++++++++++++++++++++++---------------------
|
||||||
|
1 file changed, 83 insertions(+), 53 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Monitor.c b/Monitor.c
|
||||||
|
index 9ef4dab8..029e9efd 100644
|
||||||
|
--- a/Monitor.c
|
||||||
|
+++ b/Monitor.c
|
||||||
|
@@ -32,6 +32,8 @@
|
||||||
|
#include <libudev.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#define EVENT_NAME_MAX 32
|
||||||
|
+
|
||||||
|
struct state {
|
||||||
|
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 */
|
||||||
|
@@ -65,10 +67,43 @@ struct alert_info {
|
||||||
|
int dosyslog;
|
||||||
|
int test;
|
||||||
|
} info;
|
||||||
|
+
|
||||||
|
+enum event {
|
||||||
|
+ EVENT_SPARE_ACTIVE = 0,
|
||||||
|
+ EVENT_NEW_ARRAY,
|
||||||
|
+ EVENT_MOVE_SPARE,
|
||||||
|
+ EVENT_TEST_MESSAGE,
|
||||||
|
+ EVENT_REBUILD_STARTED,
|
||||||
|
+ EVENT_REBUILD,
|
||||||
|
+ EVENT_REBUILD_FINISHED,
|
||||||
|
+ EVENT_SPARES_MISSING,
|
||||||
|
+ EVENT_DEVICE_DISAPPEARED,
|
||||||
|
+ EVENT_FAIL,
|
||||||
|
+ EVENT_FAIL_SPARE,
|
||||||
|
+ EVENT_DEGRADED_ARRAY,
|
||||||
|
+ EVENT_UNKNOWN
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+mapping_t events_map[] = {
|
||||||
|
+ {"SpareActive", EVENT_SPARE_ACTIVE},
|
||||||
|
+ {"NewArray", EVENT_NEW_ARRAY},
|
||||||
|
+ {"MoveSpare", EVENT_MOVE_SPARE},
|
||||||
|
+ {"TestMessage", EVENT_TEST_MESSAGE},
|
||||||
|
+ {"RebuildStarted", EVENT_REBUILD_STARTED},
|
||||||
|
+ {"Rebuild", EVENT_REBUILD},
|
||||||
|
+ {"RebuildFinished", EVENT_REBUILD_FINISHED},
|
||||||
|
+ {"SparesMissing", EVENT_SPARES_MISSING},
|
||||||
|
+ {"DeviceDisappeared", EVENT_DEVICE_DISAPPEARED},
|
||||||
|
+ {"Fail", EVENT_FAIL},
|
||||||
|
+ {"FailSpare", EVENT_FAIL_SPARE},
|
||||||
|
+ {"DegradedArray", EVENT_DEGRADED_ARRAY},
|
||||||
|
+ {NULL, EVENT_UNKNOWN}
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
static int make_daemon(char *pidfile);
|
||||||
|
static int check_one_sharer(int scan);
|
||||||
|
static void write_autorebuild_pid(void);
|
||||||
|
-static void alert(const char *event, const char *dev, const char *disc);
|
||||||
|
+static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc);
|
||||||
|
static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer);
|
||||||
|
static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist);
|
||||||
|
static void try_spare_migration(struct state *statelist);
|
||||||
|
@@ -415,7 +450,7 @@ static void write_autorebuild_pid()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void execute_alert_cmd(const char *event, const char *dev, const char *disc)
|
||||||
|
+static void execute_alert_cmd(const char *event_name, const char *dev, const char *disc)
|
||||||
|
{
|
||||||
|
int pid = fork();
|
||||||
|
|
||||||
|
@@ -427,12 +462,12 @@ static void execute_alert_cmd(const char *event, const char *dev, const char *di
|
||||||
|
pr_err("Cannot fork to execute alert command");
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
- execl(info.alert_cmd, info.alert_cmd, event, dev, disc, NULL);
|
||||||
|
+ execl(info.alert_cmd, info.alert_cmd, event_name, dev, disc, NULL);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void send_event_email(const char *event, const char *dev, const char *disc)
|
||||||
|
+static void send_event_email(const char *event_name, const char *dev, const char *disc)
|
||||||
|
{
|
||||||
|
FILE *mp, *mdstat;
|
||||||
|
char buf[BUFSIZ];
|
||||||
|
@@ -450,9 +485,9 @@ static void send_event_email(const char *event, const char *dev, const char *dis
|
||||||
|
else
|
||||||
|
fprintf(mp, "From: %s monitoring <root>\n", Name);
|
||||||
|
fprintf(mp, "To: %s\n", info.mailaddr);
|
||||||
|
- fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, info.hostname);
|
||||||
|
+ fprintf(mp, "Subject: %s event on %s:%s\n\n", event_name, dev, info.hostname);
|
||||||
|
fprintf(mp, "This is an automatically generated mail message. \n");
|
||||||
|
- fprintf(mp, "A %s event had been detected on md device %s.\n\n", event, dev);
|
||||||
|
+ fprintf(mp, "A %s event had been detected on md device %s.\n\n", event_name, dev);
|
||||||
|
|
||||||
|
if (disc && disc[0] != ' ')
|
||||||
|
fprintf(mp,
|
||||||
|
@@ -474,20 +509,20 @@ static void send_event_email(const char *event, const char *dev, const char *dis
|
||||||
|
pclose(mp);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void log_event_to_syslog(const char *event, const char *dev, const char *disc)
|
||||||
|
+static void log_event_to_syslog(const enum event event_enum, const char *event_name, const char *dev, const char *disc)
|
||||||
|
{
|
||||||
|
int priority;
|
||||||
|
/* Log at a different severity depending on the event.
|
||||||
|
*
|
||||||
|
* These are the critical events: */
|
||||||
|
- if (strncmp(event, "Fail", 4) == 0 ||
|
||||||
|
- strncmp(event, "Degrade", 7) == 0 ||
|
||||||
|
- strncmp(event, "DeviceDisappeared", 17) == 0)
|
||||||
|
+ if (event_enum == EVENT_FAIL ||
|
||||||
|
+ event_enum == EVENT_DEGRADED_ARRAY ||
|
||||||
|
+ event_enum == EVENT_DEVICE_DISAPPEARED)
|
||||||
|
priority = LOG_CRIT;
|
||||||
|
/* Good to know about, but are not failures: */
|
||||||
|
- else if (strncmp(event, "Rebuild", 7) == 0 ||
|
||||||
|
- strncmp(event, "MoveSpare", 9) == 0 ||
|
||||||
|
- strncmp(event, "Spares", 6) != 0)
|
||||||
|
+ else if (event_enum == EVENT_REBUILD ||
|
||||||
|
+ event_enum == EVENT_MOVE_SPARE ||
|
||||||
|
+ event_enum == EVENT_SPARES_MISSING)
|
||||||
|
priority = LOG_WARNING;
|
||||||
|
/* Everything else: */
|
||||||
|
else
|
||||||
|
@@ -495,33 +530,37 @@ static void log_event_to_syslog(const char *event, const char *dev, const char *
|
||||||
|
|
||||||
|
if (disc && disc[0] != ' ')
|
||||||
|
syslog(priority,
|
||||||
|
- "%s event detected on md device %s, component device %s", event, dev, disc);
|
||||||
|
+ "%s event detected on md device %s, component device %s",
|
||||||
|
+ event_name, dev, disc);
|
||||||
|
else if (disc)
|
||||||
|
- syslog(priority, "%s event detected on md device %s: %s", event, dev, disc);
|
||||||
|
+ syslog(priority, "%s event detected on md device %s: %s", event_name, dev, disc);
|
||||||
|
else
|
||||||
|
- syslog(priority, "%s event detected on md device %s", event, dev);
|
||||||
|
+ syslog(priority, "%s event detected on md device %s", event_name, dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void alert(const char *event, const char *dev, const char *disc)
|
||||||
|
+static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc)
|
||||||
|
{
|
||||||
|
- if (!info.alert_cmd && !info.mailaddr && !info.dosyslog) {
|
||||||
|
- time_t now = time(0);
|
||||||
|
+ char event_name[EVENT_NAME_MAX];
|
||||||
|
|
||||||
|
- printf("%1.15s: %s on %s %s\n", ctime(&now) + 4,
|
||||||
|
- event, dev, disc?disc:"unknown device");
|
||||||
|
+ if (event_enum == EVENT_REBUILD) {
|
||||||
|
+ snprintf(event_name, sizeof(event_name), "%s%02d",
|
||||||
|
+ map_num_s(events_map, EVENT_REBUILD), progress);
|
||||||
|
+ } else {
|
||||||
|
+ snprintf(event_name, sizeof(event_name), "%s", map_num_s(events_map, event_enum));
|
||||||
|
}
|
||||||
|
+
|
||||||
|
if (info.alert_cmd)
|
||||||
|
- execute_alert_cmd(event, dev, disc);
|
||||||
|
+ execute_alert_cmd(event_name, dev, disc);
|
||||||
|
|
||||||
|
- if (info.mailaddr && (strncmp(event, "Fail", 4) == 0 ||
|
||||||
|
- strncmp(event, "Test", 4) == 0 ||
|
||||||
|
- strncmp(event, "Spares", 6) == 0 ||
|
||||||
|
- strncmp(event, "Degrade", 7) == 0)) {
|
||||||
|
- send_event_email(event, dev, disc);
|
||||||
|
+ if (info.mailaddr && (event_enum == EVENT_FAIL ||
|
||||||
|
+ event_enum == EVENT_TEST_MESSAGE ||
|
||||||
|
+ event_enum == EVENT_SPARES_MISSING ||
|
||||||
|
+ event_enum == EVENT_DEGRADED_ARRAY)) {
|
||||||
|
+ send_event_email(event_name, dev, disc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.dosyslog)
|
||||||
|
- log_event_to_syslog(event, dev, disc);
|
||||||
|
+ log_event_to_syslog(event_enum, event_name, dev, disc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
@@ -546,7 +585,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
unsigned long redundancy_only_flags = 0;
|
||||||
|
|
||||||
|
if (info.test)
|
||||||
|
- alert("TestMessage", dev, NULL);
|
||||||
|
+ alert(EVENT_TEST_MESSAGE, 0, dev, NULL);
|
||||||
|
|
||||||
|
retval = 0;
|
||||||
|
|
||||||
|
@@ -595,7 +634,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
*/
|
||||||
|
if (sra->array.level == 0 || sra->array.level == -1) {
|
||||||
|
if (!st->err && !st->from_config)
|
||||||
|
- alert("DeviceDisappeared", dev, " Wrong-Level");
|
||||||
|
+ alert(EVENT_DEVICE_DISAPPEARED, 0, dev, " Wrong-Level");
|
||||||
|
st->err++;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
@@ -612,7 +651,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
st->percent = RESYNC_NONE;
|
||||||
|
new_array = 1;
|
||||||
|
if (!is_container)
|
||||||
|
- alert("NewArray", st->devname, NULL);
|
||||||
|
+ alert(EVENT_NEW_ARRAY, 0, st->devname, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (st->utime == array.utime && st->failed == sra->array.failed_disks &&
|
||||||
|
@@ -625,29 +664,20 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
}
|
||||||
|
if (st->utime == 0 && /* new array */
|
||||||
|
mse->pattern && strchr(mse->pattern, '_') /* degraded */)
|
||||||
|
- alert("DegradedArray", dev, NULL);
|
||||||
|
+ alert(EVENT_DEGRADED_ARRAY, 0, dev, NULL);
|
||||||
|
|
||||||
|
if (st->utime == 0 && /* new array */ st->expected_spares > 0 &&
|
||||||
|
sra->array.spare_disks < st->expected_spares)
|
||||||
|
- alert("SparesMissing", dev, NULL);
|
||||||
|
+ alert(EVENT_SPARES_MISSING, 0, dev, NULL);
|
||||||
|
if (st->percent < 0 && st->percent != RESYNC_UNKNOWN &&
|
||||||
|
mse->percent >= 0)
|
||||||
|
- alert("RebuildStarted", dev, NULL);
|
||||||
|
+ alert(EVENT_REBUILD_STARTED, 0, dev, NULL);
|
||||||
|
if (st->percent >= 0 && mse->percent >= 0 &&
|
||||||
|
(mse->percent / increments) > (st->percent / increments)) {
|
||||||
|
- char percentalert[18];
|
||||||
|
- /*
|
||||||
|
- * "RebuildNN" (10 chars) or "RebuildStarted" (15 chars)
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
if((mse->percent / increments) == 0)
|
||||||
|
- snprintf(percentalert, sizeof(percentalert),
|
||||||
|
- "RebuildStarted");
|
||||||
|
+ alert(EVENT_REBUILD_STARTED, 0, dev, NULL);
|
||||||
|
else
|
||||||
|
- snprintf(percentalert, sizeof(percentalert),
|
||||||
|
- "Rebuild%02d", mse->percent);
|
||||||
|
-
|
||||||
|
- alert(percentalert, dev, NULL);
|
||||||
|
+ alert(EVENT_REBUILD, mse->percent, dev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mse->percent == RESYNC_NONE && st->percent >= 0) {
|
||||||
|
@@ -660,9 +690,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
snprintf(cnt, sizeof(cnt),
|
||||||
|
" mismatches found: %d (on raid level %d)",
|
||||||
|
sra->mismatch_cnt, sra->array.level);
|
||||||
|
- alert("RebuildFinished", dev, cnt);
|
||||||
|
+ alert(EVENT_REBUILD_FINISHED, 0, dev, cnt);
|
||||||
|
} else
|
||||||
|
- alert("RebuildFinished", dev, NULL);
|
||||||
|
+ alert(EVENT_REBUILD_FINISHED, 0, dev, NULL);
|
||||||
|
}
|
||||||
|
st->percent = mse->percent;
|
||||||
|
|
||||||
|
@@ -716,14 +746,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
change = newstate ^ st->devstate[i];
|
||||||
|
if (st->utime && change && !st->err && !new_array) {
|
||||||
|
if ((st->devstate[i]&change) & (1 << MD_DISK_SYNC))
|
||||||
|
- alert("Fail", dev, dv);
|
||||||
|
+ alert(EVENT_FAIL, 0, dev, dv);
|
||||||
|
else if ((newstate & (1 << MD_DISK_FAULTY)) &&
|
||||||
|
(disc.major || disc.minor) &&
|
||||||
|
st->devid[i] == makedev(disc.major,
|
||||||
|
disc.minor))
|
||||||
|
- alert("FailSpare", dev, dv);
|
||||||
|
+ alert(EVENT_FAIL_SPARE, 0, dev, dv);
|
||||||
|
else if ((newstate&change) & (1 << MD_DISK_SYNC))
|
||||||
|
- alert("SpareActive", dev, dv);
|
||||||
|
+ alert(EVENT_SPARE_ACTIVE, 0, dev, dv);
|
||||||
|
}
|
||||||
|
st->devstate[i] = newstate;
|
||||||
|
st->devid[i] = makedev(disc.major, disc.minor);
|
||||||
|
@@ -747,7 +777,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
|
||||||
|
disappeared:
|
||||||
|
if (!st->err && !is_container)
|
||||||
|
- alert("DeviceDisappeared", dev, NULL);
|
||||||
|
+ alert(EVENT_DEVICE_DISAPPEARED, 0, dev, NULL);
|
||||||
|
st->err++;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
@@ -806,7 +836,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist)
|
||||||
|
st->parent_devnm[0] = 0;
|
||||||
|
*statelist = st;
|
||||||
|
if (info.test)
|
||||||
|
- alert("TestMessage", st->devname, NULL);
|
||||||
|
+ alert(EVENT_TEST_MESSAGE, 0, st->devname, NULL);
|
||||||
|
new_found = 1;
|
||||||
|
}
|
||||||
|
return new_found;
|
||||||
|
@@ -1029,7 +1059,7 @@ static void try_spare_migration(struct state *statelist)
|
||||||
|
if (devid > 0 &&
|
||||||
|
move_spare(from->devname, to->devname,
|
||||||
|
devid)) {
|
||||||
|
- alert("MoveSpare", to->devname, from->devname);
|
||||||
|
+ alert(EVENT_MOVE_SPARE, 0, to->devname, from->devname);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
406
SOURCES/0089-Mdmonitor-Add-helper-functions.patch
Normal file
406
SOURCES/0089-Mdmonitor-Add-helper-functions.patch
Normal file
@ -0,0 +1,406 @@
|
|||||||
|
From cc3df167c599d2ee0c132149c86fc0ad70d9f14e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Date: Thu, 2 Feb 2023 12:27:01 +0100
|
||||||
|
Subject: [PATCH 089/125] Mdmonitor: Add helper functions
|
||||||
|
|
||||||
|
Add functions:
|
||||||
|
- is_email_event(),
|
||||||
|
- get_syslog_event_priority(),
|
||||||
|
- sprint_event_message(),
|
||||||
|
with kernel style comments containing more detailed descriptions.
|
||||||
|
|
||||||
|
Also update event syslog priorities to be consistent with man. MoveSpare event was described in man as priority info, while implemented as warning. Move event data into a struct, so that it is passed between different functions if needed.
|
||||||
|
Sort function declarations alphabetically and remove redundant alert() declaration.
|
||||||
|
|
||||||
|
Signed-off-by: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Monitor.c | 228 +++++++++++++++++++++++++++++++++++++-----------------
|
||||||
|
1 file changed, 158 insertions(+), 70 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Monitor.c b/Monitor.c
|
||||||
|
index 029e9efd..39598ba0 100644
|
||||||
|
--- a/Monitor.c
|
||||||
|
+++ b/Monitor.c
|
||||||
|
@@ -73,10 +73,12 @@ enum event {
|
||||||
|
EVENT_NEW_ARRAY,
|
||||||
|
EVENT_MOVE_SPARE,
|
||||||
|
EVENT_TEST_MESSAGE,
|
||||||
|
+ __SYSLOG_PRIORITY_WARNING,
|
||||||
|
EVENT_REBUILD_STARTED,
|
||||||
|
EVENT_REBUILD,
|
||||||
|
EVENT_REBUILD_FINISHED,
|
||||||
|
EVENT_SPARES_MISSING,
|
||||||
|
+ __SYSLOG_PRIORITY_CRITICAL,
|
||||||
|
EVENT_DEVICE_DISAPPEARED,
|
||||||
|
EVENT_FAIL,
|
||||||
|
EVENT_FAIL_SPARE,
|
||||||
|
@@ -100,18 +102,31 @@ mapping_t events_map[] = {
|
||||||
|
{NULL, EVENT_UNKNOWN}
|
||||||
|
};
|
||||||
|
|
||||||
|
-static int make_daemon(char *pidfile);
|
||||||
|
-static int check_one_sharer(int scan);
|
||||||
|
-static void write_autorebuild_pid(void);
|
||||||
|
-static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc);
|
||||||
|
-static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer);
|
||||||
|
+struct event_data {
|
||||||
|
+ enum event event_enum;
|
||||||
|
+ /*
|
||||||
|
+ * @event_name: Rebuild event name must be in form "RebuildXX", where XX is rebuild progress.
|
||||||
|
+ */
|
||||||
|
+ char event_name[EVENT_NAME_MAX];
|
||||||
|
+ char message[BUFSIZ];
|
||||||
|
+ const char *description;
|
||||||
|
+ const char *dev;
|
||||||
|
+ const char *disc;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist);
|
||||||
|
static void try_spare_migration(struct state *statelist);
|
||||||
|
static void link_containers_with_subarrays(struct state *list);
|
||||||
|
static void free_statelist(struct state *statelist);
|
||||||
|
+static int check_array(struct state *st, struct mdstat_ent *mdstat, int increments, char *prefer);
|
||||||
|
+static int check_one_sharer(int scan);
|
||||||
|
#ifndef NO_LIBUDEV
|
||||||
|
static int check_udev_activity(void);
|
||||||
|
#endif
|
||||||
|
+static void link_containers_with_subarrays(struct state *list);
|
||||||
|
+static int make_daemon(char *pidfile);
|
||||||
|
+static void try_spare_migration(struct state *statelist);
|
||||||
|
+static void write_autorebuild_pid(void);
|
||||||
|
|
||||||
|
int Monitor(struct mddev_dev *devlist,
|
||||||
|
char *mailaddr, char *alert_cmd,
|
||||||
|
@@ -450,7 +465,80 @@ static void write_autorebuild_pid()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void execute_alert_cmd(const char *event_name, const char *dev, const char *disc)
|
||||||
|
+#define BASE_MESSAGE "%s event detected on md device %s"
|
||||||
|
+#define COMPONENT_DEVICE_MESSAGE ", component device %s"
|
||||||
|
+#define DESCRIPTION_MESSAGE ": %s"
|
||||||
|
+/*
|
||||||
|
+ * sprint_event_message() - Writes basic message about detected event to destination ptr.
|
||||||
|
+ * @dest: message destination, should be at least the size of BUFSIZ
|
||||||
|
+ * @data: event data
|
||||||
|
+ *
|
||||||
|
+ * Return: 0 on success, 1 on error
|
||||||
|
+ */
|
||||||
|
+static int sprint_event_message(char *dest, const struct event_data *data)
|
||||||
|
+{
|
||||||
|
+ if (!dest || !data)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ if (data->disc && data->description)
|
||||||
|
+ snprintf(dest, BUFSIZ, BASE_MESSAGE COMPONENT_DEVICE_MESSAGE DESCRIPTION_MESSAGE,
|
||||||
|
+ data->event_name, data->dev, data->disc, data->description);
|
||||||
|
+ else if (data->disc)
|
||||||
|
+ snprintf(dest, BUFSIZ, BASE_MESSAGE COMPONENT_DEVICE_MESSAGE,
|
||||||
|
+ data->event_name, data->dev, data->disc);
|
||||||
|
+ else if (data->description)
|
||||||
|
+ snprintf(dest, BUFSIZ, BASE_MESSAGE DESCRIPTION_MESSAGE,
|
||||||
|
+ data->event_name, data->dev, data->description);
|
||||||
|
+ else
|
||||||
|
+ snprintf(dest, BUFSIZ, BASE_MESSAGE, data->event_name, data->dev);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * get_syslog_event_priority() - Determines event priority.
|
||||||
|
+ * @event_enum: event to be checked
|
||||||
|
+ *
|
||||||
|
+ * Return: LOG_CRIT, LOG_WARNING or LOG_INFO
|
||||||
|
+ */
|
||||||
|
+static int get_syslog_event_priority(const enum event event_enum)
|
||||||
|
+{
|
||||||
|
+ if (event_enum > __SYSLOG_PRIORITY_CRITICAL)
|
||||||
|
+ return LOG_CRIT;
|
||||||
|
+ if (event_enum > __SYSLOG_PRIORITY_WARNING)
|
||||||
|
+ return LOG_WARNING;
|
||||||
|
+ return LOG_INFO;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * is_email_event() - Determines whether email for event should be sent or not.
|
||||||
|
+ * @event_enum: event to be checked
|
||||||
|
+ *
|
||||||
|
+ * Return: true if email should be sent, false otherwise
|
||||||
|
+ */
|
||||||
|
+static bool is_email_event(const enum event event_enum)
|
||||||
|
+{
|
||||||
|
+ static const enum event email_events[] = {
|
||||||
|
+ EVENT_FAIL,
|
||||||
|
+ EVENT_FAIL_SPARE,
|
||||||
|
+ EVENT_DEGRADED_ARRAY,
|
||||||
|
+ EVENT_SPARES_MISSING,
|
||||||
|
+ EVENT_TEST_MESSAGE
|
||||||
|
+ };
|
||||||
|
+ unsigned int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < ARRAY_SIZE(email_events); ++i) {
|
||||||
|
+ if (event_enum == email_events[i])
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * execute_alert_cmd() - Forks and executes command provided as alert_cmd.
|
||||||
|
+ * @data: event data
|
||||||
|
+ */
|
||||||
|
+static void execute_alert_cmd(const struct event_data *data)
|
||||||
|
{
|
||||||
|
int pid = fork();
|
||||||
|
|
||||||
|
@@ -462,12 +550,16 @@ static void execute_alert_cmd(const char *event_name, const char *dev, const cha
|
||||||
|
pr_err("Cannot fork to execute alert command");
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
- execl(info.alert_cmd, info.alert_cmd, event_name, dev, disc, NULL);
|
||||||
|
+ execl(info.alert_cmd, info.alert_cmd, data->event_name, data->dev, data->disc, NULL);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void send_event_email(const char *event_name, const char *dev, const char *disc)
|
||||||
|
+/*
|
||||||
|
+ * send_event_email() - Sends an email about event detected by monitor.
|
||||||
|
+ * @data: event data
|
||||||
|
+ */
|
||||||
|
+static void send_event_email(const struct event_data *data)
|
||||||
|
{
|
||||||
|
FILE *mp, *mdstat;
|
||||||
|
char buf[BUFSIZ];
|
||||||
|
@@ -485,15 +577,9 @@ static void send_event_email(const char *event_name, const char *dev, const char
|
||||||
|
else
|
||||||
|
fprintf(mp, "From: %s monitoring <root>\n", Name);
|
||||||
|
fprintf(mp, "To: %s\n", info.mailaddr);
|
||||||
|
- fprintf(mp, "Subject: %s event on %s:%s\n\n", event_name, dev, info.hostname);
|
||||||
|
- fprintf(mp, "This is an automatically generated mail message. \n");
|
||||||
|
- fprintf(mp, "A %s event had been detected on md device %s.\n\n", event_name, dev);
|
||||||
|
-
|
||||||
|
- if (disc && disc[0] != ' ')
|
||||||
|
- fprintf(mp,
|
||||||
|
- "It could be related to component device %s.\n\n", disc);
|
||||||
|
- if (disc && disc[0] == ' ')
|
||||||
|
- fprintf(mp, "Extra information:%s.\n\n", disc);
|
||||||
|
+ fprintf(mp, "Subject: %s event on %s:%s\n\n", data->event_name, data->dev, info.hostname);
|
||||||
|
+ fprintf(mp, "This is an automatically generated mail message.\n");
|
||||||
|
+ fprintf(mp, "%s\n", data->message);
|
||||||
|
|
||||||
|
mdstat = fopen("/proc/mdstat", "r");
|
||||||
|
if (!mdstat) {
|
||||||
|
@@ -509,58 +595,60 @@ static void send_event_email(const char *event_name, const char *dev, const char
|
||||||
|
pclose(mp);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void log_event_to_syslog(const enum event event_enum, const char *event_name, const char *dev, const char *disc)
|
||||||
|
+/*
|
||||||
|
+ * log_event_to_syslog() - Logs an event into syslog.
|
||||||
|
+ * @data: event data
|
||||||
|
+ */
|
||||||
|
+static void log_event_to_syslog(const struct event_data *data)
|
||||||
|
{
|
||||||
|
int priority;
|
||||||
|
- /* Log at a different severity depending on the event.
|
||||||
|
- *
|
||||||
|
- * These are the critical events: */
|
||||||
|
- if (event_enum == EVENT_FAIL ||
|
||||||
|
- event_enum == EVENT_DEGRADED_ARRAY ||
|
||||||
|
- event_enum == EVENT_DEVICE_DISAPPEARED)
|
||||||
|
- priority = LOG_CRIT;
|
||||||
|
- /* Good to know about, but are not failures: */
|
||||||
|
- else if (event_enum == EVENT_REBUILD ||
|
||||||
|
- event_enum == EVENT_MOVE_SPARE ||
|
||||||
|
- event_enum == EVENT_SPARES_MISSING)
|
||||||
|
- priority = LOG_WARNING;
|
||||||
|
- /* Everything else: */
|
||||||
|
- else
|
||||||
|
- priority = LOG_INFO;
|
||||||
|
-
|
||||||
|
- if (disc && disc[0] != ' ')
|
||||||
|
- syslog(priority,
|
||||||
|
- "%s event detected on md device %s, component device %s",
|
||||||
|
- event_name, dev, disc);
|
||||||
|
- else if (disc)
|
||||||
|
- syslog(priority, "%s event detected on md device %s: %s", event_name, dev, disc);
|
||||||
|
- else
|
||||||
|
- syslog(priority, "%s event detected on md device %s", event_name, dev);
|
||||||
|
+
|
||||||
|
+ priority = get_syslog_event_priority(data->event_enum);
|
||||||
|
+
|
||||||
|
+ syslog(priority, "%s\n", data->message);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void alert(const enum event event_enum, const unsigned int progress, const char *dev, const char *disc)
|
||||||
|
+/*
|
||||||
|
+ * alert() - Alerts about the monitor event.
|
||||||
|
+ * @event_enum: event to be sent
|
||||||
|
+ * @description: event description
|
||||||
|
+ * @progress: rebuild progress
|
||||||
|
+ * @dev: md device name
|
||||||
|
+ * @disc: component device
|
||||||
|
+ *
|
||||||
|
+ * If needed function executes alert command, sends an email or logs event to syslog.
|
||||||
|
+ */
|
||||||
|
+static void alert(const enum event event_enum, const char *description, const uint8_t progress,
|
||||||
|
+ const char *dev, const char *disc)
|
||||||
|
{
|
||||||
|
- char event_name[EVENT_NAME_MAX];
|
||||||
|
+ struct event_data data = {.dev = dev, .disc = disc, .description = description};
|
||||||
|
+
|
||||||
|
+ if (!dev)
|
||||||
|
+ return;
|
||||||
|
|
||||||
|
if (event_enum == EVENT_REBUILD) {
|
||||||
|
- snprintf(event_name, sizeof(event_name), "%s%02d",
|
||||||
|
+ snprintf(data.event_name, sizeof(data.event_name), "%s%02d",
|
||||||
|
map_num_s(events_map, EVENT_REBUILD), progress);
|
||||||
|
} else {
|
||||||
|
- snprintf(event_name, sizeof(event_name), "%s", map_num_s(events_map, event_enum));
|
||||||
|
+ snprintf(data.event_name, sizeof(data.event_name), "%s", map_num_s(events_map, event_enum));
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (info.alert_cmd)
|
||||||
|
- execute_alert_cmd(event_name, dev, disc);
|
||||||
|
+ data.event_enum = event_enum;
|
||||||
|
|
||||||
|
- if (info.mailaddr && (event_enum == EVENT_FAIL ||
|
||||||
|
- event_enum == EVENT_TEST_MESSAGE ||
|
||||||
|
- event_enum == EVENT_SPARES_MISSING ||
|
||||||
|
- event_enum == EVENT_DEGRADED_ARRAY)) {
|
||||||
|
- send_event_email(event_name, dev, disc);
|
||||||
|
+ if (sprint_event_message(data.message, &data) != 0) {
|
||||||
|
+ pr_err("Cannot create event message.\n");
|
||||||
|
+ return;
|
||||||
|
}
|
||||||
|
+ pr_err("%s\n", data.message);
|
||||||
|
+
|
||||||
|
+ if (info.alert_cmd)
|
||||||
|
+ execute_alert_cmd(&data);
|
||||||
|
+
|
||||||
|
+ if (info.mailaddr && is_email_event(event_enum))
|
||||||
|
+ send_event_email(&data);
|
||||||
|
|
||||||
|
if (info.dosyslog)
|
||||||
|
- log_event_to_syslog(event_enum, event_name, dev, disc);
|
||||||
|
+ log_event_to_syslog(&data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
@@ -585,7 +673,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
unsigned long redundancy_only_flags = 0;
|
||||||
|
|
||||||
|
if (info.test)
|
||||||
|
- alert(EVENT_TEST_MESSAGE, 0, dev, NULL);
|
||||||
|
+ alert(EVENT_TEST_MESSAGE, NULL, 0, dev, NULL);
|
||||||
|
|
||||||
|
retval = 0;
|
||||||
|
|
||||||
|
@@ -634,7 +722,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
*/
|
||||||
|
if (sra->array.level == 0 || sra->array.level == -1) {
|
||||||
|
if (!st->err && !st->from_config)
|
||||||
|
- alert(EVENT_DEVICE_DISAPPEARED, 0, dev, " Wrong-Level");
|
||||||
|
+ alert(EVENT_DEVICE_DISAPPEARED, "Wrong-Level", 0, dev, NULL);
|
||||||
|
st->err++;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
@@ -651,7 +739,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
st->percent = RESYNC_NONE;
|
||||||
|
new_array = 1;
|
||||||
|
if (!is_container)
|
||||||
|
- alert(EVENT_NEW_ARRAY, 0, st->devname, NULL);
|
||||||
|
+ alert(EVENT_NEW_ARRAY, NULL, 0, st->devname, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (st->utime == array.utime && st->failed == sra->array.failed_disks &&
|
||||||
|
@@ -664,20 +752,20 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
}
|
||||||
|
if (st->utime == 0 && /* new array */
|
||||||
|
mse->pattern && strchr(mse->pattern, '_') /* degraded */)
|
||||||
|
- alert(EVENT_DEGRADED_ARRAY, 0, dev, NULL);
|
||||||
|
+ alert(EVENT_DEGRADED_ARRAY, NULL, 0, dev, NULL);
|
||||||
|
|
||||||
|
if (st->utime == 0 && /* new array */ st->expected_spares > 0 &&
|
||||||
|
sra->array.spare_disks < st->expected_spares)
|
||||||
|
- alert(EVENT_SPARES_MISSING, 0, dev, NULL);
|
||||||
|
+ alert(EVENT_SPARES_MISSING, NULL, 0, dev, NULL);
|
||||||
|
if (st->percent < 0 && st->percent != RESYNC_UNKNOWN &&
|
||||||
|
mse->percent >= 0)
|
||||||
|
- alert(EVENT_REBUILD_STARTED, 0, dev, NULL);
|
||||||
|
+ alert(EVENT_REBUILD_STARTED, NULL, 0, dev, NULL);
|
||||||
|
if (st->percent >= 0 && mse->percent >= 0 &&
|
||||||
|
(mse->percent / increments) > (st->percent / increments)) {
|
||||||
|
if((mse->percent / increments) == 0)
|
||||||
|
- alert(EVENT_REBUILD_STARTED, 0, dev, NULL);
|
||||||
|
+ alert(EVENT_REBUILD_STARTED, NULL, 0, dev, NULL);
|
||||||
|
else
|
||||||
|
- alert(EVENT_REBUILD, mse->percent, dev, NULL);
|
||||||
|
+ alert(EVENT_REBUILD, NULL, mse->percent, dev, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mse->percent == RESYNC_NONE && st->percent >= 0) {
|
||||||
|
@@ -690,9 +778,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
snprintf(cnt, sizeof(cnt),
|
||||||
|
" mismatches found: %d (on raid level %d)",
|
||||||
|
sra->mismatch_cnt, sra->array.level);
|
||||||
|
- alert(EVENT_REBUILD_FINISHED, 0, dev, cnt);
|
||||||
|
+ alert(EVENT_REBUILD_FINISHED, NULL, 0, dev, cnt);
|
||||||
|
} else
|
||||||
|
- alert(EVENT_REBUILD_FINISHED, 0, dev, NULL);
|
||||||
|
+ alert(EVENT_REBUILD_FINISHED, NULL, 0, dev, NULL);
|
||||||
|
}
|
||||||
|
st->percent = mse->percent;
|
||||||
|
|
||||||
|
@@ -746,14 +834,14 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
change = newstate ^ st->devstate[i];
|
||||||
|
if (st->utime && change && !st->err && !new_array) {
|
||||||
|
if ((st->devstate[i]&change) & (1 << MD_DISK_SYNC))
|
||||||
|
- alert(EVENT_FAIL, 0, dev, dv);
|
||||||
|
+ alert(EVENT_FAIL, NULL, 0, dev, dv);
|
||||||
|
else if ((newstate & (1 << MD_DISK_FAULTY)) &&
|
||||||
|
(disc.major || disc.minor) &&
|
||||||
|
st->devid[i] == makedev(disc.major,
|
||||||
|
disc.minor))
|
||||||
|
- alert(EVENT_FAIL_SPARE, 0, dev, dv);
|
||||||
|
+ alert(EVENT_FAIL_SPARE, NULL, 0, dev, dv);
|
||||||
|
else if ((newstate&change) & (1 << MD_DISK_SYNC))
|
||||||
|
- alert(EVENT_SPARE_ACTIVE, 0, dev, dv);
|
||||||
|
+ alert(EVENT_SPARE_ACTIVE, NULL, 0, dev, dv);
|
||||||
|
}
|
||||||
|
st->devstate[i] = newstate;
|
||||||
|
st->devid[i] = makedev(disc.major, disc.minor);
|
||||||
|
@@ -777,7 +865,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||||
|
|
||||||
|
disappeared:
|
||||||
|
if (!st->err && !is_container)
|
||||||
|
- alert(EVENT_DEVICE_DISAPPEARED, 0, dev, NULL);
|
||||||
|
+ alert(EVENT_DEVICE_DISAPPEARED, NULL, 0, dev, NULL);
|
||||||
|
st->err++;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
@@ -836,7 +924,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist)
|
||||||
|
st->parent_devnm[0] = 0;
|
||||||
|
*statelist = st;
|
||||||
|
if (info.test)
|
||||||
|
- alert(EVENT_TEST_MESSAGE, 0, st->devname, NULL);
|
||||||
|
+ alert(EVENT_TEST_MESSAGE, NULL, 0, st->devname, NULL);
|
||||||
|
new_found = 1;
|
||||||
|
}
|
||||||
|
return new_found;
|
||||||
|
@@ -1059,7 +1147,7 @@ static void try_spare_migration(struct state *statelist)
|
||||||
|
if (devid > 0 &&
|
||||||
|
move_spare(from->devname, to->devname,
|
||||||
|
devid)) {
|
||||||
|
- alert(EVENT_MOVE_SPARE, 0, to->devname, from->devname);
|
||||||
|
+ alert(EVENT_MOVE_SPARE, NULL, 0, to->devname, from->devname);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,83 @@
|
|||||||
|
From ee9dcf9549e8cbfeb51123812776cc87016c95b0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Date: Thu, 2 Feb 2023 12:27:02 +0100
|
||||||
|
Subject: [PATCH 090/125] Add helpers to determine whether directories or files
|
||||||
|
are soft links
|
||||||
|
|
||||||
|
Signed-off-by: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
mdadm.h | 2 ++
|
||||||
|
util.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 47 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index 13f8b4cb..1674ce13 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -1777,6 +1777,8 @@ 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);
|
||||||
|
+extern bool is_directory(const char *path);
|
||||||
|
+extern bool is_file(const char *path);
|
||||||
|
|
||||||
|
#define _ROUND_UP(val, base) (((val) + (base) - 1) & ~(base - 1))
|
||||||
|
#define ROUND_UP(val, base) _ROUND_UP(val, (typeof(val))(base))
|
||||||
|
diff --git a/util.c b/util.c
|
||||||
|
index 8c7f3fd5..7fc881bf 100644
|
||||||
|
--- a/util.c
|
||||||
|
+++ b/util.c
|
||||||
|
@@ -2401,3 +2401,48 @@ void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt)
|
||||||
|
}
|
||||||
|
} while (!wake_after_interrupt && errno == EINTR);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/* is_directory() - Checks if directory provided by path is indeed a regular directory.
|
||||||
|
+ * @path: directory path to be checked
|
||||||
|
+ *
|
||||||
|
+ * Doesn't accept symlinks.
|
||||||
|
+ *
|
||||||
|
+ * Return: true if is a directory, false if not
|
||||||
|
+ */
|
||||||
|
+bool is_directory(const char *path)
|
||||||
|
+{
|
||||||
|
+ struct stat st;
|
||||||
|
+
|
||||||
|
+ if (lstat(path, &st) != 0) {
|
||||||
|
+ pr_err("%s: %s\n", strerror(errno), path);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!S_ISDIR(st.st_mode))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * is_file() - Checks if file provided by path is indeed a regular file.
|
||||||
|
+ * @path: file path to be checked
|
||||||
|
+ *
|
||||||
|
+ * Doesn't accept symlinks.
|
||||||
|
+ *
|
||||||
|
+ * Return: true if is a file, false if not
|
||||||
|
+ */
|
||||||
|
+bool is_file(const char *path)
|
||||||
|
+{
|
||||||
|
+ struct stat st;
|
||||||
|
+
|
||||||
|
+ if (lstat(path, &st) != 0) {
|
||||||
|
+ pr_err("%s: %s\n", strerror(errno), path);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!S_ISREG(st.st_mode))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
110
SOURCES/0091-Mdmonitor-Refactor-write_autorebuild_pid.patch
Normal file
110
SOURCES/0091-Mdmonitor-Refactor-write_autorebuild_pid.patch
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
From b6a84d4e92f876acd120d3062a8302db5dd2498c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Date: Thu, 2 Feb 2023 12:27:03 +0100
|
||||||
|
Subject: [PATCH 091/125] Mdmonitor: Refactor write_autorebuild_pid()
|
||||||
|
|
||||||
|
Add better error handling and check for symlinks when opening MDMON_DIR.
|
||||||
|
|
||||||
|
Signed-off-by: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Monitor.c | 55 ++++++++++++++++++++++++++++++++++++-------------------
|
||||||
|
1 file changed, 36 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Monitor.c b/Monitor.c
|
||||||
|
index 39598ba0..14a2dfe5 100644
|
||||||
|
--- a/Monitor.c
|
||||||
|
+++ b/Monitor.c
|
||||||
|
@@ -33,6 +33,7 @@
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define EVENT_NAME_MAX 32
|
||||||
|
+#define AUTOREBUILD_PID_PATH MDMON_DIR "/autorebuild.pid"
|
||||||
|
|
||||||
|
struct state {
|
||||||
|
char devname[MD_NAME_MAX + sizeof("/dev/md/")]; /* length of "/dev/md/" + device name + terminating byte*/
|
||||||
|
@@ -126,7 +127,7 @@ static int check_udev_activity(void);
|
||||||
|
static void link_containers_with_subarrays(struct state *list);
|
||||||
|
static int make_daemon(char *pidfile);
|
||||||
|
static void try_spare_migration(struct state *statelist);
|
||||||
|
-static void write_autorebuild_pid(void);
|
||||||
|
+static int write_autorebuild_pid(void);
|
||||||
|
|
||||||
|
int Monitor(struct mddev_dev *devlist,
|
||||||
|
char *mailaddr, char *alert_cmd,
|
||||||
|
@@ -234,7 +235,8 @@ int Monitor(struct mddev_dev *devlist,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (share)
|
||||||
|
- write_autorebuild_pid();
|
||||||
|
+ if (write_autorebuild_pid() != 0)
|
||||||
|
+ return 1;
|
||||||
|
|
||||||
|
if (devlist == NULL) {
|
||||||
|
mdlist = conf_get_ident(NULL);
|
||||||
|
@@ -440,29 +442,44 @@ static int check_one_sharer(int scan)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void write_autorebuild_pid()
|
||||||
|
+/*
|
||||||
|
+ * write_autorebuild_pid() - Writes pid to autorebuild.pid file.
|
||||||
|
+ *
|
||||||
|
+ * Return: 0 on success, 1 on error
|
||||||
|
+ */
|
||||||
|
+static int write_autorebuild_pid(void)
|
||||||
|
{
|
||||||
|
- char path[PATH_MAX];
|
||||||
|
- int pid;
|
||||||
|
- FILE *fp = NULL;
|
||||||
|
- sprintf(path, "%s/autorebuild.pid", MDMON_DIR);
|
||||||
|
+ FILE *fp;
|
||||||
|
+ int fd;
|
||||||
|
|
||||||
|
if (mkdir(MDMON_DIR, 0700) < 0 && errno != EEXIST) {
|
||||||
|
- pr_err("Can't create autorebuild.pid file\n");
|
||||||
|
- } else {
|
||||||
|
- int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0700);
|
||||||
|
+ pr_err("%s: %s\n", strerror(errno), MDMON_DIR);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (fd >= 0)
|
||||||
|
- fp = fdopen(fd, "w");
|
||||||
|
+ if (!is_directory(MDMON_DIR)) {
|
||||||
|
+ pr_err("%s is not a regular directory.\n", MDMON_DIR);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (!fp)
|
||||||
|
- pr_err("Can't create autorebuild.pid file\n");
|
||||||
|
- else {
|
||||||
|
- pid = getpid();
|
||||||
|
- fprintf(fp, "%d\n", pid);
|
||||||
|
- fclose(fp);
|
||||||
|
- }
|
||||||
|
+ fd = open(AUTOREBUILD_PID_PATH, O_WRONLY | O_CREAT | O_TRUNC, 0700);
|
||||||
|
+
|
||||||
|
+ if (fd < 0) {
|
||||||
|
+ pr_err("Error opening %s file.\n", AUTOREBUILD_PID_PATH);
|
||||||
|
+ return 1;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ fp = fdopen(fd, "w");
|
||||||
|
+
|
||||||
|
+ if (!fp) {
|
||||||
|
+ pr_err("Error opening fd for %s file.\n", AUTOREBUILD_PID_PATH);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ fprintf(fp, "%d\n", getpid());
|
||||||
|
+
|
||||||
|
+ fclose(fp);
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BASE_MESSAGE "%s event detected on md device %s"
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,139 @@
|
|||||||
|
From 0a07dea8d3b78a22a59f4604a5e8da15690f28e3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Date: Thu, 2 Feb 2023 12:27:04 +0100
|
||||||
|
Subject: [PATCH 092/125] Mdmonitor: Refactor check_one_sharer() for better
|
||||||
|
error handling
|
||||||
|
|
||||||
|
Also check if autorebuild.pid is a symlink, which we shouldn't accept.
|
||||||
|
|
||||||
|
Signed-off-by: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Monitor.c | 89 ++++++++++++++++++++++++++++++++++++++-----------------
|
||||||
|
1 file changed, 62 insertions(+), 27 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Monitor.c b/Monitor.c
|
||||||
|
index 14a2dfe5..44918184 100644
|
||||||
|
--- a/Monitor.c
|
||||||
|
+++ b/Monitor.c
|
||||||
|
@@ -32,6 +32,7 @@
|
||||||
|
#include <libudev.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#define TASK_COMM_LEN 16
|
||||||
|
#define EVENT_NAME_MAX 32
|
||||||
|
#define AUTOREBUILD_PID_PATH MDMON_DIR "/autorebuild.pid"
|
||||||
|
|
||||||
|
@@ -224,7 +225,7 @@ int Monitor(struct mddev_dev *devlist,
|
||||||
|
info.hostname[sizeof(info.hostname) - 1] = '\0';
|
||||||
|
|
||||||
|
if (share){
|
||||||
|
- if (check_one_sharer(c->scan))
|
||||||
|
+ if (check_one_sharer(c->scan) == 2)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -406,39 +407,73 @@ static int make_daemon(char *pidfile)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * check_one_sharer() - Checks for other mdmon processes running.
|
||||||
|
+ *
|
||||||
|
+ * Return:
|
||||||
|
+ * 0 - no other processes running,
|
||||||
|
+ * 1 - warning,
|
||||||
|
+ * 2 - error, or when scan mode is enabled, and one mdmon process already exists
|
||||||
|
+ */
|
||||||
|
static int check_one_sharer(int scan)
|
||||||
|
{
|
||||||
|
int pid;
|
||||||
|
- FILE *comm_fp;
|
||||||
|
- FILE *fp;
|
||||||
|
+ FILE *fp, *comm_fp;
|
||||||
|
char comm_path[PATH_MAX];
|
||||||
|
- char path[PATH_MAX];
|
||||||
|
- char comm[20];
|
||||||
|
-
|
||||||
|
- sprintf(path, "%s/autorebuild.pid", MDMON_DIR);
|
||||||
|
- fp = fopen(path, "r");
|
||||||
|
- if (fp) {
|
||||||
|
- if (fscanf(fp, "%d", &pid) != 1)
|
||||||
|
- pid = -1;
|
||||||
|
- snprintf(comm_path, sizeof(comm_path),
|
||||||
|
- "/proc/%d/comm", pid);
|
||||||
|
- comm_fp = fopen(comm_path, "r");
|
||||||
|
- if (comm_fp) {
|
||||||
|
- if (fscanf(comm_fp, "%19s", comm) &&
|
||||||
|
- strncmp(basename(comm), Name, strlen(Name)) == 0) {
|
||||||
|
- if (scan) {
|
||||||
|
- pr_err("Only one autorebuild process allowed in scan mode, aborting\n");
|
||||||
|
- fclose(comm_fp);
|
||||||
|
- fclose(fp);
|
||||||
|
- return 1;
|
||||||
|
- } else {
|
||||||
|
- pr_err("Warning: One autorebuild process already running.\n");
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ char comm[TASK_COMM_LEN];
|
||||||
|
+
|
||||||
|
+ if (!is_directory(MDMON_DIR)) {
|
||||||
|
+ pr_err("%s is not a regular directory.\n", MDMON_DIR);
|
||||||
|
+ 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 (fscanf(fp, "%d", &pid) != 1) {
|
||||||
|
+ pr_err("Cannot read pid from %s file.\n", AUTOREBUILD_PID_PATH);
|
||||||
|
+ fclose(fp);
|
||||||
|
+ return 2;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ snprintf(comm_path, sizeof(comm_path), "/proc/%d/comm", pid);
|
||||||
|
+
|
||||||
|
+ comm_fp = fopen(comm_path, "r");
|
||||||
|
+ if (!comm_fp) {
|
||||||
|
+ dprintf("Warning: Cannot open %s, continuing\n", comm_path);
|
||||||
|
+ fclose(fp);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (fscanf(comm_fp, "%15s", comm) == 0) {
|
||||||
|
+ dprintf("Warning: Cannot read comm from %s, continuing\n", comm_path);
|
||||||
|
+ fclose(comm_fp);
|
||||||
|
+ fclose(fp);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (strncmp(basename(comm), Name, strlen(Name)) == 0) {
|
||||||
|
+ if (scan) {
|
||||||
|
+ pr_err("Only one autorebuild process allowed in scan mode, aborting\n");
|
||||||
|
fclose(comm_fp);
|
||||||
|
+ fclose(fp);
|
||||||
|
+ return 2;
|
||||||
|
}
|
||||||
|
- fclose(fp);
|
||||||
|
+ pr_err("Warning: One autorebuild process already running.\n");
|
||||||
|
}
|
||||||
|
+ fclose(comm_fp);
|
||||||
|
+ fclose(fp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,41 @@
|
|||||||
|
From a0151041642dffff2421c22e18fb7b02b58787d9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Coly Li <colyli@suse.de>
|
||||||
|
Date: Sat, 4 Mar 2023 00:21:30 +0800
|
||||||
|
Subject: [PATCH 093/125] util.c: reorder code lines in parse_layout_faulty()
|
||||||
|
|
||||||
|
Resort the code lines in parse_layout_faulty() to make it more
|
||||||
|
comfortable, no logic change.
|
||||||
|
|
||||||
|
Signed-off-by: Coly Li <colyli@suse.de>
|
||||||
|
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
util.c | 9 ++++++---
|
||||||
|
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/util.c b/util.c
|
||||||
|
index 7fc881bf..b0b7aec4 100644
|
||||||
|
--- a/util.c
|
||||||
|
+++ b/util.c
|
||||||
|
@@ -421,12 +421,15 @@ int parse_layout_10(char *layout)
|
||||||
|
|
||||||
|
int parse_layout_faulty(char *layout)
|
||||||
|
{
|
||||||
|
+ int ln, mode;
|
||||||
|
+ char *m;
|
||||||
|
+
|
||||||
|
if (!layout)
|
||||||
|
return -1;
|
||||||
|
+
|
||||||
|
/* Parse the layout string for 'faulty' */
|
||||||
|
- int ln = strcspn(layout, "0123456789");
|
||||||
|
- char *m = xstrdup(layout);
|
||||||
|
- int mode;
|
||||||
|
+ ln = strcspn(layout, "0123456789");
|
||||||
|
+ m = xstrdup(layout);
|
||||||
|
m[ln] = 0;
|
||||||
|
mode = map_name(faultylayout, m);
|
||||||
|
if (mode == UnSet)
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
32
SOURCES/0094-util.c-fix-memleak-in-parse_layout_faulty.patch
Normal file
32
SOURCES/0094-util.c-fix-memleak-in-parse_layout_faulty.patch
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
From 06ef619582b47af89eb094c164fc5effd46d6048 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Wu Guanghao <wuguanghao3@huawei.com>
|
||||||
|
Date: Sat, 4 Mar 2023 00:21:31 +0800
|
||||||
|
Subject: [PATCH 094/125] util.c: fix memleak in parse_layout_faulty()
|
||||||
|
|
||||||
|
char *m is allocated by xstrdup but not free() before return, will cause
|
||||||
|
a memory leak
|
||||||
|
|
||||||
|
Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
|
||||||
|
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
util.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/util.c b/util.c
|
||||||
|
index b0b7aec4..9f1e1f7c 100644
|
||||||
|
--- a/util.c
|
||||||
|
+++ b/util.c
|
||||||
|
@@ -432,6 +432,8 @@ int parse_layout_faulty(char *layout)
|
||||||
|
m = xstrdup(layout);
|
||||||
|
m[ln] = 0;
|
||||||
|
mode = map_name(faultylayout, m);
|
||||||
|
+ free(m);
|
||||||
|
+
|
||||||
|
if (mode == UnSet)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
31
SOURCES/0095-Detail.c-fix-memleak-in-Detail.patch
Normal file
31
SOURCES/0095-Detail.c-fix-memleak-in-Detail.patch
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
From dac0b5121dd77bf1659b95248423445f932dfae4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Wu Guanghao <wuguanghao3@huawei.com>
|
||||||
|
Date: Sat, 4 Mar 2023 00:21:32 +0800
|
||||||
|
Subject: [PATCH 095/125] Detail.c: fix memleak in Detail()
|
||||||
|
|
||||||
|
char *sysdev = xstrdup() but not free() in for loop, will cause memory
|
||||||
|
leak
|
||||||
|
|
||||||
|
Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
|
||||||
|
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Detail.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/Detail.c b/Detail.c
|
||||||
|
index ce7a8445..4ef26460 100644
|
||||||
|
--- a/Detail.c
|
||||||
|
+++ b/Detail.c
|
||||||
|
@@ -303,6 +303,7 @@ int Detail(char *dev, struct context *c)
|
||||||
|
if (path)
|
||||||
|
printf("MD_DEVICE_%s_DEV=%s\n",
|
||||||
|
sysdev, path);
|
||||||
|
+ free(sysdev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,63 @@
|
|||||||
|
From 50cd06b484bb99bfacdd4f9d2f8ee5e52bfc7bd3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Wu Guanghao <wuguanghao3@huawei.com>
|
||||||
|
Date: Sat, 4 Mar 2023 00:21:33 +0800
|
||||||
|
Subject: [PATCH 096/125] isuper-intel.c: fix double free in load_imsm_mpb()
|
||||||
|
|
||||||
|
In load_imsm_mpb() there is potential double free issue on super->buf.
|
||||||
|
|
||||||
|
The first location to free super->buf is from get_super_block() <==
|
||||||
|
load_and_parse_mpb() <== load_imsm_mpb():
|
||||||
|
4514 if (posix_memalign(&super->migr_rec_buf, MAX_SECTOR_SIZE,
|
||||||
|
4515 MIGR_REC_BUF_SECTORS*MAX_SECTOR_SIZE) != 0) {
|
||||||
|
4516 pr_err("could not allocate migr_rec buffer\n");
|
||||||
|
4517 free(super->buf);
|
||||||
|
4518 return 2;
|
||||||
|
4519 }
|
||||||
|
|
||||||
|
If the above error condition happens, super->buf is freed and value 2
|
||||||
|
is returned to get_super_block() eventually. Then in the following code
|
||||||
|
block inside load_imsm_mpb(),
|
||||||
|
5289 error:
|
||||||
|
5290 if (!err) {
|
||||||
|
5291 s->next = *super_list;
|
||||||
|
5292 *super_list = s;
|
||||||
|
5293 } else {
|
||||||
|
5294 if (s)
|
||||||
|
5295 free_imsm(s);
|
||||||
|
5296 close_fd(&dfd);
|
||||||
|
5297 }
|
||||||
|
at line 5295 when free_imsm() is called, super->buf is freed again from
|
||||||
|
the call chain free_imsm() <== __free_imsm(), in following code block,
|
||||||
|
4651 if (super->buf) {
|
||||||
|
4652 free(super->buf);
|
||||||
|
4653 super->buf = NULL;
|
||||||
|
4654 }
|
||||||
|
|
||||||
|
This patch sets super->buf as NULL after line 4517 in load_imsm_mpb()
|
||||||
|
to avoid the potential double free().
|
||||||
|
|
||||||
|
(Coly Li helps to re-compose the commit log)
|
||||||
|
|
||||||
|
Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
|
||||||
|
Reviewed-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
super-intel.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index 89fac626..4a3da847 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -4515,6 +4515,7 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname)
|
||||||
|
MIGR_REC_BUF_SECTORS*MAX_SECTOR_SIZE) != 0) {
|
||||||
|
pr_err("could not allocate migr_rec buffer\n");
|
||||||
|
free(super->buf);
|
||||||
|
+ super->buf = NULL;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
super->clean_migration_record_by_mdmon = 0;
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,39 @@
|
|||||||
|
From 5d2434d18b6bc71bd16678b1a6d1cc3a92f1d415 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Wu Guanghao <wuguanghao3@huawei.com>
|
||||||
|
Date: Sat, 4 Mar 2023 00:21:34 +0800
|
||||||
|
Subject: [PATCH 097/125] super-intel.c: fix memleak in
|
||||||
|
find_disk_attached_hba()
|
||||||
|
|
||||||
|
If disk_path = diskfd_to_devpath(), we need free(disk_path) before
|
||||||
|
return, otherwise there will be a memory leak
|
||||||
|
|
||||||
|
Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
|
||||||
|
Reviewed-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
super-intel.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index 4a3da847..e155a8ae 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -713,12 +713,12 @@ static struct sys_dev* find_disk_attached_hba(int fd, const char *devname)
|
||||||
|
|
||||||
|
for (elem = list; elem; elem = elem->next)
|
||||||
|
if (path_attached_to_hba(disk_path, elem->path))
|
||||||
|
- return elem;
|
||||||
|
+ break;
|
||||||
|
|
||||||
|
if (disk_path != devname)
|
||||||
|
free(disk_path);
|
||||||
|
|
||||||
|
- return NULL;
|
||||||
|
+ return elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int find_intel_hba_capability(int fd, struct intel_super *super,
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,46 @@
|
|||||||
|
From 68b90794adf8287fa534cc8f35efb09772b133d0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Wu Guanghao <wuguanghao3@huawei.com>
|
||||||
|
Date: Sat, 4 Mar 2023 00:21:35 +0800
|
||||||
|
Subject: [PATCH 098/125] super-ddf.c: fix memleak in get_vd_num_of_subarray()
|
||||||
|
|
||||||
|
sra = sysfs_read() should be free before return in
|
||||||
|
get_vd_num_of_subarray()
|
||||||
|
|
||||||
|
Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
|
||||||
|
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
super-ddf.c | 9 +++++++--
|
||||||
|
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/super-ddf.c b/super-ddf.c
|
||||||
|
index 309812df..b86c6acd 100644
|
||||||
|
--- a/super-ddf.c
|
||||||
|
+++ b/super-ddf.c
|
||||||
|
@@ -1592,15 +1592,20 @@ static unsigned int get_vd_num_of_subarray(struct supertype *st)
|
||||||
|
sra = sysfs_read(-1, st->devnm, GET_VERSION);
|
||||||
|
if (!sra || sra->array.major_version != -1 ||
|
||||||
|
sra->array.minor_version != -2 ||
|
||||||
|
- !is_subarray(sra->text_version))
|
||||||
|
+ !is_subarray(sra->text_version)) {
|
||||||
|
+ if (sra)
|
||||||
|
+ sysfs_free(sra);
|
||||||
|
return DDF_NOTFOUND;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
sub = strchr(sra->text_version + 1, '/');
|
||||||
|
if (sub != NULL)
|
||||||
|
vcnum = strtoul(sub + 1, &end, 10);
|
||||||
|
if (sub == NULL || *sub == '\0' || *end != '\0' ||
|
||||||
|
- vcnum >= be16_to_cpu(ddf->active->max_vd_entries))
|
||||||
|
+ vcnum >= be16_to_cpu(ddf->active->max_vd_entries)) {
|
||||||
|
+ sysfs_free(sra);
|
||||||
|
return DDF_NOTFOUND;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return vcnum;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,36 @@
|
|||||||
|
From ba867e2ebaead20e3d9a7e62ef8fd940176c3110 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
Date: Wed, 1 Mar 2023 13:41:29 -0700
|
||||||
|
Subject: [PATCH 099/125] Create: goto abort_locked instead of return 1 in
|
||||||
|
error path
|
||||||
|
|
||||||
|
The return 1 after the fstat_is_blkdev() check should be replaced
|
||||||
|
with an error return that goes through the error path to unlock
|
||||||
|
resources locked by this function.
|
||||||
|
|
||||||
|
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
Acked-by: Kinga Tanska <kinga.tanska@linux.intel.com>
|
||||||
|
Reviewed-by: Xiao Ni <xni@redhat.com>
|
||||||
|
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Create.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/Create.c b/Create.c
|
||||||
|
index 953e7372..2e8203ec 100644
|
||||||
|
--- a/Create.c
|
||||||
|
+++ b/Create.c
|
||||||
|
@@ -939,7 +939,7 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
goto abort_locked;
|
||||||
|
}
|
||||||
|
if (!fstat_is_blkdev(fd, dv->devname, &rdev))
|
||||||
|
- return 1;
|
||||||
|
+ goto abort_locked;
|
||||||
|
inf->disk.major = major(rdev);
|
||||||
|
inf->disk.minor = minor(rdev);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,64 @@
|
|||||||
|
From fb2c0f6183e29b014608e5e1aa4d53cb55887326 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
Date: Wed, 1 Mar 2023 13:41:30 -0700
|
||||||
|
Subject: [PATCH 100/125] Create: remove safe_mode_delay local variable
|
||||||
|
|
||||||
|
All .getinfo_super() call sets the info.safe_mode_delay variables
|
||||||
|
to a constant value, so no matter what the current state is
|
||||||
|
that function will always set it to the same value.
|
||||||
|
|
||||||
|
Create() calls .getinfo_super() multiple times while creating the array.
|
||||||
|
The value is stored in a local variable for every disk in the loop
|
||||||
|
to add disks (so the last disc call takes precedence). The local
|
||||||
|
variable is then used in the call to sysfs_set_safemode().
|
||||||
|
|
||||||
|
This can be simplified by using info.safe_mode_delay directly. The info
|
||||||
|
variable had .getinfo_super() called on it early in the function so, by the
|
||||||
|
reasoning above, it will have the same value as the local variable which
|
||||||
|
can thus be removed.
|
||||||
|
|
||||||
|
Doing this allows for factoring out code from Create() in a subsequent
|
||||||
|
patch.
|
||||||
|
|
||||||
|
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
Acked-by: Kinga Tanska <kinga.tanska@linux.intel.com>
|
||||||
|
Reviewed-by: Xiao Ni <xni@redhat.com>
|
||||||
|
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Create.c | 4 +---
|
||||||
|
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Create.c b/Create.c
|
||||||
|
index 2e8203ec..8ded81dc 100644
|
||||||
|
--- a/Create.c
|
||||||
|
+++ b/Create.c
|
||||||
|
@@ -137,7 +137,6 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
int did_default = 0;
|
||||||
|
int do_default_layout = 0;
|
||||||
|
int do_default_chunk = 0;
|
||||||
|
- unsigned long safe_mode_delay = 0;
|
||||||
|
char chosen_name[1024];
|
||||||
|
struct map_ent *map = NULL;
|
||||||
|
unsigned long long newsize;
|
||||||
|
@@ -952,7 +951,6 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
goto abort_locked;
|
||||||
|
}
|
||||||
|
st->ss->getinfo_super(st, inf, NULL);
|
||||||
|
- safe_mode_delay = inf->safe_mode_delay;
|
||||||
|
|
||||||
|
if (have_container && c->verbose > 0)
|
||||||
|
pr_err("Using %s for device %d\n",
|
||||||
|
@@ -1065,7 +1063,7 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
"readonly");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- sysfs_set_safemode(&info, safe_mode_delay);
|
||||||
|
+ sysfs_set_safemode(&info, info.safe_mode_delay);
|
||||||
|
if (err) {
|
||||||
|
pr_err("failed to activate array.\n");
|
||||||
|
ioctl(mdfd, STOP_ARRAY, NULL);
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
452
SOURCES/0101-Create-Factor-out-add_disks-helpers.patch
Normal file
452
SOURCES/0101-Create-Factor-out-add_disks-helpers.patch
Normal file
@ -0,0 +1,452 @@
|
|||||||
|
From 8a4ce2c053866ac97feb436c4c85a54446ee0016 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
Date: Wed, 1 Mar 2023 13:41:31 -0700
|
||||||
|
Subject: [PATCH 101/125] Create: Factor out add_disks() helpers
|
||||||
|
|
||||||
|
The Create function is massive with a very large number of variables.
|
||||||
|
Reading and understanding the function is almost impossible. To help
|
||||||
|
with this, factor out the two pass loop that adds the disks to the array.
|
||||||
|
|
||||||
|
This moves about 160 lines into three new helper functions and removes
|
||||||
|
a bunch of local variables from the main Create function. The main new
|
||||||
|
helper function add_disks() does the two pass loop and calls into
|
||||||
|
add_disk_to_super() and update_metadata(). Factoring out the
|
||||||
|
latter two helpers also helps to reduce a ton of indentation.
|
||||||
|
|
||||||
|
No functional changes intended.
|
||||||
|
|
||||||
|
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
Acked-by: Kinga Tanska <kinga.tanska@linux.intel.com>
|
||||||
|
Reviewed-by: Xiao Ni <xni@redhat.com>
|
||||||
|
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Create.c | 382 +++++++++++++++++++++++++++++++------------------------
|
||||||
|
1 file changed, 213 insertions(+), 169 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Create.c b/Create.c
|
||||||
|
index 8ded81dc..6a044664 100644
|
||||||
|
--- a/Create.c
|
||||||
|
+++ b/Create.c
|
||||||
|
@@ -91,6 +91,214 @@ int default_layout(struct supertype *st, int level, int verbose)
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int add_disk_to_super(int mdfd, struct shape *s, struct context *c,
|
||||||
|
+ struct supertype *st, struct mddev_dev *dv,
|
||||||
|
+ struct mdinfo *info, int have_container, int major_num)
|
||||||
|
+{
|
||||||
|
+ dev_t rdev;
|
||||||
|
+ int fd;
|
||||||
|
+
|
||||||
|
+ if (dv->disposition == 'j') {
|
||||||
|
+ info->disk.raid_disk = MD_DISK_ROLE_JOURNAL;
|
||||||
|
+ info->disk.state = (1<<MD_DISK_JOURNAL);
|
||||||
|
+ } else if (info->disk.raid_disk < s->raiddisks) {
|
||||||
|
+ info->disk.state = (1<<MD_DISK_ACTIVE) |
|
||||||
|
+ (1<<MD_DISK_SYNC);
|
||||||
|
+ } else {
|
||||||
|
+ info->disk.state = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (dv->writemostly == FlagSet) {
|
||||||
|
+ if (major_num == BITMAP_MAJOR_CLUSTERED) {
|
||||||
|
+ pr_err("Can not set %s --write-mostly with a clustered bitmap\n",dv->devname);
|
||||||
|
+ return 1;
|
||||||
|
+ } else {
|
||||||
|
+ info->disk.state |= (1<<MD_DISK_WRITEMOSTLY);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (dv->failfast == FlagSet)
|
||||||
|
+ info->disk.state |= (1<<MD_DISK_FAILFAST);
|
||||||
|
+
|
||||||
|
+ if (have_container) {
|
||||||
|
+ fd = -1;
|
||||||
|
+ } else {
|
||||||
|
+ if (st->ss->external && st->container_devnm[0])
|
||||||
|
+ fd = open(dv->devname, O_RDWR);
|
||||||
|
+ else
|
||||||
|
+ fd = open(dv->devname, O_RDWR|O_EXCL);
|
||||||
|
+
|
||||||
|
+ if (fd < 0) {
|
||||||
|
+ pr_err("failed to open %s after earlier success - aborting\n",
|
||||||
|
+ dv->devname);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ if (!fstat_is_blkdev(fd, dv->devname, &rdev))
|
||||||
|
+ return 1;
|
||||||
|
+ info->disk.major = major(rdev);
|
||||||
|
+ info->disk.minor = minor(rdev);
|
||||||
|
+ }
|
||||||
|
+ if (fd >= 0)
|
||||||
|
+ remove_partitions(fd);
|
||||||
|
+ if (st->ss->add_to_super(st, &info->disk, fd, dv->devname,
|
||||||
|
+ dv->data_offset)) {
|
||||||
|
+ ioctl(mdfd, STOP_ARRAY, NULL);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ st->ss->getinfo_super(st, info, NULL);
|
||||||
|
+
|
||||||
|
+ if (have_container && c->verbose > 0)
|
||||||
|
+ pr_err("Using %s for device %d\n",
|
||||||
|
+ map_dev(info->disk.major, info->disk.minor, 0),
|
||||||
|
+ info->disk.number);
|
||||||
|
+
|
||||||
|
+ if (!have_container) {
|
||||||
|
+ /* getinfo_super might have lost these ... */
|
||||||
|
+ info->disk.major = major(rdev);
|
||||||
|
+ info->disk.minor = minor(rdev);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int update_metadata(int mdfd, struct shape *s, struct supertype *st,
|
||||||
|
+ struct map_ent **map, struct mdinfo *info,
|
||||||
|
+ char *chosen_name)
|
||||||
|
+{
|
||||||
|
+ struct mdinfo info_new;
|
||||||
|
+ struct map_ent *me = NULL;
|
||||||
|
+
|
||||||
|
+ /* check to see if the uuid has changed due to these
|
||||||
|
+ * metadata changes, and if so update the member array
|
||||||
|
+ * and container uuid. Note ->write_init_super clears
|
||||||
|
+ * the subarray cursor such that ->getinfo_super once
|
||||||
|
+ * again returns container info.
|
||||||
|
+ */
|
||||||
|
+ st->ss->getinfo_super(st, &info_new, NULL);
|
||||||
|
+ if (st->ss->external && is_container(s->level) &&
|
||||||
|
+ !same_uuid(info_new.uuid, info->uuid, 0)) {
|
||||||
|
+ map_update(map, fd2devnm(mdfd),
|
||||||
|
+ info_new.text_version,
|
||||||
|
+ info_new.uuid, chosen_name);
|
||||||
|
+ me = map_by_devnm(map, st->container_devnm);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (st->ss->write_init_super(st)) {
|
||||||
|
+ st->ss->free_super(st);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Before activating the array, perform extra steps
|
||||||
|
+ * required to configure the internal write-intent
|
||||||
|
+ * bitmap.
|
||||||
|
+ */
|
||||||
|
+ if (info_new.consistency_policy == CONSISTENCY_POLICY_BITMAP &&
|
||||||
|
+ st->ss->set_bitmap && st->ss->set_bitmap(st, info)) {
|
||||||
|
+ st->ss->free_super(st);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* update parent container uuid */
|
||||||
|
+ if (me) {
|
||||||
|
+ char *path = xstrdup(me->path);
|
||||||
|
+
|
||||||
|
+ st->ss->getinfo_super(st, &info_new, NULL);
|
||||||
|
+ map_update(map, st->container_devnm, info_new.text_version,
|
||||||
|
+ info_new.uuid, path);
|
||||||
|
+ free(path);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ flush_metadata_updates(st);
|
||||||
|
+ st->ss->free_super(st);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int add_disks(int mdfd, struct mdinfo *info, struct shape *s,
|
||||||
|
+ struct context *c, struct supertype *st,
|
||||||
|
+ struct map_ent **map, struct mddev_dev *devlist,
|
||||||
|
+ int total_slots, int have_container, int insert_point,
|
||||||
|
+ int major_num, char *chosen_name)
|
||||||
|
+{
|
||||||
|
+ struct mddev_dev *moved_disk = NULL;
|
||||||
|
+ int pass, raid_disk_num, dnum;
|
||||||
|
+ struct mddev_dev *dv;
|
||||||
|
+ struct mdinfo *infos;
|
||||||
|
+ int ret = 0;
|
||||||
|
+
|
||||||
|
+ infos = xmalloc(sizeof(*infos) * total_slots);
|
||||||
|
+ enable_fds(total_slots);
|
||||||
|
+ for (pass = 1; pass <= 2; pass++) {
|
||||||
|
+ for (dnum = 0, raid_disk_num = 0, dv = devlist; dv;
|
||||||
|
+ dv = (dv->next) ? (dv->next) : moved_disk, dnum++) {
|
||||||
|
+ if (dnum >= total_slots)
|
||||||
|
+ abort();
|
||||||
|
+ if (dnum == insert_point) {
|
||||||
|
+ raid_disk_num += 1;
|
||||||
|
+ moved_disk = dv;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ if (strcasecmp(dv->devname, "missing") == 0) {
|
||||||
|
+ raid_disk_num += 1;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ if (have_container)
|
||||||
|
+ moved_disk = NULL;
|
||||||
|
+ if (have_container && dnum < total_slots - 1)
|
||||||
|
+ /* repeatedly use the container */
|
||||||
|
+ moved_disk = dv;
|
||||||
|
+
|
||||||
|
+ switch(pass) {
|
||||||
|
+ case 1:
|
||||||
|
+ infos[dnum] = *info;
|
||||||
|
+ infos[dnum].disk.number = dnum;
|
||||||
|
+ infos[dnum].disk.raid_disk = raid_disk_num++;
|
||||||
|
+
|
||||||
|
+ if (dv->disposition == 'j')
|
||||||
|
+ raid_disk_num--;
|
||||||
|
+
|
||||||
|
+ ret = add_disk_to_super(mdfd, s, c, st, dv,
|
||||||
|
+ &infos[dnum], have_container,
|
||||||
|
+ major_num);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ break;
|
||||||
|
+ case 2:
|
||||||
|
+ infos[dnum].errors = 0;
|
||||||
|
+
|
||||||
|
+ ret = add_disk(mdfd, st, info, &infos[dnum]);
|
||||||
|
+ if (ret) {
|
||||||
|
+ pr_err("ADD_NEW_DISK for %s failed: %s\n",
|
||||||
|
+ dv->devname, strerror(errno));
|
||||||
|
+ if (errno == EINVAL &&
|
||||||
|
+ info->array.level == 0) {
|
||||||
|
+ pr_err("Possibly your kernel doesn't support RAID0 layouts.\n");
|
||||||
|
+ pr_err("Either upgrade, or use --layout=dangerous\n");
|
||||||
|
+ }
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ if (!have_container &&
|
||||||
|
+ dv == moved_disk && dnum != insert_point) break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (pass == 1) {
|
||||||
|
+ ret = update_metadata(mdfd, s, st, map, info,
|
||||||
|
+ chosen_name);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+out:
|
||||||
|
+ free(infos);
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int Create(struct supertype *st, char *mddev,
|
||||||
|
char *name, int *uuid,
|
||||||
|
int subdevs, struct mddev_dev *devlist,
|
||||||
|
@@ -117,7 +325,7 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
unsigned long long minsize = 0, maxsize = 0;
|
||||||
|
char *mindisc = NULL;
|
||||||
|
char *maxdisc = NULL;
|
||||||
|
- int dnum, raid_disk_num;
|
||||||
|
+ int dnum;
|
||||||
|
struct mddev_dev *dv;
|
||||||
|
dev_t rdev;
|
||||||
|
int fail = 0, warn = 0;
|
||||||
|
@@ -126,14 +334,13 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
int missing_disks = 0;
|
||||||
|
int insert_point = subdevs * 2; /* where to insert a missing drive */
|
||||||
|
int total_slots;
|
||||||
|
- int pass;
|
||||||
|
int rv;
|
||||||
|
int bitmap_fd;
|
||||||
|
int have_container = 0;
|
||||||
|
int container_fd = -1;
|
||||||
|
int need_mdmon = 0;
|
||||||
|
unsigned long long bitmapsize;
|
||||||
|
- struct mdinfo info, *infos;
|
||||||
|
+ struct mdinfo info;
|
||||||
|
int did_default = 0;
|
||||||
|
int do_default_layout = 0;
|
||||||
|
int do_default_chunk = 0;
|
||||||
|
@@ -869,174 +1076,11 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- infos = xmalloc(sizeof(*infos) * total_slots);
|
||||||
|
- enable_fds(total_slots);
|
||||||
|
- for (pass = 1; pass <= 2; pass++) {
|
||||||
|
- struct mddev_dev *moved_disk = NULL; /* the disk that was moved out of the insert point */
|
||||||
|
-
|
||||||
|
- for (dnum = 0, raid_disk_num = 0, dv = devlist; dv;
|
||||||
|
- dv = (dv->next) ? (dv->next) : moved_disk, dnum++) {
|
||||||
|
- int fd;
|
||||||
|
- struct mdinfo *inf = &infos[dnum];
|
||||||
|
-
|
||||||
|
- if (dnum >= total_slots)
|
||||||
|
- abort();
|
||||||
|
- if (dnum == insert_point) {
|
||||||
|
- raid_disk_num += 1;
|
||||||
|
- moved_disk = dv;
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
- if (strcasecmp(dv->devname, "missing") == 0) {
|
||||||
|
- raid_disk_num += 1;
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
- if (have_container)
|
||||||
|
- moved_disk = NULL;
|
||||||
|
- if (have_container && dnum < info.array.raid_disks - 1)
|
||||||
|
- /* repeatedly use the container */
|
||||||
|
- moved_disk = dv;
|
||||||
|
-
|
||||||
|
- switch(pass) {
|
||||||
|
- case 1:
|
||||||
|
- *inf = info;
|
||||||
|
-
|
||||||
|
- inf->disk.number = dnum;
|
||||||
|
- inf->disk.raid_disk = raid_disk_num++;
|
||||||
|
-
|
||||||
|
- if (dv->disposition == 'j') {
|
||||||
|
- inf->disk.raid_disk = MD_DISK_ROLE_JOURNAL;
|
||||||
|
- inf->disk.state = (1<<MD_DISK_JOURNAL);
|
||||||
|
- raid_disk_num--;
|
||||||
|
- } else if (inf->disk.raid_disk < s->raiddisks)
|
||||||
|
- inf->disk.state = (1<<MD_DISK_ACTIVE) |
|
||||||
|
- (1<<MD_DISK_SYNC);
|
||||||
|
- else
|
||||||
|
- inf->disk.state = 0;
|
||||||
|
-
|
||||||
|
- if (dv->writemostly == FlagSet) {
|
||||||
|
- if (major_num == BITMAP_MAJOR_CLUSTERED) {
|
||||||
|
- pr_err("Can not set %s --write-mostly with a clustered bitmap\n",dv->devname);
|
||||||
|
- goto abort_locked;
|
||||||
|
- } else
|
||||||
|
- inf->disk.state |= (1<<MD_DISK_WRITEMOSTLY);
|
||||||
|
- }
|
||||||
|
- if (dv->failfast == FlagSet)
|
||||||
|
- inf->disk.state |= (1<<MD_DISK_FAILFAST);
|
||||||
|
-
|
||||||
|
- if (have_container)
|
||||||
|
- fd = -1;
|
||||||
|
- else {
|
||||||
|
- if (st->ss->external &&
|
||||||
|
- st->container_devnm[0])
|
||||||
|
- fd = open(dv->devname, O_RDWR);
|
||||||
|
- else
|
||||||
|
- fd = open(dv->devname, O_RDWR|O_EXCL);
|
||||||
|
-
|
||||||
|
- if (fd < 0) {
|
||||||
|
- pr_err("failed to open %s after earlier success - aborting\n",
|
||||||
|
- dv->devname);
|
||||||
|
- goto abort_locked;
|
||||||
|
- }
|
||||||
|
- if (!fstat_is_blkdev(fd, dv->devname, &rdev))
|
||||||
|
- goto abort_locked;
|
||||||
|
- inf->disk.major = major(rdev);
|
||||||
|
- inf->disk.minor = minor(rdev);
|
||||||
|
- }
|
||||||
|
- if (fd >= 0)
|
||||||
|
- remove_partitions(fd);
|
||||||
|
- if (st->ss->add_to_super(st, &inf->disk,
|
||||||
|
- fd, dv->devname,
|
||||||
|
- dv->data_offset)) {
|
||||||
|
- ioctl(mdfd, STOP_ARRAY, NULL);
|
||||||
|
- goto abort_locked;
|
||||||
|
- }
|
||||||
|
- st->ss->getinfo_super(st, inf, NULL);
|
||||||
|
-
|
||||||
|
- if (have_container && c->verbose > 0)
|
||||||
|
- pr_err("Using %s for device %d\n",
|
||||||
|
- map_dev(inf->disk.major,
|
||||||
|
- inf->disk.minor,
|
||||||
|
- 0), dnum);
|
||||||
|
-
|
||||||
|
- if (!have_container) {
|
||||||
|
- /* getinfo_super might have lost these ... */
|
||||||
|
- inf->disk.major = major(rdev);
|
||||||
|
- inf->disk.minor = minor(rdev);
|
||||||
|
- }
|
||||||
|
- break;
|
||||||
|
- case 2:
|
||||||
|
- inf->errors = 0;
|
||||||
|
-
|
||||||
|
- rv = add_disk(mdfd, st, &info, inf);
|
||||||
|
-
|
||||||
|
- if (rv) {
|
||||||
|
- pr_err("ADD_NEW_DISK for %s failed: %s\n",
|
||||||
|
- dv->devname, strerror(errno));
|
||||||
|
- if (errno == EINVAL &&
|
||||||
|
- info.array.level == 0) {
|
||||||
|
- pr_err("Possibly your kernel doesn't support RAID0 layouts.\n");
|
||||||
|
- pr_err("Either upgrade, or use --layout=dangerous\n");
|
||||||
|
- }
|
||||||
|
- goto abort_locked;
|
||||||
|
- }
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- if (!have_container &&
|
||||||
|
- dv == moved_disk && dnum != insert_point) break;
|
||||||
|
- }
|
||||||
|
- if (pass == 1) {
|
||||||
|
- struct mdinfo info_new;
|
||||||
|
- struct map_ent *me = NULL;
|
||||||
|
-
|
||||||
|
- /* check to see if the uuid has changed due to these
|
||||||
|
- * metadata changes, and if so update the member array
|
||||||
|
- * and container uuid. Note ->write_init_super clears
|
||||||
|
- * the subarray cursor such that ->getinfo_super once
|
||||||
|
- * again returns container info.
|
||||||
|
- */
|
||||||
|
- st->ss->getinfo_super(st, &info_new, NULL);
|
||||||
|
- if (st->ss->external && !is_container(s->level) &&
|
||||||
|
- !same_uuid(info_new.uuid, info.uuid, 0)) {
|
||||||
|
- map_update(&map, fd2devnm(mdfd),
|
||||||
|
- info_new.text_version,
|
||||||
|
- info_new.uuid, chosen_name);
|
||||||
|
- me = map_by_devnm(&map, st->container_devnm);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (st->ss->write_init_super(st)) {
|
||||||
|
- st->ss->free_super(st);
|
||||||
|
- goto abort_locked;
|
||||||
|
- }
|
||||||
|
- /*
|
||||||
|
- * Before activating the array, perform extra steps
|
||||||
|
- * required to configure the internal write-intent
|
||||||
|
- * bitmap.
|
||||||
|
- */
|
||||||
|
- if (info_new.consistency_policy ==
|
||||||
|
- CONSISTENCY_POLICY_BITMAP &&
|
||||||
|
- st->ss->set_bitmap &&
|
||||||
|
- st->ss->set_bitmap(st, &info)) {
|
||||||
|
- st->ss->free_super(st);
|
||||||
|
- goto abort_locked;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* update parent container uuid */
|
||||||
|
- if (me) {
|
||||||
|
- char *path = xstrdup(me->path);
|
||||||
|
-
|
||||||
|
- st->ss->getinfo_super(st, &info_new, NULL);
|
||||||
|
- map_update(&map, st->container_devnm,
|
||||||
|
- info_new.text_version,
|
||||||
|
- info_new.uuid, path);
|
||||||
|
- free(path);
|
||||||
|
- }
|
||||||
|
+ if (add_disks(mdfd, &info, s, c, st, &map, devlist, total_slots,
|
||||||
|
+ have_container, insert_point, major_num, chosen_name))
|
||||||
|
+ goto abort_locked;
|
||||||
|
|
||||||
|
- flush_metadata_updates(st);
|
||||||
|
- st->ss->free_super(st);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
map_unlock(&map);
|
||||||
|
- free(infos);
|
||||||
|
|
||||||
|
if (is_container(s->level)) {
|
||||||
|
/* No need to start. But we should signal udev to
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
72
SOURCES/0102-mdadm-Introduce-pr_info.patch
Normal file
72
SOURCES/0102-mdadm-Introduce-pr_info.patch
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
From 9364dbfb264e89ab9467dfc0d2b813033e320640 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
Date: Wed, 1 Mar 2023 13:41:32 -0700
|
||||||
|
Subject: [PATCH 102/125] mdadm: Introduce pr_info()
|
||||||
|
|
||||||
|
Feedback was given to avoid informational pr_err() calls that print
|
||||||
|
to stderr, even though that's done all through out the code.
|
||||||
|
|
||||||
|
Using printf() directly doesn't maintain the same format (an "mdadm"
|
||||||
|
prefix on every line.
|
||||||
|
|
||||||
|
So introduce pr_info() which prints to stdout with the same format
|
||||||
|
and use it for a couple informational pr_err() calls in Create().
|
||||||
|
|
||||||
|
Future work can make this call used in more cases.
|
||||||
|
|
||||||
|
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
Acked-by: Kinga Tanska <kinga.tanska@linux.intel.com>
|
||||||
|
Reviewed-by: Xiao Ni <xni@redhat.com>
|
||||||
|
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Acked-by: Paul Menzel <pmenzel@molgen.mpg.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Create.c | 7 ++++---
|
||||||
|
mdadm.h | 2 ++
|
||||||
|
2 files changed, 6 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Create.c b/Create.c
|
||||||
|
index 6a044664..4acda30c 100644
|
||||||
|
--- a/Create.c
|
||||||
|
+++ b/Create.c
|
||||||
|
@@ -984,11 +984,12 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
|
||||||
|
mdi = sysfs_read(-1, devnm, GET_VERSION);
|
||||||
|
|
||||||
|
- pr_err("Creating array inside %s container %s\n",
|
||||||
|
+ pr_info("Creating array inside %s container %s\n",
|
||||||
|
mdi?mdi->text_version:"managed", devnm);
|
||||||
|
sysfs_free(mdi);
|
||||||
|
} else
|
||||||
|
- pr_err("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,
|
||||||
|
@@ -1145,7 +1146,7 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
ioctl(mdfd, RESTART_ARRAY_RW, NULL);
|
||||||
|
}
|
||||||
|
if (c->verbose >= 0)
|
||||||
|
- pr_err("array %s started.\n", mddev);
|
||||||
|
+ pr_info("array %s started.\n", mddev);
|
||||||
|
if (st->ss->external && st->container_devnm[0]) {
|
||||||
|
if (need_mdmon)
|
||||||
|
start_mdmon(st->container_devnm);
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index 1674ce13..4336be4d 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -1854,6 +1854,8 @@ static inline int xasprintf(char **strp, const char *fmt, ...) {
|
||||||
|
#endif
|
||||||
|
#define cont_err(fmt ...) fprintf(stderr, " " fmt)
|
||||||
|
|
||||||
|
+#define pr_info(fmt, args...) printf("%s: "fmt, Name, ##args)
|
||||||
|
+
|
||||||
|
void *xmalloc(size_t len);
|
||||||
|
void *xrealloc(void *ptr, size_t len);
|
||||||
|
void *xcalloc(size_t num, size_t size);
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
346
SOURCES/0103-mdadm-Add-write-zeros-option-for-Create.patch
Normal file
346
SOURCES/0103-mdadm-Add-write-zeros-option-for-Create.patch
Normal file
@ -0,0 +1,346 @@
|
|||||||
|
From 577fd10486d8d1472a6b559066f344ac30a3a391 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
Date: Wed, 1 Mar 2023 13:41:33 -0700
|
||||||
|
Subject: [PATCH 103/125] mdadm: Add --write-zeros option for Create
|
||||||
|
|
||||||
|
Add the --write-zeros option for Create which will send a write zeros
|
||||||
|
request to all the disks before assembling the array. After zeroing
|
||||||
|
the array, the disks will be in a known clean state and the initial
|
||||||
|
sync may be skipped.
|
||||||
|
|
||||||
|
Writing zeroes is best used when there is a hardware offload method
|
||||||
|
to zero the data. But even still, zeroing can take several minutes on
|
||||||
|
a large device. Because of this, all disks are zeroed in parallel using
|
||||||
|
their own forked process and a message is printed to the user. The main
|
||||||
|
process will proceed only after all the zeroing processes have completed
|
||||||
|
successfully.
|
||||||
|
|
||||||
|
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
Acked-by: Kinga Tanska <kinga.tanska@linux.intel.com>
|
||||||
|
Reviewed-by: Xiao Ni <xni@redhat.com>
|
||||||
|
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Create.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
ReadMe.c | 2 +
|
||||||
|
mdadm.c | 9 +++
|
||||||
|
mdadm.h | 5 ++
|
||||||
|
4 files changed, 190 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Create.c b/Create.c
|
||||||
|
index 4acda30c..bbe9e13d 100644
|
||||||
|
--- a/Create.c
|
||||||
|
+++ b/Create.c
|
||||||
|
@@ -26,6 +26,10 @@
|
||||||
|
#include "md_u.h"
|
||||||
|
#include "md_p.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
+#include <fcntl.h>
|
||||||
|
+#include <signal.h>
|
||||||
|
+#include <sys/signalfd.h>
|
||||||
|
+#include <sys/wait.h>
|
||||||
|
|
||||||
|
static int round_size_and_verify(unsigned long long *size, int chunk)
|
||||||
|
{
|
||||||
|
@@ -91,9 +95,149 @@ int default_layout(struct supertype *st, int level, int verbose)
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static pid_t write_zeroes_fork(int fd, struct shape *s, struct supertype *st,
|
||||||
|
+ struct mddev_dev *dv)
|
||||||
|
+
|
||||||
|
+{
|
||||||
|
+ const unsigned long long req_size = 1 << 30;
|
||||||
|
+ unsigned long long offset_bytes, size_bytes, sz;
|
||||||
|
+ sigset_t sigset;
|
||||||
|
+ int ret = 0;
|
||||||
|
+ pid_t pid;
|
||||||
|
+
|
||||||
|
+ size_bytes = KIB_TO_BYTES(s->size);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * If size_bytes is zero, this is a zoned raid array where
|
||||||
|
+ * each disk is of a different size and uses its full
|
||||||
|
+ * disk. Thus zero the entire disk.
|
||||||
|
+ */
|
||||||
|
+ if (!size_bytes && !get_dev_size(fd, dv->devname, &size_bytes))
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ if (dv->data_offset != INVALID_SECTORS)
|
||||||
|
+ offset_bytes = SEC_TO_BYTES(dv->data_offset);
|
||||||
|
+ else
|
||||||
|
+ offset_bytes = SEC_TO_BYTES(st->data_offset);
|
||||||
|
+
|
||||||
|
+ pr_info("zeroing data from %lld to %lld on: %s\n",
|
||||||
|
+ offset_bytes, size_bytes, dv->devname);
|
||||||
|
+
|
||||||
|
+ pid = fork();
|
||||||
|
+ if (pid < 0) {
|
||||||
|
+ pr_err("Could not fork to zero disks: %s\n", strerror(errno));
|
||||||
|
+ return pid;
|
||||||
|
+ } else if (pid != 0) {
|
||||||
|
+ return pid;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ sigemptyset(&sigset);
|
||||||
|
+ sigaddset(&sigset, SIGINT);
|
||||||
|
+ sigprocmask(SIG_UNBLOCK, &sigset, NULL);
|
||||||
|
+
|
||||||
|
+ while (size_bytes) {
|
||||||
|
+ /*
|
||||||
|
+ * Split requests to the kernel into 1GB chunks seeing the
|
||||||
|
+ * fallocate() call is not interruptible and blocking a
|
||||||
|
+ * ctrl-c for several minutes is not desirable.
|
||||||
|
+ *
|
||||||
|
+ * 1GB is chosen as a compromise: the user may still have
|
||||||
|
+ * to wait several seconds if they ctrl-c on devices that
|
||||||
|
+ * zero slowly, but will reduce the number of requests
|
||||||
|
+ * required and thus the overhead on devices that perform
|
||||||
|
+ * better.
|
||||||
|
+ */
|
||||||
|
+ sz = size_bytes;
|
||||||
|
+ if (sz >= req_size)
|
||||||
|
+ sz = req_size;
|
||||||
|
+
|
||||||
|
+ if (fallocate(fd, FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE,
|
||||||
|
+ offset_bytes, sz)) {
|
||||||
|
+ pr_err("zeroing %s failed: %s\n", dv->devname,
|
||||||
|
+ strerror(errno));
|
||||||
|
+ ret = 1;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ offset_bytes += sz;
|
||||||
|
+ size_bytes -= sz;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ exit(ret);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int wait_for_zero_forks(int *zero_pids, int count)
|
||||||
|
+{
|
||||||
|
+ int wstatus, ret = 0, i, sfd, wait_count = 0;
|
||||||
|
+ struct signalfd_siginfo fdsi;
|
||||||
|
+ bool interrupted = false;
|
||||||
|
+ sigset_t sigset;
|
||||||
|
+ ssize_t s;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < count; i++)
|
||||||
|
+ if (zero_pids[i])
|
||||||
|
+ wait_count++;
|
||||||
|
+ if (!wait_count)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ sigemptyset(&sigset);
|
||||||
|
+ sigaddset(&sigset, SIGINT);
|
||||||
|
+ sigaddset(&sigset, SIGCHLD);
|
||||||
|
+ sigprocmask(SIG_BLOCK, &sigset, NULL);
|
||||||
|
+
|
||||||
|
+ sfd = signalfd(-1, &sigset, 0);
|
||||||
|
+ if (sfd < 0) {
|
||||||
|
+ pr_err("Unable to create signalfd: %s\n", strerror(errno));
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ while (1) {
|
||||||
|
+ s = read(sfd, &fdsi, sizeof(fdsi));
|
||||||
|
+ if (s != sizeof(fdsi)) {
|
||||||
|
+ pr_err("Invalid signalfd read: %s\n", strerror(errno));
|
||||||
|
+ close(sfd);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (fdsi.ssi_signo == SIGINT) {
|
||||||
|
+ printf("\n");
|
||||||
|
+ pr_info("Interrupting zeroing processes, please wait...\n");
|
||||||
|
+ interrupted = true;
|
||||||
|
+ } else if (fdsi.ssi_signo == SIGCHLD) {
|
||||||
|
+ if (!--wait_count)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ close(sfd);
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < count; i++) {
|
||||||
|
+ if (!zero_pids[i])
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ waitpid(zero_pids[i], &wstatus, 0);
|
||||||
|
+ zero_pids[i] = 0;
|
||||||
|
+ if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus))
|
||||||
|
+ ret = 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (interrupted) {
|
||||||
|
+ pr_err("zeroing interrupted!\n");
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (ret)
|
||||||
|
+ pr_err("zeroing failed!\n");
|
||||||
|
+ else
|
||||||
|
+ pr_info("zeroing finished\n");
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int add_disk_to_super(int mdfd, struct shape *s, struct context *c,
|
||||||
|
struct supertype *st, struct mddev_dev *dv,
|
||||||
|
- struct mdinfo *info, int have_container, int major_num)
|
||||||
|
+ struct mdinfo *info, int have_container, int major_num,
|
||||||
|
+ int *zero_pid)
|
||||||
|
{
|
||||||
|
dev_t rdev;
|
||||||
|
int fd;
|
||||||
|
@@ -148,6 +292,14 @@ static int add_disk_to_super(int mdfd, struct shape *s, struct context *c,
|
||||||
|
}
|
||||||
|
st->ss->getinfo_super(st, info, NULL);
|
||||||
|
|
||||||
|
+ if (fd >= 0 && s->write_zeroes) {
|
||||||
|
+ *zero_pid = write_zeroes_fork(fd, s, st, dv);
|
||||||
|
+ if (*zero_pid <= 0) {
|
||||||
|
+ ioctl(mdfd, STOP_ARRAY, NULL);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (have_container && c->verbose > 0)
|
||||||
|
pr_err("Using %s for device %d\n",
|
||||||
|
map_dev(info->disk.major, info->disk.minor, 0),
|
||||||
|
@@ -224,10 +376,23 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s,
|
||||||
|
{
|
||||||
|
struct mddev_dev *moved_disk = NULL;
|
||||||
|
int pass, raid_disk_num, dnum;
|
||||||
|
+ int zero_pids[total_slots];
|
||||||
|
struct mddev_dev *dv;
|
||||||
|
struct mdinfo *infos;
|
||||||
|
+ sigset_t sigset, orig_sigset;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * Block SIGINT so the main thread will always wait for the
|
||||||
|
+ * zeroing processes when being interrupted. Otherwise the
|
||||||
|
+ * zeroing processes will finish their work in the background
|
||||||
|
+ * keeping the disk busy.
|
||||||
|
+ */
|
||||||
|
+ sigemptyset(&sigset);
|
||||||
|
+ sigaddset(&sigset, SIGINT);
|
||||||
|
+ sigprocmask(SIG_BLOCK, &sigset, &orig_sigset);
|
||||||
|
+ memset(zero_pids, 0, sizeof(zero_pids));
|
||||||
|
+
|
||||||
|
infos = xmalloc(sizeof(*infos) * total_slots);
|
||||||
|
enable_fds(total_slots);
|
||||||
|
for (pass = 1; pass <= 2; pass++) {
|
||||||
|
@@ -261,7 +426,7 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s,
|
||||||
|
|
||||||
|
ret = add_disk_to_super(mdfd, s, c, st, dv,
|
||||||
|
&infos[dnum], have_container,
|
||||||
|
- major_num);
|
||||||
|
+ major_num, &zero_pids[dnum]);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
@@ -287,6 +452,10 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pass == 1) {
|
||||||
|
+ ret = wait_for_zero_forks(zero_pids, total_slots);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
ret = update_metadata(mdfd, s, st, map, info,
|
||||||
|
chosen_name);
|
||||||
|
if (ret)
|
||||||
|
@@ -295,7 +464,10 @@ static int add_disks(int mdfd, struct mdinfo *info, struct shape *s,
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
+ if (ret)
|
||||||
|
+ wait_for_zero_forks(zero_pids, total_slots);
|
||||||
|
free(infos);
|
||||||
|
+ sigprocmask(SIG_SETMASK, &orig_sigset, NULL);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/ReadMe.c b/ReadMe.c
|
||||||
|
index bd8d50d2..db251ed2 100644
|
||||||
|
--- a/ReadMe.c
|
||||||
|
+++ b/ReadMe.c
|
||||||
|
@@ -138,6 +138,7 @@ struct option long_options[] = {
|
||||||
|
{"size", 1, 0, 'z'},
|
||||||
|
{"auto", 1, 0, Auto}, /* also for --assemble */
|
||||||
|
{"assume-clean",0,0, AssumeClean },
|
||||||
|
+ {"write-zeroes",0,0, WriteZeroes },
|
||||||
|
{"metadata", 1, 0, 'e'}, /* superblock format */
|
||||||
|
{"bitmap", 1, 0, Bitmap},
|
||||||
|
{"bitmap-chunk", 1, 0, BitmapChunk},
|
||||||
|
@@ -390,6 +391,7 @@ char Help_create[] =
|
||||||
|
" --write-journal= : Specify journal device for RAID-4/5/6 array\n"
|
||||||
|
" --consistency-policy= : Specify the policy that determines how the array\n"
|
||||||
|
" -k : maintains consistency in case of unexpected shutdown.\n"
|
||||||
|
+" --write-zeroes : Write zeroes to the disks before creating. This will bypass initial sync.\n"
|
||||||
|
"\n"
|
||||||
|
;
|
||||||
|
|
||||||
|
diff --git a/mdadm.c b/mdadm.c
|
||||||
|
index 57e8e6fa..4685ad6b 100644
|
||||||
|
--- a/mdadm.c
|
||||||
|
+++ b/mdadm.c
|
||||||
|
@@ -590,6 +590,10 @@ int main(int argc, char *argv[])
|
||||||
|
s.assume_clean = 1;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
+ case O(CREATE, WriteZeroes):
|
||||||
|
+ s.write_zeroes = 1;
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
case O(GROW,'n'):
|
||||||
|
case O(CREATE,'n'):
|
||||||
|
case O(BUILD,'n'): /* number of raid disks */
|
||||||
|
@@ -1251,6 +1255,11 @@ int main(int argc, char *argv[])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (s.write_zeroes && !s.assume_clean) {
|
||||||
|
+ pr_info("Disk zeroing requested, setting --assume-clean to skip resync\n");
|
||||||
|
+ s.assume_clean = 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!mode && devs_found) {
|
||||||
|
mode = MISC;
|
||||||
|
devmode = 'Q';
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index 4336be4d..b9127f9a 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -275,6 +275,9 @@ static inline void __put_unaligned32(__u32 val, void *p)
|
||||||
|
|
||||||
|
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
||||||
|
|
||||||
|
+#define KIB_TO_BYTES(x) ((x) << 10)
|
||||||
|
+#define SEC_TO_BYTES(x) ((x) << 9)
|
||||||
|
+
|
||||||
|
extern const char Name[];
|
||||||
|
|
||||||
|
struct md_bb_entry {
|
||||||
|
@@ -435,6 +438,7 @@ extern char Version[], Usage[], Help[], OptionHelp[],
|
||||||
|
*/
|
||||||
|
enum special_options {
|
||||||
|
AssumeClean = 300,
|
||||||
|
+ WriteZeroes,
|
||||||
|
BitmapChunk,
|
||||||
|
WriteBehind,
|
||||||
|
ReAdd,
|
||||||
|
@@ -640,6 +644,7 @@ struct shape {
|
||||||
|
int bitmap_chunk;
|
||||||
|
char *bitmap_file;
|
||||||
|
int assume_clean;
|
||||||
|
+ bool write_zeroes;
|
||||||
|
int write_behind;
|
||||||
|
unsigned long long size;
|
||||||
|
unsigned long long data_offset;
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,44 @@
|
|||||||
|
From c918cf2af993b55bca9f396c79713e54d3f8b6fb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
Date: Wed, 1 Mar 2023 13:41:34 -0700
|
||||||
|
Subject: [PATCH 104/125] tests/00raid5-zero: Introduce test to exercise
|
||||||
|
--write-zeros.
|
||||||
|
|
||||||
|
Attempt to create a raid5 array with --write-zeros. If it is successful
|
||||||
|
check the array to ensure it is in sync.
|
||||||
|
|
||||||
|
If it is unsuccessful and an unsupported error is printed, skip the
|
||||||
|
test.
|
||||||
|
|
||||||
|
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
Acked-by: Kinga Tanska <kinga.tanska@linux.intel.com>
|
||||||
|
Reviewed-by: Xiao Ni <xni@redhat.com>
|
||||||
|
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
tests/00raid5-zero | 12 ++++++++++++
|
||||||
|
1 file changed, 12 insertions(+)
|
||||||
|
create mode 100644 tests/00raid5-zero
|
||||||
|
|
||||||
|
diff --git a/tests/00raid5-zero b/tests/00raid5-zero
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..7d0f05a1
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/00raid5-zero
|
||||||
|
@@ -0,0 +1,12 @@
|
||||||
|
+
|
||||||
|
+if mdadm -CfR $md0 -l 5 -n3 $dev0 $dev1 $dev2 --write-zeroes ; then
|
||||||
|
+ check nosync
|
||||||
|
+ echo check > /sys/block/md0/md/sync_action;
|
||||||
|
+ check wait
|
||||||
|
+elif grep "zeroing [^ ]* failed: Operation not supported" \
|
||||||
|
+ $targetdir/stderr; then
|
||||||
|
+ echo "write-zeros not supported, skipping"
|
||||||
|
+else
|
||||||
|
+ echo >&2 "ERROR: mdadm return failure without not supported message"
|
||||||
|
+ exit 1
|
||||||
|
+fi
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,56 @@
|
|||||||
|
From 33831d845a48b9a2ac4d1e954c88a3dd8cb15753 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
Date: Wed, 1 Mar 2023 13:41:35 -0700
|
||||||
|
Subject: [PATCH 105/125] manpage: Add --write-zeroes option to manpage
|
||||||
|
|
||||||
|
Document the new --write-zeroes option in the manpage.
|
||||||
|
|
||||||
|
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
|
||||||
|
Acked-by: Kinga Tanska <kinga.tanska@linux.intel.com>
|
||||||
|
Reviewed-by: Xiao Ni <xni@redhat.com>
|
||||||
|
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
|
||||||
|
Acked-by: Coly Li <colyli@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
mdadm.8.in | 18 +++++++++++++++++-
|
||||||
|
1 file changed, 17 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/mdadm.8.in b/mdadm.8.in
|
||||||
|
index 64f71ed1..6f0f6c13 100644
|
||||||
|
--- a/mdadm.8.in
|
||||||
|
+++ b/mdadm.8.in
|
||||||
|
@@ -837,6 +837,22 @@ array is resynced at creation. From Linux version 3.0,
|
||||||
|
.B \-\-assume\-clean
|
||||||
|
can be used with that command to avoid the automatic resync.
|
||||||
|
|
||||||
|
+.TP
|
||||||
|
+.BR \-\-write-zeroes
|
||||||
|
+When creating an array, send write zeroes requests to all the block
|
||||||
|
+devices. This should zero the data area on all disks such that the
|
||||||
|
+initial sync is not necessary and, if successfull, will behave
|
||||||
|
+as if
|
||||||
|
+.B \-\-assume\-clean
|
||||||
|
+was specified.
|
||||||
|
+.IP
|
||||||
|
+This is intended for use with devices that have hardware offload for
|
||||||
|
+zeroing, but despite this zeroing can still take several minutes for
|
||||||
|
+large disks. Thus a message is printed before and after zeroing and
|
||||||
|
+each disk is zeroed in parallel with the others.
|
||||||
|
+.IP
|
||||||
|
+This is only meaningful with --create.
|
||||||
|
+
|
||||||
|
.TP
|
||||||
|
.BR \-\-backup\-file=
|
||||||
|
This is needed when
|
||||||
|
@@ -1370,7 +1386,7 @@ and
|
||||||
|
.B layout\-alternate
|
||||||
|
options are for RAID0 arrays with non-uniform devices size that were in
|
||||||
|
use before Linux 5.4. If the array was being used with Linux 3.13 or
|
||||||
|
-earlier, then to assemble the array on a new kernel,
|
||||||
|
+earlier, then to assemble the array on a new kernel,
|
||||||
|
.B \-\-update=layout\-original
|
||||||
|
must be given. If the array was created and used with a kernel from Linux 3.14 to
|
||||||
|
Linux 5.3, then
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,53 @@
|
|||||||
|
From 566844b93e6823a04ed65827ba3e03cb123b3a03 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Khem Raj <raj.khem@gmail.com>
|
||||||
|
Date: Wed, 18 Jan 2023 00:32:36 -0800
|
||||||
|
Subject: [PATCH 106/125] Define alignof using _Alignof when using C11 or newer
|
||||||
|
|
||||||
|
WG14 N2350 made very clear that it is an UB having type definitions
|
||||||
|
within "offsetof" [1]. This patch enhances the implementation of macro
|
||||||
|
alignof_slot to use builtin "_Alignof" to avoid undefined behavior on
|
||||||
|
when using std=c11 or newer
|
||||||
|
|
||||||
|
clang 16+ has started to flag this [2]
|
||||||
|
|
||||||
|
Fixes build when using -std >= gnu11 and using clang16+
|
||||||
|
|
||||||
|
Older compilers gcc < 4.9 or clang < 8 has buggy _Alignof even though it
|
||||||
|
may support C11, exclude those compilers too
|
||||||
|
|
||||||
|
[1] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm
|
||||||
|
[2] https://reviews.llvm.org/D133574
|
||||||
|
|
||||||
|
Upstream-Status: Pending
|
||||||
|
Signed-off-by: Khem Raj <raj.khem@gmail.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
sha1.c | 12 +++++++++++-
|
||||||
|
1 file changed, 11 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/sha1.c b/sha1.c
|
||||||
|
index 89b32f46..1e4ad5d9 100644
|
||||||
|
--- a/sha1.c
|
||||||
|
+++ b/sha1.c
|
||||||
|
@@ -229,7 +229,17 @@ sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx)
|
||||||
|
if (len >= 64)
|
||||||
|
{
|
||||||
|
#if !_STRING_ARCH_unaligned
|
||||||
|
-# define alignof(type) offsetof (struct { char c; type x; }, x)
|
||||||
|
+/* GCC releases before GCC 4.9 had a bug in _Alignof. See GCC bug 52023
|
||||||
|
+ <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023>.
|
||||||
|
+ clang versions < 8.0.0 have the same bug. */
|
||||||
|
+# if (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 \
|
||||||
|
+ || (defined __GNUC__ && __GNUC__ < 4 + (__GNUC_MINOR__ < 9) \
|
||||||
|
+ && !defined __clang__) \
|
||||||
|
+ || (defined __clang__ && __clang_major__ < 8))
|
||||||
|
+# define alignof(type) offsetof (struct { char c; type x; }, x)
|
||||||
|
+# else
|
||||||
|
+# define alignof(type) _Alignof(type)
|
||||||
|
+# endif
|
||||||
|
# define UNALIGNED_P(p) (((size_t) p) % alignof (sha1_uint32) != 0)
|
||||||
|
if (UNALIGNED_P (buffer))
|
||||||
|
while (len > 64)
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,41 @@
|
|||||||
|
From eb45d0add7cf2918f838bec2d93d99cf2d9c662f Mon Sep 17 00:00:00 2001
|
||||||
|
From: NeilBrown <neilb@suse.de>
|
||||||
|
Date: Mon, 13 Mar 2023 14:42:58 +1100
|
||||||
|
Subject: [PATCH 107/125] Use existence of /etc/initrd-release to detect
|
||||||
|
initrd.
|
||||||
|
|
||||||
|
Since v183, systemd has used the existence of /etc/initrd-release to
|
||||||
|
detect if it is running in an initrd, rather than looking at the magic
|
||||||
|
number of the root filesystem's device. It is time for mdadm to do the
|
||||||
|
same.
|
||||||
|
|
||||||
|
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
util.c | 10 +---------
|
||||||
|
1 file changed, 1 insertion(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/util.c b/util.c
|
||||||
|
index 9f1e1f7c..509fb43e 100644
|
||||||
|
--- a/util.c
|
||||||
|
+++ b/util.c
|
||||||
|
@@ -2227,15 +2227,7 @@ int continue_via_systemd(char *devnm, char *service_name)
|
||||||
|
|
||||||
|
int in_initrd(void)
|
||||||
|
{
|
||||||
|
- /* This is based on similar function in systemd. */
|
||||||
|
- struct statfs s;
|
||||||
|
- /* statfs.f_type is signed long on s390x and MIPS, causing all
|
||||||
|
- sorts of sign extension problems with RAMFS_MAGIC being
|
||||||
|
- defined as 0x858458f6 */
|
||||||
|
- return statfs("/", &s) >= 0 &&
|
||||||
|
- ((unsigned long)s.f_type == TMPFS_MAGIC ||
|
||||||
|
- ((unsigned long)s.f_type & 0xFFFFFFFFUL) ==
|
||||||
|
- ((unsigned long)RAMFS_MAGIC & 0xFFFFFFFFUL));
|
||||||
|
+ return access("/etc/initrd-release", F_OK) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reopen_mddev(int mdfd)
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,47 @@
|
|||||||
|
From d39fd87e31024804dd7f2c16c03af0379b71f5f1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: NeilBrown <neilb@suse.de>
|
||||||
|
Date: Mon, 13 Mar 2023 14:42:58 +1100
|
||||||
|
Subject: [PATCH 108/125] mdmon: don't test both 'all' and 'container_name'.
|
||||||
|
|
||||||
|
If 'all' is not set, then container_name must be NULL, as nothing else
|
||||||
|
can set it. So simplify the test to ignore container_name.
|
||||||
|
This makes the purpose of the code more obvious.
|
||||||
|
|
||||||
|
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
mdmon.c | 11 ++++-------
|
||||||
|
1 file changed, 4 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/mdmon.c b/mdmon.c
|
||||||
|
index 60ba3182..f8fd2f0f 100644
|
||||||
|
--- a/mdmon.c
|
||||||
|
+++ b/mdmon.c
|
||||||
|
@@ -352,7 +352,6 @@ int main(int argc, char *argv[])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-
|
||||||
|
if (in_initrd()) {
|
||||||
|
/*
|
||||||
|
* set first char of argv[0] to @. This is used by
|
||||||
|
@@ -362,12 +361,10 @@ int main(int argc, char *argv[])
|
||||||
|
argv[0][0] = '@';
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (all == 0 && container_name == NULL) {
|
||||||
|
- if (argv[optind]) {
|
||||||
|
- container_name = get_md_name(argv[optind]);
|
||||||
|
- if (!container_name)
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
+ if (!all && argv[optind]) {
|
||||||
|
+ container_name = get_md_name(argv[optind]);
|
||||||
|
+ if (!container_name)
|
||||||
|
+ return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (container_name == NULL || argc - optind > 1)
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,33 @@
|
|||||||
|
From 6660e33edde76329bd3b7f03383856c7efee2aa9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: NeilBrown <neilb@suse.de>
|
||||||
|
Date: Mon, 13 Mar 2023 14:42:58 +1100
|
||||||
|
Subject: [PATCH 109/125] mdmon: change systemd unit file to use --foreground
|
||||||
|
|
||||||
|
There is no value in mdmon forking when it is running under systemd -
|
||||||
|
systemd can still track it anyway.
|
||||||
|
|
||||||
|
So add --foreground option, and remove "Type=forking".
|
||||||
|
|
||||||
|
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
systemd/mdmon@.service | 3 +--
|
||||||
|
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service
|
||||||
|
index cb6482d9..bba9b0eb 100644
|
||||||
|
--- a/systemd/mdmon@.service
|
||||||
|
+++ b/systemd/mdmon@.service
|
||||||
|
@@ -20,8 +20,7 @@ Environment=IMSM_NO_PLATFORM=1
|
||||||
|
# 'takeover'. As the '--offroot --takeover' don't hurt when
|
||||||
|
# not necessary, are are useful with root-on-md in dracut,
|
||||||
|
# have them always present.
|
||||||
|
-ExecStart=BINDIR/mdmon --offroot --takeover %I
|
||||||
|
-Type=forking
|
||||||
|
+ExecStart=BINDIR/mdmon --foreground --offroot --takeover %I
|
||||||
|
# Don't set the PIDFile. It isn't necessary (systemd can work
|
||||||
|
# it out) and systemd will remove it when transitioning from
|
||||||
|
# initramfs to rootfs.
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
55
SOURCES/0110-mdmon-Remove-need-for-KillMode-none.patch
Normal file
55
SOURCES/0110-mdmon-Remove-need-for-KillMode-none.patch
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
From 0f9a4b3e11fbe4f8631d20b1f89cf43e9219db55 Mon Sep 17 00:00:00 2001
|
||||||
|
From: NeilBrown <neilb@suse.de>
|
||||||
|
Date: Mon, 13 Mar 2023 14:42:58 +1100
|
||||||
|
Subject: [PATCH 110/125] mdmon: Remove need for KillMode=none
|
||||||
|
|
||||||
|
mdmon needs to keep running during the switchroot out of (at boot) and
|
||||||
|
then back into (at shutdown) the initrd. It runs until a new mdmon
|
||||||
|
takes over.
|
||||||
|
|
||||||
|
Killmode=none is used to achieve this, with the help of --offroot which
|
||||||
|
sets argv[0][0] to '@' which systemd understands.
|
||||||
|
|
||||||
|
This is needed because mdmon is currently run in system-mdmon.slice
|
||||||
|
which conflicts with shutdown.target so without Killmode=none mdmon
|
||||||
|
would get killed early in shutdown when system.mdmon.slice is removed.
|
||||||
|
|
||||||
|
As described in systemd.service(5), this conflict with shutdown can be
|
||||||
|
resolved by explicitly requesting system.slice, which is a natural
|
||||||
|
counterpart to DefaultDependencies=no.
|
||||||
|
|
||||||
|
So add that, and also add IgnoreOnIsolate=true to avoid another possible
|
||||||
|
source of an early death. With these we no longer need KillMode=none
|
||||||
|
which the systemd developers have marked as "deprecated".
|
||||||
|
|
||||||
|
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
systemd/mdmon@.service | 7 ++++++-
|
||||||
|
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service
|
||||||
|
index bba9b0eb..303ad05c 100644
|
||||||
|
--- a/systemd/mdmon@.service
|
||||||
|
+++ b/systemd/mdmon@.service
|
||||||
|
@@ -10,6 +10,9 @@ Description=MD Metadata Monitor on /dev/%I
|
||||||
|
DefaultDependencies=no
|
||||||
|
Before=initrd-switch-root.target
|
||||||
|
Documentation=man:mdmon(8)
|
||||||
|
+# Allow mdmon to keep running after switchroot, until a new
|
||||||
|
+# instance is started.
|
||||||
|
+IgnoreOnIsolate=true
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
# mdmon should never complain due to lack of a platform,
|
||||||
|
@@ -25,4 +28,6 @@ ExecStart=BINDIR/mdmon --foreground --offroot --takeover %I
|
||||||
|
# it out) and systemd will remove it when transitioning from
|
||||||
|
# initramfs to rootfs.
|
||||||
|
#PIDFile=/run/mdadm/%I.pid
|
||||||
|
-KillMode=none
|
||||||
|
+# The default slice is system-mdmon.slice which Conflicts
|
||||||
|
+# with shutdown, causing mdmon to exit early. So use system.slice.
|
||||||
|
+Slice=system.slice
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
166
SOURCES/0111-mdmon-Improve-switchroot-interactions.patch
Normal file
166
SOURCES/0111-mdmon-Improve-switchroot-interactions.patch
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
From 723d1df4946eb40337bf494f9b2549500c1399b2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: NeilBrown <neilb@suse.de>
|
||||||
|
Date: Mon, 13 Mar 2023 14:42:58 +1100
|
||||||
|
Subject: [PATCH 111/125] mdmon: Improve switchroot interactions.
|
||||||
|
|
||||||
|
We need a new mdmon@mdfoo instance to run in the root filesystem after
|
||||||
|
switch root, as /sys and /dev are removed from the initrd.
|
||||||
|
|
||||||
|
systemd will not start a new unit with the same name running while the
|
||||||
|
old unit is still active, and we want the two mdmon processes to overlap
|
||||||
|
in time to avoid any risk of deadlock, which can happen when a write is
|
||||||
|
attempted with no mdmon running.
|
||||||
|
|
||||||
|
So we need a different unit name in the initrd than in the root. Apart
|
||||||
|
from the name, everything else should be the same.
|
||||||
|
|
||||||
|
This is easily achieved using a different instance name as the
|
||||||
|
mdmon@.service unit file already supports multiple instances (for
|
||||||
|
different arrays).
|
||||||
|
|
||||||
|
So start "mdmon@mdfoo.service" from root, but
|
||||||
|
"mdmon@initrd-mdfoo.service" from the initrd. udev can tell which
|
||||||
|
circumstance is the case by looking for /etc/initrd-release.
|
||||||
|
continue_from_systemd() is enhanced so that the "initrd-" prefix can be
|
||||||
|
requested.
|
||||||
|
|
||||||
|
Teach mdmon that a container name like "initrd/foo" should be treated
|
||||||
|
just like "foo". Note that systemd passes the instance name
|
||||||
|
"initrd-foo" as "initrd/foo".
|
||||||
|
|
||||||
|
We don't need a similar mechanism at shutdown because dracut runs
|
||||||
|
"mdmon --takeover --all" when appropriate.
|
||||||
|
|
||||||
|
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Grow.c | 4 ++--
|
||||||
|
mdadm.h | 2 +-
|
||||||
|
mdmon.c | 7 ++++++-
|
||||||
|
systemd/mdmon@.service | 2 +-
|
||||||
|
udev-md-raid-arrays.rules | 3 ++-
|
||||||
|
util.c | 7 ++++---
|
||||||
|
6 files changed, 16 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Grow.c b/Grow.c
|
||||||
|
index bb5fe45c..06001f2d 100644
|
||||||
|
--- a/Grow.c
|
||||||
|
+++ b/Grow.c
|
||||||
|
@@ -3516,7 +3516,7 @@ started:
|
||||||
|
|
||||||
|
if (!forked)
|
||||||
|
if (continue_via_systemd(container ?: sra->sys_name,
|
||||||
|
- GROW_SERVICE)) {
|
||||||
|
+ GROW_SERVICE, NULL)) {
|
||||||
|
free(fdlist);
|
||||||
|
free(offsets);
|
||||||
|
sysfs_free(sra);
|
||||||
|
@@ -3714,7 +3714,7 @@ int reshape_container(char *container, char *devname,
|
||||||
|
ping_monitor(container);
|
||||||
|
|
||||||
|
if (!forked && !freeze_reshape)
|
||||||
|
- if (continue_via_systemd(container, GROW_SERVICE))
|
||||||
|
+ if (continue_via_systemd(container, GROW_SERVICE, NULL))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (forked ? 0 : fork()) {
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index b9127f9a..1e518276 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -1608,7 +1608,7 @@ extern int same_dev(char *one, char *two);
|
||||||
|
extern int compare_paths (char* path1,char* path2);
|
||||||
|
extern void enable_fds(int devices);
|
||||||
|
extern void manage_fork_fds(int close_all);
|
||||||
|
-extern int continue_via_systemd(char *devnm, char *service_name);
|
||||||
|
+extern int continue_via_systemd(char *devnm, char *service_name, char *prefix);
|
||||||
|
|
||||||
|
extern void ident_init(struct mddev_ident *ident);
|
||||||
|
|
||||||
|
diff --git a/mdmon.c b/mdmon.c
|
||||||
|
index f8fd2f0f..096b4d76 100644
|
||||||
|
--- a/mdmon.c
|
||||||
|
+++ b/mdmon.c
|
||||||
|
@@ -362,7 +362,12 @@ int main(int argc, char *argv[])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!all && argv[optind]) {
|
||||||
|
- container_name = get_md_name(argv[optind]);
|
||||||
|
+ static const char prefix[] = "initrd/";
|
||||||
|
+ container_name = argv[optind];
|
||||||
|
+ if (strncmp(container_name, prefix,
|
||||||
|
+ sizeof(prefix) - 1) == 0)
|
||||||
|
+ container_name += sizeof(prefix)-1;
|
||||||
|
+ container_name = get_md_name(container_name);
|
||||||
|
if (!container_name)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service
|
||||||
|
index 303ad05c..23a375f6 100644
|
||||||
|
--- a/systemd/mdmon@.service
|
||||||
|
+++ b/systemd/mdmon@.service
|
||||||
|
@@ -6,7 +6,7 @@
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
-Description=MD Metadata Monitor on /dev/%I
|
||||||
|
+Description=MD Metadata Monitor on %I
|
||||||
|
DefaultDependencies=no
|
||||||
|
Before=initrd-switch-root.target
|
||||||
|
Documentation=man:mdmon(8)
|
||||||
|
diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules
|
||||||
|
index 2967ace1..4e64b249 100644
|
||||||
|
--- a/udev-md-raid-arrays.rules
|
||||||
|
+++ b/udev-md-raid-arrays.rules
|
||||||
|
@@ -38,7 +38,8 @@ ENV{MD_LEVEL}=="raid[1-9]*", ENV{SYSTEMD_WANTS}+="mdmonitor.service"
|
||||||
|
|
||||||
|
# Tell systemd to run mdmon for our container, if we need it.
|
||||||
|
ENV{MD_LEVEL}=="raid[1-9]*", ENV{MD_CONTAINER}=="?*", PROGRAM="/usr/bin/readlink $env{MD_CONTAINER}", ENV{MD_MON_THIS}="%c"
|
||||||
|
-ENV{MD_MON_THIS}=="?*", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service"
|
||||||
|
+ENV{MD_MON_THIS}=="?*", TEST=="/etc/initrd-release", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@initrd-%c.service"
|
||||||
|
+ENV{MD_MON_THIS}=="?*", TEST!="/etc/initrd-release", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service"
|
||||||
|
ENV{RESHAPE_ACTIVE}=="yes", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdadm-grow-continue@%c.service"
|
||||||
|
|
||||||
|
LABEL="md_end"
|
||||||
|
diff --git a/util.c b/util.c
|
||||||
|
index 509fb43e..d70ca43b 100644
|
||||||
|
--- a/util.c
|
||||||
|
+++ b/util.c
|
||||||
|
@@ -1916,6 +1916,7 @@ int start_mdmon(char *devnm)
|
||||||
|
int len;
|
||||||
|
pid_t pid;
|
||||||
|
int status;
|
||||||
|
+ char *prefix = in_initrd() ? "initrd-" : "";
|
||||||
|
char pathbuf[1024];
|
||||||
|
char *paths[4] = {
|
||||||
|
pathbuf,
|
||||||
|
@@ -1926,7 +1927,7 @@ int start_mdmon(char *devnm)
|
||||||
|
|
||||||
|
if (check_env("MDADM_NO_MDMON"))
|
||||||
|
return 0;
|
||||||
|
- if (continue_via_systemd(devnm, MDMON_SERVICE))
|
||||||
|
+ if (continue_via_systemd(devnm, MDMON_SERVICE, prefix))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* That failed, try running mdmon directly */
|
||||||
|
@@ -2197,7 +2198,7 @@ void manage_fork_fds(int close_all)
|
||||||
|
* 1- if systemd service has been started
|
||||||
|
* 0- otherwise
|
||||||
|
*/
|
||||||
|
-int continue_via_systemd(char *devnm, char *service_name)
|
||||||
|
+int continue_via_systemd(char *devnm, char *service_name, char *prefix)
|
||||||
|
{
|
||||||
|
int pid, status;
|
||||||
|
char pathbuf[1024];
|
||||||
|
@@ -2209,7 +2210,7 @@ int continue_via_systemd(char *devnm, char *service_name)
|
||||||
|
case 0:
|
||||||
|
manage_fork_fds(1);
|
||||||
|
snprintf(pathbuf, sizeof(pathbuf),
|
||||||
|
- "%s@%s.service", service_name, devnm);
|
||||||
|
+ "%s@%s%s.service", service_name, prefix ?: "", devnm);
|
||||||
|
status = execl("/usr/bin/systemctl", "systemctl", "restart",
|
||||||
|
pathbuf, NULL);
|
||||||
|
status = execl("/bin/systemctl", "systemctl", "restart",
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
40
SOURCES/0112-mdopen-always-try-create_named_array.patch
Normal file
40
SOURCES/0112-mdopen-always-try-create_named_array.patch
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
From 2e10c46d0906b1a1ec40e8f5005ccb63125dcd9e Mon Sep 17 00:00:00 2001
|
||||||
|
From: NeilBrown <neilb@suse.de>
|
||||||
|
Date: Tue, 14 Mar 2023 11:06:25 +1100
|
||||||
|
Subject: [PATCH 112/125] mdopen: always try create_named_array()
|
||||||
|
|
||||||
|
mdopen() will use create_named_array() to ask the kernel to create the
|
||||||
|
given md array, but only if it is given a number or name.
|
||||||
|
If it is NOT given a name and is required to choose one itself using
|
||||||
|
find_free_devnm() it does NOT use create_named_array().
|
||||||
|
|
||||||
|
On kernels with CONFIG_BLOCK_LEGACY_AUTOLOAD not set, this can result in
|
||||||
|
failure to assemble an array. This can particularly seen when the
|
||||||
|
"name" of the array begins with a host name different to the name of the
|
||||||
|
host running the command.
|
||||||
|
|
||||||
|
So add the missing call to create_named_array().
|
||||||
|
|
||||||
|
Link: https://bugzilla.kernel.org/show_bug.cgi?id=217074
|
||||||
|
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||||
|
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
mdopen.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/mdopen.c b/mdopen.c
|
||||||
|
index d18c9319..810f79a3 100644
|
||||||
|
--- a/mdopen.c
|
||||||
|
+++ b/mdopen.c
|
||||||
|
@@ -370,6 +370,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
|
||||||
|
}
|
||||||
|
if (block_udev)
|
||||||
|
udev_block(devnm);
|
||||||
|
+ create_named_array(devnm);
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(devname, "/dev/%s", devnm);
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
172
SOURCES/0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch
Normal file
172
SOURCES/0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
From 420dafcd38c5949c2ddb90ad6873e7edd625db30 Mon Sep 17 00:00:00 2001
|
||||||
|
From: NeilBrown <neilb@suse.de>
|
||||||
|
Date: Mon, 20 Mar 2023 14:43:54 +1100
|
||||||
|
Subject: [PATCH 113/125] Improvements for IMSM_NO_PLATFORM testing.
|
||||||
|
|
||||||
|
Factor out IMSM_NO_PLATFORM testing into a single function that caches
|
||||||
|
the result.
|
||||||
|
|
||||||
|
Allow mdmon to explicitly set the result to "1" so that we don't need
|
||||||
|
the ENV var in the unit file
|
||||||
|
|
||||||
|
Check if the kernel command line contains "mdadm.imsm.test=1" and in
|
||||||
|
that case assert NO_PLATFORM. This simplifies testing in a virtual
|
||||||
|
machine.
|
||||||
|
|
||||||
|
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
mdadm.8.in | 5 +++++
|
||||||
|
mdadm.h | 2 ++
|
||||||
|
mdmon.c | 6 ++++++
|
||||||
|
super-intel.c | 45 +++++++++++++++++++++++++++++++++++++++---
|
||||||
|
systemd/mdmon@.service | 3 ---
|
||||||
|
5 files changed, 55 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/mdadm.8.in b/mdadm.8.in
|
||||||
|
index 6f0f6c13..b7159509 100644
|
||||||
|
--- a/mdadm.8.in
|
||||||
|
+++ b/mdadm.8.in
|
||||||
|
@@ -3197,6 +3197,11 @@ 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
|
||||||
|
+.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.
|
||||||
|
+
|
||||||
|
.TP
|
||||||
|
.B MDADM_GROW_ALLOW_OLD
|
||||||
|
If an array is stopped while it is performing a reshape and that
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index 1e518276..0d995445 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -1263,6 +1263,8 @@ extern struct superswitch super0, super1;
|
||||||
|
extern struct superswitch super_imsm, super_ddf;
|
||||||
|
extern struct superswitch mbr, gpt;
|
||||||
|
|
||||||
|
+void imsm_set_no_platform(int v);
|
||||||
|
+
|
||||||
|
struct metadata_update {
|
||||||
|
int len;
|
||||||
|
char *buf;
|
||||||
|
diff --git a/mdmon.c b/mdmon.c
|
||||||
|
index 096b4d76..cef5bbc8 100644
|
||||||
|
--- a/mdmon.c
|
||||||
|
+++ b/mdmon.c
|
||||||
|
@@ -318,6 +318,12 @@ int main(int argc, char *argv[])
|
||||||
|
{NULL, 0, NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * mdmon should never complain due to lack of a platform,
|
||||||
|
+ * that is mdadm's job if at all.
|
||||||
|
+ */
|
||||||
|
+ imsm_set_no_platform(1);
|
||||||
|
+
|
||||||
|
while ((opt = getopt_long(argc, argv, "thaF", options, NULL)) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'a':
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index e155a8ae..a5c86cb2 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -20,6 +20,7 @@
|
||||||
|
#define HAVE_STDINT_H 1
|
||||||
|
#include "mdadm.h"
|
||||||
|
#include "mdmon.h"
|
||||||
|
+#include "dlink.h"
|
||||||
|
#include "sha1.h"
|
||||||
|
#include "platform-intel.h"
|
||||||
|
#include <values.h>
|
||||||
|
@@ -629,6 +630,44 @@ static const char *_sys_dev_type[] = {
|
||||||
|
[SYS_DEV_VMD] = "VMD"
|
||||||
|
};
|
||||||
|
|
||||||
|
+static int no_platform = -1;
|
||||||
|
+
|
||||||
|
+static int check_no_platform(void)
|
||||||
|
+{
|
||||||
|
+ static const char search[] = "mdadm.imsm.test=1";
|
||||||
|
+ FILE *fp;
|
||||||
|
+
|
||||||
|
+ if (no_platform >= 0)
|
||||||
|
+ return no_platform;
|
||||||
|
+
|
||||||
|
+ if (check_env("IMSM_NO_PLATFORM")) {
|
||||||
|
+ no_platform = 1;
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ fp = fopen("/proc/cmdline", "r");
|
||||||
|
+ if (fp) {
|
||||||
|
+ char *l = conf_line(fp);
|
||||||
|
+ char *w = l;
|
||||||
|
+
|
||||||
|
+ do {
|
||||||
|
+ if (strcmp(w, search) == 0)
|
||||||
|
+ no_platform = 1;
|
||||||
|
+ w = dl_next(w);
|
||||||
|
+ } while (w != l);
|
||||||
|
+ free_line(l);
|
||||||
|
+ fclose(fp);
|
||||||
|
+ if (no_platform >= 0)
|
||||||
|
+ return no_platform;
|
||||||
|
+ }
|
||||||
|
+ no_platform = 0;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void imsm_set_no_platform(int v)
|
||||||
|
+{
|
||||||
|
+ no_platform = v;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
const char *get_sys_dev_type(enum sys_dev_type type)
|
||||||
|
{
|
||||||
|
if (type >= SYS_DEV_MAX)
|
||||||
|
@@ -2699,7 +2738,7 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle
|
||||||
|
int result=1;
|
||||||
|
|
||||||
|
if (enumerate_only) {
|
||||||
|
- if (check_env("IMSM_NO_PLATFORM"))
|
||||||
|
+ if (check_no_platform())
|
||||||
|
return 0;
|
||||||
|
list = find_intel_devices();
|
||||||
|
if (!list)
|
||||||
|
@@ -4722,7 +4761,7 @@ static int find_intel_hba_capability(int fd, struct intel_super *super, char *de
|
||||||
|
devname);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
- if (!is_fd_valid(fd) || check_env("IMSM_NO_PLATFORM")) {
|
||||||
|
+ if (!is_fd_valid(fd) || check_no_platform()) {
|
||||||
|
super->orom = NULL;
|
||||||
|
super->hba = NULL;
|
||||||
|
return 0;
|
||||||
|
@@ -10697,7 +10736,7 @@ static int imsm_get_allowed_degradation(int level, int raid_disks,
|
||||||
|
******************************************************************************/
|
||||||
|
int validate_container_imsm(struct mdinfo *info)
|
||||||
|
{
|
||||||
|
- if (check_env("IMSM_NO_PLATFORM"))
|
||||||
|
+ if (check_no_platform())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
struct sys_dev *idev;
|
||||||
|
diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service
|
||||||
|
index 23a375f6..020cc7e1 100644
|
||||||
|
--- a/systemd/mdmon@.service
|
||||||
|
+++ b/systemd/mdmon@.service
|
||||||
|
@@ -15,9 +15,6 @@ Documentation=man:mdmon(8)
|
||||||
|
IgnoreOnIsolate=true
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
-# mdmon should never complain due to lack of a platform,
|
||||||
|
-# that is mdadm's job if at all.
|
||||||
|
-Environment=IMSM_NO_PLATFORM=1
|
||||||
|
# The mdmon starting in the initramfs (with dracut at least)
|
||||||
|
# cannot see sysfs after root is mounted, so we will have to
|
||||||
|
# 'takeover'. As the '--offroot --takeover' don't hurt when
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
From 9b6e3b43381245cb128ad98bf117a565ce5defe5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Thu, 23 Mar 2023 17:13:18 +0100
|
||||||
|
Subject: [PATCH 114/125] Revert "Revert "mdadm/systemd: remove KillMode=none
|
||||||
|
from service file""
|
||||||
|
|
||||||
|
This reverts commit 28a083955c6f58f8e582734c8c82aff909a7d461.
|
||||||
|
|
||||||
|
Resolved by commit 723d1df4946e ("mdmon: Improve switchroot
|
||||||
|
interactions.") We are ready to drop it.
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
systemd/mdadm-grow-continue@.service | 1 -
|
||||||
|
1 file changed, 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service
|
||||||
|
index 9ccadca3..64b8254a 100644
|
||||||
|
--- a/systemd/mdadm-grow-continue@.service
|
||||||
|
+++ b/systemd/mdadm-grow-continue@.service
|
||||||
|
@@ -15,4 +15,3 @@ ExecStart=BINDIR/mdadm --grow --continue /dev/%I
|
||||||
|
StandardInput=null
|
||||||
|
StandardOutput=null
|
||||||
|
StandardError=null
|
||||||
|
-KillMode=none
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,38 @@
|
|||||||
|
From ef6236da232e968dcf08b486178cd20d5ea97e2a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Date: Thu, 23 Mar 2023 12:50:00 +0100
|
||||||
|
Subject: [PATCH 115/125] Create: Fix checking for container in update_metadata
|
||||||
|
|
||||||
|
The commit 8a4ce2c05386 ("Create: Factor out add_disks() helpers")
|
||||||
|
introduced a regression that caused timeouts and udev failing to create
|
||||||
|
links.
|
||||||
|
|
||||||
|
Steps to reproduce the issue were as following:
|
||||||
|
$ mdadm -CR imsm -e imsm -n4 /dev/nvme[0-3]n1
|
||||||
|
$ mdadm -CR vol -l5 -n4 /dev/nvme[0-3]n1 --assume-clean
|
||||||
|
|
||||||
|
I found the check for container was wrong because negation was missing.
|
||||||
|
|
||||||
|
Fixes: 8a4ce2c05386 ("Create: Factor out add_disks() helpers")
|
||||||
|
Signed-off-by: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Create.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/Create.c b/Create.c
|
||||||
|
index bbe9e13d..0911bf92 100644
|
||||||
|
--- a/Create.c
|
||||||
|
+++ b/Create.c
|
||||||
|
@@ -328,7 +328,7 @@ static int update_metadata(int mdfd, struct shape *s, struct supertype *st,
|
||||||
|
* again returns container info.
|
||||||
|
*/
|
||||||
|
st->ss->getinfo_super(st, &info_new, NULL);
|
||||||
|
- if (st->ss->external && is_container(s->level) &&
|
||||||
|
+ if (st->ss->external && !is_container(s->level) &&
|
||||||
|
!same_uuid(info_new.uuid, info->uuid, 0)) {
|
||||||
|
map_update(map, fd2devnm(mdfd),
|
||||||
|
info_new.text_version,
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
43
SOURCES/0116-Fix-null-pointer-for-incremental-in-mdadm.patch
Normal file
43
SOURCES/0116-Fix-null-pointer-for-incremental-in-mdadm.patch
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
From 890212d6800646153210ac264ce73035cc7dd5cc Mon Sep 17 00:00:00 2001
|
||||||
|
From: miaoguanqin <miaoguanqin@huawei.com>
|
||||||
|
Date: Tue, 4 Apr 2023 19:31:24 +0800
|
||||||
|
Subject: [PATCH 116/125] Fix null pointer for incremental in mdadm
|
||||||
|
|
||||||
|
when we excute mdadm --assemble, udev-md-raid-assembly.rules is triggered.
|
||||||
|
Then we stop array, we found an coredump for mdadm --incremental.func
|
||||||
|
stack are as follows:
|
||||||
|
|
||||||
|
#0 enough (level=10, raid_disks=4, layout=258, clean=1,
|
||||||
|
avail=avail@entry=0x0) at util.c:555
|
||||||
|
#1 0x0000562170c26965 in Incremental (devlist=<optimized out>,
|
||||||
|
c=<optimized out>, st=0x5621729b6dc0) at Incremental.c:514
|
||||||
|
#2 0x0000562170bfb6ff in main (argc=<optimized out>,
|
||||||
|
argv=<optimized out>) at mdadm.c:1762
|
||||||
|
|
||||||
|
func enough() use array avail,avail allocate space in func count_active,
|
||||||
|
it may not alloc space, causing a coredump.We fix this coredump.
|
||||||
|
|
||||||
|
Signed-off-by: Guanqin Miao <miaoguanqin@huawei.com>
|
||||||
|
Signed-off-by: lixiaokeng <lixiaokeng@huawei.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Incremental.c | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/Incremental.c b/Incremental.c
|
||||||
|
index 09b94b9f..49a71f72 100644
|
||||||
|
--- a/Incremental.c
|
||||||
|
+++ b/Incremental.c
|
||||||
|
@@ -507,6 +507,9 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
|
||||||
|
GET_OFFSET | GET_SIZE));
|
||||||
|
active_disks = count_active(st, sra, mdfd, &avail, &info);
|
||||||
|
|
||||||
|
+ if (!avail)
|
||||||
|
+ goto out_unlock;
|
||||||
|
+
|
||||||
|
journal_device_missing = (info.journal_device_required) && (info.journal_clean == 0);
|
||||||
|
|
||||||
|
if (info.consistency_policy == CONSISTENCY_POLICY_PPL)
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,33 @@
|
|||||||
|
From 1c6f2a1dbfe17df14dd5b062fc53a60c5c387e47 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hristo Venev <hristo@venev.name>
|
||||||
|
Date: Sat, 1 Apr 2023 23:01:35 +0300
|
||||||
|
Subject: [PATCH 117/125] super1: fix truncation check for journal device
|
||||||
|
|
||||||
|
The journal device can be smaller than the component devices.
|
||||||
|
|
||||||
|
Fixes: 171e9743881e ("super1: report truncated device")
|
||||||
|
Signed-off-by: Hristo Venev <hristo@venev.name>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
super1.c | 5 +++--
|
||||||
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/super1.c b/super1.c
|
||||||
|
index f7020320..44d6ecad 100644
|
||||||
|
--- a/super1.c
|
||||||
|
+++ b/super1.c
|
||||||
|
@@ -2359,8 +2359,9 @@ static int load_super1(struct supertype *st, int fd, char *devname)
|
||||||
|
|
||||||
|
if (st->minor_version >= 1 &&
|
||||||
|
st->ignore_hw_compat == 0 &&
|
||||||
|
- (dsize < (__le64_to_cpu(super->data_offset) +
|
||||||
|
- __le64_to_cpu(super->size))
|
||||||
|
+ ((role_from_sb(super) != MD_DISK_ROLE_JOURNAL &&
|
||||||
|
+ 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)))) {
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
433
SOURCES/0118-Fix-some-cases-eyesore-formatting.patch
Normal file
433
SOURCES/0118-Fix-some-cases-eyesore-formatting.patch
Normal file
@ -0,0 +1,433 @@
|
|||||||
|
From d3bb888d885fc96fc6239fbf6c22c63143eba461 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
Date: Mon, 10 Apr 2023 11:40:42 -0400
|
||||||
|
Subject: [PATCH 118/125] Fix some cases eyesore formatting
|
||||||
|
|
||||||
|
Summary: No functional change .... just make it more readable.
|
||||||
|
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
super1.c | 117 ++++++++++++++++++++++++++++---------------------------
|
||||||
|
1 file changed, 60 insertions(+), 57 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/super1.c b/super1.c
|
||||||
|
index 44d6ecad..1d20ef55 100644
|
||||||
|
--- a/super1.c
|
||||||
|
+++ b/super1.c
|
||||||
|
@@ -192,7 +192,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
|
||||||
|
unsigned int disk_csum, csum;
|
||||||
|
unsigned long long newcsum;
|
||||||
|
int size = sizeof(*sb) + __le32_to_cpu(sb->max_dev)*2;
|
||||||
|
- unsigned int *isuper = (unsigned int*)sb;
|
||||||
|
+ unsigned int *isuper = (unsigned int *)sb;
|
||||||
|
|
||||||
|
/* make sure I can count... */
|
||||||
|
if (offsetof(struct mdp_superblock_1,data_offset) != 128 ||
|
||||||
|
@@ -204,7 +204,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
|
||||||
|
disk_csum = sb->sb_csum;
|
||||||
|
sb->sb_csum = 0;
|
||||||
|
newcsum = 0;
|
||||||
|
- for (; size>=4; size -= 4 ) {
|
||||||
|
+ for (; size >= 4; size -= 4) {
|
||||||
|
newcsum += __le32_to_cpu(*isuper);
|
||||||
|
isuper++;
|
||||||
|
}
|
||||||
|
@@ -319,7 +319,7 @@ static inline unsigned int choose_ppl_space(int chunk)
|
||||||
|
static void examine_super1(struct supertype *st, char *homehost)
|
||||||
|
{
|
||||||
|
struct mdp_superblock_1 *sb = st->sb;
|
||||||
|
- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE);
|
||||||
|
+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE);
|
||||||
|
time_t atime;
|
||||||
|
unsigned int d;
|
||||||
|
int role;
|
||||||
|
@@ -343,8 +343,9 @@ static void examine_super1(struct supertype *st, char *homehost)
|
||||||
|
printf(".0\n");
|
||||||
|
printf(" Feature Map : 0x%x\n", __le32_to_cpu(sb->feature_map));
|
||||||
|
printf(" Array UUID : ");
|
||||||
|
- for (i=0; i<16; i++) {
|
||||||
|
- if ((i&3)==0 && i != 0) printf(":");
|
||||||
|
+ for (i = 0; i < 16; i++) {
|
||||||
|
+ if ((i & 3) == 0 && i != 0)
|
||||||
|
+ printf(":");
|
||||||
|
printf("%02x", sb->set_uuid[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
@@ -416,11 +417,11 @@ static void examine_super1(struct supertype *st, char *homehost)
|
||||||
|
UINT64_MAX - info.space_after);
|
||||||
|
}
|
||||||
|
printf(" State : %s%s\n",
|
||||||
|
- (__le64_to_cpu(sb->resync_offset)+1) ? "active":"clean",
|
||||||
|
+ (__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)
|
||||||
|
+ for (i = 0; i < 16; i++) {
|
||||||
|
+ if ((i & 3)==0 && i != 0)
|
||||||
|
printf(":");
|
||||||
|
printf("%02x", sb->device_uuid[i]);
|
||||||
|
}
|
||||||
|
@@ -546,7 +547,7 @@ static void examine_super1(struct supertype *st, char *homehost)
|
||||||
|
#if 0
|
||||||
|
/* This turns out to just be confusing */
|
||||||
|
printf(" Array Slot : %d (", __le32_to_cpu(sb->dev_number));
|
||||||
|
- for (i = __le32_to_cpu(sb->max_dev); i> 0 ; i--)
|
||||||
|
+ for (i = __le32_to_cpu(sb->max_dev); i > 0 ; i--)
|
||||||
|
if (__le16_to_cpu(sb->dev_roles[i-1]) != MD_DISK_ROLE_SPARE)
|
||||||
|
break;
|
||||||
|
for (d = 0; d < i; d++) {
|
||||||
|
@@ -597,7 +598,7 @@ static void examine_super1(struct supertype *st, char *homehost)
|
||||||
|
#if 0
|
||||||
|
/* This is confusing too */
|
||||||
|
faulty = 0;
|
||||||
|
- for (i = 0; i< __le32_to_cpu(sb->max_dev); i++) {
|
||||||
|
+ 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++;
|
||||||
|
@@ -616,10 +617,12 @@ static void examine_super1(struct supertype *st, char *homehost)
|
||||||
|
if (inconsistent) {
|
||||||
|
printf("WARNING Array state is inconsistent - each number should appear only once\n");
|
||||||
|
for (d = 0; d < __le32_to_cpu(sb->max_dev); d++)
|
||||||
|
- if (__le16_to_cpu(sb->dev_roles[d]) >= MD_DISK_ROLE_FAULTY)
|
||||||
|
+ if (__le16_to_cpu(sb->dev_roles[d]) >=
|
||||||
|
+ MD_DISK_ROLE_FAULTY)
|
||||||
|
printf(" %d:-", d);
|
||||||
|
else
|
||||||
|
- printf(" %d:%d", d, __le16_to_cpu(sb->dev_roles[d]));
|
||||||
|
+ printf(" %d:%d", d,
|
||||||
|
+ __le16_to_cpu(sb->dev_roles[d]));
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -659,7 +662,7 @@ static void brief_examine_super1(struct supertype *st, int verbose)
|
||||||
|
printf("num-devices=%d ", __le32_to_cpu(sb->raid_disks));
|
||||||
|
printf("UUID=");
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
- if ((i&3)==0 && i != 0)
|
||||||
|
+ if ((i & 3)==0 && i != 0)
|
||||||
|
printf(":");
|
||||||
|
printf("%02x", sb->set_uuid[i]);
|
||||||
|
}
|
||||||
|
@@ -713,7 +716,7 @@ static void export_examine_super1(struct supertype *st)
|
||||||
|
}
|
||||||
|
printf("MD_UUID=");
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
- if ((i&3) == 0 && i != 0)
|
||||||
|
+ if ((i & 3) == 0 && i != 0)
|
||||||
|
printf(":");
|
||||||
|
printf("%02x", sb->set_uuid[i]);
|
||||||
|
}
|
||||||
|
@@ -722,7 +725,7 @@ static void export_examine_super1(struct supertype *st)
|
||||||
|
__le64_to_cpu(sb->utime) & 0xFFFFFFFFFFULL);
|
||||||
|
printf("MD_DEV_UUID=");
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
- if ((i&3) == 0 && i != 0)
|
||||||
|
+ if ((i & 3) == 0 && i != 0)
|
||||||
|
printf(":");
|
||||||
|
printf("%02x", sb->device_uuid[i]);
|
||||||
|
}
|
||||||
|
@@ -812,7 +815,7 @@ static int copy_metadata1(struct supertype *st, int from, int to)
|
||||||
|
/* have the header, can calculate
|
||||||
|
* correct bitmap bytes */
|
||||||
|
bitmap_super_t *bms;
|
||||||
|
- bms = (void*)buf;
|
||||||
|
+ bms = (void *)buf;
|
||||||
|
bytes = calc_bitmap_size(bms, 512);
|
||||||
|
if (n > bytes)
|
||||||
|
n = bytes;
|
||||||
|
@@ -867,7 +870,7 @@ err:
|
||||||
|
static void detail_super1(struct supertype *st, char *homehost, char *subarray)
|
||||||
|
{
|
||||||
|
struct mdp_superblock_1 *sb = st->sb;
|
||||||
|
- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE);
|
||||||
|
+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE);
|
||||||
|
int i;
|
||||||
|
int l = homehost ? strlen(homehost) : 0;
|
||||||
|
|
||||||
|
@@ -880,7 +883,7 @@ static void detail_super1(struct supertype *st, char *homehost, char *subarray)
|
||||||
|
printf("\n Cluster Name : %-64s", bms->cluster_name);
|
||||||
|
printf("\n UUID : ");
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
- if ((i&3) == 0 && i != 0)
|
||||||
|
+ if ((i & 3) == 0 && i != 0)
|
||||||
|
printf(":");
|
||||||
|
printf("%02x", sb->set_uuid[i]);
|
||||||
|
}
|
||||||
|
@@ -939,7 +942,7 @@ static int examine_badblocks_super1(struct supertype *st, int fd, char *devname)
|
||||||
|
}
|
||||||
|
|
||||||
|
size = __le16_to_cpu(sb->bblog_size)* 512;
|
||||||
|
- if (posix_memalign((void**)&bbl, 4096, size) != 0) {
|
||||||
|
+ if (posix_memalign((void **)&bbl, 4096, size) != 0) {
|
||||||
|
pr_err("could not allocate badblocks list\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -987,7 +990,7 @@ static int match_home1(struct supertype *st, char *homehost)
|
||||||
|
static void uuid_from_super1(struct supertype *st, int uuid[4])
|
||||||
|
{
|
||||||
|
struct mdp_superblock_1 *super = st->sb;
|
||||||
|
- char *cuuid = (char*)uuid;
|
||||||
|
+ char *cuuid = (char *)uuid;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
cuuid[i] = super->set_uuid[i];
|
||||||
|
@@ -996,9 +999,9 @@ static void uuid_from_super1(struct supertype *st, int uuid[4])
|
||||||
|
static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
|
||||||
|
{
|
||||||
|
struct mdp_superblock_1 *sb = st->sb;
|
||||||
|
- struct bitmap_super_s *bsb = (void*)(((char*)sb)+MAX_SB_SIZE);
|
||||||
|
+ struct bitmap_super_s *bsb = (void *)(((char *)sb) + MAX_SB_SIZE);
|
||||||
|
struct misc_dev_info *misc =
|
||||||
|
- (void*)(((char*)sb)+MAX_SB_SIZE+BM_SUPER_SIZE);
|
||||||
|
+ (void *)(((char *)sb) + MAX_SB_SIZE+BM_SUPER_SIZE);
|
||||||
|
int working = 0;
|
||||||
|
unsigned int i;
|
||||||
|
unsigned int role;
|
||||||
|
@@ -1166,7 +1169,7 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
|
||||||
|
info->recovery_blocked = info->reshape_active;
|
||||||
|
|
||||||
|
if (map)
|
||||||
|
- for (i=0; i<map_disks; i++)
|
||||||
|
+ for (i = 0; i < map_disks; i++)
|
||||||
|
map[i] = 0;
|
||||||
|
for (i = 0; i < __le32_to_cpu(sb->max_dev); i++) {
|
||||||
|
role = __le16_to_cpu(sb->dev_roles[i]);
|
||||||
|
@@ -1217,7 +1220,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
|
||||||
|
*/
|
||||||
|
int rv = 0;
|
||||||
|
struct mdp_superblock_1 *sb = st->sb;
|
||||||
|
- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE);
|
||||||
|
+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE);
|
||||||
|
|
||||||
|
if (update == UOPT_HOMEHOST && homehost) {
|
||||||
|
/*
|
||||||
|
@@ -1228,9 +1231,10 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
|
||||||
|
update = UOPT_NAME;
|
||||||
|
c = strchr(sb->set_name, ':');
|
||||||
|
if (c)
|
||||||
|
- snprintf(info->name, sizeof(info->name), "%s", c+1);
|
||||||
|
+ snprintf(info->name, sizeof(info->name), "%s", c + 1);
|
||||||
|
else
|
||||||
|
- snprintf(info->name, sizeof(info->name), "%s", sb->set_name);
|
||||||
|
+ snprintf(info->name, sizeof(info->name), "%s",
|
||||||
|
+ sb->set_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (update) {
|
||||||
|
@@ -1331,7 +1335,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
|
||||||
|
sb->dev_number = __cpu_to_le32(i);
|
||||||
|
|
||||||
|
if (i == max)
|
||||||
|
- sb->max_dev = __cpu_to_le32(max+1);
|
||||||
|
+ sb->max_dev = __cpu_to_le32(max + 1);
|
||||||
|
if (i > max)
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
@@ -1350,8 +1354,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
|
||||||
|
sb->data_size = __cpu_to_le64(
|
||||||
|
ds - __le64_to_cpu(sb->data_offset));
|
||||||
|
} else {
|
||||||
|
- ds -= 8*2;
|
||||||
|
- ds &= ~(unsigned long long)(4*2-1);
|
||||||
|
+ ds -= 8 * 2;
|
||||||
|
+ ds &= ~(unsigned long long)(4 * 2 - 1);
|
||||||
|
sb->super_offset = __cpu_to_le64(ds);
|
||||||
|
sb->data_size = __cpu_to_le64(
|
||||||
|
ds - __le64_to_cpu(sb->data_offset));
|
||||||
|
@@ -1367,7 +1371,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
|
||||||
|
if (i > max)
|
||||||
|
return -2;
|
||||||
|
if (i == max)
|
||||||
|
- sb->max_dev = __cpu_to_le32(max+1);
|
||||||
|
+ sb->max_dev = __cpu_to_le32(max + 1);
|
||||||
|
sb->raid_disks = __cpu_to_le32(info->array.raid_disks);
|
||||||
|
sb->dev_roles[info->disk.number] =
|
||||||
|
__cpu_to_le16(info->disk.raid_disk);
|
||||||
|
@@ -1645,7 +1649,7 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info,
|
||||||
|
char defname[10];
|
||||||
|
int sbsize;
|
||||||
|
|
||||||
|
- if (posix_memalign((void**)&sb, 4096, SUPER1_SIZE) != 0) {
|
||||||
|
+ if (posix_memalign((void **)&sb, 4096, SUPER1_SIZE) != 0) {
|
||||||
|
pr_err("could not allocate superblock\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -1679,8 +1683,8 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info,
|
||||||
|
name = defname;
|
||||||
|
}
|
||||||
|
if (homehost &&
|
||||||
|
- strchr(name, ':')== NULL &&
|
||||||
|
- strlen(homehost)+1+strlen(name) < 32) {
|
||||||
|
+ strchr(name, ':') == NULL &&
|
||||||
|
+ strlen(homehost) + 1 + strlen(name) < 32) {
|
||||||
|
strcpy(sb->set_name, homehost);
|
||||||
|
strcat(sb->set_name, ":");
|
||||||
|
strcat(sb->set_name, name);
|
||||||
|
@@ -1759,7 +1763,7 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
|
||||||
|
|
||||||
|
if (dk->number >= (int)__le32_to_cpu(sb->max_dev) &&
|
||||||
|
__le32_to_cpu(sb->max_dev) < MAX_DEVS)
|
||||||
|
- sb->max_dev = __cpu_to_le32(dk->number+1);
|
||||||
|
+ sb->max_dev = __cpu_to_le32(dk->number + 1);
|
||||||
|
|
||||||
|
sb->dev_number = __cpu_to_le32(dk->number);
|
||||||
|
sb->devflags = 0; /* don't copy another disks flags */
|
||||||
|
@@ -1840,8 +1844,8 @@ static int store_super1(struct supertype *st, int fd)
|
||||||
|
return 4;
|
||||||
|
|
||||||
|
if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) {
|
||||||
|
- struct bitmap_super_s *bm = (struct bitmap_super_s*)
|
||||||
|
- (((char*)sb)+MAX_SB_SIZE);
|
||||||
|
+ struct bitmap_super_s *bm;
|
||||||
|
+ bm = (struct bitmap_super_s *)(((char *)sb) + MAX_SB_SIZE);
|
||||||
|
if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC) {
|
||||||
|
locate_bitmap1(st, fd, 0);
|
||||||
|
if (awrite(&afd, bm, sizeof(*bm)) != sizeof(*bm))
|
||||||
|
@@ -1928,7 +1932,7 @@ static int write_empty_r5l_meta_block(struct supertype *st, int fd)
|
||||||
|
|
||||||
|
init_afd(&afd, fd);
|
||||||
|
|
||||||
|
- if (posix_memalign((void**)&mb, 4096, META_BLOCK_SIZE) != 0) {
|
||||||
|
+ if (posix_memalign((void **)&mb, 4096, META_BLOCK_SIZE) != 0) {
|
||||||
|
pr_err("Could not allocate memory for the meta block.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@@ -2197,7 +2201,7 @@ static int compare_super1(struct supertype *st, struct supertype *tst,
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (!first) {
|
||||||
|
- if (posix_memalign((void**)&first, 4096, SUPER1_SIZE) != 0) {
|
||||||
|
+ if (posix_memalign((void **)&first, 4096, SUPER1_SIZE) != 0) {
|
||||||
|
pr_err("could not allocate superblock\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@@ -2310,7 +2314,7 @@ static int load_super1(struct supertype *st, int fd, char *devname)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (posix_memalign((void**)&super, 4096, SUPER1_SIZE) != 0) {
|
||||||
|
+ if (posix_memalign((void **)&super, 4096, SUPER1_SIZE) != 0) {
|
||||||
|
pr_err("could not allocate superblock\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@@ -2349,10 +2353,10 @@ static int load_super1(struct supertype *st, int fd, char *devname)
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
- bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE);
|
||||||
|
+ bsb = (struct bitmap_super_s *)(((char *)super) + MAX_SB_SIZE);
|
||||||
|
|
||||||
|
misc = (struct misc_dev_info*)
|
||||||
|
- (((char*)super)+MAX_SB_SIZE+BM_SUPER_SIZE);
|
||||||
|
+ (((char *)super) + MAX_SB_SIZE+BM_SUPER_SIZE);
|
||||||
|
misc->device_size = dsize;
|
||||||
|
if (st->data_offset == INVALID_SECTORS)
|
||||||
|
st->data_offset = __le64_to_cpu(super->data_offset);
|
||||||
|
@@ -2360,9 +2364,8 @@ static int load_super1(struct supertype *st, int fd, char *devname)
|
||||||
|
if (st->minor_version >= 1 &&
|
||||||
|
st->ignore_hw_compat == 0 &&
|
||||||
|
((role_from_sb(super) != MD_DISK_ROLE_JOURNAL &&
|
||||||
|
- dsize < (__le64_to_cpu(super->data_offset) +
|
||||||
|
- __le64_to_cpu(super->size)))
|
||||||
|
- ||
|
||||||
|
+ 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)
|
||||||
|
@@ -2391,8 +2394,8 @@ static int load_super1(struct supertype *st, int fd, char *devname)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
no_bitmap:
|
||||||
|
- super->feature_map = __cpu_to_le32(__le32_to_cpu(super->feature_map)
|
||||||
|
- & ~MD_FEATURE_BITMAP_OFFSET);
|
||||||
|
+ super->feature_map = __cpu_to_le32(__le32_to_cpu(super->feature_map) &
|
||||||
|
+ ~MD_FEATURE_BITMAP_OFFSET);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2450,7 +2453,7 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize,
|
||||||
|
if (__le32_to_cpu(super->feature_map) & MD_FEATURE_BITMAP_OFFSET) {
|
||||||
|
/* hot-add. allow for actual size of bitmap */
|
||||||
|
struct bitmap_super_s *bsb;
|
||||||
|
- bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE);
|
||||||
|
+ bsb = (struct bitmap_super_s *)(((char *)super) + MAX_SB_SIZE);
|
||||||
|
bmspace = calc_bitmap_size(bsb, 4096) >> 9;
|
||||||
|
} else if (md_feature_any_ppl_on(super->feature_map)) {
|
||||||
|
bmspace = __le16_to_cpu(super->ppl.size);
|
||||||
|
@@ -2519,7 +2522,7 @@ add_internal_bitmap1(struct supertype *st,
|
||||||
|
int creating = 0;
|
||||||
|
int len;
|
||||||
|
struct mdp_superblock_1 *sb = st->sb;
|
||||||
|
- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE);
|
||||||
|
+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE);
|
||||||
|
int uuid[4];
|
||||||
|
|
||||||
|
if (__le64_to_cpu(sb->data_size) == 0)
|
||||||
|
@@ -2607,10 +2610,10 @@ add_internal_bitmap1(struct supertype *st,
|
||||||
|
max_bits = (room * 512 - sizeof(bitmap_super_t)) * 8;
|
||||||
|
|
||||||
|
min_chunk = 4096; /* sub-page chunks don't work yet.. */
|
||||||
|
- bits = (size*512)/min_chunk +1;
|
||||||
|
+ bits = (size * 512) / min_chunk + 1;
|
||||||
|
while (bits > max_bits) {
|
||||||
|
min_chunk *= 2;
|
||||||
|
- bits = (bits+1)/2;
|
||||||
|
+ bits = (bits + 1) / 2;
|
||||||
|
}
|
||||||
|
if (chunk == UnSet) {
|
||||||
|
/* For practical purpose, 64Meg is a good
|
||||||
|
@@ -2628,8 +2631,8 @@ add_internal_bitmap1(struct supertype *st,
|
||||||
|
/* start bitmap on a 4K boundary with enough space for
|
||||||
|
* the bitmap
|
||||||
|
*/
|
||||||
|
- bits = (size*512) / chunk + 1;
|
||||||
|
- room = ((bits+7)/8 + sizeof(bitmap_super_t) +4095)/4096;
|
||||||
|
+ bits = (size * 512) / chunk + 1;
|
||||||
|
+ room = ((bits + 7) / 8 + sizeof(bitmap_super_t) + 4095) / 4096;
|
||||||
|
room *= 8; /* convert 4K blocks to sectors */
|
||||||
|
offset = -room - bbl_size;
|
||||||
|
}
|
||||||
|
@@ -2683,7 +2686,7 @@ static int locate_bitmap1(struct supertype *st, int fd, int node_num)
|
||||||
|
|
||||||
|
offset = __le64_to_cpu(sb->super_offset) + (int32_t)__le32_to_cpu(sb->bitmap_offset);
|
||||||
|
if (node_num) {
|
||||||
|
- bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE);
|
||||||
|
+ bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE);
|
||||||
|
bm_sectors_per_node = calc_bitmap_size(bms, 4096) >> 9;
|
||||||
|
offset += bm_sectors_per_node * node_num;
|
||||||
|
}
|
||||||
|
@@ -2696,7 +2699,7 @@ static int locate_bitmap1(struct supertype *st, int fd, int node_num)
|
||||||
|
static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update)
|
||||||
|
{
|
||||||
|
struct mdp_superblock_1 *sb = st->sb;
|
||||||
|
- bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE);
|
||||||
|
+ bitmap_super_t *bms = (bitmap_super_t *)(((char *)sb) + MAX_SB_SIZE);
|
||||||
|
int rv = 0;
|
||||||
|
void *buf;
|
||||||
|
int towrite, n, len;
|
||||||
|
@@ -2970,16 +2973,16 @@ void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0
|
||||||
|
|
||||||
|
copy_uuid(sb->set_uuid, info->uuid, super1.swapuuid);
|
||||||
|
sprintf(sb->set_name, "%d", sb0->md_minor);
|
||||||
|
- sb->ctime = __cpu_to_le32(info->array.ctime+1);
|
||||||
|
+ sb->ctime = __cpu_to_le32(info->array.ctime + 1);
|
||||||
|
sb->level = __cpu_to_le32(info->array.level);
|
||||||
|
sb->layout = __cpu_to_le32(info->array.layout);
|
||||||
|
sb->size = __cpu_to_le64(info->component_size);
|
||||||
|
- sb->chunksize = __cpu_to_le32(info->array.chunk_size/512);
|
||||||
|
+ sb->chunksize = __cpu_to_le32(info->array.chunk_size / 512);
|
||||||
|
sb->raid_disks = __cpu_to_le32(info->array.raid_disks);
|
||||||
|
if (info->array.level > 0)
|
||||||
|
sb->data_size = sb->size;
|
||||||
|
else
|
||||||
|
- sb->data_size = st->ss->avail_size(st, st->devsize/512, 0);
|
||||||
|
+ sb->data_size = st->ss->avail_size(st, st->devsize / 512, 0);
|
||||||
|
sb->resync_offset = MaxSector;
|
||||||
|
sb->max_dev = __cpu_to_le32(MD_SB_DISKS);
|
||||||
|
sb->dev_number = __cpu_to_le32(info->disk.number);
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
136
SOURCES/0119-Bump-minimum-kernel-version-to-2.6.32.patch
Normal file
136
SOURCES/0119-Bump-minimum-kernel-version-to-2.6.32.patch
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
From f8d2c4286a92b7acb7872271a401ad1efe336096 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
Date: Mon, 10 Apr 2023 11:45:34 -0400
|
||||||
|
Subject: [PATCH 119/125] Bump minimum kernel version to 2.6.32
|
||||||
|
|
||||||
|
Summary: At this point it probably is reasonable to drop support for
|
||||||
|
anything prior to 3.10.
|
||||||
|
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Create.c | 5 -----
|
||||||
|
Grow.c | 16 ----------------
|
||||||
|
Manage.c | 17 -----------------
|
||||||
|
mdadm.c | 4 ++--
|
||||||
|
super1.c | 5 -----
|
||||||
|
5 files changed, 2 insertions(+), 45 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Create.c b/Create.c
|
||||||
|
index 0911bf92..aa0472dd 100644
|
||||||
|
--- a/Create.c
|
||||||
|
+++ b/Create.c
|
||||||
|
@@ -636,11 +636,6 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
break;
|
||||||
|
case LEVEL_LINEAR:
|
||||||
|
/* a chunksize of zero 0s perfectly valid (and preferred) since 2.6.16 */
|
||||||
|
- if (get_linux_version() < 2006016 && s->chunk == 0) {
|
||||||
|
- s->chunk = 64;
|
||||||
|
- if (c->verbose > 0)
|
||||||
|
- pr_err("chunk size defaults to 64K\n");
|
||||||
|
- }
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
case LEVEL_FAULTY:
|
||||||
|
diff --git a/Grow.c b/Grow.c
|
||||||
|
index 06001f2d..8fa97875 100644
|
||||||
|
--- a/Grow.c
|
||||||
|
+++ b/Grow.c
|
||||||
|
@@ -1708,14 +1708,6 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (re->after.data_disks == re->before.data_disks &&
|
||||||
|
- get_linux_version() < 2006032)
|
||||||
|
- return "in-place reshape is not safe before 2.6.32 - sorry.";
|
||||||
|
-
|
||||||
|
- if (re->after.data_disks < re->before.data_disks &&
|
||||||
|
- get_linux_version() < 2006030)
|
||||||
|
- return "reshape to fewer devices is not supported before 2.6.30 - sorry.";
|
||||||
|
-
|
||||||
|
re->backup_blocks = compute_backup_blocks(
|
||||||
|
info->new_chunk, info->array.chunk_size,
|
||||||
|
re->after.data_disks, re->before.data_disks);
|
||||||
|
@@ -1895,14 +1887,6 @@ int Grow_reshape(char *devname, int fd,
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (s->raiddisks && s->raiddisks < array.raid_disks &&
|
||||||
|
- array.level > 1 && get_linux_version() < 2006032 &&
|
||||||
|
- !check_env("MDADM_FORCE_FEWER")) {
|
||||||
|
- pr_err("reducing the number of devices is not safe before Linux 2.6.32\n"
|
||||||
|
- " Please use a newer kernel\n");
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
if (array.level > 1 && s->size > 1 &&
|
||||||
|
(unsigned long long) (array.chunk_size / 1024) > s->size) {
|
||||||
|
pr_err("component size must be larger than chunk size.\n");
|
||||||
|
diff --git a/Manage.c b/Manage.c
|
||||||
|
index fde6aba3..f54de7c6 100644
|
||||||
|
--- a/Manage.c
|
||||||
|
+++ b/Manage.c
|
||||||
|
@@ -461,17 +461,6 @@ done:
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (get_linux_version() < 2006028) {
|
||||||
|
- /* prior to 2.6.28, KOBJ_CHANGE was not sent when an md array
|
||||||
|
- * was stopped, so We'll do it here just to be sure. Drop any
|
||||||
|
- * partitions as well...
|
||||||
|
- */
|
||||||
|
- if (fd >= 0)
|
||||||
|
- ioctl(fd, BLKRRPART, 0);
|
||||||
|
- if (mdi)
|
||||||
|
- sysfs_uevent(mdi, "change");
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
if (devnm[0] && use_udev()) {
|
||||||
|
struct map_ent *mp = map_by_devnm(&map, devnm);
|
||||||
|
remove_devices(devnm, mp ? mp->path : NULL);
|
||||||
|
@@ -621,12 +610,6 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv,
|
||||||
|
* though.
|
||||||
|
*/
|
||||||
|
mdu_disk_info_t disc;
|
||||||
|
- /* re-add doesn't work for version-1 superblocks
|
||||||
|
- * before 2.6.18 :-(
|
||||||
|
- */
|
||||||
|
- if (array->major_version == 1 &&
|
||||||
|
- get_linux_version() <= 2006018)
|
||||||
|
- goto skip_re_add;
|
||||||
|
disc.number = mdi.disk.number;
|
||||||
|
if (md_get_disk_info(fd, &disc) != 0 ||
|
||||||
|
disc.major != 0 || disc.minor != 0)
|
||||||
|
diff --git a/mdadm.c b/mdadm.c
|
||||||
|
index 4685ad6b..2296911d 100644
|
||||||
|
--- a/mdadm.c
|
||||||
|
+++ b/mdadm.c
|
||||||
|
@@ -107,8 +107,8 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
|
srandom(time(0) ^ getpid());
|
||||||
|
|
||||||
|
- if (get_linux_version() < 2006015) {
|
||||||
|
- pr_err("This version of mdadm does not support kernels older than 2.6.15\n");
|
||||||
|
+ if (get_linux_version() < 2006032) {
|
||||||
|
+ pr_err("This version of mdadm does not support kernels older than 2.6.32\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/super1.c b/super1.c
|
||||||
|
index 1d20ef55..938c3a68 100644
|
||||||
|
--- a/super1.c
|
||||||
|
+++ b/super1.c
|
||||||
|
@@ -2033,11 +2033,6 @@ static int write_init_super1(struct supertype *st)
|
||||||
|
/* same array, so preserve events and
|
||||||
|
* dev_number */
|
||||||
|
sb->events = refsb->events;
|
||||||
|
- /* bugs in 2.6.17 and earlier mean the
|
||||||
|
- * dev_number chosen in Manage must be preserved
|
||||||
|
- */
|
||||||
|
- if (get_linux_version() >= 2006018)
|
||||||
|
- sb->dev_number = refsb->dev_number;
|
||||||
|
}
|
||||||
|
free_super1(refst);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,42 @@
|
|||||||
|
From 76c224c6cfc8ff154bd041d30b9551faecd593c1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Xiao Ni <xni@redhat.com>
|
||||||
|
Date: Fri, 7 Apr 2023 08:45:28 +0800
|
||||||
|
Subject: [PATCH 120/125] Remove the config files in mdcheck_start|continue
|
||||||
|
service
|
||||||
|
|
||||||
|
We set MDADM_CHECK_DURATION in the mdcheck_start|continue.service files.
|
||||||
|
And mdcheck doesn't use any configs from the config file. So we can remove
|
||||||
|
the dependencies.
|
||||||
|
|
||||||
|
Signed-off-by: Xiao Ni <xni@redhat.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
systemd/mdcheck_continue.service | 2 --
|
||||||
|
systemd/mdcheck_start.service | 2 --
|
||||||
|
2 files changed, 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/systemd/mdcheck_continue.service b/systemd/mdcheck_continue.service
|
||||||
|
index f5324905..70892a1f 100644
|
||||||
|
--- a/systemd/mdcheck_continue.service
|
||||||
|
+++ b/systemd/mdcheck_continue.service
|
||||||
|
@@ -13,6 +13,4 @@ Documentation=man:mdadm(8)
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
Environment="MDADM_CHECK_DURATION=6 hours"
|
||||||
|
-EnvironmentFile=-/run/sysconfig/mdadm
|
||||||
|
-ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
|
||||||
|
ExecStart=/usr/share/mdadm/mdcheck --continue --duration ${MDADM_CHECK_DURATION}
|
||||||
|
diff --git a/systemd/mdcheck_start.service b/systemd/mdcheck_start.service
|
||||||
|
index 703a6583..fc4fc438 100644
|
||||||
|
--- a/systemd/mdcheck_start.service
|
||||||
|
+++ b/systemd/mdcheck_start.service
|
||||||
|
@@ -13,6 +13,4 @@ Documentation=man:mdadm(8)
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
Environment="MDADM_CHECK_DURATION=6 hours"
|
||||||
|
-EnvironmentFile=-/run/sysconfig/mdadm
|
||||||
|
-ExecStartPre=-/usr/lib/mdadm/mdadm_env.sh
|
||||||
|
ExecStart=/usr/share/mdadm/mdcheck --duration ${MDADM_CHECK_DURATION}
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
347
SOURCES/0121-mdadm-define-DEV_MD_DIR.patch
Normal file
347
SOURCES/0121-mdadm-define-DEV_MD_DIR.patch
Normal file
@ -0,0 +1,347 @@
|
|||||||
|
From b9ce7ab0218c550488587fdad5708628d6a5ffc2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Thu, 23 Mar 2023 17:50:14 +0100
|
||||||
|
Subject: [PATCH 121/125] mdadm: define DEV_MD_DIR
|
||||||
|
|
||||||
|
It is used many times. Additionally define _LEN to avoid repeated
|
||||||
|
strlen() calls when length is needed.
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Create.c | 7 +++----
|
||||||
|
Detail.c | 9 ++++-----
|
||||||
|
Incremental.c | 4 ++--
|
||||||
|
Monitor.c | 32 ++++++++++++++++++--------------
|
||||||
|
config.c | 10 +++++-----
|
||||||
|
lib.c | 2 +-
|
||||||
|
mapfile.c | 12 ++++++------
|
||||||
|
mdadm.h | 8 ++++++++
|
||||||
|
mdopen.c | 6 +++---
|
||||||
|
super-ddf.c | 2 +-
|
||||||
|
super-intel.c | 2 +-
|
||||||
|
super1.c | 3 +--
|
||||||
|
sysfs.c | 2 +-
|
||||||
|
13 files changed, 54 insertions(+), 45 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Create.c b/Create.c
|
||||||
|
index aa0472dd..ea6a4745 100644
|
||||||
|
--- a/Create.c
|
||||||
|
+++ b/Create.c
|
||||||
|
@@ -1024,10 +1024,9 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
* it could be in conflict with already existing device
|
||||||
|
* e.g. container, array
|
||||||
|
*/
|
||||||
|
- if (strncmp(chosen_name, "/dev/md/", 8) == 0 &&
|
||||||
|
- map_by_name(&map, chosen_name+8) != NULL) {
|
||||||
|
- pr_err("Array name %s is in use already.\n",
|
||||||
|
- chosen_name);
|
||||||
|
+ if (strncmp(chosen_name, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 &&
|
||||||
|
+ map_by_name(&map, chosen_name + DEV_MD_DIR_LEN)) {
|
||||||
|
+ pr_err("Array name %s is in use already.\n", chosen_name);
|
||||||
|
close(mdfd);
|
||||||
|
map_unlock(&map);
|
||||||
|
udev_unblock();
|
||||||
|
diff --git a/Detail.c b/Detail.c
|
||||||
|
index 4ef26460..206d88e3 100644
|
||||||
|
--- a/Detail.c
|
||||||
|
+++ b/Detail.c
|
||||||
|
@@ -254,10 +254,9 @@ int Detail(char *dev, struct context *c)
|
||||||
|
fname_from_uuid(st, info, nbuf, ':');
|
||||||
|
printf("MD_UUID=%s\n", nbuf + 5);
|
||||||
|
mp = map_by_uuid(&map, info->uuid);
|
||||||
|
- if (mp && mp->path &&
|
||||||
|
- strncmp(mp->path, "/dev/md/", 8) == 0) {
|
||||||
|
+ if (mp && mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) {
|
||||||
|
printf("MD_DEVNAME=");
|
||||||
|
- print_escape(mp->path + 8);
|
||||||
|
+ print_escape(mp->path + DEV_MD_DIR_LEN);
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -273,9 +272,9 @@ int Detail(char *dev, struct context *c)
|
||||||
|
printf("MD_UUID=%s\n", nbuf+5);
|
||||||
|
}
|
||||||
|
if (mp && mp->path &&
|
||||||
|
- strncmp(mp->path, "/dev/md/", 8) == 0) {
|
||||||
|
+ strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) {
|
||||||
|
printf("MD_DEVNAME=");
|
||||||
|
- print_escape(mp->path+8);
|
||||||
|
+ print_escape(mp->path + DEV_MD_DIR_LEN);
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
map_free(map);
|
||||||
|
diff --git a/Incremental.c b/Incremental.c
|
||||||
|
index 49a71f72..59b850f1 100644
|
||||||
|
--- a/Incremental.c
|
||||||
|
+++ b/Incremental.c
|
||||||
|
@@ -460,8 +460,8 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
|
||||||
|
info.array.working_disks ++;
|
||||||
|
|
||||||
|
}
|
||||||
|
- if (strncmp(chosen_name, "/dev/md/", 8) == 0)
|
||||||
|
- md_devname = chosen_name+8;
|
||||||
|
+ if (strncmp(chosen_name, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0)
|
||||||
|
+ md_devname = chosen_name + DEV_MD_DIR_LEN;
|
||||||
|
else
|
||||||
|
md_devname = chosen_name;
|
||||||
|
if (c->export) {
|
||||||
|
diff --git a/Monitor.c b/Monitor.c
|
||||||
|
index 44918184..3273f2fb 100644
|
||||||
|
--- a/Monitor.c
|
||||||
|
+++ b/Monitor.c
|
||||||
|
@@ -36,9 +36,18 @@
|
||||||
|
#define EVENT_NAME_MAX 32
|
||||||
|
#define AUTOREBUILD_PID_PATH MDMON_DIR "/autorebuild.pid"
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * struct state - external array or container properties.
|
||||||
|
+ * @devname: has length of %DEV_MD_DIR + device name + terminating byte
|
||||||
|
+ * @devnm: to sync with mdstat info
|
||||||
|
+ * @parent_devnm: or subarray, devnm of parent, for others, ""
|
||||||
|
+ * @subarray: for a container it is a link to first subarray, for a subarray it is a link to next
|
||||||
|
+ * subarray in the same container
|
||||||
|
+ * @parent: for a subarray it is a link to its container
|
||||||
|
+ */
|
||||||
|
struct state {
|
||||||
|
- 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 */
|
||||||
|
+ char devname[MD_NAME_MAX + sizeof(DEV_MD_DIR)];
|
||||||
|
+ char devnm[MD_NAME_MAX];
|
||||||
|
unsigned int utime;
|
||||||
|
int err;
|
||||||
|
char *spare_group;
|
||||||
|
@@ -49,15 +58,10 @@ struct state {
|
||||||
|
int devstate[MAX_DISKS];
|
||||||
|
dev_t devid[MAX_DISKS];
|
||||||
|
int percent;
|
||||||
|
- char parent_devnm[MD_NAME_MAX]; /* For subarray, devnm of parent.
|
||||||
|
- * For others, ""
|
||||||
|
- */
|
||||||
|
+ char parent_devnm[MD_NAME_MAX];
|
||||||
|
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
|
||||||
|
- * in the same container */
|
||||||
|
- struct state *parent; /* for a subarray it is a link to its container
|
||||||
|
- */
|
||||||
|
+ struct state *subarray;
|
||||||
|
+ struct state *parent;
|
||||||
|
struct state *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -252,8 +256,8 @@ int Monitor(struct mddev_dev *devlist,
|
||||||
|
continue;
|
||||||
|
|
||||||
|
st = xcalloc(1, sizeof *st);
|
||||||
|
- snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"),
|
||||||
|
- "/dev/md/%s", basename(mdlist->devname));
|
||||||
|
+ snprintf(st->devname, MD_NAME_MAX + sizeof(DEV_MD_DIR), DEV_MD_DIR "%s",
|
||||||
|
+ basename(mdlist->devname));
|
||||||
|
st->next = statelist;
|
||||||
|
st->devnm[0] = 0;
|
||||||
|
st->percent = RESYNC_UNKNOWN;
|
||||||
|
@@ -274,7 +278,7 @@ int Monitor(struct mddev_dev *devlist,
|
||||||
|
|
||||||
|
st = xcalloc(1, sizeof *st);
|
||||||
|
mdlist = conf_get_ident(dv->devname);
|
||||||
|
- snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "%s", dv->devname);
|
||||||
|
+ snprintf(st->devname, MD_NAME_MAX + sizeof(DEV_MD_DIR), "%s", dv->devname);
|
||||||
|
st->next = statelist;
|
||||||
|
st->devnm[0] = 0;
|
||||||
|
st->percent = RESYNC_UNKNOWN;
|
||||||
|
@@ -942,7 +946,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "%s", name);
|
||||||
|
+ snprintf(st->devname, MD_NAME_MAX + sizeof(DEV_MD_DIR), "%s", name);
|
||||||
|
if ((fd = open(st->devname, O_RDONLY)) < 0 ||
|
||||||
|
md_get_array_info(fd, &array) < 0) {
|
||||||
|
/* no such array */
|
||||||
|
diff --git a/config.c b/config.c
|
||||||
|
index eeedd0c6..59d5bfb6 100644
|
||||||
|
--- a/config.c
|
||||||
|
+++ b/config.c
|
||||||
|
@@ -405,7 +405,7 @@ void arrayline(char *line)
|
||||||
|
* or anything that doesn't start '/' or '<'
|
||||||
|
*/
|
||||||
|
if (strcasecmp(w, "<ignore>") == 0 ||
|
||||||
|
- strncmp(w, "/dev/md/", 8) == 0 ||
|
||||||
|
+ strncmp(w, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 ||
|
||||||
|
(w[0] != '/' && w[0] != '<') ||
|
||||||
|
(strncmp(w, "/dev/md", 7) == 0 &&
|
||||||
|
is_number(w + 7)) ||
|
||||||
|
@@ -1102,13 +1102,13 @@ int devname_matches(char *name, char *match)
|
||||||
|
* mdNN with NN
|
||||||
|
* then just strcmp
|
||||||
|
*/
|
||||||
|
- if (strncmp(name, "/dev/md/", 8) == 0)
|
||||||
|
- name += 8;
|
||||||
|
+ if (strncmp(name, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0)
|
||||||
|
+ name += DEV_MD_DIR_LEN;
|
||||||
|
else if (strncmp(name, "/dev/", 5) == 0)
|
||||||
|
name += 5;
|
||||||
|
|
||||||
|
- if (strncmp(match, "/dev/md/", 8) == 0)
|
||||||
|
- match += 8;
|
||||||
|
+ if (strncmp(match, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0)
|
||||||
|
+ match += DEV_MD_DIR_LEN;
|
||||||
|
else if (strncmp(match, "/dev/", 5) == 0)
|
||||||
|
match += 5;
|
||||||
|
|
||||||
|
diff --git a/lib.c b/lib.c
|
||||||
|
index e395b28d..65ea51e0 100644
|
||||||
|
--- a/lib.c
|
||||||
|
+++ b/lib.c
|
||||||
|
@@ -313,7 +313,7 @@ char *map_dev_preferred(int major, int minor, int create,
|
||||||
|
|
||||||
|
for (p = devlist; p; p = p->next)
|
||||||
|
if (p->major == major && p->minor == minor) {
|
||||||
|
- if (strncmp(p->name, "/dev/md/",8) == 0 ||
|
||||||
|
+ if (strncmp(p->name, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 ||
|
||||||
|
(prefer && strstr(p->name, prefer))) {
|
||||||
|
if (preferred == NULL ||
|
||||||
|
strlen(p->name) < strlen(preferred))
|
||||||
|
diff --git a/mapfile.c b/mapfile.c
|
||||||
|
index ac351768..34fea179 100644
|
||||||
|
--- a/mapfile.c
|
||||||
|
+++ b/mapfile.c
|
||||||
|
@@ -320,9 +320,9 @@ struct map_ent *map_by_name(struct map_ent **map, char *name)
|
||||||
|
for (mp = *map ; mp ; mp = mp->next) {
|
||||||
|
if (!mp->path)
|
||||||
|
continue;
|
||||||
|
- if (strncmp(mp->path, "/dev/md/", 8) != 0)
|
||||||
|
+ if (strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) != 0)
|
||||||
|
continue;
|
||||||
|
- if (strcmp(mp->path+8, name) != 0)
|
||||||
|
+ if (strcmp(mp->path + DEV_MD_DIR_LEN, name) != 0)
|
||||||
|
continue;
|
||||||
|
if (!mddev_busy(mp->devnm)) {
|
||||||
|
mp->bad = 1;
|
||||||
|
@@ -413,7 +413,7 @@ void RebuildMap(void)
|
||||||
|
devid = devnm2devid(md->devnm);
|
||||||
|
path = map_dev(major(devid), minor(devid), 0);
|
||||||
|
if (path == NULL ||
|
||||||
|
- strncmp(path, "/dev/md/", 8) != 0) {
|
||||||
|
+ strncmp(path, DEV_MD_DIR, DEV_MD_DIR_LEN) != 0) {
|
||||||
|
/* We would really like a name that provides
|
||||||
|
* an MD_DEVNAME for udev.
|
||||||
|
* The name needs to be unique both in /dev/md/
|
||||||
|
@@ -434,7 +434,7 @@ void RebuildMap(void)
|
||||||
|
if (match && match->devname && match->devname[0] == '/') {
|
||||||
|
path = match->devname;
|
||||||
|
if (path[0] != '/') {
|
||||||
|
- strcpy(namebuf, "/dev/md/");
|
||||||
|
+ strcpy(namebuf, DEV_MD_DIR);
|
||||||
|
strcat(namebuf, path);
|
||||||
|
path = namebuf;
|
||||||
|
}
|
||||||
|
@@ -478,10 +478,10 @@ void RebuildMap(void)
|
||||||
|
|
||||||
|
while (conflict) {
|
||||||
|
if (unum >= 0)
|
||||||
|
- sprintf(namebuf, "/dev/md/%s%s%d",
|
||||||
|
+ sprintf(namebuf, DEV_MD_DIR "%s%s%d",
|
||||||
|
name, sep, unum);
|
||||||
|
else
|
||||||
|
- sprintf(namebuf, "/dev/md/%s",
|
||||||
|
+ sprintf(namebuf, DEV_MD_DIR "%s",
|
||||||
|
name);
|
||||||
|
unum++;
|
||||||
|
if (lstat(namebuf, &stb) != 0 &&
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index 0d995445..67d73f96 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -100,6 +100,14 @@ struct dlm_lksb {
|
||||||
|
#define DEFAULT_BITMAP_DELAY 5
|
||||||
|
#define DEFAULT_MAX_WRITE_BEHIND 256
|
||||||
|
|
||||||
|
+/* DEV_MD_DIR points to named MD devices directory.
|
||||||
|
+ * DEV_MD_DIR_LEN is a length with Null byte excluded.
|
||||||
|
+ */
|
||||||
|
+#ifndef DEV_MD_DIR
|
||||||
|
+#define DEV_MD_DIR "/dev/md/"
|
||||||
|
+#define DEV_MD_DIR_LEN (sizeof(DEV_MD_DIR) - 1)
|
||||||
|
+#endif /* DEV_MD_DIR */
|
||||||
|
+
|
||||||
|
/* MAP_DIR should be somewhere that persists across the pivotroot
|
||||||
|
* from early boot to late boot.
|
||||||
|
* /run seems to have emerged as the best standard.
|
||||||
|
diff --git a/mdopen.c b/mdopen.c
|
||||||
|
index 810f79a3..6c3bdb6a 100644
|
||||||
|
--- a/mdopen.c
|
||||||
|
+++ b/mdopen.c
|
||||||
|
@@ -188,12 +188,12 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
|
||||||
|
parts = autof >> 3;
|
||||||
|
autof &= 7;
|
||||||
|
|
||||||
|
- strcpy(chosen, "/dev/md/");
|
||||||
|
+ strcpy(chosen, DEV_MD_DIR);
|
||||||
|
cname = chosen + strlen(chosen);
|
||||||
|
|
||||||
|
if (dev) {
|
||||||
|
- if (strncmp(dev, "/dev/md/", 8) == 0) {
|
||||||
|
- strcpy(cname, dev+8);
|
||||||
|
+ if (strncmp(dev, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) {
|
||||||
|
+ strcpy(cname, dev + DEV_MD_DIR_LEN);
|
||||||
|
} else if (strncmp(dev, "/dev/", 5) == 0) {
|
||||||
|
char *e = dev + strlen(dev);
|
||||||
|
while (e > dev && isdigit(e[-1]))
|
||||||
|
diff --git a/super-ddf.c b/super-ddf.c
|
||||||
|
index b86c6acd..7213284e 100644
|
||||||
|
--- a/super-ddf.c
|
||||||
|
+++ b/super-ddf.c
|
||||||
|
@@ -1648,7 +1648,7 @@ static void brief_examine_subarrays_ddf(struct supertype *st, int verbose)
|
||||||
|
fname_from_uuid(st, &info, nbuf1, ':');
|
||||||
|
_ddf_array_name(namebuf, ddf, i);
|
||||||
|
printf("ARRAY%s%s container=%s member=%d UUID=%s\n",
|
||||||
|
- namebuf[0] == '\0' ? "" : " /dev/md/", namebuf,
|
||||||
|
+ namebuf[0] == '\0' ? "" : " " DEV_MD_DIR, namebuf,
|
||||||
|
nbuf+5, i, nbuf1+5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index a5c86cb2..aaf6659e 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -2309,7 +2309,7 @@ static void brief_examine_subarrays_imsm(struct supertype *st, int verbose)
|
||||||
|
super->current_vol = i;
|
||||||
|
getinfo_super_imsm(st, &info, NULL);
|
||||||
|
fname_from_uuid(st, &info, nbuf1, ':');
|
||||||
|
- printf("ARRAY /dev/md/%.16s container=%s member=%d UUID=%s\n",
|
||||||
|
+ printf("ARRAY " DEV_MD_DIR "%.16s container=%s member=%d UUID=%s\n",
|
||||||
|
dev->volume, nbuf + 5, i, nbuf1 + 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/super1.c b/super1.c
|
||||||
|
index 938c3a68..856b0208 100644
|
||||||
|
--- a/super1.c
|
||||||
|
+++ b/super1.c
|
||||||
|
@@ -645,8 +645,7 @@ static void brief_examine_super1(struct supertype *st, int verbose)
|
||||||
|
|
||||||
|
printf("ARRAY ");
|
||||||
|
if (nm) {
|
||||||
|
- printf("/dev/md/");
|
||||||
|
- print_escape(nm);
|
||||||
|
+ printf(DEV_MD_DIR "%s", nm);
|
||||||
|
putchar(' ');
|
||||||
|
}
|
||||||
|
if (verbose && c)
|
||||||
|
diff --git a/sysfs.c b/sysfs.c
|
||||||
|
index ca1d888f..94d02f53 100644
|
||||||
|
--- a/sysfs.c
|
||||||
|
+++ b/sysfs.c
|
||||||
|
@@ -1114,7 +1114,7 @@ void sysfsline(char *line)
|
||||||
|
if (strncasecmp(w, "name=", 5) == 0) {
|
||||||
|
char *devname = w + 5;
|
||||||
|
|
||||||
|
- if (strncmp(devname, "/dev/md/", 8) == 0) {
|
||||||
|
+ if (strncmp(devname, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) {
|
||||||
|
if (sr->devname)
|
||||||
|
pr_err("Only give one device per SYSFS line: %s\n",
|
||||||
|
devname);
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
73
SOURCES/0122-mdadm-define-DEV_NUM_PREF.patch
Normal file
73
SOURCES/0122-mdadm-define-DEV_NUM_PREF.patch
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
From 0f8347d4f6588ee6ded55af3e307418cee286a6f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Thu, 23 Mar 2023 17:50:15 +0100
|
||||||
|
Subject: [PATCH 122/125] mdadm: define DEV_NUM_PREF
|
||||||
|
|
||||||
|
Use define instead of inlines. Add _LEN define.
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
config.c | 4 ++--
|
||||||
|
mdadm.h | 8 ++++++++
|
||||||
|
mdopen.c | 10 +++++-----
|
||||||
|
3 files changed, 15 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.c b/config.c
|
||||||
|
index 59d5bfb6..f44cc1d3 100644
|
||||||
|
--- a/config.c
|
||||||
|
+++ b/config.c
|
||||||
|
@@ -407,8 +407,8 @@ void arrayline(char *line)
|
||||||
|
if (strcasecmp(w, "<ignore>") == 0 ||
|
||||||
|
strncmp(w, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 ||
|
||||||
|
(w[0] != '/' && w[0] != '<') ||
|
||||||
|
- (strncmp(w, "/dev/md", 7) == 0 &&
|
||||||
|
- is_number(w + 7)) ||
|
||||||
|
+ (strncmp(w, DEV_NUM_PREF, DEV_NUM_PREF_LEN) == 0 &&
|
||||||
|
+ is_number(w + DEV_NUM_PREF_LEN)) ||
|
||||||
|
(strncmp(w, "/dev/md_d", 9) == 0 &&
|
||||||
|
is_number(w + 9))) {
|
||||||
|
/* This is acceptable */;
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index 67d73f96..f2e70baa 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -100,6 +100,14 @@ struct dlm_lksb {
|
||||||
|
#define DEFAULT_BITMAP_DELAY 5
|
||||||
|
#define DEFAULT_MAX_WRITE_BEHIND 256
|
||||||
|
|
||||||
|
+/* DEV_NUM_PREF is a subpath to numbered MD devices, e.g. /dev/md1 or directory name.
|
||||||
|
+ * DEV_NUM_PREF_LEN is a length with Null byte excluded.
|
||||||
|
+ */
|
||||||
|
+#ifndef DEV_NUM_PREF
|
||||||
|
+#define DEV_NUM_PREF "/dev/md"
|
||||||
|
+#define DEV_NUM_PREF_LEN (sizeof(DEV_NUM_PREF) - 1)
|
||||||
|
+#endif /* DEV_NUM_PREF */
|
||||||
|
+
|
||||||
|
/* DEV_MD_DIR points to named MD devices directory.
|
||||||
|
* DEV_MD_DIR_LEN is a length with Null byte excluded.
|
||||||
|
*/
|
||||||
|
diff --git a/mdopen.c b/mdopen.c
|
||||||
|
index 6c3bdb6a..d3022a54 100644
|
||||||
|
--- a/mdopen.c
|
||||||
|
+++ b/mdopen.c
|
||||||
|
@@ -412,11 +412,11 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
|
||||||
|
make_parts(devname, parts);
|
||||||
|
|
||||||
|
if (strcmp(chosen, devname) != 0) {
|
||||||
|
- if (mkdir("/dev/md",0700) == 0) {
|
||||||
|
- if (chown("/dev/md", ci->uid, ci->gid))
|
||||||
|
- perror("chown /dev/md");
|
||||||
|
- if (chmod("/dev/md", ci->mode| ((ci->mode>>2) & 0111)))
|
||||||
|
- perror("chmod /dev/md");
|
||||||
|
+ if (mkdir(DEV_NUM_PREF, 0700) == 0) {
|
||||||
|
+ if (chown(DEV_NUM_PREF, ci->uid, ci->gid))
|
||||||
|
+ perror("chown " DEV_NUM_PREF);
|
||||||
|
+ if (chmod(DEV_NUM_PREF, ci->mode | ((ci->mode >> 2) & 0111)))
|
||||||
|
+ perror("chmod " DEV_NUM_PREF);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev && strcmp(chosen, dev) == 0)
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
133
SOURCES/0123-mdadm-define-is_devname_ignore.patch
Normal file
133
SOURCES/0123-mdadm-define-is_devname_ignore.patch
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
From 7b3b691ba69b909ea8c172aae693fa2a6938fd14 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Thu, 23 Mar 2023 17:50:16 +0100
|
||||||
|
Subject: [PATCH 123/125] mdadm: define is_devname_ignore()
|
||||||
|
|
||||||
|
Use function instead of direct checks across code.
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Incremental.c | 6 ++----
|
||||||
|
Monitor.c | 2 +-
|
||||||
|
config.c | 16 ++++++++++++++--
|
||||||
|
mdadm.c | 5 ++---
|
||||||
|
mdadm.h | 1 +
|
||||||
|
5 files changed, 20 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Incremental.c b/Incremental.c
|
||||||
|
index 59b850f1..f13ce027 100644
|
||||||
|
--- a/Incremental.c
|
||||||
|
+++ b/Incremental.c
|
||||||
|
@@ -202,8 +202,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
|
||||||
|
if (!match && rv == 2)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
- if (match && match->devname &&
|
||||||
|
- strcasecmp(match->devname, "<ignore>") == 0) {
|
||||||
|
+ if (match && match->devname && is_devname_ignore(match->devname) == true) {
|
||||||
|
if (c->verbose >= 0)
|
||||||
|
pr_err("array containing %s is explicitly ignored by mdadm.conf\n",
|
||||||
|
devname);
|
||||||
|
@@ -1567,8 +1566,7 @@ static int Incremental_container(struct supertype *st, char *devname,
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (match && match->devname &&
|
||||||
|
- strcasecmp(match->devname, "<ignore>") == 0) {
|
||||||
|
+ if (match && match->devname && is_devname_ignore(match->devname) == true) {
|
||||||
|
if (c->verbose > 0)
|
||||||
|
pr_err("array %s/%s is explicitly ignored by mdadm.conf\n",
|
||||||
|
match->container, match->member);
|
||||||
|
diff --git a/Monitor.c b/Monitor.c
|
||||||
|
index 3273f2fb..66175968 100644
|
||||||
|
--- a/Monitor.c
|
||||||
|
+++ b/Monitor.c
|
||||||
|
@@ -250,7 +250,7 @@ int Monitor(struct mddev_dev *devlist,
|
||||||
|
|
||||||
|
if (mdlist->devname == NULL)
|
||||||
|
continue;
|
||||||
|
- if (strcasecmp(mdlist->devname, "<ignore>") == 0)
|
||||||
|
+ if (is_devname_ignore(mdlist->devname) == true)
|
||||||
|
continue;
|
||||||
|
if (!is_mddev(mdlist->devname))
|
||||||
|
continue;
|
||||||
|
diff --git a/config.c b/config.c
|
||||||
|
index f44cc1d3..e61c0496 100644
|
||||||
|
--- a/config.c
|
||||||
|
+++ b/config.c
|
||||||
|
@@ -119,6 +119,18 @@ int match_keyword(char *word)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * is_devname_ignore() - check if &devname is a special "<ignore>" keyword.
|
||||||
|
+ */
|
||||||
|
+bool is_devname_ignore(char *devname)
|
||||||
|
+{
|
||||||
|
+ static const char keyword[] = "<ignore>";
|
||||||
|
+
|
||||||
|
+ if (strcasecmp(devname, keyword) == 0)
|
||||||
|
+ return true;
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* ident_init() - Set defaults.
|
||||||
|
* @ident: ident pointer, not NULL.
|
||||||
|
@@ -404,7 +416,7 @@ void arrayline(char *line)
|
||||||
|
* <ignore>
|
||||||
|
* or anything that doesn't start '/' or '<'
|
||||||
|
*/
|
||||||
|
- if (strcasecmp(w, "<ignore>") == 0 ||
|
||||||
|
+ if (is_devname_ignore(w) == true ||
|
||||||
|
strncmp(w, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 ||
|
||||||
|
(w[0] != '/' && w[0] != '<') ||
|
||||||
|
(strncmp(w, DEV_NUM_PREF, DEV_NUM_PREF_LEN) == 0 &&
|
||||||
|
@@ -571,7 +583,7 @@ void homehostline(char *line)
|
||||||
|
char *w;
|
||||||
|
|
||||||
|
for (w = dl_next(line); w != line; w = dl_next(w)) {
|
||||||
|
- if (strcasecmp(w, "<ignore>") == 0)
|
||||||
|
+ if (is_devname_ignore(w) == true)
|
||||||
|
require_homehost = 0;
|
||||||
|
else if (home_host == NULL) {
|
||||||
|
if (strcasecmp(w, "<none>") == 0)
|
||||||
|
diff --git a/mdadm.c b/mdadm.c
|
||||||
|
index 2296911d..076b45e0 100644
|
||||||
|
--- a/mdadm.c
|
||||||
|
+++ b/mdadm.c
|
||||||
|
@@ -154,7 +154,7 @@ int main(int argc, char *argv[])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case HomeHost:
|
||||||
|
- if (strcasecmp(optarg, "<ignore>") == 0)
|
||||||
|
+ if (is_devname_ignore(optarg) == true)
|
||||||
|
c.require_homehost = 0;
|
||||||
|
else
|
||||||
|
c.homehost = optarg;
|
||||||
|
@@ -1749,8 +1749,7 @@ static int scan_assemble(struct supertype *ss,
|
||||||
|
int r;
|
||||||
|
if (a->assembled)
|
||||||
|
continue;
|
||||||
|
- if (a->devname &&
|
||||||
|
- strcasecmp(a->devname, "<ignore>") == 0)
|
||||||
|
+ if (a->devname && is_devname_ignore(a->devname) == true)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
r = Assemble(ss, a->devname,
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index f2e70baa..0932c2d3 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -1650,6 +1650,7 @@ extern void print_escape(char *str);
|
||||||
|
extern int use_udev(void);
|
||||||
|
extern unsigned long GCD(unsigned long a, unsigned long b);
|
||||||
|
extern int conf_name_is_free(char *name);
|
||||||
|
+extern bool is_devname_ignore(char *devname);
|
||||||
|
extern int conf_verify_devnames(struct mddev_ident *array_list);
|
||||||
|
extern int devname_matches(char *name, char *match);
|
||||||
|
extern struct mddev_ident *conf_match(struct supertype *st,
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
145
SOURCES/0124-mdadm-numbered-names-verification.patch
Normal file
145
SOURCES/0124-mdadm-numbered-names-verification.patch
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
From 25aa7329141c0b28d8811671627f0f5c5dc22273 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Thu, 23 Mar 2023 17:50:17 +0100
|
||||||
|
Subject: [PATCH 124/125] mdadm: numbered names verification
|
||||||
|
|
||||||
|
New functions added to remove literals and make the code reusable.
|
||||||
|
Use parse_num() instead of is_numer().
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
config.c | 17 ++---------------
|
||||||
|
lib.c | 2 +-
|
||||||
|
mdadm.h | 4 +++-
|
||||||
|
util.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
4 files changed, 50 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.c b/config.c
|
||||||
|
index e61c0496..450880e3 100644
|
||||||
|
--- a/config.c
|
||||||
|
+++ b/config.c
|
||||||
|
@@ -385,17 +385,6 @@ void devline(char *line)
|
||||||
|
struct mddev_ident *mddevlist = NULL;
|
||||||
|
struct mddev_ident **mddevlp = &mddevlist;
|
||||||
|
|
||||||
|
-static int is_number(char *w)
|
||||||
|
-{
|
||||||
|
- /* check if there are 1 or more digits and nothing else */
|
||||||
|
- int digits = 0;
|
||||||
|
- while (*w && isdigit(*w)) {
|
||||||
|
- digits++;
|
||||||
|
- w++;
|
||||||
|
- }
|
||||||
|
- return (digits && ! *w);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
void arrayline(char *line)
|
||||||
|
{
|
||||||
|
char *w;
|
||||||
|
@@ -419,10 +408,8 @@ void arrayline(char *line)
|
||||||
|
if (is_devname_ignore(w) == true ||
|
||||||
|
strncmp(w, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 ||
|
||||||
|
(w[0] != '/' && w[0] != '<') ||
|
||||||
|
- (strncmp(w, DEV_NUM_PREF, DEV_NUM_PREF_LEN) == 0 &&
|
||||||
|
- is_number(w + DEV_NUM_PREF_LEN)) ||
|
||||||
|
- (strncmp(w, "/dev/md_d", 9) == 0 &&
|
||||||
|
- is_number(w + 9))) {
|
||||||
|
+ is_devname_md_numbered(w) == true ||
|
||||||
|
+ is_devname_md_d_numbered(w) == true) {
|
||||||
|
/* This is acceptable */;
|
||||||
|
if (mis.devname)
|
||||||
|
pr_err("only give one device per ARRAY line: %s and %s\n",
|
||||||
|
diff --git a/lib.c b/lib.c
|
||||||
|
index 65ea51e0..fe5c8d2c 100644
|
||||||
|
--- a/lib.c
|
||||||
|
+++ b/lib.c
|
||||||
|
@@ -570,7 +570,7 @@ void free_line(char *line)
|
||||||
|
*
|
||||||
|
* Return: 0 on success, 1 otherwise.
|
||||||
|
*/
|
||||||
|
-int parse_num(int *dest, char *num)
|
||||||
|
+int parse_num(int *dest, const char *num)
|
||||||
|
{
|
||||||
|
char *c = NULL;
|
||||||
|
long temp;
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index 0932c2d3..83f2cf7f 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -1601,7 +1601,7 @@ 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);
|
||||||
|
-extern int parse_num(int *dest, char *num);
|
||||||
|
+extern int parse_num(int *dest, const char *num);
|
||||||
|
extern int parse_cluster_confirm_arg(char *inp, char **devname, int *slot);
|
||||||
|
extern int check_ext2(int fd, char *name);
|
||||||
|
extern int check_reiser(int fd, char *name);
|
||||||
|
@@ -1651,6 +1651,8 @@ extern int use_udev(void);
|
||||||
|
extern unsigned long GCD(unsigned long a, unsigned long b);
|
||||||
|
extern int conf_name_is_free(char *name);
|
||||||
|
extern bool is_devname_ignore(char *devname);
|
||||||
|
+extern bool is_devname_md_numbered(const char *devname);
|
||||||
|
+extern bool is_devname_md_d_numbered(const char *devname);
|
||||||
|
extern int conf_verify_devnames(struct mddev_ident *array_list);
|
||||||
|
extern int devname_matches(char *name, char *match);
|
||||||
|
extern struct mddev_ident *conf_match(struct supertype *st,
|
||||||
|
diff --git a/util.c b/util.c
|
||||||
|
index d70ca43b..fa378eba 100644
|
||||||
|
--- a/util.c
|
||||||
|
+++ b/util.c
|
||||||
|
@@ -973,6 +973,50 @@ dev_t devnm2devid(char *devnm)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * is_devname_numbered() - helper for numbered devname verification.
|
||||||
|
+ * @devname: path or name to check.
|
||||||
|
+ * @pref: expected devname prefix.
|
||||||
|
+ * @pref_len: prefix len.
|
||||||
|
+ */
|
||||||
|
+static bool is_devname_numbered(const char *devname, const char *pref, const int pref_len)
|
||||||
|
+{
|
||||||
|
+ int val;
|
||||||
|
+
|
||||||
|
+ assert(devname && pref);
|
||||||
|
+
|
||||||
|
+ if (strncmp(devname, pref, pref_len) != 0)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ if (parse_num(&val, devname + pref_len) != 0)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ if (val > 127)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * is_devname_md_numbered() - check if &devname is numbered MD device (md).
|
||||||
|
+ * @devname: path or name to check.
|
||||||
|
+ */
|
||||||
|
+bool is_devname_md_numbered(const char *devname)
|
||||||
|
+{
|
||||||
|
+ return is_devname_numbered(devname, DEV_NUM_PREF, DEV_NUM_PREF_LEN);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * is_devname_md_d_numbered() - check if &devname is secondary numbered MD device (md_d).
|
||||||
|
+ * @devname: path or name to check.
|
||||||
|
+ */
|
||||||
|
+bool is_devname_md_d_numbered(const char *devname)
|
||||||
|
+{
|
||||||
|
+ static const char d_dev[] = DEV_NUM_PREF "_d";
|
||||||
|
+
|
||||||
|
+ return is_devname_numbered(devname, d_dev, sizeof(d_dev) - 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* get_md_name() - Get main dev node of the md device.
|
||||||
|
* @devnm: Md device name or path.
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
187
SOURCES/0125-enable-RAID-for-SATA-under-VMD.patch
Normal file
187
SOURCES/0125-enable-RAID-for-SATA-under-VMD.patch
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
From 75350d87c86001c47076e1f62478079bdc072223 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kevin Friedberg <kev.friedberg@gmail.com>
|
||||||
|
Date: Wed, 15 Feb 2023 23:41:34 -0500
|
||||||
|
Subject: [PATCH 125/125] enable RAID for SATA under VMD
|
||||||
|
|
||||||
|
Detect when a SATA controller has been mapped under Intel Alderlake RST
|
||||||
|
VMD, so that it can use the VMD controller's RAID capabilities. Create
|
||||||
|
new device type SYS_DEV_SATA_VMD and list separate controller to prevent
|
||||||
|
mixing with the NVMe SYS_DEV_VMD devices on the same VMD domain.
|
||||||
|
|
||||||
|
Signed-off-by: Kevin Friedberg <kev.friedberg@gmail.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
platform-intel.c | 21 ++++++++++++++++++---
|
||||||
|
platform-intel.h | 1 +
|
||||||
|
super-intel.c | 28 ++++++++++++++++++----------
|
||||||
|
3 files changed, 37 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/platform-intel.c b/platform-intel.c
|
||||||
|
index 757f0b1b..914164c0 100644
|
||||||
|
--- a/platform-intel.c
|
||||||
|
+++ b/platform-intel.c
|
||||||
|
@@ -64,9 +64,10 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver)
|
||||||
|
|
||||||
|
if (strcmp(driver, "isci") == 0)
|
||||||
|
type = SYS_DEV_SAS;
|
||||||
|
- else if (strcmp(driver, "ahci") == 0)
|
||||||
|
+ else if (strcmp(driver, "ahci") == 0) {
|
||||||
|
+ vmd = find_driver_devices("pci", "vmd");
|
||||||
|
type = SYS_DEV_SATA;
|
||||||
|
- else if (strcmp(driver, "nvme") == 0) {
|
||||||
|
+ } else if (strcmp(driver, "nvme") == 0) {
|
||||||
|
/* if looking for nvme devs, first look for vmd */
|
||||||
|
vmd = find_driver_devices("pci", "vmd");
|
||||||
|
type = SYS_DEV_NVME;
|
||||||
|
@@ -115,6 +116,17 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver)
|
||||||
|
free(rp);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* change sata type if under a vmd controller */
|
||||||
|
+ if (type == SYS_DEV_SATA) {
|
||||||
|
+ struct sys_dev *dev;
|
||||||
|
+ char *rp = realpath(path, NULL);
|
||||||
|
+ for (dev = vmd; dev; dev = dev->next) {
|
||||||
|
+ if ((strncmp(dev->path, rp, strlen(dev->path)) == 0))
|
||||||
|
+ type = SYS_DEV_SATA_VMD;
|
||||||
|
+ }
|
||||||
|
+ free(rp);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* if it's not Intel device or mark as VMD connected - skip it. */
|
||||||
|
if (devpath_to_vendor(path) != 0x8086 || skip == 1)
|
||||||
|
continue;
|
||||||
|
@@ -166,7 +178,8 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver)
|
||||||
|
}
|
||||||
|
closedir(driver_dir);
|
||||||
|
|
||||||
|
- if (vmd) {
|
||||||
|
+ /* nvme vmd needs a list separate from sata vmd */
|
||||||
|
+ if (vmd && type == SYS_DEV_NVME) {
|
||||||
|
if (list)
|
||||||
|
list->next = vmd;
|
||||||
|
else
|
||||||
|
@@ -273,6 +286,7 @@ struct sys_dev *find_intel_devices(void)
|
||||||
|
free_sys_dev(&intel_devices);
|
||||||
|
|
||||||
|
isci = find_driver_devices("pci", "isci");
|
||||||
|
+ /* Searching for AHCI will return list of SATA and SATA VMD controllers */
|
||||||
|
ahci = find_driver_devices("pci", "ahci");
|
||||||
|
/* Searching for NVMe will return list of NVMe and VMD controllers */
|
||||||
|
nvme = find_driver_devices("pci", "nvme");
|
||||||
|
@@ -638,6 +652,7 @@ const struct imsm_orom *find_imsm_efi(struct sys_dev *hba)
|
||||||
|
|
||||||
|
break;
|
||||||
|
case SYS_DEV_VMD:
|
||||||
|
+ case SYS_DEV_SATA_VMD:
|
||||||
|
for (i = 0; i < ARRAY_SIZE(vmd_efivars); i++) {
|
||||||
|
if (!read_efi_variable(&orom, sizeof(orom),
|
||||||
|
vmd_efivars[i], VENDOR_GUID))
|
||||||
|
diff --git a/platform-intel.h b/platform-intel.h
|
||||||
|
index 6238d23f..2c0f4e39 100644
|
||||||
|
--- a/platform-intel.h
|
||||||
|
+++ b/platform-intel.h
|
||||||
|
@@ -196,6 +196,7 @@ enum sys_dev_type {
|
||||||
|
SYS_DEV_SATA,
|
||||||
|
SYS_DEV_NVME,
|
||||||
|
SYS_DEV_VMD,
|
||||||
|
+ SYS_DEV_SATA_VMD,
|
||||||
|
SYS_DEV_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index aaf6659e..ae0f4a8c 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -627,7 +627,8 @@ static const char *_sys_dev_type[] = {
|
||||||
|
[SYS_DEV_SAS] = "SAS",
|
||||||
|
[SYS_DEV_SATA] = "SATA",
|
||||||
|
[SYS_DEV_NVME] = "NVMe",
|
||||||
|
- [SYS_DEV_VMD] = "VMD"
|
||||||
|
+ [SYS_DEV_VMD] = "VMD",
|
||||||
|
+ [SYS_DEV_SATA_VMD] = "SATA VMD"
|
||||||
|
};
|
||||||
|
|
||||||
|
static int no_platform = -1;
|
||||||
|
@@ -2598,6 +2599,8 @@ static void print_found_intel_controllers(struct sys_dev *elem)
|
||||||
|
|
||||||
|
if (elem->type == SYS_DEV_VMD)
|
||||||
|
fprintf(stderr, "VMD domain");
|
||||||
|
+ else if (elem->type == SYS_DEV_SATA_VMD)
|
||||||
|
+ fprintf(stderr, "SATA VMD domain");
|
||||||
|
else
|
||||||
|
fprintf(stderr, "RAID controller");
|
||||||
|
|
||||||
|
@@ -2768,8 +2771,9 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle
|
||||||
|
if (!find_imsm_capability(hba)) {
|
||||||
|
char buf[PATH_MAX];
|
||||||
|
pr_err("imsm capabilities not found for controller: %s (type %s)\n",
|
||||||
|
- hba->type == SYS_DEV_VMD ? vmd_domain_to_controller(hba, buf) : hba->path,
|
||||||
|
- get_sys_dev_type(hba->type));
|
||||||
|
+ hba->type == SYS_DEV_VMD || hba->type == SYS_DEV_SATA_VMD ?
|
||||||
|
+ vmd_domain_to_controller(hba, buf) :
|
||||||
|
+ hba->path, get_sys_dev_type(hba->type));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
result = 0;
|
||||||
|
@@ -2822,11 +2826,12 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle
|
||||||
|
|
||||||
|
printf(" I/O Controller : %s (%s)\n",
|
||||||
|
hba->path, get_sys_dev_type(hba->type));
|
||||||
|
- if (hba->type == SYS_DEV_SATA) {
|
||||||
|
+ if (hba->type == SYS_DEV_SATA || hba->type == SYS_DEV_SATA_VMD) {
|
||||||
|
host_base = ahci_get_port_count(hba->path, &port_count);
|
||||||
|
if (ahci_enumerate_ports(hba->path, port_count, host_base, verbose)) {
|
||||||
|
if (verbose > 0)
|
||||||
|
- pr_err("failed to enumerate ports on SATA controller at %s.\n", hba->pci_id);
|
||||||
|
+ pr_err("failed to enumerate ports on %s controller at %s.\n",
|
||||||
|
+ get_sys_dev_type(hba->type), hba->pci_id);
|
||||||
|
result |= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -2856,7 +2861,8 @@ static int export_detail_platform_imsm(int verbose, char *controller_path)
|
||||||
|
if (!find_imsm_capability(hba) && verbose > 0) {
|
||||||
|
char buf[PATH_MAX];
|
||||||
|
pr_err("IMSM_DETAIL_PLATFORM_ERROR=NO_IMSM_CAPABLE_DEVICE_UNDER_%s\n",
|
||||||
|
- hba->type == SYS_DEV_VMD ? vmd_domain_to_controller(hba, buf) : hba->path);
|
||||||
|
+ hba->type == SYS_DEV_VMD || hba->type == SYS_DEV_SATA_VMD ?
|
||||||
|
+ vmd_domain_to_controller(hba, buf) : hba->path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = 0;
|
||||||
|
@@ -2865,7 +2871,7 @@ static int export_detail_platform_imsm(int verbose, char *controller_path)
|
||||||
|
const struct orom_entry *entry;
|
||||||
|
|
||||||
|
for (entry = orom_entries; entry; entry = entry->next) {
|
||||||
|
- if (entry->type == SYS_DEV_VMD) {
|
||||||
|
+ if (entry->type == SYS_DEV_VMD || entry->type == SYS_DEV_SATA_VMD) {
|
||||||
|
for (hba = list; hba; hba = hba->next)
|
||||||
|
print_imsm_capability_export(&entry->orom);
|
||||||
|
continue;
|
||||||
|
@@ -4782,10 +4788,12 @@ static int find_intel_hba_capability(int fd, struct intel_super *super, char *de
|
||||||
|
" but the container is assigned to Intel(R) %s %s (",
|
||||||
|
devname,
|
||||||
|
get_sys_dev_type(hba_name->type),
|
||||||
|
- hba_name->type == SYS_DEV_VMD ? "domain" : "RAID controller",
|
||||||
|
+ hba_name->type == SYS_DEV_VMD || hba_name->type == SYS_DEV_SATA_VMD ?
|
||||||
|
+ "domain" : "RAID controller",
|
||||||
|
hba_name->pci_id ? : "Err!",
|
||||||
|
get_sys_dev_type(super->hba->type),
|
||||||
|
- hba->type == SYS_DEV_VMD ? "domain" : "RAID controller");
|
||||||
|
+ hba->type == SYS_DEV_VMD || hba_name->type == SYS_DEV_SATA_VMD ?
|
||||||
|
+ "domain" : "RAID controller");
|
||||||
|
|
||||||
|
while (hba) {
|
||||||
|
fprintf(stderr, "%s", hba->pci_id ? : "Err!");
|
||||||
|
@@ -11274,7 +11282,7 @@ static const char *imsm_get_disk_controller_domain(const char *path)
|
||||||
|
hba = find_disk_attached_hba(-1, path);
|
||||||
|
if (hba && hba->type == SYS_DEV_SAS)
|
||||||
|
drv = "isci";
|
||||||
|
- else if (hba && hba->type == SYS_DEV_SATA)
|
||||||
|
+ 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";
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,33 @@
|
|||||||
|
From cf1577bf54afe76b77ecaa62df25901739ca8ae9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Date: Wed, 5 Jul 2023 16:34:56 +0200
|
||||||
|
Subject: [PATCH 126/165] imsm: Fix possible segfault in check_no_platform()
|
||||||
|
|
||||||
|
conf_line() may return NULL, which is not handled and might cause
|
||||||
|
segfault.
|
||||||
|
|
||||||
|
Signed-off-by: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
super-intel.c | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index ae0f4a8c..4ef33d31 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -650,6 +650,11 @@ static int check_no_platform(void)
|
||||||
|
char *l = conf_line(fp);
|
||||||
|
char *w = l;
|
||||||
|
|
||||||
|
+ if (l == NULL) {
|
||||||
|
+ fclose(fp);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
do {
|
||||||
|
if (strcmp(w, search) == 0)
|
||||||
|
no_platform = 1;
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,105 @@
|
|||||||
|
From 9bc426fa1f236b8cad518431574a54fc60718739 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Mon, 29 May 2023 15:52:33 +0200
|
||||||
|
Subject: [PATCH 127/165] imsm: move sum_extents calculations to
|
||||||
|
merge_extents()
|
||||||
|
|
||||||
|
This logic is only used by merge_extents() code, there is no need to pass
|
||||||
|
it as parameter. Move it up. Add proper description.
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
super-intel.c | 37 +++++++++++++++++++------------------
|
||||||
|
1 file changed, 19 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index 4ef33d31..26b20313 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -6882,21 +6882,31 @@ static unsigned long long find_size(struct extent *e, int *idx, int num_extents)
|
||||||
|
return end - base_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static unsigned long long merge_extents(struct intel_super *super, int sum_extents)
|
||||||
|
+/** merge_extents() - analyze extents and get max common free size.
|
||||||
|
+ * @super: Intel metadata, not NULL.
|
||||||
|
+ *
|
||||||
|
+ * Build a composite disk with all known extents and generate a new maxsize
|
||||||
|
+ * given the "all disks in an array must share a common start offset"
|
||||||
|
+ * constraint.
|
||||||
|
+ *
|
||||||
|
+ * Return: Max free space or 0 on failure.
|
||||||
|
+ */
|
||||||
|
+static unsigned long long merge_extents(struct intel_super *super)
|
||||||
|
{
|
||||||
|
- /* build a composite disk with all known extents and generate a new
|
||||||
|
- * 'maxsize' given the "all disks in an array must share a common start
|
||||||
|
- * offset" constraint
|
||||||
|
- */
|
||||||
|
- struct extent *e = xcalloc(sum_extents, sizeof(*e));
|
||||||
|
+ struct extent *e;
|
||||||
|
struct dl *dl;
|
||||||
|
int i, j;
|
||||||
|
- int start_extent;
|
||||||
|
+ int start_extent, sum_extents = 0;
|
||||||
|
unsigned long long pos;
|
||||||
|
unsigned long long start = 0;
|
||||||
|
unsigned long long maxsize;
|
||||||
|
unsigned long reserve;
|
||||||
|
|
||||||
|
+ for (dl = super->disks; dl; dl = dl->next)
|
||||||
|
+ if (dl->e)
|
||||||
|
+ sum_extents += dl->extent_cnt;
|
||||||
|
+ e = xcalloc(sum_extents, sizeof(struct extent));
|
||||||
|
+
|
||||||
|
/* coalesce and sort all extents. also, check to see if we need to
|
||||||
|
* reserve space between member arrays
|
||||||
|
*/
|
||||||
|
@@ -7555,13 +7565,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* count total number of extents for merge */
|
||||||
|
- i = 0;
|
||||||
|
- for (dl = super->disks; dl; dl = dl->next)
|
||||||
|
- if (dl->e)
|
||||||
|
- i += dl->extent_cnt;
|
||||||
|
-
|
||||||
|
- maxsize = merge_extents(super, i);
|
||||||
|
+ maxsize = merge_extents(super);
|
||||||
|
|
||||||
|
if (mpb->num_raid_devs > 0 && size && size != maxsize)
|
||||||
|
pr_err("attempting to create a second volume with size less then remaining space.\n");
|
||||||
|
@@ -7615,7 +7619,6 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super,
|
||||||
|
struct imsm_super *mpb = super->anchor;
|
||||||
|
struct dl *dl;
|
||||||
|
int i;
|
||||||
|
- int extent_cnt;
|
||||||
|
struct extent *e;
|
||||||
|
unsigned long long maxsize;
|
||||||
|
unsigned long long minsize;
|
||||||
|
@@ -7624,7 +7627,6 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super,
|
||||||
|
|
||||||
|
/* find the largest common start free region of the possible disks */
|
||||||
|
used = 0;
|
||||||
|
- extent_cnt = 0;
|
||||||
|
cnt = 0;
|
||||||
|
for (dl = super->disks; dl; dl = dl->next) {
|
||||||
|
dl->raiddisk = -1;
|
||||||
|
@@ -7645,11 +7647,10 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super,
|
||||||
|
;
|
||||||
|
dl->e = e;
|
||||||
|
dl->extent_cnt = i;
|
||||||
|
- extent_cnt += i;
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
- maxsize = merge_extents(super, extent_cnt);
|
||||||
|
+ maxsize = merge_extents(super);
|
||||||
|
minsize = size;
|
||||||
|
if (size == 0)
|
||||||
|
/* chunk is in K */
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
72
SOURCES/0128-imsm-imsm_get_free_size-refactor.patch
Normal file
72
SOURCES/0128-imsm-imsm_get_free_size-refactor.patch
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
From 5f027b9357c011ca0421400e258a777d97f18d17 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Mon, 29 May 2023 15:52:34 +0200
|
||||||
|
Subject: [PATCH 128/165] imsm: imsm_get_free_size() refactor.
|
||||||
|
|
||||||
|
Move minsize calculations up. Add error message if free size is too small.
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
super-intel.c | 27 ++++++++++++++-------------
|
||||||
|
1 file changed, 14 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index 26b20313..16a30ba7 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -7600,7 +7600,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
|
||||||
|
* @super: &intel_super pointer, not NULL.
|
||||||
|
* @raiddisks: number of raid disks.
|
||||||
|
* @size: requested size, could be 0 (means max size).
|
||||||
|
- * @chunk: requested chunk.
|
||||||
|
+ * @chunk: requested chunk size in KiB.
|
||||||
|
* @freesize: pointer for returned size value.
|
||||||
|
*
|
||||||
|
* Return: &IMSM_STATUS_OK or &IMSM_STATUS_ERROR.
|
||||||
|
@@ -7620,14 +7620,15 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super,
|
||||||
|
struct dl *dl;
|
||||||
|
int i;
|
||||||
|
struct extent *e;
|
||||||
|
+ int cnt = 0;
|
||||||
|
+ int used = 0;
|
||||||
|
unsigned long long maxsize;
|
||||||
|
- unsigned long long minsize;
|
||||||
|
- int cnt;
|
||||||
|
- int used;
|
||||||
|
+ unsigned long long minsize = size;
|
||||||
|
+
|
||||||
|
+ if (minsize == 0)
|
||||||
|
+ minsize = chunk * 2;
|
||||||
|
|
||||||
|
/* find the largest common start free region of the possible disks */
|
||||||
|
- used = 0;
|
||||||
|
- cnt = 0;
|
||||||
|
for (dl = super->disks; dl; dl = dl->next) {
|
||||||
|
dl->raiddisk = -1;
|
||||||
|
|
||||||
|
@@ -7651,14 +7652,14 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super,
|
||||||
|
}
|
||||||
|
|
||||||
|
maxsize = merge_extents(super);
|
||||||
|
- minsize = size;
|
||||||
|
- if (size == 0)
|
||||||
|
- /* chunk is in K */
|
||||||
|
- minsize = chunk * 2;
|
||||||
|
+ if (maxsize < minsize) {
|
||||||
|
+ pr_err("imsm: Free space is %llu but must be equal or larger than %llu.\n",
|
||||||
|
+ maxsize, minsize);
|
||||||
|
+ return IMSM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (cnt < raiddisks || (super->orom && used && used != raiddisks) ||
|
||||||
|
- maxsize < minsize || maxsize == 0) {
|
||||||
|
- pr_err("not enough devices with space to create array.\n");
|
||||||
|
+ if (cnt < raiddisks || (super->orom && used && used != raiddisks)) {
|
||||||
|
+ pr_err("imsm: Not enough devices with space to create array.\n");
|
||||||
|
return IMSM_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
68
SOURCES/0129-imsm-introduce-round_member_size_to_mb.patch
Normal file
68
SOURCES/0129-imsm-introduce-round_member_size_to_mb.patch
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
From 78c8028b331c8e281554d43fde4d46e9cb4a227e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Mon, 29 May 2023 15:52:35 +0200
|
||||||
|
Subject: [PATCH 129/165] imsm: introduce round_member_size_to_mb()
|
||||||
|
|
||||||
|
Extract rounding logic to separate function.
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
super-intel.c | 31 +++++++++++++++++++++----------
|
||||||
|
1 file changed, 21 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index 16a30ba7..36171107 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -1644,17 +1644,29 @@ static int is_journal(struct imsm_disk *disk)
|
||||||
|
return (disk->status & JOURNAL_DISK) == JOURNAL_DISK;
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* round array size down to closest MB and ensure it splits evenly
|
||||||
|
- * between members
|
||||||
|
+/**
|
||||||
|
+ * round_member_size_to_mb()- Round given size to closest MiB.
|
||||||
|
+ * @size: size to round in sectors.
|
||||||
|
*/
|
||||||
|
-static unsigned long long round_size_to_mb(unsigned long long size, unsigned int
|
||||||
|
- disk_count)
|
||||||
|
+static inline unsigned long long round_member_size_to_mb(unsigned long long size)
|
||||||
|
{
|
||||||
|
- size /= disk_count;
|
||||||
|
- size = (size >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
|
||||||
|
- size *= disk_count;
|
||||||
|
+ return (size >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
|
||||||
|
+}
|
||||||
|
|
||||||
|
- return size;
|
||||||
|
+/**
|
||||||
|
+ * round_size_to_mb()- Round given size.
|
||||||
|
+ * @array_size: size to round in sectors.
|
||||||
|
+ * @disk_count: count of data members.
|
||||||
|
+ *
|
||||||
|
+ * Get size per each data member and round it to closest MiB to ensure that data
|
||||||
|
+ * splits evenly between members.
|
||||||
|
+ *
|
||||||
|
+ * Return: Array size, rounded down.
|
||||||
|
+ */
|
||||||
|
+static inline unsigned long long round_size_to_mb(unsigned long long array_size,
|
||||||
|
+ unsigned int disk_count)
|
||||||
|
+{
|
||||||
|
+ return round_member_size_to_mb(array_size / disk_count) * disk_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int able_to_resync(int raid_level, int missing_disks)
|
||||||
|
@@ -11810,8 +11822,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||||
|
} else {
|
||||||
|
/* round size due to metadata compatibility
|
||||||
|
*/
|
||||||
|
- geo->size = (geo->size >> SECT_PER_MB_SHIFT)
|
||||||
|
- << SECT_PER_MB_SHIFT;
|
||||||
|
+ geo->size = round_member_size_to_mb(geo->size);
|
||||||
|
dprintf("Prepare update for size change to %llu\n",
|
||||||
|
geo->size );
|
||||||
|
if (current_size >= geo->size) {
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,238 @@
|
|||||||
|
From cbaa7904a175628a294ed54b4de6c52afa4f830d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Mon, 29 May 2023 15:52:36 +0200
|
||||||
|
Subject: [PATCH 130/165] imsm: move expand verification code into new function
|
||||||
|
|
||||||
|
The code here is too complex. Move it to separate function and
|
||||||
|
simplify it. Add more error messages.
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
super-intel.c | 187 +++++++++++++++++++++++++++-----------------------
|
||||||
|
1 file changed, 101 insertions(+), 86 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index 36171107..5bd70356 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -11643,6 +11643,102 @@ static void imsm_update_metadata_locally(struct supertype *st,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * imsm_analyze_expand() - check expand properties and calculate new size.
|
||||||
|
+ * @st: imsm supertype.
|
||||||
|
+ * @geo: new geometry params.
|
||||||
|
+ * @array: array info.
|
||||||
|
+ * @direction: reshape direction.
|
||||||
|
+ *
|
||||||
|
+ * Obtain free space after the &array and verify if expand to requested size is
|
||||||
|
+ * possible. If geo->size is set to %MAX_SIZE, assume that max free size is
|
||||||
|
+ * requested.
|
||||||
|
+ *
|
||||||
|
+ * Return:
|
||||||
|
+ * On success %IMSM_STATUS_OK is returned, geo->size and geo->raid_disks are
|
||||||
|
+ * updated.
|
||||||
|
+ * On error, %IMSM_STATUS_ERROR is returned.
|
||||||
|
+ */
|
||||||
|
+static imsm_status_t imsm_analyze_expand(struct supertype *st,
|
||||||
|
+ struct geo_params *geo,
|
||||||
|
+ struct mdinfo *array,
|
||||||
|
+ int direction)
|
||||||
|
+{
|
||||||
|
+ struct intel_super *super = st->sb;
|
||||||
|
+ struct imsm_dev *dev = get_imsm_dev(super, super->current_vol);
|
||||||
|
+ struct imsm_map *map = get_imsm_map(dev, MAP_0);
|
||||||
|
+ int data_disks = imsm_num_data_members(map);
|
||||||
|
+
|
||||||
|
+ unsigned long long current_size;
|
||||||
|
+ unsigned long long free_size;
|
||||||
|
+ unsigned long long new_size;
|
||||||
|
+ unsigned long long max_size;
|
||||||
|
+
|
||||||
|
+ const int chunk_kib = geo->chunksize / 1024;
|
||||||
|
+ imsm_status_t rv;
|
||||||
|
+
|
||||||
|
+ if (direction == ROLLBACK_METADATA_CHANGES) {
|
||||||
|
+ /**
|
||||||
|
+ * Accept size for rollback only.
|
||||||
|
+ */
|
||||||
|
+ new_size = geo->size * 2;
|
||||||
|
+ goto success;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (super->current_vol + 1 != super->anchor->num_raid_devs) {
|
||||||
|
+ pr_err("imsm: The last volume in container can be expanded only (%i/%s).\n",
|
||||||
|
+ super->current_vol, st->devnm);
|
||||||
|
+ return IMSM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (data_disks == 0) {
|
||||||
|
+ pr_err("imsm: Cannot retrieve data disks.\n");
|
||||||
|
+ return IMSM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+ current_size = array->custom_array_size / data_disks;
|
||||||
|
+
|
||||||
|
+ rv = imsm_get_free_size(super, dev->vol.map->num_members, 0, chunk_kib, &free_size);
|
||||||
|
+ if (rv != IMSM_STATUS_OK) {
|
||||||
|
+ pr_err("imsm: Cannot find free space for expand.\n");
|
||||||
|
+ return IMSM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+ max_size = round_member_size_to_mb(free_size + current_size);
|
||||||
|
+
|
||||||
|
+ if (geo->size == MAX_SIZE)
|
||||||
|
+ new_size = max_size;
|
||||||
|
+ else
|
||||||
|
+ new_size = round_member_size_to_mb(geo->size * 2);
|
||||||
|
+
|
||||||
|
+ if (new_size == 0) {
|
||||||
|
+ pr_err("imsm: Rounded requested size is 0.\n");
|
||||||
|
+ return IMSM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (new_size > max_size) {
|
||||||
|
+ pr_err("imsm: Rounded requested size (%llu) is larger than free space available (%llu).\n",
|
||||||
|
+ new_size, max_size);
|
||||||
|
+ return IMSM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (new_size == current_size) {
|
||||||
|
+ pr_err("imsm: Rounded requested size (%llu) is same as current size (%llu).\n",
|
||||||
|
+ new_size, current_size);
|
||||||
|
+ return IMSM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (new_size < current_size) {
|
||||||
|
+ pr_err("imsm: Size reduction is not supported, rounded requested size (%llu) is smaller than current (%llu).\n",
|
||||||
|
+ new_size, current_size);
|
||||||
|
+ return IMSM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+success:
|
||||||
|
+ dprintf("imsm: New size per member is %llu.\n", new_size);
|
||||||
|
+ geo->size = data_disks * new_size;
|
||||||
|
+ geo->raid_disks = dev->vol.map->num_members;
|
||||||
|
+ return IMSM_STATUS_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/***************************************************************************
|
||||||
|
* Function: imsm_analyze_change
|
||||||
|
* Description: Function analyze change for single volume
|
||||||
|
@@ -11663,13 +11759,6 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||||
|
int devNumChange = 0;
|
||||||
|
/* imsm compatible layout value for array geometry verification */
|
||||||
|
int imsm_layout = -1;
|
||||||
|
- int data_disks;
|
||||||
|
- struct imsm_dev *dev;
|
||||||
|
- struct imsm_map *map;
|
||||||
|
- struct intel_super *super;
|
||||||
|
- unsigned long long current_size;
|
||||||
|
- unsigned long long free_size;
|
||||||
|
- unsigned long long max_size;
|
||||||
|
imsm_status_t rv;
|
||||||
|
|
||||||
|
getinfo_super_imsm_volume(st, &info, NULL);
|
||||||
|
@@ -11752,94 +11841,20 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||||
|
geo->chunksize = info.array.chunk_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
- chunk = geo->chunksize / 1024;
|
||||||
|
-
|
||||||
|
- super = st->sb;
|
||||||
|
- dev = get_imsm_dev(super, super->current_vol);
|
||||||
|
- map = get_imsm_map(dev, MAP_0);
|
||||||
|
- data_disks = imsm_num_data_members(map);
|
||||||
|
- /* compute current size per disk member
|
||||||
|
- */
|
||||||
|
- current_size = info.custom_array_size / data_disks;
|
||||||
|
-
|
||||||
|
- if (geo->size > 0 && geo->size != MAX_SIZE) {
|
||||||
|
- /* align component size
|
||||||
|
- */
|
||||||
|
- geo->size = imsm_component_size_alignment_check(
|
||||||
|
- get_imsm_raid_level(dev->vol.map),
|
||||||
|
- chunk * 1024, super->sector_size,
|
||||||
|
- geo->size * 2);
|
||||||
|
- if (geo->size == 0) {
|
||||||
|
- pr_err("Error. Size expansion is supported only (current size is %llu, requested size /rounded/ is 0).\n",
|
||||||
|
- current_size);
|
||||||
|
- goto analyse_change_exit;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (current_size != geo->size && geo->size > 0) {
|
||||||
|
+ if (geo->size > 0) {
|
||||||
|
if (change != -1) {
|
||||||
|
pr_err("Error. Size change should be the only one at a time.\n");
|
||||||
|
change = -1;
|
||||||
|
goto analyse_change_exit;
|
||||||
|
}
|
||||||
|
- if ((super->current_vol + 1) != super->anchor->num_raid_devs) {
|
||||||
|
- pr_err("Error. The last volume in container can be expanded only (%i/%s).\n",
|
||||||
|
- super->current_vol, st->devnm);
|
||||||
|
- goto analyse_change_exit;
|
||||||
|
- }
|
||||||
|
- /* check the maximum available size
|
||||||
|
- */
|
||||||
|
- rv = imsm_get_free_size(super, dev->vol.map->num_members,
|
||||||
|
- 0, chunk, &free_size);
|
||||||
|
|
||||||
|
+ rv = imsm_analyze_expand(st, geo, &info, direction);
|
||||||
|
if (rv != IMSM_STATUS_OK)
|
||||||
|
- /* Cannot find maximum available space
|
||||||
|
- */
|
||||||
|
- max_size = 0;
|
||||||
|
- else {
|
||||||
|
- max_size = free_size + current_size;
|
||||||
|
- /* align component size
|
||||||
|
- */
|
||||||
|
- max_size = imsm_component_size_alignment_check(
|
||||||
|
- get_imsm_raid_level(dev->vol.map),
|
||||||
|
- chunk * 1024, super->sector_size,
|
||||||
|
- max_size);
|
||||||
|
- }
|
||||||
|
- if (geo->size == MAX_SIZE) {
|
||||||
|
- /* requested size change to the maximum available size
|
||||||
|
- */
|
||||||
|
- if (max_size == 0) {
|
||||||
|
- pr_err("Error. Cannot find maximum available space.\n");
|
||||||
|
- change = -1;
|
||||||
|
- goto analyse_change_exit;
|
||||||
|
- } else
|
||||||
|
- geo->size = max_size;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (direction == ROLLBACK_METADATA_CHANGES) {
|
||||||
|
- /* accept size for rollback only
|
||||||
|
- */
|
||||||
|
- } else {
|
||||||
|
- /* round size due to metadata compatibility
|
||||||
|
- */
|
||||||
|
- geo->size = round_member_size_to_mb(geo->size);
|
||||||
|
- dprintf("Prepare update for size change to %llu\n",
|
||||||
|
- geo->size );
|
||||||
|
- if (current_size >= geo->size) {
|
||||||
|
- pr_err("Error. Size expansion is supported only (current size is %llu, requested size /rounded/ is %llu).\n",
|
||||||
|
- current_size, geo->size);
|
||||||
|
- goto analyse_change_exit;
|
||||||
|
- }
|
||||||
|
- if (max_size && geo->size > max_size) {
|
||||||
|
- pr_err("Error. Requested size is larger than maximum available size (maximum available size is %llu, requested size /rounded/ is %llu).\n",
|
||||||
|
- max_size, geo->size);
|
||||||
|
- goto analyse_change_exit;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- geo->size *= data_disks;
|
||||||
|
- geo->raid_disks = dev->vol.map->num_members;
|
||||||
|
+ goto analyse_change_exit;
|
||||||
|
change = CH_ARRAY_SIZE;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ chunk = geo->chunksize / 1024;
|
||||||
|
if (!validate_geometry_imsm(st,
|
||||||
|
geo->level,
|
||||||
|
imsm_layout,
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,214 @@
|
|||||||
|
From aa19fdd45b2ba474f6a51a6d4b8f3c44ef19dafd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Mon, 29 May 2023 15:52:37 +0200
|
||||||
|
Subject: [PATCH 131/165] imsm: return free space after volume for expand
|
||||||
|
|
||||||
|
merge_extends() routine searches for the biggest free space. For expand,
|
||||||
|
it works only in standard cases where the last volume is expanded and
|
||||||
|
the free space is determined after the last volume.
|
||||||
|
Add volume index to extent struct and use that do determine size after
|
||||||
|
super->current_vol during expand.
|
||||||
|
|
||||||
|
Limitation to last volume is no longer needed. It unblocks scenarios
|
||||||
|
where kill-subarray is used to remove first volume and later it is
|
||||||
|
recreated (now it is the second volume, even if it is placed before
|
||||||
|
existing one).
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
super-intel.c | 71 +++++++++++++++++++++++++++------------------------
|
||||||
|
1 file changed, 37 insertions(+), 34 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index 5bd70356..e249d925 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -499,8 +499,15 @@ struct intel_disk {
|
||||||
|
struct intel_disk *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * struct extent - reserved space details.
|
||||||
|
+ * @start: start offset.
|
||||||
|
+ * @size: size of reservation, set to 0 for metadata reservation.
|
||||||
|
+ * @vol: index of the volume, meaningful if &size is set.
|
||||||
|
+ */
|
||||||
|
struct extent {
|
||||||
|
unsigned long long start, size;
|
||||||
|
+ int vol;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* definitions of reshape process types */
|
||||||
|
@@ -1539,9 +1546,10 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl,
|
||||||
|
int get_minimal_reservation)
|
||||||
|
{
|
||||||
|
/* find a list of used extents on the given physical device */
|
||||||
|
- struct extent *rv, *e;
|
||||||
|
- int i;
|
||||||
|
int memberships = count_memberships(dl, super);
|
||||||
|
+ struct extent *rv = xcalloc(memberships + 1, sizeof(struct extent));
|
||||||
|
+ struct extent *e = rv;
|
||||||
|
+ int i;
|
||||||
|
__u32 reservation;
|
||||||
|
|
||||||
|
/* trim the reserved area for spares, so they can join any array
|
||||||
|
@@ -1553,9 +1561,6 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl,
|
||||||
|
else
|
||||||
|
reservation = MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS;
|
||||||
|
|
||||||
|
- rv = xcalloc(sizeof(struct extent), (memberships + 1));
|
||||||
|
- e = rv;
|
||||||
|
-
|
||||||
|
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);
|
||||||
|
@@ -1563,6 +1568,7 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl,
|
||||||
|
if (get_imsm_disk_slot(map, dl->index) >= 0) {
|
||||||
|
e->start = pba_of_lba0(map);
|
||||||
|
e->size = per_dev_array_size(map);
|
||||||
|
+ e->vol = i;
|
||||||
|
e++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -6894,24 +6900,26 @@ static unsigned long long find_size(struct extent *e, int *idx, int num_extents)
|
||||||
|
return end - base_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
-/** merge_extents() - analyze extents and get max common free size.
|
||||||
|
+/** merge_extents() - analyze extents and get free size.
|
||||||
|
* @super: Intel metadata, not NULL.
|
||||||
|
+ * @expanding: if set, we are expanding &super->current_vol.
|
||||||
|
*
|
||||||
|
- * Build a composite disk with all known extents and generate a new maxsize
|
||||||
|
- * given the "all disks in an array must share a common start offset"
|
||||||
|
- * constraint.
|
||||||
|
+ * Build a composite disk with all known extents and generate a size given the
|
||||||
|
+ * "all disks in an array must share a common start offset" constraint.
|
||||||
|
+ * If a volume is expanded, then return free space after the volume.
|
||||||
|
*
|
||||||
|
- * Return: Max free space or 0 on failure.
|
||||||
|
+ * Return: Free space or 0 on failure.
|
||||||
|
*/
|
||||||
|
-static unsigned long long merge_extents(struct intel_super *super)
|
||||||
|
+static unsigned long long merge_extents(struct intel_super *super, const bool expanding)
|
||||||
|
{
|
||||||
|
struct extent *e;
|
||||||
|
struct dl *dl;
|
||||||
|
- int i, j;
|
||||||
|
- int start_extent, sum_extents = 0;
|
||||||
|
- unsigned long long pos;
|
||||||
|
+ int i, j, pos_vol_idx = -1;
|
||||||
|
+ int extent_idx = 0;
|
||||||
|
+ int sum_extents = 0;
|
||||||
|
+ unsigned long long pos = 0;
|
||||||
|
unsigned long long start = 0;
|
||||||
|
- unsigned long long maxsize;
|
||||||
|
+ unsigned long long maxsize = 0;
|
||||||
|
unsigned long reserve;
|
||||||
|
|
||||||
|
for (dl = super->disks; dl; dl = dl->next)
|
||||||
|
@@ -6936,26 +6944,26 @@ static unsigned long long merge_extents(struct intel_super *super)
|
||||||
|
j = 0;
|
||||||
|
while (i < sum_extents) {
|
||||||
|
e[j].start = e[i].start;
|
||||||
|
+ e[j].vol = e[i].vol;
|
||||||
|
e[j].size = find_size(e, &i, sum_extents);
|
||||||
|
j++;
|
||||||
|
if (e[j-1].size == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- pos = 0;
|
||||||
|
- maxsize = 0;
|
||||||
|
- start_extent = 0;
|
||||||
|
i = 0;
|
||||||
|
do {
|
||||||
|
- unsigned long long esize;
|
||||||
|
+ unsigned long long esize = e[i].start - pos;
|
||||||
|
|
||||||
|
- esize = e[i].start - pos;
|
||||||
|
- if (esize >= maxsize) {
|
||||||
|
+ if (expanding ? pos_vol_idx == super->current_vol : esize >= maxsize) {
|
||||||
|
maxsize = esize;
|
||||||
|
start = pos;
|
||||||
|
- start_extent = i;
|
||||||
|
+ extent_idx = i;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
pos = e[i].start + e[i].size;
|
||||||
|
+ pos_vol_idx = e[i].vol;
|
||||||
|
+
|
||||||
|
i++;
|
||||||
|
} while (e[i-1].size);
|
||||||
|
free(e);
|
||||||
|
@@ -6966,7 +6974,7 @@ static unsigned long long merge_extents(struct intel_super *super)
|
||||||
|
/* FIXME assumes volume at offset 0 is the first volume in a
|
||||||
|
* container
|
||||||
|
*/
|
||||||
|
- if (start_extent > 0)
|
||||||
|
+ if (extent_idx > 0)
|
||||||
|
reserve = IMSM_RESERVED_SECTORS; /* gap between raid regions */
|
||||||
|
else
|
||||||
|
reserve = 0;
|
||||||
|
@@ -7577,7 +7585,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- maxsize = merge_extents(super);
|
||||||
|
+ maxsize = merge_extents(super, false);
|
||||||
|
|
||||||
|
if (mpb->num_raid_devs > 0 && size && size != maxsize)
|
||||||
|
pr_err("attempting to create a second volume with size less then remaining space.\n");
|
||||||
|
@@ -7626,7 +7634,8 @@ 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)
|
||||||
|
+ unsigned long long *freesize,
|
||||||
|
+ bool expanding)
|
||||||
|
{
|
||||||
|
struct imsm_super *mpb = super->anchor;
|
||||||
|
struct dl *dl;
|
||||||
|
@@ -7663,7 +7672,7 @@ static imsm_status_t imsm_get_free_size(struct intel_super *super,
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
- maxsize = merge_extents(super);
|
||||||
|
+ maxsize = merge_extents(super, expanding);
|
||||||
|
if (maxsize < minsize) {
|
||||||
|
pr_err("imsm: Free space is %llu but must be equal or larger than %llu.\n",
|
||||||
|
maxsize, minsize);
|
||||||
|
@@ -7721,7 +7730,7 @@ static imsm_status_t autolayout_imsm(struct intel_super *super,
|
||||||
|
int vol_cnt = super->anchor->num_raid_devs;
|
||||||
|
imsm_status_t rv;
|
||||||
|
|
||||||
|
- rv = imsm_get_free_size(super, raiddisks, size, chunk, freesize);
|
||||||
|
+ rv = imsm_get_free_size(super, raiddisks, size, chunk, freesize, false);
|
||||||
|
if (rv != IMSM_STATUS_OK)
|
||||||
|
return IMSM_STATUS_ERROR;
|
||||||
|
|
||||||
|
@@ -11685,19 +11694,13 @@ static imsm_status_t imsm_analyze_expand(struct supertype *st,
|
||||||
|
goto success;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (super->current_vol + 1 != super->anchor->num_raid_devs) {
|
||||||
|
- pr_err("imsm: The last volume in container can be expanded only (%i/%s).\n",
|
||||||
|
- super->current_vol, st->devnm);
|
||||||
|
- return IMSM_STATUS_ERROR;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
if (data_disks == 0) {
|
||||||
|
pr_err("imsm: Cannot retrieve data disks.\n");
|
||||||
|
return IMSM_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
current_size = array->custom_array_size / data_disks;
|
||||||
|
|
||||||
|
- rv = imsm_get_free_size(super, dev->vol.map->num_members, 0, chunk_kib, &free_size);
|
||||||
|
+ rv = imsm_get_free_size(super, dev->vol.map->num_members, 0, chunk_kib, &free_size, true);
|
||||||
|
if (rv != IMSM_STATUS_OK) {
|
||||||
|
pr_err("imsm: Cannot find free space for expand.\n");
|
||||||
|
return IMSM_STATUS_ERROR;
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
113
SOURCES/0132-imsm-fix-free-space-calculations.patch
Normal file
113
SOURCES/0132-imsm-fix-free-space-calculations.patch
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
From 1dea84ae38288fbefa04d9fda2b3f36c21a9e1bd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Mon, 29 May 2023 15:52:38 +0200
|
||||||
|
Subject: [PATCH 132/165] imsm: fix free space calculations
|
||||||
|
|
||||||
|
Between two volumes or between last volume and metadata at least
|
||||||
|
IMSM_RESERVED_SECTORS gap must exist. Currently the gap can be doubled
|
||||||
|
because metadata reservation contains IMSM_RESERVED_SECTORS too.
|
||||||
|
|
||||||
|
Divide reserve variable into pre_reservation and post_reservation to be
|
||||||
|
more flexible and decide separately if each reservation is needed.
|
||||||
|
|
||||||
|
Pre_reservation is needed only when a volume is created and it is not a
|
||||||
|
real first volume in a container (we can check that by extent_idx).
|
||||||
|
This type of reservation is not needed for expand.
|
||||||
|
|
||||||
|
Post_reservation is not needed only if real last volume is created or
|
||||||
|
expanded because reservation is done with the metadata.
|
||||||
|
|
||||||
|
The volume index in metadata cannot be trusted, because the real volume
|
||||||
|
order can be reversed. It is safer to use extent table, it is sorted by
|
||||||
|
start position.
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
super-intel.c | 50 ++++++++++++++++++++++++++++++--------------------
|
||||||
|
1 file changed, 30 insertions(+), 20 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index e249d925..824c1356 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -6919,8 +6919,11 @@ static unsigned long long merge_extents(struct intel_super *super, const bool ex
|
||||||
|
int sum_extents = 0;
|
||||||
|
unsigned long long pos = 0;
|
||||||
|
unsigned long long start = 0;
|
||||||
|
- unsigned long long maxsize = 0;
|
||||||
|
- unsigned long reserve;
|
||||||
|
+ unsigned long long free_size = 0;
|
||||||
|
+
|
||||||
|
+ unsigned long pre_reservation = 0;
|
||||||
|
+ unsigned long post_reservation = IMSM_RESERVED_SECTORS;
|
||||||
|
+ unsigned long reservation_size;
|
||||||
|
|
||||||
|
for (dl = super->disks; dl; dl = dl->next)
|
||||||
|
if (dl->e)
|
||||||
|
@@ -6955,8 +6958,8 @@ static unsigned long long merge_extents(struct intel_super *super, const bool ex
|
||||||
|
do {
|
||||||
|
unsigned long long esize = e[i].start - pos;
|
||||||
|
|
||||||
|
- if (expanding ? pos_vol_idx == super->current_vol : esize >= maxsize) {
|
||||||
|
- maxsize = esize;
|
||||||
|
+ if (expanding ? pos_vol_idx == super->current_vol : esize >= free_size) {
|
||||||
|
+ free_size = esize;
|
||||||
|
start = pos;
|
||||||
|
extent_idx = i;
|
||||||
|
}
|
||||||
|
@@ -6966,28 +6969,35 @@ static unsigned long long merge_extents(struct intel_super *super, const bool ex
|
||||||
|
|
||||||
|
i++;
|
||||||
|
} while (e[i-1].size);
|
||||||
|
- free(e);
|
||||||
|
|
||||||
|
- if (maxsize == 0)
|
||||||
|
+ if (free_size == 0) {
|
||||||
|
+ dprintf("imsm: Cannot find free size.\n");
|
||||||
|
+ free(e);
|
||||||
|
return 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- /* FIXME assumes volume at offset 0 is the first volume in a
|
||||||
|
- * container
|
||||||
|
- */
|
||||||
|
- if (extent_idx > 0)
|
||||||
|
- reserve = IMSM_RESERVED_SECTORS; /* gap between raid regions */
|
||||||
|
- else
|
||||||
|
- reserve = 0;
|
||||||
|
+ if (!expanding && extent_idx != 0)
|
||||||
|
+ /*
|
||||||
|
+ * Not a real first volume in a container is created, pre_reservation is needed.
|
||||||
|
+ */
|
||||||
|
+ pre_reservation = IMSM_RESERVED_SECTORS;
|
||||||
|
|
||||||
|
- if (maxsize < reserve)
|
||||||
|
- return 0;
|
||||||
|
+ if (e[extent_idx].size == 0)
|
||||||
|
+ /*
|
||||||
|
+ * extent_idx points to the metadata, post_reservation is allready done.
|
||||||
|
+ */
|
||||||
|
+ post_reservation = 0;
|
||||||
|
+ free(e);
|
||||||
|
|
||||||
|
- super->create_offset = ~((unsigned long long) 0);
|
||||||
|
- if (start + reserve > super->create_offset)
|
||||||
|
- return 0; /* start overflows create_offset */
|
||||||
|
- super->create_offset = start + reserve;
|
||||||
|
+ reservation_size = pre_reservation + post_reservation;
|
||||||
|
+
|
||||||
|
+ if (free_size < reservation_size) {
|
||||||
|
+ dprintf("imsm: Reservation size is greater than free space.\n");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- return maxsize - reserve;
|
||||||
|
+ super->create_offset = start + pre_reservation;
|
||||||
|
+ return free_size - reservation_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int is_raid_level_supported(const struct imsm_orom *orom, int level, int raiddisks)
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
124
SOURCES/0133-Add-secure-gethostname-wrapper.patch
Normal file
124
SOURCES/0133-Add-secure-gethostname-wrapper.patch
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
From 21e622f214a38c048c5689158bc6314a91a46e40 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Blazej Kucman <blazej.kucman@intel.com>
|
||||||
|
Date: Fri, 16 Jun 2023 21:45:55 +0200
|
||||||
|
Subject: [PATCH 133/165] Add secure gethostname() wrapper
|
||||||
|
|
||||||
|
gethostname() func does not ensure null-terminated string
|
||||||
|
if hostname is longer than buffer length.
|
||||||
|
For security, a function s_gethostname() has been added
|
||||||
|
to ensure that "\0" is added to the end of the buffer.
|
||||||
|
Previously this had to be handled in each place
|
||||||
|
of the gethostname() call.
|
||||||
|
|
||||||
|
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Monitor.c | 3 +--
|
||||||
|
lib.c | 19 +++++++++++++++++++
|
||||||
|
mapfile.c | 3 +--
|
||||||
|
mdadm.c | 3 +--
|
||||||
|
mdadm.h | 1 +
|
||||||
|
super-ddf.c | 3 +--
|
||||||
|
6 files changed, 24 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Monitor.c b/Monitor.c
|
||||||
|
index 66175968..e74a0558 100644
|
||||||
|
--- a/Monitor.c
|
||||||
|
+++ b/Monitor.c
|
||||||
|
@@ -222,11 +222,10 @@ int Monitor(struct mddev_dev *devlist,
|
||||||
|
info.dosyslog = dosyslog;
|
||||||
|
info.test = c->test;
|
||||||
|
|
||||||
|
- if (gethostname(info.hostname, sizeof(info.hostname)) != 0) {
|
||||||
|
+ if (s_gethostname(info.hostname, sizeof(info.hostname)) != 0) {
|
||||||
|
pr_err("Cannot get hostname.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
- info.hostname[sizeof(info.hostname) - 1] = '\0';
|
||||||
|
|
||||||
|
if (share){
|
||||||
|
if (check_one_sharer(c->scan) == 2)
|
||||||
|
diff --git a/lib.c b/lib.c
|
||||||
|
index fe5c8d2c..8a4b48e0 100644
|
||||||
|
--- a/lib.c
|
||||||
|
+++ b/lib.c
|
||||||
|
@@ -585,3 +585,22 @@ int parse_num(int *dest, const char *num)
|
||||||
|
*dest = temp;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * s_gethostname() - secure get hostname. Assure null-terminated string.
|
||||||
|
+ *
|
||||||
|
+ * @buf: buffer for hostname.
|
||||||
|
+ * @buf_len: buffer length.
|
||||||
|
+ *
|
||||||
|
+ * Return: gethostname() result.
|
||||||
|
+ */
|
||||||
|
+int s_gethostname(char *buf, int buf_len)
|
||||||
|
+{
|
||||||
|
+ assert(buf);
|
||||||
|
+
|
||||||
|
+ int ret = gethostname(buf, buf_len);
|
||||||
|
+
|
||||||
|
+ buf[buf_len - 1] = 0;
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
diff --git a/mapfile.c b/mapfile.c
|
||||||
|
index 34fea179..f1f3ee2c 100644
|
||||||
|
--- a/mapfile.c
|
||||||
|
+++ b/mapfile.c
|
||||||
|
@@ -363,8 +363,7 @@ void RebuildMap(void)
|
||||||
|
char *homehost = conf_get_homehost(&require_homehost);
|
||||||
|
|
||||||
|
if (homehost == NULL || strcmp(homehost, "<system>")==0) {
|
||||||
|
- if (gethostname(sys_hostname, sizeof(sys_hostname)) == 0) {
|
||||||
|
- sys_hostname[sizeof(sys_hostname)-1] = 0;
|
||||||
|
+ if (s_gethostname(sys_hostname, sizeof(sys_hostname)) == 0) {
|
||||||
|
homehost = sys_hostname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/mdadm.c b/mdadm.c
|
||||||
|
index 076b45e0..e32598cb 100644
|
||||||
|
--- a/mdadm.c
|
||||||
|
+++ b/mdadm.c
|
||||||
|
@@ -1340,8 +1340,7 @@ int main(int argc, char *argv[])
|
||||||
|
if (c.homehost == NULL && c.require_homehost)
|
||||||
|
c.homehost = conf_get_homehost(&c.require_homehost);
|
||||||
|
if (c.homehost == NULL || strcasecmp(c.homehost, "<system>") == 0) {
|
||||||
|
- if (gethostname(sys_hostname, sizeof(sys_hostname)) == 0) {
|
||||||
|
- sys_hostname[sizeof(sys_hostname)-1] = 0;
|
||||||
|
+ if (s_gethostname(sys_hostname, sizeof(sys_hostname)) == 0) {
|
||||||
|
c.homehost = sys_hostname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index 83f2cf7f..f0ceeb78 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -1805,6 +1805,7 @@ extern void set_dlm_hooks(void);
|
||||||
|
extern void sleep_for(unsigned int sec, long nsec, bool wake_after_interrupt);
|
||||||
|
extern bool is_directory(const char *path);
|
||||||
|
extern bool is_file(const char *path);
|
||||||
|
+extern int s_gethostname(char *buf, int buf_len);
|
||||||
|
|
||||||
|
#define _ROUND_UP(val, base) (((val) + (base) - 1) & ~(base - 1))
|
||||||
|
#define ROUND_UP(val, base) _ROUND_UP(val, (typeof(val))(base))
|
||||||
|
diff --git a/super-ddf.c b/super-ddf.c
|
||||||
|
index 7213284e..c5242654 100644
|
||||||
|
--- a/super-ddf.c
|
||||||
|
+++ b/super-ddf.c
|
||||||
|
@@ -2364,8 +2364,7 @@ static int init_super_ddf(struct supertype *st,
|
||||||
|
* Remaining 16 are serial number.... maybe a hostname would do?
|
||||||
|
*/
|
||||||
|
memcpy(ddf->controller.guid, T10, sizeof(T10));
|
||||||
|
- gethostname(hostname, sizeof(hostname));
|
||||||
|
- hostname[sizeof(hostname) - 1] = 0;
|
||||||
|
+ s_gethostname(hostname, sizeof(hostname));
|
||||||
|
hostlen = strlen(hostname);
|
||||||
|
memcpy(ddf->controller.guid + 24 - hostlen, hostname, hostlen);
|
||||||
|
for (i = strlen(T10) ; i+hostlen < 24; i++)
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,41 @@
|
|||||||
|
From 1ab341e5ce0cb01a1533a2c36e5b69eabf12bf95 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Xiao Ni <xni@redhat.com>
|
||||||
|
Date: Fri, 25 Aug 2023 20:55:41 +0800
|
||||||
|
Subject: [PATCH 134/165] mdadm: Stop mdcheck_continue timer when mdcheck_start
|
||||||
|
service can finish check
|
||||||
|
|
||||||
|
mdcheck_continue is triggered by mdcheck_start timer. It's used to
|
||||||
|
continue check action if the raid is too big and mdcheck_start
|
||||||
|
service can't finish check action. If mdcheck start can finish check
|
||||||
|
action, it doesn't need to mdcheck continue service anymore. So stop
|
||||||
|
it when mdcheck start service can finish check action.
|
||||||
|
|
||||||
|
Signed-off-by: Xiao Ni <xni@redhat.com>
|
||||||
|
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
misc/mdcheck | 8 +++++++-
|
||||||
|
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/misc/mdcheck b/misc/mdcheck
|
||||||
|
index 700c3e25..f87999d3 100644
|
||||||
|
--- a/misc/mdcheck
|
||||||
|
+++ b/misc/mdcheck
|
||||||
|
@@ -140,7 +140,13 @@ do
|
||||||
|
echo $a > $fl
|
||||||
|
any=yes
|
||||||
|
done
|
||||||
|
- if [ -z "$any" ]; then exit 0; fi
|
||||||
|
+ # mdcheck_continue.timer is started by mdcheck_start.timer.
|
||||||
|
+ # When the check action can be finished in mdcheck_start.service,
|
||||||
|
+ # it doesn't need mdcheck_continue anymore.
|
||||||
|
+ if [ -z "$any" ]; then
|
||||||
|
+ systemctl stop mdcheck_continue.timer
|
||||||
|
+ exit 0;
|
||||||
|
+ fi
|
||||||
|
sleep 120
|
||||||
|
done
|
||||||
|
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
90
SOURCES/0135-Fix-memory-leak-in-file-Assemble.patch
Normal file
90
SOURCES/0135-Fix-memory-leak-in-file-Assemble.patch
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
From e9fb93af0f769d147a13e86ab4e5d0aeb935e9fc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Guanqin Miao <miaoguanqin@huawei.com>
|
||||||
|
Date: Mon, 24 Apr 2023 16:06:34 +0800
|
||||||
|
Subject: [PATCH 135/165] Fix memory leak in file Assemble
|
||||||
|
|
||||||
|
When we test mdadm with asan, we found some memory leaks in Assemble.c
|
||||||
|
We fix these memory leaks based on code logic.
|
||||||
|
|
||||||
|
v2: Set st = NULL before jumping to loop
|
||||||
|
|
||||||
|
Signed-off-by: Guanqin Miao <miaoguanqin@huawei.com>
|
||||||
|
Signed-off-by: Li Xiao Keng <lixiaokeng@huawei.com>
|
||||||
|
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Assemble.c | 14 ++++++++++++--
|
||||||
|
1 file changed, 12 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Assemble.c b/Assemble.c
|
||||||
|
index 49804941..61e8cd17 100644
|
||||||
|
--- a/Assemble.c
|
||||||
|
+++ b/Assemble.c
|
||||||
|
@@ -341,8 +341,10 @@ static int select_devices(struct mddev_dev *devlist,
|
||||||
|
st->ss->free_super(st);
|
||||||
|
dev_policy_free(pol);
|
||||||
|
domain_free(domains);
|
||||||
|
- if (tst)
|
||||||
|
+ if (tst) {
|
||||||
|
tst->ss->free_super(tst);
|
||||||
|
+ free(tst);
|
||||||
|
+ }
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -417,6 +419,7 @@ static int select_devices(struct mddev_dev *devlist,
|
||||||
|
st->ss->free_super(st);
|
||||||
|
dev_policy_free(pol);
|
||||||
|
domain_free(domains);
|
||||||
|
+ free(st);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (c->verbose > 0)
|
||||||
|
@@ -425,6 +428,8 @@ static int select_devices(struct mddev_dev *devlist,
|
||||||
|
|
||||||
|
/* make sure we finished the loop */
|
||||||
|
tmpdev = NULL;
|
||||||
|
+ free(st);
|
||||||
|
+ st = NULL;
|
||||||
|
goto loop;
|
||||||
|
} else {
|
||||||
|
content = *contentp;
|
||||||
|
@@ -533,6 +538,7 @@ static int select_devices(struct mddev_dev *devlist,
|
||||||
|
st->ss->free_super(st);
|
||||||
|
dev_policy_free(pol);
|
||||||
|
domain_free(domains);
|
||||||
|
+ free(tst);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tmpdev->used = 1;
|
||||||
|
@@ -546,8 +552,10 @@ static int select_devices(struct mddev_dev *devlist,
|
||||||
|
}
|
||||||
|
dev_policy_free(pol);
|
||||||
|
pol = NULL;
|
||||||
|
- if (tst)
|
||||||
|
+ if (tst) {
|
||||||
|
tst->ss->free_super(tst);
|
||||||
|
+ free(tst);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we found some imsm spares but no members */
|
||||||
|
@@ -839,6 +847,7 @@ static int load_devices(struct devs *devices, char *devmap,
|
||||||
|
close(mdfd);
|
||||||
|
free(devices);
|
||||||
|
free(devmap);
|
||||||
|
+ free(best);
|
||||||
|
*stp = st;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
@@ -1950,6 +1959,7 @@ out:
|
||||||
|
} else if (mdfd >= 0)
|
||||||
|
close(mdfd);
|
||||||
|
|
||||||
|
+ free(best);
|
||||||
|
/* '2' means 'OK, but not started yet' */
|
||||||
|
if (rv == -1) {
|
||||||
|
free(devices);
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
54
SOURCES/0136-Fix-memory-leak-in-file-Kill.patch
Normal file
54
SOURCES/0136-Fix-memory-leak-in-file-Kill.patch
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
From 8fd0c565b09ba449418d7d604ceba66313246152 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Guanqin Miao <miaoguanqin@huawei.com>
|
||||||
|
Date: Mon, 24 Apr 2023 16:06:35 +0800
|
||||||
|
Subject: [PATCH 136/165] Fix memory leak in file Kill
|
||||||
|
|
||||||
|
When we test mdadm with asan, we found some memory leaks in Kill.c
|
||||||
|
We fix these memory leaks based on code logic.
|
||||||
|
|
||||||
|
Signed-off-by: Guanqin Miao <miaoguanqin@huawei.com>
|
||||||
|
Signed-off-by: Li Xiao Keng <lixiaokeng@huawei.com>
|
||||||
|
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Kill.c | 9 ++++++++-
|
||||||
|
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/Kill.c b/Kill.c
|
||||||
|
index bfd0efdc..43c9abed 100644
|
||||||
|
--- a/Kill.c
|
||||||
|
+++ b/Kill.c
|
||||||
|
@@ -41,6 +41,7 @@ int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl)
|
||||||
|
* 4 - failed to find a superblock.
|
||||||
|
*/
|
||||||
|
|
||||||
|
+ bool free_super = false;
|
||||||
|
int fd, rv = 0;
|
||||||
|
|
||||||
|
if (force)
|
||||||
|
@@ -52,8 +53,10 @@ int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl)
|
||||||
|
dev);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
- if (st == NULL)
|
||||||
|
+ if (st == NULL) {
|
||||||
|
st = guess_super(fd);
|
||||||
|
+ free_super = true;
|
||||||
|
+ }
|
||||||
|
if (st == NULL || st->ss->init_super == NULL) {
|
||||||
|
if (verbose >= 0)
|
||||||
|
pr_err("Unrecognised md component device - %s\n", dev);
|
||||||
|
@@ -77,6 +80,10 @@ int Kill(char *dev, struct supertype *st, int force, int verbose, int noexcl)
|
||||||
|
rv = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ if (free_super && st) {
|
||||||
|
+ st->ss->free_super(st);
|
||||||
|
+ free(st);
|
||||||
|
+ }
|
||||||
|
close(fd);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
74
SOURCES/0137-Fix-memory-leak-in-file-Manage.patch
Normal file
74
SOURCES/0137-Fix-memory-leak-in-file-Manage.patch
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
From f6feb3fbb50f48c193e9e4d775a20aa20f7b47b3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Guanqin Miao <miaoguanqin@huawei.com>
|
||||||
|
Date: Mon, 24 Apr 2023 16:06:36 +0800
|
||||||
|
Subject: [PATCH 137/165] Fix memory leak in file Manage
|
||||||
|
|
||||||
|
When we test mdadm with asan, we found some memory leaks in Manage.c
|
||||||
|
We fix these memory leaks based on code logic.
|
||||||
|
|
||||||
|
v2: Fix free() of uninitialized 'tst' in abort path.
|
||||||
|
|
||||||
|
Signed-off-by: Guanqin Miao <miaoguanqin@huawei.com>
|
||||||
|
Signed-off-by: Li Xiao Keng <lixiaokeng@huawei.com>
|
||||||
|
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Manage.c | 13 +++++++++++--
|
||||||
|
1 file changed, 11 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Manage.c b/Manage.c
|
||||||
|
index f54de7c6..f997b163 100644
|
||||||
|
--- a/Manage.c
|
||||||
|
+++ b/Manage.c
|
||||||
|
@@ -222,6 +222,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
|
||||||
|
if (verbose >= 0)
|
||||||
|
pr_err("Cannot get exclusive access to %s:Perhaps a running process, mounted filesystem or active volume group?\n",
|
||||||
|
devname);
|
||||||
|
+ sysfs_free(mdi);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* If this is an mdmon managed array, just write 'inactive'
|
||||||
|
@@ -801,8 +802,14 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
|
||||||
|
rdev, update, devname,
|
||||||
|
verbose, array);
|
||||||
|
dev_st->ss->free_super(dev_st);
|
||||||
|
- if (rv)
|
||||||
|
+ if (rv) {
|
||||||
|
+ free(dev_st);
|
||||||
|
return rv;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (dev_st) {
|
||||||
|
+ dev_st->ss->free_super(dev_st);
|
||||||
|
+ free(dev_st);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dv->disposition == 'M') {
|
||||||
|
@@ -1362,7 +1369,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||||
|
unsigned long long array_size;
|
||||||
|
struct mddev_dev *dv;
|
||||||
|
int tfd = -1;
|
||||||
|
- struct supertype *tst;
|
||||||
|
+ struct supertype *tst = NULL;
|
||||||
|
char *subarray = NULL;
|
||||||
|
int sysfd = -1;
|
||||||
|
int count = 0; /* number of actions taken */
|
||||||
|
@@ -1699,6 +1706,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ free(tst);
|
||||||
|
if (frozen > 0)
|
||||||
|
sysfs_set_str(&info, NULL, "sync_action","idle");
|
||||||
|
if (test && count == 0)
|
||||||
|
@@ -1706,6 +1714,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
abort:
|
||||||
|
+ free(tst);
|
||||||
|
if (frozen > 0)
|
||||||
|
sysfs_set_str(&info, NULL, "sync_action","idle");
|
||||||
|
return !test && busy ? 2 : 1;
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
34
SOURCES/0138-Fix-memory-leak-in-file-mdadm.patch
Normal file
34
SOURCES/0138-Fix-memory-leak-in-file-mdadm.patch
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
From e62a561ee8b7157a2390eab215dcef6240bd7b03 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Guanqin Miao <miaoguanqin@huawei.com>
|
||||||
|
Date: Mon, 24 Apr 2023 16:06:37 +0800
|
||||||
|
Subject: [PATCH 138/165] Fix memory leak in file mdadm
|
||||||
|
|
||||||
|
When we test mdadm with asan, we found some memory leaks in mdadm.c
|
||||||
|
We fix these memory leaks based on code logic.
|
||||||
|
|
||||||
|
Signed-off-by: Guanqin Miao <miaoguanqin@huawei.com>
|
||||||
|
Signed-off-by: Li Xiao Keng <lixiaokeng@huawei.com>
|
||||||
|
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
mdadm.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/mdadm.c b/mdadm.c
|
||||||
|
index e32598cb..22d1c53b 100644
|
||||||
|
--- a/mdadm.c
|
||||||
|
+++ b/mdadm.c
|
||||||
|
@@ -1708,6 +1708,10 @@ int main(int argc, char *argv[])
|
||||||
|
autodetect();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+ if (ss) {
|
||||||
|
+ ss->ss->free_super(ss);
|
||||||
|
+ free(ss);
|
||||||
|
+ }
|
||||||
|
if (locked)
|
||||||
|
cluster_release_dlmlock();
|
||||||
|
close_fd(&mdfd);
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
116
SOURCES/0139-Fix-unsafe-string-functions.patch
Normal file
116
SOURCES/0139-Fix-unsafe-string-functions.patch
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
From dd5ab40204b1d78ec3bdbcfd5a38a8ffb72bdb50 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kinga Tanska <kinga.tanska@intel.com>
|
||||||
|
Date: Thu, 11 May 2023 04:55:12 +0200
|
||||||
|
Subject: [PATCH 139/165] Fix unsafe string functions
|
||||||
|
|
||||||
|
Add string length limitations where necessary to
|
||||||
|
avoid buffer overflows.
|
||||||
|
|
||||||
|
Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
mdmon.c | 6 +++---
|
||||||
|
mdopen.c | 4 ++--
|
||||||
|
platform-intel.c | 2 +-
|
||||||
|
super-intel.c | 6 +++---
|
||||||
|
4 files changed, 9 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/mdmon.c b/mdmon.c
|
||||||
|
index cef5bbc8..a2038fe6 100644
|
||||||
|
--- a/mdmon.c
|
||||||
|
+++ b/mdmon.c
|
||||||
|
@@ -240,7 +240,7 @@ static int make_control_sock(char *devname)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
addr.sun_family = PF_LOCAL;
|
||||||
|
- strcpy(addr.sun_path, path);
|
||||||
|
+ snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path);
|
||||||
|
umask(077); /* ensure no world write access */
|
||||||
|
if (bind(sfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||||
|
close(sfd);
|
||||||
|
@@ -389,7 +389,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
|
if (all) {
|
||||||
|
struct mdstat_ent *mdstat, *e;
|
||||||
|
- int container_len = strlen(container_name);
|
||||||
|
+ int container_len = strnlen(container_name, MD_NAME_MAX);
|
||||||
|
|
||||||
|
/* launch an mdmon instance for each container found */
|
||||||
|
mdstat = mdstat_read(0, 0);
|
||||||
|
@@ -472,7 +472,7 @@ static int mdmon(char *devnm, int must_fork, int takeover)
|
||||||
|
pfd[0] = pfd[1] = -1;
|
||||||
|
|
||||||
|
container = xcalloc(1, sizeof(*container));
|
||||||
|
- strcpy(container->devnm, devnm);
|
||||||
|
+ snprintf(container->devnm, MD_NAME_MAX, "%s", devnm);
|
||||||
|
container->arrays = NULL;
|
||||||
|
container->sock = -1;
|
||||||
|
|
||||||
|
diff --git a/mdopen.c b/mdopen.c
|
||||||
|
index d3022a54..3daa71f9 100644
|
||||||
|
--- a/mdopen.c
|
||||||
|
+++ b/mdopen.c
|
||||||
|
@@ -193,14 +193,14 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
|
||||||
|
|
||||||
|
if (dev) {
|
||||||
|
if (strncmp(dev, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) {
|
||||||
|
- strcpy(cname, dev + DEV_MD_DIR_LEN);
|
||||||
|
+ snprintf(cname, MD_NAME_MAX, "%s", dev + DEV_MD_DIR_LEN);
|
||||||
|
} else if (strncmp(dev, "/dev/", 5) == 0) {
|
||||||
|
char *e = dev + strlen(dev);
|
||||||
|
while (e > dev && isdigit(e[-1]))
|
||||||
|
e--;
|
||||||
|
if (e[0])
|
||||||
|
num = strtoul(e, NULL, 10);
|
||||||
|
- strcpy(cname, dev+5);
|
||||||
|
+ snprintf(cname, MD_NAME_MAX, "%s", dev + 5);
|
||||||
|
cname[e-(dev+5)] = 0;
|
||||||
|
/* name *must* be mdXX or md_dXX in this context */
|
||||||
|
if (num < 0 ||
|
||||||
|
diff --git a/platform-intel.c b/platform-intel.c
|
||||||
|
index 914164c0..eb6e1b7e 100644
|
||||||
|
--- a/platform-intel.c
|
||||||
|
+++ b/platform-intel.c
|
||||||
|
@@ -214,7 +214,7 @@ struct sys_dev *device_by_id_and_path(__u16 device_id, const char *path)
|
||||||
|
|
||||||
|
static int devpath_to_ll(const char *dev_path, const char *entry, unsigned long long *val)
|
||||||
|
{
|
||||||
|
- char path[strlen(dev_path) + strlen(entry) + 2];
|
||||||
|
+ char path[strnlen(dev_path, PATH_MAX) + strnlen(entry, PATH_MAX) + 2];
|
||||||
|
int fd;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index 824c1356..ce813172 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -7043,7 +7043,7 @@ active_arrays_by_format(char *name, char* hba, struct md_list **devlist,
|
||||||
|
int fd = -1;
|
||||||
|
while (dev && !is_fd_valid(fd)) {
|
||||||
|
char *path = xmalloc(strlen(dev->name) + strlen("/dev/") + 1);
|
||||||
|
- num = sprintf(path, "%s%s", "/dev/", dev->name);
|
||||||
|
+ num = snprintf(path, PATH_MAX, "%s%s", "/dev/", dev->name);
|
||||||
|
if (num > 0)
|
||||||
|
fd = open(path, O_RDONLY, 0);
|
||||||
|
if (num <= 0 || !is_fd_valid(fd)) {
|
||||||
|
@@ -7935,7 +7935,7 @@ static int kill_subarray_imsm(struct supertype *st, char *subarray_id)
|
||||||
|
|
||||||
|
if (i < current_vol)
|
||||||
|
continue;
|
||||||
|
- sprintf(subarray, "%u", i);
|
||||||
|
+ snprintf(subarray, sizeof(subarray), "%u", i);
|
||||||
|
if (is_subarray_active(subarray, st->devnm)) {
|
||||||
|
pr_err("deleting subarray-%d would change the UUID of active subarray-%d, aborting\n",
|
||||||
|
current_vol, i);
|
||||||
|
@@ -11308,7 +11308,7 @@ static const char *imsm_get_disk_controller_domain(const char *path)
|
||||||
|
char *drv=NULL;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
- strcpy(disk_path, disk_by_path);
|
||||||
|
+ 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;
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
55
SOURCES/0140-platform-intel-limit-guid-length.patch
Normal file
55
SOURCES/0140-platform-intel-limit-guid-length.patch
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
From 5ccd457b29809bee442749b5f66ac27ebba4a72d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kinga Tanska <kinga.tanska@intel.com>
|
||||||
|
Date: Thu, 11 May 2023 04:55:13 +0200
|
||||||
|
Subject: [PATCH 140/165] platform-intel: limit guid length
|
||||||
|
|
||||||
|
Moving GUID_STR_MAX to header to use it as
|
||||||
|
a length limitation for snprintf function.
|
||||||
|
|
||||||
|
Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
platform-intel.c | 3 ---
|
||||||
|
platform-intel.h | 5 ++++-
|
||||||
|
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/platform-intel.c b/platform-intel.c
|
||||||
|
index eb6e1b7e..ef90c3fd 100644
|
||||||
|
--- a/platform-intel.c
|
||||||
|
+++ b/platform-intel.c
|
||||||
|
@@ -510,9 +510,6 @@ static const struct imsm_orom *find_imsm_hba_orom(struct sys_dev *hba)
|
||||||
|
return get_orom_by_device_id(hba->dev_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define GUID_STR_MAX 37 /* according to GUID format:
|
||||||
|
- * xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" */
|
||||||
|
-
|
||||||
|
#define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
|
||||||
|
((struct efi_guid) \
|
||||||
|
{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
|
||||||
|
diff --git a/platform-intel.h b/platform-intel.h
|
||||||
|
index 2c0f4e39..ba97fb04 100644
|
||||||
|
--- a/platform-intel.h
|
||||||
|
+++ b/platform-intel.h
|
||||||
|
@@ -19,6 +19,9 @@
|
||||||
|
#include <asm/types.h>
|
||||||
|
#include <strings.h>
|
||||||
|
|
||||||
|
+/* according to GUID format: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" */
|
||||||
|
+#define GUID_STR_MAX 37
|
||||||
|
+
|
||||||
|
/* The IMSM Capability (IMSM AHCI and ISCU OROM/EFI variable) Version Table definition */
|
||||||
|
struct imsm_orom {
|
||||||
|
__u8 signature[4];
|
||||||
|
@@ -229,7 +232,7 @@ extern struct orom_entry *orom_entries;
|
||||||
|
|
||||||
|
static inline char *guid_str(char *buf, struct efi_guid guid)
|
||||||
|
{
|
||||||
|
- sprintf(buf, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||||
|
+ snprintf(buf, GUID_STR_MAX, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||||
|
guid.b[3], guid.b[2], guid.b[1], guid.b[0],
|
||||||
|
guid.b[5], guid.b[4], guid.b[7], guid.b[6],
|
||||||
|
guid.b[8], guid.b[9], guid.b[10], guid.b[11],
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,220 @@
|
|||||||
|
From 8d1114be8c0a307d251c24078833b029efabc448 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Date: Wed, 5 Jul 2023 16:23:17 +0200
|
||||||
|
Subject: [PATCH 141/165] imsm: Add reading vmd register for finding imsm
|
||||||
|
capability
|
||||||
|
|
||||||
|
Currently mdadm does not find imsm capability when running inside VM.
|
||||||
|
This patch adds the possibility to read from vmd register and check for
|
||||||
|
capability, effectively allowing to use mdadm with imsm inside virtual machines.
|
||||||
|
|
||||||
|
Additionally refactor find_imsm_capability() to make assignments in new
|
||||||
|
lines.
|
||||||
|
|
||||||
|
Signed-off-by: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
platform-intel.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
platform-intel.h | 11 ++++-
|
||||||
|
super-intel.c | 11 +++--
|
||||||
|
3 files changed, 130 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/platform-intel.c b/platform-intel.c
|
||||||
|
index ef90c3fd..ac282bc5 100644
|
||||||
|
--- a/platform-intel.c
|
||||||
|
+++ b/platform-intel.c
|
||||||
|
@@ -700,6 +700,106 @@ const struct imsm_orom *find_imsm_nvme(struct sys_dev *hba)
|
||||||
|
return &nvme_orom->orom;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#define VMD_REGISTER_OFFSET 0x3FC
|
||||||
|
+#define VMD_REGISTER_SKU_SHIFT 1
|
||||||
|
+#define VMD_REGISTER_SKU_MASK (0x00000007)
|
||||||
|
+#define VMD_REGISTER_SKU_PREMIUM 2
|
||||||
|
+#define MD_REGISTER_VER_MAJOR_SHIFT 4
|
||||||
|
+#define MD_REGISTER_VER_MAJOR_MASK (0x0000000F)
|
||||||
|
+#define MD_REGISTER_VER_MINOR_SHIFT 8
|
||||||
|
+#define MD_REGISTER_VER_MINOR_MASK (0x0000000F)
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * read_vmd_register() - Reads VMD register and writes contents to buff ptr
|
||||||
|
+ * @buff: buffer for vmd register data, should be the size of uint32_t
|
||||||
|
+ *
|
||||||
|
+ * Return: 0 on success, 1 on error
|
||||||
|
+ */
|
||||||
|
+int read_vmd_register(uint32_t *buff, struct sys_dev *hba)
|
||||||
|
+{
|
||||||
|
+ int fd;
|
||||||
|
+ char vmd_pci_config_path[PATH_MAX];
|
||||||
|
+
|
||||||
|
+ if (!vmd_domain_to_controller(hba, vmd_pci_config_path))
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ strncat(vmd_pci_config_path, "/config", PATH_MAX - strnlen(vmd_pci_config_path, PATH_MAX));
|
||||||
|
+
|
||||||
|
+ fd = open(vmd_pci_config_path, O_RDONLY);
|
||||||
|
+ if (fd < 0)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ if (pread(fd, buff, sizeof(uint32_t), VMD_REGISTER_OFFSET) != sizeof(uint32_t)) {
|
||||||
|
+ close(fd);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ close(fd);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * add_vmd_orom() - Adds VMD orom cap to orom list, writes orom_entry ptr into vmd_orom
|
||||||
|
+ * @vmd_orom: pointer to orom entry pointer
|
||||||
|
+ *
|
||||||
|
+ * Return: 0 on success, 1 on error
|
||||||
|
+ */
|
||||||
|
+int add_vmd_orom(struct orom_entry **vmd_orom, struct sys_dev *hba)
|
||||||
|
+{
|
||||||
|
+ uint8_t sku;
|
||||||
|
+ uint32_t vmd_register_data;
|
||||||
|
+ struct imsm_orom vmd_orom_cap = {
|
||||||
|
+ .signature = IMSM_VMD_OROM_COMPAT_SIGNATURE,
|
||||||
|
+ .sss = IMSM_OROM_SSS_4kB | IMSM_OROM_SSS_8kB |
|
||||||
|
+ IMSM_OROM_SSS_16kB | IMSM_OROM_SSS_32kB |
|
||||||
|
+ IMSM_OROM_SSS_64kB | IMSM_OROM_SSS_128kB,
|
||||||
|
+ .dpa = IMSM_OROM_DISKS_PER_ARRAY_NVME,
|
||||||
|
+ .tds = IMSM_OROM_TOTAL_DISKS_VMD,
|
||||||
|
+ .vpa = IMSM_OROM_VOLUMES_PER_ARRAY,
|
||||||
|
+ .vphba = IMSM_OROM_VOLUMES_PER_HBA_VMD,
|
||||||
|
+ .attr = IMSM_OROM_ATTR_2TB | IMSM_OROM_ATTR_2TB_DISK,
|
||||||
|
+ .driver_features = IMSM_OROM_CAPABILITIES_EnterpriseSystem |
|
||||||
|
+ IMSM_OROM_CAPABILITIES_TPV
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ if (read_vmd_register(&vmd_register_data, hba) != 0)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ sku = (uint8_t)((vmd_register_data >> VMD_REGISTER_SKU_SHIFT) &
|
||||||
|
+ VMD_REGISTER_SKU_MASK);
|
||||||
|
+
|
||||||
|
+ if (sku == VMD_REGISTER_SKU_PREMIUM)
|
||||||
|
+ vmd_orom_cap.rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 |
|
||||||
|
+ IMSM_OROM_RLC_RAID10 | IMSM_OROM_RLC_RAID5;
|
||||||
|
+ else
|
||||||
|
+ vmd_orom_cap.rlc = IMSM_OROM_RLC_RAID_CNG;
|
||||||
|
+
|
||||||
|
+ vmd_orom_cap.major_ver = (uint8_t)
|
||||||
|
+ ((vmd_register_data >> MD_REGISTER_VER_MAJOR_SHIFT) &
|
||||||
|
+ MD_REGISTER_VER_MAJOR_MASK);
|
||||||
|
+ vmd_orom_cap.minor_ver = (uint8_t)
|
||||||
|
+ ((vmd_register_data >> MD_REGISTER_VER_MINOR_SHIFT) &
|
||||||
|
+ MD_REGISTER_VER_MINOR_MASK);
|
||||||
|
+
|
||||||
|
+ *vmd_orom = add_orom(&vmd_orom_cap);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const struct imsm_orom *find_imsm_vmd(struct sys_dev *hba)
|
||||||
|
+{
|
||||||
|
+ static struct orom_entry *vmd_orom;
|
||||||
|
+
|
||||||
|
+ if (hba->type != SYS_DEV_VMD)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ if (!vmd_orom && add_vmd_orom(&vmd_orom, hba) != 0)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ add_orom_device_id(vmd_orom, hba->dev_id);
|
||||||
|
+ vmd_orom->type = SYS_DEV_VMD;
|
||||||
|
+ return &vmd_orom->orom;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
const struct imsm_orom *find_imsm_capability(struct sys_dev *hba)
|
||||||
|
{
|
||||||
|
const struct imsm_orom *cap = get_orom_by_device_id(hba->dev_id);
|
||||||
|
@@ -709,9 +809,19 @@ const struct imsm_orom *find_imsm_capability(struct sys_dev *hba)
|
||||||
|
|
||||||
|
if (hba->type == SYS_DEV_NVME)
|
||||||
|
return find_imsm_nvme(hba);
|
||||||
|
- if ((cap = find_imsm_efi(hba)) != NULL)
|
||||||
|
+
|
||||||
|
+ cap = find_imsm_efi(hba);
|
||||||
|
+ if (cap)
|
||||||
|
return cap;
|
||||||
|
- if ((cap = find_imsm_hba_orom(hba)) != NULL)
|
||||||
|
+
|
||||||
|
+ if (hba->type == SYS_DEV_VMD) {
|
||||||
|
+ cap = find_imsm_vmd(hba);
|
||||||
|
+ if (cap)
|
||||||
|
+ return cap;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ cap = find_imsm_hba_orom(hba);
|
||||||
|
+ if (cap)
|
||||||
|
return cap;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
diff --git a/platform-intel.h b/platform-intel.h
|
||||||
|
index ba97fb04..ce29d3da 100644
|
||||||
|
--- a/platform-intel.h
|
||||||
|
+++ b/platform-intel.h
|
||||||
|
@@ -27,6 +27,7 @@ struct imsm_orom {
|
||||||
|
__u8 signature[4];
|
||||||
|
#define IMSM_OROM_SIGNATURE "$VER"
|
||||||
|
#define IMSM_NVME_OROM_COMPAT_SIGNATURE "$NVM"
|
||||||
|
+ #define IMSM_VMD_OROM_COMPAT_SIGNATURE "$VMD"
|
||||||
|
__u8 table_ver_major; /* Currently 2 (can change with future revs) */
|
||||||
|
__u8 table_ver_minor; /* Currently 2 (can change with future revs) */
|
||||||
|
__u16 major_ver; /* Example: 8 as in 8.6.0.1020 */
|
||||||
|
@@ -68,11 +69,13 @@ struct imsm_orom {
|
||||||
|
__u16 tds; /* Total Disks Supported */
|
||||||
|
#define IMSM_OROM_TOTAL_DISKS 6
|
||||||
|
#define IMSM_OROM_TOTAL_DISKS_NVME 12
|
||||||
|
+ #define IMSM_OROM_TOTAL_DISKS_VMD 48
|
||||||
|
__u8 vpa; /* # Volumes Per Array supported */
|
||||||
|
#define IMSM_OROM_VOLUMES_PER_ARRAY 2
|
||||||
|
__u8 vphba; /* # Volumes Per Host Bus Adapter supported */
|
||||||
|
#define IMSM_OROM_VOLUMES_PER_HBA 4
|
||||||
|
#define IMSM_OROM_VOLUMES_PER_HBA_NVME 4
|
||||||
|
+ #define IMSM_OROM_VOLUMES_PER_HBA_VMD 24
|
||||||
|
/* Attributes supported. This should map to the
|
||||||
|
* attributes in the MPB. Also, lower 16 bits
|
||||||
|
* should match/duplicate RLC bits above.
|
||||||
|
@@ -185,7 +188,13 @@ static inline int imsm_orom_is_enterprise(const struct imsm_orom *orom)
|
||||||
|
static inline int imsm_orom_is_nvme(const struct imsm_orom *orom)
|
||||||
|
{
|
||||||
|
return memcmp(orom->signature, IMSM_NVME_OROM_COMPAT_SIGNATURE,
|
||||||
|
- sizeof(orom->signature)) == 0;
|
||||||
|
+ sizeof(orom->signature)) == 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline int imsm_orom_is_vmd_without_efi(const struct imsm_orom *orom)
|
||||||
|
+{
|
||||||
|
+ return memcmp(orom->signature, IMSM_VMD_OROM_COMPAT_SIGNATURE,
|
||||||
|
+ sizeof(orom->signature)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int imsm_orom_has_tpv_support(const struct imsm_orom *orom)
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index ce813172..77b0066f 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -2672,9 +2672,14 @@ static void print_imsm_capability(const struct imsm_orom *orom)
|
||||||
|
else
|
||||||
|
printf("Rapid Storage Technology%s\n",
|
||||||
|
imsm_orom_is_enterprise(orom) ? " enterprise" : "");
|
||||||
|
- if (orom->major_ver || orom->minor_ver || orom->hotfix_ver || orom->build)
|
||||||
|
- printf(" Version : %d.%d.%d.%d\n", orom->major_ver,
|
||||||
|
- orom->minor_ver, orom->hotfix_ver, orom->build);
|
||||||
|
+ if (orom->major_ver || orom->minor_ver || orom->hotfix_ver || orom->build) {
|
||||||
|
+ if (imsm_orom_is_vmd_without_efi(orom))
|
||||||
|
+ printf(" Version : %d.%d\n", orom->major_ver,
|
||||||
|
+ orom->minor_ver);
|
||||||
|
+ else
|
||||||
|
+ printf(" Version : %d.%d.%d.%d\n", orom->major_ver,
|
||||||
|
+ orom->minor_ver, orom->hotfix_ver, orom->build);
|
||||||
|
+ }
|
||||||
|
printf(" RAID Levels :%s%s%s%s%s\n",
|
||||||
|
imsm_orom_has_raid0(orom) ? " raid0" : "",
|
||||||
|
imsm_orom_has_raid1(orom) ? " raid1" : "",
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
109
SOURCES/0142-Add-compiler-defenses-flags.patch
Normal file
109
SOURCES/0142-Add-compiler-defenses-flags.patch
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
From 55a1150c7438afcb7756fccd49713ede20a58e4a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Date: Mon, 17 Jul 2023 15:19:10 +0200
|
||||||
|
Subject: [PATCH 142/165] Add compiler defenses flags
|
||||||
|
|
||||||
|
It is essential to avoid buffer overflows and similar bugs as much as
|
||||||
|
possible.
|
||||||
|
|
||||||
|
According to Intel rules we are obligated to verify certain
|
||||||
|
compiler flags, so it will be much easier if they are added to the
|
||||||
|
Makefile.
|
||||||
|
|
||||||
|
Add gcc flags for prevention of buffer overflows, format string vulnerabilities,
|
||||||
|
stack protection to prevent stack overwrites and aslr enablement through -fPIE.
|
||||||
|
Also make the flags configurable.
|
||||||
|
|
||||||
|
The changes were verified on gcc versions 7.5, 8.3, 9.2, 10 and 12.2.
|
||||||
|
|
||||||
|
Signed-off-by: Mateusz Grzonka <mateusz.grzonka@intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Makefile | 41 +++++++++++++++++++++++++++++------------
|
||||||
|
1 file changed, 29 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index 5eac1a4e..b3aa36f6 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -30,7 +30,7 @@
|
||||||
|
|
||||||
|
# define "CXFLAGS" to give extra flags to CC.
|
||||||
|
# e.g. make CXFLAGS=-O to optimise
|
||||||
|
-CXFLAGS ?=-O2
|
||||||
|
+CXFLAGS ?=-O2 -D_FORTIFY_SOURCE=2
|
||||||
|
TCC = tcc
|
||||||
|
UCLIBC_GCC = $(shell for nm in i386-uclibc-linux-gcc i386-uclibc-gcc; do which $$nm > /dev/null && { echo $$nm ; exit; } ; done; echo false No uclibc found )
|
||||||
|
#DIET_GCC = diet gcc
|
||||||
|
@@ -50,14 +50,30 @@ ifeq ($(origin CC),default)
|
||||||
|
CC := $(CROSS_COMPILE)gcc
|
||||||
|
endif
|
||||||
|
CXFLAGS ?= -ggdb
|
||||||
|
-CWFLAGS = -Wall -Werror -Wstrict-prototypes -Wextra -Wno-unused-parameter
|
||||||
|
+CWFLAGS ?= -Wall -Werror -Wstrict-prototypes -Wextra -Wno-unused-parameter -Wformat -Wformat-security -Werror=format-security -fstack-protector-strong -fPIE -Warray-bounds
|
||||||
|
ifdef WARN_UNUSED
|
||||||
|
-CWFLAGS += -Wp,-D_FORTIFY_SOURCE=2 -O3
|
||||||
|
+CWFLAGS += -Wp -O3
|
||||||
|
endif
|
||||||
|
|
||||||
|
-FALLTHROUGH := $(shell gcc -v --help 2>&1 | grep "implicit-fallthrough" | wc -l)
|
||||||
|
-ifneq "$(FALLTHROUGH)" "0"
|
||||||
|
-CWFLAGS += -Wimplicit-fallthrough=0
|
||||||
|
+ifeq ($(origin FALLTHROUGH), undefined)
|
||||||
|
+ FALLTHROUGH := $(shell gcc -Q --help=warnings 2>&1 | grep "implicit-fallthrough" | wc -l)
|
||||||
|
+ ifneq "$(FALLTHROUGH)" "0"
|
||||||
|
+ CWFLAGS += -Wimplicit-fallthrough=0
|
||||||
|
+ endif
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
+ifeq ($(origin FORMATOVERFLOW), undefined)
|
||||||
|
+ FORMATOVERFLOW := $(shell gcc -Q --help=warnings 2>&1 | grep "format-overflow" | wc -l)
|
||||||
|
+ ifneq "$(FORMATOVERFLOW)" "0"
|
||||||
|
+ CWFLAGS += -Wformat-overflow
|
||||||
|
+ endif
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
+ifeq ($(origin STRINGOPOVERFLOW), undefined)
|
||||||
|
+ STRINGOPOVERFLOW := $(shell gcc -Q --help=warnings 2>&1 | grep "stringop-overflow" | wc -l)
|
||||||
|
+ ifneq "$(STRINGOPOVERFLOW)" "0"
|
||||||
|
+ CWFLAGS += -Wstringop-overflow
|
||||||
|
+ endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef DEBIAN
|
||||||
|
@@ -116,10 +132,12 @@ CFLAGS += -DUSE_PTHREADS
|
||||||
|
MON_LDFLAGS += -pthread
|
||||||
|
endif
|
||||||
|
|
||||||
|
+LDFLAGS = -Wl,-z,now,-z,noexecstack
|
||||||
|
+
|
||||||
|
# If you want a static binary, you might uncomment these
|
||||||
|
-# LDFLAGS = -static
|
||||||
|
+# LDFLAGS += -static
|
||||||
|
# STRIP = -s
|
||||||
|
-LDLIBS = -ldl
|
||||||
|
+LDLIBS = -ldl -pie
|
||||||
|
|
||||||
|
# To explicitly disable libudev, set -DNO_LIBUDEV in CXFLAGS
|
||||||
|
ifeq (, $(findstring -DNO_LIBUDEV, $(CXFLAGS)))
|
||||||
|
@@ -209,14 +227,13 @@ mdadm.Os : $(SRCS) $(INCL)
|
||||||
|
$(CC) -o mdadm.Os $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -DHAVE_STDINT_H -Os $(SRCS) $(LDLIBS)
|
||||||
|
|
||||||
|
mdadm.O2 : $(SRCS) $(INCL) mdmon.O2
|
||||||
|
- $(CC) -o mdadm.O2 $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -DHAVE_STDINT_H -O2 -D_FORTIFY_SOURCE=2 $(SRCS) $(LDLIBS)
|
||||||
|
+ $(CC) -o mdadm.O2 $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -DHAVE_STDINT_H -O2 $(SRCS) $(LDLIBS)
|
||||||
|
|
||||||
|
mdmon.O2 : $(MON_SRCS) $(INCL) mdmon.h
|
||||||
|
- $(CC) -o mdmon.O2 $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(MON_LDFLAGS) -DHAVE_STDINT_H -O2 -D_FORTIFY_SOURCE=2 $(MON_SRCS) $(LDLIBS)
|
||||||
|
+ $(CC) -o mdmon.O2 $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(MON_LDFLAGS) -DHAVE_STDINT_H -O2 $(MON_SRCS) $(LDLIBS)
|
||||||
|
|
||||||
|
-# use '-z now' to guarantee no dynamic linker interactions with the monitor thread
|
||||||
|
mdmon : $(MON_OBJS) | check_rundir
|
||||||
|
- $(CC) $(CFLAGS) $(LDFLAGS) $(MON_LDFLAGS) -Wl,-z,now -o mdmon $(MON_OBJS) $(LDLIBS)
|
||||||
|
+ $(CC) $(CFLAGS) $(LDFLAGS) $(MON_LDFLAGS) -o mdmon $(MON_OBJS) $(LDLIBS)
|
||||||
|
msg.o: msg.c msg.h
|
||||||
|
|
||||||
|
test_stripe : restripe.c xmalloc.o mdadm.h
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
34
SOURCES/0143-Assemble-fix-redundant-memory-free.patch
Normal file
34
SOURCES/0143-Assemble-fix-redundant-memory-free.patch
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
From 024d652e16dd9e3bd1ecdfce4d6f7a8cb498ba42 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kinga Tanska <kinga.tanska@intel.com>
|
||||||
|
Date: Tue, 12 Sep 2023 04:27:01 +0200
|
||||||
|
Subject: [PATCH 143/165] Assemble: fix redundant memory free
|
||||||
|
|
||||||
|
Commit e9fb93af0f76 ("Fix memory leak in file Assemble")
|
||||||
|
fixes few memory leaks in Assemble, but it introduces
|
||||||
|
problem with assembling RAID volume. It was caused by
|
||||||
|
clearing metadata too fast, not only on fail in
|
||||||
|
select_devices() function.
|
||||||
|
This commit removes redundant memory free.
|
||||||
|
|
||||||
|
Signed-off-by: Kinga Tanska <kinga.tanska@intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Assemble.c | 2 --
|
||||||
|
1 file changed, 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Assemble.c b/Assemble.c
|
||||||
|
index 61e8cd17..5be58e40 100644
|
||||||
|
--- a/Assemble.c
|
||||||
|
+++ b/Assemble.c
|
||||||
|
@@ -428,8 +428,6 @@ static int select_devices(struct mddev_dev *devlist,
|
||||||
|
|
||||||
|
/* make sure we finished the loop */
|
||||||
|
tmpdev = NULL;
|
||||||
|
- free(st);
|
||||||
|
- st = NULL;
|
||||||
|
goto loop;
|
||||||
|
} else {
|
||||||
|
content = *contentp;
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
92
SOURCES/0144-tests-add-a-new-test-for-rdev-lifetime.patch
Normal file
92
SOURCES/0144-tests-add-a-new-test-for-rdev-lifetime.patch
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
From 7fe21767d3ab65a686518d2e36d18a07f535972e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Kuai <yukuai3@huawei.com>
|
||||||
|
Date: Mon, 29 May 2023 21:28:19 +0800
|
||||||
|
Subject: [PATCH 144/165] tests: add a new test for rdev lifetime
|
||||||
|
|
||||||
|
This test add and remove a underlying disk to raid concurretly, verify
|
||||||
|
that the following problem is fixed:
|
||||||
|
|
||||||
|
run mdadm test 23rdev-lifetime at Fri Apr 28 03:25:30 UTC 2023
|
||||||
|
md: could not open device unknown-block(1,0).
|
||||||
|
sysfs: cannot create duplicate filename '/devices/virtual/block/md0/md/dev-ram0'
|
||||||
|
CPU: 26 PID: 10521 Comm: test Not tainted 6.3.0-rc2-00134-g7b3a8828043c #115
|
||||||
|
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/014
|
||||||
|
Call Trace:
|
||||||
|
<TASK>
|
||||||
|
dump_stack_lvl+0xe7/0x180
|
||||||
|
dump_stack+0x18/0x30
|
||||||
|
sysfs_warn_dup+0xa2/0xd0
|
||||||
|
sysfs_create_dir_ns+0x119/0x140
|
||||||
|
kobject_add_internal+0x143/0x4d0
|
||||||
|
kobject_add_varg+0x35/0x70
|
||||||
|
kobject_add+0x64/0xd0
|
||||||
|
bind_rdev_to_array+0x254/0x840 [md_mod]
|
||||||
|
new_dev_store+0x14d/0x350 [md_mod]
|
||||||
|
md_attr_store+0xc1/0x1a0 [md_mod]
|
||||||
|
sysfs_kf_write+0x51/0x70
|
||||||
|
kernfs_fop_write_iter+0x188/0x270
|
||||||
|
vfs_write+0x27e/0x460
|
||||||
|
ksys_write+0x85/0x180
|
||||||
|
__x64_sys_write+0x21/0x30
|
||||||
|
do_syscall_64+0x6c/0xe0
|
||||||
|
entry_SYSCALL_64_after_hwframe+0x63/0xcd
|
||||||
|
RIP: 0033:0x7f26bacf5387
|
||||||
|
Code: 0d 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b7 0f 1f 00 f3 0f 1e fa 64 84
|
||||||
|
RSP: 002b:00007ffe98d79e68 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
|
||||||
|
RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 00007f26bacf5387
|
||||||
|
RDX: 0000000000000004 RSI: 000055bd10282bf0 RDI: 0000000000000001
|
||||||
|
RBP: 000055bd10282bf0 R08: 000000000000000a R09: 00007f26bad8b4e0
|
||||||
|
R10: 00007f26bad8b3e0 R11: 0000000000000246 R12: 0000000000000004
|
||||||
|
R13: 00007f26badc8520 R14: 0000000000000004 R15: 00007f26badc8700
|
||||||
|
</TASK>
|
||||||
|
|
||||||
|
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
tests/23rdev-lifetime | 34 ++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 34 insertions(+)
|
||||||
|
create mode 100644 tests/23rdev-lifetime
|
||||||
|
|
||||||
|
diff --git a/tests/23rdev-lifetime b/tests/23rdev-lifetime
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..1750b0db
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/23rdev-lifetime
|
||||||
|
@@ -0,0 +1,34 @@
|
||||||
|
+devname=${dev0##*/}
|
||||||
|
+devt=`cat /sys/block/$devname/dev`
|
||||||
|
+pid=""
|
||||||
|
+runtime=2
|
||||||
|
+
|
||||||
|
+clean_up_test() {
|
||||||
|
+ pill -9 $pid
|
||||||
|
+ echo clear > /sys/block/md0/md/array_state
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+trap 'clean_up_test' EXIT
|
||||||
|
+
|
||||||
|
+add_by_sysfs() {
|
||||||
|
+ while true; do
|
||||||
|
+ echo $devt > /sys/block/md0/md/new_dev
|
||||||
|
+ done
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+remove_by_sysfs(){
|
||||||
|
+ while true; do
|
||||||
|
+ echo remove > /sys/block/md0/md/dev-${devname}/state
|
||||||
|
+ done
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+echo md0 > /sys/module/md_mod/parameters/new_array || die "create md0 failed"
|
||||||
|
+
|
||||||
|
+add_by_sysfs &
|
||||||
|
+pid="$pid $!"
|
||||||
|
+
|
||||||
|
+remove_by_sysfs &
|
||||||
|
+pid="$pid $!"
|
||||||
|
+
|
||||||
|
+sleep $runtime
|
||||||
|
+exit 0
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
38
SOURCES/0145-tests-support-to-skip-checking-dmesg.patch
Normal file
38
SOURCES/0145-tests-support-to-skip-checking-dmesg.patch
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
From 0ef9465f6355db612e53afc32e3084721c3dd7c7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Kuai <yukuai3@huawei.com>
|
||||||
|
Date: Mon, 29 May 2023 21:28:20 +0800
|
||||||
|
Subject: [PATCH 145/165] tests: support to skip checking dmesg
|
||||||
|
|
||||||
|
Prepare to add a regression test for raid10 that require error injection
|
||||||
|
to trigger error path, and kernel will complain about io error, checking
|
||||||
|
dmesg for error log will make it impossible to pass this test.
|
||||||
|
|
||||||
|
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
|
||||||
|
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
test | 8 ++++++--
|
||||||
|
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/test b/test
|
||||||
|
index 61d9ee83..b244453b 100755
|
||||||
|
--- a/test
|
||||||
|
+++ b/test
|
||||||
|
@@ -107,8 +107,12 @@ do_test() {
|
||||||
|
echo -ne "$_script... "
|
||||||
|
if ( set -ex ; . $_script ) &> $targetdir/log
|
||||||
|
then
|
||||||
|
- dmesg | grep -iq "error\|call trace\|segfault" &&
|
||||||
|
- die "dmesg prints errors when testing $_basename!"
|
||||||
|
+ if [ -f "${_script}.inject_error" ]; then
|
||||||
|
+ echo "dmesg checking is skipped because test inject error"
|
||||||
|
+ else
|
||||||
|
+ dmesg | grep -iq "error\|call trace\|segfault" &&
|
||||||
|
+ die "dmesg prints errors when testing $_basename!"
|
||||||
|
+ fi
|
||||||
|
echo "succeeded"
|
||||||
|
_fail=0
|
||||||
|
else
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,122 @@
|
|||||||
|
From 3973f65293ce69ddd7c19be9a7a796abfe80e370 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Kuai <yukuai3@huawei.com>
|
||||||
|
Date: Mon, 29 May 2023 21:28:21 +0800
|
||||||
|
Subject: [PATCH 146/165] tests: add a regression test for raid10 deadlock
|
||||||
|
|
||||||
|
The deadlock is described in [1], it's fixed first by [2], however,
|
||||||
|
it turns out this commit will trigger other problems[3], hence this
|
||||||
|
commit will be reverted and the deadlock is supposed to be fixed by [1].
|
||||||
|
|
||||||
|
[1] https://lore.kernel.org/linux-raid/20230322064122.2384589-5-yukuai1@huaweicloud.com/
|
||||||
|
[2] https://lore.kernel.org/linux-raid/20220621031129.24778-1-guoqing.jiang@linux.dev/
|
||||||
|
[3] https://lore.kernel.org/linux-raid/20230322064122.2384589-2-yukuai1@huaweicloud.com/
|
||||||
|
|
||||||
|
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
tests/24raid10deadlock | 88 +++++++++++++++++++++++++++++
|
||||||
|
tests/24raid10deadlock.inject_error | 0
|
||||||
|
2 files changed, 88 insertions(+)
|
||||||
|
create mode 100644 tests/24raid10deadlock
|
||||||
|
create mode 100644 tests/24raid10deadlock.inject_error
|
||||||
|
|
||||||
|
diff --git a/tests/24raid10deadlock b/tests/24raid10deadlock
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..ee330aa9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/24raid10deadlock
|
||||||
|
@@ -0,0 +1,88 @@
|
||||||
|
+devs="$dev0 $dev1 $dev2 $dev3"
|
||||||
|
+runtime=120
|
||||||
|
+pid=""
|
||||||
|
+action_pid=""
|
||||||
|
+
|
||||||
|
+set_up_injection()
|
||||||
|
+{
|
||||||
|
+ echo -1 > /sys/kernel/debug/fail_make_request/times
|
||||||
|
+ echo 1 > /sys/kernel/debug/fail_make_request/probability
|
||||||
|
+ echo 0 > /sys/kernel/debug/fail_make_request/verbose
|
||||||
|
+ echo 1 > /sys/block/${1##*/}/make-it-fail
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+clean_up_injection()
|
||||||
|
+{
|
||||||
|
+ echo 0 > /sys/block/${1##*/}/make-it-fail
|
||||||
|
+ echo 0 > /sys/kernel/debug/fail_make_request/times
|
||||||
|
+ echo 0 > /sys/kernel/debug/fail_make_request/probability
|
||||||
|
+ echo 2 > /sys/kernel/debug/fail_make_request/verbose
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+test_rdev()
|
||||||
|
+{
|
||||||
|
+ while true; do
|
||||||
|
+ mdadm -f $md0 $1 &> /dev/null
|
||||||
|
+ mdadm -r $md0 $1 &> /dev/null
|
||||||
|
+ mdadm --zero-superblock $1 &> /dev/null
|
||||||
|
+ mdadm -a $md0 $1 &> /dev/null
|
||||||
|
+ sleep $2
|
||||||
|
+ done
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+test_write_action()
|
||||||
|
+{
|
||||||
|
+ while true; do
|
||||||
|
+ echo frozen > /sys/block/md0/md/sync_action
|
||||||
|
+ echo idle > /sys/block/md0/md/sync_action
|
||||||
|
+ sleep 0.1
|
||||||
|
+ done
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+set_up_test()
|
||||||
|
+{
|
||||||
|
+ fio -h &> /dev/null || die "fio not found"
|
||||||
|
+
|
||||||
|
+ # create a simple raid10
|
||||||
|
+ mdadm -Cv -R -n 4 -l10 $md0 $devs || die "create raid10 failed"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+clean_up_test()
|
||||||
|
+{
|
||||||
|
+ clean_up_injection $dev0
|
||||||
|
+ pkill -9 fio
|
||||||
|
+ kill -9 $pid
|
||||||
|
+ kill -9 $action_pid
|
||||||
|
+
|
||||||
|
+ sleep 1
|
||||||
|
+
|
||||||
|
+ if ps $action_pid | tail -1 | awk '{print $3}' | grep D; then
|
||||||
|
+ die "thread that is writing sysfs is stuck in D state, deadlock is triggered"
|
||||||
|
+ fi
|
||||||
|
+ mdadm -S $md0
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+cat /sys/kernel/debug/fail_make_request/times || die "fault injection is not enabled"
|
||||||
|
+
|
||||||
|
+trap 'clean_up_test' EXIT
|
||||||
|
+
|
||||||
|
+set_up_test || die "set up test failed"
|
||||||
|
+
|
||||||
|
+# backgroup io pressure
|
||||||
|
+fio -filename=$md0 -rw=randwrite -direct=1 -name=test -bs=4k -numjobs=16 -iodepth=16 &
|
||||||
|
+
|
||||||
|
+# trigger add/remove device by io failure
|
||||||
|
+set_up_injection $dev0
|
||||||
|
+test_rdev $dev0 2 &
|
||||||
|
+pid="$pid $!"
|
||||||
|
+
|
||||||
|
+# add/remove device directly
|
||||||
|
+test_rdev $dev3 10 &
|
||||||
|
+pid="$pid $!"
|
||||||
|
+
|
||||||
|
+test_write_action &
|
||||||
|
+action_pid="$!"
|
||||||
|
+
|
||||||
|
+sleep $runtime
|
||||||
|
+
|
||||||
|
+exit 0
|
||||||
|
diff --git a/tests/24raid10deadlock.inject_error b/tests/24raid10deadlock.inject_error
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..e69de29b
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,87 @@
|
|||||||
|
From 9d0fb58f3b1314678564b4ac7bfb19942acc8926 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Kuai <yukuai3@huawei.com>
|
||||||
|
Date: Mon, 29 May 2023 21:28:22 +0800
|
||||||
|
Subject: [PATCH 147/165] tests: add a regression test for raid456 deadlock
|
||||||
|
|
||||||
|
The deadlock is described in [1], as the last patch described, it's
|
||||||
|
fixed first by [2], however this fix will be reverted and the deadlock
|
||||||
|
is supposed to be fixed by [3].
|
||||||
|
|
||||||
|
[1] https://lore.kernel.org/linux-raid/5ed54ffc-ce82-bf66-4eff-390cb23bc1ac@molgen.mpg.de/T/#t
|
||||||
|
[2] https://lore.kernel.org/linux-raid/20220621031129.24778-1-guoqing.jiang@linux.dev/
|
||||||
|
[3] https://lore.kernel.org/linux-raid/20230322064122.2384589-5-yukuai1@huaweicloud.com/
|
||||||
|
|
||||||
|
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
tests/24raid456deadlock | 58 +++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 58 insertions(+)
|
||||||
|
create mode 100644 tests/24raid456deadlock
|
||||||
|
|
||||||
|
diff --git a/tests/24raid456deadlock b/tests/24raid456deadlock
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..80e6e97e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/24raid456deadlock
|
||||||
|
@@ -0,0 +1,58 @@
|
||||||
|
+devs="$dev0 $dev1 $dev2 $dev3 $dev4 $dev5"
|
||||||
|
+runtime=120
|
||||||
|
+pid=""
|
||||||
|
+old=`cat /proc/sys/vm/dirty_background_ratio`
|
||||||
|
+
|
||||||
|
+test_write_action()
|
||||||
|
+{
|
||||||
|
+ while true; do
|
||||||
|
+ echo check > /sys/block/md0/md/sync_action &> /dev/null
|
||||||
|
+ sleep 0.1
|
||||||
|
+ echo idle > /sys/block/md0/md/sync_action &> /dev/null
|
||||||
|
+ done
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+test_write_back()
|
||||||
|
+{
|
||||||
|
+ fio -filename=$md0 -bs=4k -rw=write -numjobs=1 -name=test \
|
||||||
|
+ -time_based -runtime=$runtime &> /dev/null
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+set_up_test()
|
||||||
|
+{
|
||||||
|
+ fio -h &> /dev/null || die "fio not found"
|
||||||
|
+
|
||||||
|
+ # create a simple raid6
|
||||||
|
+ mdadm -Cv -R -n 6 -l6 $md0 $devs --assume-clean || die "create raid6 failed"
|
||||||
|
+
|
||||||
|
+ # trigger dirty pages write back
|
||||||
|
+ echo 0 > /proc/sys/vm/dirty_background_ratio
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+clean_up_test()
|
||||||
|
+{
|
||||||
|
+ echo $old > /proc/sys/vm/dirty_background_ratio
|
||||||
|
+
|
||||||
|
+ pkill -9 fio
|
||||||
|
+ kill -9 $pid
|
||||||
|
+
|
||||||
|
+ sleep 1
|
||||||
|
+
|
||||||
|
+ if ps $pid | tail -1 | awk '{print $3}' | grep D; then
|
||||||
|
+ die "thread that is writing sysfs is stuck in D state, deadlock is triggered"
|
||||||
|
+ fi
|
||||||
|
+ mdadm -S $md0
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+trap 'clean_up_test' EXIT
|
||||||
|
+
|
||||||
|
+set_up_test || die "set up test failed"
|
||||||
|
+
|
||||||
|
+test_write_back &
|
||||||
|
+
|
||||||
|
+test_write_action &
|
||||||
|
+pid="$!"
|
||||||
|
+
|
||||||
|
+sleep $runtime
|
||||||
|
+
|
||||||
|
+exit 0
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,59 @@
|
|||||||
|
From 4db8a3d452daaf2def41ca45c36e36c5781627ac Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Kuai <yukuai3@huawei.com>
|
||||||
|
Date: Mon, 29 May 2023 21:28:23 +0800
|
||||||
|
Subject: [PATCH 148/165] tests: add a regression test that raid456 can't
|
||||||
|
assemble
|
||||||
|
|
||||||
|
If recovery is interrupted and reshape is started, then this array can't
|
||||||
|
assemble anymore. The problem is supposed to be fixed by [1].
|
||||||
|
|
||||||
|
[1] https://lore.kernel.org/linux-raid/20230529031045.1760883-1-yukuai1@huaweicloud.com/
|
||||||
|
|
||||||
|
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
tests/25raid456-reshape-while-recovery | 32 ++++++++++++++++++++++++++
|
||||||
|
1 file changed, 32 insertions(+)
|
||||||
|
create mode 100644 tests/25raid456-reshape-while-recovery
|
||||||
|
|
||||||
|
diff --git a/tests/25raid456-reshape-while-recovery b/tests/25raid456-reshape-while-recovery
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..b9f871f2
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/25raid456-reshape-while-recovery
|
||||||
|
@@ -0,0 +1,32 @@
|
||||||
|
+devs="$dev0 $dev1 $dev2"
|
||||||
|
+
|
||||||
|
+set_up_test()
|
||||||
|
+{
|
||||||
|
+ mdadm -Cv -R -n 3 -l5 $md0 $devs --assume-clean --size=50M || die "create array failed"
|
||||||
|
+ mdadm -a $md0 $dev3 $dev4 || die "failed to bind new disk to array"
|
||||||
|
+ echo 1000 > /sys/block/md0/md/sync_speed_max
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+clean_up_test()
|
||||||
|
+{
|
||||||
|
+ mdadm -S $md0
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+trap 'clean_up_test' EXIT
|
||||||
|
+
|
||||||
|
+set_up_test || die "set up test failed"
|
||||||
|
+
|
||||||
|
+# set up replacement
|
||||||
|
+echo want_replacement > /sys/block/md0/md/rd0/state
|
||||||
|
+sleep 1
|
||||||
|
+
|
||||||
|
+# trigger reshape
|
||||||
|
+echo frozen > /sys/block/md0/md/sync_action
|
||||||
|
+mdadm --grow -l 6 $md0
|
||||||
|
+sleep 1
|
||||||
|
+
|
||||||
|
+# reassemeble array
|
||||||
|
+mdadm -S $md0 || die "can't stop array"
|
||||||
|
+mdadm --assemble $md0 $devs $dev3 $dev4 || die "can't assemble array"
|
||||||
|
+
|
||||||
|
+exit 0
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,58 @@
|
|||||||
|
From 8d45abd0c317d3f4971b779b4f8d1e33b5490dac Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Kuai <yukuai3@huawei.com>
|
||||||
|
Date: Mon, 29 May 2023 21:28:24 +0800
|
||||||
|
Subject: [PATCH 149/165] tests: add a regression test that raid456 can't
|
||||||
|
assemble again
|
||||||
|
|
||||||
|
This is a regression test for commit 0aecb06e2249 ("md/raid5: don't allow
|
||||||
|
replacement while reshape is in progress").
|
||||||
|
|
||||||
|
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
tests/25raid456-recovery-while-reshape | 33 ++++++++++++++++++++++++++
|
||||||
|
1 file changed, 33 insertions(+)
|
||||||
|
create mode 100644 tests/25raid456-recovery-while-reshape
|
||||||
|
|
||||||
|
diff --git a/tests/25raid456-recovery-while-reshape b/tests/25raid456-recovery-while-reshape
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..3f6251bf
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/25raid456-recovery-while-reshape
|
||||||
|
@@ -0,0 +1,33 @@
|
||||||
|
+devs="$dev0 $dev1 $dev2"
|
||||||
|
+
|
||||||
|
+set_up_test()
|
||||||
|
+{
|
||||||
|
+ mdadm -Cv -R -n 3 -l5 $md0 $devs --assume-clean --size=50M || die "create array failed"
|
||||||
|
+ mdadm -a $md0 $dev3 $dev4 || die "failed to bind new disk to array"
|
||||||
|
+ echo 1000 > /sys/block/md0/md/sync_speed_max
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+clean_up_test()
|
||||||
|
+{
|
||||||
|
+ mdadm -S $md0
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+trap 'clean_up_test' EXIT
|
||||||
|
+
|
||||||
|
+set_up_test || die "set up test failed"
|
||||||
|
+
|
||||||
|
+# trigger reshape
|
||||||
|
+mdadm --grow -l 6 $md0
|
||||||
|
+sleep 1
|
||||||
|
+
|
||||||
|
+# set up replacement
|
||||||
|
+echo frozen > /sys/block/md0/md/sync_action
|
||||||
|
+echo want_replacement > /sys/block/md0/md/rd0/state
|
||||||
|
+echo reshape > /sys/block/md0/md/sync_action
|
||||||
|
+sleep 1
|
||||||
|
+
|
||||||
|
+# reassemeble array
|
||||||
|
+mdadm -S $md0 || die "can't stop array"
|
||||||
|
+mdadm --assemble $md0 $devs $dev3 $dev4 || die "can't assemble array"
|
||||||
|
+
|
||||||
|
+exit 0
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,60 @@
|
|||||||
|
From 481433482942c2ee2990965af394eff059990901 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Kuai <yukuai3@huawei.com>
|
||||||
|
Date: Mon, 29 May 2023 21:28:25 +0800
|
||||||
|
Subject: [PATCH 150/165] tests: add a regression test that reshape can corrupt
|
||||||
|
data
|
||||||
|
|
||||||
|
This is a regression test for commit 1544e95c6dd8 ("md: fix data
|
||||||
|
corruption for raid456 when reshape restart while grow up").
|
||||||
|
|
||||||
|
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
tests/25raid456-reshape-corrupt-data | 35 ++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 35 insertions(+)
|
||||||
|
create mode 100644 tests/25raid456-reshape-corrupt-data
|
||||||
|
|
||||||
|
diff --git a/tests/25raid456-reshape-corrupt-data b/tests/25raid456-reshape-corrupt-data
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..fdb875fb
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/25raid456-reshape-corrupt-data
|
||||||
|
@@ -0,0 +1,35 @@
|
||||||
|
+devs="$dev0 $dev1 $dev2"
|
||||||
|
+
|
||||||
|
+set_up_test()
|
||||||
|
+{
|
||||||
|
+ mdadm -Cv -R -n 3 -l5 $md0 $devs --size=50M || die "create array failed"
|
||||||
|
+ mdadm -a $md0 $dev3 || die "failed to bind new disk to array"
|
||||||
|
+ mkfs.xfs -f $md0 || die "mkfs failed"
|
||||||
|
+ xfs_ncheck $md0 || die "check fs failed"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+clean_up_test()
|
||||||
|
+{
|
||||||
|
+ mdadm -S $md0
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+trap 'clean_up_test' EXIT
|
||||||
|
+
|
||||||
|
+set_up_test || die "set up test failed"
|
||||||
|
+
|
||||||
|
+# trigger reshape
|
||||||
|
+echo 1000 > /sys/block/md0/md/sync_speed_max
|
||||||
|
+mdadm --grow -l 6 $md0
|
||||||
|
+sleep 1
|
||||||
|
+
|
||||||
|
+# stop and start reshape
|
||||||
|
+echo frozen > /sys/block/md0/md/sync_action
|
||||||
|
+echo system > /sys/block/md0/md/sync_speed_max
|
||||||
|
+echo reshape > /sys/block/md0/md/sync_action
|
||||||
|
+
|
||||||
|
+mdadm -W $md0
|
||||||
|
+
|
||||||
|
+# check if data is corrupted
|
||||||
|
+xfs_ncheck $md0 || die "data is corrupted after reshape"
|
||||||
|
+
|
||||||
|
+exit 0
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,59 @@
|
|||||||
|
From c6c7bce5a3064ac9d2956ae42ecab27f2e33dc2b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Kuai <yukuai3@huawei.com>
|
||||||
|
Date: Mon, 29 May 2023 21:28:26 +0800
|
||||||
|
Subject: [PATCH 151/165] tests: add a regression test for raid456 deadlock
|
||||||
|
again
|
||||||
|
|
||||||
|
This is a regression test for commit ("md/raid5: fix a deadlock in the
|
||||||
|
case that reshape is interrupted").
|
||||||
|
|
||||||
|
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
tests/25raid456-reshape-deadlock | 34 ++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 34 insertions(+)
|
||||||
|
create mode 100644 tests/25raid456-reshape-deadlock
|
||||||
|
|
||||||
|
diff --git a/tests/25raid456-reshape-deadlock b/tests/25raid456-reshape-deadlock
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..bfa0cc56
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/25raid456-reshape-deadlock
|
||||||
|
@@ -0,0 +1,34 @@
|
||||||
|
+devs="$dev0 $dev1 $dev2"
|
||||||
|
+
|
||||||
|
+set_up_test()
|
||||||
|
+{
|
||||||
|
+ mdadm -Cv -R -n 3 -l5 $md0 $devs --size=50M || die "create array failed"
|
||||||
|
+ mdadm -a $md0 $dev3 || die "failed to bind new disk to array"
|
||||||
|
+ echo 1000 > /sys/block/md0/md/sync_speed_max
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+clean_up_test()
|
||||||
|
+{
|
||||||
|
+ echo idle > /sys/block/md0/md/sync_action
|
||||||
|
+ mdadm -S $md0
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+trap 'clean_up_test' EXIT
|
||||||
|
+
|
||||||
|
+set_up_test || die "set up test failed"
|
||||||
|
+
|
||||||
|
+# trigger reshape
|
||||||
|
+mdadm --grow -l 6 $md0
|
||||||
|
+sleep 1
|
||||||
|
+
|
||||||
|
+# stop reshape
|
||||||
|
+echo frozen > /sys/block/md0/md/sync_action
|
||||||
|
+
|
||||||
|
+# read accross reshape
|
||||||
|
+dd if=$md0 of=/dev/NULL bs=1m count=100 iflag=direct &> /dev/null &
|
||||||
|
+sleep 2
|
||||||
|
+
|
||||||
|
+# suspend array
|
||||||
|
+echo 1 > /sys/block/md0/md/suspend_lo
|
||||||
|
+
|
||||||
|
+exit 0
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
193
SOURCES/0152-tests-create-names_template.patch
Normal file
193
SOURCES/0152-tests-create-names_template.patch
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
From d5fee8654e41dc4067dfdc3312542f1f43ebe884 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Thu, 1 Jun 2023 09:27:45 +0200
|
||||||
|
Subject: [PATCH 152/165] tests: create names_template
|
||||||
|
|
||||||
|
Create templates directory and names_template. Move code from
|
||||||
|
00createnames. This code will be reused for 00confnames in next patch.
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
tests/00createnames | 86 +++++++---------------------------
|
||||||
|
tests/templates/names_template | 53 +++++++++++++++++++++
|
||||||
|
2 files changed, 70 insertions(+), 69 deletions(-)
|
||||||
|
create mode 100644 tests/templates/names_template
|
||||||
|
|
||||||
|
diff --git a/tests/00createnames b/tests/00createnames
|
||||||
|
index 64b81b92..064eeef2 100644
|
||||||
|
--- a/tests/00createnames
|
||||||
|
+++ b/tests/00createnames
|
||||||
|
@@ -1,93 +1,41 @@
|
||||||
|
set -x -e
|
||||||
|
+. tests/templates/names_template
|
||||||
|
|
||||||
|
# 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"
|
||||||
|
+names_create "/dev/md/name"
|
||||||
|
+names_verify "/dev/md127" "name" "name"
|
||||||
|
mdadm -S "/dev/md127"
|
||||||
|
|
||||||
|
-_create "name"
|
||||||
|
-_verify "/dev/md127" "name" "name"
|
||||||
|
+names_create "name"
|
||||||
|
+names_verify "/dev/md127" "name" "name"
|
||||||
|
mdadm -S "/dev/md127"
|
||||||
|
|
||||||
|
# Use 'mdX' as name.
|
||||||
|
-_create "/dev/md/md0"
|
||||||
|
-_verify "/dev/md127" "md0" "md0"
|
||||||
|
+names_create "/dev/md/md0"
|
||||||
|
+names_verify "/dev/md127" "md0" "md0"
|
||||||
|
mdadm -S "/dev/md127"
|
||||||
|
|
||||||
|
-_create "md0"
|
||||||
|
-_verify "/dev/md127" "md0" "md0"
|
||||||
|
+names_create "md0"
|
||||||
|
+names_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"
|
||||||
|
+names_create "/dev/md/devnode" "name"
|
||||||
|
+names_verify "/dev/md127" "devnode" "name"
|
||||||
|
mdadm -S "/dev/md127"
|
||||||
|
|
||||||
|
-_create "devnode" "name"
|
||||||
|
-_verify "/dev/md127" "devnode" "name"
|
||||||
|
+names_create "devnode" "name"
|
||||||
|
+names_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"
|
||||||
|
+names_create "/dev/md0"
|
||||||
|
+names_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"
|
||||||
|
+names_create "/dev/md0" "name"
|
||||||
|
+names_verify "/dev/md0" "empty" "name"
|
||||||
|
mdadm -S "/dev/md0"
|
||||||
|
diff --git a/tests/templates/names_template b/tests/templates/names_template
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..9f09be9e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/templates/names_template
|
||||||
|
@@ -0,0 +1,53 @@
|
||||||
|
+# NAME is optional. Testing with native 1.2 superblock.
|
||||||
|
+function names_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" --metadata=1.2 -l0 -n 1 $dev0 --force
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ if [[ "$?" != "0" ]]; then
|
||||||
|
+ echo "Cannot create device."
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+# Three properties to check:
|
||||||
|
+# - devnode name
|
||||||
|
+# - link in /dev/md/ (MD_DEVNAME property from --detail --export)
|
||||||
|
+# - name in metadata (MD_NAME property from --detail --export)- that works only with 1.2 sb.
|
||||||
|
+function names_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"
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ if [[ "$RES" != "$EXPECTED" ]]; then
|
||||||
|
+ echo "$RES doesn't match $EXPECTED."
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ local RES="$(mdadm -D --export $DEVNODE_NAME | 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
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
164
SOURCES/0153-tests-create-00confnames.patch
Normal file
164
SOURCES/0153-tests-create-00confnames.patch
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
From 569a23425939e4bfc7b4d7f871d8510bb968f892 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Thu, 1 Jun 2023 09:27:46 +0200
|
||||||
|
Subject: [PATCH 153/165] tests: create 00confnames
|
||||||
|
|
||||||
|
The test is an attempt to document current implementation of devnode
|
||||||
|
and name handling for config entries. It is focused on incremental-
|
||||||
|
default way of array assembling on boot.
|
||||||
|
The expectations are aligned to current implementation for native
|
||||||
|
metadata because it is the most complicated scenario- both variables
|
||||||
|
can be set.
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
tests/00confnames | 107 +++++++++++++++++++++++++++++++++
|
||||||
|
tests/templates/names_template | 20 ++++++
|
||||||
|
2 files changed, 127 insertions(+)
|
||||||
|
create mode 100644 tests/00confnames
|
||||||
|
|
||||||
|
diff --git a/tests/00confnames b/tests/00confnames
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..25a7127b
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/00confnames
|
||||||
|
@@ -0,0 +1,107 @@
|
||||||
|
+set -x -e
|
||||||
|
+. tests/templates/names_template
|
||||||
|
+
|
||||||
|
+# Test how <devname> and <name> from config are handled during Incremental assemblation.
|
||||||
|
+# 1-6 <devnode> only tests (no <name> in config).
|
||||||
|
+# 6-10 <devname> and <name> combinations are tested.
|
||||||
|
+# 11-13 corner cases.
|
||||||
|
+
|
||||||
|
+names_create "/dev/md/name"
|
||||||
|
+local _UUID="$(mdadm -D --export /dev/md127 | grep MD_UUID | cut -d'=' -f2)"
|
||||||
|
+[[ "$_UUID" == "" ]] && echo "Cannot obtain UUID for $DEVNODE_NAME" && exit 1
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+# 1. <devname> definition consistent with metadata name.
|
||||||
|
+names_make_conf $_UUID "/dev/md/name" "empty" $config
|
||||||
|
+mdadm -S "/dev/md127"
|
||||||
|
+mdadm -I $dev0 --config=$config
|
||||||
|
+names_verify "/dev/md127" "name" "name"
|
||||||
|
+mdadm -S "/dev/md127"
|
||||||
|
+
|
||||||
|
+# 2. Same as 1, but use short name form of <devname>.
|
||||||
|
+names_make_conf $_UUID "name" "empty" $config
|
||||||
|
+mdadm -I $dev0 --config=$config
|
||||||
|
+names_verify "/dev/md127" "name" "name"
|
||||||
|
+mdadm -S "/dev/md127"
|
||||||
|
+
|
||||||
|
+# 3. Same as 1, but use different <devname> than metadata provides.
|
||||||
|
+names_make_conf $_UUID "/dev/md/other" "empty" $config
|
||||||
|
+mdadm -I $dev0 --config=$config
|
||||||
|
+names_verify "/dev/md127" "other" "name"
|
||||||
|
+mdadm -S "/dev/md127"
|
||||||
|
+
|
||||||
|
+# 4. Same as 3, but use short name form of <devname>.
|
||||||
|
+names_make_conf $_UUID "other" "empty" $config
|
||||||
|
+mdadm -I $dev0 --config=$config
|
||||||
|
+names_verify "/dev/md127" "other" "name"
|
||||||
|
+mdadm -S "/dev/md127"
|
||||||
|
+
|
||||||
|
+# 5. Force particular node creation by setting <devname> to /dev/mdX. Link is not created in this
|
||||||
|
+# case.
|
||||||
|
+names_make_conf $_UUID "/dev/md4" "empty" $config
|
||||||
|
+mdadm -I $dev0 --config=$config
|
||||||
|
+names_verify "/dev/md4" "empty" "name"
|
||||||
|
+mdadm -S "/dev/md4"
|
||||||
|
+
|
||||||
|
+# 6. <devname> set to /dev/mdX, <name> same as in metadata.
|
||||||
|
+# Metadata name and default node used - controversial. Current behavior documented.
|
||||||
|
+names_make_conf $_UUID "/dev/md22" "name" $config
|
||||||
|
+mdadm -I $dev0 --config=$config
|
||||||
|
+names_verify "/dev/md127" "name" "name"
|
||||||
|
+mdadm -S "/dev/md127"
|
||||||
|
+
|
||||||
|
+# 7. <devname> set to /dev/mdX, <name> different than in metadata.
|
||||||
|
+# Metadata name and default node used - controversial. Current behavior documented.
|
||||||
|
+names_make_conf $_UUID "/dev/md8" "other" $config
|
||||||
|
+mdadm -I $dev0 --config=$config
|
||||||
|
+names_verify "/dev/md127" "name" "name"
|
||||||
|
+mdadm -S "/dev/md127"
|
||||||
|
+
|
||||||
|
+# 8. Both <devname> and <name> different than in metadata.
|
||||||
|
+# Metadata name and default node used - controversial. Current behavior documented.
|
||||||
|
+names_make_conf $_UUID "devnode" "other_name" $config
|
||||||
|
+mdadm -I $dev0 --config=$config
|
||||||
|
+names_verify "/dev/md127" "name" "name"
|
||||||
|
+mdadm -S "/dev/md127"
|
||||||
|
+
|
||||||
|
+# 9. <devname> set to metadata name, <name> different than in metadata.
|
||||||
|
+# Metadata name and default node used - controversial. Current behavior documented.
|
||||||
|
+names_make_conf $_UUID "name" "other_name" $config
|
||||||
|
+mdadm -I $dev0 --config=$config
|
||||||
|
+names_verify "/dev/md127" "name" "name"
|
||||||
|
+mdadm -S "/dev/md127"
|
||||||
|
+
|
||||||
|
+# 10. Bad <devname> set, no <name>.
|
||||||
|
+# Metadata name and default node used - expected.
|
||||||
|
+names_make_conf $_UUID "/im/bad/devname" "empty" $config
|
||||||
|
+mdadm -I $dev0 --config=$config
|
||||||
|
+names_verify "/dev/md127" "name" "name"
|
||||||
|
+mdadm -S "/dev/md127"
|
||||||
|
+
|
||||||
|
+# 11. <devname> with some special symbols and locales, no <name>.
|
||||||
|
+# It needs to wait a while for timeout because udev cannot create a link - known issue.
|
||||||
|
+names_make_conf $_UUID "tźż-\.,<>st+-" "empty" $config
|
||||||
|
+mdadm -I $dev0 --config=$config
|
||||||
|
+names_verify "/dev/md127" "tźż-\.,<>st+-" "name"
|
||||||
|
+mdadm -S "/dev/md127"
|
||||||
|
+
|
||||||
|
+# 12. No <devname> and <name> set.
|
||||||
|
+# Metadata name and default node used - expected.
|
||||||
|
+names_make_conf $_UUID "empty" "empty" $config
|
||||||
|
+mdadm -I $dev0 --config=$config
|
||||||
|
+names_verify "/dev/md127" "name" "name"
|
||||||
|
+mdadm -S "/dev/md127"
|
||||||
|
+
|
||||||
|
+# 13. No <devname>, <name> set to /dev/mdX.
|
||||||
|
+# Entry should be ignored, it is not ignored but result is good anyway.
|
||||||
|
+names_make_conf $_UUID "empty" "/dev/md12" $config
|
||||||
|
+mdadm -I $dev0 --config=$config
|
||||||
|
+names_verify "/dev/md127" "name" "name"
|
||||||
|
+mdadm -S "/dev/md127"
|
||||||
|
+
|
||||||
|
+# 13. No <devname>, <name> with special symbols and locales.
|
||||||
|
+# Entry should be ignored, it is not ignored but result is good anyway.
|
||||||
|
+names_make_conf $_UUID "empty" "./\śćń#&" $config
|
||||||
|
+mdadm -I $dev0 --config=$config
|
||||||
|
+names_verify "/dev/md127" "name" "name"
|
||||||
|
+mdadm -S "/dev/md127"
|
||||||
|
diff --git a/tests/templates/names_template b/tests/templates/names_template
|
||||||
|
index 9f09be9e..8d2b5c81 100644
|
||||||
|
--- a/tests/templates/names_template
|
||||||
|
+++ b/tests/templates/names_template
|
||||||
|
@@ -51,3 +51,23 @@ function names_verify() {
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+# Generate ARRAYLINE for tested array.
|
||||||
|
+names_make_conf() {
|
||||||
|
+ local UUID="$1"
|
||||||
|
+ local WANTED_DEVNAME="$2"
|
||||||
|
+ local WANTED_NAME="$3"
|
||||||
|
+ local CONF="$4"
|
||||||
|
+
|
||||||
|
+ local LINE="ARRAY metadata=1.2 UUID=$UUID"
|
||||||
|
+
|
||||||
|
+ if [[ "$WANTED_DEVNAME" != "empty" ]]; then
|
||||||
|
+ LINE="$LINE $WANTED_DEVNAME"
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ if [[ "$WANTED_NAME" != "empty" ]]; then
|
||||||
|
+ LINE="$LINE name=$WANTED_NAME"
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ echo $LINE > $CONF
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
399
SOURCES/0154-mdadm-set-ident.devname-if-applicable.patch
Normal file
399
SOURCES/0154-mdadm-set-ident.devname-if-applicable.patch
Normal file
@ -0,0 +1,399 @@
|
|||||||
|
From 330c07f8e4d26f4f2d068e11f09c9df8a3380087 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Thu, 1 Jun 2023 09:27:47 +0200
|
||||||
|
Subject: [PATCH 154/165] mdadm: set ident.devname if applicable
|
||||||
|
|
||||||
|
This patch tries to propagate the usage of struct mddev_ident for cmdline
|
||||||
|
where it is applicable. To avoid regression, this value is derived
|
||||||
|
from devlist->devname for applicable modes only.
|
||||||
|
As a result, the whole structure is passed to some functions. It produces
|
||||||
|
some changes for Build, Create and Assemble.
|
||||||
|
No functional changes intended.
|
||||||
|
|
||||||
|
The goal of the change is to unify devname validation which is done in
|
||||||
|
next patches.
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Build.c | 21 +++++++++------------
|
||||||
|
Create.c | 35 ++++++++++++++++------------------
|
||||||
|
mdadm.c | 57 +++++++++++++++++++++++++-------------------------------
|
||||||
|
mdadm.h | 13 +++++--------
|
||||||
|
4 files changed, 55 insertions(+), 71 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Build.c b/Build.c
|
||||||
|
index 8d6f6f58..657ab315 100644
|
||||||
|
--- a/Build.c
|
||||||
|
+++ b/Build.c
|
||||||
|
@@ -24,8 +24,8 @@
|
||||||
|
|
||||||
|
#include "mdadm.h"
|
||||||
|
|
||||||
|
-int Build(char *mddev, struct mddev_dev *devlist,
|
||||||
|
- struct shape *s, struct context *c)
|
||||||
|
+int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s,
|
||||||
|
+ struct context *c)
|
||||||
|
{
|
||||||
|
/* Build a linear or raid0 arrays without superblocks
|
||||||
|
* We cannot really do any checks, we just do it.
|
||||||
|
@@ -75,13 +75,12 @@ int Build(char *mddev, struct mddev_dev *devlist,
|
||||||
|
|
||||||
|
/* We need to create the device. It can have no name. */
|
||||||
|
map_lock(&map);
|
||||||
|
- mdfd = create_mddev(mddev, NULL, c->autof, LOCAL,
|
||||||
|
+ mdfd = create_mddev(ident->devname, NULL, c->autof, LOCAL,
|
||||||
|
chosen_name, 0);
|
||||||
|
if (mdfd < 0) {
|
||||||
|
map_unlock(&map);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
- mddev = chosen_name;
|
||||||
|
|
||||||
|
map_update(&map, fd2devnm(mdfd), "none", uuid, chosen_name);
|
||||||
|
map_unlock(&map);
|
||||||
|
@@ -93,7 +92,7 @@ int Build(char *mddev, struct mddev_dev *devlist,
|
||||||
|
array.nr_disks = s->raiddisks;
|
||||||
|
array.raid_disks = s->raiddisks;
|
||||||
|
array.md_minor = 0;
|
||||||
|
- if (fstat_is_blkdev(mdfd, mddev, &rdev))
|
||||||
|
+ if (fstat_is_blkdev(mdfd, chosen_name, &rdev))
|
||||||
|
array.md_minor = minor(rdev);
|
||||||
|
array.not_persistent = 1;
|
||||||
|
array.state = 0; /* not clean, but no errors */
|
||||||
|
@@ -108,8 +107,7 @@ int Build(char *mddev, struct mddev_dev *devlist,
|
||||||
|
array.chunk_size = s->chunk*1024;
|
||||||
|
array.layout = s->layout;
|
||||||
|
if (md_set_array_info(mdfd, &array)) {
|
||||||
|
- pr_err("md_set_array_info() failed for %s: %s\n",
|
||||||
|
- mddev, strerror(errno));
|
||||||
|
+ pr_err("md_set_array_info() failed for %s: %s\n", chosen_name, strerror(errno));
|
||||||
|
goto abort;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -178,8 +176,8 @@ int Build(char *mddev, struct mddev_dev *devlist,
|
||||||
|
}
|
||||||
|
if (bitmap_fd >= 0) {
|
||||||
|
if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
|
||||||
|
- pr_err("Cannot set bitmap file for %s: %s\n",
|
||||||
|
- mddev, strerror(errno));
|
||||||
|
+ pr_err("Cannot set bitmap file for %s: %s\n", chosen_name,
|
||||||
|
+ strerror(errno));
|
||||||
|
goto abort;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -193,9 +191,8 @@ int Build(char *mddev, struct mddev_dev *devlist,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->verbose >= 0)
|
||||||
|
- pr_err("array %s built and started.\n",
|
||||||
|
- mddev);
|
||||||
|
- wait_for(mddev, mdfd);
|
||||||
|
+ pr_err("array %s built and started.\n", chosen_name);
|
||||||
|
+ wait_for(chosen_name, mdfd);
|
||||||
|
close(mdfd);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
diff --git a/Create.c b/Create.c
|
||||||
|
index ea6a4745..a280c7bc 100644
|
||||||
|
--- a/Create.c
|
||||||
|
+++ b/Create.c
|
||||||
|
@@ -471,11 +471,8 @@ out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int Create(struct supertype *st, char *mddev,
|
||||||
|
- char *name, int *uuid,
|
||||||
|
- int subdevs, struct mddev_dev *devlist,
|
||||||
|
- struct shape *s,
|
||||||
|
- struct context *c)
|
||||||
|
+int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
|
||||||
|
+ struct mddev_dev *devlist, struct shape *s, struct context *c)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Create a new raid array.
|
||||||
|
@@ -497,6 +494,8 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
unsigned long long minsize = 0, maxsize = 0;
|
||||||
|
char *mindisc = NULL;
|
||||||
|
char *maxdisc = NULL;
|
||||||
|
+ char *name = ident->name;
|
||||||
|
+ int *uuid = ident->uuid_set == 1 ? ident->uuid : NULL;
|
||||||
|
int dnum;
|
||||||
|
struct mddev_dev *dv;
|
||||||
|
dev_t rdev;
|
||||||
|
@@ -1015,7 +1014,7 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
|
||||||
|
/* We need to create the device */
|
||||||
|
map_lock(&map);
|
||||||
|
- mdfd = create_mddev(mddev, name, c->autof, LOCAL, chosen_name, 1);
|
||||||
|
+ mdfd = create_mddev(ident->devname, ident->name, c->autof, LOCAL, chosen_name, 1);
|
||||||
|
if (mdfd < 0) {
|
||||||
|
map_unlock(&map);
|
||||||
|
return 1;
|
||||||
|
@@ -1032,7 +1031,6 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
udev_unblock();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
- mddev = chosen_name;
|
||||||
|
|
||||||
|
memset(&inf, 0, sizeof(inf));
|
||||||
|
md_get_array_info(mdfd, &inf);
|
||||||
|
@@ -1050,7 +1048,7 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
* with, but it chooses to trust me instead. Sigh
|
||||||
|
*/
|
||||||
|
info.array.md_minor = 0;
|
||||||
|
- if (fstat_is_blkdev(mdfd, mddev, &rdev))
|
||||||
|
+ if (fstat_is_blkdev(mdfd, chosen_name, &rdev))
|
||||||
|
info.array.md_minor = minor(rdev);
|
||||||
|
info.array.not_persistent = 0;
|
||||||
|
|
||||||
|
@@ -1102,8 +1100,8 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
info.array.layout = s->layout;
|
||||||
|
info.array.chunk_size = s->chunk*1024;
|
||||||
|
|
||||||
|
- if (name == NULL || *name == 0) {
|
||||||
|
- /* base name on mddev */
|
||||||
|
+ if (*name == 0) {
|
||||||
|
+ /* base name on devname */
|
||||||
|
/* /dev/md0 -> 0
|
||||||
|
* /dev/md_d0 -> d0
|
||||||
|
* /dev/md_foo -> foo
|
||||||
|
@@ -1113,15 +1111,16 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
* /dev/mdhome -> home
|
||||||
|
*/
|
||||||
|
/* FIXME compare this with rules in create_mddev */
|
||||||
|
- name = strrchr(mddev, '/');
|
||||||
|
+ name = strrchr(chosen_name, '/');
|
||||||
|
+
|
||||||
|
if (name) {
|
||||||
|
name++;
|
||||||
|
if (strncmp(name, "md_", 3) == 0 &&
|
||||||
|
- strlen(name) > 3 && (name-mddev) == 5 /* /dev/ */)
|
||||||
|
+ strlen(name) > 3 && (name - chosen_name) == 5 /* /dev/ */)
|
||||||
|
name += 3;
|
||||||
|
else if (strncmp(name, "md", 2) == 0 &&
|
||||||
|
strlen(name) > 2 && isdigit(name[2]) &&
|
||||||
|
- (name-mddev) == 5 /* /dev/ */)
|
||||||
|
+ (name - chosen_name) == 5 /* /dev/ */)
|
||||||
|
name += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1215,8 +1214,7 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
}
|
||||||
|
rv = set_array_info(mdfd, st, &info);
|
||||||
|
if (rv) {
|
||||||
|
- pr_err("failed to set array info for %s: %s\n",
|
||||||
|
- mddev, strerror(errno));
|
||||||
|
+ pr_err("failed to set array info for %s: %s\n", chosen_name, strerror(errno));
|
||||||
|
goto abort_locked;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1237,8 +1235,7 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
goto abort_locked;
|
||||||
|
}
|
||||||
|
if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
|
||||||
|
- pr_err("Cannot set bitmap file for %s: %s\n",
|
||||||
|
- mddev, strerror(errno));
|
||||||
|
+ pr_err("Cannot set bitmap file for %s: %s\n", chosen_name, strerror(errno));
|
||||||
|
goto abort_locked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1254,7 +1251,7 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
* create links */
|
||||||
|
sysfs_uevent(&info, "change");
|
||||||
|
if (c->verbose >= 0)
|
||||||
|
- pr_err("container %s prepared.\n", mddev);
|
||||||
|
+ pr_err("container %s prepared.\n", chosen_name);
|
||||||
|
wait_for(chosen_name, mdfd);
|
||||||
|
} else if (c->runstop == 1 || subdevs >= s->raiddisks) {
|
||||||
|
if (st->ss->external) {
|
||||||
|
@@ -1312,7 +1309,7 @@ int Create(struct supertype *st, char *mddev,
|
||||||
|
ioctl(mdfd, RESTART_ARRAY_RW, NULL);
|
||||||
|
}
|
||||||
|
if (c->verbose >= 0)
|
||||||
|
- pr_info("array %s started.\n", mddev);
|
||||||
|
+ pr_info("array %s started.\n", chosen_name);
|
||||||
|
if (st->ss->external && st->container_devnm[0]) {
|
||||||
|
if (need_mdmon)
|
||||||
|
start_mdmon(st->container_devnm);
|
||||||
|
diff --git a/mdadm.c b/mdadm.c
|
||||||
|
index 22d1c53b..0a56ed26 100644
|
||||||
|
--- a/mdadm.c
|
||||||
|
+++ b/mdadm.c
|
||||||
|
@@ -1290,37 +1290,39 @@ int main(int argc, char *argv[])
|
||||||
|
pr_err("an md device must be given in this mode\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
+ ident.devname = devlist->devname;
|
||||||
|
+
|
||||||
|
if ((int)ident.super_minor == -2 && c.autof) {
|
||||||
|
pr_err("--super-minor=dev is incompatible with --auto\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
if (mode == MANAGE || mode == GROW) {
|
||||||
|
- mdfd = open_mddev(devlist->devname, 1);
|
||||||
|
+ mdfd = open_mddev(ident.devname, 1);
|
||||||
|
if (mdfd < 0)
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
ret = fstat(mdfd, &stb);
|
||||||
|
if (ret) {
|
||||||
|
- pr_err("fstat failed on %s.\n", devlist->devname);
|
||||||
|
+ pr_err("fstat failed on %s.\n", ident.devname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
- char *bname = basename(devlist->devname);
|
||||||
|
+ char *bname = basename(ident.devname);
|
||||||
|
|
||||||
|
if (strlen(bname) > MD_NAME_MAX) {
|
||||||
|
- pr_err("Name %s is too long.\n", devlist->devname);
|
||||||
|
+ pr_err("Name %s is too long.\n", ident.devname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = stat(devlist->devname, &stb);
|
||||||
|
+ ret = stat(ident.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);
|
||||||
|
+ ident.devname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ret && !stat_is_md_dev(&stb)) {
|
||||||
|
- pr_err("device %s exists but is not an md array.\n", devlist->devname);
|
||||||
|
+ pr_err("device %s exists but is not an md array.\n", ident.devname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1408,17 +1410,17 @@ int main(int argc, char *argv[])
|
||||||
|
case MANAGE:
|
||||||
|
/* readonly, add/remove, readwrite, runstop */
|
||||||
|
if (c.readonly > 0)
|
||||||
|
- rv = Manage_ro(devlist->devname, mdfd, c.readonly);
|
||||||
|
+ rv = Manage_ro(ident.devname, mdfd, c.readonly);
|
||||||
|
if (!rv && devs_found > 1)
|
||||||
|
- rv = Manage_subdevs(devlist->devname, mdfd,
|
||||||
|
+ rv = Manage_subdevs(ident.devname, mdfd,
|
||||||
|
devlist->next, c.verbose,
|
||||||
|
c.test, c.update, c.force);
|
||||||
|
if (!rv && c.readonly < 0)
|
||||||
|
- rv = Manage_ro(devlist->devname, mdfd, c.readonly);
|
||||||
|
+ rv = Manage_ro(ident.devname, mdfd, c.readonly);
|
||||||
|
if (!rv && c.runstop > 0)
|
||||||
|
- rv = Manage_run(devlist->devname, mdfd, &c);
|
||||||
|
+ rv = Manage_run(ident.devname, mdfd, &c);
|
||||||
|
if (!rv && c.runstop < 0)
|
||||||
|
- rv = Manage_stop(devlist->devname, mdfd, c.verbose, 0);
|
||||||
|
+ rv = Manage_stop(ident.devname, mdfd, c.verbose, 0);
|
||||||
|
break;
|
||||||
|
case ASSEMBLE:
|
||||||
|
if (!c.scan && c.runstop == -1) {
|
||||||
|
@@ -1428,22 +1430,19 @@ int main(int argc, char *argv[])
|
||||||
|
ident.super_minor == UnSet && ident.name[0] == 0 &&
|
||||||
|
!c.scan) {
|
||||||
|
/* Only a device has been given, so get details from config file */
|
||||||
|
- struct mddev_ident *array_ident = conf_get_ident(devlist->devname);
|
||||||
|
+ struct mddev_ident *array_ident = conf_get_ident(ident.devname);
|
||||||
|
if (array_ident == NULL) {
|
||||||
|
- pr_err("%s not identified in config file.\n",
|
||||||
|
- devlist->devname);
|
||||||
|
+ pr_err("%s not identified in config file.\n", ident.devname);
|
||||||
|
rv |= 1;
|
||||||
|
if (mdfd >= 0)
|
||||||
|
close(mdfd);
|
||||||
|
} else {
|
||||||
|
if (array_ident->autof == 0)
|
||||||
|
array_ident->autof = c.autof;
|
||||||
|
- rv |= Assemble(ss, devlist->devname, array_ident,
|
||||||
|
- NULL, &c);
|
||||||
|
+ rv |= Assemble(ss, ident.devname, array_ident, NULL, &c);
|
||||||
|
}
|
||||||
|
} else if (!c.scan)
|
||||||
|
- rv = Assemble(ss, devlist->devname, &ident,
|
||||||
|
- devlist->next, &c);
|
||||||
|
+ rv = Assemble(ss, ident.devname, &ident, devlist->next, &c);
|
||||||
|
else if (devs_found > 0) {
|
||||||
|
if (c.update && devs_found > 1) {
|
||||||
|
pr_err("can only update a single array at a time\n");
|
||||||
|
@@ -1501,7 +1500,7 @@ int main(int argc, char *argv[])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- rv = Build(devlist->devname, devlist->next, &s, &c);
|
||||||
|
+ rv = Build(&ident, devlist->next, &s, &c);
|
||||||
|
break;
|
||||||
|
case CREATE:
|
||||||
|
if (c.delay == 0)
|
||||||
|
@@ -1538,9 +1537,7 @@ int main(int argc, char *argv[])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- rv = Create(ss, devlist->devname,
|
||||||
|
- ident.name, ident.uuid_set ? ident.uuid : NULL,
|
||||||
|
- devs_found - 1, devlist->next, &s, &c);
|
||||||
|
+ rv = Create(ss, &ident, devs_found - 1, devlist->next, &s, &c);
|
||||||
|
break;
|
||||||
|
case MISC:
|
||||||
|
if (devmode == 'E') {
|
||||||
|
@@ -1637,8 +1634,7 @@ int main(int argc, char *argv[])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (dv = devlist->next; dv; dv = dv->next) {
|
||||||
|
- rv = Grow_Add_device(devlist->devname, mdfd,
|
||||||
|
- dv->devname);
|
||||||
|
+ rv = Grow_Add_device(ident.devname, mdfd, dv->devname);
|
||||||
|
if (rv)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -1651,18 +1647,15 @@ int main(int argc, char *argv[])
|
||||||
|
}
|
||||||
|
if (c.delay == 0)
|
||||||
|
c.delay = DEFAULT_BITMAP_DELAY;
|
||||||
|
- rv = Grow_addbitmap(devlist->devname, mdfd, &c, &s);
|
||||||
|
+ rv = Grow_addbitmap(ident.devname, mdfd, &c, &s);
|
||||||
|
} else if (grow_continue)
|
||||||
|
- rv = Grow_continue_command(devlist->devname,
|
||||||
|
- mdfd, c.backup_file,
|
||||||
|
- c.verbose);
|
||||||
|
+ rv = Grow_continue_command(ident.devname, mdfd, c.backup_file, c.verbose);
|
||||||
|
else if (s.size > 0 || s.raiddisks || s.layout_str ||
|
||||||
|
s.chunk != 0 || s.level != UnSet ||
|
||||||
|
s.data_offset != INVALID_SECTORS) {
|
||||||
|
- rv = Grow_reshape(devlist->devname, mdfd,
|
||||||
|
- devlist->next, &c, &s);
|
||||||
|
+ rv = Grow_reshape(ident.devname, mdfd, devlist->next, &c, &s);
|
||||||
|
} else if (s.consistency_policy != CONSISTENCY_POLICY_UNKNOWN) {
|
||||||
|
- rv = Grow_consistency_policy(devlist->devname, mdfd, &c, &s);
|
||||||
|
+ rv = Grow_consistency_policy(ident.devname, mdfd, &c, &s);
|
||||||
|
} else if (array_size == 0)
|
||||||
|
pr_err("no changes to --grow\n");
|
||||||
|
break;
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index f0ceeb78..5678eb11 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -1531,14 +1531,11 @@ extern int Assemble(struct supertype *st, char *mddev,
|
||||||
|
struct mddev_dev *devlist,
|
||||||
|
struct context *c);
|
||||||
|
|
||||||
|
-extern int Build(char *mddev, struct mddev_dev *devlist,
|
||||||
|
- struct shape *s, struct context *c);
|
||||||
|
-
|
||||||
|
-extern int Create(struct supertype *st, char *mddev,
|
||||||
|
- char *name, int *uuid,
|
||||||
|
- int subdevs, struct mddev_dev *devlist,
|
||||||
|
- struct shape *s,
|
||||||
|
- struct context *c);
|
||||||
|
+extern int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s,
|
||||||
|
+ struct context *c);
|
||||||
|
+
|
||||||
|
+extern int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
|
||||||
|
+ struct mddev_dev *devlist, struct shape *s, 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.40.1
|
||||||
|
|
253
SOURCES/0155-mdadm-refactor-ident-name-handling.patch
Normal file
253
SOURCES/0155-mdadm-refactor-ident-name-handling.patch
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
From 67417d9222c505103357191bb0e0ae300892e8a9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Thu, 1 Jun 2023 09:27:48 +0200
|
||||||
|
Subject: [PATCH 155/165] mdadm: refactor ident->name handling
|
||||||
|
|
||||||
|
Create dedicated setter for name in mddev_ident and propagate it.
|
||||||
|
Following changes are made:
|
||||||
|
- move duplicated code from config.c and mdadm.c into new function.
|
||||||
|
- Add error enum in mdadm.h.
|
||||||
|
- Use MD_NAME_MAX instead of hardcoded value in mddev_ident.
|
||||||
|
- Use secure functions.
|
||||||
|
- Add more detailed verification of the name.
|
||||||
|
- make error messages reusable for cmdline and config:
|
||||||
|
- for cmdline, these are errors so use pr_err().
|
||||||
|
- for config, these are just warnings, so use pr_info().
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
config.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++------
|
||||||
|
lib.c | 18 +++++++++++++
|
||||||
|
mdadm.c | 12 +++------
|
||||||
|
mdadm.h | 20 ++++++++++-----
|
||||||
|
4 files changed, 104 insertions(+), 23 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.c b/config.c
|
||||||
|
index 450880e3..a9a0b4f7 100644
|
||||||
|
--- a/config.c
|
||||||
|
+++ b/config.c
|
||||||
|
@@ -131,6 +131,34 @@ bool is_devname_ignore(char *devname)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * ident_log() - generate and write message to the user.
|
||||||
|
+ * @param_name: name of the property.
|
||||||
|
+ * @value: value of the property.
|
||||||
|
+ * @reason: meaningful description.
|
||||||
|
+ * @cmdline: context dependent actions, see below.
|
||||||
|
+ *
|
||||||
|
+ * The function is made to provide similar error handling for both config and cmdline. The behavior
|
||||||
|
+ * is configurable via @cmdline. Message has following format:
|
||||||
|
+ * "Value "@value" cannot be set for @param_name. Reason: @reason."
|
||||||
|
+ *
|
||||||
|
+ * If cmdline is on:
|
||||||
|
+ * - message is written to stderr.
|
||||||
|
+ * otherwise:
|
||||||
|
+ * - message is written to stdout.
|
||||||
|
+ * - "Value ignored" is added at the end of the message.
|
||||||
|
+ */
|
||||||
|
+static void ident_log(const char *param_name, const char *value, const char *reason,
|
||||||
|
+ const bool cmdline)
|
||||||
|
+{
|
||||||
|
+ if (cmdline == true)
|
||||||
|
+ pr_err("Value \"%s\" cannot be set as %s. Reason: %s.\n", value, param_name,
|
||||||
|
+ reason);
|
||||||
|
+ else
|
||||||
|
+ pr_info("Value \"%s\" cannot be set as %s. Reason: %s. Value ignored.\n", value,
|
||||||
|
+ param_name, reason);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* ident_init() - Set defaults.
|
||||||
|
* @ident: ident pointer, not NULL.
|
||||||
|
@@ -159,6 +187,46 @@ inline void ident_init(struct mddev_ident *ident)
|
||||||
|
ident->uuid_set = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * _ident_set_name()- set name in &mddev_ident.
|
||||||
|
+ * @ident: pointer to &mddev_ident.
|
||||||
|
+ * @name: name to be set.
|
||||||
|
+ * @cmdline: context dependent actions.
|
||||||
|
+ *
|
||||||
|
+ * If criteria passed, set name in @ident.
|
||||||
|
+ *
|
||||||
|
+ * Return: %MDADM_STATUS_SUCCESS or %MDADM_STATUS_ERROR.
|
||||||
|
+ */
|
||||||
|
+static mdadm_status_t _ident_set_name(struct mddev_ident *ident, const char *name,
|
||||||
|
+ const bool cmdline)
|
||||||
|
+{
|
||||||
|
+ assert(name);
|
||||||
|
+ assert(ident);
|
||||||
|
+
|
||||||
|
+ const char *prop_name = "name";
|
||||||
|
+
|
||||||
|
+ if (ident->name[0]) {
|
||||||
|
+ ident_log(prop_name, name, "Already defined", cmdline);
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (is_string_lq(name, MD_NAME_MAX + 1) == false) {
|
||||||
|
+ ident_log(prop_name, name, "Too long or empty", cmdline);
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ snprintf(ident->name, MD_NAME_MAX + 1, "%s", name);
|
||||||
|
+ return MDADM_STATUS_SUCCESS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * ident_set_name()- exported, for cmdline.
|
||||||
|
+ */
|
||||||
|
+mdadm_status_t ident_set_name(struct mddev_ident *ident, const char *name)
|
||||||
|
+{
|
||||||
|
+ return _ident_set_name(ident, name, true);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
struct conf_dev {
|
||||||
|
struct conf_dev *next;
|
||||||
|
char *name;
|
||||||
|
@@ -444,14 +512,7 @@ void arrayline(char *line)
|
||||||
|
mis.super_minor = minor;
|
||||||
|
}
|
||||||
|
} else if (strncasecmp(w, "name=", 5) == 0) {
|
||||||
|
- if (mis.name[0])
|
||||||
|
- pr_err("only specify name once, %s ignored.\n",
|
||||||
|
- w);
|
||||||
|
- else if (strlen(w + 5) > 32)
|
||||||
|
- pr_err("name too long, ignoring %s\n", w);
|
||||||
|
- else
|
||||||
|
- strcpy(mis.name, w + 5);
|
||||||
|
-
|
||||||
|
+ _ident_set_name(&mis, w + 5, false);
|
||||||
|
} else if (strncasecmp(w, "bitmap=", 7) == 0) {
|
||||||
|
if (mis.bitmap_file)
|
||||||
|
pr_err("only specify bitmap file once. %s ignored\n",
|
||||||
|
diff --git a/lib.c b/lib.c
|
||||||
|
index 8a4b48e0..03198e2d 100644
|
||||||
|
--- a/lib.c
|
||||||
|
+++ b/lib.c
|
||||||
|
@@ -27,6 +27,24 @@
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * is_string_lq() - Check if string length with NULL byte is lower or equal to requested.
|
||||||
|
+ * @str: string to check.
|
||||||
|
+ * @max_len: max length.
|
||||||
|
+ *
|
||||||
|
+ * @str length must be bigger than 0 and be lower or equal @max_len, including termination byte.
|
||||||
|
+ */
|
||||||
|
+bool is_string_lq(const char * const str, size_t max_len)
|
||||||
|
+{
|
||||||
|
+ assert(str);
|
||||||
|
+
|
||||||
|
+ size_t _len = strnlen(str, max_len);
|
||||||
|
+
|
||||||
|
+ if (_len > 0 && _len < max_len)
|
||||||
|
+ return true;
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
bool is_dev_alive(char *path)
|
||||||
|
{
|
||||||
|
if (!path)
|
||||||
|
diff --git a/mdadm.c b/mdadm.c
|
||||||
|
index 0a56ed26..8bc9304e 100644
|
||||||
|
--- a/mdadm.c
|
||||||
|
+++ b/mdadm.c
|
||||||
|
@@ -690,20 +690,14 @@ int main(int argc, char *argv[])
|
||||||
|
case O(CREATE,'N'):
|
||||||
|
case O(ASSEMBLE,'N'):
|
||||||
|
case O(MISC,'N'):
|
||||||
|
- if (ident.name[0]) {
|
||||||
|
- pr_err("name cannot be set twice. Second value %s.\n", optarg);
|
||||||
|
- exit(2);
|
||||||
|
- }
|
||||||
|
if (mode == MISC && !c.subarray) {
|
||||||
|
pr_err("-N/--name only valid with --update-subarray in misc mode\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
- if (strlen(optarg) > 32) {
|
||||||
|
- pr_err("name '%s' is too long, 32 chars max.\n",
|
||||||
|
- optarg);
|
||||||
|
+
|
||||||
|
+ if (ident_set_name(&ident, optarg) != MDADM_STATUS_SUCCESS)
|
||||||
|
exit(2);
|
||||||
|
- }
|
||||||
|
- strcpy(ident.name, optarg);
|
||||||
|
+
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case O(ASSEMBLE,'m'): /* super-minor for array */
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index 5678eb11..bbf386d6 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -294,6 +294,11 @@ static inline void __put_unaligned32(__u32 val, void *p)
|
||||||
|
#define KIB_TO_BYTES(x) ((x) << 10)
|
||||||
|
#define SEC_TO_BYTES(x) ((x) << 9)
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * This is true for native and DDF, IMSM allows 16.
|
||||||
|
+ */
|
||||||
|
+#define MD_NAME_MAX 32
|
||||||
|
+
|
||||||
|
extern const char Name[];
|
||||||
|
|
||||||
|
struct md_bb_entry {
|
||||||
|
@@ -425,6 +430,12 @@ struct spare_criteria {
|
||||||
|
unsigned int sector_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
+typedef enum mdadm_status {
|
||||||
|
+ MDADM_STATUS_SUCCESS = 0,
|
||||||
|
+ MDADM_STATUS_ERROR,
|
||||||
|
+ MDADM_STATUS_UNDEF,
|
||||||
|
+} mdadm_status_t;
|
||||||
|
+
|
||||||
|
enum mode {
|
||||||
|
ASSEMBLE=1,
|
||||||
|
BUILD,
|
||||||
|
@@ -593,7 +604,7 @@ struct mddev_ident {
|
||||||
|
|
||||||
|
int uuid_set;
|
||||||
|
int uuid[4];
|
||||||
|
- char name[33];
|
||||||
|
+ char name[MD_NAME_MAX + 1];
|
||||||
|
|
||||||
|
int super_minor;
|
||||||
|
|
||||||
|
@@ -1609,6 +1620,7 @@ extern int check_partitions(int fd, char *dname,
|
||||||
|
extern int fstat_is_blkdev(int fd, char *devname, dev_t *rdev);
|
||||||
|
extern int stat_is_blkdev(char *devname, dev_t *rdev);
|
||||||
|
|
||||||
|
+extern bool is_string_lq(const char * const str, size_t max_len);
|
||||||
|
extern bool is_dev_alive(char *path);
|
||||||
|
extern int get_mdp_major(void);
|
||||||
|
extern int get_maj_min(char *dev, int *major, int *minor);
|
||||||
|
@@ -1626,6 +1638,7 @@ extern void manage_fork_fds(int close_all);
|
||||||
|
extern int continue_via_systemd(char *devnm, char *service_name, char *prefix);
|
||||||
|
|
||||||
|
extern void ident_init(struct mddev_ident *ident);
|
||||||
|
+extern mdadm_status_t ident_set_name(struct mddev_ident *ident, const char *name);
|
||||||
|
|
||||||
|
extern int parse_auto(char *str, char *msg, int config);
|
||||||
|
extern struct mddev_ident *conf_get_ident(char *dev);
|
||||||
|
@@ -2002,11 +2015,6 @@ enum r0layout {
|
||||||
|
/* And another special number needed for --data_offset=variable */
|
||||||
|
#define VARIABLE_OFFSET 3
|
||||||
|
|
||||||
|
-/**
|
||||||
|
- * This is true for native and DDF, IMSM allows 16.
|
||||||
|
- */
|
||||||
|
-#define MD_NAME_MAX 32
|
||||||
|
-
|
||||||
|
/**
|
||||||
|
* is_container() - check if @level is &LEVEL_CONTAINER
|
||||||
|
* @level: level value
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
249
SOURCES/0156-mdadm-define-ident_set_devname.patch
Normal file
249
SOURCES/0156-mdadm-define-ident_set_devname.patch
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
From ae5f13a971bc309e0e25087421119b86daf2e510 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Thu, 1 Jun 2023 09:27:49 +0200
|
||||||
|
Subject: [PATCH 156/165] mdadm: define ident_set_devname()
|
||||||
|
|
||||||
|
Use dedicated set method for ident->devname. Now, devname validation
|
||||||
|
is done early for modes where device is created (Build, Create and
|
||||||
|
Assemble). The rules, used for devname validation are derived from
|
||||||
|
config file.
|
||||||
|
|
||||||
|
It could cause regression with execeptional cases where existing device
|
||||||
|
has name which doesn't match criteria for Manage and Grow modes. It is
|
||||||
|
low risk and those modes are not omitted from early devname validation.
|
||||||
|
Use can used main numbered devnode to avoid this problem.
|
||||||
|
Messages exposed to user are changed so it might cause a regression
|
||||||
|
in negative scenarios. Error codes are not changed.
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
config.c | 102 +++++++++++++++++++++++++--------
|
||||||
|
mdadm.c | 10 +---
|
||||||
|
mdadm.h | 3 +-
|
||||||
|
tests/00createnames | 3 +
|
||||||
|
tests/templates/names_template | 7 +++
|
||||||
|
5 files changed, 92 insertions(+), 33 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.c b/config.c
|
||||||
|
index a9a0b4f7..a0424845 100644
|
||||||
|
--- a/config.c
|
||||||
|
+++ b/config.c
|
||||||
|
@@ -122,7 +122,7 @@ int match_keyword(char *word)
|
||||||
|
/**
|
||||||
|
* is_devname_ignore() - check if &devname is a special "<ignore>" keyword.
|
||||||
|
*/
|
||||||
|
-bool is_devname_ignore(char *devname)
|
||||||
|
+bool is_devname_ignore(const char *devname)
|
||||||
|
{
|
||||||
|
static const char keyword[] = "<ignore>";
|
||||||
|
|
||||||
|
@@ -187,6 +187,74 @@ inline void ident_init(struct mddev_ident *ident)
|
||||||
|
ident->uuid_set = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * _ident_set_devname()- verify devname and set it in &mddev_ident.
|
||||||
|
+ * @ident: pointer to &mddev_ident.
|
||||||
|
+ * @devname: devname to be set.
|
||||||
|
+ * @cmdline: context dependent actions. If set, ignore keyword is not allowed.
|
||||||
|
+ *
|
||||||
|
+ * @devname can have following forms:
|
||||||
|
+ * '<ignore>' keyword (if allowed)
|
||||||
|
+ * /dev/md{number}
|
||||||
|
+ * /dev/md_d{number} (legacy)
|
||||||
|
+ * /dev/md_{name}
|
||||||
|
+ * /dev/md/{name}
|
||||||
|
+ * {name} - anything that doesn't start from '/' or '<'.
|
||||||
|
+ *
|
||||||
|
+ * {name} must follow name's criteria.
|
||||||
|
+ * If criteria passed, duplicate memory and set devname in @ident.
|
||||||
|
+ *
|
||||||
|
+ * Return: %MDADM_STATUS_SUCCESS or %MDADM_STATUS_ERROR.
|
||||||
|
+ */
|
||||||
|
+mdadm_status_t _ident_set_devname(struct mddev_ident *ident, const char *devname,
|
||||||
|
+ const bool cmdline)
|
||||||
|
+{
|
||||||
|
+ assert(ident);
|
||||||
|
+ assert(devname);
|
||||||
|
+
|
||||||
|
+ static const char named_dev_pref[] = DEV_NUM_PREF "_";
|
||||||
|
+ static const int named_dev_pref_size = sizeof(named_dev_pref) - 1;
|
||||||
|
+ const char *prop_name = "devname";
|
||||||
|
+ const char *name;
|
||||||
|
+
|
||||||
|
+ if (ident->devname) {
|
||||||
|
+ ident_log(prop_name, devname, "Already defined", cmdline);
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (is_devname_ignore(devname) == true) {
|
||||||
|
+ if (!cmdline)
|
||||||
|
+ goto pass;
|
||||||
|
+
|
||||||
|
+ ident_log(prop_name, devname, "Special keyword is invalid in this context",
|
||||||
|
+ cmdline);
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (is_devname_md_numbered(devname) == true || is_devname_md_d_numbered(devname) == true)
|
||||||
|
+ goto pass;
|
||||||
|
+
|
||||||
|
+ if (strncmp(devname, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0)
|
||||||
|
+ name = devname + DEV_MD_DIR_LEN;
|
||||||
|
+ else if (strncmp(devname, named_dev_pref, named_dev_pref_size) == 0)
|
||||||
|
+ name = devname + named_dev_pref_size;
|
||||||
|
+ else
|
||||||
|
+ name = devname;
|
||||||
|
+
|
||||||
|
+ if (*name == '/' || *name == '<') {
|
||||||
|
+ ident_log(prop_name, devname, "Cannot be started from \'/\' or \'<\'", cmdline);
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (is_string_lq(name, MD_NAME_MAX + 1) == false) {
|
||||||
|
+ ident_log(prop_name, devname, "Invalid length", cmdline);
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+pass:
|
||||||
|
+ ident->devname = xstrdup(devname);
|
||||||
|
+ return MDADM_STATUS_SUCCESS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* _ident_set_name()- set name in &mddev_ident.
|
||||||
|
* @ident: pointer to &mddev_ident.
|
||||||
|
@@ -219,6 +287,14 @@ static mdadm_status_t _ident_set_name(struct mddev_ident *ident, const char *nam
|
||||||
|
return MDADM_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * ident_set_devname()- exported, for cmdline.
|
||||||
|
+ */
|
||||||
|
+mdadm_status_t ident_set_devname(struct mddev_ident *ident, const char *name)
|
||||||
|
+{
|
||||||
|
+ return _ident_set_devname(ident, name, true);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* ident_set_name()- exported, for cmdline.
|
||||||
|
*/
|
||||||
|
@@ -464,29 +540,7 @@ void arrayline(char *line)
|
||||||
|
|
||||||
|
for (w = dl_next(line); w != line; w = dl_next(w)) {
|
||||||
|
if (w[0] == '/' || strchr(w, '=') == NULL) {
|
||||||
|
- /* This names the device, or is '<ignore>'.
|
||||||
|
- * The rules match those in create_mddev.
|
||||||
|
- * 'w' must be:
|
||||||
|
- * /dev/md/{anything}
|
||||||
|
- * /dev/mdNN
|
||||||
|
- * /dev/md_dNN
|
||||||
|
- * <ignore>
|
||||||
|
- * or anything that doesn't start '/' or '<'
|
||||||
|
- */
|
||||||
|
- if (is_devname_ignore(w) == true ||
|
||||||
|
- strncmp(w, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0 ||
|
||||||
|
- (w[0] != '/' && w[0] != '<') ||
|
||||||
|
- is_devname_md_numbered(w) == true ||
|
||||||
|
- is_devname_md_d_numbered(w) == true) {
|
||||||
|
- /* This is acceptable */;
|
||||||
|
- if (mis.devname)
|
||||||
|
- pr_err("only give one device per ARRAY line: %s and %s\n",
|
||||||
|
- mis.devname, w);
|
||||||
|
- else
|
||||||
|
- mis.devname = w;
|
||||||
|
- }else {
|
||||||
|
- pr_err("%s is an invalid name for an md device - ignored.\n", w);
|
||||||
|
- }
|
||||||
|
+ _ident_set_devname(&mis, w, false);
|
||||||
|
} else if (strncasecmp(w, "uuid=", 5) == 0) {
|
||||||
|
if (mis.uuid_set)
|
||||||
|
pr_err("only specify uuid once, %s ignored.\n",
|
||||||
|
diff --git a/mdadm.c b/mdadm.c
|
||||||
|
index 8bc9304e..62f981df 100644
|
||||||
|
--- a/mdadm.c
|
||||||
|
+++ b/mdadm.c
|
||||||
|
@@ -1284,7 +1284,8 @@ int main(int argc, char *argv[])
|
||||||
|
pr_err("an md device must be given in this mode\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
- ident.devname = devlist->devname;
|
||||||
|
+ if (ident_set_devname(&ident, devlist->devname) != MDADM_STATUS_SUCCESS)
|
||||||
|
+ exit(1);
|
||||||
|
|
||||||
|
if ((int)ident.super_minor == -2 && c.autof) {
|
||||||
|
pr_err("--super-minor=dev is incompatible with --auto\n");
|
||||||
|
@@ -1301,13 +1302,6 @@ int main(int argc, char *argv[])
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
- char *bname = basename(ident.devname);
|
||||||
|
-
|
||||||
|
- if (strlen(bname) > MD_NAME_MAX) {
|
||||||
|
- pr_err("Name %s is too long.\n", ident.devname);
|
||||||
|
- exit(1);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
ret = stat(ident.devname, &stb);
|
||||||
|
if (ident.super_minor == -2 && ret != 0) {
|
||||||
|
pr_err("--super-minor=dev given, and listed device %s doesn't exist.\n",
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index bbf386d6..49422e24 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -1638,6 +1638,7 @@ extern void manage_fork_fds(int close_all);
|
||||||
|
extern int continue_via_systemd(char *devnm, char *service_name, char *prefix);
|
||||||
|
|
||||||
|
extern void ident_init(struct mddev_ident *ident);
|
||||||
|
+extern mdadm_status_t ident_set_devname(struct mddev_ident *ident, const char *devname);
|
||||||
|
extern mdadm_status_t ident_set_name(struct mddev_ident *ident, const char *name);
|
||||||
|
|
||||||
|
extern int parse_auto(char *str, char *msg, int config);
|
||||||
|
@@ -1660,7 +1661,7 @@ extern void print_escape(char *str);
|
||||||
|
extern int use_udev(void);
|
||||||
|
extern unsigned long GCD(unsigned long a, unsigned long b);
|
||||||
|
extern int conf_name_is_free(char *name);
|
||||||
|
-extern bool is_devname_ignore(char *devname);
|
||||||
|
+extern bool is_devname_ignore(const char *devname);
|
||||||
|
extern bool is_devname_md_numbered(const char *devname);
|
||||||
|
extern bool is_devname_md_d_numbered(const char *devname);
|
||||||
|
extern int conf_verify_devnames(struct mddev_ident *array_list);
|
||||||
|
diff --git a/tests/00createnames b/tests/00createnames
|
||||||
|
index 064eeef2..a95e7d2b 100644
|
||||||
|
--- a/tests/00createnames
|
||||||
|
+++ b/tests/00createnames
|
||||||
|
@@ -39,3 +39,6 @@ mdadm -S "/dev/md0"
|
||||||
|
names_create "/dev/md0" "name"
|
||||||
|
names_verify "/dev/md0" "empty" "name"
|
||||||
|
mdadm -S "/dev/md0"
|
||||||
|
+
|
||||||
|
+# Devnode is a special ignore keyword. Should be rejected.
|
||||||
|
+names_create "<ignore>" "name", "true"
|
||||||
|
diff --git a/tests/templates/names_template b/tests/templates/names_template
|
||||||
|
index 8d2b5c81..6181bfaa 100644
|
||||||
|
--- a/tests/templates/names_template
|
||||||
|
+++ b/tests/templates/names_template
|
||||||
|
@@ -2,6 +2,7 @@
|
||||||
|
function names_create() {
|
||||||
|
local DEVNAME=$1
|
||||||
|
local NAME=$2
|
||||||
|
+ local NEG_TEST=$3
|
||||||
|
|
||||||
|
if [[ -z "$NAME" ]]; then
|
||||||
|
mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force
|
||||||
|
@@ -9,6 +10,12 @@ function names_create() {
|
||||||
|
mdadm -CR "$DEVNAME" --name="$NAME" --metadata=1.2 -l0 -n 1 $dev0 --force
|
||||||
|
fi
|
||||||
|
|
||||||
|
+ if [[ "$NEG_TEST" == "true" ]]; then
|
||||||
|
+ [[ "$?" == "0" ]] && return 0
|
||||||
|
+ echo "Negative verification failed"
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
if [[ "$?" != "0" ]]; then
|
||||||
|
echo "Cannot create device."
|
||||||
|
exit 1
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
471
SOURCES/0157-mdadm-Follow-POSIX-Portable-Character-Set.patch
Normal file
471
SOURCES/0157-mdadm-Follow-POSIX-Portable-Character-Set.patch
Normal file
@ -0,0 +1,471 @@
|
|||||||
|
From e2eb503bd797908f515b58428b274f1ba6a05349 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Thu, 1 Jun 2023 09:27:50 +0200
|
||||||
|
Subject: [PATCH 157/165] mdadm: Follow POSIX Portable Character Set
|
||||||
|
|
||||||
|
When the user creates a device with a name that contains whitespace,
|
||||||
|
mdadm timeouts and throws an error. This issue is caused by udev, which
|
||||||
|
truncates /dev/md link until the first whitespace.
|
||||||
|
|
||||||
|
This patch introduces prohibition of characters other than A-Za-z0-9.-_
|
||||||
|
in the device name. Also, it prohibits using leading "-" in device name,
|
||||||
|
so name won't be confused with cli parameter.
|
||||||
|
Set of allowed characters is taken from POSIX 3.280 Portable Character
|
||||||
|
Set. Also, device name length now is limited to NAME_MAX.
|
||||||
|
|
||||||
|
In some places, there are other requirements for string length (e.g. size
|
||||||
|
up to MD_NAME_MAX for device name). This routine is made to follow POSIX
|
||||||
|
and other, more strict limitations should be checked separately.
|
||||||
|
We are aware of the risk of regression in exceptional cases (as
|
||||||
|
escape_devname function is removed) that should be fixed by updating
|
||||||
|
the array name.
|
||||||
|
|
||||||
|
The POSIX validation is added for:
|
||||||
|
- 'name' parameter in every mode.
|
||||||
|
- first devlist entry, for Build, Create, Assemble, Manage, Grow.
|
||||||
|
- config entries, both devname and "name=".
|
||||||
|
|
||||||
|
Additionally, some manual cleanups are made.
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Detail.c | 17 ++++--------
|
||||||
|
config.c | 13 ++++++---
|
||||||
|
lib.c | 58 ++++++++++++++++++++++++++++-----------
|
||||||
|
mdadm.8.in | 70 ++++++++++++++++++++---------------------------
|
||||||
|
mdadm.conf.5.in | 4 ---
|
||||||
|
mdadm.h | 2 +-
|
||||||
|
super-intel.c | 47 ++++++++++++++++---------------
|
||||||
|
tests/00confnames | 4 +--
|
||||||
|
8 files changed, 113 insertions(+), 102 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Detail.c b/Detail.c
|
||||||
|
index 206d88e3..57ac336f 100644
|
||||||
|
--- a/Detail.c
|
||||||
|
+++ b/Detail.c
|
||||||
|
@@ -254,11 +254,9 @@ int Detail(char *dev, struct context *c)
|
||||||
|
fname_from_uuid(st, info, nbuf, ':');
|
||||||
|
printf("MD_UUID=%s\n", nbuf + 5);
|
||||||
|
mp = map_by_uuid(&map, info->uuid);
|
||||||
|
- if (mp && mp->path && strncmp(mp->path, DEV_MD_DIR, DEV_MD_DIR_LEN) == 0) {
|
||||||
|
- printf("MD_DEVNAME=");
|
||||||
|
- print_escape(mp->path + DEV_MD_DIR_LEN);
|
||||||
|
- putchar('\n');
|
||||||
|
- }
|
||||||
|
+
|
||||||
|
+ 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);
|
||||||
|
|
||||||
|
if (st->ss->export_detail_super)
|
||||||
|
st->ss->export_detail_super(st);
|
||||||
|
@@ -271,12 +269,9 @@ int Detail(char *dev, struct context *c)
|
||||||
|
__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=");
|
||||||
|
- print_escape(mp->path + DEV_MD_DIR_LEN);
|
||||||
|
- putchar('\n');
|
||||||
|
- }
|
||||||
|
+ 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) {
|
||||||
|
diff --git a/config.c b/config.c
|
||||||
|
index a0424845..5f12a1f8 100644
|
||||||
|
--- a/config.c
|
||||||
|
+++ b/config.c
|
||||||
|
@@ -199,9 +199,9 @@ inline void ident_init(struct mddev_ident *ident)
|
||||||
|
* /dev/md_d{number} (legacy)
|
||||||
|
* /dev/md_{name}
|
||||||
|
* /dev/md/{name}
|
||||||
|
- * {name} - anything that doesn't start from '/' or '<'.
|
||||||
|
+ * {name}
|
||||||
|
*
|
||||||
|
- * {name} must follow name's criteria.
|
||||||
|
+ * {name} must follow name's criteria and be POSIX compatible.
|
||||||
|
* If criteria passed, duplicate memory and set devname in @ident.
|
||||||
|
*
|
||||||
|
* Return: %MDADM_STATUS_SUCCESS or %MDADM_STATUS_ERROR.
|
||||||
|
@@ -241,8 +241,8 @@ mdadm_status_t _ident_set_devname(struct mddev_ident *ident, const char *devname
|
||||||
|
else
|
||||||
|
name = devname;
|
||||||
|
|
||||||
|
- if (*name == '/' || *name == '<') {
|
||||||
|
- ident_log(prop_name, devname, "Cannot be started from \'/\' or \'<\'", cmdline);
|
||||||
|
+ if (is_name_posix_compatible(name) == false) {
|
||||||
|
+ ident_log(prop_name, name, "Not POSIX compatible", cmdline);
|
||||||
|
return MDADM_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -283,6 +283,11 @@ static mdadm_status_t _ident_set_name(struct mddev_ident *ident, const char *nam
|
||||||
|
return MDADM_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (is_name_posix_compatible(name) == false) {
|
||||||
|
+ ident_log(prop_name, name, "Not POSIX compatible", cmdline);
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
snprintf(ident->name, MD_NAME_MAX + 1, "%s", name);
|
||||||
|
return MDADM_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
diff --git a/lib.c b/lib.c
|
||||||
|
index 03198e2d..7ab59988 100644
|
||||||
|
--- a/lib.c
|
||||||
|
+++ b/lib.c
|
||||||
|
@@ -483,24 +483,50 @@ void print_quoted(char *str)
|
||||||
|
putchar(q);
|
||||||
|
}
|
||||||
|
|
||||||
|
-void print_escape(char *str)
|
||||||
|
+/**
|
||||||
|
+ * is_alphanum() - Check if sign is letter or digit.
|
||||||
|
+ * @c: char to analyze.
|
||||||
|
+ *
|
||||||
|
+ * Similar to isalnum() but additional locales are excluded.
|
||||||
|
+ *
|
||||||
|
+ * Return: %true on success, %false otherwise.
|
||||||
|
+ */
|
||||||
|
+bool is_alphanum(const char c)
|
||||||
|
{
|
||||||
|
- /* print str, but change space and tab to '_'
|
||||||
|
- * as is suitable for device names
|
||||||
|
- */
|
||||||
|
- for (; *str; str++) {
|
||||||
|
- switch (*str) {
|
||||||
|
- case ' ':
|
||||||
|
- case '\t':
|
||||||
|
- putchar('_');
|
||||||
|
- break;
|
||||||
|
- case '/':
|
||||||
|
- putchar('-');
|
||||||
|
- break;
|
||||||
|
- default:
|
||||||
|
- putchar(*str);
|
||||||
|
- }
|
||||||
|
+ if (isupper(c) || islower(c) || isdigit(c) != 0)
|
||||||
|
+ return true;
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * is_name_posix_compatible() - Check if name is POSIX compatible.
|
||||||
|
+ * @name: name to check.
|
||||||
|
+ *
|
||||||
|
+ * POSIX portable file name character set contains ASCII letters,
|
||||||
|
+ * digits, '_', '.', and '-'. Also forbid leading '-'.
|
||||||
|
+ * The length of the name cannot exceed NAME_MAX - 1 (ensure NULL ending).
|
||||||
|
+ *
|
||||||
|
+ * Return: %true on success, %false otherwise.
|
||||||
|
+ */
|
||||||
|
+bool is_name_posix_compatible(const char * const name)
|
||||||
|
+{
|
||||||
|
+ assert(name);
|
||||||
|
+
|
||||||
|
+ char allowed_symbols[] = "-_.";
|
||||||
|
+ const char *n = name;
|
||||||
|
+
|
||||||
|
+ if (!is_string_lq(name, NAME_MAX))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ if (*n == '-')
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ while (*n != '\0') {
|
||||||
|
+ if (!is_alphanum(*n) && !strchr(allowed_symbols, *n))
|
||||||
|
+ return false;
|
||||||
|
+ n++;
|
||||||
|
}
|
||||||
|
+ return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int check_env(char *name)
|
||||||
|
diff --git a/mdadm.8.in b/mdadm.8.in
|
||||||
|
index b7159509..3142436f 100644
|
||||||
|
--- a/mdadm.8.in
|
||||||
|
+++ b/mdadm.8.in
|
||||||
|
@@ -364,7 +364,7 @@ Use the Intel(R) Matrix Storage Manager metadata format. This creates a
|
||||||
|
which is managed in a similar manner to DDF, and is supported by an
|
||||||
|
option-rom on some platforms:
|
||||||
|
.IP
|
||||||
|
-.B https://www.intel.com/content/www/us/en/support/products/122484/memory-and-storage/ssd-software/intel-virtual-raid-on-cpu-intel-vroc.html
|
||||||
|
+.B https://www.intel.com/content/www/us/en/support/products/122484
|
||||||
|
.PP
|
||||||
|
.RE
|
||||||
|
|
||||||
|
@@ -932,17 +932,14 @@ option will be ignored.
|
||||||
|
.BR \-N ", " \-\-name=
|
||||||
|
Set a
|
||||||
|
.B name
|
||||||
|
-for the array. This is currently only effective when creating an
|
||||||
|
-array with a version-1 superblock, or an array in a DDF container.
|
||||||
|
-The name is a simple textual string that can be used to identify array
|
||||||
|
-components when assembling. If name is needed but not specified, it
|
||||||
|
-is taken from the basename of the device that is being created.
|
||||||
|
-e.g. when creating
|
||||||
|
-.I /dev/md/home
|
||||||
|
-the
|
||||||
|
-.B name
|
||||||
|
-will default to
|
||||||
|
-.IR home .
|
||||||
|
+for the array. It must be
|
||||||
|
+.BR "POSIX PORTABLE NAME"
|
||||||
|
+compatible and cannot be longer than 32 chars. This is effective when creating an array
|
||||||
|
+with a v1 metadata, or an external array.
|
||||||
|
+
|
||||||
|
+If name is needed but not specified, it is taken from the basename of the device
|
||||||
|
+that is being created. See
|
||||||
|
+.BR "DEVICE NAMES"
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR \-R ", " \-\-run
|
||||||
|
@@ -1132,8 +1129,10 @@ is much safer.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR \-N ", " \-\-name=
|
||||||
|
-Specify the name of the array to assemble. This must be the name
|
||||||
|
-that was specified when creating the array. It must either match
|
||||||
|
+Specify the name of the array to assemble. It must be
|
||||||
|
+.BR "POSIX PORTABLE NAME"
|
||||||
|
+compatible and cannot be longer than 32 chars. This must be the name
|
||||||
|
+that was specified when creating the array. It must either match
|
||||||
|
the name stored in the superblock exactly, or it must match
|
||||||
|
with the current
|
||||||
|
.I homehost
|
||||||
|
@@ -2179,14 +2178,17 @@ Usage:
|
||||||
|
.I md-device
|
||||||
|
.BI \-\-chunk= X
|
||||||
|
.BI \-\-level= Y
|
||||||
|
-.br
|
||||||
|
.BI \-\-raid\-devices= Z
|
||||||
|
.I devices
|
||||||
|
|
||||||
|
.PP
|
||||||
|
-This usage will initialise a new md array, associate some devices with
|
||||||
|
+This usage will initialize a new md array, associate some devices with
|
||||||
|
it, and activate the array.
|
||||||
|
|
||||||
|
+.I md-device
|
||||||
|
+is a new device. This could be standard name or chosen name. For details see:
|
||||||
|
+.BR "DEVICE NAMES"
|
||||||
|
+
|
||||||
|
The named device will normally not exist when
|
||||||
|
.I "mdadm \-\-create"
|
||||||
|
is run, but will be created by
|
||||||
|
@@ -2227,24 +2229,6 @@ array. This feature can be overridden with the
|
||||||
|
.B \-\-force
|
||||||
|
option.
|
||||||
|
|
||||||
|
-When creating an array with version-1 metadata a name for the array is
|
||||||
|
-required.
|
||||||
|
-If this is not given with the
|
||||||
|
-.B \-\-name
|
||||||
|
-option,
|
||||||
|
-.I mdadm
|
||||||
|
-will choose a name based on the last component of the name of the
|
||||||
|
-device being created. So if
|
||||||
|
-.B /dev/md3
|
||||||
|
-is being created, then the name
|
||||||
|
-.B 3
|
||||||
|
-will be chosen.
|
||||||
|
-If
|
||||||
|
-.B /dev/md/home
|
||||||
|
-is being created, then the name
|
||||||
|
-.B home
|
||||||
|
-will be used.
|
||||||
|
-
|
||||||
|
When creating a partition based array, using
|
||||||
|
.I mdadm
|
||||||
|
with version-1.x metadata, the partition type should be set to
|
||||||
|
@@ -2429,12 +2413,10 @@ and
|
||||||
|
|
||||||
|
The
|
||||||
|
.B name
|
||||||
|
-option updates the subarray name in the metadata, it may not affect the
|
||||||
|
-device node name or the device node symlink until the subarray is
|
||||||
|
-re\-assembled. If updating
|
||||||
|
-.B name
|
||||||
|
-would change the UUID of an active subarray this operation is blocked,
|
||||||
|
-and the command will end in an error.
|
||||||
|
+option updates the subarray name in the metadata. It must be
|
||||||
|
+.BR "POSIX PORTABLE NAME"
|
||||||
|
+compatible and cannot be longer than 32 chars. If successes, new value will be respected after
|
||||||
|
+next assembly.
|
||||||
|
|
||||||
|
The
|
||||||
|
.B ppl
|
||||||
|
@@ -3395,6 +3377,10 @@ When
|
||||||
|
.B \-\-incremental
|
||||||
|
mode is used, this file gets a list of arrays currently being created.
|
||||||
|
|
||||||
|
+.SH POSIX PORTABLE NAME
|
||||||
|
+A valid name can only consist of characters "A-Za-z0-9.-_".
|
||||||
|
+The name cannot start with a leading "-" and cannot exceed 255 chars.
|
||||||
|
+
|
||||||
|
.SH DEVICE NAMES
|
||||||
|
|
||||||
|
.I mdadm
|
||||||
|
@@ -3416,6 +3402,10 @@ can be given, or just the suffix of the second sort of name, such as
|
||||||
|
.I home
|
||||||
|
can be given.
|
||||||
|
|
||||||
|
+In every style, raw name must be compatible with
|
||||||
|
+.BR "POSIX PORTABLE NAME"
|
||||||
|
+and has to be no longer than 32 chars.
|
||||||
|
+
|
||||||
|
When
|
||||||
|
.I mdadm
|
||||||
|
chooses device names during auto-assembly or incremental assembly, it
|
||||||
|
diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in
|
||||||
|
index bc2295c2..94e23dd0 100644
|
||||||
|
--- a/mdadm.conf.5.in
|
||||||
|
+++ b/mdadm.conf.5.in
|
||||||
|
@@ -717,10 +717,6 @@ ARRAY /dev/md/home UUID=9187a482:5dde19d9:eea3cc4a:d646ab8b
|
||||||
|
.br
|
||||||
|
auto=part
|
||||||
|
.br
|
||||||
|
-# The name of this array contains a space.
|
||||||
|
-.br
|
||||||
|
-ARRAY /dev/md9 name='Data Storage'
|
||||||
|
-.sp
|
||||||
|
POLICY domain=domain1 metadata=imsm path=pci-0000:00:1f.2-scsi-*
|
||||||
|
.br
|
||||||
|
action=spare
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index 49422e24..9effb941 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -1617,6 +1617,7 @@ extern int check_raid(int fd, char *name);
|
||||||
|
extern int check_partitions(int fd, char *dname,
|
||||||
|
unsigned long long freesize,
|
||||||
|
unsigned long long size);
|
||||||
|
+extern bool is_name_posix_compatible(const char *path);
|
||||||
|
extern int fstat_is_blkdev(int fd, char *devname, dev_t *rdev);
|
||||||
|
extern int stat_is_blkdev(char *devname, dev_t *rdev);
|
||||||
|
|
||||||
|
@@ -1657,7 +1658,6 @@ extern int conf_get_monitor_delay(void);
|
||||||
|
extern char *conf_line(FILE *file);
|
||||||
|
extern char *conf_word(FILE *file, int allow_key);
|
||||||
|
extern void print_quoted(char *str);
|
||||||
|
-extern void print_escape(char *str);
|
||||||
|
extern int use_udev(void);
|
||||||
|
extern unsigned long GCD(unsigned long a, unsigned long b);
|
||||||
|
extern int conf_name_is_free(char *name);
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index 77b0066f..05d3b056 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -5561,40 +5561,37 @@ static void imsm_update_version_info(struct intel_super *super)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int check_name(struct intel_super *super, char *name, int quiet)
|
||||||
|
+/**
|
||||||
|
+ * imsm_check_name() - check imsm naming criteria.
|
||||||
|
+ * @super: &intel_super pointer, not NULL.
|
||||||
|
+ * @name: name to check.
|
||||||
|
+ * @verbose: verbose level.
|
||||||
|
+ *
|
||||||
|
+ * Name must be no longer than &MAX_RAID_SERIAL_LEN and must be unique across volumes.
|
||||||
|
+ *
|
||||||
|
+ * Returns: &true if @name matches, &false otherwise.
|
||||||
|
+ */
|
||||||
|
+static bool imsm_is_name_allowed(struct intel_super *super, const char * const name,
|
||||||
|
+ const int verbose)
|
||||||
|
{
|
||||||
|
struct imsm_super *mpb = super->anchor;
|
||||||
|
- char *reason = NULL;
|
||||||
|
- char *start = name;
|
||||||
|
- size_t len = strlen(name);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
- if (len > 0) {
|
||||||
|
- while (isspace(start[len - 1]))
|
||||||
|
- start[--len] = 0;
|
||||||
|
- while (*start && isspace(*start))
|
||||||
|
- ++start, --len;
|
||||||
|
- memmove(name, start, len + 1);
|
||||||
|
+ if (is_string_lq(name, MAX_RAID_SERIAL_LEN + 1) == false) {
|
||||||
|
+ pr_vrb("imsm: Name \"%s\" is too long\n", name);
|
||||||
|
+ return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (len > MAX_RAID_SERIAL_LEN)
|
||||||
|
- reason = "must be 16 characters or less";
|
||||||
|
- else if (len == 0)
|
||||||
|
- reason = "must be a non-empty string";
|
||||||
|
-
|
||||||
|
for (i = 0; i < mpb->num_raid_devs; i++) {
|
||||||
|
struct imsm_dev *dev = get_imsm_dev(super, i);
|
||||||
|
|
||||||
|
if (strncmp((char *) dev->volume, name, MAX_RAID_SERIAL_LEN) == 0) {
|
||||||
|
- reason = "already exists";
|
||||||
|
- break;
|
||||||
|
+ pr_vrb("imsm: Name \"%s\" already exists\n", name);
|
||||||
|
+ return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (reason && !quiet)
|
||||||
|
- pr_err("imsm volume name %s\n", reason);
|
||||||
|
-
|
||||||
|
- return !reason;
|
||||||
|
+ return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
||||||
|
@@ -5689,8 +5686,9 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!check_name(super, name, 0))
|
||||||
|
+ if (imsm_is_name_allowed(super, name, 1) == false)
|
||||||
|
return 0;
|
||||||
|
+
|
||||||
|
dv = xmalloc(sizeof(*dv));
|
||||||
|
dev = xcalloc(1, sizeof(*dev) + sizeof(__u32) * (info->raid_disks - 1));
|
||||||
|
/*
|
||||||
|
@@ -8018,7 +8016,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray,
|
||||||
|
char *ep;
|
||||||
|
int vol;
|
||||||
|
|
||||||
|
- if (!check_name(super, name, 0))
|
||||||
|
+ if (imsm_is_name_allowed(super, name, 1) == false)
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
vol = strtoul(subarray, &ep, 10);
|
||||||
|
@@ -10345,7 +10343,8 @@ 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 || !check_name(super, name, 1)) {
|
||||||
|
+
|
||||||
|
+ if (a || !dev || imsm_is_name_allowed(super, name, 0) == false) {
|
||||||
|
dprintf("failed to rename subarray-%d\n", target);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
diff --git a/tests/00confnames b/tests/00confnames
|
||||||
|
index 25a7127b..10823f01 100644
|
||||||
|
--- a/tests/00confnames
|
||||||
|
+++ b/tests/00confnames
|
||||||
|
@@ -79,10 +79,10 @@ names_verify "/dev/md127" "name" "name"
|
||||||
|
mdadm -S "/dev/md127"
|
||||||
|
|
||||||
|
# 11. <devname> with some special symbols and locales, no <name>.
|
||||||
|
-# It needs to wait a while for timeout because udev cannot create a link - known issue.
|
||||||
|
+# <devname> should be ignored.
|
||||||
|
names_make_conf $_UUID "tźż-\.,<>st+-" "empty" $config
|
||||||
|
mdadm -I $dev0 --config=$config
|
||||||
|
-names_verify "/dev/md127" "tźż-\.,<>st+-" "name"
|
||||||
|
+names_verify "/dev/md127" "name" "name"
|
||||||
|
mdadm -S "/dev/md127"
|
||||||
|
|
||||||
|
# 12. No <devname> and <name> set.
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
128
SOURCES/0158-Incremental-remove-obsoleted-calls-to-udisks.patch
Normal file
128
SOURCES/0158-Incremental-remove-obsoleted-calls-to-udisks.patch
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
From ba489abd688bf70c83e70700aaaec5f5e90889c5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Coly Li <colyli@suse.de>
|
||||||
|
Date: Mon, 14 Aug 2023 00:46:13 +0800
|
||||||
|
Subject: [PATCH 158/165] Incremental: remove obsoleted calls to udisks
|
||||||
|
|
||||||
|
Utility udisks is removed from udev upstream, calling this obsoleted
|
||||||
|
command in run_udisks() doesn't make any sense now.
|
||||||
|
|
||||||
|
This patch removes the calls chain of udisks, which includes routines
|
||||||
|
run_udisk(), force_remove(), and 2 locations where force_remove() are
|
||||||
|
called. Considering force_remove() is removed with udisks util, it is
|
||||||
|
fair to remove Manage_stop() inside force_remove() as well.
|
||||||
|
|
||||||
|
In the two modifications where calling force_remove() are removed,
|
||||||
|
the failure from Manage_subdevs() can be safely ignored, because,
|
||||||
|
1) udisks doesn't exist, no need to check the return value to umount
|
||||||
|
the file system by udisks and remove the component disk again.
|
||||||
|
2) After the 'I' inremental remove, there is another 'r' hot remove
|
||||||
|
following up. The first incremental remove is a best-try effort.
|
||||||
|
|
||||||
|
Therefore in this patch, where force_remove() is removed, the return
|
||||||
|
value of calling Manage_subdevs() is not checked too.
|
||||||
|
|
||||||
|
Signed-off-by: Coly Li <colyli@suse.de>
|
||||||
|
Reviewed-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Cc: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Incremental.c | 64 +++++++++++----------------------------------------
|
||||||
|
1 file changed, 13 insertions(+), 51 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Incremental.c b/Incremental.c
|
||||||
|
index f13ce027..05b33c45 100644
|
||||||
|
--- a/Incremental.c
|
||||||
|
+++ b/Incremental.c
|
||||||
|
@@ -1628,54 +1628,18 @@ release:
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void run_udisks(char *arg1, char *arg2)
|
||||||
|
-{
|
||||||
|
- int pid = fork();
|
||||||
|
- int status;
|
||||||
|
- if (pid == 0) {
|
||||||
|
- manage_fork_fds(1);
|
||||||
|
- execl("/usr/bin/udisks", "udisks", arg1, arg2, NULL);
|
||||||
|
- execl("/bin/udisks", "udisks", arg1, arg2, NULL);
|
||||||
|
- exit(1);
|
||||||
|
- }
|
||||||
|
- while (pid > 0 && wait(&status) != pid)
|
||||||
|
- ;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static int force_remove(char *devnm, int fd, struct mdinfo *mdi, int verbose)
|
||||||
|
-{
|
||||||
|
- int rv;
|
||||||
|
- int devid = devnm2devid(devnm);
|
||||||
|
-
|
||||||
|
- run_udisks("--unmount", map_dev(major(devid), minor(devid), 0));
|
||||||
|
- rv = Manage_stop(devnm, fd, verbose, 1);
|
||||||
|
- if (rv) {
|
||||||
|
- /* At least we can try to trigger a 'remove' */
|
||||||
|
- sysfs_uevent(mdi, "remove");
|
||||||
|
- if (verbose)
|
||||||
|
- pr_err("Fail to stop %s too.\n", devnm);
|
||||||
|
- }
|
||||||
|
- return rv;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static void remove_from_member_array(struct mdstat_ent *memb,
|
||||||
|
struct mddev_dev *devlist, int verbose)
|
||||||
|
{
|
||||||
|
- int rv;
|
||||||
|
- struct mdinfo mmdi;
|
||||||
|
int subfd = open_dev(memb->devnm);
|
||||||
|
|
||||||
|
if (subfd >= 0) {
|
||||||
|
- rv = Manage_subdevs(memb->devnm, subfd, devlist, verbose,
|
||||||
|
- 0, UOPT_UNDEFINED, 0);
|
||||||
|
- if (rv & 2) {
|
||||||
|
- if (sysfs_init(&mmdi, -1, memb->devnm))
|
||||||
|
- pr_err("unable to initialize sysfs for: %s\n",
|
||||||
|
- memb->devnm);
|
||||||
|
- else
|
||||||
|
- force_remove(memb->devnm, subfd, &mmdi,
|
||||||
|
- verbose);
|
||||||
|
- }
|
||||||
|
+ /*
|
||||||
|
+ * Ignore the return value because it's necessary
|
||||||
|
+ * to handle failure condition here.
|
||||||
|
+ */
|
||||||
|
+ Manage_subdevs(memb->devnm, subfd, devlist, verbose,
|
||||||
|
+ 0, UOPT_UNDEFINED, 0);
|
||||||
|
close(subfd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1758,21 +1722,19 @@ int IncrementalRemove(char *devname, char *id_path, int verbose)
|
||||||
|
}
|
||||||
|
free_mdstat(mdstat);
|
||||||
|
} else {
|
||||||
|
- rv |= Manage_subdevs(ent->devnm, mdfd, &devlist,
|
||||||
|
- verbose, 0, UOPT_UNDEFINED, 0);
|
||||||
|
- if (rv & 2) {
|
||||||
|
- /* Failed due to EBUSY, try to stop the array.
|
||||||
|
- * Give udisks a chance to unmount it first.
|
||||||
|
+ /*
|
||||||
|
+ * This 'I' incremental remove is a try-best effort,
|
||||||
|
+ * the failure condition can be safely ignored
|
||||||
|
+ * because of the following up 'r' remove.
|
||||||
|
*/
|
||||||
|
- rv = force_remove(ent->devnm, mdfd, &mdi, verbose);
|
||||||
|
- goto end;
|
||||||
|
- }
|
||||||
|
+ Manage_subdevs(ent->devnm, mdfd, &devlist,
|
||||||
|
+ verbose, 0, UOPT_UNDEFINED, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
devlist.disposition = 'r';
|
||||||
|
rv = Manage_subdevs(ent->devnm, mdfd, &devlist,
|
||||||
|
verbose, 0, UOPT_UNDEFINED, 0);
|
||||||
|
-end:
|
||||||
|
+
|
||||||
|
close(mdfd);
|
||||||
|
free_mdstat(ent);
|
||||||
|
return rv;
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,31 @@
|
|||||||
|
From 28fc84168646910a9271ebe1a12b1571e14f5900 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Xiao Ni <xni@redhat.com>
|
||||||
|
Date: Thu, 7 Sep 2023 16:57:44 +0800
|
||||||
|
Subject: [PATCH 159/165] mdadm/tests: Fix regular expression failure
|
||||||
|
|
||||||
|
The test fails because of the regular expression.
|
||||||
|
|
||||||
|
Signed-off-by: Xiao Ni <xni@redhat.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
tests/06name | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tests/06name b/tests/06name
|
||||||
|
index 4d5e824d..86eaab69 100644
|
||||||
|
--- a/tests/06name
|
||||||
|
+++ b/tests/06name
|
||||||
|
@@ -3,8 +3,8 @@ set -x
|
||||||
|
# create an array with a name
|
||||||
|
|
||||||
|
mdadm -CR $md0 -l0 -n2 --metadata=1 --name="Fred" $dev0 $dev1
|
||||||
|
-mdadm -E $dev0 | grep 'Name : [^:]*:Fred ' > /dev/null || exit 1
|
||||||
|
-mdadm -D $md0 | grep 'Name : [^:]*:Fred ' > /dev/null || exit 1
|
||||||
|
+mdadm -E $dev0 | grep 'Name : Fred' > /dev/null || exit 1
|
||||||
|
+mdadm -D $md0 | grep 'Name : Fred' > /dev/null || exit 1
|
||||||
|
mdadm -S $md0
|
||||||
|
|
||||||
|
mdadm -A $md0 --name="Fred" $devlist
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
141
SOURCES/0160-Fix-race-of-mdadm-add-and-mdadm-incremental.patch
Normal file
141
SOURCES/0160-Fix-race-of-mdadm-add-and-mdadm-incremental.patch
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
From ed2c2cb3d440f3bd2692f1896446c4bcc703f05c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Li Xiao Keng <lixiaokeng@huawei.com>
|
||||||
|
Date: Thu, 7 Sep 2023 19:37:44 +0800
|
||||||
|
Subject: [PATCH 160/165] Fix race of "mdadm --add" and "mdadm --incremental"
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
There is a raid1 with sda and sdb. And we add sdc to this raid,
|
||||||
|
it may return -EBUSY.
|
||||||
|
|
||||||
|
The main process of --add:
|
||||||
|
1. dev_open(sdc) in Manage_add
|
||||||
|
2. store_super1(st, di->fd) in write_init_super1
|
||||||
|
3. fsync(fd) in store_super1
|
||||||
|
4. close(di->fd) in write_init_super1
|
||||||
|
5. ioctl(ADD_NEW_DISK)
|
||||||
|
|
||||||
|
Step 2 and 3 will add sdc to metadata of raid1. There will be
|
||||||
|
udev(change of sdc) event after step4. Then "/usr/sbin/mdadm
|
||||||
|
--incremental --export $devnode --offroot $env{DEVLINKS}"
|
||||||
|
will be run, and the sdc will be added to the raid1. Then
|
||||||
|
step 5 will return -EBUSY because it checks if device isn't
|
||||||
|
claimed in md_import_device()->lock_rdev()->blkdev_get_by_dev()
|
||||||
|
->blkdev_get().
|
||||||
|
|
||||||
|
It will be confusing for users because sdc is added first time.
|
||||||
|
The "incremental" will get map_lock before add sdc to raid1.
|
||||||
|
So we add map_lock before write_init_super in "mdadm --add"
|
||||||
|
to fix the race of "add" and "incremental".
|
||||||
|
|
||||||
|
Signed-off-by: Li Xiao Keng <lixiaokeng@huawei.com>
|
||||||
|
Signed-off-by: Guanqin Miao <miaoguanqin@huawei.com>
|
||||||
|
Reviewed-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Manage.c | 24 ++++++++++++++++--------
|
||||||
|
1 file changed, 16 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Manage.c b/Manage.c
|
||||||
|
index f997b163..075dd720 100644
|
||||||
|
--- a/Manage.c
|
||||||
|
+++ b/Manage.c
|
||||||
|
@@ -704,6 +704,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
|
||||||
|
struct supertype *dev_st;
|
||||||
|
int j;
|
||||||
|
mdu_disk_info_t disc;
|
||||||
|
+ struct map_ent *map = NULL;
|
||||||
|
|
||||||
|
if (!get_dev_size(tfd, dv->devname, &ldsize)) {
|
||||||
|
if (dv->disposition == 'M')
|
||||||
|
@@ -907,6 +908,9 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
|
||||||
|
disc.raid_disk = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (map_lock(&map))
|
||||||
|
+ pr_err("failed to get exclusive lock on mapfile when add disk\n");
|
||||||
|
+
|
||||||
|
if (array->not_persistent==0) {
|
||||||
|
int dfd;
|
||||||
|
if (dv->disposition == 'j')
|
||||||
|
@@ -918,9 +922,9 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
|
||||||
|
dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT);
|
||||||
|
if (tst->ss->add_to_super(tst, &disc, dfd,
|
||||||
|
dv->devname, INVALID_SECTORS))
|
||||||
|
- return -1;
|
||||||
|
+ goto unlock;
|
||||||
|
if (tst->ss->write_init_super(tst))
|
||||||
|
- return -1;
|
||||||
|
+ goto unlock;
|
||||||
|
} else if (dv->disposition == 'A') {
|
||||||
|
/* this had better be raid1.
|
||||||
|
* As we are "--re-add"ing we must find a spare slot
|
||||||
|
@@ -978,14 +982,14 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
|
||||||
|
pr_err("add failed for %s: could not get exclusive access to container\n",
|
||||||
|
dv->devname);
|
||||||
|
tst->ss->free_super(tst);
|
||||||
|
- return -1;
|
||||||
|
+ 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);
|
||||||
|
- return -1;
|
||||||
|
+ goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
Kill(dv->devname, NULL, 0, -1, 0);
|
||||||
|
@@ -994,7 +998,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
|
||||||
|
dv->devname, INVALID_SECTORS)) {
|
||||||
|
close(dfd);
|
||||||
|
close(container_fd);
|
||||||
|
- return -1;
|
||||||
|
+ goto unlock;
|
||||||
|
}
|
||||||
|
if (!mdmon_running(tst->container_devnm))
|
||||||
|
tst->ss->sync_metadata(tst);
|
||||||
|
@@ -1005,7 +1009,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
|
||||||
|
dv->devname);
|
||||||
|
close(container_fd);
|
||||||
|
tst->ss->free_super(tst);
|
||||||
|
- return -1;
|
||||||
|
+ goto unlock;
|
||||||
|
}
|
||||||
|
sra->array.level = LEVEL_CONTAINER;
|
||||||
|
/* Need to set data_offset and component_size */
|
||||||
|
@@ -1020,7 +1024,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
|
||||||
|
pr_err("add new device to external metadata failed for %s\n", dv->devname);
|
||||||
|
close(container_fd);
|
||||||
|
sysfs_free(sra);
|
||||||
|
- return -1;
|
||||||
|
+ goto unlock;
|
||||||
|
}
|
||||||
|
ping_monitor(devnm);
|
||||||
|
sysfs_free(sra);
|
||||||
|
@@ -1034,7 +1038,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
|
||||||
|
else
|
||||||
|
pr_err("add new device failed for %s as %d: %s\n",
|
||||||
|
dv->devname, j, strerror(errno));
|
||||||
|
- return -1;
|
||||||
|
+ goto unlock;
|
||||||
|
}
|
||||||
|
if (dv->disposition == 'j') {
|
||||||
|
pr_err("Journal added successfully, making %s read-write\n", devname);
|
||||||
|
@@ -1045,7 +1049,11 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
|
||||||
|
}
|
||||||
|
if (verbose >= 0)
|
||||||
|
pr_err("added %s\n", dv->devname);
|
||||||
|
+ map_unlock(&map);
|
||||||
|
return 1;
|
||||||
|
+unlock:
|
||||||
|
+ map_unlock(&map);
|
||||||
|
+ return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,32 @@
|
|||||||
|
From c32b4754014c1eec8cc0c025fad2e9b621486164 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Xiao Ni <xni@redhat.com>
|
||||||
|
Date: Fri, 8 Sep 2023 16:44:35 +0800
|
||||||
|
Subject: [PATCH 161/165] mdadm/tests: Don't run mknod before losetup
|
||||||
|
|
||||||
|
Sometimes it can fail:
|
||||||
|
losetup: /var/tmp/mdtest0: failed to set up loop device: No such device or address
|
||||||
|
/dev/loop0 and /var/tmp/mdtest0 are already created before losetup.
|
||||||
|
|
||||||
|
Because losetup can create device node by itself. So remove mknod.
|
||||||
|
|
||||||
|
Signed-off-by: Xiao Ni <xni@redhat.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
tests/func.sh | 1 -
|
||||||
|
1 file changed, 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/tests/func.sh b/tests/func.sh
|
||||||
|
index 9710a53b..5053b012 100644
|
||||||
|
--- a/tests/func.sh
|
||||||
|
+++ b/tests/func.sh
|
||||||
|
@@ -170,7 +170,6 @@ do_setup() {
|
||||||
|
dd if=/dev/zero of=$targetdir/mdtest$d count=$sz bs=1K > /dev/null 2>&1
|
||||||
|
# make sure udev doesn't touch
|
||||||
|
mdadm --zero $targetdir/mdtest$d 2> /dev/null
|
||||||
|
- [ -b /dev/loop$d ] || mknod /dev/loop$d b 7 $d
|
||||||
|
if [ $d -eq 7 ]
|
||||||
|
then
|
||||||
|
losetup /dev/loop$d $targetdir/mdtest6 # for multipath use
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
From 246b4b40558f6f7f84882e9c34659f1b582944e2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Xiao Ni <xni@redhat.com>
|
||||||
|
Date: Wed, 11 Oct 2023 21:03:32 +0800
|
||||||
|
Subject: [PATCH 162/165] mdadm/ddf: Abort when raid disk is smaller in
|
||||||
|
getinfo_super_ddf
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
The metadata is corrupted when the raid_disk<0. So abort directly.
|
||||||
|
This also can avoid a building error:
|
||||||
|
super-ddf.c:1988:58: error: array subscript -1 is below array bounds of ‘struct phys_disk_entry[0]’
|
||||||
|
|
||||||
|
Suggested-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Ackedy-by: Xiao Ni <xni@redhat.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, 4 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/super-ddf.c b/super-ddf.c
|
||||||
|
index c5242654..7571e3b7 100644
|
||||||
|
--- a/super-ddf.c
|
||||||
|
+++ b/super-ddf.c
|
||||||
|
@@ -1984,12 +1984,14 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *m
|
||||||
|
info->disk.number = be32_to_cpu(ddf->dlist->disk.refnum);
|
||||||
|
info->disk.raid_disk = find_phys(ddf, ddf->dlist->disk.refnum);
|
||||||
|
|
||||||
|
+ if (info->disk.raid_disk < 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
info->data_offset = be64_to_cpu(ddf->phys->
|
||||||
|
entries[info->disk.raid_disk].
|
||||||
|
config_size);
|
||||||
|
info->component_size = ddf->dlist->size - info->data_offset;
|
||||||
|
- if (info->disk.raid_disk >= 0)
|
||||||
|
- pde = ddf->phys->entries + info->disk.raid_disk;
|
||||||
|
+ pde = ddf->phys->entries + info->disk.raid_disk;
|
||||||
|
if (pde &&
|
||||||
|
!(be16_to_cpu(pde->state) & DDF_Failed) &&
|
||||||
|
!(be16_to_cpu(pde->state) & DDF_Missing))
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,75 @@
|
|||||||
|
From 6af520a5b4d91cd0fd32ab6361ff4519505c7f47 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Xiao Ni <xni@redhat.com>
|
||||||
|
Date: Tue, 17 Oct 2023 20:35:46 +0800
|
||||||
|
Subject: [PATCH 163/165] mdadm/super1: Add MD_FEATURE_RAID0_LAYOUT if
|
||||||
|
kernel>=5.4
|
||||||
|
|
||||||
|
After and include kernel v5.4, it adds one feature bit MD_FEATURE_RAID0_LAYOUT.
|
||||||
|
It must need to specify a layout for raid0 with more than one zone. But for
|
||||||
|
raid0 with one zone, in fact it also has a defalut layout.
|
||||||
|
|
||||||
|
Now for raid0 with one zone, *unknown* layout can be seen when running mdadm -D
|
||||||
|
command. It's the reason that mdadm doesn't set MD_FEATURE_RAID0_LAYOUT for
|
||||||
|
raid0 with one zone. Then in kernel space, super_1_validate sets mddev->layout
|
||||||
|
to -1 because of no MD_FEATURE_RAID0_LAYOUT. In fact, in raid0 io path, it
|
||||||
|
uses the default layout. Set raid0_need_layout to true if kernel_version<=v5.4.
|
||||||
|
|
||||||
|
Fixes: 329dfc28debb ('Create: add support for RAID0 layouts.')
|
||||||
|
Signed-off-by: Xiao Ni <xni@redhat.com>
|
||||||
|
Reviewed-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
super1.c | 19 ++++++++++++++++---
|
||||||
|
1 file changed, 16 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/super1.c b/super1.c
|
||||||
|
index 856b0208..1da71b98 100644
|
||||||
|
--- a/super1.c
|
||||||
|
+++ b/super1.c
|
||||||
|
@@ -1967,6 +1967,14 @@ fail_to_write:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool has_raid0_layout(struct mdp_superblock_1 *sb)
|
||||||
|
+{
|
||||||
|
+ if (sb->level == 0 && sb->layout != 0)
|
||||||
|
+ return true;
|
||||||
|
+ else
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int write_init_super1(struct supertype *st)
|
||||||
|
{
|
||||||
|
struct mdp_superblock_1 *sb = st->sb;
|
||||||
|
@@ -1978,12 +1986,17 @@ static int write_init_super1(struct supertype *st)
|
||||||
|
unsigned long long sb_offset;
|
||||||
|
unsigned long long data_offset;
|
||||||
|
long bm_offset;
|
||||||
|
- int raid0_need_layout = 0;
|
||||||
|
+ bool raid0_need_layout = false;
|
||||||
|
+
|
||||||
|
+ /* Since linux kernel v5.4, raid0 always has a layout */
|
||||||
|
+ if (has_raid0_layout(sb) && get_linux_version() >= 5004000)
|
||||||
|
+ raid0_need_layout = true;
|
||||||
|
|
||||||
|
for (di = st->info; di; di = di->next) {
|
||||||
|
if (di->disk.state & (1 << MD_DISK_JOURNAL))
|
||||||
|
sb->feature_map |= __cpu_to_le32(MD_FEATURE_JOURNAL);
|
||||||
|
- if (sb->level == 0 && sb->layout != 0) {
|
||||||
|
+ if (has_raid0_layout(sb) && !raid0_need_layout) {
|
||||||
|
+
|
||||||
|
struct devinfo *di2 = st->info;
|
||||||
|
unsigned long long s1, s2;
|
||||||
|
s1 = di->dev_size;
|
||||||
|
@@ -1995,7 +2008,7 @@ static int write_init_super1(struct supertype *st)
|
||||||
|
s2 -= di2->data_offset;
|
||||||
|
s2 /= __le32_to_cpu(sb->chunksize);
|
||||||
|
if (s1 != s2)
|
||||||
|
- raid0_need_layout = 1;
|
||||||
|
+ raid0_need_layout = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
139
SOURCES/0164-mdadm-remove-container_enough-logic.patch
Normal file
139
SOURCES/0164-mdadm-remove-container_enough-logic.patch
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
From 4dde420fc3e24077ab926f79674eaae1b71de10b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pawel Piatkowski <pawel.piatkowski@intel.com>
|
||||||
|
Date: Thu, 19 Oct 2023 16:35:24 +0200
|
||||||
|
Subject: [PATCH 164/165] mdadm: remove container_enough logic
|
||||||
|
|
||||||
|
Arrays without enough disk count will be assembled but not
|
||||||
|
started.
|
||||||
|
Now RAIDs will be assembled always (even if they are failed).
|
||||||
|
RAID devices in all states will be assembled and exposed
|
||||||
|
to mdstat.
|
||||||
|
This change affects only IMSM (for ddf it wasn't used,
|
||||||
|
container_enough was set to true always).
|
||||||
|
Removed this logic from incremental_container as well with
|
||||||
|
runstop checking because runstop condition is being verified
|
||||||
|
in assemble_container_content function.
|
||||||
|
|
||||||
|
Signed-off-by: Pawel Piatkowski <pawel.piatkowski@intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Incremental.c | 11 -----------
|
||||||
|
mdadm.h | 3 ---
|
||||||
|
super-ddf.c | 1 -
|
||||||
|
super-intel.c | 32 +-------------------------------
|
||||||
|
4 files changed, 1 insertion(+), 46 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Incremental.c b/Incremental.c
|
||||||
|
index 05b33c45..3551c65b 100644
|
||||||
|
--- a/Incremental.c
|
||||||
|
+++ b/Incremental.c
|
||||||
|
@@ -1467,17 +1467,6 @@ static int Incremental_container(struct supertype *st, char *devname,
|
||||||
|
|
||||||
|
st->ss->getinfo_super(st, &info, NULL);
|
||||||
|
|
||||||
|
- if ((c->runstop > 0 && info.container_enough >= 0) ||
|
||||||
|
- info.container_enough > 0)
|
||||||
|
- /* pass */;
|
||||||
|
- else {
|
||||||
|
- if (c->export) {
|
||||||
|
- printf("MD_STARTED=no\n");
|
||||||
|
- } else if (c->verbose)
|
||||||
|
- pr_err("not enough devices to start the container\n");
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
match = conf_match(st, &info, devname, c->verbose, &rv);
|
||||||
|
if (match == NULL && rv == 2)
|
||||||
|
return rv;
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index 9effb941..b48e6f86 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -377,9 +377,6 @@ struct mdinfo {
|
||||||
|
int container_member; /* for assembling external-metatdata arrays
|
||||||
|
* This is to be used internally by metadata
|
||||||
|
* handler only */
|
||||||
|
- int container_enough; /* flag external handlers can set to
|
||||||
|
- * indicate that subarrays have not enough (-1),
|
||||||
|
- * enough to start (0), or all expected disks (1) */
|
||||||
|
char sys_name[32];
|
||||||
|
struct mdinfo *devs;
|
||||||
|
struct mdinfo *next;
|
||||||
|
diff --git a/super-ddf.c b/super-ddf.c
|
||||||
|
index 7571e3b7..a87e3169 100644
|
||||||
|
--- a/super-ddf.c
|
||||||
|
+++ b/super-ddf.c
|
||||||
|
@@ -1975,7 +1975,6 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *m
|
||||||
|
info->array.ctime = DECADE + __be32_to_cpu(*cptr);
|
||||||
|
|
||||||
|
info->array.chunk_size = 0;
|
||||||
|
- info->container_enough = 1;
|
||||||
|
|
||||||
|
info->disk.major = 0;
|
||||||
|
info->disk.minor = 0;
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index 05d3b056..6bdd5c4c 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -3806,7 +3806,6 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *
|
||||||
|
struct intel_super *super = st->sb;
|
||||||
|
struct imsm_disk *disk;
|
||||||
|
int map_disks = info->array.raid_disks;
|
||||||
|
- int max_enough = -1;
|
||||||
|
int i;
|
||||||
|
struct imsm_super *mpb;
|
||||||
|
|
||||||
|
@@ -3848,12 +3847,9 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *
|
||||||
|
|
||||||
|
for (i = 0; i < mpb->num_raid_devs; i++) {
|
||||||
|
struct imsm_dev *dev = get_imsm_dev(super, i);
|
||||||
|
- int failed, enough, j, missing = 0;
|
||||||
|
+ int j = 0;
|
||||||
|
struct imsm_map *map;
|
||||||
|
- __u8 state;
|
||||||
|
|
||||||
|
- failed = imsm_count_failed(super, dev, MAP_0);
|
||||||
|
- state = imsm_check_degraded(super, dev, failed, MAP_0);
|
||||||
|
map = get_imsm_map(dev, MAP_0);
|
||||||
|
|
||||||
|
/* any newly missing disks?
|
||||||
|
@@ -3868,36 +3864,10 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *
|
||||||
|
|
||||||
|
if (!(ord & IMSM_ORD_REBUILD) &&
|
||||||
|
get_imsm_missing(super, idx)) {
|
||||||
|
- missing = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- if (state == IMSM_T_STATE_FAILED)
|
||||||
|
- enough = -1;
|
||||||
|
- else if (state == IMSM_T_STATE_DEGRADED &&
|
||||||
|
- (state != map->map_state || missing))
|
||||||
|
- enough = 0;
|
||||||
|
- else /* we're normal, or already degraded */
|
||||||
|
- enough = 1;
|
||||||
|
- if (is_gen_migration(dev) && missing) {
|
||||||
|
- /* during general migration we need all disks
|
||||||
|
- * that process is running on.
|
||||||
|
- * No new missing disk is allowed.
|
||||||
|
- */
|
||||||
|
- max_enough = -1;
|
||||||
|
- enough = -1;
|
||||||
|
- /* no more checks necessary
|
||||||
|
- */
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- /* in the missing/failed disk case check to see
|
||||||
|
- * if at least one array is runnable
|
||||||
|
- */
|
||||||
|
- max_enough = max(max_enough, enough);
|
||||||
|
}
|
||||||
|
- dprintf("enough: %d\n", max_enough);
|
||||||
|
- info->container_enough = max_enough;
|
||||||
|
|
||||||
|
if (super->disks) {
|
||||||
|
__u32 reserved = imsm_reserved_sectors(super, super->disks);
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,49 @@
|
|||||||
|
From d8d09c1633b2f06f88633ab960aa02b41a6bdfb6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pawel Piatkowski <pawel.piatkowski@intel.com>
|
||||||
|
Date: Thu, 19 Oct 2023 16:35:25 +0200
|
||||||
|
Subject: [PATCH 165/165] Fix assembling RAID volume by using incremental
|
||||||
|
|
||||||
|
After change "mdadm: remove container_enough logic"
|
||||||
|
IMSM volumes are started immediately. If volume is during
|
||||||
|
reshape, then it will be blocked by block_subarray() during
|
||||||
|
first mdadm -I <devname>. Assemble_container_content() for
|
||||||
|
next disk will see the change because metadata version from
|
||||||
|
sysfs and metadata doesn't match and will execute
|
||||||
|
sysfs_set_array again. Then it fails to set same
|
||||||
|
component_size, it is prohibited by kernel.
|
||||||
|
|
||||||
|
If array is frozen then first sign from metadata version
|
||||||
|
is different ("/" vs "-"), so exclude it from comparison.
|
||||||
|
All we want is to double check that base properties are set
|
||||||
|
and we don't need to call sysfs_set_array again.
|
||||||
|
|
||||||
|
Signed-off-by: Pawel Piatkowski <pawel.piatkowski@intel.com>
|
||||||
|
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
|
||||||
|
---
|
||||||
|
Assemble.c | 10 ++++------
|
||||||
|
1 file changed, 4 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Assemble.c b/Assemble.c
|
||||||
|
index 5be58e40..0557a007 100644
|
||||||
|
--- a/Assemble.c
|
||||||
|
+++ b/Assemble.c
|
||||||
|
@@ -1990,12 +1990,10 @@ int assemble_container_content(struct supertype *st, int mdfd,
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (strcmp(sra->text_version, content->text_version) != 0) {
|
||||||
|
- if (content->array.major_version == -1 &&
|
||||||
|
- content->array.minor_version == -2 &&
|
||||||
|
- c->readonly &&
|
||||||
|
- content->text_version[0] == '/')
|
||||||
|
- content->text_version[0] = '-';
|
||||||
|
+ /* Fill sysfs properties only if they are not set. Determine it by checking text_version
|
||||||
|
+ * 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) {
|
||||||
|
sysfs_free(sra);
|
||||||
|
return 1;
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
151
SOURCES/0166-Revert-mdadm-remove-container_enough-logic.patch
Normal file
151
SOURCES/0166-Revert-mdadm-remove-container_enough-logic.patch
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
From 476b00bdeeb6c004b3a758bd842b0fa9e4164508 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Mon, 5 Feb 2024 15:50:29 +0100
|
||||||
|
Subject: [PATCH 1/1] Revert "mdadm: remove container_enough logic"
|
||||||
|
|
||||||
|
Mentioned patch changes way of IMSM member arrays assembling, they are
|
||||||
|
updated by every new drive incremental processes. Previously, member
|
||||||
|
arrays were created and filled once, by last drive incremental process.
|
||||||
|
|
||||||
|
We determined regressions with various impact. Unfortunately, initial
|
||||||
|
testing didn't show them.
|
||||||
|
|
||||||
|
Regressions are connected to drive appearance order and may not be
|
||||||
|
reproducible on every configuration, there are at least two know
|
||||||
|
issues for now:
|
||||||
|
|
||||||
|
- sysfs attributes are filled using old metadata if there is
|
||||||
|
outdated drive and it is enumerated first.
|
||||||
|
|
||||||
|
- rebuild may be aborted and started from beginning after reboot,
|
||||||
|
if drive under rebuild is enumerated as the last one.
|
||||||
|
|
||||||
|
This reverts commit 4dde420fc3e24077ab926f79674eaae1b71de10b. It fixes
|
||||||
|
checkpatch issues and reworks logic to remove empty "if" branch in
|
||||||
|
Incremental.
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
Incremental.c | 9 +++++++++
|
||||||
|
mdadm.h | 7 +++++++
|
||||||
|
super-ddf.c | 1 +
|
||||||
|
super-intel.c | 32 +++++++++++++++++++++++++++++++-
|
||||||
|
4 files changed, 48 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/Incremental.c b/Incremental.c
|
||||||
|
index 6cbc164a27b9..30c07c037028 100644
|
||||||
|
--- a/Incremental.c
|
||||||
|
+++ b/Incremental.c
|
||||||
|
@@ -1467,6 +1467,15 @@ static int Incremental_container(struct supertype *st, char *devname,
|
||||||
|
|
||||||
|
st->ss->getinfo_super(st, &info, NULL);
|
||||||
|
|
||||||
|
+ if (info.container_enough < 0 || (info.container_enough == 0 && c->runstop < 1)) {
|
||||||
|
+ if (c->export)
|
||||||
|
+ printf("MD_STARTED=no\n");
|
||||||
|
+ else if (c->verbose)
|
||||||
|
+ pr_err("Not enough devices to start the container.\n");
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
match = conf_match(st, &info, devname, c->verbose, &rv);
|
||||||
|
if (match == NULL && rv == 2)
|
||||||
|
return rv;
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index 709b6104c401..1f28b3e754be 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -377,6 +377,13 @@ struct mdinfo {
|
||||||
|
int container_member; /* for assembling external-metatdata arrays
|
||||||
|
* This is to be used internally by metadata
|
||||||
|
* handler only */
|
||||||
|
+ /**
|
||||||
|
+ * flag external handlers can set to indicate that subarrays have:
|
||||||
|
+ * - not enough disks to start (-1),
|
||||||
|
+ * - enough disks to start (0),
|
||||||
|
+ * - all expected disks (1).
|
||||||
|
+ */
|
||||||
|
+ int container_enough;
|
||||||
|
char sys_name[32];
|
||||||
|
struct mdinfo *devs;
|
||||||
|
struct mdinfo *next;
|
||||||
|
diff --git a/super-ddf.c b/super-ddf.c
|
||||||
|
index a87e3169d325..7571e3b740c6 100644
|
||||||
|
--- a/super-ddf.c
|
||||||
|
+++ b/super-ddf.c
|
||||||
|
@@ -1975,6 +1975,7 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *m
|
||||||
|
info->array.ctime = DECADE + __be32_to_cpu(*cptr);
|
||||||
|
|
||||||
|
info->array.chunk_size = 0;
|
||||||
|
+ info->container_enough = 1;
|
||||||
|
|
||||||
|
info->disk.major = 0;
|
||||||
|
info->disk.minor = 0;
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index 6a664a2e58d3..dbea235dd4bd 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -3778,6 +3778,7 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *
|
||||||
|
struct intel_super *super = st->sb;
|
||||||
|
struct imsm_disk *disk;
|
||||||
|
int map_disks = info->array.raid_disks;
|
||||||
|
+ int max_enough = -1;
|
||||||
|
int i;
|
||||||
|
struct imsm_super *mpb;
|
||||||
|
|
||||||
|
@@ -3819,9 +3820,12 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *
|
||||||
|
|
||||||
|
for (i = 0; i < mpb->num_raid_devs; i++) {
|
||||||
|
struct imsm_dev *dev = get_imsm_dev(super, i);
|
||||||
|
- int j = 0;
|
||||||
|
+ int failed, enough, j, missing = 0;
|
||||||
|
struct imsm_map *map;
|
||||||
|
+ __u8 state;
|
||||||
|
|
||||||
|
+ failed = imsm_count_failed(super, dev, MAP_0);
|
||||||
|
+ state = imsm_check_degraded(super, dev, failed, MAP_0);
|
||||||
|
map = get_imsm_map(dev, MAP_0);
|
||||||
|
|
||||||
|
/* any newly missing disks?
|
||||||
|
@@ -3836,11 +3840,37 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *
|
||||||
|
|
||||||
|
if (!(ord & IMSM_ORD_REBUILD) &&
|
||||||
|
get_imsm_missing(super, idx)) {
|
||||||
|
+ missing = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (state == IMSM_T_STATE_FAILED)
|
||||||
|
+ enough = -1;
|
||||||
|
+ else if (state == IMSM_T_STATE_DEGRADED &&
|
||||||
|
+ (state != map->map_state || missing))
|
||||||
|
+ enough = 0;
|
||||||
|
+ else /* we're normal, or already degraded */
|
||||||
|
+ enough = 1;
|
||||||
|
+ if (is_gen_migration(dev) && missing) {
|
||||||
|
+ /* during general migration we need all disks
|
||||||
|
+ * that process is running on.
|
||||||
|
+ * No new missing disk is allowed.
|
||||||
|
+ */
|
||||||
|
+ max_enough = -1;
|
||||||
|
+ enough = -1;
|
||||||
|
+ /* no more checks necessary
|
||||||
|
+ */
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ /* in the missing/failed disk case check to see
|
||||||
|
+ * if at least one array is runnable
|
||||||
|
+ */
|
||||||
|
+ max_enough = max(max_enough, enough);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ info->container_enough = max_enough;
|
||||||
|
+
|
||||||
|
if (super->disks) {
|
||||||
|
__u32 reserved = imsm_reserved_sectors(super, super->disks);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.32.0 (Apple Git-132)
|
||||||
|
|
@ -1,11 +0,0 @@
|
|||||||
--- mdadm/Makefile.orig 2021-07-28 21:39:23.887433859 +0800
|
|
||||||
+++ mdadm/Makefile 2021-07-28 21:39:37.989432841 +0800
|
|
||||||
@@ -50,7 +50,7 @@
|
|
||||||
CC := $(CROSS_COMPILE)gcc
|
|
||||||
endif
|
|
||||||
CXFLAGS ?= -ggdb
|
|
||||||
-CWFLAGS = -Wall -Werror -Wstrict-prototypes -Wextra -Wno-unused-parameter
|
|
||||||
+CWFLAGS = -Wall -Wstrict-prototypes -Wextra -Wno-unused-parameter
|
|
||||||
ifdef WARN_UNUSED
|
|
||||||
CWFLAGS += -Wp,-D_FORTIFY_SOURCE=2 -O3
|
|
||||||
endif
|
|
27
SOURCES/md-auto-readd.rule
Normal file
27
SOURCES/md-auto-readd.rule
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#
|
||||||
|
# Enable/Disable - default is Disabled
|
||||||
|
# to disable this rule, GOTO="md_end" should be the first active command.
|
||||||
|
# to enable this rule, Comment out GOTO="md_end".
|
||||||
|
GOTO="md_end"
|
||||||
|
|
||||||
|
# Required: MD arrays must have a bitmap for transient devices to
|
||||||
|
# be added back in the array.
|
||||||
|
# mdadm -CR /dev/md0 -l1 -n2 /dev/sd[ab] –bitmap=internal
|
||||||
|
|
||||||
|
# Don't process any events if anaconda is running as anaconda brings up
|
||||||
|
# raid devices manually
|
||||||
|
ENV{ANACONDA}=="?*", GOTO="md_end"
|
||||||
|
|
||||||
|
# Also don't process disks that are slated to be a multipath device
|
||||||
|
ENV{DM_MULTIPATH_DEVICE_PATH}=="1", GOTO="md_end"
|
||||||
|
|
||||||
|
# We process add events on block devices (since they are ready as soon as
|
||||||
|
# they are added to the system)
|
||||||
|
|
||||||
|
ACTION!="add", GOTO="md_end"
|
||||||
|
ENV{ID_FS_TYPE}!="linux_raid_member", GOTO="md_end"
|
||||||
|
SUBSYSTEM=="block", RUN{program}+="/usr/sbin/md-auto-readd.sh $devnode"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Land here to exit cleanly
|
||||||
|
LABEL="md_end"
|
17
SOURCES/md-auto-readd.sh
Normal file
17
SOURCES/md-auto-readd.sh
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
MDADM=/sbin/mdadm
|
||||||
|
DEVNAME=$1
|
||||||
|
|
||||||
|
export $(${MDADM} --examine --export ${DEVNAME})
|
||||||
|
if [ -z "${MD_UUID}" ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
UUID_LINK=$(readlink /dev/disk/by-id/md-uuid-${MD_UUID})
|
||||||
|
MD_DEVNAME=${UUID_LINK##*/}
|
||||||
|
export $(${MDADM} --detail --export /dev/${MD_DEVNAME})
|
||||||
|
if [ -z "${MD_METADATA}" ] ; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
${MDADM} --manage /dev/${MD_DEVNAME} --re-add ${DEVNAME} --verbose
|
166
SOURCES/mdcheck
Normal file
166
SOURCES/mdcheck
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Copyright (C) 2014-2017 Neil Brown <neilb@suse.de>
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# Author: Neil Brown
|
||||||
|
# Email: <neilb@suse.com>
|
||||||
|
|
||||||
|
# This script should be run periodically to automatically
|
||||||
|
# perform a 'check' on any md arrays.
|
||||||
|
#
|
||||||
|
# It supports a 'time budget' such that any incomplete 'check'
|
||||||
|
# will be checkpointed when that time has expired.
|
||||||
|
# A subsequent invocation can allow the 'check' to continue.
|
||||||
|
#
|
||||||
|
# Options are:
|
||||||
|
# --continue Don't start new checks, only continue old ones.
|
||||||
|
# --duration This is passed to "date --date=$duration" to find out
|
||||||
|
# when to finish
|
||||||
|
#
|
||||||
|
# To support '--continue', arrays are identified by UUID and the 'sync_completed'
|
||||||
|
# value is stored in /var/lib/mdcheck/$UUID
|
||||||
|
|
||||||
|
# convert a /dev/md name into /sys/.../md equivalent
|
||||||
|
sysname() {
|
||||||
|
set `ls -lLd $1`
|
||||||
|
maj=${5%,}
|
||||||
|
min=$6
|
||||||
|
readlink -f /sys/dev/block/$maj:$min
|
||||||
|
}
|
||||||
|
|
||||||
|
args=$(getopt -o hcd: -l help,continue,duration: -n mdcheck -- "$@")
|
||||||
|
rv=$?
|
||||||
|
if [ $rv -ne 0 ]; then exit $rv; fi
|
||||||
|
|
||||||
|
eval set -- $args
|
||||||
|
|
||||||
|
cont=
|
||||||
|
endtime=
|
||||||
|
while [ " $1" != " --" ]
|
||||||
|
do
|
||||||
|
case $1 in
|
||||||
|
--help )
|
||||||
|
echo >&2 'Usage: mdcheck [--continue] [--duration time-offset]'
|
||||||
|
echo >&2 ' time-offset must be understood by "date --date"'
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--continue ) cont=yes ;;
|
||||||
|
--duration ) shift; dur=$1
|
||||||
|
endtime=$(date --date "$dur" "+%s")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
shift
|
||||||
|
|
||||||
|
# We need a temp file occasionally...
|
||||||
|
tmp=/var/lib/mdcheck/.md-check-$$
|
||||||
|
trap 'rm -f "$tmp"' 0 2 3 15
|
||||||
|
|
||||||
|
|
||||||
|
# firstly, clean out really old state files
|
||||||
|
mkdir -p /var/lib/mdcheck
|
||||||
|
find /var/lib/mdcheck -name "MD_UUID*" -type f -mtime +180 -exec rm {} \;
|
||||||
|
|
||||||
|
# Now look at each md device.
|
||||||
|
cnt=0
|
||||||
|
for dev in /dev/md?*
|
||||||
|
do
|
||||||
|
[ -e "$dev" ] || continue
|
||||||
|
sys=`sysname $dev`
|
||||||
|
if [ ! -f "$sys/md/sync_action" ]
|
||||||
|
then # cannot check this array
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if [ "`cat $sys/md/sync_action`" != 'idle' ]
|
||||||
|
then # This array is busy
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
mdadm --detail --export "$dev" | grep '^MD_UUID=' > $tmp || continue
|
||||||
|
source $tmp
|
||||||
|
fl="/var/lib/mdcheck/MD_UUID_$MD_UUID"
|
||||||
|
if [ -z "$cont" ]
|
||||||
|
then
|
||||||
|
start=0
|
||||||
|
logger -p daemon.info mdcheck start checking $dev
|
||||||
|
elif [ -z "$MD_UUID" -o ! -f "$fl" ]
|
||||||
|
then
|
||||||
|
# Nothing to continue here
|
||||||
|
continue
|
||||||
|
else
|
||||||
|
start=`cat "$fl"`
|
||||||
|
logger -p daemon.info mdcheck continue checking $dev from $start
|
||||||
|
fi
|
||||||
|
|
||||||
|
cnt=$[cnt+1]
|
||||||
|
eval MD_${cnt}_fl=\$fl
|
||||||
|
eval MD_${cnt}_sys=\$sys
|
||||||
|
eval MD_${cnt}_dev=\$dev
|
||||||
|
echo $start > $fl
|
||||||
|
echo $start > $sys/md/sync_min
|
||||||
|
echo check > $sys/md/sync_action
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$endtime" ]
|
||||||
|
then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
while [ `date +%s` -lt $endtime ]
|
||||||
|
do
|
||||||
|
any=
|
||||||
|
for i in `eval echo {1..$cnt}`
|
||||||
|
do
|
||||||
|
eval fl=\$MD_${i}_fl
|
||||||
|
eval sys=\$MD_${i}_sys
|
||||||
|
eval dev=\$MD_${i}_dev
|
||||||
|
|
||||||
|
if [ -z "$fl" ]; then continue; fi
|
||||||
|
|
||||||
|
if [ "`cat $sys/md/sync_action`" != 'check' ]
|
||||||
|
then
|
||||||
|
logger -p daemon.info mdcheck finished checking $dev
|
||||||
|
eval MD_${i}_fl=
|
||||||
|
rm -f $fl
|
||||||
|
continue;
|
||||||
|
fi
|
||||||
|
read a rest < $sys/md/sync_completed
|
||||||
|
echo $a > $fl
|
||||||
|
any=yes
|
||||||
|
done
|
||||||
|
if [ -z "$any" ]; then exit 0; fi
|
||||||
|
sleep 120
|
||||||
|
done
|
||||||
|
|
||||||
|
# We've waited, and there are still checks running.
|
||||||
|
# Time to stop them.
|
||||||
|
for i in `eval echo {1..$cnt}`
|
||||||
|
do
|
||||||
|
eval fl=\$MD_${i}_fl
|
||||||
|
eval sys=\$MD_${i}_sys
|
||||||
|
eval dev=\$MD_${i}_dev
|
||||||
|
|
||||||
|
if [ -z "$fl" ]; then continue; fi
|
||||||
|
|
||||||
|
if [ "`cat $sys/md/sync_action`" != 'check' ]
|
||||||
|
then
|
||||||
|
eval MD_${i}_fl=
|
||||||
|
rm -f $fl
|
||||||
|
continue;
|
||||||
|
fi
|
||||||
|
echo idle > $sys/md/sync_action
|
||||||
|
cat $sys/md/sync_min > $fl
|
||||||
|
logger -p daemon.info pause checking $dev at `cat $fl`
|
||||||
|
done
|
255
SPECS/mdadm.spec
255
SPECS/mdadm.spec
@ -1,7 +1,7 @@
|
|||||||
Name: mdadm
|
Name: mdadm
|
||||||
Version: 4.2
|
Version: 4.2
|
||||||
# extraversion is used to define rhel internal version
|
# extraversion is used to define rhel internal version
|
||||||
%define extraversion 8
|
%define extraversion 12
|
||||||
Release: %{extraversion}%{?dist}
|
Release: %{extraversion}%{?dist}
|
||||||
Summary: The mdadm program controls Linux md devices (software RAID arrays)
|
Summary: The mdadm program controls Linux md devices (software RAID arrays)
|
||||||
URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/
|
URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/
|
||||||
@ -15,6 +15,9 @@ Source4: mdadm.conf
|
|||||||
Source5: mdadm_event.conf
|
Source5: mdadm_event.conf
|
||||||
Source6: raid-check.timer
|
Source6: raid-check.timer
|
||||||
Source7: raid-check.service
|
Source7: raid-check.service
|
||||||
|
Source8: mdcheck
|
||||||
|
Source9: md-auto-readd.rule
|
||||||
|
Source10: md-auto-readd.sh
|
||||||
|
|
||||||
Patch000: 0001-Unify-error-message.patch
|
Patch000: 0001-Unify-error-message.patch
|
||||||
Patch001: 0002-mdadm-Fix-double-free.patch
|
Patch001: 0002-mdadm-Fix-double-free.patch
|
||||||
@ -27,85 +30,166 @@ Patch007: 0008-mdadm-Update-config-man-regarding-default-files-and-.patch
|
|||||||
Patch008: 0009-mdadm-Update-config-manual.patch
|
Patch008: 0009-mdadm-Update-config-manual.patch
|
||||||
Patch009: 0010-Create-Build-use-default_layout.patch
|
Patch009: 0010-Create-Build-use-default_layout.patch
|
||||||
Patch010: 0011-mdadm-add-map_num_s.patch
|
Patch010: 0011-mdadm-add-map_num_s.patch
|
||||||
# patch0012 is deleted because of needing KillMode=none
|
Patch011: 0012-mdadm-systemd-remove-KillMode-none-from-service-file.patch
|
||||||
Patch011: 0013-mdmon-Stop-parsing-duplicate-options.patch
|
Patch012: 0013-mdmon-Stop-parsing-duplicate-options.patch
|
||||||
Patch012: 0014-Grow-block-n-on-external-volumes.patch
|
Patch013: 0014-Grow-block-n-on-external-volumes.patch
|
||||||
Patch013: 0015-Incremental-Fix-possible-memory-and-resource-leaks.patch
|
Patch014: 0015-Incremental-Fix-possible-memory-and-resource-leaks.patch
|
||||||
Patch014: 0016-Mdmonitor-Fix-segfault.patch
|
Patch015: 0016-Mdmonitor-Fix-segfault.patch
|
||||||
Patch015: 0017-Mdmonitor-Improve-logging-method.patch
|
Patch016: 0017-Mdmonitor-Improve-logging-method.patch
|
||||||
Patch016: 0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch
|
Patch017: 0018-Fix-possible-NULL-ptr-dereferences-and-memory-leaks.patch
|
||||||
Patch017: 0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch
|
Patch018: 0019-imsm-Remove-possibility-for-get_imsm_dev-to-return-N.patch
|
||||||
Patch018: 0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch
|
Patch019: 0020-Revert-mdadm-fix-coredump-of-mdadm-monitor-r.patch
|
||||||
Patch019: 0021-util-replace-ioctl-use-with-function.patch
|
Patch020: 0021-util-replace-ioctl-use-with-function.patch
|
||||||
Patch020: 0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch
|
Patch021: 0022-mdadm-super1-restore-commit-45a87c2f31335-to-fix-clu.patch
|
||||||
Patch021: 0023-imsm-introduce-get_disk_slot_in_dev.patch
|
Patch022: 0023-imsm-introduce-get_disk_slot_in_dev.patch
|
||||||
Patch022: 0024-imsm-use-same-slot-across-container.patch
|
Patch023: 0024-imsm-use-same-slot-across-container.patch
|
||||||
Patch023: 0025-imsm-block-changing-slots-during-creation.patch
|
Patch024: 0025-imsm-block-changing-slots-during-creation.patch
|
||||||
Patch024: 0026-mdadm-block-update-ppl-for-non-raid456-levels.patch
|
Patch025: 0026-mdadm-block-update-ppl-for-non-raid456-levels.patch
|
||||||
Patch025: 0027-mdadm-Fix-array-size-mismatch-after-grow.patch
|
Patch026: 0027-mdadm-Fix-array-size-mismatch-after-grow.patch
|
||||||
Patch026: 0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch
|
Patch027: 0028-mdadm-Remove-dead-code-in-imsm_fix_size_mismatch.patch
|
||||||
Patch027: 0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch
|
Patch028: 0029-Monitor-use-devname-as-char-array-instead-of-pointer.patch
|
||||||
Patch028: 0030-Monitor-use-snprintf-to-fill-device-name.patch
|
Patch029: 0030-Monitor-use-snprintf-to-fill-device-name.patch
|
||||||
Patch029: 0031-Makefile-Don-t-build-static-build-with-everything-an.patch
|
Patch030: 0031-Makefile-Don-t-build-static-build-with-everything-an.patch
|
||||||
Patch030: 0032-DDF-Cleanup-validate_geometry_ddf_container.patch
|
Patch031: 0032-DDF-Cleanup-validate_geometry_ddf_container.patch
|
||||||
Patch031: 0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch
|
Patch032: 0033-DDF-Fix-NULL-pointer-dereference-in-validate_geometr.patch
|
||||||
Patch032: 0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch
|
Patch033: 0034-mdadm-Grow-Fix-use-after-close-bug-by-closing-after-.patch
|
||||||
Patch033: 0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch
|
Patch034: 0035-monitor-Avoid-segfault-when-calling-NULL-get_bad_blo.patch
|
||||||
Patch034: 0036-mdadm-Fix-mdadm-r-remove-option-regression.patch
|
Patch035: 0036-mdadm-Fix-mdadm-r-remove-option-regression.patch
|
||||||
Patch035: 0037-mdadm-Fix-optional-write-behind-parameter.patch
|
Patch036: 0037-mdadm-Fix-optional-write-behind-parameter.patch
|
||||||
Patch036: 0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch
|
Patch037: 0038-tests-00raid0-add-a-test-that-validates-raid0-with-l.patch
|
||||||
Patch037: 0039-tests-fix-raid0-tests-for-0.90-metadata.patch
|
Patch038: 0039-tests-fix-raid0-tests-for-0.90-metadata.patch
|
||||||
Patch038: 0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch
|
Patch039: 0040-tests-04update-metadata-avoid-passing-chunk-size-to-.patch
|
||||||
Patch039: 0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch
|
Patch040: 0041-tests-02lineargrow-clear-the-superblock-at-every-ite.patch
|
||||||
Patch040: 0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch
|
Patch041: 0042-mdadm-test-Add-a-mode-to-repeat-specified-tests.patch
|
||||||
Patch041: 0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch
|
Patch042: 0043-mdadm-test-Mark-and-ignore-broken-test-failures.patch
|
||||||
Patch042: 0044-tests-Add-broken-files-for-all-broken-tests.patch
|
Patch043: 0044-tests-Add-broken-files-for-all-broken-tests.patch
|
||||||
Patch043: 0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch
|
Patch044: 0045-mdadm-Replace-obsolete-usleep-with-nanosleep.patch
|
||||||
Patch044: 0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch
|
Patch045: 0046-tests-00readonly-Run-udevadm-settle-before-setting-r.patch
|
||||||
Patch045: 0047-tests-add-test-for-names.patch
|
Patch046: 0047-tests-add-test-for-names.patch
|
||||||
Patch046: 0048-mdadm-remove-symlink-option.patch
|
Patch047: 0048-mdadm-remove-symlink-option.patch
|
||||||
Patch047: 0049-mdadm-move-data_offset-to-struct-shape.patch
|
Patch048: 0049-mdadm-move-data_offset-to-struct-shape.patch
|
||||||
Patch048: 0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch
|
Patch049: 0050-mdadm-Don-t-open-md-device-for-CREATE-and-ASSEMBLE.patch
|
||||||
Patch049: 0051-Grow-Split-Grow_reshape-into-helper-function.patch
|
Patch050: 0051-Grow-Split-Grow_reshape-into-helper-function.patch
|
||||||
Patch050: 0052-Assemble-check-if-device-is-container-before-schedul.patch
|
Patch051: 0052-Assemble-check-if-device-is-container-before-schedul.patch
|
||||||
Patch051: 0053-super1-report-truncated-device.patch
|
Patch052: 0053-super1-report-truncated-device.patch
|
||||||
Patch052: 0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch
|
Patch053: 0054-mdadm-Correct-typos-punctuation-and-grammar-in-man.patch
|
||||||
Patch053: 0055-Manage-Block-unsafe-member-failing.patch
|
Patch054: 0055-Manage-Block-unsafe-member-failing.patch
|
||||||
Patch054: 0056-Monitor-Fix-statelist-memory-leaks.patch
|
Patch055: 0056-Monitor-Fix-statelist-memory-leaks.patch
|
||||||
Patch055: 0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch
|
Patch056: 0057-mdadm-added-support-for-Intel-Alderlake-RST-on-VMD-p.patch
|
||||||
Patch056: 0058-mdadm-Add-Documentation-entries-to-systemd-services.patch
|
Patch057: 0058-mdadm-Add-Documentation-entries-to-systemd-services.patch
|
||||||
Patch057: 0059-ReadMe-fix-command-line-help.patch
|
Patch058: 0059-ReadMe-fix-command-line-help.patch
|
||||||
Patch058: 0060-mdadm-replace-container-level-checking-with-inline.patch
|
Patch059: 0060-mdadm-replace-container-level-checking-with-inline.patch
|
||||||
Patch059: 0061-Mdmonitor-Omit-non-md-devices.patch
|
Patch060: 0061-Mdmonitor-Omit-non-md-devices.patch
|
||||||
Patch060: 0062-Mdmonitor-Split-alert-into-separate-functions.patch
|
Patch061: 0062-Mdmonitor-Split-alert-into-separate-functions.patch
|
||||||
Patch061: 0063-Monitor-block-if-monitor-modes-are-combined.patch
|
Patch062: 0063-Monitor-block-if-monitor-modes-are-combined.patch
|
||||||
Patch062: 0064-Update-mdadm-Monitor-manual.patch
|
Patch063: 0064-Update-mdadm-Monitor-manual.patch
|
||||||
Patch063: 0065-Grow-fix-possible-memory-leak.patch
|
Patch064: 0065-Grow-fix-possible-memory-leak.patch
|
||||||
Patch064: 0066-mdadm-create-ident_init.patch
|
Patch065: 0066-mdadm-create-ident_init.patch
|
||||||
Patch065: 0067-mdadm-Add-option-validation-for-update-subarray.patch
|
Patch066: 0067-mdadm-Add-option-validation-for-update-subarray.patch
|
||||||
Patch066: 0068-Fix-update-subarray-on-active-volume.patch
|
Patch067: 0068-Fix-update-subarray-on-active-volume.patch
|
||||||
Patch067: 0069-Add-code-specific-update-options-to-enum.patch
|
Patch068: 0069-Add-code-specific-update-options-to-enum.patch
|
||||||
Patch068: 0070-super-ddf-Remove-update_super_ddf.patch
|
Patch069: 0070-super-ddf-Remove-update_super_ddf.patch
|
||||||
Patch069: 0071-super0-refactor-the-code-for-enum.patch
|
Patch070: 0071-super0-refactor-the-code-for-enum.patch
|
||||||
Patch070: 0072-super1-refactor-the-code-for-enum.patch
|
Patch071: 0072-super1-refactor-the-code-for-enum.patch
|
||||||
Patch071: 0073-super-intel-refactor-the-code-for-enum.patch
|
Patch072: 0073-super-intel-refactor-the-code-for-enum.patch
|
||||||
Patch072: 0074-Change-update-to-enum-in-update_super-and-update_sub.patch
|
Patch073: 0074-Change-update-to-enum-in-update_super-and-update_sub.patch
|
||||||
Patch073: 0075-Manage-Incremental-code-refactor-string-to-enum.patch
|
Patch074: 0075-Manage-Incremental-code-refactor-string-to-enum.patch
|
||||||
Patch074: 0076-Change-char-to-enum-in-context-update-refactor-code.patch
|
Patch075: 0076-Change-char-to-enum-in-context-update-refactor-code.patch
|
||||||
Patch075: 0077-mdmon-fix-segfault.patch
|
Patch076: 0077-mdmon-fix-segfault.patch
|
||||||
Patch076: 0078-util-remove-obsolete-code-from-get_md_name.patch
|
Patch077: 0078-util-remove-obsolete-code-from-get_md_name.patch
|
||||||
Patch077: 0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch
|
Patch078: 0079-mdadm-udev-Don-t-handle-change-event-on-raw-devices.patch
|
||||||
Patch078: 0080-Manage-do-not-check-array-state-when-drive-is-remove.patch
|
Patch079: 0080-Manage-do-not-check-array-state-when-drive-is-remove.patch
|
||||||
Patch079: 0081-incremental-manage-do-not-verify-if-remove-is-safe.patch
|
Patch080: 0081-incremental-manage-do-not-verify-if-remove-is-safe.patch
|
||||||
Patch080: 0082-super-intel-make-freesize-not-required-for-chunk-siz.patch
|
Patch081: 0082-super-intel-make-freesize-not-required-for-chunk-siz.patch
|
||||||
Patch081: 0083-manage-move-comment-with-function-description.patch
|
Patch082: 0083-manage-move-comment-with-function-description.patch
|
||||||
|
Patch083: 0084-Revert-mdadm-systemd-remove-KillMode-none-from-servi.patch
|
||||||
|
Patch084: 0085-Grow-fix-can-t-change-bitmap-type-from-none-to-clust.patch
|
||||||
|
Patch085: 0086-Fix-NULL-dereference-in-super_by_fd.patch
|
||||||
|
Patch086: 0087-Mdmonitor-Make-alert_info-global.patch
|
||||||
|
Patch087: 0088-Mdmonitor-Pass-events-to-alert-using-enums-instead-o.patch
|
||||||
|
Patch088: 0089-Mdmonitor-Add-helper-functions.patch
|
||||||
|
Patch089: 0090-Add-helpers-to-determine-whether-directories-or-file.patch
|
||||||
|
Patch090: 0091-Mdmonitor-Refactor-write_autorebuild_pid.patch
|
||||||
|
Patch091: 0092-Mdmonitor-Refactor-check_one_sharer-for-better-error.patch
|
||||||
|
Patch092: 0093-util.c-reorder-code-lines-in-parse_layout_faulty.patch
|
||||||
|
Patch093: 0094-util.c-fix-memleak-in-parse_layout_faulty.patch
|
||||||
|
Patch094: 0095-Detail.c-fix-memleak-in-Detail.patch
|
||||||
|
Patch095: 0096-isuper-intel.c-fix-double-free-in-load_imsm_mpb.patch
|
||||||
|
Patch096: 0097-super-intel.c-fix-memleak-in-find_disk_attached_hba.patch
|
||||||
|
Patch097: 0098-super-ddf.c-fix-memleak-in-get_vd_num_of_subarray.patch
|
||||||
|
Patch098: 0099-Create-goto-abort_locked-instead-of-return-1-in-erro.patch
|
||||||
|
Patch099: 0100-Create-remove-safe_mode_delay-local-variable.patch
|
||||||
|
Patch100: 0101-Create-Factor-out-add_disks-helpers.patch
|
||||||
|
Patch101: 0102-mdadm-Introduce-pr_info.patch
|
||||||
|
Patch102: 0103-mdadm-Add-write-zeros-option-for-Create.patch
|
||||||
|
Patch103: 0104-tests-00raid5-zero-Introduce-test-to-exercise-write-.patch
|
||||||
|
Patch104: 0105-manpage-Add-write-zeroes-option-to-manpage.patch
|
||||||
|
Patch105: 0106-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch
|
||||||
|
Patch106: 0107-Use-existence-of-etc-initrd-release-to-detect-initrd.patch
|
||||||
|
Patch107: 0108-mdmon-don-t-test-both-all-and-container_name.patch
|
||||||
|
Patch108: 0109-mdmon-change-systemd-unit-file-to-use-foreground.patch
|
||||||
|
Patch109: 0110-mdmon-Remove-need-for-KillMode-none.patch
|
||||||
|
Patch110: 0111-mdmon-Improve-switchroot-interactions.patch
|
||||||
|
Patch111: 0112-mdopen-always-try-create_named_array.patch
|
||||||
|
Patch112: 0113-Improvements-for-IMSM_NO_PLATFORM-testing.patch
|
||||||
|
Patch113: 0114-Revert-Revert-mdadm-systemd-remove-KillMode-none-fro.patch
|
||||||
|
Patch114: 0115-Create-Fix-checking-for-container-in-update_metadata.patch
|
||||||
|
Patch115: 0116-Fix-null-pointer-for-incremental-in-mdadm.patch
|
||||||
|
Patch116: 0117-super1-fix-truncation-check-for-journal-device.patch
|
||||||
|
Patch117: 0118-Fix-some-cases-eyesore-formatting.patch
|
||||||
|
Patch118: 0119-Bump-minimum-kernel-version-to-2.6.32.patch
|
||||||
|
Patch119: 0120-Remove-the-config-files-in-mdcheck_start-continue-se.patch
|
||||||
|
Patch120: 0121-mdadm-define-DEV_MD_DIR.patch
|
||||||
|
Patch121: 0122-mdadm-define-DEV_NUM_PREF.patch
|
||||||
|
Patch122: 0123-mdadm-define-is_devname_ignore.patch
|
||||||
|
Patch123: 0124-mdadm-numbered-names-verification.patch
|
||||||
|
Patch124: 0125-enable-RAID-for-SATA-under-VMD.patch
|
||||||
|
Patch125: 0126-imsm-Fix-possible-segfault-in-check_no_platform.patch
|
||||||
|
Patch126: 0127-imsm-move-sum_extents-calculations-to-merge_extents.patch
|
||||||
|
Patch127: 0128-imsm-imsm_get_free_size-refactor.patch
|
||||||
|
Patch128: 0129-imsm-introduce-round_member_size_to_mb.patch
|
||||||
|
Patch129: 0130-imsm-move-expand-verification-code-into-new-function.patch
|
||||||
|
Patch130: 0131-imsm-return-free-space-after-volume-for-expand.patch
|
||||||
|
Patch131: 0132-imsm-fix-free-space-calculations.patch
|
||||||
|
Patch132: 0133-Add-secure-gethostname-wrapper.patch
|
||||||
|
Patch133: 0134-mdadm-Stop-mdcheck_continue-timer-when-mdcheck_start.patch
|
||||||
|
Patch134: 0135-Fix-memory-leak-in-file-Assemble.patch
|
||||||
|
Patch135: 0136-Fix-memory-leak-in-file-Kill.patch
|
||||||
|
Patch136: 0137-Fix-memory-leak-in-file-Manage.patch
|
||||||
|
Patch137: 0138-Fix-memory-leak-in-file-mdadm.patch
|
||||||
|
Patch138: 0139-Fix-unsafe-string-functions.patch
|
||||||
|
Patch139: 0140-platform-intel-limit-guid-length.patch
|
||||||
|
Patch140: 0141-imsm-Add-reading-vmd-register-for-finding-imsm-capab.patch
|
||||||
|
Patch141: 0142-Add-compiler-defenses-flags.patch
|
||||||
|
Patch142: 0143-Assemble-fix-redundant-memory-free.patch
|
||||||
|
Patch143: 0144-tests-add-a-new-test-for-rdev-lifetime.patch
|
||||||
|
Patch144: 0145-tests-support-to-skip-checking-dmesg.patch
|
||||||
|
Patch145: 0146-tests-add-a-regression-test-for-raid10-deadlock.patch
|
||||||
|
Patch146: 0147-tests-add-a-regression-test-for-raid456-deadlock.patch
|
||||||
|
Patch147: 0148-tests-add-a-regression-test-that-raid456-can-t-assem.patch
|
||||||
|
Patch148: 0149-tests-add-a-regression-test-that-raid456-can-t-assem.patch
|
||||||
|
Patch149: 0150-tests-add-a-regression-test-that-reshape-can-corrupt.patch
|
||||||
|
Patch150: 0151-tests-add-a-regression-test-for-raid456-deadlock-aga.patch
|
||||||
|
Patch151: 0152-tests-create-names_template.patch
|
||||||
|
Patch152: 0153-tests-create-00confnames.patch
|
||||||
|
Patch153: 0154-mdadm-set-ident.devname-if-applicable.patch
|
||||||
|
Patch154: 0155-mdadm-refactor-ident-name-handling.patch
|
||||||
|
Patch155: 0156-mdadm-define-ident_set_devname.patch
|
||||||
|
Patch156: 0157-mdadm-Follow-POSIX-Portable-Character-Set.patch
|
||||||
|
Patch157: 0158-Incremental-remove-obsoleted-calls-to-udisks.patch
|
||||||
|
Patch158: 0159-mdadm-tests-Fix-regular-expression-failure.patch
|
||||||
|
Patch159: 0160-Fix-race-of-mdadm-add-and-mdadm-incremental.patch
|
||||||
|
Patch160: 0161-mdadm-tests-Don-t-run-mknod-before-losetup.patch
|
||||||
|
Patch161: 0162-mdadm-ddf-Abort-when-raid-disk-is-smaller-in-getinfo.patch
|
||||||
|
Patch162: 0163-mdadm-super1-Add-MD_FEATURE_RAID0_LAYOUT-if-kernel-5.patch
|
||||||
|
Patch163: 0164-mdadm-remove-container_enough-logic.patch
|
||||||
|
Patch164: 0165-Fix-assembling-RAID-volume-by-using-incremental.patch
|
||||||
|
Patch165: 0166-Revert-mdadm-remove-container_enough-logic.patch
|
||||||
|
|
||||||
# Fedora customization patches
|
# Fedora customization patches
|
||||||
|
|
||||||
Patch200: mdadm-udev.patch
|
Patch200: mdadm-udev.patch
|
||||||
Patch201: mdadm-2.5.2-static.patch
|
Patch201: mdadm-2.5.2-static.patch
|
||||||
# Build without -Werror.
|
|
||||||
Patch202: disable-Werror.patch
|
|
||||||
|
|
||||||
BuildRequires: make
|
BuildRequires: make
|
||||||
BuildRequires: systemd-rpm-macros binutils-devel gcc systemd-devel
|
BuildRequires: systemd-rpm-macros binutils-devel gcc systemd-devel
|
||||||
@ -133,6 +217,10 @@ make DESTDIR=%{buildroot} MANDIR=%{_mandir} BINDIR=%{_sbindir} SYSTEMD_DIR=%{_un
|
|||||||
install -Dp -m 755 %{SOURCE1} %{buildroot}%{_sbindir}/raid-check
|
install -Dp -m 755 %{SOURCE1} %{buildroot}%{_sbindir}/raid-check
|
||||||
install -Dp -m 644 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/raid-check
|
install -Dp -m 644 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/raid-check
|
||||||
mkdir -p -m 710 %{buildroot}/run/mdadm
|
mkdir -p -m 710 %{buildroot}/run/mdadm
|
||||||
|
mkdir -p -m 700 %{buildroot}/usr/share/mdadm
|
||||||
|
install -Dp -m 755 %{SOURCE8} %{buildroot}/usr/share/mdadm/mdcheck
|
||||||
|
install -Dp -m 644 %{SOURCE9} %{buildroot}%{_udevrulesdir}/66-md-auto-readd.rules
|
||||||
|
install -Dp -m 755 %{SOURCE10} %{buildroot}%{_sbindir}/md-auto-readd.sh
|
||||||
|
|
||||||
# systemd
|
# systemd
|
||||||
mkdir -p %{buildroot}%{_unitdir}
|
mkdir -p %{buildroot}%{_unitdir}
|
||||||
@ -172,8 +260,25 @@ install -m644 %{SOURCE5} %{buildroot}/etc/libreport/events.d
|
|||||||
%dir /run/%{name}/
|
%dir /run/%{name}/
|
||||||
%config(noreplace) %{_tmpfilesdir}/%{name}.conf
|
%config(noreplace) %{_tmpfilesdir}/%{name}.conf
|
||||||
/etc/libreport/events.d/*
|
/etc/libreport/events.d/*
|
||||||
|
/usr/share/mdadm/mdcheck
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Mar 20 2024 Xiao Ni <xni@redhat.com> 4.2-12
|
||||||
|
- To fix errata/osci problems
|
||||||
|
- Resolves RHEL-26272
|
||||||
|
|
||||||
|
* Fri Mar 15 2024 Xiao Ni <xni@redhat.com> 4.2-11
|
||||||
|
- revert "mdadm: remove container_enough logic"
|
||||||
|
- Resolves RHEL-26272
|
||||||
|
|
||||||
|
* Fri Nov 3 2023 Xiao Ni <xni@redhat.com> - 4.2-10
|
||||||
|
- Update to latest upstream
|
||||||
|
- Resolves RHEL-15386
|
||||||
|
|
||||||
|
* Tue May 16 2023 Xiao Ni <xni@redhat.com> - 4.2-9
|
||||||
|
- Update to latest upstream and fix mdcheck service bug
|
||||||
|
- Resolves rhbz#2159923, rhbz#2150865, rhbz#2124071, rhbz#2203859
|
||||||
|
|
||||||
* Fri Jan 6 2023 Xiao Ni <xni@redhat.com> - 4.2-8
|
* Fri Jan 6 2023 Xiao Ni <xni@redhat.com> - 4.2-8
|
||||||
- Update to latest upstream
|
- Update to latest upstream
|
||||||
- Resolves rhbz#2127101, rhbz#2139789, rhbz#2149292, rhbz#2151209, rhbz#2148945
|
- Resolves rhbz#2127101, rhbz#2139789, rhbz#2149292, rhbz#2151209, rhbz#2148945
|
||||||
|
Loading…
Reference in New Issue
Block a user