enough, we should lstat() the sublink if it's defined.
(amfs_nfsl_ffserver): ditto
(ALL): Removed some obsolete comments. The nfsl code is now little
more than a very straight-forward switch between link and nfs.
* amd/amfs_link.c (amfs_link_match): more up-to-date explanation
for the prepend-the-dot hack for type link; also, the sublink is
already normalized and absolute, so take advantage of that
* amd/amfs_generic.c (amfs_lookup_one_mntfs): the sublink is
already normalized and absolute, so take advantage of that
* amd/am_ops.c (ops_match): normalize the sublink here, early into
the matching process
2003-09-19 Ion Badulescu <ionut@moisil.badula.org>
+ * amd/amfs_nfsl.c (amfs_nfsl_match): checking opt_fs is not always
+ enough, we should lstat() the sublink if it's defined.
+ (amfs_nfsl_ffserver): ditto
+ (ALL): Removed some obsolete comments. The nfsl code is now little
+ more than a very straight-forward switch between link and nfs.
+
+ * amd/amfs_link.c (amfs_link_match): more up-to-date explanation
+ for the prepend-the-dot hack for type link; also, the sublink is
+ already normalized and absolute, so take advantage of that
+
+ * amd/amfs_generic.c (amfs_lookup_one_mntfs): the sublink is
+ already normalized and absolute, so take advantage of that
+
+ * amd/am_ops.c (ops_match): normalize the sublink here, early into
+ the matching process
+
* amd/autil.c (am_mounted): be consistent and accept both
"nounmount" and "noumount" as pseudo mount options (same as
"unmount" and "umount" nearby)
* SUCH DAMAGE.
*
*
- * $Id: am_ops.c,v 1.17 2002/12/27 22:43:46 ezk Exp $
+ * $Id: am_ops.c,v 1.18 2003/09/20 03:19:48 ib42 Exp $
*
*/
ops_match(am_opts *fo, char *key, char *g_key, char *path, char *keym, char *map)
{
am_ops *rop = 0;
+ char *link_dir;
/*
* First crack the global opts and the local opts
if (!fo->opt_mount_type)
fo->opt_mount_type = "nfs";
+ /* Normalize the sublink and make it absolute */
+ link_dir = fo->opt_sublink;
+ if (link_dir && link_dir[0] && link_dir[0] != '/') {
+ link_dir = str3cat((char *) 0, fo->opt_fs, "/", link_dir);
+ normalize_slash(link_dir);
+ XFREE(fo->opt_sublink);
+ fo->opt_sublink = link_dir;
+ }
+
/*
* Check the filesystem is happy
*/
* SUCH DAMAGE.
*
*
- * $Id: amfs_generic.c,v 1.17 2003/08/27 16:30:04 ib42 Exp $
+ * $Id: amfs_generic.c,v 1.18 2003/09/20 03:19:48 ib42 Exp $
*
*/
am_ops *p;
am_opts *fs_opts;
mntfs *new_mf;
- char *link_dir;
char *mp_dir = 0;
#ifdef HAVE_FS_AUTOFS
int on_autofs = 1;
if (new_mp->am_flags & AMF_AUTOFS) {
/* ignore user-provided fs if we're using autofs */
if (fs_opts->opt_sublink) {
+ /*
+ * For sublinks we need to use a hack with autofs:
+ * mount the filesystem on the original opt_fs (which is NOT an
+ * autofs mountpoint) and symlink (or lofs-mount) to it from
+ * the autofs mountpoint.
+ */
on_autofs = 0;
- if (fs_opts->opt_sublink[0] == '/') {
- mp_dir = new_mp->am_path;
- } else {
- /*
- * For a relative sublink we need to use a hack with autofs:
- * mount the filesystem on the original opt_fs (which is NOT an
- * autofs mountpoint) and symlink (or lofs-mount) to it from
- * the autofs mountpoint.
- */
- mp_dir = fs_opts->opt_fs;
- }
+ mp_dir = fs_opts->opt_fs;
} else {
if (p->autofs_fs_flags & FS_ON_AUTOFS) {
mp_dir = new_mp->am_path;
new_mf->mf_flags |= MFF_IS_AUTOFS;
#endif /* HAVE_FS_AUTOFS */
- link_dir = new_mf->mf_fo->opt_sublink;
- if (link_dir && link_dir[0] && link_dir[0] != '/') {
- link_dir = str3cat((char *) 0, mp_dir, "/", link_dir);
- normalize_slash(link_dir);
- XFREE(new_mf->mf_fo->opt_sublink);
- new_mf->mf_fo->opt_sublink = link_dir;
- }
return new_mf;
}
* SUCH DAMAGE.
*
*
- * $Id: amfs_link.c,v 1.18 2003/08/25 23:49:47 ib42 Exp $
+ * $Id: amfs_link.c,v 1.19 2003/09/20 03:19:48 ib42 Exp $
*
*/
}
/*
- * Bug report (14/12/89) from Jay Plett <jay@princeton.edu>
- * If an automount point has the same name as an existing
- * link type mount Amd hits a race condition and either hangs
- * or causes a symlink loop.
+ * If the link target points to another mount point, then we could
+ * end up with an unpleasant situation, where the link f/s simply
+ * "assumes" the mntfs of that mount point.
*
- * If fs begins with a '/' change the opt_fs & opt_sublink
- * fields so that the fs option doesn't end up pointing at
- * an existing symlink.
+ * For example, if the link points to /usr, and /usr is a real ufs
+ * filesystem, then the link f/s will use the inherited ufs mntfs,
+ * and the end result will be that it will become unmountable.
*
- * If sublink is nil then set sublink to fs
- * else set sublink to fs / sublink
+ * To prevent this, we use a hack: we prepend a dot ('.') to opt_fs if
+ * its original value was an absolute path, so that it will never match
+ * any other mntfs.
*
- * Finally set fs to ".".
+ * XXX: a less hacky solution should be used...
*/
- if (*fo->opt_fs == '/') {
- char *fullpath;
- char *link = fo->opt_sublink;
- if (link) {
- if (*link == '/')
- fullpath = strdup(link);
- else
- fullpath = str3cat((char *) 0, fo->opt_fs, "/", link);
- } else {
- fullpath = strdup(fo->opt_fs);
- }
-
- if (fo->opt_sublink)
- XFREE(fo->opt_sublink);
- fo->opt_sublink = fullpath;
- fo->opt_fs = str3cat(fo->opt_fs, ".", fullpath, "");
+ if (fo->opt_fs[0] == '/') {
+ char *link_hack = str3cat(NULL, ".", fo->opt_fs, "");
+ if (!fo->opt_sublink)
+ fo->opt_sublink = strdup(fo->opt_fs);
+ XFREE(fo->opt_fs);
+ fo->opt_fs = link_hack;
}
return strdup(fo->opt_fs);
* SUCH DAMAGE.
*
*
- * $Id: amfs_nfsl.c,v 1.19 2003/08/25 23:49:48 ib42 Exp $
+ * $Id: amfs_nfsl.c,v 1.20 2003/09/20 03:19:48 ib42 Exp $
*
*/
static char *
amfs_nfsl_match(am_opts *fo)
{
- char *cp = fo->opt_fs;
+ char *cp;
char *ho = fo->opt_rhost;
+ char *retval;
struct stat stb;
+ if (fo->opt_sublink)
+ cp = fo->opt_sublink;
+ else
+ cp = fo->opt_fs;
+
if (!cp || !ho) {
plog(XLOG_USER, "amfs_nfsl: host $fs and $rhost must be specified");
return NULL;
/*
* If this host is not the same as $rhost, or if link does not exist,
- * perform nfs_match(), same as for type:=nfs.
- * If link value exists (or same host), then perform amfs_link_match(),
- * same as for linkx.
+ * call nfs_ops.fs_match().
+ * If link value exists (or same host), call amfs_link_ops.fs_match().
*/
if (!STRCEQ(ho, am_get_hostname())) {
plog(XLOG_INFO, "amfs_nfsl: \"%s\" is not local host, using type:=nfs", ho);
- return nfs_ops.fs_match(fo);
+ retval = nfs_ops.fs_match(fo);
} else if (lstat(cp, &stb) < 0) {
plog(XLOG_INFO, "amfs_nfsl: \"%s\" does not exist, using type:=nfs", cp);
- return nfs_ops.fs_match(fo);
+ retval = nfs_ops.fs_match(fo);
} else {
plog(XLOG_INFO, "amfs_nfsl: \"%s\" exists, using type:=link", cp);
- return amfs_link_ops.fs_match(fo);
+ retval = amfs_link_ops.fs_match(fo);
}
+ return retval;
}
amfs_nfsl_init(mntfs *mf)
{
int ret = 0;
- /*
- * If a link, do nothing (same as type:=link).
- * If non-link, do nfs_init (same as type:=nfs).
- */
if (mf->mf_flags & MFF_NFSLINK) {
if (amfs_link_ops.fs_init)
ret = amfs_link_ops.fs_init(mf);
static int
amfs_nfsl_mount(am_node *mp, mntfs *mf)
{
- /*
- * If a link, do run amfs_link_fmount() (same as type:=link)
- * If non-link, do nfs_fmount (same as type:=nfs).
- */
+ int ret = 0;
if (mf->mf_flags & MFF_NFSLINK) {
- return amfs_link_ops.mount_fs(mp, mf);
+ if (amfs_link_ops.mount_fs)
+ ret = amfs_link_ops.mount_fs(mp, mf);
} else {
- return nfs_ops.mount_fs(mp, mf);
+ if (nfs_ops.mount_fs)
+ ret = nfs_ops.mount_fs(mp, mf);
}
+ return ret;
}
static int
amfs_nfsl_umount(am_node *mp, mntfs *mf)
{
- /*
- * If a link, do run amfs_link_umount() (same as type:=link)
- * If non-link, do nfs_umount (same as type:=nfs).
- */
+ int ret = 0;
if (mf->mf_flags & MFF_NFSLINK) {
- return amfs_link_ops.umount_fs(mp, mf);
+ if (amfs_link_ops.umount_fs)
+ ret = amfs_link_ops.umount_fs(mp, mf);
} else {
- return nfs_ops.umount_fs(mp, mf);
+ if (nfs_ops.umount_fs)
+ ret = nfs_ops.umount_fs(mp, mf);
}
+ return ret;
}
static void
amfs_nfsl_umounted(mntfs *mf)
{
- /*
- * If a link, do nothing (same as type:=link)
- * If non-link, do nfs_umount (same as type:=nfs).
- */
if (mf->mf_flags & MFF_NFSLINK) {
if (amfs_link_ops.umounted)
amfs_link_ops.umounted(mf);
static fserver *
amfs_nfsl_ffserver(mntfs *mf)
{
- char *cp = mf->mf_fo->opt_fs;
+ char *cp;
char *ho = mf->mf_fo->opt_rhost;
struct stat stb;
+ if (mf->mf_fo->opt_sublink)
+ cp = mf->mf_fo->opt_sublink;
+ else
+ cp = mf->mf_fo->opt_fs;
+
/*
* If this host is not the same as $rhost, or if link does not exist,
- * perform find_nfs_srvr(), same as for type:=nfs.
- * If link value exists (or same host), then perform
- * amfs_generic_find_srvr(), same as for linkx.
+ * call amfs_link_ops.ffserver().
+ * If link value exists (or same host), then call ops_nfs.ffserver().
*/
if (!STRCEQ(ho, am_get_hostname()) || lstat(cp, &stb) < 0) {
- return find_nfs_srvr(mf);
+ return nfs_ops.ffserver(mf);
} else {
mf->mf_flags |= MFF_NFSLINK;
/* remove the FS_MKMNT flag, we don't want amd touching the mountpoint */
mf->mf_fsflags &= ~FS_MKMNT;
- return amfs_generic_find_srvr(mf);
+ return amfs_link_ops.ffserver(mf);
}
}