aboutsummaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>1998-04-02 04:54:47 +0000
committerH. Peter Anvin <hpa@zytor.com>1998-04-02 04:54:47 +0000
commite954633943f5975462a138324a7a14b75e5d87f1 (patch)
tree1936a2639b7f4766580b6e45e86d38d5071d902e /modules
parenta2500fdc36efb2a8cba72fa2faafa339e44b5f99 (diff)
downloadautofs3-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.c108
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;
}
}