libmultipath: allow printing local maps in snprint_config
authorMartin Wilck <mwilck@suse.com>
Fri, 8 Jun 2018 10:20:35 +0000 (12:20 +0200)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Thu, 21 Jun 2018 07:49:54 +0000 (09:49 +0200)
"mulitpatd show config" only dumps multipath sections for maps which are
present in local configuration files. This patch adds the ability to dump
"multipath" subsections for every locally detected map, even for those
that have no local configuration, and at the same time, skip dumping
multipath configurations for maps that aree not present locally.

This makes it possible for users to generate a multipath.conf template
matching local devices, and e.g. add explicit alias entries for existing
maps. If user_friendly_names is in use, a commented-out config line is added
to the dump output showing the implicitly configured alias, simplifying
identification of the devices.

This facility is optional and will only be used in new commands added
in follow-up patches.

Signed-off-by: Martin Wilck <mwilck@suse.com>
libmultipath/print.c
libmultipath/print.h
multipath/main.c
multipathd/cli_handlers.c
tests/hwtable.c

index af4c00e..222d270 100644 (file)
@@ -1404,12 +1404,16 @@ static int snprint_hwtable(const struct config *conf,
 
 static int
 snprint_mpentry (const struct config *conf, char * buff, int len,
-                const struct mpentry * mpe)
+                const struct mpentry * mpe, const struct _vector *mpvec)
 {
        int i;
        int fwd = 0;
        struct keyword * kw;
        struct keyword * rootkw;
+       struct multipath *mpp = NULL;
+
+       if (mpvec != NULL && (mpp = find_mp_by_wwid(mpvec, mpe->wwid)) == NULL)
+               return 0;
 
        rootkw = find_keyword(conf->keywords, NULL, "multipath");
        if (!rootkw)
@@ -1424,6 +1428,15 @@ snprint_mpentry (const struct config *conf, char * buff, int len,
                if (fwd >= len)
                        return len;
        }
+       /*
+        * This mpp doesn't have alias defined. Add the alias in a comment.
+        */
+       if (mpp != NULL && strcmp(mpp->alias, mpp->wwid)) {
+               fwd += snprintf(buff + fwd, len - fwd, "\t\t# alias \"%s\"\n",
+                               mpp->alias);
+               if (fwd >= len)
+                       return len;
+       }
        fwd += snprintf(buff + fwd, len - fwd, "\t}\n");
        if (fwd >= len)
                return len;
@@ -1431,7 +1444,7 @@ snprint_mpentry (const struct config *conf, char * buff, int len,
 }
 
 static int snprint_mptable(const struct config *conf,
-                          char *buff, int len, vector mptable)
+                          char *buff, int len, const struct _vector *mpvec)
 {
        int fwd = 0;
        int i;
@@ -1445,11 +1458,43 @@ static int snprint_mptable(const struct config *conf,
        fwd += snprintf(buff + fwd, len - fwd, "multipaths {\n");
        if (fwd >= len)
                return len;
-       vector_foreach_slot (mptable, mpe, i) {
-               fwd += snprint_mpentry(conf, buff + fwd, len - fwd, mpe);
+       vector_foreach_slot (conf->mptable, mpe, i) {
+               fwd += snprint_mpentry(conf, buff + fwd, len - fwd, mpe, mpvec);
                if (fwd >= len)
                        return len;
        }
+       if (mpvec != NULL) {
+               struct multipath *mpp;
+
+               vector_foreach_slot(mpvec, mpp, i) {
+                       if (find_mpe(conf->mptable, mpp->wwid) != NULL)
+                               continue;
+
+                       fwd += snprintf(buff + fwd, len - fwd,
+                                       "\tmultipath {\n");
+                       if (fwd >= len)
+                               return len;
+                       fwd += snprintf(buff + fwd, len - fwd,
+                                       "\t\twwid \"%s\"\n", mpp->wwid);
+                       if (fwd >= len)
+                               return len;
+                       /*
+                        * This mpp doesn't have alias defined in
+                        * multipath.conf - otherwise find_mpe would have
+                        * found it. Add the alias in a comment.
+                        */
+                       if (strcmp(mpp->alias, mpp->wwid)) {
+                               fwd += snprintf(buff + fwd, len - fwd,
+                                               "\t\t# alias \"%s\"\n",
+                                               mpp->alias);
+                               if (fwd >= len)
+                                       return len;
+                       }
+                       fwd += snprintf(buff + fwd, len - fwd, "\t}\n");
+                       if (fwd >= len)
+                               return len;
+               }
+       }
        fwd += snprintf(buff + fwd, len - fwd, "}\n");
        if (fwd >= len)
                return len;
@@ -1783,7 +1828,7 @@ static int snprint_blacklist_except(const struct config *conf,
 }
 
 char *snprint_config(const struct config *conf, int *len,
-                    const struct _vector *hwtable)
+                    const struct _vector *hwtable, const struct _vector *mpvec)
 {
        char *reply;
        /* built-in config is >20kB already */
@@ -1821,9 +1866,10 @@ char *snprint_config(const struct config *conf, int *len,
                if ((c - reply) == maxlen)
                        continue;
 
-               if (VECTOR_SIZE(conf->mptable) > 0)
+               if (VECTOR_SIZE(conf->mptable) > 0 ||
+                   (mpvec != NULL && VECTOR_SIZE(mpvec) > 0))
                        c += snprint_mptable(conf, c, reply + maxlen - c,
-                                            conf->mptable);
+                                            mpvec);
 
                if ((c - reply) < maxlen) {
                        if (len)
index c63e054..608b7d5 100644 (file)
@@ -120,7 +120,8 @@ int _snprint_multipath_topology (const struct gen_multipath *, char *, int,
 int snprint_multipath_topology_json (char * buff, int len,
                                const struct vectors * vecs);
 char *snprint_config(const struct config *conf, int *len,
-                    const struct _vector *hwtable);
+                    const struct _vector *hwtable,
+                    const struct _vector *mpvec);
 int snprint_multipath_map_json (char * buff, int len,
                                const struct multipath * mpp, int last);
 int snprint_blacklist_report (struct config *, char *, int);
index 87d80dd..54a9802 100644 (file)
@@ -753,7 +753,7 @@ out:
 static int
 dump_config (struct config *conf)
 {
-       char * reply = snprint_config(conf, NULL, NULL);
+       char * reply = snprint_config(conf, NULL, NULL, NULL);
 
        if (reply != NULL) {
                printf("%s", reply);
index 184a4f0..d4a2cb1 100644 (file)
@@ -254,7 +254,7 @@ show_config (char ** r, int * len, const struct _vector *hwtable)
 
        conf = get_multipath_config();
        pthread_cleanup_push(put_multipath_config, conf);
-       reply = snprint_config(conf, len, hwtable);
+       reply = snprint_config(conf, len, hwtable, NULL);
        pthread_cleanup_pop(1);
        if (reply == NULL)
                return 1;
index 08ed67d..1a6b318 100644 (file)
@@ -458,11 +458,11 @@ static void replicate_config(const struct hwt_state *hwt, bool local)
        conf = get_multipath_config();
        if (!local)
                /* "full" configuration */
-               cfg1 = snprint_config(conf, NULL, NULL);
+               cfg1 = snprint_config(conf, NULL, NULL, NULL);
        else {
                /* "local" configuration */
                hwtable = get_used_hwes(hwt->vecs->pathvec);
-               cfg1 = snprint_config(conf, NULL, hwtable);
+               cfg1 = snprint_config(conf, NULL, hwtable, hwt->vecs->mpvec);
        }
 
        assert_non_null(cfg1);
@@ -483,7 +483,7 @@ static void replicate_config(const struct hwt_state *hwt, bool local)
        }
 
        conf = get_multipath_config();
-       cfg2 = snprint_config(conf, NULL, NULL);
+       cfg2 = snprint_config(conf, NULL, NULL, NULL);
        assert_non_null(cfg2);
        put_multipath_config(conf);