From 84f02085b9678625f9e7476a537d1ae4e7720a54 Mon Sep 17 00:00:00 2001 From: Aurelien Degremont Date: Tue, 17 Oct 2023 15:07:45 +0200 Subject: [PATCH] LU-17205 utils: add lctl get_param -H option - Add a new '-H' option to 'lctl get_param' that will prefix each output line with the parameter name instead of only the first line by default. That makes grepping lctl get_param with wildcards much easier as you can now easily know which parameter returns which value. $ lctl get_param -H osc.*.state | grep current osc.lustre-OST0000-osc-ff1148c0.state=current_state: FULL osc.lustre-OST0001-osc-ff1248c0.state=current_state: DISCONN osc.lustre-OST0002-osc-ff1348c0.state=current_state: FULL osc.lustre-OST0003-osc-ff1448c0.state=current_state: FULL osc.lustre-OST0004-osc-ff1548c0.state=current_state: FULL It also prints an output line even for empty values. That also makes like easier for admins. - The patch also removes the force line feed if the parameter value was larger than 80 chars. This was considered a misfeature and is now drop for all usages, with or without -H. Lustre-change: https://review.whamcloud.com/52730 Lustre-commit: a12c352a3dd8d424b1da09efc6884530c60d105b Test-Parameters: trivial Signed-off-by: Aurelien Degremont Change-Id: Ib1fa0dc400db4c19fed10ad4cced9be5668418e3 Reviewed-by: Andreas Dilger Reviewed-by: Alexander Boyko Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/53067 Tested-by: jenkins Tested-by: Maloo --- lustre/doc/lctl-get_param.8 | 7 ++++++- lustre/utils/lctl.c | 1 + lustre/utils/lustre_cfg.c | 38 ++++++++++++++++++++++++++++++-------- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/lustre/doc/lctl-get_param.8 b/lustre/doc/lctl-get_param.8 index d2db46d..e34ad76 100644 --- a/lustre/doc/lctl-get_param.8 +++ b/lustre/doc/lctl-get_param.8 @@ -3,7 +3,7 @@ lctl get_param \- retrieve tunable parameters .SH SYNOPSIS .br -.IR "\fBlctl get_param " [ -F "] [" -n | -N "] [" -R "] <" parameter ...> +.IR "\fBlctl get_param " [ -F "] [" -H "] [" -n | -N "] [" -R "] <" parameter ...> .br .SH DESCRIPTION Get the value of the named Lustre or LNet @@ -36,6 +36,11 @@ parameters, respectively. is equivalent to .BR "lctl list_param -F" . .TP +.B -H +Prefix each parameter value line with the parameter name, as a header. It +also print a line for empty values. It could be useful when wildcards are +used and filtering the output. +.TP .B -n Print only the parameter value and not parameter name. This may be confusing if multiple parameter names are specified, as the parameters are not diff --git a/lustre/utils/lctl.c b/lustre/utils/lctl.c index b359c3e..c88288e 100644 --- a/lustre/utils/lctl.c +++ b/lustre/utils/lctl.c @@ -217,6 +217,7 @@ command_t cmdlist[] = { "The path can contain shell-style filename patterns.\n" " -F When -N specified, add '/', '@' or '=' for directories,\n" " symlinks and writeable files, respectively.\n" + " -H Prefix each output line with the parameter name.\n" " -n Print only the value and not parameter name.\n" " -N Print only matched parameter names and not the values.\n" " (Especially useful when using patterns.)\n" diff --git a/lustre/utils/lustre_cfg.c b/lustre/utils/lustre_cfg.c index 327c42f..8ab71fc 100644 --- a/lustre/utils/lustre_cfg.c +++ b/lustre/utils/lustre_cfg.c @@ -443,6 +443,7 @@ struct param_opts { unsigned int po_delete:1; unsigned int po_only_dir:1; unsigned int po_file:1; + unsigned int po_header:1; }; int lcfg_setparam_perm(char *func, char *buf) @@ -816,17 +817,35 @@ read_param(const char *path, const char *param_name, struct param_opts *popt) goto free_buf; } /* don't print anything for empty files */ - if (buf[0] == '\0') + if (buf[0] == '\0') { + if (popt->po_header) + printf("%s=\n", param_name); goto free_buf; + } + + if (popt->po_header) { + char *oldbuf = buf; + char *next; + + do { + /* Split at first \n, if any */ + next = strchrnul(oldbuf, '\n'); + + printf("%s=%.*s\n", param_name, (int)(next - oldbuf), + oldbuf); + + buflen -= next - oldbuf + 1; + oldbuf = next + 1; - if (popt->po_show_path) { - bool longbuf; + } while (buflen > 0); - longbuf = memchr(buf, '\n', buflen - 1) || - buflen + strlen(param_name) >= 80; - printf("%s=%s", param_name, longbuf ? "\n" : ""); + } else if (popt->po_show_path) { + bool multilines = memchr(buf, '\n', buflen - 1); + + printf("%s=%s%s", param_name, multilines ? "\n" : "", buf); + } else { + printf("%s", buf); } - printf("%s", buf); free_buf: free(buf); @@ -1142,11 +1161,14 @@ static int getparam_cmdline(int argc, char **argv, struct param_opts *popt) popt->po_show_path = 1; - while ((ch = getopt(argc, argv, "FnNR")) != -1) { + while ((ch = getopt(argc, argv, "FHnNR")) != -1) { switch (ch) { case 'F': popt->po_show_type = 1; break; + case 'H': + popt->po_header = 1; + break; case 'n': popt->po_show_path = 0; break; -- 1.8.3.1