If a checker shared library contains a symbol "libcheck_async_func",
use this as a callback for the async checker functions, and do not
read any other symbols from the .so file except the message table.

Checkers can provide a symbol async_context_size that will cause
the async_checker code to reserve extra space in runner_data for
the checker to use, and a symbol async_init() for initializing
this private context.

Only emc_clariion will use the latter functionality.

Signed-off-by: Martin Wilck <[email protected]>
---
 libmultipath/checkers.c           | 51 +++++++++++++++++++++----------
 libmultipath/libmultipath.version |  2 +-
 2 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c
index 3a1663f..2f20b25 100644
--- a/libmultipath/checkers.c
+++ b/libmultipath/checkers.c
@@ -101,6 +101,18 @@ void reset_checker_classes(void)
        }
 }
 
+static struct checker_class *add_async_checker_class(struct checker_class *c)
+{
+       c->init = async_check_init;
+       c->check = async_check_check;
+       c->need_wait = async_check_need_wait;
+       c->pending = async_check_pending;
+       c->free = async_check_free;
+
+       list_add(&c->node, &checkers);
+       return c;
+}
+
 static struct checker_class *add_checker_class(const char *name)
 {
        char libname[LIB_CHECKER_NAMELEN];
@@ -129,6 +141,29 @@ static struct checker_class *add_checker_class(const char 
*name)
                                errstr);
                goto out;
        }
+
+       c->msgtable_size = 0;
+       c->msgtable = dlsym(c->handle, "libcheck_msgtable");
+
+       if (c->msgtable != NULL) {
+               const char **p;
+
+               for (p = c->msgtable;
+                    *p && (p - c->msgtable) < CHECKER_MSGTABLE_SIZE; p++)
+                       /* nothing */;
+
+               c->msgtable_size = p - c->msgtable;
+       } else
+               c->msgtable_size = 0;
+       condlog(3, "checker %s: message table size = %d", c->name,
+               c->msgtable_size);
+
+       c->async_func = (int (*)(struct runner_data *))
+               dlsym(c->handle, "libcheck_async_func");
+       errstr = dlerror();
+       if (c->async_func)
+               return add_async_checker_class(c);
+
        c->check = (int (*)(struct checker *)) dlsym(c->handle, 
"libcheck_check");
        errstr = dlerror();
        if (errstr != NULL)
@@ -158,22 +193,6 @@ static struct checker_class *add_checker_class(const char 
*name)
        if (!c->free)
                goto out;
 
-       c->msgtable_size = 0;
-       c->msgtable = dlsym(c->handle, "libcheck_msgtable");
-
-       if (c->msgtable != NULL) {
-               const char **p;
-
-               for (p = c->msgtable;
-                    *p && (p - c->msgtable) < CHECKER_MSGTABLE_SIZE; p++)
-                       /* nothing */;
-
-               c->msgtable_size = p - c->msgtable;
-       } else
-               c->msgtable_size = 0;
-       condlog(3, "checker %s: message table size = %d",
-               c->name, c->msgtable_size);
-
 done:
        c->sync = 1;
        list_add(&c->node, &checkers);
diff --git a/libmultipath/libmultipath.version 
b/libmultipath/libmultipath.version
index 78fa2d4..5e8dbda 100644
--- a/libmultipath/libmultipath.version
+++ b/libmultipath/libmultipath.version
@@ -43,7 +43,7 @@ LIBMPATHCOMMON_1.0.0 {
        put_multipath_config;
 };
 
-LIBMULTIPATH_32.0.0 {
+LIBMULTIPATH_33.0.0 {
 global:
        /* symbols referenced by multipath and multipathd */
        add_foreign;
-- 
2.54.0


Reply via email to