Whamcloud - gitweb
LU-14442 utils: [-r|-w] options for get/list_param 65/55665/18
authorFrederick Dilger <fdilger@whamcloud.com>
Mon, 8 Jul 2024 20:29:29 +0000 (14:29 -0600)
committerOleg Drokin <green@whamcloud.com>
Sun, 2 Feb 2025 06:23:58 +0000 (06:23 +0000)
New [--readable|-r] and [--writable|-w] options have been added for
get_param and list_param that will only print parameters with the
specified permissions.
This is useful to find tunable parameters, or avoid write-only
parameters or statistics.

Signed-off-by: Frederick Dilger <fdilger@whamcloud.com>
Change-Id: I00fca8f354733c9ee6d75c60e39121c12068a2a4
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/55665
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Olaf Faaland <faaland1@llnl.gov>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/conf/mount.client.params
lustre/doc/lctl-get_param.8
lustre/doc/lctl-list_param.8
lustre/tests/sanity.sh
lustre/utils/lctl.c
lustre/utils/lctl_thread.h
lustre/utils/lustre_param.c

index b9aca77..5027023 100644 (file)
@@ -1,13 +1,14 @@
 # This is the per-client lustre configuration file.
-# The parameters declared in this file will be set after the system has mounted,
-# but only on this node.
+# The parameters declared in this file will be set after
+# the system has mounted, but only on this node.
+# Parameters for ALL clients should use "lctl set_param -P".
 
-# if mount.$FS_NAME.params exists, the parameters declared in
+# If mount.$FS_NAME.params exists, the parameters declared in
 # that file will be loaded afterwards, meaning the filesystem
 # specific parameters will override the client specific ones.
 
 # Examples:
-# max_dirty_mb=7873
+# osc.*.max_dirty_mb=7873
 # mdc.*.max_rpcs_in_flight=16
 # jobid_var=nodelocal
 # jobid_name=%H:%e:%u
\ No newline at end of file
index eba0fc9..6358bc1 100644 (file)
@@ -9,7 +9,9 @@ lctl-get_param \- retrieve configuration parameters
 .RB [ --no-links | -L ]
 .RB [ --no-name | -n ]
 .RB [ --only-name | -N ]
+.RB [ --readable | -r ]
 .RB [ --recursive | -R ]
+.RB [ --writable | -w ]
 .RB [ --yaml | -y ]
 .IR PARAM_PATH1 " [" PARAM_PATH2 " ...]"
 .YS
@@ -67,9 +69,19 @@ Print only matched parameter names and not the values. This is especially
 useful when using patterns. This option is equivalent to
 .BR "lctl list_param".
 .TP
+.BR -r ", " --readable
+Print only parameters that are have read permission. Can be used with
+.RB [ -w | --writable ]
+to print parameters that are both readable and writable.
+.TP
 .BR -R ", " --recursive
 Recursively show all of the parameter names below the specified name.
 .TP
+.BR -w ", " --writable
+Print only parameters that are have write permission. Can be used with
+.RB [ -r | --readable ]
+to print parameters that are both readable and writable.
+.TP
 .BR -y ", " --yaml
 Some paramters can be presented in a YAML format but are not by default. This
 will format the parameter data in YAML. If the YAML provides a source: field
index ac3bfb6..bc55ffe 100644 (file)
@@ -8,7 +8,9 @@ lctl-list_param \- list configuration parameter names
 .RB [ --links | -l ]
 .RB [ --no-links | -L ]
 .RB [ --path | -p ]
+.RB [ --readable | -r ]
 .RB [ --recursive | -R ]
+.RB [ --writeable | -w ]
 .IR PARAM_PATH1 " [" PARAM_PATH2 " ...]"
 .YS
 .SH DESCRIPTION
@@ -37,10 +39,20 @@ Do not follow symlinks while searching for parameters.
 .BR -p ", " --path
 Print the path name instead of the parameter name.
 .TP
+.BR -r ", " --readable
+Print only parameters that have read permission. Can be used with
+.RB [ -w | --writable ]
+to print parameters that are both readable and writable.
+.TP
 .BR -R ", " --recursive
 Recursively list all parameters under the specified parameter search string. If
 .I param_search
 is unspecified, all the parameters will be shown.
+.TP
+.BR -w ", " --writable
+Print only parameters that have write permission. Can be used with
+.RB [ -r | --readable ]
+to print parameters that are both readable and writable.
 .SH EXAMPLES
 Use wildcards to obtain all matching parameters:
 .RS
index a22a0d8..9468be3 100755 (executable)
@@ -29567,6 +29567,41 @@ test_401aa() {
 }
 run_test 401aa "Verify that 'lctl list_param -p' lists the correct path names"
 
+test_401ab() {
+       $LCTL list_param -pr "*" | while read path; do
+               [[ -r $path ]] || error "'$path' not readable"
+       done
+
+       $LCTL list_param -pLr "*" | while read path; do
+               [[ -r $path ]] || error "'$path' not readable (--no-links)"
+       done
+}
+run_test 401ab "Check that 'lctl list_param -r' lists only readable params"
+
+test_401ac() {
+       $LCTL list_param -pw "*" | while read path; do
+               [[ -w $path ]] || error "'$path' not writable"
+       done
+
+       $LCTL list_param -pLw "*" | while read path; do
+               [[ -w $path ]] || error "'$path' not writable (--no-links)"
+       done
+}
+run_test 401ac "Check that 'lctl list_param -w' lists only writable params"
+
+test_401ad() {
+       $LCTL list_param -prw "*" | while read path; do
+               [[ -r $path && -w $path ]] ||
+                       error "'$path' not readable and writable"
+       done
+
+       $LCTL list_param -pLrw "*" | while read path; do
+               [[ -r $path && -w $path ]] ||
+                       error "'$path' not readable and writable (--no-links)"
+       done
+}
+run_test 401ad "Check that 'lctl list_param -wr' is conjunctive"
+
 test_401b() {
        # jobid_var may not allow arbitrary values, so use jobid_name
        # if available
index b3277ad..0fd8956 100644 (file)
@@ -365,7 +365,8 @@ command_t cmdlist[] = {
        {"get_param", jt_lcfg_getparam, 0, "get the Lustre or LNET parameter\n"
         "usage: get_param [--classify|-F] [--header|-H] [--links|-l]\n"
         "                 [--no-links|-L] [--no-name|-n] [--only-name|-N]\n"
-        "                 [--recursive|-R] [--yaml|-y]\n"
+        "                 [--readable|-r] [--recursive|-R]\n"
+        "                 [--writable|-w] [--yaml|-y]\n"
         "                 <param_path1 param_path2 ...>\n"
         "Get the value of Lustre or LNET parameter from the specified path.\n"
         "The path can contain shell-style filename patterns.\n"},
@@ -384,7 +385,8 @@ command_t cmdlist[] = {
        {"list_param", jt_lcfg_listparam, 0,
         "list the Lustre or LNET parameter name\n"
         "usage: list_param [--dir-only|-D] [--classify|-F] [--links|-l]\n"
-        "                  [--no-links|-L] [--path|-p] [--recursive|-R]\n"
+        "                  [--no-links|-L] [--path|-p] [--readable|-r]\n"
+        "                  [--recursive|-R] [--writable|-w]\n"
         "                  <param_path1 param_path2 ...>\n"
         "List the name of Lustre or LNet parameter from the specified path.\n"},
        {"del_ost", jt_del_ost, 0, "permanently delete OST records\n"
index b0b2aa9..6a19634 100644 (file)
@@ -50,6 +50,7 @@ struct param_opts {
        unsigned int po_header:1;
        unsigned int po_follow_symlinks:1;
        unsigned int po_parallel_threads;
+       unsigned int po_permissions;
 };
 
 #ifdef HAVE_LIBPTHREAD
index c38bc8d..6356c27 100644 (file)
@@ -469,6 +469,9 @@ static int do_param_op(struct param_opts *popt, char *pattern, char *value,
                        continue;
                if (popt->po_only_dir && !S_ISDIR(st.st_mode))
                        continue;
+               if (popt->po_permissions &&
+                   (st.st_mode & popt->po_permissions) != popt->po_permissions)
+                       continue;
 
                param_name = display_name(paths.gl_pathv[i], &st, popt);
                if (!param_name) {
@@ -631,7 +634,9 @@ static int listparam_cmdline(int argc, char **argv, struct param_opts *popt)
        { .val = 'F',   .name = "classify",     .has_arg = no_argument},
        { .val = 'l',   .name = "links",        .has_arg = no_argument},
        { .val = 'L',   .name = "no-links",     .has_arg = no_argument},
+       { .val = 'r',   .name = "readable",     .has_arg = no_argument},
        { .val = 'R',   .name = "recursive",    .has_arg = no_argument},
+       { .val = 'w',   .name = "writable",     .has_arg = no_argument},
        };
 
        int ch;
@@ -642,7 +647,7 @@ static int listparam_cmdline(int argc, char **argv, struct param_opts *popt)
 
        /* reset optind for each getopt_long() in case of multiple calls */
        optind = 0;
-       while ((ch = getopt_long(argc, argv, "DFlLpR",
+       while ((ch = getopt_long(argc, argv, "DFlLprRw",
                                      long_opts, NULL)) != -1) {
                switch (ch) {
                case 'D':
@@ -660,9 +665,15 @@ static int listparam_cmdline(int argc, char **argv, struct param_opts *popt)
                case 'p':
                        popt->po_only_pathname = 1;
                        break;
+               case 'r':
+                       popt->po_permissions |= S_IREAD;
+                       break;
                case 'R':
                        popt->po_recursive = 1;
                        break;
+               case 'w':
+                       popt->po_recursive |= S_IWRITE;
+                       break;
                default:
                        return -1;
                }
@@ -727,7 +738,9 @@ static int getparam_cmdline(int argc, char **argv, struct param_opts *popt)
        { .val = 'L',   .name = "no-links",     .has_arg = no_argument},
        { .val = 'n',   .name = "no-name",      .has_arg = no_argument},
        { .val = 'N',   .name = "only-name",    .has_arg = no_argument},
+       { .val = 'r',   .name = "readable",     .has_arg = no_argument},
        { .val = 'R',   .name = "recursive",    .has_arg = no_argument},
+       { .val = 'w',   .name = "writable",     .has_arg = no_argument},
        { .val = 'y',   .name = "yaml",         .has_arg = no_argument},
        };
 
@@ -738,7 +751,7 @@ static int getparam_cmdline(int argc, char **argv, struct param_opts *popt)
 
        /* reset optind for each getopt_long() in case of multiple calls */
        optind = 0;
-       while ((ch = getopt_long(argc, argv, "FHlLnNRy",
+       while ((ch = getopt_long(argc, argv, "FHlLnNrRwy",
                                      long_opts, NULL)) != -1) {
                switch (ch) {
                case 'F':
@@ -759,9 +772,15 @@ static int getparam_cmdline(int argc, char **argv, struct param_opts *popt)
                case 'N':
                        popt->po_only_name = 1;
                        break;
+               case 'r':
+                       popt->po_permissions |= S_IREAD;
+                       break;
                case 'R':
                        popt->po_recursive = 1;
                        break;
+               case 'w':
+                       popt->po_permissions |= S_IWRITE;
+                       break;
                case 'y':
                        popt->po_yaml = 1;
                        break;