]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
msgr: include features in connection handshake (protocol change)
authorSage Weil <sage@newdream.net>
Tue, 22 Dec 2009 19:42:29 +0000 (11:42 -0800)
committerSage Weil <sage@newdream.net>
Wed, 23 Dec 2009 16:52:13 +0000 (08:52 -0800)
src/include/ceph_fs.h
src/include/msgr.h
src/msg/SimpleMessenger.cc

index e87dfa6ec8e5286af1b532ae344557254a00e9d9..db3fed33c4aac3e9892b187b6aa5fcc846eccb7e 100644 (file)
 #define CEPH_MAX_MON   31
 
 
+/*
+ * feature bits
+ */
+#define CEPH_FEATURE_SUPPORTED  0
+#define CEPH_FEATURE_REQUIRED   0
+
 
 /*
  * ceph_file_layout - describe data layout for a file/inode
index e46d8b806dea7b5712562f2ae0b26c9bb2fddcac..be83f93182ee8040d37b158964c5059f760f0955 100644 (file)
@@ -21,7 +21,7 @@
  * whenever the wire protocol changes.  try to keep this string length
  * constant.
  */
-#define CEPH_BANNER "ceph v025"
+#define CEPH_BANNER "ceph v026"
 #define CEPH_BANNER_MAX_LEN 30
 
 
@@ -100,12 +100,14 @@ struct ceph_entity_inst {
 #define CEPH_MSGR_TAG_KEEPALIVE     9  /* just a keepalive byte! */
 #define CEPH_MSGR_TAG_BADPROTOVER  10  /* bad protocol version */
 #define CEPH_MSGR_TAG_BADAUTHORIZER 11 /* bad authorizer */
+#define CEPH_MSGR_TAG_FEATURES      12 /* insufficient features */
 
 
 /*
  * connection negotiation
  */
 struct ceph_msg_connect {
+       __le64 features;     /* supported feature bits */
        __le32 host_type;    /* CEPH_ENTITY_TYPE_* */
        __le32 global_seq;   /* count connections initiated by this host */
        __le32 connect_seq;  /* count connections initiated in this session */
@@ -117,6 +119,7 @@ struct ceph_msg_connect {
 
 struct ceph_msg_connect_reply {
        __u8 tag;
+       __le64 features;     /* feature bits for this session */
        __le32 global_seq;
        __le32 connect_seq;
        __le32 protocol_version;
index fef87a8d54afad169b8b776a3cc4ca2ddaa6391d..f07df1492b0944fb16a0b58a2b8bee5999d6e3dc 100644 (file)
@@ -608,6 +608,7 @@ int SimpleMessenger::Pipe::accept()
   bufferptr bp;
   bufferlist authorizer, authorizer_reply;
   bool authorizer_valid;
+  __u64 feat_missing;
 
   // this should roughly mirror pseudocode at
   //  http://ceph.newdream.net/wiki/Messaging_protocol
@@ -655,6 +656,14 @@ int SimpleMessenger::Pipe::accept()
       rank->lock.Unlock();
       goto reply;
     }
+
+    feat_missing = CEPH_FEATURE_REQUIRED & ~(__u64)connect.features;
+    if (feat_missing) {
+      dout(1) << "peer missing required features " << std::hex << feat_missing << std::dec << dendl;
+      reply.tag = CEPH_MSGR_TAG_FEATURES;
+      rank->lock.Unlock();
+      goto reply;
+    }
     
     if (rank->verify_authorizer(connection_state, peer_type,
                                connect.authorizer_protocol, authorizer, authorizer_reply, authorizer_valid) &&
@@ -779,6 +788,7 @@ int SimpleMessenger::Pipe::accept()
     assert(0);    
 
   reply:
+    reply.features = ((__u64)connect.features & CEPH_FEATURE_SUPPORTED) | CEPH_FEATURE_REQUIRED;
     reply.authorizer_len = authorizer_reply.length();
     rc = tcp_write(sd, (char*)&reply, sizeof(reply));
     if (rc < 0)
@@ -995,6 +1005,7 @@ int SimpleMessenger::Pipe::connect()
     bufferlist authorizer_reply;
 
     ceph_msg_connect connect;
+    connect.features = CEPH_FEATURE_SUPPORTED;
     connect.host_type = rank->my_type;
     connect.global_seq = gseq;
     connect.connect_seq = cseq;
@@ -1066,6 +1077,14 @@ int SimpleMessenger::Pipe::connect()
       goto stop_locked;
     }
 
+    if (reply.tag == CEPH_MSGR_TAG_FEATURES) {
+      dout(0) << "connect protocol feature mismatch, my " << std::hex
+             << connect.features << " < peer " << reply.features
+             << " missing " << (reply.features & ~CEPH_FEATURE_SUPPORTED)
+             << std::dec << dendl;
+      goto fail_locked;
+    }
+
     if (reply.tag == CEPH_MSGR_TAG_BADPROTOVER) {
       dout(0) << "connect protocol version mismatch, my " << connect.protocol_version
              << " != " << reply.protocol_version << dendl;
@@ -1111,6 +1130,12 @@ int SimpleMessenger::Pipe::connect()
     }
 
     if (reply.tag == CEPH_MSGR_TAG_READY) {
+      __u64 feat_missing = CEPH_FEATURE_REQUIRED & ~(__u64)reply.features;
+      if (feat_missing) {
+       dout(1) << "missing required features " << std::hex << feat_missing << std::dec << dendl;
+       goto fail_locked;
+      }
+
       // hooray!
       peer_global_seq = reply.global_seq;
       policy.lossy = reply.flags & CEPH_MSG_CONNECT_LOSSY;