# check if \f is being used to format man pages
if ($line =~ /\\f[BIR]/) {
if ($prevline =~ /^\.TP/) {
- CHK("ESCAPE_SEQUENCE_AFTER_TP",
- "IGNORE THIS CHECK. Avoid using \\f[BIR] for formatting purposes, however \\c is not supported when following .TP in groff 1.22.3 or older\n" . $hereprev);
+ #CHK("ESCAPE_SEQUENCE_AFTER_TP",
+ # "IGNORE THIS CHECK. Avoid using \\f[BIR] for formatting purposes, however \\c is not supported when following .TP in groff 1.22.3 or older\n" . $hereprev);
} else {
WARN("AVOID_ESCAPE_SEQUENCE",
"Avoid using \\f[BIR] for formatting purposes, instead use .[BI] or .[BIR][BIR] on a new line. Use \\c at the end of the previous line to use a different format without a space.\n" . $herecurr);
} else {
foreach my $subject (split(", ", $subjectline)) {
$subject =~ s/\-/ /;
- if ($line =~ /$subject/ && $line !~ /^\.B [#\$]/) {
+ if ($line =~ /$subject/ && $line !~ /^\.B [clientmgods]*[#\$]/) {
CHK("EXAMPLES_FORMAT_USER_INPUT",
"If this line is user input, it should be bold (.B) and prefaced with either '#'/'\$' for root/non-root users respectively\n" . $herecurr);
}
}
}
return $clean
-}
\ No newline at end of file
+}
.BR lustrefs-MDT0000 .
.SH EXAMPLES
To print the configuration records from the
-.BR testfs-client logfile:
+.BR testfs-client
+logfile, and save it to a file for later restoration by
+.BR lctl-set_param (8):
.RS
.EX
-.B # lctl llog_print testfs-client
+.B # lctl llog_print testfs-client | tee /root/testfs-client.yaml
- { index: 3, event: attach, device: testfs-clilov, type: lov,
UUID: testfs-clilov_UUID }
- { index: 6, event: setup, device: testfs-clilov, UUID: }
.BR lctl (8),
.BR lctl-llog_cancel (8),
.BR lctl-llog_catlist (8),
-.BR lctl-llog_info (8)
+.BR lctl-llog_info (8),
+.BR lctl-set_param (8)
-.TH LCTL-SET_PARAM 8 2024-08-14 Lustre "Lustre Configuration Utilities"
+.TH LCTL-SET_PARAM 8 2025-03-26 Lustre "Lustre Configuration Utilities"
.SH NAME
lctl-set_param \- Lustre filesystem set parameter utility
.SH SYNOPSIS
.RB [ --thread | -t\c
.RI [ THREAD_COUNT ]]
.IR PARAMETER \= VALUE " ..."
-.SY lctl set_param -F
+.SY "lctl set_param -F"
.I FILENAME
.YS
.SH DESCRIPTION
.I FILENAME
instead of from the command-line. The contents of
.I FILENAME
-is YAML format, created as an output from
-.RB ' "lctl --device MGS llog_print"
+is YAML format, created by the output from running
+.RB ' "lctl llog_print"
.I FSNAME\c
-.BR -client '
-or any other valid llog configuration log as listed by
-.RB ' "lctl --device MGS llog_catlist" '
+.BR -client ',
+or from any other valid llog configuration log as listed by
+.RB ' "lctl llog_catlist" '.
.TP
.BR -n ", " --no-name
Disable printing of the parameter name after setting it.
.B -t
is specified without any argument, it runs up to 8 threads by default.
.SH EXAMPLES
+Set two parameters temporarily on the local node:
+.RS
+.EX
+.B client# lctl set_param jobid_name=%H:%e:%u debug_mb=1024
+jobid_name=%H:%e:%u
+debug_mb=1024
+.EE
+.RE
+.PP
+Set two parameters, but don't print parameter names with the values:
+.RS
.EX
-.B # lctl set_param fail_loc=0 timeout=20
-fail_loc=0
-timeout=20
-.B # lctl set_param -n fail_loc=0 timeout=20
-0
-20
-.B # lctl set_param -t2 "ldlm.namespaces.*osc*.lru_size=clear"
+.B client# lctl set_param -n jobid_name=%H:%e:%u debug_mb=1024
+%H:%e:%u
+1024
+.EE
+.RE
+.PP
+Run two parallel threads to set parameters that may do a lot of work:
+.RS
+.EX
+.B client# lctl set_param -t2 "ldlm.namespaces.*osc*.lru_size=clear"
ldlm.namespaces.fsname-OST0001-osc-MDT0000.lru_size=clear
ldlm.namespaces.fsname-OST0000-osc-MDT0000.lru_size=clear
-.B # lctl set_param -P osc.testfs-OST*.max_dirty_mb=512
+.EE
+.RE
+.PP
+Permanently set a parameter with a wildcard in the MGS config llog:
+.RS
+.EX
+.B mgs# lctl set_param -P osc.testfs-OST*.max_dirty_mb=512
osc.testfs-OST0000-osc-ffff8803c9c0f000.max_dirty_mb=512
osc.testfs-OST0001-osc-ffff8803c9c0f000.max_dirty_mb=512
osc.testfs-OST0002-osc-ffff8803c9c0f000.max_dirty_mb=512
osc.testfs-OST0003-osc-ffff8803c9c0f000.max_dirty_mb=512
osc.testfs-OST0004-osc-ffff8803c9c0f000.max_dirty_mb=512
+.EE
+.RE
.PP
-Set
+Permanently set
.B osc.testfs-*.max_dirty_mb=2000
when mounting 'testfs' and
.B osc.testfs-*.max_dirty_mb=1024
-for other Lustre mountpoints on this client node
+for other Lustre mountpoints on this client node:
+.RS
.EX
+.B client# lctl set_param -C=test_fs osc.testfs-*.max_dirty_mb=2000
+.B client# lctl set_param -C osc.*.max_dirty_mb=1024
+.RE
+.EE
+.PP
+Backup the
+.RB ' params '
+configuration log, and then restore it (at some later time):
.RS
-.B # lctl set_param -C=test_fs osc.testfs-*.max_dirty_mb=2000
-.B # lctl set_param -C osc.testfs-*.max_dirty_mb=1024
+.EX
+.B mgs# lctl llog_print params > /tmp/params.yaml
+[ params log is erased, not shown here ]
+.B mgs# lctl set_param -F /tmp/params.yaml
.RE
.EE
.SH AVAILABILITY
# Reapply the config from before
echo "Setting configuration parameters"
- do_facet mgs "lctl set_param -F $yaml_file"
+ do_facet mgs "$LCTL set_param -F $yaml_file" ||
+ error "'set_param -F $yaml_file' failed"
test_123_restore
}
# Reapply the config from before
echo "Setting configuration parameters"
- do_facet mgs "lctl apply_yaml $yaml_file"
+ do_facet mgs "$LCTL apply_yaml $yaml_file" ||
+ error "'apply_yaml $yaml_file' failed"
test_123_restore
}
" [--no-links|-L] [--no-name|-n] [--only-name|-N]\n"
" [--readable|-r] [--recursive|-R]\n"
" [--tunable|-t] [--writable|-w] [--yaml|-y]\n"
- " <param_path1 param_path2 ...>\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"},
{"set_param", jt_lcfg_setparam, 0, "set the Lustre or LNET parameter\n"
- "usage: set_param [--client|-C[FSNAME]] [--delete|-d] [--file|-F]\n"
- " [--no-name|-n] [--permanent|-P]"
+ "usage: set_param [--client|-C[FSNAME]] [--delete|-d] [--no-name|-n]\n"
+ " [--file|-F YAML_PARAM FILE] [--permanent|-P]"
#ifdef HAVE_LIBPTHREAD
" [--thread|-t[THREAD_COUNT]]"
#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"},
+ {"apply_yaml", jt_lcfg_applyyaml, 0, "alias for 'set_param -F'\n"
+ "usage: apply_yaml YAML_PARAM_FILE\n"},
{"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] [--readable|-r]\n"
" [--recursive|-R] [--tunable|-t] [--writable|-w]\n"
- " <param_path1 param_path2 ...>\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"
+ "usage: del_ost [--dryrun] --target FSNAME-OSTxxxx\n"
"Cancel the config records for a specific OST to forget about it.\n"},
/* Debug commands */
#include <stdio.h>
#include <yaml.h>
+static int lcfg_apply_param_yaml(const char *func, const char *filename);
+
static char *lcfg_devname;
int lcfg_set_devname(char *name)
return jt_lcfg_ioctl(&bufs, argv[0], LCFG_PARAM);
}
-static int lcfg_setparam_perm(char *func, char *buf)
+static int lcfg_setparam_perm(const char *func, char *buf)
{
int rc = 0;
struct lustre_cfg_bufs bufs;
{
int rc;
int i;
- int first_param;
char *buf = NULL;
- first_param = optind;
- if (first_param < 0 || first_param >= argc)
+ if (optind < 0 || optind >= argc)
return CMD_HELP;
- for (i = first_param, rc = 0; i < argc; i++) {
+ if (popt->po_file)
+ return lcfg_apply_param_yaml(argv[0], argv[optind]);
+
+ for (i = optind, rc = 0; i < argc; i++) {
buf = argv[i];
if (popt->po_delete) {
char *end_pos;
return rc;
}
-static int lcfg_conf_param(char *func, char *buf)
+static int lcfg_conf_param(const char *func, char *buf)
{
int rc;
struct lustre_cfg_bufs bufs;
return PT_NONE;
}
-static int lcfg_apply_param_yaml(char *func, char *filename)
+static int lcfg_apply_param_yaml(const char *func, const char *filename)
{
FILE *file;
yaml_parser_t parser;
char device[PARAM_SZ + 1];
bool convert;
- convert = !strncmp(func, "set_param", 9);
+ convert = strncmp(func, "set_param", 9) == 0;
file = fopen(filename, "rb");
if (!file) {
rc1 = -errno;
return -1;
}
}
- if (popt->po_perm && popt->po_file) {
- fprintf(stderr, "warning: ignoring -P option\n");
- popt->po_perm = 0;
- }
if (popt->po_delete && !popt->po_perm && !popt->po_client) {
- fprintf(stderr, "warning: setting -P option\n");
+ fprintf(stderr, "warning: setting '-P' option with '-d'\n");
popt->po_perm = 1;
}
return optind;
if (index < 0 || index >= argc)
return CMD_HELP;
- if (popt.po_perm)
+ if (popt.po_perm || popt.po_file)
/*
* We can't delete parameters that were
* set with old conf_param interface
if (popt.po_client)
return jt_lcfg_setparam_client(argc, argv, &popt);
- if (popt.po_file) {
- fprintf(stderr,
- "warning: 'lctl set_param -F' is deprecated, use 'lctl apply_yaml' instead\n");
- return -EINVAL;
- }
-
if (popt_is_parallel(popt)) {
rc = spwq_init(&wq, &popt);
if (rc < 0) {
return 0;
}
-char *jt_cmdname(char *func)
+const char *jt_cmdname(const char *func)
{
return func;
}
}
/* Returns 0 on success, -errno on failure */
-int lcfg_mgs_ioctl(char *func, int dev_id, struct lustre_cfg *lcfg)
+int lcfg_mgs_ioctl(const char *func, int dev_id, struct lustre_cfg *lcfg)
{
struct obd_ioctl_data data;
char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
#define BAD_VERBOSE (-999999999)
-char *jt_cmdname(char *func)
+const char *jt_cmdname(const char *func)
{
static char buf[512];
struct lustre_cfg;
int lcfg_ioctl(char * func, int dev_id, struct lustre_cfg *lcfg);
-int lcfg_mgs_ioctl(char *func, int dev_id, struct lustre_cfg *lcfg);
+int lcfg_mgs_ioctl(const char *func, int dev_id, struct lustre_cfg *lcfg);
int parse_devname(char *func, char *name, int dev_id);
-char *jt_cmdname(char *func);
+const char *jt_cmdname(const char *func);
/* lustre_param.c */
struct param_opts;