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