.SH NAME
lctl-get_param \- retrieve configuration parameters
.SH SYNOPSIS
-.br
-.IR "\fBlctl get_param " [ -F "] [" -H "] [" -n | -N "] [" -R "] <" parameter ...>
-.br
+.B "\fBlctl get_param "
+.RB [ --classify | -F ]
+.RB [ --header | -H ]
+.RB [ --links | -l ]
+.RB [ --no-links | -L ]
+.RB [ --no-name | -n ]
+.RB [ --only-name | -N ]
+.RB [ --recursive | -R ]
+.RB [ --yaml | -y ]
+.IR PARAM_PATH1 " " PARAM_PATH2 " ..."
.SH DESCRIPTION
Get the value of the named Lustre or LNet
.I parameter
implementation reasons.
.SH OPTIONS
.TP
-.B -F
+.B -F ", " --classify
Append a '/', '@', or '=' suffix for directories, symlinks, and writeable
parameters, respectively.
.B "lctl get_param -NF"
is equivalent to
.BR "lctl list_param -F" .
.TP
-.B -H
+.B -H ", " --header
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
+.B -l ", " --links
+Follow symlinks while searching for parameters. (enabled by default)
+.TP
+.B -L ", " --no-links
+Do not follow symlinks while searching for parameters.
+.TP
+.B -n ", " --no-name
Print only the parameter value and not parameter name. This may be confusing
if multiple parameter names are specified, as the parameters are not
identified, and may not be returned in the order that they are specified.
.TP
-.B -N
+.B -N ", " --only-name
Print only matched parameter names and not the values. This is especially
-useful when using patterns.
+useful when using patterns. This option is equivalent to
+.BR "lctl list_param".
.TP
-.B -R
+.B -R ", " --recursive
Recursively show all of the parameter names below the specified name.
.TP
-.B -y
+.B -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
it can be suppressed with the -n option.
.SH NAME
lctl-list_param \- list configuration parameter names
.SH SYNOPSIS
-.BR list_param " ["-D | -F | -p | -R ]
-.RI < param_search " ...>"
+.B "\fBlctl list_param "
+.RB [ --dir-only | -D ]
+.RB [ --classify | -F ]
+.RB [ --links | -l ]
+.RB [ --no-links | -L ]
+.RB [ --path | -p ]
+.RB [ --recursive | -R ]
+.IR PARAM_PATH1 " " PARAM_PATH2 " ..."
.SH DESCRIPTION
List the Lustre or LNet parameter name(s) matching
.IR param_search .
The parameter name(s) may contain wildcards using
.BR glob (3)
pathname patterns.
+.SH OPTIONS
+The various options supported by
+.B lctl list_param
+are listed and explained below:
.TP
-.B -D
+.B -D ", " --dir-only
Only list directories.
.TP
-.B -F
+.B -F ", " --classify
Append '/', '@' or '=' for dirs, symlinks and writeable files, respectively.
.TP
-.B -p
-Print the pathname instead of the parameter name.
+.B -l ", " --links
+Follow symlinks while searching for parameters. (enabled by default)
.TP
-.B -R
+.B -L ", " --no-links
+Do not follow symlinks while searching for parameters.
+.TP
+.b -p ", " --path
+Print the path name instead of the parameter name.
+.TP
+.B -R ", " --recursive
Recursively list all parameters under the specified parameter search string. If
.I param_search
is unspecified, all the parameters will be shown.
mdt.lustre-MDT0000.evict_client
.br
...
+.br
+.B
+# lctl list_param -L -R mgs.MGS | grep -c .osd
+.br
+ 0
+.br
+# mgs.MGS.osd is a \fIsymlink\fR -> ../../osd-ldiskfs/lustre-MDT0000
+.br
+Compare this to the same command with --links enabled
+.br
+.B
+# lctl list_param -l -R mgs.MGS | grep .osd
+.br
+ mgs.MGS.osd
+.br
+ mgs.MGS.osd.auto_scrub
+.br
+ mgs.MGS.osd.blocksize
+.br
+ mgs.MGS.osd.enable_projid.xattr
+.br
+ mgs.MGS.osd.extent_bytes_allocation
+.br
+ ...
.SH SEE ALSO
.BR lustre (7),
.BR lctl-get_param (8),
lctl-set_param \- Lustre filesystem set parameter utility
.SH SYNOPSIS
.B "\fBlctl set_param "
-.RB [ \-d ]
-.RB [ \-h ]
-.RB [ \-n ]
-.RB [ \-P ]
-.RB [ \-t [ \fITHREAD_COUNT ]]
-.RI < parameter \= value ...>
-.br
-.IR "\fBlctl set_param -F " < filename >
+.RB [ --delete | -d ]
+.RB [ --file | -F ]
+.RB [ --no-name | -n ]
+.RB [ --permanent | -P ]
+.RB [ --thread | -t [ \fITHREAD_COUNT ]]
+.IR PARAMETER \= VALUE " ..."
+.br
+.B lctl set_param -F
+.IR FILENAME
.SH DESCRIPTION
Set the value of the named Lustre or LNet
.I parameter
but may be a specific component, or contain wildcards to match some or all
devices on the node. Parameters can only be modified by the root user for
security reasons.
+.SH OPTIONS
+The various options supported by
+.B lctl list_param
+are listed and explained below:
.TP
-.B -d
+.B -d ", " --delete
Remove the permanent setting (only for parameters set with the
.B -P
option).
.TP
-.B -F
+.B -F ", " --file
Set parameters from
.I filename
instead of from the command-line. The contents of
.I filename
is YAML format, created as an output from
-.BR ' "lctl --device MGS llog_print " < \fIfsname\fR >- client '
+.RB ' "lctl --device MGS llog_print " \fIFSNAME\fB "-client" '
or any other valid llog configuration log as listed by
.RB ' "lctl --device MGS llog_catlist" '
.TP
-.B -n
+.B -n ", " --no-name
Disable printing of the parameter name after setting it.
.TP
-.B -P
+.B -P ", " --permanent
Set
.I parameter
permanently on
in Lustre 2.5.0 and later clients, older clients cannot set persistent
parameters, nor will they see them.
.TP
-.B -t
+.B -t ", " --thread
Spawn threads to set multiple parameters in parallel, optionally specifying
the maximum number of threads to run (with no space between
.B -t
sort -u | wc -l)
[ $params -eq $procs ] ||
- error "found $params parameters vs. $procs proc files"
+ error "found $params parameters vs. $procs proc files '-D'"
}
run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
if $LCTL list_param jobid_name > /dev/null 2>&1; then
local testname=jobid_name new_value='foo=bar%p'
else
- local testname=jobid_var new_valuie=foo=bar
+ local testname=jobid_var new_value=foo=bar
fi
local jobid_var_old=$($LCTL get_param -n $testname)
}
run_test 401e "verify 'lctl get_param' works with NID in parameter"
+test_401f() {
+ $LCTL list_param -RpL "*" | while read path; do
+ [[ ! -L $path ]] ||
+ error "list_param -RpL returned the symlink: '$path'"
+ done
+}
+run_test 401f "check 'lctl list_param' doesn't follow symlinks with --no-links"
+
test_402() {
[[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
[[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
{"local_param", jt_lcfg_param, 0, "set a temporary, local param\n"
"usage: local_param <target.keyword=val>\n"},
{"get_param", jt_lcfg_getparam, 0, "get the Lustre or LNET parameter\n"
- "usage: get_param [-F|n|-N|-R] <param_path1 param_path2 ...>\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"
+ " <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"
- " -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"
- " -R Get parameters recursively from the specified entry.\n"},
+ "The path can contain shell-style filename patterns.\n"},
{"set_param", jt_lcfg_setparam, 0, "set the Lustre or LNET parameter\n"
- "usage: set_param [-n] [-P] [-d] [-F] "
+ "usage: set_param [--delete|-d] [--file|-F] [--no-name|-n]\n"
+ " [--permanent|-P]"
#ifdef HAVE_LIBPTHREAD
- "[-t[THREAD_COUNT]] "
+ " [--thread|-t [THREAD_COUNT]]"
#endif
- "PARAM1=VALUE1 [PARAM2=VALUE2 ...]\n"
- "Set the value of the Lustre or LNET parameter at the specified path.\n"
- " -n Disable printing of the key name when printing values.\n"
- " -P Set the parameter permanently, filesystem-wide.\n"
- " -d Remove the permanent setting (only with -P option).\n"
- " -F Read permanent configuration from a YAML file.\n"
-#ifdef HAVE_LIBPTHREAD
- " -t Set parameters in parallel, max THREAD_COUNT threads\n"
- " (default " STRINGIFY(LCFG_THREADS_DEF) ").\n"
-#endif
- },
+ "\n"
+ " PARAM1=VALUE1 [PARAM2=VALUE2 ...]\n"
+ "Set the value of the Lustre or LNET parameter at the specified path.\n"},
{"apply_yaml", jt_lcfg_applyyaml, 0, "set/config the Lustre or LNET "
"parameters using configuration from a YAML file.\n"
"usage: apply_yaml file\n"},
{"list_param", jt_lcfg_listparam, 0,
"list the Lustre or LNET parameter name\n"
- "usage: list_param [-D|-F|-p|-R] <param_path1 param_path2 ...>\n"
- "List the name of Lustre or LNET parameter from the specified path.\n"
- " -D Only list directories.\n"
- " -F Add '/', '@' or '=' for dirs, symlinks and writeable files, respectively.\n"
- " -p Prints the pathname instead of the parameter name.\n"
- " -R Recursively list all parameters under the specified path.\n"},
+ "usage: list_param [--dir-only|-D] [--classify|-F] [--links|-l]\n"
+ " [--no-links|-L] [--path|-p] [--recursive|-R]\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"
"usage: del_ost [--dryrun] --target <$fsname-OSTxxxx>\n"
"Cancel the config records for a specific OST to forget about it.\n"},
unsigned int po_yaml:1;
unsigned int po_detail:1;
unsigned int po_header:1;
+ unsigned int po_follow_symlinks:1;
unsigned int po_parallel_threads;
};
struct stat st;
int rc2, j;
- if (stat(paths.gl_pathv[i], &st) == -1) {
+ if (!popt->po_follow_symlinks)
+ rc2 = lstat(paths.gl_pathv[i], &st);
+ else
+ rc2 = stat(paths.gl_pathv[i], &st);
+
+ if (rc2 == -1) {
fprintf(stderr, "error: %s: stat '%s': %s\n",
opname, paths.gl_pathv[i], strerror(errno));
if (!rc)
continue;
}
+ if (S_ISLNK(st.st_mode) && !popt->po_follow_symlinks)
+ continue;
if (popt->po_only_dir && !S_ISDIR(st.st_mode))
continue;
static int listparam_cmdline(int argc, char **argv, struct param_opts *popt)
{
+ struct option long_opts[] = {
+ { .val = 'D', .name = "dir-only", .has_arg = no_argument},
+ { .val = 'D', .name = "directory-only", .has_arg = no_argument},
+ { .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 = "recursive", .has_arg = no_argument},
+ };
+
int ch;
popt->po_show_name = 1;
popt->po_only_name = 1;
+ popt->po_follow_symlinks = 1;
- while ((ch = getopt(argc, argv, "DFpR")) != -1) {
+ while ((ch = getopt_long(argc, argv, "DFlLpR",
+ long_opts, NULL)) != -1) {
switch (ch) {
case 'D':
popt->po_only_dir = 1;
case 'F':
popt->po_show_type = 1;
break;
+ case 'l':
+ popt->po_follow_symlinks = 1;
+ break;
+ case 'L':
+ popt->po_follow_symlinks = 0;
+ break;
case 'p':
popt->po_only_pathname = 1;
break;
static int getparam_cmdline(int argc, char **argv, struct param_opts *popt)
{
+ struct option long_opts[] = {
+ { .val = 'F', .name = "classify", .has_arg = no_argument},
+ { .val = 'H', .name = "header", .has_arg = no_argument},
+ { .val = 'l', .name = "links", .has_arg = no_argument},
+ { .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 = "recursive", .has_arg = no_argument},
+ { .val = 'y', .name = "yaml", .has_arg = no_argument},
+ };
+
int ch;
popt->po_show_name = 1;
+ popt->po_follow_symlinks = 1;
- while ((ch = getopt(argc, argv, "FHnNRy")) != -1) {
+ while ((ch = getopt_long(argc, argv, "FHlLnNRy",
+ long_opts, NULL)) != -1) {
switch (ch) {
case 'F':
popt->po_show_type = 1;
case 'H':
popt->po_header = 1;
break;
+ case 'l':
+ popt->po_follow_symlinks = 1;
+ break;
+ case 'L':
+ popt->po_follow_symlinks = 0;
+ break;
case 'n':
popt->po_show_name = 0;
break;
*/
static int setparam_cmdline(int argc, char **argv, struct param_opts *popt)
{
+ struct option long_opts[] = {
+ { .val = 'd', .name = "delete", .has_arg = no_argument},
+ { .val = 'F', .name = "file", .has_arg = no_argument},
+ { .val = 'n', .name = "no-name", .has_arg = no_argument},
+ { .val = 'P', .name = "perm", .has_arg = no_argument},
+ { .val = 'P', .name = "permanent", .has_arg = no_argument},
+ { .val = 't', .name = "thread", .has_arg = optional_argument},
+ };
+
int ch;
popt->po_show_name = 1;
popt->po_delete = 0;
popt->po_file = 0;
popt->po_parallel_threads = 0;
+ popt->po_follow_symlinks = 1;
opterr = 0;
- while ((ch = getopt(argc, argv, "dFnPt::")) != -1) {
+ while ((ch = getopt_long(argc, argv, "dFnPt::",
+ long_opts, NULL)) != -1) {
switch (ch) {
case 'n':
popt->po_show_name = 0;