X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Futils%2Flctl.c;h=4fb70716d8c34238e9a50769249bb8b971e28cdd;hp=6d9a3a25e80007217415450b19fc8cc443f69fb6;hb=0d75d5cd5a6217ec75bac8d3f479bbfb8a10be29;hpb=a0f7174c4106104f45977eeec7338e8f7fd1dafa diff --git a/lustre/utils/lctl.c b/lustre/utils/lctl.c index 6d9a3a2..4fb7071 100644 --- a/lustre/utils/lctl.c +++ b/lustre/utils/lctl.c @@ -15,11 +15,7 @@ * * You should have received a copy of the GNU General Public License * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * http://www.gnu.org/licenses/gpl-2.0.html * * GPL HEADER END */ @@ -27,7 +23,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, 2014, Intel Corporation. + * Copyright (c) 2012, 2017, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -46,22 +42,51 @@ #include #include #include -#include +#include #include "obdctl.h" -#include +#include +#include -static int jt_noop(int argc, char **argv) { - return 0; -} +static int lctl_list_commands(int argc, char **argv); static int jt_opt_ignore_errors(int argc, char **argv) { Parser_ignore_errors(1); return 0; } +static int jt_pcc_list_commands(int argc, char **argv); +static int jt_pcc(int argc, char **argv); + +/** + * command_t pccdev_cmdlist - lctl pcc commands. + */ +command_t pccdev_cmdlist[] = { + { .pc_name = "add", .pc_func = jt_pcc_add, + .pc_help = "Add a PCC backend to a client.\n" + "usage: lctl pcc add [--param|-p ]\n" + "\tmntpath: Lustre mount point.\n" + "\tpccpath: Path of the PCC backend.\n" + "\tparam: Setting parameters for PCC backend.\n" }, + { .pc_name = "del", .pc_func = jt_pcc_del, + .pc_help = "Delete the specified PCC backend on a client.\n" + "usage: clt pcc del \n" }, + { .pc_name = "clear", .pc_func = jt_pcc_clear, + .pc_help = "Remove all PCC backend on a client.\n" + "usage: lctl pcc clear \n" }, + { .pc_name = "list", .pc_func = jt_pcc_list, + .pc_help = "List all PCC backends on a client.\n" + "usage: lctl pcc list \n" }, + { .pc_name = "list-commands", .pc_func = jt_pcc_list_commands, + .pc_help = "list commands supported by lctl pcc"}, + { .pc_name = "help", .pc_func = Parser_help, .pc_help = "help" }, + { .pc_name = "exit", .pc_func = Parser_quit, .pc_help = "quit" }, + { .pc_name = "quit", .pc_func = Parser_quit, .pc_help = "quit" }, + { .pc_help = NULL } +}; + command_t cmdlist[] = { /* Metacommands */ - {"===== metacommands =======", jt_noop, 0, "metacommands"}, + {"===== metacommands =======", NULL, 0, "metacommands"}, {"--device", jt_opt_device, 0, "run after connecting to device \n" "--device "}, @@ -73,7 +98,7 @@ command_t cmdlist[] = { "ignore_errors"}, /* User interface commands */ - {"======== control =========", jt_noop, 0, "control commands"}, + {"======== control =========", NULL, 0, "control commands"}, {"help", Parser_help, 0, "help"}, {"lustre_build_version", jt_get_version, 0, "print version of Lustre modules\n" @@ -82,9 +107,11 @@ command_t cmdlist[] = { {"quit", Parser_quit, 0, "quit"}, {"--version", Parser_version, 0, "print build version of this utility and exit"}, + {"--list-commands", lctl_list_commands, 0, + "list commands supported by this utility and exit"}, /* Network configuration commands */ - {"===== network config =====", jt_noop, 0, "network config"}, + {"===== network config =====", NULL, 0, "network config"}, {"--net", jt_opt_net, 0, "run after selecting network \n" "usage: --net "}, {"network", jt_ptl_network, 0, "configure LNET" @@ -97,7 +124,7 @@ command_t cmdlist[] = { "usage: which_nid NID [NID...]"}, {"replace_nids", jt_replace_nids, 0, "replace primary NIDs for a device\n" - "usage: replace_nids [,nid2,nid3]"}, + "usage: replace_nids [,nid2,nid3:nid4,nid5:nid6]"}, {"interface_list", jt_ptl_print_interfaces, 0, "print network interface entries\n" "usage: interface_list"}, @@ -118,9 +145,10 @@ command_t cmdlist[] = { "usage: net_drop_add <-s | --source NID>\n" " <-d | --dest NID>\n" " <<-r | --rate DROP_RATE> |\n" - " <-i | --interval SECONDS>>\n" + " <-i | --interval SECONDS>>\n" " [<-p | --portal> PORTAL...]\n" - " [<-m | --message> ...]\n"}, + " [<-m | --message> ...]\n" + " [< -e | --health_error]\n"}, {"net_drop_del", jt_ptl_drop_del, 0, "remove LNet drop rule\n" "usage: net_drop_del <[-a | --all] |\n" " <-s | --source NID>\n" @@ -147,7 +175,7 @@ command_t cmdlist[] = { "usage: net_delay_list"}, /* Device selection commands */ - {"==== obd device selection ====", jt_noop, 0, "device selection"}, + {"==== obd device selection ====", NULL, 0, "device selection"}, {"device", jt_obd_device, 0, "set current device to \n" "usage: device <%name|$name|devno>"}, @@ -157,7 +185,7 @@ command_t cmdlist[] = { "usage: dl [-t]"}, /* Device operations */ - {"==== obd device operations ====", jt_noop, 0, "device operations"}, + {"==== obd device operations ====", NULL, 0, "device operations"}, {"activate", jt_obd_activate, 0, "activate an import\n"}, {"deactivate", jt_obd_deactivate, 0, "deactivate an import. " "This command should be used on failed OSC devices in an MDT LOV.\n"}, @@ -166,10 +194,11 @@ command_t cmdlist[] = { {"set_timeout", jt_lcfg_set_timeout, 0, "usage: conf_param obd_timeout=\n"}, #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0) - {"conf_param", jt_lcfg_mgsparam, 0,"set a permanent config parameter.\n" + {"conf_param", jt_lcfg_confparam, 0, + "set a permanent config parameter.\n" "This command must be run on the MGS node\n" "usage: conf_param [-d] \n" - " -d Remove the permanent setting."}, + " -d Delete the permanent setting from the configuration."}, #endif {"local_param", jt_lcfg_param, 0, "set a temporary, local param\n" "usage: local_param \n"}, @@ -184,12 +213,13 @@ command_t cmdlist[] = { " (Especially useful when using patterns.)\n" " -R Get parameters recursively from the specified entry.\n"}, {"set_param", jt_lcfg_setparam, 0, "set the Lustre or LNET parameter\n" - "usage: set_param [-n] [-P] [-d]" + "usage: set_param [-n] [-P] [-d] [-F]" "\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"}, + " -d Remove the permanent setting (only with -P option).\n" + " -F Read permanent configuration from a YAML file.\n"}, {"list_param", jt_lcfg_listparam, 0, "list the Lustre or LNET parameter name\n" "usage: list_param [-F|-R|-D] \n" @@ -200,7 +230,7 @@ command_t cmdlist[] = { " -R Recursively list all parameters under the specified path.\n"}, /* Debug commands */ - {"==== debugging control ====", jt_noop, 0, "debug"}, + {"==== debugging control ====", NULL, 0, "debug"}, {"debug_daemon", jt_dbg_debug_daemon, 0, "debug daemon control and dump to a file\n" "usage: debug_daemon {start file [#MB]|stop}"}, @@ -231,20 +261,8 @@ command_t cmdlist[] = { "provide gdb-friendly module information\n" "usage: modules "}, - /* virtual block operations */ - {"==== virtual block device ====", jt_noop, 0, "virtual block device"}, - {"blockdev_attach", jt_blockdev_attach, 0, - "attach a lustre regular file to a virtual block device\n" - "usage: blockdev_attach "}, - {"blockdev_detach", jt_blockdev_detach, 0, - "detach a lustre regular file from a virtual block device\n" - "usage: blockdev_detach "}, - {"blockdev_info", jt_blockdev_info, 0, - "get the device info of an attached file\n" - "usage: blockdev_info "}, - /* Pool commands */ - {"=== Pools ==", jt_noop, 0, "pool management"}, + {"=== Pools ==", NULL, 0, "pool management"}, {"pool_new", jt_pool_cmd, 0, "add a new pool\n" "usage: pool_new ."}, @@ -261,8 +279,62 @@ command_t cmdlist[] = { "list pools and pools members\n" "usage: pool_list [.] | "}, +#ifdef HAVE_SERVER_SUPPORT + /* Barrier commands */ + {"=== Barrier ==", NULL, 0, "barrier management"}, + {"barrier_freeze", jt_barrier_freeze, 0, + "freeze write barrier on MDTs\n" + "usage: barrier_freeze [timeout (in seconds)]"}, + {"barrier_thaw", jt_barrier_thaw, 0, + "thaw write barrier on MDTs\n" + "usage: barrier_thaw "}, + {"barrier_stat", jt_barrier_stat, 0, + "query write barrier status on MDTs\n" + "usage: barrier_stat [--state|-s] [--timeout|-t] "}, + {"barrier_rescan", jt_barrier_rescan, 0, + "rescan the system to filter out inactive MDT(s) for barrier\n" + "usage: barrier_rescan [timeout (in seconds)]"}, + + /* Snapshot commands */ + {"=== Snapshot ==", NULL, 0, "Snapshot management"}, + {"snapshot_create", jt_snapshot_create, 0, + "create the snapshot\n" + "usage: snapshot_create [-b | --barrier [on | off]]\n" + " [-c | --comment comment]\n" + " <-F | --fsname fsname>\n" + " [-h | --help] <-n | --name ssname>\n" + " [-r | --rsh remote_shell]\n" + " [-t | --timeout timeout]"}, + {"snapshot_destroy", jt_snapshot_destroy, 0, + "destroy the snapshot\n" + "usage: snapshot_destroy [-f | --force]\n" + " <-F | --fsname fsname> [-h | --help]\n" + " <-n | --name ssname>\n" + " [-r | --rsh remote_shell]"}, + {"snapshot_modify", jt_snapshot_modify, 0, + "modify the snapshot\n" + "usage: snapshot_modify [-c | --comment comment]\n" + " <-F | --fsname fsname> [-h | --help]\n" + " <-n | --name ssname> [-N | --new new_ssname]\n" + " [-r | --rsh remote_shell]"}, + {"snapshot_list", jt_snapshot_list, 0, + "query the snapshot(s)\n" + "usage: snapshot_list [-d | --detail]\n" + " <-F | --fsname fsname> [-h | --help]\n" + " [-n | --name ssname] [-r | --rsh remote_shell]"}, + {"snapshot_mount", jt_snapshot_mount, 0, + "mount the snapshot\n" + "usage: snapshot_mount <-F | --fsname fsname> [-h | --help]\n" + " <-n | --name ssname>\n" + " [-r | --rsh remote_shell]"}, + {"snapshot_umount", jt_snapshot_umount, 0, + "umount the snapshot\n" + "usage: snapshot_umount <-F | --fsname fsname> [-h | --help]\n" + " <-n | --name ssname>\n" + " [-r | --rsh remote_shell]"}, +#endif /* HAVE_SERVER_SUPPORT */ /* Nodemap commands */ - {"=== Nodemap ===", jt_noop, 0, "nodemap management"}, + {"=== Nodemap ===", NULL, 0, "nodemap management"}, {"nodemap_activate", jt_nodemap_activate, 0, "activate nodemap idmapping functions\n" "usage: nodemap_activate {0|1}"}, @@ -288,6 +360,9 @@ command_t cmdlist[] = { {"nodemap_set_fileset", jt_nodemap_set_fileset, 0, "set a fileset on a nodemap\n" "usage: nodemap_set_fileset "}, + {"nodemap_set_sepol", jt_nodemap_set_sepol, 0, + "set SELinux policy info on a nodemap\n" + "usage: nodemap_set_sepol "}, {"nodemap_test_nid", jt_nodemap_test_nid, 0, "usage: nodemap_test_nid "}, {"nodemap_test_id", jt_nodemap_test_id, 0, @@ -296,7 +371,7 @@ command_t cmdlist[] = { "Usage: nodemap_info [list|nodemap_name|all]"}, /* Changelog commands */ - {"=== Changelogs ==", jt_noop, 0, "changelog user management"}, + {"=== Changelogs ==", NULL, 0, "changelog user management"}, {"changelog_register", jt_changelog_register, 0, "register a new persistent changelog user, returns id\n" "usage: --device changelog_register [-n]"}, @@ -304,9 +379,18 @@ command_t cmdlist[] = { "deregister an existing changelog user\n" "usage: --device changelog_deregister "}, + /* Persistent Client Cache (PCC) commands */ + {"=== Persistent Client Cache ===", NULL, 0, "PCC user management"}, + {"pcc", jt_pcc, pccdev_cmdlist, + "lctl commands used to interact with PCC features:\n" + "lctl pcc add - add a PCC backend to a client\n" + "lctl pcc del - delete a PCC backend on a client\n" + "lctl pcc clear - remove all PCC backends on a client\n" + "lctl pcc list - list all PCC backends on a client\n"}, + /* Device configuration commands */ {"== device setup (these are not normally used post 1.4) ==", - jt_noop, 0, "device config"}, + NULL, 0, "device config"}, {"attach", jt_lcfg_attach, 0, "set the type, name, and uuid of the current device\n" "usage: attach type name uuid"}, @@ -318,9 +402,18 @@ command_t cmdlist[] = { "usage: setup "}, {"cleanup", jt_obd_cleanup, 0, "cleanup previously setup device\n" "usage: cleanup [force | failover]"}, + {"clear_conf", jt_lcfg_clear, 0, + "drop unused config logs for a device or filesystem\n" + "usage: clear_conf "}, + {"fork_lcfg", jt_lcfg_fork, 0, + "copy configuration files for named filesystem with given name\n" + "usage: fork_lcfg "}, + {"erase_lcfg", jt_lcfg_erase, 0, + "permanently erase configuration for the named filesystem\n" + "usage: erase_lcfg "}, /* Test only commands */ - {"==== testing (DANGEROUS) ====", jt_noop, 0, "testing (DANGEROUS)"}, + {"==== testing (DANGEROUS) ====", NULL, 0, "testing (DANGEROUS)"}, {"--threads", jt_opt_threads, 0, "run separate instances of on device \n" "--threads "}, @@ -408,13 +501,14 @@ command_t cmdlist[] = { "get the version of an object on servers\n" "usage: getobjversion \n" " getobjversion -i -g "}, - +#ifdef HAVE_SERVER_SUPPORT /* LFSCK commands */ - {"==== LFSCK ====", jt_noop, 0, "LFSCK"}, + {"==== LFSCK ====", NULL, 0, "LFSCK"}, {"lfsck_start", jt_lfsck_start, 0, "start LFSCK\n" "usage: lfsck_start [-M | --device [MDT,OST]_device]\n" " [-A | --all] [-c | --create-ostobj [on | off]]\n" " [-C | --create-mdtobj [on | off]]\n" + " [-d | --delay-create-ostobj [on | off]]\n" " [-e | --error {continue | abort}] [-h | --help]\n" " [-n | --dryrun [on | off]] [-o | --orphan]\n" " [-r | --reset] [-s | --speed speed_limit]\n" @@ -427,48 +521,40 @@ command_t cmdlist[] = { "usage: lfsck_query [-M | --device MDT_device] [-h | --help]\n" " [-t | --type lfsck_type[,lfsck_type...]]\n" " [-w | --wait]"}, - - {"==== obsolete (DANGEROUS) ====", jt_noop, 0, "obsolete (DANGEROUS)"}, - /* some test scripts still use these */ +#endif /* HAVE_SERVER_SUPPORT */ {"cfg_device", jt_obd_device, 0, "set current device to \n" "usage: device "}, {"recover", jt_obd_recover, 0, "try to restore a lost connection immediately\n" "usage: recover [MDC/OSC device]"}, - /* saving for sanity 44a */ - {"lov_getconfig", jt_obd_lov_getconfig, 0, - "read lov configuration from an mds device\n" - "usage: lov_getconfig "}, /* Llog operations */ {"llog_catlist", jt_llog_catlist, 0, - "list all catalog logs on current device.\n" + "list all catalog files on current device.\n" "usage: llog_catlist"}, {"llog_info", jt_llog_info, 0, "print log header information.\n" - "usage: llog_info <$logname|#oid#ogr#ogen>\n" - " oid, ogr and ogen are hexadecimal."}, + "usage: llog_info \n"}, {"llog_print", jt_llog_print, 0, "print log content information.\n" - "usage: llog_print <$logname|#oid#ogr#ogen> [from] [to]\n" - " oid, ogr and ogen are hexadecimal.\n" - " print all records from index 1 by default."}, + "usage: llog_print [--start ] [--end j]\n" + " print all records by default, or within given index range."}, + {"llog_cancel", jt_llog_cancel, 0, + "cancel one record in specified log.\n" + "usage:llog_cancel --log_idx \n"}, {"llog_check", jt_llog_check, 0, - "print log content information.\n" - "usage: llog_check <$logname|#oid#ogr#ogen> [from] [to]\n" - " oid, ogr and ogen are hexadecimal.\n" + "verify that log content is valid.\n" + "usage: llog_check [--start ] [--end j]\n" " check all records from index 1 by default."}, - {"llog_cancel", jt_llog_cancel, 0, - "cancel one record in log.\n" - "This command supports both positional and optional arguments\n" - "usage (positional args): " - "llog_cancel [log id] \n" - "usage (optional args): " - "llog_cancel --catalog --log_id " - "--log_idx "}, {"llog_remove", jt_llog_remove, 0, "remove one log from catalog or plain log, erase it from disk.\n" - "usage: llog_remove "}, + "usage: llog_remove [--log_id ]"}, + {"==== obsolete (DANGEROUS) ====", NULL, 0, "obsolete (DANGEROUS)"}, + /* some test scripts still use these */ + /* saving for sanity 44a */ + {"lov_getconfig", jt_obd_lov_getconfig, 0, + "read lov configuration from an mds device\n" + "usage: lov_getconfig "}, /* network operations */ {"add_interface", jt_ptl_add_interface, 0, "add interface entry\n" "usage: add_interface ip [netmask]"}, @@ -487,6 +573,55 @@ command_t cmdlist[] = { { 0, 0, 0, NULL } }; +/** + * jt_pcc_list_commands() - List lctl pcc commands. + * @argc: The count of command line arguments. + * @argv: Array of strings for command line arguments. + * + * This function lists lctl pcc commands defined in pccdev_cmdlist[]. + * + * Return: 0 on success. + */ +static int jt_pcc_list_commands(int argc, char **argv) +{ + char buffer[81] = ""; + + Parser_list_commands(pccdev_cmdlist, buffer, sizeof(buffer), + NULL, 0, 4); + + return 0; +} + +/** + * jt_pcc() - Parse and execute lctl pcc commands. + * @argc: The count of lctl pcc command line arguments. + * @argv: Array of strings for lctl pcc command line arguments. + * + * This function parses lfs pcc commands and performs the + * corresponding functions specified in pccdev_cmdlist[]. + * + * Return: 0 on success or an error code on failure. + */ +static int jt_pcc(int argc, char **argv) +{ + char cmd[PATH_MAX]; + int rc = 0; + + setlinebuf(stdout); + + Parser_init("lctl-pcc > ", pccdev_cmdlist); + + snprintf(cmd, sizeof(cmd), "%s %s", program_invocation_short_name, + argv[0]); + program_invocation_short_name = cmd; + if (argc > 1) + rc = Parser_execarg(argc - 1, argv + 1, pccdev_cmdlist); + else + rc = Parser_commands(); + + return rc < 0 ? -rc : rc; +} + int lctl_main(int argc, char **argv) { int rc; @@ -503,7 +638,9 @@ int lctl_main(int argc, char **argv) Parser_init("lctl > ", cmdlist); if (argc > 1) { + llapi_set_command_name(argv[1]); rc = Parser_execarg(argc - 1, argv + 1, cmdlist); + llapi_clear_command_name(); } else { rc = Parser_commands(); } @@ -512,6 +649,24 @@ int lctl_main(int argc, char **argv) return rc < 0 ? -rc : rc; } +static int lctl_list_commands(int argc, char **argv) +{ + char buffer[81] = ""; /* 80 printable chars + terminating NUL */ + command_t *cmd; + int rc; + + cmd = cmdlist; + while (cmd->pc_name != NULL) { + printf("\n%s\n", cmd->pc_name); /* Command category */ + cmd++; + rc = Parser_list_commands(cmd, buffer, sizeof(buffer), NULL, + 0, 4); + cmd += rc; + } + + return 0; +} + int main(int argc, char **argv) { return lctl_main(argc, argv);