diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2023-12-10 10:50:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2023-12-10 10:50:28 +0000 |
commit | f0ab034d5b67bbd37fa4067c26dc7b5642b06172 (patch) | |
tree | 78092973d6591d33af1e0a0fb03c11d8458e1793 /Monitor.c | |
parent | Adding upstream version 4.2+20231026. (diff) | |
download | mdadm-f0ab034d5b67bbd37fa4067c26dc7b5642b06172.tar.xz mdadm-f0ab034d5b67bbd37fa4067c26dc7b5642b06172.zip |
Adding upstream version 4.2+20231121.upstream/4.2+20231121
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | Monitor.c | 137 |
1 files changed, 50 insertions, 87 deletions
@@ -23,18 +23,17 @@ */ #include "mdadm.h" +#include "udev.h" #include "md_p.h" #include "md_u.h" #include <sys/wait.h> #include <limits.h> #include <syslog.h> -#ifndef NO_LIBUDEV -#include <libudev.h> -#endif #define TASK_COMM_LEN 16 #define EVENT_NAME_MAX 32 #define AUTOREBUILD_PID_PATH MDMON_DIR "/autorebuild.pid" +#define FALLBACK_DELAY 5 /** * struct state - external array or container properties. @@ -126,12 +125,11 @@ 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 wait_for_events(int *delay_for_event, int c_delay); +static void wait_for_events_mdstat(int *delay_for_event, int c_delay); static int write_autorebuild_pid(void); int Monitor(struct mddev_dev *devlist, @@ -326,32 +324,12 @@ int Monitor(struct mddev_dev *devlist, if (!new_found) { if (oneshot) break; - else if (!anyredundant) { + if (!anyredundant) { pr_err("No array with redundancy detected, stopping\n"); break; } - else { -#ifndef NO_LIBUDEV - /* - * Wait for udevd to finish new devices - * processing. - */ - if (mdstat_wait(delay_for_event) && - check_udev_activity()) - pr_err("Error while waiting for UDEV to complete new devices processing\n"); -#else - int wait_result = mdstat_wait(delay_for_event); - /* - * Give chance to process new device - */ - if (wait_result != 0) { - if (c->delay > 5) - delay_for_event = 5; - } else - delay_for_event = c->delay; -#endif - mdstat_close(); - } + + wait_for_events(&delay_for_event, c->delay); } info.test = 0; @@ -374,6 +352,49 @@ int Monitor(struct mddev_dev *devlist, return 0; } +/* + * wait_for_events() - Waits for events on md devices. + * @delay_for_event: pointer to current event delay + * @c_delay: delay from config + */ +static void wait_for_events(int *delay_for_event, int c_delay) +{ +#ifndef NO_LIBUDEV + if (udev_is_available()) { + if (udev_wait_for_events(*delay_for_event) == UDEV_STATUS_ERROR) + pr_err("Error while waiting for udev events.\n"); + return; + } +#endif + wait_for_events_mdstat(delay_for_event, c_delay); +} + +/* + * wait_for_events_mdstat() - Waits for events on mdstat. + * @delay_for_event: pointer to current event delay + * @c_delay: delay from config + */ +static void wait_for_events_mdstat(int *delay_for_event, int c_delay) +{ + int wait_result = mdstat_wait(*delay_for_event); + + if (wait_result < 0) { + pr_err("Error while waiting for events on mdstat.\n"); + return; + } + + /* + * Give chance to process new device + */ + if (wait_result != 0) { + if (c_delay > FALLBACK_DELAY) + *delay_for_event = FALLBACK_DELAY; + } else { + *delay_for_event = c_delay; + } + mdstat_close(); +} + static int make_daemon(char *pidfile) { /* Return: @@ -1254,64 +1275,6 @@ static void free_statelist(struct state *statelist) } } -#ifndef NO_LIBUDEV -/* function: check_udev_activity - * Description: Function waits for udev to finish - * events processing. - * Returns: - * 1 - detected error while opening udev - * 2 - timeout - * 0 - successfull completion - */ -static int check_udev_activity(void) -{ - struct udev *udev = NULL; - struct udev_queue *udev_queue = NULL; - int timeout_cnt = 30; - int rc = 0; - - /* - * In rare cases systemd may not have udevm, - * in such cases just exit with rc 0 - */ - if (!use_udev()) - goto out; - - udev = udev_new(); - if (!udev) { - rc = 1; - goto out; - } - - udev_queue = udev_queue_new(udev); - if (!udev_queue) { - rc = 1; - goto out; - } - - if (udev_queue_get_queue_is_empty(udev_queue)) - goto out; - - while (!udev_queue_get_queue_is_empty(udev_queue)) { - sleep(1); - - if (timeout_cnt) - timeout_cnt--; - else { - rc = 2; - goto out; - } - } - -out: - if (udev_queue) - udev_queue_unref(udev_queue); - if (udev) - udev_unref(udev); - return rc; -} -#endif - /* Not really Monitor but ... */ int Wait(char *dev) { |