2 * Copyright (c) 2004, 2005 Christophe Varoqui
3 * Copyright (c) 2004 Stefan Bader, IBM
7 #include <libdevmapper.h>
17 #include "structs_vec.h"
18 #include "blacklist.h"
26 pp = (struct path *)MALLOC(sizeof(struct path));
29 pp->sg_id.host_no = -1;
30 pp->sg_id.channel = -1;
31 pp->sg_id.scsi_id = -1;
34 pp->priority = PRIO_UNDEF;
40 free_path (struct path * pp)
45 if (checker_selected(&pp->checker))
46 checker_put(&pp->checker);
48 if (prio_selected(&pp->prio))
55 udev_device_unref(pp->udev);
63 free_pathvec (vector vec, enum free_path_mode free_paths)
71 if (free_paths == FREE_PATHS)
72 vector_foreach_slot(vec, pp, i)
79 alloc_pathgroup (void)
81 struct pathgroup * pgp;
83 pgp = (struct pathgroup *)MALLOC(sizeof(struct pathgroup));
88 pgp->paths = vector_alloc();
99 free_pathgroup (struct pathgroup * pgp, enum free_path_mode free_paths)
104 free_pathvec(pgp->paths, free_paths);
109 free_pgvec (vector pgvec, enum free_path_mode free_paths)
112 struct pathgroup * pgp;
117 vector_foreach_slot(pgvec, pgp, i)
118 free_pathgroup(pgp, free_paths);
124 alloc_multipath (void)
126 struct multipath * mpp;
128 mpp = (struct multipath *)MALLOC(sizeof(struct multipath));
132 mpp->mpcontext = NULL;
133 mpp->no_path_retry = NO_PATH_RETRY_UNDEF;
134 mpp->fast_io_fail = MP_FAST_IO_FAIL_UNSET;
140 free_multipath_attributes (struct multipath * mpp)
146 mpp->selector != conf->selector &&
147 (!mpp->mpe || (mpp->mpe && mpp->selector != mpp->mpe->selector)) &&
148 (!mpp->hwe || (mpp->hwe && mpp->selector != mpp->hwe->selector))) {
150 mpp->selector = NULL;
155 mpp->features = NULL;
158 if (mpp->hwhandler &&
159 mpp->hwhandler != conf->hwhandler &&
160 (!mpp->hwe || (mpp->hwe && mpp->hwhandler != mpp->hwe->hwhandler))) {
161 FREE(mpp->hwhandler);
162 mpp->hwhandler = NULL;
167 free_multipath (struct multipath * mpp, enum free_path_mode free_paths)
172 free_multipath_attributes(mpp);
184 free_pathvec(mpp->paths, free_paths);
185 free_pgvec(mpp->pg, free_paths);
186 FREE_PTR(mpp->mpcontext);
191 drop_multipath (vector mpvec, char * wwid, enum free_path_mode free_paths)
194 struct multipath * mpp;
199 vector_foreach_slot (mpvec, mpp, i) {
200 if (!strncmp(mpp->wwid, wwid, WWID_SIZE)) {
201 free_multipath(mpp, free_paths);
202 vector_del_slot(mpvec, i);
209 free_multipathvec (vector mpvec, enum free_path_mode free_paths)
212 struct multipath * mpp;
217 vector_foreach_slot (mpvec, mpp, i)
218 free_multipath(mpp, free_paths);
224 store_path (vector pathvec, struct path * pp)
226 if (!vector_alloc_slot(pathvec))
229 vector_set_slot(pathvec, pp);
235 store_pathgroup (vector pgvec, struct pathgroup * pgp)
237 if (!vector_alloc_slot(pgvec))
240 vector_set_slot(pgvec, pgp);
246 find_mp_by_minor (vector mpvec, int minor)
249 struct multipath * mpp;
254 vector_foreach_slot (mpvec, mpp, i) {
258 if (mpp->dmi->minor == minor)
265 find_mp_by_wwid (vector mpvec, char * wwid)
268 struct multipath * mpp;
273 vector_foreach_slot (mpvec, mpp, i)
274 if (!strncmp(mpp->wwid, wwid, WWID_SIZE))
281 find_mp_by_alias (vector mpvec, char * alias)
285 struct multipath * mpp;
295 vector_foreach_slot (mpvec, mpp, i) {
296 if (strlen(mpp->alias) == len &&
297 !strncmp(mpp->alias, alias, len))
304 find_mp_by_str (vector mpvec, char * str)
308 if (sscanf(str, "dm-%d", &minor) == 1)
309 return find_mp_by_minor(mpvec, minor);
311 return find_mp_by_alias(mpvec, str);
315 find_path_by_dev (vector pathvec, char * dev)
323 vector_foreach_slot (pathvec, pp, i)
324 if (!strcmp(pp->dev, dev))
327 condlog(3, "%s: not found in pathvec", dev);
332 find_path_by_devt (vector pathvec, char * dev_t)
340 vector_foreach_slot (pathvec, pp, i)
341 if (!strcmp(pp->dev_t, dev_t))
344 condlog(3, "%s: not found in pathvec", dev_t);
349 pathcountgr (struct pathgroup * pgp, int state)
355 vector_foreach_slot (pgp->paths, pp, i)
356 if ((pp->state == state) || (state == PATH_WILD))
363 pathcount (struct multipath * mpp, int state)
365 struct pathgroup *pgp;
370 vector_foreach_slot (mpp->pg, pgp, i)
371 count += pathcountgr(pgp, state);
377 pathcmp (struct pathgroup *pgp, struct pathgroup *cpgp)
380 struct path *pp, *cpp;
381 int pnum = 0, found = 0;
383 vector_foreach_slot(pgp->paths, pp, i) {
385 vector_foreach_slot(cpgp->paths, cpp, j) {
386 if ((long)pp == (long)cpp) {
397 first_path (struct multipath * mpp)
399 struct pathgroup * pgp;
402 pgp = VECTOR_SLOT(mpp->pg, 0);
404 return pgp?VECTOR_SLOT(pgp->paths, 0):NULL;
408 setup_feature(struct multipath * mpp, char *feature)
410 if (!strncmp(feature, "queue_if_no_path", 16)) {
411 if (mpp->no_path_retry <= NO_PATH_RETRY_UNDEF)
412 mpp->no_path_retry = NO_PATH_RETRY_QUEUE;
417 add_feature (char **f, char *n)
429 /* Check if feature is already present */
433 /* Get feature count */
434 c = strtoul(*f, &e, 10);
439 /* Check if we need to increase feature count space */
440 l = strlen(*f) + strlen(n) + 1;
442 /* Count new features */
448 if (*p == ' ' && p[1] != '\0' && p[1] != ' ') {
462 /* Update feature count */
470 snprintf(p, l + 2, "%0d ", c);
472 /* Copy the feature string */
491 remove_feature(char **f, char *o)
500 if (!o || *o == '\0')
503 /* Check if not present */
507 /* Get feature count */
508 c = strtoul(*f, &e, 10);
513 /* Normalize features */
517 /* Just spaces, return */
525 /* Update feature count */
528 while (p[0] != '\0') {
529 if (p[0] == ' ' && p[1] != ' ' && p[1] != '\0')
534 /* Quick exit if all features have been removed */
543 /* Search feature to be removed */
546 /* Not found, return */
549 /* Update feature count space */
555 /* Copy the feature count */
556 sprintf(n, "%0d", c);
558 * Copy existing features up to the feature
559 * about to be removed
563 /* Internal error, feature string inconsistent */
574 strncat(n, p, (size_t)(e - p));
575 p += (size_t)(e - p);
577 /* Skip feature to be removed */
580 /* Copy remaining features */