#define LMD_FLG_DEV_RDONLY 0x8000 /* discard modification quitely */
#define LMD_FLG_NO_PRECREATE 0x10000 /* do not allow OST object creation */
#define LMD_FLG_LOCAL_RECOV 0x20000 /* force recovery for local clients */
+#define LMD_FLG_ABORT_RECOV_MDT 0x40000 /* Abort recovery between MDTs */
#define lmd_is_client(x) ((x)->lmd_flags & LMD_FLG_CLIENT)
obd_set_up:1, /* finished setup */
obd_recovering:1, /* there are recoverable clients */
obd_abort_recovery:1, /* recovery expired */
+ obd_abort_recov_mdt:1, /* only abort recovery between MDTs */
obd_version_recov:1, /* obd uses version checking */
obd_replayable:1, /* recovery enabled; inform clients */
obd_no_recov:1, /* fail instead of retry messages */
/* was OBD_IOC_NO_TRANSNO _IOW('f', 140, OBD_IOC_DATA_TYPE) until 2.14 */
#define OBD_IOC_SET_READONLY _IOW('f', 141, OBD_IOC_DATA_TYPE)
#define OBD_IOC_ABORT_RECOVERY _IOR('f', 142, OBD_IOC_DATA_TYPE)
+enum obd_abort_recovery_flags {
+ OBD_FLG_ABORT_RECOV_OST = 0x00008, /* LMD_FLG_ABORT_RECOV */
+ OBD_FLG_ABORT_RECOV_MDT = 0x40000, /* LMD_FLG_ABORT_RECOV_MDT */
+};
/* OBD_IOC_ROOT_SQUASH _IOWR('f', 143, OBD_IOC_DATA_TYPE) */
#define OBD_GET_VERSION _IOWR('f', 144, OBD_IOC_DATA_TYPE)
/* OBD_IOC_GSS_SUPPORT _IOWR('f', 145, OBD_IOC_DATA_TYPE) */
req_transno = lustre_msg_get_transno(req->rq_reqmsg);
}
- if (tdtd != NULL)
+ if (!obd->obd_abort_recov_mdt && tdtd)
update_transno = distribute_txn_get_next_transno(tdtd);
connected = atomic_read(&obd->obd_connected_clients);
} else if (obd->obd_recovery_expired) {
CDEBUG(D_HA, "waking for expired recovery\n");
wake_up = 1;
- } else if (tdtd != NULL && req != NULL &&
+ } else if (!obd->obd_abort_recov_mdt && tdtd && req &&
is_req_replayed_by_update(req)) {
LASSERTF(req_transno < next_transno,
"req_transno %llu next_transno%llu\n", req_transno,
* left in the queue
*/
spin_lock(&obd->obd_recovery_task_lock);
- if (lut->lut_tdtd != NULL) {
+ if (!obd->obd_abort_recov_mdt && lut->lut_tdtd) {
next_update_transno =
distribute_txn_get_next_transno(lut->lut_tdtd);
return 0;
}
- if (lut->lut_tdtd != NULL) {
+ if (!obd->obd_abort_recov_mdt && lut->lut_tdtd != NULL) {
if (!lut->lut_tdtd->tdtd_replay_ready &&
!obd->obd_abort_recovery && !obd->obd_stopping) {
/*
if (type != NULL)
*type = REQUEST_RECOVERY;
- if (tdtd == NULL)
+ if (!tdtd || obd->obd_abort_recov_mdt)
RETURN(transno);
update_transno = distribute_txn_get_next_transno(tdtd);
if (rc == 0)
rc = dt_ro(&env, dt);
break;
- case OBD_IOC_ABORT_RECOVERY:
+ case OBD_IOC_ABORT_RECOVERY: {
+ struct obd_ioctl_data *data = karg;
+
CERROR("%s: Aborting recovery for device\n", mdt_obd_name(mdt));
- obd->obd_abort_recovery = 1;
+ if (data->ioc_type & OBD_FLG_ABORT_RECOV_MDT)
+ obd->obd_abort_recov_mdt = 1;
+ else /* if (data->ioc_type & OBD_FLG_ABORT_RECOV_OST) */
+ /* lctl didn't set OBD_FLG_ABORT_RECOV_OST < 2.13.57 */
+ obd->obd_abort_recovery = 1;
+
target_stop_recovery_thread(obd);
rc = 0;
break;
+ }
case OBD_IOC_CHANGELOG_REG:
case OBD_IOC_CHANGELOG_DEREG:
case OBD_IOC_CHANGELOG_CLEAR:
if (strncmp(s1, "abort_recov", 11) == 0) {
lmd->lmd_flags |= LMD_FLG_ABORT_RECOV;
clear++;
+ } else if (strncmp(s1, "abort_recov_mdt", 15) == 0) {
+ lmd->lmd_flags |= LMD_FLG_ABORT_RECOV_MDT;
+ clear++;
} else if (strncmp(s1, "recovery_time_soft=", 19) == 0) {
lmd->lmd_recovery_time_soft =
max_t(int, simple_strtoul(s1 + 19, NULL, 10),
/* abort recovery only on the complete stack:
* many devices can be involved */
- if ((lsi->lsi_lmd->lmd_flags & LMD_FLG_ABORT_RECOV) &&
+ if ((lsi->lsi_lmd->lmd_flags &
+ (LMD_FLG_ABORT_RECOV | LMD_FLG_ABORT_RECOV_MDT)) &&
(OBP(obd, iocontrol))) {
+ struct obd_ioctl_data karg = {
+ .ioc_type = lsi->lsi_lmd->lmd_flags,
+ };
+
obd_iocontrol(OBD_IOC_ABORT_RECOVERY, obd->obd_self_export, 0,
- NULL, NULL);
+ &karg, NULL);
}
out_mgc:
}
run_test 100b "DNE: create striped dir, fail MDT0"
+test_100c() {
+ [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
+ ([ $FAILURE_MODE == "HARD" ] &&
+ [ "$(facet_host mds1)" == "$(facet_host mds2)" ]) &&
+ skip "MDTs needs to be on diff hosts for HARD fail mode" &&
+ return 0
+
+ local striped_dir=$DIR/$tdir/striped_dir
+
+ mkdir $DIR/$tdir || error "mkdir $DIR/$tdir failed"
+
+ #To make sure MDT1 and MDT0 are connected
+ #otherwise it may create single stripe dir here
+ $LFS setdirstripe -i1 $DIR/$tdir/remote_dir
+
+ replay_barrier mds2
+ $LFS mkdir -i1 -c2 $striped_dir
+
+ fail_abort mds2 abort_recov_mdt
+
+ createmany -o $striped_dir/f-%d 20 &&
+ error "createmany -o $DIR/$tfile should fail"
+
+ fail mds2
+ striped_dir_check_100 || error "striped dir check failed"
+ rm -rf $DIR/$tdir || error "rmdir failed"
+}
+run_test 100c "DNE: create striped dir, fail MDT0"
+
test_101() { #LU-5648
mkdir -p $DIR/$tdir/d1
mkdir -p $DIR/$tdir/d2
}
fail_nodf() {
- local facet=$1
- facet_failover $facet
+ local facet=$1
+
+ facet_failover $facet
}
fail_abort() {
local facet=$1
+ local abort_type=${2:-"abort_recovery"}
+
stop $facet
change_active $facet
wait_for_facet $facet
- mount_facet $facet -o abort_recovery
+ mount_facet $facet -o $abort_type
clients_up || echo "first stat failed: $?"
clients_up || error "post-failover stat: $?"
}
"This command should be used on failed OSC devices in an MDT LOV.\n"},
{"abort_recovery", jt_obd_abort_recovery, 0,
"abort recovery on a restarting MDT or OST device\n"},
+ {"abort_recovery_mdt", jt_obd_abort_recovery_mdt, 0,
+ "abort recovery between MDTs\n"},
{"set_timeout", jt_lcfg_set_timeout, 0,
"usage: conf_param obd_timeout=<secs>\n"},
#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
#include <linux/lustre/lustre_barrier_user.h>
#endif
#include <linux/lustre/lustre_cfg.h>
+#include <linux/lustre/lustre_disk.h>
#include <linux/lustre/lustre_ioctl.h>
#include <linux/lustre/lustre_ostid.h>
#include <linux/lustre/lustre_param.h>
return rc;
}
-int jt_obd_abort_recovery(int argc, char **argv)
+static int obd_abort_recovery(char *cmd, enum obd_abort_recovery_flags flags)
{
- struct obd_ioctl_data data;
+ struct obd_ioctl_data data = {
+ .ioc_dev = cur_device,
+ .ioc_type = flags,
+ };
char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
int rc;
- memset(&data, 0, sizeof(data));
- data.ioc_dev = cur_device;
-
- if (argc != 1)
- return CMD_HELP;
-
memset(buf, 0, sizeof(rawbuf));
rc = llapi_ioctl_pack(&data, &buf, sizeof(rawbuf));
if (rc) {
fprintf(stderr, "error: %s: invalid ioctl\n",
- jt_cmdname(argv[0]));
+ jt_cmdname(cmd));
return rc;
}
rc = l_ioctl(OBD_DEV_ID, OBD_IOC_ABORT_RECOVERY, buf);
if (rc < 0)
- fprintf(stderr, "error: %s: %s\n", jt_cmdname(argv[0]),
+ fprintf(stderr, "error: %s: %s\n", jt_cmdname(cmd),
strerror(rc = errno));
return rc;
}
+int jt_obd_abort_recovery(int argc, char **argv)
+{
+ if (argc != 1)
+ return CMD_HELP;
+
+ return obd_abort_recovery(argv[0], OBD_FLG_ABORT_RECOV_OST);
+}
+
+int jt_obd_abort_recovery_mdt(int argc, char **argv)
+{
+ if (argc != 1)
+ return CMD_HELP;
+
+ return obd_abort_recovery(argv[0], OBD_FLG_ABORT_RECOV_MDT);
+}
+
int jt_get_version(int argc, char **argv)
{
char version[128];
int jt_obd_no_transno(int argc, char **argv);
int jt_obd_set_readonly(int argc, char **argv);
int jt_obd_abort_recovery(int argc, char **argv);
+int jt_obd_abort_recovery_mdt(int argc, char **argv);
int jt_obd_list(int argc, char **argv);
int jt_obd_create(int argc, char **argv);
int jt_obd_test_create(int argc, char **argv);