]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
auth: add authmon handling
authorYehuda Sadeh <yehuda@hq.newdream.net>
Thu, 17 Sep 2009 23:31:58 +0000 (16:31 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Thu, 17 Sep 2009 23:31:58 +0000 (16:31 -0700)
16 files changed:
src/Makefile.am
src/auth/Auth.h
src/auth/AuthProtocol.h
src/authtool.cc [new file with mode: 0644]
src/ceph.cc
src/include/AuthLibrary.h [new file with mode: 0644]
src/include/ClassLibrary.h
src/messages/MAuthMon.h [new file with mode: 0644]
src/messages/MAuthMonAck.h [new file with mode: 0644]
src/mon/AuthMonitor.cc [new file with mode: 0644]
src/mon/AuthMonitor.h [new file with mode: 0644]
src/mon/ClassMonitor.cc
src/mon/Monitor.cc
src/mon/Monitor.h
src/mon/mon_types.h
src/msg/Message.h

index e8017b2f4f9bcf03406175d89d2c9e0aa6e459cb..3f07de4f9a3f39a1f2eed45eff7aca28c71da11b 100644 (file)
@@ -31,7 +31,9 @@ mkmonfs_SOURCES = mkmonfs.cc
 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
@@ -329,6 +331,7 @@ libmon_a_SOURCES = \
        mon/PGMonitor.cc \
        mon/LogMonitor.cc \
        mon/ClassMonitor.cc \
+       mon/AuthMonitor.cc \
        mon/Elector.cc \
        mon/MonitorStore.cc
 
@@ -717,7 +720,7 @@ noinst_HEADERS = \
        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) \
index 8ae579304f1deb91ec678ddf22fbeb5fb23af10e..660c6ac40a8ed866fc951b5b505c6ef0109f5703 100644 (file)
@@ -16,6 +16,7 @@
 #define __AUTHTYPES_H
 
 #include "Crypto.h"
+#include "AuthProtocol.h"
 #include "msg/msg_types.h"
 
 class Cond;
@@ -39,6 +40,66 @@ struct EntityName {
     ::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);
 
index 25d60e52867030e398668d292b5c0bcb413d4066..2067d87dc055b270b5d868ce6466dd28683a241b 100644 (file)
@@ -176,6 +176,7 @@ WRITE_CLASS_ENCODER(CephXEnvRequest2);
 #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
 
diff --git a/src/authtool.cc b/src/authtool.cc
new file mode 100644 (file)
index 0000000..ab7592b
--- /dev/null
@@ -0,0 +1,69 @@
+// -*- 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;
+}
index f336a2a16a0cfaac8eb6adac30a8e61f2cb799c1..f2b3560e01e11098598383d91a4e9fe6618f40d6 100644 (file)
@@ -72,6 +72,7 @@ Context *resend_event = 0;
 #include "mds/MDSMap.h"
 #include "include/LogEntry.h"
 #include "include/ClassLibrary.h"
+#include "include/AuthLibrary.h"
 
 #include "mon/mon_types.h"
 
@@ -199,6 +200,28 @@ void handle_notify(MMonObserveNotify *notify)
       }
       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;
diff --git a/src/include/AuthLibrary.h b/src/include/AuthLibrary.h
new file mode 100644 (file)
index 0000000..a5123ed
--- /dev/null
@@ -0,0 +1,111 @@
+// -*- 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
index 4433fe78457d65fb644c9db999088de9f19b34c4..cfea207d51f4d705f85c06714c818194d1e0606b 100644 (file)
@@ -12,8 +12,8 @@
  * 
  */
 
-#ifndef __CLASSENTRY_H
-#define __CLASSENTRY_H
+#ifndef __CLASSLIBRARY_H
+#define __CLASSLIBRARY_H
 
 #include "include/types.h"
 #include "include/encoding.h"
@@ -56,10 +56,10 @@ struct ClassInfo {
 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 {
@@ -77,7 +77,7 @@ 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);
   }
diff --git a/src/messages/MAuthMon.h b/src/messages/MAuthMon.h
new file mode 100644 (file)
index 0000000..8d54b59
--- /dev/null
@@ -0,0 +1,88 @@
+// -*- 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
diff --git a/src/messages/MAuthMonAck.h b/src/messages/MAuthMonAck.h
new file mode 100644 (file)
index 0000000..6e38430
--- /dev/null
@@ -0,0 +1,51 @@
+// -*- 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
diff --git a/src/mon/AuthMonitor.cc b/src/mon/AuthMonitor.cc
new file mode 100644 (file)
index 0000000..1932519
--- /dev/null
@@ -0,0 +1,353 @@
+// -*- 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;
+}
diff --git a/src/mon/AuthMonitor.h b/src/mon/AuthMonitor.h
new file mode 100644 (file)
index 0000000..2517dda
--- /dev/null
@@ -0,0 +1,72 @@
+// -*- 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
index e092055498a975751ed8f8e1d958211a17759e0c..fda534b1d81473d9c4afa6e44d43f7d5d91e7ea0 100644 (file)
@@ -71,7 +71,7 @@ void ClassMonitor::create_initial(bufferlist& bl)
   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));
 }
 
@@ -124,17 +124,17 @@ bool ClassMonitor::update_from_paxos()
     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()) {
@@ -144,7 +144,7 @@ bool ClassMonitor::update_from_paxos()
         }
       }
       break;
-    case INC_NOP:
+    case CLASS_INC_NOP:
       break;
     default:
       assert(0);
@@ -332,7 +332,7 @@ bool ClassMonitor::prepare_command(MMonCommand *m)
       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";
@@ -362,7 +362,7 @@ bool ClassMonitor::prepare_command(MMonCommand *m)
       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));
 
@@ -388,7 +388,7 @@ bool ClassMonitor::prepare_command(MMonCommand *m)
       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";
index 57935c329327f34eab15093c5e0367e59db89792..b89253c1826e3ebd3fe55d44d9ac11a9416fa5d7 100644 (file)
@@ -49,6 +49,7 @@
 #include "PGMonitor.h"
 #include "LogMonitor.h"
 #include "ClassMonitor.h"
+#include "AuthMonitor.h"
 
 #include "osd/OSDMap.h"
 
@@ -93,6 +94,7 @@ Monitor::Monitor(int w, MonitorStore *s, Messenger *m, MonMap *map) :
   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)
@@ -270,7 +272,11 @@ void Monitor::handle_command(MMonCommand *m)
       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";
index 09d26ffd0b60d12c5617f6b1d5731b051d1f7cb1..bb9c9f5db452c48cd87d8823d2674c360ab2cf16 100644 (file)
@@ -118,6 +118,7 @@ public:
   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;
index 0bb6e71e80debf8ed70d21b8c55413239eda257d..9441bb5e28db727cd5856e07a15e6a7958600c6c 100644 (file)
@@ -21,7 +21,8 @@
 #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) {
@@ -31,6 +32,7 @@ inline const char *get_paxos_name(int 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;
   }
 }
index f33c1a75f9fc88e1826b638ac7dddf546014b437..d56234cbdd3e597320eec6928eacc2550cb1d8fe 100644 (file)
@@ -20,8 +20,8 @@
 #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
@@ -36,6 +36,9 @@
 #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