Whamcloud - gitweb
b=14149
[fs/lustre-release.git] / lustre / ptlrpc / gss / gss_cli_upcall.c
index ac2a903..da435a5 100644 (file)
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  *  Copyright (C) 2006 Cluster File Systems, Inc.
+ *   Author: Eric Mei <ericm@clusterfs.com>
  *
  *   This file is part of the Lustre file system, http://www.lustre.org
  *   Lustre is a trademark of Cluster File Systems, Inc.
@@ -71,6 +72,8 @@ int ctx_init_pack_request(struct obd_import *imp,
         rawobj_t                 obj;
 
         LASSERT(msg->lm_bufcount <= 4);
+        LASSERT(req->rq_cli_ctx);
+        LASSERT(req->rq_cli_ctx->cc_sec);
 
         /* gss hdr */
         ghdr = lustre_msg_buf(msg, 0, sizeof(*ghdr));
@@ -78,11 +81,13 @@ int ctx_init_pack_request(struct obd_import *imp,
         ghdr->gh_flags = 0;
         ghdr->gh_proc = PTLRPC_GSS_PROC_INIT;
         ghdr->gh_seq = 0;
-        ghdr->gh_svc = PTLRPC_GSS_SVC_NONE;
+        ghdr->gh_svc = SPTLRPC_SVC_NULL;
         ghdr->gh_handle.len = 0;
 
         /* fix the user desc */
-        if (SEC_FLAVOR_HAS_USER(req->rq_sec_flavor)) {
+        if (req->rq_pack_udesc) {
+                ghdr->gh_flags |= LUSTRE_GSS_PACK_USER;
+
                 pud = lustre_msg_buf(msg, offset, sizeof(*pud));
                 LASSERT(pud);
                 pud->pud_uid = pud->pud_fsuid = uid;
@@ -95,6 +100,7 @@ int ctx_init_pack_request(struct obd_import *imp,
         /* security payload */
         p = lustre_msg_buf(msg, offset, 0);
         size = msg->lm_buflens[offset];
+        LASSERT(p);
 
         /* 1. lustre svc type */
         LASSERT(size > 4);
@@ -108,9 +114,8 @@ int ctx_init_pack_request(struct obd_import *imp,
                 LBUG();
 
         /* 3. reverse context handle. actually only needed by root user,
-         *    but we send it anyway.
-         */
-        gsec = container_of(imp->imp_sec, struct gss_sec, gs_base);
+         *    but we send it anyway. */
+        gsec = sec2gsec(req->rq_cli_ctx->cc_sec);
         obj.len = sizeof(gsec->gs_rvs_hdl);
         obj.data = (__u8 *) &gsec->gs_rvs_hdl;
         if (rawobj_serialize(&obj, &p, &size))
@@ -205,6 +210,7 @@ int ctx_init_parse_reply(struct lustre_msg *msg,
 /* XXX move to where lgssd could see */
 struct lgssd_ioctl_param {
         int             version;        /* in   */
+        int             secid;          /* in   */
         char           *uuid;           /* in   */
         int             lustre_svc;     /* in   */
         uid_t           uid;            /* in   */
@@ -225,7 +231,6 @@ int gss_do_ctx_init_rpc(__user char *buffer, unsigned long count)
         struct obd_device        *obd;
         char                      obdname[64];
         long                      lsize;
-        int                       lmsg_size = sizeof(struct ptlrpc_body);
         int                       rc;
 
         if (count != sizeof(param)) {
@@ -262,13 +267,21 @@ int gss_do_ctx_init_rpc(__user char *buffer, unsigned long count)
         /* force this import to use v2 msg */
         imp->imp_msg_magic = LUSTRE_MSG_MAGIC_V2;
 
-        req = ptlrpc_prep_req(imp, LUSTRE_OBD_VERSION, SEC_CTX_INIT,
-                              1, &lmsg_size, NULL);
-        if (!req) {
+        req = ptlrpc_request_alloc_pack(imp, &RQF_SEC_CTX, LUSTRE_OBD_VERSION,
+                                        SEC_CTX_INIT);
+        if (req == NULL) {
                 param.status = -ENOMEM;
                 goto out_copy;
         }
 
+        if (req->rq_cli_ctx->cc_sec->ps_id != param.secid) {
+                CWARN("original secid %d, now has changed to %d, "
+                      "cancel this negotiation\n", param.secid,
+                      req->rq_cli_ctx->cc_sec->ps_id);
+                param.status = -EINVAL;
+                goto out_copy;
+        }
+
         /* get token */
         rc = ctx_init_pack_request(imp, req,
                                    param.lustre_svc,
@@ -280,7 +293,7 @@ int gss_do_ctx_init_rpc(__user char *buffer, unsigned long count)
                 goto out_copy;
         }
 
-        req->rq_replen = lustre_msg_size_v2(1, &lmsg_size);
+        ptlrpc_request_set_replen(req);
 
         rc = ptlrpc_queue_wait(req);
         if (rc) {
@@ -291,8 +304,7 @@ int gss_do_ctx_init_rpc(__user char *buffer, unsigned long count)
                  * leave recovery decisions to general ptlrpc layer.
                  *
                  * FIXME maybe some other error code shouldn't be treated
-                 * as timeout.
-                 */
+                 * as timeout. */
                 param.status = rc;
                 if (rc != -EACCES)
                         param.status = -ETIMEDOUT;
@@ -326,58 +338,46 @@ int gss_do_ctx_fini_rpc(struct gss_cli_ctx *gctx)
         struct obd_import       *imp = ctx->cc_sec->ps_import;
         struct ptlrpc_request   *req;
         struct ptlrpc_user_desc *pud;
-        int                      buflens = sizeof(struct ptlrpc_body);
         int                      rc;
         ENTRY;
 
-        if (ctx->cc_sec->ps_flags & PTLRPC_SEC_FL_REVERSE) {
-                CWARN("ctx %p(%u) is reverse, don't send destroy rpc\n",
-                      ctx, ctx->cc_vcred.vc_uid);
-                RETURN(0);
-        }
+        LASSERT(atomic_read(&ctx->cc_refcount) > 0);
 
-        /* FIXME
-         * this could be called when import being tearing down, thus import's
-         * spinlock is held. A more clean solution might be: let gss worker
-         * thread handle the ctx destroying; don't wait reply for fini rpc.
-         */
-        if (imp->imp_invalid) {
-                CWARN("ctx %p(%u): skip because import is invalid\n",
-                      ctx, ctx->cc_vcred.vc_uid);
-                RETURN(0);
-        }
-        RETURN(0); // XXX remove after using gss worker thread
-
-        if (test_bit(PTLRPC_CTX_ERROR_BIT, &ctx->cc_flags) ||
-            !test_bit(PTLRPC_CTX_UPTODATE_BIT, &ctx->cc_flags)) {
-                CWARN("ctx %p(%u->%s) already dead, don't send destroy rpc\n",
-                      ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
+        if (cli_ctx_is_error(ctx) || !cli_ctx_is_uptodate(ctx)) {
+                CDEBUG(D_SEC, "ctx %p(%u->%s) not uptodate, "
+                       "don't send destroy rpc\n", ctx,
+                       ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
                 RETURN(0);
         }
 
         might_sleep();
 
-        CWARN("client destroy ctx %p(%u->%s)\n",
-              ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
-
-        /* context's refcount could be 0, steal one */
-        atomic_inc(&ctx->cc_refcount);
+        CWARN("%s ctx %p idx "LPX64" (%u->%s)\n",
+              sec_is_reverse(ctx->cc_sec) ?
+              "server finishing reverse" : "client finishing forward",
+              ctx, gss_handle_to_u64(&gctx->gc_handle),
+              ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
 
         gctx->gc_proc = PTLRPC_GSS_PROC_DESTROY;
 
-        req = ptlrpc_prep_req_pool(imp, LUSTRE_OBD_VERSION, SEC_CTX_FINI,
-                                   1, &buflens, NULL, NULL, ctx);
-        if (!req) {
+        req = ptlrpc_request_alloc(imp, &RQF_SEC_CTX);
+        if (req == NULL) {
                 CWARN("ctx %p(%u): fail to prepare rpc, destroy locally\n",
                       ctx, ctx->cc_vcred.vc_uid);
-                GOTO(out_ref, rc = -ENOMEM);
+                GOTO(out, rc = -ENOMEM);
+        }
+
+        rc = ptlrpc_request_bufs_pack(req, LUSTRE_OBD_VERSION, SEC_CTX_FINI,
+                                      NULL, ctx);
+        if (rc) {
+                ptlrpc_request_free(req);
+                GOTO(out_ref, rc);
         }
 
         /* fix the user desc */
-        if (SEC_FLAVOR_HAS_USER(req->rq_sec_flavor)) {
+        if (req->rq_pack_udesc) {
                 /* we rely the fact that this request is in AUTH mode,
-                 * and user_desc at offset 2.
-                 */
+                 * and user_desc at offset 2. */
                 pud = lustre_msg_buf(req->rq_reqbuf, 2, sizeof(*pud));
                 LASSERT(pud);
                 pud->pud_uid = pud->pud_fsuid = ctx->cc_vcred.vc_uid;
@@ -386,17 +386,16 @@ int gss_do_ctx_fini_rpc(struct gss_cli_ctx *gctx)
                 pud->pud_ngroups = 0;
         }
 
-        req->rq_replen = lustre_msg_size_v2(1, &buflens);
-
-        rc = ptlrpc_queue_wait(req);
+        req->rq_phase = RQ_PHASE_RPC;
+        rc = ptl_send_rpc(req, 1);
         if (rc) {
-                CWARN("ctx %p(%u): rpc error %d, destroy locally\n",
-                      ctx, ctx->cc_vcred.vc_uid, rc);
+                CWARN("ctx %p(%u->%s): rpc error %d, destroy locally\n",
+                      ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec),
+                      rc);
         }
 
         ptlrpc_req_finished(req);
-out_ref:
-        atomic_dec(&ctx->cc_refcount);
+out:
         RETURN(rc);
 }