All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@redhat.com>
To: Neil Brown <neilb@suse.de>
Cc: nfs@lists.sourceforge.net
Subject: Re: [PATCH 0/2] mountd: clean up rmtab handling
Date: Mon, 04 Dec 2006 21:28:52 -0500	[thread overview]
Message-ID: <4574D964.8070504@redhat.com> (raw)
In-Reply-To: <17779.49460.590066.210744@cse.unsw.edu.au>

Neil Brown wrote:
 > It tries a bit harder to keep vaguely sensible information in rmtab
 > and if you run mounted with "-I", then "showmount -a" will list IP and
 > export-point of all current mounts ... as best as possible.
 > e.g. if you mount the same filesystem twice on the one client, then it
 > will appear once in "showmount -a".  If you then unmount one of them,
 > it will disappear.  But as soon as you access it again it will
 > re-appear.
 >
 > I think this is about the best I can do.
 >
 > Does it meet the needs?
 >

I think we need to fix the default case here instead of adding a 
workaround flag. We should also strive to make it report hostnames 
rather than ip addresses if possible. I don't see a need for the -I flag 
here.

How about this patch instead? It combines some of my earlier patches 
with the one you just proposed.  I did some very cursory testing and it 
seems to work correctly, populating rmtab with hostname:/path instead of 
ipaddr:/path.

Signed-off-by: Jeff Layton <jlayton@redhat.com>

--- nfs-utils-1.0.10/support/export/client.c.rmtab	2006-08-07 
02:40:50.000000000 -0400
+++ nfs-utils-1.0.10/support/export/client.c	2006-12-04 
20:33:51.000000000 -0500
@@ -234,102 +234,15 @@
  	return NULL;
  }

-/*
- * Find client name given an IP address
- * This is found by gathering all known names that match that IP address,
- * sorting them and joining them with '+'
- *
- */
-static char *add_name(char *old, char *add);
-
-char *
-client_compose(struct in_addr addr)
+struct hostent *
+client_resolve(struct in_addr addr)
  {
  	struct hostent *he = NULL;
-	char *name = NULL;
-	int i;

-	if (clientlist[MCL_WILDCARD] || clientlist[MCL_NETGROUP])
-		he = get_reliable_hostbyaddr((const char*)&addr, sizeof(addr), AF_INET);
+	he = get_reliable_hostbyaddr((const char*)&addr, sizeof(addr), AF_INET);
  	if (he == NULL)
  		he = get_hostent((const char*)&addr, sizeof(addr), AF_INET);
-
-	for (i = 0 ; i < MCL_MAXTYPES; i++) {
-		nfs_client	*clp;
-		for (clp = clientlist[i]; clp ; clp = clp->m_next) {
-			if (!client_check(clp, he))
-				continue;
-			name = add_name(name, clp->m_hostname);
-		}
-	}
-	return name;
-}
-
-int
-client_member(char *client, char *name)
-{
-	/* check if "client" (a ',' separated list of names)
-	 * contains 'name' as a member
-	 */
-	int l = strlen(name);
-	while (*client) {
-		if (strncmp(client, name, l) == 0 &&
-		    (client[l] == ',' || client[l] == '\0'))
-			return 1;
-		client = strchr(client, ',');
-		if (client == NULL)
-			return 0;
-		client++;
-	}
-	return 0;
-}
-
-
-int
-name_cmp(char *a, char *b)
-{
-	/* compare strings a and b, but only upto ',' in a */
-	while (*a && *b && *a != ',' && *a == *b)
-		a++, b++;
-	if (!*b && (!*a || !a == ',') )
-		return 0;
-	if (!*b) return 1;
-	if (!*a || *a == ',') return -1;
-	return *a - *b;
-}
-
-static char *
-add_name(char *old, char *add)
-{
-	int len = strlen(add)+2;
-	char *new;
-	char *cp;
-	if (old) len += strlen(old);
-	
-	new = malloc(len);
-	if (!new) {
-		free(old);
-		return NULL;
-	}
-	cp = old;
-	while (cp && *cp && name_cmp(cp, add) < 0) {
-		/* step cp forward over a name */
-		char *e = strchr(cp, ',');
-		if (e)
-			cp = e+1;
-		else
-			cp = cp + strlen(cp);
-	}
-	strncpy(new, old, cp-old);
-	new[cp-old] = 0;
-	if (cp != old && !*cp)
-		strcat(new, ",");
-	strcat(new, add);
-	if (cp && *cp) {
-		strcat(new, ",");
-		strcat(new, cp);
-	}
-	return new;
+	return he;
  }

  /*
--- nfs-utils-1.0.10/support/include/exportfs.h.rmtab	2006-08-07 
02:40:50.000000000 -0400
+++ nfs-utils-1.0.10/support/include/exportfs.h	2006-12-04 
20:38:46.000000000 -0500
@@ -55,8 +55,7 @@
  int				client_match(nfs_client *, char *hname);
  void				client_release(nfs_client *);
  void				client_freeall(void);
-char *				client_compose(struct in_addr addr);
-int 				client_member(char *client, char *name);
+struct hostent *		client_resolve(struct in_addr addr);

  int				export_read(char *fname);
  void				export_add(nfs_export *);
--- nfs-utils-1.0.10/utils/mountd/auth.c.rmtab	2006-08-07 
02:40:50.000000000 -0400
+++ nfs-utils-1.0.10/utils/mountd/auth.c	2006-12-04 20:33:51.000000000 -0500
@@ -76,27 +76,16 @@
  	if (new_cache) {
  		int i;
  		/* return static nfs_export with details filled in */
-		if (my_client.m_naddr != 1 ||
-		    my_client.m_addrlist[0].s_addr != caller->sin_addr.s_addr) {
-			/* different client to last time, so do a lookup */
-			char *n;
-			my_client.m_naddr = 0;
-			my_client.m_addrlist[0] = caller->sin_addr;
-			n = client_compose(caller->sin_addr);
-			*error = unknown_host;
-			if (!n)
-				return NULL;
-			strcpy(my_client.m_hostname, *n?n:"DEFAULT");
-			free(n);
-			my_client.m_naddr = 1;
-		}
-
+		my_client.m_addrlist[0] = caller->sin_addr;
+		my_client.m_naddr = 1;
+		strncpy(my_client.m_hostname, hp->h_name,
+			sizeof(my_client.m_hostname));
  		my_exp.m_client = &my_client;

  		exp = NULL;
  		for (i = 0; !exp && i < MCL_MAXTYPES; i++)
  			for (exp = exportlist[i]; exp; exp = exp->m_next) {
-				if (!client_member(my_client.m_hostname, exp->m_client->m_hostname))
+				if (!client_check(exp->m_client, hp))
  					continue;
  				if (strcmp(path, exp->m_export.e_path))
  					continue;
--- nfs-utils-1.0.10/utils/mountd/cache.c.rmtab	2006-08-07 
02:40:50.000000000 -0400
+++ nfs-utils-1.0.10/utils/mountd/cache.c	2006-12-04 20:37:24.000000000 
-0500
@@ -53,8 +53,8 @@
  	char *cp;
  	char class[20];
  	char ipaddr[20];
-	char *client;
  	struct in_addr addr;
+	struct hostent *he;
  	if (readline(fileno(f), &lbuf, &lbuflen) != 1)
  		return;

@@ -73,21 +73,16 @@
  	auth_reload();

  	/* addr is a valid, interesting address, find the domain name... */
-	client = client_compose(addr);
+	he = client_resolve(addr);

-	
  	qword_print(f, "nfsd");
  	qword_print(f, ipaddr);
  	qword_printint(f, time(0)+30*60);
-	if (client)
-		qword_print(f, *client?client:"DEFAULT");
+	if (he) {
+		qword_print(f, *he->h_name?he->h_name:"DEFAULT");
+		free(he);
+	}
  	qword_eol(f);
-
-	if (client && strcmp(ipaddr, client))
-		mountlist_add(ipaddr, *client?client:"DEFAULT");
-
-	if (client) free(client);
-	
  }

  void nfsd_fh(FILE *f)
@@ -109,6 +104,7 @@
  	nfs_export *exp;
  	int i;
  	int dev_missing = 0;
+	struct hostent *hp = NULL;

  	if (readline(fileno(f), &lbuf, &lbuflen) != 1)
  		return;
@@ -170,11 +166,12 @@
  	auth_reload();

  	/* Now determine export point for this fsid/domain */
+	hp = gethostbyname(dom);
  	for (i=0 ; i < MCL_MAXTYPES; i++) {
  		for (exp = exportlist[i]; exp; exp = exp->m_next) {
  			struct stat stb;

-			if (!client_member(dom, exp->m_client->m_hostname))
+			if (!client_check(exp->m_client, hp))
  				continue;
  			if (exp->m_export.e_mountpoint &&
  			    !is_mountpoint(exp->m_export.e_mountpoint[0]?
@@ -251,6 +248,7 @@
  	int i;
  	char *dom, *path;
  	nfs_export *exp, *found = NULL;
+	struct hostent *hp;


  	if (readline(fileno(f), &lbuf, &lbuflen) != 1)
@@ -271,9 +269,10 @@
  	auth_reload();

  	/* now find flags for this export point in this domain */
+	hp = gethostbyname(dom);
  	for (i=0 ; i < MCL_MAXTYPES; i++) {
  		for (exp = exportlist[i]; exp; exp = exp->m_next) {
-			if (!client_member(dom, exp->m_client->m_hostname))
+			if (!client_check(exp->m_client, hp))
  				continue;
  			if (strcmp(path, exp->m_export.e_path))
  				continue;
@@ -377,6 +376,23 @@
  	mountlist_add(domain, exp->e_path);
  }

+void cache_export_flush(char *domain, struct exportent *exp)
+{
+
+	FILE *f = fopen("/proc/net/rpc/nfsd.export/channel", "w");
+	if (!f)
+		return;
+
+	qword_print(f, domain);
+	qword_print(f, exp->e_path);
+	qword_printint(f, time(0)-60);
+	qword_eol(f);
+
+	fclose(f);
+
+	mountlist_del(domain, exp->e_path, 1);
+}
+
  void cache_export(nfs_export *exp)
  {
  	FILE *f;
@@ -393,9 +409,6 @@
  	
  	fclose(f);

-	if (strcmp(inet_ntoa(exp->m_client->m_addrlist[0]), 
exp->m_client->m_hostname))
-		mountlist_add(inet_ntoa(exp->m_client->m_addrlist[0]), 
exp->m_client->m_hostname);
-
  	cache_export_ent(exp->m_client->m_hostname, &exp->m_export);
  }

--- nfs-utils-1.0.10/utils/mountd/mountd.c.rmtab	2006-08-07 
02:40:50.000000000 -0400
+++ nfs-utils-1.0.10/utils/mountd/mountd.c	2006-12-04 20:33:51.000000000 
-0500
@@ -30,6 +30,7 @@
  extern void	cache_open(void);
  extern struct nfs_fh_len *cache_get_filehandle(nfs_export *exp, int 
len, char *p);
  extern void cache_export(nfs_export *exp);
+extern void cache_export_flush(char *domain, struct exportent *exp);

  extern void my_svc_run(void);

@@ -226,11 +227,10 @@
  		return 1;
  	}
  	if (new_cache) {
-		if (strcmp(inet_ntoa(exp->m_client->m_addrlist[0]), 
exp->m_client->m_hostname))
-			mountlist_del(inet_ntoa(exp->m_client->m_addrlist[0]), 
exp->m_client->m_hostname);
-		mountlist_del(exp->m_client->m_hostname, p);
+		cache_export_flush(exp->m_client->m_hostname,
+				   &exp->m_export);
  	} else {
-		mountlist_del(exp->m_client->m_hostname, p);
+		mountlist_del(exp->m_client->m_hostname, p, 0);
  		export_reset (exp);
  	}
  	return 1;
--- nfs-utils-1.0.10/utils/mountd/mountd.h.rmtab	2006-08-07 
02:40:50.000000000 -0400
+++ nfs-utils-1.0.10/utils/mountd/mountd.h	2006-12-04 20:33:51.000000000 
-0500
@@ -46,7 +46,7 @@
  void		auth_export(nfs_export *exp);

  void		mountlist_add(char *host, const char *path);
-void		mountlist_del(char *host, const char *path);
+void		mountlist_del(char *host, const char *path, int force);
  void		mountlist_del_all(struct sockaddr_in *sin);
  mountlist	mountlist_list(void);

--- nfs-utils-1.0.10/utils/mountd/rmtab.c.rmtab	2006-08-07 
02:40:50.000000000 -0400
+++ nfs-utils-1.0.10/utils/mountd/rmtab.c	2006-12-04 20:33:51.000000000 
-0500
@@ -11,6 +11,7 @@
  #endif

  #include <sys/types.h>
+#include <time.h>
  #include <sys/stat.h>
  #include <unistd.h>
  #include <netinet/in.h>
@@ -89,7 +90,7 @@
  }

  void
-mountlist_del(char *hname, const char *path)
+mountlist_del(char *hname, const char *path, int force)
  {
  	struct rmtabent	*rep;
  	FILE		*fp;
@@ -115,7 +116,7 @@
  			/* PRC: do the HA callout: */
  			ha_callout("unmount", rep->r_client, rep->r_path, rep->r_count);
  		}
-		if (!match || rep->r_count)
+		if (!match || (!force && rep->r_count))
  			fputrmtabent(fp, rep, NULL);
  	}
  	if (slink_safe_rename(_PATH_RMTABTMP, _PATH_RMTAB) < 0) {
@@ -200,6 +201,8 @@
  			xfree(m);
  		}
  		last_mtime = stb.st_mtime;
+		if (last_mtime == time(0))
+			last_mtime--;

  		setrmtabent("r");
  		while ((rep = getrmtabent(1, NULL)) != NULL) {

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

  reply	other threads:[~2006-12-05  2:27 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-10-25 13:07 [PATCH 0/2] mountd: clean up rmtab handling Jeff Layton
2006-12-01 15:29 ` Jeff Layton
2006-12-04  4:38   ` Neil Brown
2006-12-04  6:33     ` Neil Brown
2006-12-05  2:28       ` Jeff Layton [this message]
2006-12-05  2:51         ` Jeff Layton
2006-12-09 12:27           ` Jeff Layton
2006-12-04 15:05     ` Jeff Layton
2006-12-11  1:00       ` Neil Brown
2006-12-11  3:40         ` Jeff Layton
2006-12-12  1:07           ` Neil Brown
2006-12-12  7:52             ` Warren Beldad
2006-12-13 13:17             ` Jeff Layton

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=4574D964.8070504@redhat.com \
    --to=jlayton@redhat.com \
    --cc=neilb@suse.de \
    --cc=nfs@lists.sourceforge.net \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.