12621Sllai1 /* 22621Sllai1 * CDDL HEADER START 32621Sllai1 * 42621Sllai1 * The contents of this file are subject to the terms of the 52621Sllai1 * Common Development and Distribution License (the "License"). 62621Sllai1 * You may not use this file except in compliance with the License. 72621Sllai1 * 82621Sllai1 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 92621Sllai1 * or http://www.opensolaris.org/os/licensing. 102621Sllai1 * See the License for the specific language governing permissions 112621Sllai1 * and limitations under the License. 122621Sllai1 * 132621Sllai1 * When distributing Covered Code, include this CDDL HEADER in each 142621Sllai1 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 152621Sllai1 * If applicable, add the following below this CDDL HEADER, with the 162621Sllai1 * fields enclosed by brackets "[]" replaced with your own identifying 172621Sllai1 * information: Portions Copyright [yyyy] [name of copyright owner] 182621Sllai1 * 192621Sllai1 * CDDL HEADER END 202621Sllai1 */ 212621Sllai1 /* 22*12633Sjohn.levon@sun.com * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 232621Sllai1 */ 242621Sllai1 252621Sllai1 #ifndef _SYS_SDEV_IMPL_H 262621Sllai1 #define _SYS_SDEV_IMPL_H 272621Sllai1 282621Sllai1 #ifdef __cplusplus 292621Sllai1 extern "C" { 302621Sllai1 #endif 312621Sllai1 322621Sllai1 #include <rpc/rpc.h> 332621Sllai1 #include <sys/dirent.h> 342621Sllai1 #include <sys/vfs.h> 353898Srsb #include <sys/vfs_opreg.h> 362621Sllai1 #include <sys/list.h> 372621Sllai1 #include <sys/nvpair.h> 382621Sllai1 392621Sllai1 /* 402621Sllai1 * sdev_nodes are the file-system specific part of the 412621Sllai1 * vnodes for the device filesystem. 422621Sllai1 * 432621Sllai1 * The device filesystem exports two node types: 442621Sllai1 * 452621Sllai1 * VDIR nodes to represent directories 462621Sllai1 * VCHR & VBLK nodes to represent devices 472621Sllai1 */ 482621Sllai1 492621Sllai1 /* 502621Sllai1 * /dev mount arguments 512621Sllai1 */ 522621Sllai1 struct sdev_mountargs { 532621Sllai1 uint64_t sdev_attrdir; 542621Sllai1 }; 552621Sllai1 562621Sllai1 572621Sllai1 /* 582621Sllai1 * Nvpair names of profile information (list of device files available) of 592621Sllai1 * non-global /dev mounts. These strings must be unique among them. 602621Sllai1 */ 612621Sllai1 #define SDEV_NVNAME_MOUNTPT "prof_mountpt" 622621Sllai1 #define SDEV_NVNAME_INCLUDE "prof_include" 632621Sllai1 #define SDEV_NVNAME_EXCLUDE "prof_exclude" 642621Sllai1 #define SDEV_NVNAME_SYMLINK "prof_symlink" 652621Sllai1 #define SDEV_NVNAME_MAP "prof_map" 662621Sllai1 672621Sllai1 /* 682621Sllai1 * supported devfsadm_cmd 692621Sllai1 */ 702621Sllai1 #define DEVFSADMD_RUN_ALL 1 712621Sllai1 722621Sllai1 /* 732621Sllai1 * devfsadm_error codes 742621Sllai1 */ 752621Sllai1 #define DEVFSADM_RUN_INVALID 1 762621Sllai1 #define DEVFSADM_RUN_EPERM 2 772621Sllai1 #define DEVFSADM_RUN_NOTSUP 3 782621Sllai1 792621Sllai1 /* 802621Sllai1 * devfsadm/devname door data structures 812621Sllai1 */ 822621Sllai1 typedef struct sdev_door_arg { 832621Sllai1 uint8_t devfsadm_cmd; /* what to do for devfsadm[d] */ 842621Sllai1 } sdev_door_arg_t; 852621Sllai1 862621Sllai1 typedef struct sdev_door_res { 872621Sllai1 int32_t devfsadm_error; 882621Sllai1 } sdev_door_res_t; 892621Sllai1 902621Sllai1 #ifdef _KERNEL 912621Sllai1 922621Sllai1 struct sdev_dprof { 932621Sllai1 int has_glob; 942621Sllai1 nvlist_t *dev_name; 952621Sllai1 nvlist_t *dev_map; 962621Sllai1 nvlist_t *dev_symlink; 972621Sllai1 nvlist_t *dev_glob_incdir; 982621Sllai1 nvlist_t *dev_glob_excdir; 992621Sllai1 }; 1002621Sllai1 1012621Sllai1 /* 1022621Sllai1 * devname_handle_t 1032621Sllai1 */ 1042621Sllai1 struct devname_handle { 1052621Sllai1 struct sdev_node *dh_data; /* the sdev_node */ 1062621Sllai1 void *dh_args; 1072621Sllai1 }; 1082621Sllai1 typedef struct devname_handle devname_handle_t; 1092621Sllai1 1102621Sllai1 /* 1112621Sllai1 * Per-instance node data for the global zone instance 1122621Sllai1 * Only one mount of /dev in the global zone 1132621Sllai1 */ 1142621Sllai1 typedef struct sdev_global_data { 1152621Sllai1 struct devname_handle sdev_ghandle; 1162621Sllai1 ulong_t sdev_dir_ggen; /* name space generation # */ 1172621Sllai1 } sdev_global_data_t; 1182621Sllai1 1192621Sllai1 /* 1202621Sllai1 * Per-instance node data - profile data per non-global zone mount instance 1212621Sllai1 */ 1222621Sllai1 typedef struct sdev_local_data { 1232621Sllai1 ulong_t sdev_dir_lgen; /* cached generation # of /dev dir */ 1242621Sllai1 ulong_t sdev_devtree_lgen; /* cached generation # of devtree */ 1252621Sllai1 struct sdev_node *sdev_lorigin; /* corresponding global sdev_node */ 1262621Sllai1 struct sdev_dprof sdev_lprof; /* profile for multi-inst */ 1272621Sllai1 } sdev_local_data_t; 1282621Sllai1 1292621Sllai1 /* 1302621Sllai1 * /dev filesystem sdev_node defines 1312621Sllai1 */ 1322621Sllai1 typedef struct sdev_node { 1332621Sllai1 char *sdev_name; /* node name */ 1342621Sllai1 size_t sdev_namelen; /* strlen(sdev_name) */ 1352621Sllai1 char *sdev_path; /* absolute path */ 1362621Sllai1 char *sdev_symlink; /* source for a symlink */ 1372621Sllai1 struct vnode *sdev_vnode; /* vnode */ 1382621Sllai1 1392621Sllai1 krwlock_t sdev_contents; /* rw lock for this data structure */ 1402621Sllai1 struct sdev_node *sdev_dotdot; /* parent */ 1416260Sjg 1426260Sjg avl_tree_t sdev_entries; /* VDIR: contents as avl tree */ 1436260Sjg avl_node_t sdev_avllink; /* avl node linkage */ 1442621Sllai1 1452621Sllai1 struct vnode *sdev_attrvp; /* backing store vnode if persisted */ 1462621Sllai1 struct vattr *sdev_attr; /* memory copy of the vattr */ 1472621Sllai1 1482621Sllai1 ino64_t sdev_ino; /* inode */ 1492621Sllai1 uint_t sdev_nlink; /* link count */ 1502621Sllai1 int sdev_state; /* state of this node */ 1512621Sllai1 int sdev_flags; /* flags bit */ 1522621Sllai1 1532621Sllai1 kmutex_t sdev_lookup_lock; /* node creation synch lock */ 1542621Sllai1 kcondvar_t sdev_lookup_cv; /* node creation sync cv */ 1552621Sllai1 int sdev_lookup_flags; /* node creation flags */ 1562621Sllai1 1572621Sllai1 /* per-instance data, either global or non-global zone */ 1582621Sllai1 union { 1592621Sllai1 struct sdev_global_data sdev_globaldata; 1602621Sllai1 struct sdev_local_data sdev_localdata; 1612621Sllai1 } sdev_instance_data; 1625895Syz147064 1635895Syz147064 void *sdev_private; 1642621Sllai1 } sdev_node_t; 1652621Sllai1 1662621Sllai1 #define sdev_ldata sdev_instance_data.sdev_localdata 1672621Sllai1 #define sdev_gdata sdev_instance_data.sdev_globaldata 1682621Sllai1 1692621Sllai1 #define sdev_handle sdev_gdata.sdev_ghandle 1702621Sllai1 #define sdev_gdir_gen sdev_gdata.sdev_dir_ggen 1712621Sllai1 1722621Sllai1 #define sdev_ldir_gen sdev_ldata.sdev_dir_lgen 1732621Sllai1 #define sdev_devtree_gen sdev_ldata.sdev_devtree_lgen 1742621Sllai1 #define sdev_origin sdev_ldata.sdev_lorigin 1752621Sllai1 #define sdev_prof sdev_ldata.sdev_lprof 1762621Sllai1 1772621Sllai1 /* 1786260Sjg * Directory contents traversal 1796260Sjg */ 1806260Sjg #define SDEV_FIRST_ENTRY(ddv) avl_first(&(ddv)->sdev_entries) 1816260Sjg #define SDEV_NEXT_ENTRY(ddv, dv) AVL_NEXT(&(ddv)->sdev_entries, (dv)) 1826260Sjg 1836260Sjg /* 1842621Sllai1 * sdev_state 1852621Sllai1 * 1862621Sllai1 * A sdev_node may go through 3 states: 1872621Sllai1 * SDEV_INIT: When a new /dev file is first looked up, a sdev_node 1882621Sllai1 * is allocated, initialized and added to the directory's 1892621Sllai1 * sdev_node cache. A node at this state will also 1902621Sllai1 * have the SDEV_LOOKUP flag set. 1912621Sllai1 * 1922621Sllai1 * Other threads that are trying to look up a node at 1932621Sllai1 * this state will be blocked until the SDEV_LOOKUP flag 1942621Sllai1 * is cleared. 1952621Sllai1 * 1962621Sllai1 * When the SDEV_LOOKUP flag is cleared, the node may 1972621Sllai1 * transition into the SDEV_READY state for a successful 1982621Sllai1 * lookup or the node is removed from the directory cache 1992621Sllai1 * and destroyed if the named node can not be found. 2002621Sllai1 * An ENOENT error is returned for the second case. 2012621Sllai1 * 2022621Sllai1 * SDEV_READY: A /dev file has been successfully looked up and 2032621Sllai1 * associated with a vnode. The /dev file is available 2042621Sllai1 * for the supported /dev filesystem operations. 2052621Sllai1 * 2062621Sllai1 * SDEV_ZOMBIE: Deletion of a /dev file has been explicitely issued 2072621Sllai1 * to an SDEV_READY node. The node is transitioned into 2082621Sllai1 * the SDEV_ZOMBIE state if the vnode reference count 2092621Sllai1 * is still held. A SDEV_ZOMBIE node does not support 2102621Sllai1 * any of the /dev filesystem operations. A SDEV_ZOMBIE 2112621Sllai1 * node is removed from the directory cache and destroyed 2122621Sllai1 * once the reference count reaches "zero". 2132621Sllai1 */ 2142621Sllai1 typedef enum { 2152621Sllai1 SDEV_ZOMBIE = -1, 2162621Sllai1 SDEV_INIT = 0, 2172621Sllai1 SDEV_READY 2182621Sllai1 } sdev_node_state_t; 2192621Sllai1 2202621Sllai1 /* sdev_flags */ 2215895Syz147064 #define SDEV_BUILD 0x0001 /* directory cache out-of-date */ 2225895Syz147064 #define SDEV_STALE 0x0002 /* stale sdev nodes */ 2235895Syz147064 #define SDEV_GLOBAL 0x0004 /* global /dev nodes */ 2245895Syz147064 #define SDEV_PERSIST 0x0008 /* backing store persisted node */ 2255895Syz147064 #define SDEV_NO_NCACHE 0x0010 /* do not include in neg. cache */ 2265895Syz147064 #define SDEV_DYNAMIC 0x0020 /* special-purpose vnode ops */ 2275895Syz147064 /* (ex: pts) */ 2285895Syz147064 #define SDEV_VTOR 0x0040 /* validate sdev_nodes during search */ 2295895Syz147064 #define SDEV_ATTR_INVALID 0x0080 /* invalid node attributes, */ 2305895Syz147064 /* need update */ 23110588SEric.Taylor@Sun.COM #define SDEV_SUBDIR 0x0100 /* match all subdirs under here */ 232*12633Sjohn.levon@sun.com #define SDEV_ZONED 0x0200 /* zoned subdir */ 2332621Sllai1 2342621Sllai1 /* sdev_lookup_flags */ 2352621Sllai1 #define SDEV_LOOKUP 0x0001 /* node creation in progress */ 2362621Sllai1 #define SDEV_READDIR 0x0002 /* VDIR readdir in progress */ 2372621Sllai1 #define SDEV_LGWAITING 0x0004 /* waiting for devfsadm completion */ 2382621Sllai1 2392621Sllai1 #define SDEV_VTOR_INVALID -1 2402621Sllai1 #define SDEV_VTOR_SKIP 0 2412621Sllai1 #define SDEV_VTOR_VALID 1 2428023SPhil.Kirk@Sun.COM #define SDEV_VTOR_STALE 2 2432621Sllai1 2442621Sllai1 /* convenient macros */ 2452621Sllai1 #define SDEV_IS_GLOBAL(dv) \ 2462621Sllai1 (dv->sdev_flags & SDEV_GLOBAL) 2472621Sllai1 #define SDEV_IS_PERSIST(dv) \ 2482621Sllai1 (dv->sdev_flags & SDEV_PERSIST) 2492621Sllai1 #define SDEV_IS_DYNAMIC(dv) \ 2502621Sllai1 (dv->sdev_flags & SDEV_DYNAMIC) 2512621Sllai1 #define SDEV_IS_NO_NCACHE(dv) \ 2522621Sllai1 (dv->sdev_flags & SDEV_NO_NCACHE) 2532621Sllai1 #define SDEV_IS_LOOKUP(dv) \ 2542621Sllai1 (dv->sdev_lookup_flags & SDEV_LOOKUP) 2552621Sllai1 #define SDEV_IS_READDIR(dv) \ 2562621Sllai1 (dv->sdev_lookup_flags & SDEV_READDIR) 2572621Sllai1 #define SDEV_IS_LGWAITING(dv) \ 2582621Sllai1 (dv->sdev_lookup_flags & SDEV_LGWAITING) 2592621Sllai1 2602621Sllai1 #define SDEVTOV(n) ((struct vnode *)(n)->sdev_vnode) 2612621Sllai1 #define VTOSDEV(vp) ((struct sdev_node *)(vp)->v_data) 2622621Sllai1 #define VN_HELD(v) ((v)->v_count != 0) 2632621Sllai1 #define SDEV_HELD(dv) (VN_HELD(SDEVTOV(dv))) 2642621Sllai1 #define SDEV_HOLD(dv) VN_HOLD(SDEVTOV(dv)) 2652621Sllai1 #define SDEV_RELE(dv) VN_RELE(SDEVTOV(dv)) 2662621Sllai1 #define SDEV_SIMPLE_RELE(dv) { \ 2672621Sllai1 mutex_enter(&SDEVTOV(dv)->v_lock); \ 2682621Sllai1 SDEVTOV(dv)->v_count--; \ 2692621Sllai1 mutex_exit(&SDEVTOV(dv)->v_lock); \ 2702621Sllai1 } 2712621Sllai1 2722621Sllai1 #define SDEV_ACL_FLAVOR(vp) (VFSTOSDEVFS(vp->v_vfsp)->sdev_acl_flavor) 2732621Sllai1 2742621Sllai1 /* 2752621Sllai1 * some defaults 2762621Sllai1 */ 2772621Sllai1 #define SDEV_ROOTINO ((ino_t)2) 2782621Sllai1 #define SDEV_UID_DEFAULT (0) 2792621Sllai1 #define SDEV_GID_DEFAULT (3) 2802621Sllai1 #define SDEV_DIRMODE_DEFAULT (S_IFDIR |0755) 2812621Sllai1 #define SDEV_DEVMODE_DEFAULT (0600) 2822621Sllai1 #define SDEV_LNKMODE_DEFAULT (S_IFLNK | 0777) 2832621Sllai1 2842621Sllai1 extern struct vattr sdev_vattr_dir; 2852621Sllai1 extern struct vattr sdev_vattr_lnk; 2862621Sllai1 extern struct vattr sdev_vattr_blk; 2872621Sllai1 extern struct vattr sdev_vattr_chr; 2882621Sllai1 2892621Sllai1 /* 2902621Sllai1 * devname_lookup_func() 2912621Sllai1 */ 2922621Sllai1 extern int devname_lookup_func(struct sdev_node *, char *, struct vnode **, 2932621Sllai1 struct cred *, int (*)(struct sdev_node *, char *, void **, struct cred *, 2942621Sllai1 void *, char *), int); 2952621Sllai1 2962621Sllai1 /* 2972621Sllai1 * flags used by devname_lookup_func callbacks 2982621Sllai1 */ 2992621Sllai1 #define SDEV_VATTR 0x4 /* callback returning node vattr */ 3007688SAaron.Zang@Sun.COM #define SDEV_VLINK 0x8 /* callback returning /dev link */ 3012621Sllai1 3022621Sllai1 /* 3032621Sllai1 * devname_readdir_func() 3042621Sllai1 */ 3052621Sllai1 extern int devname_readdir_func(vnode_t *, uio_t *, cred_t *, int *, int); 3062621Sllai1 3072621Sllai1 /* 3082621Sllai1 * flags for devname_readdir_func 3092621Sllai1 */ 3102621Sllai1 #define SDEV_BROWSE 0x1 /* fetch all entries from backing store */ 3112621Sllai1 3122621Sllai1 /* 3132621Sllai1 * devname_setattr_func() 3142621Sllai1 */ 3152621Sllai1 extern int devname_setattr_func(struct vnode *, struct vattr *, int, 3162621Sllai1 struct cred *, int (*)(struct sdev_node *, struct vattr *, int), int); 3172621Sllai1 /* 3185895Syz147064 * devname_inactive_func() 3195895Syz147064 */ 32010588SEric.Taylor@Sun.COM extern void devname_inactive_func(struct vnode *, struct cred *, 3215895Syz147064 void (*)(struct vnode *)); 3225895Syz147064 3235895Syz147064 /* 3242621Sllai1 * /dev file system instance defines 3252621Sllai1 */ 3262621Sllai1 /* 3272621Sllai1 * /dev version of vfs_data 3282621Sllai1 */ 3292621Sllai1 struct sdev_data { 3302621Sllai1 struct sdev_data *sdev_prev; 3312621Sllai1 struct sdev_data *sdev_next; 3322621Sllai1 struct sdev_node *sdev_root; 3332621Sllai1 struct vfs *sdev_vfsp; 3342621Sllai1 struct sdev_mountargs *sdev_mountargs; 3352621Sllai1 ulong_t sdev_acl_flavor; 3362621Sllai1 }; 3372621Sllai1 3382621Sllai1 #define VFSTOSDEVFS(vfsp) ((struct sdev_data *)((vfsp)->vfs_data)) 3392621Sllai1 3402621Sllai1 /* 3412621Sllai1 * sdev_fid overlays the fid structure (for VFS_VGET) 3422621Sllai1 */ 3432621Sllai1 struct sdev_fid { 3442621Sllai1 uint16_t sdevfid_len; 3452621Sllai1 ino32_t sdevfid_ino; 3462621Sllai1 int32_t sdevfid_gen; 3472621Sllai1 }; 3482621Sllai1 3492621Sllai1 /* 3502621Sllai1 * devfsadm and devname communication defines 3512621Sllai1 */ 3522621Sllai1 typedef enum { 3532621Sllai1 DEVNAME_DEVFSADM_STOPPED = 0, /* devfsadm has never run */ 3542621Sllai1 DEVNAME_DEVFSADM_RUNNING, /* devfsadm is running */ 3552621Sllai1 DEVNAME_DEVFSADM_RUN /* devfsadm ran once */ 3562621Sllai1 } devname_devfsadm_state_t; 3572621Sllai1 3582621Sllai1 extern volatile uint_t devfsadm_state; /* atomic mask for devfsadm status */ 3592621Sllai1 3602621Sllai1 #define DEVNAME_DEVFSADM_SET_RUNNING(devfsadm_state) \ 3612621Sllai1 devfsadm_state = DEVNAME_DEVFSADM_RUNNING 3622621Sllai1 #define DEVNAME_DEVFSADM_SET_STOP(devfsadm_state) \ 3632621Sllai1 devfsadm_state = DEVNAME_DEVFSADM_STOPPED 3642621Sllai1 #define DEVNAME_DEVFSADM_SET_RUN(devfsadm_state) \ 3652621Sllai1 devfsadm_state = DEVNAME_DEVFSADM_RUN 3662621Sllai1 #define DEVNAME_DEVFSADM_IS_RUNNING(devfsadm_state) \ 3672621Sllai1 devfsadm_state == DEVNAME_DEVFSADM_RUNNING 3682621Sllai1 #define DEVNAME_DEVFSADM_HAS_RUN(devfsadm_state) \ 3692621Sllai1 (devfsadm_state == DEVNAME_DEVFSADM_RUN) 3702621Sllai1 3712621Sllai1 #define SDEV_BLOCK_OTHERS(dv, cmd) { \ 3722621Sllai1 ASSERT(MUTEX_HELD(&dv->sdev_lookup_lock)); \ 3732621Sllai1 dv->sdev_lookup_flags |= cmd; \ 3742621Sllai1 } 3752621Sllai1 extern void sdev_unblock_others(struct sdev_node *, uint_t); 3762621Sllai1 #define SDEV_UNBLOCK_OTHERS(dv, cmd) { \ 3772621Sllai1 sdev_unblock_others(dv, cmd); \ 3782621Sllai1 } 3792621Sllai1 3802621Sllai1 #define SDEV_CLEAR_LOOKUP_FLAGS(dv, cmd) { \ 3812621Sllai1 dv->sdev_lookup_flags &= ~cmd; \ 3822621Sllai1 } 3832621Sllai1 3842621Sllai1 extern int sdev_wait4lookup(struct sdev_node *, int); 38510097SEric.Taylor@Sun.COM extern int devname_filename_register(char *); 3862621Sllai1 extern int devname_nsmaps_register(char *, size_t); 3872621Sllai1 extern void sdev_devfsadm_lockinit(void); 3882621Sllai1 extern void sdev_devfsadm_lockdestroy(void); 3892621Sllai1 extern void devname_add_devfsadm_node(char *); 3902621Sllai1 extern void sdev_devfsadmd_thread(struct sdev_node *, struct sdev_node *, 3912621Sllai1 struct cred *); 3922621Sllai1 extern int devname_profile_update(char *, size_t); 3932621Sllai1 extern struct sdev_data *sdev_find_mntinfo(char *); 3942621Sllai1 void sdev_mntinfo_rele(struct sdev_data *); 3952621Sllai1 extern struct vnodeops *devpts_getvnodeops(void); 3967688SAaron.Zang@Sun.COM extern struct vnodeops *devvt_getvnodeops(void); 3972621Sllai1 3982621Sllai1 /* 3992621Sllai1 * boot states - warning, the ordering here is significant 4002621Sllai1 * 4012621Sllai1 * the difference between "system available" and "boot complete" 4022621Sllai1 * is a debounce timeout to catch some daemon issuing a readdir 4032621Sllai1 * triggering a nuisance implict reconfig on each boot. 4042621Sllai1 */ 4052621Sllai1 #define SDEV_BOOT_STATE_INITIAL 0 4062621Sllai1 #define SDEV_BOOT_STATE_RECONFIG 1 /* reconfig */ 4072621Sllai1 #define SDEV_BOOT_STATE_SYSAVAIL 2 /* system available */ 4082621Sllai1 #define SDEV_BOOT_STATE_COMPLETE 3 /* boot complete */ 4092621Sllai1 4102621Sllai1 /* 4112621Sllai1 * Negative cache list and list element 4122621Sllai1 * The mutex protects the flags against multiple accesses and 4132621Sllai1 * must only be acquired when already holding the r/w lock. 4142621Sllai1 */ 4152621Sllai1 typedef struct sdev_nc_list { 4162621Sllai1 list_t ncl_list; /* the list itself */ 4172621Sllai1 kmutex_t ncl_mutex; /* protects ncl_flags */ 4182621Sllai1 krwlock_t ncl_lock; /* protects ncl_list */ 4192621Sllai1 int ncl_flags; 4202621Sllai1 int ncl_nentries; 4212621Sllai1 } sdev_nc_list_t; 4222621Sllai1 4232621Sllai1 typedef struct sdev_nc_node { 4242621Sllai1 char *ncn_name; /* name of the node */ 4252621Sllai1 int ncn_flags; /* state information */ 4262621Sllai1 int ncn_expirecnt; /* remove once expired */ 4272621Sllai1 list_node_t ncn_link; /* link to next in list */ 4282621Sllai1 } sdev_nc_node_t; 4292621Sllai1 4302621Sllai1 /* ncl_flags */ 4312621Sllai1 #define NCL_LIST_DIRTY 0x01 /* needs to be flushed */ 4322621Sllai1 #define NCL_LIST_WRITING 0x02 /* write in progress */ 4332621Sllai1 #define NCL_LIST_WENABLE 0x04 /* write-enabled post boot */ 4342621Sllai1 4352621Sllai1 /* ncn_flags */ 4362621Sllai1 #define NCN_ACTIVE 0x01 /* a lookup has occurred */ 4372621Sllai1 #define NCN_SRC_STORE 0x02 /* src: persistent store */ 4382621Sllai1 #define NCN_SRC_CURRENT 0x04 /* src: current boot */ 4392621Sllai1 4402621Sllai1 /* sdev_lookup_failed flags */ 4412621Sllai1 #define SLF_NO_NCACHE 0x01 /* node should not be added to ncache */ 4422621Sllai1 #define SLF_REBUILT 0x02 /* reconfig performed during lookup attempt */ 4432621Sllai1 4442621Sllai1 /* 4452797Sjg * The nvlist name and nvpair identifiers in the 4462797Sjg * /etc/devices/devname_cache nvlist format 4472797Sjg */ 4482797Sjg #define DP_DEVNAME_ID "devname" 4492797Sjg #define DP_DEVNAME_NCACHE_ID "ncache" 4502797Sjg #define DP_DEVNAME_NC_EXPIRECNT_ID "expire-counts" 4512797Sjg 4522797Sjg /* devname-cache list element */ 4532797Sjg typedef struct nvp_devname { 4542797Sjg char **nvp_paths; 4552797Sjg int *nvp_expirecnts; 4562797Sjg int nvp_npaths; 4572797Sjg list_node_t nvp_link; 4582797Sjg } nvp_devname_t; 4592797Sjg 4602797Sjg /* 4612621Sllai1 * name service globals and prototypes 4622621Sllai1 */ 4632621Sllai1 4642621Sllai1 /* 4652621Sllai1 * vnodeops and vfsops helpers 4662621Sllai1 */ 4672621Sllai1 4682621Sllai1 typedef enum { 4692621Sllai1 SDEV_CACHE_ADD = 0, 4702621Sllai1 SDEV_CACHE_DELETE 4712621Sllai1 } sdev_cache_ops_t; 4722621Sllai1 4732621Sllai1 extern struct sdev_node *sdev_cache_lookup(struct sdev_node *, char *); 4742621Sllai1 extern int sdev_cache_update(struct sdev_node *, struct sdev_node **, char *, 4752621Sllai1 sdev_cache_ops_t); 4762621Sllai1 extern void sdev_node_cache_init(void); 4772621Sllai1 extern void sdev_node_cache_fini(void); 4782621Sllai1 extern struct sdev_node *sdev_mkroot(struct vfs *, dev_t, struct vnode *, 4792621Sllai1 struct vnode *, struct cred *); 4803843Sjg extern void sdev_filldir_dynamic(struct sdev_node *); 4812621Sllai1 extern int sdev_mknode(struct sdev_node *, char *, struct sdev_node **, 4822621Sllai1 struct vattr *, struct vnode *, void *, struct cred *, sdev_node_state_t); 48310588SEric.Taylor@Sun.COM extern int sdev_getlink(struct vnode *linkvp, char **link); 48410588SEric.Taylor@Sun.COM 4852621Sllai1 extern int sdev_nodeinit(struct sdev_node *, char *, struct sdev_node **, 4862621Sllai1 vattr_t *); 4872621Sllai1 extern int sdev_nodeready(struct sdev_node *, vattr_t *, vnode_t *, void *, 4882621Sllai1 cred_t *); 4892621Sllai1 extern int sdev_shadow_node(struct sdev_node *, struct cred *); 4902621Sllai1 extern void sdev_nodedestroy(struct sdev_node *, uint_t); 4912621Sllai1 extern void sdev_update_timestamps(struct vnode *, cred_t *, uint_t); 4922621Sllai1 extern void sdev_vattr_merge(struct sdev_node *, struct vattr *); 4932621Sllai1 extern void sdev_devstate_change(void); 4942621Sllai1 extern int sdev_lookup_filter(sdev_node_t *, char *); 4952621Sllai1 extern void sdev_lookup_failed(sdev_node_t *, char *, int); 4962621Sllai1 extern int sdev_unlocked_access(void *, int, struct cred *); 4972621Sllai1 4982621Sllai1 #define SDEV_ENFORCE 0x1 4992621Sllai1 extern void sdev_stale(struct sdev_node *); 5002621Sllai1 extern int sdev_cleandir(struct sdev_node *, char *, uint_t); 5012621Sllai1 extern int sdev_rnmnode(struct sdev_node *, struct sdev_node *, 5022621Sllai1 struct sdev_node *, struct sdev_node **, char *, struct cred *); 5032621Sllai1 extern size_t add_dir_entry(dirent64_t *, char *, size_t, ino_t, offset_t); 50410588SEric.Taylor@Sun.COM extern struct vattr *sdev_getdefault_attr(enum vtype type); 5052621Sllai1 extern int sdev_to_vp(struct sdev_node *, struct vnode **); 5062621Sllai1 extern ino_t sdev_mkino(struct sdev_node *); 5072621Sllai1 extern int devname_backstore_lookup(struct sdev_node *, char *, 5082621Sllai1 struct vnode **); 5092621Sllai1 extern int sdev_is_devfs_node(char *); 5102621Sllai1 extern int sdev_copyin_mountargs(struct mounta *, struct sdev_mountargs *); 5112621Sllai1 extern int sdev_reserve_subdirs(struct sdev_node *); 5122621Sllai1 extern int prof_lookup(); 5132621Sllai1 extern void prof_filldir(struct sdev_node *); 5142621Sllai1 extern int devpts_validate(struct sdev_node *dv); 5155895Syz147064 extern int devnet_validate(struct sdev_node *dv); 5168023SPhil.Kirk@Sun.COM extern int devipnet_validate(struct sdev_node *dv); 5177688SAaron.Zang@Sun.COM extern int devvt_validate(struct sdev_node *dv); 51810588SEric.Taylor@Sun.COM extern int devzvol_validate(struct sdev_node *dv); 5192621Sllai1 extern void *sdev_get_vtor(struct sdev_node *dv); 5202621Sllai1 5212621Sllai1 /* 52210588SEric.Taylor@Sun.COM * devinfo helpers 52310588SEric.Taylor@Sun.COM */ 52410588SEric.Taylor@Sun.COM extern int sdev_modctl_readdir(const char *, char ***, int *, int *, int); 52510588SEric.Taylor@Sun.COM extern void sdev_modctl_readdir_free(char **, int, int); 52610588SEric.Taylor@Sun.COM extern int sdev_modctl_devexists(const char *); 52710588SEric.Taylor@Sun.COM 52810588SEric.Taylor@Sun.COM /* 5292621Sllai1 * ncache handlers 5302621Sllai1 */ 5312621Sllai1 5322621Sllai1 extern void sdev_ncache_init(void); 5332621Sllai1 extern void sdev_ncache_setup(void); 5342621Sllai1 extern void sdev_ncache_teardown(void); 5352621Sllai1 extern void sdev_nc_addname(sdev_nc_list_t *, sdev_node_t *, char *, int); 5362621Sllai1 extern void sdev_nc_node_exists(sdev_node_t *); 5372621Sllai1 extern void sdev_nc_path_exists(sdev_nc_list_t *, char *); 5382621Sllai1 extern void sdev_modctl_dump_files(void); 5392621Sllai1 5402621Sllai1 /* 5412621Sllai1 * globals 5422621Sllai1 */ 5432729Sllai1 extern kmutex_t sdev_lock; 5442621Sllai1 extern int devtype; 5452621Sllai1 extern kmem_cache_t *sdev_node_cache; 5462621Sllai1 extern struct vnodeops *sdev_vnodeops; 5472621Sllai1 extern struct vnodeops *devpts_vnodeops; 5485895Syz147064 extern struct vnodeops *devnet_vnodeops; 5498023SPhil.Kirk@Sun.COM extern struct vnodeops *devipnet_vnodeops; 5507688SAaron.Zang@Sun.COM extern struct vnodeops *devvt_vnodeops; 5512621Sllai1 extern struct sdev_data *sdev_origins; /* mount info for global /dev instance */ 55210588SEric.Taylor@Sun.COM extern struct vnodeops *devzvol_vnodeops; 55310588SEric.Taylor@Sun.COM 5542621Sllai1 extern const fs_operation_def_t sdev_vnodeops_tbl[]; 5552621Sllai1 extern const fs_operation_def_t devpts_vnodeops_tbl[]; 5565895Syz147064 extern const fs_operation_def_t devnet_vnodeops_tbl[]; 5578023SPhil.Kirk@Sun.COM extern const fs_operation_def_t devipnet_vnodeops_tbl[]; 5587688SAaron.Zang@Sun.COM extern const fs_operation_def_t devvt_vnodeops_tbl[]; 5592621Sllai1 extern const fs_operation_def_t devsys_vnodeops_tbl[]; 5602621Sllai1 extern const fs_operation_def_t devpseudo_vnodeops_tbl[]; 56110588SEric.Taylor@Sun.COM extern const fs_operation_def_t devzvol_vnodeops_tbl[]; 5622621Sllai1 5632621Sllai1 extern sdev_nc_list_t *sdev_ncache; 5642621Sllai1 extern int sdev_reconfig_boot; 5652621Sllai1 extern int sdev_boot_state; 5662621Sllai1 extern int sdev_reconfig_verbose; 5672621Sllai1 extern int sdev_reconfig_disable; 5682621Sllai1 extern int sdev_nc_disable; 5692621Sllai1 extern int sdev_nc_disable_reset; 5702621Sllai1 extern int sdev_nc_verbose; 5712621Sllai1 5722621Sllai1 /* 5732621Sllai1 * misc. defines 5742621Sllai1 */ 5752621Sllai1 #ifdef DEBUG 5762621Sllai1 extern int sdev_debug; 5772621Sllai1 #define SDEV_DEBUG 0x01 /* error messages to console/log */ 5782621Sllai1 #define SDEV_DEBUG_VOPS 0x02 /* vnode ops errors */ 5792621Sllai1 #define SDEV_DEBUG_DLF 0x04 /* trace devname_lookup_func */ 5802621Sllai1 #define SDEV_DEBUG_DRF 0x08 /* trace devname_readdir_func */ 5812621Sllai1 #define SDEV_DEBUG_NCACHE 0x10 /* negative cache tracing */ 5822621Sllai1 #define SDEV_DEBUG_DEVFSADMD 0x20 /* comm. of devnamefs & devfsadm */ 5832621Sllai1 #define SDEV_DEBUG_PTS 0x40 /* /dev/pts tracing */ 5842621Sllai1 #define SDEV_DEBUG_RECONFIG 0x80 /* events triggering reconfig */ 5852621Sllai1 #define SDEV_DEBUG_SDEV_NODE 0x100 /* trace sdev_node activities */ 5862621Sllai1 #define SDEV_DEBUG_PROFILE 0x200 /* trace sdev_profile */ 5872621Sllai1 #define SDEV_DEBUG_MODCTL 0x400 /* trace modctl activity */ 5882621Sllai1 #define SDEV_DEBUG_FLK 0x800 /* trace failed lookups */ 5895895Syz147064 #define SDEV_DEBUG_NET 0x1000 /* /dev/net tracing */ 59010588SEric.Taylor@Sun.COM #define SDEV_DEBUG_ZVOL 0x2000 /* /dev/zvol/tracing */ 5912621Sllai1 5922621Sllai1 #define sdcmn_err(args) if (sdev_debug & SDEV_DEBUG) printf args 5932621Sllai1 #define sdcmn_err2(args) if (sdev_debug & SDEV_DEBUG_VOPS) printf args 5942621Sllai1 #define sdcmn_err3(args) if (sdev_debug & SDEV_DEBUG_DLF) printf args 5952621Sllai1 #define sdcmn_err4(args) if (sdev_debug & SDEV_DEBUG_DRF) printf args 5962621Sllai1 #define sdcmn_err5(args) if (sdev_debug & SDEV_DEBUG_NCACHE) printf args 5972621Sllai1 #define sdcmn_err6(args) if (sdev_debug & SDEV_DEBUG_DEVFSADMD) printf args 5982621Sllai1 #define sdcmn_err7(args) if (sdev_debug & SDEV_DEBUG_PTS) printf args 5992621Sllai1 #define sdcmn_err8(args) if (sdev_debug & SDEV_DEBUG_RECONFIG) printf args 6002621Sllai1 #define sdcmn_err9(args) if (sdev_debug & SDEV_DEBUG_SDEV_NODE) printf args 6012621Sllai1 #define sdcmn_err10(args) if (sdev_debug & SDEV_DEBUG_PROFILE) printf args 6022621Sllai1 #define sdcmn_err11(args) if (sdev_debug & SDEV_DEBUG_MODCTL) printf args 6035895Syz147064 #define sdcmn_err12(args) if (sdev_debug & SDEV_DEBUG_NET) printf args 60410588SEric.Taylor@Sun.COM #define sdcmn_err13(args) if (sdev_debug & SDEV_DEBUG_ZVOL) printf args 6052621Sllai1 #define impossible(args) printf args 6062621Sllai1 #else 6072621Sllai1 #define sdcmn_err(args) /* does nothing */ 6082621Sllai1 #define sdcmn_err2(args) /* does nothing */ 6092621Sllai1 #define sdcmn_err3(args) /* does nothing */ 6102621Sllai1 #define sdcmn_err4(args) /* does nothing */ 6112621Sllai1 #define sdcmn_err5(args) /* does nothing */ 6122621Sllai1 #define sdcmn_err6(args) /* does nothing */ 6132621Sllai1 #define sdcmn_err7(args) /* does nothing */ 6142621Sllai1 #define sdcmn_err8(args) /* does nothing */ 6152621Sllai1 #define sdcmn_err9(args) /* does nothing */ 6162621Sllai1 #define sdcmn_err10(args) /* does nothing */ 6172621Sllai1 #define sdcmn_err11(args) /* does nothing */ 6185895Syz147064 #define sdcmn_err12(args) /* does nothing */ 61910588SEric.Taylor@Sun.COM #define sdcmn_err13(args) /* does nothing */ 6202621Sllai1 #define impossible(args) /* does nothing */ 6212621Sllai1 #endif 6222621Sllai1 6232621Sllai1 #ifdef DEBUG 6242621Sllai1 #define SD_TRACE_FAILED_LOOKUP(ddv, nm, retried) \ 6252621Sllai1 if ((sdev_debug & SDEV_DEBUG_FLK) || \ 6262621Sllai1 ((retried) && (sdev_debug & SDEV_DEBUG_RECONFIG))) { \ 6272621Sllai1 printf("lookup of %s/%s by %s failed, line %d\n", \ 6282621Sllai1 (ddv)->sdev_name, (nm), curproc->p_user.u_comm, \ 6292621Sllai1 __LINE__); \ 6302621Sllai1 } 6312621Sllai1 #else 6322621Sllai1 #define SD_TRACE_FAILED_LOOKUP(ddv, nm, retried) 6332621Sllai1 #endif 6342621Sllai1 6352621Sllai1 #endif /* _KERNEL */ 6362621Sllai1 6372621Sllai1 #ifdef __cplusplus 6382621Sllai1 } 6392621Sllai1 #endif 6402621Sllai1 6412621Sllai1 #endif /* _SYS_SDEV_IMPL_H */ 642