From: Patrick Donnelly Date: Wed, 3 Nov 2021 20:41:24 +0000 (-0400) Subject: mds/FSMap: assign v16.2.4 compat to pre-v16.2.5 standby daemons X-Git-Tag: v16.2.7~36^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0c3026b3f65dd1c28a60df0a05bff42f6a96267b;p=ceph.git 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 (cherry picked from commit 74e3f5ec5a49ce99b56c305624e9110fcb4b787c) --- diff --git a/src/mds/FSMap.cc b/src/mds/FSMap.cc index e1026a677c4..65c94427535 100644 --- a/src/mds/FSMap.cc +++ b/src/mds/FSMap.cc @@ -1044,10 +1044,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 17741ec2b79..9de050e3e81 100644 --- a/src/mds/MDSMap.cc +++ b/src/mds/MDSMap.cc @@ -82,6 +82,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); @@ -613,6 +630,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 45652d44eaf..f583e22ea88 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;