mirror of
https://github.com/versity/scoutfs.git
synced 2026-10-22 14:22:42 +00:00
Add pre-fencing grace period when starting a new server
One of the first steps in starting a new server is to fence the previous server if it's still running. This happens nearly immediately, and it can take some time for the old server to shut down cleanly. So we're often fencing when we should really just be patient. Add a grace period, currently up to about 10s, watching for an old server to write out its STOP record. After that, go ahead and fence. Signed-off-by: Chris Kirby <ckirby@versity.com>
This commit is contained in:
+13
-2
@@ -536,17 +536,21 @@ static int update_quorum_block(struct super_block *sb, int event, u64 term, bool
|
||||
*
|
||||
* Quorum will be sending heartbeats while we wait for fencing. That
|
||||
* keeps us from being fenced while we allow userspace fencing to take a
|
||||
* reasonably long time. We still want to timeout eventually.
|
||||
* reasonably long time. We still want to time out eventually.
|
||||
*/
|
||||
|
||||
#define SCOUTFS_OLD_LEADER_GRACE_PERIOD ((time64_t)10) /* arbitrary number of seconds */
|
||||
|
||||
int scoutfs_quorum_fence_leaders(struct super_block *sb, struct scoutfs_quorum_config *qconf,
|
||||
u64 term)
|
||||
{
|
||||
#define NR_OLD 2
|
||||
struct scoutfs_quorum_block_event old[SCOUTFS_QUORUM_MAX_SLOTS][NR_OLD] = {{{0,}}};
|
||||
struct scoutfs_quorum_block_event old[SCOUTFS_QUORUM_MAX_SLOTS][NR_OLD];
|
||||
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
|
||||
struct scoutfs_quorum_block blk;
|
||||
struct sockaddr_in sin;
|
||||
const __le64 lefsid = cpu_to_le64(sbi->fsid);
|
||||
time64_t start = ktime_get_seconds();
|
||||
const u64 rid = sbi->rid;
|
||||
bool fence_started = false;
|
||||
u64 fenced = 0;
|
||||
@@ -558,6 +562,9 @@ int scoutfs_quorum_fence_leaders(struct super_block *sb, struct scoutfs_quorum_c
|
||||
|
||||
BUILD_BUG_ON(SCOUTFS_QUORUM_BLOCKS < SCOUTFS_QUORUM_MAX_SLOTS);
|
||||
|
||||
restart:
|
||||
memset(old, 0, sizeof(old));
|
||||
|
||||
for (i = 0; i < SCOUTFS_QUORUM_MAX_SLOTS; i++) {
|
||||
if (!quorum_slot_present(qconf, i))
|
||||
continue;
|
||||
@@ -591,6 +598,10 @@ int scoutfs_quorum_fence_leaders(struct super_block *sb, struct scoutfs_quorum_c
|
||||
le64_to_cpu(old[i][j].rid) == rid) /* us */
|
||||
continue;
|
||||
|
||||
/* Give any previous leader(s) a grace period before fencing */
|
||||
if (ktime_get_seconds() - start < SCOUTFS_OLD_LEADER_GRACE_PERIOD)
|
||||
goto restart;
|
||||
|
||||
scoutfs_inc_counter(sb, quorum_fence_leader);
|
||||
quorum_slot_sin(qconf, i, &sin);
|
||||
fence_rid = old[i][j].rid;
|
||||
|
||||
@@ -78,7 +78,12 @@ test_timeout()
|
||||
|
||||
# make sure the new leader delay was reasonable, allowing for some slack
|
||||
low=$((to - 1000))
|
||||
high=$((to + 5000))
|
||||
|
||||
# There's a race with the old server shutting down and writing its
|
||||
# STOP record, which will trigger a delay (SCOUTFS_OLD_LEADER_GRACE_PERIOD)
|
||||
# while the new server gives the old one a grace period. That duration needs
|
||||
# to be included in the upper limit.
|
||||
high=$((to + 15000))
|
||||
|
||||
# make sure the new leader delay was reasonable
|
||||
test "$delay" -lt "$low" && t_fail "delay $delay < low $low (to $to)"
|
||||
|
||||
Reference in New Issue
Block a user