#include "common/Formatter.h"
#include "common/errno.h"
+#include "auth/KeyRing.h"
+#include "auth/cephx/CephxKeyServer.h"
#include "global/global_init.h"
#include "include/stringify.h"
+#include "mon/AuthMonitor.h"
#include "mon/MonitorDBStore.h"
#include "mon/Paxos.h"
#include "mon/MonMap.h"
<< " (rewrite-crush -- --help for more info)\n"
<< " inflate-pgmap [-- options] add given number of pgmaps to store\n"
<< " (inflate-pgmap -- --help for more info)\n"
+ << " rebuild rebuild store\n"
+ << " (rebuild -- --help for more info)\n"
<< std::endl;
std::cerr << d << std::endl;
std::cerr
return 0;
}
+static int update_auth(MonitorDBStore& st, const string& keyring_path)
+{
+ // import all keyrings stored in the keyring file
+ KeyRing keyring;
+ int r = keyring.load(g_ceph_context, keyring_path);
+ if (r < 0) {
+ cerr << "unable to load admin keyring: " << keyring_path << std::endl;
+ return r;
+ }
+
+ bufferlist bl;
+ __u8 v = 1;
+ ::encode(v, bl);
+
+ for (map<EntityName, EntityAuth>::const_iterator k = keyring.get_keys().begin();
+ k != keyring.get_keys().end(); ++k) {
+ KeyServerData::Incremental auth_inc;
+ auth_inc.name = k->first;
+ auth_inc.auth = k->second;
+ auth_inc.op = KeyServerData::AUTH_INC_ADD;
+
+ AuthMonitor::Incremental inc;
+ inc.inc_type = AuthMonitor::AUTH_DATA;
+ ::encode(auth_inc, inc.auth_data);
+ inc.auth_type = CEPH_AUTH_CEPHX;
+
+ inc.encode(bl, CEPH_FEATURES_ALL);
+ }
+
+ const string prefix("auth");
+ version_t last_committed = st.get(prefix, "last_committed") + 1;
+ MonitorDBStore::TransactionRef t(new MonitorDBStore::Transaction);
+ t->put(prefix, last_committed, bl);
+ t->put(prefix, "last_committed", last_committed);
+ version_t first_committed = st.get(prefix, "first_committed");
+ if (!first_committed) {
+ t->put(prefix, "first_committed", last_committed);
+ }
+ st.apply_transaction(t);
+ return 0;
+}
+
+static int update_mkfs(MonitorDBStore& st)
+{
+ MonMap monmap;
+ int r = monmap.build_initial(g_ceph_context, cerr);
+ if (r) {
+ cerr << "no initial monitors" << std::endl;
+ return -EINVAL;
+ }
+ bufferlist bl;
+ monmap.encode(bl, CEPH_FEATURES_ALL);
+ monmap.set_epoch(0);
+ MonitorDBStore::TransactionRef t(new MonitorDBStore::Transaction);
+ t->put("mkfs", "monmap", bl);
+ st.apply_transaction(t);
+ return 0;
+}
+
+static int update_monitor(MonitorDBStore& st)
+{
+ const string prefix("monitor");
+ // a stripped-down Monitor::mkfs()
+ bufferlist bl;
+ bl.append(CEPH_MON_ONDISK_MAGIC "\n");
+ MonitorDBStore::TransactionRef t(new MonitorDBStore::Transaction);
+ t->put(prefix, "magic", bl);
+ st.apply_transaction(t);
+ return 0;
+}
+
+static int update_paxos(MonitorDBStore& st)
+{
+ // build a pending paxos proposal from all non-permanent k/v pairs. once the
+ // proposal is committed, it will gets applied. on the sync provider side, it
+ // will be a no-op, but on its peers, the paxos commit will help to build up
+ // the necessary epochs.
+ bufferlist pending_proposal;
+ {
+ MonitorDBStore::Transaction t;
+ const char* prefixes[] = {"auth", "osdmap", "pgmap", "pgmap_pg"};
+ for (const char** prefix = &prefixes[0]; prefix != prefixes + sizeof(prefixes); prefix++) {
+ for (KeyValueDB::Iterator i = st.get_iterator(*prefix); i->valid(); i->next()) {
+ bufferlist value = i->value();
+ t.put(*prefix, i->key(), value);
+ }
+ }
+ t.encode(pending_proposal);
+ }
+ const string prefix("paxos");
+ MonitorDBStore::TransactionRef t(new MonitorDBStore::Transaction);
+ t->put(prefix, "first_committed", 0);
+ t->put(prefix, "last_committed", 0);
+ version_t pending_v = 1;
+ t->put(prefix, pending_v, pending_proposal);
+ t->put(prefix, "pending_v", pending_v);
+ t->put(prefix, "pending_pn", 400);
+ st.apply_transaction(t);
+ return 0;
+}
+
+int rebuild_monstore(const char* progname,
+ vector<string>& subcmds,
+ MonitorDBStore& st)
+{
+ po::options_description op_desc("Allowed 'rebuild' options");
+ string keyring_path;
+ op_desc.add_options()
+ ("keyring", po::value<string>(&keyring_path),
+ "path to the client.admin key");
+ po::variables_map op_vm;
+ int r = parse_cmd_args(&op_desc, NULL, NULL, subcmds, &op_vm);
+ if (r) {
+ return -r;
+ }
+ if (op_vm.count("help")) {
+ usage(progname, op_desc);
+ return 0;
+ }
+ if (!keyring_path.empty())
+ update_auth(st, keyring_path);
+ if ((r = update_paxos(st))) {
+ return r;
+ }
+ if ((r = update_mkfs(st))) {
+ return r;
+ }
+ if ((r = update_monitor(st))) {
+ return r;
+ }
+ return 0;
+}
+
int main(int argc, char **argv) {
int err = 0;
po::options_description desc("Allowed options");
goto done;
}
err = inflate_pgmap(st, n, can_be_trimmed);
+ } else if (cmd == "rebuild") {
+ err = rebuild_monstore(argv[0], subcmds, st);
} else {
std::cerr << "Unrecognized command: " << cmd << std::endl;
usage(argv[0], desc);