[checkers] API rewrite
[platform/upstream/multipath-tools.git] / libmultipath / structs.c
1 /*
2  * Copyright (c) 2004, 2005 Christophe Varoqui
3  * Copyright (c) 2004 Stefan Bader, IBM
4  */
5 #include <stdio.h>
6 #include <unistd.h>
7 #include <libdevmapper.h>
8
9 #include <checkers.h>
10
11 #include "memory.h"
12 #include "vector.h"
13 #include "util.h"
14 #include "structs.h"
15 #include "config.h"
16 #include "debug.h"
17 #include "structs_vec.h"
18 #include "blacklist.h"
19
20 struct path *
21 alloc_path (void)
22 {
23         struct path * pp;
24         
25         pp = (struct path *)MALLOC(sizeof(struct path));
26
27         if (pp) {
28                 pp->sg_id.host_no = -1;
29                 pp->sg_id.channel = -1;
30                 pp->sg_id.scsi_id = -1;
31                 pp->sg_id.lun = -1;
32                 pp->fd = -1;
33         }
34         return pp;
35 }
36
37 void
38 free_path (struct path * pp)
39 {
40         if (!pp)
41                 return;
42
43         if (checker_selected(&pp->checker))
44                 checker_put(&pp->checker);
45
46         if (pp->fd >= 0)
47                 close(pp->fd);
48
49         FREE(pp);
50 }
51
52 void
53 free_pathvec (vector vec, int free_paths)
54 {
55         int i;
56         struct path * pp;
57
58         if (!vec)
59                 return;
60
61         if (free_paths)
62                 vector_foreach_slot(vec, pp, i)
63                         free_path(pp);
64
65         vector_free(vec);
66 }
67
68 struct pathgroup *
69 alloc_pathgroup (void)
70 {
71         struct pathgroup * pgp;
72
73         pgp = (struct pathgroup *)MALLOC(sizeof(struct pathgroup));
74
75         if (!pgp)
76                 return NULL;
77
78         pgp->paths = vector_alloc();
79
80         if (!pgp->paths)
81                 FREE(pgp);
82
83         return pgp;
84 }
85
86 void
87 free_pathgroup (struct pathgroup * pgp, int free_paths)
88 {
89         if (!pgp)
90                 return;
91
92         free_pathvec(pgp->paths, free_paths);
93         FREE(pgp);
94 }
95
96 void
97 free_pgvec (vector pgvec, int free_paths)
98 {
99         int i;
100         struct pathgroup * pgp;
101
102         if (!pgvec)
103                 return;
104
105         vector_foreach_slot(pgvec, pgp, i)
106                 free_pathgroup(pgp, free_paths);
107
108         vector_free(pgvec);
109 }
110
111 struct multipath *
112 alloc_multipath (void)
113 {
114         struct multipath * mpp;
115
116         mpp = (struct multipath *)MALLOC(sizeof(struct multipath));
117
118         if (mpp)
119                 mpp->bestpg = 1;
120
121         return mpp;
122 }
123
124 extern void
125 free_multipath_attributes (struct multipath * mpp)
126 {
127         if (!mpp)
128                 return;
129
130         if (mpp->selector &&
131             mpp->selector != conf->selector &&
132             (!mpp->mpe || (mpp->mpe && mpp->selector != mpp->mpe->selector)) &&
133             (!mpp->hwe || (mpp->hwe && mpp->selector != mpp->hwe->selector))) {
134                 FREE(mpp->selector);
135                 mpp->selector = NULL;
136         }
137
138         if (mpp->features &&
139             mpp->features != conf->features &&
140             (!mpp->hwe || (mpp->hwe && mpp->features != mpp->hwe->features))) {
141                 FREE(mpp->features);
142                 mpp->features = NULL;
143         }
144
145         if (mpp->hwhandler &&
146             mpp->hwhandler != conf->hwhandler &&
147             (!mpp->hwe || (mpp->hwe && mpp->hwhandler != mpp->hwe->hwhandler))) {
148                 FREE(mpp->hwhandler);
149                 mpp->hwhandler = NULL;
150         }
151 }
152
153 void
154 free_multipath (struct multipath * mpp, int free_paths)
155 {
156         if (!mpp)
157                 return;
158
159         free_multipath_attributes(mpp);
160
161         if (mpp->alias &&
162             (!mpp->mpe || (mpp->mpe && mpp->alias != mpp->mpe->alias)) &&
163             (mpp->wwid && mpp->alias != mpp->wwid)) {
164                 FREE(mpp->alias);
165                 mpp->alias = NULL;
166         }
167
168         if (mpp->dmi)
169                 FREE(mpp->dmi);
170         
171 #if DAEMON
172         /*
173          * better own vecs->lock here
174          */
175         if (mpp->waiter)
176                 ((struct event_thread *)mpp->waiter)->mpp = NULL;
177 #endif
178
179         free_pathvec(mpp->paths, free_paths);
180         free_pgvec(mpp->pg, free_paths);
181         FREE(mpp);
182 }
183
184 void
185 drop_multipath (vector mpvec, char * wwid, int free_paths)
186 {
187         int i;
188         struct multipath * mpp;
189
190         if (!mpvec)
191                 return;
192
193         vector_foreach_slot (mpvec, mpp, i) {
194                 if (!strncmp(mpp->wwid, wwid, WWID_SIZE)) {
195                         free_multipath(mpp, free_paths);
196                         vector_del_slot(mpvec, i);
197                         return;
198                 }
199         }
200 }
201
202 void
203 free_multipathvec (vector mpvec, int free_paths)
204 {
205         int i;
206         struct multipath * mpp;
207
208         if (!mpvec)
209                 return;
210
211         vector_foreach_slot (mpvec, mpp, i)
212                 free_multipath(mpp, free_paths);
213
214         vector_free(mpvec);
215 }
216
217 int
218 store_path (vector pathvec, struct path * pp)
219 {
220         if (!vector_alloc_slot(pathvec))
221                 return 1;
222
223         vector_set_slot(pathvec, pp);
224
225         return 0;
226 }
227
228 int
229 store_pathgroup (vector pgvec, struct pathgroup * pgp)
230 {
231         if (!vector_alloc_slot(pgvec))
232                 return 1;
233
234         vector_set_slot(pgvec, pgp);
235
236         return 0;
237 }
238
239 struct multipath *
240 find_mp_by_minor (vector mpvec, int minor)
241 {
242         int i;
243         struct multipath * mpp;
244         
245         if (!mpvec)
246                 return NULL;
247
248         vector_foreach_slot (mpvec, mpp, i) {
249                 if (!mpp->dmi)
250                         continue;
251
252                 if (mpp->dmi->minor == minor)
253                         return mpp;
254         }
255         return NULL;
256 }
257
258 struct multipath *
259 find_mp_by_wwid (vector mpvec, char * wwid)
260 {
261         int i;
262         struct multipath * mpp;
263         
264         if (!mpvec)
265                 return NULL;
266
267         vector_foreach_slot (mpvec, mpp, i)
268                 if (!strncmp(mpp->wwid, wwid, WWID_SIZE))
269                         return mpp;
270
271         return NULL;
272 }
273
274 struct multipath *
275 find_mp_by_alias (vector mpvec, char * alias)
276 {
277         int i;
278         int len;
279         struct multipath * mpp;
280         
281         if (!mpvec)
282                 return NULL;
283
284         len = strlen(alias);
285
286         if (!len)
287                 return NULL;
288         
289         vector_foreach_slot (mpvec, mpp, i) {
290                 if (strlen(mpp->alias) == len &&
291                     !strncmp(mpp->alias, alias, len))
292                         return mpp;
293         }
294         return NULL;
295 }
296
297 struct multipath *
298 find_mp_by_str (vector mpvec, char * str)
299 {
300         int minor;
301
302         if (sscanf(str, "dm-%d", &minor) == 1)
303                 return find_mp_by_minor(mpvec, minor);
304         else
305                 return find_mp_by_alias(mpvec, str);
306 }
307
308 struct path *
309 find_path_by_dev (vector pathvec, char * dev)
310 {
311         int i;
312         struct path * pp;
313
314         if (!pathvec)
315                 return NULL;
316         
317         vector_foreach_slot (pathvec, pp, i)
318                 if (!strcmp_chomp(pp->dev, dev))
319                         return pp;
320
321         condlog(3, "%s: not found in pathvec", dev);
322         return NULL;
323 }
324
325 struct path *
326 find_path_by_devt (vector pathvec, char * dev_t)
327 {
328         int i;
329         struct path * pp;
330
331         if (!pathvec)
332                 return NULL;
333
334         vector_foreach_slot (pathvec, pp, i)
335                 if (!strcmp_chomp(pp->dev_t, dev_t))
336                         return pp;
337
338         condlog(3, "%s: not found in pathvec", dev_t);
339         return NULL;
340 }
341
342 extern int
343 pathcount (struct multipath * mpp, int state)
344 {
345         struct pathgroup *pgp;
346         struct path *pp;
347         int i, j;
348         int count = 0;
349
350         vector_foreach_slot (mpp->pg, pgp, i)
351                 vector_foreach_slot (pgp->paths, pp, j)
352                         if ((pp->state == state) || (state < 0))
353                                 count++;
354
355         return count;
356 }