]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: pave way for more per-client mount info in monitor
authorSage Weil <sage@newdream.net>
Thu, 13 Nov 2008 18:56:30 +0000 (10:56 -0800)
committerSage Weil <sage@newdream.net>
Thu, 13 Nov 2008 20:45:37 +0000 (12:45 -0800)
Eventually we'll need some security stuff in here

src/mon/ClientMonitor.cc
src/mon/ClientMonitor.h

index 9fd0487433934a2bb83ab1c9279c7fef5ee0fb29..92f6dad238e9555caedc4986db0208c8bc2c3b19 100644 (file)
@@ -43,7 +43,7 @@ static ostream& _prefix(Monitor *mon, ClientMonitor::Map& client_map) {
 ostream& operator<<(ostream& out, ClientMonitor& om)
 {
   return out << "v" << om.client_map.version << ": "
-            << om.client_map.client_addr.size() << " clients, next is client" << om.client_map.next_client;
+            << om.client_map.client_info.size() << " clients, next is client" << om.client_map.next_client;
 }
 
 bool ClientMonitor::update_from_paxos()
@@ -80,7 +80,7 @@ bool ClientMonitor::update_from_paxos()
     inc.decode(p);
     client_map.apply_incremental(inc);
     
-    dout(1) << client_map.client_addr.size() << " clients (+" 
+    dout(1) << client_map.client_info.size() << " clients (+" 
            << inc.mount.size() << " -" << inc.unmount.size() << ")" 
            << dendl;
   }
@@ -149,7 +149,7 @@ bool ClientMonitor::preprocess_query(Message *m)
     {
       // already unmounted?
       int client = m->get_orig_source().num();
-      if (client_map.client_addr.count(client) == 0) {
+      if (client_map.client_info.count(client) == 0) {
        dout(7) << " client" << client << " not mounted" << dendl;
        _unmounted((MClientUnmount*)m);
        return true;
@@ -185,14 +185,17 @@ bool ClientMonitor::prepare_update(Message *m)
        dout(10) << "mount: assigned client" << client << " to " << addr << dendl;
       } else {
        dout(10) << "mount: client" << client << " requested by " << addr << dendl;
-       if (client_map.client_addr.count(client)) {
-         assert(client_map.client_addr[client] != addr);
+       if (client_map.client_info.count(client)) {
+         assert(client_map.client_info[client].addr != addr);
          dout(0) << "mount: WARNING: client" << client << " requested by " << addr
-                 << ", which used to be "  << client_map.client_addr[client] << dendl;
+                 << ", which used to be "  << client_map.client_info[client].addr << dendl;
        }
       }
       
-      pending_inc.add_mount(client, addr);
+      client_info_t info;
+      info.addr = addr;
+      info.mount_time = g_clock.now();
+      pending_inc.add_mount(client, info);
       paxos->wait_for_commit(new C_Mounted(this, client, (MClientMount*)m));
     }
     return true;
@@ -202,7 +205,7 @@ bool ClientMonitor::prepare_update(Message *m)
       assert(m->get_orig_source().is_client());
       int client = m->get_orig_source().num();
 
-      assert(client_map.client_addr.count(client));
+      assert(client_map.client_info.count(client));
       
       pending_inc.add_unmount(client);
       paxos->wait_for_commit(new C_Unmounted(this, (MClientUnmount*)m));
@@ -243,10 +246,13 @@ bool ClientMonitor::preprocess_command(MMonCommand *m)
     else if (m->cmd[1] == "dump") {
       ss << "version " << client_map.version << std::endl;
       ss << "next_client " << client_map.next_client << std::endl;
-      for (map<uint32_t, entity_addr_t>::iterator p = client_map.client_addr.begin();
-          p != client_map.client_addr.end();
+      for (map<uint32_t, client_info_t>::iterator p = client_map.client_info.begin();
+          p != client_map.client_info.end();
           p++) {
-       ss << "client" << p->first << "\t" << p->second << std::endl;
+       ss << "client" << p->first
+          << "\t" << p->second.addr
+          << "\t" << p->second.mount_time
+          << std::endl;
       }
       while (!ss.eof()) {
        string s;
@@ -317,7 +323,7 @@ void ClientMonitor::_unmounted(MClientUnmount *m)
   // (hack for fakesyn/newsyn, mostly)
   if (mon->is_leader() &&
       client_map.version > 1 &&
-      client_map.client_addr.empty() && 
+      client_map.client_info.empty() && 
       g_conf.mon_stop_on_last_unmount &&
       !mon->is_stopping()) {
     dout(1) << "last client unmounted" << dendl;
index 722500150bc6e4d5b467600102a9f9ef9c085faf..96cb23f6980fd171f61fbe0714c4c5b1d1749eef 100644 (file)
@@ -36,21 +36,38 @@ class MClientMount;
 class MClientUnmount;
 class MMonCommand;
 
+
+struct client_info_t {
+  entity_addr_t addr;
+  utime_t mount_time;
+  
+  void encode(bufferlist& bl) const {
+    ::encode(addr, bl);
+    ::encode(mount_time, bl);
+  }
+  void decode(bufferlist::iterator& bl) {
+    ::decode(addr, bl);
+    ::decode(mount_time, bl);
+  }
+};
+WRITE_CLASS_ENCODER(client_info_t)
+
+
 class ClientMonitor : public PaxosService {
 public:
 
   struct Incremental {
     version_t version;
     uint32_t next_client;
-    map<int32_t, entity_addr_t> mount;
+    map<int32_t, client_info_t> mount;
     set<int32_t> unmount;
     
     Incremental() : version(0), next_client() {}
 
     bool is_empty() { return mount.empty() && unmount.empty(); }
-    void add_mount(uint32_t client, entity_addr_t addr) {
+    void add_mount(uint32_t client, client_info_t& info) {
       next_client = MAX(next_client, client+1);
-      mount[client] = addr;
+      mount[client] = info;
     }
     void add_unmount(uint32_t client) {
       assert(client < next_client);
@@ -77,48 +94,48 @@ public:
   struct Map {
     version_t version;
     uint32_t next_client;
-    map<uint32_t,entity_addr_t> client_addr;
-    map<entity_addr_t,uint32_t> addr_client;
+    map<uint32_t,client_info_t> client_info;
+    map<entity_addr_t,uint32_t> addr_client;  // reverse map
 
     Map() : version(0), next_client(0) {}
 
     void reverse() {
       addr_client.clear();
-      for (map<uint32_t,entity_addr_t>::iterator p = client_addr.begin();
-          p != client_addr.end();
+      for (map<uint32_t,client_info_t>::iterator p = client_info.begin();
+          p != client_info.end();
           ++p) {
-       addr_client[p->second] = p->first;
+       addr_client[p->second.addr] = p->first;
       }
     }
     void apply_incremental(Incremental &inc) {
       assert(inc.version == version+1);
       version = inc.version;
       next_client = inc.next_client;
-      for (map<int32_t,entity_addr_t>::iterator p = inc.mount.begin();
+      for (map<int32_t,client_info_t>::iterator p = inc.mount.begin();
           p != inc.mount.end();
           ++p) {
-       client_addr[p->first] = p->second;
-       addr_client[p->second] = p->first;
+       client_info[p->first] = p->second;
+       addr_client[p->second.addr] = p->first;
       }
        
       for (set<int32_t>::iterator p = inc.unmount.begin();
           p != inc.unmount.end();
           ++p) {
-       assert(client_addr.count(*p));
-       addr_client.erase(client_addr[*p]);
-       client_addr.erase(*p);
+       assert(client_info.count(*p));
+       addr_client.erase(client_info[*p].addr);
+       client_info.erase(*p);
       }
     }
 
     void encode(bufferlist &bl) const {
       ::encode(version, bl);
       ::encode(next_client, bl);
-      ::encode(client_addr, bl);
+      ::encode(client_info, bl);
     }
     void decode(bufferlist::iterator &bl) {
       ::decode(version, bl);
       ::decode(next_client, bl);
-      ::decode(client_addr, bl);
+      ::decode(client_info, bl);
       reverse();
     }
   };