From 3f9ee896b5b0ec12aa6ec1d661b98c27aaabfb05 Mon Sep 17 00:00:00 2001 From: Matthias Rudolph Date: Wed, 27 Jun 2007 23:35:52 +0200 Subject: [PATCH] [Prioritizer] HDS update o queue_if_no_path in hwtable.c o tur instead of readsector0 in hwtable.c o get prio with device name instead of major:minor in hwtable.c and pp_hds_modular.c Signed-off-by: Christophe Varoqui --- libmultipath/hwtable.c | 10 +- path_priority/pp_hds_modular/pp_hds_modular.c | 305 +++++++++++--------------- 2 files changed, 137 insertions(+), 178 deletions(-) diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c index c7bcf3d..356e184 100644 --- a/libmultipath/hwtable.c +++ b/libmultipath/hwtable.c @@ -243,7 +243,7 @@ static struct hwentry default_hw[] = { .product = "OPEN-.*", .getuid = DEFAULT_GETUID, .getprio = NULL, - .features = DEFAULT_FEATURES, + .features = "1 queue_if_no_path", .hwhandler = DEFAULT_HWHANDLER, .selector = DEFAULT_SELECTOR, .pgpolicy = MULTIBUS, @@ -251,14 +251,14 @@ static struct hwentry default_hw[] = { .rr_weight = RR_WEIGHT_NONE, .no_path_retry = NO_PATH_RETRY_UNDEF, .minio = DEFAULT_MINIO, - .checker_name = READSECTOR0, + .checker_name = TUR, }, { .vendor = "HITACHI", .product = "DF.*", .getuid = DEFAULT_GETUID, - .getprio = "/sbin/mpath_prio_hds_modular %d", - .features = DEFAULT_FEATURES, + .getprio = "/sbin/mpath_prio_hds_modular /dev/%n", + .features = "1 queue_if_no_path", .hwhandler = DEFAULT_HWHANDLER, .selector = DEFAULT_SELECTOR, .pgpolicy = GROUP_BY_PRIO, @@ -266,7 +266,7 @@ static struct hwentry default_hw[] = { .rr_weight = RR_WEIGHT_NONE, .no_path_retry = NO_PATH_RETRY_UNDEF, .minio = DEFAULT_MINIO, - .checker_name = READSECTOR0, + .checker_name = TUR, }, /* * IBM controller family diff --git a/path_priority/pp_hds_modular/pp_hds_modular.c b/path_priority/pp_hds_modular/pp_hds_modular.c index e93ea8d..7411508 100644 --- a/path_priority/pp_hds_modular/pp_hds_modular.c +++ b/path_priority/pp_hds_modular/pp_hds_modular.c @@ -2,40 +2,40 @@ * (C) Copyright HDS GmbH 2006. All Rights Reserved. * * pp_hds_modular.c - * Version 1.12 + * Version 2.00 * - * Prioritizer for multipath tools device mapper and HDS Storage + * Prioritizer for Device Mapper Multipath and HDS Storage * - * Hitachis Modular Storage contains two controllers for redundancy. The - * Storage internal LUN (LDEV) will normally allocated via two pathes to the - * server (one path per controller). For performance reasons should the server + * Hitachis Modular Storage contains two controllers for redundancy. The + * Storage internal LUN (LDEV) will normally allocated via two pathes to the + * server (one path per controller). For performance reasons should the server * access to a LDEV only via one controller. The other path to the other - * controller is stand-by. It is also possible to allocate more as one path - * for a LDEV per controller. Here is active/active access allowed. The other + * controller is stand-by. It is also possible to allocate more as one path + * for a LDEV per controller. Here is active/active access allowed. The other * pathes via the other controller are stand-by. - * - * This prioritizer checks with inquiry commands the represented LDEV and - * Controller number and gives back a priority followed by this scheme : + * + * This prioritizer checks with inquiry command the represented LDEV and + * Controller number and gives back a priority followed by this scheme: * * CONTROLLER ODD and LDEV ODD: PRIORITY 1 * CONTROLLER ODD and LDEV EVEN: PRIORITY 0 * CONTROLLER EVEN and LDEV ODD: PRIORITY 0 * CONTROLLER EVEN and LDEV EVEN: PRIORITY 1 * - * In the storage you can define for each LDEV a owner controller. If the - * server makes IOs via the other controller the storage will switch the - * ownership automatically. In this case you can see in the storage that the + * In the storage you can define for each LDEV a owner controller. If the + * server makes IOs via the other controller the storage will switch the + * ownership automatically. In this case you can see in the storage that the * current controller is different from the default controller, but this is * absolutely no problem. * - * With this prioritizer it is possible to establish a static load balancing. - * Half of the LUNs are accessed via one HBA/storage controller and the other + * With this prioritizer it is possible to establish a static load balancing. + * Half of the LUNs are accessed via one HBA/storage controller and the other * half via the other HBA/storage controller. * - * In cluster environmemnts (RAC) it also guarantees that all cluster nodes - * have access to the LDEVs via the same controller. + * In cluster environmemnts (RAC) it also guarantees that all cluster nodes have + * access to the LDEVs via the same controller. * - * You can run the prioritizer manually in verbose mode : + * You can run the prioritizer manually in verbose mode: * # pp_hds_modular -v 8:224 * VENDOR: HITACHI * PRODUCT: DF600F-CM @@ -45,31 +45,21 @@ * PORT: B * CTRL ODD, LDEV EVEN, PRIO 0 * - * The items VENDOR and PRODUCT helps you to make the correct entries in file - * /etc/multipath.conf : - * # cat /etc/multipath.conf - * ... - * devices { - * device { - * vendor "HITACHI" - * product "DF600F" - * path_grouping_policy group_by_prio - * prio_callout "/sbin/pp_hds_modular %d" - * path_checker readsector0 - * getuid_callout "/lib/udev/scsi_id -g -u -s /block/%n" - * failback immediate - * } - * device { - * vendor "HITACHI" - * product "DF600F-CM" - * path_grouping_policy group_by_prio - * prio_callout "/sbin/pp_hds_modular %d" - * path_checker readsector0 - * getuid_callout "/sbin/scsi_id -g -u -s /block/%n" - * failback immediate - * + * To compile this source please execute # cc pp_hds_modular.c -o /sbin/mpath_prio_hds_modular * - * Author: Matthias Rudolph + * Changes 2006-07-16: + * - Changed to forward declaration of functions + * - The switch-statement was changed to a logical expression + * - unlinking of the devpath now also occurs at the end of + * hds_modular_prio to avoid old /tmp/.pp_balance.%u.%u.devnode + * entries in /tmp-Directory + * - The for-statements for passing variables where changed to + * snprintf-commands in verbose mode + * Changes 2006-08-10: + * - Back to the old switch statements because the regular expression does + * not work under RHEL4 U3 i386 + * Changes 2007-06-27: + * - switched from major:minor argument to device node argument * * This file is released under the GPL. * @@ -86,167 +76,136 @@ #include #include #include -#include /* take care: fetches glibc's /usr/include/scsi/sg.h */ +#include #define INQ_REPLY_LEN 255 #define INQ_CMD_CODE 0x12 #define INQ_CMD_LEN 6 #define FILE_NAME_SIZE 255 -#define safe_sprintf(var, format, args...) \ - snprintf(var, sizeof(var), format, ##args) >= sizeof(var) -#define safe_snprintf(var, size, format, args...) \ - snprintf(var, size, format, ##args) >= size -int verbose; +int verbose=0; + +void print_help (void); +int hds_modular_prio (const char *); + +int main (int argc, char **argv) +{ + int prio; + if (argc == 2) + { + if (strcmp (argv[1], "-h") == 0) + { + print_help (); + exit (0); + } + else + { + verbose = 0; + prio = hds_modular_prio (argv[1]); + printf ("%d\n", prio); + exit (0); + } + } + if ((argc == 3) && (strcmp (argv[1], "-v")) == 0) + { + verbose = 1; + prio = hds_modular_prio (argv[2]); + printf ("%d\n", prio); + exit (0); + } + print_help (); + exit (1); +} -int hds_modular_prio(char * major_minor) +int hds_modular_prio (const char *dev) { - int sg_fd, k, i; - char vendor[32]; + int sg_fd, k; + char vendor[8]; char product[32]; char serial[32]; char ldev[32]; char ctrl[32]; char port[32]; - char devpath[FILE_NAME_SIZE]; - unsigned int major; - unsigned int minor; - unsigned char inqCmdBlk[INQ_CMD_LEN] = - {INQ_CMD_CODE, 0, 0, 0, INQ_REPLY_LEN, 0}; + unsigned char inqCmdBlk[INQ_CMD_LEN] = { INQ_CMD_CODE, 0, 0, 0, INQ_REPLY_LEN, 0 }; unsigned char inqBuff[INQ_REPLY_LEN]; + unsigned char *inqBuffp = inqBuff; unsigned char sense_buffer[32]; sg_io_hdr_t io_hdr; - sscanf(major_minor, "%u:%u", &major, &minor); - memset(devpath, 0, FILE_NAME_SIZE); + if ((sg_fd = open (dev, O_RDONLY)) < 0) exit (1); + if ((ioctl (sg_fd, SG_GET_VERSION_NUM, &k) < 0) || (k < 30000)) exit (1); - if (safe_sprintf(devpath, "/tmp/.pp_balance.%u.%u.devnode", - major, minor)) - exit(1); - - unlink (devpath); - mknod(devpath, S_IFBLK|S_IRUSR|S_IWUSR, makedev(major, minor)); - - if ((sg_fd = open(devpath, O_RDONLY)) < 0) exit(1); - if ((ioctl(sg_fd, SG_GET_VERSION_NUM, &k) < 0) || (k < 30000)) - exit(1); - - memset(&io_hdr, 0, sizeof(sg_io_hdr_t)); + memset (&io_hdr, 0, sizeof (sg_io_hdr_t)); io_hdr.interface_id = 'S'; - io_hdr.cmd_len = sizeof(inqCmdBlk); - io_hdr.mx_sb_len = sizeof(sense_buffer); + io_hdr.cmd_len = sizeof (inqCmdBlk); + io_hdr.mx_sb_len = sizeof (sense_buffer); io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; io_hdr.dxfer_len = INQ_REPLY_LEN; io_hdr.dxferp = inqBuff; io_hdr.cmdp = inqCmdBlk; io_hdr.sbp = sense_buffer; - io_hdr.timeout = 2000; /* TimeOut = 2 seconds */ - - if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) exit(1); - if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) exit(1); - - for (i = 0; i < 8 ; i++) vendor[i] = inqBuff[i+8]; - vendor[8] = 0; - for (i = 0; i < 16 ; i++) product[i] = inqBuff[i+16]; - product[16] = 0; - for (i = 0; i < 4 ; i++) serial[i] = inqBuff[i+40]; - serial[4] = 0; - for (i = 0; i < 4 ; i++) ldev[i] = inqBuff[i+44]; - ldev[4] = 0; - ctrl[0] = inqBuff[49]; - ctrl[1] = 0; - port[0] = inqBuff[50]; - port[1] = 0; - - close(sg_fd); - - if (1 == verbose) { - printf("VENDOR: %s\n", vendor); - printf("PRODUCT: %s\n", product); - printf("SERIAL: 0x%s\n", serial); - printf("LDEV: 0x%s\n", ldev); - printf("CTRL: %s\n", ctrl); - printf("PORT: %s\n", port); + io_hdr.timeout = 2000; /* TimeOut = 2 seconds */ + + if (ioctl (sg_fd, SG_IO, &io_hdr) < 0) exit (1); + if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) exit (1); + + snprintf (vendor, 9, "%.8s\n", inqBuffp + 8); + snprintf (product, 17, "%.16s", inqBuffp + 16); + snprintf (serial, 5, "%.4s", inqBuffp + 40); + snprintf (ldev, 5, "%.4s", inqBuffp + 44); + snprintf (ctrl, 2, "%.1s", inqBuffp + 49); + snprintf (port, 2, "%.1s", inqBuffp + 50); + + close (sg_fd); + + if (verbose) + { + printf ("VENDOR: %s\n", vendor); + printf ("PRODUCT: %s\n", product); + printf ("SERIAL: 0x%s\n", serial); + printf ("LDEV: 0x%s\n", ldev); + printf ("CTRL: %s\n", ctrl); + printf ("PORT: %s\n", port); } - switch( ctrl[0] ) { - case '0': case '2': case '4': case '6': case '8': - switch( ldev[3] ) { - case '0': case '2': case '4': case '6': - case '8': case 'A': case 'C': case 'E': - if (1 == verbose) - printf("CTRL EVEN, LDEV EVEN, " - "PRIO 1\n"); - return 1; - break; - case '1': case '3': case '5': case '7': - case '9': case 'B': case 'D': case 'F': - if (1 == verbose) - printf("CTRL EVEN, LDEV ODD, " - "PRIO 0\n"); - return 0; - break; - } - case '1': case '3': case '5': case '7': case '9': - switch( ldev[3] ) { - case '0': case '2': case '4': case '6': - case '8': case 'A': case 'C': case 'E': - if (1 == verbose) - printf("CTRL ODD, LDEV EVEN, " - "PRIO 0\n"); - return 0; - break; - case '1': case '3': case '5': case '7': - case '9': case 'B': case 'D': case 'F': - if (1 == verbose) - printf("CTRL ODD, LDEV ODD, " - "PRIO 1\n"); - return 1; - break; - } + switch (ctrl[0]) { + case '0': case '2': case '4': case '6': case '8': + switch (ldev[3]) { + case '0': case '2': case '4': case '6': case '8': case 'A': case 'C': case 'E': + if (1 == verbose) printf("CTRL EVEN, LDEV EVEN, PRIO 1\n"); + return 1; + break; + case '1': case '3': case '5': case '7': case '9': case 'B': case 'D': case 'F': + if (1 == verbose) printf("CTRL EVEN, LDEV ODD, PRIO 0\n"); + return 0; + break; + } + case '1': case '3': case '5': case '7': case '9': + switch (ldev[3]) { + case '0': case '2': case '4': case '6': case '8': case 'A': case 'C': case 'E': + if (1 == verbose) printf("CTRL ODD, LDEV EVEN, PRIO 0\n"); + return 0; + break; + case '1': case '3': case '5': case '7': case '9': case 'B': case 'D': case 'F': + if (1 == verbose) printf("CTRL ODD, LDEV ODD, PRIO 1\n"); + return 1; + break; + } } - exit(1); + return 0; } -void print_help(void) +void print_help (void) { - printf("Usage: " - "pp_hds_modular [-v] \n"); - printf("Option: " - "-v verbose mode\n"); - printf("Description: " - "Prioritizer for Multipath Tools and HDS Storage\n"); - printf("Version: " - "1.12\n"); - printf("Author: " - "Matthias Rudolph \n"); + printf ("\n"); + printf ("Usage: pp_hds_modular [-v] \n"); + printf ("Option: -v verbose mode\n"); + printf ("Description: Prioritizer for Device Mapper Multipath and HDS Storage\n"); + printf ("Version: 2.00\n"); + printf ("Author: Matthias Rudolph \n"); + printf ("Remarks: Prioritizer CTRL#1 corresponds to hardware CTRL#0\n"); + printf (" Prioritizer CTRL#2 corresponds to hardware CTRL#1\n"); + printf ("\n"); return; } -int main(int argc, char * argv[]) -{ - int prio; - - if (2 == argc) { - if (0 == strcmp(argv[1], "-h")) { - print_help(); - exit(0); - } - else { - verbose = 0; - prio = hds_modular_prio(argv[1]); - printf("%d\n", prio); - exit(0); - } - } - - if ((3 == argc) && (0 == strcmp(argv[1], "-v"))) { - verbose = 1; - prio = hds_modular_prio(argv[2]); - printf("%d\n", prio); - exit(0); - } - print_help(); - exit(1); -} - -- 2.7.4