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.
static struct checker checkers[] = {
{
.fd = 0,
+ .sync = 1,
.name = DIRECTIO,
.message = "",
.context = NULL,
},
{
.fd = 0,
+ .sync = 1,
.name = TUR,
.message = "",
.context = NULL,
},
{
.fd = 0,
+ .sync = 1,
.name = HP_SW,
.message = "",
.context = NULL,
},
{
.fd = 0,
+ .sync = 1,
.name = EMC_CLARIION,
.message = "",
.context = NULL,
},
{
.fd = 0,
+ .sync = 1,
.name = RDAC,
.message = "",
.context = NULL,
},
{
.fd = 0,
+ .sync = 1,
.name = READSECTOR0,
.message = "",
.context = NULL,
.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)
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];
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;
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 */
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 *);
}
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;
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 };
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
if (!ct)
return PATH_UNCHECKED;
- ret = check_state(c->fd, ct);
+ ret = check_state(c->fd, ct, c->sync);
switch (ret)
{
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) {