- umount.nfs command: Add an AF_INET6-capable version of nfs_call_unmount()
- umount.nfs command: Support AF_INET6 server addresses - umount command: remove do_nfs_umount23 function
This commit is contained in:
parent
0b66620759
commit
3de3019b29
343
nfs-utils-1.1.4-umount-ipv6.patch
Normal file
343
nfs-utils-1.1.4-umount-ipv6.patch
Normal file
@ -0,0 +1,343 @@
|
||||
Author: Chuck Lever <chuck.lever@oracle.com>
|
||||
Date: Tue Feb 17 16:27:43 2009 -0500
|
||||
|
||||
umount command: remove do_nfs_umount23 function
|
||||
|
||||
Remove do_nfs_umount23() now that it is unused.
|
||||
|
||||
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||
|
||||
commit c735a8331b082038a0e83ec4187c2656b0804eea
|
||||
Author: Chuck Lever <chuck.lever@oracle.com>
|
||||
Date: Tue Feb 17 16:26:31 2009 -0500
|
||||
|
||||
umount.nfs command: Support AF_INET6 server addresses
|
||||
|
||||
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>
|
||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||
|
||||
commit 97de03f8c866b9d3e790d64f4e9ac24011aaa5b1
|
||||
Author: Chuck Lever <chuck.lever@oracle.com>
|
||||
Date: Tue Feb 17 16:25:27 2009 -0500
|
||||
|
||||
umount.nfs command: Add an AF_INET6-capable version of nfs_call_unmount()
|
||||
|
||||
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>
|
||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||
|
||||
diff -up nfs-utils-1.1.4/utils/mount/network.c.save nfs-utils-1.1.4/utils/mount/network.c
|
||||
--- nfs-utils-1.1.4/utils/mount/network.c.save 2009-02-17 16:37:18.000000000 -0500
|
||||
+++ nfs-utils-1.1.4/utils/mount/network.c 2009-02-17 16:38:10.000000000 -0500
|
||||
@@ -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 -up nfs-utils-1.1.4/utils/mount/network.h.save nfs-utils-1.1.4/utils/mount/network.h
|
||||
--- nfs-utils-1.1.4/utils/mount/network.h.save 2009-02-17 16:37:26.000000000 -0500
|
||||
+++ nfs-utils-1.1.4/utils/mount/network.h 2009-02-17 16:38:10.000000000 -0500
|
||||
@@ -52,7 +52,6 @@ int nfs_present_sockaddr(const struct so
|
||||
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);
|
||||
|
||||
diff -up nfs-utils-1.1.4/utils/mount/nfsumount.c.save nfs-utils-1.1.4/utils/mount/nfsumount.c
|
||||
--- nfs-utils-1.1.4/utils/mount/nfsumount.c.save 2009-02-17 16:37:42.000000000 -0500
|
||||
+++ nfs-utils-1.1.4/utils/mount/nfsumount.c 2009-02-17 16:38:29.000000000 -0500
|
||||
@@ -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,64 @@ static int del_mtab(const char *spec, co
|
||||
}
|
||||
|
||||
/*
|
||||
+ * 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.
|
||||
@@ -142,85 +201,28 @@ static int del_mtab(const char *spec, co
|
||||
* 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 do_nfs_umount23(const char *spec, char *opts)
|
||||
+static int nfs_umount23(const char *devname, char *string)
|
||||
{
|
||||
- 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;
|
||||
+ char *hostname, *dirname;
|
||||
+ struct mount_options *options;
|
||||
+ int result = EX_FAIL;
|
||||
|
||||
- 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;
|
||||
- }
|
||||
+ if (!nfs_parse_devname(devname, &hostname, &dirname))
|
||||
+ return EX_USAGE;
|
||||
|
||||
- result = EX_SUCCESS;
|
||||
+ 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);
|
||||
|
||||
-out:
|
||||
free(hostname);
|
||||
free(dirname);
|
||||
return result;
|
||||
@@ -350,16 +352,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);
|
||||
|
@ -2,7 +2,7 @@ Summary: NFS utilities and supporting clients and daemons for the kernel NFS ser
|
||||
Name: nfs-utils
|
||||
URL: http://sourceforge.net/projects/nfs
|
||||
Version: 1.1.4
|
||||
Release: 17%{?dist}
|
||||
Release: 18%{?dist}
|
||||
Epoch: 1
|
||||
|
||||
# group all 32bit related archs
|
||||
@ -50,6 +50,7 @@ Patch120: nfs-utils-1.1.4-tcpwrap-cleanup.patch
|
||||
Patch121: nfs-utils-1.1.4-mount-textbased.patch
|
||||
Patch122: nfs-utils-1.1.4-mount-nolock.patch
|
||||
Patch123: nfs-utils-1.1.4-mount-udponly.patch
|
||||
Patch124: nfs-utils-1.1.4-umount-ipv6.patch
|
||||
|
||||
%if %{enablefscache}
|
||||
Patch90: nfs-utils-1.1.0-mount-fsc.patch
|
||||
@ -128,6 +129,7 @@ This package also contains the mount.nfs and umount.nfs program.
|
||||
%patch121 -p1
|
||||
%patch122 -p1
|
||||
%patch123 -p1
|
||||
%patch124 -p1
|
||||
|
||||
%if %{enablefscache}
|
||||
%patch90 -p1
|
||||
@ -291,6 +293,11 @@ fi
|
||||
%attr(4755,root,root) /sbin/umount.nfs4
|
||||
|
||||
%changelog
|
||||
* Tue Feb 17 2009 Steve Dickson <steved@redhat.com> 1.1.4-18
|
||||
- umount.nfs command: Add an AF_INET6-capable version of nfs_call_unmount()
|
||||
- umount.nfs command: Support AF_INET6 server addresses
|
||||
- umount command: remove do_nfs_umount23 function
|
||||
|
||||
* Tue Feb 17 2009 Steve Dickson <steved@redhat.com> 1.1.4-17
|
||||
- Integrated the upstream fix for bz 483375
|
||||
- mount: segmentation faults on UDP mounts (bz 485448)
|
||||
|
Loading…
Reference in New Issue
Block a user