[libmultipath] move coalesce_path() to libmultipath/configure.c
authorChristophe Varoqui <root@xa-s05.(none)>
Thu, 17 Nov 2005 15:50:43 +0000 (16:50 +0100)
committerChristophe Varoqui <root@xa-s05.(none)>
Thu, 17 Nov 2005 15:50:43 +0000 (16:50 +0100)
and consequences ...

- coalesce_paths() and all functions used only in this code path are
  folded into configure.c
- move print_*() to libmultipath/print.c, although they are only needed
  for multipath(8) (in their current form)
- declare {map,path}_layout as globals in print.c so we can now remove
  them from the parameter list in all print.c-exported functions

Now we can use coalesce_path() from multipathd.

libmultipath/Makefile
libmultipath/configure.c [new file with mode: 0644]
libmultipath/configure.h [new file with mode: 0644]
libmultipath/print.c
libmultipath/print.h
multipath/main.c
multipath/main.h
multipathd/main.c

index 0e2bfa3..441aad1 100644 (file)
@@ -11,7 +11,7 @@ OBJS = memory.o parser.o vector.o devmapper.o callout.o \
        structs.o cache.o discovery.o propsel.o dict.o \
        pgpolicies.o debug.o regex.o defaults.o uevent.o \
        switchgroup.o uxsock.o print.o alias.o log_pthread.o \
-       log.o
+       log.o configure.o
 
 CFLAGS = -pipe -g -Wall -Wunused -Wstrict-prototypes
 
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
new file mode 100644 (file)
index 0000000..16d6472
--- /dev/null
@@ -0,0 +1,481 @@
+/*
+ * Copyright (c) 2003, 2004, 2005 Christophe Varoqui
+ * Copyright (c) 2005 Benjamin Marzinski, Redhat
+ * Copyright (c) 2005 Kiyoshi Ueda, NEC
+ * Copyright (c) 2005 Patrick Caulfield, Redhat
+ * Copyright (c) 2005 Edward Goggin, EMC
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/file.h>
+#include <errno.h>
+#include <libdevmapper.h>
+
+#include "../libcheckers/path_state.h"
+#include "vector.h"
+#include "memory.h"
+#include "devmapper.h"
+#include "blacklist.h"
+#include "defaults.h"
+#include "structs.h"
+#include "dmparser.h"
+#include "config.h"
+#include "propsel.h"
+#include "discovery.h"
+#include "debug.h"
+#include "switchgroup.h"
+#include "print.h"
+#include "configure.h"
+#include "pgpolicies.h"
+#include "dict.h"
+
+static int
+setup_map (struct multipath * mpp)
+{
+       struct pathgroup * pgp;
+       int i;
+       
+       /*
+        * don't bother if devmap size is unknown
+        */
+       if (mpp->size <= 0) {
+               condlog(3, "%s: devmap size is unknown", mpp->alias);
+               return 1;
+       }
+
+       /*
+        * properties selectors
+        */
+       select_pgfailback(mpp);
+       select_pgpolicy(mpp);
+       select_selector(mpp);
+       select_features(mpp);
+       select_hwhandler(mpp);
+       select_rr_weight(mpp);
+       select_minio(mpp);
+       select_no_path_retry(mpp);
+
+       /*
+        * assign paths to path groups -- start with no groups and all paths
+        * in mpp->paths
+        */
+       if (mpp->pg) {
+               vector_foreach_slot (mpp->pg, pgp, i)
+                       free_pathgroup(pgp, KEEP_PATHS);
+
+               vector_free(mpp->pg);
+               mpp->pg = NULL;
+       }
+       if (mpp->pgpolicyfn && mpp->pgpolicyfn(mpp))
+               return 1;
+
+       mpp->nr_active = pathcount(mpp, PATH_UP);
+
+       /*
+        * ponders each path group and determine highest prio pg
+        * to switch over (default to first)
+        */
+       mpp->bestpg = select_path_group(mpp);
+
+       /*
+        * transform the mp->pg vector of vectors of paths
+        * into a mp->params strings to feed the device-mapper
+        */
+       if (assemble_map(mpp)) {
+               condlog(0, "%s: problem assembing map", mpp->alias);
+               return 1;
+       }
+       return 0;
+}
+
+static void
+compute_pgid(struct pathgroup * pgp)
+{
+       struct path * pp;
+       int i;
+
+       vector_foreach_slot (pgp->paths, pp, i)
+               pgp->id ^= (long)pp;
+}
+
+static int
+pgcmp (struct multipath * mpp, struct multipath * cmpp)
+{
+       int i, j;
+       struct pathgroup * pgp;
+       struct pathgroup * cpgp;
+       int r = 0;
+
+       vector_foreach_slot (mpp->pg, pgp, i) {
+               compute_pgid(pgp);
+
+               vector_foreach_slot (cmpp->pg, cpgp, j) {
+                       if (pgp->id == cpgp->id) {
+                               r = 0;
+                               break;
+                       }
+                       r++;
+               }
+               if (r)
+                       return r;
+       }
+       return r;
+}
+
+static void
+select_action (struct multipath * mpp, vector curmp)
+{
+       struct multipath * cmpp;
+
+       cmpp = find_mp_by_alias(curmp, mpp->alias);
+
+       if (!cmpp) {
+               cmpp = find_mp_by_wwid(curmp, mpp->wwid);
+
+               if (cmpp && !conf->dry_run) {
+                       condlog(2, "remove: %s (dup of %s)",
+                               cmpp->alias, mpp->alias);
+                       dm_flush_map(cmpp->alias, DEFAULT_TARGET);
+               }
+               mpp->action = ACT_CREATE;
+               condlog(3, "set ACT_CREATE: map does not exists");
+               return;
+       }
+
+       if (!find_mp_by_wwid(curmp, mpp->wwid)) {
+               condlog(2, "remove: %s (wwid changed)", cmpp->alias);
+               dm_flush_map(mpp->alias, NULL);
+               strncat(cmpp->wwid, mpp->wwid, WWID_SIZE);
+               drop_multipath(curmp, cmpp->wwid, KEEP_PATHS);
+               mpp->action = ACT_CREATE;
+               condlog(3, "set ACT_CREATE: map wwid change");
+               return;
+       }
+               
+       if (pathcount(mpp, PATH_UP) == 0) {
+               mpp->action = ACT_NOTHING;
+               condlog(3, "set ACT_NOTHING: no usable path");
+               return;
+       }
+       if (cmpp->size != mpp->size) {
+               mpp->action = ACT_RELOAD;
+               condlog(3, "set ACT_RELOAD: size change");
+               return;
+       }
+       if (!mpp->no_path_retry && /* let features be handled by the daemon */
+           strncmp(cmpp->features, mpp->features, strlen(mpp->features))) {
+               mpp->action =  ACT_RELOAD;
+               condlog(3, "set ACT_RELOAD: features change");
+               return;
+       }
+       if (strncmp(cmpp->hwhandler, mpp->hwhandler,
+                   strlen(mpp->hwhandler))) {
+               mpp->action = ACT_RELOAD;
+               condlog(3, "set ACT_RELOAD: hwhandler change");
+               return;
+       }
+       if (strncmp(cmpp->selector, mpp->selector,
+                   strlen(mpp->selector))) {
+               mpp->action = ACT_RELOAD;
+               condlog(3, "set ACT_RELOAD: selector change");
+               return;
+       }
+       if (cmpp->minio != mpp->minio) {
+               mpp->action = ACT_RELOAD;
+               condlog(3, "set ACT_RELOAD: minio change (%u->%u)",
+                       cmpp->minio, mpp->minio);
+               return;
+       }
+       if (VECTOR_SIZE(cmpp->pg) != VECTOR_SIZE(mpp->pg)) {
+               mpp->action = ACT_RELOAD;
+               condlog(3, "set ACT_RELOAD: number of path group change");
+               return;
+       }
+       if (pgcmp(mpp, cmpp)) {
+               mpp->action = ACT_RELOAD;
+               condlog(3, "set ACT_RELOAD: path group topology change");
+               return;
+       }
+       if (cmpp->nextpg != mpp->bestpg) {
+               mpp->action = ACT_SWITCHPG;
+               condlog(3, "set ACT_SWITCHPG: next path group change");
+               return;
+       }
+       mpp->action = ACT_NOTHING;
+       condlog(3, "set ACT_NOTHING: map unchanged");
+       return;
+}
+
+extern int
+reinstate_paths (struct multipath * mpp)
+{
+       int i, j;
+       struct pathgroup * pgp;
+       struct path * pp;
+
+       if (!mpp->pg)
+               return 0;
+
+       vector_foreach_slot (mpp->pg, pgp, i) {
+               if (!pgp->paths)
+                       continue;
+
+               vector_foreach_slot (pgp->paths, pp, j) {
+                       if (pp->state != PATH_UP &&
+                           (pgp->status == PGSTATE_DISABLED ||
+                            pgp->status == PGSTATE_ACTIVE))
+                               continue;
+
+                       if (pp->dmstate == PSTATE_FAILED) {
+                               if (dm_reinstate_path(mpp->alias, pp->dev_t))
+                                       condlog(0, "error reinstating %s",
+                                               pp->dev);
+                       }
+               }
+       }
+       return 0;
+}
+
+static int
+lock_multipath (struct multipath * mpp, int lock)
+{
+       struct pathgroup * pgp;
+       struct path * pp;
+       int i, j;
+
+       if (!mpp || !mpp->pg)
+               return 0;
+       
+       vector_foreach_slot (mpp->pg, pgp, i) {
+               if (!pgp->paths)
+                       continue;
+               vector_foreach_slot(pgp->paths, pp, j) {
+                       if (lock && flock(pp->fd, LOCK_EX | LOCK_NB) &&
+                           errno == EWOULDBLOCK)
+                               return 1;
+                       else if (!lock)
+                               flock(pp->fd, LOCK_UN);
+               }
+       }
+       return 0;
+}
+
+/*
+ * Return value:
+ *  -1: Retry
+ *   0: DM_DEVICE_CREATE or DM_DEVICE_RELOAD failed, or dry_run mode.
+ *   1: DM_DEVICE_CREATE or DM_DEVICE_RELOAD succeeded.
+ *   2: Map is already existing.
+ */
+static int
+domap (struct multipath * mpp)
+{
+       int r = 0;
+
+       /*
+        * last chance to quit before touching the devmaps
+        */
+       if (conf->dry_run) {
+               print_mp(mpp, conf->verbosity);
+               return 0;
+       }
+
+       switch (mpp->action) {
+       case ACT_NOTHING:
+               return 2;
+
+       case ACT_SWITCHPG:
+               dm_switchgroup(mpp->alias, mpp->bestpg);
+               /*
+                * we may have avoided reinstating paths because there where in
+                * active or disabled PG. Now that the topology has changed,
+                * retry.
+                */
+               reinstate_paths(mpp);
+               return 2;
+
+       case ACT_CREATE:
+               if (lock_multipath(mpp, 1)) {
+                       condlog(3, "%s: in use", mpp->alias);
+                       return -1;
+               }
+               dm_shut_log();
+
+               if (dm_map_present(mpp->alias))
+                       break;
+
+               r = dm_addmap(DM_DEVICE_CREATE, mpp->alias, DEFAULT_TARGET,
+                             mpp->params, mpp->size, mpp->wwid);
+
+               /*
+                * DM_DEVICE_CREATE is actually DM_DEV_CREATE plus
+                * DM_TABLE_LOAD. Failing the second part leaves an
+                * empty map. Clean it up.
+                */
+               if (!r && dm_map_present(mpp->alias)) {
+                       condlog(3, "%s: failed to load map "
+                                  "(a path might be in use)",
+                                  mpp->alias);
+                       dm_flush_map(mpp->alias, NULL);
+               }
+
+               lock_multipath(mpp, 0);
+               dm_restore_log();
+               break;
+
+       case ACT_RELOAD:
+               r = (dm_addmap(DM_DEVICE_RELOAD, mpp->alias, DEFAULT_TARGET,
+                             mpp->params, mpp->size, NULL) &&
+                    dm_simplecmd(DM_DEVICE_RESUME, mpp->alias));
+               break;
+
+       default:
+               break;
+       }
+
+       if (r) {
+               /*
+                * DM_DEVICE_CREATE or DM_DEVICE_RELOAD succeeded
+                */
+               dm_switchgroup(mpp->alias, mpp->bestpg);
+               print_mp(mpp, conf->verbosity);
+       }
+
+       return r;
+}
+
+static int
+deadmap (struct multipath * mpp)
+{
+       int i, j;
+       struct pathgroup * pgp;
+       struct path * pp;
+
+       if (!mpp->pg)
+               return 1;
+
+       vector_foreach_slot (mpp->pg, pgp, i) {
+               if (!pgp->paths)
+                       continue;
+
+               vector_foreach_slot (pgp->paths, pp, j)
+                       if (strlen(pp->dev))
+                               return 0; /* alive */
+       }
+       
+       return 1; /* dead */
+}
+
+extern int
+coalesce_paths (vector curmp, vector pathvec)
+{
+       int r = 1;
+       int k, i;
+       char empty_buff[WWID_SIZE];
+       struct multipath * mpp;
+       struct path * pp1;
+       struct path * pp2;
+
+       memset(empty_buff, 0, WWID_SIZE);
+
+       vector_foreach_slot (pathvec, pp1, k) {
+               /* skip this path for some reason */
+
+               /* 1. if path has no unique id or wwid blacklisted */
+               if (memcmp(empty_buff, pp1->wwid, WWID_SIZE) == 0 ||
+                   blacklist(conf->blist, pp1->wwid))
+                       continue;
+
+               /* 2. if path already coalesced */
+               if (pp1->mpp)
+                       continue;
+
+               /*
+                * at this point, we know we really got a new mp
+                */
+               mpp = alloc_multipath();
+
+               if (!mpp)
+                       return 1;
+
+               mpp->mpe = find_mpe(pp1->wwid);
+               mpp->hwe = pp1->hwe;
+               strcpy(mpp->wwid, pp1->wwid);
+               select_alias(mpp);
+
+               pp1->mpp = mpp;
+               mpp->size = pp1->size;
+               mpp->paths = vector_alloc();
+
+               if (pp1->priority < 0)
+                       mpp->action = ACT_NOTHING;
+
+               if (!mpp->paths)
+                       return 1;
+               
+               if (store_path(mpp->paths, pp1))
+                       return 1;
+
+               for (i = k + 1; i < VECTOR_SIZE(pathvec); i++) {
+                       pp2 = VECTOR_SLOT(pathvec, i);
+
+                       if (strcmp(pp1->wwid, pp2->wwid))
+                               continue;
+                       
+                       pp2->mpp = mpp;
+
+                       if (pp2->size != mpp->size) {
+                               /*
+                                * ouch, avoid feeding that to the DM
+                                */
+                               condlog(3, "path size mismatch : discard %s",
+                                    mpp->wwid);
+                               mpp->action = ACT_NOTHING;
+                       }
+                       if (pp2->priority < 0)
+                               mpp->action = ACT_NOTHING;
+
+                       if (store_path(mpp->paths, pp2))
+                               return 1;
+               }
+               if (setup_map(mpp))
+                       goto next;
+
+               if (mpp->action == ACT_UNDEF)
+                       select_action(mpp, curmp);
+
+               r = domap(mpp);
+
+               if (r < 0)
+                       return r;
+
+               if (r && mpp->no_path_retry != NO_PATH_RETRY_UNDEF) {
+                       if (mpp->no_path_retry == NO_PATH_RETRY_FAIL)
+                               dm_queue_if_no_path(mpp->alias, 0);
+                       else
+                               dm_queue_if_no_path(mpp->alias, 1);
+               }
+
+next:
+               drop_multipath(curmp, mpp->wwid, KEEP_PATHS);
+               free_multipath(mpp, KEEP_PATHS);
+       }
+       /*
+        * Flush maps with only dead paths (ie not in sysfs)
+        * Keep maps with only failed paths
+        */
+       vector_foreach_slot (curmp, mpp, i) {
+               if (!deadmap(mpp))
+                       continue;
+
+               if (dm_flush_map(mpp->alias, DEFAULT_TARGET))
+                       condlog(2, "remove: %s (dead) failed!",
+                               mpp->alias);
+               else
+                       condlog(2, "remove: %s (dead)", mpp->alias);
+       }
+       return 0;
+}
diff --git a/libmultipath/configure.h b/libmultipath/configure.h
new file mode 100644 (file)
index 0000000..26d125a
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * configurator actions
+ */
+#define ACT_NOTHING_STR         "unchanged"
+#define ACT_RELOAD_STR          "reload"
+#define ACT_SWITCHPG_STR        "switchpg"
+#define ACT_CREATE_STR          "create"
+
+enum actions {
+       ACT_UNDEF,
+       ACT_NOTHING,
+       ACT_RELOAD,
+       ACT_SWITCHPG,
+       ACT_CREATE
+};
+
+#define FLUSH_ONE 1
+#define FLUSH_ALL 2
+
+int reinstate_paths (struct multipath * mpp);
+int coalesce_paths (vector curmp, vector pathvec);
index 0b14eae..41f0005 100644 (file)
@@ -10,6 +10,8 @@
 #include "structs.h"
 #include "print.h"
 #include "dmparser.h"
+#include "configure.h"
+#include "defaults.h"
 
 #include "../libcheckers/path_state.h"
 
 
 #define MAX(x,y) (x > y) ? x : y
 
+/* for column aligned output */
+struct path_layout pl;
+struct map_layout ml;
+
 void
-get_path_layout (struct path_layout * pl, vector pathvec)
+get_path_layout (vector pathvec)
 {
        int i;
        char buff[MAX_FIELD_LEN];
@@ -31,11 +37,11 @@ get_path_layout (struct path_layout * pl, vector pathvec)
        int prio_len;
 
        /* reset max col lengths */
-       pl->uuid_len = 0;
-       pl->hbtl_len = 0;
-       pl->dev_len = 0;
-       pl->dev_t_len = 0;
-       pl->prio_len = 0;
+       pl.uuid_len = 0;
+       pl.hbtl_len = 0;
+       pl.dev_len = 0;
+       pl.dev_t_len = 0;
+       pl.prio_len = 0;
 
        vector_foreach_slot (pathvec, pp, i) {
                uuid_len = strlen(pp->wwid);
@@ -48,17 +54,17 @@ get_path_layout (struct path_layout * pl, vector pathvec)
                dev_t_len = strlen(pp->dev_t);
                prio_len = 1 + (int)log10(pp->priority);
 
-               pl->uuid_len = MAX(uuid_len, pl->uuid_len);
-               pl->hbtl_len = MAX(hbtl_len, pl->hbtl_len);
-               pl->dev_len = MAX(dev_len, pl->dev_len);
-               pl->dev_t_len = MAX(dev_t_len, pl->dev_t_len);
-               pl->prio_len = MAX(prio_len, pl->prio_len);
+               pl.uuid_len = MAX(uuid_len, pl.uuid_len);
+               pl.hbtl_len = MAX(hbtl_len, pl.hbtl_len);
+               pl.dev_len = MAX(dev_len, pl.dev_len);
+               pl.dev_t_len = MAX(dev_t_len, pl.dev_t_len);
+               pl.prio_len = MAX(prio_len, pl.prio_len);
        }
        return;
 }
 
 void
-get_map_layout (struct map_layout * ml, vector mpvec)
+get_map_layout (vector mpvec)
 {
        int i;
        char buff[MAX_FIELD_LEN];
@@ -71,11 +77,11 @@ get_map_layout (struct map_layout * ml, vector mpvec)
        int nr_active_len;
 
        /* reset max col lengths */
-       ml->mapname_len = 0;
-       ml->mapdev_len = 0;
-       ml->failback_progress_len = 0;
-       ml->queueing_progress_len = 0;
-       ml->nr_active_len = 0;
+       ml.mapname_len = 0;
+       ml.mapdev_len = 0;
+       ml.failback_progress_len = 0;
+       ml.queueing_progress_len = 0;
+       ml.nr_active_len = 0;
 
        vector_foreach_slot (mpvec, mpp, i) {
                mapname_len = (mpp->alias) ?
@@ -91,13 +97,13 @@ get_map_layout (struct map_layout * ml, vector mpvec)
                queueing_progress_len = 5 + (int)log10(mpp->retry_tick);
                nr_active_len = (int)log10(mpp->nr_active);
 
-               ml->mapname_len = MAX(mapname_len, ml->mapname_len);
-               ml->mapdev_len = MAX(mapdev_len, ml->mapdev_len);
-               ml->failback_progress_len = MAX(failback_progress_len,
-                                               ml->failback_progress_len);
-               ml->queueing_progress_len = MAX(queueing_progress_len,
-                                               ml->queueing_progress_len);
-               ml->nr_active_len = MAX(nr_active_len, ml->nr_active_len);
+               ml.mapname_len = MAX(mapname_len, ml.mapname_len);
+               ml.mapdev_len = MAX(mapdev_len, ml.mapdev_len);
+               ml.failback_progress_len = MAX(failback_progress_len,
+                                               ml.failback_progress_len);
+               ml.queueing_progress_len = MAX(queueing_progress_len,
+                                               ml.queueing_progress_len);
+               ml.nr_active_len = MAX(nr_active_len, ml.nr_active_len);
        }
        return;
 }
@@ -124,8 +130,7 @@ get_map_layout (struct map_layout * ml, vector mpvec)
                PRINT(c, TAIL, " %i/%i", cur, total)
 
 int
-snprint_map_header (char * line, int len, char * format,
-                   struct map_layout * ml)
+snprint_map_header (char * line, int len, char * format)
 {
        char * c = line;   /* line cursor */
        char * s = line;   /* for padding */
@@ -145,30 +150,30 @@ snprint_map_header (char * line, int len, char * format,
                switch (*f) {
                case 'w':       
                        PRINT(c, TAIL, "name");
-                       ml->mapname_len = MAX(ml->mapname_len, 4);
-                       PAD(ml->mapname_len);
+                       ml.mapname_len = MAX(ml.mapname_len, 4);
+                       PAD(ml.mapname_len);
                        break;
                case 'd':
                        PRINT(c, TAIL, "sysfs");
-                       ml->mapdev_len = MAX(ml->mapdev_len, 5);
-                       PAD(ml->mapdev_len);
+                       ml.mapdev_len = MAX(ml.mapdev_len, 5);
+                       PAD(ml.mapdev_len);
                        break;
                case 'F':
                        PRINT(c, TAIL, "failback");
-                       ml->failback_progress_len =
-                               MAX(ml->failback_progress_len, 8);
-                       PAD(ml->failback_progress_len);
+                       ml.failback_progress_len =
+                               MAX(ml.failback_progress_len, 8);
+                       PAD(ml.failback_progress_len);
                        break;
                case 'Q':
                        PRINT(c, TAIL, "queueing");
-                       ml->queueing_progress_len =
-                               MAX(ml->queueing_progress_len, 8);
-                       PAD(ml->queueing_progress_len);
+                       ml.queueing_progress_len =
+                               MAX(ml.queueing_progress_len, 8);
+                       PAD(ml.queueing_progress_len);
                        break;
                case 'n':
                        PRINT(c, TAIL, "paths");
-                       ml->nr_active_len = MAX(ml->nr_active_len, 5);
-                       PAD(ml->nr_active_len);
+                       ml.nr_active_len = MAX(ml.nr_active_len, 5);
+                       PAD(ml.nr_active_len);
                        break;
                case 't':
                        PRINT(c, TAIL, "dm-st");
@@ -187,7 +192,7 @@ snprint_map_header (char * line, int len, char * format,
 
 int
 snprint_map (char * line, int len, char * format,
-            struct multipath * mpp, struct map_layout * ml)
+            struct multipath * mpp)
 {
        char * c = line;   /* line cursor */
        char * s = line;   /* for padding */
@@ -211,18 +216,18 @@ snprint_map (char * line, int len, char * format,
                        } else {
                                PRINT(c, TAIL, "%s", mpp->wwid);
                        }
-                       PAD(ml->mapname_len);
+                       PAD(ml.mapname_len);
                        break;
                case 'd':
                        if (mpp->dmi) {
                                PRINT(c, TAIL, "dm-%i", mpp->dmi->minor);
                        }
-                       PAD(ml->mapdev_len);
+                       PAD(ml.mapdev_len);
                        break;
                case 'F':
                        if (mpp->pgfailback == -FAILBACK_IMMEDIATE) {
                                PRINT(c, TAIL, "immediate");
-                               PAD(ml->failback_progress_len);
+                               PAD(ml.failback_progress_len);
                                break;
                        }
                        if (!mpp->failback_tick) {
@@ -231,7 +236,7 @@ snprint_map (char * line, int len, char * format,
                                PRINT_PROGRESS(mpp->failback_tick,
                                               mpp->pgfailback);
                        }
-                       PAD(ml->failback_progress_len);
+                       PAD(ml.failback_progress_len);
                        break;
                case 'Q':
                        if (mpp->no_path_retry == NO_PATH_RETRY_FAIL) {
@@ -249,11 +254,11 @@ snprint_map (char * line, int len, char * format,
                                              mpp->no_path_retry);
                                }
                        }
-                       PAD(ml->queueing_progress_len);
+                       PAD(ml.queueing_progress_len);
                        break;
                case 'n':
                        PRINT(c, TAIL, "%i", mpp->nr_active);
-                       PAD(ml->nr_active_len);
+                       PAD(ml.nr_active_len);
                        break;
                case 't':
                        if (mpp->dmi && mpp->dmi->suspended) {
@@ -275,8 +280,7 @@ snprint_map (char * line, int len, char * format,
 }
 
 int
-snprint_path_header (char * line, int len, char * format,
-                    struct path_layout * pl)
+snprint_path_header (char * line, int len, char * format)
 {
        char * c = line;   /* line cursor */
        char * s = line;   /* for padding */
@@ -296,21 +300,21 @@ snprint_path_header (char * line, int len, char * format,
                switch (*f) {
                case 'w':
                        PRINT(c, TAIL, "uuid");
-                       PAD(pl->uuid_len);
+                       PAD(pl.uuid_len);
                        break;
                case 'i':
                        PRINT(c, TAIL, "hcil");
-                       PAD(pl->hbtl_len);
+                       PAD(pl.hbtl_len);
                        break;
                case 'd':
                        PRINT(c, TAIL, "dev");
-                       pl->dev_len = MAX(pl->dev_len, 3);
-                       PAD(pl->dev_len);
+                       pl.dev_len = MAX(pl.dev_len, 3);
+                       PAD(pl.dev_len);
                        break;
                case 'D':
                        PRINT(c, TAIL, "dev_t");
-                       pl->dev_t_len = MAX(pl->dev_t_len, 5);
-                       PAD(pl->dev_t_len);
+                       pl.dev_t_len = MAX(pl.dev_t_len, 5);
+                       PAD(pl.dev_t_len);
                        break;
                case 'T':
                        PRINT(c, TAIL, "chk-st");
@@ -330,8 +334,8 @@ snprint_path_header (char * line, int len, char * format,
                        break;
                case 'p':
                        PRINT(c, TAIL, "pri");
-                       pl->prio_len = MAX(pl->prio_len, 3);
-                       PAD(pl->prio_len);
+                       pl.prio_len = MAX(pl.prio_len, 3);
+                       PAD(pl.prio_len);
                        break;
                default:
                        break;
@@ -345,8 +349,7 @@ snprint_path_header (char * line, int len, char * format,
 }
 
 int
-snprint_path (char * line, int len, char * format, struct path * pp,
-           struct path_layout * pl)
+snprint_path (char * line, int len, char * format, struct path * pp)
 {
        char * c = line;   /* line cursor */
        char * s = line;   /* for padding */
@@ -366,7 +369,7 @@ snprint_path (char * line, int len, char * format, struct path * pp,
                switch (*f) {
                case 'w':       
                        PRINT(c, TAIL, "%s", pp->wwid);
-                       PAD(pl->uuid_len);
+                       PAD(pl.uuid_len);
                        break;
                case 'i':
                        if (pp->sg_id.host_no < 0) {
@@ -378,7 +381,7 @@ snprint_path (char * line, int len, char * format, struct path * pp,
                                        pp->sg_id.scsi_id,
                                        pp->sg_id.lun);
                        }
-                       PAD(pl->hbtl_len);
+                       PAD(pl.hbtl_len);
                        break;
                case 'd':
                        if (!strlen(pp->dev)) {
@@ -386,11 +389,11 @@ snprint_path (char * line, int len, char * format, struct path * pp,
                        } else {
                                PRINT(c, TAIL, "%s", pp->dev);
                        }
-                       PAD(pl->dev_len);
+                       PAD(pl.dev_len);
                        break;
                case 'D':
                        PRINT(c, TAIL, "%s", pp->dev_t);
-                       PAD(pl->dev_t_len);
+                       PAD(pl.dev_t_len);
                        break;
                case 'T':
                        switch (pp->state) {
@@ -445,7 +448,7 @@ snprint_path (char * line, int len, char * format, struct path * pp,
                        } else {
                                PRINT(c, TAIL, "#");
                        }
-                       PAD(pl->prio_len);
+                       PAD(pl.prio_len);
                        break;
                default:
                        break;
@@ -458,3 +461,142 @@ snprint_path (char * line, int len, char * format, struct path * pp,
        return (c - line);
 }
 
+extern void
+print_mp (struct multipath * mpp, int verbosity)
+{
+       int j, i;
+       struct path * pp = NULL;
+       struct pathgroup * pgp = NULL;
+
+       if (mpp->action == ACT_NOTHING || !verbosity || !mpp->size)
+               return;
+
+       if (verbosity > 1) {
+               switch (mpp->action) {
+               case ACT_RELOAD:
+                       printf("%s: ", ACT_RELOAD_STR);
+                       break;
+
+               case ACT_CREATE:
+                       printf("%s: ", ACT_CREATE_STR);
+                       break;
+
+               case ACT_SWITCHPG:
+                       printf("%s: ", ACT_SWITCHPG_STR);
+                       break;
+
+               default:
+                       break;
+               }
+       }
+
+       if (mpp->alias)
+               printf("%s", mpp->alias);
+
+       if (verbosity == 1) {
+               printf("\n");
+               return;
+       }
+       if (strncmp(mpp->alias, mpp->wwid, WWID_SIZE))
+               printf(" (%s)", mpp->wwid);
+
+       printf("\n");
+
+       if (mpp->size < (1 << 11))
+               printf("[size=%llu kB]", mpp->size >> 1);
+       else if (mpp->size < (1 << 21))
+               printf("[size=%llu MB]", mpp->size >> 11);
+       else if (mpp->size < (1 << 31))
+               printf("[size=%llu GB]", mpp->size >> 21);
+       else
+               printf("[size=%llu TB]", mpp->size >> 31);
+
+       if (mpp->features)
+               printf("[features=\"%s\"]", mpp->features);
+
+       if (mpp->hwhandler)
+               printf("[hwhandler=\"%s\"]", mpp->hwhandler);
+
+       fprintf(stdout, "\n");
+
+       if (!mpp->pg)
+               return;
+
+       vector_foreach_slot (mpp->pg, pgp, j) {
+               printf("\\_ ");
+
+               if (mpp->selector) {
+                       printf("%s ", mpp->selector);
+#if 0
+                       /* align to path status info */
+                       for (i = pl.hbtl_len + pl.dev_len + pl.dev_t_len + 4;
+                            i > strlen(mpp->selector); i--)
+                               printf(" ");
+#endif
+               }
+               if (pgp->priority)
+                       printf("[prio=%i]", pgp->priority);
+
+               switch (pgp->status) {
+               case PGSTATE_ENABLED:
+                       printf("[enabled]");
+                       break;
+               case PGSTATE_DISABLED:
+                       printf("[disabled]");
+                       break;
+               case PGSTATE_ACTIVE:
+                       printf("[active]");
+                       break;
+               default:
+                       break;
+               }
+               printf("\n");
+
+               vector_foreach_slot (pgp->paths, pp, i)
+                       print_path(pp, PRINT_PATH_INDENT);
+       }
+       printf("\n");
+}
+
+extern void
+print_path (struct path * pp, char * style)
+{
+       char line[MAX_LINE_LEN];
+
+       snprint_path(&line[0], MAX_LINE_LEN, style, pp);
+       printf("%s", line);
+}
+
+extern void
+print_map (struct multipath * mpp)
+{
+       if (mpp->size && mpp->params)
+               printf("0 %llu %s %s\n",
+                        mpp->size, DEFAULT_TARGET, mpp->params);
+       return;
+}
+
+extern void
+print_all_paths (vector pathvec, int banner)
+{
+       int i;
+       struct path * pp;
+       char line[MAX_LINE_LEN];
+
+       if (!VECTOR_SIZE(pathvec)) {
+               if (banner)
+                       fprintf(stdout, "===== no paths =====\n");
+               return;
+       }
+       
+       if (banner)
+               fprintf(stdout, "===== paths list =====\n");
+
+       get_path_layout(pathvec);
+       snprint_path_header(line, MAX_LINE_LEN, PRINT_PATH_LONG);
+       fprintf(stdout, "%s", line);
+
+       vector_foreach_slot (pathvec, pp, i)
+               print_path(pp, PRINT_PATH_LONG);
+}
+
index 5da4396..da69edc 100644 (file)
@@ -45,9 +45,14 @@ struct map_layout {
 };
 
 
-void get_path_layout (struct path_layout * pl, vector pathvec);
-void get_map_layout (struct map_layout * pl, vector mpvec);
-int snprint_path_header (char *, int, char *, struct path_layout *);
-int snprint_map_header (char *, int, char *, struct map_layout *);
-int snprint_path (char *, int, char *, struct path *, struct path_layout *);
-int snprint_map (char *, int, char *,struct multipath *, struct map_layout *);
+void get_path_layout (vector pathvec);
+void get_map_layout (vector mpvec);
+int snprint_path_header (char *, int, char *);
+int snprint_map_header (char *, int, char *);
+int snprint_path (char *, int, char *, struct path *);
+int snprint_map (char *, int, char *,struct multipath *);
+
+void print_mp (struct multipath * mpp, int verbosity);
+void print_path (struct path * pp, char * style);
+void print_map (struct multipath * mpp);
+void print_all_paths (vector pathvec, int banner);
index 9bd1063..3cd0fb2 100644 (file)
  */
 
 #include <stdio.h>
-#include <stdlib.h>
 #include <unistd.h>
-#include <string.h>
-#include <sys/file.h>
-#include <errno.h>
+#include <ctype.h>
+#include <sysfs/libsysfs.h>
 
-#include <parser.h>
 #include <vector.h>
 #include <memory.h>
 #include <libdevmapper.h>
 #include <devmapper.h>
-#include <checkers.h>
 #include <path_state.h>
 #include <blacklist.h>
-#include <hwtable.h>
 #include <util.h>
 #include <defaults.h>
 #include <structs.h>
 #include <dmparser.h>
 #include <cache.h>
 #include <config.h>
-#include <propsel.h>
 #include <discovery.h>
 #include <debug.h>
 #include <switchgroup.h>
-#include <sysfs/libsysfs.h>
 #include <print.h>
 #include <alias.h>
+#include <configure.h>
+#include <pgpolicies.h>
 
 #include "main.h"
-#include "pgpolicies.h"
-#include "dict.h"
-
-/* for column aligned output */
-struct path_layout pl;
 
 static char *
 get_refwwid (vector pathvec)
@@ -146,145 +136,6 @@ out:
        return NULL;
 }
 
-static void
-print_path (struct path * pp, char * style)
-{
-       char line[MAX_LINE_LEN];
-
-       snprint_path(&line[0], MAX_LINE_LEN, style, pp, &pl);
-       printf("%s", line);
-}
-
-static void
-print_map (struct multipath * mpp)
-{
-       if (mpp->size && mpp->params)
-               printf("0 %llu %s %s\n",
-                        mpp->size, DEFAULT_TARGET, mpp->params);
-       return;
-}
-
-static void
-print_all_paths (vector pathvec, int banner)
-{
-       int i;
-       struct path * pp;
-       char line[MAX_LINE_LEN];
-
-       if (!VECTOR_SIZE(pathvec)) {
-               if (banner)
-                       fprintf(stdout, "===== no paths =====\n");
-               return;
-       }
-       
-       if (banner)
-               fprintf(stdout, "===== paths list =====\n");
-
-       get_path_layout(&pl, pathvec);
-       snprint_path_header(line, MAX_LINE_LEN, PRINT_PATH_LONG, &pl);
-       fprintf(stdout, "%s", line);
-
-       vector_foreach_slot (pathvec, pp, i)
-               print_path(pp, PRINT_PATH_LONG);
-}
-
-static void
-print_mp (struct multipath * mpp)
-{
-       int j, i;
-       struct path * pp = NULL;
-       struct pathgroup * pgp = NULL;
-
-       if (mpp->action == ACT_NOTHING || !conf->verbosity || !mpp->size)
-               return;
-
-       if (conf->verbosity > 1) {
-               switch (mpp->action) {
-               case ACT_RELOAD:
-                       printf("%s: ", ACT_RELOAD_STR);
-                       break;
-
-               case ACT_CREATE:
-                       printf("%s: ", ACT_CREATE_STR);
-                       break;
-
-               case ACT_SWITCHPG:
-                       printf("%s: ", ACT_SWITCHPG_STR);
-                       break;
-
-               default:
-                       break;
-               }
-       }
-
-       if (mpp->alias)
-               printf("%s", mpp->alias);
-
-       if (conf->verbosity == 1) {
-               printf("\n");
-               return;
-       }
-       if (strncmp(mpp->alias, mpp->wwid, WWID_SIZE))
-               printf(" (%s)", mpp->wwid);
-
-       printf("\n");
-
-       if (mpp->size < (1 << 11))
-               printf("[size=%llu kB]", mpp->size >> 1);
-       else if (mpp->size < (1 << 21))
-               printf("[size=%llu MB]", mpp->size >> 11);
-       else if (mpp->size < (1 << 31))
-               printf("[size=%llu GB]", mpp->size >> 21);
-       else
-               printf("[size=%llu TB]", mpp->size >> 31);
-
-       if (mpp->features)
-               printf("[features=\"%s\"]", mpp->features);
-
-       if (mpp->hwhandler)
-               printf("[hwhandler=\"%s\"]", mpp->hwhandler);
-
-       fprintf(stdout, "\n");
-
-       if (!mpp->pg)
-               return;
-
-       vector_foreach_slot (mpp->pg, pgp, j) {
-               printf("\\_ ");
-
-               if (mpp->selector) {
-                       printf("%s ", mpp->selector);
-#if 0
-                       /* align to path status info */
-                       for (i = pl.hbtl_len + pl.dev_len + pl.dev_t_len + 4;
-                            i > strlen(mpp->selector); i--)
-                               printf(" ");
-#endif
-               }
-               if (pgp->priority)
-                       printf("[prio=%i]", pgp->priority);
-
-               switch (pgp->status) {
-               case PGSTATE_ENABLED:
-                       printf("[enabled]");
-                       break;
-               case PGSTATE_DISABLED:
-                       printf("[disabled]");
-                       break;
-               case PGSTATE_ACTIVE:
-                       printf("[active]");
-                       break;
-               default:
-                       break;
-               }
-               printf("\n");
-
-               vector_foreach_slot (pgp->paths, pp, i)
-                       print_path(pp, PRINT_PATH_INDENT);
-       }
-       printf("\n");
-}
-
 static int
 filter_pathvec (vector pathvec, char * refwwid)
 {
@@ -305,453 +156,6 @@ filter_pathvec (vector pathvec, char * refwwid)
        return 0;
 }
 
-static int
-setup_map (struct multipath * mpp)
-{
-       struct pathgroup * pgp;
-       int i;
-       
-       /*
-        * don't bother if devmap size is unknown
-        */
-       if (mpp->size <= 0) {
-               condlog(3, "%s: devmap size is unknown", mpp->alias);
-               return 1;
-       }
-
-       /*
-        * properties selectors
-        */
-       select_pgfailback(mpp);
-       select_pgpolicy(mpp);
-       select_selector(mpp);
-       select_features(mpp);
-       select_hwhandler(mpp);
-       select_rr_weight(mpp);
-       select_minio(mpp);
-       select_no_path_retry(mpp);
-
-       /*
-        * assign paths to path groups -- start with no groups and all paths
-        * in mpp->paths
-        */
-       if (mpp->pg) {
-               vector_foreach_slot (mpp->pg, pgp, i)
-                       free_pathgroup(pgp, KEEP_PATHS);
-
-               vector_free(mpp->pg);
-               mpp->pg = NULL;
-       }
-       if (mpp->pgpolicyfn && mpp->pgpolicyfn(mpp))
-               return 1;
-
-       mpp->nr_active = pathcount(mpp, PATH_UP);
-
-       /*
-        * ponders each path group and determine highest prio pg
-        * to switch over (default to first)
-        */
-       mpp->bestpg = select_path_group(mpp);
-
-       /*
-        * transform the mp->pg vector of vectors of paths
-        * into a mp->params strings to feed the device-mapper
-        */
-       if (assemble_map(mpp)) {
-               condlog(0, "%s: problem assembing map", mpp->alias);
-               return 1;
-       }
-       return 0;
-}
-
-static void
-compute_pgid(struct pathgroup * pgp)
-{
-       struct path * pp;
-       int i;
-
-       vector_foreach_slot (pgp->paths, pp, i)
-               pgp->id ^= (long)pp;
-}
-
-static int
-pgcmp (struct multipath * mpp, struct multipath * cmpp)
-{
-       int i, j;
-       struct pathgroup * pgp;
-       struct pathgroup * cpgp;
-       int r = 0;
-
-       vector_foreach_slot (mpp->pg, pgp, i) {
-               compute_pgid(pgp);
-
-               vector_foreach_slot (cmpp->pg, cpgp, j) {
-                       if (pgp->id == cpgp->id) {
-                               r = 0;
-                               break;
-                       }
-                       r++;
-               }
-               if (r)
-                       return r;
-       }
-       return r;
-}
-
-static void
-select_action (struct multipath * mpp, vector curmp)
-{
-       struct multipath * cmpp;
-
-       cmpp = find_mp_by_alias(curmp, mpp->alias);
-
-       if (!cmpp) {
-               cmpp = find_mp_by_wwid(curmp, mpp->wwid);
-
-               if (cmpp && !conf->dry_run) {
-                       condlog(2, "remove: %s (dup of %s)",
-                               cmpp->alias, mpp->alias);
-                       dm_flush_map(cmpp->alias, DEFAULT_TARGET);
-               }
-               mpp->action = ACT_CREATE;
-               condlog(3, "set ACT_CREATE: map does not exists");
-               return;
-       }
-
-       if (!find_mp_by_wwid(curmp, mpp->wwid)) {
-               condlog(2, "remove: %s (wwid changed)", cmpp->alias);
-               dm_flush_map(mpp->alias, NULL);
-               strncat(cmpp->wwid, mpp->wwid, WWID_SIZE);
-               drop_multipath(curmp, cmpp->wwid, KEEP_PATHS);
-               mpp->action = ACT_CREATE;
-               condlog(3, "set ACT_CREATE: map wwid change");
-               return;
-       }
-               
-       if (pathcount(mpp, PATH_UP) == 0) {
-               mpp->action = ACT_NOTHING;
-               condlog(3, "set ACT_NOTHING: no usable path");
-               return;
-       }
-       if (cmpp->size != mpp->size) {
-               mpp->action = ACT_RELOAD;
-               condlog(3, "set ACT_RELOAD: size change");
-               return;
-       }
-       if (!mpp->no_path_retry && /* let features be handled by the daemon */
-           strncmp(cmpp->features, mpp->features, strlen(mpp->features))) {
-               mpp->action =  ACT_RELOAD;
-               condlog(3, "set ACT_RELOAD: features change");
-               return;
-       }
-       if (strncmp(cmpp->hwhandler, mpp->hwhandler,
-                   strlen(mpp->hwhandler))) {
-               mpp->action = ACT_RELOAD;
-               condlog(3, "set ACT_RELOAD: hwhandler change");
-               return;
-       }
-       if (strncmp(cmpp->selector, mpp->selector,
-                   strlen(mpp->selector))) {
-               mpp->action = ACT_RELOAD;
-               condlog(3, "set ACT_RELOAD: selector change");
-               return;
-       }
-       if (cmpp->minio != mpp->minio) {
-               mpp->action = ACT_RELOAD;
-               condlog(3, "set ACT_RELOAD: minio change (%u->%u)",
-                       cmpp->minio, mpp->minio);
-               return;
-       }
-       if (VECTOR_SIZE(cmpp->pg) != VECTOR_SIZE(mpp->pg)) {
-               mpp->action = ACT_RELOAD;
-               condlog(3, "set ACT_RELOAD: number of path group change");
-               return;
-       }
-       if (pgcmp(mpp, cmpp)) {
-               mpp->action = ACT_RELOAD;
-               condlog(3, "set ACT_RELOAD: path group topology change");
-               return;
-       }
-       if (cmpp->nextpg != mpp->bestpg) {
-               mpp->action = ACT_SWITCHPG;
-               condlog(3, "set ACT_SWITCHPG: next path group change");
-               return;
-       }
-       mpp->action = ACT_NOTHING;
-       condlog(3, "set ACT_NOTHING: map unchanged");
-       return;
-}
-
-static int
-reinstate_paths (struct multipath * mpp)
-{
-       int i, j;
-       struct pathgroup * pgp;
-       struct path * pp;
-
-       if (!mpp->pg)
-               return 0;
-
-       vector_foreach_slot (mpp->pg, pgp, i) {
-               if (!pgp->paths)
-                       continue;
-
-               vector_foreach_slot (pgp->paths, pp, j) {
-                       if (pp->state != PATH_UP &&
-                           (pgp->status == PGSTATE_DISABLED ||
-                            pgp->status == PGSTATE_ACTIVE))
-                               continue;
-
-                       if (pp->dmstate == PSTATE_FAILED) {
-                               if (dm_reinstate_path(mpp->alias, pp->dev_t))
-                                       condlog(0, "error reinstating %s",
-                                               pp->dev);
-                       }
-               }
-       }
-       return 0;
-}
-
-int lock_multipath (struct multipath * mpp, int lock)
-{
-       struct pathgroup * pgp;
-       struct path * pp;
-       int i, j;
-
-       if (!mpp || !mpp->pg)
-               return 0;
-       
-       vector_foreach_slot (mpp->pg, pgp, i) {
-               if (!pgp->paths)
-                       continue;
-               vector_foreach_slot(pgp->paths, pp, j) {
-                       if (lock && flock(pp->fd, LOCK_EX | LOCK_NB) &&
-                           errno == EWOULDBLOCK)
-                               return 1;
-                       else if (!lock)
-                               flock(pp->fd, LOCK_UN);
-               }
-       }
-       return 0;
-}
-
-/*
- * Return value:
- *  -1: Retry
- *   0: DM_DEVICE_CREATE or DM_DEVICE_RELOAD failed, or dry_run mode.
- *   1: DM_DEVICE_CREATE or DM_DEVICE_RELOAD succeeded.
- *   2: Map is already existing.
- */
-static int
-domap (struct multipath * mpp)
-{
-       int r = 0;
-
-       /*
-        * last chance to quit before touching the devmaps
-        */
-       if (conf->dry_run) {
-               print_mp(mpp);
-               return 0;
-       }
-
-       switch (mpp->action) {
-       case ACT_NOTHING:
-               return 2;
-
-       case ACT_SWITCHPG:
-               dm_switchgroup(mpp->alias, mpp->bestpg);
-               /*
-                * we may have avoided reinstating paths because there where in
-                * active or disabled PG. Now that the topology has changed,
-                * retry.
-                */
-               reinstate_paths(mpp);
-               return 2;
-
-       case ACT_CREATE:
-               if (lock_multipath(mpp, 1)) {
-                       condlog(3, "%s: in use", mpp->alias);
-                       return -1;
-               }
-               dm_shut_log();
-
-               if (dm_map_present(mpp->alias))
-                       break;
-
-               r = dm_addmap(DM_DEVICE_CREATE, mpp->alias, DEFAULT_TARGET,
-                             mpp->params, mpp->size, mpp->wwid);
-
-               /*
-                * DM_DEVICE_CREATE is actually DM_DEV_CREATE plus
-                * DM_TABLE_LOAD. Failing the second part leaves an
-                * empty map. Clean it up.
-                */
-               if (!r && dm_map_present(mpp->alias)) {
-                       condlog(3, "%s: failed to load map "
-                                  "(a path might be in use)",
-                                  mpp->alias);
-                       dm_flush_map(mpp->alias, NULL);
-               }
-
-               lock_multipath(mpp, 0);
-               dm_restore_log();
-               break;
-
-       case ACT_RELOAD:
-               r = (dm_addmap(DM_DEVICE_RELOAD, mpp->alias, DEFAULT_TARGET,
-                             mpp->params, mpp->size, NULL) &&
-                    dm_simplecmd(DM_DEVICE_RESUME, mpp->alias));
-               break;
-
-       default:
-               break;
-       }
-
-       if (r) {
-               /*
-                * DM_DEVICE_CREATE or DM_DEVICE_RELOAD succeeded
-                */
-               dm_switchgroup(mpp->alias, mpp->bestpg);
-               print_mp(mpp);
-       }
-
-       return r;
-}
-
-static int
-deadmap (struct multipath * mpp)
-{
-       int i, j;
-       struct pathgroup * pgp;
-       struct path * pp;
-
-       if (!mpp->pg)
-               return 1;
-
-       vector_foreach_slot (mpp->pg, pgp, i) {
-               if (!pgp->paths)
-                       continue;
-
-               vector_foreach_slot (pgp->paths, pp, j)
-                       if (strlen(pp->dev))
-                               return 0; /* alive */
-       }
-       
-       return 1; /* dead */
-}
-
-static int
-coalesce_paths (vector curmp, vector pathvec)
-{
-       int r = 1;
-       int k, i;
-       char empty_buff[WWID_SIZE];
-       struct multipath * mpp;
-       struct path * pp1;
-       struct path * pp2;
-
-       memset(empty_buff, 0, WWID_SIZE);
-
-       vector_foreach_slot (pathvec, pp1, k) {
-               /* skip this path for some reason */
-
-               /* 1. if path has no unique id or wwid blacklisted */
-               if (memcmp(empty_buff, pp1->wwid, WWID_SIZE) == 0 ||
-                   blacklist(conf->blist, pp1->wwid))
-                       continue;
-
-               /* 2. if path already coalesced */
-               if (pp1->mpp)
-                       continue;
-
-               /*
-                * at this point, we know we really got a new mp
-                */
-               mpp = alloc_multipath();
-
-               if (!mpp)
-                       return 1;
-
-               mpp->mpe = find_mpe(pp1->wwid);
-               mpp->hwe = pp1->hwe;
-               strcpy(mpp->wwid, pp1->wwid);
-               select_alias(mpp);
-
-               pp1->mpp = mpp;
-               mpp->size = pp1->size;
-               mpp->paths = vector_alloc();
-
-               if (pp1->priority < 0)
-                       mpp->action = ACT_NOTHING;
-
-               if (!mpp->paths)
-                       return 1;
-               
-               if (store_path(mpp->paths, pp1))
-                       return 1;
-
-               for (i = k + 1; i < VECTOR_SIZE(pathvec); i++) {
-                       pp2 = VECTOR_SLOT(pathvec, i);
-
-                       if (strcmp(pp1->wwid, pp2->wwid))
-                               continue;
-                       
-                       pp2->mpp = mpp;
-
-                       if (pp2->size != mpp->size) {
-                               /*
-                                * ouch, avoid feeding that to the DM
-                                */
-                               condlog(3, "path size mismatch : discard %s",
-                                    mpp->wwid);
-                               mpp->action = ACT_NOTHING;
-                       }
-                       if (pp2->priority < 0)
-                               mpp->action = ACT_NOTHING;
-
-                       if (store_path(mpp->paths, pp2))
-                               return 1;
-               }
-               if (setup_map(mpp))
-                       goto next;
-
-               if (mpp->action == ACT_UNDEF)
-                       select_action(mpp, curmp);
-
-               r = domap(mpp);
-
-               if (r < 0)
-                       return r;
-
-               if (r && mpp->no_path_retry != NO_PATH_RETRY_UNDEF) {
-                       if (mpp->no_path_retry == NO_PATH_RETRY_FAIL)
-                               dm_queue_if_no_path(mpp->alias, 0);
-                       else
-                               dm_queue_if_no_path(mpp->alias, 1);
-               }
-
-next:
-               drop_multipath(curmp, mpp->wwid, KEEP_PATHS);
-               free_multipath(mpp, KEEP_PATHS);
-       }
-       /*
-        * Flush maps with only dead paths (ie not in sysfs)
-        * Keep maps with only failed paths
-        */
-       vector_foreach_slot (curmp, mpp, i) {
-               if (!deadmap(mpp))
-                       continue;
-
-               if (dm_flush_map(mpp->alias, DEFAULT_TARGET))
-                       condlog(2, "remove: %s (dead) failed!",
-                               mpp->alias);
-               else
-                       condlog(2, "remove: %s (dead)", mpp->alias);
-       }
-       return 0;
-}
-
 static void
 usage (char * progname)
 {
@@ -865,7 +269,7 @@ get_dm_mpvec (vector curmp, vector pathvec, char * refwwid)
                disassemble_status(mpp->status, mpp);
 
                if (conf->list)
-                       print_mp(mpp);
+                       print_mp(mpp, conf->verbosity);
 
                if (!conf->dry_run)
                        reinstate_paths(mpp);
@@ -957,7 +361,7 @@ configure (void)
        if (conf->verbosity > 2)
                print_all_paths(pathvec, 1);
 
-       get_path_layout(&pl, pathvec);
+       get_path_layout(pathvec);
 
        if (get_dm_mpvec(curmp, pathvec, refwwid))
                goto out;
index b4d79c9..89d98fb 100644 (file)
 #define _MAIN_H
 
 /*
- * configurator actions
- */
-#define ACT_NOTHING_STR                "unchanged"
-#define ACT_RELOAD_STR         "reload"
-#define ACT_SWITCHPG_STR       "switchpg"
-#define ACT_CREATE_STR         "create"
-
-enum actions {
-       ACT_UNDEF,
-       ACT_NOTHING,
-       ACT_RELOAD,
-       ACT_SWITCHPG,
-       ACT_CREATE
-};
-
-#define FLUSH_ONE 1
-#define FLUSH_ALL 2
-
-/*
  * Build version
  */
 #define PROG    "multipath"
index 30e2979..0f93039 100644 (file)
@@ -780,11 +780,10 @@ show_paths (char ** r, int * len, struct vectors * vecs)
        struct path * pp;
        char * c;
        char * reply;
-       struct path_layout pl;
        int maxlen = INITIAL_REPLY_LEN;
        int again = 1;
 
-       get_path_layout(&pl, vecs->pathvec);
+       get_path_layout(vecs->pathvec);
        reply = MALLOC(maxlen);
 
        while (again) {
@@ -795,11 +794,11 @@ show_paths (char ** r, int * len, struct vectors * vecs)
 
                if (VECTOR_SIZE(vecs->pathvec) > 0)
                        c += snprint_path_header(c, reply + maxlen - c,
-                                                PRINT_PATH_CHECKER, &pl);
+                                                PRINT_PATH_CHECKER);
 
                vector_foreach_slot(vecs->pathvec, pp, i)
                        c += snprint_path(c, reply + maxlen - c,
-                                         PRINT_PATH_CHECKER, pp, &pl);
+                                         PRINT_PATH_CHECKER, pp);
 
                again = ((c - reply) == (maxlen - 1));
 
@@ -819,11 +818,10 @@ show_maps (char ** r, int *len, struct vectors * vecs)
        struct multipath * mpp;
        char * c;
        char * reply;
-       struct map_layout ml;
        int maxlen = INITIAL_REPLY_LEN;
        int again = 1;
 
-       get_map_layout(&ml, vecs->mpvec);
+       get_map_layout(vecs->mpvec);
        reply = MALLOC(maxlen);
 
        while (again) {
@@ -833,11 +831,11 @@ show_maps (char ** r, int *len, struct vectors * vecs)
                c = reply;
                if (VECTOR_SIZE(vecs->mpvec) > 0)
                        c += snprint_map_header(c, reply + maxlen - c,
-                                               PRINT_MAP_FAILBACK, &ml);
+                                               PRINT_MAP_FAILBACK);
 
                vector_foreach_slot(vecs->mpvec, mpp, i)
                        c += snprint_map(c, reply + maxlen - c,
-                                        PRINT_MAP_FAILBACK, mpp, &ml);
+                                        PRINT_MAP_FAILBACK, mpp);
 
                again = ((c - reply) == (maxlen - 1));