Whamcloud - gitweb
LU-13498 gss: update sequence in case of target disconnect 22/40122/5
authorSebastien Buisson <sbuisson@ddn.com>
Fri, 2 Oct 2020 12:05:55 +0000 (21:05 +0900)
committerOleg Drokin <green@whamcloud.com>
Thu, 22 Oct 2020 06:03:47 +0000 (06:03 +0000)
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 <sbuisson@ddn.com>
Change-Id: I65c27e1ab459b2a29670580121ef6e1a00f18918
Reviewed-on: https://review.whamcloud.com/40122
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Mike Pershin <mpershin@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/lustre_sec.h
lustre/ldlm/ldlm_lib.c
lustre/ptlrpc/gss/gss_keyring.c
lustre/ptlrpc/sec.c
lustre/ptlrpc/sec_null.c

index 68d64ee..664c234 100644 (file)
@@ -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);
 
index d6d793b..e2605a5 100644 (file)
@@ -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));
 
index d2640a9..820037d 100644 (file)
@@ -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
index 9c53ebe..093a1a3 100644 (file)
@@ -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.
  *
index 1687033..d8408ed 100644 (file)
@@ -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,
 };