[dm-devel] Re: patch for handling clariion I/O to
Christophe Varoqui
christophe.varoqui at free.fr
Wed Oct 4 22:09:13 UTC 2006
Le mercredi 04 octobre 2006 à 16:01 -0400, Edward Goggin a écrit :
> Christophe,
>
> This patch attempts to prevent an I/O hang which can occur with host I/O
> to an "in-active" CLARiiON snapshot LU. While the snapshot LU is
> presented to the host, inquiry, TUR, and read capacity commands succeed,
> but read and write commands are failed.
>
> The patch is not entirely CLARiiON specific since I've added a field to
> the multipath structure (failallpaths) and I've modified the interface
> of the sg_read function in libcheckers/readsector0.c. If you prefer
> that I do this with a solution which is entirely isolated to the
> CLARiiON, I can do that instead.
>
I don't see you ever reseting "allfailpaths". Isn't it a problem ?
If "failallpaths" usage is limited to "emc_clariion.c", I would rather
see it added to the "struct emc_clariion_checker_context" instead of
"struct multipath" :
- no need to include libmultipath headers in checkers
- no need to declare (and use) the "container_of" macro ;)
The sg_read() change looks opportune indeed. I'll apply it as soon as we
have the other pieces sorted out.
Thanks,
cvaroqui
> diff --git a/libcheckers/emc_clariion.c b/libcheckers/emc_clariion.c
> index a883e3d..e4004a7 100644
> --- a/libcheckers/emc_clariion.c
> +++ b/libcheckers/emc_clariion.c
> @@ -3,6 +3,7 @@
> */
> #include <stdio.h>
> #include <stdlib.h>
> +#include <stddef.h>
> #include <string.h>
> #include <sys/types.h>
> #include <sys/stat.h>
> @@ -14,6 +15,14 @@
> #include "checkers.h"
>
> #include "../libmultipath/sg_include.h"
> +#include "../libmultipath/vector.h"
> +#include "../libmultipath/structs.h"
> +
> +#define container_of(ptr, type, member) ({ \
> + const typeof( ((type *)0)->member ) *__mptr = (ptr); \
> + (type *)( (char *)__mptr - offsetof(type,member) );})
> +
> +int sg_read (int sg_fd, unsigned char * buff, unsigned char *
> senseBuff);
>
> #define INQUIRY_CMD 0x12
> #define INQUIRY_CMDLEN 6
> @@ -40,13 +49,18 @@ void emc_clariion_free (struct checker *
>
> int emc_clariion(struct checker * c)
> {
> - unsigned char sense_buffer[256] = { 0, };
> + unsigned char sense_buffer[256] = { 0, }, *sbb;
> unsigned char sb[128] = { 0, };
> unsigned char inqCmdBlk[INQUIRY_CMDLEN] = {INQUIRY_CMD, 1, 0xC0,
> 0,
> sizeof(sb), 0};
> struct sg_io_hdr io_hdr;
> struct emc_clariion_checker_context * ct =
> (struct emc_clariion_checker_context *)c->context;
> + struct path *p;
> + int ret;
> +
> + p = container_of(c, struct path, checker);
> +
>
> memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
> io_hdr.interface_id = 'S';
> @@ -110,7 +124,27 @@ int emc_clariion(struct checker * c)
> ct->wwn_set = 1;
> }
>
> -
> - MSG(c, "emc_clariion_checker: Path healthy");
> - return PATH_UP;
> + if (p->mpp && p->mpp->failallpaths) {
> + ret = PATH_DOWN;
> + MSG(c, "emc_clariion_checker: Path to inactive
> snapshot.");
> + }
> + else {
> + unsigned char buf[512];
> +
> + ret = sg_read(c->fd, &buf[0], sbb = &sense_buffer[0]);
> +
> + if (((sbb[2]&0xf) == 5) && (sbb[12] == 0x25) &&
> (sbb[13]==1)) {
> + if (p->mpp)
> + p->mpp->failallpaths = 1;
> + MSG(c, "emc_clariion_checker: Path to inactive
> snapshot.");
> + ret = PATH_DOWN;
> + }
> + else if (((sbb[2]&0xf)==2) && (sbb[12]==4) &&
> (sbb[13]==3)) {
> + MSG(c, "emc_clariion_checker: Passive path is
> healthy.");
> + ret = PATH_UP; /* not ghost */
> + }
> + else
> + MSG(c, "emc_clariion_checker: Active path is
> healthy.");
> + }
> + return ret;
> }
> diff --git a/libcheckers/readsector0.c b/libcheckers/readsector0.c
> index b0acec9..dd18528 100644
> --- a/libcheckers/readsector0.c
> +++ b/libcheckers/readsector0.c
> @@ -34,8 +34,8 @@ void readsector0_free (struct checker *
> return;
> }
>
> -static int
> -sg_read (int sg_fd, unsigned char * buff)
> +int
> +sg_read (int sg_fd, unsigned char * buff, unsigned char * senseBuff)
> {
> /* defaults */
> int blocks = 1;
> @@ -45,7 +45,6 @@ sg_read (int sg_fd, unsigned char * buff
> int * diop = NULL;
>
> unsigned char rdCmd[cdbsz];
> - unsigned char senseBuff[SENSE_BUFF_LEN];
> struct sg_io_hdr io_hdr;
> int res;
> int rd_opcode[] = {0x8, 0x28, 0xa8, 0x88};
> @@ -97,9 +96,10 @@ extern int
> readsector0 (struct checker * c)
> {
> unsigned char buf[512];
> + unsigned char sbuf[SENSE_BUFF_LEN];
> int ret;
>
> - ret = sg_read(c->fd, &buf[0]);
> + ret = sg_read(c->fd, &buf[0], &sbuf[0]);
>
> switch (ret)
> {
> diff --git a/libmultipath/structs.h b/libmultipath/structs.h
> index faa2b8f..049c82b 100644
> --- a/libmultipath/structs.h
> +++ b/libmultipath/structs.h
> @@ -127,6 +127,7 @@ struct multipath {
> int no_path_retry; /* number of retries after all paths are down
> */
> int retry_tick; /* remaining times for retries */
> int minio;
> + int failallpaths;
> unsigned long long size;
> vector paths;
> vector pg;
>
>
>
More information about the dm-devel
mailing list