libmultipath: uev_update_path: always warn if WWID changed
[multipath-tools/.git] / multipathd / main.c
1 /*
2  * Copyright (c) 2004, 2005 Christophe Varoqui
3  * Copyright (c) 2005 Kiyoshi Ueda, NEC
4  * Copyright (c) 2005 Benjamin Marzinski, Redhat
5  * Copyright (c) 2005 Edward Goggin, EMC
6  */
7 #include <unistd.h>
8 #include <sys/stat.h>
9 #include <libdevmapper.h>
10 #include <sys/wait.h>
11 #include <sys/mman.h>
12 #include <sys/types.h>
13 #include <fcntl.h>
14 #include <errno.h>
15 #include <sys/time.h>
16 #include <sys/resource.h>
17 #include <limits.h>
18 #include <linux/oom.h>
19 #include <libudev.h>
20 #include <urcu.h>
21 #ifdef USE_SYSTEMD
22 #include <systemd/sd-daemon.h>
23 #endif
24 #include <semaphore.h>
25 #include <time.h>
26 #include <stdbool.h>
27
28 /*
29  * libmultipath
30  */
31 #include "time-util.h"
32
33 /*
34  * libcheckers
35  */
36 #include "checkers.h"
37
38 #ifdef USE_SYSTEMD
39 static int use_watchdog;
40 #endif
41
42 /*
43  * libmultipath
44  */
45 #include "parser.h"
46 #include "vector.h"
47 #include "memory.h"
48 #include "config.h"
49 #include "util.h"
50 #include "hwtable.h"
51 #include "defaults.h"
52 #include "structs.h"
53 #include "blacklist.h"
54 #include "structs_vec.h"
55 #include "dmparser.h"
56 #include "devmapper.h"
57 #include "sysfs.h"
58 #include "dict.h"
59 #include "discovery.h"
60 #include "debug.h"
61 #include "propsel.h"
62 #include "uevent.h"
63 #include "switchgroup.h"
64 #include "print.h"
65 #include "configure.h"
66 #include "prio.h"
67 #include "wwids.h"
68 #include "pgpolicies.h"
69 #include "uevent.h"
70 #include "log.h"
71
72 #include "mpath_cmd.h"
73 #include "mpath_persist.h"
74
75 #include "prioritizers/alua_rtpg.h"
76
77 #include "main.h"
78 #include "pidfile.h"
79 #include "uxlsnr.h"
80 #include "uxclnt.h"
81 #include "cli.h"
82 #include "cli_handlers.h"
83 #include "lock.h"
84 #include "waiter.h"
85 #include "io_err_stat.h"
86 #include "wwids.h"
87 #include "foreign.h"
88 #include "../third-party/valgrind/drd.h"
89
90 #define FILE_NAME_SIZE 256
91 #define CMDSIZE 160
92
93 #define LOG_MSG(a, b) \
94 do { \
95         if (pp->offline) \
96                 condlog(a, "%s: %s - path offline", pp->mpp->alias, pp->dev); \
97         else if (strlen(b)) \
98                 condlog(a, "%s: %s - %s", pp->mpp->alias, pp->dev, b); \
99 } while(0)
100
101 struct mpath_event_param
102 {
103         char * devname;
104         struct multipath *mpp;
105 };
106
107 int logsink;
108 int uxsock_timeout;
109 int verbosity;
110 int bindings_read_only;
111 int ignore_new_devs;
112 enum daemon_status running_state = DAEMON_INIT;
113 pid_t daemon_pid;
114 pthread_mutex_t config_lock = PTHREAD_MUTEX_INITIALIZER;
115 pthread_cond_t config_cond;
116
117 /*
118  * global copy of vecs for use in sig handlers
119  */
120 struct vectors * gvecs;
121
122 struct udev * udev;
123
124 struct config *multipath_conf;
125
126 /* Local variables */
127 static volatile sig_atomic_t exit_sig;
128 static volatile sig_atomic_t reconfig_sig;
129 static volatile sig_atomic_t log_reset_sig;
130
131 const char *
132 daemon_status(void)
133 {
134         switch (running_state) {
135         case DAEMON_INIT:
136                 return "init";
137         case DAEMON_START:
138                 return "startup";
139         case DAEMON_CONFIGURE:
140                 return "configure";
141         case DAEMON_IDLE:
142                 return "idle";
143         case DAEMON_RUNNING:
144                 return "running";
145         case DAEMON_SHUTDOWN:
146                 return "shutdown";
147         }
148         return NULL;
149 }
150
151 /*
152  * I love you too, systemd ...
153  */
154 const char *
155 sd_notify_status(void)
156 {
157         switch (running_state) {
158         case DAEMON_INIT:
159                 return "STATUS=init";
160         case DAEMON_START:
161                 return "STATUS=startup";
162         case DAEMON_CONFIGURE:
163                 return "STATUS=configure";
164         case DAEMON_IDLE:
165         case DAEMON_RUNNING:
166                 return "STATUS=up";
167         case DAEMON_SHUTDOWN:
168                 return "STATUS=shutdown";
169         }
170         return NULL;
171 }
172
173 #ifdef USE_SYSTEMD
174 static void do_sd_notify(enum daemon_status old_state)
175 {
176         /*
177          * Checkerloop switches back and forth between idle and running state.
178          * No need to tell systemd each time.
179          * These notifications cause a lot of overhead on dbus.
180          */
181         if ((running_state == DAEMON_IDLE || running_state == DAEMON_RUNNING) &&
182             (old_state == DAEMON_IDLE || old_state == DAEMON_RUNNING))
183                 return;
184         sd_notify(0, sd_notify_status());
185 }
186 #endif
187
188 static void config_cleanup(void *arg)
189 {
190         pthread_mutex_unlock(&config_lock);
191 }
192
193 void post_config_state(enum daemon_status state)
194 {
195         pthread_mutex_lock(&config_lock);
196         if (state != running_state) {
197                 enum daemon_status old_state = running_state;
198
199                 running_state = state;
200                 pthread_cond_broadcast(&config_cond);
201 #ifdef USE_SYSTEMD
202                 do_sd_notify(old_state);
203 #endif
204         }
205         pthread_mutex_unlock(&config_lock);
206 }
207
208 int set_config_state(enum daemon_status state)
209 {
210         int rc = 0;
211
212         pthread_cleanup_push(config_cleanup, NULL);
213         pthread_mutex_lock(&config_lock);
214         if (running_state != state) {
215                 enum daemon_status old_state = running_state;
216
217                 if (running_state != DAEMON_IDLE) {
218                         struct timespec ts;
219
220                         clock_gettime(CLOCK_MONOTONIC, &ts);
221                         ts.tv_sec += 1;
222                         rc = pthread_cond_timedwait(&config_cond,
223                                                     &config_lock, &ts);
224                 }
225                 if (!rc) {
226                         running_state = state;
227                         pthread_cond_broadcast(&config_cond);
228 #ifdef USE_SYSTEMD
229                         do_sd_notify(old_state);
230 #endif
231                 }
232         }
233         pthread_cleanup_pop(1);
234         return rc;
235 }
236
237 struct config *get_multipath_config(void)
238 {
239         rcu_read_lock();
240         return rcu_dereference(multipath_conf);
241 }
242
243 void put_multipath_config(struct config *conf)
244 {
245         rcu_read_unlock();
246 }
247
248 static int
249 need_switch_pathgroup (struct multipath * mpp, int refresh)
250 {
251         struct pathgroup * pgp;
252         struct path * pp;
253         unsigned int i, j;
254         struct config *conf;
255         int bestpg;
256
257         if (!mpp)
258                 return 0;
259
260         /*
261          * Refresh path priority values
262          */
263         if (refresh) {
264                 vector_foreach_slot (mpp->pg, pgp, i) {
265                         vector_foreach_slot (pgp->paths, pp, j) {
266                                 conf = get_multipath_config();
267                                 pathinfo(pp, conf, DI_PRIO);
268                                 put_multipath_config(conf);
269                         }
270                 }
271         }
272
273         if (!mpp->pg || VECTOR_SIZE(mpp->paths) == 0)
274                 return 0;
275
276         bestpg = select_path_group(mpp);
277         if (mpp->pgfailback == -FAILBACK_MANUAL)
278                 return 0;
279
280         mpp->bestpg = bestpg;
281         if (mpp->bestpg != mpp->nextpg)
282                 return 1;
283
284         return 0;
285 }
286
287 static void
288 switch_pathgroup (struct multipath * mpp)
289 {
290         mpp->stat_switchgroup++;
291         dm_switchgroup(mpp->alias, mpp->bestpg);
292         condlog(2, "%s: switch to path group #%i",
293                  mpp->alias, mpp->bestpg);
294 }
295
296 static int
297 coalesce_maps(struct vectors *vecs, vector nmpv)
298 {
299         struct multipath * ompp;
300         vector ompv = vecs->mpvec;
301         unsigned int i, reassign_maps;
302         struct config *conf;
303
304         conf = get_multipath_config();
305         reassign_maps = conf->reassign_maps;
306         put_multipath_config(conf);
307         vector_foreach_slot (ompv, ompp, i) {
308                 condlog(3, "%s: coalesce map", ompp->alias);
309                 if (!find_mp_by_wwid(nmpv, ompp->wwid)) {
310                         /*
311                          * remove all current maps not allowed by the
312                          * current configuration
313                          */
314                         if (dm_flush_map(ompp->alias)) {
315                                 condlog(0, "%s: unable to flush devmap",
316                                         ompp->alias);
317                                 /*
318                                  * may be just because the device is open
319                                  */
320                                 if (setup_multipath(vecs, ompp) != 0) {
321                                         i--;
322                                         continue;
323                                 }
324                                 if (!vector_alloc_slot(nmpv))
325                                         return 1;
326
327                                 vector_set_slot(nmpv, ompp);
328
329                                 vector_del_slot(ompv, i);
330                                 i--;
331                         }
332                         else {
333                                 dm_lib_release();
334                                 condlog(2, "%s devmap removed", ompp->alias);
335                         }
336                 } else if (reassign_maps) {
337                         condlog(3, "%s: Reassign existing device-mapper"
338                                 " devices", ompp->alias);
339                         dm_reassign(ompp->alias);
340                 }
341         }
342         return 0;
343 }
344
345 static void
346 sync_maps_state(vector mpvec)
347 {
348         unsigned int i;
349         struct multipath *mpp;
350
351         vector_foreach_slot (mpvec, mpp, i)
352                 sync_map_state(mpp);
353 }
354
355 static int
356 flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths)
357 {
358         int r;
359
360         if (nopaths)
361                 r = dm_flush_map_nopaths(mpp->alias, mpp->deferred_remove);
362         else
363                 r = dm_flush_map(mpp->alias);
364         /*
365          * clear references to this map before flushing so we can ignore
366          * the spurious uevent we may generate with the dm_flush_map call below
367          */
368         if (r) {
369                 /*
370                  * May not really be an error -- if the map was already flushed
371                  * from the device mapper by dmsetup(8) for instance.
372                  */
373                 if (r == 1)
374                         condlog(0, "%s: can't flush", mpp->alias);
375                 else {
376                         condlog(2, "%s: devmap deferred remove", mpp->alias);
377                         mpp->deferred_remove = DEFERRED_REMOVE_IN_PROGRESS;
378                 }
379                 return r;
380         }
381         else {
382                 dm_lib_release();
383                 condlog(2, "%s: map flushed", mpp->alias);
384         }
385
386         orphan_paths(vecs->pathvec, mpp);
387         remove_map_and_stop_waiter(mpp, vecs, 1);
388
389         return 0;
390 }
391
392 static int
393 uev_add_map (struct uevent * uev, struct vectors * vecs)
394 {
395         char *alias;
396         int major = -1, minor = -1, rc;
397
398         condlog(3, "%s: add map (uevent)", uev->kernel);
399         alias = uevent_get_dm_name(uev);
400         if (!alias) {
401                 condlog(3, "%s: No DM_NAME in uevent", uev->kernel);
402                 major = uevent_get_major(uev);
403                 minor = uevent_get_minor(uev);
404                 alias = dm_mapname(major, minor);
405                 if (!alias) {
406                         condlog(2, "%s: mapname not found for %d:%d",
407                                 uev->kernel, major, minor);
408                         return 1;
409                 }
410         }
411         pthread_cleanup_push(cleanup_lock, &vecs->lock);
412         lock(&vecs->lock);
413         pthread_testcancel();
414         rc = ev_add_map(uev->kernel, alias, vecs);
415         lock_cleanup_pop(vecs->lock);
416         FREE(alias);
417         return rc;
418 }
419
420 /*
421  * ev_add_map expects that the multipath device already exists in kernel
422  * before it is called. It just adds a device to multipathd or updates an
423  * existing device.
424  */
425 int
426 ev_add_map (char * dev, const char * alias, struct vectors * vecs)
427 {
428         struct multipath * mpp;
429         int delayed_reconfig, reassign_maps;
430         struct config *conf;
431
432         if (!dm_is_mpath(alias)) {
433                 condlog(4, "%s: not a multipath map", alias);
434                 return 0;
435         }
436
437         mpp = find_mp_by_alias(vecs->mpvec, alias);
438
439         if (mpp) {
440                 if (mpp->wait_for_udev > 1) {
441                         condlog(2, "%s: performing delayed actions",
442                                 mpp->alias);
443                         if (update_map(mpp, vecs))
444                                 /* setup multipathd removed the map */
445                                 return 1;
446                 }
447                 conf = get_multipath_config();
448                 delayed_reconfig = conf->delayed_reconfig;
449                 reassign_maps = conf->reassign_maps;
450                 put_multipath_config(conf);
451                 if (mpp->wait_for_udev) {
452                         mpp->wait_for_udev = 0;
453                         if (delayed_reconfig &&
454                             !need_to_delay_reconfig(vecs)) {
455                                 condlog(2, "reconfigure (delayed)");
456                                 set_config_state(DAEMON_CONFIGURE);
457                                 return 0;
458                         }
459                 }
460                 /*
461                  * Not really an error -- we generate our own uevent
462                  * if we create a multipath mapped device as a result
463                  * of uev_add_path
464                  */
465                 if (reassign_maps) {
466                         condlog(3, "%s: Reassign existing device-mapper devices",
467                                 alias);
468                         dm_reassign(alias);
469                 }
470                 return 0;
471         }
472         condlog(2, "%s: adding map", alias);
473
474         /*
475          * now we can register the map
476          */
477         if ((mpp = add_map_without_path(vecs, alias))) {
478                 sync_map_state(mpp);
479                 condlog(2, "%s: devmap %s registered", alias, dev);
480                 return 0;
481         } else {
482                 condlog(2, "%s: ev_add_map failed", dev);
483                 return 1;
484         }
485 }
486
487 static int
488 uev_remove_map (struct uevent * uev, struct vectors * vecs)
489 {
490         char *alias;
491         int minor;
492         struct multipath *mpp;
493
494         condlog(2, "%s: remove map (uevent)", uev->kernel);
495         alias = uevent_get_dm_name(uev);
496         if (!alias) {
497                 condlog(3, "%s: No DM_NAME in uevent, ignoring", uev->kernel);
498                 return 0;
499         }
500         minor = uevent_get_minor(uev);
501
502         pthread_cleanup_push(cleanup_lock, &vecs->lock);
503         lock(&vecs->lock);
504         pthread_testcancel();
505         mpp = find_mp_by_minor(vecs->mpvec, minor);
506
507         if (!mpp) {
508                 condlog(2, "%s: devmap not registered, can't remove",
509                         uev->kernel);
510                 goto out;
511         }
512         if (strcmp(mpp->alias, alias)) {
513                 condlog(2, "%s: minor number mismatch (map %d, event %d)",
514                         mpp->alias, mpp->dmi->minor, minor);
515                 goto out;
516         }
517
518         orphan_paths(vecs->pathvec, mpp);
519         remove_map_and_stop_waiter(mpp, vecs, 1);
520 out:
521         lock_cleanup_pop(vecs->lock);
522         FREE(alias);
523         return 0;
524 }
525
526 /* Called from CLI handler */
527 int
528 ev_remove_map (char * devname, char * alias, int minor, struct vectors * vecs)
529 {
530         struct multipath * mpp;
531
532         mpp = find_mp_by_minor(vecs->mpvec, minor);
533
534         if (!mpp) {
535                 condlog(2, "%s: devmap not registered, can't remove",
536                         devname);
537                 return 1;
538         }
539         if (strcmp(mpp->alias, alias)) {
540                 condlog(2, "%s: minor number mismatch (map %d, event %d)",
541                         mpp->alias, mpp->dmi->minor, minor);
542                 return 1;
543         }
544         return flush_map(mpp, vecs, 0);
545 }
546
547 static int
548 uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map)
549 {
550         struct path *pp;
551         int ret = 0, i;
552         struct config *conf;
553
554         condlog(2, "%s: add path (uevent)", uev->kernel);
555         if (strstr(uev->kernel, "..") != NULL) {
556                 /*
557                  * Don't allow relative device names in the pathvec
558                  */
559                 condlog(0, "%s: path name is invalid", uev->kernel);
560                 return 1;
561         }
562
563         pthread_cleanup_push(cleanup_lock, &vecs->lock);
564         lock(&vecs->lock);
565         pthread_testcancel();
566         pp = find_path_by_dev(vecs->pathvec, uev->kernel);
567         if (pp) {
568                 int r;
569
570                 condlog(2, "%s: spurious uevent, path already in pathvec",
571                         uev->kernel);
572                 if (!pp->mpp && !strlen(pp->wwid)) {
573                         condlog(3, "%s: reinitialize path", uev->kernel);
574                         udev_device_unref(pp->udev);
575                         pp->udev = udev_device_ref(uev->udev);
576                         conf = get_multipath_config();
577                         r = pathinfo(pp, conf,
578                                      DI_ALL | DI_BLACKLIST);
579                         put_multipath_config(conf);
580                         if (r == PATHINFO_OK)
581                                 ret = ev_add_path(pp, vecs, need_do_map);
582                         else if (r == PATHINFO_SKIPPED) {
583                                 condlog(3, "%s: remove blacklisted path",
584                                         uev->kernel);
585                                 i = find_slot(vecs->pathvec, (void *)pp);
586                                 if (i != -1)
587                                         vector_del_slot(vecs->pathvec, i);
588                                 free_path(pp);
589                         } else {
590                                 condlog(0, "%s: failed to reinitialize path",
591                                         uev->kernel);
592                                 ret = 1;
593                         }
594                 }
595         }
596         lock_cleanup_pop(vecs->lock);
597         if (pp)
598                 return ret;
599
600         /*
601          * get path vital state
602          */
603         conf = get_multipath_config();
604         ret = alloc_path_with_pathinfo(conf, uev->udev,
605                                        uev->wwid, DI_ALL, &pp);
606         put_multipath_config(conf);
607         if (!pp) {
608                 if (ret == PATHINFO_SKIPPED)
609                         return 0;
610                 condlog(3, "%s: failed to get path info", uev->kernel);
611                 return 1;
612         }
613         pthread_cleanup_push(cleanup_lock, &vecs->lock);
614         lock(&vecs->lock);
615         pthread_testcancel();
616         ret = store_path(vecs->pathvec, pp);
617         if (!ret) {
618                 conf = get_multipath_config();
619                 pp->checkint = conf->checkint;
620                 put_multipath_config(conf);
621                 ret = ev_add_path(pp, vecs, need_do_map);
622         } else {
623                 condlog(0, "%s: failed to store path info, "
624                         "dropping event",
625                         uev->kernel);
626                 free_path(pp);
627                 ret = 1;
628         }
629         lock_cleanup_pop(vecs->lock);
630         return ret;
631 }
632
633 /*
634  * returns:
635  * 0: added
636  * 1: error
637  */
638 int
639 ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map)
640 {
641         struct multipath * mpp;
642         char params[PARAMS_SIZE] = {0};
643         int retries = 3;
644         int start_waiter = 0;
645         int ret;
646
647         /*
648          * need path UID to go any further
649          */
650         if (strlen(pp->wwid) == 0) {
651                 condlog(0, "%s: failed to get path uid", pp->dev);
652                 goto fail; /* leave path added to pathvec */
653         }
654         mpp = find_mp_by_wwid(vecs->mpvec, pp->wwid);
655         if (mpp && mpp->wait_for_udev &&
656             (pathcount(mpp, PATH_UP) > 0 ||
657              (pathcount(mpp, PATH_GHOST) > 0 && pp->tpgs != TPGS_IMPLICIT &&
658               mpp->ghost_delay_tick <= 0))) {
659                 /* if wait_for_udev is set and valid paths exist */
660                 condlog(2, "%s: delaying path addition until %s is fully initialized", pp->dev, mpp->alias);
661                 mpp->wait_for_udev = 2;
662                 orphan_path(pp, "waiting for create to complete");
663                 return 0;
664         }
665
666         pp->mpp = mpp;
667 rescan:
668         if (mpp) {
669                 if (pp->size && mpp->size != pp->size) {
670                         condlog(0, "%s: failed to add new path %s, "
671                                 "device size mismatch",
672                                 mpp->alias, pp->dev);
673                         int i = find_slot(vecs->pathvec, (void *)pp);
674                         if (i != -1)
675                                 vector_del_slot(vecs->pathvec, i);
676                         free_path(pp);
677                         return 1;
678                 }
679
680                 condlog(4,"%s: adopting all paths for path %s",
681                         mpp->alias, pp->dev);
682                 if (adopt_paths(vecs->pathvec, mpp))
683                         goto fail; /* leave path added to pathvec */
684
685                 verify_paths(mpp, vecs);
686                 mpp->action = ACT_RELOAD;
687                 extract_hwe_from_path(mpp);
688         } else {
689                 if (!should_multipath(pp, vecs->pathvec)) {
690                         orphan_path(pp, "only one path");
691                         return 0;
692                 }
693                 condlog(4,"%s: creating new map", pp->dev);
694                 if ((mpp = add_map_with_path(vecs, pp, 1))) {
695                         mpp->action = ACT_CREATE;
696                         /*
697                          * We don't depend on ACT_CREATE, as domap will
698                          * set it to ACT_NOTHING when complete.
699                          */
700                         start_waiter = 1;
701                 }
702                 if (!start_waiter)
703                         goto fail; /* leave path added to pathvec */
704         }
705
706         /* persistent reservation check*/
707         mpath_pr_event_handle(pp);
708
709         if (!need_do_map)
710                 return 0;
711
712         if (!dm_map_present(mpp->alias)) {
713                 mpp->action = ACT_CREATE;
714                 start_waiter = 1;
715         }
716         /*
717          * push the map to the device-mapper
718          */
719         if (setup_map(mpp, params, PARAMS_SIZE, vecs)) {
720                 condlog(0, "%s: failed to setup map for addition of new "
721                         "path %s", mpp->alias, pp->dev);
722                 goto fail_map;
723         }
724         /*
725          * reload the map for the multipath mapped device
726          */
727 retry:
728         ret = domap(mpp, params, 1);
729         if (ret <= 0) {
730                 if (ret < 0 && retries-- > 0) {
731                         condlog(0, "%s: retry domap for addition of new "
732                                 "path %s", mpp->alias, pp->dev);
733                         sleep(1);
734                         goto retry;
735                 }
736                 condlog(0, "%s: failed in domap for addition of new "
737                         "path %s", mpp->alias, pp->dev);
738                 /*
739                  * deal with asynchronous uevents :((
740                  */
741                 if (mpp->action == ACT_RELOAD && retries-- > 0) {
742                         condlog(0, "%s: ev_add_path sleep", mpp->alias);
743                         sleep(1);
744                         update_mpp_paths(mpp, vecs->pathvec);
745                         goto rescan;
746                 }
747                 else if (mpp->action == ACT_RELOAD)
748                         condlog(0, "%s: giving up reload", mpp->alias);
749                 else
750                         goto fail_map;
751         }
752         dm_lib_release();
753
754         /*
755          * update our state from kernel regardless of create or reload
756          */
757         if (setup_multipath(vecs, mpp))
758                 goto fail; /* if setup_multipath fails, it removes the map */
759
760         sync_map_state(mpp);
761
762         if ((mpp->action == ACT_CREATE ||
763              (mpp->action == ACT_NOTHING && start_waiter && !mpp->waiter)) &&
764             start_waiter_thread(mpp, vecs))
765                         goto fail_map;
766
767         if (retries >= 0) {
768                 condlog(2, "%s [%s]: path added to devmap %s",
769                         pp->dev, pp->dev_t, mpp->alias);
770                 return 0;
771         } else
772                 goto fail;
773
774 fail_map:
775         remove_map(mpp, vecs, 1);
776 fail:
777         orphan_path(pp, "failed to add path");
778         return 1;
779 }
780
781 static int
782 uev_remove_path (struct uevent *uev, struct vectors * vecs, int need_do_map)
783 {
784         struct path *pp;
785         int ret;
786
787         condlog(2, "%s: remove path (uevent)", uev->kernel);
788         delete_foreign(uev->udev);
789
790         pthread_cleanup_push(cleanup_lock, &vecs->lock);
791         lock(&vecs->lock);
792         pthread_testcancel();
793         pp = find_path_by_dev(vecs->pathvec, uev->kernel);
794         if (pp)
795                 ret = ev_remove_path(pp, vecs, need_do_map);
796         lock_cleanup_pop(vecs->lock);
797         if (!pp) {
798                 /* Not an error; path might have been purged earlier */
799                 condlog(0, "%s: path already removed", uev->kernel);
800                 return 0;
801         }
802         return ret;
803 }
804
805 int
806 ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map)
807 {
808         struct multipath * mpp;
809         int i, retval = 0;
810         char params[PARAMS_SIZE] = {0};
811
812         /*
813          * avoid referring to the map of an orphaned path
814          */
815         if ((mpp = pp->mpp)) {
816                 /*
817                  * transform the mp->pg vector of vectors of paths
818                  * into a mp->params string to feed the device-mapper
819                  */
820                 if (update_mpp_paths(mpp, vecs->pathvec)) {
821                         condlog(0, "%s: failed to update paths",
822                                 mpp->alias);
823                         goto fail;
824                 }
825                 if ((i = find_slot(mpp->paths, (void *)pp)) != -1)
826                         vector_del_slot(mpp->paths, i);
827
828                 /*
829                  * remove the map IFF removing the last path
830                  */
831                 if (VECTOR_SIZE(mpp->paths) == 0) {
832                         char alias[WWID_SIZE];
833
834                         /*
835                          * flush_map will fail if the device is open
836                          */
837                         strncpy(alias, mpp->alias, WWID_SIZE);
838                         if (mpp->flush_on_last_del == FLUSH_ENABLED) {
839                                 condlog(2, "%s Last path deleted, disabling queueing", mpp->alias);
840                                 mpp->retry_tick = 0;
841                                 mpp->no_path_retry = NO_PATH_RETRY_FAIL;
842                                 mpp->disable_queueing = 1;
843                                 mpp->stat_map_failures++;
844                                 dm_queue_if_no_path(mpp->alias, 0);
845                         }
846                         if (!flush_map(mpp, vecs, 1)) {
847                                 condlog(2, "%s: removed map after"
848                                         " removing all paths",
849                                         alias);
850                                 retval = 0;
851                                 goto out;
852                         }
853                         /*
854                          * Not an error, continue
855                          */
856                 }
857
858                 if (setup_map(mpp, params, PARAMS_SIZE, vecs)) {
859                         condlog(0, "%s: failed to setup map for"
860                                 " removal of path %s", mpp->alias, pp->dev);
861                         goto fail;
862                 }
863
864                 if (mpp->wait_for_udev) {
865                         mpp->wait_for_udev = 2;
866                         goto out;
867                 }
868
869                 if (!need_do_map)
870                         goto out;
871                 /*
872                  * reload the map
873                  */
874                 mpp->action = ACT_RELOAD;
875                 if (domap(mpp, params, 1) <= 0) {
876                         condlog(0, "%s: failed in domap for "
877                                 "removal of path %s",
878                                 mpp->alias, pp->dev);
879                         retval = 1;
880                 } else {
881                         /*
882                          * update our state from kernel
883                          */
884                         if (setup_multipath(vecs, mpp))
885                                 return 1;
886                         sync_map_state(mpp);
887
888                         condlog(2, "%s [%s]: path removed from map %s",
889                                 pp->dev, pp->dev_t, mpp->alias);
890                 }
891         }
892
893 out:
894         if ((i = find_slot(vecs->pathvec, (void *)pp)) != -1)
895                 vector_del_slot(vecs->pathvec, i);
896
897         free_path(pp);
898
899         return retval;
900
901 fail:
902         remove_map_and_stop_waiter(mpp, vecs, 1);
903         return 1;
904 }
905
906 static int
907 uev_update_path (struct uevent *uev, struct vectors * vecs)
908 {
909         int ro, retval = 0, rc;
910         struct path * pp;
911         struct config *conf;
912         int disable_changed_wwids;
913         int needs_reinit = 0;
914
915         switch ((rc = change_foreign(uev->udev))) {
916         case FOREIGN_OK:
917                 /* known foreign path, ignore event */
918                 return 0;
919         case FOREIGN_IGNORED:
920                 break;
921         case FOREIGN_ERR:
922                 condlog(3, "%s: error in change_foreign", __func__);
923                 break;
924         default:
925                 condlog(1, "%s: return code %d of change_forein is unsupported",
926                         __func__, rc);
927                 break;
928         }
929
930         conf = get_multipath_config();
931         disable_changed_wwids = conf->disable_changed_wwids;
932         put_multipath_config(conf);
933
934         ro = uevent_get_disk_ro(uev);
935
936         pthread_cleanup_push(cleanup_lock, &vecs->lock);
937         lock(&vecs->lock);
938         pthread_testcancel();
939
940         pp = find_path_by_dev(vecs->pathvec, uev->kernel);
941         if (pp) {
942                 struct multipath *mpp = pp->mpp;
943                 char wwid[WWID_SIZE];
944
945                 strcpy(wwid, pp->wwid);
946                 get_uid(pp, pp->state, uev->udev);
947
948                 if (strncmp(wwid, pp->wwid, WWID_SIZE) != 0) {
949                         condlog(0, "%s: path wwid changed from '%s' to '%s'. %s",
950                                 uev->kernel, wwid, pp->wwid,
951                                 (disable_changed_wwids ? "disallowing" :
952                                  "continuing"));
953                         if (disable_changed_wwids &&
954                             (strlen(wwid) || pp->wwid_changed)) {
955                                 strcpy(pp->wwid, wwid);
956                                 if (!pp->wwid_changed) {
957                                         pp->wwid_changed = 1;
958                                         pp->tick = 1;
959                                         if (pp->mpp)
960                                                 dm_fail_path(pp->mpp->alias, pp->dev_t);
961                                 }
962                                 goto out;
963                         } else if (!disable_changed_wwids)
964                                 strcpy(pp->wwid, wwid);
965                         else
966                                 pp->wwid_changed = 0;
967                 }
968
969                 if (pp->initialized == INIT_REQUESTED_UDEV)
970                         needs_reinit = 1;
971                 else if (mpp && ro >= 0) {
972                         condlog(2, "%s: update path write_protect to '%d' (uevent)", uev->kernel, ro);
973
974                         if (mpp->wait_for_udev)
975                                 mpp->wait_for_udev = 2;
976                         else {
977                                 if (ro == 1)
978                                         pp->mpp->force_readonly = 1;
979                                 retval = reload_map(vecs, mpp, 0, 1);
980                                 pp->mpp->force_readonly = 0;
981                                 condlog(2, "%s: map %s reloaded (retval %d)",
982                                         uev->kernel, mpp->alias, retval);
983                         }
984                 }
985         }
986 out:
987         lock_cleanup_pop(vecs->lock);
988         if (!pp) {
989                 /* If the path is blacklisted, print a debug/non-default verbosity message. */
990                 if (uev->udev) {
991                         int flag = DI_SYSFS | DI_WWID;
992
993                         conf = get_multipath_config();
994                         retval = alloc_path_with_pathinfo(conf, uev->udev, uev->wwid, flag, NULL);
995                         put_multipath_config(conf);
996
997                         if (retval == PATHINFO_SKIPPED) {
998                                 condlog(3, "%s: spurious uevent, path is blacklisted", uev->kernel);
999                                 return 0;
1000                         }
1001                 }
1002
1003                 condlog(0, "%s: spurious uevent, path not found", uev->kernel);
1004         }
1005         if (needs_reinit)
1006                 retval = uev_add_path(uev, vecs, 1);
1007         return retval;
1008 }
1009
1010 static int
1011 uev_pathfail_check(struct uevent *uev, struct vectors *vecs)
1012 {
1013         char *action = NULL, *devt = NULL;
1014         struct path *pp;
1015         int r = 1;
1016
1017         action = uevent_get_dm_action(uev);
1018         if (!action)
1019                 return 1;
1020         if (strncmp(action, "PATH_FAILED", 11))
1021                 goto out;
1022         devt = uevent_get_dm_path(uev);
1023         if (!devt) {
1024                 condlog(3, "%s: No DM_PATH in uevent", uev->kernel);
1025                 goto out;
1026         }
1027
1028         pthread_cleanup_push(cleanup_lock, &vecs->lock);
1029         lock(&vecs->lock);
1030         pthread_testcancel();
1031         pp = find_path_by_devt(vecs->pathvec, devt);
1032         if (!pp)
1033                 goto out_lock;
1034         r = io_err_stat_handle_pathfail(pp);
1035         if (r)
1036                 condlog(3, "io_err_stat: %s: cannot handle pathfail uevent",
1037                                 pp->dev);
1038 out_lock:
1039         lock_cleanup_pop(vecs->lock);
1040         FREE(devt);
1041         FREE(action);
1042         return r;
1043 out:
1044         FREE(action);
1045         return 1;
1046 }
1047
1048 static int
1049 map_discovery (struct vectors * vecs)
1050 {
1051         struct multipath * mpp;
1052         unsigned int i;
1053
1054         if (dm_get_maps(vecs->mpvec))
1055                 return 1;
1056
1057         vector_foreach_slot (vecs->mpvec, mpp, i)
1058                 if (update_multipath_table(mpp, vecs->pathvec, 1) ||
1059                     update_multipath_status(mpp)) {
1060                         remove_map(mpp, vecs, 1);
1061                         i--;
1062                 }
1063
1064         return 0;
1065 }
1066
1067 int
1068 uxsock_trigger (char * str, char ** reply, int * len, bool is_root,
1069                 void * trigger_data)
1070 {
1071         struct vectors * vecs;
1072         int r;
1073
1074         *reply = NULL;
1075         *len = 0;
1076         vecs = (struct vectors *)trigger_data;
1077
1078         if ((str != NULL) && (is_root == false) &&
1079             (strncmp(str, "list", strlen("list")) != 0) &&
1080             (strncmp(str, "show", strlen("show")) != 0)) {
1081                 *reply = STRDUP("permission deny: need to be root");
1082                 if (*reply)
1083                         *len = strlen(*reply) + 1;
1084                 return 1;
1085         }
1086
1087         r = parse_cmd(str, reply, len, vecs, uxsock_timeout / 1000);
1088
1089         if (r > 0) {
1090                 if (r == ETIMEDOUT)
1091                         *reply = STRDUP("timeout\n");
1092                 else
1093                         *reply = STRDUP("fail\n");
1094                 if (*reply)
1095                         *len = strlen(*reply) + 1;
1096                 r = 1;
1097         }
1098         else if (!r && *len == 0) {
1099                 *reply = STRDUP("ok\n");
1100                 if (*reply)
1101                         *len = strlen(*reply) + 1;
1102                 r = 0;
1103         }
1104         /* else if (r < 0) leave *reply alone */
1105
1106         return r;
1107 }
1108
1109 int
1110 uev_trigger (struct uevent * uev, void * trigger_data)
1111 {
1112         int r = 0;
1113         struct vectors * vecs;
1114         struct uevent *merge_uev, *tmp;
1115
1116         vecs = (struct vectors *)trigger_data;
1117
1118         pthread_cleanup_push(config_cleanup, NULL);
1119         pthread_mutex_lock(&config_lock);
1120         if (running_state != DAEMON_IDLE &&
1121             running_state != DAEMON_RUNNING)
1122                 pthread_cond_wait(&config_cond, &config_lock);
1123         pthread_cleanup_pop(1);
1124
1125         if (running_state == DAEMON_SHUTDOWN)
1126                 return 0;
1127
1128         /*
1129          * device map event
1130          * Add events are ignored here as the tables
1131          * are not fully initialised then.
1132          */
1133         if (!strncmp(uev->kernel, "dm-", 3)) {
1134                 if (!uevent_is_mpath(uev)) {
1135                         if (!strncmp(uev->action, "change", 6))
1136                                 (void)add_foreign(uev->udev);
1137                         else if (!strncmp(uev->action, "remove", 6))
1138                                 (void)delete_foreign(uev->udev);
1139                         goto out;
1140                 }
1141                 if (!strncmp(uev->action, "change", 6)) {
1142                         r = uev_add_map(uev, vecs);
1143
1144                         /*
1145                          * the kernel-side dm-mpath issues a PATH_FAILED event
1146                          * when it encounters a path IO error. It is reason-
1147                          * able be the entry of path IO error accounting pro-
1148                          * cess.
1149                          */
1150                         uev_pathfail_check(uev, vecs);
1151                 } else if (!strncmp(uev->action, "remove", 6)) {
1152                         r = uev_remove_map(uev, vecs);
1153                 }
1154                 goto out;
1155         }
1156
1157         /*
1158          * path add/remove/change event, add/remove maybe merged
1159          */
1160         list_for_each_entry_safe(merge_uev, tmp, &uev->merge_node, node) {
1161                 if (!strncmp(merge_uev->action, "add", 3))
1162                         r += uev_add_path(merge_uev, vecs, 0);
1163                 if (!strncmp(merge_uev->action, "remove", 6))
1164                         r += uev_remove_path(merge_uev, vecs, 0);
1165         }
1166
1167         if (!strncmp(uev->action, "add", 3))
1168                 r += uev_add_path(uev, vecs, 1);
1169         if (!strncmp(uev->action, "remove", 6))
1170                 r += uev_remove_path(uev, vecs, 1);
1171         if (!strncmp(uev->action, "change", 6))
1172                 r += uev_update_path(uev, vecs);
1173
1174 out:
1175         return r;
1176 }
1177
1178 static void rcu_unregister(void *param)
1179 {
1180         rcu_unregister_thread();
1181 }
1182
1183 static void *
1184 ueventloop (void * ap)
1185 {
1186         struct udev *udev = ap;
1187
1188         pthread_cleanup_push(rcu_unregister, NULL);
1189         rcu_register_thread();
1190         if (uevent_listen(udev))
1191                 condlog(0, "error starting uevent listener");
1192         pthread_cleanup_pop(1);
1193         return NULL;
1194 }
1195
1196 static void *
1197 uevqloop (void * ap)
1198 {
1199         pthread_cleanup_push(rcu_unregister, NULL);
1200         rcu_register_thread();
1201         if (uevent_dispatch(&uev_trigger, ap))
1202                 condlog(0, "error starting uevent dispatcher");
1203         pthread_cleanup_pop(1);
1204         return NULL;
1205 }
1206 static void *
1207 uxlsnrloop (void * ap)
1208 {
1209         if (cli_init()) {
1210                 condlog(1, "Failed to init uxsock listener");
1211                 return NULL;
1212         }
1213         pthread_cleanup_push(rcu_unregister, NULL);
1214         rcu_register_thread();
1215         set_handler_callback(LIST+PATHS, cli_list_paths);
1216         set_handler_callback(LIST+PATHS+FMT, cli_list_paths_fmt);
1217         set_handler_callback(LIST+PATHS+RAW+FMT, cli_list_paths_raw);
1218         set_handler_callback(LIST+PATH, cli_list_path);
1219         set_handler_callback(LIST+MAPS, cli_list_maps);
1220         set_handler_callback(LIST+STATUS, cli_list_status);
1221         set_unlocked_handler_callback(LIST+DAEMON, cli_list_daemon);
1222         set_handler_callback(LIST+MAPS+STATUS, cli_list_maps_status);
1223         set_handler_callback(LIST+MAPS+STATS, cli_list_maps_stats);
1224         set_handler_callback(LIST+MAPS+FMT, cli_list_maps_fmt);
1225         set_handler_callback(LIST+MAPS+RAW+FMT, cli_list_maps_raw);
1226         set_handler_callback(LIST+MAPS+TOPOLOGY, cli_list_maps_topology);
1227         set_handler_callback(LIST+TOPOLOGY, cli_list_maps_topology);
1228         set_handler_callback(LIST+MAPS+JSON, cli_list_maps_json);
1229         set_handler_callback(LIST+MAP+TOPOLOGY, cli_list_map_topology);
1230         set_handler_callback(LIST+MAP+FMT, cli_list_map_fmt);
1231         set_handler_callback(LIST+MAP+RAW+FMT, cli_list_map_fmt);
1232         set_handler_callback(LIST+MAP+JSON, cli_list_map_json);
1233         set_handler_callback(LIST+CONFIG, cli_list_config);
1234         set_handler_callback(LIST+BLACKLIST, cli_list_blacklist);
1235         set_handler_callback(LIST+DEVICES, cli_list_devices);
1236         set_handler_callback(LIST+WILDCARDS, cli_list_wildcards);
1237         set_handler_callback(RESET+MAPS+STATS, cli_reset_maps_stats);
1238         set_handler_callback(RESET+MAP+STATS, cli_reset_map_stats);
1239         set_handler_callback(ADD+PATH, cli_add_path);
1240         set_handler_callback(DEL+PATH, cli_del_path);
1241         set_handler_callback(ADD+MAP, cli_add_map);
1242         set_handler_callback(DEL+MAP, cli_del_map);
1243         set_handler_callback(SWITCH+MAP+GROUP, cli_switch_group);
1244         set_unlocked_handler_callback(RECONFIGURE, cli_reconfigure);
1245         set_handler_callback(SUSPEND+MAP, cli_suspend);
1246         set_handler_callback(RESUME+MAP, cli_resume);
1247         set_handler_callback(RESIZE+MAP, cli_resize);
1248         set_handler_callback(RELOAD+MAP, cli_reload);
1249         set_handler_callback(RESET+MAP, cli_reassign);
1250         set_handler_callback(REINSTATE+PATH, cli_reinstate);
1251         set_handler_callback(FAIL+PATH, cli_fail);
1252         set_handler_callback(DISABLEQ+MAP, cli_disable_queueing);
1253         set_handler_callback(RESTOREQ+MAP, cli_restore_queueing);
1254         set_handler_callback(DISABLEQ+MAPS, cli_disable_all_queueing);
1255         set_handler_callback(RESTOREQ+MAPS, cli_restore_all_queueing);
1256         set_unlocked_handler_callback(QUIT, cli_quit);
1257         set_unlocked_handler_callback(SHUTDOWN, cli_shutdown);
1258         set_handler_callback(GETPRSTATUS+MAP, cli_getprstatus);
1259         set_handler_callback(SETPRSTATUS+MAP, cli_setprstatus);
1260         set_handler_callback(UNSETPRSTATUS+MAP, cli_unsetprstatus);
1261         set_handler_callback(FORCEQ+DAEMON, cli_force_no_daemon_q);
1262         set_handler_callback(RESTOREQ+DAEMON, cli_restore_no_daemon_q);
1263         set_handler_callback(GETPRKEY+MAP, cli_getprkey);
1264         set_handler_callback(SETPRKEY+MAP+KEY, cli_setprkey);
1265         set_handler_callback(UNSETPRKEY+MAP, cli_unsetprkey);
1266
1267         umask(077);
1268         uxsock_listen(&uxsock_trigger, ap);
1269         pthread_cleanup_pop(1);
1270         return NULL;
1271 }
1272
1273 void
1274 exit_daemon (void)
1275 {
1276         post_config_state(DAEMON_SHUTDOWN);
1277 }
1278
1279 static void
1280 fail_path (struct path * pp, int del_active)
1281 {
1282         if (!pp->mpp)
1283                 return;
1284
1285         condlog(2, "checker failed path %s in map %s",
1286                  pp->dev_t, pp->mpp->alias);
1287
1288         dm_fail_path(pp->mpp->alias, pp->dev_t);
1289         if (del_active)
1290                 update_queue_mode_del_path(pp->mpp);
1291 }
1292
1293 /*
1294  * caller must have locked the path list before calling that function
1295  */
1296 static int
1297 reinstate_path (struct path * pp, int add_active)
1298 {
1299         int ret = 0;
1300
1301         if (!pp->mpp)
1302                 return 0;
1303
1304         if (dm_reinstate_path(pp->mpp->alias, pp->dev_t)) {
1305                 condlog(0, "%s: reinstate failed", pp->dev_t);
1306                 ret = 1;
1307         } else {
1308                 condlog(2, "%s: reinstated", pp->dev_t);
1309                 if (add_active)
1310                         update_queue_mode_add_path(pp->mpp);
1311         }
1312         return ret;
1313 }
1314
1315 static void
1316 enable_group(struct path * pp)
1317 {
1318         struct pathgroup * pgp;
1319
1320         /*
1321          * if path is added through uev_add_path, pgindex can be unset.
1322          * next update_strings() will set it, upon map reload event.
1323          *
1324          * we can safely return here, because upon map reload, all
1325          * PG will be enabled.
1326          */
1327         if (!pp->mpp->pg || !pp->pgindex)
1328                 return;
1329
1330         pgp = VECTOR_SLOT(pp->mpp->pg, pp->pgindex - 1);
1331
1332         if (pgp->status == PGSTATE_DISABLED) {
1333                 condlog(2, "%s: enable group #%i", pp->mpp->alias, pp->pgindex);
1334                 dm_enablegroup(pp->mpp->alias, pp->pgindex);
1335         }
1336 }
1337
1338 static void
1339 mpvec_garbage_collector (struct vectors * vecs)
1340 {
1341         struct multipath * mpp;
1342         unsigned int i;
1343
1344         if (!vecs->mpvec)
1345                 return;
1346
1347         vector_foreach_slot (vecs->mpvec, mpp, i) {
1348                 if (mpp && mpp->alias && !dm_map_present(mpp->alias)) {
1349                         condlog(2, "%s: remove dead map", mpp->alias);
1350                         remove_map_and_stop_waiter(mpp, vecs, 1);
1351                         i--;
1352                 }
1353         }
1354 }
1355
1356 /* This is called after a path has started working again. It the multipath
1357  * device for this path uses the followover failback type, and this is the
1358  * best pathgroup, and this is the first path in the pathgroup to come back
1359  * up, then switch to this pathgroup */
1360 static int
1361 followover_should_failback(struct path * pp)
1362 {
1363         struct pathgroup * pgp;
1364         struct path *pp1;
1365         int i;
1366
1367         if (pp->mpp->pgfailback != -FAILBACK_FOLLOWOVER ||
1368             !pp->mpp->pg || !pp->pgindex ||
1369             pp->pgindex != pp->mpp->bestpg)
1370                 return 0;
1371
1372         pgp = VECTOR_SLOT(pp->mpp->pg, pp->pgindex - 1);
1373         vector_foreach_slot(pgp->paths, pp1, i) {
1374                 if (pp1 == pp)
1375                         continue;
1376                 if (pp1->chkrstate != PATH_DOWN && pp1->chkrstate != PATH_SHAKY)
1377                         return 0;
1378         }
1379         return 1;
1380 }
1381
1382 static void
1383 missing_uev_wait_tick(struct vectors *vecs)
1384 {
1385         struct multipath * mpp;
1386         unsigned int i;
1387         int timed_out = 0, delayed_reconfig;
1388         struct config *conf;
1389
1390         vector_foreach_slot (vecs->mpvec, mpp, i) {
1391                 if (mpp->wait_for_udev && --mpp->uev_wait_tick <= 0) {
1392                         timed_out = 1;
1393                         condlog(0, "%s: timeout waiting on creation uevent. enabling reloads", mpp->alias);
1394                         if (mpp->wait_for_udev > 1 && update_map(mpp, vecs)) {
1395                                 /* update_map removed map */
1396                                 i--;
1397                                 continue;
1398                         }
1399                         mpp->wait_for_udev = 0;
1400                 }
1401         }
1402
1403         conf = get_multipath_config();
1404         delayed_reconfig = conf->delayed_reconfig;
1405         put_multipath_config(conf);
1406         if (timed_out && delayed_reconfig &&
1407             !need_to_delay_reconfig(vecs)) {
1408                 condlog(2, "reconfigure (delayed)");
1409                 set_config_state(DAEMON_CONFIGURE);
1410         }
1411 }
1412
1413 static void
1414 ghost_delay_tick(struct vectors *vecs)
1415 {
1416         struct multipath * mpp;
1417         unsigned int i;
1418
1419         vector_foreach_slot (vecs->mpvec, mpp, i) {
1420                 if (mpp->ghost_delay_tick <= 0)
1421                         continue;
1422                 if (--mpp->ghost_delay_tick <= 0) {
1423                         condlog(0, "%s: timed out waiting for active path",
1424                                 mpp->alias);
1425                         mpp->force_udev_reload = 1;
1426                         if (update_map(mpp, vecs) != 0) {
1427                                 /* update_map removed map */
1428                                 i--;
1429                                 continue;
1430                         }
1431                 }
1432         }
1433 }
1434
1435 static void
1436 defered_failback_tick (vector mpvec)
1437 {
1438         struct multipath * mpp;
1439         unsigned int i;
1440
1441         vector_foreach_slot (mpvec, mpp, i) {
1442                 /*
1443                  * defered failback getting sooner
1444                  */
1445                 if (mpp->pgfailback > 0 && mpp->failback_tick > 0) {
1446                         mpp->failback_tick--;
1447
1448                         if (!mpp->failback_tick && need_switch_pathgroup(mpp, 1))
1449                                 switch_pathgroup(mpp);
1450                 }
1451         }
1452 }
1453
1454 static void
1455 retry_count_tick(vector mpvec)
1456 {
1457         struct multipath *mpp;
1458         unsigned int i;
1459
1460         vector_foreach_slot (mpvec, mpp, i) {
1461                 if (mpp->retry_tick > 0) {
1462                         mpp->stat_total_queueing_time++;
1463                         condlog(4, "%s: Retrying.. No active path", mpp->alias);
1464                         if(--mpp->retry_tick == 0) {
1465                                 mpp->stat_map_failures++;
1466                                 dm_queue_if_no_path(mpp->alias, 0);
1467                                 condlog(2, "%s: Disable queueing", mpp->alias);
1468                         }
1469                 }
1470         }
1471 }
1472
1473 int update_prio(struct path *pp, int refresh_all)
1474 {
1475         int oldpriority;
1476         struct path *pp1;
1477         struct pathgroup * pgp;
1478         int i, j, changed = 0;
1479         struct config *conf;
1480
1481         if (refresh_all) {
1482                 vector_foreach_slot (pp->mpp->pg, pgp, i) {
1483                         vector_foreach_slot (pgp->paths, pp1, j) {
1484                                 oldpriority = pp1->priority;
1485                                 conf = get_multipath_config();
1486                                 pathinfo(pp1, conf, DI_PRIO);
1487                                 put_multipath_config(conf);
1488                                 if (pp1->priority != oldpriority)
1489                                         changed = 1;
1490                         }
1491                 }
1492                 return changed;
1493         }
1494         oldpriority = pp->priority;
1495         conf = get_multipath_config();
1496         if (pp->state != PATH_DOWN)
1497                 pathinfo(pp, conf, DI_PRIO);
1498         put_multipath_config(conf);
1499
1500         if (pp->priority == oldpriority)
1501                 return 0;
1502         return 1;
1503 }
1504
1505 int update_path_groups(struct multipath *mpp, struct vectors *vecs, int refresh)
1506 {
1507         if (reload_map(vecs, mpp, refresh, 1))
1508                 return 1;
1509
1510         dm_lib_release();
1511         if (setup_multipath(vecs, mpp) != 0)
1512                 return 1;
1513         sync_map_state(mpp);
1514
1515         return 0;
1516 }
1517
1518 void repair_path(struct path * pp)
1519 {
1520         if (pp->state != PATH_DOWN)
1521                 return;
1522
1523         checker_repair(&pp->checker);
1524         LOG_MSG(1, checker_message(&pp->checker));
1525 }
1526
1527 /*
1528  * Returns '1' if the path has been checked, '-1' if it was blacklisted
1529  * and '0' otherwise
1530  */
1531 int
1532 check_path (struct vectors * vecs, struct path * pp, int ticks)
1533 {
1534         int newstate;
1535         int new_path_up = 0;
1536         int chkr_new_path_up = 0;
1537         int add_active;
1538         int disable_reinstate = 0;
1539         int oldchkrstate = pp->chkrstate;
1540         int retrigger_tries, checkint;
1541         struct config *conf;
1542         int ret;
1543
1544         if ((pp->initialized == INIT_OK ||
1545              pp->initialized == INIT_REQUESTED_UDEV) && !pp->mpp)
1546                 return 0;
1547
1548         if (pp->tick)
1549                 pp->tick -= (pp->tick > ticks) ? ticks : pp->tick;
1550         if (pp->tick)
1551                 return 0; /* don't check this path yet */
1552
1553         conf = get_multipath_config();
1554         retrigger_tries = conf->retrigger_tries;
1555         checkint = conf->checkint;
1556         put_multipath_config(conf);
1557         if (!pp->mpp && pp->initialized == INIT_MISSING_UDEV &&
1558             pp->retriggers < retrigger_tries) {
1559                 condlog(2, "%s: triggering change event to reinitialize",
1560                         pp->dev);
1561                 pp->initialized = INIT_REQUESTED_UDEV;
1562                 pp->retriggers++;
1563                 sysfs_attr_set_value(pp->udev, "uevent", "change",
1564                                      strlen("change"));
1565                 return 0;
1566         }
1567
1568         /*
1569          * provision a next check soonest,
1570          * in case we exit abnormaly from here
1571          */
1572         pp->tick = checkint;
1573
1574         newstate = path_offline(pp);
1575         /*
1576          * Wait for uevent for removed paths;
1577          * some LLDDs like zfcp keep paths unavailable
1578          * without sending uevents.
1579          */
1580         if (newstate == PATH_REMOVED)
1581                 newstate = PATH_DOWN;
1582
1583         if (newstate == PATH_UP) {
1584                 conf = get_multipath_config();
1585                 newstate = get_state(pp, conf, 1, newstate);
1586                 put_multipath_config(conf);
1587         } else
1588                 checker_clear_message(&pp->checker);
1589
1590         if (pp->wwid_changed) {
1591                 condlog(2, "%s: path wwid has changed. Refusing to use",
1592                         pp->dev);
1593                 newstate = PATH_DOWN;
1594         }
1595
1596         if (newstate == PATH_WILD || newstate == PATH_UNCHECKED) {
1597                 condlog(2, "%s: unusable path", pp->dev);
1598                 conf = get_multipath_config();
1599                 pathinfo(pp, conf, 0);
1600                 put_multipath_config(conf);
1601                 return 1;
1602         }
1603         if (!pp->mpp) {
1604                 if (!strlen(pp->wwid) && pp->initialized != INIT_MISSING_UDEV &&
1605                     (newstate == PATH_UP || newstate == PATH_GHOST)) {
1606                         condlog(2, "%s: add missing path", pp->dev);
1607                         conf = get_multipath_config();
1608                         ret = pathinfo(pp, conf, DI_ALL | DI_BLACKLIST);
1609                         if (ret == PATHINFO_OK) {
1610                                 ev_add_path(pp, vecs, 1);
1611                                 pp->tick = 1;
1612                         } else if (ret == PATHINFO_SKIPPED) {
1613                                 put_multipath_config(conf);
1614                                 return -1;
1615                         }
1616                         put_multipath_config(conf);
1617                 }
1618                 return 0;
1619         }
1620         /*
1621          * Async IO in flight. Keep the previous path state
1622          * and reschedule as soon as possible
1623          */
1624         if (newstate == PATH_PENDING) {
1625                 pp->tick = 1;
1626                 return 0;
1627         }
1628         /*
1629          * Synchronize with kernel state
1630          */
1631         if (update_multipath_strings(pp->mpp, vecs->pathvec, 1)) {
1632                 condlog(1, "%s: Could not synchronize with kernel state",
1633                         pp->dev);
1634                 pp->dmstate = PSTATE_UNDEF;
1635         }
1636         /* if update_multipath_strings orphaned the path, quit early */
1637         if (!pp->mpp)
1638                 return 0;
1639
1640         if (pp->io_err_disable_reinstate && hit_io_err_recheck_time(pp)) {
1641                 pp->state = PATH_SHAKY;
1642                 /*
1643                  * to reschedule as soon as possible,so that this path can
1644                  * be recoverd in time
1645                  */
1646                 pp->tick = 1;
1647                 return 1;
1648         }
1649
1650         if ((newstate == PATH_UP || newstate == PATH_GHOST) &&
1651              pp->wait_checks > 0) {
1652                 if (pp->mpp->nr_active > 0) {
1653                         pp->state = PATH_DELAYED;
1654                         pp->wait_checks--;
1655                         return 1;
1656                 } else
1657                         pp->wait_checks = 0;
1658         }
1659
1660         /*
1661          * don't reinstate failed path, if its in stand-by
1662          * and if target supports only implicit tpgs mode.
1663          * this will prevent unnecessary i/o by dm on stand-by
1664          * paths if there are no other active paths in map.
1665          */
1666         disable_reinstate = (newstate == PATH_GHOST &&
1667                             pp->mpp->nr_active == 0 &&
1668                             pp->tpgs == TPGS_IMPLICIT) ? 1 : 0;
1669
1670         pp->chkrstate = newstate;
1671         if (newstate != pp->state) {
1672                 int oldstate = pp->state;
1673                 pp->state = newstate;
1674
1675                 LOG_MSG(1, checker_message(&pp->checker));
1676
1677                 /*
1678                  * upon state change, reset the checkint
1679                  * to the shortest delay
1680                  */
1681                 conf = get_multipath_config();
1682                 pp->checkint = conf->checkint;
1683                 put_multipath_config(conf);
1684
1685                 if (newstate != PATH_UP && newstate != PATH_GHOST) {
1686                         /*
1687                          * proactively fail path in the DM
1688                          */
1689                         if (oldstate == PATH_UP ||
1690                             oldstate == PATH_GHOST) {
1691                                 fail_path(pp, 1);
1692                                 if (pp->mpp->delay_wait_checks > 0 &&
1693                                     pp->watch_checks > 0) {
1694                                         pp->wait_checks = pp->mpp->delay_wait_checks;
1695                                         pp->watch_checks = 0;
1696                                 }
1697                         }else
1698                                 fail_path(pp, 0);
1699
1700                         /*
1701                          * cancel scheduled failback
1702                          */
1703                         pp->mpp->failback_tick = 0;
1704
1705                         pp->mpp->stat_path_failures++;
1706                         repair_path(pp);
1707                         return 1;
1708                 }
1709
1710                 if(newstate == PATH_UP || newstate == PATH_GHOST){
1711                         if ( pp->mpp && pp->mpp->prflag ){
1712                                 /*
1713                                  * Check Persistent Reservation.
1714                                  */
1715                         condlog(2, "%s: checking persistent reservation "
1716                                 "registration", pp->dev);
1717                         mpath_pr_event_handle(pp);
1718                         }
1719                 }
1720
1721                 /*
1722                  * reinstate this path
1723                  */
1724                 if (oldstate != PATH_UP &&
1725                     oldstate != PATH_GHOST) {
1726                         if (pp->mpp->delay_watch_checks > 0)
1727                                 pp->watch_checks = pp->mpp->delay_watch_checks;
1728                         add_active = 1;
1729                 } else {
1730                         if (pp->watch_checks > 0)
1731                                 pp->watch_checks--;
1732                         add_active = 0;
1733                 }
1734                 if (!disable_reinstate && reinstate_path(pp, add_active)) {
1735                         condlog(3, "%s: reload map", pp->dev);
1736                         ev_add_path(pp, vecs, 1);
1737                         pp->tick = 1;
1738                         return 0;
1739                 }
1740                 new_path_up = 1;
1741
1742                 if (oldchkrstate != PATH_UP && oldchkrstate != PATH_GHOST)
1743                         chkr_new_path_up = 1;
1744
1745                 /*
1746                  * if at least one path is up in a group, and
1747                  * the group is disabled, re-enable it
1748                  */
1749                 if (newstate == PATH_UP)
1750                         enable_group(pp);
1751         }
1752         else if (newstate == PATH_UP || newstate == PATH_GHOST) {
1753                 if ((pp->dmstate == PSTATE_FAILED ||
1754                     pp->dmstate == PSTATE_UNDEF) &&
1755                     !disable_reinstate) {
1756                         /* Clear IO errors */
1757                         if (reinstate_path(pp, 0)) {
1758                                 condlog(3, "%s: reload map", pp->dev);
1759                                 ev_add_path(pp, vecs, 1);
1760                                 pp->tick = 1;
1761                                 return 0;
1762                         }
1763                 } else {
1764                         unsigned int max_checkint;
1765                         LOG_MSG(4, checker_message(&pp->checker));
1766                         conf = get_multipath_config();
1767                         max_checkint = conf->max_checkint;
1768                         put_multipath_config(conf);
1769                         if (pp->checkint != max_checkint) {
1770                                 /*
1771                                  * double the next check delay.
1772                                  * max at conf->max_checkint
1773                                  */
1774                                 if (pp->checkint < (max_checkint / 2))
1775                                         pp->checkint = 2 * pp->checkint;
1776                                 else
1777                                         pp->checkint = max_checkint;
1778
1779                                 condlog(4, "%s: delay next check %is",
1780                                         pp->dev_t, pp->checkint);
1781                         }
1782                         if (pp->watch_checks > 0)
1783                                 pp->watch_checks--;
1784                         pp->tick = pp->checkint;
1785                 }
1786         }
1787         else if (newstate != PATH_UP && newstate != PATH_GHOST) {
1788                 if (pp->dmstate == PSTATE_ACTIVE ||
1789                     pp->dmstate == PSTATE_UNDEF)
1790                         fail_path(pp, 0);
1791                 if (newstate == PATH_DOWN) {
1792                         int log_checker_err;
1793
1794                         conf = get_multipath_config();
1795                         log_checker_err = conf->log_checker_err;
1796                         put_multipath_config(conf);
1797                         if (log_checker_err == LOG_CHKR_ERR_ONCE)
1798                                 LOG_MSG(3, checker_message(&pp->checker));
1799                         else
1800                                 LOG_MSG(2, checker_message(&pp->checker));
1801                 }
1802         }
1803
1804         pp->state = newstate;
1805         repair_path(pp);
1806
1807         if (pp->mpp->wait_for_udev)
1808                 return 1;
1809         /*
1810          * path prio refreshing
1811          */
1812         condlog(4, "path prio refresh");
1813
1814         if (update_prio(pp, new_path_up) &&
1815             (pp->mpp->pgpolicyfn == (pgpolicyfn *)group_by_prio) &&
1816              pp->mpp->pgfailback == -FAILBACK_IMMEDIATE)
1817                 update_path_groups(pp->mpp, vecs, !new_path_up);
1818         else if (need_switch_pathgroup(pp->mpp, 0)) {
1819                 if (pp->mpp->pgfailback > 0 &&
1820                     (new_path_up || pp->mpp->failback_tick <= 0))
1821                         pp->mpp->failback_tick =
1822                                 pp->mpp->pgfailback + 1;
1823                 else if (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE ||
1824                          (chkr_new_path_up && followover_should_failback(pp)))
1825                         switch_pathgroup(pp->mpp);
1826         }
1827         return 1;
1828 }
1829
1830 static void init_path_check_interval(struct vectors *vecs)
1831 {
1832         struct config *conf;
1833         struct path *pp;
1834         unsigned int i;
1835
1836         vector_foreach_slot (vecs->pathvec, pp, i) {
1837                 conf = get_multipath_config();
1838                 pp->checkint = conf->checkint;
1839                 put_multipath_config(conf);
1840         }
1841 }
1842
1843 static void *
1844 checkerloop (void *ap)
1845 {
1846         struct vectors *vecs;
1847         struct path *pp;
1848         int count = 0;
1849         unsigned int i;
1850         struct itimerval timer_tick_it;
1851         struct timespec last_time;
1852         struct config *conf;
1853
1854         pthread_cleanup_push(rcu_unregister, NULL);
1855         rcu_register_thread();
1856         mlockall(MCL_CURRENT | MCL_FUTURE);
1857         vecs = (struct vectors *)ap;
1858         condlog(2, "path checkers start up");
1859
1860         /* Tweak start time for initial path check */
1861         if (clock_gettime(CLOCK_MONOTONIC, &last_time) != 0)
1862                 last_time.tv_sec = 0;
1863         else
1864                 last_time.tv_sec -= 1;
1865
1866         while (1) {
1867                 struct timespec diff_time, start_time, end_time;
1868                 int num_paths = 0, ticks = 0, signo, strict_timing, rc = 0;
1869                 sigset_t mask;
1870
1871                 if (clock_gettime(CLOCK_MONOTONIC, &start_time) != 0)
1872                         start_time.tv_sec = 0;
1873                 if (start_time.tv_sec && last_time.tv_sec) {
1874                         timespecsub(&start_time, &last_time, &diff_time);
1875                         condlog(4, "tick (%lu.%06lu secs)",
1876                                 diff_time.tv_sec, diff_time.tv_nsec / 1000);
1877                         last_time = start_time;
1878                         ticks = diff_time.tv_sec;
1879                 } else {
1880                         ticks = 1;
1881                         condlog(4, "tick (%d ticks)", ticks);
1882                 }
1883 #ifdef USE_SYSTEMD
1884                 if (use_watchdog)
1885                         sd_notify(0, "WATCHDOG=1");
1886 #endif
1887                 rc = set_config_state(DAEMON_RUNNING);
1888                 if (rc == ETIMEDOUT) {
1889                         condlog(4, "timeout waiting for DAEMON_IDLE");
1890                         continue;
1891                 }
1892
1893                 pthread_cleanup_push(cleanup_lock, &vecs->lock);
1894                 lock(&vecs->lock);
1895                 pthread_testcancel();
1896                 vector_foreach_slot (vecs->pathvec, pp, i) {
1897                         rc = check_path(vecs, pp, ticks);
1898                         if (rc < 0) {
1899                                 vector_del_slot(vecs->pathvec, i);
1900                                 free_path(pp);
1901                                 i--;
1902                         } else
1903                                 num_paths += rc;
1904                 }
1905                 lock_cleanup_pop(vecs->lock);
1906
1907                 pthread_cleanup_push(cleanup_lock, &vecs->lock);
1908                 lock(&vecs->lock);
1909                 pthread_testcancel();
1910                 defered_failback_tick(vecs->mpvec);
1911                 retry_count_tick(vecs->mpvec);
1912                 missing_uev_wait_tick(vecs);
1913                 ghost_delay_tick(vecs);
1914                 lock_cleanup_pop(vecs->lock);
1915
1916                 if (count)
1917                         count--;
1918                 else {
1919                         pthread_cleanup_push(cleanup_lock, &vecs->lock);
1920                         lock(&vecs->lock);
1921                         pthread_testcancel();
1922                         condlog(4, "map garbage collection");
1923                         mpvec_garbage_collector(vecs);
1924                         count = MAPGCINT;
1925                         lock_cleanup_pop(vecs->lock);
1926                 }
1927
1928                 diff_time.tv_nsec = 0;
1929                 if (start_time.tv_sec &&
1930                     clock_gettime(CLOCK_MONOTONIC, &end_time) == 0) {
1931                         timespecsub(&end_time, &start_time, &diff_time);
1932                         if (num_paths) {
1933                                 unsigned int max_checkint;
1934
1935                                 condlog(3, "checked %d path%s in %lu.%06lu secs",
1936                                         num_paths, num_paths > 1 ? "s" : "",
1937                                         diff_time.tv_sec,
1938                                         diff_time.tv_nsec / 1000);
1939                                 conf = get_multipath_config();
1940                                 max_checkint = conf->max_checkint;
1941                                 put_multipath_config(conf);
1942                                 if (diff_time.tv_sec > max_checkint)
1943                                         condlog(1, "path checkers took longer "
1944                                                 "than %lu seconds, consider "
1945                                                 "increasing max_polling_interval",
1946                                                 diff_time.tv_sec);
1947                         }
1948                 }
1949                 check_foreign();
1950                 post_config_state(DAEMON_IDLE);
1951                 conf = get_multipath_config();
1952                 strict_timing = conf->strict_timing;
1953                 put_multipath_config(conf);
1954                 if (!strict_timing)
1955                         sleep(1);
1956                 else {
1957                         timer_tick_it.it_interval.tv_sec = 0;
1958                         timer_tick_it.it_interval.tv_usec = 0;
1959                         if (diff_time.tv_nsec) {
1960                                 timer_tick_it.it_value.tv_sec = 0;
1961                                 timer_tick_it.it_value.tv_usec =
1962                                      1000UL * 1000 * 1000 - diff_time.tv_nsec;
1963                         } else {
1964                                 timer_tick_it.it_value.tv_sec = 1;
1965                                 timer_tick_it.it_value.tv_usec = 0;
1966                         }
1967                         setitimer(ITIMER_REAL, &timer_tick_it, NULL);
1968
1969                         sigemptyset(&mask);
1970                         sigaddset(&mask, SIGALRM);
1971                         condlog(3, "waiting for %lu.%06lu secs",
1972                                 timer_tick_it.it_value.tv_sec,
1973                                 timer_tick_it.it_value.tv_usec);
1974                         if (sigwait(&mask, &signo) != 0) {
1975                                 condlog(3, "sigwait failed with error %d",
1976                                         errno);
1977                                 conf = get_multipath_config();
1978                                 conf->strict_timing = 0;
1979                                 put_multipath_config(conf);
1980                                 break;
1981                         }
1982                 }
1983         }
1984         pthread_cleanup_pop(1);
1985         return NULL;
1986 }
1987
1988 int
1989 configure (struct vectors * vecs)
1990 {
1991         struct multipath * mpp;
1992         struct path * pp;
1993         vector mpvec;
1994         int i, ret;
1995         struct config *conf;
1996         static int force_reload = FORCE_RELOAD_WEAK;
1997
1998         if (!vecs->pathvec && !(vecs->pathvec = vector_alloc())) {
1999                 condlog(0, "couldn't allocate path vec in configure");
2000                 return 1;
2001         }
2002
2003         if (!vecs->mpvec && !(vecs->mpvec = vector_alloc())) {
2004                 condlog(0, "couldn't allocate multipath vec in configure");
2005                 return 1;
2006         }
2007
2008         if (!(mpvec = vector_alloc())) {
2009                 condlog(0, "couldn't allocate new maps vec in configure");
2010                 return 1;
2011         }
2012
2013         /*
2014          * probe for current path (from sysfs) and map (from dm) sets
2015          */
2016         ret = path_discovery(vecs->pathvec, DI_ALL);
2017         if (ret < 0) {
2018                 condlog(0, "configure failed at path discovery");
2019                 return 1;
2020         }
2021
2022         vector_foreach_slot (vecs->pathvec, pp, i){
2023                 conf = get_multipath_config();
2024                 if (filter_path(conf, pp) > 0){
2025                         vector_del_slot(vecs->pathvec, i);
2026                         free_path(pp);
2027                         i--;
2028                 }
2029                 else
2030                         pp->checkint = conf->checkint;
2031                 put_multipath_config(conf);
2032         }
2033         if (map_discovery(vecs)) {
2034                 condlog(0, "configure failed at map discovery");
2035                 return 1;
2036         }
2037
2038         /*
2039          * create new set of maps & push changed ones into dm
2040          * In the first call, use FORCE_RELOAD_WEAK to avoid making
2041          * superfluous ACT_RELOAD ioctls. Later calls are done
2042          * with FORCE_RELOAD_YES.
2043          */
2044         ret = coalesce_paths(vecs, mpvec, NULL, force_reload, CMD_NONE);
2045         if (force_reload == FORCE_RELOAD_WEAK)
2046                 force_reload = FORCE_RELOAD_YES;
2047         if (ret) {
2048                 condlog(0, "configure failed while coalescing paths");
2049                 return 1;
2050         }
2051
2052         /*
2053          * may need to remove some maps which are no longer relevant
2054          * e.g., due to blacklist changes in conf file
2055          */
2056         if (coalesce_maps(vecs, mpvec)) {
2057                 condlog(0, "configure failed while coalescing maps");
2058                 return 1;
2059         }
2060
2061         dm_lib_release();
2062
2063         sync_maps_state(mpvec);
2064         vector_foreach_slot(mpvec, mpp, i){
2065                 remember_wwid(mpp->wwid);
2066                 update_map_pr(mpp);
2067         }
2068
2069         /*
2070          * purge dm of old maps
2071          */
2072         remove_maps(vecs);
2073
2074         /*
2075          * save new set of maps formed by considering current path state
2076          */
2077         vector_free(vecs->mpvec);
2078         vecs->mpvec = mpvec;
2079
2080         /*
2081          * start dm event waiter threads for these new maps
2082          */
2083         vector_foreach_slot(vecs->mpvec, mpp, i) {
2084                 if (setup_multipath(vecs, mpp)) {
2085                         i--;
2086                         continue;
2087                 }
2088                 if (start_waiter_thread(mpp, vecs)) {
2089                         remove_map(mpp, vecs, 1);
2090                         i--;
2091                 }
2092         }
2093         return 0;
2094 }
2095
2096 int
2097 need_to_delay_reconfig(struct vectors * vecs)
2098 {
2099         struct multipath *mpp;
2100         int i;
2101
2102         if (!VECTOR_SIZE(vecs->mpvec))
2103                 return 0;
2104
2105         vector_foreach_slot(vecs->mpvec, mpp, i) {
2106                 if (mpp->wait_for_udev)
2107                         return 1;
2108         }
2109         return 0;
2110 }
2111
2112 void rcu_free_config(struct rcu_head *head)
2113 {
2114         struct config *conf = container_of(head, struct config, rcu);
2115
2116         free_config(conf);
2117 }
2118
2119 int
2120 reconfigure (struct vectors * vecs)
2121 {
2122         struct config * old, *conf;
2123
2124         conf = load_config(DEFAULT_CONFIGFILE);
2125         if (!conf)
2126                 return 1;
2127
2128         /*
2129          * free old map and path vectors ... they use old conf state
2130          */
2131         if (VECTOR_SIZE(vecs->mpvec))
2132                 remove_maps_and_stop_waiters(vecs);
2133
2134         free_pathvec(vecs->pathvec, FREE_PATHS);
2135         vecs->pathvec = NULL;
2136         delete_all_foreign();
2137
2138         /* Re-read any timezone changes */
2139         tzset();
2140
2141         dm_drv_version(conf->version, TGT_MPATH);
2142         if (verbosity)
2143                 conf->verbosity = verbosity;
2144         if (bindings_read_only)
2145                 conf->bindings_read_only = bindings_read_only;
2146         if (conf->find_multipaths) {
2147                 condlog(2, "find_multipaths is set: -n is implied");
2148                 ignore_new_devs = 1;
2149         }
2150         if (ignore_new_devs)
2151                 conf->ignore_new_devs = ignore_new_devs;
2152         uxsock_timeout = conf->uxsock_timeout;
2153
2154         old = rcu_dereference(multipath_conf);
2155         rcu_assign_pointer(multipath_conf, conf);
2156         call_rcu(&old->rcu, rcu_free_config);
2157
2158         configure(vecs);
2159
2160
2161         return 0;
2162 }
2163
2164 static struct vectors *
2165 init_vecs (void)
2166 {
2167         struct vectors * vecs;
2168
2169         vecs = (struct vectors *)MALLOC(sizeof(struct vectors));
2170
2171         if (!vecs)
2172                 return NULL;
2173
2174         pthread_mutex_init(&vecs->lock.mutex, NULL);
2175
2176         return vecs;
2177 }
2178
2179 static void *
2180 signal_set(int signo, void (*func) (int))
2181 {
2182         int r;
2183         struct sigaction sig;
2184         struct sigaction osig;
2185
2186         sig.sa_handler = func;
2187         sigemptyset(&sig.sa_mask);
2188         sig.sa_flags = 0;
2189
2190         r = sigaction(signo, &sig, &osig);
2191
2192         if (r < 0)
2193                 return (SIG_ERR);
2194         else
2195                 return (osig.sa_handler);
2196 }
2197
2198 void
2199 handle_signals(bool nonfatal)
2200 {
2201         if (exit_sig) {
2202                 condlog(2, "exit (signal)");
2203                 exit_sig = 0;
2204                 exit_daemon();
2205         }
2206         if (!nonfatal)
2207                 return;
2208         if (reconfig_sig) {
2209                 condlog(2, "reconfigure (signal)");
2210                 set_config_state(DAEMON_CONFIGURE);
2211         }
2212         if (log_reset_sig) {
2213                 condlog(2, "reset log (signal)");
2214                 pthread_mutex_lock(&logq_lock);
2215                 log_reset("multipathd");
2216                 pthread_mutex_unlock(&logq_lock);
2217         }
2218         reconfig_sig = 0;
2219         log_reset_sig = 0;
2220 }
2221
2222 static void
2223 sighup (int sig)
2224 {
2225         reconfig_sig = 1;
2226 }
2227
2228 static void
2229 sigend (int sig)
2230 {
2231         exit_sig = 1;
2232 }
2233
2234 static void
2235 sigusr1 (int sig)
2236 {
2237         log_reset_sig = 1;
2238 }
2239
2240 static void
2241 sigusr2 (int sig)
2242 {
2243         condlog(3, "SIGUSR2 received");
2244 }
2245
2246 static void
2247 signal_init(void)
2248 {
2249         sigset_t set;
2250
2251         /* block all signals */
2252         sigfillset(&set);
2253         /* SIGPIPE occurs if logging fails */
2254         sigdelset(&set, SIGPIPE);
2255         pthread_sigmask(SIG_SETMASK, &set, NULL);
2256
2257         /* Other signals will be unblocked in the uxlsnr thread */
2258         signal_set(SIGHUP, sighup);
2259         signal_set(SIGUSR1, sigusr1);
2260         signal_set(SIGUSR2, sigusr2);
2261         signal_set(SIGINT, sigend);
2262         signal_set(SIGTERM, sigend);
2263         signal_set(SIGPIPE, sigend);
2264 }
2265
2266 static void
2267 setscheduler (void)
2268 {
2269         int res;
2270         static struct sched_param sched_param = {
2271                 .sched_priority = 99
2272         };
2273
2274         res = sched_setscheduler (0, SCHED_RR, &sched_param);
2275
2276         if (res == -1)
2277                 condlog(LOG_WARNING, "Could not set SCHED_RR at priority 99");
2278         return;
2279 }
2280
2281 static void
2282 set_oom_adj (void)
2283 {
2284 #ifdef OOM_SCORE_ADJ_MIN
2285         int retry = 1;
2286         char *file = "/proc/self/oom_score_adj";
2287         int score = OOM_SCORE_ADJ_MIN;
2288 #else
2289         int retry = 0;
2290         char *file = "/proc/self/oom_adj";
2291         int score = OOM_ADJUST_MIN;
2292 #endif
2293         FILE *fp;
2294         struct stat st;
2295         char *envp;
2296
2297         envp = getenv("OOMScoreAdjust");
2298         if (envp) {
2299                 condlog(3, "Using systemd provided OOMScoreAdjust");
2300                 return;
2301         }
2302         do {
2303                 if (stat(file, &st) == 0){
2304                         fp = fopen(file, "w");
2305                         if (!fp) {
2306                                 condlog(0, "couldn't fopen %s : %s", file,
2307                                         strerror(errno));
2308                                 return;
2309                         }
2310                         fprintf(fp, "%i", score);
2311                         fclose(fp);
2312                         return;
2313                 }
2314                 if (errno != ENOENT) {
2315                         condlog(0, "couldn't stat %s : %s", file,
2316                                 strerror(errno));
2317                         return;
2318                 }
2319 #ifdef OOM_ADJUST_MIN
2320                 file = "/proc/self/oom_adj";
2321                 score = OOM_ADJUST_MIN;
2322 #else
2323                 retry = 0;
2324 #endif
2325         } while (retry--);
2326         condlog(0, "couldn't adjust oom score");
2327 }
2328
2329 static int
2330 child (void * param)
2331 {
2332         pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr;
2333         pthread_attr_t log_attr, misc_attr, uevent_attr;
2334         struct vectors * vecs;
2335         struct multipath * mpp;
2336         int i;
2337 #ifdef USE_SYSTEMD
2338         unsigned long checkint;
2339         int startup_done = 0;
2340 #endif
2341         int rc;
2342         int pid_fd = -1;
2343         struct config *conf;
2344         char *envp;
2345
2346         mlockall(MCL_CURRENT | MCL_FUTURE);
2347         signal_init();
2348         rcu_init();
2349
2350         setup_thread_attr(&misc_attr, 64 * 1024, 0);
2351         setup_thread_attr(&uevent_attr, DEFAULT_UEVENT_STACKSIZE * 1024, 0);
2352         setup_thread_attr(&waiter_attr, 32 * 1024, 1);
2353         setup_thread_attr(&io_err_stat_attr, 32 * 1024, 0);
2354
2355         if (logsink == 1) {
2356                 setup_thread_attr(&log_attr, 64 * 1024, 0);
2357                 log_thread_start(&log_attr);
2358                 pthread_attr_destroy(&log_attr);
2359         }
2360         pid_fd = pidfile_create(DEFAULT_PIDFILE, daemon_pid);
2361         if (pid_fd < 0) {
2362                 condlog(1, "failed to create pidfile");
2363                 if (logsink == 1)
2364                         log_thread_stop();
2365                 exit(1);
2366         }
2367
2368         post_config_state(DAEMON_START);
2369
2370         condlog(2, "--------start up--------");
2371         condlog(2, "read " DEFAULT_CONFIGFILE);
2372
2373         conf = load_config(DEFAULT_CONFIGFILE);
2374         if (!conf)
2375                 goto failed;
2376
2377         if (verbosity)
2378                 conf->verbosity = verbosity;
2379         if (bindings_read_only)
2380                 conf->bindings_read_only = bindings_read_only;
2381         if (ignore_new_devs)
2382                 conf->ignore_new_devs = ignore_new_devs;
2383         uxsock_timeout = conf->uxsock_timeout;
2384         rcu_assign_pointer(multipath_conf, conf);
2385         if (init_checkers(conf->multipath_dir)) {
2386                 condlog(0, "failed to initialize checkers");
2387                 goto failed;
2388         }
2389         if (init_prio(conf->multipath_dir)) {
2390                 condlog(0, "failed to initialize prioritizers");
2391                 goto failed;
2392         }
2393         /* Failing this is non-fatal */
2394
2395         init_foreign(conf->multipath_dir);
2396
2397         setlogmask(LOG_UPTO(conf->verbosity + 3));
2398
2399         envp = getenv("LimitNOFILE");
2400
2401         if (envp) {
2402                 condlog(2,"Using systemd provided open fds limit of %s", envp);
2403         } else if (conf->max_fds) {
2404                 struct rlimit fd_limit;
2405
2406                 if (getrlimit(RLIMIT_NOFILE, &fd_limit) < 0) {
2407                         condlog(0, "can't get open fds limit: %s",
2408                                 strerror(errno));
2409                         fd_limit.rlim_cur = 0;
2410                         fd_limit.rlim_max = 0;
2411                 }
2412                 if (fd_limit.rlim_cur < conf->max_fds) {
2413                         fd_limit.rlim_cur = conf->max_fds;
2414                         if (fd_limit.rlim_max < conf->max_fds)
2415                                 fd_limit.rlim_max = conf->max_fds;
2416                         if (setrlimit(RLIMIT_NOFILE, &fd_limit) < 0) {
2417                                 condlog(0, "can't set open fds limit to "
2418                                         "%lu/%lu : %s",
2419                                         fd_limit.rlim_cur, fd_limit.rlim_max,
2420                                         strerror(errno));
2421                         } else {
2422                                 condlog(3, "set open fds limit to %lu/%lu",
2423                                         fd_limit.rlim_cur, fd_limit.rlim_max);
2424                         }
2425                 }
2426
2427         }
2428
2429         vecs = gvecs = init_vecs();
2430         if (!vecs)
2431                 goto failed;
2432
2433         setscheduler();
2434         set_oom_adj();
2435
2436 #ifdef USE_SYSTEMD
2437         envp = getenv("WATCHDOG_USEC");
2438         if (envp && sscanf(envp, "%lu", &checkint) == 1) {
2439                 /* Value is in microseconds */
2440                 conf->max_checkint = checkint / 1000000;
2441                 /* Rescale checkint */
2442                 if (conf->checkint > conf->max_checkint)
2443                         conf->checkint = conf->max_checkint;
2444                 else
2445                         conf->checkint = conf->max_checkint / 4;
2446                 condlog(3, "enabling watchdog, interval %d max %d",
2447                         conf->checkint, conf->max_checkint);
2448                 use_watchdog = conf->checkint;
2449         }
2450 #endif
2451         /*
2452          * Startup done, invalidate configuration
2453          */
2454         conf = NULL;
2455
2456         /*
2457          * Signal start of configuration
2458          */
2459         post_config_state(DAEMON_CONFIGURE);
2460
2461         init_path_check_interval(vecs);
2462
2463         /*
2464          * Start uevent listener early to catch events
2465          */
2466         if ((rc = pthread_create(&uevent_thr, &uevent_attr, ueventloop, udev))) {
2467                 condlog(0, "failed to create uevent thread: %d", rc);
2468                 goto failed;
2469         }
2470         pthread_attr_destroy(&uevent_attr);
2471         if ((rc = pthread_create(&uxlsnr_thr, &misc_attr, uxlsnrloop, vecs))) {
2472                 condlog(0, "failed to create cli listener: %d", rc);
2473                 goto failed;
2474         }
2475
2476         /*
2477          * start threads
2478          */
2479         if ((rc = pthread_create(&check_thr, &misc_attr, checkerloop, vecs))) {
2480                 condlog(0,"failed to create checker loop thread: %d", rc);
2481                 goto failed;
2482         }
2483         if ((rc = pthread_create(&uevq_thr, &misc_attr, uevqloop, vecs))) {
2484                 condlog(0, "failed to create uevent dispatcher: %d", rc);
2485                 goto failed;
2486         }
2487         pthread_attr_destroy(&misc_attr);
2488
2489         while (running_state != DAEMON_SHUTDOWN) {
2490                 pthread_cleanup_push(config_cleanup, NULL);
2491                 pthread_mutex_lock(&config_lock);
2492                 if (running_state != DAEMON_CONFIGURE &&
2493                     running_state != DAEMON_SHUTDOWN) {
2494                         pthread_cond_wait(&config_cond, &config_lock);
2495                 }
2496                 pthread_cleanup_pop(1);
2497                 if (running_state == DAEMON_CONFIGURE) {
2498                         pthread_cleanup_push(cleanup_lock, &vecs->lock);
2499                         lock(&vecs->lock);
2500                         pthread_testcancel();
2501                         if (!need_to_delay_reconfig(vecs)) {
2502                                 reconfigure(vecs);
2503                         } else {
2504                                 conf = get_multipath_config();
2505                                 conf->delayed_reconfig = 1;
2506                                 put_multipath_config(conf);
2507                         }
2508                         lock_cleanup_pop(vecs->lock);
2509                         post_config_state(DAEMON_IDLE);
2510 #ifdef USE_SYSTEMD
2511                         if (!startup_done) {
2512                                 sd_notify(0, "READY=1");
2513                                 startup_done = 1;
2514                         }
2515 #endif
2516                 }
2517         }
2518
2519         lock(&vecs->lock);
2520         conf = get_multipath_config();
2521         if (conf->queue_without_daemon == QUE_NO_DAEMON_OFF)
2522                 vector_foreach_slot(vecs->mpvec, mpp, i)
2523                         dm_queue_if_no_path(mpp->alias, 0);
2524         put_multipath_config(conf);
2525         remove_maps_and_stop_waiters(vecs);
2526         unlock(&vecs->lock);
2527
2528         pthread_cancel(check_thr);
2529         pthread_cancel(uevent_thr);
2530         pthread_cancel(uxlsnr_thr);
2531         pthread_cancel(uevq_thr);
2532
2533         pthread_join(check_thr, NULL);
2534         pthread_join(uevent_thr, NULL);
2535         pthread_join(uxlsnr_thr, NULL);
2536         pthread_join(uevq_thr, NULL);
2537
2538         stop_io_err_stat_thread();
2539
2540         lock(&vecs->lock);
2541         free_pathvec(vecs->pathvec, FREE_PATHS);
2542         vecs->pathvec = NULL;
2543         unlock(&vecs->lock);
2544
2545         pthread_mutex_destroy(&vecs->lock.mutex);
2546         FREE(vecs);
2547         vecs = NULL;
2548
2549         cleanup_foreign();
2550         cleanup_checkers();
2551         cleanup_prio();
2552
2553         dm_lib_release();
2554         dm_lib_exit();
2555
2556         /* We're done here */
2557         condlog(3, "unlink pidfile");
2558         unlink(DEFAULT_PIDFILE);
2559
2560         condlog(2, "--------shut down-------");
2561
2562         if (logsink == 1)
2563                 log_thread_stop();
2564
2565         /*
2566          * Freeing config must be done after condlog() and dm_lib_exit(),
2567          * because logging functions like dlog() and dm_write_log()
2568          * reference the config.
2569          */
2570         conf = rcu_dereference(multipath_conf);
2571         rcu_assign_pointer(multipath_conf, NULL);
2572         call_rcu(&conf->rcu, rcu_free_config);
2573         udev_unref(udev);
2574         udev = NULL;
2575         pthread_attr_destroy(&waiter_attr);
2576         pthread_attr_destroy(&io_err_stat_attr);
2577 #ifdef _DEBUG_
2578         dbg_free_final(NULL);
2579 #endif
2580
2581 #ifdef USE_SYSTEMD
2582         sd_notify(0, "ERRNO=0");
2583 #endif
2584         exit(0);
2585
2586 failed:
2587 #ifdef USE_SYSTEMD
2588         sd_notify(0, "ERRNO=1");
2589 #endif
2590         if (pid_fd >= 0)
2591                 close(pid_fd);
2592         exit(1);
2593 }
2594
2595 static int
2596 daemonize(void)
2597 {
2598         int pid;
2599         int dev_null_fd;
2600
2601         if( (pid = fork()) < 0){
2602                 fprintf(stderr, "Failed first fork : %s\n", strerror(errno));
2603                 return -1;
2604         }
2605         else if (pid != 0)
2606                 return pid;
2607
2608         setsid();
2609
2610         if ( (pid = fork()) < 0)
2611                 fprintf(stderr, "Failed second fork : %s\n", strerror(errno));
2612         else if (pid != 0)
2613                 _exit(0);
2614
2615         if (chdir("/") < 0)
2616                 fprintf(stderr, "cannot chdir to '/', continuing\n");
2617
2618         dev_null_fd = open("/dev/null", O_RDWR);
2619         if (dev_null_fd < 0){
2620                 fprintf(stderr, "cannot open /dev/null for input & output : %s\n",
2621                         strerror(errno));
2622                 _exit(0);
2623         }
2624
2625         close(STDIN_FILENO);
2626         if (dup(dev_null_fd) < 0) {
2627                 fprintf(stderr, "cannot dup /dev/null to stdin : %s\n",
2628                         strerror(errno));
2629                 _exit(0);
2630         }
2631         close(STDOUT_FILENO);
2632         if (dup(dev_null_fd) < 0) {
2633                 fprintf(stderr, "cannot dup /dev/null to stdout : %s\n",
2634                         strerror(errno));
2635                 _exit(0);
2636         }
2637         close(STDERR_FILENO);
2638         if (dup(dev_null_fd) < 0) {
2639                 fprintf(stderr, "cannot dup /dev/null to stderr : %s\n",
2640                         strerror(errno));
2641                 _exit(0);
2642         }
2643         close(dev_null_fd);
2644         daemon_pid = getpid();
2645         return 0;
2646 }
2647
2648 int
2649 main (int argc, char *argv[])
2650 {
2651         extern char *optarg;
2652         extern int optind;
2653         int arg;
2654         int err;
2655         int foreground = 0;
2656         struct config *conf;
2657
2658         ANNOTATE_BENIGN_RACE_SIZED(&multipath_conf, sizeof(multipath_conf),
2659                                    "Manipulated through RCU");
2660         ANNOTATE_BENIGN_RACE_SIZED(&running_state, sizeof(running_state),
2661                 "Suppress complaints about unprotected running_state reads");
2662         ANNOTATE_BENIGN_RACE_SIZED(&uxsock_timeout, sizeof(uxsock_timeout),
2663                 "Suppress complaints about this scalar variable");
2664
2665         logsink = 1;
2666
2667         if (getuid() != 0) {
2668                 fprintf(stderr, "need to be root\n");
2669                 exit(1);
2670         }
2671
2672         /* make sure we don't lock any path */
2673         if (chdir("/") < 0)
2674                 fprintf(stderr, "can't chdir to root directory : %s\n",
2675                         strerror(errno));
2676         umask(umask(077) | 022);
2677
2678         pthread_cond_init_mono(&config_cond);
2679
2680         udev = udev_new();
2681         libmp_udev_set_sync_support(0);
2682
2683         while ((arg = getopt(argc, argv, ":dsv:k::Bn")) != EOF ) {
2684                 switch(arg) {
2685                 case 'd':
2686                         foreground = 1;
2687                         if (logsink > 0)
2688                                 logsink = 0;
2689                         //debug=1; /* ### comment me out ### */
2690                         break;
2691                 case 'v':
2692                         if (sizeof(optarg) > sizeof(char *) ||
2693                             !isdigit(optarg[0]))
2694                                 exit(1);
2695
2696                         verbosity = atoi(optarg);
2697                         break;
2698                 case 's':
2699                         logsink = -1;
2700                         break;
2701                 case 'k':
2702                         conf = load_config(DEFAULT_CONFIGFILE);
2703                         if (!conf)
2704                                 exit(1);
2705                         if (verbosity)
2706                                 conf->verbosity = verbosity;
2707                         uxsock_timeout = conf->uxsock_timeout;
2708                         uxclnt(optarg, uxsock_timeout + 100);
2709                         free_config(conf);
2710                         exit(0);
2711                 case 'B':
2712                         bindings_read_only = 1;
2713                         break;
2714                 case 'n':
2715                         ignore_new_devs = 1;
2716                         break;
2717                 default:
2718                         fprintf(stderr, "Invalid argument '-%c'\n",
2719                                 optopt);
2720                         exit(1);
2721                 }
2722         }
2723         if (optind < argc) {
2724                 char cmd[CMDSIZE];
2725                 char * s = cmd;
2726                 char * c = s;
2727
2728                 conf = load_config(DEFAULT_CONFIGFILE);
2729                 if (!conf)
2730                         exit(1);
2731                 if (verbosity)
2732                         conf->verbosity = verbosity;
2733                 uxsock_timeout = conf->uxsock_timeout;
2734                 memset(cmd, 0x0, CMDSIZE);
2735                 while (optind < argc) {
2736                         if (strchr(argv[optind], ' '))
2737                                 c += snprintf(c, s + CMDSIZE - c, "\"%s\" ", argv[optind]);
2738                         else
2739                                 c += snprintf(c, s + CMDSIZE - c, "%s ", argv[optind]);
2740                         optind++;
2741                 }
2742                 c += snprintf(c, s + CMDSIZE - c, "\n");
2743                 uxclnt(s, uxsock_timeout + 100);
2744                 free_config(conf);
2745                 exit(0);
2746         }
2747
2748         if (foreground) {
2749                 if (!isatty(fileno(stdout)))
2750                         setbuf(stdout, NULL);
2751                 err = 0;
2752                 daemon_pid = getpid();
2753         } else
2754                 err = daemonize();
2755
2756         if (err < 0)
2757                 /* error */
2758                 exit(1);
2759         else if (err > 0)
2760                 /* parent dies */
2761                 exit(0);
2762         else
2763                 /* child lives */
2764                 return (child(NULL));
2765 }
2766
2767 void *  mpath_pr_event_handler_fn (void * pathp )
2768 {
2769         struct multipath * mpp;
2770         int i, ret, isFound;
2771         struct path * pp = (struct path *)pathp;
2772         struct prout_param_descriptor *param;
2773         struct prin_resp *resp;
2774
2775         mpp = pp->mpp;
2776
2777         resp = mpath_alloc_prin_response(MPATH_PRIN_RKEY_SA);
2778         if (!resp){
2779                 condlog(0,"%s Alloc failed for prin response", pp->dev);
2780                 return NULL;
2781         }
2782
2783         ret = prin_do_scsi_ioctl(pp->dev, MPATH_PRIN_RKEY_SA, resp, 0);
2784         if (ret != MPATH_PR_SUCCESS )
2785         {
2786                 condlog(0,"%s : pr in read keys service action failed. Error=%d", pp->dev, ret);
2787                 goto out;
2788         }
2789
2790         condlog(3, " event pr=%d addlen=%d",resp->prin_descriptor.prin_readkeys.prgeneration,
2791                         resp->prin_descriptor.prin_readkeys.additional_length );
2792
2793         if (resp->prin_descriptor.prin_readkeys.additional_length == 0 )
2794         {
2795                 condlog(1, "%s: No key found. Device may not be registered.", pp->dev);
2796                 ret = MPATH_PR_SUCCESS;
2797                 goto out;
2798         }
2799         condlog(2, "Multipath  reservation_key: 0x%" PRIx64 " ",
2800                 get_be64(mpp->reservation_key));
2801
2802         isFound =0;
2803         for (i = 0; i < resp->prin_descriptor.prin_readkeys.additional_length/8; i++ )
2804         {
2805                 condlog(2, "PR IN READKEYS[%d]  reservation key:",i);
2806                 dumpHex((char *)&resp->prin_descriptor.prin_readkeys.key_list[i*8], 8 , -1);
2807                 if (!memcmp(&mpp->reservation_key, &resp->prin_descriptor.prin_readkeys.key_list[i*8], 8))
2808                 {
2809                         condlog(2, "%s: pr key found in prin readkeys response", mpp->alias);
2810                         isFound =1;
2811                         break;
2812                 }
2813         }
2814         if (!isFound)
2815         {
2816                 condlog(0, "%s: Either device not registered or ", pp->dev);
2817                 condlog(0, "host is not authorised for registration. Skip path");
2818                 ret = MPATH_PR_OTHER;
2819                 goto out;
2820         }
2821
2822         param= malloc(sizeof(struct prout_param_descriptor));
2823         memset(param, 0 , sizeof(struct prout_param_descriptor));
2824         memcpy(param->sa_key, &mpp->reservation_key, 8);
2825         param->num_transportid = 0;
2826
2827         condlog(3, "device %s:%s", pp->dev, pp->mpp->wwid);
2828
2829         ret = prout_do_scsi_ioctl(pp->dev, MPATH_PROUT_REG_IGN_SA, 0, 0, param, 0);
2830         if (ret != MPATH_PR_SUCCESS )
2831         {
2832                 condlog(0,"%s: Reservation registration failed. Error: %d", pp->dev, ret);
2833         }
2834         mpp->prflag = 1;
2835
2836         free(param);
2837 out:
2838         free(resp);
2839         return NULL;
2840 }
2841
2842 int mpath_pr_event_handle(struct path *pp)
2843 {
2844         pthread_t thread;
2845         int rc;
2846         pthread_attr_t attr;
2847         struct multipath * mpp;
2848
2849         mpp = pp->mpp;
2850
2851         if (get_be64(mpp->reservation_key))
2852                 return -1;
2853
2854         pthread_attr_init(&attr);
2855         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
2856
2857         rc = pthread_create(&thread, NULL , mpath_pr_event_handler_fn, pp);
2858         if (rc) {
2859                 condlog(0, "%s: ERROR; return code from pthread_create() is %d", pp->dev, rc);
2860                 return -1;
2861         }
2862         pthread_attr_destroy(&attr);
2863         rc = pthread_join(thread, NULL);
2864         return 0;
2865 }