Imported Upstream version 0.8.9
[platform/upstream/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 <ctype.h>
16 #include <libdevmapper.h>
17 #include <libudev.h>
18 #include "mpath_cmd.h"
19
20 #include "checkers.h"
21 #include "vector.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 "dm-generic.h"
34 #include "print.h"
35 #include "configure.h"
36 #include "pgpolicies.h"
37 #include "dict.h"
38 #include "alias.h"
39 #include "prio.h"
40 #include "util.h"
41 #include "uxsock.h"
42 #include "wwids.h"
43 #include "sysfs.h"
44 #include "io_err_stat.h"
45
46 /* group paths in pg by host adapter
47  */
48 int group_by_host_adapter(struct pathgroup *pgp, vector adapters)
49 {
50         struct adapter_group *agp;
51         struct host_group *hgp;
52         struct path *pp, *pp1;
53         char adapter_name1[SLOT_NAME_SIZE];
54         char adapter_name2[SLOT_NAME_SIZE];
55         int i, j;
56         int found_hostgroup = 0;
57
58         while (VECTOR_SIZE(pgp->paths) > 0) {
59
60                 pp = VECTOR_SLOT(pgp->paths, 0);
61
62                 if (sysfs_get_host_adapter_name(pp, adapter_name1))
63                         goto out;
64                 /* create a new host adapter group
65                  */
66                 agp = alloc_adaptergroup();
67                 if (!agp)
68                         goto out;
69                 agp->pgp = pgp;
70
71                 strlcpy(agp->adapter_name, adapter_name1, SLOT_NAME_SIZE);
72                 store_adaptergroup(adapters, agp);
73
74                 /* create a new host port group
75                  */
76                 hgp = alloc_hostgroup();
77                 if (!hgp)
78                         goto out;
79                 if (store_hostgroup(agp->host_groups, hgp))
80                         goto out;
81
82                 hgp->host_no = pp->sg_id.host_no;
83                 agp->num_hosts++;
84                 if (store_path(hgp->paths, pp))
85                         goto out;
86
87                 hgp->num_paths++;
88                 /* delete path from path group
89                  */
90                 vector_del_slot(pgp->paths, 0);
91
92                 /* add all paths belonging to same host adapter
93                  */
94                 vector_foreach_slot(pgp->paths, pp1, i) {
95                         if (sysfs_get_host_adapter_name(pp1, adapter_name2))
96                                 goto out;
97                         if (strcmp(adapter_name1, adapter_name2) == 0) {
98                                 found_hostgroup = 0;
99                                 vector_foreach_slot(agp->host_groups, hgp, j) {
100                                         if (hgp->host_no == pp1->sg_id.host_no) {
101                                                 if (store_path(hgp->paths, pp1))
102                                                         goto out;
103                                                 hgp->num_paths++;
104                                                 found_hostgroup = 1;
105                                                 break;
106                                         }
107                                 }
108                                 if (!found_hostgroup) {
109                                         /* this path belongs to new host port
110                                          * within this adapter
111                                          */
112                                         hgp = alloc_hostgroup();
113                                         if (!hgp)
114                                                 goto out;
115
116                                         if (store_hostgroup(agp->host_groups, hgp))
117                                                 goto out;
118
119                                         agp->num_hosts++;
120                                         if (store_path(hgp->paths, pp1))
121                                                 goto out;
122
123                                         hgp->host_no = pp1->sg_id.host_no;
124                                         hgp->num_paths++;
125                                 }
126                                 /* delete paths from original path_group
127                                  * as they are added into adapter group now
128                                  */
129                                 vector_del_slot(pgp->paths, i);
130                                 i--;
131                         }
132                 }
133         }
134         return 0;
135
136 out:    /* add back paths into pg as re-ordering failed
137          */
138         vector_foreach_slot(adapters, agp, i) {
139                         vector_foreach_slot(agp->host_groups, hgp, j) {
140                                 while (VECTOR_SIZE(hgp->paths) > 0) {
141                                         pp = VECTOR_SLOT(hgp->paths, 0);
142                                         if (store_path(pgp->paths, pp))
143                                                 condlog(3, "failed to restore "
144                                                 "path %s into path group",
145                                                  pp->dev);
146                                         vector_del_slot(hgp->paths, 0);
147                                 }
148                         }
149                 }
150         free_adaptergroup(adapters);
151         return 1;
152 }
153
154 /* re-order paths in pg by alternating adapters and host ports
155  * for optimized selection
156  */
157 int order_paths_in_pg_by_alt_adapters(struct pathgroup *pgp, vector adapters,
158                  int total_paths)
159 {
160         int next_adapter_index = 0;
161         struct adapter_group *agp;
162         struct host_group *hgp;
163         struct path *pp;
164
165         while (total_paths > 0) {
166                 agp = VECTOR_SLOT(adapters, next_adapter_index);
167                 if (!agp) {
168                         condlog(0, "can't get adapter group %d", next_adapter_index);
169                         return 1;
170                 }
171
172                 hgp = VECTOR_SLOT(agp->host_groups, agp->next_host_index);
173                 if (!hgp) {
174                         condlog(0, "can't get host group %d of adapter group %d", next_adapter_index, agp->next_host_index);
175                         return 1;
176                 }
177
178                 if (!hgp->num_paths) {
179                         agp->next_host_index++;
180                         agp->next_host_index %= agp->num_hosts;
181                         next_adapter_index++;
182                         next_adapter_index %= VECTOR_SIZE(adapters);
183                         continue;
184                 }
185
186                 pp  = VECTOR_SLOT(hgp->paths, 0);
187
188                 if (store_path(pgp->paths, pp))
189                         return 1;
190
191                 total_paths--;
192
193                 vector_del_slot(hgp->paths, 0);
194
195                 hgp->num_paths--;
196
197                 agp->next_host_index++;
198                 agp->next_host_index %= agp->num_hosts;
199                 next_adapter_index++;
200                 next_adapter_index %= VECTOR_SIZE(adapters);
201         }
202
203         /* all paths are added into path_group
204          * in crafted child order
205          */
206         return 0;
207 }
208
209 /* round-robin: order paths in path group to alternate
210  * between all host adapters
211  */
212 int rr_optimize_path_order(struct pathgroup *pgp)
213 {
214         vector adapters;
215         struct path *pp;
216         int total_paths;
217         int i;
218
219         total_paths = VECTOR_SIZE(pgp->paths);
220         vector_foreach_slot(pgp->paths, pp, i) {
221                 if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP &&
222                         pp->sg_id.proto_id != SCSI_PROTOCOL_SAS &&
223                         pp->sg_id.proto_id != SCSI_PROTOCOL_ISCSI &&
224                         pp->sg_id.proto_id != SCSI_PROTOCOL_SRP) {
225                         /* return success as default path order
226                          * is maintained in path group
227                          */
228                         return 0;
229                 }
230         }
231         adapters = vector_alloc();
232         if (!adapters)
233                 return 0;
234
235         /* group paths in path group by host adapters
236          */
237         if (group_by_host_adapter(pgp, adapters)) {
238                 /* already freed adapters */
239                 condlog(3, "Failed to group paths by adapters");
240                 return 0;
241         }
242
243         /* re-order paths in pg to alternate between adapters and host ports
244          */
245         if (order_paths_in_pg_by_alt_adapters(pgp, adapters, total_paths)) {
246                 condlog(3, "Failed to re-order paths in pg by adapters "
247                         "and host ports");
248                 free_adaptergroup(adapters);
249                 /* return failure as original paths are
250                  * removed form pgp
251                  */
252                 return 1;
253         }
254
255         free_adaptergroup(adapters);
256         return 0;
257 }
258
259 int setup_map(struct multipath *mpp, char **params, struct vectors *vecs)
260 {
261         struct pathgroup * pgp;
262         struct config *conf;
263         int i, marginal_pathgroups;
264         char *save_attr;
265
266         /*
267          * don't bother if devmap size is unknown
268          */
269         if (mpp->size <= 0) {
270                 condlog(3, "%s: devmap size is unknown", mpp->alias);
271                 return 1;
272         }
273
274         if (mpp->disable_queueing && VECTOR_SIZE(mpp->paths) != 0)
275                 mpp->disable_queueing = 0;
276
277         /*
278          * If this map was created with add_map_without_path(),
279          * mpp->hwe might not be set yet.
280          */
281         if (!mpp->hwe)
282                 extract_hwe_from_path(mpp);
283
284         /*
285          * properties selectors
286          *
287          * Ordering matters for some properties:
288          * - features after no_path_retry and retain_hwhandler
289          * - hwhandler after retain_hwhandler
290          * No guarantee that this list is complete, check code in
291          * propsel.c if in doubt.
292          */
293         conf = get_multipath_config();
294         pthread_cleanup_push(put_multipath_config, conf);
295
296         select_pgfailback(conf, mpp);
297         select_pgpolicy(conf, mpp);
298
299         /*
300          * If setup_map() is called from e.g. from reload_map() or resize_map(),
301          * make sure that we don't corrupt attributes.
302          */
303         save_attr = steal_ptr(mpp->selector);
304         select_selector(conf, mpp);
305         if (!mpp->selector)
306                 mpp->selector = save_attr;
307         else
308                 free(save_attr);
309
310         select_no_path_retry(conf, mpp);
311         select_retain_hwhandler(conf, mpp);
312
313         save_attr = steal_ptr(mpp->features);
314         select_features(conf, mpp);
315         if (!mpp->features)
316                 mpp->features = save_attr;
317         else
318                 free(save_attr);
319
320         save_attr = steal_ptr(mpp->hwhandler);
321         select_hwhandler(conf, mpp);
322         if (!mpp->hwhandler)
323                 mpp->hwhandler = save_attr;
324         else
325                 free(save_attr);
326
327         select_rr_weight(conf, mpp);
328         select_minio(conf, mpp);
329         select_mode(conf, mpp);
330         select_uid(conf, mpp);
331         select_gid(conf, mpp);
332         select_fast_io_fail(conf, mpp);
333         select_dev_loss(conf, mpp);
334         select_eh_deadline(conf, mpp);
335         select_reservation_key(conf, mpp);
336         select_deferred_remove(conf, mpp);
337         select_marginal_path_err_sample_time(conf, mpp);
338         select_marginal_path_err_rate_threshold(conf, mpp);
339         select_marginal_path_err_recheck_gap_time(conf, mpp);
340         select_marginal_path_double_failed_time(conf, mpp);
341         select_san_path_err_threshold(conf, mpp);
342         select_san_path_err_forget_rate(conf, mpp);
343         select_san_path_err_recovery_time(conf, mpp);
344         select_delay_checks(conf, mpp);
345         select_skip_kpartx(conf, mpp);
346         select_max_sectors_kb(conf, mpp);
347         select_ghost_delay(conf, mpp);
348         select_flush_on_last_del(conf, mpp);
349
350         sysfs_set_scsi_tmo(mpp, conf->checkint);
351         marginal_pathgroups = conf->marginal_pathgroups;
352         pthread_cleanup_pop(1);
353
354         if (!mpp->features || !mpp->hwhandler || !mpp->selector) {
355                 condlog(0, "%s: map select failed", mpp->alias);
356                 return 1;
357         }
358
359         if (marginal_path_check_enabled(mpp))
360                 start_io_err_stat_thread(vecs);
361
362         /*
363          * assign paths to path groups -- start with no groups and all paths
364          * in mpp->paths
365          */
366         if (mpp->pg) {
367                 vector_foreach_slot (mpp->pg, pgp, i)
368                         free_pathgroup(pgp, KEEP_PATHS);
369
370                 vector_free(mpp->pg);
371                 mpp->pg = NULL;
372         }
373         if (group_paths(mpp, marginal_pathgroups))
374                 return 1;
375
376         /*
377          * ponders each path group and determine highest prio pg
378          * to switch over (default to first)
379          */
380         mpp->bestpg = select_path_group(mpp);
381
382         /* re-order paths in all path groups in an optimized way
383          * for round-robin path selectors to get maximum throughput.
384          */
385         if (!strncmp(mpp->selector, "round-robin", 11)) {
386                 vector_foreach_slot(mpp->pg, pgp, i) {
387                         if (VECTOR_SIZE(pgp->paths) <= 2)
388                                 continue;
389                         if (rr_optimize_path_order(pgp)) {
390                                 condlog(2, "cannot re-order paths for "
391                                         "optimization: %s",
392                                         mpp->alias);
393                                 return 1;
394                         }
395                 }
396         }
397
398         /*
399          * transform the mp->pg vector of vectors of paths
400          * into a mp->params strings to feed the device-mapper
401          */
402         if (assemble_map(mpp, params)) {
403                 condlog(0, "%s: problem assembing map", mpp->alias);
404                 return 1;
405         }
406         return 0;
407 }
408
409 static void
410 compute_pgid(struct pathgroup * pgp)
411 {
412         struct path * pp;
413         int i;
414
415         vector_foreach_slot (pgp->paths, pp, i)
416                 pgp->id ^= (long)pp;
417 }
418
419 static int
420 pgcmp (struct multipath * mpp, struct multipath * cmpp)
421 {
422         int i, j;
423         struct pathgroup * pgp;
424         struct pathgroup * cpgp;
425         int r = 0;
426
427         if (!mpp)
428                 return 0;
429
430         vector_foreach_slot (mpp->pg, pgp, i) {
431                 compute_pgid(pgp);
432
433                 vector_foreach_slot (cmpp->pg, cpgp, j) {
434                         if (pgp->id == cpgp->id &&
435                             !pathcmp(pgp, cpgp)) {
436                                 r = 0;
437                                 break;
438                         }
439                         r++;
440                 }
441                 if (r)
442                         return r;
443         }
444         return r;
445 }
446
447 static struct udev_device *
448 get_udev_for_mpp(const struct multipath *mpp)
449 {
450         dev_t devnum;
451         struct udev_device *udd;
452
453         if (!mpp || !has_dm_info(mpp)) {
454                 condlog(1, "%s called with empty mpp", __func__);
455                 return NULL;
456         }
457
458         devnum = makedev(mpp->dmi.major, mpp->dmi.minor);
459         udd = udev_device_new_from_devnum(udev, 'b', devnum);
460         if (!udd) {
461                 condlog(1, "failed to get udev device for %s", mpp->alias);
462                 return NULL;
463         }
464         return udd;
465 }
466
467 void trigger_partitions_udev_change(struct udev_device *dev,
468                                     const char *action, int len)
469 {
470         struct udev_enumerate *part_enum;
471         struct udev_list_entry *item;
472         const char *devtype;
473
474         part_enum = udev_enumerate_new(udev);
475         if (!part_enum)
476                 return;
477
478         if (udev_enumerate_add_match_parent(part_enum, dev) < 0 ||
479             udev_enumerate_add_match_subsystem(part_enum, "block") < 0 ||
480             udev_enumerate_scan_devices(part_enum) < 0)
481                 goto unref;
482
483         udev_list_entry_foreach(item,
484                                 udev_enumerate_get_list_entry(part_enum)) {
485                 const char *syspath;
486                 struct udev_device *part;
487
488                 syspath = udev_list_entry_get_name(item);
489                 part = udev_device_new_from_syspath(udev, syspath);
490                 if (!part)
491                         continue;
492
493                 devtype = udev_device_get_devtype(part);
494                 if (devtype && !strcmp("partition", devtype)) {
495                         condlog(4, "%s: triggering %s event for %s", __func__,
496                                 action, syspath);
497                         sysfs_attr_set_value(part, "uevent", action, len);
498                 }
499                 udev_device_unref(part);
500         }
501 unref:
502         udev_enumerate_unref(part_enum);
503 }
504
505 void
506 trigger_path_udev_change(struct path *pp, bool is_mpath)
507 {
508         /*
509          * If a path changes from multipath to non-multipath, we must
510          * synthesize an artificial "add" event, otherwise the LVM2 rules
511          * (69-lvm2-lvmetad.rules) won't pick it up. Otherwise, we'd just
512          * irritate ourselves with an "add", so use "change".
513          */
514         const char *action = is_mpath ? "change" : "add";
515         const char *env;
516
517         if (!pp->udev)
518                 return;
519         /*
520          * Paths that are already classified as multipath
521          * members don't need another uevent.
522          */
523         env = udev_device_get_property_value(
524                 pp->udev, "DM_MULTIPATH_DEVICE_PATH");
525
526         if (is_mpath && env != NULL && !strcmp(env, "1")) {
527                 /*
528                  * If FIND_MULTIPATHS_WAIT_UNTIL is not "0",
529                  * path is in "maybe" state and timer is running
530                  * Send uevent now (see multipath.rules).
531                  */
532                 env = udev_device_get_property_value(
533                         pp->udev, "FIND_MULTIPATHS_WAIT_UNTIL");
534                 if (env == NULL || !strcmp(env, "0"))
535                         return;
536         } else if (!is_mpath &&
537                    (env == NULL || !strcmp(env, "0")))
538                 return;
539
540         condlog(3, "triggering %s uevent for %s (is %smultipath member)",
541                 action, pp->dev, is_mpath ? "" : "no ");
542         sysfs_attr_set_value(pp->udev, "uevent",
543                              action, strlen(action));
544         trigger_partitions_udev_change(pp->udev, action,
545                                        strlen(action));
546 }
547
548 void
549 trigger_paths_udev_change(struct multipath *mpp, bool is_mpath)
550 {
551         struct pathgroup *pgp;
552         struct path *pp;
553         int i, j;
554
555         if (!mpp || !mpp->pg)
556                 return;
557
558         vector_foreach_slot (mpp->pg, pgp, i) {
559                 if (!pgp->paths)
560                         continue;
561                 vector_foreach_slot(pgp->paths, pp, j)
562                         trigger_path_udev_change(pp, is_mpath);
563         }
564
565         mpp->needs_paths_uevent = 0;
566 }
567
568 static int
569 sysfs_set_max_sectors_kb(struct multipath *mpp, int is_reload)
570 {
571         struct pathgroup * pgp;
572         struct path *pp;
573         char buff[11];
574         int i, j, ret, err = 0;
575         struct udev_device *udd;
576         int max_sectors_kb;
577
578         if (mpp->max_sectors_kb == MAX_SECTORS_KB_UNDEF)
579                 return 0;
580         max_sectors_kb = mpp->max_sectors_kb;
581         if (is_reload) {
582                 if (!has_dm_info(mpp) &&
583                     dm_get_info(mpp->alias, &mpp->dmi) != 0) {
584                         condlog(1, "failed to get dm info for %s", mpp->alias);
585                         return 1;
586                 }
587                 udd = get_udev_for_mpp(mpp);
588                 if (!udd) {
589                         condlog(1, "failed to get udev device to set max_sectors_kb for %s", mpp->alias);
590                         return 1;
591                 }
592                 ret = sysfs_attr_get_value(udd, "queue/max_sectors_kb", buff,
593                                            sizeof(buff));
594                 udev_device_unref(udd);
595                 if (ret <= 0) {
596                         condlog(1, "failed to get current max_sectors_kb from %s", mpp->alias);
597                         return 1;
598                 }
599                 if (sscanf(buff, "%u\n", &max_sectors_kb) != 1) {
600                         condlog(1, "can't parse current max_sectors_kb from %s",
601                                 mpp->alias);
602                         return 1;
603                 }
604         }
605         snprintf(buff, 11, "%d", max_sectors_kb);
606
607         vector_foreach_slot (mpp->pg, pgp, i) {
608                 vector_foreach_slot(pgp->paths, pp, j) {
609                         ret = sysfs_attr_set_value(pp->udev,
610                                                    "queue/max_sectors_kb",
611                                                    buff, strlen(buff));
612                         if (ret < 0) {
613                                 condlog(1, "failed setting max_sectors_kb on %s : %s", pp->dev, strerror(-ret));
614                                 err = 1;
615                         }
616                 }
617         }
618         return err;
619 }
620
621 static bool is_udev_ready(struct multipath *cmpp)
622 {
623         struct udev_device *mpp_ud;
624         const char *env;
625         bool rc;
626
627         /*
628          * MPATH_DEVICE_READY != 1 can mean two things:
629          *  (a) no usable paths
630          *  (b) device was never fully processed (e.g. udev killed)
631          * If we are in this code path (startup or forced reconfigure),
632          * (b) can mean that upper layers like kpartx have never been
633          * run for this map. Thus force udev reload.
634          */
635
636         mpp_ud = get_udev_for_mpp(cmpp);
637         if (!mpp_ud)
638                 return true;
639         env = udev_device_get_property_value(mpp_ud, "MPATH_DEVICE_READY");
640         rc = (env != NULL && !strcmp(env, "1"));
641         udev_device_unref(mpp_ud);
642         condlog(4, "%s: %s: \"%s\" -> %d\n", __func__, cmpp->alias, env, rc);
643         return rc;
644 }
645
646 static void
647 select_reload_action(struct multipath *mpp, const char *reason)
648 {
649         mpp->action = ACT_RELOAD;
650         condlog(3, "%s: set ACT_RELOAD (%s)", mpp->alias, reason);
651 }
652
653 void select_action (struct multipath *mpp, const struct _vector *curmp,
654                     int force_reload)
655 {
656         struct multipath * cmpp;
657         struct multipath * cmpp_by_name;
658         char * mpp_feat, * cmpp_feat;
659
660         cmpp = find_mp_by_wwid(curmp, mpp->wwid);
661         cmpp_by_name = find_mp_by_alias(curmp, mpp->alias);
662         if (mpp->need_reload || (cmpp && cmpp->need_reload))
663                 force_reload = 1;
664
665         if (!cmpp_by_name) {
666                 if (cmpp) {
667                         condlog(2, "%s: rename %s to %s", mpp->wwid,
668                                 cmpp->alias, mpp->alias);
669                         strlcpy(mpp->alias_old, cmpp->alias, WWID_SIZE);
670                         mpp->action = ACT_RENAME;
671                         if (force_reload) {
672                                 mpp->force_udev_reload = 1;
673                                 mpp->action = ACT_FORCERENAME;
674                         }
675                         return;
676                 }
677                 mpp->action = ACT_CREATE;
678                 condlog(3, "%s: set ACT_CREATE (map does not exist)",
679                         mpp->alias);
680                 return;
681         }
682
683         if (!cmpp) {
684                 condlog(1, "%s: can't use alias \"%s\" used by %s, falling back to WWID",
685                         mpp->wwid, mpp->alias, cmpp_by_name->wwid);
686                 /* We can do this because wwid wasn't found */
687                 free(mpp->alias);
688                 mpp->alias = strdup(mpp->wwid);
689                 mpp->action = ACT_CREATE;
690                 condlog(3, "%s: set ACT_CREATE (map does not exist, name changed)",
691                         mpp->alias);
692                 return;
693         }
694
695         if (cmpp != cmpp_by_name) {
696                 condlog(2, "%s: unable to rename %s to %s (%s is used by %s)",
697                         mpp->wwid, cmpp->alias, mpp->alias,
698                         mpp->alias, cmpp_by_name->wwid);
699                 /* reset alias to existing alias */
700                 free(mpp->alias);
701                 mpp->alias = strdup(cmpp->alias);
702                 mpp->action = ACT_IMPOSSIBLE;
703                 return;
704         }
705
706         if (force_reload) {
707                 mpp->force_udev_reload = 1;
708                 mpp->action = ACT_RELOAD;
709                 condlog(3, "%s: set ACT_RELOAD (forced by user)",
710                         mpp->alias);
711                 return;
712         }
713         if (cmpp->size != mpp->size) {
714                 mpp->force_udev_reload = 1;
715                 mpp->action = ACT_RESIZE;
716                 condlog(3, "%s: set ACT_RESIZE (size change)",
717                         mpp->alias);
718                 return;
719         }
720
721         if (!is_udev_ready(cmpp) && count_active_paths(mpp) > 0) {
722                 mpp->force_udev_reload = 1;
723                 mpp->action = ACT_RELOAD;
724                 condlog(3, "%s: set ACT_RELOAD (udev incomplete)",
725                         mpp->alias);
726                 return;
727         }
728
729         if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF &&
730             !!strstr(mpp->features, "queue_if_no_path") !=
731             !!strstr(cmpp->features, "queue_if_no_path")) {
732                 select_reload_action(mpp, "no_path_retry change");
733                 return;
734         }
735         if ((mpp->retain_hwhandler != RETAIN_HWHANDLER_ON ||
736              strcmp(cmpp->hwhandler, "0") == 0) &&
737             (strlen(cmpp->hwhandler) != strlen(mpp->hwhandler) ||
738              strncmp(cmpp->hwhandler, mpp->hwhandler,
739                     strlen(mpp->hwhandler)))) {
740                 select_reload_action(mpp, "hwhandler change");
741                 return;
742         }
743
744         if (mpp->retain_hwhandler != RETAIN_HWHANDLER_UNDEF &&
745             !!strstr(mpp->features, "retain_attached_hw_handler") !=
746             !!strstr(cmpp->features, "retain_attached_hw_handler") &&
747             get_linux_version_code() < KERNEL_VERSION(4, 3, 0)) {
748                 select_reload_action(mpp, "retain_hwhandler change");
749                 return;
750         }
751
752         cmpp_feat = strdup(cmpp->features);
753         mpp_feat = strdup(mpp->features);
754         if (cmpp_feat && mpp_feat) {
755                 remove_feature(&mpp_feat, "queue_if_no_path");
756                 remove_feature(&mpp_feat, "retain_attached_hw_handler");
757                 remove_feature(&cmpp_feat, "queue_if_no_path");
758                 remove_feature(&cmpp_feat, "retain_attached_hw_handler");
759                 if (strcmp(mpp_feat, cmpp_feat)) {
760                         select_reload_action(mpp, "features change");
761                         free(cmpp_feat);
762                         free(mpp_feat);
763                         return;
764                 }
765         }
766         free(cmpp_feat);
767         free(mpp_feat);
768
769         if (!cmpp->selector || strncmp(cmpp->selector, mpp->selector,
770                     strlen(mpp->selector))) {
771                 select_reload_action(mpp, "selector change");
772                 return;
773         }
774         if (cmpp->minio != mpp->minio) {
775                 select_reload_action(mpp, "minio change");
776                 return;
777         }
778         if (!cmpp->pg || VECTOR_SIZE(cmpp->pg) != VECTOR_SIZE(mpp->pg)) {
779                 select_reload_action(mpp, "path group number change");
780                 return;
781         }
782         if (pgcmp(mpp, cmpp)) {
783                 select_reload_action(mpp, "path group topology change");
784                 return;
785         }
786         if (cmpp->nextpg != mpp->bestpg) {
787                 mpp->action = ACT_SWITCHPG;
788                 condlog(3, "%s: set ACT_SWITCHPG (next path group change)",
789                         mpp->alias);
790                 return;
791         }
792         mpp->action = ACT_NOTHING;
793         condlog(3, "%s: set ACT_NOTHING (map unchanged)",
794                 mpp->alias);
795         return;
796 }
797
798 int reinstate_paths(struct multipath *mpp)
799 {
800         int i, j;
801         struct pathgroup * pgp;
802         struct path * pp;
803
804         if (!mpp->pg)
805                 return 0;
806
807         vector_foreach_slot (mpp->pg, pgp, i) {
808                 if (!pgp->paths)
809                         continue;
810
811                 vector_foreach_slot (pgp->paths, pp, j) {
812                         if (pp->state != PATH_UP &&
813                             (pgp->status == PGSTATE_DISABLED ||
814                              pgp->status == PGSTATE_ACTIVE))
815                                 continue;
816
817                         if (pp->dmstate == PSTATE_FAILED) {
818                                 if (dm_reinstate_path(mpp->alias, pp->dev_t))
819                                         condlog(0, "%s: error reinstating",
820                                                 pp->dev);
821                         }
822                 }
823         }
824         return 0;
825 }
826
827 static int
828 lock_multipath (struct multipath * mpp, int lock)
829 {
830         struct pathgroup * pgp;
831         struct path * pp;
832         int i, j;
833         int x, y;
834
835         if (!mpp || !mpp->pg)
836                 return 0;
837
838         vector_foreach_slot (mpp->pg, pgp, i) {
839                 if (!pgp->paths)
840                         continue;
841                 vector_foreach_slot(pgp->paths, pp, j) {
842                         if (lock && flock(pp->fd, LOCK_SH | LOCK_NB) &&
843                             errno == EWOULDBLOCK)
844                                 goto fail;
845                         else if (!lock)
846                                 flock(pp->fd, LOCK_UN);
847                 }
848         }
849         return 0;
850 fail:
851         vector_foreach_slot (mpp->pg, pgp, x) {
852                 if (x > i)
853                         return 1;
854                 if (!pgp->paths)
855                         continue;
856                 vector_foreach_slot(pgp->paths, pp, y) {
857                         if (x == i && y >= j)
858                                 return 1;
859                         flock(pp->fd, LOCK_UN);
860                 }
861         }
862         return 1;
863 }
864
865 int domap(struct multipath *mpp, char *params, int is_daemon)
866 {
867         int r = DOMAP_FAIL;
868         struct config *conf;
869
870         /*
871          * last chance to quit before touching the devmaps
872          */
873         if (mpp->action == ACT_DRY_RUN) {
874                 print_multipath_topology(mpp, libmp_verbosity);
875                 return DOMAP_DRY;
876         }
877
878         if (mpp->action == ACT_CREATE && dm_map_present(mpp->alias)) {
879                 char wwid[WWID_SIZE];
880
881                 if (dm_get_uuid(mpp->alias, wwid, sizeof(wwid)) == 0) {
882                         if (!strncmp(mpp->wwid, wwid, sizeof(wwid))) {
883                                 condlog(3, "%s: map already present",
884                                         mpp->alias);
885                                 mpp->action = ACT_RELOAD;
886                         } else {
887                                 condlog(0, "%s: map \"%s\" already present with WWID %s, skipping",
888                                         mpp->wwid, mpp->alias, wwid);
889                                 condlog(0, "please check alias settings in config and bindings file");
890                                 mpp->action = ACT_REJECT;
891                         }
892                 }
893         }
894
895         switch (mpp->action) {
896         case ACT_REJECT:
897         case ACT_NOTHING:
898         case ACT_IMPOSSIBLE:
899                 return DOMAP_EXIST;
900
901         case ACT_SWITCHPG:
902                 dm_switchgroup(mpp->alias, mpp->bestpg);
903                 /*
904                  * we may have avoided reinstating paths because there where in
905                  * active or disabled PG. Now that the topology has changed,
906                  * retry.
907                  */
908                 reinstate_paths(mpp);
909                 return DOMAP_EXIST;
910
911         case ACT_CREATE:
912                 if (lock_multipath(mpp, 1)) {
913                         condlog(3, "%s: failed to create map (in use)",
914                                 mpp->alias);
915                         return DOMAP_RETRY;
916                 }
917
918                 sysfs_set_max_sectors_kb(mpp, 0);
919                 if (is_daemon && mpp->ghost_delay > 0 && count_active_paths(mpp) &&
920                     pathcount(mpp, PATH_UP) == 0)
921                         mpp->ghost_delay_tick = mpp->ghost_delay;
922                 r = dm_addmap_create(mpp, params);
923
924                 lock_multipath(mpp, 0);
925                 break;
926
927         case ACT_RELOAD:
928                 sysfs_set_max_sectors_kb(mpp, 1);
929                 if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP))
930                         mpp->ghost_delay_tick = 0;
931                 r = dm_addmap_reload(mpp, params, 0);
932                 break;
933
934         case ACT_RESIZE:
935                 sysfs_set_max_sectors_kb(mpp, 1);
936                 if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP))
937                         mpp->ghost_delay_tick = 0;
938                 r = dm_addmap_reload(mpp, params, 1);
939                 break;
940
941         case ACT_RENAME:
942                 conf = get_multipath_config();
943                 pthread_cleanup_push(put_multipath_config, conf);
944                 r = dm_rename(mpp->alias_old, mpp->alias,
945                               conf->partition_delim, mpp->skip_kpartx);
946                 pthread_cleanup_pop(1);
947                 break;
948
949         case ACT_FORCERENAME:
950                 conf = get_multipath_config();
951                 pthread_cleanup_push(put_multipath_config, conf);
952                 r = dm_rename(mpp->alias_old, mpp->alias,
953                               conf->partition_delim, mpp->skip_kpartx);
954                 pthread_cleanup_pop(1);
955                 if (r) {
956                         sysfs_set_max_sectors_kb(mpp, 1);
957                         if (mpp->ghost_delay_tick > 0 &&
958                             pathcount(mpp, PATH_UP))
959                                 mpp->ghost_delay_tick = 0;
960                         r = dm_addmap_reload(mpp, params, 0);
961                 }
962                 break;
963
964         default:
965                 break;
966         }
967
968         if (r == DOMAP_OK) {
969                 /*
970                  * DM_DEVICE_CREATE, DM_DEVICE_RENAME, or DM_DEVICE_RELOAD
971                  * succeeded
972                  */
973                 mpp->force_udev_reload = 0;
974                 if (mpp->action == ACT_CREATE &&
975                     (remember_wwid(mpp->wwid) == 1 ||
976                      mpp->needs_paths_uevent))
977                         trigger_paths_udev_change(mpp, true);
978                 if (!is_daemon) {
979                         /* multipath client mode */
980                         dm_switchgroup(mpp->alias, mpp->bestpg);
981                 } else  {
982                         /* multipath daemon mode */
983                         mpp->stat_map_loads++;
984                         condlog(4, "%s: load table [0 %llu %s %s]", mpp->alias,
985                                 mpp->size, TGT_MPATH, params);
986                         /*
987                          * Required action is over, reset for the stateful daemon.
988                          * But don't do it for creation as we use in the caller the
989                          * mpp->action to figure out whether to start the watievent checker.
990                          */
991                         if (mpp->action != ACT_CREATE)
992                                 mpp->action = ACT_NOTHING;
993                         else {
994                                 conf = get_multipath_config();
995                                 mpp->wait_for_udev = 1;
996                                 mpp->uev_wait_tick = conf->uev_wait_timeout;
997                                 put_multipath_config(conf);
998                         }
999                 }
1000                 dm_setgeometry(mpp);
1001                 return DOMAP_OK;
1002         } else if (r == DOMAP_FAIL && mpp->action == ACT_CREATE &&
1003                    mpp->needs_paths_uevent)
1004                 trigger_paths_udev_change(mpp, false);
1005
1006         return DOMAP_FAIL;
1007 }
1008
1009 extern int
1010 check_daemon(void)
1011 {
1012         int fd;
1013         char *reply;
1014         int ret = 0;
1015         unsigned int timeout;
1016         struct config *conf;
1017
1018         fd = mpath_connect();
1019         if (fd == -1)
1020                 return 0;
1021
1022         if (send_packet(fd, "show daemon") != 0)
1023                 goto out;
1024         conf = get_multipath_config();
1025         timeout = conf->uxsock_timeout;
1026         put_multipath_config(conf);
1027         if (recv_packet(fd, &reply, timeout) != 0)
1028                 goto out;
1029
1030         if (reply && strstr(reply, "shutdown"))
1031                 goto out_free;
1032
1033         ret = 1;
1034
1035 out_free:
1036         free(reply);
1037 out:
1038         mpath_disconnect(fd);
1039         return ret;
1040 }
1041
1042 /*
1043  * The force_reload parameter determines how coalesce_paths treats existing maps.
1044  * FORCE_RELOAD_NONE: existing maps aren't touched at all
1045  * FORCE_RELOAD_YES: all maps are rebuilt from scratch and (re)loaded in DM
1046  * FORCE_RELOAD_WEAK: existing maps are compared to the current conf and only
1047  * reloaded in DM if there's a difference. This is normally sufficient.
1048  */
1049 int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid,
1050                     int force_reload, enum mpath_cmds cmd)
1051 {
1052         int ret = CP_FAIL;
1053         int k, i, r;
1054         int is_daemon = (cmd == CMD_NONE) ? 1 : 0;
1055         char *params __attribute__((cleanup(cleanup_charp))) = NULL;
1056         struct multipath * mpp;
1057         struct path * pp1 = NULL;
1058         struct path * pp2;
1059         vector curmp = vecs->mpvec;
1060         vector pathvec = vecs->pathvec;
1061         vector newmp;
1062         struct config *conf = NULL;
1063         int allow_queueing;
1064         struct bitfield *size_mismatch_seen;
1065
1066         /* ignore refwwid if it's empty */
1067         if (refwwid && !strlen(refwwid))
1068                 refwwid = NULL;
1069
1070         if (force_reload != FORCE_RELOAD_NONE) {
1071                 vector_foreach_slot (pathvec, pp1, k) {
1072                         pp1->mpp = NULL;
1073                 }
1074         }
1075
1076         if (VECTOR_SIZE(pathvec) == 0)
1077                 return CP_OK;
1078         size_mismatch_seen = alloc_bitfield(VECTOR_SIZE(pathvec));
1079         if (size_mismatch_seen == NULL)
1080                 return CP_FAIL;
1081
1082         if (mpvec)
1083                 newmp = mpvec;
1084         else
1085                 newmp = vector_alloc();
1086         if (!newmp) {
1087                 condlog(0, "can not allocate newmp");
1088                 goto out;
1089         }
1090
1091         vector_foreach_slot (pathvec, pp1, k) {
1092                 int invalid;
1093
1094                 if (should_exit()) {
1095                         ret = CP_FAIL;
1096                         goto out;
1097                 }
1098
1099                 /* skip this path for some reason */
1100
1101                 /* 1. if path has no unique id or wwid blacklisted */
1102                 if (strlen(pp1->wwid) == 0) {
1103                         orphan_path(pp1, "no WWID");
1104                         continue;
1105                 }
1106
1107                 conf = get_multipath_config();
1108                 pthread_cleanup_push(put_multipath_config, conf);
1109                 invalid = (filter_path(conf, pp1) > 0);
1110                 pthread_cleanup_pop(1);
1111                 if (invalid) {
1112                         orphan_path(pp1, "blacklisted");
1113                         continue;
1114                 }
1115
1116                 /* 2. if path already coalesced, or seen and discarded */
1117                 if (pp1->mpp || is_bit_set_in_bitfield(k, size_mismatch_seen))
1118                         continue;
1119
1120                 /* 3. if path has disappeared */
1121                 if (pp1->state == PATH_REMOVED) {
1122                         orphan_path(pp1, "path removed");
1123                         continue;
1124                 }
1125
1126                 /* 4. path is out of scope */
1127                 if (refwwid && strncmp(pp1->wwid, refwwid, WWID_SIZE - 1))
1128                         continue;
1129
1130                 /* If find_multipaths was selected check if the path is valid */
1131                 if (!refwwid && !should_multipath(pp1, pathvec, curmp)) {
1132                         orphan_path(pp1, "only one path");
1133                         continue;
1134                 }
1135
1136                 /*
1137                  * at this point, we know we really got a new mp
1138                  */
1139                 mpp = add_map_with_path(vecs, pp1, 0);
1140                 if (!mpp) {
1141                         orphan_path(pp1, "failed to create multipath device");
1142                         continue;
1143                 }
1144
1145                 if (!mpp->paths) {
1146                         condlog(0, "%s: skip coalesce (no paths)", mpp->alias);
1147                         remove_map(mpp, vecs->pathvec, NULL);
1148                         continue;
1149                 }
1150
1151                 for (i = k + 1; i < VECTOR_SIZE(pathvec); i++) {
1152                         pp2 = VECTOR_SLOT(pathvec, i);
1153
1154                         if (strcmp(pp1->wwid, pp2->wwid))
1155                                 continue;
1156
1157                         if (!mpp->size && pp2->size)
1158                                 mpp->size = pp2->size;
1159
1160                         if (mpp->size && pp2->size &&
1161                             pp2->size != mpp->size) {
1162                                 /*
1163                                  * ouch, avoid feeding that to the DM
1164                                  */
1165                                 condlog(0, "%s: size %llu, expected %llu. "
1166                                         "Discard", pp2->dev, pp2->size,
1167                                         mpp->size);
1168                                 mpp->action = ACT_REJECT;
1169                                 set_bit_in_bitfield(i, size_mismatch_seen);
1170                         }
1171                 }
1172                 verify_paths(mpp);
1173
1174                 if (setup_map(mpp, &params, vecs)) {
1175                         remove_map(mpp, vecs->pathvec, NULL);
1176                         continue;
1177                 }
1178
1179                 if (cmd == CMD_DRY_RUN)
1180                         mpp->action = ACT_DRY_RUN;
1181                 if (mpp->action == ACT_UNDEF)
1182                         select_action(mpp, curmp,
1183                                       force_reload == FORCE_RELOAD_YES ? 1 : 0);
1184
1185                 r = domap(mpp, params, is_daemon);
1186                 free(params);
1187                 params = NULL;
1188
1189                 if (r == DOMAP_FAIL || r == DOMAP_RETRY) {
1190                         condlog(3, "%s: domap (%u) failure "
1191                                    "for create/reload map",
1192                                 mpp->alias, r);
1193                         if (r == DOMAP_FAIL || is_daemon) {
1194                                 condlog(2, "%s: %s map",
1195                                         mpp->alias, (mpp->action == ACT_CREATE)?
1196                                         "ignoring" : "removing");
1197                                 remove_map(mpp, vecs->pathvec, NULL);
1198                                 continue;
1199                         } else /* if (r == DOMAP_RETRY && !is_daemon) */ {
1200                                 ret = CP_RETRY;
1201                                 goto out;
1202                         }
1203                 }
1204                 if (r == DOMAP_DRY) {
1205                         if (!vector_alloc_slot(newmp)) {
1206                                 remove_map(mpp, vecs->pathvec, NULL);
1207                                 goto out;
1208                         }
1209                         vector_set_slot(newmp, mpp);
1210                         continue;
1211                 }
1212
1213                 conf = get_multipath_config();
1214                 allow_queueing = conf->allow_queueing;
1215                 put_multipath_config(conf);
1216                 if (!is_daemon && !allow_queueing && !check_daemon()) {
1217                         if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF &&
1218                             mpp->no_path_retry != NO_PATH_RETRY_FAIL)
1219                                 condlog(3, "%s: multipathd not running, unset "
1220                                         "queue_if_no_path feature", mpp->alias);
1221                         if (!dm_queue_if_no_path(mpp->alias, 0))
1222                                 remove_feature(&mpp->features,
1223                                                "queue_if_no_path");
1224                 }
1225
1226                 if (!is_daemon && mpp->action != ACT_NOTHING)
1227                         print_multipath_topology(mpp, libmp_verbosity);
1228
1229                 if (mpp->action != ACT_REJECT) {
1230                         if (!vector_alloc_slot(newmp)) {
1231                                 remove_map(mpp, vecs->pathvec, NULL);
1232                                 goto out;
1233                         }
1234                         vector_set_slot(newmp, mpp);
1235                 }
1236                 else
1237                         remove_map(mpp, vecs->pathvec, NULL);
1238         }
1239         ret = CP_OK;
1240 out:
1241         free(size_mismatch_seen);
1242         if (!mpvec)
1243                 free_multipathvec(newmp, KEEP_PATHS);
1244         return ret;
1245 }
1246
1247 struct udev_device *get_udev_device(const char *dev, enum devtypes dev_type)
1248 {
1249         struct udev_device *ud = NULL;
1250         const char *base;
1251
1252         if (dev == NULL || *dev == '\0')
1253                 return NULL;
1254
1255         switch (dev_type) {
1256         case DEV_DEVNODE:
1257         case DEV_DEVMAP:
1258                 /* This should be GNU basename, compiler will warn if not */
1259                 base = basename(dev);
1260                 if (*base == '\0')
1261                         break;
1262                 ud = udev_device_new_from_subsystem_sysname(udev, "block",
1263                                                             base);
1264                 break;
1265         case DEV_DEVT:
1266                 ud = udev_device_new_from_devnum(udev, 'b', parse_devt(dev));
1267                 break;
1268         case DEV_UEVENT:
1269                 ud = udev_device_new_from_environment(udev);
1270                 break;
1271         default:
1272                 condlog(0, "Internal error: get_udev_device called with invalid type %d\n",
1273                         dev_type);
1274                 break;
1275         }
1276         if (ud == NULL)
1277                 condlog(2, "get_udev_device: failed to look up %s with type %d",
1278                         dev, dev_type);
1279         return ud;
1280 }
1281
1282 static int _get_refwwid(enum mpath_cmds cmd, const char *dev,
1283                         enum devtypes dev_type,
1284                         vector pathvec, struct config *conf, char **wwid)
1285 {
1286         int ret = 1;
1287         struct path * pp;
1288         char buff[FILE_NAME_SIZE];
1289         const char *refwwid = NULL;
1290         char tmpwwid[WWID_SIZE];
1291         struct udev_device *udevice;
1292         int flags = DI_SYSFS | DI_WWID;
1293
1294         if (!wwid)
1295                 return PATHINFO_FAILED;
1296         *wwid = NULL;
1297
1298         if (dev_type == DEV_NONE)
1299                 return PATHINFO_FAILED;
1300
1301         if (cmd != CMD_REMOVE_WWID)
1302                 flags |= DI_BLACKLIST;
1303
1304         switch (dev_type) {
1305         case DEV_DEVNODE:
1306                 if (basenamecpy(dev, buff, FILE_NAME_SIZE) == 0) {
1307                         condlog(1, "basename failed for '%s' (%s)",
1308                                 dev, buff);
1309                         return PATHINFO_FAILED;
1310                 }
1311
1312                 /* dev is used in common code below */
1313                 dev = buff;
1314                 pp = find_path_by_dev(pathvec, dev);
1315                 goto common;
1316
1317         case DEV_DEVT:
1318                 pp = find_path_by_devt(pathvec, dev);
1319                 goto common;
1320
1321         case DEV_UEVENT:
1322                 pp = NULL;
1323                 /* For condlog below, dev is unused in get_udev_device() */
1324                 dev = "environment";
1325         common:
1326                 if (!pp) {
1327                         udevice = get_udev_device(dev, dev_type);
1328
1329                         if (!udevice) {
1330                                 condlog(0, "%s: cannot find block device", dev);
1331                                 return PATHINFO_FAILED;
1332                         }
1333
1334                         ret = store_pathinfo(pathvec, conf, udevice,
1335                                              flags, &pp);
1336                         udev_device_unref(udevice);
1337                         if (!pp) {
1338                                 if (ret == PATHINFO_FAILED)
1339                                         condlog(0, "%s: can't store path info",
1340                                                 dev);
1341                                 return ret;
1342                         }
1343                 }
1344                 if (flags & DI_BLACKLIST &&
1345                     filter_property(conf, pp->udev, 3, pp->uid_attribute) > 0)
1346                         return PATHINFO_SKIPPED;
1347                 refwwid = pp->wwid;
1348                 break;
1349
1350         case DEV_DEVMAP:
1351                 if (((dm_get_uuid(dev, tmpwwid, WWID_SIZE)) == 0)
1352                     && (strlen(tmpwwid)))
1353                         refwwid = tmpwwid;
1354
1355                 /* or may be a binding */
1356                 else if (get_user_friendly_wwid(dev, tmpwwid,
1357                                                 conf->bindings_file) == 0)
1358                         refwwid = tmpwwid;
1359
1360                 /* or may be an alias */
1361                 else {
1362                         refwwid = get_mpe_wwid(conf->mptable, dev);
1363
1364                         /* or directly a wwid */
1365                         if (!refwwid)
1366                                 refwwid = dev;
1367                 }
1368
1369                 if (flags & DI_BLACKLIST && refwwid && strlen(refwwid) &&
1370                     filter_wwid(conf->blist_wwid, conf->elist_wwid, refwwid,
1371                                 NULL) > 0)
1372                         return PATHINFO_SKIPPED;
1373                 break;
1374         default:
1375                 break;
1376         }
1377
1378         if (refwwid && strlen(refwwid)) {
1379                 *wwid = strdup(refwwid);
1380                 return PATHINFO_OK;
1381         }
1382
1383         return PATHINFO_FAILED;
1384 }
1385
1386 /*
1387  * Returns: PATHINFO_OK, PATHINFO_FAILED, or PATHINFO_SKIPPED (see pathinfo())
1388  */
1389 int get_refwwid(enum mpath_cmds cmd, const char *dev, enum devtypes dev_type,
1390                 vector pathvec, char **wwid)
1391
1392 {
1393         int ret;
1394         struct config *conf = get_multipath_config();
1395
1396         pthread_cleanup_push(put_multipath_config, conf);
1397         ret = _get_refwwid(cmd, dev, dev_type, pathvec, conf, wwid);
1398         pthread_cleanup_pop(1);
1399         return ret;
1400 }