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