From be1fd5f1be6386e7c49153b8cd7ba2c722fb077d 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. Lustre-change: https://review.whamcloud.com/40122 Lustre-commit: 1275857c178fdf6e301345c7588499451c8ffd37 Signed-off-by: Sebastien Buisson Change-Id: I65c27e1ab459b2a29670580121ef6e1a00f18918 Reviewed-on: https://review.whamcloud.com/40993 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Mike Pershin Reviewed-by: Oleg Drokin --- lustre/include/lustre_sec.h | 1 + lustre/ldlm/ldlm_lib.c | 18 +++++++++++++++--- lustre/ptlrpc/gss/gss_keyring.c | 12 ++++++++++-- lustre/ptlrpc/sec.c | 33 ++++++++++++++++++++++++++++----- lustre/ptlrpc/sec_null.c | 15 +++------------ 5 files changed, 57 insertions(+), 22 deletions(-) diff --git a/lustre/include/lustre_sec.h b/lustre/include/lustre_sec.h index 08f74aa..cef4bd5 100644 --- a/lustre/include/lustre_sec.h +++ b/lustre/include/lustre_sec.h @@ -1121,6 +1121,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 e080e35..af6577c 100644 --- a/lustre/ldlm/ldlm_lib.c +++ b/lustre/ldlm/ldlm_lib.c @@ -1473,11 +1473,23 @@ int target_handle_disconnect(struct ptlrpc_request *req) ENTRY; rc = req_capsule_server_pack(&req->rq_pill); - if (rc) - RETURN(rc); + 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)); + req->rq_status = obd_disconnect(class_export_get(req->rq_export)); RETURN(0); } diff --git a/lustre/ptlrpc/gss/gss_keyring.c b/lustre/ptlrpc/gss/gss_keyring.c index de5a59d..4047e14 100644 --- a/lustre/ptlrpc/gss/gss_keyring.c +++ b/lustre/ptlrpc/gss/gss_keyring.c @@ -1131,8 +1131,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 666510a..75319b2 100644 --- a/lustre/ptlrpc/sec.c +++ b/lustre/ptlrpc/sec.c @@ -711,12 +711,12 @@ again: sptlrpc_sec_put(sec); if (cli_ctx_is_eternal(ctx)) - RETURN(0); + 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); LASSERT(ctx->cc_ops->validate); @@ -838,7 +838,30 @@ again: RETURN(rc); } - goto 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; } /** diff --git a/lustre/ptlrpc/sec_null.c b/lustre/ptlrpc/sec_null.c index 35aeba8..a17a4e1 100644 --- a/lustre/ptlrpc/sec_null.c +++ b/lustre/ptlrpc/sec_null.c @@ -63,14 +63,7 @@ void null_encode_sec_part(struct lustre_msg *msg, enum lustre_sec_part sp) static inline 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; + return (msg->lm_secflvr >> 24) & 0xFF; } static @@ -370,11 +363,9 @@ 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, + .sign = null_ctx_sign, + .verify = null_ctx_verify, }; - static struct ptlrpc_sec_cops null_sec_cops = { .create_sec = null_create_sec, .destroy_sec = null_destroy_sec, -- 1.8.3.1