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