*/
void ptlrpc_update_export_timer(struct obd_export *exp, time64_t extra_delay)
{
- struct obd_export *oldest_exp;
- time64_t oldest_time, new_time;
-
+ struct obd_export *oldest_exp, *newest_exp;
+ time64_t oldest_time, current_time;
+ bool evict = false;
ENTRY;
LASSERT(exp);
*/
/* Do not pay attention on 1sec or smaller renewals. */
- new_time = ktime_get_real_seconds() + extra_delay;
- if (exp->exp_last_request_time + 1 /*second */ >= new_time)
+ current_time = ktime_get_real_seconds();
+ /* 1 seconds */
+ if (exp->exp_last_request_time + 1 >= current_time + extra_delay)
RETURN_EXIT;
- exp->exp_last_request_time = new_time;
+ exp->exp_last_request_time = current_time + extra_delay;
/*
* exports may get disconnected from the chain even though the
RETURN_EXIT;
}
+ newest_exp = list_entry(exp->exp_obd->obd_exports_timed.prev,
+ struct obd_export, exp_obd_chain_timed);
+
list_move_tail(&exp->exp_obd_chain_timed,
&exp->exp_obd->obd_exports_timed);
+ if (exp->exp_obd->obd_recovering) {
+ /* be nice to everyone during recovery */
+ spin_unlock(&exp->exp_obd->obd_dev_lock);
+ RETURN_EXIT;
+ }
+
oldest_exp = list_entry(exp->exp_obd->obd_exports_timed.next,
struct obd_export, exp_obd_chain_timed);
+
oldest_time = oldest_exp->exp_last_request_time;
- spin_unlock(&exp->exp_obd->obd_dev_lock);
- if (exp->exp_obd->obd_recovering) {
- /* be nice to everyone during recovery */
- EXIT;
- return;
- }
+ /* Check if the oldest entry is expired. */
+ if (exp->exp_obd->obd_eviction_timer == 0 &&
+ current_time > oldest_time + PING_EVICT_TIMEOUT + extra_delay) {
- /* Note - racing to start/reset the obd_eviction timer is safe */
- if (exp->exp_obd->obd_eviction_timer == 0) {
- /* Check if the oldest entry is expired. */
- if (ktime_get_real_seconds() >
- oldest_time + PING_EVICT_TIMEOUT + extra_delay) {
+ if (current_time < newest_exp->exp_last_request_time +
+ PING_EVICT_TIMEOUT / 2) {
+ /* If import is active - evict stale clients */
+ evict = true;
+ } else {
/*
* We need a second timer, in case the net was down and
* it just came back. Since the pinger may skip every
CDEBUG(D_HA, "%s: Think about evicting %s from %lld\n",
exp->exp_obd->obd_name,
obd_export_nid2str(oldest_exp), oldest_time);
+
}
+ }
+
+ spin_unlock(&exp->exp_obd->obd_dev_lock);
+
+ if (evict) {
+ /* Evict stale clients */
+ ping_evictor_wake(exp);
} else {
if (ktime_get_real_seconds() >
(exp->exp_obd->obd_eviction_timer + extra_delay)) {
local before=$(date +%s)
local rc=0
- # evictor takes PING_EVICT_TIMEOUT + 3 * PING_INTERVAL to evict.
+ # evictor takes PING_EVICT_TIMEOUT to evict.
# But if there's a race to start the evictor from various obds,
# the loser might have to wait for the next ping.
- sleep $((TIMEOUT * 2 + TIMEOUT * 3 / 4))
+ sleep $((TIMEOUT * 2))
do_facet client lctl set_param fail_loc=0x0
do_facet client lfs df > /dev/null
# PING_INTERVAL max(obd_timeout / 4, 1U)
# PING_EVICT_TIMEOUT (PING_INTERVAL * 6)
- # evictor takes PING_EVICT_TIMEOUT + 3 * PING_INTERVAL to evict.
+ # evictor takes PING_EVICT_TIMEOUT to evict.
# But if there's a race to start the evictor from various obds,
# the loser might have to wait for the next ping.
- # = 9 * PING_INTERVAL + PING_INTERVAL
- # = 10 PING_INTERVAL = 10 obd_timeout / 4 = 2.5 obd_timeout
- # let's wait $((TIMEOUT * 3)) # bug 19887
- wait_client_evicted ost1 $OST_NEXP $((TIMEOUT * 3)) ||
+ # = 6 * PING_INTERVAL + PING_INTERVAL
+ # = 7 PING_INTERVAL = 7 obd_timeout / 4 = (1+3/4)obd_timeout
+ # let's wait $((TIMEOUT * 2)) # bug 19887
+ wait_client_evicted ost1 $OST_NEXP $((TIMEOUT * 2)) ||
error "Client was not evicted by ost"
- wait_client_evicted $SINGLEMDS $MDS_NEXP $((TIMEOUT * 3)) ||
+ wait_client_evicted $SINGLEMDS $MDS_NEXP $((TIMEOUT * 2)) ||
error "Client was not evicted by mds"
}
run_test 26b "evict dead exports"
$LCTL set_param fail_loc=0x80000514
facet_failover $SINGLEMDS
[ -f "$LU482_FAILED" ] && skip "LU-482 failure" && return 0
- client_up || return 1
+ client_up || (sleep 10; client_up) || (sleep 10; client_up) ||
+ error "reconnect failed"
umount -f $MOUNT2
- client_up || return 1
- zconf_mount `hostname` $MOUNT2 || error "mount2 fais"
- unlinkmany $MOUNT1/$tfile- 50 || return 2
- rm $MOUNT2/$tfile || return 3
- rm $MOUNT2/$tfile-A || return 4
+ client_up || (sleep 10; client_up) || (sleep 10; client_up) ||
+ error "reconnect failed"
+ zconf_mount `hostname` $MOUNT2 || error "mount2 failed"
+ unlinkmany $MOUNT1/$tfile- 50 || errot "unlinkmany failed"
+ rm $MOUNT2/$tfile || error "rm $MOUNT2/$tfile failed"
+ rm $MOUNT2/$tfile-A || error "rm $MOUNT2/$tfile-A failed"
}
run_test 0a "expired recovery with lost client"