From 1275857c178fdf6e301345c7588499451c8ffd37 Mon Sep 17 00:00:00 2001 From: Sebastien Buisson Date: Fri, 2 Oct 2020 21:05:55 +0900 Subject: [PATCH] LU-13498 gss: update sequence in case of target disconnect Client to OST connections can go idle, leading to target disconnect. In this event, maintaining correct sequence number ensures that GSS does not erroneously consider requests as replays. Sequence is normally updated on export destroy, but this can occur too late, ie after a new target connect request has been processed. So explicitly update sec context at disconnect time. Test-Parameters: env=SHARED_KEY=true,SK_FLAVOR=skn mdscount=2 mdtcount=4 osscount=1 ostcount=8 clientcount=2 testlist=sanity,recovery-small,sanity-sec Test-Parameters: env=SHARED_KEY=true,SK_FLAVOR=ska mdscount=2 mdtcount=4 osscount=1 ostcount=8 clientcount=2 testlist=sanity,recovery-small,sanity-sec Test-Parameters: env=SHARED_KEY=true,SK_FLAVOR=ski mdscount=2 mdtcount=4 osscount=1 ostcount=8 clientcount=2 testlist=sanity,recovery-small,sanity-sec Test-Parameters: env=SHARED_KEY=true,SK_FLAVOR=skpi mdscount=2 mdtcount=4 osscount=1 ostcount=8 clientcount=2 testlist=sanity,recovery-small,sanity-sec Signed-off-by: Sebastien Buisson Change-Id: I65c27e1ab459b2a29670580121ef6e1a00f18918 Reviewed-on: https://review.whamcloud.com/40122 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Mike Pershin Reviewed-by: James Simmons Reviewed-by: Oleg Drokin --- lustre/include/lustre_sec.h | 1 + lustre/ldlm/ldlm_lib.c | 12 ++++++++++++ lustre/ptlrpc/gss/gss_keyring.c | 12 ++++++++++-- lustre/ptlrpc/sec.c | 27 +++++++++++++++++++++++++-- lustre/ptlrpc/sec_null.c | 8 -------- 5 files changed, 48 insertions(+), 12 deletions(-) diff --git a/lustre/include/lustre_sec.h b/lustre/include/lustre_sec.h index 68d64ee..664c234 100644 --- a/lustre/include/lustre_sec.h +++ b/lustre/include/lustre_sec.h @@ -1117,6 +1117,7 @@ void sptlrpc_import_flush_all_ctx(struct obd_import *imp); int sptlrpc_req_get_ctx(struct ptlrpc_request *req); void sptlrpc_req_put_ctx(struct ptlrpc_request *req, int sync); int sptlrpc_req_refresh_ctx(struct ptlrpc_request *req, long timeout); +int sptlrpc_export_update_ctx(struct obd_export *exp); int sptlrpc_req_replace_dead_ctx(struct ptlrpc_request *req); void sptlrpc_req_set_flavor(struct ptlrpc_request *req, int opcode); diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c index d6d793b..e2605a5 100644 --- a/lustre/ldlm/ldlm_lib.c +++ b/lustre/ldlm/ldlm_lib.c @@ -1594,6 +1594,18 @@ int target_handle_disconnect(struct ptlrpc_request *req) if (rc) RETURN(rc); + /* In case of target disconnect, updating sec ctx immediately is + * required in order to record latest sequence number used. + * Sequence is normally updated on export destroy, but this event + * can occur too late, ie after a new target connect request has + * been processed. + * Maintaining correct sequence when client connection becomes idle + * ensures that GSS does not erroneously consider requests as replays. + */ + rc = sptlrpc_export_update_ctx(req->rq_export); + if (rc) + RETURN(rc); + /* Keep the rq_export around so we can send the reply. */ req->rq_status = obd_disconnect(class_export_get(req->rq_export)); diff --git a/lustre/ptlrpc/gss/gss_keyring.c b/lustre/ptlrpc/gss/gss_keyring.c index d2640a9..820037d 100644 --- a/lustre/ptlrpc/gss/gss_keyring.c +++ b/lustre/ptlrpc/gss/gss_keyring.c @@ -1130,8 +1130,16 @@ int gss_sec_display_kr(struct ptlrpc_sec *sec, struct seq_file *seq) static int gss_cli_ctx_refresh_kr(struct ptlrpc_cli_ctx *ctx) { - /* upcall is already on the way */ - return 0; + /* upcall is already on the way */ + struct gss_cli_ctx *gctx = ctx ? ctx2gctx(ctx) : NULL; + + /* record latest sequence number in buddy svcctx */ + if (gctx && !rawobj_empty(&gctx->gc_svc_handle) && + sec_is_reverse(gctx->gc_base.cc_sec)) { + return gss_svc_upcall_update_sequence(&gctx->gc_svc_handle, + (__u32)atomic_read(&gctx->gc_seq)); + } + return 0; } static diff --git a/lustre/ptlrpc/sec.c b/lustre/ptlrpc/sec.c index 9c53ebe..093a1a3 100644 --- a/lustre/ptlrpc/sec.c +++ b/lustre/ptlrpc/sec.c @@ -700,8 +700,8 @@ again: RETURN(0); if (unlikely(test_bit(PTLRPC_CTX_NEW_BIT, &ctx->cc_flags))) { - LASSERT(ctx->cc_ops->refresh); - ctx->cc_ops->refresh(ctx); + if (ctx->cc_ops->refresh) + ctx->cc_ops->refresh(ctx); } LASSERT(test_bit(PTLRPC_CTX_NEW_BIT, &ctx->cc_flags) == 0); @@ -831,6 +831,29 @@ again: goto again; } +/* Bring ptlrpc_sec context up-to-date */ +int sptlrpc_export_update_ctx(struct obd_export *exp) +{ + struct obd_import *imp = exp ? exp->exp_imp_reverse : NULL; + struct ptlrpc_sec *sec = NULL; + struct ptlrpc_cli_ctx *ctx = NULL; + int rc = 0; + + if (imp) + sec = sptlrpc_import_sec_ref(imp); + if (sec) { + ctx = get_my_ctx(sec); + sptlrpc_sec_put(sec); + } + + if (ctx) { + if (ctx->cc_ops->refresh) + rc = ctx->cc_ops->refresh(ctx); + sptlrpc_cli_ctx_put(ctx, 1); + } + return rc; +} + /** * Initialize flavor settings for \a req, according to \a opcode. * diff --git a/lustre/ptlrpc/sec_null.c b/lustre/ptlrpc/sec_null.c index 1687033..d8408ed 100644 --- a/lustre/ptlrpc/sec_null.c +++ b/lustre/ptlrpc/sec_null.c @@ -66,13 +66,6 @@ enum lustre_sec_part null_decode_sec_part(struct lustre_msg *msg) return (msg->lm_secflvr >> 24) & 0xFF; } -static int null_ctx_refresh(struct ptlrpc_cli_ctx *ctx) -{ - /* should never reach here */ - LBUG(); - return 0; -} - static int null_ctx_sign(struct ptlrpc_cli_ctx *ctx, struct ptlrpc_request *req) { @@ -373,7 +366,6 @@ int null_authorize(struct ptlrpc_request *req) } static struct ptlrpc_ctx_ops null_ctx_ops = { - .refresh = null_ctx_refresh, .sign = null_ctx_sign, .verify = null_ctx_verify, }; -- 1.8.3.1