From: Chuck Lever Date: Tue, 17 Feb 2009 21:25:27 +0000 (-0500) Subject: umount.nfs command: Add an AF_INET6-capable version of nfs_call_unmount() X-Git-Tag: nfs-utils-1-1-5~22 X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=commitdiff_plain;h=97de03f8c866b9d3e790d64f4e9ac24011aaa5b1 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 Signed-off-by: Steve Dickson --- diff --git a/utils/mount/network.c b/utils/mount/network.c index a974953..92f75b4 100644 --- a/utils/mount/network.c +++ b/utils/mount/network.c @@ -837,6 +837,59 @@ int start_statd(void) return 0; } +/** + * 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 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);