* [PATCH 0/4] libceph: auth retry/invalidate fixes
@ 2016-01-15 14:50 Ilya Dryomov
2016-01-15 14:50 ` [PATCH 1/4] libceph: clear messenger auth_retry flag if we fault Ilya Dryomov
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Ilya Dryomov @ 2016-01-15 14:50 UTC (permalink / raw)
To: ceph-devel; +Cc: Sage Weil
Hello,
These are fixes for http://tracker.ceph.com/issues/4282, which was
never properly fixed, it looks like. All long-standing bugs.
Thanks,
Ilya
Ilya Dryomov (4):
libceph: clear messenger auth_retry flag if we fault
libceph: fix authorizer invalidation, take 2
libceph: invalidate AUTH in addition to a service ticket
libceph: kill off ceph_x_ticket_handler::validity
net/ceph/auth_x.c | 49 ++++++++++++++++++++++++++++++++++++++-----------
net/ceph/auth_x.h | 2 +-
net/ceph/messenger.c | 10 +++++++---
3 files changed, 46 insertions(+), 15 deletions(-)
--
2.4.3
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/4] libceph: clear messenger auth_retry flag if we fault
2016-01-15 14:50 [PATCH 0/4] libceph: auth retry/invalidate fixes Ilya Dryomov
@ 2016-01-15 14:50 ` Ilya Dryomov
2016-01-15 14:50 ` [PATCH 2/4] libceph: fix authorizer invalidation, take 2 Ilya Dryomov
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Ilya Dryomov @ 2016-01-15 14:50 UTC (permalink / raw)
To: ceph-devel; +Cc: Sage Weil
Commit 20e55c4cc758 ("libceph: clear messenger auth_retry flag when we
authenticate") got us only half way there. We clear the flag if the
second attempt succeeds, but it also needs to be cleared if that
attempt fails, to allow for the exponential backoff to kick in.
Otherwise, if ->should_authenticate() thinks our keys are valid, we
will busy loop, incrementing auth_retry to no avail:
process_connect ffff880079a63830 got BADAUTHORIZER attempt 1
process_connect ffff880079a63830 got BADAUTHORIZER attempt 2
process_connect ffff880079a63830 got BADAUTHORIZER attempt 3
process_connect ffff880079a63830 got BADAUTHORIZER attempt 4
process_connect ffff880079a63830 got BADAUTHORIZER attempt 5
...
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
net/ceph/messenger.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 3850d1a5bd7c..9cfedf565f5b 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -2827,13 +2827,17 @@ static bool con_backoff(struct ceph_connection *con)
static void con_fault_finish(struct ceph_connection *con)
{
+ dout("%s %p\n", __func__, con);
+
/*
* in case we faulted due to authentication, invalidate our
* current tickets so that we can get new ones.
*/
- if (con->auth_retry && con->ops->invalidate_authorizer) {
- dout("calling invalidate_authorizer()\n");
- con->ops->invalidate_authorizer(con);
+ if (con->auth_retry) {
+ dout("auth_retry %d, invalidating\n", con->auth_retry);
+ if (con->ops->invalidate_authorizer)
+ con->ops->invalidate_authorizer(con);
+ con->auth_retry = 0;
}
if (con->ops->fault)
--
2.4.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/4] libceph: fix authorizer invalidation, take 2
2016-01-15 14:50 [PATCH 0/4] libceph: auth retry/invalidate fixes Ilya Dryomov
2016-01-15 14:50 ` [PATCH 1/4] libceph: clear messenger auth_retry flag if we fault Ilya Dryomov
@ 2016-01-15 14:50 ` Ilya Dryomov
2016-01-15 14:50 ` [PATCH 3/4] libceph: invalidate AUTH in addition to a service ticket Ilya Dryomov
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Ilya Dryomov @ 2016-01-15 14:50 UTC (permalink / raw)
To: ceph-devel; +Cc: Sage Weil
Back in 2013, commit 4b8e8b5d78b8 ("libceph: fix authorizer
invalidation") tried to fix authorizer invalidation issues by clearing
validity field. However, nothing ever consults this field, so it
doesn't force us to request any new secrets in any way and therefore we
never get out of the exponential backoff mode:
[ 129.973812] libceph: osd2 192.168.122.1:6810 connect authorization failure
[ 130.706785] libceph: osd2 192.168.122.1:6810 connect authorization failure
[ 131.710088] libceph: osd2 192.168.122.1:6810 connect authorization failure
[ 133.708321] libceph: osd2 192.168.122.1:6810 connect authorization failure
[ 137.706598] libceph: osd2 192.168.122.1:6810 connect authorization failure
...
AFAICT this was the case at the time 4b8e8b5d78b8 was merged, too.
Using timespec solely as a bool isn't nice, so introduce a new have_key
flag, specifically for this purpose.
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
net/ceph/auth_x.c | 27 ++++++++++++++++++++++-----
net/ceph/auth_x.h | 1 +
2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
index 10d87753ed87..ab080bb18254 100644
--- a/net/ceph/auth_x.c
+++ b/net/ceph/auth_x.c
@@ -237,6 +237,7 @@ static int process_one_ticket(struct ceph_auth_client *ac,
th->secret_id = new_secret_id;
th->expires = new_expires;
th->renew_after = new_renew_after;
+ th->have_key = true;
dout(" got ticket service %d (%s) secret_id %lld len %d\n",
type, ceph_entity_type_name(type), th->secret_id,
(int)th->ticket_blob->vec.iov_len);
@@ -384,6 +385,24 @@ bad:
return -ERANGE;
}
+static bool need_key(struct ceph_x_ticket_handler *th)
+{
+ if (!th->have_key)
+ return true;
+
+ return get_seconds() >= th->renew_after;
+}
+
+static bool have_key(struct ceph_x_ticket_handler *th)
+{
+ if (th->have_key) {
+ if (get_seconds() >= th->expires)
+ th->have_key = false;
+ }
+
+ return th->have_key;
+}
+
static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed)
{
int want = ac->want_keys;
@@ -402,20 +421,18 @@ static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed)
continue;
th = get_ticket_handler(ac, service);
-
if (IS_ERR(th)) {
*pneed |= service;
continue;
}
- if (get_seconds() >= th->renew_after)
+ if (need_key(th))
*pneed |= service;
- if (get_seconds() >= th->expires)
+ if (!have_key(th))
xi->have_keys &= ~service;
}
}
-
static int ceph_x_build_request(struct ceph_auth_client *ac,
void *buf, void *end)
{
@@ -674,7 +691,7 @@ static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac,
th = get_ticket_handler(ac, peer_type);
if (!IS_ERR(th))
- memset(&th->validity, 0, sizeof(th->validity));
+ th->have_key = false;
}
static int calcu_signature(struct ceph_x_authorizer *au,
diff --git a/net/ceph/auth_x.h b/net/ceph/auth_x.h
index e8b7c6917d47..5334b9b159c5 100644
--- a/net/ceph/auth_x.h
+++ b/net/ceph/auth_x.h
@@ -17,6 +17,7 @@ struct ceph_x_ticket_handler {
struct ceph_crypto_key session_key;
struct ceph_timespec validity;
+ bool have_key;
u64 secret_id;
struct ceph_buffer *ticket_blob;
--
2.4.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] libceph: invalidate AUTH in addition to a service ticket
2016-01-15 14:50 [PATCH 0/4] libceph: auth retry/invalidate fixes Ilya Dryomov
2016-01-15 14:50 ` [PATCH 1/4] libceph: clear messenger auth_retry flag if we fault Ilya Dryomov
2016-01-15 14:50 ` [PATCH 2/4] libceph: fix authorizer invalidation, take 2 Ilya Dryomov
@ 2016-01-15 14:50 ` Ilya Dryomov
2016-01-15 14:50 ` [PATCH 4/4] libceph: kill off ceph_x_ticket_handler::validity Ilya Dryomov
2016-01-20 21:45 ` [PATCH 0/4] libceph: auth retry/invalidate fixes Sage Weil
4 siblings, 0 replies; 6+ messages in thread
From: Ilya Dryomov @ 2016-01-15 14:50 UTC (permalink / raw)
To: ceph-devel; +Cc: Sage Weil
If we fault due to authentication, we invalidate the service ticket we
have and request a new one - the idea being that if a service rejected
our authorizer, it must have expired, despite mon_client's attempts at
periodic renewal. (The other possibility is that our ticket is too new
and the service hasn't gotten it yet, in which case invalidating isn't
necessary but doesn't hurt.)
Invalidating just the service ticket is not enough, though. If we
assume a failure on mon_client's part to renew a service ticket, we
have to assume the same for the AUTH ticket. If our AUTH ticket is
bad, we won't get any service tickets no matter how hard we try, so
invalidate AUTH ticket along with the service ticket.
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
net/ceph/auth_x.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
index ab080bb18254..05e9fc21d460 100644
--- a/net/ceph/auth_x.c
+++ b/net/ceph/auth_x.c
@@ -684,8 +684,7 @@ static void ceph_x_destroy(struct ceph_auth_client *ac)
ac->private = NULL;
}
-static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac,
- int peer_type)
+static void invalidate_ticket(struct ceph_auth_client *ac, int peer_type)
{
struct ceph_x_ticket_handler *th;
@@ -694,6 +693,19 @@ static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac,
th->have_key = false;
}
+static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac,
+ int peer_type)
+{
+ /*
+ * We are to invalidate a service ticket in the hopes of
+ * getting a new, hopefully more valid, one. But, we won't get
+ * it unless our AUTH ticket is good, so invalidate AUTH ticket
+ * as well, just in case.
+ */
+ invalidate_ticket(ac, peer_type);
+ invalidate_ticket(ac, CEPH_ENTITY_TYPE_AUTH);
+}
+
static int calcu_signature(struct ceph_x_authorizer *au,
struct ceph_msg *msg, __le64 *sig)
{
--
2.4.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] libceph: kill off ceph_x_ticket_handler::validity
2016-01-15 14:50 [PATCH 0/4] libceph: auth retry/invalidate fixes Ilya Dryomov
` (2 preceding siblings ...)
2016-01-15 14:50 ` [PATCH 3/4] libceph: invalidate AUTH in addition to a service ticket Ilya Dryomov
@ 2016-01-15 14:50 ` Ilya Dryomov
2016-01-20 21:45 ` [PATCH 0/4] libceph: auth retry/invalidate fixes Sage Weil
4 siblings, 0 replies; 6+ messages in thread
From: Ilya Dryomov @ 2016-01-15 14:50 UTC (permalink / raw)
To: ceph-devel; +Cc: Sage Weil
With it gone, no need to preserve ceph_timespec in process_one_ticket()
either.
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
net/ceph/auth_x.c | 6 ++----
net/ceph/auth_x.h | 1 -
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
index 05e9fc21d460..9e43a315e662 100644
--- a/net/ceph/auth_x.c
+++ b/net/ceph/auth_x.c
@@ -152,7 +152,6 @@ static int process_one_ticket(struct ceph_auth_client *ac,
void *ticket_buf = NULL;
void *tp, *tpend;
void **ptp;
- struct ceph_timespec new_validity;
struct ceph_crypto_key new_session_key;
struct ceph_buffer *new_ticket_blob;
unsigned long new_expires, new_renew_after;
@@ -193,8 +192,8 @@ static int process_one_ticket(struct ceph_auth_client *ac,
if (ret)
goto out;
- ceph_decode_copy(&dp, &new_validity, sizeof(new_validity));
- ceph_decode_timespec(&validity, &new_validity);
+ ceph_decode_timespec(&validity, dp);
+ dp += sizeof(struct ceph_timespec);
new_expires = get_seconds() + validity.tv_sec;
new_renew_after = new_expires - (validity.tv_sec / 4);
dout(" expires=%lu renew_after=%lu\n", new_expires,
@@ -233,7 +232,6 @@ static int process_one_ticket(struct ceph_auth_client *ac,
ceph_buffer_put(th->ticket_blob);
th->session_key = new_session_key;
th->ticket_blob = new_ticket_blob;
- th->validity = new_validity;
th->secret_id = new_secret_id;
th->expires = new_expires;
th->renew_after = new_renew_after;
diff --git a/net/ceph/auth_x.h b/net/ceph/auth_x.h
index 5334b9b159c5..40b1a3cf7397 100644
--- a/net/ceph/auth_x.h
+++ b/net/ceph/auth_x.h
@@ -16,7 +16,6 @@ struct ceph_x_ticket_handler {
unsigned int service;
struct ceph_crypto_key session_key;
- struct ceph_timespec validity;
bool have_key;
u64 secret_id;
--
2.4.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 0/4] libceph: auth retry/invalidate fixes
2016-01-15 14:50 [PATCH 0/4] libceph: auth retry/invalidate fixes Ilya Dryomov
` (3 preceding siblings ...)
2016-01-15 14:50 ` [PATCH 4/4] libceph: kill off ceph_x_ticket_handler::validity Ilya Dryomov
@ 2016-01-20 21:45 ` Sage Weil
4 siblings, 0 replies; 6+ messages in thread
From: Sage Weil @ 2016-01-20 21:45 UTC (permalink / raw)
To: Ilya Dryomov; +Cc: ceph-devel
On Fri, 15 Jan 2016, Ilya Dryomov wrote:
> Hello,
>
> These are fixes for http://tracker.ceph.com/issues/4282, which was
> never properly fixed, it looks like. All long-standing bugs.
Whole series looks good!
Reviewed-by: Sage Weil <sage@redhat.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2016-01-20 21:44 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-15 14:50 [PATCH 0/4] libceph: auth retry/invalidate fixes Ilya Dryomov
2016-01-15 14:50 ` [PATCH 1/4] libceph: clear messenger auth_retry flag if we fault Ilya Dryomov
2016-01-15 14:50 ` [PATCH 2/4] libceph: fix authorizer invalidation, take 2 Ilya Dryomov
2016-01-15 14:50 ` [PATCH 3/4] libceph: invalidate AUTH in addition to a service ticket Ilya Dryomov
2016-01-15 14:50 ` [PATCH 4/4] libceph: kill off ceph_x_ticket_handler::validity Ilya Dryomov
2016-01-20 21:45 ` [PATCH 0/4] libceph: auth retry/invalidate fixes Sage Weil
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox