From abd3c16d13ad3e7d13cb96e17d5ff903363fb253 Mon Sep 17 00:00:00 2001 From: Christophe Varoqui Date: Tue, 19 Jun 2007 00:49:36 +0200 Subject: [PATCH] [libchecker] restore synchronous checker operation to async-capable checkers 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 | 19 ++++++++++++++++++- libcheckers/checkers.h | 3 +++ libcheckers/directio.c | 11 ++++++++--- multipathd/main.c | 7 ++++++- 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/libcheckers/checkers.c b/libcheckers/checkers.c index a49ad59..d7728a5 100644 --- a/libcheckers/checkers.c +++ b/libcheckers/checkers.c @@ -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; diff --git a/libcheckers/checkers.h b/libcheckers/checkers.h index b0e2a62..482ffb8 100644 --- a/libcheckers/checkers.h +++ b/libcheckers/checkers.h @@ -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 *); diff --git a/libcheckers/directio.c b/libcheckers/directio.c index db19881..ee09af7 100644 --- a/libcheckers/directio.c +++ b/libcheckers/directio.c @@ -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) { diff --git a/multipathd/main.c b/multipathd/main.c index a574bee..5f98c33 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -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) { -- 2.7.4