Add two symbols that can be read from checker .so files with dlsym():
"async_context_size" for defining the size of a checker-private context,
and "async_init" for initializing this context.

Signed-off-by: Martin Wilck <[email protected]>
---
 libmultipath/async_checker.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/libmultipath/async_checker.c b/libmultipath/async_checker.c
index 06159dd..52e24f2 100644
--- a/libmultipath/async_checker.c
+++ b/libmultipath/async_checker.c
@@ -6,37 +6,64 @@
 #include <sys/stat.h>
 #include <stdlib.h>
 #include <stdbool.h>
+#include <dlfcn.h>
 #include "async_checker.h"
 #include "checkers.h"
 #include "debug.h"
 #include "runner.h"
 
 #define MAX_NR_TIMEOUTS 1
+typedef int (*async_init_func)(struct runner_data *);
 
 struct async_checker_context {
        struct checker_context chkr;
        int last_runner_state;
        unsigned int nr_timeouts;
        struct runner_context *rtx;
+       async_init_func async_init;
+       int async_context_size;
        struct runner_data rdata;
 };
 
-#define rdata_size(acc) (sizeof(acc->rdata))
+#define rdata_size(acc) (sizeof(acc->rdata) + acc->async_context_size)
 
 int async_check_init(struct checker *c)
 {
        struct async_checker_context *acc;
        struct stat sb;
+       const int *p_ctx_size;
+       int ctx_size;
+       char *errstr __attribute__((unused));
 
-       acc = calloc(1, sizeof(*acc));
+       p_ctx_size = dlsym(c->cls->handle, "async_context_size");
+       errstr = dlerror();
+       if (p_ctx_size)
+               ctx_size = *p_ctx_size;
+       else
+               ctx_size = 0;
+
+       if (ctx_size < 0 || ctx_size > CHECKER_MAX_CONTEXT_SIZE) {
+               condlog(0, "%s: invalid context size %d", __func__, ctx_size);
+               return -1;
+       }
+       condlog(3, "%s: extra context size: %d", __func__, ctx_size);
+       acc = calloc(1, sizeof(*acc) + ctx_size);
        if (!acc)
                return -1;
+
+       acc->async_context_size = ctx_size;
+       acc->async_init =
+               (int (*)(struct runner_data *))dlsym(c->cls->handle, 
"async_init");
+       errstr = dlerror();
+
        acc->rdata.state = PATH_UNCHECKED;
        acc->rdata.fd = -1;
        if (fstat(c->fd, &sb) == 0)
                acc->rdata.devt = sb.st_rdev;
        acc->chkr.cls = c->cls;
        c->context = acc;
+       if (acc->async_init)
+               return acc->async_init(&acc->rdata);
        return 0;
 }
 
-- 
2.54.0


Reply via email to