[Prioritizer] HDS update
authorMatthias Rudolph <Matthias.Rudolph@hds.com>
Wed, 27 Jun 2007 21:35:52 +0000 (23:35 +0200)
committerChristophe Varoqui <christophe.varoqui@free.fr>
Wed, 27 Jun 2007 21:35:52 +0000 (23:35 +0200)
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 <christophe.varoqui@free.fr>
libmultipath/hwtable.c
path_priority/pp_hds_modular/pp_hds_modular.c

index c7bcf3d..356e184 100644 (file)
@@ -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
index e93ea8d..7411508 100644 (file)
@@ -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
  * 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 <matthias.rudolph@hds.com>
+ * 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.
  *
 #include <memory.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <scsi/sg.h> /* take care: fetches glibc's /usr/include/scsi/sg.h */
+#include <scsi/sg.h>
 
 #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] <device_major:device_minor>\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 <matthias.rudolph@hds.com>\n");
+       printf ("\n");
+       printf ("Usage:       pp_hds_modular [-v] <device>\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 <matthias.rudolph@hds.com>\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);
-}
-