Whamcloud - gitweb
land b_hd_sec onto HEAD, some debugging code also kept.
[fs/lustre-release.git] / lustre / sec / gss / svcsec_gss.c
index fda3d01..c5e2ddb 100644 (file)
@@ -127,6 +127,7 @@ static void rsi_free(struct rsi *rsii)
 static void rsi_put(struct cache_head *item, struct cache_detail *cd)
 {
         struct rsi *rsii = container_of(item, struct rsi, h);
+        LASSERT(atomic_read(&item->refcnt) > 0);
         if (cache_put(item, cd)) {
                 rsi_free(rsii);
                 OBD_FREE(rsii, sizeof(*rsii));
@@ -135,8 +136,8 @@ static void rsi_put(struct cache_head *item, struct cache_detail *cd)
 
 static inline int rsi_hash(struct rsi *item)
 {
-        return hash_mem(item->in_handle.data, item->in_handle.len, RSI_HASHBITS)
-              ^ hash_mem(item->in_token.data, item->in_token.len, RSI_HASHBITS);
+        return hash_mem((char *)item->in_handle.data, item->in_handle.len, RSI_HASHBITS)
+                ^ hash_mem((char *)item->in_token.data, item->in_token.len, RSI_HASHBITS);
 }
 
 static inline int rsi_match(struct rsi *item, struct rsi *tmp)
@@ -151,11 +152,11 @@ static void rsi_request(struct cache_detail *cd,
 {
         struct rsi *rsii = container_of(h, struct rsi, h);
 
-        qword_addhex(bpp, blen, (char *) &rsii->naltype, sizeof(rsii->naltype));
-        qword_addhex(bpp, blen, (char *) &rsii->netid, sizeof(rsii->netid));
-        qword_addhex(bpp, blen, (char *) &rsii->nid, sizeof(rsii->nid));
-        qword_addhex(bpp, blen, rsii->in_handle.data, rsii->in_handle.len);
-        qword_addhex(bpp, blen, rsii->in_token.data, rsii->in_token.len);
+        qword_addhex(bpp, blen, (char *)&rsii->naltype, sizeof(rsii->naltype));
+        qword_addhex(bpp, blen, (char *)&rsii->netid, sizeof(rsii->netid));
+        qword_addhex(bpp, blen, (char *)&rsii->nid, sizeof(rsii->nid));
+        qword_addhex(bpp, blen, (char *)rsii->in_handle.data, rsii->in_handle.len);
+        qword_addhex(bpp, blen, (char *)rsii->in_token.data, rsii->in_token.len);
         (*bpp)[-1] = '\n';
 }
 
@@ -177,6 +178,7 @@ gssd_reply(struct rsi *item)
                         tmp->h.next = NULL;
                         rsi_cache.entries--;
                         if (test_bit(CACHE_VALID, &tmp->h.flags)) {
+                                CERROR("rsi is valid\n");
                                 write_unlock(&rsi_cache.hash_lock);
                                 rsi_put(&tmp->h, &rsi_cache);
                                 RETURN(-EINVAL);
@@ -229,18 +231,19 @@ gssd_upcall(struct rsi *item, struct cache_req *chandle)
                         return tmp;
                 }
         }
-        // cache_get(&item->h);
-        set_bit(CACHE_HASHED, &item->h.flags);
+        cache_get(&item->h);
+        //set_bit(CACHE_HASHED, &item->h.flags);
         item->h.next = *head;
         *head = &item->h;
         rsi_cache.entries++;
         read_unlock(&rsi_cache.hash_lock);
-        cache_get(&item->h);
+        //cache_get(&item->h);
 
         cache_check(&rsi_cache, &item->h, chandle);
         starttime = get_seconds();
         do {
-                yield();
+                set_current_state(TASK_UNINTERRUPTIBLE);
+                schedule_timeout(HZ/2);
                 read_lock(&rsi_cache.hash_lock);
                 for (hp = head; *hp != NULL; hp = &tmp->h.next) {
                         tmp = container_of(*hp, struct rsi, h);
@@ -261,8 +264,8 @@ gssd_upcall(struct rsi *item, struct cache_req *chandle)
                         }
                 }
                 read_unlock(&rsi_cache.hash_lock);
-        } while ((get_seconds() - starttime) <= 5);
-        CERROR("5s timeout while waiting cache refill\n");
+        } while ((get_seconds() - starttime) <= 15);
+        CERROR("15s timeout while waiting cache refill\n");
         return NULL;
 }
 
@@ -409,6 +412,7 @@ static void rsc_put(struct cache_head *item, struct cache_detail *cd)
 {
         struct rsc *rsci = container_of(item, struct rsc, h);
 
+        LASSERT(atomic_read(&item->refcnt) > 0);
         if (cache_put(item, cd)) {
                 rsc_free(rsci);
                 OBD_FREE(rsci, sizeof(*rsci));
@@ -418,7 +422,8 @@ static void rsc_put(struct cache_head *item, struct cache_detail *cd)
 static inline int
 rsc_hash(struct rsc *rsci)
 {
-        return hash_mem(rsci->handle.data, rsci->handle.len, RSC_HASHBITS);
+        return hash_mem((char *)rsci->handle.data,
+                        rsci->handle.len, RSC_HASHBITS);
 }
 
 static inline int
@@ -454,7 +459,7 @@ static struct rsc *rsc_lookup(struct rsc *item, int set)
         }
         /* Didn't find anything */
         if (!set)
-                goto out_noset;
+                goto out_nada;
         rsc_cache.entries++;
 out_set:
         set_bit(CACHE_HASHED, &item->h.flags);
@@ -464,6 +469,8 @@ out_set:
         cache_fresh(&rsc_cache, &item->h, item->h.expiry_time);
         cache_get(&item->h);
         RETURN(item);
+out_nada:
+        tmp = NULL;
 out_noset:
         read_unlock(&rsc_cache.hash_lock);
         RETURN(tmp);
@@ -472,7 +479,8 @@ out_noset:
 static int rsc_parse(struct cache_detail *cd,
                      char *mesg, int mlen)
 {
-        /* contexthandle expiry [ uid gid N <n gids> mechname ...mechdata... ] */
+        /* contexthandle expiry [ uid gid N <n gids> mechname
+         * ...mechdata... ] */
         char *buf = mesg;
         int len, rv;
         struct rsc *rsci, *res = NULL;
@@ -500,21 +508,21 @@ static int rsc_parse(struct cache_detail *cd,
                 goto out;
 
         /* remote flag */
-        rv = get_int(&mesg, &rsci->remote_realm);
+        rv = get_int(&mesg, (int *)&rsci->remote_realm);
         if (rv) {
                 CERROR("fail to get remote flag\n");
                 goto out;
         }
 
         /* mapped uid */
-        rv = get_int(&mesg, &rsci->mapped_uid);
+        rv = get_int(&mesg, (int *)&rsci->mapped_uid);
         if (rv) {
                 CERROR("fail to get mapped uid\n");
                 goto out;
         }
 
         /* uid, or NEGATIVE */
-        rv = get_int(&mesg, &rsci->cred.vc_uid);
+        rv = get_int(&mesg, (int *)&rsci->cred.vc_uid);
         if (rv == -EINVAL)
                 goto out;
         if (rv == -ENOENT) {
@@ -526,7 +534,7 @@ static int rsc_parse(struct cache_detail *cd,
                 __u64 ctx_expiry;
 
                 /* gid */
-                if (get_int(&mesg, &rsci->cred.vc_gid))
+                if (get_int(&mesg, (int *)&rsci->cred.vc_gid))
                         goto out;
 
                 /* mech name */
@@ -546,7 +554,7 @@ static int rsc_parse(struct cache_detail *cd,
                         goto out;
                 }
                 tmp_buf.len = len;
-                tmp_buf.data = buf;
+                tmp_buf.data = (unsigned char *)buf;
                 if (kgss_import_sec_context(&tmp_buf, gm, &rsci->mechctx)) {
                         kgss_mech_put(gm);
                         goto out;
@@ -599,7 +607,7 @@ static void rsc_flush(uid_t uid)
                                 cache_get(&rscp->h);
                                 set_bit(CACHE_NEGATIVE, &rscp->h.flags);
                                 clear_bit(CACHE_HASHED, &rscp->h.flags);
-                                CWARN("flush rsc %p for uid %u\n",
+                                CDEBUG(D_SEC, "flush rsc %p for uid %u\n",
                                        rscp, rscp->cred.vc_uid);
                                 rsc_put(&rscp->h, &rsc_cache);
                                 rsc_cache.entries--;
@@ -718,7 +726,7 @@ gss_svc_verify_request(struct ptlrpc_request *req,
         msg.data = (__u8 *)req->rq_reqmsg;
 
         mic.len = le32_to_cpu(*vp++);
-        mic.data = (char *) vp;
+        mic.data = (unsigned char *)vp;
         vlen -= 4;
 
         if (mic.len > vlen) {
@@ -739,8 +747,9 @@ gss_svc_verify_request(struct ptlrpc_request *req,
         }
 
         if (gss_check_seq_num(&rsci->seqdata, gc->gc_seq)) {
-                CERROR("discard request %p with old seq_num %u\n",
-                        req, gc->gc_seq);
+                CERROR("discard replayed request %p(o%u,x"LPU64",t"LPU64")\n",
+                        req, req->rq_reqmsg->opc, req->rq_xid,
+                        req->rq_reqmsg->transno);
                 RETURN(GSS_S_DUPLICATE_TOKEN);
         }
 
@@ -785,8 +794,9 @@ gss_svc_unseal_request(struct ptlrpc_request *req,
         }
 
         if (gss_check_seq_num(&rsci->seqdata, gc->gc_seq)) {
-                CERROR("discard request %p with old seq_num %u\n",
-                        req, gc->gc_seq);
+                CERROR("discard replayed request %p(o%u,x"LPU64",t"LPU64")\n",
+                        req, req->rq_reqmsg->opc, req->rq_xid,
+                        req->rq_reqmsg->transno);
                 RETURN(GSS_S_DUPLICATE_TOKEN);
         }
 
@@ -852,12 +862,30 @@ gss_pack_err_notify(struct ptlrpc_request *req,
         *reslenp = cpu_to_le32(secdata_len);
 
         req->rq_reply_state->rs_repdata_len += (secdata_len);
-        CWARN("prepare gss error notify(0x%x/0x%x) to %s\n", major, minor,
+        CDEBUG(D_SEC, "prepare gss error notify(0x%x/0x%x) to %s\n",
+               major, minor,
                portals_nid2str(req->rq_peer.peer_ni->pni_number,
                                req->rq_peer.peer_id.nid, nidstr));
         RETURN(0);
 }
 
+static void dump_cache_head(struct cache_head *h)
+{
+        CWARN("ref %d, fl %lx, n %p, t %ld, %ld\n",
+              atomic_read(&h->refcnt), h->flags, h->next,
+              h->expiry_time, h->last_refresh);
+}
+static void dump_rsi(struct rsi *rsi)
+{
+        CWARN("dump rsi %p\n", rsi);
+        dump_cache_head(&rsi->h);
+        CWARN("%x,%x,%llx\n", rsi->naltype, rsi->netid, rsi->nid);
+        CWARN("len %d, d %p\n", rsi->in_handle.len, rsi->in_handle.data);
+        CWARN("len %d, d %p\n", rsi->in_token.len, rsi->in_token.data);
+        CWARN("len %d, d %p\n", rsi->out_handle.len, rsi->out_handle.data);
+        CWARN("len %d, d %p\n", rsi->out_token.len, rsi->out_token.data);
+}
+
 static int
 gss_svcsec_handle_init(struct ptlrpc_request *req,
                        struct rpc_gss_wire_cred *gc,
@@ -875,7 +903,7 @@ gss_svcsec_handle_init(struct ptlrpc_request *req,
 
         LASSERT(svcdata);
 
-        CWARN("processing gss init(%d) request from %s\n", gc->gc_proc,
+        CDEBUG(D_SEC, "processing gss init(%d) request from %s\n", gc->gc_proc,
                portals_nid2str(req->rq_peer.peer_ni->pni_number,
                                req->rq_peer.peer_id.nid, nidstr));
 
@@ -917,21 +945,25 @@ gss_svcsec_handle_init(struct ptlrpc_request *req,
         rsip = gssd_upcall(rsikey, &my_chandle);
         if (!rsip) {
                 CERROR("error in gssd_upcall.\n");
-                GOTO(out_rsikey, rc = SVC_DROP);
+
+                rc = SVC_COMPLETE;
+                if (gss_pack_err_notify(req, GSS_S_FAILURE, 0))
+                        rc = SVC_DROP;
+
+                GOTO(out_rsikey, rc);
         }
 
         rsci = gss_svc_searchbyctx(&rsip->out_handle);
         if (!rsci) {
                 CERROR("rsci still not mature yet?\n");
 
+                rc = SVC_COMPLETE;
                 if (gss_pack_err_notify(req, GSS_S_FAILURE, 0))
                         rc = SVC_DROP;
-                else
-                        rc = SVC_COMPLETE;
 
                 GOTO(out_rsip, rc);
         }
-        CWARN("svcsec create gss context %p(%u@%s)\n",
+        CDEBUG(D_SEC, "svcsec create gss context %p(%u@%s)\n",
                rsci, rsci->cred.vc_uid,
                portals_nid2str(req->rq_peer.peer_ni->pni_number,
                                req->rq_peer.peer_id.nid, nidstr));
@@ -944,6 +976,7 @@ gss_svcsec_handle_init(struct ptlrpc_request *req,
         rc = lustre_pack_reply(req, 0, NULL, NULL);
         if (rc) {
                 CERROR("failed to pack reply, rc = %d\n", rc);
+                set_bit(CACHE_NEGATIVE, &rsci->h.flags);
                 GOTO(out, rc = SVC_DROP);
         }
 
@@ -966,11 +999,17 @@ gss_svcsec_handle_init(struct ptlrpc_request *req,
         *resp++ = cpu_to_le32(GSS_SEQ_WIN);
         reslen -= (4 * 4);
         if (rawobj_serialize(&rsip->out_handle,
-                             &resp, &reslen))
+                             &resp, &reslen)) {
+                dump_rsi(rsip);
+                dump_rsi(rsikey);
                 LBUG();
+        }
         if (rawobj_serialize(&rsip->out_token,
-                             &resp, &reslen))
+                             &resp, &reslen)) {
+                dump_rsi(rsip);
+                dump_rsi(rsikey);
                 LBUG();
+        }
         /* the actual sec data length */
         *reslenp = cpu_to_le32(svcdata->reserve_len - reslen);
 
@@ -1111,7 +1150,7 @@ gss_svcsec_handle_destroy(struct ptlrpc_request *req,
         if (lustre_pack_reply(req, 0, NULL, NULL))
                 GOTO(out, rc = SVC_DROP);
 
-        CWARN("svcsec destroy gss context %p(%u@%s)\n",
+        CDEBUG(D_SEC, "svcsec destroy gss context %p(%u@%s)\n",
                rsci, rsci->cred.vc_uid,
                portals_nid2str(req->rq_peer.peer_ni->pni_number,
                                req->rq_peer.peer_id.nid, nidstr));
@@ -1286,7 +1325,7 @@ gss_svcsec_authorize(struct ptlrpc_request *req)
                 vlen -= 7 * 4;
 
                 mic.len = vlen;
-                mic.data = (char *) vp;
+                mic.data = (unsigned char *)vp;
 
                 major = kgss_get_mic(rscp->mechctx, 0, &lmsg, &mic);
                 if (major) {