]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Update protocol with Merkle trees bascially done
authoranwleung <anwleung@29311d96-e01e-0410-9327-a35deaab8ce9>
Wed, 7 Mar 2007 06:43:29 +0000 (06:43 +0000)
committeranwleung <anwleung@29311d96-e01e-0410-9327-a35deaab8ce9>
Wed, 7 Mar 2007 06:43:29 +0000 (06:43 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1177 29311d96-e01e-0410-9327-a35deaab8ce9

15 files changed:
branches/aleung/security1/ceph/client/Client.cc
branches/aleung/security1/ceph/client/Client.h
branches/aleung/security1/ceph/crypto/CapGroup.h
branches/aleung/security1/ceph/crypto/ExtCap.h
branches/aleung/security1/ceph/mds/Locker.cc
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/MClientUpdate.h
branches/aleung/security1/ceph/messages/MOSDUpdate.h
branches/aleung/security1/ceph/messages/MOSDUpdateReply.h
branches/aleung/security1/ceph/msg/Message.cc
branches/aleung/security1/ceph/msg/Message.h
branches/aleung/security1/ceph/osd/OSD.cc
branches/aleung/security1/ceph/osd/OSD.h

index 63f43af8257bc3624cea39466d3d9481b901338c..9e847ebe660d86837de3a1cf1407d8a96ed23b61 100644 (file)
@@ -713,18 +713,56 @@ void Client::put_user_ticket(Ticket *tk)
 }
 
 void Client::handle_osd_update(MOSDUpdate *m) {
-  // check local cache
-  MOSDUpdateReply *reply;
-  gid_t my_group = m->get_group();
-  cout << "Received a request to resolve group " << my_group << endl;
-  // if we dont have it cached, ask mds, cache it
-  //if (groups.count(my_group) == 0) {
-  //  MClientUpdate *update = new MClientUpdate(my_group);
-  //}
-  //reply = new MOSDUpdateReply(groups[my_group].get_list());
-  reply = new MOSDUpdateReply(my_group);
 
-  messenger->send_message(reply, m->get_source_inst());
+  hash_t my_hash = m->get_hash();
+  cout << "Client::handle_osd_request Received a request to resolve group " << my_hash << endl;
+
+  // if we dont have it cached, ask mds
+  // this will lose execution control
+  if (groups.count(my_hash) == 0) {
+    MClientUpdate *update = new MClientUpdate(my_hash);
+
+    // is anyone else already waiting for this hash?
+    if (update_waiter_osd.count(my_hash) == 0) {
+      dout(10) << "mds_group_update for " << my_hash << endl;
+      // FIXME choose mds (always choose 0)
+      messenger->send_message(update, mdsmap->get_inst(0), MDS_PORT_SERVER);
+    }
+    else
+      dout(10) << "mds_group_update for " << my_hash << endl;
+
+    update_waiter_osd[my_hash].insert(m->get_source().num());
+  }
+  // we have the group, hand it back
+  else {
+    MOSDUpdateReply *reply = new MOSDUpdateReply(my_hash,
+                                                groups[my_hash].get_list());
+    messenger->send_message(reply, m->get_source_inst());
+  }
+
+  // default test option (only for debug)
+  //reply = new MOSDUpdateReply(my_hash);
+  //messenger->send_message(reply, m->get_source_inst());
+
+}
+
+void Client::handle_client_update_reply(MClientUpdateReply *m) {
+  
+  hash_t my_hash = m->get_user_hash();
+  cout << "Client::handle_client_update_reply for " << my_hash << endl;
+
+  // cache the list
+  groups[my_hash].set_list(m->get_user_list());
+
+  MOSDUpdateReply *reply = new MOSDUpdateReply(my_hash, groups[my_hash].get_list());
+
+  // wake the waiters and send them all a reply
+  for (set<int>::iterator oi = update_waiter_osd[my_hash].begin();
+       oi != update_waiter_osd[my_hash].end();
+       ++oi) {
+    messenger->send_message(reply, osdmap->get_inst(*oi));
+  }
+  
 }
 
 // ------------------------
@@ -746,7 +784,10 @@ void Client::dispatch(Message *m)
   case MSG_OSD_UPDATE:
     handle_osd_update((MOSDUpdate*)m);
     break;
-    
+  case MSG_CLIENT_UPDATE_REPLY:
+    handle_client_update_reply((MClientUpdateReply*)m);
+    break;
+
     // client
   case MSG_MDS_MAP:
     handle_mds_map((MMDSMap*)m);
index 0cadf3d7c79df125c61212c78754ca4d42f9aa34..10bb6c1802386788f237e17fac1522fcbebdc193 100644 (file)
@@ -30,6 +30,7 @@
 #include "messages/MOSDUpdate.h"
 #include "messages/MOSDUpdateReply.h"
 #include "messages/MClientUpdate.h"
+#include "messages/MClientUpdateReply.h"
 
 //#include "msgthread.h"
 
@@ -47,6 +48,7 @@ using namespace CryptoLib;
 
 #include "crypto/Ticket.h"
 #include "crypto/CapGroup.h"
+#include "crypto/MerkleTree.h"
 
 // stl
 #include <set>
@@ -512,7 +514,10 @@ protected:
   map<uid_t,esignPub*> user_pub_key;
   map<uid_t,esignPriv*> user_priv_key;
 
-  map<gid_t, CapGroup> groups;
+  map<hash_t, CapGroup> groups;
+  map<hash_t, set<int> > update_waiter_osd;
+  //map<hash_t, list<Cond*> > update_waiter_cond;
+  
 
   // user map
   //map<uid_t, User*> user_identity;
@@ -521,6 +526,7 @@ protected:
   void put_user_ticket(Ticket *tk);
 
   void handle_osd_update(MOSDUpdate *m);
+  void handle_client_update_reply(MClientUpdateReply *m);
 
   // friends
   friend class SyntheticClient;
index 77f96a7b278ed290fa35e2b437a6296d16d2e2bf..8f71fbaea54e63921800c232fc8c4bcc77cfbc28 100644 (file)
 #include<iostream>
 using namespace std;
 
-//#include "include/types.h"
 #include "crypto/MerkleTree.h"
 
 class CapGroup {
  private:
-  //gid_t group_id;
+  gid_t group_id;
   hash_t root_hash;
+  MerkleTree mtree;
   list<uid_t> users;
 
  public:
   friend class OSD;
   friend class Locker;
   CapGroup () { }
-  //CapGroup (gid_t id) { group_id = id; }
+  CapGroup (gid_t id) { group_id = id; }
   CapGroup (hash_t rhash, list<uid_t>& ulist) :
     root_hash(rhash), users(ulist) { }
+  CapGroup (gid_t id, list<uid_t>& ulist) : group_id(id), users(ulist) {
+    // add users to MerkleTree
+    mtree = MerkleTree(users);
+    root_hash = mtree.get_root_hash();
+  }
   
-  //gid_t get_gid() { return group_id; }
-  //void set_gid(gid_t id) { group_id = id; }
+  gid_t get_gid() { return group_id; }
+  void set_gid(gid_t id) { group_id = id; }
 
   hash_t get_root_hash() { return root_hash; }
   void set_root_hash(hash_t nhash) { root_hash = nhash; }
 
   void add_user(uid_t user) {
     users.push_back(user);
+    // re-compute root-hash
+    mtree.add_user(user);
+    root_hash = mtree.get_root_hash();
   }
   void remove_user(uid_t user) {
     users.remove(user);
+    //FIXME need to re-compute hash
   }
 
   bool contains(uid_t user) {
     for (list<uid_t>::iterator ui = users.begin();
         ui != users.end();
         ui++) {
-      //uid_t test& = *ui;
       if (*ui == user)
        return true;
     }
index b7f2229dd428c6b1cabe8bc0bbf3422322053707..91a37dbfb3eebab85c642db5c694d77050c5e1c6 100644 (file)
@@ -24,6 +24,7 @@ using namespace std;
 #include "crypto/CryptoLib.h"
 using namespace CryptoLib;
 #include "crypto/MerkleTree.h"
+#include "crypto/CapGroup.h"
 
 #define NO_GROUP 0
 #define UNIX_GROUP 1
@@ -147,6 +148,20 @@ public:
     data.ino = n;
   }
 
+  ExtCap(int m, uid_t u, CapGroup& cg, inodeno_t n)
+  {
+    data.id.cid = 0;
+    data.id.mds_id = 0;
+    data.t_s = g_clock.now();
+    data.t_e = data.t_s;
+    data.t_e += 3600;
+    data.mode = m;
+    data.uid = u;
+    data.gid = cg.get_gid();
+    data.user_group = cg.get_root_hash();
+    data.ino = n;
+  }
+
   // capability for too many user, many named files
 
   // capability for too many user, too many files
@@ -171,11 +186,11 @@ public:
   }
   void set_type(__int8_t new_type) { data.type = new_type;}
 
-  void set_user_hash(hash_t nhash) { user_group = nhash; }
-  void set_file_hash(hash_t nhash) { file_group = nhash; }
+  void set_user_hash(hash_t nhash) { data.user_group = nhash; }
+  void set_file_hash(hash_t nhash) { data.file_group = nhash; }
 
-  hash_t get_user_hash() { return user_group; }
-  hash_t get_file_hash() { return file_group; }
+  hash_t get_user_hash() { return data.user_group; }
+  hash_t get_file_hash() { return data.file_group; }
 
   const cap_data_t* get_data() const {
     return (&data);
index dec9f918f7358dca50b678f776ba0056970644e4..09a522e112040b665f15a5f711fbd5a243f047cc 100644 (file)
@@ -227,7 +227,7 @@ ExtCap* Locker::issue_new_extcaps(CInode *in, int mode, MClientRequest *req) {
   // get the uid
   uid_t my_user = req->get_caller_uid();
   gid_t my_group = req->get_caller_gid();
-  gid_t file_group = req->get_gid();
+
   int my_want = 0;
   // issue most generic cap (RW)
   my_want |= FILE_MODE_RW;
@@ -239,22 +239,32 @@ ExtCap* Locker::issue_new_extcaps(CInode *in, int mode, MClientRequest *req) {
     // make new cap
     // unix grouping
     if (g_conf.mds_group == 1) {
+
       // configure group
       if (mds->unix_groups.count(my_group) == 0)
        mds->unix_groups[my_group].set_gid(my_group);
-      
-      // add user to group if not know already
-      if (!(mds->unix_groups[my_group].contains(my_user)))
+
+      // add user to group if not in group
+      if (!(mds->unix_groups[my_group].contains(my_user))) {
        mds->unix_groups[my_group].add_user(my_user);
+       hash_t temp_hash = mds->unix_groups[my_group].get_root_hash();
+       mds->unix_groups_byhash[temp_hash] = mds->unix_groups[my_group];
+      }
 
-      ext_cap = new ExtCap(my_want, my_user, my_group, in->ino());
+      ext_cap  = new ExtCap(my_want, my_user,
+                           mds->unix_groups[my_group], in->ino());
 
       ext_cap->set_type(1);
+      
+      dout(3) << "Made new " << my_want << " capability for uid: "
+             << ext_cap->get_uid() << ", group: " << ext_cap->get_gid()
+             << ", for hash: " << ext_cap->get_user_hash()
+             << " for inode: " << ext_cap->get_ino()<< endl;
     }
     // default no grouping
     else
       ext_cap = new ExtCap(my_want, my_user, in->ino());
-
+    
     ext_cap->set_id(cap_id_count, mds->get_nodeid());
     // increment capability count
     cap_id_count++;
index 1dd7feb28567a376147c2c357beff2610a205e80..52146db61b06d42210bf5b904249cdc63efdcea4 100644 (file)
@@ -155,9 +155,10 @@ class MDS : public Dispatcher {
 public:
   map<int,version_t> peer_mdsmap_epoch;
 
-  // user groups
+  // logical user group
   map<gid_t, CapGroup> unix_groups;
-  map<hash_t, CapGroup> user_groups;
+  // hash to group map
+  map<hash_t, CapGroup> unix_groups_byhash;
 
   void queue_waitfor_active(Context *c) { waitfor_active.push_back(c); }
 
index 68ad806bba1ae5cfffb808395718f087da902c51..23058f7570cd7734f7ad83449d614b45398fddfb 100644 (file)
@@ -78,6 +78,9 @@ void Server::dispatch(Message *m)
   case MSG_CLIENT_REQUEST:
     handle_client_request((MClientRequest*)m);
     return;
+  case MSG_CLIENT_UPDATE:
+    handle_client_update((MClientUpdate*)m);
+    return;
 
   case MSG_MDS_HASHREADDIR:
     handle_hash_readdir((MHashReaddir*)m);
@@ -251,7 +254,16 @@ void Server::commit_request(MClientRequest *req,
   }
 }
 
+// update group operations
+void Server::handle_client_update(MClientUpdate *m)
+{
+  hash_t my_hash = m->get_user_hash();
+  dout(3) << "handle_client_update for " << my_hash << endl;
+
+  MClientUpdateReply *reply = new MClientUpdateReply(my_hash, mds->unix_groups_byhash[my_hash].get_list());
 
+  messenger->send_message(reply, m->get_source_inst());
+}
 
 /***
  * process a client request
index d4509f1418e07a59f0baa42e1cc4cc67f3c7eec1..f8d2a23c2bf9d99b80d1e6618a188686e9446e5d 100644 (file)
@@ -15,6 +15,8 @@
 #define __MDS_SERVER_H
 
 #include "MDS.h"
+#include "messages/MClientUpdate.h"
+#include "messages/MClientUpdateReply.h"
 
 class LogEvent;
 
@@ -62,6 +64,9 @@ public:
   void handle_client_request_2(MClientRequest *req, 
                                vector<CDentry*>& trace,
                                int r);
+
+  // group updates
+  void handle_client_update(MClientUpdate *m);
   
   // fs ops
   void handle_client_fstat(MClientRequest *req);
index 919f337f006b517d9dc604530f893e1107becb19..62035d9320cea50ff99383eb536a889d949c2925 100644 (file)
 
 #include "msg/Message.h"
 #include "osd/osd_types.h"
+#include "crypto/MerkleTree.h"
 
 class MClientUpdate : public Message {
 private:
   struct {
+    hash_t user_hash;
     gid_t group;
     entity_inst_t asking_client;
   } mds_update_st;
@@ -29,8 +31,16 @@ public:
     memset(&mds_update_st, 0, sizeof(mds_update_st));
     this->mds_update_st.group = gid;
   }
+  MClientUpdate (hash_t uhash) : Message(MSG_CLIENT_UPDATE) {
+    memset(&mds_update_st, 0, sizeof(mds_update_st));
+    this->mds_update_st.user_hash = uhash;
+  }
   
+  void set_group(gid_t ngroup) { mds_update_st.group = ngroup; }
   gid_t get_group () { return mds_update_st.group; }
+  void set_user_hash(hash_t nhash) { mds_update_st.user_hash = nhash; }
+  hash_t get_user_hash() { return mds_update_st.user_hash; }
+  entity_inst_t& get_client_inst() { return mds_update_st.asking_client; }
 
   virtual void encode_payload() {
     payload.append((char*)&mds_update_st, sizeof(mds_update_st));
@@ -43,6 +53,7 @@ public:
   virtual char *get_type_name() { return "mds_update"; }
   void print(ostream& out) {
     out << "mds_update(" << mds_update_st.group
+       << ", " << mds_update_st.user_hash
        << ")";
   }
 };
index 6ba2c0ae35552b2d22e93473a132b078c96b24a2..0958c8c385e5e2a82c47219dce2de6566c5de777 100644 (file)
 
 #include "msg/Message.h"
 #include "osd/osd_types.h"
+#include "crypto/MerkleTree.h"
 
 class MOSDUpdate : public Message {
 private:
   struct {
     gid_t group;
+    hash_t uhash;
     entity_inst_t client;
     entity_inst_t asker;
   } update_st;
 public:
   gid_t get_group() { return update_st.group; }
+  hash_t get_hash() { return update_st.uhash; }
   entity_inst_t get_client_inst() { return update_st.client; }
   entity_inst_t get_asker() { return update_st.asker; }
 
@@ -36,6 +39,11 @@ public:
     this->update_st.group = upGr;
   }
 
+  MOSDUpdate(hash_t h) : Message(MSG_OSD_UPDATE) {
+    memset(&update_st,0, sizeof(update_st));
+    this->update_st.uhash = h;
+  }
+
   MOSDUpdate(entity_inst_t asking_osd, entity_inst_t target_client,
             gid_t upGr) : Message(MSG_OSD_UPDATE) {
     memset(&update_st,0, sizeof(update_st));
@@ -56,6 +64,7 @@ public:
   virtual char *get_type_name() { return "oop_update"; }
   void print(ostream& out) {
     out << "osd_update(" << update_st.group
+       << ", " << update_st.uhash
        << ")";
   }
 };
index 29035a57e7a088a8b154a1789fdbe920f889faf7..b6c758725f615d26f949510b1bb5ac0d136438af 100644 (file)
 class MOSDUpdateReply : public Message {
 private:
   gid_t group;
+  hash_t user_hash;
   list<uid_t> updated_users;
 public:
   MOSDUpdateReply () : Message(MSG_OSD_UPDATE_REPLY) { }
   MOSDUpdateReply(gid_t gid) : Message(MSG_OSD_UPDATE_REPLY),
                               group(gid) { }
+  MOSDUpdateReply(hash_t uhash) : Message(MSG_OSD_UPDATE_REPLY),
+                                 user_hash(uhash) { }
   MOSDUpdateReply (gid_t gid, list<uid_t> users) :
     Message(MSG_OSD_UPDATE_REPLY), group(gid), updated_users(users) { }
+  MOSDUpdateReply(hash_t uhash, list<uid_t>& users) :
+    Message(MSG_OSD_UPDATE_REPLY), user_hash(uhash), updated_users(users) { }
 
   gid_t get_group() { return group; }
+  hash_t get_user_hash() { return user_hash; }
   list<uid_t>& get_list() { return updated_users; }
 
   virtual void encode_payload() {
     payload.append((char*)&group, sizeof(group));
+    payload.append((char*)&user_hash, sizeof(user_hash));
     _encode(updated_users, payload);
   }
   virtual void decode_payload() {
     int off = 0;
     payload.copy(off, sizeof(group), (char*)&group);
     off += sizeof(group);
+    payload.copy(off, sizeof(user_hash), (char*)&user_hash);
+    off += sizeof(user_hash);
     _decode(updated_users, payload, off);
   }
   virtual char *get_type_name() { return "oop_update_reply"; }
   void print(ostream& out) {
     out << "osd_update_reply(" << group
+       << ", " << user_hash
        << ")";
   }
 };
index 31f65f863fdcbca64a8a70c335671cb81d3db4d3..adc121349f72945bad83ae5c2af0652259b1b3d2 100644 (file)
@@ -55,6 +55,7 @@ using namespace std;
 #include "messages/MClientReply.h"
 #include "messages/MClientFileCaps.h"
 #include "messages/MClientUpdate.h"
+#include "messages/MClientUpdateReply.h"
 
 #include "messages/MMDSGetMap.h"
 #include "messages/MMDSMap.h"
@@ -265,6 +266,12 @@ decode_message(msg_envelope_t& env, bufferlist& payload)
   case MSG_CLIENT_FILECAPS:
     m = new MClientFileCaps();
     break;
+  case MSG_CLIENT_UPDATE:
+    m = new MClientUpdate();
+    break;
+  case MSG_CLIENT_UPDATE_REPLY:
+    m = new MClientUpdateReply();
+    break;
 
     // mds
   case MSG_MDS_GETMAP:
index 74bba6d7d01efa447dedb1ffda5b8af151fa725c..eb79984c462e47244cb1458b9dc8ad0fe0afd10b 100644 (file)
@@ -83,6 +83,7 @@
 #define MSG_CLIENT_FILECAPS        63
 #define MSG_CLIENT_INODEAUTHUPDATE 64
 #define MSG_CLIENT_UPDATE          65
+#define MSG_CLIENT_UPDATE_REPLY    66
 
 #define MSG_CLIENT_BOOT            70
 #define MSG_CLIENT_MOUNT           71
index 016d5e81210d6e00fafbd0edd31790aeb89dc69d..c59f7d7221eb63db2dbb8eccce8ac4f86c4d9561 100644 (file)
@@ -376,21 +376,16 @@ bool OSD::check_request(MOSDOp *op, ExtCap *op_capability) {
   
   if (op_capability->get_type() == UNIX_GROUP) {
     // check if user is in group
-    gid_t my_group = op_capability->get_gid();
+    hash_t my_hash = op_capability->get_user_hash();
 
-    // do we have group cached? if not, update group
-    // this will block till we have the group!!
-    if (unix_groups.count(my_group) == 0) {
-      update_group(op->get_client_inst(), my_group);
-    }
-    
     // now we should have the group, is the client in it?
-    if (!(unix_groups[my_group].contains(op_capability->get_uid()))) {
+    if (!(user_groups[my_hash].contains(op_capability->get_uid()))) {
       // do update to get new unix groups
       cout << "User " << op_capability->get_uid() << " not in group "
-          << my_group << endl;
+          << my_hash << endl;
       return false;
     }
+
   }
   // check users match
   else if (op->get_user() != op_capability->get_uid()) {
@@ -417,30 +412,28 @@ bool OSD::check_request(MOSDOp *op, ExtCap *op_capability) {
 }
 
 // gets group information from client (will block!)
-void OSD::update_group(entity_inst_t client, gid_t group) {
-    // set up reply
-  MOSDUpdate *update = new MOSDUpdate(group);
+void OSD::update_group(entity_inst_t client, hash_t my_hash, MOSDOp *op) {
+  // set up reply
+  MOSDUpdate *update = new MOSDUpdate(my_hash);
   Cond cond;
   
   // if no one has already requested the ticket
-  if (update_waiter_cond.count(group) == 0) {
-    dout(10) << "update_group requesting update for gid " << group << endl;
+  if (update_waiter_op.count(my_hash) == 0) {
+    dout(10) << "update_group requesting update for hash " << my_hash << endl;
       // send it
     messenger->send_message(update, client);
   } else {
     // don't request, someone else already did.  just wait!
-    dout(10) << "update_group waiting for update for gid " << group << endl;
+    dout(10) << "update_group waiting for update for hash " << my_hash << endl;
   }
   
   // wait for reply
-  update_waiter_cond[group].push_back( &cond );
+  update_waiter_op[my_hash].push_back( op );
   
   // naively assume we'll get an update FIXME
-  while (unix_groups.count(group) == 0) { 
-    cond.Wait(osd_lock);
-    //cout << "Received a singal, going to check group " << group << endl;
-  }
-  cout << "Received updated group, returning" << endl;
+  //while (user_groups.count(my_hash) == 0) { 
+  //  cond.Wait(osd_lock);
+  //}
   
 }
 
@@ -448,23 +441,24 @@ void OSD::update_group(entity_inst_t client, gid_t group) {
 void OSD::handle_osd_update_reply(MOSDUpdateReply *m) {
 
   // store the new list into group
-  gid_t my_group = m->get_group();
+  hash_t my_hash = m->get_user_hash();
 
-  cout << "hande_osd_update_reply for " << my_group << endl;
-  dout(10) << "hande_osd_update_reply for " << my_group << endl;
+  cout << "hande_osd_update_reply for " << my_hash << endl;
+  dout(10) << "hande_osd_update_reply for " << my_hash << endl;
 
   // add the new list to our cache
-  unix_groups[my_group].set_list(m->get_list());
+  user_groups[my_hash].set_list(m->get_list());
 
   // wait up the waiter(s)
   // this signals all update waiters
-  for (list<Cond*>::iterator p = update_waiter_cond[my_group].begin();
-       p != update_waiter_cond[my_group].end();
-       ++p) {
-    (*p)->Signal();
-  }
+  //for (list<Cond*>::iterator p = update_waiter_cond[my_hash].begin();
+  //   p != update_waiter_cond[my_hash].end();
+  //   ++p) {
+  //(*p)->Signal();
+  //}
+  take_waiters(update_waiter_op[my_hash]);
 
-  update_waiter_cond.erase(my_group);
+  update_waiter_op.erase(my_hash);
 }
 
 // assumes the request and cap contents has already been checked
@@ -3339,9 +3333,23 @@ void OSD::op_modify(MOSDOp *op, PG *pg)
     // i know, i know...not secure but they should all have caps
     if (op->get_op() == OSD_OP_WRITE
        && op->get_source().is_client()) {
-
+      
       ExtCap *op_capability = op->get_capability();
       assert(op_capability);
+      // if using groups...do we know group?
+      if (op_capability->get_type() == UNIX_GROUP) {
+       // check if user is in group
+       hash_t my_hash = op_capability->get_user_hash();
+       
+       // do we have group cached? if not, update group
+       // we will lose execution control here! re-gain on reply
+       if (user_groups.count(my_hash) == 0) {
+         update_group(op->get_client_inst(), my_hash, op);
+         return;
+       }
+       
+      }
+      
       // check accesses are right
       if (check_request(op, op_capability)) {
        cout << "Access permissions are correct" << endl;
@@ -3351,9 +3359,7 @@ void OSD::op_modify(MOSDOp *op, PG *pg)
       
       assert(verify_cap(op_capability));
     }
-    //else
-    //cout << "Received some write with no cap from " <<
-    //op->get_source().type() << endl;
+
   }
   
   // locked by someone else?
index e2248abbcfa02dffeff87a909fd5a3cd0e1599b6..52f447281000d74a01a64c6c231b5d028d20d905 100644 (file)
@@ -114,11 +114,9 @@ public:
 
   hash_map<int, float> peer_qlen;
 
-  // unix group cache
-  //map<gid_t, CapGroup> unix_groups;
+  // user group cache
   map<hash_t, CapGroup> user_groups;
-  //map<gid_t, list<Cond*> > update_waiter_cond;
-  map<hash_t, list<Cond*> > update_waiter_cond;
+  map<hash_t, list<Message*> >update_waiter_op;
   void handle_osd_update_reply(MOSDUpdateReply *m);
   
   // per-pg locking (serializing)
@@ -274,7 +272,7 @@ public:
 
   // security ops
   bool check_request(class MOSDOp *op, ExtCap *op_capability);
-  void update_group(entity_inst_t client, gid_t group);
+  void update_group(entity_inst_t client, hash_t group, MOSDOp *op);
   bool verify_cap(ExtCap *cap);
 
   // messages