]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
renewal stuff coming together, mds handling stuff incomplete
authoranwleung <anwleung@29311d96-e01e-0410-9327-a35deaab8ce9>
Sun, 11 Mar 2007 23:40:32 +0000 (23:40 +0000)
committeranwleung <anwleung@29311d96-e01e-0410-9327-a35deaab8ce9>
Sun, 11 Mar 2007 23:40:32 +0000 (23:40 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1206 29311d96-e01e-0410-9327-a35deaab8ce9

branches/aleung/security1/ceph/client/Client.cc
branches/aleung/security1/ceph/client/Client.h
branches/aleung/security1/ceph/client/ClientCapCache.h
branches/aleung/security1/ceph/mds/MDS.h
branches/aleung/security1/ceph/mds/Server.cc
branches/aleung/security1/ceph/mds/Server.h
branches/aleung/security1/ceph/messages/MClientRenewal.h [new file with mode: 0644]
branches/aleung/security1/ceph/msg/Message.h

index df245125519f98e95ca8b79d09d7f0a5ce6102d4..96952e158ff185a357f88d33b878cb5eb48963d7 100644 (file)
@@ -128,7 +128,7 @@ Client::Client(Messenger *m, MonMap *mm)
   objecter = new Objecter(messenger, monmap, osdmap);
   objectcacher = new ObjectCacher(objecter, client_lock);
   filer = new Filer(objecter);
-  capcache = new ClientCapCache(client_lock);
+  capcache = new ClientCapCache(messenger, mdsmap, client_lock);
 }
 
 
index b99cba3510a7a2e87504581f39b01cb886a8f06c..0c81778afb641fbf6e934e98189234f95e7e9038 100644 (file)
@@ -31,6 +31,8 @@
 #include "messages/MOSDUpdateReply.h"
 #include "messages/MClientUpdate.h"
 #include "messages/MClientUpdateReply.h"
+#include "messages/MClientRenewal.h"
+#include "messages/MClientRenewalReply.h"
 
 //#include "msgthread.h"
 
index 62ed82223d1f91861218847a45da17490b6cc330..34a382be83d13ecddf1b4cab96be1318e04fb1ec 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "common/Cond.h"
 #include "common/Thread.h"
+#include "mds/MDSMap.h"
 
 class ClientCapCache {
  public:
@@ -30,33 +31,90 @@ class ClientCapCache {
   void close_cap(uid_t user, cap_id_t cid) {
     caps_in_use[user].erase(cid);
   }
+  bool is_open(cap_id_t cid) {
+    for (map<uid_t, set<cap_id_t> >::iterator mi = caps_in_use.begin();
+        mi != caps_in_use.end();
+        mi++) {
+      if (mi->second.count(cid) != 0)
+       return true;
+    }
+    return false;
+  }
   ExtCap *get_cache_cap(inodeno_t ino, uid_t user) {
     if (inode_user_cap_cache[ino].count(user) == 0)
       return 0;
     return &(inode_user_cap_cache[ino][user]);
   }
 
-  ClientCapCache (Mutex& l) : lock(l), cleaner_stop(false),
-  cleaner_thread(this) { cleaner_thread.create(); }
+  ClientCapCache (Messenger *m, MDSMap *mmap, Mutex& l) : messenger(m),
+                                                        mdsmap(mmap), lock(l),
+                                                        cleaner_stop(false),
+                                                        cleaner_thread(this),
+                                                        renewer_stop(false),
+                                                        renewer_thread(this)
+  {
+    cleaner_thread.create();
+    renewer_thread.create();
+  }
   ~ClientCapCache () {
     cleaner_stop = true;
     cleaner_cond.Signal();
     cleaner_thread.join();
+
+    renewer_stop = true;
+    renewer_cond.Signal();
+    renewer_thread.join();
   }
 
  private:
+  Messenger *messenger;
+  MDSMap *mdsmap;
   Mutex& lock;
   map<inodeno_t, map<uid_t, ExtCap> > inode_user_cap_cache;
   map<uid_t, set<cap_id_t> > caps_in_use;
   
   bool cleaner_stop;
   Cond cleaner_cond;
+  // expunge caps that are not in use, are expired and have no extension
   void cleaner_entry() {
     cout << "Cleaner start" << endl;
     lock.Lock();
+    /*
+    while (!cleaner_stop) {
+      cout << "Cleaner running" << endl;
+      while (!cleaner_stop) {
+       cout << "Cleaner cleaning" << endl;
+       utime_t cutoff = g_clock.now();
+       // clean all inodes
+       for (map<inodeno_t, map<uid_t, ExtCap> >::iterator mi = inode_user_cap_cache.begin();
+            mi != inode_user_cap_cache.end();
+            mi++)
+         // clean all users
+         for (map<uid_t, ExtCap>::iterator ui = mi->second.begin();
+              ui != mi->second.begin();
+              ui++) {
+           cap_id_t cid = ui->second.get_id();
+           // if not open
+           if (!(cc->is_open(cid))) {
+             // if past cutoff
+             if (ui->second.get_te() < cutoff) {
+               // if no extension
+               //if () {
+               //}
+               cout << "Found a cap to expunge" << endl;
+             }
+           }
+         }
+      }
+      if (cleaner_stop) break;
+      // clean every 8 minutes
+      cleaner_cond.WaitInterval(lock, utime_t(480,0));
+    }
+    */
     lock.Unlock();
     cout << "Cleaner finish" << endl;
   }
+
   class CleanerThread : public Thread {
     ClientCapCache *cc;
   public:
@@ -66,6 +124,50 @@ class ClientCapCache {
       return 0;
     }
   } cleaner_thread;
+  
+  bool renewer_stop;
+  Cond renewer_cond;
+  // renew caps that are in use (leaves a re-use grace period)
+  void renewer_entry() {
+    cout << "Renewer start" << endl;
+    lock.Lock();
+
+    while (!renewer_stop) {
+
+      cout << "Renewer running" << endl;
+      // renewal all open caps
+      MClientRenewal *renewal = new MClientRenewal();
+      for (map<uid_t, set<cap_id_t> >::iterator mi = caps_in_use.begin();
+          mi != caps_in_use.end();
+          mi++) {
+       renewal->add_cap_set(mi->second);
+      }
+      
+      // make asynchronous renewal request
+      // FIXME always send to mds 0
+      if (mdsmap)
+       messenger->send_message(renewal, mdsmap->get_inst(0), MDS_PORT_SERVER);
+      
+      if (renewer_stop) break;
+      // clean every 4 minutes
+      cout << "Renewer sleeping" << endl;
+      renewer_cond.WaitInterval(lock, utime_t(240,0));
+    }
+
+    lock.Unlock();
+    cout << "Renewer finish" << endl;
+  }
+
+  class RenewerThread : public Thread {
+    ClientCapCache *cc;
+  public:
+    RenewerThread(ClientCapCache *c) : cc(c) {}
+    void *entry() {
+      cc->renewer_entry();
+      return 0;
+    }
+  } renewer_thread;
+  
 };
 
 #endif
index 388cb9ce846ebb44209da6c5c6ea08fa06b58240..2354491a969c03a291fb260c7f1141b0103fcc4c 100644 (file)
@@ -161,6 +161,8 @@ public:
   map<gid_t, hash_t> unix_groups_map;
   // hash to group map
   map<hash_t, CapGroup> unix_groups_byhash;
+  // recent capabilities to renew
+  set<cap_id_t> recent_caps;
 
   void queue_waitfor_active(Context *c) { waitfor_active.push_back(c); }
 
index 630d9fc4f09eab255da006473c7a564708e85b0a..4c685454f8d9ec8cdc18fc88d79e01b1f58f4ae8 100644 (file)
@@ -81,6 +81,9 @@ void Server::dispatch(Message *m)
   case MSG_CLIENT_UPDATE:
     handle_client_update((MClientUpdate*)m);
     return;
+  case MSG_CLIENT_RENEWAL:
+    handle_client_renewal((MClientRenewal*)m);
+    return;
 
   case MSG_MDS_HASHREADDIR:
     handle_hash_readdir((MHashReaddir*)m);
@@ -267,6 +270,32 @@ void Server::handle_client_update(MClientUpdate *m)
   messenger->send_message(reply, m->get_source_inst());
 }
 
+// capability renewal request
+void Server::handle_client_renewal(MClientRenewal *m)
+{
+  bool new_caps = false;
+  set<cap_id_t> requested_caps = m->get_cap_set();  
+
+  // any new caps requested?
+  for (set<cap_id_t>::iterator si = requested_caps.begin();
+       si != requested_caps.end();
+       si++) {
+    // new cap renewal request
+    if (mds->recent_caps.count(*si) == 0) {
+      new_caps = true;
+      mds->recent_caps.insert(*si);
+    }
+  }
+
+  // if no new caps && cached extension, return cached extension
+  if (!new_caps) {
+  }
+    
+  // create extension for entire recent_cap set
+  // cache the extension
+  //
+}
+
 /***
  * process a client request
  */
index f8d2a23c2bf9d99b80d1e6618a188686e9446e5d..b7e025e4d4e76056db251cd94d514c52c33497f8 100644 (file)
@@ -17,6 +17,8 @@
 #include "MDS.h"
 #include "messages/MClientUpdate.h"
 #include "messages/MClientUpdateReply.h"
+#include "messages/MClientRenewal.h"
+#include "messages/MClientRenewalReply.h"
 
 class LogEvent;
 
@@ -68,6 +70,9 @@ public:
   // group updates
   void handle_client_update(MClientUpdate *m);
   
+  // renewal requests
+  void handle_client_renewal(MClientRenewal *m);
+  
   // fs ops
   void handle_client_fstat(MClientRequest *req);
 
diff --git a/branches/aleung/security1/ceph/messages/MClientRenewal.h b/branches/aleung/security1/ceph/messages/MClientRenewal.h
new file mode 100644 (file)
index 0000000..55df973
--- /dev/null
@@ -0,0 +1,47 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+/*
+ * 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 __MCLIENTRENEWAL_H
+#define __MCLIENTRENEWAL_H
+
+#include "msg/Message.h"
+
+class MClientRenewal : public Message {
+ private:
+  set<cap_id_t> caps_to_renew;
+ public:
+  MClientRenewal() : Message(MSG_CLIENT_RENEWAL) { }
+  void add_cap_set(set<cap_id_t>& capset) {
+    for (set<cap_id_t>::iterator si = capset.begin();
+        si != capset.end();
+        si++)
+      caps_to_renew.insert(*si);
+  }
+  set<cap_id_t>& get_cap_set() {
+    return caps_to_renew;
+  }
+
+  virtual void encode_payload() {
+    _encode(caps_to_renew, payload);
+  }
+  virtual void decode_payload() {
+    int off = 0;
+    _decode(caps_to_renew, payload, off);
+  }
+  virtual char *get_type_name() { return "client_renewal"; }
+  void print(ostream& out) {
+    out << "client_renewal_request()";
+  }
+};
+
+#endif
index eb79984c462e47244cb1458b9dc8ad0fe0afd10b..5724148f9531cd758cb9565d341c4363f20439fb 100644 (file)
@@ -84,6 +84,7 @@
 #define MSG_CLIENT_INODEAUTHUPDATE 64
 #define MSG_CLIENT_UPDATE          65
 #define MSG_CLIENT_UPDATE_REPLY    66
+#define MSG_CLIENT_RENEWAL         67
 
 #define MSG_CLIENT_BOOT            70
 #define MSG_CLIENT_MOUNT           71