[multipath] option to use priorities as weights in the round-robin scheduler
[multipath-tools/.git] / libmultipath / structs.c
1 #include <stdio.h>
2 #include <unistd.h>
3
4 #include "memory.h"
5 #include "vector.h"
6 #include "util.h"
7 #include "structs.h"
8 #include "config.h"
9 #include "debug.h"
10
11 struct path *
12 alloc_path (void)
13 {
14         struct path * pp;
15         
16         pp = (struct path *)MALLOC(sizeof(struct path));
17
18         if (pp) {
19                 pp->sg_id.host_no = -1;
20                 pp->sg_id.channel = -1;
21                 pp->sg_id.scsi_id = -1;
22                 pp->sg_id.lun = -1;
23         }
24         return pp;
25 }
26
27 void
28 free_path (struct path * pp)
29 {
30         if (!pp)
31                 return;
32
33         if (pp->checker_context)
34                 free(pp->checker_context);
35
36         if (pp->fd > 0)
37                 close(pp->fd);
38
39         FREE(pp);
40 }
41
42 void
43 free_pathvec (vector vec, int free_paths)
44 {
45         int i;
46         struct path * pp;
47
48         if (!vec)
49                 return;
50
51         if (free_paths)
52                 vector_foreach_slot(vec, pp, i)
53                         free_path(pp);
54
55         vector_free(vec);
56 }
57
58 struct pathgroup *
59 alloc_pathgroup (void)
60 {
61         struct pathgroup * pgp;
62
63         pgp = (struct pathgroup *)MALLOC(sizeof(struct pathgroup));
64
65         if (!pgp)
66                 return NULL;
67
68         pgp->paths = vector_alloc();
69
70         if (!pgp->paths)
71                 FREE(pgp);
72
73         return pgp;
74 }
75
76 void
77 free_pathgroup (struct pathgroup * pgp, int free_paths)
78 {
79         if (!pgp)
80                 return;
81
82         free_pathvec(pgp->paths, free_paths);
83         FREE(pgp);
84 }
85
86 void
87 free_pgvec (vector pgvec, int free_paths)
88 {
89         int i;
90         struct pathgroup * pgp;
91
92         if (!pgvec)
93                 return;
94
95         vector_foreach_slot(pgvec, pgp, i)
96                 free_pathgroup(pgp, free_paths);
97
98         vector_free(pgvec);
99 }
100
101 struct multipath *
102 alloc_multipath (void)
103 {
104         struct multipath * mpp;
105
106         mpp = (struct multipath *)MALLOC(sizeof(struct multipath));
107
108         if (mpp)
109                 mpp->nextpg = 1;
110
111         return mpp;
112 }
113
114 void
115 free_multipath (struct multipath * mpp, int free_paths)
116 {
117         if (!mpp)
118                 return;
119
120         if (mpp->selector &&
121             mpp->selector != conf->default_selector &&
122             (!mpp->mpe || (mpp->mpe && mpp->selector != mpp->mpe->selector)) &&
123             (!mpp->hwe || (mpp->hwe && mpp->selector != mpp->hwe->selector)))
124                 FREE(mpp->selector);
125
126         if (mpp->alias &&
127             (!mpp->mpe || (mpp->mpe && mpp->alias != mpp->mpe->alias)) &&
128             (mpp->wwid && mpp->alias != mpp->wwid))
129                 FREE(mpp->alias);
130
131         if (mpp->features &&
132             mpp->features != conf->default_features &&
133             (!mpp->hwe || (mpp->hwe && mpp->features != mpp->hwe->features)))
134                 FREE(mpp->features);
135
136         if (mpp->hwhandler &&
137             mpp->hwhandler != conf->default_hwhandler &&
138             (!mpp->hwe || (mpp->hwe && mpp->hwhandler != mpp->hwe->hwhandler)))
139                 FREE(mpp->hwhandler);
140
141         free_pathvec(mpp->paths, free_paths);
142         free_pgvec(mpp->pg, free_paths);
143         FREE(mpp);
144 }
145
146 void
147 free_multipathvec (vector mpvec, int free_paths)
148 {
149         int i;
150         struct multipath * mpp;
151
152         if (!mpvec)
153                 return;
154
155         vector_foreach_slot (mpvec, mpp, i)
156                 free_multipath(mpp, free_paths);
157
158         vector_free(mpvec);
159 }
160
161 int
162 store_path (vector pathvec, struct path * pp)
163 {
164         if (!vector_alloc_slot(pathvec))
165                 return 1;
166
167         vector_set_slot(pathvec, pp);
168
169         return 0;
170 }
171
172 int
173 store_pathgroup (vector pgvec, struct pathgroup * pgp)
174 {
175         if (!vector_alloc_slot(pgvec))
176                 return 1;
177
178         vector_set_slot(pgvec, pgp);
179
180         return 0;
181 }
182
183 struct multipath *
184 find_mp_by_minor (vector mp, int minor)
185 {
186         int i;
187         struct multipath * mpp;
188         
189         vector_foreach_slot (mp, mpp, i)
190                 if (mpp->minor == minor)
191                         return mpp;
192
193         return NULL;
194 }
195
196 struct multipath *
197 find_mp_by_wwid (vector mp, char * wwid)
198 {
199         int i;
200         struct multipath * mpp;
201         
202         vector_foreach_slot (mp, mpp, i)
203                 if (!strncmp(mpp->wwid, wwid, WWID_SIZE))
204                         return mpp;
205
206         return NULL;
207 }
208
209 struct multipath *
210 find_mp (vector mp, char * alias)
211 {
212         int i;
213         int len;
214         struct multipath * mpp;
215         
216         len = strlen(alias);
217
218         if (!len)
219                 return NULL;
220         
221         vector_foreach_slot (mp, mpp, i) {
222                 if (strlen(mpp->alias) == len &&
223                     !strncmp(mpp->alias, alias, len))
224                         return mpp;
225         }
226         return NULL;
227 }
228
229 struct path *
230 find_path_by_dev (vector pathvec, char * dev)
231 {
232         int i;
233         struct path * pp;
234         
235         vector_foreach_slot (pathvec, pp, i)
236                 if (!strcmp_chomp(pp->dev, dev))
237                         return pp;
238
239         condlog(3, "path %s not found in pathvec\n", dev);
240         return NULL;
241 }
242
243 struct path *
244 find_path_by_devt (vector pathvec, char * dev_t)
245 {
246         int i;
247         struct path * pp;
248
249         vector_foreach_slot (pathvec, pp, i)
250                 if (!strcmp_chomp(pp->dev_t, dev_t))
251                         return pp;
252
253         condlog(3, "path %s not found in pathvec\n", dev_t);
254         return NULL;
255 }
256