diff mbox series

[v2,19/22] libmultipath: add libcheck_need_wait checker function

Message ID 20240912214947.783819-20-bmarzins@redhat.com (mailing list archive)
State Not Applicable, archived
Delegated to: Benjamin Marzinski
Headers show
Series Yet Another path checker refactor | expand

Commit Message

Benjamin Marzinski Sept. 12, 2024, 9:49 p.m. UTC
Add a new optional checker class function, libcheck_need_wait() and a
new function to call it, checker_need_wait(). This can be used to see if
a path_checker is currently running. This will be used to determine if
there are pending checkers that need to be waited for.

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
 libmultipath/checkers.c          | 12 +++++++++++-
 libmultipath/checkers.h          |  4 +++-
 libmultipath/checkers/directio.c | 10 ++++++++++
 libmultipath/checkers/tur.c      | 10 ++++++++++
 4 files changed, 34 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c
index f3e98352..e2eda58d 100644
--- a/libmultipath/checkers.c
+++ b/libmultipath/checkers.c
@@ -27,6 +27,7 @@  struct checker_class {
 	void (*reset)(void);		     /* to reset the global variables */
 	void *(*thread)(void *);	     /* async thread entry point */
 	int (*pending)(struct checker *);    /* to recheck pending paths */
+	bool (*need_wait)(struct checker *); /* checker needs waiting for */
 	const char **msgtable;
 	short msgtable_size;
 };
@@ -182,7 +183,8 @@  static struct checker_class *add_checker_class(const char *name)
 	c->reset = (void (*)(void)) dlsym(c->handle, "libcheck_reset");
 	c->thread = (void *(*)(void*)) dlsym(c->handle, "libcheck_thread");
 	c->pending = (int (*)(struct checker *)) dlsym(c->handle, "libcheck_pending");
-	/* These 4 functions can be NULL. call dlerror() to clear out any
+	c->need_wait = (bool (*)(struct checker *)) dlsym(c->handle, "libcheck_need_wait");
+	/* These 5 functions can be NULL. call dlerror() to clear out any
 	 * error string */
 	dlerror();
 
@@ -313,6 +315,14 @@  int checker_get_state(struct checker *c)
 	return c->path_state;
 }
 
+bool checker_need_wait(struct checker *c)
+{
+	if (!c || !c->cls || c->path_state != PATH_PENDING ||
+	    !c->cls->need_wait)
+		return false;
+	return c->cls->need_wait(c);
+}
+
 void checker_check (struct checker * c, int path_state)
 {
 	if (!c)
diff --git a/libmultipath/checkers.h b/libmultipath/checkers.h
index b2342a1b..da91f499 100644
--- a/libmultipath/checkers.h
+++ b/libmultipath/checkers.h
@@ -2,6 +2,7 @@ 
 #define CHECKERS_H_INCLUDED
 
 #include <pthread.h>
+#include <stdbool.h>
 #include "list.h"
 #include "defaults.h"
 
@@ -171,6 +172,7 @@  struct checker_context {
 int start_checker_thread (pthread_t *thread, const pthread_attr_t *attr,
 			  struct checker_context *ctx);
 int checker_get_state(struct checker *c);
+bool checker_need_wait(struct checker *c);
 void checker_check (struct checker *, int);
 int checker_is_sync(const struct checker *);
 const char *checker_name (const struct checker *);
@@ -191,7 +193,7 @@  void *libcheck_thread(struct checker_context *ctx);
 void libcheck_reset(void);
 int libcheck_mp_init(struct checker *);
 int libcheck_pending(struct checker *c);
-
+bool libcheck_need_wait(struct checker *c);
 
 /*
  * msgid => message map.
diff --git a/libmultipath/checkers/directio.c b/libmultipath/checkers/directio.c
index 904e3071..4beed02e 100644
--- a/libmultipath/checkers/directio.c
+++ b/libmultipath/checkers/directio.c
@@ -65,6 +65,7 @@  struct directio_context {
 	struct aio_group *aio_grp;
 	struct async_req *req;
 	struct timespec endtime;
+	bool waited_for;
 };
 
 static struct aio_group *
@@ -295,6 +296,7 @@  check_pending(struct directio_context *ct, struct timespec endtime)
 	int r;
 	struct timespec currtime, timeout;
 
+	ct->waited_for = true;
 	while(1) {
 		get_monotonic_time(&currtime);
 		timespecsub(&endtime, &currtime, &timeout);
@@ -346,6 +348,7 @@  check_state(int fd, struct directio_context *ct, int sync, int timeout_secs)
 		get_monotonic_time(&ct->endtime);
 		ct->endtime.tv_nsec += 1000 * 1000;
 		normalize_timespec(&ct->endtime);
+		ct->waited_for = false;
 	}
 	ct->running++;
 	if (!sync)
@@ -386,6 +389,13 @@  static void set_msgid(struct checker *c, int state)
 	}
 }
 
+bool libcheck_need_wait(struct checker *c)
+{
+	struct directio_context *ct = (struct directio_context *)c->context;
+	return (ct && ct->running && ct->req->state == PATH_PENDING &&
+		!ct->waited_for);
+}
+
 int libcheck_pending(struct checker *c)
 {
 	int rc;
diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c
index 81db565b..41d6b9c3 100644
--- a/libmultipath/checkers/tur.c
+++ b/libmultipath/checkers/tur.c
@@ -59,6 +59,7 @@  struct tur_checker_context {
 	struct checker_context ctx;
 	unsigned int nr_timeouts;
 	struct timespec endtime;
+	bool waited_for;
 };
 
 int libcheck_init (struct checker * c)
@@ -351,9 +352,17 @@  int check_pending(struct checker *c)
 		ct->thread = 0;
 	}
 
+	ct->waited_for = true;
 	return tur_status;
 }
 
+bool libcheck_need_wait(struct checker *c)
+{
+	struct tur_checker_context *ct = c->context;
+	return (ct && ct->thread && uatomic_read(&ct->running) != 0 &&
+		!ct->waited_for);
+}
+
 int libcheck_pending(struct checker *c)
 {
 	struct tur_checker_context *ct = c->context;
@@ -463,6 +472,7 @@  int libcheck_check(struct checker * c)
 		pthread_mutex_unlock(&ct->lock);
 		ct->fd = c->fd;
 		ct->timeout = c->timeout;
+		ct->waited_for = false;
 		uatomic_add(&ct->holders, 1);
 		uatomic_set(&ct->running, 1);
 		tur_set_async_timeout(c);