[libchecker] restore synchronous checker operation to async-capable checkers
authorChristophe Varoqui <christophe.varoqui@free.fr>
Mon, 18 Jun 2007 22:49:36 +0000 (00:49 +0200)
committerChristophe Varoqui <christophe.varoqui@free.fr>
Mon, 18 Jun 2007 22:49:36 +0000 (00:49 +0200)
Add a "sync" flag the struct checker to inform the checker the caller wants a synchronous or asynchronous answer to path status request.

Default value is "synchronous" to kept legacy code unchanged.

Set async mode in the daemon checker loop.

libcheckers/checkers.c
libcheckers/checkers.h
libcheckers/directio.c
multipathd/main.c

index a49ad59..d7728a5 100644 (file)
@@ -13,6 +13,7 @@
 static struct checker checkers[] = {
        {
                .fd         = 0,
+               .sync       = 1,
                .name       = DIRECTIO,
                .message    = "",
                .context    = NULL,
@@ -22,6 +23,7 @@ static struct checker checkers[] = {
        },
        {
                .fd         = 0,
+               .sync       = 1,
                .name       = TUR,
                .message    = "",
                .context    = NULL,
@@ -31,6 +33,7 @@ static struct checker checkers[] = {
        },
        {
                .fd         = 0,
+               .sync       = 1,
                .name       = HP_SW,
                .message    = "",
                .context    = NULL,
@@ -40,6 +43,7 @@ static struct checker checkers[] = {
        },
        {
                .fd         = 0,
+               .sync       = 1,
                .name       = EMC_CLARIION,
                .message    = "",
                .context    = NULL,
@@ -49,6 +53,7 @@ static struct checker checkers[] = {
        },
        {
                .fd         = 0,
+               .sync       = 1,
                .name       = RDAC,
                .message    = "",
                .context    = NULL,
@@ -58,6 +63,7 @@ static struct checker checkers[] = {
        },
        {
                .fd         = 0,
+               .sync       = 1,
                .name       = READSECTOR0,
                .message    = "",
                .context    = NULL,
@@ -65,7 +71,7 @@ static struct checker checkers[] = {
                .init       = readsector0_init,
                .free       = readsector0_free
        },
-       {0, "", "", NULL, NULL, NULL, NULL},
+       {0, 1, "", "", NULL, NULL, NULL, NULL},
 };
 
 void checker_set_fd (struct checker * c, int fd)
@@ -73,6 +79,16 @@ void checker_set_fd (struct checker * c, int fd)
        c->fd = fd;
 }
 
+void checker_set_sync (struct checker * c)
+{
+       c->sync = 1;
+}
+
+void checker_set_async (struct checker * c)
+{
+       c->sync = 0;
+}
+
 struct checker * checker_lookup (char * name)
 {
        struct checker * c = &checkers[0];
@@ -134,6 +150,7 @@ struct checker * checker_default (void)
 void checker_get (struct checker * dst, struct checker * src)
 {
        dst->fd = src->fd;
+       dst->sync = src->sync;
        strncpy(dst->name, src->name, CHECKER_NAME_LEN);
        strncpy(dst->message, src->message, CHECKER_MSG_LEN);
        dst->check = src->check;
index b0e2a62..482ffb8 100644 (file)
@@ -86,6 +86,7 @@
 
 struct checker {
        int fd;
+       int sync;
        char name[CHECKER_NAME_LEN];
        char message[CHECKER_MSG_LEN];       /* comm with callers */
        void * context;                      /* store for persistent data */
@@ -101,6 +102,8 @@ struct checker {
 int checker_init (struct checker *, void **);
 void checker_put (struct checker *);
 void checker_reset (struct checker * c);
+void checker_set_sync (struct checker * c);
+void checker_set_async (struct checker * c);
 void checker_set_fd (struct checker *, int);
 struct checker * checker_lookup (char *);
 int checker_check (struct checker *);
index db19881..ee09af7 100644 (file)
@@ -118,7 +118,7 @@ void directio_free (struct checker * c)
 }
 
 static int
-check_state(int fd, struct directio_context *ct)
+check_state(int fd, struct directio_context *ct, int sync)
 {
        struct timespec timeout = { .tv_nsec = 5 };
        struct io_event event;
@@ -129,6 +129,11 @@ check_state(int fd, struct directio_context *ct)
        if (fstat(fd, &sb) == 0) {
                LOG(4, "called for %x", (unsigned) sb.st_rdev);
        }
+       if (sync) {
+               LOG(4, "called in synchronous mode");
+               timeout.tv_sec  = ASYNC_TIMEOUT_SEC;
+               timeout.tv_nsec = 0;
+       }
 
        if (!ct->running) {
                struct iocb *ios[1] = { &ct->io };
@@ -147,7 +152,7 @@ check_state(int fd, struct directio_context *ct)
        LOG(3, "async io getevents returns %li (errno=%s)", r, strerror(errno));
 
        if (r < 1L) {
-               if (ct->running > ASYNC_TIMEOUT_SEC) {
+               if (ct->running > ASYNC_TIMEOUT_SEC || sync) {
                        LOG(3, "abort check on timeout");
                        rc = PATH_DOWN;
                } else
@@ -169,7 +174,7 @@ int directio (struct checker * c)
        if (!ct)
                return PATH_UNCHECKED;
 
-       ret = check_state(c->fd, ct);
+       ret = check_state(c->fd, ct, c->sync);
 
        switch (ret)
        {
index a574bee..5f98c33 100644 (file)
@@ -888,11 +888,16 @@ checkerloop (void *ap)
                                pathinfo(pp, conf->hwtable, DI_SYSFS);
                                select_checker(pp);
                        }
-
                        if (!checker_selected(&pp->checker)) {
                                condlog(0, "%s: checker is not set", pp->dev);
                                continue;
                        }
+                       /*
+                        * Set checker in async mode.
+                        * Honored only by checker implementing the said mode.
+                        */
+                       checker_set_async(&pp->checker);
+
                        newstate = checker_check(&pp->checker);
                        
                        if (newstate < 0) {