Skip to content

Commit

Permalink
libceph: add update_authorizer auth method
Browse files Browse the repository at this point in the history
Currently the messenger calls out to a get_authorizer con op, which will
create a new authorizer if it doesn't yet have one.  In the meantime, when
we rotate our service keys, the authorizer doesn't get updated.  Eventually
it will be rejected by the server on a new connection attempt and get
invalidated, and we will then rebuild a new authorizer, but this is not
ideal.

Instead, if we do have an authorizer, call a new update_authorizer op that
will verify that the current authorizer is using the latest secret.  If it
is not, we will build a new one that does.  This avoids the transient
failure.

This fixes one of the sorry sequence of events for bug

	http://tracker.ceph.com/issues/4282

Signed-off-by: Sage Weil <[email protected]>
Reviewed-by: Alex Elder <[email protected]>
  • Loading branch information
Sage Weil committed May 2, 2013
1 parent 4b8e8b5 commit 0bed9b5
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 1 deletion.
7 changes: 6 additions & 1 deletion fs/ceph/mds_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -3445,7 +3445,12 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con,
}
if (!auth->authorizer && ac->ops && ac->ops->create_authorizer) {
int ret = ac->ops->create_authorizer(ac, CEPH_ENTITY_TYPE_MDS,
auth);
auth);
if (ret)
return ERR_PTR(ret);
} else if (ac->ops && ac->ops_update_authorizer) {
int ret = ac->ops->update_authorizer(ac, CEPH_ENTITY_TYPE_MDS,
auth);
if (ret)
return ERR_PTR(ret);
}
Expand Down
3 changes: 3 additions & 0 deletions include/linux/ceph/auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ struct ceph_auth_client_ops {
*/
int (*create_authorizer)(struct ceph_auth_client *ac, int peer_type,
struct ceph_auth_handshake *auth);
/* ensure that an existing authorizer is up to date */
int (*update_authorizer)(struct ceph_auth_client *ac, int peer_type,
struct ceph_auth_handshake *auth);
int (*verify_authorizer_reply)(struct ceph_auth_client *ac,
struct ceph_authorizer *a, size_t len);
void (*destroy_authorizer)(struct ceph_auth_client *ac,
Expand Down
23 changes: 23 additions & 0 deletions net/ceph/auth_x.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
return -ENOMEM;
}
au->service = th->service;
au->secret_id = th->secret_id;

msg_a = au->buf->vec.iov_base;
msg_a->struct_v = 1;
Expand Down Expand Up @@ -555,6 +556,27 @@ static int ceph_x_create_authorizer(
return 0;
}

static int ceph_x_update_authorizer(
struct ceph_auth_client *ac, int peer_type,
struct ceph_auth_handshake *auth)
{
struct ceph_x_authorizer *au;
struct ceph_x_ticket_handler *th;
int ret;

th = get_ticket_handler(ac, peer_type);
if (IS_ERR(th))
return PTR_ERR(th);

au = (struct ceph_x_authorizer *)auth->authorizer;
if (au->secret_id < th->secret_id) {
dout("ceph_x_update_authorizer service %u secret %llu < %llu\n",
au->service, au->secret_id, th->secret_id);
return ceph_x_build_authorizer(ac, th, au);
}
return 0;
}

static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac,
struct ceph_authorizer *a, size_t len)
{
Expand Down Expand Up @@ -641,6 +663,7 @@ static const struct ceph_auth_client_ops ceph_x_ops = {
.build_request = ceph_x_build_request,
.handle_reply = ceph_x_handle_reply,
.create_authorizer = ceph_x_create_authorizer,
.update_authorizer = ceph_x_update_authorizer,
.verify_authorizer_reply = ceph_x_verify_authorizer_reply,
.destroy_authorizer = ceph_x_destroy_authorizer,
.invalidate_authorizer = ceph_x_invalidate_authorizer,
Expand Down
1 change: 1 addition & 0 deletions net/ceph/auth_x.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct ceph_x_authorizer {
struct ceph_buffer *buf;
unsigned int service;
u64 nonce;
u64 secret_id;
char reply_buf[128]; /* big enough for encrypted blob */
};

Expand Down
5 changes: 5 additions & 0 deletions net/ceph/osd_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -2220,6 +2220,11 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con,
auth);
if (ret)
return ERR_PTR(ret);
} else if (ac->ops && ac->ops->update_authorizer) {
int ret = ac->ops->update_authorizer(ac, CEPH_ENTITY_TYPE_OSD,
auth);
if (ret)
return ERR_PTR(ret);
}
*proto = ac->protocol;

Expand Down

0 comments on commit 0bed9b5

Please sign in to comment.