diff options
author | H. Peter Anvin <hpa@zytor.com> | 1998-04-02 04:54:47 +0000 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 1998-04-02 04:54:47 +0000 |
commit | e954633943f5975462a138324a7a14b75e5d87f1 (patch) | |
tree | 1936a2639b7f4766580b6e45e86d38d5071d902e /modules | |
parent | a2500fdc36efb2a8cba72fa2faafa339e44b5f99 (diff) | |
download | autofs3-e954633943f5975462a138324a7a14b75e5d87f1.tar.gz autofs3-e954633943f5975462a138324a7a14b75e5d87f1.tar.xz autofs3-e954633943f5975462a138324a7a14b75e5d87f1.zip |
Integrated NFS patches from David Engels (multiserver mount support);
started support for mount_cdchanger
Diffstat (limited to 'modules')
-rw-r--r-- | modules/mount_nfs.c | 108 |
1 files changed, 71 insertions, 37 deletions
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c index a932171..e9b4ee4 100644 --- a/modules/mount_nfs.c +++ b/modules/mount_nfs.c @@ -59,18 +59,26 @@ int mount_mount(const char *root, const char *name, int name_len, const char *options, void *context) { char *colon, **haddr, *fullpath; + char *whatstr, *hostname, *comma, *paren; struct hostent *he; struct sockaddr_in saddr, laddr; int sock, local, err; size_t len; - colon = strchr(what, ':'); + whatstr = alloca(strlen(what)+1); + if ( !whatstr ) { + syslog(LOG_NOTICE, MODPREFIX "alloca: %m"); + return 1; + } + strcpy(whatstr, what); + + colon = strchr(whatstr, ':'); if ( !colon ) { /* No colon, take this as a symlink (local) entry */ syslog(LOG_DEBUG, MODPREFIX "entry %s -> %s: no colon, assume local", - name, what); + name, whatstr); chdir(root); - err = symlink(what, name); + err = symlink(whatstr, name); if ( err && errno == EEXIST ) err = 0; if ( err ) @@ -80,40 +88,66 @@ int mount_mount(const char *root, const char *name, int name_len, } *colon = '\0'; - if ( !(he = gethostbyname(what)) ) { - syslog(LOG_NOTICE, MODPREFIX "entry %s: host %s: lookup failure", - name, what); - return 1; /* No such host */ - } - - /* Probe to see if we are the local host. Open a UDP socket and see - if the local address is the same as the remote one */ + /* The host part may actually be a comma-separated list of hosts with + parenthesized weights. We want to check each host, ignoring any + weights, until we either find the localhost or reach the end of the + list. */ local = 0; - for ( haddr = he->h_addr_list ; *haddr ; haddr++ ) { - sock = socket(AF_INET, SOCK_DGRAM, udpproto); - if ( sock < 0 ) { - syslog(LOG_ERR, MODPREFIX "socket: %m"); - return 1; + hostname = whatstr; + do { + comma = strchr(hostname, ','); + if ( comma ) + *comma = '\0'; + + paren = strchr(hostname, '('); + if ( paren ) + *paren = '\0'; + + if ( !(he = gethostbyname(hostname)) ) { + syslog(LOG_NOTICE, MODPREFIX "entry %s: host %s: lookup failure", + name, hostname); + return 1; /* No such host */ } - saddr.sin_family = AF_INET; - bcopy(*haddr, &saddr.sin_addr, he->h_length); - saddr.sin_port = port_discard; - - len = sizeof(laddr); - if ( connect(sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0 - || getsockname(sock, (struct sockaddr *) &laddr, &len) < 0 ) { - syslog(LOG_ERR, MODPREFIX "connect+getsockname failed for %s", name); + + /* Probe to see if we are the local host. Open a UDP socket and see + if the local address is the same as the remote one */ + + for ( haddr = he->h_addr_list ; *haddr ; haddr++ ) { + sock = socket(AF_INET, SOCK_DGRAM, udpproto); + if ( sock < 0 ) { + syslog(LOG_ERR, MODPREFIX "socket: %m"); + return 1; + } + saddr.sin_family = AF_INET; + bcopy(*haddr, &saddr.sin_addr, he->h_length); + saddr.sin_port = port_discard; + + len = sizeof(laddr); + if ( connect(sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0 + || getsockname(sock, (struct sockaddr *) &laddr, &len) < 0 ) { + syslog(LOG_ERR, MODPREFIX "connect+getsockname failed for %s", name); + close(sock); + return 1; + } close(sock); - return 1; + + if ( !memcmp(&saddr.sin_addr,&laddr.sin_addr,he->h_length) ) { + local = 1; + break; + } } - close(sock); - - if ( !memcmp(&saddr.sin_addr,&laddr.sin_addr,he->h_length) ) { - local = 1; - break; + + if ( paren ) + *paren = '('; + + if ( comma ) { + *comma = ','; + hostname = comma + 1; + } else { + hostname += strlen(hostname); } - } + } while (*hostname && !local); if ( local ) { /* Local host -- do a symlink */ @@ -146,21 +180,21 @@ int mount_mount(const char *root, const char *name, int name_len, if ( options ) { syslog(LOG_DEBUG, MODPREFIX "calling mount -t nfs " SLOPPY "-o %s %s %s", - options, what, fullpath); + options, whatstr, fullpath); err = spawnl(LOG_NOTICE, PATH_MOUNT, PATH_MOUNT, "-t", "nfs", "-o", - SLOPPYOPT options, what, fullpath, NULL); + SLOPPYOPT options, whatstr, fullpath, NULL); } else { - syslog(LOG_DEBUG, MODPREFIX "calling mount -t nfs %s %s", what, fullpath); + syslog(LOG_DEBUG, MODPREFIX "calling mount -t nfs %s %s", whatstr, fullpath); err = spawnl(LOG_NOTICE, PATH_MOUNT, PATH_MOUNT, "-t", "nfs", - what, fullpath, NULL); + whatstr, fullpath, NULL); } if ( err ) { rmdir(fullpath); syslog(LOG_NOTICE, MODPREFIX "nfs: mount failure %s on %s", - what, fullpath); + whatstr, fullpath); return 1; } else { - syslog(LOG_DEBUG, MODPREFIX "mounted %s on %s", what, fullpath); + syslog(LOG_DEBUG, MODPREFIX "mounted %s on %s", whatstr, fullpath); return 0; } } |