summaryrefslogtreecommitdiffstats
path: root/utils/mount/nfsmount.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2007-07-16 16:28:46 -0400
committerNeil Brown <neilb@suse.de>2007-07-20 16:10:51 +1000
commit0dfc8a5426381c6d65aed4d9d0e50bae3238cc8f (patch)
tree85d4cea7a49d37b26780031913a3bce550de1d41 /utils/mount/nfsmount.c
parent13b5fbc6cb4e41cd6a4d80e224ee2feaade65ce1 (diff)
downloadnfs-utils-0dfc8a5426381c6d65aed4d9d0e50bae3238cc8f.tar.gz
nfs-utils-0dfc8a5426381c6d65aed4d9d0e50bae3238cc8f.tar.xz
nfs-utils-0dfc8a5426381c6d65aed4d9d0e50bae3238cc8f.zip
mount.nfs: Move network functions into a common source module
Separate network oriented functions from filesystem oriented functions, for general cleanliness. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Neil Brown <neilb@suse.de>
Diffstat (limited to 'utils/mount/nfsmount.c')
-rw-r--r--utils/mount/nfsmount.c264
1 files changed, 1 insertions, 263 deletions
diff --git a/utils/mount/nfsmount.c b/utils/mount/nfsmount.c
index 4b862f0..9c08ff5 100644
--- a/utils/mount/nfsmount.c
+++ b/utils/mount/nfsmount.c
@@ -64,6 +64,7 @@
#include "mount_constants.h"
#include "nls.h"
#include "error.h"
+#include "network.h"
#ifndef NFS_PORT
#define NFS_PORT 2049
@@ -93,269 +94,6 @@ extern int sloppy;
extern int linux_version_code();
-static const unsigned int probe_udp_only[] = {
- IPPROTO_UDP,
- 0,
-};
-
-static const unsigned int probe_udp_first[] = {
- IPPROTO_UDP,
- IPPROTO_TCP,
- 0,
-};
-
-static const unsigned int probe_tcp_first[] = {
- IPPROTO_TCP,
- IPPROTO_UDP,
- 0,
-};
-
-static const unsigned long probe_nfs2_only[] = {
- 2,
- 0,
-};
-
-static const unsigned long probe_nfs3_first[] = {
- 3,
- 2,
- 0,
-};
-
-static const unsigned long probe_mnt1_first[] = {
- 1,
- 2,
- 0,
-};
-
-static const unsigned long probe_mnt3_first[] = {
- 3,
- 1,
- 2,
- 0,
-};
-
-int nfs_gethostbyname(const char *, struct sockaddr_in *);
-int nfs_gethostbyname(const char *hostname, struct sockaddr_in *saddr)
-{
- struct hostent *hp;
-
- saddr->sin_family = AF_INET;
- if (!inet_aton(hostname, &saddr->sin_addr)) {
- if ((hp = gethostbyname(hostname)) == NULL) {
- fprintf(stderr, _("mount: can't get address for %s\n"),
- hostname);
- return 0;
- } else {
- if (hp->h_length > sizeof(*saddr)) {
- fprintf(stderr,
- _("mount: got bad hp->h_length\n"));
- hp->h_length = sizeof(*saddr);
- }
- memcpy(&saddr->sin_addr, hp->h_addr, hp->h_length);
- }
- }
- return 1;
-}
-
-/*
- * getport() is very similar to pmap_getport() with
- * the exception this version uses a non-reserve ports
- * instead of reserve ports since reserve ports
- * are not needed for pmap requests.
- */
-u_short
-getport(
- struct sockaddr_in *saddr,
- u_long prog,
- u_long vers,
- u_int prot)
-{
- u_short port = 0;
- int socket;
- CLIENT *clnt = NULL;
- struct pmap parms;
- enum clnt_stat stat;
-
- saddr->sin_port = htons (PMAPPORT);
- socket = get_socket(saddr, prot, FALSE, FALSE);
-
- switch (prot) {
- case IPPROTO_UDP:
- clnt = clntudp_bufcreate(saddr,
- PMAPPROG, PMAPVERS, TIMEOUT, &socket,
- UDPMSGSIZE, UDPMSGSIZE);
- break;
- case IPPROTO_TCP:
- clnt = clnttcp_create(saddr,
- PMAPPROG, PMAPVERS, &socket, 50, 500);
- break;
- }
- if (clnt != NULL) {
- parms.pm_prog = prog;
- parms.pm_vers = vers;
- parms.pm_prot = prot;
- parms.pm_port = 0; /* not needed or used */
-
- stat = clnt_call(clnt, PMAPPROC_GETPORT, (xdrproc_t)xdr_pmap,
- (caddr_t)&parms, (xdrproc_t)xdr_u_short, (caddr_t)&port, TIMEOUT);
- if (stat) {
- clnt_geterr(clnt, &rpc_createerr.cf_error);
- rpc_createerr.cf_stat = stat;
- }
- clnt_destroy(clnt);
- if (stat != RPC_SUCCESS)
- port = 0;
- else if (port == 0)
- rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
- }
- if (socket != 1)
- close(socket);
-
- return port;
-}
-
-/*
- * Use the portmapper to discover whether or not the service we want is
- * available. The lists 'versions' and 'protos' define ordered sequences
- * of service versions and udp/tcp protocols to probe for.
- */
-static int
-probe_port(clnt_addr_t *server,
- const u_long *versions,
- const u_int *protos)
-{
- struct sockaddr_in *saddr = &server->saddr;
- struct pmap *pmap = &server->pmap;
- const u_long prog = pmap->pm_prog, *p_vers;
- const u_int prot = (u_int)pmap->pm_prot,
- *p_prot;
- const u_short port = (u_short) pmap->pm_port;
- u_long vers = pmap->pm_vers;
- u_short p_port;
- p_prot = prot ? &prot : protos;
- p_vers = vers ? &vers : versions;
- rpc_createerr.cf_stat = 0;
- for (;;) {
- saddr->sin_port = htons(PMAPPORT);
- p_port = getport(saddr, prog, *p_vers, *p_prot);
- if (p_port) {
- if (!port || port == p_port) {
- saddr->sin_port = htons(p_port);
- if (verbose) {
- fprintf(stderr,
- "mount: trying %s prog %ld vers %ld prot %s port %d\n",
- inet_ntoa(saddr->sin_addr), prog, *p_vers,
- *p_prot == IPPROTO_UDP ? "udp" : "tcp", p_port);
- }
- if (clnt_ping(saddr, prog, *p_vers, *p_prot, NULL))
- goto out_ok;
- if (rpc_createerr.cf_stat == RPC_TIMEDOUT)
- goto out_bad;
- }
- }
- if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED)
- goto out_bad;
-
- if (!prot) {
- if (*++p_prot)
- continue;
- p_prot = protos;
- }
- if (vers == pmap->pm_vers) {
- p_vers = versions;
- vers = 0;
- }
- if (vers || !*++p_vers)
- break;
- }
-out_bad:
- return 0;
-
- out_ok:
- if (!vers)
- pmap->pm_vers = *p_vers;
- if (!prot)
- pmap->pm_prot = *p_prot;
- if (!port)
- pmap->pm_port = p_port;
- rpc_createerr.cf_stat = 0;
- return 1;
-}
-
-static int probe_nfsport(clnt_addr_t *nfs_server)
-{
- struct pmap *pmap = &nfs_server->pmap;
-
- if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port)
- return 1;
-
- if (nfs_mount_data_version >= 4)
- return probe_port(nfs_server, probe_nfs3_first, probe_tcp_first);
- else
- return probe_port(nfs_server, probe_nfs2_only, probe_udp_only);
-}
-
-int probe_mntport(clnt_addr_t *mnt_server)
-{
- struct pmap *pmap = &mnt_server->pmap;
-
- if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port)
- return 1;
-
- if (nfs_mount_data_version >= 4)
- return probe_port(mnt_server, probe_mnt3_first, probe_udp_first);
- else
- return probe_port(mnt_server, probe_mnt1_first, probe_udp_only);
-}
-
-static int
-probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server)
-{
- struct pmap *nfs_pmap = &nfs_server->pmap;
- struct pmap *mnt_pmap = &mnt_server->pmap;
- struct pmap save_nfs, save_mnt;
- int res;
- const unsigned long *probe_vers;
-
- if (mnt_pmap->pm_vers && !nfs_pmap->pm_vers)
- nfs_pmap->pm_vers = mntvers_to_nfs(mnt_pmap->pm_vers);
- else if (nfs_pmap->pm_vers && !mnt_pmap->pm_vers)
- mnt_pmap->pm_vers = nfsvers_to_mnt(nfs_pmap->pm_vers);
- if (nfs_pmap->pm_vers)
- goto version_fixed;
-
- memcpy(&save_nfs, nfs_pmap, sizeof(save_nfs));
- memcpy(&save_mnt, mnt_pmap, sizeof(save_mnt));
- probe_vers = (nfs_mount_data_version >= 4) ?
- probe_mnt3_first : probe_mnt1_first;
-
- for (; *probe_vers; probe_vers++) {
- nfs_pmap->pm_vers = mntvers_to_nfs(*probe_vers);
- if ((res = probe_nfsport(nfs_server) != 0)) {
- mnt_pmap->pm_vers = nfsvers_to_mnt(nfs_pmap->pm_vers);
- if ((res = probe_mntport(mnt_server)) != 0)
- return 1;
- memcpy(mnt_pmap, &save_mnt, sizeof(*mnt_pmap));
- }
- switch (rpc_createerr.cf_stat) {
- case RPC_PROGVERSMISMATCH:
- case RPC_PROGNOTREGISTERED:
- break;
- default:
- goto out_bad;
- }
- memcpy(nfs_pmap, &save_nfs, sizeof(*nfs_pmap));
- }
-
-out_bad:
- return 0;
-
-version_fixed:
- if (!probe_nfsport(nfs_server))
- goto out_bad;
- return probe_mntport(mnt_server);
-}
-
static inline enum clnt_stat
nfs3_mount(CLIENT *clnt, mnt3arg_t *mnt3arg, mnt3res_t *mnt3res)
{