xref: /illumos-gate/usr/src/uts/common/sys/fs/sdev_impl.h (revision 07a48826732249fcd3aa8dd53c8389595e9f1fbc)
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_SDEV_IMPL_H
27 #define	_SYS_SDEV_IMPL_H
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 #include <rpc/rpc.h>
34 #include <sys/dirent.h>
35 #include <sys/vfs.h>
36 #include <sys/vfs_opreg.h>
37 #include <sys/list.h>
38 #include <sys/nvpair.h>
39 
40 /*
41  * sdev_nodes are the file-system specific part of the
42  * vnodes for the device filesystem.
43  *
44  * The device filesystem exports two node types:
45  *
46  * VDIR nodes		to represent directories
47  * VCHR & VBLK nodes	to represent devices
48  */
49 
50 /*
51  * /dev mount arguments
52  */
53 struct sdev_mountargs {
54 	uint64_t sdev_attrdir;
55 };
56 
57 
58 /*
59  * Nvpair names of profile information (list of device files available) of
60  * non-global /dev mounts.  These strings must be unique among them.
61  */
62 #define	SDEV_NVNAME_MOUNTPT	"prof_mountpt"
63 #define	SDEV_NVNAME_INCLUDE	"prof_include"
64 #define	SDEV_NVNAME_EXCLUDE	"prof_exclude"
65 #define	SDEV_NVNAME_SYMLINK	"prof_symlink"
66 #define	SDEV_NVNAME_MAP		"prof_map"
67 
68 /*
69  * supported devfsadm_cmd
70  */
71 #define	DEVFSADMD_RUN_ALL	1
72 
73 /*
74  * devfsadm_error codes
75  */
76 #define	DEVFSADM_RUN_INVALID		1
77 #define	DEVFSADM_RUN_EPERM		2
78 #define	DEVFSADM_RUN_NOTSUP		3
79 
80 /*
81  * devfsadm/devname door data structures
82  */
83 typedef struct sdev_door_arg {
84 	uint8_t devfsadm_cmd;	/* what to do for devfsadm[d] */
85 } sdev_door_arg_t;
86 
87 typedef struct sdev_door_res {
88 	int32_t devfsadm_error;
89 } sdev_door_res_t;
90 
91 #ifdef _KERNEL
92 
93 struct sdev_dprof {
94 	int has_glob;
95 	nvlist_t *dev_name;
96 	nvlist_t *dev_map;
97 	nvlist_t *dev_symlink;
98 	nvlist_t *dev_glob_incdir;
99 	nvlist_t *dev_glob_excdir;
100 };
101 
102 /*
103  * devname_handle_t
104  */
105 struct devname_handle {
106 	struct sdev_node *dh_data;	/* the sdev_node */
107 	void    *dh_args;
108 };
109 typedef struct devname_handle devname_handle_t;
110 
111 /*
112  * Per-instance node data for the global zone instance
113  * Only one mount of /dev in the global zone
114  */
115 typedef struct sdev_global_data {
116 	struct devname_handle sdev_ghandle;
117 	ulong_t		sdev_dir_ggen;		/* name space generation # */
118 } sdev_global_data_t;
119 
120 /*
121  * Per-instance node data - profile data per non-global zone mount instance
122  */
123 typedef struct sdev_local_data {
124 	ulong_t sdev_dir_lgen;		/* cached generation # of /dev dir */
125 	ulong_t sdev_devtree_lgen;	/* cached generation # of devtree */
126 	struct sdev_node *sdev_lorigin;	/* corresponding global sdev_node */
127 	struct sdev_dprof sdev_lprof;	/* profile for multi-inst */
128 } sdev_local_data_t;
129 
130 /*
131  * /dev filesystem sdev_node defines
132  */
133 typedef struct sdev_node {
134 	char		*sdev_name;	/* node name */
135 	size_t		sdev_namelen;	/* strlen(sdev_name) */
136 	char		*sdev_path;	/* absolute path */
137 	char		*sdev_symlink;	/* source for a symlink */
138 	struct vnode	*sdev_vnode;	/* vnode */
139 
140 	krwlock_t	sdev_contents;	/* rw lock for this data structure */
141 	struct sdev_node *sdev_dotdot;	/* parent */
142 
143 	avl_tree_t	sdev_entries;	/* VDIR: contents as avl tree */
144 	avl_node_t	sdev_avllink;	/* avl node linkage */
145 
146 	struct vnode	*sdev_attrvp;	/* backing store vnode if persisted */
147 	struct vattr	*sdev_attr;	/* memory copy of the vattr */
148 
149 	ino64_t		sdev_ino;	/* inode */
150 	uint_t		sdev_nlink;	/* link count */
151 	int		sdev_state;	/* state of this node */
152 	int		sdev_flags;	/* flags bit */
153 
154 	kmutex_t	sdev_lookup_lock; /* node creation synch lock */
155 	kcondvar_t	sdev_lookup_cv;	/* node creation sync cv */
156 	int		sdev_lookup_flags; /* node creation flags */
157 
158 	/* per-instance data, either global or non-global zone */
159 	union {
160 		struct sdev_global_data	sdev_globaldata;
161 		struct sdev_local_data	sdev_localdata;
162 	} sdev_instance_data;
163 
164 	void		*sdev_private;
165 } sdev_node_t;
166 
167 #define	sdev_ldata sdev_instance_data.sdev_localdata
168 #define	sdev_gdata sdev_instance_data.sdev_globaldata
169 
170 #define	sdev_handle		sdev_gdata.sdev_ghandle
171 #define	sdev_gdir_gen		sdev_gdata.sdev_dir_ggen
172 
173 #define	sdev_ldir_gen		sdev_ldata.sdev_dir_lgen
174 #define	sdev_devtree_gen	sdev_ldata.sdev_devtree_lgen
175 #define	sdev_origin		sdev_ldata.sdev_lorigin
176 #define	sdev_prof		sdev_ldata.sdev_lprof
177 
178 /*
179  * Directory contents traversal
180  */
181 #define	SDEV_FIRST_ENTRY(ddv)		avl_first(&(ddv)->sdev_entries)
182 #define	SDEV_NEXT_ENTRY(ddv, dv)	AVL_NEXT(&(ddv)->sdev_entries, (dv))
183 
184 /*
185  * sdev_state
186  *
187  * A sdev_node may go through 3 states:
188  *	SDEV_INIT: When a new /dev file is first looked up, a sdev_node
189  *		   is allocated, initialized and added to the directory's
190  *		   sdev_node cache. A node at this state will also
191  *		   have the SDEV_LOOKUP flag set.
192  *
193  *		   Other threads that are trying to look up a node at
194  *		   this state will be blocked until the SDEV_LOOKUP flag
195  *		   is cleared.
196  *
197  *		   When the SDEV_LOOKUP flag is cleared, the node may
198  *		   transition into the SDEV_READY state for a successful
199  *		   lookup or the node is removed from the directory cache
200  *		   and destroyed if the named node can not be found.
201  *		   An ENOENT error is returned for the second case.
202  *
203  *	SDEV_READY: A /dev file has been successfully looked up and
204  *		    associated with a vnode. The /dev file is available
205  *		    for the supported /dev filesystem operations.
206  *
207  *	SDEV_ZOMBIE: Deletion of a /dev file has been explicitely issued
208  *		    to an SDEV_READY node. The node is transitioned into
209  *		    the SDEV_ZOMBIE state if the vnode reference count
210  *		    is still held. A SDEV_ZOMBIE node does not support
211  *		    any of the /dev filesystem operations. A SDEV_ZOMBIE
212  *		    node is removed from the directory cache and destroyed
213  *		    once the reference count reaches "zero".
214  */
215 typedef enum {
216 	SDEV_ZOMBIE = -1,
217 	SDEV_INIT = 0,
218 	SDEV_READY
219 } sdev_node_state_t;
220 
221 /* sdev_flags */
222 #define	SDEV_BUILD		0x0001	/* directory cache out-of-date */
223 #define	SDEV_STALE		0x0002	/* stale sdev nodes */
224 #define	SDEV_GLOBAL		0x0004	/* global /dev nodes */
225 #define	SDEV_PERSIST		0x0008	/* backing store persisted node */
226 #define	SDEV_NO_NCACHE		0x0010	/* do not include in neg. cache */
227 #define	SDEV_DYNAMIC		0x0020	/* special-purpose vnode ops */
228 					/* (ex: pts) */
229 #define	SDEV_VTOR		0x0040	/* validate sdev_nodes during search */
230 #define	SDEV_ATTR_INVALID	0x0080	/* invalid node attributes, */
231 					/* need update */
232 
233 /* sdev_lookup_flags */
234 #define	SDEV_LOOKUP	0x0001	/* node creation in progress */
235 #define	SDEV_READDIR	0x0002	/* VDIR readdir in progress */
236 #define	SDEV_LGWAITING	0x0004	/* waiting for devfsadm completion */
237 
238 #define	SDEV_VTOR_INVALID	-1
239 #define	SDEV_VTOR_SKIP		0
240 #define	SDEV_VTOR_VALID		1
241 #define	SDEV_VTOR_STALE		2
242 
243 /* convenient macros */
244 #define	SDEV_IS_GLOBAL(dv)	\
245 	(dv->sdev_flags & SDEV_GLOBAL)
246 #define	SDEV_IS_PERSIST(dv)	\
247 	(dv->sdev_flags & SDEV_PERSIST)
248 #define	SDEV_IS_DYNAMIC(dv)	\
249 	(dv->sdev_flags & SDEV_DYNAMIC)
250 #define	SDEV_IS_NO_NCACHE(dv)	\
251 	(dv->sdev_flags & SDEV_NO_NCACHE)
252 
253 #define	SDEV_IS_LOOKUP(dv)	\
254 	(dv->sdev_lookup_flags & SDEV_LOOKUP)
255 #define	SDEV_IS_READDIR(dv)	\
256 	(dv->sdev_lookup_flags & SDEV_READDIR)
257 #define	SDEV_IS_LGWAITING(dv)	\
258 	(dv->sdev_lookup_flags  & SDEV_LGWAITING)
259 
260 #define	SDEVTOV(n)	((struct vnode *)(n)->sdev_vnode)
261 #define	VTOSDEV(vp)	((struct sdev_node *)(vp)->v_data)
262 #define	VN_HELD(v)	((v)->v_count != 0)
263 #define	SDEV_HELD(dv)	(VN_HELD(SDEVTOV(dv)))
264 #define	SDEV_HOLD(dv)	VN_HOLD(SDEVTOV(dv))
265 #define	SDEV_RELE(dv)	VN_RELE(SDEVTOV(dv))
266 #define	SDEV_SIMPLE_RELE(dv)	{	\
267 	mutex_enter(&SDEVTOV(dv)->v_lock);	\
268 	SDEVTOV(dv)->v_count--;	\
269 	mutex_exit(&SDEVTOV(dv)->v_lock);	\
270 }
271 
272 #define	SDEV_ACL_FLAVOR(vp)	(VFSTOSDEVFS(vp->v_vfsp)->sdev_acl_flavor)
273 
274 /*
275  * some defaults
276  */
277 #define	SDEV_ROOTINO		((ino_t)2)
278 #define	SDEV_UID_DEFAULT	(0)
279 #define	SDEV_GID_DEFAULT	(3)
280 #define	SDEV_DIRMODE_DEFAULT	(S_IFDIR |0755)
281 #define	SDEV_DEVMODE_DEFAULT	(0600)
282 #define	SDEV_LNKMODE_DEFAULT	(S_IFLNK | 0777)
283 
284 extern struct vattr sdev_vattr_dir;
285 extern struct vattr sdev_vattr_lnk;
286 extern struct vattr sdev_vattr_blk;
287 extern struct vattr sdev_vattr_chr;
288 
289 /*
290  * devname_lookup_func()
291  */
292 extern int devname_lookup_func(struct sdev_node *, char *, struct vnode **,
293     struct cred *, int (*)(struct sdev_node *, char *, void **, struct cred *,
294     void *, char *), int);
295 
296 /*
297  * flags used by devname_lookup_func callbacks
298  */
299 #define	SDEV_PATH	0x1	/* callback returning /devices physical path */
300 #define	SDEV_VNODE	0x2	/* callback returning backing store vnode */
301 #define	SDEV_VATTR	0x4	/* callback returning node vattr */
302 #define	SDEV_VLINK	0x8	/* callback returning /dev link */
303 
304 /*
305  * devname_readdir_func()
306  */
307 extern int devname_readdir_func(vnode_t *, uio_t *, cred_t *, int *, int);
308 
309 /*
310  * flags for devname_readdir_func
311  */
312 #define	SDEV_BROWSE	0x1	/* fetch all entries from backing store */
313 
314 /*
315  * devname_setattr_func()
316  */
317 extern int devname_setattr_func(struct vnode *, struct vattr *, int,
318     struct cred *, int (*)(struct sdev_node *, struct vattr *, int), int);
319 
320 /*
321  * devname_inactive_func()
322  */
323 extern void devname_inactive_func(struct vnode *, struct cred *cred,
324     void (*)(struct vnode *));
325 
326 /*
327  * /dev file system instance defines
328  */
329 /*
330  * /dev version of vfs_data
331  */
332 struct sdev_data {
333 	struct sdev_data	*sdev_prev;
334 	struct sdev_data	*sdev_next;
335 	struct sdev_node	*sdev_root;
336 	struct vfs		*sdev_vfsp;
337 	struct sdev_mountargs	*sdev_mountargs;
338 	ulong_t			sdev_acl_flavor;
339 };
340 
341 #define	VFSTOSDEVFS(vfsp)	((struct sdev_data *)((vfsp)->vfs_data))
342 
343 /*
344  * sdev_fid overlays the fid structure (for VFS_VGET)
345  */
346 struct sdev_fid {
347 	uint16_t	sdevfid_len;
348 	ino32_t		sdevfid_ino;
349 	int32_t		sdevfid_gen;
350 };
351 
352 /*
353  * devfsadm and devname communication defines
354  */
355 typedef enum {
356 	DEVNAME_DEVFSADM_STOPPED = 0,	/* devfsadm has never run */
357 	DEVNAME_DEVFSADM_RUNNING,	/* devfsadm is running */
358 	DEVNAME_DEVFSADM_RUN		/* devfsadm ran once */
359 } devname_devfsadm_state_t;
360 
361 extern volatile uint_t  devfsadm_state; /* atomic mask for devfsadm status */
362 
363 #define	DEVNAME_DEVFSADM_SET_RUNNING(devfsadm_state)	\
364 	devfsadm_state = DEVNAME_DEVFSADM_RUNNING
365 #define	DEVNAME_DEVFSADM_SET_STOP(devfsadm_state)	\
366 	devfsadm_state = DEVNAME_DEVFSADM_STOPPED
367 #define	DEVNAME_DEVFSADM_SET_RUN(devfsadm_state)	\
368 	devfsadm_state = DEVNAME_DEVFSADM_RUN
369 #define	DEVNAME_DEVFSADM_IS_RUNNING(devfsadm_state)	\
370 	devfsadm_state == DEVNAME_DEVFSADM_RUNNING
371 #define	DEVNAME_DEVFSADM_HAS_RUN(devfsadm_state)	\
372 	(devfsadm_state == DEVNAME_DEVFSADM_RUN)
373 
374 #define	SDEV_BLOCK_OTHERS(dv, cmd)	{	\
375 	ASSERT(MUTEX_HELD(&dv->sdev_lookup_lock));	\
376 	dv->sdev_lookup_flags |= cmd;			\
377 }
378 extern void sdev_unblock_others(struct sdev_node *, uint_t);
379 #define	SDEV_UNBLOCK_OTHERS(dv, cmd)	{	\
380 	sdev_unblock_others(dv, cmd);		\
381 }
382 
383 #define	SDEV_CLEAR_LOOKUP_FLAGS(dv, cmd)	{	\
384 	dv->sdev_lookup_flags &= ~cmd;	\
385 }
386 
387 extern int sdev_wait4lookup(struct sdev_node *, int);
388 extern int devname_filename_register(char *);
389 extern int devname_nsmaps_register(char *, size_t);
390 extern void sdev_devfsadm_lockinit(void);
391 extern void sdev_devfsadm_lockdestroy(void);
392 extern void devname_add_devfsadm_node(char *);
393 extern void sdev_devfsadmd_thread(struct sdev_node *, struct sdev_node *,
394     struct cred *);
395 extern int devname_profile_update(char *, size_t);
396 extern struct sdev_data *sdev_find_mntinfo(char *);
397 void sdev_mntinfo_rele(struct sdev_data *);
398 extern struct vnodeops *devpts_getvnodeops(void);
399 extern struct vnodeops *devvt_getvnodeops(void);
400 
401 /*
402  * directory name rule
403  */
404 struct devname_nsmap {
405 	struct devname_nsmap	*prev;	/* previous entry */
406 	struct devname_nsmap	*next;	/* next entry */
407 	char	*dir_name;	/* /dev subdir name, e.g. /dev/disk */
408 	char	*dir_module;	/* devname module impl the operations */
409 	char	*dir_map;	/* dev naming rules, e.g. /etc/dev/disks */
410 	char    *dir_newmodule; /* to be reloaded  */
411 	char    *dir_newmap;    /* to be reloaded */
412 	int	dir_invalid;    /* map entry obsolete */
413 	int	dir_maploaded;	/* map contents read */
414 	krwlock_t dir_lock;	/* protects the data structure */
415 };
416 
417 /*
418  * name-property pairs to be looked up
419  */
420 typedef struct devname_lkp_arg {
421 	char *devname_dir;	/* the directory to look */
422 	char *devname_name;	/* the device name to be looked up */
423 	char *devname_map;	/* the directory device naming map */
424 	int reserved;
425 } devname_lkp_arg_t;
426 
427 /*
428  * directory name-value populating results
429  */
430 typedef struct devname_rdr_result {
431 	uint32_t	ns_mapcount;
432 } devname_rdr_result_t;
433 
434 /*
435  * sdev_nsrdr work
436  */
437 typedef struct sdev_nsrdr_work {
438 	char *dir_name;
439 	char *dir_map;
440 	struct sdev_node *dir_dv;
441 	devname_rdr_result_t **result;
442 	struct sdev_nsrdr_work *next;
443 } sdev_nsrdr_work_t;
444 
445 
446 /*
447  * boot states - warning, the ordering here is significant
448  *
449  * the difference between "system available" and "boot complete"
450  * is a debounce timeout to catch some daemon issuing a readdir
451  * triggering a nuisance implict reconfig on each boot.
452  */
453 #define	SDEV_BOOT_STATE_INITIAL		0
454 #define	SDEV_BOOT_STATE_RECONFIG	1	/* reconfig */
455 #define	SDEV_BOOT_STATE_SYSAVAIL	2	/* system available */
456 #define	SDEV_BOOT_STATE_COMPLETE	3	/* boot complete */
457 
458 /*
459  * Negative cache list and list element
460  * The mutex protects the flags against multiple accesses and
461  * must only be acquired when already holding the r/w lock.
462  */
463 typedef struct sdev_nc_list {
464 	list_t		ncl_list;	/* the list itself */
465 	kmutex_t	ncl_mutex;	/* protects ncl_flags */
466 	krwlock_t	ncl_lock;	/* protects ncl_list */
467 	int		ncl_flags;
468 	int		ncl_nentries;
469 } sdev_nc_list_t;
470 
471 typedef struct sdev_nc_node {
472 	char		*ncn_name;	/* name of the node */
473 	int		ncn_flags;	/* state information */
474 	int		ncn_expirecnt;	/* remove once expired */
475 	list_node_t	ncn_link;	/* link to next in list */
476 } sdev_nc_node_t;
477 
478 /* ncl_flags */
479 #define	NCL_LIST_DIRTY		0x01	/* needs to be flushed */
480 #define	NCL_LIST_WRITING	0x02	/* write in progress */
481 #define	NCL_LIST_WENABLE	0x04	/* write-enabled post boot */
482 
483 /* ncn_flags */
484 #define	NCN_ACTIVE	0x01	/* a lookup has occurred */
485 #define	NCN_SRC_STORE	0x02	/* src: persistent store */
486 #define	NCN_SRC_CURRENT	0x04	/* src: current boot */
487 
488 /* sdev_lookup_failed flags */
489 #define	SLF_NO_NCACHE	0x01	/* node should not be added to ncache */
490 #define	SLF_REBUILT	0x02	/* reconfig performed during lookup attempt */
491 
492 /*
493  * The nvlist name and nvpair identifiers in the
494  * /etc/devices/devname_cache nvlist format
495  */
496 #define	DP_DEVNAME_ID			"devname"
497 #define	DP_DEVNAME_NCACHE_ID		"ncache"
498 #define	DP_DEVNAME_NC_EXPIRECNT_ID	"expire-counts"
499 
500 /* devname-cache list element */
501 typedef struct nvp_devname {
502 	char			**nvp_paths;
503 	int			*nvp_expirecnts;
504 	int			nvp_npaths;
505 	list_node_t		nvp_link;
506 } nvp_devname_t;
507 
508 /*
509  * name service globals and prototypes
510  */
511 
512 /*
513  * vnodeops and vfsops helpers
514  */
515 
516 typedef enum {
517 	SDEV_CACHE_ADD = 0,
518 	SDEV_CACHE_DELETE
519 } sdev_cache_ops_t;
520 
521 extern struct sdev_node *sdev_cache_lookup(struct sdev_node *, char *);
522 extern int sdev_cache_update(struct sdev_node *, struct sdev_node **, char *,
523     sdev_cache_ops_t);
524 extern void sdev_node_cache_init(void);
525 extern void sdev_node_cache_fini(void);
526 extern struct sdev_node *sdev_mkroot(struct vfs *, dev_t, struct vnode *,
527     struct vnode *, struct cred *);
528 extern void sdev_filldir_dynamic(struct sdev_node *);
529 extern int sdev_mknode(struct sdev_node *, char *, struct sdev_node **,
530     struct vattr *, struct vnode *, void *, struct cred *, sdev_node_state_t);
531 extern int sdev_nodeinit(struct sdev_node *, char *, struct sdev_node **,
532     vattr_t *);
533 extern int sdev_nodeready(struct sdev_node *, vattr_t *, vnode_t *, void *,
534     cred_t *);
535 extern int sdev_shadow_node(struct sdev_node *, struct cred *);
536 extern void sdev_nodedestroy(struct sdev_node *, uint_t);
537 extern void sdev_update_timestamps(struct vnode *, cred_t *, uint_t);
538 extern void sdev_vattr_merge(struct sdev_node *, struct vattr *);
539 extern void sdev_devstate_change(void);
540 extern int sdev_lookup_filter(sdev_node_t *, char *);
541 extern void sdev_lookup_failed(sdev_node_t *, char *, int);
542 extern int sdev_unlocked_access(void *, int, struct cred *);
543 
544 #define	SDEV_ENFORCE	0x1
545 extern void sdev_stale(struct sdev_node *);
546 extern int sdev_cleandir(struct sdev_node *, char *, uint_t);
547 extern int sdev_rnmnode(struct sdev_node *, struct sdev_node *,
548     struct sdev_node *, struct sdev_node **, char *, struct cred *);
549 extern size_t add_dir_entry(dirent64_t *, char *, size_t, ino_t, offset_t);
550 extern int sdev_to_vp(struct sdev_node *, struct vnode **);
551 extern ino_t sdev_mkino(struct sdev_node *);
552 extern int devname_backstore_lookup(struct sdev_node *, char *,
553     struct vnode **);
554 extern int sdev_is_devfs_node(char *);
555 extern int sdev_copyin_mountargs(struct mounta *, struct sdev_mountargs *);
556 extern int sdev_reserve_subdirs(struct sdev_node *);
557 extern int prof_lookup();
558 extern void prof_filldir(struct sdev_node *);
559 extern int devpts_validate(struct sdev_node *dv);
560 extern int devnet_validate(struct sdev_node *dv);
561 extern int devipnet_validate(struct sdev_node *dv);
562 extern int devvt_validate(struct sdev_node *dv);
563 extern void *sdev_get_vtor(struct sdev_node *dv);
564 
565 /*
566  * ncache handlers
567  */
568 
569 extern void sdev_ncache_init(void);
570 extern void sdev_ncache_setup(void);
571 extern void sdev_ncache_teardown(void);
572 extern void sdev_nc_addname(sdev_nc_list_t *, sdev_node_t *, char *, int);
573 extern void sdev_nc_node_exists(sdev_node_t *);
574 extern void sdev_nc_path_exists(sdev_nc_list_t *, char *);
575 extern void sdev_modctl_dump_files(void);
576 
577 /*
578  * devinfo helpers
579  */
580 extern int sdev_modctl_readdir(const char *, char ***, int *, int *, int);
581 extern void sdev_modctl_readdir_free(char **, int, int);
582 extern int sdev_modctl_devexists(const char *);
583 
584 /*
585  * globals
586  */
587 extern kmutex_t sdev_lock;
588 extern int devtype;
589 extern kmem_cache_t *sdev_node_cache;
590 extern struct vnodeops		*sdev_vnodeops;
591 extern struct vnodeops		*devpts_vnodeops;
592 extern struct vnodeops		*devnet_vnodeops;
593 extern struct vnodeops		*devipnet_vnodeops;
594 extern struct vnodeops		*devvt_vnodeops;
595 extern struct sdev_data *sdev_origins; /* mount info for global /dev instance */
596 extern const fs_operation_def_t	sdev_vnodeops_tbl[];
597 extern const fs_operation_def_t	devpts_vnodeops_tbl[];
598 extern const fs_operation_def_t	devnet_vnodeops_tbl[];
599 extern const fs_operation_def_t devipnet_vnodeops_tbl[];
600 extern const fs_operation_def_t	devvt_vnodeops_tbl[];
601 extern const fs_operation_def_t	devsys_vnodeops_tbl[];
602 extern const fs_operation_def_t	devpseudo_vnodeops_tbl[];
603 
604 extern sdev_nc_list_t	*sdev_ncache;
605 extern int		sdev_reconfig_boot;
606 extern int		sdev_boot_state;
607 extern int		sdev_reconfig_verbose;
608 extern int		sdev_reconfig_disable;
609 extern int		sdev_nc_disable;
610 extern int		sdev_nc_disable_reset;
611 extern int		sdev_nc_verbose;
612 
613 /*
614  * misc. defines
615  */
616 #ifdef DEBUG
617 extern int sdev_debug;
618 #define	SDEV_DEBUG		0x01	/* error messages to console/log */
619 #define	SDEV_DEBUG_VOPS 	0x02	/* vnode ops errors */
620 #define	SDEV_DEBUG_DLF		0x04	/* trace devname_lookup_func */
621 #define	SDEV_DEBUG_DRF		0x08	/* trace devname_readdir_func */
622 #define	SDEV_DEBUG_NCACHE	0x10	/* negative cache tracing */
623 #define	SDEV_DEBUG_DEVFSADMD	0x20	/* comm. of devnamefs & devfsadm */
624 #define	SDEV_DEBUG_PTS		0x40	/* /dev/pts tracing */
625 #define	SDEV_DEBUG_RECONFIG	0x80	/* events triggering reconfig */
626 #define	SDEV_DEBUG_SDEV_NODE	0x100	/* trace sdev_node activities */
627 #define	SDEV_DEBUG_PROFILE	0x200	/* trace sdev_profile */
628 #define	SDEV_DEBUG_MODCTL	0x400	/* trace modctl activity */
629 #define	SDEV_DEBUG_FLK		0x800	/* trace failed lookups */
630 #define	SDEV_DEBUG_NET		0x1000	/* /dev/net tracing */
631 
632 #define	sdcmn_err(args)  if (sdev_debug & SDEV_DEBUG) printf args
633 #define	sdcmn_err2(args) if (sdev_debug & SDEV_DEBUG_VOPS) printf args
634 #define	sdcmn_err3(args) if (sdev_debug & SDEV_DEBUG_DLF) printf args
635 #define	sdcmn_err4(args) if (sdev_debug & SDEV_DEBUG_DRF) printf args
636 #define	sdcmn_err5(args) if (sdev_debug & SDEV_DEBUG_NCACHE) printf args
637 #define	sdcmn_err6(args) if (sdev_debug & SDEV_DEBUG_DEVFSADMD) printf args
638 #define	sdcmn_err7(args) if (sdev_debug & SDEV_DEBUG_PTS) printf args
639 #define	sdcmn_err8(args) if (sdev_debug & SDEV_DEBUG_RECONFIG) printf args
640 #define	sdcmn_err9(args) if (sdev_debug & SDEV_DEBUG_SDEV_NODE) printf args
641 #define	sdcmn_err10(args) if (sdev_debug & SDEV_DEBUG_PROFILE) printf args
642 #define	sdcmn_err11(args) if (sdev_debug & SDEV_DEBUG_MODCTL) printf args
643 #define	sdcmn_err12(args) if (sdev_debug & SDEV_DEBUG_NET) printf args
644 #define	impossible(args) printf args
645 #else
646 #define	sdcmn_err(args)		/* does nothing */
647 #define	sdcmn_err2(args)	/* does nothing */
648 #define	sdcmn_err3(args)	/* does nothing */
649 #define	sdcmn_err4(args)	/* does nothing */
650 #define	sdcmn_err5(args)	/* does nothing */
651 #define	sdcmn_err6(args)	/* does nothing */
652 #define	sdcmn_err7(args)	/* does nothing */
653 #define	sdcmn_err8(args)	/* does nothing */
654 #define	sdcmn_err9(args)	/* does nothing */
655 #define	sdcmn_err10(args)	/* does nothing */
656 #define	sdcmn_err11(args)	/* does nothing */
657 #define	sdcmn_err12(args)	/* does nothing */
658 #define	impossible(args)	/* does nothing */
659 #endif
660 
661 #ifdef DEBUG
662 #define	SD_TRACE_FAILED_LOOKUP(ddv, nm, retried)			\
663 	if ((sdev_debug & SDEV_DEBUG_FLK) ||				\
664 	    ((retried) && (sdev_debug & SDEV_DEBUG_RECONFIG))) {	\
665 		printf("lookup of %s/%s by %s failed, line %d\n",	\
666 		    (ddv)->sdev_name, (nm), curproc->p_user.u_comm,	\
667 		    __LINE__);						\
668 	}
669 #else
670 #define	SD_TRACE_FAILED_LOOKUP(ddv, nm, retried)
671 #endif
672 
673 #endif	/* _KERNEL */
674 
675 #ifdef __cplusplus
676 }
677 #endif
678 
679 #endif	/* _SYS_SDEV_IMPL_H */
680