fb5a5a923ce5c253fd8d0d724abae667847d41a4
[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 int setup_map(struct multipath *mpp, char *params, int params_size)
257 {
258         struct pathgroup * pgp;
259         struct config *conf;
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         conf = get_multipath_config();
279         select_pgfailback(conf, mpp);
280         select_pgpolicy(conf, mpp);
281         select_selector(conf, mpp);
282         select_features(conf, mpp);
283         select_hwhandler(conf, mpp);
284         select_rr_weight(conf, mpp);
285         select_minio(conf, mpp);
286         select_no_path_retry(conf, mpp);
287         select_mode(conf, mpp);
288         select_uid(conf, mpp);
289         select_gid(conf, mpp);
290         select_fast_io_fail(conf, mpp);
291         select_dev_loss(conf, mpp);
292         select_reservation_key(conf, mpp);
293         select_retain_hwhandler(conf, mpp);
294         select_deferred_remove(conf, mpp);
295         select_delay_watch_checks(conf, mpp);
296         select_delay_wait_checks(conf, mpp);
297         select_san_path_err_threshold(conf, mpp);
298         select_san_path_err_forget_rate(conf, mpp);
299         select_san_path_err_recovery_time(conf, mpp);
300         select_skip_kpartx(conf, mpp);
301         select_max_sectors_kb(conf, mpp);
302
303         sysfs_set_scsi_tmo(mpp, conf->checkint);
304         sysfs_set_max_sectors_kb(mpp);
305         put_multipath_config(conf);
306         /*
307          * assign paths to path groups -- start with no groups and all paths
308          * in mpp->paths
309          */
310         if (mpp->pg) {
311                 vector_foreach_slot (mpp->pg, pgp, i)
312                         free_pathgroup(pgp, KEEP_PATHS);
313
314                 vector_free(mpp->pg);
315                 mpp->pg = NULL;
316         }
317         if (mpp->pgpolicyfn && mpp->pgpolicyfn(mpp))
318                 return 1;
319
320         mpp->nr_active = pathcount(mpp, PATH_UP) + pathcount(mpp, PATH_GHOST);
321
322         /*
323          * ponders each path group and determine highest prio pg
324          * to switch over (default to first)
325          */
326         mpp->bestpg = select_path_group(mpp);
327
328         /* re-order paths in all path groups in an optimized way
329          * for round-robin path selectors to get maximum throughput.
330          */
331         if (!strncmp(mpp->selector, "round-robin", 11)) {
332                 vector_foreach_slot(mpp->pg, pgp, i) {
333                         if (VECTOR_SIZE(pgp->paths) <= 2)
334                                 continue;
335                         if (rr_optimize_path_order(pgp)) {
336                                 condlog(2, "cannot re-order paths for "
337                                         "optimization: %s",
338                                         mpp->alias);
339                                 return 1;
340                         }
341                 }
342         }
343
344         /*
345          * transform the mp->pg vector of vectors of paths
346          * into a mp->params strings to feed the device-mapper
347          */
348         if (assemble_map(mpp, params, params_size)) {
349                 condlog(0, "%s: problem assembing map", mpp->alias);
350                 return 1;
351         }
352         return 0;
353 }
354
355 static void
356 compute_pgid(struct pathgroup * pgp)
357 {
358         struct path * pp;
359         int i;
360
361         vector_foreach_slot (pgp->paths, pp, i)
362                 pgp->id ^= (long)pp;
363 }
364
365 static int
366 pgcmp (struct multipath * mpp, struct multipath * cmpp)
367 {
368         int i, j;
369         struct pathgroup * pgp;
370         struct pathgroup * cpgp;
371         int r = 0;
372
373         if (!mpp)
374                 return 0;
375
376         vector_foreach_slot (mpp->pg, pgp, i) {
377                 compute_pgid(pgp);
378
379                 vector_foreach_slot (cmpp->pg, cpgp, j) {
380                         if (pgp->id == cpgp->id &&
381                             !pathcmp(pgp, cpgp)) {
382                                 r = 0;
383                                 break;
384                         }
385                         r++;
386                 }
387                 if (r)
388                         return r;
389         }
390         return r;
391 }
392
393 static void
394 select_action (struct multipath * mpp, vector curmp, int force_reload)
395 {
396         struct multipath * cmpp;
397         struct multipath * cmpp_by_name;
398         char * mpp_feat, * cmpp_feat;
399
400         cmpp = find_mp_by_wwid(curmp, mpp->wwid);
401         cmpp_by_name = find_mp_by_alias(curmp, mpp->alias);
402
403         if (!cmpp_by_name) {
404                 if (cmpp) {
405                         condlog(2, "%s: rename %s to %s", mpp->wwid,
406                                 cmpp->alias, mpp->alias);
407                         strncpy(mpp->alias_old, cmpp->alias, WWID_SIZE - 1);
408                         mpp->action = ACT_RENAME;
409                         if (force_reload)
410                                 mpp->action = ACT_FORCERENAME;
411                         return;
412                 }
413                 mpp->action = ACT_CREATE;
414                 condlog(3, "%s: set ACT_CREATE (map does not exist)",
415                         mpp->alias);
416                 return;
417         }
418
419         if (!cmpp) {
420                 condlog(2, "%s: remove (wwid changed)", mpp->alias);
421                 dm_flush_map(mpp->alias);
422                 strncpy(cmpp_by_name->wwid, mpp->wwid, WWID_SIZE - 1);
423                 drop_multipath(curmp, cmpp_by_name->wwid, KEEP_PATHS);
424                 mpp->action = ACT_CREATE;
425                 condlog(3, "%s: set ACT_CREATE (map wwid change)",
426                         mpp->alias);
427                 return;
428         }
429
430         if (cmpp != cmpp_by_name) {
431                 condlog(2, "%s: unable to rename %s to %s (%s is used by %s)",
432                         mpp->wwid, cmpp->alias, mpp->alias,
433                         mpp->alias, cmpp_by_name->wwid);
434                 /* reset alias to existing alias */
435                 FREE(mpp->alias);
436                 mpp->alias = STRDUP(cmpp->alias);
437                 mpp->action = ACT_NOTHING;
438                 return;
439         }
440
441         if (pathcount(mpp, PATH_UP) == 0) {
442                 mpp->action = ACT_NOTHING;
443                 condlog(3, "%s: set ACT_NOTHING (no usable path)",
444                         mpp->alias);
445                 return;
446         }
447         if (force_reload) {
448                 mpp->action = ACT_RELOAD;
449                 condlog(3, "%s: set ACT_RELOAD (forced by user)",
450                         mpp->alias);
451                 return;
452         }
453         if (cmpp->size != mpp->size) {
454                 mpp->action = ACT_RESIZE;
455                 condlog(3, "%s: set ACT_RESIZE (size change)",
456                         mpp->alias);
457                 return;
458         }
459
460         if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF &&
461             mpp->no_path_retry != cmpp->no_path_retry) {
462                 mpp->action =  ACT_RELOAD;
463                 condlog(3, "%s: set ACT_RELOAD (no_path_retry change)",
464                         mpp->alias);
465                 return;
466         }
467         if (mpp->retain_hwhandler != RETAIN_HWHANDLER_ON &&
468             (strlen(cmpp->hwhandler) != strlen(mpp->hwhandler) ||
469              strncmp(cmpp->hwhandler, mpp->hwhandler,
470                     strlen(mpp->hwhandler)))) {
471                 mpp->action = ACT_RELOAD;
472                 condlog(3, "%s: set ACT_RELOAD (hwhandler change)",
473                         mpp->alias);
474                 return;
475         }
476
477         if (mpp->retain_hwhandler != RETAIN_HWHANDLER_UNDEF &&
478             mpp->retain_hwhandler != cmpp->retain_hwhandler) {
479                 mpp->action = ACT_RELOAD;
480                 condlog(3, "%s: set ACT_RELOAD (retain_hwhandler change)",
481                         mpp->alias);
482                 return;
483         }
484
485         cmpp_feat = STRDUP(cmpp->features);
486         mpp_feat = STRDUP(mpp->features);
487         if (cmpp_feat && mpp_feat) {
488                 remove_feature(&mpp_feat, "queue_if_no_path");
489                 remove_feature(&mpp_feat, "retain_attached_hw_handler");
490                 remove_feature(&cmpp_feat, "queue_if_no_path");
491                 remove_feature(&cmpp_feat, "retain_attached_hw_handler");
492                 if (strncmp(mpp_feat, cmpp_feat, PARAMS_SIZE)) {
493                         mpp->action =  ACT_RELOAD;
494                         condlog(3, "%s: set ACT_RELOAD (features change)",
495                                 mpp->alias);
496                 }
497         }
498         FREE(cmpp_feat);
499         FREE(mpp_feat);
500
501         if (!cmpp->selector || strncmp(cmpp->selector, mpp->selector,
502                     strlen(mpp->selector))) {
503                 mpp->action = ACT_RELOAD;
504                 condlog(3, "%s: set ACT_RELOAD (selector change)",
505                         mpp->alias);
506                 return;
507         }
508         if (cmpp->minio != mpp->minio) {
509                 mpp->action = ACT_RELOAD;
510                 condlog(3, "%s: set ACT_RELOAD (minio change, %u->%u)",
511                         mpp->alias, cmpp->minio, mpp->minio);
512                 return;
513         }
514         if (!cmpp->pg || VECTOR_SIZE(cmpp->pg) != VECTOR_SIZE(mpp->pg)) {
515                 mpp->action = ACT_RELOAD;
516                 condlog(3, "%s: set ACT_RELOAD (path group number change)",
517                         mpp->alias);
518                 return;
519         }
520         if (pgcmp(mpp, cmpp)) {
521                 mpp->action = ACT_RELOAD;
522                 condlog(3, "%s: set ACT_RELOAD (path group topology change)",
523                         mpp->alias);
524                 return;
525         }
526         if (cmpp->nextpg != mpp->bestpg) {
527                 mpp->action = ACT_SWITCHPG;
528                 condlog(3, "%s: set ACT_SWITCHPG (next path group change)",
529                         mpp->alias);
530                 return;
531         }
532         mpp->action = ACT_NOTHING;
533         condlog(3, "%s: set ACT_NOTHING (map unchanged)",
534                 mpp->alias);
535         return;
536 }
537
538 int reinstate_paths(struct multipath *mpp)
539 {
540         int i, j;
541         struct pathgroup * pgp;
542         struct path * pp;
543
544         if (!mpp->pg)
545                 return 0;
546
547         vector_foreach_slot (mpp->pg, pgp, i) {
548                 if (!pgp->paths)
549                         continue;
550
551                 vector_foreach_slot (pgp->paths, pp, j) {
552                         if (pp->state != PATH_UP &&
553                             (pgp->status == PGSTATE_DISABLED ||
554                              pgp->status == PGSTATE_ACTIVE))
555                                 continue;
556
557                         if (pp->dmstate == PSTATE_FAILED) {
558                                 if (dm_reinstate_path(mpp->alias, pp->dev_t))
559                                         condlog(0, "%s: error reinstating",
560                                                 pp->dev);
561                         }
562                 }
563         }
564         return 0;
565 }
566
567 static int
568 lock_multipath (struct multipath * mpp, int lock)
569 {
570         struct pathgroup * pgp;
571         struct path * pp;
572         int i, j;
573         int x, y;
574
575         if (!mpp || !mpp->pg)
576                 return 0;
577
578         vector_foreach_slot (mpp->pg, pgp, i) {
579                 if (!pgp->paths)
580                         continue;
581                 vector_foreach_slot(pgp->paths, pp, j) {
582                         if (lock && flock(pp->fd, LOCK_SH | LOCK_NB) &&
583                             errno == EWOULDBLOCK)
584                                 goto fail;
585                         else if (!lock)
586                                 flock(pp->fd, LOCK_UN);
587                 }
588         }
589         return 0;
590 fail:
591         vector_foreach_slot (mpp->pg, pgp, x) {
592                 if (x > i)
593                         return 1;
594                 if (!pgp->paths)
595                         continue;
596                 vector_foreach_slot(pgp->paths, pp, y) {
597                         if (x == i && y >= j)
598                                 return 1;
599                         flock(pp->fd, LOCK_UN);
600                 }
601         }
602         return 1;
603 }
604
605 /*
606  * Return value:
607  */
608 #define DOMAP_RETRY     -1
609 #define DOMAP_FAIL      0
610 #define DOMAP_OK        1
611 #define DOMAP_EXIST     2
612 #define DOMAP_DRY       3
613
614 int domap(struct multipath *mpp, char *params, int is_daemon)
615 {
616         int r = DOMAP_FAIL;
617         struct config *conf;
618
619         /*
620          * last chance to quit before touching the devmaps
621          */
622         if (mpp->action == ACT_DRY_RUN) {
623                 conf = get_multipath_config();
624                 print_multipath_topology(mpp, conf->verbosity);
625                 put_multipath_config(conf);
626                 return DOMAP_DRY;
627         }
628
629         if (mpp->action == ACT_CREATE &&
630             dm_map_present(mpp->alias)) {
631                 condlog(3, "%s: map already present", mpp->alias);
632                 mpp->action = ACT_RELOAD;
633         }
634
635         switch (mpp->action) {
636         case ACT_REJECT:
637         case ACT_NOTHING:
638                 return DOMAP_EXIST;
639
640         case ACT_SWITCHPG:
641                 dm_switchgroup(mpp->alias, mpp->bestpg);
642                 /*
643                  * we may have avoided reinstating paths because there where in
644                  * active or disabled PG. Now that the topology has changed,
645                  * retry.
646                  */
647                 reinstate_paths(mpp);
648                 return DOMAP_EXIST;
649
650         case ACT_CREATE:
651                 if (lock_multipath(mpp, 1)) {
652                         condlog(3, "%s: failed to create map (in use)",
653                                 mpp->alias);
654                         return DOMAP_RETRY;
655                 }
656
657                 r = dm_addmap_create(mpp, params);
658
659                 lock_multipath(mpp, 0);
660                 break;
661
662         case ACT_RELOAD:
663                 r = dm_addmap_reload(mpp, params, 0);
664                 break;
665
666         case ACT_RESIZE:
667                 r = dm_addmap_reload(mpp, params, 1);
668                 break;
669
670         case ACT_RENAME:
671                 conf = get_multipath_config();
672                 r = dm_rename(mpp->alias_old, mpp->alias,
673                               conf->partition_delim, mpp->skip_kpartx);
674                 put_multipath_config(conf);
675                 break;
676
677         case ACT_FORCERENAME:
678                 conf = get_multipath_config();
679                 r = dm_rename(mpp->alias_old, mpp->alias,
680                               conf->partition_delim, mpp->skip_kpartx);
681                 put_multipath_config(conf);
682                 if (r)
683                         r = dm_addmap_reload(mpp, params, 0);
684                 break;
685
686         default:
687                 break;
688         }
689
690         if (r == DOMAP_OK) {
691                 /*
692                  * DM_DEVICE_CREATE, DM_DEVICE_RENAME, or DM_DEVICE_RELOAD
693                  * succeeded
694                  */
695                 if (mpp->action == ACT_CREATE)
696                         remember_wwid(mpp->wwid);
697                 if (!is_daemon) {
698                         /* multipath client mode */
699                         dm_switchgroup(mpp->alias, mpp->bestpg);
700                 } else  {
701                         /* multipath daemon mode */
702                         mpp->stat_map_loads++;
703                         condlog(2, "%s: load table [0 %llu %s %s]", mpp->alias,
704                                 mpp->size, TGT_MPATH, params);
705                         /*
706                          * Required action is over, reset for the stateful daemon.
707                          * But don't do it for creation as we use in the caller the
708                          * mpp->action to figure out whether to start the watievent checker.
709                          */
710                         if (mpp->action != ACT_CREATE)
711                                 mpp->action = ACT_NOTHING;
712                         else {
713                                 conf = get_multipath_config();
714                                 mpp->wait_for_udev = 1;
715                                 mpp->uev_wait_tick = conf->uev_wait_timeout;
716                                 put_multipath_config(conf);
717                         }
718                 }
719                 dm_setgeometry(mpp);
720                 return DOMAP_OK;
721         }
722         return DOMAP_FAIL;
723 }
724
725 static int
726 deadmap (struct multipath * mpp)
727 {
728         int i, j;
729         struct pathgroup * pgp;
730         struct path * pp;
731
732         if (!mpp->pg)
733                 return 1;
734
735         vector_foreach_slot (mpp->pg, pgp, i) {
736                 if (!pgp->paths)
737                         continue;
738
739                 vector_foreach_slot (pgp->paths, pp, j)
740                         if (strlen(pp->dev))
741                                 return 0; /* alive */
742         }
743
744         return 1; /* dead */
745 }
746
747 int check_daemon(void)
748 {
749         int fd;
750         char *reply;
751         int ret = 0;
752         unsigned int timeout;
753         struct config *conf;
754
755         fd = mpath_connect();
756         if (fd == -1)
757                 return 0;
758
759         if (send_packet(fd, "show daemon") != 0)
760                 goto out;
761         conf = get_multipath_config();
762         timeout = conf->uxsock_timeout;
763         put_multipath_config(conf);
764         if (recv_packet(fd, &reply, timeout) != 0)
765                 goto out;
766
767         if (strstr(reply, "shutdown"))
768                 goto out_free;
769
770         ret = 1;
771
772 out_free:
773         FREE(reply);
774 out:
775         mpath_disconnect(fd);
776         return ret;
777 }
778
779 /*
780  * The force_reload parameter determines how coalesce_paths treats existing maps.
781  * FORCE_RELOAD_NONE: existing maps aren't touched at all
782  * FORCE_RELOAD_YES: all maps are rebuilt from scratch and (re)loaded in DM
783  * FORCE_RELOAD_WEAK: existing maps are compared to the current conf and only
784  * reloaded in DM if there's a difference. This is useful during startup.
785  */
786 int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
787                     int force_reload, enum mpath_cmds cmd)
788 {
789         int r = 1;
790         int k, i;
791         int is_daemon = (cmd == CMD_NONE) ? 1 : 0;
792         char params[PARAMS_SIZE];
793         struct multipath * mpp;
794         struct path * pp1;
795         struct path * pp2;
796         vector curmp = vecs->mpvec;
797         vector pathvec = vecs->pathvec;
798         struct config *conf;
799         int allow_queueing;
800
801         /* ignore refwwid if it's empty */
802         if (refwwid && !strlen(refwwid))
803                 refwwid = NULL;
804
805         if (force_reload != FORCE_RELOAD_NONE) {
806                 vector_foreach_slot (pathvec, pp1, k) {
807                         pp1->mpp = NULL;
808                 }
809         }
810         vector_foreach_slot (pathvec, pp1, k) {
811                 /* skip this path for some reason */
812
813                 /* 1. if path has no unique id or wwid blacklisted */
814                 conf = get_multipath_config();
815                 if (strlen(pp1->wwid) == 0 ||
816                     filter_path(conf, pp1) > 0) {
817                         put_multipath_config(conf);
818                         orphan_path(pp1, "wwid blacklisted");
819                         continue;
820                 }
821                 put_multipath_config(conf);
822
823                 /* 2. if path already coalesced */
824                 if (pp1->mpp)
825                         continue;
826
827                 /* 3. if path has disappeared */
828                 if (pp1->state == PATH_REMOVED) {
829                         orphan_path(pp1, "path removed");
830                         continue;
831                 }
832
833                 /* 4. path is out of scope */
834                 if (refwwid && strncmp(pp1->wwid, refwwid, WWID_SIZE - 1))
835                         continue;
836
837                 /* If find_multipaths was selected check if the path is valid */
838                 if (!refwwid && !should_multipath(pp1, pathvec)) {
839                         orphan_path(pp1, "only one path");
840                         continue;
841                 }
842
843                 /*
844                  * at this point, we know we really got a new mp
845                  */
846                 mpp = add_map_with_path(vecs, pp1, 0);
847                 if (!mpp) {
848                         orphan_path(pp1, "failed to create multipath device");
849                         continue;
850                 }
851
852                 if (pp1->priority == PRIO_UNDEF)
853                         mpp->action = ACT_REJECT;
854
855                 if (!mpp->paths) {
856                         condlog(0, "%s: skip coalesce (no paths)", mpp->alias);
857                         remove_map(mpp, vecs, 0);
858                         continue;
859                 }
860
861                 for (i = k + 1; i < VECTOR_SIZE(pathvec); i++) {
862                         pp2 = VECTOR_SLOT(pathvec, i);
863
864                         if (strcmp(pp1->wwid, pp2->wwid))
865                                 continue;
866
867                         if (!mpp->size && pp2->size)
868                                 mpp->size = pp2->size;
869
870                         if (mpp->size && pp2->size &&
871                             pp2->size != mpp->size) {
872                                 /*
873                                  * ouch, avoid feeding that to the DM
874                                  */
875                                 condlog(0, "%s: size %llu, expected %llu. "
876                                         "Discard", pp2->dev_t, pp2->size,
877                                         mpp->size);
878                                 mpp->action = ACT_REJECT;
879                         }
880                         if (pp2->priority == PRIO_UNDEF)
881                                 mpp->action = ACT_REJECT;
882                 }
883                 verify_paths(mpp, vecs);
884
885                 params[0] = '\0';
886                 if (setup_map(mpp, params, PARAMS_SIZE)) {
887                         remove_map(mpp, vecs, 0);
888                         continue;
889                 }
890
891                 if (cmd == CMD_DRY_RUN)
892                         mpp->action = ACT_DRY_RUN;
893                 if (mpp->action == ACT_UNDEF)
894                         select_action(mpp, curmp,
895                                       force_reload == FORCE_RELOAD_YES ? 1 : 0);
896
897                 r = domap(mpp, params, is_daemon);
898
899                 if (r == DOMAP_FAIL || r == DOMAP_RETRY) {
900                         condlog(3, "%s: domap (%u) failure "
901                                    "for create/reload map",
902                                 mpp->alias, r);
903                         if (r == DOMAP_FAIL || is_daemon) {
904                                 condlog(2, "%s: %s map",
905                                         mpp->alias, (mpp->action == ACT_CREATE)?
906                                         "ignoring" : "removing");
907                                 remove_map(mpp, vecs, 0);
908                                 continue;
909                         } else /* if (r == DOMAP_RETRY) */
910                                 return r;
911                 }
912                 if (r == DOMAP_DRY)
913                         continue;
914
915                 conf = get_multipath_config();
916                 allow_queueing = conf->allow_queueing;
917                 put_multipath_config(conf);
918                 if (!is_daemon && !allow_queueing && !check_daemon()) {
919                         if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF &&
920                             mpp->no_path_retry != NO_PATH_RETRY_FAIL)
921                                 condlog(3, "%s: multipathd not running, unset "
922                                         "queue_if_no_path feature", mpp->alias);
923                         if (!dm_queue_if_no_path(mpp->alias, 0))
924                                 remove_feature(&mpp->features,
925                                                "queue_if_no_path");
926                 }
927                 else if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF) {
928                         if (mpp->no_path_retry == NO_PATH_RETRY_FAIL) {
929                                 condlog(3, "%s: unset queue_if_no_path feature",
930                                         mpp->alias);
931                                 if (!dm_queue_if_no_path(mpp->alias, 0))
932                                         remove_feature(&mpp->features,
933                                                        "queue_if_no_path");
934                         } else {
935                                 condlog(3, "%s: set queue_if_no_path feature",
936                                         mpp->alias);
937                                 if (!dm_queue_if_no_path(mpp->alias, 1))
938                                         add_feature(&mpp->features,
939                                                     "queue_if_no_path");
940                         }
941                 }
942
943                 if (!is_daemon && mpp->action != ACT_NOTHING) {
944                         conf = get_multipath_config();
945                         print_multipath_topology(mpp, conf->verbosity);
946                         put_multipath_config(conf);
947                 }
948
949                 if (newmp) {
950                         if (mpp->action != ACT_REJECT) {
951                                 if (!vector_alloc_slot(newmp))
952                                         return 1;
953                                 vector_set_slot(newmp, mpp);
954                         }
955                         else
956                                 remove_map(mpp, vecs, 0);
957                 }
958         }
959         /*
960          * Flush maps with only dead paths (ie not in sysfs)
961          * Keep maps with only failed paths
962          */
963         if (newmp) {
964                 vector_foreach_slot (newmp, mpp, i) {
965                         char alias[WWID_SIZE];
966
967                         if (!deadmap(mpp))
968                                 continue;
969
970                         strncpy(alias, mpp->alias, WWID_SIZE - 1);
971
972                         vector_del_slot(newmp, i);
973                         i--;
974                         remove_map(mpp, vecs, 0);
975
976                         if (dm_flush_map(alias))
977                                 condlog(2, "%s: remove failed (dead)",
978                                         alias);
979                         else
980                                 condlog(2, "%s: remove (dead)", alias);
981                 }
982         }
983         return 0;
984 }
985
986 /*
987  * returns:
988  * 0 - success
989  * 1 - failure
990  * 2 - blacklist
991  */
992 int get_refwwid(enum mpath_cmds cmd, char *dev, enum devtypes dev_type,
993                 vector pathvec, char **wwid)
994 {
995         int ret = 1;
996         struct path * pp;
997         char buff[FILE_NAME_SIZE];
998         char * refwwid = NULL, tmpwwid[WWID_SIZE];
999         int flags = DI_SYSFS | DI_WWID;
1000         struct config *conf;
1001
1002         if (!wwid)
1003                 return 1;
1004         *wwid = NULL;
1005
1006         if (dev_type == DEV_NONE)
1007                 return 1;
1008
1009         if (cmd != CMD_REMOVE_WWID)
1010                 flags |= DI_BLACKLIST;
1011
1012         if (dev_type == DEV_DEVNODE) {
1013                 if (basenamecpy(dev, buff, FILE_NAME_SIZE) == 0) {
1014                         condlog(1, "basename failed for '%s' (%s)",
1015                                 dev, buff);
1016                         return 1;
1017                 }
1018
1019                 pp = find_path_by_dev(pathvec, buff);
1020                 if (!pp) {
1021                         struct udev_device *udevice = udev_device_new_from_subsystem_sysname(udev, "block", buff);
1022
1023                         if (!udevice) {
1024                                 condlog(2, "%s: can't get udev device", buff);
1025                                 return 1;
1026                         }
1027                         conf = get_multipath_config();
1028                         ret = store_pathinfo(pathvec, conf, udevice,
1029                                              flags, &pp);
1030                         put_multipath_config(conf);
1031                         udev_device_unref(udevice);
1032                         if (!pp) {
1033                                 if (ret == 1)
1034                                         condlog(0, "%s: can't store path info",
1035                                                 dev);
1036                                 return ret;
1037                         }
1038                 }
1039                 conf = get_multipath_config();
1040                 if (pp->udev && pp->uid_attribute &&
1041                     filter_property(conf, pp->udev) > 0) {
1042                         put_multipath_config(conf);
1043                         return 2;
1044                 }
1045                 put_multipath_config(conf);
1046
1047                 refwwid = pp->wwid;
1048                 goto out;
1049         }
1050
1051         if (dev_type == DEV_DEVT) {
1052                 strchop(dev);
1053                 if (devt2devname(buff, FILE_NAME_SIZE, dev)) {
1054                         condlog(0, "%s: cannot find block device\n", dev);
1055                         return 1;
1056                 }
1057                 pp = find_path_by_dev(pathvec, buff);
1058                 if (!pp) {
1059                         struct udev_device *udevice = udev_device_new_from_devnum(udev, 'b', parse_devt(dev));
1060
1061                         if (!udevice) {
1062                                 condlog(2, "%s: can't get udev device", dev);
1063                                 return 1;
1064                         }
1065                         conf = get_multipath_config();
1066                         ret = store_pathinfo(pathvec, conf, udevice,
1067                                              flags, &pp);
1068                         put_multipath_config(conf);
1069                         udev_device_unref(udevice);
1070                         if (!pp) {
1071                                 if (ret == 1)
1072                                         condlog(0, "%s can't store path info",
1073                                                 buff);
1074                                 return ret;
1075                         }
1076                 }
1077                 conf = get_multipath_config();
1078                 if (pp->udev && pp->uid_attribute &&
1079                     filter_property(conf, pp->udev) > 0) {
1080                         put_multipath_config(conf);
1081                         return 2;
1082                 }
1083                 put_multipath_config(conf);
1084                 refwwid = pp->wwid;
1085                 goto out;
1086         }
1087
1088         if (dev_type == DEV_UEVENT) {
1089                 struct udev_device *udevice = udev_device_new_from_environment(udev);
1090
1091                 if (!udevice) {
1092                         condlog(2, "%s: can't get udev device", dev);
1093                         return 1;
1094                 }
1095                 conf = get_multipath_config();
1096                 ret = store_pathinfo(pathvec, conf, udevice,
1097                                      flags, &pp);
1098                 udev_device_unref(udevice);
1099                 if (!pp) {
1100                         if (ret == 1)
1101                                 condlog(0, "%s: can't store path info",
1102                                         dev);
1103                         put_multipath_config(conf);
1104                         return ret;
1105                 }
1106                 if (pp->udev && pp->uid_attribute &&
1107                     filter_property(conf, pp->udev) > 0) {
1108                         put_multipath_config(conf);
1109                         return 2;
1110                 }
1111                 put_multipath_config(conf);
1112                 refwwid = pp->wwid;
1113                 goto out;
1114         }
1115
1116         if (dev_type == DEV_DEVMAP) {
1117
1118                 conf = get_multipath_config();
1119                 if (((dm_get_uuid(dev, tmpwwid)) == 0) && (strlen(tmpwwid))) {
1120                         refwwid = tmpwwid;
1121                         goto check;
1122                 }
1123
1124                 /*
1125                  * may be a binding
1126                  */
1127                 if (get_user_friendly_wwid(dev, tmpwwid,
1128                                            conf->bindings_file) == 0) {
1129                         refwwid = tmpwwid;
1130                         put_multipath_config(conf);
1131                         goto check;
1132                 }
1133
1134                 /*
1135                  * or may be an alias
1136                  */
1137                 refwwid = get_mpe_wwid(conf->mptable, dev);
1138
1139                 /*
1140                  * or directly a wwid
1141                  */
1142                 if (!refwwid)
1143                         refwwid = dev;
1144
1145 check:
1146                 if (refwwid && strlen(refwwid)) {
1147                         if (filter_wwid(conf->blist_wwid, conf->elist_wwid,
1148                                         refwwid, NULL) > 0) {
1149                                 put_multipath_config(conf);
1150                                 return 2;
1151                         }
1152                 }
1153                 put_multipath_config(conf);
1154         }
1155 out:
1156         if (refwwid && strlen(refwwid)) {
1157                 *wwid = STRDUP(refwwid);
1158                 return 0;
1159         }
1160
1161         return 1;
1162 }
1163
1164 int reload_map(struct vectors *vecs, struct multipath *mpp, int refresh,
1165                int is_daemon)
1166 {
1167         char params[PARAMS_SIZE] = {0};
1168         struct path *pp;
1169         int i, r;
1170
1171         update_mpp_paths(mpp, vecs->pathvec);
1172         if (refresh) {
1173                 vector_foreach_slot (mpp->paths, pp, i) {
1174                         struct config *conf = get_multipath_config();
1175                         r = pathinfo(pp, conf, DI_PRIO);
1176                         put_multipath_config(conf);
1177                         if (r) {
1178                                 condlog(2, "%s: failed to refresh pathinfo",
1179                                         mpp->alias);
1180                                 return 1;
1181                         }
1182                 }
1183         }
1184         if (setup_map(mpp, params, PARAMS_SIZE)) {
1185                 condlog(0, "%s: failed to setup map", mpp->alias);
1186                 return 1;
1187         }
1188         select_action(mpp, vecs->mpvec, 1);
1189
1190         r = domap(mpp, params, is_daemon);
1191         if (r == DOMAP_FAIL || r == DOMAP_RETRY) {
1192                 condlog(3, "%s: domap (%u) failure "
1193                         "for reload map", mpp->alias, r);
1194                 return 1;
1195         }
1196         if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF) {
1197                 if (mpp->no_path_retry == NO_PATH_RETRY_FAIL)
1198                         dm_queue_if_no_path(mpp->alias, 0);
1199                 else
1200                         dm_queue_if_no_path(mpp->alias, 1);
1201         }
1202
1203         return 0;
1204 }