X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Futils%2Flctl.c;h=a90eeee5256b7012289b422bb95ff91909f5187b;hb=f569e36c2c16090108dfdeaf380c3dd237c546ec;hp=7b8ed18b618e68bf2db66adc0c46435438a47599;hpb=1f6c7e91ce774815808d5616cfa48402f716ebb3;p=fs%2Flustre-release.git diff --git a/lustre/utils/lctl.c b/lustre/utils/lctl.c index 7b8ed18..a90eeee 100644 --- a/lustre/utils/lctl.c +++ b/lustre/utils/lctl.c @@ -4,7 +4,8 @@ * Copyright (C) 2002 Cluster File Systems, Inc. * Author: Peter J. Braam * Author: Phil Schwan - * Author: Robert Read + * Author: Robert Read + * * This file is part of Lustre, http://www.lustre.org. * * Lustre is free software; you can redistribute it and/or @@ -24,40 +25,11 @@ #include -#include -#include -#include -#include -#include -#include #include -#include -#include -#define printk printf - - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include /* needed for PAGE_SIZE - rread*/ - -#include "lctl.h" - -#define __KERNEL__ -#include -#undef __KERNEL__ - -int thread; - -command_t cmdlist[]; +#include +#include +#include "obdctl.h" +#include "parser.h" static int jt_quit(int argc, char **argv) { Parser_quit(argc, argv); @@ -68,131 +40,203 @@ static int jt_noop(int argc, char **argv) { return 0; } +static int jt_opt_ignore_errors(int argc, char **argv) { + Parser_ignore_errors(1); + return 0; +} + command_t cmdlist[] = { /* Metacommands */ - {"--device", jt_opt_device, 0, "--device "}, + {"--device", jt_opt_device, 0, + "run after connecting to device \n" + "--device "}, {"--threads", jt_opt_threads, 0, - "--threads "}, + "run separate instances of on device \n" + "--threads "}, + {"--ignore_errors", jt_opt_ignore_errors, 0, + "ignore errors that occur during script processing\n" + "--ignore_errors"}, + {"ignore_errors", jt_opt_ignore_errors, 0, + "ignore errors that occur during script processing\n" + "ignore_errors"}, + {"dump", jt_ioc_dump, 0, "usage: dump file, save ioctl buffer to file"}, /* Network configuration commands */ {"==== network config ====", jt_noop, 0, "network config"}, - {"network", jt_net_network, 0, "commands that follow apply to net\n" - "usage: network "}, - {"connect", jt_net_connect, 0, "connect to a remote nid\n" - "usage: connect [[ ] | ]"}, - {"disconnect", jt_net_disconnect, 0, "disconnect from a remote nid\n" - "usage: disconnect "}, - {"mynid", jt_net_mynid, 0, "inform the socknal of the local nid. " + {"network", jt_ptl_network, 0, "commands that follow apply to net\n" + "usage: network "}, + {"autoconn_list", jt_ptl_print_autoconnects, 0, "print autoconnect entries\n" + "usage: print_autoconns"}, + {"add_autoconn", jt_ptl_add_autoconnect, 0, "add an autoconnect entry\n" + "usage: add_autoconn [ixs]"}, + {"del_autoconn", jt_ptl_del_autoconnect, 0, "remove an autoconnect entry\n" + "usage: del_autoconn [] [] [ks]"}, + {"conn_list", jt_ptl_print_connections, 0, "connect to a remote nid\n" + "usage: print_conns"}, + {"connect", jt_ptl_connect, 0, "connect to a remote nid\n" + "usage: connect [ix]"}, + {"disconnect", jt_ptl_disconnect, 0, "disconnect from a remote nid\n" + "usage: disconnect []"}, + {"active_tx", jt_ptl_print_active_txs, 0, "print active transmits (no args)\n" + "usage: active_tx"}, + {"mynid", jt_ptl_mynid, 0, "inform the socknal of the local nid. " "The nid defaults to hostname for tcp networks and is automatically " - "setup for elan/myrinet networks.\n" - "usage: mynid [nid]"}, - {"add_uuid", jt_net_add_uuid, 0, "associate a name/uuid with a nid\n" - "usage: add_uuid "}, - {"del_uuid", jt_net_del_uuid, 0, "delete a uuid association\n" + "setup for elan/myrinet/scimac networks.\n" + "usage: mynid []"}, + {"shownid", jt_ptl_shownid, 0, "print the local NID\n" + "usage: shownid"}, + {"add_uuid", jt_obd_add_uuid, 0, "associate a UUID with a nid\n" + "usage: add_uuid "}, + {"close_uuid", jt_obd_close_uuid, 0, "disconnect a UUID\n" + "usage: close_uuid )"}, + {"del_uuid", jt_obd_del_uuid, 0, "delete a UUID association\n" "usage: del_uuid "}, - {"add_route", jt_net_add_route, 0, + {"add_route", jt_ptl_add_route, 0, "add an entry to the routing table\n" "usage: add_route [target]"}, - {"del_route", jt_net_del_route, 0, + {"del_route", jt_ptl_del_route, 0, "delete an entry from the routing table\n" "usage: del_route "}, - {"route_list", jt_net_route_list, 0, "print the routing table\n" + {"route_list", jt_ptl_print_routes, 0, "print the routing table\n" "usage: route_list"}, - {"recv_mem", jt_net_recv_mem, 0, "set socket receive buffer size, " + {"recv_mem", jt_ptl_rxmem, 0, "set socket receive buffer size, " "if size is omited the current size is reported.\n" "usage: recv_mem [size]"}, - {"send_mem", jt_net_send_mem, 0, "set socket send buffer size, " + {"send_mem", jt_ptl_txmem, 0, "set socket send buffer size, " "if size is omited the current size is reported.\n" "usage: send_mem [size]"}, - {"nagle", jt_net_nagle, 0, "enable/disable nagle, omiting the " - "argument will cause the current nagle setting to be reported.\n" - "usage: nagle [on/off]"}, - + {"nagle", jt_ptl_nagle, 0, "enable/disable nagle, omitting the " + "argument will cause the current nagle setting to be reported.\n" + "usage: nagle [on/off]"}, + {"fail", jt_ptl_fail_nid, 0, "fail/restore communications.\n" + "Omitting the count means indefinitely, 0 means restore, " + "otherwise fail 'count' messages.\n" + "usage: fail nid|_all_ [count]"}, + /* Device selection commands */ {"=== device selection ===", jt_noop, 0, "device selection"}, - {"newdev", jt_dev_newdev, 0, "create a new device\n" + {"newdev", jt_obd_newdev, 0, "create a new device\n" "usage: newdev"}, - {"uuid2dev", jt_dev_uuid2dev, 0, - "find a uuid and make it the current device\n" - "usage: uuid2dev "}, - {"name2dev", jt_dev_name2dev, 0, - "find a name and make it the current device\n" - "usage: name2dev "}, - {"device", jt_dev_device, 0, "set current device to devno\n" - "usage: device "}, - {"device_list", jt_dev_list, 0, "show all devices\n" + {"device", jt_obd_device, 0, + "set current device to <%name|$name|devno>\n" + "usage: device <%name|$name|devno>"}, + {"device_list", jt_obd_list, 0, "show all devices\n" "usage: device_list"}, - + {"lustre_build_version", jt_get_version, 0, + "print the build version of lustre\n" + "usage: lustre_build_version"}, + /* Device configuration commands */ {"==== device config =====", jt_noop, 0, "device config"}, - {"attach", jt_dev_attach, 0, "name and type the device\n" + {"attach", jt_obd_attach, 0, + "set the type of the current device (with and )\n" "usage: attach type [name [uuid]]"}, - {"setup", jt_dev_setup, 0, + {"setup", jt_obd_setup, 0, "type specific device configuration information\n" "usage: setup "}, - {"cleanup", jt_dev_cleanup, 0, "cleanup setup\n" - "usage: cleanup"}, - {"detach", jt_dev_detach, 0, "un-name a device\n" + {"cleanup", jt_obd_cleanup, 0, "cleanup previously setup device\n" + "usage: cleanup [force | failover]"}, + {"detach", jt_obd_detach, 0, + "remove driver (and name and uuid) from current device\n" "usage: detach"}, - {"lovconfig", jt_dev_lov_config, 0, - "write lov configuration to a mds device\n" - "usage: lovconfig"}, + {"lov_setconfig", jt_obd_lov_setconfig, 0, + "write lov configuration to an mds device\n" + "usage: lov_setconfig lov-uuid stripe-count stripe-size offset pattern UUID1 [UUID2 ...]"}, + {"lov_getconfig", jt_obd_lov_getconfig, 0, + "read lov configuration from an mds device\n" + "usage: lov_getconfig lov-uuid"}, /* Device operations */ {"=== device operations ==", jt_noop, 0, "device operations"}, - {"probe", jt_dev_probe, 0, - "build a connection handle to a device. This command is used too " + {"probe", jt_obd_connect, 0, + "build a connection handle to a device. This command is used to " "suspend configuration until lctl has ensured that the mds and osc " "services are available. This is to avoid mount failures in a " "rebooting cluster.\n" - "usage: probe ["}, - {"setattr", jt_dev_setattr, 0, "set attribute for id\n" - "usage: setattr "}, - {"test_getattr", jt_dev_test_getattr, 0, - "perform count number of getattr's\n" - "usage: test_getattr [verbose]"}, - {"test_brw", jt_dev_test_brw, 0, - "perform count number of bulk read/writes\n" - "usage: test_brw [write [verbose [pages [obdos]]]]"}, - {"test_ldlm", jt_dev_test_ldlm, 0, "perform lock manager test\n" + {"getattr", jt_obd_getattr, 0, + "get attribute for OST object \n" + "usage: getattr "}, + {"setattr", jt_obd_setattr, 0, + "set mode attribute for OST object \n" + "usage: setattr "}, + {"create", jt_obd_create, 0, + "create OST objects (with )\n" + "usage: create [num [mode [verbose [lsm data]]]]"}, + {"destroy", jt_obd_destroy, 0, + "destroy OST object [num [verbose]]\n" + "usage: destroy objects, starting at objid "}, + {"test_getattr", jt_obd_test_getattr, 0, + "do getattrs (on OST object (objid+1 on each thread))\n" + "usage: test_getattr [verbose [[t]objid]]"}, + {"test_brw", jt_obd_test_brw, 0, + "do bulk read/writes ( per I/O, on OST object )\n" + "usage: test_brw [t] [write [verbose [npages [[t]objid]]]]"}, + {"get_stripe", jt_obd_get_stripe, 0, + "show stripe info for an echo client object\n" + "usage: get_stripe objid\n"}, + {"set_stripe", jt_obd_set_stripe, 0, + "set stripe info for an echo client object\n" + "usage: set_stripe objid[=width!count[@offset][:id:id...]\n"}, + {"unset_stripe", jt_obd_unset_stripe, 0, + "unset stripe info for an echo client object\n" + "usage: unset_stripe objid\n"}, + {"test_ldlm", jt_obd_test_ldlm, 0, + "perform lock manager test\n" "usage: test_ldlm"}, + {"ldlm_regress_start", jt_obd_ldlm_regress_start, 0, + "start lock manager stress test\n" + "usage: ldlm_regress_start [numthreads [refheld [numres [numext]]]]"}, + {"ldlm_regress_stop", jt_obd_ldlm_regress_stop, 0, + "stop lock manager stress test (no args)\n"}, + {"dump_ldlm", jt_obd_dump_ldlm, 0, + "dump all lock manager state (no args)"}, + {"activate", jt_obd_activate, 0, "activate an import\n"}, + {"deactivate", jt_obd_deactivate, 0, "deactivate an import\n"}, + {"recover", jt_obd_recover, 0, "usage: recover []"}, + {"lookup", jt_obd_mdc_lookup, 0, "usage: lookup "}, + {"notransno", jt_obd_no_transno, 0, + "disable sending of committed-transno updates\n"}, + {"readonly", jt_obd_set_readonly, 0, + "disable writes to the underlying device\n"}, + {"abort_recovery", jt_obd_abort_recovery, 0, + "abort recovery on MDS device\n"}, + {"mount_option", jt_obd_mount_option, 0, + "dump mount options to file\n"}, -#if 0 - {"create", jt_create, 0, "create [count [mode [verbose]]]"}, - {"destroy", jt_destroy, 0, "destroy "}, - {"newconn", jt_newconn, 0, "newconn [newuuid]"}, -#endif /* Debug commands */ {"======== debug =========", jt_noop, 0, "debug"}, - {"debug_lctl", jt_debug_lctl, 0, - "set debug status of lctl " - "usage: debug_kernel [file] [raw]"}, - {"debug_kernel", jt_debug_kernel, 0, + {"debug_daemon", jt_dbg_debug_daemon, 0, + "debug daemon control and dump to a file" + "usage: debug_daemon [start file <#MB>|stop|pause|continue]"}, + {"debug_kernel", jt_dbg_debug_kernel, 0, "get debug buffer and dump to a file" "usage: debug_kernel [file] [raw]"}, - {"debug_file", jt_debug_file, 0, + {"dk", jt_dbg_debug_kernel, 0, + "get debug buffer and dump to a file" + "usage: dk [file] [raw]"}, + {"debug_file", jt_dbg_debug_file, 0, "read debug buffer from input and dump to output" "usage: debug_file [output] [raw]"}, - {"clear", jt_debug_clear, 0, "clear kernel debug buffer\n" + {"clear", jt_dbg_clear_debug_buf, 0, "clear kernel debug buffer\n" "usage: clear"}, - {"mark", jt_debug_mark, 0,"insert marker text in kernel debug buffer\n" + {"mark", jt_dbg_mark_debug_buf, 0,"insert marker text in kernel debug buffer\n" "usage: mark "}, - {"filter", jt_debug_filter, 0, "filter message type\n" + {"filter", jt_dbg_filter, 0, "filter message type\n" "usage: filter "}, - {"show", jt_debug_show, 0, "show message type\n" + {"show", jt_dbg_show, 0, "show message type\n" "usage: show "}, - {"debug_list", jt_debug_list, 0, "list subsystem and debug types\n" + {"debug_list", jt_dbg_list, 0, "list subsystem and debug types\n" "usage: debug_list "}, - {"modules", jt_debug_modules, 0, + {"modules", jt_dbg_modules, 0, "provide gdb-friendly module information\n" "usage: modules "}, - {"panic", jt_debug_panic, 0, "force the kernel to panic\n" + {"panic", jt_dbg_panic, 0, "force the kernel to panic\n" "usage: panic"}, - + /* User interface commands */ {"======= control ========", jt_noop, 0, "control commands"}, {"help", Parser_help, 0, "help"}, @@ -201,181 +245,29 @@ command_t cmdlist[] = { { 0, 0, 0, NULL } }; -static void signal_server(int sig) { - if (sig == SIGINT) { - do_disconnect("sigint", 1); - exit(1); - } else { - fprintf(stderr, "%s: got signal %d\n", cmdname("sigint"), sig); - } -} - -int get_verbose(const char *arg) -{ - int verbose; - - if (!arg || arg[0] == 'v') - verbose = 1; - else if (arg[0] == 's' || arg[0] == 'q') - verbose = 0; - else - verbose = (int) strtoul(arg, NULL, 0); - - if (verbose < 0) - printf("Print status every %d seconds\n", -verbose); - else if (verbose == 1) - printf("Print status every operation\n"); - else if (verbose > 1) - printf("Print status every %d operations\n", verbose); - - return verbose; -} - -int be_verbose(int verbose, struct timeval *next_time, - int num, int *next_num, int num_total) -{ - struct timeval now; - - if (!verbose) - return 0; - - if (next_time != NULL) - gettimeofday(&now, NULL); - /* A positive verbosity means to print every X iterations */ - if (verbose > 0 && - (next_num == NULL || num >= *next_num || num >= num_total)) { - *next_num += verbose; - if (next_time) { - next_time->tv_sec = now.tv_sec - verbose; - next_time->tv_usec = now.tv_usec; - } - return 1; - } - - /* A negative verbosity means to print at most each X seconds */ - if (verbose < 0 && next_time != NULL && difftime(&now, next_time) >= 0){ - next_time->tv_sec = now.tv_sec - verbose; - next_time->tv_usec = now.tv_usec; - if (next_num) - *next_num = num; - return 1; - } - - return 0; -} -int jt_opt_threads(int argc, char **argv) +int main(int argc, char **argv) { - int threads, next_thread; - int verbose; - int i, j; int rc; - if (argc < 5) { - fprintf(stderr, - "usage: %s numthreads verbose devno \n", - argv[0]); - return -1; - } - - threads = strtoul(argv[1], NULL, 0); + setlinebuf(stdout); - verbose = get_verbose(argv[2]); - - printf("%s: starting %d threads on device %s running %s\n", - argv[0], threads, argv[3], argv[4]); - - for (i = 1, next_thread = verbose; i <= threads; i++) { - rc = fork(); - if (rc < 0) { - fprintf(stderr, "error: %s: #%d - %s\n", argv[0], i, - strerror(rc = errno)); - break; - } else if (rc == 0) { - thread = i; - argv[2] = "--device"; - return jt_opt_device(argc - 2, argv + 2); - } else if (be_verbose(verbose, NULL, i, &next_thread, threads)) - printf("%s: thread #%d (PID %d) started\n", - argv[0], i, rc); - rc = 0; - } - - if (!thread) { /* parent process */ - if (!verbose) - printf("%s: started %d threads\n\n", argv[0], i - 1); - else - printf("\n"); - - for (j = 1; j < i; j++) { - int status; - int ret = wait(&status); - - if (ret < 0) { - fprintf(stderr, "error: %s: wait - %s\n", - argv[0], strerror(errno)); - if (!rc) - rc = errno; - } else { - /* - * This is a hack. We _should_ be able to use - * WIFEXITED(status) to see if there was an - * error, but it appears to be broken and it - * always returns 1 (OK). See wait(2). - */ - int err = WEXITSTATUS(status); - if (err) - fprintf(stderr, - "%s: PID %d had rc=%d\n", - argv[0], ret, err); - if (!rc) - rc = err; - } - } - } - - return rc; -} - -char *cmdname(char *func) -{ - static char buf[512]; - - if (thread) { - sprintf(buf, "%s-%d", func, thread); - return buf; - } - - return func; -} - -int main(int argc, char **argv) { - struct sigaction sigact; - int rc; - - sigact.sa_handler = signal_server; - sigfillset(&sigact.sa_mask); - sigact.sa_flags = SA_RESTART; - sigaction(SIGINT, &sigact, NULL); - - if (network_setup(argc, argv) < 0) - exit(1); - - if (device_setup(argc, argv) < 0) + ptl_initialize(argc, argv); + if (obd_initialize(argc, argv) < 0) exit(2); - - if (debug_setup(argc, argv) < 0) + if (dbg_initialize(argc, argv) < 0) exit(3); - + + Parser_init("lctl > ", cmdlist); + if (argc > 1) { rc = Parser_execarg(argc - 1, argv + 1, cmdlist); } else { - Parser_init("lctl > ", cmdlist); rc = Parser_commands(); } - do_disconnect(argv[0], 1); + obd_cleanup(argc, argv); return rc; }