diff -urN autofs-3.1.4/.autofs-3.1.4 autofs-3.1.5-pre1/.autofs-3.1.4 --- autofs-3.1.4/.autofs-3.1.4 Fri Jan 21 11:08:10 2000 +++ autofs-3.1.5-pre1/.autofs-3.1.4 Wed Dec 31 16:00:00 1969 @@ -1 +0,0 @@ -x diff -urN autofs-3.1.4/.autofs-3.1.5 autofs-3.1.5-pre1/.autofs-3.1.5 --- autofs-3.1.4/.autofs-3.1.5 Wed Dec 31 16:00:00 1969 +++ autofs-3.1.5-pre1/.autofs-3.1.5 Thu Jun 1 12:32:48 2000 @@ -0,0 +1 @@ +x diff -urN autofs-3.1.4/.version autofs-3.1.5-pre1/.version --- autofs-3.1.4/.version Fri Jan 21 11:08:10 2000 +++ autofs-3.1.5-pre1/.version Thu Jun 1 12:32:48 2000 @@ -1 +1 @@ -3.1.4 +3.1.5 diff -urN autofs-3.1.4/NEWS autofs-3.1.5-pre1/NEWS --- autofs-3.1.4/NEWS Fri Jan 21 11:08:09 2000 +++ autofs-3.1.5-pre1/NEWS Thu Jun 1 12:32:48 2000 @@ -1,3 +1,10 @@ +Since autofs-3.1.4: +------------------- +* Support "bind" mounts introduced in linux-2.3.99-pre7.7 instead of + using symlinks. If you are using a version of the Linux kernel + which supports "bind" mounts, you will no longer see symlinks when + mounting local filesystems. + Since autofs-3.1.3: ------------------- * Merge in documentation changes from RedHat RPM. diff -urN autofs-3.1.4/configure autofs-3.1.5-pre1/configure --- autofs-3.1.4/configure Fri Jan 21 11:08:11 2000 +++ autofs-3.1.5-pre1/configure Thu Jun 1 12:32:49 2000 @@ -456,7 +456,7 @@ # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. -ac_unique_file=.autofs-3.1.4 +ac_unique_file=.autofs-3.1.5 # Find the source files, if location was not specified. if test -z "$srcdir"; then diff -urN autofs-3.1.4/configure.in autofs-3.1.5-pre1/configure.in --- autofs-3.1.4/configure.in Fri Jan 21 11:08:10 2000 +++ autofs-3.1.5-pre1/configure.in Thu Jun 1 12:32:49 2000 @@ -1,4 +1,4 @@ -# $Id: configure.in,v 1.12 1999/12/17 19:02:44 hpa Exp $ +# $Id: configure.in,v 1.13 2000/01/22 22:17:32 hpa Exp $ # configure.in for the autofs daemon # @@ -7,7 +7,7 @@ # define([AC_CACHE_LOAD], )dnl define([AC_CACHE_SAVE], )dnl -AC_INIT(.autofs-3.1.4) +AC_INIT(.autofs-3.1.5) # # autofs installs by default in /usr diff -urN autofs-3.1.4/daemon/mount.c autofs-3.1.5-pre1/daemon/mount.c --- autofs-3.1.4/daemon/mount.c Fri Jan 21 11:08:09 2000 +++ autofs-3.1.5-pre1/daemon/mount.c Thu Jun 1 12:32:47 2000 @@ -1,4 +1,4 @@ -#ident "$Id: mount.c,v 1.4 1999/12/17 19:02:47 hpa Exp $" +#ident "$Id: mount.c,v 1.6 2000/06/01 19:29:31 hpa Exp $" /* ----------------------------------------------------------------------- * * * mount.c - Abstract mount code used by modules for an unexpected @@ -26,7 +26,7 @@ /* These filesystems are known not to work with the "generic" module */ /* Note: starting with Samba 2.0.6, smbfs is handled generically. */ static char *not_generic[] = { "nfs", "ncpfs", "userfs", "afs", - "autofs", "changer", NULL }; + "autofs", "changer", "bind", NULL }; int do_mount(const char *root, const char *name, int name_len, const char *what, const char *fstype, const char *options) diff -urN autofs-3.1.4/modules/Makefile autofs-3.1.5-pre1/modules/Makefile --- autofs-3.1.4/modules/Makefile Fri Jan 21 11:08:09 2000 +++ autofs-3.1.5-pre1/modules/Makefile Thu Jun 1 12:32:48 2000 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.11 1999/12/17 19:02:47 hpa Exp $ +# $Id: Makefile,v 1.13 2000/06/01 19:29:31 hpa Exp $ # # Makefile for autofs # @@ -10,13 +10,13 @@ lookup_multi.c \ parse_sun.c \ mount_generic.c mount_nfs.c mount_afs.c mount_autofs.c \ - mount_changer.c + mount_changer.c mount_bind.c MODS := lookup_yp.so lookup_file.so lookup_program.so lookup_userhome.so \ lookup_multi.so \ parse_sun.so \ mount_generic.so mount_nfs.so mount_afs.so mount_autofs.so \ - mount_changer.so + mount_changer.so mount_bind.so ifeq ($(EXT2FS), 1) SRCS += mount_ext2.c diff -urN autofs-3.1.4/modules/mount_bind.c autofs-3.1.5-pre1/modules/mount_bind.c --- autofs-3.1.4/modules/mount_bind.c Wed Dec 31 16:00:00 1969 +++ autofs-3.1.5-pre1/modules/mount_bind.c Thu Jun 1 12:32:48 2000 @@ -0,0 +1,94 @@ +#ident "$Id: mount_bind.c,v 1.1 2000/06/01 19:29:31 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * mount_bind.c - module to mount a local filesystem if possible; + * otherwise create a symlink. + * + * Copyright 2000 Transmeta Corporation - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, + * USA; either version 2 of the License, or (at your option) any later + * version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MODULE_MOUNT +#include "automount.h" + +#define MODPREFIX "mount(bind): " +int mount_version = AUTOFS_MOUNT_VERSION; /* Required by protocol */ + +int mount_init(void **context) +{ + return 0; +} + +int mount_mount(const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, + void *context) +{ + char *fullpath; + int err; + + fullpath = alloca(strlen(root)+name_len+2); + if ( !fullpath ) { + syslog(LOG_ERR, MODPREFIX "alloca: %m"); + return 1; + } + sprintf(fullpath, "%s/%s", root, name); + + syslog(LOG_DEBUG, MODPREFIX "calling mkdir %s", fullpath); + if ( mkdir(fullpath, 0555) && errno != EEXIST ) { + syslog(LOG_NOTICE, MODPREFIX "mkdir %s failed: %m", name); + return 1; + } + + if ( options ) { + syslog(LOG_DEBUG, MODPREFIX "calling mount -t %s " SLOPPY "-o %s %s %s", + fstype, options, what, fullpath); + err = spawnl(LOG_NOTICE, PATH_MOUNT, PATH_MOUNT, "-t", fstype, + SLOPPYOPT "-o", options, what, fullpath, NULL); + } else { + syslog(LOG_DEBUG, MODPREFIX "calling mount -t %s %s %s", + fstype, what, fullpath); + err = spawnl(LOG_NOTICE, PATH_MOUNT, PATH_MOUNT, "-t", fstype, + what, fullpath, NULL); + } + if ( err ) { + if ( rmdir(fullpath) && errno == EBUSY ) + return 0; + + syslog(LOG_DEBUG, MODPREFIX "failed to mount %s (type %s) on %s, trying symlink", + what, fstype, fullpath); + if ( symlink(what, fullpath) && errno != EEXIST ) { + syslog(LOG_NOTICE, MODPREFIX "failed to create local mount %s -> %s", fullpath, what); + + return 1; + } else { + syslog(LOG_DEBUG, MODPREFIX "symlinked %s -> %s", fullpath, what); + return 0; + } + } else { + syslog(LOG_DEBUG, MODPREFIX "mounted %s type %s on %s", + what, fstype, fullpath); + return 0; + } +} + +int mount_done(void *context) +{ + return 0; +} diff -urN autofs-3.1.4/modules/mount_nfs.c autofs-3.1.5-pre1/modules/mount_nfs.c --- autofs-3.1.4/modules/mount_nfs.c Fri Jan 21 11:08:09 2000 +++ autofs-3.1.5-pre1/modules/mount_nfs.c Thu Jun 1 12:32:48 2000 @@ -1,10 +1,10 @@ -#ident "$Id: mount_nfs.c,v 1.7 1998/04/09 23:31:58 hpa Exp $" +#ident "$Id: mount_nfs.c,v 1.8 2000/06/01 19:29:31 hpa Exp $" /* ----------------------------------------------------------------------- * * * mount_nfs.c - Module for Linux automountd to mount an NFS filesystem, * with fallback to symlinking if the path is local * - * Copyright 1997 Transmeta Corporation - All Rights Reserved + * Copyright 1997-2000 Transmeta Corporation - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,6 +37,8 @@ static int udpproto; static short port_discard; +static struct mount_mod *mount_bind = NULL; + int mount_init(void **context) { struct protoent *udp; @@ -51,14 +53,18 @@ else port_discard = htons(9); /* 9 is the standard discard port */ - return 0; + /* Make sure we have the local mount method available */ + if ( !mount_bind ) + mount_bind = open_mount("bind", MODPREFIX); + + return !mount_bind; } int mount_mount(const char *root, const char *name, int name_len, const char *what, const char *fstype, const char *options, void *context) { - char *colon, **haddr, *fullpath; + char *colon, *localname, **haddr, *fullpath; char *whatstr, *hostname, *comma, *paren; struct hostent *he; struct sockaddr_in saddr, laddr; @@ -74,106 +80,93 @@ 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, whatstr); - chdir(root); - err = symlink(whatstr, name); - if ( err && errno == EEXIST ) - err = 0; - if ( err ) - syslog(LOG_NOTICE, MODPREFIX "symlink %s: %m", name); - chdir("/"); - return err ? 1 : 0; - } - - *colon = '\0'; + /* No colon, take this as a bind (local) entry */ + local = 1; + localname = whatstr; + } else { + *colon = '\0'; - /* 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; - 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 */ - } - - /* 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; + /* 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; + localname = colon+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; - memcpy(&saddr.sin_addr, *haddr, he->h_length); - saddr.sin_port = port_discard; - len = sizeof(laddr); - - if ( connect(sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0 ) - continue; /* Assume it wasn't local */ - - if ( getsockname(sock, (struct sockaddr *) &laddr, &len) < 0 ) { - syslog(LOG_ERR, MODPREFIX "getsockname failed for %s: %m", 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; + memcpy(&saddr.sin_addr, *haddr, he->h_length); + saddr.sin_port = port_discard; + + len = sizeof(laddr); + + if ( connect(sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0 ) + continue; /* Assume it wasn't local */ + + if ( getsockname(sock, (struct sockaddr *) &laddr, &len) < 0 ) { + syslog(LOG_ERR, MODPREFIX "getsockname failed for %s: %m", 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 ( paren ) - *paren = '('; + fullpath = alloca(strlen(root)+name_len+2); + if ( !fullpath ) { + syslog(LOG_ERR, MODPREFIX "alloca: %m"); + return 1; + } + sprintf(fullpath, "%s/%s", root, name); + + if ( local ) { + /* Local host -- do a "bind" */ - if ( comma ) { - *comma = ','; - hostname = comma + 1; - } else { - hostname += strlen(hostname); - } - } while (*hostname && !local); + syslog(LOG_DEBUG, MODPREFIX "%s is local, doing bind", name); - if ( local ) { - /* Local host -- do a symlink */ - - syslog(LOG_DEBUG, MODPREFIX "%s is local, symlinking", name); - chdir(root); - err = symlink(colon+1, name); - if ( err && errno == EEXIST ) - err = 0; - if ( err ) - syslog(LOG_NOTICE, MODPREFIX "symlink %s: %m", name); - chdir("/"); - return err ? 1 : 0; + return mount_bind->mount_mount(root,name,name_len,localname,"bind",NULL,mount_bind->context); } else { - /* Not a local host - do a mount */ + /* Not a local host - do an NFS mount */ - fullpath = alloca(strlen(root)+name_len+2); - if ( !fullpath ) { - syslog(LOG_ERR, MODPREFIX "alloca: %m"); - return 1; - } - sprintf(fullpath, "%s/%s", root, name); - *colon = ':'; syslog(LOG_DEBUG, MODPREFIX "calling mkdir %s", fullpath); if ( mkdir(fullpath, 0555) && errno != EEXIST ) { @@ -205,5 +198,5 @@ int mount_done(void *context) { - return 0; + return mount_bind->mount_done(mount_bind->context); } diff -urN autofs-3.1.4/samples/rc.autofs.in autofs-3.1.5-pre1/samples/rc.autofs.in --- autofs-3.1.4/samples/rc.autofs.in Fri Jan 21 11:08:09 2000 +++ autofs-3.1.5-pre1/samples/rc.autofs.in Thu Jun 1 12:32:48 2000 @@ -1,6 +1,6 @@ #! /bin/bash # -# $Id: rc.autofs.in,v 1.3 1999/03/07 22:59:55 hpa Exp $ +# $Id: rc.autofs.in,v 1.4 2000/01/22 22:17:34 hpa Exp $ # # rc file for automount using a Sun-style "master map". # We first look for a local /etc/auto.master, then a YP