xref: /csrg-svn/usr.sbin/amd/include/am.h (revision 44922)
1*44922Smckusick /*
2*44922Smckusick  * $Id: am.h,v 5.2 90/06/23 22:20:28 jsp Rel $
3*44922Smckusick  *
4*44922Smckusick  * Copyright (c) 1990 Jan-Simon Pendry
5*44922Smckusick  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
6*44922Smckusick  * Copyright (c) 1990 The Regents of the University of California.
7*44922Smckusick  * All rights reserved.
8*44922Smckusick  *
9*44922Smckusick  * This code is derived from software contributed to Berkeley by
10*44922Smckusick  * Jan-Simon Pendry at Imperial College, London.
11*44922Smckusick  *
12*44922Smckusick  * %sccs.include.redist.c%
13*44922Smckusick  *
14*44922Smckusick  *	@(#)am.h	5.1 (Berkeley) 07/19/90
15*44922Smckusick  */
16*44922Smckusick 
17*44922Smckusick /*
18*44922Smckusick  * Get this in now so that OS_HDR can use it
19*44922Smckusick  */
20*44922Smckusick #ifdef __STDC__
21*44922Smckusick #define	P(x) x
22*44922Smckusick #define	P_void void
23*44922Smckusick #else
24*44922Smckusick #define P(x) ()
25*44922Smckusick #define P_void /* as nothing */
26*44922Smckusick #define const /* as nothing */
27*44922Smckusick #endif /* __STDC__ */
28*44922Smckusick 
29*44922Smckusick #ifdef __GNUC__
30*44922Smckusick #define INLINE /* __inline */
31*44922Smckusick #else
32*44922Smckusick #define	INLINE
33*44922Smckusick #endif /* __GNUC__ */
34*44922Smckusick 
35*44922Smckusick /*
36*44922Smckusick  * Pick up target dependent definitions
37*44922Smckusick  */
38*44922Smckusick #include "os-defaults.h"
39*44922Smckusick #include OS_HDR
40*44922Smckusick 
41*44922Smckusick #ifndef UPDATE_MTAB
42*44922Smckusick #define	unlock_mntlist()
43*44922Smckusick #endif /* UPDATE_MTAB */
44*44922Smckusick 
45*44922Smckusick #ifdef VOIDP
46*44922Smckusick typedef void *voidp;
47*44922Smckusick #else
48*44922Smckusick typedef char *voidp;
49*44922Smckusick #endif /* VOIDP */
50*44922Smckusick 
51*44922Smckusick /*
52*44922Smckusick  * Global declarations
53*44922Smckusick  */
54*44922Smckusick #include <stdio.h>
55*44922Smckusick #include <sys/param.h>
56*44922Smckusick #include <sys/errno.h>
57*44922Smckusick extern int errno;
58*44922Smckusick #include <sys/socket.h>
59*44922Smckusick #include <rpc/rpc.h>
60*44922Smckusick #include "nfs_prot.h"
61*44922Smckusick #ifdef MNTENT_HDR
62*44922Smckusick #include MNTENT_HDR
63*44922Smckusick #endif /* MNTENT_HDR */
64*44922Smckusick #include <sys/time.h>
65*44922Smckusick #include <assert.h>
66*44922Smckusick 
67*44922Smckusick #ifdef DEBUG_MEM
68*44922Smckusick #include <malloc.h>
69*44922Smckusick #endif /* DEBUG_MEM */
70*44922Smckusick 
71*44922Smckusick #ifndef MAXHOSTNAMELEN
72*44922Smckusick #define MAXHOSTNAMELEN 64
73*44922Smckusick #endif /* MAXHOSTNAMELEN */
74*44922Smckusick 
75*44922Smckusick #ifndef MNTTYPE_AUTO
76*44922Smckusick #define MNTTYPE_AUTO "auto"
77*44922Smckusick #endif /* MNTTYPE_AUTO */
78*44922Smckusick 
79*44922Smckusick #ifndef FALSE
80*44922Smckusick #define FALSE 0
81*44922Smckusick #define TRUE 1
82*44922Smckusick #endif /* FALSE */
83*44922Smckusick 
84*44922Smckusick #ifndef ROOT_MAP
85*44922Smckusick #define	ROOT_MAP "\"root\""
86*44922Smckusick #endif /* ROOT_MAP */
87*44922Smckusick 
88*44922Smckusick /*
89*44922Smckusick  * Flags from command line
90*44922Smckusick  */
91*44922Smckusick extern int print_pid;		/* Print pid to stdout */
92*44922Smckusick extern int normalize_hosts;	/* Normalize host names before use */
93*44922Smckusick extern int restart_existing_mounts;
94*44922Smckusick #ifdef HAS_NIS_MAPS
95*44922Smckusick extern char *domain;		/* NIS domain to use */
96*44922Smckusick #endif /* HAS_NIS_MAPS */
97*44922Smckusick extern FILE *logfp;		/* Log file */
98*44922Smckusick extern int xlog_level;		/* Logging level */
99*44922Smckusick #ifdef HAS_SYSLOG
100*44922Smckusick extern int syslogging;		/* Really using syslog */
101*44922Smckusick #endif /* HAS_SYSLOG */
102*44922Smckusick extern int am_timeo;		/* Cache period */
103*44922Smckusick extern int afs_timeo;		/* AFS timeout */
104*44922Smckusick extern int afs_retrans;		/* AFS retrans */
105*44922Smckusick extern int am_timeo_w;		/* Unmount timeout */
106*44922Smckusick extern char *mtab;		/* Mount table */
107*44922Smckusick 
108*44922Smckusick #define	XLOG_FATAL	0x0001
109*44922Smckusick #define	XLOG_ERROR	0x0002
110*44922Smckusick #define	XLOG_USER	0x0004
111*44922Smckusick #define	XLOG_WARNING	0x0008
112*44922Smckusick #define	XLOG_INFO	0x0010
113*44922Smckusick #define	XLOG_DEBUG	0x0020
114*44922Smckusick #define	XLOG_MAP	0x0040
115*44922Smckusick #define	XLOG_STATS	0x0080
116*44922Smckusick 
117*44922Smckusick #define XLOG_DEFSTR	"all,nomap,nostats"		/* Default log options */
118*44922Smckusick #define XLOG_ALL	(XLOG_FATAL|XLOG_ERROR|XLOG_USER|XLOG_WARNING|XLOG_INFO|XLOG_MAP|XLOG_STATS)
119*44922Smckusick 
120*44922Smckusick #ifdef DEBUG
121*44922Smckusick #ifdef DEBUG_MEM
122*44922Smckusick #define free(x) xfree(__FILE__,__LINE__,x)
123*44922Smckusick #endif /* DEBUG_MEM */
124*44922Smckusick 
125*44922Smckusick #define	DEBUG_MTAB	"./mtab"
126*44922Smckusick 
127*44922Smckusick extern int debug_flags;		/* Debug options */
128*44922Smckusick 
129*44922Smckusick #define	D_DAEMON	0x0001	/* Enter daemon mode */
130*44922Smckusick #define	D_TRACE		0x0002	/* Do protocol trace */
131*44922Smckusick #define	D_FULL		0x0004	/* Do full trace */
132*44922Smckusick #define	D_MTAB		0x0008	/* Use local mtab */
133*44922Smckusick #define	D_AMQ		0x0010	/* Register amq program */
134*44922Smckusick #define	D_STR		0x0020	/* Debug string munging */
135*44922Smckusick #define	D_MEM		0x0040	/* Trace memory allocations */
136*44922Smckusick 
137*44922Smckusick /*
138*44922Smckusick  * Normally, don't enter daemon mode, and don't register amq
139*44922Smckusick  */
140*44922Smckusick #define	D_TEST	(~(D_DAEMON|D_MEM|D_STR))
141*44922Smckusick #define	D_ALL	(~0)
142*44922Smckusick 
143*44922Smckusick #define Debug(x) if (!(debug_flags & (x))) ; else
144*44922Smckusick #define dlog Debug(D_FULL) dplog
145*44922Smckusick #endif /* DEBUG */
146*44922Smckusick 
147*44922Smckusick /*
148*44922Smckusick  * Option tables
149*44922Smckusick  */
150*44922Smckusick struct opt_tab {
151*44922Smckusick 	char *opt;
152*44922Smckusick 	int flag;
153*44922Smckusick };
154*44922Smckusick 
155*44922Smckusick typedef enum {
156*44922Smckusick 	Start,
157*44922Smckusick 	Run,
158*44922Smckusick 	Finishing,
159*44922Smckusick 	Quit,
160*44922Smckusick 	Done
161*44922Smckusick } serv_state;
162*44922Smckusick 
163*44922Smckusick extern serv_state amd_state;	/* Should we go now */
164*44922Smckusick extern int immediate_abort;	/* Should close-down unmounts be retried */
165*44922Smckusick extern time_t do_mapc_reload;	/* Flush & reload mount map cache */
166*44922Smckusick 
167*44922Smckusick /*
168*44922Smckusick  * Useful constants
169*44922Smckusick  */
170*44922Smckusick extern char *progname;		/* "amd" */
171*44922Smckusick extern char pid_fsname[];	/* kiska.southseas.nz:(pid%d) */
172*44922Smckusick extern char hostname[];		/* "kiska" */
173*44922Smckusick extern char hostd[];		/* "kiska.southseas.nz" */
174*44922Smckusick extern char *hostdomain;	/* "southseas.nz" */
175*44922Smckusick extern char *op_sys;		/* "sos4" */
176*44922Smckusick extern char *arch;		/* "sun4" */
177*44922Smckusick extern char *karch;		/* "sun4c" */
178*44922Smckusick extern char *cluster;		/* "r+d-kluster" */
179*44922Smckusick extern char *endian;		/* "big" */
180*44922Smckusick extern char *auto_dir;		/* "/a" */
181*44922Smckusick extern char version[];		/* Version info */
182*44922Smckusick 
183*44922Smckusick typedef struct am_ops am_ops;
184*44922Smckusick typedef struct am_node am_node;
185*44922Smckusick typedef struct am_opts am_opts;
186*44922Smckusick typedef struct mntfs mntfs;
187*44922Smckusick typedef struct fserver fserver;
188*44922Smckusick typedef struct fsrvinfo fsrvinfo;
189*44922Smckusick 
190*44922Smckusick /*
191*44922Smckusick  * Global variables.
192*44922Smckusick  */
193*44922Smckusick extern unsigned short nfs_port;	/* Our NFS service port */
194*44922Smckusick extern int mypid;		/* Current process id */
195*44922Smckusick extern struct in_addr myipaddr;	/* (An) IP address of this host */
196*44922Smckusick 
197*44922Smckusick extern int foreground;		/* Foreground process */
198*44922Smckusick extern int orig_umask;		/* umask() on startup */
199*44922Smckusick #define clocktime() (clock_valid ? clock_valid : time(&clock_valid))
200*44922Smckusick extern time_t time P((time_t *));
201*44922Smckusick extern time_t clock_valid;	/* Clock needs recalculating */
202*44922Smckusick extern time_t next_softclock;	/* Time to call softclock() */
203*44922Smckusick extern int task_notify_todo;	/* Task notifier needs running */
204*44922Smckusick #ifdef HAS_TFS
205*44922Smckusick extern int nfs_server_code_available;
206*44922Smckusick #endif /* HAS_TFS */
207*44922Smckusick extern int last_used_map;	/* Last map being used for mounts */
208*44922Smckusick extern AUTH *nfs_auth;		/* Dummy uthorisation for remote servers */
209*44922Smckusick extern am_node *exported_ap[];	/* List of nodes */
210*44922Smckusick extern int first_free_map;	/* First free node */
211*44922Smckusick #define	NEXP_AP	(256)
212*44922Smckusick 
213*44922Smckusick typedef int (*task_fun)P((voidp));
214*44922Smckusick typedef void (*cb_fun)P((int, int, voidp));
215*44922Smckusick typedef void (*fwd_fun)P((voidp, int, struct sockaddr_in *,
216*44922Smckusick 				struct sockaddr_in *, voidp, int));
217*44922Smckusick 
218*44922Smckusick /*
219*44922Smckusick  * String comparison macros
220*44922Smckusick  */
221*44922Smckusick #define STREQ(s1, s2) (strcmp((s1), (s2)) == 0)
222*44922Smckusick #define FSTREQ(s1, s2) ((*(s1) == *(s2)) && STREQ((s1),(s2)))
223*44922Smckusick 
224*44922Smckusick /*
225*44922Smckusick  * Linked list
226*44922Smckusick  */
227*44922Smckusick typedef struct qelem qelem;
228*44922Smckusick struct qelem {
229*44922Smckusick 	qelem *q_forw;
230*44922Smckusick 	qelem *q_back;
231*44922Smckusick };
232*44922Smckusick #define	FIRST(ty, q)	((ty *) ((q)->q_forw))
233*44922Smckusick #define	LAST(ty, q)	((ty *) ((q)->q_back))
234*44922Smckusick #define	NEXT(ty, q)	((ty *) (((qelem *) q)->q_forw))
235*44922Smckusick #define	PREV(ty, q)	((ty *) (((qelem *) q)->q_back))
236*44922Smckusick #define	HEAD(ty, q)	((ty *) q)
237*44922Smckusick #define	ITER(v, ty, q) \
238*44922Smckusick 	for ((v) = FIRST(ty,(q)); (v) != HEAD(ty,(q)); (v) = NEXT(ty,(v)))
239*44922Smckusick 
240*44922Smckusick /*
241*44922Smckusick  * List of mount table entries
242*44922Smckusick  */
243*44922Smckusick typedef struct mntlist mntlist;
244*44922Smckusick struct mntlist {
245*44922Smckusick 	struct mntlist *mnext;
246*44922Smckusick 	struct mntent *mnt;
247*44922Smckusick };
248*44922Smckusick 
249*44922Smckusick /*
250*44922Smckusick  * Mount map
251*44922Smckusick  */
252*44922Smckusick typedef struct mnt_map mnt_map;
253*44922Smckusick 
254*44922Smckusick /*
255*44922Smckusick  * Global routines
256*44922Smckusick  */
257*44922Smckusick extern int atoi P((const char *)); /* C */
258*44922Smckusick extern void am_mounted P((am_node*));
259*44922Smckusick extern void am_unmounted P((am_node*));
260*44922Smckusick extern int background(P_void);
261*44922Smckusick extern int bind_resv_port P((int, unsigned short*));
262*44922Smckusick extern int compute_mount_flags P((struct mntent *));
263*44922Smckusick extern int softclock(P_void);
264*44922Smckusick #ifdef DEBUG
265*44922Smckusick extern int debug_option P((char*));
266*44922Smckusick extern void dplog ();
267*44922Smckusick /*extern void dplog P((char*, ...));*/
268*44922Smckusick #endif /* DEBUG */
269*44922Smckusick /*extern void domain_strip P((char*, char*));*/
270*44922Smckusick extern mntfs* dup_mntfs P((mntfs*));
271*44922Smckusick extern fserver* dup_srvr P((fserver*));
272*44922Smckusick extern int eval_fs_opts P((am_opts*, char*, char*, char*, char*, char*));
273*44922Smckusick extern char* expand_key P((char*));
274*44922Smckusick extern am_node* exported_ap_alloc(P_void);
275*44922Smckusick extern am_node* find_ap P((char*));
276*44922Smckusick extern mntfs* find_mntfs P((am_ops*, am_opts*, char*, char*, char*));
277*44922Smckusick extern void flush_mntfs(P_void);
278*44922Smckusick extern FREE_RETURN_TYPE free P((voidp)); /* C */
279*44922Smckusick extern void free_mntfs P((mntfs*));
280*44922Smckusick extern void free_opts P((am_opts*));
281*44922Smckusick extern void free_map P((am_node*));
282*44922Smckusick extern void free_mntlist P((mntlist*));
283*44922Smckusick extern int fwd_init(P_void);
284*44922Smckusick extern int fwd_packet P((int, voidp, int, struct sockaddr_in *,
285*44922Smckusick 		struct sockaddr_in *, voidp, fwd_fun));
286*44922Smckusick extern void fwd_reply(P_void);
287*44922Smckusick extern void get_args P((int, char*[]));
288*44922Smckusick extern void going_down P((int));
289*44922Smckusick #ifdef NEED_MNTOPT_PARSER
290*44922Smckusick extern char *hasmntopt P((struct mntent*, char*));
291*44922Smckusick #endif /* NEED_MNTOPT_PARSER */
292*44922Smckusick extern int hasmntval P((struct mntent*, char*));
293*44922Smckusick extern void host_normalize P((char **));
294*44922Smckusick extern void init_map P((am_node*, char*));
295*44922Smckusick extern void insert_am P((am_node*, am_node*));
296*44922Smckusick extern void ins_que P((qelem*, qelem*));
297*44922Smckusick extern void make_root_node(P_void);
298*44922Smckusick extern int make_rpc_packet P((char*, int, u_long, struct rpc_msg*, voidp, xdrproc_t, AUTH*));
299*44922Smckusick extern void mapc_add_kv P((mnt_map*, char*, char*));
300*44922Smckusick extern mnt_map* mapc_find P((char*, char*));
301*44922Smckusick extern void mapc_free P((mnt_map*));
302*44922Smckusick extern int mapc_search P((mnt_map*, char*, char**));
303*44922Smckusick extern void mapc_reload(P_void);
304*44922Smckusick extern void mapc_showtypes P((FILE*));
305*44922Smckusick extern int mkdirs P((char*, int));
306*44922Smckusick extern void mnt_free P((struct mntent*));
307*44922Smckusick extern int mount_automounter P((int));
308*44922Smckusick extern int mount_exported(P_void);
309*44922Smckusick extern int mount_node P((am_node*));
310*44922Smckusick extern mntfs* new_mntfs(P_void);
311*44922Smckusick extern void new_ttl P((am_node*));
312*44922Smckusick extern am_node* next_map P((int*));
313*44922Smckusick extern int nfs_srvr_port P((fserver*, u_short*, voidp));
314*44922Smckusick extern int pickup_rpc_reply P((voidp, int, voidp, xdrproc_t));
315*44922Smckusick extern void plog ();
316*44922Smckusick /*extern void plog P((int, char*, ...));*/
317*44922Smckusick extern mntlist* read_mtab P((char*));
318*44922Smckusick extern mntfs* realloc_mntfs  P((mntfs*, am_ops*, am_opts*, char*, char*, char*));
319*44922Smckusick extern void rem_que P((qelem*));
320*44922Smckusick extern void reschedule_timeout_mp(P_void);
321*44922Smckusick extern void restart(P_void);
322*44922Smckusick #ifdef UPDATE_MTAB
323*44922Smckusick extern void rewrite_mtab P((mntlist *));
324*44922Smckusick #endif /* UPDATE_MTAB */
325*44922Smckusick extern void rmdirs P((char*));
326*44922Smckusick extern am_node* root_ap P((char*, int));
327*44922Smckusick extern void root_newmap P((char*, char*, char*));
328*44922Smckusick extern void rpc_msg_init P((struct rpc_msg*, u_long, u_long, u_long));
329*44922Smckusick extern void run_task P((task_fun, voidp, cb_fun, voidp));
330*44922Smckusick extern void sched_task P((cb_fun, voidp, voidp));
331*44922Smckusick extern void show_rcs_info P((const char*, char*));
332*44922Smckusick extern void sigchld P((int));
333*44922Smckusick extern void srvrlog P((fserver*, char*));
334*44922Smckusick extern char* str3cat P((char*, char*, char*, char*));
335*44922Smckusick extern char* strcat P((char*, const char*)); /* C */
336*44922Smckusick extern char* strchr P((const char*, int)); /* C */
337*44922Smckusick extern int strcmp P((const char*, const char*)); /* C */
338*44922Smckusick extern char* strdup P((const char*));
339*44922Smckusick extern int strlen P((const char*)); /* C */
340*44922Smckusick extern char* strnsave P((const char*, int));
341*44922Smckusick extern char* strrchr P((const char*, int)); /* C */
342*44922Smckusick extern char* strealloc P((char*, char *));
343*44922Smckusick extern char** strsplit P((char*, int));
344*44922Smckusick extern int switch_option P((char*));
345*44922Smckusick extern void task_notify(P_void);
346*44922Smckusick extern int timeout P((unsigned int, void (*fn)(), voidp));
347*44922Smckusick extern void timeout_mp(P_void);
348*44922Smckusick extern void umount_exported(P_void);
349*44922Smckusick /*extern int unmount_node P((am_node*));
350*44922Smckusick extern int unmount_node_wrap P((voidp));*/
351*44922Smckusick extern void unregister_amq(P_void);
352*44922Smckusick extern void untimeout P((int));
353*44922Smckusick extern int valid_key P((char*));
354*44922Smckusick extern void wakeup P((voidp));
355*44922Smckusick extern void wakeup_task P((int,int,voidp));
356*44922Smckusick extern void wakeup_srvr P((fserver*));
357*44922Smckusick extern void write_mntent P((struct mntent*));
358*44922Smckusick extern voidp xmalloc P((int));
359*44922Smckusick extern voidp xrealloc P((voidp, int));
360*44922Smckusick 
361*44922Smckusick #define	ALLOC(ty)	((struct ty *) xmalloc(sizeof(struct ty)))
362*44922Smckusick 
363*44922Smckusick /*
364*44922Smckusick  * Options
365*44922Smckusick  */
366*44922Smckusick struct am_opts {
367*44922Smckusick 	char	*fs_glob;		/* Smashed copy of global options */
368*44922Smckusick 	char	*fs_local;		/* Expanded copy of local options */
369*44922Smckusick 	char	*fs_mtab;		/* Mount table entry */
370*44922Smckusick 	/* Other options ... */
371*44922Smckusick 	char	*opt_dev;
372*44922Smckusick 	char	*opt_delay;
373*44922Smckusick 	char	*opt_dir;
374*44922Smckusick 	char	*opt_fs;
375*44922Smckusick 	char	*opt_group;
376*44922Smckusick 	char	*opt_mount;
377*44922Smckusick 	char	*opt_opts;
378*44922Smckusick 	char	*opt_pref;
379*44922Smckusick 	char	*opt_cache;
380*44922Smckusick 	char	*opt_rfs;
381*44922Smckusick 	char	*opt_rhost;
382*44922Smckusick 	char	*opt_sublink;
383*44922Smckusick 	char	*opt_type;
384*44922Smckusick 	char	*opt_unmount;
385*44922Smckusick 	char	*opt_user;
386*44922Smckusick };
387*44922Smckusick 
388*44922Smckusick /*
389*44922Smckusick  * File Handle
390*44922Smckusick  *
391*44922Smckusick  * This is interpreted by indexing the exported array
392*44922Smckusick  * by fhh_id.
393*44922Smckusick  *
394*44922Smckusick  * The whole structure is mapped onto a standard fhandle_t
395*44922Smckusick  * when transmitted.
396*44922Smckusick  */
397*44922Smckusick struct am_fh {
398*44922Smckusick 	int	fhh_pid;		/* process id */
399*44922Smckusick 	int	fhh_id;			/* map id */
400*44922Smckusick 	int	fhh_gen;		/* generation number */
401*44922Smckusick };
402*44922Smckusick 
403*44922Smckusick extern am_node *fh_to_mp P((nfs_fh*));
404*44922Smckusick extern am_node *fh_to_mp3 P((nfs_fh*,int*,int));
405*44922Smckusick extern void mp_to_fh P((am_node*, nfs_fh*));
406*44922Smckusick #define	fh_to_mp2(fhp, rp) fh_to_mp3(fhp, rp, VLOOK_CREATE)
407*44922Smckusick 
408*44922Smckusick typedef int	(*vfs_match)P((am_opts*));
409*44922Smckusick typedef int	(*vfs_init)P((mntfs*));
410*44922Smckusick typedef int	(*vmount_fs)P((am_node*));
411*44922Smckusick typedef int	(*vumount_fs)P((am_node*));
412*44922Smckusick typedef am_node*(*vlookuppn)P((am_node*, char*, int*, int));
413*44922Smckusick typedef int	(*vreaddir)P((am_node*, nfscookie, dirlist*, entry*));
414*44922Smckusick typedef am_node*(*vreadlink)P((am_node*, int*));
415*44922Smckusick typedef int	(*vmounted)P((mntfs*));
416*44922Smckusick typedef void	(*vumounted)P((am_node*));
417*44922Smckusick typedef fserver*(*vffserver)P((mntfs*));
418*44922Smckusick 
419*44922Smckusick struct am_ops {
420*44922Smckusick 	char		*fs_type;
421*44922Smckusick 	vfs_match	fs_match;
422*44922Smckusick 	vfs_init	fs_init;
423*44922Smckusick 	vmount_fs	mount_fs;
424*44922Smckusick 	vumount_fs	umount_fs;
425*44922Smckusick 	vlookuppn	lookuppn;
426*44922Smckusick 	vreaddir	readdir;
427*44922Smckusick 	vreadlink	readlink;
428*44922Smckusick 	vmounted	mounted;
429*44922Smckusick 	vumounted	umounted;
430*44922Smckusick 	vffserver	ffserver;
431*44922Smckusick 	int		fs_flags;
432*44922Smckusick };
433*44922Smckusick extern am_node *efs_lookuppn P((am_node*, char*, int*, int));
434*44922Smckusick extern int efs_readdir P((am_node*, nfscookie, dirlist*, entry*));
435*44922Smckusick 
436*44922Smckusick #define	VLOOK_CREATE	0x1
437*44922Smckusick #define	VLOOK_DELETE	0x2
438*44922Smckusick 
439*44922Smckusick #define	FS_RETRY	0x0001		/* Retry this type of mount */
440*44922Smckusick #define	FS_MBACKGROUND	0x0002		/* Should background this mount */
441*44922Smckusick #define	FS_NOTIMEOUT	0x0004		/* Don't bother with timeouts */
442*44922Smckusick #define FS_MKMNT	0x0008		/* Need to make the mkdir point */
443*44922Smckusick #define FS_UBACKGROUND	0x0010		/* Unmount in background */
444*44922Smckusick #define	FS_BACKGROUND	(FS_MBACKGROUND|FS_UBACKGROUND)
445*44922Smckusick #define	FS_DISCARD	0x0020		/* Discard immediately on last reference */
446*44922Smckusick #define	FS_AMQINFO	0x0040		/* Amq is interested in this fs type */
447*44922Smckusick 
448*44922Smckusick #ifdef SUNOS4_COMPAT
449*44922Smckusick extern am_ops *sunos4_match P((am_opts*, char*, char*, char*, char*, char*));
450*44922Smckusick #endif /* SUNOS4_COMPAT */
451*44922Smckusick extern am_ops *ops_match P((am_opts*, char*, char*, char*, char*, char*));
452*44922Smckusick #include "fstype.h"
453*44922Smckusick 
454*44922Smckusick /*
455*44922Smckusick  * Per-mountpoint statistics
456*44922Smckusick  */
457*44922Smckusick struct am_stats {
458*44922Smckusick 	time_t	s_mtime;	/* Mount time */
459*44922Smckusick 	u_short	s_uid;		/* Uid of mounter */
460*44922Smckusick 	int	s_getattr;	/* Count of getattrs */
461*44922Smckusick 	int	s_lookup;	/* Count of lookups */
462*44922Smckusick 	int	s_readdir;	/* Count of readdirs */
463*44922Smckusick 	int	s_readlink;	/* Count of readlinks */
464*44922Smckusick 	int	s_statfs;	/* Count of statfs */
465*44922Smckusick };
466*44922Smckusick typedef struct am_stats am_stats;
467*44922Smckusick 
468*44922Smckusick /*
469*44922Smckusick  * System statistics
470*44922Smckusick  */
471*44922Smckusick struct amd_stats {
472*44922Smckusick 	int	d_drops;	/* Dropped requests */
473*44922Smckusick 	int	d_stale;	/* Stale NFS handles */
474*44922Smckusick 	int	d_mok;		/* Succesful mounts */
475*44922Smckusick 	int	d_merr;		/* Failed mounts */
476*44922Smckusick 	int	d_uerr;		/* Failed unmounts */
477*44922Smckusick };
478*44922Smckusick extern struct amd_stats amd_stats;
479*44922Smckusick 
480*44922Smckusick /*
481*44922Smckusick  * List of fileservers
482*44922Smckusick  */
483*44922Smckusick struct fserver {
484*44922Smckusick 	qelem		fs_q;		/* List of fileservers */
485*44922Smckusick 	int		fs_refc;	/* Number of references to this node */
486*44922Smckusick 	char		*fs_host;	/* Normalized hostname of server */
487*44922Smckusick 	struct sockaddr_in *fs_ip;	/* Network address of server */
488*44922Smckusick 	int		fs_cid;		/* Callout id */
489*44922Smckusick 	int		fs_pinger;	/* Ping (keepalive) interval */
490*44922Smckusick 	int		fs_flags;	/* Flags */
491*44922Smckusick 	char		*fs_type;	/* File server type */
492*44922Smckusick 	voidp		fs_private;	/* Private data */
493*44922Smckusick 	void		(*fs_prfree)();	/* Free private data */
494*44922Smckusick };
495*44922Smckusick #define	FSF_VALID	0x0001		/* Valid information available */
496*44922Smckusick #define	FSF_DOWN	0x0002		/* This fileserver is thought to be down */
497*44922Smckusick #define	FSF_ERROR	0x0004		/* Permanent error has occured */
498*44922Smckusick #define	FSF_WANT	0x0008		/* Want a wakeup call */
499*44922Smckusick #define	FSF_PINGING	0x0010		/* Already doing pings */
500*44922Smckusick #define	FSRV_ISDOWN(fs)	(((fs)->fs_flags & (FSF_DOWN|FSF_VALID)) == (FSF_DOWN|FSF_VALID))
501*44922Smckusick #define	FSRV_ISUP(fs)	(((fs)->fs_flags & (FSF_DOWN|FSF_VALID)) == (FSF_VALID))
502*44922Smckusick 
503*44922Smckusick /*
504*44922Smckusick  * List of mounted filesystems
505*44922Smckusick  */
506*44922Smckusick struct mntfs {
507*44922Smckusick 	qelem		mf_q;		/* List of mounted filesystems */
508*44922Smckusick 	am_ops		*mf_ops;	/* Operations on this mountpoint */
509*44922Smckusick 	am_opts		*mf_fo;		/* File opts */
510*44922Smckusick 	struct attrstat	mf_attr;	/* File attributes */
511*44922Smckusick #define mf_fattr	mf_attr.attrstat_u.attributes
512*44922Smckusick 	char		*mf_mount;	/* "/a/kiska/home/kiska" */
513*44922Smckusick 	char		*mf_info;	/* Mount info */
514*44922Smckusick 	char		*mf_opts;	/* Mount opts */
515*44922Smckusick 	fserver		*mf_server;	/* File server */
516*44922Smckusick 	int		mf_flags;	/* Flags */
517*44922Smckusick 	int		mf_error;	/* Error code from background mount */
518*44922Smckusick 	int		mf_refc;	/* Number of references to this node */
519*44922Smckusick 	int		mf_cid;		/* Callout id */
520*44922Smckusick 	void		(*mf_prfree)();	/* Free private space */
521*44922Smckusick 	voidp		mf_private;	/* Private - per-fs data */
522*44922Smckusick };
523*44922Smckusick 
524*44922Smckusick #define	MFF_MOUNTED	0x0001		/* Node is mounted */
525*44922Smckusick #define	MFF_MOUNTING	0x0002		/* Mount is in progress */
526*44922Smckusick #define	MFF_UNMOUNTING	0x0004		/* Unmount is in progress */
527*44922Smckusick #define	MFF_RESTART	0x0008		/* Restarted node */
528*44922Smckusick #define MFF_MKMNT	0x0010		/* Delete this node's am_mount */
529*44922Smckusick #define	MFF_ERROR	0x0020		/* This node failed to mount */
530*44922Smckusick #define	MFF_LOGDOWN	0x0040		/* Logged that this mount is down */
531*44922Smckusick #define	MFF_RSTKEEP	0x0080		/* Don't timeout this filesystem - restarted */
532*44922Smckusick #define	MFF_WANTTIMO	0x0100		/* Need a timeout call when not busy */
533*44922Smckusick 
534*44922Smckusick /*
535*44922Smckusick  * Map of auto-mount points.
536*44922Smckusick  */
537*44922Smckusick struct am_node {
538*44922Smckusick 	int		am_mapno;	/* Map number */
539*44922Smckusick 	mntfs		*am_mnt;	/* Mounted filesystem */
540*44922Smckusick 	char		*am_name;	/* "kiska"
541*44922Smckusick 					   Name of this node */
542*44922Smckusick 	char		*am_path;	/* "/home/kiska"
543*44922Smckusick 					   Path of this node's mount point */
544*44922Smckusick 	char		*am_link;	/* "/a/kiska/home/kiska/this/that"
545*44922Smckusick 					   Link to sub-directory */
546*44922Smckusick 	am_node		*am_parent,	/* Parent of this node */
547*44922Smckusick 			*am_ysib,	/* Younger sibling of this node */
548*44922Smckusick 			*am_osib,	/* Older sibling of this node */
549*44922Smckusick 			*am_child;	/* First child of this node */
550*44922Smckusick 	int		am_flags;	/* Boolean flags */
551*44922Smckusick 	int		am_error;	/* Specific mount error */
552*44922Smckusick 	time_t		am_ttl;		/* Time to live */
553*44922Smckusick 	int		am_timeo_w;	/* Wait interval */
554*44922Smckusick 	int		am_timeo;	/* Timeout interval */
555*44922Smckusick 	unsigned int	am_gen;		/* Generation number */
556*44922Smckusick 	char		*am_pref;	/* Mount info prefix */
557*44922Smckusick 	am_stats	am_stats;	/* Statistics gathering */
558*44922Smckusick };
559*44922Smckusick 
560*44922Smckusick #define	AMF_NOTIMEOUT	0x0001		/* This node never times out */
561*44922Smckusick #define	AMF_ROOT	0x0002		/* This is a root node */
562*44922Smckusick #define AMF_MKPATH	0x0004		/* Delete this node's am_path */
563*44922Smckusick 
564*44922Smckusick #define	ONE_HOUR	(60 * 60)	/* One hour in seconds */
565*44922Smckusick 
566*44922Smckusick /*
567*44922Smckusick  * The following values can be tuned...
568*44922Smckusick  */
569*44922Smckusick #define	ALLOWED_MOUNT_TIME	40		/* 40s for a mount */
570*44922Smckusick #define	AM_TTL			(5 * 60)	/* Default cache period */
571*44922Smckusick #define	AM_TTL_W		(2 * 60)	/* Default unmount interval */
572*44922Smckusick #define	AM_PINGER		30		/* NFS ping interval for live systems */
573*44922Smckusick #define	AFS_TIMEO		8		/* Default afs timeout - .8s */
574*44922Smckusick #define	AFS_RETRANS		((ALLOWED_MOUNT_TIME*10+2*afs_timeo)/afs_timeo)
575*44922Smckusick 						/* Default afs timeout - 1/10th seconds */
576*44922Smckusick 
577*44922Smckusick #define	RPC_XID_PORTMAP		0
578*44922Smckusick #define	RPC_XID_MOUNTD		1
579*44922Smckusick #define	RPC_XID_NFSPING		2
580*44922Smckusick #define	RPC_XID_MASK		(0x0f)		/* 16 id's for now */
581*44922Smckusick #define	MK_RPC_XID(type_id, uniq)	((type_id) | ((uniq) << 4))
582