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