]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
auth: refactor interface with monclient
authorYehuda Sadeh <yehuda@hq.newdream.net>
Thu, 10 Sep 2009 21:20:49 +0000 (14:20 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Thu, 10 Sep 2009 21:20:49 +0000 (14:20 -0700)
src/auth/AuthClient.h [new file with mode: 0644]
src/auth/AuthClientHandler.cc
src/auth/AuthClientHandler.h
src/librados.cc
src/mon/MonClient.cc
src/mon/MonClient.h

diff --git a/src/auth/AuthClient.h b/src/auth/AuthClient.h
new file mode 100644 (file)
index 0000000..f39fbd9
--- /dev/null
@@ -0,0 +1,28 @@
+// -*- 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.
+ * 
+ */
+
+#ifndef __AUTHCLIENT_H
+#define __AUTHCLIENT_H
+
+
+class Message;
+
+class AuthClient {
+public:
+  virtual void send_message(Message *m) = 0;
+};
+
+
+#endif
+
index 66a6cdf0cbf441b3ef0afa22ffef11048c3ff4ec..e1b998137902b6a30ac9c9c73906e36085a8aa77 100644 (file)
 #include "AuthProtocol.h"
 #include "AuthClientHandler.h"
 
+#include "messages/MAuth.h"
 #include "messages/MAuthReply.h"
 
-#if 0
+
 int AuthClientHandler::generate_request(bufferlist& bl)
 {
   dout(0) << "status=" << status << dendl;
@@ -63,9 +64,13 @@ int AuthClientHandler::generate_request(bufferlist& bl)
 }
 
 
-int AuthClientHandler::handle_response(int ret, bufferlist& bl)
+int AuthClientHandler::handle_response(Message *response)
 {
-char buf[4096];
+  bufferlist bl;
+  int ret;
+
+#if 1
+      char buf[4096];
       const char *s = bl.c_str();
       int pos = 0;
       for (unsigned int i=0; i<bl.length() && pos<sizeof(buf) - 8; i++) {
@@ -76,14 +81,19 @@ char buf[4096];
           pos += snprintf(&buf[pos], sizeof(buf)-pos, "\n");
       }
       dout(0) << "result_buf=" << buf << dendl;
+#endif
 
+  MAuthReply* m = (MAuthReply *)response;
+  bl = m->result_bl;
+  ret = m->result;
+
+  got_response = true;
 
   bufferlist::iterator iter = bl.begin();
 
   if (ret != 0 && ret != -EAGAIN) {
     response_state = request_state;
     cephx_response_state = cephx_request_state;
-    status = ret;
     return ret;
   }
 
@@ -94,6 +104,7 @@ char buf[4096];
     { 
       CephXEnvResponse1 response;
 
+      response_state++;
       ::decode(response, iter);
       server_challenge = response.server_challenge;
     }
@@ -108,8 +119,7 @@ char buf[4096];
   default:
     return handle_cephx_protocol_response(iter);
   }
-  response_state++;
-  return  -EAGAIN;
+  return -EAGAIN;
 }
 
 int AuthClientHandler::generate_cephx_protocol_request(bufferlist& bl)
@@ -131,11 +141,11 @@ int AuthClientHandler::generate_cephx_protocol_request(bufferlist& bl)
     return 0;
   }
 
-  dout(0) << "want_keys=" << hex << want_keys << " have_keys=" << have_keys << dec << dendl;
+  dout(0) << "want=" << hex << want << " have=" << have << dec << dendl;
 
   cephx_request_state = 2;
 
-  if (want_keys == have_keys) {
+  if (want == have) {
     cephx_response_state = 2;
     return 0;
   }
@@ -143,7 +153,7 @@ int AuthClientHandler::generate_cephx_protocol_request(bufferlist& bl)
   header.request_type = CEPHX_GET_PRINCIPAL_SESSION_KEY;
 
   ::encode(header, bl);
-  build_service_ticket_request(name, addr, want_keys,
+  build_service_ticket_request(name, addr, want,
                              true, ticket_handler.session_key, ticket_handler.ticket, bl);
   
   return 0;
@@ -174,7 +184,7 @@ int AuthClientHandler::handle_cephx_protocol_response(bufferlist::iterator& inda
         return -EPERM;
       }
 
-      if (want_keys)
+      if (want)
         ret = -EAGAIN;
     }
     break;
@@ -211,31 +221,105 @@ bool AuthClientHandler::request_pending() {
   return (request_state != response_state) || (cephx_request_state != cephx_response_state);
 }
 
-#endif
 
 // -----------
 
-void AuthClientHandler::handle_auth_reply(MAuthReply *m)
+int AuthClientHandler::start_session(AuthClient *client, double timeout)
 {
   Mutex::Locker l(lock);
-  dout(10) << "handle_auth_reply " << *m << dendl;
+  this->client = client;
+  dout(10) << "start_session" << dendl;
+  _reset();
 
+  do {
+    status = 0;
+    int err = _do_request(timeout);
+    dout(0) << "_do_request returned " << err << dendl;
+    if (err < 0)
+      return err;
+
+  } while (status == -EAGAIN);
+
+  return status;
 }
 
-void AuthClientHandler::start_session()
+void AuthClientHandler::tick()
 {
   Mutex::Locker l(lock);
-  dout(10) << "start_session" << dendl;
-  _reset();
 
+  // do i need to renew any tickets?
   // ...
+
 }
 
-void AuthClientHandler::tick()
+Message *AuthClientHandler::build_request()
+{
+  MAuth *msg = new MAuth;
+  if (!msg)
+    return NULL;
+  bufferlist& bl = msg->get_auth_payload();
+
+  if (generate_request(bl) < 0) {
+    delete msg;
+    return NULL;
+  }
+
+  return msg;
+}
+
+int AuthClientHandler::_do_request(double timeout)
+{
+  Message *msg = build_request();
+
+  if (!msg)
+    return -EIO;
+
+  got_response = false;
+  client->send_message(msg);
+
+  // schedule timeout?
+  assert(timeout_event == 0);
+  timeout_event = new C_OpTimeout(this, timeout);
+  timer.add_event_after(timeout, timeout_event);
+
+  Cond request_cond;
+
+  cur_request_cond = &request_cond;
+
+  dout(0) << "got_response=" << got_response << " got_timeout=" << got_timeout << dendl;
+
+  while (!got_response && !got_timeout) {
+    request_cond.Wait(lock);
+  }
+
+  cur_request_cond = NULL;
+
+  // finish.
+  timer.cancel_event(timeout_event);
+  timeout_event = 0;
+
+  return 0;
+}
+
+void AuthClientHandler::_request_timeout(double timeout)
 {
   Mutex::Locker l(lock);
+  dout(10) << "_op_timeout" << dendl;
+  timeout_event = 0;
+  if (!got_response) {
+    got_timeout = 1;
+    assert(cur_request_cond);
+    cur_request_cond->Signal();
+  }
+  status = -ETIMEDOUT;
+}
 
-  // do i need to renew any tickets?
-  // ...
+void AuthClientHandler::handle_auth_reply(MAuthReply *m)
+{
+  Mutex::Locker l(lock);
 
+  status = handle_response(m);
+  cur_request_cond->Signal();
 }
+
index 85cd9f58b1990fd1ae610181d2009a7417b40ae5..f705fe6cf4faf435391921716c4f087fc1fc9cf2 100644 (file)
 
 
 #include "auth/Auth.h"
+#include "auth/AuthClient.h"
 
 #include "common/Mutex.h"
 #include "common/Cond.h"
 
+#include "common/Timer.h"
+
 class MAuthReply;
+class Message;
+class AuthClient;
 
 class AuthClientHandler {
   Mutex lock;
-  Cond cond;
+  Cond keys_cond;
+  Cond *cur_request_cond;
+  Context *timeout_event;
 
   uint32_t want;
   uint32_t have;
@@ -39,6 +46,9 @@ class AuthClientHandler {
   int cephx_request_state;
   int cephx_response_state;
 
+  bool got_response;
+  bool got_timeout;
+
   EntityName name;
   entity_addr_t addr;
 
@@ -51,6 +61,13 @@ class AuthClientHandler {
 
   CryptoKey secret;
 
+  AuthClient *client;
+
+  bool request_pending();
+  Message *build_request();
+
+  int generate_request(bufferlist& bl);
+  int handle_response(Message *response);
   int generate_cephx_protocol_request(bufferlist& bl);
   int handle_cephx_protocol_response(bufferlist::iterator& indata);
 
@@ -60,12 +77,33 @@ class AuthClientHandler {
     status = 0;
     cephx_request_state = 0;
     cephx_response_state = 0;
+    got_response = false;
+    got_timeout = false;
+    timeout_event = NULL;
+    cur_request_cond = NULL;
   }
 
+  SafeTimer timer;
+
+ class C_OpTimeout : public Context {
+  protected:
+    AuthClientHandler *client_handler;
+    double timeout;
+  public:
+    C_OpTimeout(AuthClientHandler *handler, double to) :
+                                        client_handler(handler), timeout(to) {
+    }
+    void finish(int r) {
+      if (r >= 0) client_handler->_request_timeout(timeout);
+    }
+  };
+
+  void _request_timeout(double timeout);
+  int _do_request(double timeout);
 
 public:
   AuthClientHandler() : lock("AuthClientHandler::lock"),
-                       want(0), have(0) {
+                       want(0), have(0), client(NULL), timer(lock) {
     _reset();
   }
   
@@ -86,11 +124,11 @@ public:
     utime_t t;
     t += timeout;
     while ((want & have) != have)
-      cond.WaitInterval(lock, t);
+      keys_cond.WaitInterval(lock, t);
     return (want & have) == have;
   }
 
-  void start_session();
+  int start_session(AuthClient *client, double timeout);
   void handle_auth_reply(MAuthReply *m);
   void tick();
 };
index ea7e814c6ab288fb822d84fbbbce210b5159e9df..a6fe3e879118d72fadfbdec378860fde9dec5d07 100644 (file)
@@ -304,9 +304,9 @@ bool RadosClient::init()
 
   monclient.init();
   monclient.mount(g_conf.client_mount_timeout);
-
   dout(0) << "librados: before monclient.authorize()" << dendl;
   monclient.auth.set_want_keys(CEPHX_PRINCIPAL_MON | CEPHX_PRINCIPAL_OSD);
+  monclient.authorize(g_conf.client_mount_timeout);
 
   lock.Lock();
 
index 3717f0f0691b36e5ad49ca33f9a8b855b1592e2a..b76df515bb937dd399f7b2770997ff3f1f981538 100644 (file)
@@ -261,6 +261,14 @@ void MonClient::handle_mount_ack(MClientMountAck* m)
   delete m;
 }
 
+int MonClient::authorize(double timeout)
+{
+  Mutex::Locker lock(monc_lock);
+
+  auth_timeout = timeout;
+
+  return auth.start_session(this, timeout);
+}
 
 // ---------
 
@@ -270,6 +278,11 @@ void MonClient::_send_mon_message(Message *m)
   messenger->send_message(m, monmap.mon_inst[mon]);
 }
 
+void MonClient::send_message(Message *m)
+{
+  _send_mon_message(m);
+}
+
 void MonClient::_pick_new_mon()
 {
   int oldmon = monmap.pick_mon();
@@ -287,7 +300,7 @@ void MonClient::ms_handle_reset(const entity_addr_t& peer)
     if (mounting)
       _send_mount();
     _renew_subs();
-    auth.start_session();
+    auth.start_session(this, 30.0);
   }
 }
 
@@ -302,7 +315,7 @@ void MonClient::tick()
     if (mounting)
       _send_mount();
     _renew_subs();
-    auth.start_session();
+    auth.start_session(this, 30.0);
   } else {
     // just renew as needed
     utime_t now = g_clock.now();
index df73f4ccf02f01494278e8f176cf4003b5871494..8afe46dd27b2efb11b5bf43b2309030e1a41f24e 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "common/Timer.h"
 
+#include "auth/AuthClient.h"
 #include "auth/AuthClientHandler.h"
 
 #include "messages/MMonSubscribe.h"
@@ -31,7 +32,7 @@ class MMonMap;
 class MClientMountAck;
 class MMonSubscribeAck;
 
-class MonClient : public Dispatcher {
+class MonClient : public Dispatcher, public AuthClient {
 public:
   MonMap monmap;
 private:
@@ -76,7 +77,7 @@ private:
 
 public:
   int mount(double mount_timeout);
-
+  int authorize(double timeout);
 
   // mon subscriptions
 private:
@@ -118,6 +119,7 @@ public:
   // auth tickets
 public:
   AuthClientHandler auth;
+  double auth_timeout;
 
  public:
   MonClient() : messenger(NULL),
@@ -173,6 +175,7 @@ public:
 
   void set_messenger(Messenger *m) { messenger = m; }
 
+  void send_message(Message *m);
 };
 
 #endif