ceph: add feature bits to connection handshake (protocol change)
Define supported and required feature set. Fail connection if the server requires features we do not support (TAG_FEATURES), or if the server does not support features we require. Signed-off-by: Sage Weil <sage@newdream.net>
This commit is contained in:
parent
6df058c025
commit
04a419f908
4 changed files with 53 additions and 17 deletions
|
@ -50,6 +50,12 @@
|
|||
#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
|
||||
|
|
|
@ -1135,9 +1135,9 @@ void ceph_dentry_lru_add(struct dentry *dn)
|
|||
{
|
||||
struct ceph_dentry_info *di = ceph_dentry(dn);
|
||||
struct ceph_mds_client *mdsc;
|
||||
dout("dentry_lru_add %p %p\t%.*s\n",
|
||||
di, dn, dn->d_name.len, dn->d_name.name);
|
||||
|
||||
dout("dentry_lru_add %p %p '%.*s'\n", di, dn,
|
||||
dn->d_name.len, dn->d_name.name);
|
||||
if (di) {
|
||||
mdsc = &ceph_client(dn->d_sb)->mdsc;
|
||||
spin_lock(&mdsc->dentry_lru_lock);
|
||||
|
@ -1151,9 +1151,9 @@ void ceph_dentry_lru_touch(struct dentry *dn)
|
|||
{
|
||||
struct ceph_dentry_info *di = ceph_dentry(dn);
|
||||
struct ceph_mds_client *mdsc;
|
||||
dout("dentry_lru_touch %p %p\t%.*s\n",
|
||||
di, dn, dn->d_name.len, dn->d_name.name);
|
||||
|
||||
dout("dentry_lru_touch %p %p '%.*s'\n", di, dn,
|
||||
dn->d_name.len, dn->d_name.name);
|
||||
if (di) {
|
||||
mdsc = &ceph_client(dn->d_sb)->mdsc;
|
||||
spin_lock(&mdsc->dentry_lru_lock);
|
||||
|
@ -1167,8 +1167,8 @@ void ceph_dentry_lru_del(struct dentry *dn)
|
|||
struct ceph_dentry_info *di = ceph_dentry(dn);
|
||||
struct ceph_mds_client *mdsc;
|
||||
|
||||
dout("dentry_lru_del %p %p\t%.*s\n",
|
||||
di, dn, dn->d_name.len, dn->d_name.name);
|
||||
dout("dentry_lru_del %p %p '%.*s'\n", di, dn,
|
||||
dn->d_name.len, dn->d_name.name);
|
||||
if (di) {
|
||||
mdsc = &ceph_client(dn->d_sb)->mdsc;
|
||||
spin_lock(&mdsc->dentry_lru_lock);
|
||||
|
|
|
@ -631,6 +631,7 @@ static void prepare_write_connect(struct ceph_messenger *msgr,
|
|||
dout("prepare_write_connect %p cseq=%d gseq=%d proto=%d\n", con,
|
||||
con->connect_seq, global_seq, proto);
|
||||
|
||||
con->out_connect.features = CEPH_FEATURE_SUPPORTED;
|
||||
con->out_connect.host_type = cpu_to_le32(CEPH_ENTITY_TYPE_CLIENT);
|
||||
con->out_connect.connect_seq = cpu_to_le32(con->connect_seq);
|
||||
con->out_connect.global_seq = cpu_to_le32(global_seq);
|
||||
|
@ -1080,15 +1081,37 @@ static int process_banner(struct ceph_connection *con)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void fail_protocol(struct ceph_connection *con)
|
||||
{
|
||||
reset_connection(con);
|
||||
set_bit(CLOSED, &con->state); /* in case there's queued work */
|
||||
|
||||
mutex_unlock(&con->mutex);
|
||||
if (con->ops->bad_proto)
|
||||
con->ops->bad_proto(con);
|
||||
mutex_lock(&con->mutex);
|
||||
}
|
||||
|
||||
static int process_connect(struct ceph_connection *con)
|
||||
{
|
||||
u64 sup_feat = CEPH_FEATURE_SUPPORTED;
|
||||
u64 req_feat = CEPH_FEATURE_REQUIRED;
|
||||
u64 server_feat = le64_to_cpu(con->in_reply.features);
|
||||
|
||||
dout("process_connect on %p tag %d\n", con, (int)con->in_tag);
|
||||
|
||||
switch (con->in_reply.tag) {
|
||||
case CEPH_MSGR_TAG_FEATURES:
|
||||
pr_err("%s%lld %s feature set mismatch,"
|
||||
" my %llx < server's %llx, missing %llx\n",
|
||||
ENTITY_NAME(con->peer_name),
|
||||
pr_addr(&con->peer_addr.in_addr),
|
||||
sup_feat, server_feat, server_feat & ~sup_feat);
|
||||
con->error_msg = "missing required protocol features";
|
||||
fail_protocol(con);
|
||||
return -1;
|
||||
|
||||
case CEPH_MSGR_TAG_BADPROTOVER:
|
||||
dout("process_connect got BADPROTOVER my %d != their %d\n",
|
||||
le32_to_cpu(con->out_connect.protocol_version),
|
||||
le32_to_cpu(con->in_reply.protocol_version));
|
||||
pr_err("%s%lld %s protocol version mismatch,"
|
||||
" my %d != server's %d\n",
|
||||
ENTITY_NAME(con->peer_name),
|
||||
|
@ -1096,13 +1119,7 @@ static int process_connect(struct ceph_connection *con)
|
|||
le32_to_cpu(con->out_connect.protocol_version),
|
||||
le32_to_cpu(con->in_reply.protocol_version));
|
||||
con->error_msg = "protocol version mismatch";
|
||||
reset_connection(con);
|
||||
set_bit(CLOSED, &con->state); /* in case there's queued work */
|
||||
|
||||
mutex_unlock(&con->mutex);
|
||||
if (con->ops->bad_proto)
|
||||
con->ops->bad_proto(con);
|
||||
mutex_lock(&con->mutex);
|
||||
fail_protocol(con);
|
||||
return -1;
|
||||
|
||||
case CEPH_MSGR_TAG_BADAUTHORIZER:
|
||||
|
@ -1173,6 +1190,16 @@ static int process_connect(struct ceph_connection *con)
|
|||
break;
|
||||
|
||||
case CEPH_MSGR_TAG_READY:
|
||||
if (req_feat & ~server_feat) {
|
||||
pr_err("%s%lld %s protocol feature mismatch,"
|
||||
" my required %llx > server's %llx, need %llx\n",
|
||||
ENTITY_NAME(con->peer_name),
|
||||
pr_addr(&con->peer_addr.in_addr),
|
||||
req_feat, server_feat, req_feat & ~server_feat);
|
||||
con->error_msg = "missing required protocol features";
|
||||
fail_protocol(con);
|
||||
return -1;
|
||||
}
|
||||
clear_bit(CONNECTING, &con->state);
|
||||
con->peer_global_seq = le32_to_cpu(con->in_reply.global_seq);
|
||||
con->connect_seq++;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue