#define CEPH_MDSMAP_ALLOW_SNAPS (1<<1) /* cluster allowed to create snapshots */
/* deprecated #define CEPH_MDSMAP_ALLOW_MULTIMDS (1<<2) cluster allowed to have >1 active MDS */
/* deprecated #define CEPH_MDSMAP_ALLOW_DIRFRAGS (1<<3) cluster allowed to fragment directories */
-#define CEPH_MDSMAP_ALLOW_MULTIMDS_SNAPS (1<<4) /* cluster alllowed to enable MULTIMDS
- and SNAPS at the same time */
+#define CEPH_MDSMAP_ALLOW_MULTIMDS_SNAPS (1<<4) /* cluster alllowed to enable MULTIMDS
+ and SNAPS at the same time */
+#define CEPH_MDSMAP_ALLOW_STANDBY_REPLAY (1<<5) /* cluster alllowed to enable MULTIMDS */
#define CEPH_MDSMAP_DEFAULTS (CEPH_MDSMAP_ALLOW_SNAPS | \
CEPH_MDSMAP_ALLOW_MULTIMDS_SNAPS)
bool allows_snaps() const { return test_flag(CEPH_MDSMAP_ALLOW_SNAPS); }
bool was_snaps_ever_allowed() const { return ever_allowed_features & CEPH_MDSMAP_ALLOW_SNAPS; }
+ void set_standby_replay_allowed() {
+ set_flag(CEPH_MDSMAP_ALLOW_STANDBY_REPLAY);
+ ever_allowed_features |= CEPH_MDSMAP_ALLOW_STANDBY_REPLAY;
+ explicitly_allowed_features |= CEPH_MDSMAP_ALLOW_STANDBY_REPLAY;
+ }
+ void clear_standby_replay_allowed() { clear_flag(CEPH_MDSMAP_ALLOW_STANDBY_REPLAY); }
+ bool allows_standby_replay() const { return test_flag(CEPH_MDSMAP_ALLOW_STANDBY_REPLAY); }
+ bool was_standby_replay_ever_allowed() const { return ever_allowed_features & CEPH_MDSMAP_ALLOW_STANDBY_REPLAY; }
+
void set_multimds_snaps_allowed() {
set_flag(CEPH_MDSMAP_ALLOW_MULTIMDS_SNAPS);
ever_allowed_features |= CEPH_MDSMAP_ALLOW_MULTIMDS_SNAPS;
{
fs->mds_map.set_session_autoclose((uint32_t)n);
});
+ } else if (var == "allow_standby_replay") {
+ bool allow = false;
+ int r = parse_bool(val, &allow, ss);
+ if (r != 0) {
+ return r;
+ }
+
+ auto f = [allow](auto& fs) {
+ if (allow) {
+ fs->mds_map.set_standby_replay_allowed();
+ } else {
+ fs->mds_map.clear_standby_replay_allowed();
+ }
+ };
+ fsmap.modify_filesystem(fs->fscid, std::move(f));
} else if (var == "min_compat_client") {
int vno = ceph_release_from_name(val.c_str());
if (vno <= 0) {
}
}
+ if (fs.mds_map.allows_standby_replay() && !fs.mds_map.is_degraded()) {
+ // There were no failures to replace, so try using any available standbys
+ // as standby-replay daemons. Don't do this when the cluster is degraded
+ // as a standby-replay daemon may try to read a journal being migrated.
+ for (;;) {
+ auto standby_gid = fsmap.get_available_standby();
+ if (standby_gid == MDS_GID_NONE) break;
+ dout(20) << "standby available mds." << standby_gid << dendl;
+ bool changed = false;
+ for (const auto& rank : fs.mds_map.in) {
+ dout(20) << "exmaining " << rank << dendl;
+ if (fs.mds_map.is_followable(rank)) {
+ dout(1) << " setting mds." << standby_gid
+ << " to follow mds rank " << rank << dendl;
+ fsmap.assign_standby_replay(standby_gid, fs.fscid, rank);
+ do_propose = true;
+ changed = true;
+ break;
+ }
+ }
+ if (!changed) break;
+ }
+ }
+
return do_propose;
}
"name=var,type=CephChoices,strings=max_mds|max_file_size"
"|allow_new_snaps|inline_data|cluster_down|allow_dirfrags|balancer" \
"|standby_count_wanted|session_timeout|session_autoclose" \
- "|down|joinable|min_compat_client " \
+ "|allow_standby_replay|down|joinable|min_compat_client " \
"name=val,type=CephString " \
"name=yes_i_really_mean_it,type=CephBool,req=false", \
"set fs parameter <var> to <val>", "mds", "rw")