From: Sage Weil Date: Wed, 5 Jun 2013 14:55:46 +0000 (-0700) Subject: mon: upgrade auth database on leader X-Git-Tag: v0.65~136^2^2~14 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f43c974571beac0c8e54fa699bfa96a1befaf56c;p=ceph.git mon: upgrade auth database on leader If we are the leader, and the auth database has not yet been upgraded, do so. The upgrade consists of translating old-style (pre-v0.64) caps to new-style caps (e.g., 'allow profile bootstrap-osd'). This happens once and the conversion takes the form of a normal paxos transaction. Signed-off-by: Sage Weil Reviewed-by: Joao Eduardo Luis --- diff --git a/src/mon/AuthMonitor.cc b/src/mon/AuthMonitor.cc index e6a15ec832a..93ad368f186 100644 --- a/src/mon/AuthMonitor.cc +++ b/src/mon/AuthMonitor.cc @@ -87,6 +87,8 @@ void AuthMonitor::on_active() /* check_rotate(); */ + + upgrade_format(); } void AuthMonitor::create_initial() @@ -193,8 +195,12 @@ void AuthMonitor::update_from_paxos() if (last_allocated_id == 0) last_allocated_id = max_global_id; + format_version = get_version(get_service_name(), "format_version"); + dout(10) << "update_from_paxos() last_allocated_id=" << last_allocated_id - << " max_global_id=" << max_global_id << dendl; + << " max_global_id=" << max_global_id + << " format_version " << format_version + << dendl; /* bufferlist bl; @@ -242,6 +248,10 @@ void AuthMonitor::encode_pending(MonitorDBStore::Transaction *t) for (p = pending_auth.begin(); p != pending_auth.end(); ++p) p->encode(bl, mon->get_quorum_features()); + if (format_version > 0) { + t->put(get_service_name(), "format_version", format_version); + } + version_t version = get_version() + 1; put_version(t, version, bl); put_last_committed(t, version); @@ -870,3 +880,74 @@ bool AuthMonitor::prepare_global_id(MMonGlobalID *m) m->put(); return true; } + +void AuthMonitor::upgrade_format() +{ + int current = 1; + if (format_version >= current) { + dout(20) << __func__ << " format " << format_version << " is current" << dendl; + return; + } + + dout(1) << __func__ << " upgrading from format " << format_version << " to " << current << dendl; + bool changed = false; + map::iterator p; + for (p = mon->key_server.secrets_begin(); + p != mon->key_server.secrets_end(); + ++p) { + // grab mon caps, if any + string mon_caps; + if (p->second.caps.count("mon") == 0) + continue; + try { + bufferlist::iterator it = p->second.caps["mon"].begin(); + ::decode(mon_caps, it); + } + catch (buffer::error) { + dout(10) << __func__ << " unable to parse mon cap for " + << p->first << dendl; + continue; + } + + string n = p->first.to_str(); + string new_caps; + + // set daemon profiles + if ((p->first.is_osd() || p->first.is_mds()) && + mon_caps == "allow rwx") { + new_caps = string("allow profile ") + string(p->first.get_type_name()); + } + + // update bootstrap keys + if (n == "client.bootstrap-osd") { + new_caps = "allow profile bootstrap-osd"; + } + if (n == "client.bootstrap-mds") { + new_caps = "allow profile bootstrap-mds"; + } + + if (new_caps.length() > 0) { + dout(5) << __func__ << " updating " << p->first << " mon cap from " + << mon_caps << " to " << new_caps << dendl; + + bufferlist bl; + ::encode(new_caps, bl); + + KeyServerData::Incremental auth_inc; + auth_inc.name = p->first; + auth_inc.auth = p->second; + auth_inc.auth.caps["mon"] = bl; + auth_inc.op = KeyServerData::AUTH_INC_ADD; + push_cephx_inc(auth_inc); + changed = true; + } + } + + if (changed) { + // note new format + dout(10) << __func__ << " proposing update from format " << format_version + << " -> " << current << dendl; + format_version = current; + propose_pending(); + } +} diff --git a/src/mon/AuthMonitor.h b/src/mon/AuthMonitor.h index 3d305f5630c..9368fcd8613 100644 --- a/src/mon/AuthMonitor.h +++ b/src/mon/AuthMonitor.h @@ -112,6 +112,10 @@ private: uint64_t max_global_id; uint64_t last_allocated_id; + version_t format_version; + + void upgrade_format(); + void export_keyring(KeyRing& keyring); void import_keyring(KeyRing& keyring); @@ -148,7 +152,9 @@ private: public: AuthMonitor(Monitor *mn, Paxos *p, const string& service_name) : PaxosService(mn, p, service_name), last_rotating_ver(0), - max_global_id(0), last_allocated_id(0) {} + max_global_id(0), last_allocated_id(0), + format_version(0) + {} void pre_auth(MAuth *m);