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