libmultipath: Do not access 'conf->cmd' in domap()
[multipath-tools/.git] / libmultipath / configure.c
1 /*
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
7  */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <string.h>
13 #include <sys/file.h>
14 #include <errno.h>
15 #include <libdevmapper.h>
16 #include <libudev.h>
17 #include <mpath_cmd.h>
18
19 #include "checkers.h"
20 #include "vector.h"
21 #include "memory.h"
22 #include "devmapper.h"
23 #include "defaults.h"
24 #include "structs.h"
25 #include "structs_vec.h"
26 #include "dmparser.h"
27 #include "config.h"
28 #include "blacklist.h"
29 #include "propsel.h"
30 #include "discovery.h"
31 #include "debug.h"
32 #include "switchgroup.h"
33 #include "print.h"
34 #include "configure.h"
35 #include "pgpolicies.h"
36 #include "dict.h"
37 #include "alias.h"
38 #include "prio.h"
39 #include "util.h"
40 #include "uxsock.h"
41 #include "wwids.h"
42
43 /* group paths in pg by host adapter
44  */
45 int group_by_host_adapter(struct pathgroup *pgp, vector adapters)
46 {
47         struct adapter_group *agp;
48         struct host_group *hgp;
49         struct path *pp, *pp1;
50         char adapter_name1[SLOT_NAME_SIZE];
51         char adapter_name2[SLOT_NAME_SIZE];
52         int i, j;
53         int found_hostgroup = 0;
54
55         while (VECTOR_SIZE(pgp->paths) > 0) {
56
57                 pp = VECTOR_SLOT(pgp->paths, 0);
58
59                 if (sysfs_get_host_adapter_name(pp, adapter_name1))
60                         goto out;
61                 /* create a new host adapter group
62                  */
63                 agp = alloc_adaptergroup();
64                 if (!agp)
65                         goto out;
66                 agp->pgp = pgp;
67
68                 strncpy(agp->adapter_name, adapter_name1, SLOT_NAME_SIZE - 1);
69                 store_adaptergroup(adapters, agp);
70
71                 /* create a new host port group
72                  */
73                 hgp = alloc_hostgroup();
74                 if (!hgp)
75                         goto out;
76                 if (store_hostgroup(agp->host_groups, hgp))
77                         goto out;
78
79                 hgp->host_no = pp->sg_id.host_no;
80                 agp->num_hosts++;
81                 if (store_path(hgp->paths, pp))
82                         goto out;
83
84                 hgp->num_paths++;
85                 /* delete path from path group
86                  */
87                 vector_del_slot(pgp->paths, 0);
88
89                 /* add all paths belonging to same host adapter
90                  */
91                 vector_foreach_slot(pgp->paths, pp1, i) {
92                         if (sysfs_get_host_adapter_name(pp1, adapter_name2))
93                                 goto out;
94                         if (strcmp(adapter_name1, adapter_name2) == 0) {
95                                 found_hostgroup = 0;
96                                 vector_foreach_slot(agp->host_groups, hgp, j) {
97                                         if (hgp->host_no == pp1->sg_id.host_no) {
98                                                 if (store_path(hgp->paths, pp1))
99                                                         goto out;
100                                                 hgp->num_paths++;
101                                                 found_hostgroup = 1;
102                                                 break;
103                                         }
104                                 }
105                                 if (!found_hostgroup) {
106                                         /* this path belongs to new host port
107                                          * within this adapter
108                                          */
109                                         hgp = alloc_hostgroup();
110                                         if (!hgp)
111                                                 goto out;
112
113                                         if (store_hostgroup(agp->host_groups, hgp))
114                                                 goto out;
115
116                                         agp->num_hosts++;
117                                         if (store_path(hgp->paths, pp1))
118                                                 goto out;
119
120                                         hgp->host_no = pp1->sg_id.host_no;
121                                         hgp->num_paths++;
122                                 }
123                                 /* delete paths from original path_group
124                                  * as they are added into adapter group now
125                                  */
126                                 vector_del_slot(pgp->paths, i);
127                                 i--;
128                         }
129                 }
130         }
131         return 0;
132
133 out:    /* add back paths into pg as re-ordering failed
134          */
135         vector_foreach_slot(adapters, agp, i) {
136                         vector_foreach_slot(agp->host_groups, hgp, j) {
137                                 while (VECTOR_SIZE(hgp->paths) > 0) {
138                                         pp = VECTOR_SLOT(hgp->paths, 0);
139                                         if (store_path(pgp->paths, pp))
140                                                 condlog(3, "failed to restore "
141                                                 "path %s into path group",
142                                                  pp->dev);
143                                         vector_del_slot(hgp->paths, 0);
144                                 }
145                         }
146                 }
147         free_adaptergroup(adapters);
148         return 1;
149 }
150
151 /* re-order paths in pg by alternating adapters and host ports
152  * for optimized selection
153  */
154 int order_paths_in_pg_by_alt_adapters(struct pathgroup *pgp, vector adapters,
155                  int total_paths)
156 {
157         int next_adapter_index = 0;
158         struct adapter_group *agp;
159         struct host_group *hgp;
160         struct path *pp;
161
162         while (total_paths > 0) {
163                 agp = VECTOR_SLOT(adapters, next_adapter_index);
164                 if (!agp) {
165                         condlog(0, "can't get adapter group %d", next_adapter_index);
166                         return 1;
167                 }
168
169                 hgp = VECTOR_SLOT(agp->host_groups, agp->next_host_index);
170                 if (!hgp) {
171                         condlog(0, "can't get host group %d of adapter group %d", next_adapter_index, agp->next_host_index);
172                         return 1;
173                 }
174
175                 if (!hgp->num_paths) {
176                         agp->next_host_index++;
177                         agp->next_host_index %= agp->num_hosts;
178                         next_adapter_index++;
179                         next_adapter_index %= VECTOR_SIZE(adapters);
180                         continue;
181                 }
182
183                 pp  = VECTOR_SLOT(hgp->paths, 0);
184
185                 if (store_path(pgp->paths, pp))
186                         return 1;
187
188                 total_paths--;
189
190                 vector_del_slot(hgp->paths, 0);
191
192                 hgp->num_paths--;
193
194                 agp->next_host_index++;
195                 agp->next_host_index %= agp->num_hosts;
196                 next_adapter_index++;
197                 next_adapter_index %= VECTOR_SIZE(adapters);
198         }
199
200         /* all paths are added into path_group
201          * in crafted child order
202          */
203         return 0;
204 }
205
206 /* round-robin: order paths in path group to alternate
207  * between all host adapters
208  */
209 int rr_optimize_path_order(struct pathgroup *pgp)
210 {
211         vector adapters;
212         struct path *pp;
213         int total_paths;
214         int i;
215
216         total_paths = VECTOR_SIZE(pgp->paths);
217         vector_foreach_slot(pgp->paths, pp, i) {
218                 if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP &&
219                         pp->sg_id.proto_id != SCSI_PROTOCOL_SAS &&
220                         pp->sg_id.proto_id != SCSI_PROTOCOL_ISCSI &&
221                         pp->sg_id.proto_id != SCSI_PROTOCOL_SRP) {
222                         /* return success as default path order
223                          * is maintained in path group
224                          */
225                         return 0;
226                 }
227         }
228         adapters = vector_alloc();
229         if (!adapters)
230                 return 0;
231
232         /* group paths in path group by host adapters
233          */
234         if (group_by_host_adapter(pgp, adapters)) {
235                 /* already freed adapters */
236                 condlog(3, "Failed to group paths by adapters");
237                 return 0;
238         }
239
240         /* re-order paths in pg to alternate between adapters and host ports
241          */
242         if (order_paths_in_pg_by_alt_adapters(pgp, adapters, total_paths)) {
243                 condlog(3, "Failed to re-order paths in pg by adapters "
244                         "and host ports");
245                 free_adaptergroup(adapters);
246                 /* return failure as original paths are
247                  * removed form pgp
248                  */
249                 return 1;
250         }
251
252         free_adaptergroup(adapters);
253         return 0;
254 }
255
256 extern int
257 setup_map (struct multipath * mpp, char * params, int params_size)
258 {
259         struct pathgroup * pgp;
260         int i;
261
262         /*
263          * don't bother if devmap size is unknown
264          */
265         if (mpp->size <= 0) {
266                 condlog(3, "%s: devmap size is unknown", mpp->alias);
267                 return 1;
268         }
269
270         /*
271          * free features, selector, and hwhandler properties if they are being reused
272          */
273         free_multipath_attributes(mpp);
274
275         /*
276          * properties selectors
277          */
278         select_pgfailback(mpp);
279         select_pgpolicy(mpp);
280         select_selector(mpp);
281         select_features(mpp);
282         select_hwhandler(mpp);
283         select_rr_weight(mpp);
284         select_minio(mpp);
285         select_no_path_retry(mpp);
286         select_mode(mpp);
287         select_uid(mpp);
288         select_gid(mpp);
289         select_fast_io_fail(mpp);
290         select_dev_loss(mpp);
291         select_reservation_key(mpp);
292         select_retain_hwhandler(mpp);
293         select_deferred_remove(mpp);
294         select_delay_watch_checks(mpp);
295         select_delay_wait_checks(mpp);
296
297         sysfs_set_scsi_tmo(mpp);
298         /*
299          * assign paths to path groups -- start with no groups and all paths
300          * in mpp->paths
301          */
302         if (mpp->pg) {
303                 vector_foreach_slot (mpp->pg, pgp, i)
304                         free_pathgroup(pgp, KEEP_PATHS);
305
306                 vector_free(mpp->pg);
307                 mpp->pg = NULL;
308         }
309         if (mpp->pgpolicyfn && mpp->pgpolicyfn(mpp))
310                 return 1;
311
312         mpp->nr_active = pathcount(mpp, PATH_UP) + pathcount(mpp, PATH_GHOST);
313
314         /*
315          * ponders each path group and determine highest prio pg
316          * to switch over (default to first)
317          */
318         mpp->bestpg = select_path_group(mpp);
319
320         /* re-order paths in all path groups in an optimized way
321          * for round-robin path selectors to get maximum throughput.
322          */
323         if (!strncmp(mpp->selector, "round-robin", 11)) {
324                 vector_foreach_slot(mpp->pg, pgp, i) {
325                         if (VECTOR_SIZE(pgp->paths) <= 2)
326                                 continue;
327                         if (rr_optimize_path_order(pgp)) {
328                                 condlog(2, "cannot re-order paths for "
329                                         "optimization: %s",
330                                         mpp->alias);
331                                 return 1;
332                         }
333                 }
334         }
335
336         /*
337          * transform the mp->pg vector of vectors of paths
338          * into a mp->params strings to feed the device-mapper
339          */
340         if (assemble_map(mpp, params, params_size)) {
341                 condlog(0, "%s: problem assembing map", mpp->alias);
342                 return 1;
343         }
344         return 0;
345 }
346
347 static void
348 compute_pgid(struct pathgroup * pgp)
349 {
350         struct path * pp;
351         int i;
352
353         vector_foreach_slot (pgp->paths, pp, i)
354                 pgp->id ^= (long)pp;
355 }
356
357 static int
358 pgcmp (struct multipath * mpp, struct multipath * cmpp)
359 {
360         int i, j;
361         struct pathgroup * pgp;
362         struct pathgroup * cpgp;
363         int r = 0;
364
365         if (!mpp)
366                 return 0;
367
368         vector_foreach_slot (mpp->pg, pgp, i) {
369                 compute_pgid(pgp);
370
371                 vector_foreach_slot (cmpp->pg, cpgp, j) {
372                         if (pgp->id == cpgp->id &&
373                             !pathcmp(pgp, cpgp)) {
374                                 r = 0;
375                                 break;
376                         }
377                         r++;
378                 }
379                 if (r)
380                         return r;
381         }
382         return r;
383 }
384
385 static void
386 select_action (struct multipath * mpp, vector curmp, int force_reload)
387 {
388         struct multipath * cmpp;
389         struct multipath * cmpp_by_name;
390
391         cmpp = find_mp_by_wwid(curmp, mpp->wwid);
392         cmpp_by_name = find_mp_by_alias(curmp, mpp->alias);
393
394         if (!cmpp_by_name) {
395                 if (cmpp) {
396                         condlog(2, "%s: rename %s to %s", mpp->wwid,
397                                 cmpp->alias, mpp->alias);
398                         strncpy(mpp->alias_old, cmpp->alias, WWID_SIZE - 1);
399                         mpp->action = ACT_RENAME;
400                         if (force_reload)
401                                 mpp->action = ACT_FORCERENAME;
402                         return;
403                 }
404                 mpp->action = ACT_CREATE;
405                 condlog(3, "%s: set ACT_CREATE (map does not exist)",
406                         mpp->alias);
407                 return;
408         }
409
410         if (!cmpp) {
411                 condlog(2, "%s: remove (wwid changed)", mpp->alias);
412                 dm_flush_map(mpp->alias);
413                 strncpy(cmpp_by_name->wwid, mpp->wwid, WWID_SIZE - 1);
414                 drop_multipath(curmp, cmpp_by_name->wwid, KEEP_PATHS);
415                 mpp->action = ACT_CREATE;
416                 condlog(3, "%s: set ACT_CREATE (map wwid change)",
417                         mpp->alias);
418                 return;
419         }
420
421         if (cmpp != cmpp_by_name) {
422                 condlog(2, "%s: unable to rename %s to %s (%s is used by %s)",
423                         mpp->wwid, cmpp->alias, mpp->alias,
424                         mpp->alias, cmpp_by_name->wwid);
425                 /* reset alias to existing alias */
426                 FREE(mpp->alias);
427                 mpp->alias = STRDUP(cmpp->alias);
428                 mpp->action = ACT_NOTHING;
429                 return;
430         }
431
432         if (pathcount(mpp, PATH_UP) == 0) {
433                 mpp->action = ACT_NOTHING;
434                 condlog(3, "%s: set ACT_NOTHING (no usable path)",
435                         mpp->alias);
436                 return;
437         }
438         if (force_reload) {
439                 mpp->action = ACT_RELOAD;
440                 condlog(3, "%s: set ACT_RELOAD (forced by user)",
441                         mpp->alias);
442                 return;
443         }
444         if (cmpp->size != mpp->size) {
445                 mpp->action = ACT_RESIZE;
446                 condlog(3, "%s: set ACT_RESIZE (size change)",
447                         mpp->alias);
448                 return;
449         }
450         if (!mpp->no_path_retry &&
451             (strlen(cmpp->features) != strlen(mpp->features) ||
452              strcmp(cmpp->features, mpp->features))) {
453                 mpp->action =  ACT_RELOAD;
454                 condlog(3, "%s: set ACT_RELOAD (features change)",
455                         mpp->alias);
456                 return;
457         }
458         if (mpp->retain_hwhandler != RETAIN_HWHANDLER_ON &&
459             (strlen(cmpp->hwhandler) != strlen(mpp->hwhandler) ||
460              strncmp(cmpp->hwhandler, mpp->hwhandler,
461                     strlen(mpp->hwhandler)))) {
462                 mpp->action = ACT_RELOAD;
463                 condlog(3, "%s: set ACT_RELOAD (hwhandler change)",
464                         mpp->alias);
465                 return;
466         }
467         if (!cmpp->selector || strncmp(cmpp->selector, mpp->selector,
468                     strlen(mpp->selector))) {
469                 mpp->action = ACT_RELOAD;
470                 condlog(3, "%s: set ACT_RELOAD (selector change)",
471                         mpp->alias);
472                 return;
473         }
474         if (cmpp->minio != mpp->minio) {
475                 mpp->action = ACT_RELOAD;
476                 condlog(3, "%s: set ACT_RELOAD (minio change, %u->%u)",
477                         mpp->alias, cmpp->minio, mpp->minio);
478                 return;
479         }
480         if (!cmpp->pg || VECTOR_SIZE(cmpp->pg) != VECTOR_SIZE(mpp->pg)) {
481                 mpp->action = ACT_RELOAD;
482                 condlog(3, "%s: set ACT_RELOAD (path group number change)",
483                         mpp->alias);
484                 return;
485         }
486         if (pgcmp(mpp, cmpp)) {
487                 mpp->action = ACT_RELOAD;
488                 condlog(3, "%s: set ACT_RELOAD (path group topology change)",
489                         mpp->alias);
490                 return;
491         }
492         if (cmpp->nextpg != mpp->bestpg) {
493                 mpp->action = ACT_SWITCHPG;
494                 condlog(3, "%s: set ACT_SWITCHPG (next path group change)",
495                         mpp->alias);
496                 return;
497         }
498         mpp->action = ACT_NOTHING;
499         condlog(3, "%s: set ACT_NOTHING (map unchanged)",
500                 mpp->alias);
501         return;
502 }
503
504 extern int
505 reinstate_paths (struct multipath * mpp)
506 {
507         int i, j;
508         struct pathgroup * pgp;
509         struct path * pp;
510
511         if (!mpp->pg)
512                 return 0;
513
514         vector_foreach_slot (mpp->pg, pgp, i) {
515                 if (!pgp->paths)
516                         continue;
517
518                 vector_foreach_slot (pgp->paths, pp, j) {
519                         if (pp->state != PATH_UP &&
520                             (pgp->status == PGSTATE_DISABLED ||
521                              pgp->status == PGSTATE_ACTIVE))
522                                 continue;
523
524                         if (pp->dmstate == PSTATE_FAILED) {
525                                 if (dm_reinstate_path(mpp->alias, pp->dev_t))
526                                         condlog(0, "%s: error reinstating",
527                                                 pp->dev);
528                         }
529                 }
530         }
531         return 0;
532 }
533
534 static int
535 lock_multipath (struct multipath * mpp, int lock)
536 {
537         struct pathgroup * pgp;
538         struct path * pp;
539         int i, j;
540         int x, y;
541
542         if (!mpp || !mpp->pg)
543                 return 0;
544
545         vector_foreach_slot (mpp->pg, pgp, i) {
546                 if (!pgp->paths)
547                         continue;
548                 vector_foreach_slot(pgp->paths, pp, j) {
549                         if (lock && flock(pp->fd, LOCK_SH | LOCK_NB) &&
550                             errno == EWOULDBLOCK)
551                                 goto fail;
552                         else if (!lock)
553                                 flock(pp->fd, LOCK_UN);
554                 }
555         }
556         return 0;
557 fail:
558         vector_foreach_slot (mpp->pg, pgp, x) {
559                 if (x > i)
560                         return 1;
561                 if (!pgp->paths)
562                         continue;
563                 vector_foreach_slot(pgp->paths, pp, y) {
564                         if (x == i && y >= j)
565                                 return 1;
566                         flock(pp->fd, LOCK_UN);
567                 }
568         }
569         return 1;
570 }
571
572 /*
573  * Return value:
574  */
575 #define DOMAP_RETRY     -1
576 #define DOMAP_FAIL      0
577 #define DOMAP_OK        1
578 #define DOMAP_EXIST     2
579 #define DOMAP_DRY       3
580
581 extern int
582 domap (struct multipath * mpp, char * params, int is_daemon)
583 {
584         int r = DOMAP_FAIL;
585
586         /*
587          * last chance to quit before touching the devmaps
588          */
589         if (mpp->action == ACT_DRY_RUN) {
590                 print_multipath_topology(mpp, conf->verbosity);
591                 return DOMAP_DRY;
592         }
593
594         if (mpp->action == ACT_CREATE &&
595             dm_map_present(mpp->alias)) {
596                 condlog(3, "%s: map already present", mpp->alias);
597                 mpp->action = ACT_RELOAD;
598         }
599
600         switch (mpp->action) {
601         case ACT_REJECT:
602         case ACT_NOTHING:
603                 return DOMAP_EXIST;
604
605         case ACT_SWITCHPG:
606                 dm_switchgroup(mpp->alias, mpp->bestpg);
607                 /*
608                  * we may have avoided reinstating paths because there where in
609                  * active or disabled PG. Now that the topology has changed,
610                  * retry.
611                  */
612                 reinstate_paths(mpp);
613                 return DOMAP_EXIST;
614
615         case ACT_CREATE:
616                 if (lock_multipath(mpp, 1)) {
617                         condlog(3, "%s: failed to create map (in use)",
618                                 mpp->alias);
619                         return DOMAP_RETRY;
620                 }
621
622                 r = dm_addmap_create(mpp, params);
623
624                 lock_multipath(mpp, 0);
625                 break;
626
627         case ACT_RELOAD:
628                 r = dm_addmap_reload(mpp, params, 0);
629                 break;
630
631         case ACT_RESIZE:
632                 r = dm_addmap_reload(mpp, params, 1);
633                 break;
634
635         case ACT_RENAME:
636                 r = dm_rename(mpp->alias_old, mpp->alias,
637                               conf->partition_delim);
638                 break;
639
640         case ACT_FORCERENAME:
641                 r = dm_rename(mpp->alias_old, mpp->alias,
642                               conf->partition_delim);
643                 if (r)
644                         r = dm_addmap_reload(mpp, params, 0);
645                 break;
646
647         default:
648                 break;
649         }
650
651         if (r == DOMAP_OK) {
652                 /*
653                  * DM_DEVICE_CREATE, DM_DEVICE_RENAME, or DM_DEVICE_RELOAD
654                  * succeeded
655                  */
656                 if (mpp->action == ACT_CREATE)
657                         remember_wwid(mpp->wwid);
658                 if (!is_daemon) {
659                         /* multipath client mode */
660                         dm_switchgroup(mpp->alias, mpp->bestpg);
661                 } else  {
662                         /* multipath daemon mode */
663                         mpp->stat_map_loads++;
664                         condlog(2, "%s: load table [0 %llu %s %s]", mpp->alias,
665                                 mpp->size, TGT_MPATH, params);
666                         /*
667                          * Required action is over, reset for the stateful daemon.
668                          * But don't do it for creation as we use in the caller the
669                          * mpp->action to figure out whether to start the watievent checker.
670                          */
671                         if (mpp->action != ACT_CREATE)
672                                 mpp->action = ACT_NOTHING;
673                         else {
674                                 mpp->wait_for_udev = 1;
675                                 mpp->uev_wait_tick = conf->uev_wait_timeout;
676                         }
677                 }
678                 dm_setgeometry(mpp);
679                 return DOMAP_OK;
680         }
681         return DOMAP_FAIL;
682 }
683
684 static int
685 deadmap (struct multipath * mpp)
686 {
687         int i, j;
688         struct pathgroup * pgp;
689         struct path * pp;
690
691         if (!mpp->pg)
692                 return 1;
693
694         vector_foreach_slot (mpp->pg, pgp, i) {
695                 if (!pgp->paths)
696                         continue;
697
698                 vector_foreach_slot (pgp->paths, pp, j)
699                         if (strlen(pp->dev))
700                                 return 0; /* alive */
701         }
702
703         return 1; /* dead */
704 }
705
706 int check_daemon(void)
707 {
708         int fd;
709         char *reply;
710         int ret = 0;
711
712         fd = mpath_connect();
713         if (fd == -1)
714                 return 0;
715
716         if (send_packet(fd, "show daemon") != 0)
717                 goto out;
718         if (recv_packet(fd, &reply, conf->uxsock_timeout) != 0)
719                 goto out;
720
721         if (strstr(reply, "shutdown"))
722                 goto out_free;
723
724         ret = 1;
725
726 out_free:
727         FREE(reply);
728 out:
729         mpath_disconnect(fd);
730         return ret;
731 }
732
733 extern int
734 coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, int force_reload, enum mpath_cmds cmd)
735 {
736         int r = 1;
737         int k, i;
738         int is_daemon = (cmd == CMD_NONE) ? 1 : 0;
739         char params[PARAMS_SIZE];
740         struct multipath * mpp;
741         struct path * pp1;
742         struct path * pp2;
743         vector curmp = vecs->mpvec;
744         vector pathvec = vecs->pathvec;
745
746         /* ignore refwwid if it's empty */
747         if (refwwid && !strlen(refwwid))
748                 refwwid = NULL;
749
750         if (force_reload) {
751                 vector_foreach_slot (pathvec, pp1, k) {
752                         pp1->mpp = NULL;
753                 }
754         }
755         vector_foreach_slot (pathvec, pp1, k) {
756                 /* skip this path for some reason */
757
758                 /* 1. if path has no unique id or wwid blacklisted */
759                 if (strlen(pp1->wwid) == 0 ||
760                     filter_path(conf, pp1) > 0) {
761                         orphan_path(pp1, "wwid blacklisted");
762                         continue;
763                 }
764
765                 /* 2. if path already coalesced */
766                 if (pp1->mpp)
767                         continue;
768
769                 /* 3. if path has disappeared */
770                 if (pp1->state == PATH_REMOVED) {
771                         orphan_path(pp1, "path removed");
772                         continue;
773                 }
774
775                 /* 4. path is out of scope */
776                 if (refwwid && strncmp(pp1->wwid, refwwid, WWID_SIZE - 1))
777                         continue;
778
779                 /* If find_multipaths was selected check if the path is valid */
780                 if (!refwwid && !should_multipath(pp1, pathvec)) {
781                         orphan_path(pp1, "only one path");
782                         continue;
783                 }
784
785                 /*
786                  * at this point, we know we really got a new mp
787                  */
788                 mpp = add_map_with_path(vecs, pp1, 0);
789                 if (!mpp)
790                         return 1;
791
792                 if (pp1->priority == PRIO_UNDEF)
793                         mpp->action = ACT_REJECT;
794
795                 if (!mpp->paths) {
796                         condlog(0, "%s: skip coalesce (no paths)", mpp->alias);
797                         remove_map(mpp, vecs, 0);
798                         continue;
799                 }
800
801                 for (i = k + 1; i < VECTOR_SIZE(pathvec); i++) {
802                         pp2 = VECTOR_SLOT(pathvec, i);
803
804                         if (strcmp(pp1->wwid, pp2->wwid))
805                                 continue;
806
807                         if (!mpp->size && pp2->size)
808                                 mpp->size = pp2->size;
809
810                         if (mpp->size && pp2->size &&
811                             pp2->size != mpp->size) {
812                                 /*
813                                  * ouch, avoid feeding that to the DM
814                                  */
815                                 condlog(0, "%s: size %llu, expected %llu. "
816                                         "Discard", pp2->dev_t, pp2->size,
817                                         mpp->size);
818                                 mpp->action = ACT_REJECT;
819                         }
820                         if (pp2->priority == PRIO_UNDEF)
821                                 mpp->action = ACT_REJECT;
822                 }
823                 verify_paths(mpp, vecs);
824
825                 params[0] = '\0';
826                 if (setup_map(mpp, params, PARAMS_SIZE)) {
827                         remove_map(mpp, vecs, 0);
828                         continue;
829                 }
830
831                 if (cmd == CMD_DRY_RUN)
832                         mpp->action = ACT_DRY_RUN;
833                 if (mpp->action == ACT_UNDEF)
834                         select_action(mpp, curmp, force_reload);
835
836                 r = domap(mpp, params, is_daemon);
837
838                 if (r == DOMAP_FAIL || r == DOMAP_RETRY) {
839                         condlog(3, "%s: domap (%u) failure "
840                                    "for create/reload map",
841                                 mpp->alias, r);
842                         if (r == DOMAP_FAIL) {
843                                 condlog(2, "%s: %s map",
844                                         mpp->alias, (mpp->action == ACT_CREATE)?
845                                         "ignoring" : "removing");
846                                 remove_map(mpp, vecs, 0);
847                                 continue;
848                         } else /* if (r == DOMAP_RETRY) */
849                                 return r;
850                 }
851                 if (r == DOMAP_DRY)
852                         continue;
853
854                 if (!is_daemon && !conf->allow_queueing && !check_daemon()) {
855                         if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF &&
856                             mpp->no_path_retry != NO_PATH_RETRY_FAIL)
857                                 condlog(3, "%s: multipathd not running, unset "
858                                         "queue_if_no_path feature", mpp->alias);
859                         if (!dm_queue_if_no_path(mpp->alias, 0))
860                                 remove_feature(&mpp->features,
861                                                "queue_if_no_path");
862                 }
863                 else if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF) {
864                         if (mpp->no_path_retry == NO_PATH_RETRY_FAIL) {
865                                 condlog(3, "%s: unset queue_if_no_path feature",
866                                         mpp->alias);
867                                 if (!dm_queue_if_no_path(mpp->alias, 0))
868                                         remove_feature(&mpp->features,
869                                                        "queue_if_no_path");
870                         } else {
871                                 condlog(3, "%s: set queue_if_no_path feature",
872                                         mpp->alias);
873                                 if (!dm_queue_if_no_path(mpp->alias, 1))
874                                         add_feature(&mpp->features,
875                                                     "queue_if_no_path");
876                         }
877                 }
878
879                 if (!is_daemon && mpp->action != ACT_NOTHING)
880                         print_multipath_topology(mpp, conf->verbosity);
881
882                 if (newmp) {
883                         if (mpp->action != ACT_REJECT) {
884                                 if (!vector_alloc_slot(newmp))
885                                         return 1;
886                                 vector_set_slot(newmp, mpp);
887                         }
888                         else
889                                 remove_map(mpp, vecs, 0);
890                 }
891         }
892         /*
893          * Flush maps with only dead paths (ie not in sysfs)
894          * Keep maps with only failed paths
895          */
896         if (newmp) {
897                 vector_foreach_slot (newmp, mpp, i) {
898                         char alias[WWID_SIZE];
899                         int j;
900
901                         if (!deadmap(mpp))
902                                 continue;
903
904                         strncpy(alias, mpp->alias, WWID_SIZE - 1);
905
906                         if ((j = find_slot(newmp, (void *)mpp)) != -1)
907                                 vector_del_slot(newmp, j);
908
909                         remove_map(mpp, vecs, 0);
910
911                         if (dm_flush_map(alias))
912                                 condlog(2, "%s: remove failed (dead)",
913                                         alias);
914                         else
915                                 condlog(2, "%s: remove (dead)", alias);
916                 }
917         }
918         return 0;
919 }
920
921 /*
922  * returns:
923  * 0 - success
924  * 1 - failure
925  * 2 - blacklist
926  */
927 extern int
928 get_refwwid (char * dev, enum devtypes dev_type, vector pathvec, char **wwid)
929 {
930         int ret = 1;
931         struct path * pp;
932         char buff[FILE_NAME_SIZE];
933         char * refwwid = NULL, tmpwwid[WWID_SIZE];
934
935         if (!wwid)
936                 return 1;
937         *wwid = NULL;
938
939         if (dev_type == DEV_NONE)
940                 return 1;
941
942         if (dev_type == DEV_DEVNODE) {
943                 if (basenamecpy(dev, buff, FILE_NAME_SIZE) == 0) {
944                         condlog(1, "basename failed for '%s' (%s)",
945                                 dev, buff);
946                         return 1;
947                 }
948
949                 pp = find_path_by_dev(pathvec, buff);
950                 if (!pp) {
951                         struct udev_device *udevice = udev_device_new_from_subsystem_sysname(conf->udev, "block", buff);
952
953                         if (!udevice) {
954                                 condlog(2, "%s: can't get udev device", buff);
955                                 return 1;
956                         }
957                         ret = store_pathinfo(pathvec, conf->hwtable, udevice,
958                                              DI_SYSFS | DI_WWID, &pp);
959                         udev_device_unref(udevice);
960                         if (!pp) {
961                                 if (ret == 1)
962                                         condlog(0, "%s: can't store path info",
963                                                 dev);
964                                 return ret;
965                         }
966                 }
967                 if (pp->udev && pp->uid_attribute &&
968                     filter_property(conf, pp->udev) > 0)
969                         return 2;
970
971                 refwwid = pp->wwid;
972                 goto out;
973         }
974
975         if (dev_type == DEV_DEVT) {
976                 strchop(dev);
977                 if (devt2devname(buff, FILE_NAME_SIZE, dev)) {
978                         condlog(0, "%s: cannot find block device\n", dev);
979                         return 1;
980                 }
981                 pp = find_path_by_dev(pathvec, buff);
982                 if (!pp) {
983                         struct udev_device *udevice = udev_device_new_from_devnum(conf->udev, 'b', parse_devt(dev));
984
985                         if (!udevice) {
986                                 condlog(2, "%s: can't get udev device", dev);
987                                 return 1;
988                         }
989                         ret = store_pathinfo(pathvec, conf->hwtable, udevice,
990                                              DI_SYSFS | DI_WWID, &pp);
991                         udev_device_unref(udevice);
992                         if (!pp) {
993                                 if (ret == 1)
994                                         condlog(0, "%s can't store path info",
995                                                 buff);
996                                 return ret;
997                         }
998                 }
999                 if (pp->udev && pp->uid_attribute &&
1000                     filter_property(conf, pp->udev) > 0)
1001                         return 2;
1002
1003                 refwwid = pp->wwid;
1004                 goto out;
1005         }
1006
1007         if (dev_type == DEV_UEVENT) {
1008                 struct udev_device *udevice = udev_device_new_from_environment(conf->udev);
1009
1010                 if (!udevice) {
1011                         condlog(2, "%s: can't get udev device", dev);
1012                         return 1;
1013                 }
1014                 ret = store_pathinfo(pathvec, conf->hwtable, udevice,
1015                                      DI_SYSFS | DI_WWID, &pp);
1016                 udev_device_unref(udevice);
1017                 if (!pp) {
1018                         if (ret == 1)
1019                                 condlog(0, "%s: can't store path info",
1020                                         dev);
1021                         return ret;
1022                 }
1023                 if (pp->udev && pp->uid_attribute &&
1024                     filter_property(conf, pp->udev) > 0)
1025                         return 2;
1026
1027                 refwwid = pp->wwid;
1028                 goto out;
1029         }
1030
1031         if (dev_type == DEV_DEVMAP) {
1032
1033                 if (((dm_get_uuid(dev, tmpwwid)) == 0) && (strlen(tmpwwid))) {
1034                         refwwid = tmpwwid;
1035                         goto check;
1036                 }
1037
1038                 /*
1039                  * may be a binding
1040                  */
1041                 if (get_user_friendly_wwid(dev, tmpwwid,
1042                                            conf->bindings_file) == 0) {
1043                         refwwid = tmpwwid;
1044                         goto check;
1045                 }
1046
1047                 /*
1048                  * or may be an alias
1049                  */
1050                 refwwid = get_mpe_wwid(conf->mptable, dev);
1051
1052                 /*
1053                  * or directly a wwid
1054                  */
1055                 if (!refwwid)
1056                         refwwid = dev;
1057
1058 check:
1059                 if (refwwid && strlen(refwwid)) {
1060                         if (filter_wwid(conf->blist_wwid, conf->elist_wwid,
1061                                         refwwid, NULL) > 0)
1062                         return 2;
1063                 }
1064         }
1065 out:
1066         if (refwwid && strlen(refwwid)) {
1067                 *wwid = STRDUP(refwwid);
1068                 return 0;
1069         }
1070
1071         return 1;
1072 }
1073
1074 extern int reload_map(struct vectors *vecs, struct multipath *mpp, int refresh, int is_daemon)
1075 {
1076         char params[PARAMS_SIZE] = {0};
1077         struct path *pp;
1078         int i, r;
1079
1080         update_mpp_paths(mpp, vecs->pathvec);
1081         if (refresh) {
1082                 vector_foreach_slot (mpp->paths, pp, i) {
1083                         r = pathinfo(pp, conf->hwtable, DI_PRIO);
1084                         if (r) {
1085                                 condlog(2, "%s: failed to refresh pathinfo",
1086                                         mpp->alias);
1087                                 return 1;
1088                         }
1089                 }
1090         }
1091         if (setup_map(mpp, params, PARAMS_SIZE)) {
1092                 condlog(0, "%s: failed to setup map", mpp->alias);
1093                 return 1;
1094         }
1095         select_action(mpp, vecs->mpvec, 1);
1096
1097         r = domap(mpp, params, is_daemon);
1098         if (r == DOMAP_FAIL || r == DOMAP_RETRY) {
1099                 condlog(3, "%s: domap (%u) failure "
1100                         "for reload map", mpp->alias, r);
1101                 return 1;
1102         }
1103         if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF) {
1104                 if (mpp->no_path_retry == NO_PATH_RETRY_FAIL)
1105                         dm_queue_if_no_path(mpp->alias, 0);
1106                 else
1107                         dm_queue_if_no_path(mpp->alias, 1);
1108         }
1109
1110         return 0;
1111 }