diff --git a/lustre/include/linux/lustre_ha.h b/lustre/include/linux/lustre_ha.h index ecc6543cbc8b1c6aa041b53ebf8d2c324a21a79e..7016274ce33cd6b379c73a6ef4f83d4764bd77f0 100644 --- a/lustre/include/linux/lustre_ha.h +++ b/lustre/include/linux/lustre_ha.h @@ -27,5 +27,6 @@ void ptlrpc_fail_export(struct obd_export *exp); int ptlrpc_check_suspend(void); void ptlrpc_activate_timeouts(void); void ptlrpc_deactivate_timeouts(void); +int ptlrpc_import_control_recovery(struct obd_import *imp, int disable); #endif diff --git a/lustre/include/linux/obd.h b/lustre/include/linux/obd.h index 0b581eb2c6eeb75c88de1005b36480851d78acee..30323721ff5a3a14b0caf2c45197552b3a3c49f7 100644 --- a/lustre/include/linux/obd.h +++ b/lustre/include/linux/obd.h @@ -13,6 +13,7 @@ #define IOC_OSC_TYPE 'h' #define IOC_OSC_MIN_NR 20 #define IOC_OSC_SET_ACTIVE _IOWR(IOC_OSC_TYPE, 21, struct obd_device *) +#define IOC_OSC_CTL_RECOVERY _IOWR(IOC_OSC_TYPE, 22, struct obd_device *) #define IOC_OSC_MAX_NR 50 #define IOC_MDC_TYPE 'i' diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index 3da3334d85700bb8c4423f95d042647c3f9865c7..260c0c7df8bfb2c1490feef75002143a129e69c9 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -775,6 +775,9 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len, case IOC_OSC_SET_ACTIVE: rc = ptlrpc_set_import_active(imp, data->ioc_offset); GOTO(out, rc); + case IOC_OSC_CTL_RECOVERY: + rc = ptlrpc_import_control_recovery(imp, data->ioc_offset); + GOTO(out, rc); case OBD_IOC_PARSE: { ctxt = llog_get_context(&exp->exp_obd->obd_llogs, LLOG_CONFIG_REPL_CTXT); diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 6ffede7a3df69c8a66c995dd169315abc87fad1a..2eb95bc82f43c89ab8c421dd3a53de46b400ff55 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -2779,6 +2779,10 @@ static int osc_iocontrol(unsigned int cmd, struct obd_export *exp, int len, err = ptlrpc_set_import_active(obd->u.cli.cl_import, data->ioc_offset); GOTO(out, err); + case IOC_OSC_CTL_RECOVERY: + err = ptlrpc_import_control_recovery(obd->u.cli.cl_import, + data->ioc_offset); + GOTO(out, err); default: CDEBUG(D_INODE, "unrecognised ioctl %#x by %s\n", cmd, current->comm); GOTO(out, err = -ENOTTY); diff --git a/lustre/ptlrpc/ptlrpc_module.c b/lustre/ptlrpc/ptlrpc_module.c index 2e5ba9d692f7beec9b7d309538a8a66746c621ab..786bdceaafe7cd45c5013b960eb422afbc77ada8 100644 --- a/lustre/ptlrpc/ptlrpc_module.c +++ b/lustre/ptlrpc/ptlrpc_module.c @@ -132,6 +132,7 @@ EXPORT_SYMBOL(ptlrpc_invalidate_import); EXPORT_SYMBOL(ptlrpc_activate_import); EXPORT_SYMBOL(ptlrpc_fail_import); EXPORT_SYMBOL(ptlrpc_disconnect_import); +EXPORT_SYMBOL(ptlrpc_import_control_recovery); /* service.c */ EXPORT_SYMBOL(ptlrpc_require_repack); diff --git a/lustre/ptlrpc/recover.c b/lustre/ptlrpc/recover.c index a09c8a2f1a1643fe4dccf77b695a0b6e7a8c387f..6faea9bc6249b7df5527745f6979736d16d8540b 100644 --- a/lustre/ptlrpc/recover.c +++ b/lustre/ptlrpc/recover.c @@ -354,6 +354,24 @@ int ptlrpc_import_in_recovery(struct obd_import *imp) return in_recovery; } +int ptlrpc_import_control_recovery(struct obd_import *imp, int disable) +{ + unsigned long flags; + + /* with imp_deactivate == 1 pinger won't initiate re-connect */ + spin_lock_irqsave(&imp->imp_lock, flags); + if (disable) + imp->imp_deactive = 1; + else + imp->imp_deactive = 0; + if (imp->imp_state == LUSTRE_IMP_DISCON) { + imp->imp_force_verify = 1; + ptlrpc_pinger_wake_up(); + } + spin_unlock_irqrestore(&imp->imp_lock, flags); + RETURN(0); +} + static int ptlrpc_recover_import_no_retry(struct obd_import *imp, char *new_uuid) { diff --git a/lustre/utils/lctl.c b/lustre/utils/lctl.c index 879237cf65a9c161f1eb679201cad4292577f9f8..e2e9e7375984cde88c087d90600f6734f73e8c5f 100644 --- a/lustre/utils/lctl.c +++ b/lustre/utils/lctl.c @@ -223,6 +223,8 @@ command_t cmdlist[] = { "stop lock manager stress test (no args)\n"}, {"dump_ldlm", jt_obd_dump_ldlm, 0, "dump all lock manager state (no args)"}, + {"disable_recovery", jt_obd_disable_recovery, 0, "disable recovery on an import\n"}, + {"enable_recovery", jt_obd_enable_recovery, 0, "enable recovery on an import\n"}, {"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 [<connection UUID>]"}, diff --git a/lustre/utils/obd.c b/lustre/utils/obd.c index 03864ca61c3f1f0871444533caec350d3995b31c..c56ae41c9eaa576a9dc9fbfe61651905dd72bfa5 100644 --- a/lustre/utils/obd.c +++ b/lustre/utils/obd.c @@ -1938,6 +1938,37 @@ int jt_obd_activate(int argc, char **argv) return do_activate(argc, argv, 1); } +static int do_control_recovery(int argc, char **argv, int flag) +{ + struct obd_ioctl_data data; + int rc; + + IOC_INIT(data); + if (argc != 1) + return CMD_HELP; + + /* reuse offset for 'active' */ + data.ioc_offset = flag; + + IOC_PACK(argv[0], data); + rc = l2_ioctl(OBD_DEV_ID, IOC_OSC_CTL_RECOVERY, buf); + if (rc) + fprintf(stderr, "error: %s: failed: %s\n", + jt_cmdname(argv[0]), strerror(rc = errno)); + + return rc; +} + +int jt_obd_disable_recovery(int argc, char **argv) +{ + return do_control_recovery(argc, argv, 1); +} + +int jt_obd_enable_recovery(int argc, char **argv) +{ + return do_control_recovery(argc, argv, 0); +} + int jt_obd_recover(int argc, char **argv) { int rc; diff --git a/lustre/utils/obdctl.h b/lustre/utils/obdctl.h index 79440811fac07a5066bad012f350687cf0d10c2a..02fbe8aea6bcd84234d3dc614be0db6d718d0652 100644 --- a/lustre/utils/obdctl.h +++ b/lustre/utils/obdctl.h @@ -70,6 +70,8 @@ int jt_obd_test_ldlm(int argc, char **argv); int jt_obd_ldlm_regress_start(int argc, char **argv); int jt_obd_ldlm_regress_stop(int argc, char **argv); int jt_obd_dump_ldlm(int argc, char **argv); +int jt_obd_disable_recovery(int argc, char **argv); +int jt_obd_enable_recovery(int argc, char **argv); int jt_obd_activate(int argc, char **argv); int jt_obd_deactivate(int argc, char **argv); int jt_obd_recover(int argc, char **argv);