Honour ALUA preference indicator
authorColin Watson <cjwatson@canonical.com>
Fri, 12 Feb 2010 12:18:59 +0000 (12:18 +0000)
committerChristophe Varoqui <christophe.varoqui@free.fr>
Sat, 13 Feb 2010 14:32:02 +0000 (15:32 +0100)
SPC defines the preference indicator (bit 7 of the first byte returned
by REPORT TARGET PORT GROUPS) as indicating a preferred primary target
port group, and says that applications may use it to influence path
selection.  Choose TPGs with this bit set over TPGs with it unset.

This fixes failback handling with the Intel Modular Server.

Signed-off-by: Yingying Zhao <yingying.zhao@intel.com>
Signed-off-by: Colin Watson <cjwatson@canonical.com>
libmultipath/prioritizers/alua.c
libmultipath/prioritizers/alua_spc3.h

index 0048a4408161a7a87e7a675a3e7010b3b7e4d2be..abf623258fd75d43444943cf5591ed2c109cebfc 100644 (file)
@@ -37,6 +37,7 @@ get_alua_info(int fd)
        };
        int     rc;
        int     tpg;
+       int     aas;
 
        rc = get_target_port_group_support(fd);
        if (rc < 0)
@@ -53,22 +54,27 @@ get_alua_info(int fd)
        rc = get_asymmetric_access_state(fd, tpg);
        if (rc < 0)
                return -ALUA_PRIO_GETAAS_FAILED;
+       aas = (rc & 0x0f);
 
        condlog(3, "aas = [%s]",
-               (rc < 4) ? aas_string[rc] : "invalid/reserved");
+               (aas < 4) ? aas_string[aas] : "invalid/reserved");
        return rc;
 }
 
 int getprio (struct path * pp)
 {
        int rc;
+       int aas;
+       int priopath;
 
        if (pp->fd < 0)
                return -ALUA_PRIO_NO_INFORMATION;
 
        rc = get_alua_info(pp->fd);
        if (rc >= 0) {
-               switch(rc) {
+               aas = (rc & 0x0f);
+               priopath = (rc & 0x80);
+               switch(aas) {
                        case AAS_OPTIMIZED:
                                rc = 50;
                                break;
@@ -81,6 +87,8 @@ int getprio (struct path * pp)
                        default:
                                rc = 0;
                }
+               if (priopath)
+                       rc += 80;
        } else {
                switch(-rc) {
                        case ALUA_PRIO_NOT_SUPPORTED:
index bddbbdd582d79616149c6682e9eba3df5327b8db..4bbdded1ff1f9cd82c6e5d5286b5aff44cec416a 100644 (file)
@@ -299,7 +299,7 @@ struct rtpg_tpg_dscr {
 static inline int
 rtpg_tpg_dscr_get_aas(struct rtpg_tpg_dscr *d)
 {
-       return (d->b0 & 0x0f);
+       return (d->b0 & 0x8f);
 }
 
 struct rtpg_data {