From patchwork Tue Feb 20 13:26:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Wilck X-Patchwork-Id: 10230075 X-Patchwork-Delegate: christophe.varoqui@free.fr Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 7D0F7602B1 for ; Tue, 20 Feb 2018 13:28:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6DE0E28508 for ; Tue, 20 Feb 2018 13:28:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6262228516; Tue, 20 Feb 2018 13:28:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E59FC28508 for ; Tue, 20 Feb 2018 13:28:15 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1E13161D0F; Tue, 20 Feb 2018 13:28:15 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D99105D759; Tue, 20 Feb 2018 13:28:14 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 9034A6B512; Tue, 20 Feb 2018 13:28:14 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w1KDRuHv020709 for ; Tue, 20 Feb 2018 08:27:56 -0500 Received: by smtp.corp.redhat.com (Postfix) id 993605D759; Tue, 20 Feb 2018 13:27:56 +0000 (UTC) Delivered-To: dm-devel@redhat.com Received: from mx1.redhat.com (ext-mx04.extmail.prod.ext.phx2.redhat.com [10.5.110.28]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 90A505D75C; Tue, 20 Feb 2018 13:27:56 +0000 (UTC) Received: from smtp.nue.novell.com (smtp.nue.novell.com [195.135.221.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3EC5478540; Tue, 20 Feb 2018 13:27:54 +0000 (UTC) Received: from emea4-mta.ukb.novell.com ([10.120.13.87]) by smtp.nue.novell.com with ESMTP (TLS encrypted); Tue, 20 Feb 2018 14:27:52 +0100 Received: from apollon.suse.de.de (nwb-a10-snat.microfocus.com [10.120.13.201]) by emea4-mta.ukb.novell.com with ESMTP (TLS encrypted); Tue, 20 Feb 2018 13:27:20 +0000 From: Martin Wilck To: Christophe Varoqui , Hannes Reinecke Date: Tue, 20 Feb 2018 14:26:51 +0100 Message-Id: <20180220132658.22295-14-mwilck@suse.com> In-Reply-To: <20180220132658.22295-1-mwilck@suse.com> References: <20180220132658.22295-1-mwilck@suse.com> X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 207 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Tue, 20 Feb 2018 13:27:55 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Tue, 20 Feb 2018 13:27:55 +0000 (UTC) for IP:'195.135.221.5' DOMAIN:'smtp.nue.novell.com' HELO:'smtp.nue.novell.com' FROM:'mwilck@suse.com' RCPT:'' X-RedHat-Spam-Score: -2.301 (RCVD_IN_DNSWL_MED, SPF_PASS) 195.135.221.5 smtp.nue.novell.com 195.135.221.5 smtp.nue.novell.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.28 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: dm-devel@redhat.com Cc: dm-devel@redhat.com, Martin Wilck Subject: [dm-devel] [RFC PATCH 13/20] libmultipath: print: convert API to generic data type X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Tue, 20 Feb 2018 13:28:15 +0000 (UTC) X-Virus-Scanned: ClamAV using ClamSMTP Convert higher level API (snprint_multipath_topology() etc) to using the generic multipath API. This will allow "foreign" multipath objects that implement the generic API to be printed exactly like native multipathd objects. The previous API (using "struct multipath*" and "struct path" remains in place through macros mapping to the new functions. By doing this and testing in regular setups, it's easily verified that the new API works and produces the same results. Moreover, abstract out the code to determine the output format from multipath properties into snprint_multipath_style(), to be able to use it as generic ->style() method. Signed-off-by: Martin Wilck --- libmultipath/configure.c | 1 + libmultipath/dm-generic.c | 2 +- libmultipath/print.c | 116 +++++++++++++++++++++++++++++----------------- libmultipath/print.h | 28 ++++++++--- multipath/main.c | 1 + multipathd/cli_handlers.c | 1 + 6 files changed, 100 insertions(+), 49 deletions(-) diff --git a/libmultipath/configure.c b/libmultipath/configure.c index 13e14cc25fff..42b7c896ee65 100644 --- a/libmultipath/configure.c +++ b/libmultipath/configure.c @@ -30,6 +30,7 @@ #include "discovery.h" #include "debug.h" #include "switchgroup.h" +#include "dm-generic.h" #include "print.h" #include "configure.h" #include "pgpolicies.h" diff --git a/libmultipath/dm-generic.c b/libmultipath/dm-generic.c index 42a26085d087..bdc9ca0a488b 100644 --- a/libmultipath/dm-generic.c +++ b/libmultipath/dm-generic.c @@ -56,7 +56,7 @@ const struct gen_multipath_ops dm_gen_multipath_ops = { .get_pathgroups = dm_mp_get_pgs, .rel_pathgroups = dm_mp_rel_pgs, .snprint = snprint_multipath_attr, - /* .style = snprint_multipath_style, TBD */ + .style = snprint_multipath_style, }; const struct gen_pathgroup_ops dm_gen_pathgroup_ops = { diff --git a/libmultipath/print.c b/libmultipath/print.c index e6f56381791f..8846765066ef 100644 --- a/libmultipath/print.c +++ b/libmultipath/print.c @@ -31,7 +31,8 @@ #include "discovery.h" #include "dm-generic.h" -#define MAX(x,y) (x > y) ? x : y +#define MAX(x,y) (((x) > (y)) ? (x) : (y)) +#define MIN(x,y) (((x) > (y)) ? (y) : (x)) #define TAIL (line + len - 1 - c) #define NOPAD s = c #define PAD(x) \ @@ -846,8 +847,8 @@ snprint_multipath_header (char * line, int len, const char * format) } int -snprint_multipath (char * line, int len, const char * format, - const struct multipath * mpp, int pad) +_snprint_multipath (const struct gen_multipath * gmp, + char * line, int len, const char * format, int pad) { char * c = line; /* line cursor */ char * s = line; /* for padding */ @@ -870,7 +871,7 @@ snprint_multipath (char * line, int len, const char * format, if (!(data = mpd_lookup(*f))) continue; - data->snprint(buff, MAX_FIELD_LEN, mpp); + gmp->ops->snprint(gmp, buff, MAX_FIELD_LEN, *f); PRINT(c, TAIL, "%s", buff); if (pad) PAD(data->width); @@ -913,8 +914,8 @@ snprint_path_header (char * line, int len, const char * format) } int -snprint_path (char * line, int len, const char * format, - const struct path * pp, int pad) +_snprint_path (const struct gen_path * gp, char * line, int len, + const char * format, int pad) { char * c = line; /* line cursor */ char * s = line; /* for padding */ @@ -937,7 +938,7 @@ snprint_path (char * line, int len, const char * format, if (!(data = pd_lookup(*f))) continue; - data->snprint(buff, MAX_FIELD_LEN, pp); + gp->ops->snprint(gp, buff, MAX_FIELD_LEN, *f); PRINT(c, TAIL, "%s", buff); if (pad) PAD(data->width); @@ -948,8 +949,8 @@ snprint_path (char * line, int len, const char * format, } int -snprint_pathgroup (char * line, int len, char * format, - const struct pathgroup * pgp) +_snprint_pathgroup (const struct gen_pathgroup * ggp, char * line, int len, + char * format) { char * c = line; /* line cursor */ char * s = line; /* for padding */ @@ -972,7 +973,7 @@ snprint_pathgroup (char * line, int len, char * format, if (!(data = pgd_lookup(*f))) continue; - data->snprint(buff, MAX_FIELD_LEN, pgp); + ggp->ops->snprint(ggp, buff, MAX_FIELD_LEN, *f); PRINT(c, TAIL, "%s", buff); PAD(data->width); } while (*f++); @@ -980,8 +981,10 @@ snprint_pathgroup (char * line, int len, char * format, __endline(line, len, c); return (c - line); } +#define snprint_pathgroup(line, len, fmt, pgp) \ + _snprint_pathgroup(dm_pathgroup_to_gen(pgp), line, len, fmt) -void print_multipath_topology(struct multipath *mpp, int verbosity) +void _print_multipath_topology(const struct gen_multipath *gmp, int verbosity) { int resize; char *buff = NULL; @@ -998,7 +1001,7 @@ void print_multipath_topology(struct multipath *mpp, int verbosity) return; } - len = snprint_multipath_topology(buff, maxlen, mpp, verbosity); + len = _snprint_multipath_topology(gmp, buff, maxlen, verbosity); resize = (len == maxlen - 1); if (resize) { @@ -1011,12 +1014,30 @@ void print_multipath_topology(struct multipath *mpp, int verbosity) FREE(buff); } -int snprint_multipath_topology(char *buff, int len, const struct multipath *mpp, - int verbosity) +int +snprint_multipath_style(const struct gen_multipath *gmp, char *style, int len, + int verbosity) +{ + int n; + const struct multipath *mpp = gen_multipath_to_dm(gmp); + bool need_action = (verbosity > 1 && + mpp->action != ACT_NOTHING && + mpp->action != ACT_UNDEF && + mpp->action != ACT_IMPOSSIBLE); + bool need_wwid = (strncmp(mpp->alias, mpp->wwid, WWID_SIZE)); + + n = snprintf(style, len, "%s%s%s%s", + need_action ? "%A: " : "", "%n", + need_wwid ? " (%w)" : "", " %d %s"); + return MIN(n, len - 1); +} + +int _snprint_multipath_topology(const struct gen_multipath *gmp, + char *buff, int len, int verbosity) { int j, i, fwd = 0; - struct path * pp = NULL; - struct pathgroup * pgp = NULL; + const struct _vector *pgvec; + const struct gen_pathgroup *gpg; char style[64]; char * c = style; char fmt[64]; @@ -1028,60 +1049,71 @@ int snprint_multipath_topology(char *buff, int len, const struct multipath *mpp, reset_multipath_layout(); if (verbosity == 1) - return snprint_multipath(buff, len, "%n", mpp, 1); + return _snprint_multipath(gmp, buff, len, "%n", 1); if(isatty(1)) c += sprintf(c, "%c[%dm", 0x1B, 1); /* bold on */ - if (verbosity > 1 && - mpp->action != ACT_NOTHING && - mpp->action != ACT_UNDEF && mpp->action != ACT_IMPOSSIBLE) - c += sprintf(c, "%%A: "); - - c += sprintf(c, "%%n"); - - if (strncmp(mpp->alias, mpp->wwid, WWID_SIZE)) - c += sprintf(c, " (%%w)"); - - c += sprintf(c, " %%d %%s"); + c += gmp->ops->style(gmp, c, sizeof(style) - (c - style), + verbosity); + c += snprintf(c, sizeof(style) - (c - style), " %%d %%s"); if(isatty(1)) c += sprintf(c, "%c[%dm", 0x1B, 0); /* bold off */ - fwd += snprint_multipath(buff + fwd, len - fwd, style, mpp, 1); + fwd += _snprint_multipath(gmp, buff + fwd, len - fwd, style, 1); if (fwd >= len) return len; - fwd += snprint_multipath(buff + fwd, len - fwd, PRINT_MAP_PROPS, mpp, - 1); + fwd += _snprint_multipath(gmp, buff + fwd, len - fwd, + PRINT_MAP_PROPS, 1); if (fwd >= len) return len; - if (!mpp->pg) + pgvec = gmp->ops->get_pathgroups(gmp); + if (pgvec == NULL) return fwd; - vector_foreach_slot (mpp->pg, pgp, j) { + vector_foreach_slot (pgvec, gpg, j) { + const struct _vector *pathvec; + struct gen_path *gp; + f=fmt; - if (j + 1 < VECTOR_SIZE(mpp->pg)) { + + if (j + 1 < VECTOR_SIZE(pgvec)) { strcpy(f, "|-+- " PRINT_PG_INDENT); } else strcpy(f, "`-+- " PRINT_PG_INDENT); - fwd += snprint_pathgroup(buff + fwd, len - fwd, fmt, pgp); - if (fwd >= len) - return len; + fwd += _snprint_pathgroup(gpg, buff + fwd, len - fwd, fmt); - vector_foreach_slot (pgp->paths, pp, i) { + if (fwd >= len) { + fwd = len; + break; + } + + pathvec = gpg->ops->get_paths(gpg); + if (pathvec == NULL) + continue; + + vector_foreach_slot (pathvec, gp, i) { f=fmt; if (*f != '|') *f=' '; f++; - if (i + 1 < VECTOR_SIZE(pgp->paths)) + if (i + 1 < VECTOR_SIZE(pathvec)) strcpy(f, " |- " PRINT_PATH_INDENT); else strcpy(f, " `- " PRINT_PATH_INDENT); - fwd += snprint_path(buff + fwd, len - fwd, fmt, pp, 1); - if (fwd >= len) - return len; + fwd += _snprint_path(gp, buff + fwd, len - fwd, fmt, 1); + if (fwd >= len) { + fwd = len; + break; + } } + gpg->ops->rel_paths(gpg, pathvec); + + if (fwd == len) + break; } + gmp->ops->rel_pathgroups(gmp, pgvec); return fwd; } diff --git a/libmultipath/print.h b/libmultipath/print.h index c624d2bfe8d4..e71f87722315 100644 --- a/libmultipath/print.h +++ b/libmultipath/print.h @@ -1,3 +1,6 @@ +#ifndef _PRINT_H +#define _PRINT_H + #define PRINT_PATH_LONG "%w %i %d %D %p %t %T %s %o" #define PRINT_PATH_INDENT "%i %d %D %t %T %o" #define PRINT_PATH_CHECKER "%i %d %D %p %t %T %o %C" @@ -94,11 +97,17 @@ void get_path_layout (vector pathvec, int header); void get_multipath_layout (vector mpvec, int header); int snprint_path_header (char *, int, const char *); int snprint_multipath_header (char *, int, const char *); -int snprint_path (char *, int, const char *, const struct path *, int); -int snprint_multipath (char *, int, const char *, - const struct multipath *, int); -int snprint_multipath_topology (char *, int, const struct multipath * mpp, - int verbosity); +int _snprint_path (const struct gen_path *, char *, int, const char *, int); +#define snprint_path(buf, len, fmt, pp, v) \ + _snprint_path(dm_path_to_gen(pp), buf, len, fmt, v) +int _snprint_multipath (const struct gen_multipath *, char *, int, + const char *, int); +#define snprint_multipath(buf, len, fmt, mp, v) \ + _snprint_multipath(dm_multipath_to_gen(mp), buf, len, fmt, v) +int _snprint_multipath_topology (const struct gen_multipath *, char *, int, + int verbosity); +#define snprint_multipath_topology(buf, len, mpp, v) \ + _snprint_multipath_topology (dm_multipath_to_gen(mpp), buf, len, v) int snprint_multipath_topology_json (char * buff, int len, const struct vectors * vecs); int snprint_multipath_map_json (char * buff, int len, @@ -119,7 +128,11 @@ int snprint_host_wwpn (char *, size_t, const struct path *); int snprint_tgt_wwnn (char *, size_t, const struct path *); int snprint_tgt_wwpn (char *, size_t, const struct path *); -void print_multipath_topology (struct multipath * mpp, int verbosity); +void _print_multipath_topology (const struct gen_multipath * gmp, + int verbosity); +#define print_multipath_topology(mpp, v) \ + _print_multipath_topology(dm_multipath_to_gen(mpp), v) + void print_all_paths (vector pathvec, int banner); void print_all_paths_custo (vector pathvec, int banner, char *fmt); @@ -129,3 +142,6 @@ int snprint_pathgroup_attr(const struct gen_pathgroup* gpg, char *buf, int len, char wildcard); int snprint_multipath_attr(const struct gen_multipath* gm, char *buf, int len, char wildcard); +int snprint_multipath_style(const struct gen_multipath *gmp, + char *style, int len, int verbosity); +#endif /* _PRINT_H */ diff --git a/multipath/main.c b/multipath/main.c index 52bf1658bbca..a0c750e6f623 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -47,6 +47,7 @@ #include "discovery.h" #include "debug.h" #include "switchgroup.h" +#include "dm-generic.h" #include "print.h" #include "alias.h" #include "configure.h" diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c index 7f13bc9d6f32..78f2a12bc2f8 100644 --- a/multipathd/cli_handlers.c +++ b/multipathd/cli_handlers.c @@ -16,6 +16,7 @@ #include "configure.h" #include "blacklist.h" #include "debug.h" +#include "dm-generic.h" #include "print.h" #include "sysfs.h" #include