Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / bsd / am-utils / dist / amd / amfs_nfsl.c
blobf942d3862ad085a32509b7d9ec113334174ca3bd
1 /* $NetBSD$ */
3 /*
4 * Copyright (c) 1997-2009 Erez Zadok
5 * Copyright (c) 1990 Jan-Simon Pendry
6 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
7 * Copyright (c) 1990 The Regents of the University of California.
8 * All rights reserved.
10 * This code is derived from software contributed to Berkeley by
11 * Jan-Simon Pendry at Imperial College, London.
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgment:
23 * This product includes software developed by the University of
24 * California, Berkeley and its contributors.
25 * 4. Neither the name of the University nor the names of its contributors
26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * SUCH DAMAGE.
42 * File: am-utils/amd/amfs_nfsl.c
47 * NFSL: Network file system with local existence check. If the local
48 * path denoted by $rfs exists, it behaves as type:=link.
50 * Example:
51 * pkg type:=nfsl;rhost:=jonny;rfs:=/n/johnny/src/pkg;fs:=${rfs}
54 #ifdef HAVE_CONFIG_H
55 # include <config.h>
56 #endif /* HAVE_CONFIG_H */
57 #include <am_defs.h>
58 #include <amd.h>
61 /* forward declarations */
62 static char *amfs_nfsl_match(am_opts *fo);
63 static int amfs_nfsl_init(mntfs *mf);
64 static int amfs_nfsl_mount(am_node *mp, mntfs *mf);
65 static int amfs_nfsl_umount(am_node *mp, mntfs *mf);
66 static void amfs_nfsl_umounted(mntfs *mf);
67 static fserver *amfs_nfsl_ffserver(mntfs *mf);
70 * NFS-Link operations
72 am_ops amfs_nfsl_ops =
74 "nfsl",
75 amfs_nfsl_match,
76 amfs_nfsl_init,
77 amfs_nfsl_mount,
78 amfs_nfsl_umount,
79 amfs_error_lookup_child,
80 amfs_error_mount_child,
81 amfs_error_readdir,
82 0, /* amfs_nfsl_readlink */
83 0, /* amfs_nfsl_mounted */
84 amfs_nfsl_umounted,
85 amfs_nfsl_ffserver,
86 0, /* amfs_nfsl_get_wchan */
87 FS_MKMNT | FS_BACKGROUND | FS_AMQINFO, /* nfs_fs_flags */
88 #ifdef HAVE_FS_AUTOFS
89 AUTOFS_NFSL_FS_FLAGS,
90 #endif /* HAVE_FS_AUTOFS */
95 * Check that f/s has all needed fields.
96 * Returns: matched string if found, NULL otherwise.
98 static char *
99 amfs_nfsl_match(am_opts *fo)
101 char *cp;
102 char *ho = fo->opt_rhost;
103 char *retval;
104 struct stat stb;
106 if (fo->opt_sublink && fo->opt_sublink[0])
107 cp = fo->opt_sublink;
108 else
109 cp = fo->opt_fs;
111 if (!cp || !ho) {
112 plog(XLOG_USER, "amfs_nfsl: host $fs and $rhost must be specified");
113 return NULL;
117 * If this host is not the same as $rhost, or if link does not exist,
118 * call nfs_ops.fs_match().
119 * If link value exists (or same host), call amfs_link_ops.fs_match().
121 if (!STRCEQ(ho, am_get_hostname())) {
122 plog(XLOG_INFO, "amfs_nfsl: \"%s\" is not local host, using type:=nfs", ho);
123 retval = nfs_ops.fs_match(fo);
124 } else if (lstat(cp, &stb) < 0) {
125 plog(XLOG_INFO, "amfs_nfsl: \"%s\" does not exist, using type:=nfs", cp);
126 retval = nfs_ops.fs_match(fo);
127 } else {
128 plog(XLOG_INFO, "amfs_nfsl: \"%s\" exists, using type:=link", cp);
129 retval = amfs_link_ops.fs_match(fo);
131 return retval;
136 * Initialize.
137 * Returns: 0 if OK, non-zero (errno) if failed.
139 static int
140 amfs_nfsl_init(mntfs *mf)
142 int ret = 0;
143 if (mf->mf_flags & MFF_NFSLINK) {
144 if (amfs_link_ops.fs_init)
145 ret = amfs_link_ops.fs_init(mf);
146 } else {
147 if (nfs_ops.fs_init)
148 ret = nfs_ops.fs_init(mf);
150 return ret;
155 * Mount vfs.
156 * Returns: 0 if OK, non-zero (errno) if failed.
158 static int
159 amfs_nfsl_mount(am_node *mp, mntfs *mf)
161 int ret = 0;
162 if (mf->mf_flags & MFF_NFSLINK) {
163 if (amfs_link_ops.mount_fs)
164 ret = amfs_link_ops.mount_fs(mp, mf);
165 } else {
166 if (nfs_ops.mount_fs)
167 ret = nfs_ops.mount_fs(mp, mf);
169 return ret;
174 * Unmount VFS.
175 * Returns: 0 if OK, non-zero (errno) if failed.
177 static int
178 amfs_nfsl_umount(am_node *mp, mntfs *mf)
180 int ret = 0;
181 if (mf->mf_flags & MFF_NFSLINK) {
182 if (amfs_link_ops.umount_fs)
183 ret = amfs_link_ops.umount_fs(mp, mf);
184 } else {
185 if (nfs_ops.umount_fs)
186 ret = nfs_ops.umount_fs(mp, mf);
188 return ret;
193 * Async unmount callback function.
194 * After the base umount() succeeds, we may want to take extra actions,
195 * such as informing remote mount daemons that we've unmounted them.
196 * See amfs_auto_umounted(), host_umounted(), nfs_umounted().
198 static void
199 amfs_nfsl_umounted(mntfs *mf)
201 if (mf->mf_flags & MFF_NFSLINK) {
202 if (amfs_link_ops.umounted)
203 amfs_link_ops.umounted(mf);
204 } else {
205 if (nfs_ops.umounted)
206 nfs_ops.umounted(mf);
212 * Find a file server.
213 * Returns: fserver of found server, or NULL if not found.
215 static fserver *
216 amfs_nfsl_ffserver(mntfs *mf)
218 char *cp;
219 char *ho = mf->mf_fo->opt_rhost;
220 struct stat stb;
222 if (mf->mf_fo->opt_sublink && mf->mf_fo->opt_sublink[0])
223 cp = mf->mf_fo->opt_sublink;
224 else
225 cp = mf->mf_fo->opt_fs;
228 * If this host is not the same as $rhost, or if link does not exist,
229 * call amfs_link_ops.ffserver().
230 * If link value exists (or same host), then call ops_nfs.ffserver().
232 if (!STRCEQ(ho, am_get_hostname()) || lstat(cp, &stb) < 0) {
233 return nfs_ops.ffserver(mf);
234 } else {
235 mf->mf_flags |= MFF_NFSLINK;
236 /* remove the FS_MKMNT flag, we don't want amd touching the mountpoint */
237 mf->mf_fsflags &= ~FS_MKMNT;
238 return amfs_link_ops.ffserver(mf);