Imported Upstream version 0.8.9
[platform/upstream/multipath-tools.git] / libmultipath / checkers.h
1 #ifndef _CHECKERS_H
2 #define _CHECKERS_H
3
4 #include <pthread.h>
5 #include "list.h"
6 #include "defaults.h"
7
8 /*
9  *
10  * Userspace (multipath/multipathd) path states
11  *
12  * PATH_WILD:
13  * - Use: Any checker
14  * - Description: Corner case where "fd < 0" for path fd (see checker_check()),
15  *   or where a checker detects an unsupported device
16  *   (e.g. wrong checker configured for a given device).
17  *
18  * PATH_UNCHECKED:
19  * - Use: Only in directio checker
20  * - Description: set when fcntl(F_GETFL) fails to return flags or O_DIRECT
21  *   not include in flags, or O_DIRECT read fails
22  * - Notes:
23  *   - multipathd: uses it to skip over paths in sync_map_state()
24  *   - multipath: used in update_paths(); if state==PATH_UNCHECKED, call
25  *     pathinfo()
26  *
27  * PATH_DOWN:
28  * - Use: All checkers (directio, emc_clariion, hp_sw, readsector0, tur)
29  * - Description: Either a) SG_IO ioctl failed, or b) check condition on some
30  *   SG_IO ioctls that succeed (tur, readsector0 checkers); path is down and
31  *   you shouldn't try to send commands to it
32  *
33  * PATH_UP:
34  * - Use: All checkers (directio, emc_clariion, hp_sw, readsector0, tur)
35  * - Description: Path is up and I/O can be sent to it
36  *
37  * PATH_SHAKY:
38  * - Use: Only emc_clariion
39  * - Description: Indicates path not available for "normal" operations
40  *
41  * PATH_GHOST:
42  * - Use: Only hp_sw and rdac
43  * - Description: Indicates a "passive/standby" path on active/passive HP
44  *   arrays.  These paths will return valid answers to certain SCSI commands
45  *   (tur, read_capacity, inquiry, start_stop), but will fail I/O commands.
46  *   The path needs an initialization command to be sent to it in order for
47  *   I/Os to succeed.
48  *
49  * PATH_PENDING:
50  * - Use: All async checkers
51  * - Description: Indicates a check IO is in flight.
52  *
53  * PATH_TIMEOUT:
54  * - Use: Only tur checker
55  * - Description: Command timed out
56  *
57  * PATH REMOVED:
58  * - Use: All checkers
59  * - Description: Device has been removed from the system
60  *
61  * PATH_DELAYED:
62  * - Use: None of the checkers (returned if the path is being delayed before
63  *   reintegration.
64  * - Description: If a path fails after being up for less than
65  *   delay_watch_checks checks, when it comes back up again, it will not
66  *   be marked as up until it has been up for delay_wait_checks checks.
67  *   During this time, it is marked as "delayed"
68  */
69 enum path_check_state {
70         PATH_WILD = 0,
71         PATH_UNCHECKED,
72         PATH_DOWN,
73         PATH_UP,
74         PATH_SHAKY,
75         PATH_GHOST,
76         PATH_PENDING,
77         PATH_TIMEOUT,
78         PATH_REMOVED,
79         PATH_DELAYED,
80         PATH_MAX_STATE
81 };
82
83 #define DIRECTIO     "directio"
84 #define TUR          "tur"
85 #define HP_SW        "hp_sw"
86 #define RDAC         "rdac"
87 #define EMC_CLARIION "emc_clariion"
88 #define READSECTOR0  "readsector0"
89 #define CCISS_TUR    "cciss_tur"
90 #define NONE         "none"
91 #define INVALID      "invalid"
92
93 #define ASYNC_TIMEOUT_SEC       30
94
95 /*
96  * strings lengths
97  */
98 #define CHECKER_NAME_LEN 16
99 #define CHECKER_MSG_LEN 256
100 #define CHECKER_DEV_LEN 256
101 #define LIB_CHECKER_NAMELEN 256
102
103 /*
104  * Generic message IDs for use in checkers.
105  */
106 enum {
107         CHECKER_MSGID_NONE = 0,
108         CHECKER_MSGID_DISABLED,
109         CHECKER_MSGID_NO_FD,
110         CHECKER_MSGID_INVALID,
111         CHECKER_MSGID_UP,
112         CHECKER_MSGID_DOWN,
113         CHECKER_MSGID_GHOST,
114         CHECKER_MSGID_UNSUPPORTED,
115         CHECKER_GENERIC_MSGTABLE_SIZE,
116         CHECKER_FIRST_MSGID = 100,      /* lowest msgid for checkers */
117         CHECKER_MSGTABLE_SIZE = 100,    /* max msg table size for checkers */
118 };
119
120 struct checker_class;
121 struct checker {
122         struct checker_class *cls;
123         int fd;
124         unsigned int timeout;
125         int disable;
126         short msgid;                         /* checker-internal extra status */
127         void * context;                      /* store for persistent data */
128         void ** mpcontext;                   /* store for persistent data shared
129                                                 multipath-wide. */
130 };
131
132 static inline int checker_selected(const struct checker *c)
133 {
134         return c != NULL && c->cls != NULL;
135 }
136
137 const char *checker_state_name(int);
138 int init_checkers(const char *);
139 void cleanup_checkers (void);
140 int checker_init (struct checker *, void **);
141 int checker_mp_init(struct checker *, void **);
142 void checker_clear (struct checker *);
143 void checker_put (struct checker *);
144 void checker_reset (struct checker *);
145 void checker_set_sync (struct checker *);
146 void checker_set_async (struct checker *);
147 void checker_set_fd (struct checker *, int);
148 void checker_enable (struct checker *);
149 void checker_disable (struct checker *);
150 /*
151  * start_checker_thread(): start async path checker thread
152  *
153  * This function provides a wrapper around pthread_create().
154  * The created thread will call the DSO's "libcheck_thread" function with the
155  * checker context as argument.
156  *
157  * Rationale:
158  * Path checkers that do I/O may hang forever. To avoid blocking, some
159  * checkers therefore use asynchronous, detached threads for checking
160  * the paths. These threads may continue hanging if multipathd is stopped.
161  * In this case, we can't unload the checker DSO at exit. In order to
162  * avoid race conditions and crashes, the entry point of the thread
163  * needs to be in libmultipath, not in the DSO itself.
164  *
165  * @param arg: pointer to struct checker_context.
166  */
167 struct checker_context {
168         struct checker_class *cls;
169 };
170 int start_checker_thread (pthread_t *thread, const pthread_attr_t *attr,
171                           struct checker_context *ctx);
172 int checker_check (struct checker *, int);
173 int checker_is_sync(const struct checker *);
174 const char *checker_name (const struct checker *);
175 void reset_checker_classes(void);
176 /*
177  * This returns a string that's best prepended with "$NAME checker",
178  * where $NAME is the return value of checker_name().
179  */
180 const char *checker_message(const struct checker *);
181 void checker_clear_message (struct checker *c);
182 void checker_get(const char *, struct checker *, const char *);
183
184 /* Prototypes for symbols exported by path checker dynamic libraries (.so) */
185 int libcheck_check(struct checker *);
186 int libcheck_init(struct checker *);
187 void libcheck_free(struct checker *);
188 void *libcheck_thread(struct checker_context *ctx);
189
190 /*
191  * msgid => message map.
192  *
193  * It only needs to be provided if the checker defines specific
194  * message IDs.
195  * Message IDs available to checkers start at CHECKER_FIRST_MSG.
196  * The msgtable array is 0-based, i.e. msgtable[0] is the message
197  * for msgid == __CHECKER_FIRST_MSG.
198  * The table ends with a NULL element.
199  */
200 extern const char *libcheck_msgtable[];
201
202 #endif /* _CHECKERS_H */