import CS mdadm-4.2-14.el8
This commit is contained in:
parent
5ec1ce78ee
commit
b8124cfbb2
@ -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;
|