2 * Copyright (c) 1997-2006 Erez Zadok
3 * Copyright (c) 1990 Jan-Simon Pendry
4 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
5 * Copyright (c) 1990 The Regents of the University of California.
8 * This code is derived from software contributed to Berkeley by
9 * Jan-Simon Pendry at Imperial College, London.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgment:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * File: am-utils/amd/amfs_nfsl.c
45 * NFSL: Network file system with local existence check. If the local
46 * path denoted by $rfs exists, it behaves as type:=link.
49 * pkg type:=nfsl;rhost:=jonny;rfs:=/n/johnny/src/pkg;fs:=${rfs}
54 #endif /* HAVE_CONFIG_H */
59 /* forward declarations */
60 static char *amfs_nfsl_match(am_opts *fo);
61 static int amfs_nfsl_init(mntfs *mf);
62 static int amfs_nfsl_mount(am_node *mp, mntfs *mf);
63 static int amfs_nfsl_umount(am_node *mp, mntfs *mf);
64 static void amfs_nfsl_umounted(mntfs *mf);
65 static fserver *amfs_nfsl_ffserver(mntfs *mf);
70 am_ops amfs_nfsl_ops =
77 amfs_error_lookup_child,
78 amfs_error_mount_child,
80 0, /* amfs_nfsl_readlink */
81 0, /* amfs_nfsl_mounted */
84 0, /* amfs_nfsl_get_wchan */
85 FS_MKMNT | FS_BACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
88 #endif /* HAVE_FS_AUTOFS */
93 * Check that f/s has all needed fields.
94 * Returns: matched string if found, NULL otherwise.
97 amfs_nfsl_match(am_opts *fo)
100 char *ho = fo->opt_rhost;
105 cp = fo->opt_sublink;
110 plog(XLOG_USER, "amfs_nfsl: host $fs and $rhost must be specified");
115 * If this host is not the same as $rhost, or if link does not exist,
116 * call nfs_ops.fs_match().
117 * If link value exists (or same host), call amfs_link_ops.fs_match().
119 if (!STRCEQ(ho, am_get_hostname())) {
120 plog(XLOG_INFO, "amfs_nfsl: \"%s\" is not local host, using type:=nfs", ho);
121 retval = nfs_ops.fs_match(fo);
122 } else if (lstat(cp, &stb) < 0) {
123 plog(XLOG_INFO, "amfs_nfsl: \"%s\" does not exist, using type:=nfs", cp);
124 retval = nfs_ops.fs_match(fo);
126 plog(XLOG_INFO, "amfs_nfsl: \"%s\" exists, using type:=link", cp);
127 retval = amfs_link_ops.fs_match(fo);
135 * Returns: 0 if OK, non-zero (errno) if failed.
138 amfs_nfsl_init(mntfs *mf)
141 if (mf->mf_flags & MFF_NFSLINK) {
142 if (amfs_link_ops.fs_init)
143 ret = amfs_link_ops.fs_init(mf);
146 ret = nfs_ops.fs_init(mf);
154 * Returns: 0 if OK, non-zero (errno) if failed.
157 amfs_nfsl_mount(am_node *mp, mntfs *mf)
160 if (mf->mf_flags & MFF_NFSLINK) {
161 if (amfs_link_ops.mount_fs)
162 ret = amfs_link_ops.mount_fs(mp, mf);
164 if (nfs_ops.mount_fs)
165 ret = nfs_ops.mount_fs(mp, mf);
173 * Returns: 0 if OK, non-zero (errno) if failed.
176 amfs_nfsl_umount(am_node *mp, mntfs *mf)
179 if (mf->mf_flags & MFF_NFSLINK) {
180 if (amfs_link_ops.umount_fs)
181 ret = amfs_link_ops.umount_fs(mp, mf);
183 if (nfs_ops.umount_fs)
184 ret = nfs_ops.umount_fs(mp, mf);
191 * Async unmount callback function.
192 * After the base umount() succeeds, we may want to take extra actions,
193 * such as informing remote mount daemons that we've unmounted them.
194 * See amfs_auto_umounted(), host_umounted(), nfs_umounted().
197 amfs_nfsl_umounted(mntfs *mf)
199 if (mf->mf_flags & MFF_NFSLINK) {
200 if (amfs_link_ops.umounted)
201 amfs_link_ops.umounted(mf);
203 if (nfs_ops.umounted)
204 nfs_ops.umounted(mf);
210 * Find a file server.
211 * Returns: fserver of found server, or NULL if not found.
214 amfs_nfsl_ffserver(mntfs *mf)
217 char *ho = mf->mf_fo->opt_rhost;
220 if (mf->mf_fo->opt_sublink)
221 cp = mf->mf_fo->opt_sublink;
223 cp = mf->mf_fo->opt_fs;
226 * If this host is not the same as $rhost, or if link does not exist,
227 * call amfs_link_ops.ffserver().
228 * If link value exists (or same host), then call ops_nfs.ffserver().
230 if (!STRCEQ(ho, am_get_hostname()) || lstat(cp, &stb) < 0) {
231 return nfs_ops.ffserver(mf);
233 mf->mf_flags |= MFF_NFSLINK;
234 /* remove the FS_MKMNT flag, we don't want amd touching the mountpoint */
235 mf->mf_fsflags &= ~FS_MKMNT;
236 return amfs_link_ops.ffserver(mf);