* ptlrpc_connect_interpret().
*/
client_adjust_max_dirty(cli);
- INIT_LIST_HEAD(&cli->cl_cache_waiters);
+ init_waitqueue_head(&cli->cl_cache_waiters);
INIT_LIST_HEAD(&cli->cl_loi_ready_list);
INIT_LIST_HEAD(&cli->cl_loi_hp_ready_list);
INIT_LIST_HEAD(&cli->cl_loi_write_list);
}
EXPORT_SYMBOL(server_disconnect_export);
+static inline int target_check_recovery_timer(struct obd_device *target)
+{
+ ktime_t remaining;
+ s64 timeout;
+
+ if (!target->obd_recovering || target->obd_recovery_start == 0)
+ return 0;
+
+ remaining = hrtimer_expires_remaining(&target->obd_recovery_timer);
+ timeout = ktime_divns(remaining, NSEC_PER_SEC);
+ if (timeout > -30)
+ return 0;
+
+ /* the recovery timer should expire, but it isn't triggered,
+ * it's better to abort the recovery of this target to speed up
+ * the recovery of the whole cluster. */
+ spin_lock(&target->obd_dev_lock);
+ if (target->obd_recovering) {
+ CERROR("%s: Aborting recovery\n", target->obd_name);
+ target->obd_abort_recovery = 1;
+ wake_up(&target->obd_next_transno_waitq);
+ }
+ spin_unlock(&target->obd_dev_lock);
+ return 0;
+}
+
/*
* --------------------------------------------------------------------------
* from old lib/target.c
* --------------------------------------------------------------------------
*/
-
static int target_handle_reconnect(struct lustre_handle *conn,
struct obd_export *exp,
struct obd_uuid *cluuid)
int count = 0;
char *buf = NULL;
+ target_check_recovery_timer(target);
+
tdtd = class_exp2tgt(exp)->lut_tdtd;
if (tdtd && tdtd->tdtd_show_update_logs_retrievers)
buf = tdtd->tdtd_show_update_logs_retrievers(
OBD_CONNECT_MDS_MDS) != 0;
/*
- * OBD_CONNECT_MNE_SWAB is defined as OBD_CONNECT_MDS_MDS
- * for Imperative Recovery connection from MGC to MGS.
+ * OBD_CONNECT_MNE_SWAB is removed at 2.14
+ * Checking OBD_CONNECT_FID can be removed in the future.
*
* Via check OBD_CONNECT_FID, we can distinguish whether
* the OBD_CONNECT_MDS_MDS/OBD_CONNECT_MNE_SWAB is from
} else {
msg = "already passed deadline";
timeout = -left;
+
+ target_check_recovery_timer(target);
}
LCONSOLE_WARN("%s: Denying connection for new client %s (at %s), waiting for %d known clients (%d recovered, %d in progress, and %d evicted) %s %lld:%.02lld\n",
if (export->exp_connection != NULL) {
/* Check to see if connection came from another NID. */
- if ((export->exp_connection->c_peer.nid != req->rq_peer.nid) &&
- !hlist_unhashed(&export->exp_nid_hash))
- cfs_hash_del(export->exp_obd->obd_nid_hash,
- &export->exp_connection->c_peer.nid,
- &export->exp_nid_hash);
+ if (export->exp_connection->c_peer.nid != req->rq_peer.nid)
+ obd_nid_del(export->exp_obd, export);
ptlrpc_connection_put(export->exp_connection);
}
export->exp_connection = ptlrpc_connection_get(req->rq_peer,
req->rq_self,
&cluuid);
- if (hlist_unhashed(&export->exp_nid_hash))
- cfs_hash_add(export->exp_obd->obd_nid_hash,
- &export->exp_connection->c_peer.nid,
- &export->exp_nid_hash);
+ if (!export->exp_connection)
+ GOTO(out, rc = -ENOTCONN);
+
+ obd_nid_add(export->exp_obd, export);
lustre_msg_set_handle(req->rq_repmsg, &conn);
elapsed_time = max_t(time64_t, now - obd->obd_recovery_start,
1);
LCONSOLE_INFO("%s: Recovery over after %lld:%.02lld, of %d clients %d recovered and %d %s evicted.\n",
- obd->obd_name, (s64)elapsed_time / 60,
- (s64)elapsed_time % 60,
+ obd->obd_name, elapsed_time / 60,
+ elapsed_time % 60,
atomic_read(&obd->obd_max_recoverable_clients),
atomic_read(&obd->obd_connected_clients),
obd->obd_stale_clients,
hrtimer_start(&obd->obd_recovery_timer, delay, HRTIMER_MODE_ABS);
spin_unlock(&obd->obd_dev_lock);
- LCONSOLE_WARN("%s: Will be in recovery for at least %lu:%02lu, or until %d client%s reconnect%s\n",
+ LCONSOLE_WARN("%s: Will be in recovery for at least %u:%02u, or until %d client%s reconnect%s\n",
obd->obd_name,
obd->obd_recovery_timeout / 60,
obd->obd_recovery_timeout % 60,
* at least; otherwise, make sure the recovery timeout value is not less
* than @dr_timeout.
*/
-static void extend_recovery_timer(struct obd_device *obd, time_t dr_timeout,
+static void extend_recovery_timer(struct obd_device *obd, timeout_t dr_timeout,
bool extend)
{
ktime_t left_ns;
- time_t timeout;
- time_t left;
+ timeout_t timeout;
+ timeout_t left;
spin_lock(&obd->obd_dev_lock);
if (!obd->obd_recovering || obd->obd_abort_recovery ||
*/
if (dr_timeout > left) {
timeout += dr_timeout - left;
- timeout = min_t(time_t, obd->obd_recovery_time_hard,
+ timeout = min_t(timeout_t, obd->obd_recovery_time_hard,
timeout);
}
} else {
- timeout = clamp_t(time_t, dr_timeout, obd->obd_recovery_timeout,
+ timeout = clamp_t(timeout_t, dr_timeout,
+ obd->obd_recovery_timeout,
obd->obd_recovery_time_hard);
}
if (timeout == obd->obd_recovery_time_hard)
- CWARN("%s: extended recovery timer reached hard limit: %ld, extend: %d\n",
+ CWARN("%s: extended recovery timer reached hard limit: %d, extend: %d\n",
obd->obd_name, timeout, extend);
if (obd->obd_recovery_timeout < timeout) {
}
spin_unlock(&obd->obd_dev_lock);
- CDEBUG(D_HA, "%s: recovery timer will expire in %ld seconds\n",
+ CDEBUG(D_HA, "%s: recovery timer will expire in %d seconds\n",
obd->obd_name, left);
}
struct ptlrpc_request *req,
int new_client)
{
- time_t service_time = lustre_msg_get_service_time(req->rq_reqmsg);
+ timeout_t service_timeout = lustre_msg_get_service_timeout(req->rq_reqmsg);
struct obd_device_target *obt = &obd->u.obt;
- if (!new_client && service_time)
+ if (!new_client && service_timeout)
/*
* Teach server about old server's estimates, as first guess
* at how long new requests will take.
*/
at_measured(&req->rq_rqbd->rqbd_svcpt->scp_at_estimate,
- service_time);
+ service_timeout);
target_start_recovery_timer(obd);
/*
* Convert the service time to RPC timeout,
- * and reuse service_time to limit stack usage.
+ * and reuse service_timeout to limit stack usage.
*/
- service_time = at_est2timeout(service_time);
+ service_timeout = at_est2timeout(service_timeout);
if (OBD_FAIL_CHECK(OBD_FAIL_TGT_SLUGGISH_NET) &&
- service_time < at_extra)
- service_time = at_extra;
+ service_timeout < at_extra)
+ service_timeout = at_extra;
/*
- * We expect other clients to timeout within service_time, then try
+ * We expect other clients to timeout within service_timeout, then try
* to reconnect, then try the failover server. The max delay between
* connect attempts is SWITCH_MAX + SWITCH_INC + INITIAL.
*/
- service_time += 2 * INITIAL_CONNECT_TIMEOUT;
+ service_timeout += 2 * INITIAL_CONNECT_TIMEOUT;
LASSERT(obt->obt_magic == OBT_MAGIC);
- service_time += 2 * (CONNECTION_SWITCH_MAX + CONNECTION_SWITCH_INC);
- if (service_time > obd->obd_recovery_timeout && !new_client)
- extend_recovery_timer(obd, service_time, false);
+ service_timeout += 2 * (CONNECTION_SWITCH_MAX + CONNECTION_SWITCH_INC);
+ if (service_timeout > obd->obd_recovery_timeout && !new_client)
+ extend_recovery_timer(obd, service_timeout, false);
}
/** Health checking routines */
/* don't reset timer for final stage */
if (!exp_finished(req->rq_export)) {
- time_t to = obd_timeout;
+ timeout_t timeout = obd_timeout;
/**
- * Add request timeout to the recovery time so next request from
+ * Add request @timeout to the recovery time so next request from
* this client may come in recovery time
*/
if (!AT_OFF) {
struct ptlrpc_service_part *svcpt;
+ timeout_t est_timeout;
svcpt = req->rq_rqbd->rqbd_svcpt;
/*
* use the maxium timeout here for waiting the client
* sending the next req
*/
- to = max_t(time_t,
- at_est2timeout(at_get(&svcpt->scp_at_estimate)),
- lustre_msg_get_timeout(req->rq_reqmsg));
+ est_timeout = at_get(&svcpt->scp_at_estimate);
+ timeout = max_t(timeout_t, at_est2timeout(est_timeout),
+ lustre_msg_get_timeout(req->rq_reqmsg));
/*
* Add 2 net_latency, one for balance rq_deadline
* (see ptl_send_rpc), one for resend the req to server,
* Note: client will pack net_latency in replay req
* (see ptlrpc_replay_req)
*/
- to += 2 * lustre_msg_get_service_time(req->rq_reqmsg);
+ timeout += 2 * lustre_msg_get_service_timeout(req->rq_reqmsg);
}
- extend_recovery_timer(class_exp2obd(req->rq_export), to, true);
+ extend_recovery_timer(class_exp2obd(req->rq_export), timeout,
+ true);
}
EXIT;
}
extend_recovery_timer(obd, obd->obd_recovery_timeout,
true);
CDEBUG(D_HA,
- "%s update recovery is not ready, extend recovery %lu\n",
+ "%s update recovery is not ready, extend recovery %d\n",
obd->obd_name, obd->obd_recovery_timeout);
return 0;
}
CDEBUG(D_HA,
"%s: recovery timed out; %d clients are still in recovery after %llu seconds (%d clients connected)\n",
obd->obd_name, atomic_read(&obd->obd_lock_replay_clients),
- ktime_get_real_seconds() - obd->obd_recovery_start,
+ ktime_get_seconds() - obd->obd_recovery_start,
atomic_read(&obd->obd_connected_clients));
obd->obd_recovery_expired = 1;