mon: refactor monitor feature checks

Three helpers:
 - legacy features (if file isn't present)
 - required features
 - supported features

Write out the feature file on startup with legacy values if it isn't
present, so that everything else can assume it is there.

Signed-off-by: Sage Weil <sage@inktank.com>
This commit is contained in:
Sage Weil 2012-09-12 16:22:26 -07:00
parent e84f2e4926
commit ebdfd4badf
4 changed files with 47 additions and 32 deletions

View File

@ -45,8 +45,6 @@ using namespace std;
#define dout_subsys ceph_subsys_mon
extern CompatSet get_ceph_mon_feature_compat_set();
Monitor *mon = NULL;
void handle_mon_signal(int signum)

View File

@ -41,6 +41,9 @@ struct CompatSet {
names[f.id] = f.name;
}
bool contains(Feature f) const {
return names.count(f.id);
}
bool contains(uint64_t f) const {
return names.count(f);
}

View File

@ -81,16 +81,6 @@ static ostream& _prefix(std::ostream *_dout, const Monitor *mon) {
<< "(" << mon->get_state_name() << ") e" << mon->monmap->get_epoch() << " ";
}
CompatSet get_ceph_mon_feature_compat_set()
{
CompatSet::FeatureSet ceph_mon_feature_compat;
CompatSet::FeatureSet ceph_mon_feature_ro_compat;
CompatSet::FeatureSet ceph_mon_feature_incompat;
ceph_mon_feature_incompat.insert(CEPH_MON_FEATURE_INCOMPAT_BASE);
return CompatSet(ceph_mon_feature_compat, ceph_mon_feature_ro_compat,
ceph_mon_feature_incompat);
}
long parse_pos_long(const char *s, ostream *pss)
{
char *e = 0;
@ -301,31 +291,53 @@ void Monitor::handle_signal(int signum)
shutdown();
}
CompatSet Monitor::get_supported_features()
{
CompatSet::FeatureSet ceph_mon_feature_compat;
CompatSet::FeatureSet ceph_mon_feature_ro_compat;
CompatSet::FeatureSet ceph_mon_feature_incompat;
ceph_mon_feature_incompat.insert(CEPH_MON_FEATURE_INCOMPAT_BASE);
return CompatSet(ceph_mon_feature_compat, ceph_mon_feature_ro_compat,
ceph_mon_feature_incompat);
}
CompatSet Monitor::get_legacy_features()
{
CompatSet::FeatureSet ceph_mon_feature_compat;
CompatSet::FeatureSet ceph_mon_feature_ro_compat;
CompatSet::FeatureSet ceph_mon_feature_incompat;
ceph_mon_feature_incompat.insert(CEPH_MON_FEATURE_INCOMPAT_BASE);
return CompatSet(ceph_mon_feature_compat, ceph_mon_feature_ro_compat,
ceph_mon_feature_incompat);
}
int Monitor::check_features(MonitorStore *store)
{
CompatSet mon_features = get_ceph_mon_feature_compat_set();
CompatSet ondisk_features;
CompatSet required = get_supported_features();
CompatSet ondisk;
bufferlist features;
store->get_bl_ss(features, COMPAT_SET_LOC, 0);
if (features.length() == 0) {
cerr << "WARNING: mon fs missing feature list.\n"
<< "Assuming it is old-style and introducing one." << std::endl;
generic_dout(0) << "WARNING: mon fs missing feature list.\n"
<< "Assuming it is old-style and introducing one." << dendl;
//we only want the baseline ~v.18 features assumed to be on disk.
//If new features are introduced this code needs to disappear or
//be made smarter.
ondisk_features = get_ceph_mon_feature_compat_set();
ondisk = get_legacy_features();
bufferlist bl;
ondisk.encode(bl);
store->put_bl_ss(bl, COMPAT_SET_LOC, 0);
} else {
bufferlist::iterator it = features.begin();
ondisk_features.decode(it);
ondisk.decode(it);
}
if (!mon_features.writeable(ondisk_features)) {
cerr << "monitor executable cannot read disk! Missing features: "
<< std::endl;
CompatSet diff = mon_features.unsupported(ondisk_features);
//NEEDS_COMPATSET_ITER
return -1;
if (!required.writeable(ondisk)) {
CompatSet diff = required.unsupported(ondisk);
generic_derr << "ERROR: on disk data includes unsupported features: " << diff << dendl;
return -EPERM;
}
return 0;
@ -335,12 +347,10 @@ void Monitor::read_features()
{
bufferlist bl;
store->get_bl_ss(bl, COMPAT_SET_LOC, 0);
if (bl.length()) {
bufferlist::iterator p = bl.begin();
::decode(features, p);
} else {
features = get_ceph_mon_feature_compat_set();
}
assert(bl.length());
bufferlist::iterator p = bl.begin();
::decode(features, p);
dout(10) << "features " << features << dendl;
}
@ -2273,7 +2283,7 @@ int Monitor::mkfs(bufferlist& osdmapbl)
if (r < 0)
return r;
features = get_ceph_mon_feature_compat_set();
features = get_supported_features();
write_features();
// save monmap, osdmap, keyring.

View File

@ -418,6 +418,9 @@ public:
void extract_save_mon_key(KeyRing& keyring);
// features
static CompatSet get_supported_features();
static CompatSet get_legacy_features();
void read_features();
void write_features();
@ -460,6 +463,7 @@ private:
};
#define CEPH_MON_FEATURE_INCOMPAT_BASE CompatSet::Feature (1, "initial feature set (~v.18)")
#define CEPH_MON_FEATURE_INCOMPAT_GV CompatSet::Feature (2, "global version sequencing (v0.52)")
long parse_pos_long(const char *s, ostream *pss = NULL);