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