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"
21 struct adapter_group *
22 alloc_adaptergroup(void)
24 struct adapter_group *agp;
26 agp = (struct adapter_group *)MALLOC(sizeof(struct adapter_group));
31 agp->host_groups = vector_alloc();
32 if (!agp->host_groups) {
39 void free_adaptergroup(vector adapters)
42 struct adapter_group *agp;
44 vector_foreach_slot(adapters, agp, i) {
45 free_hostgroup(agp->host_groups);
48 vector_free(adapters);
51 void free_hostgroup(vector hostgroups)
54 struct host_group *hgp;
59 vector_foreach_slot(hostgroups, hgp, i) {
60 vector_free(hgp->paths);
63 vector_free(hostgroups);
69 struct host_group *hgp;
71 hgp = (struct host_group *)MALLOC(sizeof(struct host_group));
76 hgp->paths = vector_alloc();
90 pp = (struct path *)MALLOC(sizeof(struct path));
93 pp->sg_id.host_no = -1;
94 pp->sg_id.channel = -1;
95 pp->sg_id.scsi_id = -1;
97 pp->sg_id.proto_id = SCSI_PROTOCOL_UNSPEC;
99 pp->priority = PRIO_UNDEF;
105 free_path (struct path * pp)
110 if (checker_selected(&pp->checker))
111 checker_put(&pp->checker);
113 if (prio_selected(&pp->prio))
120 udev_device_unref(pp->udev);
128 free_pathvec (vector vec, enum free_path_mode free_paths)
136 if (free_paths == FREE_PATHS)
137 vector_foreach_slot(vec, pp, i)
144 alloc_pathgroup (void)
146 struct pathgroup * pgp;
148 pgp = (struct pathgroup *)MALLOC(sizeof(struct pathgroup));
153 pgp->paths = vector_alloc();
164 free_pathgroup (struct pathgroup * pgp, enum free_path_mode free_paths)
169 free_pathvec(pgp->paths, free_paths);
174 free_pgvec (vector pgvec, enum free_path_mode free_paths)
177 struct pathgroup * pgp;
182 vector_foreach_slot(pgvec, pgp, i)
183 free_pathgroup(pgp, free_paths);
189 alloc_multipath (void)
191 struct multipath * mpp;
193 mpp = (struct multipath *)MALLOC(sizeof(struct multipath));
197 mpp->mpcontext = NULL;
198 mpp->no_path_retry = NO_PATH_RETRY_UNDEF;
199 mpp->fast_io_fail = MP_FAST_IO_FAIL_UNSET;
205 free_multipath_attributes (struct multipath * mpp)
212 mpp->selector = NULL;
217 mpp->features = NULL;
220 if (mpp->hwhandler) {
221 FREE(mpp->hwhandler);
222 mpp->hwhandler = NULL;
227 free_multipath (struct multipath * mpp, enum free_path_mode free_paths)
232 free_multipath_attributes(mpp);
244 free_pathvec(mpp->paths, free_paths);
245 free_pgvec(mpp->pg, free_paths);
246 FREE_PTR(mpp->mpcontext);
251 drop_multipath (vector mpvec, char * wwid, enum free_path_mode free_paths)
254 struct multipath * mpp;
259 vector_foreach_slot (mpvec, mpp, i) {
260 if (!strncmp(mpp->wwid, wwid, WWID_SIZE)) {
261 free_multipath(mpp, free_paths);
262 vector_del_slot(mpvec, i);
269 free_multipathvec (vector mpvec, enum free_path_mode free_paths)
272 struct multipath * mpp;
277 vector_foreach_slot (mpvec, mpp, i)
278 free_multipath(mpp, free_paths);
284 store_path (vector pathvec, struct path * pp)
288 if (!strlen(pp->dev_t)) {
289 condlog(2, "%s: Empty device number", pp->dev);
292 if (!strlen(pp->dev)) {
293 condlog(2, "%s: Empty device name", pp->dev_t);
300 if (!vector_alloc_slot(pathvec))
303 vector_set_slot(pathvec, pp);
309 store_pathgroup (vector pgvec, struct pathgroup * pgp)
311 if (!vector_alloc_slot(pgvec))
314 vector_set_slot(pgvec, pgp);
320 store_hostgroup(vector hostgroupvec, struct host_group * hgp)
322 if (!vector_alloc_slot(hostgroupvec))
325 vector_set_slot(hostgroupvec, hgp);
330 store_adaptergroup(vector adapters, struct adapter_group * agp)
332 if (!vector_alloc_slot(adapters))
335 vector_set_slot(adapters, agp);
340 find_mp_by_minor (vector mpvec, int minor)
343 struct multipath * mpp;
348 vector_foreach_slot (mpvec, mpp, i) {
352 if (mpp->dmi->minor == minor)
359 find_mp_by_wwid (vector mpvec, char * wwid)
362 struct multipath * mpp;
367 vector_foreach_slot (mpvec, mpp, i)
368 if (!strncmp(mpp->wwid, wwid, WWID_SIZE))
375 find_mp_by_alias (vector mpvec, char * alias)
379 struct multipath * mpp;
389 vector_foreach_slot (mpvec, mpp, i) {
390 if (strlen(mpp->alias) == len &&
391 !strncmp(mpp->alias, alias, len))
398 find_mp_by_str (vector mpvec, char * str)
402 if (sscanf(str, "dm-%d", &minor) == 1)
403 return find_mp_by_minor(mpvec, minor);
405 return find_mp_by_alias(mpvec, str);
409 find_path_by_dev (vector pathvec, char * dev)
417 vector_foreach_slot (pathvec, pp, i)
418 if (!strcmp(pp->dev, dev))
421 condlog(4, "%s: dev not found in pathvec", dev);
426 find_path_by_devt (vector pathvec, char * dev_t)
434 vector_foreach_slot (pathvec, pp, i)
435 if (!strcmp(pp->dev_t, dev_t))
438 condlog(4, "%s: dev_t not found in pathvec", dev_t);
443 pathcountgr (struct pathgroup * pgp, int state)
449 vector_foreach_slot (pgp->paths, pp, i)
450 if ((pp->state == state) || (state == PATH_WILD))
457 pathcount (struct multipath * mpp, int state)
459 struct pathgroup *pgp;
464 vector_foreach_slot (mpp->pg, pgp, i)
465 count += pathcountgr(pgp, state);
471 pathcmp (struct pathgroup *pgp, struct pathgroup *cpgp)
474 struct path *pp, *cpp;
475 int pnum = 0, found = 0;
477 vector_foreach_slot(pgp->paths, pp, i) {
479 vector_foreach_slot(cpgp->paths, cpp, j) {
480 if ((long)pp == (long)cpp) {
491 first_path (struct multipath * mpp)
493 struct pathgroup * pgp;
496 pgp = VECTOR_SLOT(mpp->pg, 0);
498 return pgp?VECTOR_SLOT(pgp->paths, 0):NULL;
502 setup_feature(struct multipath * mpp, char *feature)
504 if (!strncmp(feature, "queue_if_no_path", 16)) {
505 if (mpp->no_path_retry <= NO_PATH_RETRY_UNDEF)
506 mpp->no_path_retry = NO_PATH_RETRY_QUEUE;
511 add_feature (char **f, char *n)
523 /* Check if feature is already present */
527 /* Get feature count */
528 c = strtoul(*f, &e, 10);
533 /* Check if we need to increase feature count space */
534 l = strlen(*f) + strlen(n) + 1;
536 /* Count new features */
542 if (*p == ' ' && p[1] != '\0' && p[1] != ' ') {
556 /* Update feature count */
564 snprintf(p, l + 2, "%0d ", c);
566 /* Copy the feature string */
585 remove_feature(char **f, char *o)
594 if (!o || *o == '\0')
597 /* Check if not present */
601 /* Get feature count */
602 c = strtoul(*f, &e, 10);
607 /* Normalize features */
611 /* Just spaces, return */
619 /* Update feature count */
622 while (p[0] != '\0') {
623 if (p[0] == ' ' && p[1] != ' ' && p[1] != '\0')
628 /* Quick exit if all features have been removed */
637 /* Search feature to be removed */
640 /* Not found, return */
643 /* Update feature count space */
649 /* Copy the feature count */
650 sprintf(n, "%0d", c);
652 * Copy existing features up to the feature
653 * about to be removed
657 /* Internal error, feature string inconsistent */
668 strncat(n, p, (size_t)(e - p));
669 p += (size_t)(e - p);
671 /* Skip feature to be removed */
674 /* Copy remaining features */