linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: NeilBrown <neilb@suse.de>
To: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Steve Dickson <SteveD@RedHat.com>,
	Linux NFS Mailing list <linux-nfs@vger.kernel.org>
Subject: [PATCH v2] mountd/exportd: only log confirmed clients, and poll for updates
Date: Sat, 20 Mar 2021 09:39:23 +1100	[thread overview]
Message-ID: <87eegaepk4.fsf@notabene.neil.brown.name> (raw)
In-Reply-To: <87sg4rerta.fsf@notabene.neil.brown.name>

[-- Attachment #1: Type: text/plain, Size: 4759 bytes --]


It is possible (and common with the Linux NFS client) for the nfs server
to receive multiple SET_CLIENT_ID or EXCHANGE_ID requests when starting
a connection.  This results in some clients appearing in
 /proc/fs/nfsd/clients
which never get confirmed.  mountd currently logs these, but they aren't
really helpful.

If the kernel supports the reporting of the confirmation status of
clients, we can suppress the message until a client is confirmed.

With this patch we:
 - record if the client is confirmed, assuming it is if the status is
    not reported
 - don't log unconfirmed clients
 - request MODIFY notification from unconfirmed clients.
 - recheck an info file when it is modified.

Signed-off-by: NeilBrown <neilb@suse.de>
---
 support/export/v4clients.c | 86 +++++++++++++++++++++++++++++---------
 1 file changed, 67 insertions(+), 19 deletions(-)

diff --git a/support/export/v4clients.c b/support/export/v4clients.c
index 056ddc9b065d..f2c9bb482ba7 100644
--- a/support/export/v4clients.c
+++ b/support/export/v4clients.c
@@ -48,12 +48,15 @@ void v4clients_set_fds(fd_set *fdset)
 }
 
 static void *tree_root;
+static int have_unconfirmed;
 
 struct ent {
 	unsigned long num;
 	char *clientid;
 	char *addr;
 	int vers;
+	int unconfirmed;
+	int wid;
 };
 
 static int ent_cmp(const void *av, const void *bv)
@@ -89,15 +92,14 @@ static char *dup_line(char *line)
 	return ret;
 }
 
-static void add_id(int id)
+static void read_info(struct ent *key)
 {
 	char buf[2048];
-	struct ent **ent;
-	struct ent *key;
 	char *path;
+	int was_unconfirmed = key->unconfirmed;
 	FILE *f;
 
-	if (asprintf(&path, "/proc/fs/nfsd/clients/%d/info", id) < 0)
+	if (asprintf(&path, "/proc/fs/nfsd/clients/%lu/info", key->num) < 0)
 		return;
 
 	f = fopen(path, "r");
@@ -105,35 +107,64 @@ static void add_id(int id)
 		free(path);
 		return;
 	}
-	key = calloc(1, sizeof(*key));
-	if (!key) {
-		fclose(f);
-		free(path);
-		return;
-	}
-	key->num = id;
+	if (key->wid < 0)
+		key->wid = inotify_add_watch(clients_fd, path, IN_MODIFY);
+
 	while (fgets(buf, sizeof(buf), f)) {
-		if (strncmp(buf, "clientid: ", 10) == 0)
+		if (strncmp(buf, "clientid: ", 10) == 0) {
+			free(key->clientid);
 			key->clientid = dup_line(buf+10);
-		if (strncmp(buf, "address: ", 9) == 0)
+		}
+		if (strncmp(buf, "address: ", 9) == 0) {
+			free(key->addr);
 			key->addr = dup_line(buf+9);
+		}
 		if (strncmp(buf, "minor version: ", 15) == 0)
 			key->vers = atoi(buf+15);
+		if (strncmp(buf, "status: ", 8) == 0 &&
+		    strstr(buf, " unconfirmed") != NULL) {
+			key->unconfirmed = 1;
+			have_unconfirmed = 1;
+		}
+		if (strncmp(buf, "status: ", 8) == 0 &&
+		    strstr(buf, " confirmed") != NULL)
+			key->unconfirmed = 0;
 	}
 	fclose(f);
 	free(path);
 
-	xlog(L_NOTICE, "v4.%d client attached: %s from %s",
-	     key->vers, key->clientid, key->addr);
+	if (was_unconfirmed && !key->unconfirmed)
+		xlog(L_NOTICE, "v4.%d client attached: %s from %s",
+		     key->vers, key->clientid ?: "-none-",
+		     key->addr ?: "-none-");
+	if (!key->unconfirmed && ent->wid >= 0) {
+		inotify_rm_watch(clients_fd, ent->wid);
+		ent->wid = -1;
+	}
+}
+
+static void add_id(int id)
+{
+	struct ent **ent;
+	struct ent *key;
+
+	key = calloc(1, sizeof(*key));
+	if (!key) {
+		return;
+	}
+	key->num = id;
+	key->wid = -1;
 
 	ent = tsearch(key, &tree_root, ent_cmp);
 
 	if (!ent || *ent != key)
 		/* Already existed, or insertion failed */
 		free_ent(key);
+	else
+		read_info(key);
 }
 
-static void del_id(int id)
+static void del_id(unsigned long id)
 {
 	struct ent key = {.num = id};
 	struct ent **e, *ent;
@@ -143,11 +174,27 @@ static void del_id(int id)
 		return;
 	ent = *e;
 	tdelete(ent, &tree_root, ent_cmp);
-	xlog(L_NOTICE, "v4.%d client detached: %s from %s",
-	     ent->vers, ent->clientid, ent->addr);
+	if (!ent->unconfirmed)
+		xlog(L_NOTICE, "v4.%d client detached: %s from %s",
+		     ent->vers, ent->clientid, ent->addr);
+	if (ent->wid >= 0)
+		inotify_rm_watch(clients_fd, ent->wid);
 	free_ent(ent);
 }
 
+static void check_id(unsigned long id)
+{
+	struct ent key = {.num = id};
+	struct ent **e, *ent;
+
+	e = tfind(&key, &tree_root, ent_cmp);
+	if (!e || !*e)
+		return;
+	ent = *e;
+	if (ent->unconfirmed)
+		read_info(ent);
+}
+
 int v4clients_process(fd_set *fdset)
 {
 	char buf[4096] __attribute__((aligned(__alignof__(struct inotify_event))));
@@ -172,8 +219,9 @@ int v4clients_process(fd_set *fdset)
 				add_id(id);
 			if (ev->mask & IN_DELETE)
 				del_id(id);
+			if (ev->mask & IN_MODIFY)
+				check_id(id);
 		}
 	}
 	return 1;
 }
-
-- 
2.30.1


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 853 bytes --]

  parent reply	other threads:[~2021-03-19 22:40 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-01  2:17 [PATCH 0/5 v2] nfs-utils: provide audit-logging of NFSv4 access NeilBrown
2021-03-01  2:17 ` [PATCH 5/5] mountd: make default ttl settable by option NeilBrown
2021-03-01  2:17 ` [PATCH 3/5] mountd: add logging for authentication results for accesses NeilBrown
2021-03-01  2:17 ` [PATCH 2/5] mountd: Don't proactively add export info when fh info is requested NeilBrown
2021-03-01  2:17 ` [PATCH 1/5] mountd: reject unknown client IP when !use_ipaddr NeilBrown
2021-03-01  2:17 ` [PATCH 4/5] mountd: add --cache-use-ipaddr option to force use_ipaddr NeilBrown
2021-03-01  3:43 ` [PATCH 0/5 v2] nfs-utils: provide audit-logging of NFSv4 access Yongcheng Yang
2021-03-02  2:26   ` NeilBrown
2021-03-01 18:50 ` J. Bruce Fields
2021-03-01 21:59   ` NeilBrown
2021-03-02  3:01   ` NeilBrown
2021-03-02  3:27     ` J. Bruce Fields
2021-03-02  3:49       ` NeilBrown
2021-03-02  4:05         ` J. Bruce Fields
2021-03-19  3:36       ` NeilBrown
2021-03-19  3:37         ` [PATCH] nfsd: report client confirmation status in "info" file NeilBrown
2021-03-19  3:38           ` [PATCH] mountd/exportd: only log confirmed clients, and poll for updates NeilBrown
2021-03-19 14:15             ` J. Bruce Fields
2021-03-19 20:43               ` NeilBrown
2021-03-19 22:39             ` NeilBrown [this message]
2021-03-22 14:30               ` [PATCH v2] " Chuck Lever III
2021-04-07 18:26               ` Steve Dickson
2021-03-19 22:38           ` [PATCH v2] nfsd: report client confirmation status in "info" file NeilBrown
2022-05-18 14:45             ` Chuck Lever III
2022-05-18 15:26               ` Chuck Lever III
2021-03-19 13:28         ` [PATCH 0/5 v2] nfs-utils: provide audit-logging of NFSv4 access J. Bruce Fields
2021-03-19 20:48           ` NeilBrown
2021-03-19 21:09             ` J. Bruce Fields
2021-03-22 17:06               ` J. Bruce Fields
2021-04-07 19:14               ` J. Bruce Fields
2021-04-07 19:33                 ` Steve Dickson
2021-04-07 19:55                   ` J. Bruce Fields

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87eegaepk4.fsf@notabene.neil.brown.name \
    --to=neilb@suse.de \
    --cc=SteveD@RedHat.com \
    --cc=bfields@fieldses.org \
    --cc=linux-nfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).