From 74e3f5ec5a49ce99b56c305624e9110fcb4b787c Mon Sep 17 00:00:00 2001 From: Patrick Donnelly Date: Wed, 3 Nov 2021 16:41:24 -0400 Subject: [PATCH] mds/FSMap: assign v16.2.4 compat to pre-v16.2.5 standby daemons With v16.2.5, the monitors store an MDS's CompatSet with its mds_info_t in the MDSMap. If an older MDS fails and rejoins the cluster, it gets assigned the empty CompatSet. This is problematic during upgrades as an MDS failure may prevent the upgrade process from continuing and cause file system unavailability. This patch makes it so the mons will assign a reasonable default: a CompatSet used since v14.2.0 until v16.2.5. Fixes: https://tracker.ceph.com/issues/53150 Signed-off-by: Patrick Donnelly --- src/mds/FSMap.cc | 10 +++++++++- src/mds/MDSMap.cc | 19 +++++++++++++++++++ src/mds/MDSMap.h | 1 + 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/mds/FSMap.cc b/src/mds/FSMap.cc index e258cc139ad..6a5b84b91e4 100644 --- a/src/mds/FSMap.cc +++ b/src/mds/FSMap.cc @@ -1054,10 +1054,18 @@ bool FSMap::undamaged(const fs_cluster_id_t fscid, const mds_rank_t rank) void FSMap::insert(const MDSMap::mds_info_t &new_info) { + static const CompatSet empty; + ceph_assert(new_info.state == MDSMap::STATE_STANDBY); ceph_assert(new_info.rank == MDS_RANK_NONE); mds_roles[new_info.global_id] = FS_CLUSTER_ID_NONE; - standby_daemons[new_info.global_id] = new_info; + auto& info = standby_daemons[new_info.global_id]; + info = new_info; + if (empty.compare(info.compat) == 0) { + // bootstrap old compat: boot beacon contains empty compat on old (v16.2.4 + // or older) MDS. + info.compat = MDSMap::get_compat_set_v16_2_4(); + } standby_epochs[new_info.global_id] = epoch; } diff --git a/src/mds/MDSMap.cc b/src/mds/MDSMap.cc index 956dff2d930..8aea8d01982 100644 --- a/src/mds/MDSMap.cc +++ b/src/mds/MDSMap.cc @@ -83,6 +83,23 @@ CompatSet MDSMap::get_compat_set_base() { return CompatSet(feature_compat_base, feature_ro_compat_base, feature_incompat_base); } +// pre-v16.2.5 CompatSet in MDS beacon +CompatSet MDSMap::get_compat_set_v16_2_4() { + CompatSet::FeatureSet feature_compat; + CompatSet::FeatureSet feature_ro_compat; + CompatSet::FeatureSet feature_incompat; + feature_incompat.insert(MDS_FEATURE_INCOMPAT_BASE); + feature_incompat.insert(MDS_FEATURE_INCOMPAT_CLIENTRANGES); + feature_incompat.insert(MDS_FEATURE_INCOMPAT_FILELAYOUT); + feature_incompat.insert(MDS_FEATURE_INCOMPAT_DIRINODE); + feature_incompat.insert(MDS_FEATURE_INCOMPAT_ENCODING); + feature_incompat.insert(MDS_FEATURE_INCOMPAT_OMAPDIRFRAG); + feature_incompat.insert(MDS_FEATURE_INCOMPAT_NOANCHOR); + feature_incompat.insert(MDS_FEATURE_INCOMPAT_FILE_LAYOUT_V2); + feature_incompat.insert(MDS_FEATURE_INCOMPAT_SNAPREALM_V2); + return CompatSet(feature_compat, feature_ro_compat, feature_incompat); +} + void MDSMap::mds_info_t::dump(Formatter *f) const { f->dump_unsigned("gid", global_id); @@ -638,6 +655,8 @@ void MDSMap::mds_info_t::decode(bufferlist::const_iterator& bl) } if (struct_v >= 10) { decode(compat, bl); + } else { + compat = MDSMap::get_compat_set_v16_2_4(); } DECODE_FINISH(bl); } diff --git a/src/mds/MDSMap.h b/src/mds/MDSMap.h index 2b4021ba1f4..b9f3c6cabe1 100644 --- a/src/mds/MDSMap.h +++ b/src/mds/MDSMap.h @@ -168,6 +168,7 @@ public: static CompatSet get_compat_set_all(); static CompatSet get_compat_set_default(); static CompatSet get_compat_set_base(); // pre v0.20 + static CompatSet get_compat_set_v16_2_4(); // pre-v16.2.5 CompatSet in MDS beacon static MDSMap create_null_mdsmap() { MDSMap null_map; -- 2.39.5