mkmonfs_LDADD = libmon.a libcrush.a libcommon.a -lcrypto
cconf_SOURCES = cconf.cc
cconf_LDADD = libcommon.a -lcrypto
-bin_PROGRAMS += ceph mkmonfs cconf
+authtool_SOURCES = authtool.cc
+authtool_LDADD = libcommon.a -lcrypto
+bin_PROGRAMS += ceph mkmonfs cconf authtool
monmaptool_SOURCES = monmaptool.cc
monmaptool_LDADD = libcommon.a -lcrypto
mon/PGMonitor.cc \
mon/LogMonitor.cc \
mon/ClassMonitor.cc \
+ mon/AuthMonitor.cc \
mon/Elector.cc \
mon/MonitorStore.cc
radosgw/rgw_user.h\
sample.ceph.conf
-all_sources = $(cmon_SOURCES) $(ceph_SOURCES) $(mkmonfs_SOURCES) $(monmaptool_SOURCES) \
+all_sources = $(cmon_SOURCES) $(ceph_SOURCES) $(mkmonfs_SOURCES) $(authtool_SOURCES) $(monmaptool_SOURCES) \
$(crushtool_SOURCES) $(osdmaptool_SOURCES) $(cconf_SOURCES) $(mount_ceph_SOURCES) $(cmds_SOURCES) \
$(dumpjournal_SOURCES) $(cosd_SOURCES) $(dupstore_SOURCES) $(streamtest_SOURCES) $(csyn_SOURCES) \
$(testmsgr_SOURCES) $(cfuse_SOURCES) $(fakefuse_SOURCES) $(psim_SOURCES) \
#define __AUTHTYPES_H
#include "Crypto.h"
+#include "AuthProtocol.h"
#include "msg/msg_types.h"
class Cond;
::decode(entity_type, bl);
::decode(name, bl);
}
+
+ void to_str(string& str) const {
+ switch (entity_type) {
+ case CEPHX_PRINCIPAL_AUTH:
+ str = "auth";
+ break;
+ case CEPHX_PRINCIPAL_MON:
+ str = "mon";
+ break;
+ case CEPHX_PRINCIPAL_OSD:
+ str = "osd";
+ break;
+ case CEPHX_PRINCIPAL_MDS:
+ str = "mds";
+ break;
+ case CEPHX_PRINCIPAL_CLIENT:
+ str = "client";
+ break;
+ default:
+ str = "???";
+ break;
+ }
+ str.append(".");
+ str.append(name);
+ }
+ string to_str() const {
+ string s;
+ to_str(s);
+ return s;
+ }
+
+ bool from_str(string& s) {
+ int pos = s.find('.');
+
+ if (pos < 0)
+ return false;
+ if (pos >= (int)s.size())
+ return false;
+
+ string pre = s.substr(0, pos);
+ const char *pres = pre.c_str();
+
+ if (strcmp(pres, "auth") == 0) {
+ entity_type = CEPHX_PRINCIPAL_AUTH;
+ } else if (strcmp(pres, "mon") == 0) {
+ entity_type = CEPHX_PRINCIPAL_MON;
+ } else if (strcmp(pres, "osd") == 0) {
+ entity_type = CEPHX_PRINCIPAL_OSD;
+ } else if (strcmp(pres, "mds") == 0) {
+ entity_type = CEPHX_PRINCIPAL_MDS;
+ } else if (strcmp(pres, "client") == 0) {
+ entity_type = CEPHX_PRINCIPAL_CLIENT;
+ } else {
+ return false;
+ }
+
+ name = s.substr(pos);
+
+ return true;
+ }
};
WRITE_CLASS_ENCODER(EntityName);
#define CEPHX_PRINCIPAL_MON 0x0002
#define CEPHX_PRINCIPAL_OSD 0x0004
#define CEPHX_PRINCIPAL_MDS 0x0008
+#define CEPHX_PRINCIPAL_CLIENT 0x0010
#define CEPHX_PRINCIPAL_TYPE_MASK 0x00FF
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2009 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+using namespace std;
+
+#include "config.h"
+
+#include "common/common_init.h"
+#include "auth/Crypto.h"
+
+void usage()
+{
+ cout << " usage: [--gen-key] <filename>" << std::endl;
+ exit(1);
+}
+
+
+
+
+int main(int argc, const char **argv)
+{
+ vector<const char*> args;
+ argv_to_vec(argc, argv, args);
+ env_to_vec(args);
+ DEFINE_CONF_VARS(usage);
+ common_init(args, "osdmaptool", false);
+
+ const char *me = argv[0];
+
+ const char *fn = 0;
+ bool gen_key = false;
+
+ FOR_EACH_ARG(args) {
+ if (CONF_ARG_EQ("gen-key", 'g')) {
+ CONF_SAFE_SET_ARG_VAL(&gen_key, OPT_BOOL);
+ } else if (!fn) {
+ fn = args[i];
+ } else
+ usage();
+ }
+ if (!fn) {
+ cerr << me << ": must specify filename" << std::endl;
+ usage();
+ }
+
+ CryptoKey key;
+ key.create(CEPH_SECRET_AES);
+
+ bufferlist bl;
+ ::encode(key, bl);
+ int r = bl.write_file(fn);
+
+ if (r < 0) {
+ cerr << "could not write " << fn << std::endl;
+ }
+
+ return 0;
+}
#include "mds/MDSMap.h"
#include "include/LogEntry.h"
#include "include/ClassLibrary.h"
+#include "include/AuthLibrary.h"
#include "mon/mon_types.h"
}
break;
}
+
+ case PAXOS_AUTH:
+ {
+ bufferlist::iterator p = notify->bl.begin();
+ if (notify->is_latest) {
+ AuthLibrary list;
+ ::decode(list, p);
+ // show the first class info
+ map<EntityName, AuthLibEntry>::iterator mapiter = list.library_map.begin();
+ if (mapiter != list.library_map.end()) {
+ dout(0) << " auth " << mapiter->first.to_str() << dendl;
+ }
+ } else {
+ AuthLibEntry entry;
+
+ while (!p.end()) {
+ entry.decode(p);
+ dout(0) << " auth " << entry.name.to_str() << dendl;
+ }
+ }
+ break;
+ }
}
map_ver[notify->machine_id] = notify->ver;
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef __AUTHLIBRARY_H
+#define __AUTHLIBRARY_H
+
+#include "include/types.h"
+#include "include/encoding.h"
+#include "auth/Auth.h"
+
+struct AuthLibEntry {
+ EntityName name;
+ CryptoKey secret;
+
+ void encode(bufferlist& bl) const {
+ ::encode(name, bl);
+ ::encode(secret, bl);
+ }
+ void decode(bufferlist::iterator& bl) {
+ ::decode(name, bl);
+ ::decode(secret, bl);
+ }
+};
+WRITE_CLASS_ENCODER(AuthLibEntry)
+
+typedef enum {
+ AUTH_INC_NOP,
+ AUTH_INC_ADD,
+ AUTH_INC_DEL,
+ AUTH_INC_ACTIVATE,
+} AuthLibIncOp;
+
+struct AuthLibIncremental {
+ AuthLibIncOp op;
+ bufferlist info;
+
+ void encode(bufferlist& bl) const {
+ __u32 _op = (__u32)op;
+ ::encode(_op, bl);
+ ::encode(info, bl);
+ }
+ void decode(bufferlist::iterator& bl) {
+ __u32 _op;
+ ::decode(_op, bl);
+ op = (AuthLibIncOp)_op;
+ assert( op >= AUTH_INC_NOP && op <= AUTH_INC_ACTIVATE);
+ ::decode(info, bl);
+ }
+
+ void decode_entry(AuthLibEntry& e) {
+ bufferlist::iterator iter = info.begin();
+ ::decode(e, iter);
+ }
+};
+WRITE_CLASS_ENCODER(AuthLibIncremental)
+
+struct AuthLibrary {
+ version_t version;
+ map<EntityName, AuthLibEntry> library_map;
+
+ AuthLibrary() : version(0) {}
+
+ void add(const EntityName& name, CryptoKey& secret) {
+ AuthLibEntry entry;
+ entry.name = name;
+ entry.secret = secret;
+ add(entry);
+ }
+
+ void add(AuthLibEntry& entry) {
+ library_map[entry.name] = entry;
+ }
+
+ void remove(const EntityName& name) {
+ map<EntityName, AuthLibEntry>::iterator mapiter = library_map.find(name);
+ if (mapiter == library_map.end())
+ return;
+ library_map.erase(mapiter);
+ }
+
+ bool contains(EntityName& name) {
+ return (library_map.find(name) != library_map.end());
+ }
+ void encode(bufferlist& bl) const {
+ ::encode(version, bl);
+ ::encode(library_map, bl);
+ }
+ void decode(bufferlist::iterator& bl) {
+ ::decode(version, bl);
+ ::decode(library_map, bl);
+ }
+};
+WRITE_CLASS_ENCODER(AuthLibrary)
+
+inline ostream& operator<<(ostream& out, const AuthLibEntry& e)
+{
+ return out << e.name.to_str();
+}
+
+#endif
*
*/
-#ifndef __CLASSENTRY_H
-#define __CLASSENTRY_H
+#ifndef __CLASSLIBRARY_H
+#define __CLASSLIBRARY_H
#include "include/types.h"
#include "include/encoding.h"
WRITE_CLASS_ENCODER(ClassInfo)
typedef enum {
- INC_NOP,
- INC_ADD,
- INC_DEL,
- INC_ACTIVATE,
+ CLASS_INC_NOP,
+ CLASS_INC_ADD,
+ CLASS_INC_DEL,
+ CLASS_INC_ACTIVATE,
} ClassLibraryIncOp;
struct ClassLibraryIncremental {
__u32 _op;
::decode(_op, bl);
op = (ClassLibraryIncOp)_op;
- assert( op >= INC_NOP && op <= INC_ACTIVATE);
+ assert( op >= CLASS_INC_NOP && op <= CLASS_INC_ACTIVATE);
::decode(info, bl);
::decode(impl, bl);
}
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef __MAUTH_H
+#define __MAUTH_H
+
+#include "include/AuthLibrary.h"
+#include "messages/PaxosServiceMessage.h"
+
+enum {
+ AUTH_NOOP = 0,
+ AUTH_GET,
+ AUTH_SET,
+ AUTH_RESPONSE,
+};
+
+class MAuthMon : public PaxosServiceMessage {
+public:
+ ceph_fsid_t fsid;
+ deque<AuthLibEntry> info;
+ deque<bool> add;
+ version_t last;
+ __s32 action;
+
+
+ MAuthMon() : PaxosServiceMessage(MSG_AUTHMON, 0) {}
+ MAuthMon(const ceph_fsid_t& f, version_t l) : PaxosServiceMessage(MSG_AUTHMON, 0), fsid(f), last(l) {}
+ MAuthMon(const ceph_fsid_t& f, version_t l, version_t paxos_version) :
+ PaxosServiceMessage(MSG_AUTHMON, paxos_version), fsid(f), last(l) {}
+
+ const char *get_type_name() { return "class"; }
+ void print(ostream& out) {
+ out << "class(";
+ switch (action) {
+ case AUTH_NOOP:
+ out << "NOOP, ";
+ break;
+ case AUTH_GET:
+ out << "GET, ";
+ break;
+ case AUTH_SET:
+ out << "SET, ";
+ break;
+ case AUTH_RESPONSE:
+ out << "SET, ";
+ break;
+ default:
+ out << "Unknown op, ";
+ break;
+ }
+ if (info.size())
+ out << info.size() << " entries";
+ if (last)
+ out << "last " << last;
+ out << ")";
+ }
+
+ void encode_payload() {
+ paxos_encode();
+ ::encode(fsid, payload);
+ ::encode(info, payload);
+ ::encode(add, payload);
+ ::encode(last, payload);
+ ::encode(action, payload);
+ }
+ void decode_payload() {
+ bufferlist::iterator p = payload.begin();
+ paxos_decode(p);
+ ::decode(fsid, p);
+ ::decode(info, p);
+ ::decode(add, p);
+ ::decode(last, p);
+ ::decode(action, p);
+ }
+};
+
+#endif
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef __MAUTHMONACK_H
+#define __MHAUTHMONACK_H
+
+#include "include/AuthLibrary.h"
+
+class MAuthMonAck : public PaxosServiceMessage {
+public:
+ ceph_fsid_t fsid;
+ version_t last;
+
+ MAuthMonAck() : PaxosServiceMessage(MSG_AUTHMON_ACK, 0) {}
+ MAuthMonAck(ceph_fsid_t& f, version_t l) : PaxosServiceMessage(MSG_AUTHMON_ACK, 0),
+ fsid(f), last(l) {}
+
+ MAuthMonAck(ceph_fsid_t& f, version_t l, version_t paxos_version) :
+ PaxosServiceMessage(MSG_AUTHMON_ACK, paxos_version), fsid(f), last(l) {}
+
+
+ const char *get_type_name() { return "auth_mon_ack"; }
+ void print(ostream& out) {
+ out << "auth_mon(last " << last << ")";
+ }
+
+ void encode_payload() {
+ paxos_encode();
+ ::encode(fsid, payload);
+ ::encode(last, payload);
+ }
+ void decode_payload() {
+ bufferlist::iterator p = payload.begin();
+ paxos_decode(p);
+ ::decode(fsid, p);
+ ::decode(last, p);
+ }
+};
+
+#endif
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+
+#include "AuthMonitor.h"
+#include "Monitor.h"
+#include "MonitorStore.h"
+
+#include "messages/MMonCommand.h"
+#include "messages/MAuthMon.h"
+#include "messages/MAuthMonAck.h"
+
+#include "include/AuthLibrary.h"
+#include "common/Timer.h"
+
+#include "osd/osd_types.h"
+#include "osd/PG.h" // yuck
+
+#include "config.h"
+#include <sstream>
+
+#define DOUT_SUBSYS mon
+#undef dout_prefix
+#define dout_prefix _prefix(mon, paxos->get_version())
+static ostream& _prefix(Monitor *mon, version_t v) {
+ return *_dout << dbeginl
+ << "mon" << mon->whoami
+ << (mon->is_starting() ? (const char*)"(starting)":(mon->is_leader() ? (const char*)"(leader)":(mon->is_peon() ? (const char*)"(peon)":(const char*)"(?\?)")))
+ << ".class v" << v << " ";
+}
+
+ostream& operator<<(ostream& out, AuthMonitor& pm)
+{
+ std::stringstream ss;
+
+ return out << "auth";
+}
+
+/*
+ Tick function to update the map based on performance every N seconds
+*/
+
+void AuthMonitor::tick()
+{
+ if (!paxos->is_active()) return;
+
+ update_from_paxos();
+ dout(10) << *this << dendl;
+
+ if (!mon->is_leader()) return;
+
+}
+
+void AuthMonitor::create_initial(bufferlist& bl)
+{
+ dout(0) << "create_initial -- creating initial map" << dendl;
+ AuthLibEntry l;
+ AuthLibIncremental inc;
+ ::encode(l, inc.info);
+ inc.op = AUTH_INC_NOP;
+ pending_auth.push_back(inc);
+}
+
+bool AuthMonitor::store_entry(AuthLibEntry& entry)
+{
+ string entry_str;
+
+ entry.name.to_str(entry_str);
+
+
+ bufferlist bl;
+ ::encode(entry, bl);
+ mon->store->put_bl_ss(bl, "auth_lib", entry_str.c_str());
+ dout(0) << "adding name=" << entry_str << dendl;
+
+ return true;
+}
+
+
+bool AuthMonitor::update_from_paxos()
+{
+ version_t paxosv = paxos->get_version();
+ if (paxosv == list.version) return true;
+ assert(paxosv >= list.version);
+
+ bufferlist blog;
+
+ if (list.version == 0 && paxosv > 1) {
+ // startup: just load latest full map
+ bufferlist latest;
+ version_t v = paxos->get_latest(latest);
+ if (v) {
+ dout(7) << "update_from_paxos startup: loading summary e" << v << dendl;
+ bufferlist::iterator p = latest.begin();
+ ::decode(list, p);
+ }
+ }
+
+ // walk through incrementals
+ while (paxosv > list.version) {
+ bufferlist bl;
+ bool success = paxos->read(list.version+1, bl);
+ assert(success);
+
+ bufferlist::iterator p = bl.begin();
+ AuthLibIncremental inc;
+ ::decode(inc, p);
+ AuthLibEntry entry;
+ inc.decode_entry(entry);
+ switch (inc.op) {
+ case AUTH_INC_ADD:
+ list.add(entry);
+ break;
+ case AUTH_INC_DEL:
+ list.remove(entry.name);
+ break;
+ case AUTH_INC_NOP:
+ break;
+ default:
+ assert(0);
+ }
+
+ list.version++;
+ }
+
+ bufferlist bl;
+ ::encode(list, bl);
+ paxos->stash_latest(paxosv, bl);
+
+ return true;
+}
+
+void AuthMonitor::create_pending()
+{
+ pending_auth.clear();
+ pending_list = list;
+ dout(10) << "create_pending v " << (paxos->get_version() + 1) << dendl;
+}
+
+void AuthMonitor::encode_pending(bufferlist &bl)
+{
+ dout(10) << "encode_pending v " << (paxos->get_version() + 1) << dendl;
+ for (vector<AuthLibIncremental>::iterator p = pending_auth.begin();
+ p != pending_auth.end();
+ p++)
+ p->encode(bl);
+}
+
+bool AuthMonitor::preprocess_query(PaxosServiceMessage *m)
+{
+ dout(10) << "preprocess_query " << *m << " from " << m->get_orig_source_inst() << dendl;
+ switch (m->get_type()) {
+ case MSG_MON_COMMAND:
+ return preprocess_command((MMonCommand*)m);
+
+ case MSG_AUTHMON:
+ return preprocess_auth((MAuthMon*)m);
+
+ default:
+ assert(0);
+ delete m;
+ return true;
+ }
+}
+
+bool AuthMonitor::prepare_update(PaxosServiceMessage *m)
+{
+ dout(10) << "prepare_update " << *m << " from " << m->get_orig_source_inst() << dendl;
+ switch (m->get_type()) {
+ case MSG_MON_COMMAND:
+ return prepare_command((MMonCommand*)m);
+ case MSG_AUTHMON:
+ return prepare_auth((MAuthMon*)m);
+ default:
+ assert(0);
+ delete m;
+ return false;
+ }
+}
+
+void AuthMonitor::committed()
+{
+
+}
+
+bool AuthMonitor::preprocess_auth(MAuthMon *m)
+{
+ dout(10) << "preprocess_auth " << *m << " from " << m->get_orig_source() << dendl;
+
+ int num_new = 0;
+ for (deque<AuthLibEntry>::iterator p = m->info.begin();
+ p != m->info.end();
+ p++) {
+ if (!pending_list.contains((*p).name))
+ num_new++;
+ }
+ if (!num_new) {
+ dout(10) << " nothing new" << dendl;
+ return true;
+ }
+ return false;
+}
+
+bool AuthMonitor::prepare_auth(MAuthMon *m)
+{
+ dout(10) << "prepare_auth " << *m << " from " << m->get_orig_source() << dendl;
+
+ if (ceph_fsid_compare(&m->fsid, &mon->monmap->fsid)) {
+ dout(0) << "handle_auth on fsid " << m->fsid << " != " << mon->monmap->fsid << dendl;
+ delete m;
+ return false;
+ }
+ for (deque<AuthLibEntry>::iterator p = m->info.begin();
+ p != m->info.end(); p++) {
+ dout(10) << " writing auth " << *p << dendl;
+ if (!pending_list.contains((*p).name)) {
+ AuthLibIncremental inc;
+ ::encode(*p, inc.info);
+ pending_list.add(*p);
+ pending_auth.push_back(inc);
+ }
+ }
+
+ paxos->wait_for_commit(new C_Auth(this, m, m->get_orig_source_inst()));
+ return true;
+}
+
+void AuthMonitor::_updated_auth(MAuthMon *m, entity_inst_t who)
+{
+ dout(7) << "_updated_auth for " << who << dendl;
+ mon->messenger->send_message(new MAuthMonAck(m->fsid, m->last), who);
+ delete m;
+}
+
+void AuthMonitor::auth_usage(stringstream& ss)
+{
+ ss << "error: usage:" << std::endl;
+ ss << " auth <add | del> <name> <--in-file=filename>" << std::endl;
+ ss << " auth <list>" << std::endl;
+}
+
+bool AuthMonitor::preprocess_command(MMonCommand *m)
+{
+ int r = -1;
+ bufferlist rdata;
+ stringstream ss;
+
+ if (m->cmd.size() > 1) {
+ if (m->cmd[1] == "add" ||
+ m->cmd[1] == "del" ||
+ m->cmd[1] == "activate" ||
+ m->cmd[1] == "list") {
+ return false;
+ }
+ }
+
+ auth_usage(ss);
+ r = -EINVAL;
+
+ string rs;
+ getline(ss, rs, '\0');
+ mon->reply_command(m, r, rs, rdata, paxos->get_version());
+ return true;
+}
+
+
+bool AuthMonitor::prepare_command(MMonCommand *m)
+{
+ stringstream ss;
+ string rs;
+ int err = -EINVAL;
+
+ // nothing here yet
+ if (m->cmd.size() > 1) {
+ if (m->cmd[1] == "add" && m->cmd.size() >= 3) {
+ string entity_name = m->cmd[2];
+
+ AuthLibEntry entry;
+ entry.name.from_str(entity_name);
+
+ bufferlist bl = m->get_data();
+ bufferlist::iterator iter = bl.begin();
+ ::decode(entry.secret, iter);
+
+ AuthLibIncremental inc;
+ dout(0) << "storing auth for " << entity_name << dendl;
+ ::encode(entry, inc.info);
+ inc.op = AUTH_INC_ADD;
+ pending_list.add(entry);
+ pending_auth.push_back(inc);
+ ss << "updated";
+ getline(ss, rs);
+ paxos->wait_for_commit(new Monitor::C_Command(mon, m, 0, rs, paxos->get_version()));
+ return true;
+ } else if (m->cmd[1] == "del" && m->cmd.size() >= 5) {
+ string name = m->cmd[2];
+ AuthLibEntry entry;
+ entry.name.from_str(name);
+ map<EntityName, AuthLibEntry>::iterator iter = list.library_map.find(entry.name);
+ if (iter == list.library_map.end()) {
+ ss << "couldn't find entry " << name;
+ rs = -ENOENT;
+ goto done;
+ }
+ AuthLibIncremental inc;
+ ::encode(entry, inc.info);
+ inc.op = AUTH_INC_DEL;
+ pending_list.add(entry);
+ pending_auth.push_back(inc);
+
+ ss << "updated";
+ getline(ss, rs);
+ paxos->wait_for_commit(new Monitor::C_Command(mon, m, 0, rs, paxos->get_version()));
+ return true;
+ } else if (m->cmd[1] == "list") {
+ map<EntityName, AuthLibEntry>::iterator mapiter = list.library_map.begin();
+ if (mapiter != list.library_map.end()) {
+ ss << "installed auth entries: " << std::endl;
+
+ while (mapiter != list.library_map.end()) {
+ AuthLibEntry& entry = mapiter->second;
+ ss << entry.name.to_str() << std::endl;
+
+ ++mapiter;
+ }
+ } else {
+ ss << "no installed auth entries!";
+ }
+ err = 0;
+ goto done;
+ } else {
+ auth_usage(ss);
+ }
+ } else {
+ auth_usage(ss);
+ }
+
+done:
+ getline(ss, rs, '\0');
+ mon->reply_command(m, err, rs, paxos->get_version());
+ return false;
+}
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef __AUTHMONITOR_H
+#define __AUTHMONITOR_H
+
+#include <map>
+#include <set>
+using namespace std;
+
+#include "include/types.h"
+#include "msg/Messenger.h"
+#include "PaxosService.h"
+#include "mon/Monitor.h"
+
+#include "include/AuthLibrary.h"
+
+class MMonCommand;
+class MAuthMon;
+
+class AuthMonitor : public PaxosService {
+ void auth_usage(stringstream& ss);
+private:
+ vector<AuthLibIncremental> pending_auth;
+ AuthLibrary pending_list, list;
+
+ void create_initial(bufferlist& bl);
+ bool update_from_paxos();
+ void create_pending(); // prepare a new pending
+ void encode_pending(bufferlist &bl); // propose pending update to peers
+
+ void committed();
+
+ bool preprocess_query(PaxosServiceMessage *m); // true if processed.
+ bool prepare_update(PaxosServiceMessage *m);
+
+ bool preprocess_auth(MAuthMon *m);
+ bool prepare_auth(MAuthMon *m);
+ void _updated_auth(MAuthMon *m, entity_inst_t who);
+
+ struct C_Auth : public Context {
+ AuthMonitor *authmon;
+ MAuthMon *ack;
+ entity_inst_t who;
+ C_Auth(AuthMonitor *p, MAuthMon *a, entity_inst_t w) : authmon(p), ack(a), who(w) {}
+ void finish(int r) {
+ authmon->_updated_auth(ack, who);
+ }
+ };
+
+ bool preprocess_command(MMonCommand *m);
+ bool prepare_command(MMonCommand *m);
+ bool store_entry(AuthLibEntry& entry);
+ public:
+ AuthMonitor(Monitor *mn, Paxos *p) : PaxosService(mn, p) { }
+ void handle_request(MAuthMon *m);
+
+ void tick(); // check state, take actions
+};
+
+#endif
ClassLibraryIncremental inc;
::encode(i, inc.impl);
::encode(l, inc.info);
- inc.op = INC_NOP;
+ inc.op = CLASS_INC_NOP;
pending_class.insert(pair<utime_t,ClassLibraryIncremental>(i.stamp, inc));
}
ClassInfo info;
inc.decode_info(info);
switch (inc.op) {
- case INC_ADD:
+ case CLASS_INC_ADD:
inc.decode_impl(impl);
if (impl.binary.length() > 0) {
store_impl(info, impl);
list.add(info.name, info.version);
}
break;
- case INC_DEL:
+ case CLASS_INC_DEL:
list.remove(info.name, info.version);
break;
- case INC_ACTIVATE:
+ case CLASS_INC_ACTIVATE:
{
map<string, ClassVersionMap>::iterator mapiter = list.library_map.find(info.name);
if (mapiter == list.library_map.end()) {
}
}
break;
- case INC_NOP:
+ case CLASS_INC_NOP:
break;
default:
assert(0);
dout(0) << "storing class " << name << " v" << info.version << dendl;
::encode(impl, inc.impl);
::encode(info, inc.info);
- inc.op = INC_ADD;
+ inc.op = CLASS_INC_ADD;
pending_list.add(info);
pending_class.insert(pair<utime_t,ClassLibraryIncremental>(impl.stamp, inc));
ss << "updated";
ClassImpl impl;
impl.stamp = g_clock.now();
::encode(*info, inc.info);
- inc.op = INC_DEL;
+ inc.op = CLASS_INC_DEL;
pending_list.add(*info);
pending_class.insert(pair<utime_t,ClassLibraryIncremental>(impl.stamp, inc));
ClassImpl impl;
impl.stamp = g_clock.now();
::encode(info, inc.info);
- inc.op = INC_ACTIVATE;
+ inc.op = CLASS_INC_ACTIVATE;
pending_list.add(info);
pending_class.insert(pair<utime_t,ClassLibraryIncremental>(impl.stamp, inc));
ss << "updated";
#include "PGMonitor.h"
#include "LogMonitor.h"
#include "ClassMonitor.h"
+#include "AuthMonitor.h"
#include "osd/OSDMap.h"
paxos_service[PAXOS_PGMAP] = new PGMonitor(this, add_paxos(PAXOS_PGMAP));
paxos_service[PAXOS_LOG] = new LogMonitor(this, add_paxos(PAXOS_LOG));
paxos_service[PAXOS_CLASS] = new ClassMonitor(this, add_paxos(PAXOS_CLASS));
+ paxos_service[PAXOS_AUTH] = new AuthMonitor(this, add_paxos(PAXOS_AUTH));
}
Paxos *Monitor::add_paxos(int type)
classmon()->dispatch(m);
return;
}
- if (m->cmd[0] == "mon") {
+ if (m->cmd[0] == "auth") {
+ authmon()->dispatch(m);
+ return;
+ }
+ if (m->cmd[0] == "mon") {
if (m->cmd[1] == "injectargs" && m->cmd.size() == 4) {
vector<string> args(2);
args[0] = "_injectargs";
class OSDMonitor *osdmon() { return (class OSDMonitor *)paxos_service[PAXOS_OSDMAP]; }
class ClientMonitor *clientmon() { return (class ClientMonitor *)paxos_service[PAXOS_CLIENTMAP]; }
class ClassMonitor *classmon() { return (class ClassMonitor *)paxos_service[PAXOS_CLASS]; }
+ class AuthMonitor *authmon() { return (class AuthMonitor *)paxos_service[PAXOS_AUTH]; }
friend class Paxos;
friend class OSDMonitor;
#define PAXOS_CLIENTMAP 3
#define PAXOS_LOG 4
#define PAXOS_CLASS 5
-#define PAXOS_NUM 6
+#define PAXOS_AUTH 6
+#define PAXOS_NUM 7
inline const char *get_paxos_name(int p) {
switch (p) {
case PAXOS_PGMAP: return "pgmap";
case PAXOS_LOG: return "logm";
case PAXOS_CLASS: return "class";
+ case PAXOS_AUTH: return "auth";
default: assert(0); return 0;
}
}
#include "config.h"
// monitor internal
-#define MSG_MON_ELECTION 60
-#define MSG_MON_PAXOS 61
+#define MSG_MON_ELECTION 65
+#define MSG_MON_PAXOS 66
/* monitor <-> mon admin tool */
#define MSG_MON_COMMAND 50
#define MSG_GETPOOLSTATS 58
#define MSG_GETPOOLSTATSREPLY 59
+#define MSG_AUTHMON 60
+#define MSG_AUTHMON_ACK 61
+
#define MSG_POOLOP 49
#define MSG_POOLOPREPLY 48