From owner-svn-src-stable-10@freebsd.org Wed Jun 6 22:18:25 2018 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2E2C5FE4FCD; Wed, 6 Jun 2018 22:18:25 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id CDF58698E3; Wed, 6 Jun 2018 22:18:24 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 86EEB10EB3; Wed, 6 Jun 2018 22:18:24 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w56MIOFR077173; Wed, 6 Jun 2018 22:18:24 GMT (envelope-from rmacklem@FreeBSD.org) Received: (from rmacklem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w56MIOVQ077172; Wed, 6 Jun 2018 22:18:24 GMT (envelope-from rmacklem@FreeBSD.org) Message-Id: <201806062218.w56MIOVQ077172@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: rmacklem set sender to rmacklem@FreeBSD.org using -f From: Rick Macklem Date: Wed, 6 Jun 2018 22:18:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r334741 - stable/10/sys/fs/nfsserver X-SVN-Group: stable-10 X-SVN-Commit-Author: rmacklem X-SVN-Commit-Paths: stable/10/sys/fs/nfsserver X-SVN-Commit-Revision: 334741 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 Jun 2018 22:18:25 -0000 Author: rmacklem Date: Wed Jun 6 22:18:24 2018 New Revision: 334741 URL: https://svnweb.freebsd.org/changeset/base/334741 Log: MFC: r333580 Fix a slow leak of session structures in the NFSv4.1 server. For a fairly rare case of a client doing an ExchangeID after a hard reboot, the old confirmed clientid still exists, but some clients use a new co_verifier. For this case, the server was not freeing up the sessions on the old confirmed clientid. This patch fixes this case. It also adds two LIST_INIT() macros, which are actually no-ops, since the structure is malloc()d with M_ZERO so the pointer is already set to NULL. It should have minimal impact, since the only way I could exercise this code path was by doing a hard power cycle (pulling the plus) on a machine running Linux with a NFSv4.1 mount on the server. Originally spotted during testing of the ESXi 6.5 client. PR: 228497 Modified: stable/10/sys/fs/nfsserver/nfs_nfsdstate.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/fs/nfsserver/nfs_nfsdstate.c ============================================================================== --- stable/10/sys/fs/nfsserver/nfs_nfsdstate.c Wed Jun 6 22:02:44 2018 (r334740) +++ stable/10/sys/fs/nfsserver/nfs_nfsdstate.c Wed Jun 6 22:18:24 2018 (r334741) @@ -183,9 +183,10 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsc nfsquad_t *clientidp, nfsquad_t *confirmp, NFSPROC_T *p) { struct nfsclient *clp = NULL, *new_clp = *new_clpp; - int i, error = 0; + int i, error = 0, ret; struct nfsstate *stp, *tstp; struct sockaddr_in *sad, *rad; + struct nfsdsession *sep, *nsep; int zapit = 0, gotit, hasstate = 0, igotlock; static u_int64_t confirm_index = 0; @@ -355,6 +356,15 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsc * can be thrown away once the SETCLIENTID_CONFIRM occurs. */ LIST_REMOVE(clp, lc_hash); + + /* Get rid of all sessions on this clientid. */ + LIST_FOREACH_SAFE(sep, &clp->lc_session, sess_list, nsep) { + ret = nfsrv_freesession(sep, NULL); + if (ret != 0) + printf("nfsrv_setclient: verifier changed free" + " session failed=%d\n", ret); + } + new_clp->lc_flags |= LCL_NEEDSCONFIRM; if ((nd->nd_flag & ND_NFSV41) != 0) new_clp->lc_confirm.lval[0] = confirmp->lval[0] = @@ -390,6 +400,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsc LIST_FOREACH(tstp, &new_clp->lc_stateid[i], ls_hash) tstp->ls_clp = new_clp; } + LIST_INIT(&new_clp->lc_session); LIST_INSERT_HEAD(NFSCLIENTHASH(new_clp->lc_clientid), new_clp, lc_hash); newnfsstats.srvclients++; @@ -454,6 +465,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsc LIST_FOREACH(tstp, &new_clp->lc_stateid[i], ls_hash) tstp->ls_clp = new_clp; } + LIST_INIT(&new_clp->lc_session); LIST_INSERT_HEAD(NFSCLIENTHASH(new_clp->lc_clientid), new_clp, lc_hash); newnfsstats.srvclients++;