1facf4a8dSllai1 /* 2facf4a8dSllai1 * CDDL HEADER START 3facf4a8dSllai1 * 4facf4a8dSllai1 * The contents of this file are subject to the terms of the 5facf4a8dSllai1 * Common Development and Distribution License (the "License"). 6facf4a8dSllai1 * You may not use this file except in compliance with the License. 7facf4a8dSllai1 * 8facf4a8dSllai1 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9facf4a8dSllai1 * or http://www.opensolaris.org/os/licensing. 10facf4a8dSllai1 * See the License for the specific language governing permissions 11facf4a8dSllai1 * and limitations under the License. 12facf4a8dSllai1 * 13facf4a8dSllai1 * When distributing Covered Code, include this CDDL HEADER in each 14facf4a8dSllai1 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15facf4a8dSllai1 * If applicable, add the following below this CDDL HEADER, with the 16facf4a8dSllai1 * fields enclosed by brackets "[]" replaced with your own identifying 17facf4a8dSllai1 * information: Portions Copyright [yyyy] [name of copyright owner] 18facf4a8dSllai1 * 19facf4a8dSllai1 * CDDL HEADER END 20facf4a8dSllai1 */ 21facf4a8dSllai1 /* 220fbb751dSJohn Levon * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 230ad555adSAlex Wilson * Copyright 2015 Joyent, Inc. All rights reserved. 24facf4a8dSllai1 */ 25facf4a8dSllai1 26facf4a8dSllai1 #ifndef _SYS_SDEV_IMPL_H 27facf4a8dSllai1 #define _SYS_SDEV_IMPL_H 28facf4a8dSllai1 29facf4a8dSllai1 #ifdef __cplusplus 30facf4a8dSllai1 extern "C" { 31facf4a8dSllai1 #endif 32facf4a8dSllai1 33facf4a8dSllai1 #include <rpc/rpc.h> 34facf4a8dSllai1 #include <sys/dirent.h> 35facf4a8dSllai1 #include <sys/vfs.h> 36aa59c4cbSrsb #include <sys/vfs_opreg.h> 37facf4a8dSllai1 #include <sys/list.h> 38facf4a8dSllai1 #include <sys/nvpair.h> 390ad555adSAlex Wilson #include <sys/sunddi.h> 40facf4a8dSllai1 41facf4a8dSllai1 /* 42facf4a8dSllai1 * sdev_nodes are the file-system specific part of the 43facf4a8dSllai1 * vnodes for the device filesystem. 44facf4a8dSllai1 * 45facf4a8dSllai1 * The device filesystem exports two node types: 46facf4a8dSllai1 * 47facf4a8dSllai1 * VDIR nodes to represent directories 48facf4a8dSllai1 * VCHR & VBLK nodes to represent devices 49facf4a8dSllai1 */ 50facf4a8dSllai1 51facf4a8dSllai1 /* 52facf4a8dSllai1 * /dev mount arguments 53facf4a8dSllai1 */ 54facf4a8dSllai1 struct sdev_mountargs { 55facf4a8dSllai1 uint64_t sdev_attrdir; 56facf4a8dSllai1 }; 57facf4a8dSllai1 58facf4a8dSllai1 59facf4a8dSllai1 /* 60facf4a8dSllai1 * Nvpair names of profile information (list of device files available) of 61facf4a8dSllai1 * non-global /dev mounts. These strings must be unique among them. 62facf4a8dSllai1 */ 63facf4a8dSllai1 #define SDEV_NVNAME_MOUNTPT "prof_mountpt" 64facf4a8dSllai1 #define SDEV_NVNAME_INCLUDE "prof_include" 65facf4a8dSllai1 #define SDEV_NVNAME_EXCLUDE "prof_exclude" 66facf4a8dSllai1 #define SDEV_NVNAME_SYMLINK "prof_symlink" 67facf4a8dSllai1 #define SDEV_NVNAME_MAP "prof_map" 68facf4a8dSllai1 69facf4a8dSllai1 /* 70facf4a8dSllai1 * supported devfsadm_cmd 71facf4a8dSllai1 */ 72facf4a8dSllai1 #define DEVFSADMD_RUN_ALL 1 73facf4a8dSllai1 74facf4a8dSllai1 /* 75facf4a8dSllai1 * devfsadm_error codes 76facf4a8dSllai1 */ 77facf4a8dSllai1 #define DEVFSADM_RUN_INVALID 1 78facf4a8dSllai1 #define DEVFSADM_RUN_EPERM 2 79facf4a8dSllai1 #define DEVFSADM_RUN_NOTSUP 3 80facf4a8dSllai1 81facf4a8dSllai1 /* 82facf4a8dSllai1 * devfsadm/devname door data structures 83facf4a8dSllai1 */ 84facf4a8dSllai1 typedef struct sdev_door_arg { 85facf4a8dSllai1 uint8_t devfsadm_cmd; /* what to do for devfsadm[d] */ 86facf4a8dSllai1 } sdev_door_arg_t; 87facf4a8dSllai1 88facf4a8dSllai1 typedef struct sdev_door_res { 89facf4a8dSllai1 int32_t devfsadm_error; 90facf4a8dSllai1 } sdev_door_res_t; 91facf4a8dSllai1 92facf4a8dSllai1 #ifdef _KERNEL 93facf4a8dSllai1 94facf4a8dSllai1 struct sdev_dprof { 95facf4a8dSllai1 int has_glob; 96facf4a8dSllai1 nvlist_t *dev_name; 97facf4a8dSllai1 nvlist_t *dev_map; 98facf4a8dSllai1 nvlist_t *dev_symlink; 99facf4a8dSllai1 nvlist_t *dev_glob_incdir; 100facf4a8dSllai1 nvlist_t *dev_glob_excdir; 101facf4a8dSllai1 }; 102facf4a8dSllai1 103facf4a8dSllai1 /* 104facf4a8dSllai1 * devname_handle_t 105facf4a8dSllai1 */ 106facf4a8dSllai1 struct devname_handle { 107facf4a8dSllai1 struct sdev_node *dh_data; /* the sdev_node */ 108facf4a8dSllai1 void *dh_args; 109facf4a8dSllai1 }; 110facf4a8dSllai1 typedef struct devname_handle devname_handle_t; 111facf4a8dSllai1 112facf4a8dSllai1 /* 113facf4a8dSllai1 * Per-instance node data for the global zone instance 114facf4a8dSllai1 * Only one mount of /dev in the global zone 115facf4a8dSllai1 */ 116facf4a8dSllai1 typedef struct sdev_global_data { 117facf4a8dSllai1 struct devname_handle sdev_ghandle; 118facf4a8dSllai1 ulong_t sdev_dir_ggen; /* name space generation # */ 119facf4a8dSllai1 } sdev_global_data_t; 120facf4a8dSllai1 121facf4a8dSllai1 /* 122facf4a8dSllai1 * Per-instance node data - profile data per non-global zone mount instance 123facf4a8dSllai1 */ 124facf4a8dSllai1 typedef struct sdev_local_data { 125facf4a8dSllai1 ulong_t sdev_dir_lgen; /* cached generation # of /dev dir */ 126facf4a8dSllai1 ulong_t sdev_devtree_lgen; /* cached generation # of devtree */ 127facf4a8dSllai1 struct sdev_node *sdev_lorigin; /* corresponding global sdev_node */ 128facf4a8dSllai1 struct sdev_dprof sdev_lprof; /* profile for multi-inst */ 129facf4a8dSllai1 } sdev_local_data_t; 130facf4a8dSllai1 131facf4a8dSllai1 /* 132facf4a8dSllai1 * /dev filesystem sdev_node defines 133facf4a8dSllai1 */ 134facf4a8dSllai1 typedef struct sdev_node { 135facf4a8dSllai1 char *sdev_name; /* node name */ 136facf4a8dSllai1 size_t sdev_namelen; /* strlen(sdev_name) */ 137facf4a8dSllai1 char *sdev_path; /* absolute path */ 138facf4a8dSllai1 char *sdev_symlink; /* source for a symlink */ 139facf4a8dSllai1 struct vnode *sdev_vnode; /* vnode */ 140facf4a8dSllai1 141facf4a8dSllai1 krwlock_t sdev_contents; /* rw lock for this data structure */ 142facf4a8dSllai1 struct sdev_node *sdev_dotdot; /* parent */ 143aac43a5fSjg 144aac43a5fSjg avl_tree_t sdev_entries; /* VDIR: contents as avl tree */ 145aac43a5fSjg avl_node_t sdev_avllink; /* avl node linkage */ 146facf4a8dSllai1 147facf4a8dSllai1 struct vnode *sdev_attrvp; /* backing store vnode if persisted */ 148facf4a8dSllai1 struct vattr *sdev_attr; /* memory copy of the vattr */ 149facf4a8dSllai1 150facf4a8dSllai1 ino64_t sdev_ino; /* inode */ 151facf4a8dSllai1 uint_t sdev_nlink; /* link count */ 152facf4a8dSllai1 int sdev_state; /* state of this node */ 153facf4a8dSllai1 int sdev_flags; /* flags bit */ 154facf4a8dSllai1 155facf4a8dSllai1 kmutex_t sdev_lookup_lock; /* node creation synch lock */ 156facf4a8dSllai1 kcondvar_t sdev_lookup_cv; /* node creation sync cv */ 157facf4a8dSllai1 int sdev_lookup_flags; /* node creation flags */ 158facf4a8dSllai1 159facf4a8dSllai1 /* per-instance data, either global or non-global zone */ 160facf4a8dSllai1 union { 161facf4a8dSllai1 struct sdev_global_data sdev_globaldata; 162facf4a8dSllai1 struct sdev_local_data sdev_localdata; 163facf4a8dSllai1 } sdev_instance_data; 164d62bc4baSyz147064 165d62bc4baSyz147064 void *sdev_private; 166facf4a8dSllai1 } sdev_node_t; 167facf4a8dSllai1 168facf4a8dSllai1 #define sdev_ldata sdev_instance_data.sdev_localdata 169facf4a8dSllai1 #define sdev_gdata sdev_instance_data.sdev_globaldata 170facf4a8dSllai1 171facf4a8dSllai1 #define sdev_handle sdev_gdata.sdev_ghandle 172facf4a8dSllai1 #define sdev_gdir_gen sdev_gdata.sdev_dir_ggen 173facf4a8dSllai1 174facf4a8dSllai1 #define sdev_ldir_gen sdev_ldata.sdev_dir_lgen 175facf4a8dSllai1 #define sdev_devtree_gen sdev_ldata.sdev_devtree_lgen 176facf4a8dSllai1 #define sdev_origin sdev_ldata.sdev_lorigin 177facf4a8dSllai1 #define sdev_prof sdev_ldata.sdev_lprof 178facf4a8dSllai1 179facf4a8dSllai1 /* 180aac43a5fSjg * Directory contents traversal 181aac43a5fSjg */ 182aac43a5fSjg #define SDEV_FIRST_ENTRY(ddv) avl_first(&(ddv)->sdev_entries) 183aac43a5fSjg #define SDEV_NEXT_ENTRY(ddv, dv) AVL_NEXT(&(ddv)->sdev_entries, (dv)) 184aac43a5fSjg 185aac43a5fSjg /* 1869e5aa9d8SRobert Mustacchi * See the big theory statement in sdev_vnops.c for an explanation of these 1879e5aa9d8SRobert Mustacchi * states. 188facf4a8dSllai1 */ 189facf4a8dSllai1 typedef enum { 190facf4a8dSllai1 SDEV_ZOMBIE = -1, 191facf4a8dSllai1 SDEV_INIT = 0, 192facf4a8dSllai1 SDEV_READY 193facf4a8dSllai1 } sdev_node_state_t; 194facf4a8dSllai1 195facf4a8dSllai1 /* sdev_flags */ 196facf4a8dSllai1 #define SDEV_BUILD 0x0001 /* directory cache out-of-date */ 1979e5aa9d8SRobert Mustacchi #define SDEV_GLOBAL 0x0002 /* global /dev nodes */ 1989e5aa9d8SRobert Mustacchi #define SDEV_PERSIST 0x0004 /* backing store persisted node */ 1999e5aa9d8SRobert Mustacchi #define SDEV_NO_NCACHE 0x0008 /* do not include in neg. cache */ 2009e5aa9d8SRobert Mustacchi #define SDEV_DYNAMIC 0x0010 /* special-purpose vnode ops */ 201d62bc4baSyz147064 /* (ex: pts) */ 2029e5aa9d8SRobert Mustacchi #define SDEV_VTOR 0x0020 /* validate sdev_nodes during search */ 2039e5aa9d8SRobert Mustacchi #define SDEV_ATTR_INVALID 0x0040 /* invalid node attributes, */ 204d62bc4baSyz147064 /* need update */ 2059e5aa9d8SRobert Mustacchi #define SDEV_SUBDIR 0x0080 /* match all subdirs under here */ 2069e5aa9d8SRobert Mustacchi #define SDEV_ZONED 0x0100 /* zoned subdir */ 207facf4a8dSllai1 208facf4a8dSllai1 /* sdev_lookup_flags */ 209facf4a8dSllai1 #define SDEV_LOOKUP 0x0001 /* node creation in progress */ 210facf4a8dSllai1 #define SDEV_READDIR 0x0002 /* VDIR readdir in progress */ 211facf4a8dSllai1 #define SDEV_LGWAITING 0x0004 /* waiting for devfsadm completion */ 212facf4a8dSllai1 213facf4a8dSllai1 #define SDEV_VTOR_INVALID -1 214facf4a8dSllai1 #define SDEV_VTOR_SKIP 0 215facf4a8dSllai1 #define SDEV_VTOR_VALID 1 216b127ac41SPhilip Kirk #define SDEV_VTOR_STALE 2 217facf4a8dSllai1 218facf4a8dSllai1 /* convenient macros */ 219facf4a8dSllai1 #define SDEV_IS_GLOBAL(dv) \ 220facf4a8dSllai1 (dv->sdev_flags & SDEV_GLOBAL) 221facf4a8dSllai1 #define SDEV_IS_PERSIST(dv) \ 222facf4a8dSllai1 (dv->sdev_flags & SDEV_PERSIST) 223facf4a8dSllai1 #define SDEV_IS_DYNAMIC(dv) \ 224facf4a8dSllai1 (dv->sdev_flags & SDEV_DYNAMIC) 225facf4a8dSllai1 #define SDEV_IS_NO_NCACHE(dv) \ 226facf4a8dSllai1 (dv->sdev_flags & SDEV_NO_NCACHE) 227facf4a8dSllai1 #define SDEV_IS_LOOKUP(dv) \ 228facf4a8dSllai1 (dv->sdev_lookup_flags & SDEV_LOOKUP) 229facf4a8dSllai1 #define SDEV_IS_READDIR(dv) \ 230facf4a8dSllai1 (dv->sdev_lookup_flags & SDEV_READDIR) 231facf4a8dSllai1 #define SDEV_IS_LGWAITING(dv) \ 232facf4a8dSllai1 (dv->sdev_lookup_flags & SDEV_LGWAITING) 233facf4a8dSllai1 234facf4a8dSllai1 #define SDEVTOV(n) ((struct vnode *)(n)->sdev_vnode) 235facf4a8dSllai1 #define VTOSDEV(vp) ((struct sdev_node *)(vp)->v_data) 236facf4a8dSllai1 #define VN_HELD(v) ((v)->v_count != 0) 237facf4a8dSllai1 #define SDEV_HELD(dv) (VN_HELD(SDEVTOV(dv))) 238facf4a8dSllai1 #define SDEV_HOLD(dv) VN_HOLD(SDEVTOV(dv)) 239facf4a8dSllai1 #define SDEV_RELE(dv) VN_RELE(SDEVTOV(dv)) 240facf4a8dSllai1 #define SDEV_SIMPLE_RELE(dv) { \ 241facf4a8dSllai1 mutex_enter(&SDEVTOV(dv)->v_lock); \ 242facf4a8dSllai1 SDEVTOV(dv)->v_count--; \ 243facf4a8dSllai1 mutex_exit(&SDEVTOV(dv)->v_lock); \ 244facf4a8dSllai1 } 245facf4a8dSllai1 246facf4a8dSllai1 #define SDEV_ACL_FLAVOR(vp) (VFSTOSDEVFS(vp->v_vfsp)->sdev_acl_flavor) 247facf4a8dSllai1 248facf4a8dSllai1 /* 249facf4a8dSllai1 * some defaults 250facf4a8dSllai1 */ 251facf4a8dSllai1 #define SDEV_ROOTINO ((ino_t)2) 252facf4a8dSllai1 #define SDEV_UID_DEFAULT (0) 253facf4a8dSllai1 #define SDEV_GID_DEFAULT (3) 254facf4a8dSllai1 #define SDEV_DIRMODE_DEFAULT (S_IFDIR |0755) 255facf4a8dSllai1 #define SDEV_DEVMODE_DEFAULT (0600) 256facf4a8dSllai1 #define SDEV_LNKMODE_DEFAULT (S_IFLNK | 0777) 257facf4a8dSllai1 258facf4a8dSllai1 extern struct vattr sdev_vattr_dir; 259facf4a8dSllai1 extern struct vattr sdev_vattr_lnk; 260facf4a8dSllai1 extern struct vattr sdev_vattr_blk; 261facf4a8dSllai1 extern struct vattr sdev_vattr_chr; 262facf4a8dSllai1 263facf4a8dSllai1 /* 264facf4a8dSllai1 * devname_lookup_func() 265facf4a8dSllai1 */ 266facf4a8dSllai1 extern int devname_lookup_func(struct sdev_node *, char *, struct vnode **, 267facf4a8dSllai1 struct cred *, int (*)(struct sdev_node *, char *, void **, struct cred *, 268facf4a8dSllai1 void *, char *), int); 269facf4a8dSllai1 270facf4a8dSllai1 /* 271facf4a8dSllai1 * flags used by devname_lookup_func callbacks 272facf4a8dSllai1 */ 273facf4a8dSllai1 #define SDEV_VATTR 0x4 /* callback returning node vattr */ 274aecfc01dSrui zang - Sun Microsystems - Beijing China #define SDEV_VLINK 0x8 /* callback returning /dev link */ 275facf4a8dSllai1 276facf4a8dSllai1 /* 277facf4a8dSllai1 * devname_readdir_func() 278facf4a8dSllai1 */ 279facf4a8dSllai1 extern int devname_readdir_func(vnode_t *, uio_t *, cred_t *, int *, int); 280facf4a8dSllai1 281facf4a8dSllai1 /* 282facf4a8dSllai1 * flags for devname_readdir_func 283facf4a8dSllai1 */ 284facf4a8dSllai1 #define SDEV_BROWSE 0x1 /* fetch all entries from backing store */ 285facf4a8dSllai1 286facf4a8dSllai1 /* 287facf4a8dSllai1 * devname_setattr_func() 288facf4a8dSllai1 */ 289facf4a8dSllai1 extern int devname_setattr_func(struct vnode *, struct vattr *, int, 290facf4a8dSllai1 struct cred *, int (*)(struct sdev_node *, struct vattr *, int), int); 291facf4a8dSllai1 /* 292d62bc4baSyz147064 * devname_inactive_func() 293d62bc4baSyz147064 */ 294681d9761SEric Taylor extern void devname_inactive_func(struct vnode *, struct cred *, 295d62bc4baSyz147064 void (*)(struct vnode *)); 296d62bc4baSyz147064 297d62bc4baSyz147064 /* 298facf4a8dSllai1 * /dev file system instance defines 299facf4a8dSllai1 */ 300facf4a8dSllai1 /* 301facf4a8dSllai1 * /dev version of vfs_data 302facf4a8dSllai1 */ 303facf4a8dSllai1 struct sdev_data { 304facf4a8dSllai1 struct sdev_data *sdev_prev; 305facf4a8dSllai1 struct sdev_data *sdev_next; 306facf4a8dSllai1 struct sdev_node *sdev_root; 307facf4a8dSllai1 struct vfs *sdev_vfsp; 308facf4a8dSllai1 struct sdev_mountargs *sdev_mountargs; 309facf4a8dSllai1 ulong_t sdev_acl_flavor; 310facf4a8dSllai1 }; 311facf4a8dSllai1 312facf4a8dSllai1 #define VFSTOSDEVFS(vfsp) ((struct sdev_data *)((vfsp)->vfs_data)) 313facf4a8dSllai1 314facf4a8dSllai1 /* 315facf4a8dSllai1 * sdev_fid overlays the fid structure (for VFS_VGET) 316facf4a8dSllai1 */ 317facf4a8dSllai1 struct sdev_fid { 318facf4a8dSllai1 uint16_t sdevfid_len; 319facf4a8dSllai1 ino32_t sdevfid_ino; 320facf4a8dSllai1 int32_t sdevfid_gen; 321facf4a8dSllai1 }; 322facf4a8dSllai1 323facf4a8dSllai1 /* 324facf4a8dSllai1 * devfsadm and devname communication defines 325facf4a8dSllai1 */ 326facf4a8dSllai1 typedef enum { 327facf4a8dSllai1 DEVNAME_DEVFSADM_STOPPED = 0, /* devfsadm has never run */ 328facf4a8dSllai1 DEVNAME_DEVFSADM_RUNNING, /* devfsadm is running */ 329facf4a8dSllai1 DEVNAME_DEVFSADM_RUN /* devfsadm ran once */ 330facf4a8dSllai1 } devname_devfsadm_state_t; 331facf4a8dSllai1 332facf4a8dSllai1 extern volatile uint_t devfsadm_state; /* atomic mask for devfsadm status */ 333facf4a8dSllai1 334facf4a8dSllai1 #define DEVNAME_DEVFSADM_SET_RUNNING(devfsadm_state) \ 335*1a7f23d9SRichard Lowe (devfsadm_state = DEVNAME_DEVFSADM_RUNNING) 336facf4a8dSllai1 #define DEVNAME_DEVFSADM_SET_STOP(devfsadm_state) \ 337*1a7f23d9SRichard Lowe (devfsadm_state = DEVNAME_DEVFSADM_STOPPED) 338facf4a8dSllai1 #define DEVNAME_DEVFSADM_SET_RUN(devfsadm_state) \ 339*1a7f23d9SRichard Lowe (devfsadm_state = DEVNAME_DEVFSADM_RUN) 340facf4a8dSllai1 #define DEVNAME_DEVFSADM_IS_RUNNING(devfsadm_state) \ 341*1a7f23d9SRichard Lowe (devfsadm_state == DEVNAME_DEVFSADM_RUNNING) 342facf4a8dSllai1 #define DEVNAME_DEVFSADM_HAS_RUN(devfsadm_state) \ 343facf4a8dSllai1 (devfsadm_state == DEVNAME_DEVFSADM_RUN) 344facf4a8dSllai1 345facf4a8dSllai1 #define SDEV_BLOCK_OTHERS(dv, cmd) { \ 346facf4a8dSllai1 ASSERT(MUTEX_HELD(&dv->sdev_lookup_lock)); \ 347facf4a8dSllai1 dv->sdev_lookup_flags |= cmd; \ 348facf4a8dSllai1 } 349facf4a8dSllai1 extern void sdev_unblock_others(struct sdev_node *, uint_t); 350facf4a8dSllai1 #define SDEV_UNBLOCK_OTHERS(dv, cmd) { \ 351facf4a8dSllai1 sdev_unblock_others(dv, cmd); \ 352facf4a8dSllai1 } 353facf4a8dSllai1 354facf4a8dSllai1 #define SDEV_CLEAR_LOOKUP_FLAGS(dv, cmd) { \ 355facf4a8dSllai1 dv->sdev_lookup_flags &= ~cmd; \ 356facf4a8dSllai1 } 357facf4a8dSllai1 358facf4a8dSllai1 extern int sdev_wait4lookup(struct sdev_node *, int); 3593c5e027bSEric Taylor extern int devname_filename_register(char *); 360facf4a8dSllai1 extern int devname_nsmaps_register(char *, size_t); 361facf4a8dSllai1 extern void sdev_devfsadm_lockinit(void); 362facf4a8dSllai1 extern void sdev_devfsadm_lockdestroy(void); 363facf4a8dSllai1 extern void devname_add_devfsadm_node(char *); 364facf4a8dSllai1 extern void sdev_devfsadmd_thread(struct sdev_node *, struct sdev_node *, 365facf4a8dSllai1 struct cred *); 366facf4a8dSllai1 extern int devname_profile_update(char *, size_t); 367facf4a8dSllai1 extern struct sdev_data *sdev_find_mntinfo(char *); 368facf4a8dSllai1 void sdev_mntinfo_rele(struct sdev_data *); 369facf4a8dSllai1 extern struct vnodeops *devpts_getvnodeops(void); 370aecfc01dSrui zang - Sun Microsystems - Beijing China extern struct vnodeops *devvt_getvnodeops(void); 371facf4a8dSllai1 372facf4a8dSllai1 /* 373facf4a8dSllai1 * boot states - warning, the ordering here is significant 374facf4a8dSllai1 * 375facf4a8dSllai1 * the difference between "system available" and "boot complete" 376facf4a8dSllai1 * is a debounce timeout to catch some daemon issuing a readdir 377facf4a8dSllai1 * triggering a nuisance implict reconfig on each boot. 378facf4a8dSllai1 */ 379facf4a8dSllai1 #define SDEV_BOOT_STATE_INITIAL 0 380facf4a8dSllai1 #define SDEV_BOOT_STATE_RECONFIG 1 /* reconfig */ 381facf4a8dSllai1 #define SDEV_BOOT_STATE_SYSAVAIL 2 /* system available */ 382facf4a8dSllai1 #define SDEV_BOOT_STATE_COMPLETE 3 /* boot complete */ 383facf4a8dSllai1 384facf4a8dSllai1 /* 385facf4a8dSllai1 * Negative cache list and list element 386facf4a8dSllai1 * The mutex protects the flags against multiple accesses and 387facf4a8dSllai1 * must only be acquired when already holding the r/w lock. 388facf4a8dSllai1 */ 389facf4a8dSllai1 typedef struct sdev_nc_list { 390facf4a8dSllai1 list_t ncl_list; /* the list itself */ 391facf4a8dSllai1 kmutex_t ncl_mutex; /* protects ncl_flags */ 392facf4a8dSllai1 krwlock_t ncl_lock; /* protects ncl_list */ 393facf4a8dSllai1 int ncl_flags; 394facf4a8dSllai1 int ncl_nentries; 395facf4a8dSllai1 } sdev_nc_list_t; 396facf4a8dSllai1 397facf4a8dSllai1 typedef struct sdev_nc_node { 398facf4a8dSllai1 char *ncn_name; /* name of the node */ 399facf4a8dSllai1 int ncn_flags; /* state information */ 400facf4a8dSllai1 int ncn_expirecnt; /* remove once expired */ 401facf4a8dSllai1 list_node_t ncn_link; /* link to next in list */ 402facf4a8dSllai1 } sdev_nc_node_t; 403facf4a8dSllai1 404facf4a8dSllai1 /* ncl_flags */ 405facf4a8dSllai1 #define NCL_LIST_DIRTY 0x01 /* needs to be flushed */ 406facf4a8dSllai1 #define NCL_LIST_WRITING 0x02 /* write in progress */ 407facf4a8dSllai1 #define NCL_LIST_WENABLE 0x04 /* write-enabled post boot */ 408facf4a8dSllai1 409facf4a8dSllai1 /* ncn_flags */ 410facf4a8dSllai1 #define NCN_ACTIVE 0x01 /* a lookup has occurred */ 411facf4a8dSllai1 #define NCN_SRC_STORE 0x02 /* src: persistent store */ 412facf4a8dSllai1 #define NCN_SRC_CURRENT 0x04 /* src: current boot */ 413facf4a8dSllai1 414facf4a8dSllai1 /* sdev_lookup_failed flags */ 415facf4a8dSllai1 #define SLF_NO_NCACHE 0x01 /* node should not be added to ncache */ 416facf4a8dSllai1 #define SLF_REBUILT 0x02 /* reconfig performed during lookup attempt */ 417facf4a8dSllai1 418facf4a8dSllai1 /* 41983c4dfe9Sjg * The nvlist name and nvpair identifiers in the 42083c4dfe9Sjg * /etc/devices/devname_cache nvlist format 42183c4dfe9Sjg */ 42283c4dfe9Sjg #define DP_DEVNAME_ID "devname" 42383c4dfe9Sjg #define DP_DEVNAME_NCACHE_ID "ncache" 42483c4dfe9Sjg #define DP_DEVNAME_NC_EXPIRECNT_ID "expire-counts" 42583c4dfe9Sjg 42683c4dfe9Sjg /* devname-cache list element */ 42783c4dfe9Sjg typedef struct nvp_devname { 42883c4dfe9Sjg char **nvp_paths; 42983c4dfe9Sjg int *nvp_expirecnts; 43083c4dfe9Sjg int nvp_npaths; 43183c4dfe9Sjg list_node_t nvp_link; 43283c4dfe9Sjg } nvp_devname_t; 43383c4dfe9Sjg 43483c4dfe9Sjg /* 435facf4a8dSllai1 * name service globals and prototypes 436facf4a8dSllai1 */ 437facf4a8dSllai1 438facf4a8dSllai1 /* 439facf4a8dSllai1 * vnodeops and vfsops helpers 440facf4a8dSllai1 */ 441facf4a8dSllai1 442facf4a8dSllai1 typedef enum { 443facf4a8dSllai1 SDEV_CACHE_ADD = 0, 444facf4a8dSllai1 SDEV_CACHE_DELETE 445facf4a8dSllai1 } sdev_cache_ops_t; 446facf4a8dSllai1 447facf4a8dSllai1 extern struct sdev_node *sdev_cache_lookup(struct sdev_node *, char *); 4489e5aa9d8SRobert Mustacchi extern void sdev_cache_update(struct sdev_node *, struct sdev_node **, char *, 449facf4a8dSllai1 sdev_cache_ops_t); 450facf4a8dSllai1 extern void sdev_node_cache_init(void); 451facf4a8dSllai1 extern void sdev_node_cache_fini(void); 452facf4a8dSllai1 extern struct sdev_node *sdev_mkroot(struct vfs *, dev_t, struct vnode *, 453facf4a8dSllai1 struct vnode *, struct cred *); 4546b938478Sjg extern void sdev_filldir_dynamic(struct sdev_node *); 455facf4a8dSllai1 extern int sdev_mknode(struct sdev_node *, char *, struct sdev_node **, 456facf4a8dSllai1 struct vattr *, struct vnode *, void *, struct cred *, sdev_node_state_t); 457681d9761SEric Taylor extern int sdev_getlink(struct vnode *linkvp, char **link); 458681d9761SEric Taylor 459facf4a8dSllai1 extern int sdev_nodeinit(struct sdev_node *, char *, struct sdev_node **, 460facf4a8dSllai1 vattr_t *); 461facf4a8dSllai1 extern int sdev_nodeready(struct sdev_node *, vattr_t *, vnode_t *, void *, 462facf4a8dSllai1 cred_t *); 463facf4a8dSllai1 extern int sdev_shadow_node(struct sdev_node *, struct cred *); 464facf4a8dSllai1 extern void sdev_nodedestroy(struct sdev_node *, uint_t); 465facf4a8dSllai1 extern void sdev_update_timestamps(struct vnode *, cred_t *, uint_t); 466facf4a8dSllai1 extern void sdev_vattr_merge(struct sdev_node *, struct vattr *); 467facf4a8dSllai1 extern void sdev_devstate_change(void); 468facf4a8dSllai1 extern int sdev_lookup_filter(sdev_node_t *, char *); 469facf4a8dSllai1 extern void sdev_lookup_failed(sdev_node_t *, char *, int); 470facf4a8dSllai1 extern int sdev_unlocked_access(void *, int, struct cred *); 471facf4a8dSllai1 472facf4a8dSllai1 #define SDEV_ENFORCE 0x1 473facf4a8dSllai1 extern void sdev_stale(struct sdev_node *); 474facf4a8dSllai1 extern int sdev_cleandir(struct sdev_node *, char *, uint_t); 475facf4a8dSllai1 extern int sdev_rnmnode(struct sdev_node *, struct sdev_node *, 476facf4a8dSllai1 struct sdev_node *, struct sdev_node **, char *, struct cred *); 477facf4a8dSllai1 extern size_t add_dir_entry(dirent64_t *, char *, size_t, ino_t, offset_t); 478681d9761SEric Taylor extern struct vattr *sdev_getdefault_attr(enum vtype type); 479facf4a8dSllai1 extern int sdev_to_vp(struct sdev_node *, struct vnode **); 480facf4a8dSllai1 extern ino_t sdev_mkino(struct sdev_node *); 481facf4a8dSllai1 extern int devname_backstore_lookup(struct sdev_node *, char *, 482facf4a8dSllai1 struct vnode **); 483facf4a8dSllai1 extern int sdev_is_devfs_node(char *); 484facf4a8dSllai1 extern int sdev_copyin_mountargs(struct mounta *, struct sdev_mountargs *); 485facf4a8dSllai1 extern int sdev_reserve_subdirs(struct sdev_node *); 486facf4a8dSllai1 extern int prof_lookup(); 487facf4a8dSllai1 extern void prof_filldir(struct sdev_node *); 488facf4a8dSllai1 extern int devpts_validate(struct sdev_node *dv); 489d62bc4baSyz147064 extern int devnet_validate(struct sdev_node *dv); 490b127ac41SPhilip Kirk extern int devipnet_validate(struct sdev_node *dv); 491aecfc01dSrui zang - Sun Microsystems - Beijing China extern int devvt_validate(struct sdev_node *dv); 492681d9761SEric Taylor extern int devzvol_validate(struct sdev_node *dv); 493facf4a8dSllai1 extern void *sdev_get_vtor(struct sdev_node *dv); 494facf4a8dSllai1 495facf4a8dSllai1 /* 496681d9761SEric Taylor * devinfo helpers 497681d9761SEric Taylor */ 498681d9761SEric Taylor extern int sdev_modctl_readdir(const char *, char ***, int *, int *, int); 499681d9761SEric Taylor extern void sdev_modctl_readdir_free(char **, int, int); 500681d9761SEric Taylor extern int sdev_modctl_devexists(const char *); 501681d9761SEric Taylor 502681d9761SEric Taylor /* 503facf4a8dSllai1 * ncache handlers 504facf4a8dSllai1 */ 505facf4a8dSllai1 506facf4a8dSllai1 extern void sdev_ncache_init(void); 507facf4a8dSllai1 extern void sdev_ncache_setup(void); 508facf4a8dSllai1 extern void sdev_ncache_teardown(void); 509facf4a8dSllai1 extern void sdev_nc_addname(sdev_nc_list_t *, sdev_node_t *, char *, int); 510facf4a8dSllai1 extern void sdev_nc_node_exists(sdev_node_t *); 511facf4a8dSllai1 extern void sdev_nc_path_exists(sdev_nc_list_t *, char *); 512facf4a8dSllai1 extern void sdev_modctl_dump_files(void); 513facf4a8dSllai1 514facf4a8dSllai1 /* 515facf4a8dSllai1 * globals 516facf4a8dSllai1 */ 5170bfaec69Sllai1 extern kmutex_t sdev_lock; 518facf4a8dSllai1 extern int devtype; 519facf4a8dSllai1 extern kmem_cache_t *sdev_node_cache; 520facf4a8dSllai1 extern struct vnodeops *sdev_vnodeops; 521facf4a8dSllai1 extern struct vnodeops *devpts_vnodeops; 522d62bc4baSyz147064 extern struct vnodeops *devnet_vnodeops; 523b127ac41SPhilip Kirk extern struct vnodeops *devipnet_vnodeops; 524aecfc01dSrui zang - Sun Microsystems - Beijing China extern struct vnodeops *devvt_vnodeops; 525facf4a8dSllai1 extern struct sdev_data *sdev_origins; /* mount info for global /dev instance */ 526681d9761SEric Taylor extern struct vnodeops *devzvol_vnodeops; 527681d9761SEric Taylor 528facf4a8dSllai1 extern const fs_operation_def_t sdev_vnodeops_tbl[]; 529facf4a8dSllai1 extern const fs_operation_def_t devpts_vnodeops_tbl[]; 530d62bc4baSyz147064 extern const fs_operation_def_t devnet_vnodeops_tbl[]; 531b127ac41SPhilip Kirk extern const fs_operation_def_t devipnet_vnodeops_tbl[]; 532aecfc01dSrui zang - Sun Microsystems - Beijing China extern const fs_operation_def_t devvt_vnodeops_tbl[]; 533facf4a8dSllai1 extern const fs_operation_def_t devsys_vnodeops_tbl[]; 534facf4a8dSllai1 extern const fs_operation_def_t devpseudo_vnodeops_tbl[]; 535681d9761SEric Taylor extern const fs_operation_def_t devzvol_vnodeops_tbl[]; 536facf4a8dSllai1 537facf4a8dSllai1 extern sdev_nc_list_t *sdev_ncache; 538facf4a8dSllai1 extern int sdev_reconfig_boot; 539facf4a8dSllai1 extern int sdev_boot_state; 540facf4a8dSllai1 extern int sdev_reconfig_verbose; 541facf4a8dSllai1 extern int sdev_reconfig_disable; 542facf4a8dSllai1 extern int sdev_nc_disable; 543facf4a8dSllai1 extern int sdev_nc_disable_reset; 544facf4a8dSllai1 extern int sdev_nc_verbose; 545facf4a8dSllai1 5460ad555adSAlex Wilson extern taskq_t *sdev_taskq; 5470ad555adSAlex Wilson 548facf4a8dSllai1 /* 549facf4a8dSllai1 * misc. defines 550facf4a8dSllai1 */ 551facf4a8dSllai1 #ifdef DEBUG 552facf4a8dSllai1 extern int sdev_debug; 553facf4a8dSllai1 #define SDEV_DEBUG 0x01 /* error messages to console/log */ 554facf4a8dSllai1 #define SDEV_DEBUG_VOPS 0x02 /* vnode ops errors */ 555facf4a8dSllai1 #define SDEV_DEBUG_DLF 0x04 /* trace devname_lookup_func */ 556facf4a8dSllai1 #define SDEV_DEBUG_DRF 0x08 /* trace devname_readdir_func */ 557facf4a8dSllai1 #define SDEV_DEBUG_NCACHE 0x10 /* negative cache tracing */ 558facf4a8dSllai1 #define SDEV_DEBUG_DEVFSADMD 0x20 /* comm. of devnamefs & devfsadm */ 559facf4a8dSllai1 #define SDEV_DEBUG_PTS 0x40 /* /dev/pts tracing */ 560facf4a8dSllai1 #define SDEV_DEBUG_RECONFIG 0x80 /* events triggering reconfig */ 561facf4a8dSllai1 #define SDEV_DEBUG_SDEV_NODE 0x100 /* trace sdev_node activities */ 562facf4a8dSllai1 #define SDEV_DEBUG_PROFILE 0x200 /* trace sdev_profile */ 563facf4a8dSllai1 #define SDEV_DEBUG_MODCTL 0x400 /* trace modctl activity */ 564facf4a8dSllai1 #define SDEV_DEBUG_FLK 0x800 /* trace failed lookups */ 565d62bc4baSyz147064 #define SDEV_DEBUG_NET 0x1000 /* /dev/net tracing */ 566681d9761SEric Taylor #define SDEV_DEBUG_ZVOL 0x2000 /* /dev/zvol/tracing */ 567facf4a8dSllai1 568facf4a8dSllai1 #define sdcmn_err(args) if (sdev_debug & SDEV_DEBUG) printf args 569facf4a8dSllai1 #define sdcmn_err2(args) if (sdev_debug & SDEV_DEBUG_VOPS) printf args 570facf4a8dSllai1 #define sdcmn_err3(args) if (sdev_debug & SDEV_DEBUG_DLF) printf args 571facf4a8dSllai1 #define sdcmn_err4(args) if (sdev_debug & SDEV_DEBUG_DRF) printf args 572facf4a8dSllai1 #define sdcmn_err5(args) if (sdev_debug & SDEV_DEBUG_NCACHE) printf args 573facf4a8dSllai1 #define sdcmn_err6(args) if (sdev_debug & SDEV_DEBUG_DEVFSADMD) printf args 574facf4a8dSllai1 #define sdcmn_err7(args) if (sdev_debug & SDEV_DEBUG_PTS) printf args 575facf4a8dSllai1 #define sdcmn_err8(args) if (sdev_debug & SDEV_DEBUG_RECONFIG) printf args 576facf4a8dSllai1 #define sdcmn_err9(args) if (sdev_debug & SDEV_DEBUG_SDEV_NODE) printf args 577facf4a8dSllai1 #define sdcmn_err10(args) if (sdev_debug & SDEV_DEBUG_PROFILE) printf args 578facf4a8dSllai1 #define sdcmn_err11(args) if (sdev_debug & SDEV_DEBUG_MODCTL) printf args 579d62bc4baSyz147064 #define sdcmn_err12(args) if (sdev_debug & SDEV_DEBUG_NET) printf args 580681d9761SEric Taylor #define sdcmn_err13(args) if (sdev_debug & SDEV_DEBUG_ZVOL) printf args 581facf4a8dSllai1 #define impossible(args) printf args 582facf4a8dSllai1 #else 583facf4a8dSllai1 #define sdcmn_err(args) /* does nothing */ 584facf4a8dSllai1 #define sdcmn_err2(args) /* does nothing */ 585facf4a8dSllai1 #define sdcmn_err3(args) /* does nothing */ 586facf4a8dSllai1 #define sdcmn_err4(args) /* does nothing */ 587facf4a8dSllai1 #define sdcmn_err5(args) /* does nothing */ 588facf4a8dSllai1 #define sdcmn_err6(args) /* does nothing */ 589facf4a8dSllai1 #define sdcmn_err7(args) /* does nothing */ 590facf4a8dSllai1 #define sdcmn_err8(args) /* does nothing */ 591facf4a8dSllai1 #define sdcmn_err9(args) /* does nothing */ 592facf4a8dSllai1 #define sdcmn_err10(args) /* does nothing */ 593facf4a8dSllai1 #define sdcmn_err11(args) /* does nothing */ 594d62bc4baSyz147064 #define sdcmn_err12(args) /* does nothing */ 595681d9761SEric Taylor #define sdcmn_err13(args) /* does nothing */ 596facf4a8dSllai1 #define impossible(args) /* does nothing */ 597facf4a8dSllai1 #endif 598facf4a8dSllai1 599facf4a8dSllai1 #ifdef DEBUG 600facf4a8dSllai1 #define SD_TRACE_FAILED_LOOKUP(ddv, nm, retried) \ 601facf4a8dSllai1 if ((sdev_debug & SDEV_DEBUG_FLK) || \ 602facf4a8dSllai1 ((retried) && (sdev_debug & SDEV_DEBUG_RECONFIG))) { \ 603facf4a8dSllai1 printf("lookup of %s/%s by %s failed, line %d\n", \ 604facf4a8dSllai1 (ddv)->sdev_name, (nm), curproc->p_user.u_comm, \ 605facf4a8dSllai1 __LINE__); \ 606facf4a8dSllai1 } 607facf4a8dSllai1 #else 608facf4a8dSllai1 #define SD_TRACE_FAILED_LOOKUP(ddv, nm, retried) 609facf4a8dSllai1 #endif 610facf4a8dSllai1 611facf4a8dSllai1 #endif /* _KERNEL */ 612facf4a8dSllai1 613facf4a8dSllai1 #ifdef __cplusplus 614facf4a8dSllai1 } 615facf4a8dSllai1 #endif 616facf4a8dSllai1 617facf4a8dSllai1 #endif /* _SYS_SDEV_IMPL_H */ 618