Merge branch 'master' of git://git.kernel.org/pub/scm/linux/storage/multipath-tools/
[multipath-tools/.git] / libmultipath / prioritizers / alua.c
1 /*
2  * (C) Copyright IBM Corp. 2004, 2005   All Rights Reserved.
3  *
4  * main.c
5  *
6  * Tool to make use of a SCSI-feature called Asymmetric Logical Unit Access.
7  * It determines the ALUA state of a device and prints a priority value to
8  * stdout.
9  *
10  * Author(s): Jan Kunigk
11  *            S. Bader <shbader@de.ibm.com>
12  * 
13  * This file is released under the GPL.
14  */
15 #include <stdio.h>
16
17 #include <debug.h>
18 #include <prio.h>
19
20 #include "alua.h"
21
22 #define ALUA_PRIO_NOT_SUPPORTED                 1
23 #define ALUA_PRIO_RTPG_FAILED                   2
24 #define ALUA_PRIO_GETAAS_FAILED                 3
25
26 int
27 get_alua_info(int fd)
28 {
29         char *  aas_string[] = {
30                 [AAS_OPTIMIZED]         = "active/optimized",
31                 [AAS_NON_OPTIMIZED]     = "active/non-optimized",
32                 [AAS_STANDBY]           = "standby",
33                 [AAS_UNAVAILABLE]       = "unavailable",
34                 [AAS_TRANSITIONING]     = "transitioning between states",
35         };
36         int     rc;
37         int     tpg;
38
39         rc = get_target_port_group_support(fd);
40         if (rc < 0)
41                 return rc;
42
43         if (rc == TPGS_NONE)
44                 return -ALUA_PRIO_NOT_SUPPORTED;
45
46         tpg = get_target_port_group(fd);
47         if (tpg < 0)
48                 return -ALUA_PRIO_RTPG_FAILED;
49
50         condlog(3, "reported target port group is %i", tpg);
51         rc = get_asymmetric_access_state(fd, tpg);
52         if (rc < 0)
53                 return -ALUA_PRIO_GETAAS_FAILED;
54
55         condlog(3, "aas = [%s]",
56                 (aas_string[rc]) ? aas_string[rc] : "invalid/reserved");
57         return rc;
58 }
59
60 int getprio (struct path * pp)
61 {
62         int rc = get_alua_info(pp->fd);
63         if (rc >= 0) {
64                 switch(rc) {
65                         case AAS_OPTIMIZED:
66                                 rc = 50;
67                                 break;
68                         case AAS_NON_OPTIMIZED:
69                                 rc = 10;
70                                 break;
71                         case AAS_STANDBY:
72                                 rc = 1;
73                                 break;
74                         default:
75                                 rc = 0;
76                 }
77         } else {
78                 switch(-rc) {
79                         case ALUA_PRIO_NOT_SUPPORTED:
80                                 condlog(0, "%s: alua not supported", pp->dev);
81                                 break;
82                         case ALUA_PRIO_RTPG_FAILED:
83                                 condlog(0, "%s: couldn't get target port group", pp->dev);
84                                 break;
85                         case ALUA_PRIO_GETAAS_FAILED:
86                                 condlog(0, "%s: couln't get asymmetric access state", pp->dev);
87                                 break;
88                 }
89         }
90         return rc;
91 }