2 * Copyright (c) 2003, 2004, 2005 Christophe Varoqui
3 * Copyright (c) 2005 Benjamin Marzinski, Redhat
4 * Copyright (c) 2005 Kiyoshi Ueda, NEC
5 * Copyright (c) 2005 Patrick Caulfield, Redhat
6 * Copyright (c) 2005 Edward Goggin, EMC
15 #include <libdevmapper.h>
21 #include "devmapper.h"
24 #include "structs_vec.h"
27 #include "blacklist.h"
29 #include "discovery.h"
31 #include "switchgroup.h"
33 #include "configure.h"
34 #include "pgpolicies.h"
39 setup_map (struct multipath * mpp)
41 struct pathgroup * pgp;
45 * don't bother if devmap size is unknown
48 condlog(3, "%s: devmap size is unknown", mpp->alias);
53 * properties selectors
55 select_pgfailback(mpp);
59 select_hwhandler(mpp);
60 select_rr_weight(mpp);
62 select_no_path_retry(mpp);
65 * assign paths to path groups -- start with no groups and all paths
69 vector_foreach_slot (mpp->pg, pgp, i)
70 free_pathgroup(pgp, KEEP_PATHS);
75 if (mpp->pgpolicyfn && mpp->pgpolicyfn(mpp))
78 mpp->nr_active = pathcount(mpp, PATH_UP);
81 * ponders each path group and determine highest prio pg
82 * to switch over (default to first)
84 mpp->bestpg = select_path_group(mpp);
87 * transform the mp->pg vector of vectors of paths
88 * into a mp->params strings to feed the device-mapper
90 if (assemble_map(mpp)) {
91 condlog(0, "%s: problem assembing map", mpp->alias);
98 compute_pgid(struct pathgroup * pgp)
103 vector_foreach_slot (pgp->paths, pp, i)
108 pgcmp (struct multipath * mpp, struct multipath * cmpp)
111 struct pathgroup * pgp;
112 struct pathgroup * cpgp;
115 vector_foreach_slot (mpp->pg, pgp, i) {
118 vector_foreach_slot (cmpp->pg, cpgp, j) {
119 if (pgp->id == cpgp->id) {
132 select_action (struct multipath * mpp, vector curmp)
134 struct multipath * cmpp;
136 cmpp = find_mp_by_alias(curmp, mpp->alias);
139 cmpp = find_mp_by_wwid(curmp, mpp->wwid);
141 if (cmpp && !conf->dry_run) {
142 condlog(2, "%s: rename %s to %s", mpp->wwid,
143 cmpp->alias, mpp->alias);
144 strncpy(mpp->alias_old, cmpp->alias, WWID_SIZE);
145 mpp->action = ACT_RENAME;
149 condlog(3, "%s: set ACT_CREATE (map does not exist)",
151 mpp->action = ACT_CREATE;
153 mpp->action = ACT_CREATE;
154 condlog(3, "%s: set ACT_CREATE (map does not exist)",
159 if (!find_mp_by_wwid(curmp, mpp->wwid)) {
160 condlog(2, "%s: remove (wwid changed)", cmpp->alias);
161 dm_flush_map(mpp->alias, DEFAULT_TARGET);
162 strncat(cmpp->wwid, mpp->wwid, WWID_SIZE);
163 drop_multipath(curmp, cmpp->wwid, KEEP_PATHS);
164 mpp->action = ACT_CREATE;
165 condlog(3, "%s: set ACT_CREATE (map wwid change)",
170 if (pathcount(mpp, PATH_UP) == 0) {
171 mpp->action = ACT_NOTHING;
172 condlog(3, "%s: set ACT_NOTHING (no usable path)",
176 if (cmpp->size != mpp->size) {
177 mpp->action = ACT_RELOAD;
178 condlog(3, "%s: set ACT_RELOAD (size change)",
182 if (!mpp->no_path_retry && /* let features be handled by the daemon */
183 strncmp(cmpp->features, mpp->features, strlen(mpp->features))) {
184 mpp->action = ACT_RELOAD;
185 condlog(3, "%s: set ACT_RELOAD (features change)",
189 if (strncmp(cmpp->hwhandler, mpp->hwhandler,
190 strlen(mpp->hwhandler))) {
191 mpp->action = ACT_RELOAD;
192 condlog(3, "%s: set ACT_RELOAD (hwhandler change)",
196 if (strncmp(cmpp->selector, mpp->selector,
197 strlen(mpp->selector))) {
198 mpp->action = ACT_RELOAD;
199 condlog(3, "%s: set ACT_RELOAD (selector change)",
203 if (cmpp->minio != mpp->minio) {
204 mpp->action = ACT_RELOAD;
205 condlog(3, "%s: set ACT_RELOAD (minio change, %u->%u)",
206 mpp->alias, cmpp->minio, mpp->minio);
209 if (VECTOR_SIZE(cmpp->pg) != VECTOR_SIZE(mpp->pg)) {
210 mpp->action = ACT_RELOAD;
211 condlog(3, "%s: set ACT_RELOAD (path group number change)",
215 if (pgcmp(mpp, cmpp)) {
216 mpp->action = ACT_RELOAD;
217 condlog(3, "%s: set ACT_RELOAD (path group topology change)",
221 if (cmpp->nextpg != mpp->bestpg) {
222 mpp->action = ACT_SWITCHPG;
223 condlog(3, "%s: set ACT_SWITCHPG (next path group change)",
227 mpp->action = ACT_NOTHING;
228 condlog(3, "%s: set ACT_NOTHING (map unchanged)",
234 reinstate_paths (struct multipath * mpp)
237 struct pathgroup * pgp;
243 vector_foreach_slot (mpp->pg, pgp, i) {
247 vector_foreach_slot (pgp->paths, pp, j) {
248 if (pp->state != PATH_UP &&
249 (pgp->status == PGSTATE_DISABLED ||
250 pgp->status == PGSTATE_ACTIVE))
253 if (pp->dmstate == PSTATE_FAILED) {
254 if (dm_reinstate_path(mpp->alias, pp->dev_t))
255 condlog(0, "%s: error reinstating",
264 lock_multipath (struct multipath * mpp, int lock)
266 struct pathgroup * pgp;
270 if (!mpp || !mpp->pg)
273 vector_foreach_slot (mpp->pg, pgp, i) {
276 vector_foreach_slot(pgp->paths, pp, j) {
277 if (lock && flock(pp->fd, LOCK_EX | LOCK_NB) &&
278 errno == EWOULDBLOCK)
281 flock(pp->fd, LOCK_UN);
290 * 0: DM_DEVICE_CREATE or DM_DEVICE_RELOAD failed, or dry_run mode.
291 * 1: DM_DEVICE_CREATE or DM_DEVICE_RELOAD succeeded.
292 * 2: Map is already existing.
295 domap (struct multipath * mpp)
300 * last chance to quit before touching the devmaps
303 print_multipath_topology(mpp, conf->verbosity);
307 switch (mpp->action) {
313 dm_switchgroup(mpp->alias, mpp->bestpg);
315 * we may have avoided reinstating paths because there where in
316 * active or disabled PG. Now that the topology has changed,
319 reinstate_paths(mpp);
323 if (lock_multipath(mpp, 1)) {
324 condlog(3, "%s: failed to create map (in use)",
330 if (dm_map_present(mpp->alias))
333 r = dm_addmap(DM_DEVICE_CREATE, mpp->alias, DEFAULT_TARGET,
334 mpp->params, mpp->size, mpp->wwid);
337 * DM_DEVICE_CREATE is actually DM_DEV_CREATE plus
338 * DM_TABLE_LOAD. Failing the second part leaves an
339 * empty map. Clean it up.
341 if (!r && dm_map_present(mpp->alias)) {
342 condlog(3, "%s: failed to load map "
343 "(a path might be in use)",
345 dm_flush_map(mpp->alias, DEFAULT_TARGET);
348 lock_multipath(mpp, 0);
353 r = (dm_addmap(DM_DEVICE_RELOAD, mpp->alias, DEFAULT_TARGET,
354 mpp->params, mpp->size, NULL) &&
355 dm_simplecmd(DM_DEVICE_RESUME, mpp->alias));
359 r = dm_rename(mpp->alias_old, mpp->alias);
368 * DM_DEVICE_CREATE, DM_DEIVCE_RENAME, or DM_DEVICE_RELOAD
372 dm_switchgroup(mpp->alias, mpp->bestpg);
373 if (mpp->action != ACT_NOTHING)
374 print_multipath_topology(mpp, conf->verbosity);
376 mpp->stat_map_loads++;
377 condlog(2, "%s: load table [0 %llu %s %s]", mpp->alias,
378 mpp->size, DEFAULT_TARGET, mpp->params);
386 deadmap (struct multipath * mpp)
389 struct pathgroup * pgp;
395 vector_foreach_slot (mpp->pg, pgp, i) {
399 vector_foreach_slot (pgp->paths, pp, j)
401 return 0; /* alive */
408 coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid)
412 char empty_buff[WWID_SIZE];
413 struct multipath * mpp;
416 vector curmp = vecs->mpvec;
417 vector pathvec = vecs->pathvec;
419 memset(empty_buff, 0, WWID_SIZE);
421 vector_foreach_slot (pathvec, pp1, k) {
422 /* skip this path for some reason */
424 /* 1. if path has no unique id or wwid blacklisted */
425 if (memcmp(empty_buff, pp1->wwid, WWID_SIZE) == 0 ||
426 blacklist_path(conf, pp1))
429 /* 2. if path already coalesced */
433 /* 3. if path has disappeared */
437 /* 4. path is out of scope */
438 if (refwwid && strncmp(pp1->wwid, refwwid, WWID_SIZE))
442 * at this point, we know we really got a new mp
444 if ((mpp = add_map_with_path(vecs, pp1, 0)) == NULL)
447 if (pp1->priority < 0)
448 mpp->action = ACT_REJECT;
451 condlog(0, "%s: skip coalesce (no paths)", mpp->alias);
452 remove_map(mpp, vecs, NULL, 0);
456 for (i = k + 1; i < VECTOR_SIZE(pathvec); i++) {
457 pp2 = VECTOR_SLOT(pathvec, i);
459 if (strcmp(pp1->wwid, pp2->wwid))
465 if (pp2->size != mpp->size) {
467 * ouch, avoid feeding that to the DM
469 condlog(0, "%s: size %llu, expected %llu. "
470 "Discard", pp2->dev_t, pp2->size,
472 mpp->action = ACT_REJECT;
474 if (pp2->priority < 0)
475 mpp->action = ACT_REJECT;
477 verify_paths(mpp, vecs, NULL);
479 if (setup_map(mpp)) {
480 remove_map(mpp, vecs, NULL, 0);
484 if (mpp->action == ACT_UNDEF)
485 select_action(mpp, curmp);
490 condlog(3, "%s: domap (%u) failure "
491 "for create/reload map",
493 remove_map(mpp, vecs, NULL, 0);
497 condlog(3, "%s: domap (%u) failure "
498 "for create/reload map",
503 if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF) {
504 if (mpp->no_path_retry == NO_PATH_RETRY_FAIL)
505 dm_queue_if_no_path(mpp->alias, 0);
507 dm_queue_if_no_path(mpp->alias, 1);
511 if (mpp->action != ACT_REJECT) {
512 if (!vector_alloc_slot(newmp))
514 vector_set_slot(newmp, mpp);
517 remove_map(mpp, vecs, NULL, 0);
521 * Flush maps with only dead paths (ie not in sysfs)
522 * Keep maps with only failed paths
525 vector_foreach_slot (newmp, mpp, i) {
526 char alias[WWID_SIZE];
532 strncpy(alias, mpp->alias, WWID_SIZE);
534 if ((j = find_slot(newmp, (void *)mpp)) != -1)
535 vector_del_slot(newmp, j);
537 remove_map(mpp, vecs, NULL, 0);
539 if (dm_flush_map(mpp->alias, DEFAULT_TARGET))
540 condlog(2, "%s: remove failed (dead)",
543 condlog(2, "%s: remove (dead)", mpp->alias);
550 get_refwwid (char * dev, enum devtypes dev_type, vector pathvec)
553 char buff[FILE_NAME_SIZE];
554 char * refwwid = NULL;
556 if (dev_type == DEV_NONE)
559 if (dev_type == DEV_DEVNODE) {
561 pp = find_path_by_dev(pathvec, buff);
569 strncpy(pp->dev, buff, FILE_NAME_SIZE);
571 if (pathinfo(pp, conf->hwtable, DI_SYSFS | DI_WWID))
574 if (store_path(pathvec, pp)) {
583 if (dev_type == DEV_DEVT) {
584 pp = find_path_by_devt(pathvec, dev);
587 if (devt2devname(buff, dev))
595 strncpy(pp->dev, buff, FILE_NAME_SIZE);
597 if (pathinfo(pp, conf->hwtable, DI_SYSFS | DI_WWID))
600 if (store_path(pathvec, pp)) {
608 if (dev_type == DEV_DEVMAP) {
612 refwwid = get_user_friendly_wwid(dev,
613 conf->bindings_file);
621 refwwid = get_mpe_wwid(dev);
630 if (refwwid && strlen(refwwid))
631 return STRDUP(refwwid);