#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 (const auto& k : keyring.get_keys()) {
+ 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");
+ auto last_committed = st.get(prefix, "last_committed") + 1;
+ auto t = make_shared<MonitorDBStore::Transaction>();
+ t->put(prefix, last_committed, bl);
+ t->put(prefix, "last_committed", last_committed);
+ auto 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);
+ auto t = make_shared<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");
+ auto t = make_shared<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;
+ vector<string> prefixes = {"auth", "osdmap", "pgmap", "pgmap_pg"};
+ for (const auto& prefix : prefixes) {
+ for (auto i = st.get_iterator(prefix); i->valid(); i->next()) {
+ auto key = i->raw_key();
+ auto val = i->value();
+ t.put(key.first, key.second, val);
+ }
+ }
+ t.encode(pending_proposal);
+ }
+ const string prefix("paxos");
+ auto t = make_shared<MonitorDBStore::Transaction>();
+ t->put(prefix, "first_committed", 0);
+ t->put(prefix, "last_committed", 0);
+ auto 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, nullptr, nullptr, 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);