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 <pdonnell@redhat.com>
This commit is contained in:
Patrick Donnelly 2021-11-03 16:41:24 -04:00
parent 56463c4bc5
commit 74e3f5ec5a
No known key found for this signature in database
GPG Key ID: BE69BB7D36E459B4
3 changed files with 29 additions and 1 deletions

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;