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