summaryrefslogtreecommitdiffstats
path: root/Monitor.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2023-12-10 10:50:33 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2023-12-10 10:50:33 +0000
commitb91e755b8dfd53f713b588a649dd69c2bb8c8c92 (patch)
tree9d6f22932d0da01b8a149aa642b1bfadd8998991 /Monitor.c
parentReleasing debian version 4.2+20231026-1. (diff)
downloadmdadm-b91e755b8dfd53f713b588a649dd69c2bb8c8c92.tar.xz
mdadm-b91e755b8dfd53f713b588a649dd69c2bb8c8c92.zip
Merging upstream version 4.2+20231121.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'Monitor.c')
-rw-r--r--Monitor.c137
1 files changed, 50 insertions, 87 deletions
diff --git a/Monitor.c b/Monitor.c
index e74a055..9a1f251 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -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)
{