From owner-svn-src-stable-12@freebsd.org Sat Nov 14 02:00:50 2020 Return-Path: Delivered-To: svn-src-stable-12@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id B982C2D0531; Sat, 14 Nov 2020 02:00:50 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4CXz824nqSz3mPl; Sat, 14 Nov 2020 02:00:50 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 9762D220DA; Sat, 14 Nov 2020 02:00:50 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0AE20oR4097835; Sat, 14 Nov 2020 02:00:50 GMT (envelope-from kevans@FreeBSD.org) Received: (from kevans@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0AE20ovq097834; Sat, 14 Nov 2020 02:00:50 GMT (envelope-from kevans@FreeBSD.org) Message-Id: <202011140200.0AE20ovq097834@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kevans set sender to kevans@FreeBSD.org using -f From: Kyle Evans Date: Sat, 14 Nov 2020 02:00:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r367664 - stable/12/usr.sbin/ngctl X-SVN-Group: stable-12 X-SVN-Commit-Author: kevans X-SVN-Commit-Paths: stable/12/usr.sbin/ngctl X-SVN-Commit-Revision: 367664 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-12@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: SVN commit messages for only the 12-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 14 Nov 2020 02:00:50 -0000 Author: kevans Date: Sat Nov 14 02:00:50 2020 New Revision: 367664 URL: https://svnweb.freebsd.org/changeset/base/367664 Log: MFC r366430: ngctl: add -c (compact output) for the dot command The output of "ngctl dot" is suitable for small netgraph networks. Even moderate complex netgraph setups (about a dozen nodes) are hard to understand from the .dot output, because each node and each hook are shown as a full blown structure. This patch allows to generate much more compact output and graphs by omitting the extra structures for the individual hooks. Instead the names of the hooks are labels to the edges. Modified: stable/12/usr.sbin/ngctl/dot.c Directory Properties: stable/12/ (props changed) Modified: stable/12/usr.sbin/ngctl/dot.c ============================================================================== --- stable/12/usr.sbin/ngctl/dot.c Sat Nov 14 01:58:33 2020 (r367663) +++ stable/12/usr.sbin/ngctl/dot.c Sat Nov 14 02:00:50 2020 (r367664) @@ -2,6 +2,7 @@ /* * dot.c * + * Copyright (c) 2019 Lutz Donnerhacke * Copyright (c) 2004 Brian Fundakowski Feldman * Copyright (c) 1996-1999 Whistle Communications, Inc. * All rights reserved. @@ -53,9 +54,11 @@ static int DotCmd(int ac, char **av); const struct ngcmd dot_cmd = { DotCmd, - "dot [outputfile]", + "dot [-c] [outputfile]", "Produce a GraphViz (.dot) of the entire netgraph.", - "If no outputfile is specified, stdout will be assumed.", + "If no outputfile is specified, stdout will be assumed." + " The optional -c argument generates a graph without separate" + " structures for edge names. Such a graph is more compact.", { "graphviz", "confdot" } }; @@ -66,12 +69,16 @@ DotCmd(int ac, char **av) struct namelist *nlist; FILE *f = stdout; int ch; + int compact = 0; u_int i; /* Get options */ optind = 1; - while ((ch = getopt(ac, av, "")) != -1) { + while ((ch = getopt(ac, av, "c")) != -1) { switch (ch) { + case 'c': + compact = 1; + break; case '?': default: return (CMDRTN_USAGE); @@ -109,9 +116,14 @@ DotCmd(int ac, char **av) } nlist = (struct namelist *)nlresp->data; - fprintf(f, "graph netgraph {\n"); - /* TODO: implement rank = same or subgraphs at some point */ - fprintf(f, "\tedge [ weight = 1.0 ];\n"); + if (compact) { + fprintf(f, "digraph netgraph {\n"); + fprintf(f, "\tedge [ dir = \"none\", fontsize = 10 ];\n"); + } else { + fprintf(f, "graph netgraph {\n"); + /* TODO: implement rank = same or subgraphs at some point */ + fprintf(f, "\tedge [ weight = 1.0 ];\n"); + } fprintf(f, "\tnode [ shape = record, fontsize = 12 ] {\n"); for (i = 0; i < nlist->numnames; i++) fprintf(f, "\t\t\"%jx\" [ label = \"{%s:|{%s|[%jx]:}}\" ];\n", @@ -159,30 +171,40 @@ DotCmd(int ac, char **av) continue; } - fprintf(f, "\tnode [ shape = octagon, fontsize = 10 ] {\n"); - for (j = 0; j < ninfo->hooks; j++) - fprintf(f, "\t\t\"%jx.%s\" [ label = \"%s\" ];\n", - (uintmax_t)nlist->nodeinfo[i].id, - hlist->link[j].ourhook, hlist->link[j].ourhook); - fprintf(f, "\t};\n"); + if (!compact) { + fprintf(f, "\tnode [ shape = octagon, fontsize = 10 ] {\n"); + for (j = 0; j < ninfo->hooks; j++) + fprintf(f, "\t\t\"%jx.%s\" [ label = \"%s\" ];\n", + (uintmax_t)nlist->nodeinfo[i].id, + hlist->link[j].ourhook, hlist->link[j].ourhook); + fprintf(f, "\t};\n"); - fprintf(f, "\t{\n\t\tedge [ weight = 2.0, style = bold ];\n"); - for (j = 0; j < ninfo->hooks; j++) - fprintf(f, "\t\t\"%jx\" -- \"%jx.%s\";\n", - (uintmax_t)nlist->nodeinfo[i].id, - (uintmax_t)nlist->nodeinfo[i].id, - hlist->link[j].ourhook); - fprintf(f, "\t};\n"); + fprintf(f, "\t{\n\t\tedge [ weight = 2.0, style = bold ];\n"); + for (j = 0; j < ninfo->hooks; j++) + fprintf(f, "\t\t\"%jx\" -- \"%jx.%s\";\n", + (uintmax_t)nlist->nodeinfo[i].id, + (uintmax_t)nlist->nodeinfo[i].id, + hlist->link[j].ourhook); + fprintf(f, "\t};\n"); + } for (j = 0; j < ninfo->hooks; j++) { /* Only print the edges going in one direction. */ if (hlist->link[j].nodeinfo.id > nlist->nodeinfo[i].id) continue; - fprintf(f, "\t\"%jx.%s\" -- \"%jx.%s\";\n", - (uintmax_t)nlist->nodeinfo[i].id, - hlist->link[j].ourhook, - (uintmax_t)hlist->link[j].nodeinfo.id, - hlist->link[j].peerhook); + if (compact) { + fprintf(f, "\t\"%jx\" -> \"%jx\" [ headlabel = \"%s\", taillabel = \"%s\" ] ;\n", + (uintmax_t)hlist->link[j].nodeinfo.id, + (uintmax_t)nlist->nodeinfo[i].id, + hlist->link[j].ourhook, + hlist->link[j].peerhook); + } else { + fprintf(f, "\t\"%jx.%s\" -- \"%jx.%s\";\n", + (uintmax_t)nlist->nodeinfo[i].id, + hlist->link[j].ourhook, + (uintmax_t)hlist->link[j].nodeinfo.id, + hlist->link[j].peerhook); + } } free(hlresp); }