From 7f466aa2548488d355b107f7e874df340a287306 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 28 Jan 2019 14:58:26 -0600 Subject: [PATCH] osd: refuse to start if release > recorded min_osd_release + 2 If we try to start up the objectstore, we may make writeable changes to (say) rocksdb that are not backwards compatible. This happens, for example, if you start a mimic osd. Even if the compatset checks fail, rocksdb may have written something that is not backwards compatible. Fixes: http://tracker.ceph.com/issues/38076 Signed-off-by: Sage Weil (cherry picked from commit 9f7713a905d67441b28371e4494e9447319d2129) Conflicts: src/ceph_osd.cc - include common/version.h for ceph_release() - use exit instead of forker.exit --- src/ceph_osd.cc | 13 ++++++++++++- src/osd/OSD.cc | 23 ++++++++++++++++------- src/osd/OSD.h | 8 ++++++-- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/ceph_osd.cc b/src/ceph_osd.cc index efab291e6d9d3..0fcd8681bab35 100644 --- a/src/ceph_osd.cc +++ b/src/ceph_osd.cc @@ -27,6 +27,7 @@ using namespace std; #include "include/ceph_features.h" #include "common/config.h" +#include "common/version.h" #include "mon/MonMap.h" @@ -403,8 +404,10 @@ flushjournal_out: string magic; uuid_d cluster_fsid, osd_fsid; + int require_osd_release = 0; int w; - int r = OSD::peek_meta(store, magic, cluster_fsid, osd_fsid, w); + int r = OSD::peek_meta(store, &magic, &cluster_fsid, &osd_fsid, &w, + &require_osd_release); if (r < 0) { derr << TEXT_RED << " ** ERROR: unable to open OSD superblock on " << g_conf->osd_data << ": " << cpp_strerror(-r) @@ -434,6 +437,14 @@ flushjournal_out: exit(0); } + if (require_osd_release > 0 && + require_osd_release + 2 < ceph_release()) { + derr << "OSD's recorded require_osd_release " << require_osd_release + << " + 2 < this release " << ceph_release() + << "; you can only upgrade 2 releases at a time" << dendl; + exit(1); + } + pick_addresses(g_ceph_context, CEPH_PICK_ADDRESS_PUBLIC |CEPH_PICK_ADDRESS_CLUSTER); diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 776a63fb37738..4222d456d8362 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -1890,37 +1890,46 @@ int OSD::write_meta(CephContext *cct, ObjectStore *store, uuid_d& cluster_fsid, return 0; } -int OSD::peek_meta(ObjectStore *store, std::string& magic, - uuid_d& cluster_fsid, uuid_d& osd_fsid, int& whoami) +int OSD::peek_meta(ObjectStore *store, + std::string *magic, + uuid_d *cluster_fsid, + uuid_d *osd_fsid, + int *whoami, + int *require_osd_release) { string val; int r = store->read_meta("magic", &val); if (r < 0) return r; - magic = val; + *magic = val; r = store->read_meta("whoami", &val); if (r < 0) return r; - whoami = atoi(val.c_str()); + *whoami = atoi(val.c_str()); r = store->read_meta("ceph_fsid", &val); if (r < 0) return r; - r = cluster_fsid.parse(val.c_str()); + r = cluster_fsid->parse(val.c_str()); if (!r) return -EINVAL; r = store->read_meta("fsid", &val); if (r < 0) { - osd_fsid = uuid_d(); + *osd_fsid = uuid_d(); } else { - r = osd_fsid.parse(val.c_str()); + r = osd_fsid->parse(val.c_str()); if (!r) return -EINVAL; } + r = store->read_meta("require_osd_release", &val); + if (r >= 0) { + *require_osd_release = atoi(val.c_str()); + } + return 0; } diff --git a/src/osd/OSD.h b/src/osd/OSD.h index 2f7e3c7c8cbda..52a281bc368a3 100644 --- a/src/osd/OSD.h +++ b/src/osd/OSD.h @@ -2502,8 +2502,12 @@ private: float get_osd_recovery_sleep(); public: - static int peek_meta(ObjectStore *store, string& magic, - uuid_d& cluster_fsid, uuid_d& osd_fsid, int& whoami); + static int peek_meta(ObjectStore *store, + string *magic, + uuid_d *cluster_fsid, + uuid_d *osd_fsid, + int *whoami, + int *min_osd_release); // startup/shutdown -- 2.39.5