Home | History | Annotate | Download | only in fs
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #ifndef	_SYS_FS_AUTOFS_H
     27 #define	_SYS_FS_AUTOFS_H
     28 
     29 #include <rpc/clnt.h>
     30 #include <gssapi/gssapi.h>
     31 #include <sys/vfs.h>
     32 #include <sys/dirent.h>
     33 #include <sys/types.h>
     34 #include <sys/types32.h>
     35 #include <sys/note.h>
     36 #include <sys/time_impl.h>
     37 #include <sys/mntent.h>
     38 #include <nfs/mount.h>
     39 #include <rpc/rpcsec_gss.h>
     40 #include <sys/zone.h>
     41 #include <sys/door.h>
     42 #include <rpcsvc/autofs_prot.h>
     43 
     44 #ifdef _KERNEL
     45 #include <sys/vfs_opreg.h>
     46 #endif
     47 
     48 #ifdef	__cplusplus
     49 extern "C" {
     50 #endif
     51 
     52 
     53 #ifdef	_KERNEL
     54 
     55 
     56 /*
     57  * Tracing macro; expands to nothing for non-debug kernels.
     58  */
     59 #ifndef DEBUG
     60 #define	AUTOFS_DPRINT(x)
     61 #else
     62 #define	AUTOFS_DPRINT(x)	auto_dprint x
     63 #endif
     64 
     65 /*
     66  * Per AUTOFS mountpoint information.
     67  */
     68 typedef struct fninfo {
     69 	struct vfs	*fi_mountvfs;		/* mounted-here VFS */
     70 	struct vnode	*fi_rootvp;		/* root vnode */
     71 	struct knetconfig fi_knconf;		/* netconfig */
     72 	struct netbuf	fi_addr;		/* daemon address */
     73 	char		*fi_path;		/* autofs mountpoint */
     74 	char 		*fi_map;		/* context/map-name */
     75 	char		*fi_subdir;		/* subdir within map */
     76 	char		*fi_key;		/* key to use on direct maps */
     77 	char		*fi_opts;		/* default mount options */
     78 	int		fi_pathlen;		/* autofs mountpoint len */
     79 	int		fi_maplen;		/* size of context */
     80 	int		fi_subdirlen;
     81 	int		fi_keylen;
     82 	int		fi_optslen;		/* default mount options len */
     83 	int		fi_refcnt;		/* reference count */
     84 	int		fi_flags;
     85 	int		fi_mount_to;
     86 	int		fi_rpc_to;
     87 	zoneid_t	fi_zoneid;		/* zone mounted in */
     88 } fninfo_t;
     89 
     90 /*
     91  * The AUTOFS locking scheme:
     92  *
     93  * The locks:
     94  * 	fn_lock: protects the fn_node. It must be grabbed to change any
     95  *		 field on the fn_node, except for those protected by
     96  *		 fn_rwlock.
     97  *
     98  * 	fn_rwlock: readers/writers lock to protect the subdirectory and
     99  *		   top level list traversal.
    100  *		   Protects: fn_dirents
    101  *			     fn_next
    102  *		             fn_size
    103  *		             fn_linkcnt
    104  *                 - Grab readers when checking if certain fn_node exists
    105  *                   under fn_dirents.
    106  *		   - Grab readers when attempting to reference a node
    107  *                   pointed to by fn_dirents, fn_next, and fn_parent.
    108  *                 - Grab writers to add a new fnnode under fn_dirents and
    109  *		     to remove a node pointed to by fn_dirents or fn_next.
    110  *
    111  *
    112  * The flags:
    113  *	MF_INPROG:
    114  *		- Indicates a mount request has been sent to the daemon.
    115  *		- If this flag is set, the thread sets MF_WAITING on the
    116  *                fnnode and sleeps.
    117  *
    118  *	MF_WAITING:
    119  *		- Set by a thread when it puts itself to sleep waiting for
    120  *		  the ongoing operation on this fnnode to be done.
    121  *
    122  * 	MF_LOOKUP:
    123  * 		- Indicates a lookup request has been sent to the daemon.
    124  *		- If this flag is set, the thread sets MF_WAITING on the
    125  *                fnnode and sleeps.
    126  *
    127  *	MF_IK_MOUNT:
    128  *		- This flag is set to indicate the mount was done in the
    129  *		  kernel, and so should the unmount.
    130  *
    131  *	MF_DIRECT:
    132  *		- Direct mountpoint if set, indirect otherwise.
    133  *
    134  *	MF_TRIGGER:
    135  *		- This is a trigger node.
    136  *
    137  *	MF_THISUID_MATCH_RQD:
    138  *		- User-relative context binding kind of node.
    139  *		- Node with this flag set requires a name match as well
    140  *		  as a cred match in order to be returned from the directory
    141  *		  hierarchy.
    142  *
    143  * 	MF_MOUNTPOINT:
    144  * 		- At some point automountd mounted a filesystem on this node.
    145  * 		If fn_trigger is non-NULL, v_vfsmountedhere is NULL and this
    146  * 		flag is set then the filesystem must have been forcibly
    147  * 		unmounted.
    148  */
    149 
    150 /*
    151  * The inode of AUTOFS
    152  */
    153 typedef struct fnnode {
    154 	char		*fn_name;
    155 	char		*fn_symlink;		/* if VLNK, this is what it */
    156 						/* points to */
    157 	int		fn_namelen;
    158 	int		fn_symlinklen;
    159 	uint_t		fn_linkcnt;		/* link count */
    160 	mode_t		fn_mode;		/* file mode bits */
    161 	uid_t		fn_uid;			/* owner's uid */
    162 	gid_t		fn_gid;			/* group's uid */
    163 	int		fn_error;		/* mount/lookup error */
    164 	ino_t		fn_nodeid;
    165 	off_t		fn_offset;		/* offset into directory */
    166 	int		fn_flags;
    167 	uint_t		fn_size;		/* size of directory */
    168 	struct vnode	*fn_vnode;
    169 	struct fnnode	*fn_parent;
    170 	struct fnnode	*fn_next;		/* sibling */
    171 	struct fnnode	*fn_dirents;		/* children */
    172 	struct fnnode	*fn_trigger; 		/* pointer to next level */
    173 						/* AUTOFS trigger nodes */
    174 	struct action_list *fn_alp;		/* Pointer to mount info */
    175 						/* used for remounting */
    176 						/* trigger nodes */
    177 	cred_t		*fn_cred;		/* pointer to cred, used for */
    178 						/* "thisuser" processing */
    179 	krwlock_t	fn_rwlock;		/* protects list traversal */
    180 	kmutex_t	fn_lock;		/* protects the fnnode */
    181 	timestruc_t	fn_atime;
    182 	timestruc_t	fn_mtime;
    183 	timestruc_t	fn_ctime;
    184 	time_t		fn_ref_time;		/* time last referenced */
    185 	time_t		fn_unmount_ref_time;	/* last time unmount was done */
    186 	kcondvar_t	fn_cv_mount;		/* mount blocking variable */
    187 	struct vnode	*fn_seen;		/* vnode already traversed */
    188 	kthread_t	*fn_thread;		/* thread that has currently */
    189 						/* modified fn_seen */
    190 	struct autofs_globals *fn_globals;	/* global variables */
    191 } fnnode_t;
    192 
    193 
    194 #define	vntofn(vp)	((struct fnnode *)((vp)->v_data))
    195 #define	fntovn(fnp)	(((fnp)->fn_vnode))
    196 #define	vfstofni(vfsp)	((struct fninfo *)((vfsp)->vfs_data))
    197 
    198 #define	MF_DIRECT	0x001
    199 #define	MF_INPROG	0x002		/* Mount in progress */
    200 #define	MF_WAITING	0x004
    201 #define	MF_LOOKUP	0x008		/* Lookup in progress */
    202 #define	MF_ATTR_WAIT	0x010
    203 #define	MF_IK_MOUNT	0x040
    204 #define	MF_TRIGGER	0x080
    205 #define	MF_THISUID_MATCH_RQD	0x100	/* UID match required for this node */
    206 					/* required for thisuser kind of */
    207 					/* nodes */
    208 #define	MF_MOUNTPOINT	0x200		/* Node is/was a mount point */
    209 
    210 #define	AUTOFS_MODE		0555
    211 #define	AUTOFS_BLOCKSIZE	1024
    212 
    213 struct autofs_callargs {
    214 	fnnode_t	*fnc_fnp;	/* fnnode */
    215 	char		*fnc_name;	/* path to lookup/mount */
    216 	kthread_t	*fnc_origin;	/* thread that fired up this thread */
    217 					/* used for debugging purposes */
    218 	cred_t		*fnc_cred;
    219 };
    220 
    221 struct autofs_globals {
    222 	fnnode_t		*fng_rootfnnodep;
    223 	int			fng_fnnode_count;
    224 	int			fng_printed_not_running_msg;
    225 	kmutex_t		fng_unmount_threads_lock;
    226 	int			fng_unmount_threads;
    227 	int			fng_verbose;
    228 	zoneid_t		fng_zoneid;
    229 	pid_t			fng_autofs_pid;
    230 	kmutex_t		fng_autofs_daemon_lock;
    231 	/*
    232 	 * autofs_daemon_lock protects fng_autofs_daemon_dh
    233 	 */
    234 	door_handle_t		fng_autofs_daemon_dh;
    235 };
    236 
    237 extern kmutex_t autofs_minor_lock;
    238 extern zone_key_t autofs_key;
    239 
    240 /*
    241  * Sets the MF_INPROG flag on this fnnode.
    242  * fnp->fn_lock should be held before this macro is called,
    243  * operation is either MF_INPROG or MF_LOOKUP.
    244  */
    245 #define	AUTOFS_BLOCK_OTHERS(fnp, operation)	{ \
    246 	ASSERT(MUTEX_HELD(&(fnp)->fn_lock)); \
    247 	ASSERT(!((fnp)->fn_flags & operation)); \
    248 	(fnp)->fn_flags |= (operation); \
    249 }
    250 
    251 #define	AUTOFS_UNBLOCK_OTHERS(fnp, operation)	{ \
    252 	auto_unblock_others((fnp), (operation)); \
    253 }
    254 
    255 extern struct vnodeops *auto_vnodeops;
    256 extern const struct fs_operation_def auto_vnodeops_template[];
    257 
    258 /*
    259  * Utility routines
    260  */
    261 extern int auto_search(fnnode_t *, char *, fnnode_t **, cred_t *);
    262 extern int auto_enter(fnnode_t *, char *, fnnode_t **, cred_t *);
    263 extern void auto_unblock_others(fnnode_t *, uint_t);
    264 extern int auto_wait4mount(fnnode_t *);
    265 extern fnnode_t *auto_makefnnode(vtype_t, vfs_t *, char *, cred_t *,
    266     struct autofs_globals *);
    267 extern void auto_freefnnode(fnnode_t *);
    268 extern void auto_disconnect(fnnode_t *, fnnode_t *);
    269 extern void auto_do_unmount(struct autofs_globals *);
    270 /*PRINTFLIKE4*/
    271 extern void auto_log(int verbose, zoneid_t zoneid, int level,
    272 	const char *fmt, ...)
    273     __KPRINTFLIKE(4);
    274 /*PRINTFLIKE2*/
    275 extern void auto_dprint(int level, const char *fmt, ...)
    276     __KPRINTFLIKE(2);
    277 extern int auto_calldaemon(zoneid_t, int, xdrproc_t, void *, xdrproc_t,
    278 	void *, int, bool_t);
    279 extern int auto_lookup_aux(fnnode_t *, char *, cred_t *);
    280 extern void auto_new_mount_thread(fnnode_t *, char *, cred_t *);
    281 extern int auto_nobrowse_option(char *);
    282 
    283 extern void unmount_tree(struct autofs_globals *, int);
    284 extern void autofs_free_globals(struct autofs_globals *);
    285 extern void autofs_shutdown_zone(struct autofs_globals *);
    286 /*
    287  * external routines not defined in any header file
    288  */
    289 extern bool_t xdr_uid_t(XDR *, uid_t *);
    290 
    291 #endif	/* _KERNEL */
    292 
    293 /*
    294  * autofs structures and defines needed for use with doors.
    295  */
    296 #define	AUTOFS_NULL	0
    297 #define	AUTOFS_MOUNT	1
    298 #define	AUTOFS_UNMOUNT	2
    299 #define	AUTOFS_READDIR	3
    300 #define	AUTOFS_LOOKUP	4
    301 #define	AUTOFS_SRVINFO	5
    302 #define	AUTOFS_MNTINFO	6
    303 
    304 /*
    305  * autofs_door_args is a generic structure used to grab the command
    306  * from any of the argument structures passed in.
    307  */
    308 
    309 typedef struct {
    310 	int cmd;
    311 	int xdr_len;
    312 	char xdr_arg[1];	/* buffer holding xdr encoded data */
    313 } autofs_door_args_t;
    314 
    315 
    316 typedef struct {
    317 	int res_status;
    318 	int xdr_len;
    319 	char xdr_res[1];	/* buffer holding xdr encoded data */
    320 } autofs_door_res_t;
    321 
    322 typedef enum autofs_res autofs_res_t;
    323 typedef enum autofs_stat autofs_stat_t;
    324 typedef enum autofs_action autofs_action_t;
    325 
    326 typedef struct {
    327 	void *	atsd_buf;
    328 	size_t	atsd_len;
    329 } autofs_tsd_t;
    330 
    331 typedef struct sec_desdata {
    332 	int		nd_sec_syncaddr_len;
    333 	int		nd_sec_knc_semantics;
    334 	int		nd_sec_netnamelen;
    335 	uint64_t	nd_sec_knc_rdev;
    336 	int		nd_sec_knc_unused[8];
    337 } sec_desdata_t;
    338 
    339 typedef struct sec_gssdata {
    340 	int			element_length;
    341 	rpc_gss_service_t	service;
    342 	char			uname[MAX_NAME_LEN];
    343 	char			inst[MAX_NAME_LEN];
    344 	char			realm[MAX_NAME_LEN];
    345 	uint_t			qop;
    346 } sec_gssdata_t;
    347 
    348 typedef struct nfs_secdata  {
    349 	sec_desdata_t	nfs_des_clntdata;
    350 	sec_gssdata_t	nfs_gss_clntdata;
    351 } nfs_secdata_t;
    352 
    353 /*
    354  * Comma separated list of mntoptions which are inherited when the
    355  * "restrict" option is present.  The RESTRICT option must be first!
    356  * This define is shared between the kernel and the automount daemon.
    357  */
    358 #define	RESTRICTED_MNTOPTS	\
    359 	MNTOPT_RESTRICT, MNTOPT_NOSUID, MNTOPT_NOSETUID, MNTOPT_NODEVICES
    360 
    361 /*
    362  * AUTOFS syscall entry point
    363  */
    364 enum autofssys_op { AUTOFS_UNMOUNTALL, AUTOFS_SETDOOR };
    365 
    366 #ifdef	_KERNEL
    367 extern int autofssys(enum autofssys_op, uintptr_t);
    368 
    369 #endif	/* _KERNEL */
    370 
    371 #ifdef	__cplusplus
    372 }
    373 #endif
    374 
    375 #endif	/* _SYS_FS_AUTOFS_H */
    376