Linux NFS development
 help / color / mirror / Atom feed
* [PATCH 0/4] Support IPv6 in umount.nfs command
@ 2009-01-28 23:07 Chuck Lever
       [not found] ` <20090128225938.21484.82096.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  0 siblings, 1 reply; 6+ messages in thread
From: Chuck Lever @ 2009-01-28 23:07 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

Hi Steve-

The first patch in this series is a simple update to .gitignore.

The following patches implement support for IPv6 addresses in the
umount.nfs command.

I think it would be prudent to stop after this set, and let the
extensive changes I've submitted so far soak a little bit.  These
probably won't see wide-ranging use until after the next release of
nfs-utils, I'm guessing.

Given the problems that arose after the last nfs-utils release, I
think this might be a good stopping point until after the next
nfs-utils release.  By then, I might even have full support completed
for IPv6 in rpc.statd and sm-notify.

---

Chuck Lever (4):
      umount command: remove do_nfs_umount23 function
      umount.nfs command: Support AF_INET6 server addresses
      umount.nfs command: Add an AF_INET6-capable version of nfs_call_unmount()
      nfs-utils: git should ignore cscope.* files


 .gitignore              |    2 +
 utils/mount/network.c   |   53 ++++++++++++++++
 utils/mount/network.h   |    4 +
 utils/mount/nfsumount.c |  158 ++++++++++++++++++++++++-----------------------
 4 files changed, 138 insertions(+), 79 deletions(-)

-- 
Chuck Lever < chuck [dot] lever [at] oracle [dot] com >

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] nfs-utils: git should ignore cscope.* files
       [not found] ` <20090128225938.21484.82096.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
@ 2009-01-28 23:07   ` Chuck Lever
  2009-01-28 23:07   ` [PATCH 2/4] umount.nfs command: Add an AF_INET6-capable version of nfs_call_unmount() Chuck Lever
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Chuck Lever @ 2009-01-28 23:07 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

Tell git to ignore cscope database files.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 .gitignore |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore
index a5cf8ce..cfc329a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -54,5 +54,7 @@ utils/statd/sm_inter.h
 utils/statd/sm_inter_clnt.c
 utils/statd/sm_inter_svc.c
 utils/statd/sm_inter_xdr.c
+# cscope database files
+cscope.*
 # generic editor backup et al
 *~


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] umount.nfs command: Add an AF_INET6-capable version of nfs_call_unmount()
       [not found] ` <20090128225938.21484.82096.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  2009-01-28 23:07   ` [PATCH 1/4] nfs-utils: git should ignore cscope.* files Chuck Lever
@ 2009-01-28 23:07   ` Chuck Lever
  2009-01-28 23:07   ` [PATCH 3/4] umount.nfs command: Support AF_INET6 server addresses Chuck Lever
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Chuck Lever @ 2009-01-28 23:07 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

We need an AF_INET6-capable version of nfs_call_unmount() to allow the
umount.nfs command to support unmounting NFS servers over IPv6.  The legacy
mount.nfs command still likes to use nfs_call_umount(), so we leave it in
place and introduce a new API that can take a "struct sockaddr *".

The umount.nfs command will invoke this new API, but we'll leave the legacy
mount.nfs command and the umount.nfs4 command alone.  The umount.nfs4
command does not need this support because NFSv4 unmount operations are
entirely local.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 utils/mount/network.c |   53 +++++++++++++++++++++++++++++++++++++++++++++++++
 utils/mount/network.h |    4 +++-
 2 files changed, 56 insertions(+), 1 deletions(-)

diff --git a/utils/mount/network.c b/utils/mount/network.c
index 91a005c..174d7f6 100644
--- a/utils/mount/network.c
+++ b/utils/mount/network.c
@@ -838,6 +838,59 @@ int start_statd(void)
 }
 
 /**
+ * nfs_advise_umount - ask the server to remove a share from it's rmtab
+ * @sap: pointer to IP address of server to call
+ * @salen: length of server address
+ * @pmap: partially filled-in mountd RPC service tuple
+ * @argp: directory path of share to "unmount"
+ *
+ * Returns one if the unmount call succeeded; zero if the unmount
+ * failed for any reason;  rpccreateerr.cf_stat is set to reflect
+ * the nature of the error.
+ *
+ * We use a fast timeout since this call is advisory only.
+ */
+int nfs_advise_umount(const struct sockaddr *sap, const socklen_t salen,
+		      const struct pmap *pmap, const dirpath *argp)
+{
+	struct sockaddr_storage address;
+	struct sockaddr *saddr = (struct sockaddr *)&address;
+	struct pmap mnt_pmap = *pmap;
+	struct timeval timeout = {
+		.tv_sec		= MOUNT_TIMEOUT >> 3,
+	};
+	CLIENT *client;
+	enum clnt_stat res = 0;
+
+	if (nfs_probe_mntport(sap, salen, &mnt_pmap) == 0)
+		return 0;
+
+	memcpy(saddr, sap, salen);
+	nfs_set_port(saddr, mnt_pmap.pm_port);
+
+	client = nfs_get_rpcclient(saddr, salen, mnt_pmap.pm_prot,
+					mnt_pmap.pm_prog, mnt_pmap.pm_vers,
+					&timeout);
+	if (client == NULL)
+		return 0;
+
+	client->cl_auth = authunix_create_default();
+
+	res = CLNT_CALL(client, MOUNTPROC_UMNT,
+			(xdrproc_t)xdr_dirpath, (caddr_t)argp,
+			(xdrproc_t)xdr_void, NULL,
+			timeout);
+
+	auth_destroy(client->cl_auth);
+	CLNT_DESTROY(client);
+
+	if (res != RPC_SUCCESS)
+		return 0;
+
+	return 1;
+}
+
+/**
  * nfs_call_umount - ask the server to remove a share from it's rmtab
  * @mnt_server: address of RPC MNT program server
  * @argp: directory path of share to "unmount"
diff --git a/utils/mount/network.h b/utils/mount/network.h
index 25060ab..0dd90f8 100644
--- a/utils/mount/network.h
+++ b/utils/mount/network.h
@@ -52,7 +52,6 @@ int nfs_present_sockaddr(const struct sockaddr *,
 			 const socklen_t, char *, const size_t);
 int nfs_callback_address(const struct sockaddr *, const socklen_t,
 		struct sockaddr *, socklen_t *);
-int nfs_call_umount(clnt_addr_t *, dirpath *);
 int clnt_ping(struct sockaddr_in *, const unsigned long,
 		const unsigned long, const unsigned int,
 		struct sockaddr_in *);
@@ -66,6 +65,9 @@ int start_statd(void);
 
 unsigned long nfsvers_to_mnt(const unsigned long);
 
+int nfs_call_umount(clnt_addr_t *, dirpath *);
+int nfs_advise_umount(const struct sockaddr *, const socklen_t,
+		      const struct pmap *, const dirpath *);
 CLIENT *mnt_openclnt(clnt_addr_t *, int *);
 void mnt_closeclnt(CLIENT *, int);
 


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] umount.nfs command: Support AF_INET6 server addresses
       [not found] ` <20090128225938.21484.82096.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  2009-01-28 23:07   ` [PATCH 1/4] nfs-utils: git should ignore cscope.* files Chuck Lever
  2009-01-28 23:07   ` [PATCH 2/4] umount.nfs command: Add an AF_INET6-capable version of nfs_call_unmount() Chuck Lever
@ 2009-01-28 23:07   ` Chuck Lever
  2009-01-28 23:07   ` [PATCH 4/4] umount command: remove do_nfs_umount23 function Chuck Lever
  2009-02-17 21:27   ` [PATCH 0/4] Support IPv6 in umount.nfs command Steve Dickson
  4 siblings, 0 replies; 6+ messages in thread
From: Chuck Lever @ 2009-01-28 23:07 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

Replace existing mount option parser in nfsumount.c with the new pmap stuffer
function nfs_options2pmap().  Mount option parsing for umount.nfs now works
the same as it does for mount option rewriting in the text-based mount.nfs
command.

This adds a number of new features:

  1.  The new logic supports resolving AF_INET6 server addresses
  2.  Support is added for the recently introduced "mountaddr" option.
  3.  Parsing numeric option values is much more careful
  4.  Option parsing no longer uses xmalloc/xstrdup, so it won't fail
      silently if memory can't be allocated
  5.  Mount program number set in /etc/rpc is respected
  6.  Mount doesn't exit with EX_USAGE if the hostname lookup fails

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 utils/mount/nfsumount.c |  103 +++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 99 insertions(+), 4 deletions(-)

diff --git a/utils/mount/nfsumount.c b/utils/mount/nfsumount.c
index b2327e0..04990f0 100644
--- a/utils/mount/nfsumount.c
+++ b/utils/mount/nfsumount.c
@@ -34,6 +34,7 @@
 #include "mount.h"
 #include "error.h"
 #include "network.h"
+#include "parse_opt.h"
 #include "parse_dev.h"
 
 #if !defined(MNT_FORCE)
@@ -134,6 +135,100 @@ static int del_mtab(const char *spec, const char *node)
 }
 
 /*
+ * Discover mount server's hostname/address by examining mount options
+ *
+ * Returns a pointer to a string that the caller must free, on
+ * success; otherwise NULL is returned.
+ */
+static char *nfs_umount_hostname(struct mount_options *options,
+				 char *hostname)
+{
+	char *option;
+
+	option = po_get(options, "mountaddr");
+	if (option)
+		goto out;
+	option = po_get(options, "mounthost");
+	if (option)
+		goto out;
+	option = po_get(options, "addr");
+	if (option)
+		goto out;
+
+	return hostname;
+
+out:
+	free(hostname);
+	return strdup(option);
+}
+
+/*
+ * Returns EX_SUCCESS if mount options and device name have been
+ * parsed successfully; otherwise EX_FAIL.
+ */
+static int nfs_umount_do_umnt(struct mount_options *options,
+			      char **hostname, char **dirname)
+{
+	struct sockaddr_storage address;
+	struct sockaddr *sap = (struct sockaddr *)&address;
+	socklen_t salen = sizeof(address);
+	struct pmap nfs_pmap, mnt_pmap;
+
+	nfs_options2pmap(options, &nfs_pmap, &mnt_pmap);
+
+	*hostname = nfs_umount_hostname(options, *hostname);
+	if (!*hostname) {
+		nfs_error(_("%s: out of memory"), progname);
+		return EX_FAIL;
+	}
+
+	if (nfs_name_to_address(*hostname, AF_UNSPEC, sap, &salen)) {
+		if (nfs_advise_umount(sap, salen, &mnt_pmap, dirname) != 0)
+			return EX_SUCCESS;
+		else
+			nfs_error(_("%s: Server failed to unmount '%s:%s'"),
+					progname, *hostname, *dirname);
+	}
+	return EX_FAIL;
+}
+
+/*
+ * Pick up certain mount options used during the original mount
+ * from /etc/mtab.  The basics include the server's IP address and
+ * the server pathname of the share to unregister.
+ *
+ * These options might also describe the mount port, mount protocol
+ * version, and transport protocol used to punch through a firewall.
+ * We will need this information to get through the firewall again
+ * to do the umount.
+ *
+ * Note that option parsing failures won't necessarily cause the
+ * umount request to fail.  Those values will be left zero in the
+ * pmap tuple.  If the GETPORT call later fails to disambiguate them,
+ * then we fail.
+ */
+static int nfs_umount23(const char *devname, char *string)
+{
+	char *hostname, *dirname;
+	struct mount_options *options;
+	int result = EX_FAIL;
+
+	if (!nfs_parse_devname(devname, &hostname, &dirname))
+		return EX_USAGE;
+
+	options = po_split(string);
+	if (options) {
+		result = nfs_umount_do_umnt(options, &hostname, &dirname);
+		po_destroy(options);
+	} else
+		nfs_error(_("%s: option parsing error"), progname);
+
+	free(hostname);
+	free(dirname);
+	return result;
+}
+
+/*
  * Pick up certain mount options used during the original mount
  * from /etc/mtab.  The basics include the server's IP address and
  * the server pathname of the share to unregister.
@@ -350,16 +445,16 @@ int nfsumount(int argc, char *argv[])
 	ret = 0;
 	if (mc) {
 		if (!lazy && strcmp(mc->m.mnt_type, "nfs4") != 0)
-			/* We ignore the error from do_nfs_umount23.
+			/* We ignore the error from nfs_umount23.
 			 * If the actual umount succeeds (in del_mtab),
 			 * we don't want to signal an error, as that
 			 * could cause /sbin/mount to retry!
 			 */
-			do_nfs_umount23(mc->m.mnt_fsname, mc->m.mnt_opts);
-		ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir);
+			nfs_umount23(mc->m.mnt_fsname, mc->m.mnt_opts);
+		ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir) ?: ret;
 	} else if (*spec != '/') {
 		if (!lazy)
-			ret = do_nfs_umount23(spec, "tcp,v3");
+			ret = nfs_umount23(spec, "tcp,v3");
 	} else
 		ret = del_mtab(NULL, spec);
 


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] umount command: remove do_nfs_umount23 function
       [not found] ` <20090128225938.21484.82096.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (2 preceding siblings ...)
  2009-01-28 23:07   ` [PATCH 3/4] umount.nfs command: Support AF_INET6 server addresses Chuck Lever
@ 2009-01-28 23:07   ` Chuck Lever
  2009-02-17 21:27   ` [PATCH 0/4] Support IPv6 in umount.nfs command Steve Dickson
  4 siblings, 0 replies; 6+ messages in thread
From: Chuck Lever @ 2009-01-28 23:07 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

Remove do_nfs_umount23() now that it is unused.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 utils/mount/nfsumount.c |   93 -----------------------------------------------
 1 files changed, 0 insertions(+), 93 deletions(-)

diff --git a/utils/mount/nfsumount.c b/utils/mount/nfsumount.c
index 04990f0..78ebd4a 100644
--- a/utils/mount/nfsumount.c
+++ b/utils/mount/nfsumount.c
@@ -228,99 +228,6 @@ static int nfs_umount23(const char *devname, char *string)
 	return result;
 }
 
-/*
- * Pick up certain mount options used during the original mount
- * from /etc/mtab.  The basics include the server's IP address and
- * the server pathname of the share to unregister.
- *
- * These options might also describe the mount port, mount protocol
- * version, and transport protocol used to punch through a firewall.
- * We will need this information to get through the firewall again
- * to do the umount.
- */
-static int do_nfs_umount23(const char *spec, char *opts)
-{
-	char *hostname;
-	char *dirname;
-	clnt_addr_t mnt_server = { &hostname, };
-	struct mntent mnt = { .mnt_opts = opts };
-	struct pmap *pmap = &mnt_server.pmap;
-	char *p;
-	int result = EX_USAGE;
-
-	if (!nfs_parse_devname(spec, &hostname, &dirname))
-		return result;
-
-#ifdef NFS_MOUNT_DEBUG
-	printf(_("host: %s, directory: %s\n"), hostname, dirname);
-#endif
-
-	if (opts && (p = strstr(opts, "addr="))) {
-		char *q;
-
-		free(hostname);
-		p += 5;
-		q = p;
-		while (*q && *q != ',') q++;
-		hostname = xstrndup(p,q-p);
-	}
-
-	if (opts && (p = strstr(opts, "mounthost="))) {
-		char *q;
-
-		free(hostname);
-		p += 10;
-		q = p;
-		while (*q && *q != ',') q++;
-		hostname = xstrndup(p,q-p);
-	}
-
-	pmap->pm_prog = MOUNTPROG;
-	pmap->pm_vers = 0; /* unknown */
-	if (opts && (p = strstr(opts, "mountprog=")) && isdigit(*(p+10)))
-		pmap->pm_prog = atoi(p+10);
-	if (opts && (p = strstr(opts, "mountport=")) && isdigit(*(p+10)))
-		pmap->pm_port = atoi(p+10);
-	if (opts && hasmntopt(&mnt, "v2"))
-		pmap->pm_vers = nfsvers_to_mnt(2);
-	if (opts && hasmntopt(&mnt, "v3"))
-		pmap->pm_vers = nfsvers_to_mnt(3);
-	if (opts && (p = strstr(opts, "vers=")) && isdigit(*(p+5)))
-		pmap->pm_vers = nfsvers_to_mnt(atoi(p+5));
-	if (opts && (p = strstr(opts, "mountvers=")) && isdigit(*(p+10)))
-		pmap->pm_vers = atoi(p+10);
-	if (opts && (hasmntopt(&mnt, "udp")
-		     || hasmntopt(&mnt, "proto=udp")
-		     || hasmntopt(&mnt, "mountproto=udp")
-		    ))
-		pmap->pm_prot = IPPROTO_UDP;
-	if (opts && (hasmntopt(&mnt, "tcp")
-		     || hasmntopt(&mnt, "proto=tcp")
-		     || hasmntopt(&mnt, "mountproto=tcp")
-		    ))
-		pmap->pm_prot = IPPROTO_TCP;
-
-	if (!nfs_gethostbyname(hostname, &mnt_server.saddr)) {
-		nfs_error(_("%s: DNS resolution of '%s' failed"),
-				progname, hostname);
-		goto out;
-	}
-
-	if (!nfs_call_umount(&mnt_server, &dirname)) {
-		nfs_error(_("%s: Server failed to unmount '%s'"),
-				progname, spec);
-		result = EX_FAIL;
-		goto out;
-	}
-
-	result = EX_SUCCESS;
-
-out:
-	free(hostname);
-	free(dirname);
-	return result;
-}
-
 static struct option umount_longopts[] =
 {
   { "force", 0, 0, 'f' },


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/4] Support IPv6 in umount.nfs command
       [not found] ` <20090128225938.21484.82096.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
                     ` (3 preceding siblings ...)
  2009-01-28 23:07   ` [PATCH 4/4] umount command: remove do_nfs_umount23 function Chuck Lever
@ 2009-02-17 21:27   ` Steve Dickson
  4 siblings, 0 replies; 6+ messages in thread
From: Steve Dickson @ 2009-02-17 21:27 UTC (permalink / raw)
  To: Chuck Lever; +Cc: linux-nfs



Chuck Lever wrote:
> Hi Steve-
> 
> The first patch in this series is a simple update to .gitignore.
> 
> The following patches implement support for IPv6 addresses in the
> umount.nfs command.
> 
> I think it would be prudent to stop after this set, and let the
> extensive changes I've submitted so far soak a little bit.  These
> probably won't see wide-ranging use until after the next release of
> nfs-utils, I'm guessing.
> 
> Given the problems that arose after the last nfs-utils release, I
> think this might be a good stopping point until after the next
> nfs-utils release.  By then, I might even have full support completed
> for IPv6 in rpc.statd and sm-notify.
> 
Committed...

steved.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2009-02-17 21:30 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-28 23:07 [PATCH 0/4] Support IPv6 in umount.nfs command Chuck Lever
     [not found] ` <20090128225938.21484.82096.stgit-07a7zB5ZJzbwdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2009-01-28 23:07   ` [PATCH 1/4] nfs-utils: git should ignore cscope.* files Chuck Lever
2009-01-28 23:07   ` [PATCH 2/4] umount.nfs command: Add an AF_INET6-capable version of nfs_call_unmount() Chuck Lever
2009-01-28 23:07   ` [PATCH 3/4] umount.nfs command: Support AF_INET6 server addresses Chuck Lever
2009-01-28 23:07   ` [PATCH 4/4] umount command: remove do_nfs_umount23 function Chuck Lever
2009-02-17 21:27   ` [PATCH 0/4] Support IPv6 in umount.nfs command Steve Dickson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox