From: Hannes Reinecke <hare@suse.de>
To: christophe varoqui <christophe.varoqui@free.fr>
Cc: device-mapper development <dm-devel@redhat.com>
Subject: directio path-checker for multipath-tools
Date: Thu, 11 Aug 2005 16:44:23 +0200 [thread overview]
Message-ID: <42FB6447.8000105@suse.de> (raw)
[-- Attachment #1: Type: text/plain, Size: 530 bytes --]
Hi Christophe,
I've implemented yet another path checker, based on O_DIRECT.
Rationale: On S/390 it's possible to activate multipath support for DASD
devices (called Parallel Access Volume (PAV)). As these are no SCSI
devices the readsector0 path checker wouldn't work.
And as this checker is quite generic it'll work for just about anybody.
Cheers,
Hannes
--
Dr. Hannes Reinecke hare@suse.de
SuSE Linux Products GmbH S390 & zSeries
Maxfeldstraße 5 +49 911 74053 688
90409 Nürnberg http://www.suse.de
[-- Attachment #2: multipath-tools-directio-checker.patch --]
[-- Type: text/x-patch, Size: 5648 bytes --]
diff -purN multipath-tools-0.4.4.orig/libcheckers/checkers.h multipath-tools-0.4.4/libcheckers/checkers.h
--- multipath-tools-0.4.4.orig/libcheckers/checkers.h 2005-03-29 16:21:40.000000000 +0200
+++ multipath-tools-0.4.4/libcheckers/checkers.h 2005-08-04 15:20:52.000000000 +0200
@@ -9,6 +9,7 @@ enum checkers {
CHECKER_RESERVED,
TUR,
READSECTOR0,
+ DIRECTIO,
EMC_CLARIION,
HP_SW
};
@@ -20,6 +21,7 @@ void *get_checker_addr (int);
int get_checker_name (char *, int);
int emc_clariion (int fd, char * msg, void ** ctxt);
+int directio (int fd, char * msg, void ** ctxt);
int readsector0 (int fd, char * msg, void ** ctxt);
int tur (int fd, char * msg, void ** ctxt);
diff -purN multipath-tools-0.4.4.orig/libcheckers/directio.c multipath-tools-0.4.4/libcheckers/directio.c
--- multipath-tools-0.4.4.orig/libcheckers/directio.c 1970-01-01 01:00:00.000000000 +0100
+++ multipath-tools-0.4.4/libcheckers/directio.c 2005-08-04 15:19:10.000000000 +0200
@@ -0,0 +1,165 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/fs.h>
+#include <errno.h>
+
+#include "path_state.h"
+#include "checkers.h"
+
+#define MSG_DIRECTIO_UNKNOWN "directio checker is not available"
+#define MSG_DIRECTIO_UP "directio checker reports path is up"
+#define MSG_DIRECTIO_DOWN "directio checker reports path is down"
+
+struct readsector0_checker_context {
+ void * dummy;
+};
+
+static int
+direct_read (int fd, unsigned char * buff, int size)
+{
+ long flags;
+ int reset_flags = 0;
+ int res, retval;
+
+ flags = fcntl(fd,F_GETFL);
+
+ if (flags < 0) {
+ return PATH_UNCHECKED;
+ }
+
+ if (!(flags & O_DIRECT)) {
+ flags |= O_DIRECT;
+ if (fcntl(fd,F_SETFL,flags) < 0) {
+ return PATH_UNCHECKED;
+ }
+ reset_flags = 1;
+ }
+
+ while ( (res = read(fd,buff,size)) < 0 && errno == EINTR );
+ if (res < 0) {
+ if (errno == EINVAL) {
+ /* O_DIRECT is not available */
+ retval = PATH_UNCHECKED;
+ } else if (errno == ENOMEM) {
+ retval = PATH_UP;
+ } else {
+ retval = PATH_DOWN;
+ }
+ } else {
+ retval = PATH_UP;
+ }
+
+ if (reset_flags) {
+ flags &= ~O_DIRECT;
+ /* No point in checking for errors */
+ fcntl(fd,F_SETFL,flags);
+ }
+
+ return retval;
+}
+
+extern int
+directio (int fd, char *msg, void **context)
+{
+ unsigned char *buf, *ptr;
+ struct readsector0_checker_context * ctxt = NULL;
+ unsigned long pgsize, numsect;
+ int ret, blksize;
+
+ pgsize = getpagesize();
+
+ /*
+ * caller passed in a context : use its address
+ */
+ if (context)
+ ctxt = (struct readsector0_checker_context *) (*context);
+
+ /*
+ * passed in context is uninitialized or volatile context :
+ * initialize it
+ */
+ if (!ctxt) {
+ ctxt = malloc(sizeof(struct readsector0_checker_context));
+ memset(ctxt, 0, sizeof(struct readsector0_checker_context));
+
+ if (!ctxt) {
+ MSG("cannot allocate context");
+ return -1;
+ }
+ if (context)
+ *context = ctxt;
+ }
+ if (fd <= 0) {
+ MSG("no usable fd");
+ ret = -1;
+ goto out;
+ }
+
+ if (ioctl(fd, BLKGETSIZE, &numsect) < 0) {
+ MSG("cannot get number of sectors, set default");
+ numsect = 0;
+ }
+
+ if (ioctl(fd, BLKBSZGET, &blksize) < 0) {
+ MSG("cannot get blocksize, set default");
+ blksize = 512;
+ }
+
+ if (blksize > 4096) {
+ /*
+ * Sanity check for DASD; BSZGET is broken
+ */
+ blksize = 4096;
+ }
+
+ if (!blksize) {
+ /*
+ * Blocksize is 0, assume we can't write
+ * to this device.
+ */
+ MSG(MSG_DIRECTIO_DOWN);
+ ret = PATH_DOWN;
+ goto out;
+ }
+
+ buf = (unsigned char *)malloc(blksize + pgsize);
+ if (!buf){
+ goto out;
+ }
+ ptr = (char *)(((unsigned long)buf + pgsize - 1) &
+ (~(pgsize - 1)));
+ ret = direct_read(fd, ptr, blksize);
+
+ switch (ret)
+ {
+ case PATH_UNCHECKED:
+ MSG(MSG_DIRECTIO_UNKNOWN);
+ break;
+ case PATH_DOWN:
+ MSG(MSG_DIRECTIO_DOWN);
+ break;
+ case PATH_UP:
+ MSG(MSG_DIRECTIO_UP);
+ break;
+ default:
+ break;
+ }
+ free(buf);
+
+out:
+ /*
+ * caller told us he doesn't want to keep the context :
+ * free it
+ */
+ if (!context)
+ free(ctxt);
+
+ return ret;
+}
diff -purN multipath-tools-0.4.4.orig/libcheckers/Makefile multipath-tools-0.4.4/libcheckers/Makefile
--- multipath-tools-0.4.4.orig/libcheckers/Makefile 2005-04-04 12:09:58.000000000 +0200
+++ multipath-tools-0.4.4/libcheckers/Makefile 2005-08-04 15:19:20.000000000 +0200
@@ -6,7 +6,7 @@ BUILD = glibc
include ../Makefile.inc
-OBJS = readsector0.o tur.o selector.o emc_clariion.o hp_sw.o
+OBJS = readsector0.o tur.o selector.o directio.o emc_clariion.o hp_sw.o
all: $(BUILD)
diff -purN multipath-tools-0.4.4.orig/libcheckers/selector.c multipath-tools-0.4.4/libcheckers/selector.c
--- multipath-tools-0.4.4.orig/libcheckers/selector.c 2005-03-29 16:27:46.000000000 +0200
+++ multipath-tools-0.4.4/libcheckers/selector.c 2005-08-04 15:20:27.000000000 +0200
@@ -10,6 +10,8 @@ get_checker_id (char * str)
return TUR;
if (0 == strncmp(str, "readsector0", 11))
return READSECTOR0;
+ if (0 == strncmp(str, "directio", 8))
+ return DIRECTIO;
if (0 == strncmp(str, "emc_clariion", 12))
return EMC_CLARIION;
return -1;
@@ -27,6 +29,9 @@ get_checker_addr (int id)
case READSECTOR0:
checker = &readsector0;
break;
+ case DIRECTIO:
+ checker = &directio;
+ break;
case EMC_CLARIION:
checker = &emc_clariion;
break;
@@ -49,6 +54,9 @@ get_checker_name (char * str, int id)
case READSECTOR0:
s = "readsector0";
break;
+ case DIRECTIO:
+ s = "directio";
+ break;
case EMC_CLARIION:
s = "emc_clariion";
break;
[-- Attachment #3: Type: text/plain, Size: 0 bytes --]
next reply other threads:[~2005-08-11 14:44 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-08-11 14:44 Hannes Reinecke [this message]
2005-08-23 22:40 ` directio path-checker for multipath-tools christophe varoqui
2005-08-23 22:48 ` christophe varoqui
2006-02-09 22:31 ` Christophe Varoqui
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=42FB6447.8000105@suse.de \
--to=hare@suse.de \
--cc=christophe.varoqui@free.fr \
--cc=dm-devel@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.