Home | History | Annotate | Download | only in devfsadm
      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 /*
     23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*
     28  * Devfsadm replaces drvconfig, audlinks, disks, tapes, ports, devlinks
     29  * as a general purpose device administrative utility.	It creates
     30  * devices special files in /devices and logical links in /dev, and
     31  * coordinates updates to /etc/path_to_instance with the kernel.  It
     32  * operates in both command line mode to handle user or script invoked
     33  * reconfiguration updates, and operates in daemon mode to handle dynamic
     34  * reconfiguration for hotplugging support.
     35  */
     36 
     37 #include <string.h>
     38 #include <deflt.h>
     39 #include <tsol/label.h>
     40 #include <bsm/devices.h>
     41 #include <bsm/devalloc.h>
     42 #include <utime.h>
     43 #include <sys/param.h>
     44 #include <bsm/libbsm.h>
     45 #include "devfsadm_impl.h"
     46 
     47 /* externs from devalloc.c */
     48 extern void  _reset_devalloc(int);
     49 extern void _update_devalloc_db(devlist_t *, int, int, char *, char *);
     50 extern int _da_check_for_usb(char *, char *);
     51 
     52 /* create or remove nodes or links. unset with -n */
     53 static int file_mods = TRUE;
     54 
     55 /* cleanup mode.  Set with -C */
     56 static int cleanup = FALSE;
     57 
     58 /* devlinks -d compatibility */
     59 static int devlinks_debug = FALSE;
     60 
     61 /* flag to check if system is labeled */
     62 int system_labeled = FALSE;
     63 
     64 /* flag to enable/disable device allocation with -e/-d */
     65 static int devalloc_flag = 0;
     66 
     67 /* flag that indicates if device allocation is on or not */
     68 static int devalloc_is_on = 0;
     69 
     70 /* flag to update device allocation database for this device type */
     71 static int update_devdb = 0;
     72 
     73 /*
     74  * devices to be deallocated with -d :
     75  *	audio, floppy, cd, floppy, tape, rmdisk.
     76  */
     77 static char *devalloc_list[10] = {DDI_NT_AUDIO, DDI_NT_CD, DDI_NT_CD_CHAN,
     78 				    DDI_NT_FD, DDI_NT_TAPE, DDI_NT_BLOCK_CHAN,
     79 				    DDI_NT_UGEN, DDI_NT_USB_ATTACHMENT_POINT,
     80 				    DDI_NT_SCSI_NEXUS, NULL};
     81 
     82 /* list of allocatable devices */
     83 static devlist_t devlist;
     84 
     85 /* load a single driver only.  set with -i */
     86 static int single_drv = FALSE;
     87 static char *driver = NULL;
     88 
     89 /* attempt to load drivers or defer attach nodes */
     90 static int load_attach_drv = TRUE;
     91 
     92 /* set if invoked via /usr/lib/devfsadm/devfsadmd */
     93 static int daemon_mode = FALSE;
     94 
     95 /* output directed to syslog during daemon mode if set */
     96 static int logflag = FALSE;
     97 
     98 /* build links in /dev.  -x to turn off */
     99 static int build_dev = TRUE;
    100 
    101 /* build nodes in /devices.  -y to turn off */
    102 static int build_devices = TRUE;
    103 
    104 /* -z to turn off */
    105 static int flush_path_to_inst_enable = TRUE;
    106 
    107 /* variables used for path_to_inst flushing */
    108 static int inst_count = 0;
    109 static mutex_t count_lock;
    110 static cond_t cv;
    111 
    112 /* variables for minor_fini thread */
    113 static mutex_t minor_fini_mutex;
    114 static int minor_fini_canceled = TRUE;
    115 static int minor_fini_delayed = FALSE;
    116 static cond_t minor_fini_cv;
    117 static int minor_fini_timeout = MINOR_FINI_TIMEOUT_DEFAULT;
    118 
    119 /* single-threads /dev modification */
    120 static sema_t dev_sema;
    121 
    122 /* the program we were invoked as; ie argv[0] */
    123 static char *prog;
    124 
    125 /* pointers to create/remove link lists */
    126 static create_list_t *create_head = NULL;
    127 static remove_list_t *remove_head = NULL;
    128 
    129 /*  supports the class -c option */
    130 static char **classes = NULL;
    131 static int num_classes = 0;
    132 
    133 /* used with verbose option -v or -V */
    134 static int num_verbose = 0;
    135 static char **verbose = NULL;
    136 
    137 static struct mperm *minor_perms = NULL;
    138 static driver_alias_t *driver_aliases = NULL;
    139 
    140 /* set if -r alternate root given */
    141 static char *root_dir = "";
    142 
    143 /* /devices or <rootdir>/devices */
    144 static char *devices_dir  = DEVICES;
    145 
    146 /* /dev or <rootdir>/dev */
    147 static char *dev_dir = DEV;
    148 
    149 /* /etc/dev or <rootdir>/etc/dev */
    150 static char *etc_dev_dir = ETCDEV;
    151 
    152 /*
    153  * writable root (for lock files and doors during install).
    154  * This is also root dir for /dev attr dir during install.
    155  */
    156 static char *attr_root = NULL;
    157 
    158 /* /etc/path_to_inst unless -p used */
    159 static char *inst_file = INSTANCE_FILE;
    160 
    161 /* /usr/lib/devfsadm/linkmods unless -l used */
    162 static char *module_dirs = MODULE_DIRS;
    163 
    164 /* default uid/gid used if /etc/minor_perm entry not found */
    165 static uid_t root_uid;
    166 static gid_t sys_gid;
    167 
    168 /* /etc/devlink.tab unless devlinks -t used */
    169 static char *devlinktab_file = NULL;
    170 
    171 /* File and data structure to reserve enumerate IDs */
    172 static char *enumerate_file = ENUMERATE_RESERVED;
    173 static enumerate_file_t *enumerate_reserved = NULL;
    174 
    175 /* set if /dev link is new. speeds up rm_stale_links */
    176 static int linknew = TRUE;
    177 
    178 /* variables for devlink.tab compat processing */
    179 static devlinktab_list_t *devlinktab_list = NULL;
    180 static unsigned int devlinktab_line = 0;
    181 
    182 /* cache head for devfsadm_enumerate*() functions */
    183 static numeral_set_t *head_numeral_set = NULL;
    184 
    185 /* list list of devfsadm modules */
    186 static module_t *module_head = NULL;
    187 
    188 /* name_to_major list used in utility function */
    189 static n2m_t *n2m_list = NULL;
    190 
    191 /* cache of some links used for performance */
    192 static linkhead_t *headlinkhead = NULL;
    193 
    194 /* locking variables to prevent multiples writes to /dev */
    195 static int hold_dev_lock = FALSE;
    196 static int hold_daemon_lock = FALSE;
    197 static int dev_lock_fd;
    198 static int daemon_lock_fd;
    199 static char dev_lockfile[PATH_MAX + 1];
    200 static char daemon_lockfile[PATH_MAX + 1];
    201 
    202 /* last devinfo node/minor processed. used for performance */
    203 static di_node_t lnode;
    204 static di_minor_t lminor;
    205 static char lphy_path[PATH_MAX + 1] = {""};
    206 
    207 /* Globals used by the link database */
    208 static di_devlink_handle_t devlink_cache;
    209 static int update_database = FALSE;
    210 
    211 /* Globals used to set logindev perms */
    212 static struct login_dev *login_dev_cache = NULL;
    213 static int login_dev_enable = FALSE;
    214 
    215 /* Global to use devinfo snapshot cache */
    216 static int use_snapshot_cache = FALSE;
    217 
    218 /* Global for no-further-processing hash */
    219 static item_t **nfp_hash;
    220 static mutex_t  nfp_mutex = DEFAULTMUTEX;
    221 
    222 /*
    223  * Packaged directories - not removed even when empty.
    224  * The dirs must be listed in canonical form
    225  * i.e. without leading "/dev/"
    226  */
    227 static char *packaged_dirs[] =
    228 	{"dsk", "rdsk", "term", NULL};
    229 
    230 /* Devname globals */
    231 static int devname_debug_msg = 1;
    232 static nvlist_t *devname_maps = NULL;
    233 static int devname_first_call = 1;
    234 static int load_devname_nsmaps = FALSE;
    235 static int lookup_door_fd = -1;
    236 static char *lookup_door_path;
    237 
    238 static void load_dev_acl(void);
    239 static void update_drvconf(major_t);
    240 static void check_reconfig_state(void);
    241 static void devname_setup_nsmaps(void);
    242 static int s_stat(const char *, struct stat *);
    243 
    244 static int is_blank(char *);
    245 
    246 /* sysevent queue related globals */
    247 static mutex_t  syseventq_mutex = DEFAULTMUTEX;
    248 static syseventq_t *syseventq_front;
    249 static syseventq_t *syseventq_back;
    250 static void process_syseventq();
    251 
    252 int
    253 main(int argc, char *argv[])
    254 {
    255 	struct passwd *pw;
    256 	struct group *gp;
    257 	pid_t pid;
    258 	int cond = 0;
    259 
    260 	(void) setlocale(LC_ALL, "");
    261 	(void) textdomain(TEXT_DOMAIN);
    262 
    263 	if ((prog = strrchr(argv[0], '/')) == NULL) {
    264 		prog = argv[0];
    265 	} else {
    266 		prog++;
    267 	}
    268 
    269 	if (getuid() != 0) {
    270 		err_print(MUST_BE_ROOT);
    271 		devfsadm_exit(1);
    272 		/*NOTREACHED*/
    273 	}
    274 
    275 	/*
    276 	 * Close all files except stdin/stdout/stderr
    277 	 */
    278 	closefrom(3);
    279 
    280 	if ((pw = getpwnam(DEFAULT_DEV_USER)) != NULL) {
    281 		root_uid = pw->pw_uid;
    282 	} else {
    283 		err_print(CANT_FIND_USER, DEFAULT_DEV_USER);
    284 		root_uid = (uid_t)0;	/* assume 0 is root */
    285 	}
    286 
    287 	/* the default group is sys */
    288 
    289 	if ((gp = getgrnam(DEFAULT_DEV_GROUP)) != NULL) {
    290 		sys_gid = gp->gr_gid;
    291 	} else {
    292 		err_print(CANT_FIND_GROUP, DEFAULT_DEV_GROUP);
    293 		sys_gid = (gid_t)3;	/* assume 3 is sys */
    294 	}
    295 
    296 	(void) umask(0);
    297 
    298 	system_labeled = is_system_labeled();
    299 	if (system_labeled == FALSE) {
    300 		/*
    301 		 * is_system_labeled() will return false in case we are
    302 		 * starting before the first reboot after Trusted Extensions
    303 		 * is enabled.  Check the setting in /etc/system to see if
    304 		 * TX is enabled (even if not yet booted).
    305 		 */
    306 		if (defopen("/etc/system") == 0) {
    307 			if (defread("set sys_labeling=1") != NULL)
    308 				system_labeled = TRUE;
    309 
    310 			/* close defaults file */
    311 			(void) defopen(NULL);
    312 		}
    313 	}
    314 	/*
    315 	 * Check if device allocation is enabled.
    316 	 */
    317 	if (system_labeled) {
    318 		/*
    319 		 * In TX, the first line in /etc/security/device_allocate has
    320 		 * DEVICE_ALLOCATION=ON if the feature is enabled.
    321 		 */
    322 		devalloc_is_on = da_is_on();
    323 	} else if (auditon(A_GETCOND, (caddr_t)&cond, sizeof (cond)) == 0) {
    324 		/*
    325 		 * Device allocation (and auditing) is enabled if BSM is
    326 		 * enabled. auditon returns -1 and sets errno to EINVAL if BSM
    327 		 * is not enabled.
    328 		 */
    329 		devalloc_is_on = 1;
    330 	}
    331 
    332 #ifdef DEBUG
    333 	if (system_labeled == FALSE) {
    334 		struct stat tx_stat;
    335 
    336 		/* test hook: see also mkdevalloc.c and allocate.c */
    337 		system_labeled = is_system_labeled_debug(&tx_stat);
    338 	}
    339 #endif
    340 
    341 	parse_args(argc, argv);
    342 
    343 	(void) sema_init(&dev_sema, 1, USYNC_THREAD, NULL);
    344 
    345 	/* Initialize device allocation list */
    346 	devlist.audio = devlist.cd = devlist.floppy = devlist.tape =
    347 	    devlist.rmdisk = NULL;
    348 
    349 	if (daemon_mode == TRUE) {
    350 		/*
    351 		 * Build /dev and /devices before daemonizing if
    352 		 * reconfig booting and daemon invoked with alternate
    353 		 * root. This is to support install.
    354 		 */
    355 		if (getenv(RECONFIG_BOOT) != NULL && root_dir[0] != '\0') {
    356 			vprint(INFO_MID, CONFIGURING);
    357 			load_dev_acl();
    358 			update_drvconf((major_t)-1);
    359 			process_devinfo_tree();
    360 			(void) modctl(MODSETMINIROOT);
    361 		}
    362 
    363 		/*
    364 		 * fork before detaching from tty in order to print error
    365 		 * message if unable to acquire file lock.  locks not preserved
    366 		 * across forks.  Even under debug we want to fork so that
    367 		 * when executed at boot we don't hang.
    368 		 */
    369 		if (fork() != 0) {
    370 			devfsadm_exit(0);
    371 			/*NOTREACHED*/
    372 		}
    373 
    374 		/* set directory to / so it coredumps there */
    375 		if (chdir("/") == -1) {
    376 			err_print(CHROOT_FAILED, strerror(errno));
    377 		}
    378 
    379 		/* only one daemon can run at a time */
    380 		if ((pid = enter_daemon_lock()) == getpid()) {
    381 			detachfromtty();
    382 			(void) cond_init(&cv, USYNC_THREAD, 0);
    383 			(void) mutex_init(&count_lock, USYNC_THREAD, 0);
    384 			if (thr_create(NULL, NULL,
    385 			    (void *(*)(void *))instance_flush_thread,
    386 			    NULL, THR_DETACHED, NULL) != 0) {
    387 				err_print(CANT_CREATE_THREAD, "daemon",
    388 				    strerror(errno));
    389 				devfsadm_exit(1);
    390 				/*NOTREACHED*/
    391 			}
    392 
    393 			/* start the minor_fini_thread */
    394 			(void) mutex_init(&minor_fini_mutex, USYNC_THREAD, 0);
    395 			(void) cond_init(&minor_fini_cv, USYNC_THREAD, 0);
    396 			if (thr_create(NULL, NULL,
    397 			    (void *(*)(void *))minor_fini_thread,
    398 			    NULL, THR_DETACHED, NULL)) {
    399 				err_print(CANT_CREATE_THREAD, "minor_fini",
    400 				    strerror(errno));
    401 				devfsadm_exit(1);
    402 				/*NOTREACHED*/
    403 			}
    404 
    405 
    406 			/*
    407 			 * logindevperms need only be set
    408 			 * in daemon mode and when root dir is "/".
    409 			 */
    410 			if (root_dir[0] == '\0')
    411 				login_dev_enable = TRUE;
    412 			daemon_update();
    413 			devfsadm_exit(0);
    414 			/*NOTREACHED*/
    415 		} else {
    416 			err_print(DAEMON_RUNNING, pid);
    417 			devfsadm_exit(1);
    418 			/*NOTREACHED*/
    419 		}
    420 	} else {
    421 		/* not a daemon, so just build /dev and /devices */
    422 
    423 		/*
    424 		 * If turning off device allocation, load the
    425 		 * minor_perm file because process_devinfo_tree() will
    426 		 * need this in order to reset the permissions of the
    427 		 * device files.
    428 		 */
    429 		if (devalloc_flag == DA_OFF) {
    430 			read_minor_perm_file();
    431 		}
    432 
    433 		process_devinfo_tree();
    434 		if (devalloc_flag != 0)
    435 			/* Enable/disable device allocation */
    436 			_reset_devalloc(devalloc_flag);
    437 	}
    438 	return (0);
    439 }
    440 
    441 static void
    442 update_drvconf(major_t major)
    443 {
    444 	if (modctl(MODLOADDRVCONF, major) != 0)
    445 		err_print(gettext("update_drvconf failed for major %d\n"),
    446 		    major);
    447 }
    448 
    449 
    450 static void
    451 load_dev_acl()
    452 {
    453 	if (load_devpolicy() != 0)
    454 		err_print(gettext("device policy load failed\n"));
    455 	load_minor_perm_file();
    456 }
    457 
    458 /*
    459  * As devfsadm is run early in boot to provide the kernel with
    460  * minor_perm info, we might as well check for reconfig at the
    461  * same time to avoid running devfsadm twice.  This gets invoked
    462  * earlier than the env variable RECONFIG_BOOT is set up.
    463  */
    464 static void
    465 check_reconfig_state()
    466 {
    467 	struct stat sb;
    468 
    469 	if (s_stat("/reconfigure", &sb) == 0) {
    470 		(void) modctl(MODDEVNAME, MODDEVNAME_RECONFIG, 0);
    471 	}
    472 }
    473 
    474 static void
    475 modctl_sysavail()
    476 {
    477 	/*
    478 	 * Inform /dev that system is available, that
    479 	 * implicit reconfig can now be performed.
    480 	 */
    481 	(void) modctl(MODDEVNAME, MODDEVNAME_SYSAVAIL, 0);
    482 }
    483 
    484 static void
    485 set_lock_root(void)
    486 {
    487 	struct stat sb;
    488 	char *lock_root;
    489 	size_t len;
    490 
    491 	lock_root = attr_root ? attr_root : root_dir;
    492 
    493 	len = strlen(lock_root) + strlen(ETCDEV) + 1;
    494 	etc_dev_dir = s_malloc(len);
    495 	(void) snprintf(etc_dev_dir, len, "%s%s", lock_root, ETCDEV);
    496 
    497 	if (s_stat(etc_dev_dir, &sb) != 0) {
    498 		s_mkdirp(etc_dev_dir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
    499 	} else if (!S_ISDIR(sb.st_mode)) {
    500 		err_print(NOT_DIR, etc_dev_dir);
    501 		devfsadm_exit(1);
    502 		/*NOTREACHED*/
    503 	}
    504 }
    505 
    506 
    507 /*
    508  * Parse arguments for all 6 programs handled from devfsadm.
    509  */
    510 static void
    511 parse_args(int argc, char *argv[])
    512 {
    513 	char opt;
    514 	char get_linkcompat_opts = FALSE;
    515 	char *compat_class;
    516 	int num_aliases = 0;
    517 	int len;
    518 	int retval;
    519 	int add_bind = FALSE;
    520 	struct aliases *ap = NULL;
    521 	struct aliases *a_head = NULL;
    522 	struct aliases *a_tail = NULL;
    523 	struct modconfig mc;
    524 
    525 	if (strcmp(prog, DISKS) == 0) {
    526 		compat_class = "disk";
    527 		get_linkcompat_opts = TRUE;
    528 
    529 	} else if (strcmp(prog, TAPES) == 0) {
    530 		compat_class = "tape";
    531 		get_linkcompat_opts = TRUE;
    532 
    533 	} else if (strcmp(prog, PORTS) == 0) {
    534 		compat_class = "port";
    535 		get_linkcompat_opts = TRUE;
    536 
    537 	} else if (strcmp(prog, AUDLINKS) == 0) {
    538 		compat_class = "audio";
    539 		get_linkcompat_opts = TRUE;
    540 
    541 	} else if (strcmp(prog, DEVLINKS) == 0) {
    542 		devlinktab_file = DEVLINKTAB_FILE;
    543 
    544 		build_devices = FALSE;
    545 		load_attach_drv = FALSE;
    546 
    547 		while ((opt = getopt(argc, argv, "dnr:st:vV:")) != EOF) {
    548 			switch (opt) {
    549 			case 'd':
    550 				file_mods = FALSE;
    551 				flush_path_to_inst_enable = FALSE;
    552 				devlinks_debug = TRUE;
    553 				break;
    554 			case 'n':
    555 				/* prevent driver loading and deferred attach */
    556 				load_attach_drv = FALSE;
    557 				break;
    558 			case 'r':
    559 				set_root_devices_dev_dir(optarg);
    560 				if (zone_pathcheck(root_dir) !=
    561 				    DEVFSADM_SUCCESS)
    562 					devfsadm_exit(1);
    563 					/*NOTREACHED*/
    564 				break;
    565 			case 's':
    566 				/*
    567 				 * suppress.  don't create/remove links/nodes
    568 				 * useful with -v or -V
    569 				 */
    570 				file_mods = FALSE;
    571 				flush_path_to_inst_enable = FALSE;
    572 				break;
    573 			case 't':
    574 				/* supply a non-default table file */
    575 				devlinktab_file = optarg;
    576 				break;
    577 			case 'v':
    578 				/* documented verbose flag */
    579 				add_verbose_id(VERBOSE_MID);
    580 				break;
    581 			case 'V':
    582 				/* undocumented for extra verbose levels */
    583 				add_verbose_id(optarg);
    584 				break;
    585 			default:
    586 				usage();
    587 				break;
    588 			}
    589 		}
    590 
    591 		if (optind < argc) {
    592 			usage();
    593 		}
    594 
    595 	} else if (strcmp(prog, DRVCONFIG) == 0) {
    596 		build_dev = FALSE;
    597 
    598 		while ((opt =
    599 		    getopt(argc, argv, "a:bdc:i:m:np:R:r:svV:")) != EOF) {
    600 			switch (opt) {
    601 			case 'a':
    602 				ap = calloc(sizeof (struct aliases), 1);
    603 				ap->a_name = dequote(optarg);
    604 				len = strlen(ap->a_name) + 1;
    605 				if (len > MAXMODCONFNAME) {
    606 					err_print(ALIAS_TOO_LONG,
    607 					    MAXMODCONFNAME, ap->a_name);
    608 					devfsadm_exit(1);
    609 					/*NOTREACHED*/
    610 				}
    611 				ap->a_len = len;
    612 				if (a_tail == NULL) {
    613 					a_head = ap;
    614 				} else {
    615 					a_tail->a_next = ap;
    616 				}
    617 				a_tail = ap;
    618 				num_aliases++;
    619 				add_bind = TRUE;
    620 				break;
    621 			case 'b':
    622 				add_bind = TRUE;
    623 				break;
    624 			case 'c':
    625 				(void) strcpy(mc.drvclass, optarg);
    626 				break;
    627 			case 'd':
    628 				/*
    629 				 * need to keep for compatibility, but
    630 				 * do nothing.
    631 				 */
    632 				break;
    633 			case 'i':
    634 				single_drv = TRUE;
    635 				(void) strcpy(mc.drvname, optarg);
    636 				driver = s_strdup(optarg);
    637 				break;
    638 			case 'm':
    639 				mc.major = atoi(optarg);
    640 				break;
    641 			case 'n':
    642 				/* prevent driver loading and deferred attach */
    643 				load_attach_drv = FALSE;
    644 				break;
    645 			case 'p':
    646 				/* specify alternate path_to_inst file */
    647 				inst_file = s_strdup(optarg);
    648 				break;
    649 			case 'R':
    650 				/*
    651 				 * Private flag for suninstall to populate
    652 				 * device information on the installed root.
    653 				 */
    654 				root_dir = s_strdup(optarg);
    655 				if (zone_pathcheck(root_dir) !=
    656 				    DEVFSADM_SUCCESS)
    657 				devfsadm_exit(devfsadm_copy());
    658 				/*NOTREACHED*/
    659 				break;
    660 			case 'r':
    661 				devices_dir = s_strdup(optarg);
    662 				if (zone_pathcheck(devices_dir) !=
    663 				    DEVFSADM_SUCCESS)
    664 					devfsadm_exit(1);
    665 					/*NOTREACHED*/
    666 				break;
    667 			case 's':
    668 				/*
    669 				 * suppress.  don't create nodes
    670 				 * useful with -v or -V
    671 				 */
    672 				file_mods = FALSE;
    673 				flush_path_to_inst_enable = FALSE;
    674 				break;
    675 			case 'v':
    676 				/* documented verbose flag */
    677 				add_verbose_id(VERBOSE_MID);
    678 				break;
    679 			case 'V':
    680 				/* undocumented for extra verbose levels */
    681 				add_verbose_id(optarg);
    682 				break;
    683 			default:
    684 				usage();
    685 			}
    686 		}
    687 
    688 		if (optind < argc) {
    689 			usage();
    690 		}
    691 
    692 		if ((add_bind == TRUE) && (mc.major == -1 ||
    693 		    mc.drvname[0] == NULL)) {
    694 			err_print(MAJOR_AND_B_FLAG);
    695 			devfsadm_exit(1);
    696 			/*NOTREACHED*/
    697 		}
    698 		if (add_bind == TRUE) {
    699 			mc.num_aliases = num_aliases;
    700 			mc.ap = a_head;
    701 			retval =  modctl(MODADDMAJBIND, NULL, (caddr_t)&mc);
    702 			if (retval < 0) {
    703 				err_print(MODCTL_ADDMAJBIND);
    704 			}
    705 			devfsadm_exit(retval);
    706 			/*NOTREACHED*/
    707 		}
    708 
    709 	} else if ((strcmp(prog, DEVFSADM) == 0) ||
    710 	    (strcmp(prog, DEVFSADMD) == 0)) {
    711 		char *zonename = NULL;
    712 		int init_drvconf = 0;
    713 		int init_perm = 0;
    714 		int public_mode = 0;
    715 		int init_sysavail = 0;
    716 
    717 		if (strcmp(prog, DEVFSADMD) == 0) {
    718 			daemon_mode = TRUE;
    719 		}
    720 
    721 		devlinktab_file = DEVLINKTAB_FILE;
    722 
    723 		while ((opt = getopt(argc, argv,
    724 		    "a:Cc:deIi:l:mnp:PR:r:sSt:vV:x:")) != EOF) {
    725 			if (opt == 'I' || opt == 'P' || opt == 'S') {
    726 				if (public_mode)
    727 					usage();
    728 			} else {
    729 				if (init_perm || init_drvconf || init_sysavail)
    730 					usage();
    731 				public_mode = 1;
    732 			}
    733 			switch (opt) {
    734 			case 'a':
    735 				attr_root = s_strdup(optarg);
    736 				break;
    737 			case 'C':
    738 				cleanup = TRUE;
    739 				break;
    740 			case 'c':
    741 				num_classes++;
    742 				classes = s_realloc(classes,
    743 				    num_classes * sizeof (char *));
    744 				classes[num_classes - 1] = optarg;
    745 				break;
    746 			case 'd':
    747 				if (daemon_mode == FALSE) {
    748 					/*
    749 					 * Device allocation to be disabled.
    750 					 */
    751 					devalloc_flag = DA_OFF;
    752 					build_dev = FALSE;
    753 				}
    754 				break;
    755 			case 'e':
    756 				if (daemon_mode == FALSE) {
    757 					/*
    758 					 * Device allocation to be enabled.
    759 					 */
    760 					devalloc_flag = DA_ON;
    761 					build_dev = FALSE;
    762 				}
    763 				break;
    764 			case 'I':	/* update kernel driver.conf cache */
    765 				if (daemon_mode == TRUE)
    766 					usage();
    767 				init_drvconf = 1;
    768 				break;
    769 			case 'i':
    770 				single_drv = TRUE;
    771 				driver = s_strdup(optarg);
    772 				break;
    773 			case 'l':
    774 				/* specify an alternate module load path */
    775 				module_dirs = s_strdup(optarg);
    776 				break;
    777 			case 'm':
    778 				load_devname_nsmaps = TRUE;
    779 				break;
    780 			case 'n':
    781 				/* prevent driver loading and deferred attach */
    782 				load_attach_drv = FALSE;
    783 				break;
    784 			case 'p':
    785 				/* specify alternate path_to_inst file */
    786 				inst_file = s_strdup(optarg);
    787 				break;
    788 			case 'P':
    789 				if (daemon_mode == TRUE)
    790 					usage();
    791 				/* load minor_perm and device_policy */
    792 				init_perm = 1;
    793 				break;
    794 			case 'R':
    795 				/*
    796 				 * Private flag for suninstall to populate
    797 				 * device information on the installed root.
    798 				 */
    799 				root_dir = s_strdup(optarg);
    800 				devfsadm_exit(devfsadm_copy());
    801 				/*NOTREACHED*/
    802 				break;
    803 			case 'r':
    804 				set_root_devices_dev_dir(optarg);
    805 				break;
    806 			case 's':
    807 				/*
    808 				 * suppress. don't create/remove links/nodes
    809 				 * useful with -v or -V
    810 				 */
    811 				file_mods = FALSE;
    812 				flush_path_to_inst_enable = FALSE;
    813 				break;
    814 			case 'S':
    815 				if (daemon_mode == TRUE)
    816 					usage();
    817 				init_sysavail = 1;
    818 				break;
    819 			case 't':
    820 				devlinktab_file = optarg;
    821 				break;
    822 			case 'v':
    823 				/* documented verbose flag */
    824 				add_verbose_id(VERBOSE_MID);
    825 				break;
    826 			case 'V':
    827 				/* undocumented: specify verbose lvl */
    828 				add_verbose_id(optarg);
    829 				break;
    830 			case 'x':
    831 				/*
    832 				 * x is the "private switch" option.  The
    833 				 * goal is to not suck up all the other
    834 				 * option letters.
    835 				 */
    836 				if (strcmp(optarg, "update_devlinksdb") == 0) {
    837 					update_database = TRUE;
    838 				} else if (strcmp(optarg, "no_dev") == 0) {
    839 					/* don't build /dev */
    840 					build_dev = FALSE;
    841 				} else if (strcmp(optarg, "no_devices") == 0) {
    842 					/* don't build /devices */
    843 					build_devices = FALSE;
    844 				} else if (strcmp(optarg, "no_p2i") == 0) {
    845 					/* don't flush path_to_inst */
    846 					flush_path_to_inst_enable = FALSE;
    847 				} else if (strcmp(optarg, "use_dicache") == 0) {
    848 					use_snapshot_cache = TRUE;
    849 				} else {
    850 					usage();
    851 				}
    852 				break;
    853 			default:
    854 				usage();
    855 				break;
    856 			}
    857 		}
    858 		if (optind < argc) {
    859 			usage();
    860 		}
    861 
    862 		/*
    863 		 * We're not in zone mode; Check to see if the rootpath
    864 		 * collides with any zonepaths.
    865 		 */
    866 		if (zonename == NULL) {
    867 			if (zone_pathcheck(root_dir) != DEVFSADM_SUCCESS)
    868 				devfsadm_exit(1);
    869 				/*NOTREACHED*/
    870 		}
    871 
    872 		if (init_drvconf || init_perm || init_sysavail) {
    873 			/*
    874 			 * Load minor perm before force-loading drivers
    875 			 * so the correct permissions are picked up.
    876 			 */
    877 			if (init_perm) {
    878 				check_reconfig_state();
    879 				load_dev_acl();
    880 			}
    881 			if (init_drvconf)
    882 				update_drvconf((major_t)-1);
    883 			if (init_sysavail)
    884 				modctl_sysavail();
    885 			devfsadm_exit(0);
    886 			/*NOTREACHED*/
    887 		}
    888 
    889 		if (load_devname_nsmaps == TRUE) {
    890 			devname_setup_nsmaps();
    891 			devfsadm_exit(0);
    892 			/*NOTREACHED*/
    893 		}
    894 	}
    895 
    896 
    897 	if (get_linkcompat_opts == TRUE) {
    898 
    899 		build_devices = FALSE;
    900 		load_attach_drv = FALSE;
    901 		num_classes++;
    902 		classes = s_realloc(classes, num_classes *
    903 		    sizeof (char *));
    904 		classes[num_classes - 1] = compat_class;
    905 
    906 		while ((opt = getopt(argc, argv, "Cnr:svV:")) != EOF) {
    907 			switch (opt) {
    908 			case 'C':
    909 				cleanup = TRUE;
    910 				break;
    911 			case 'n':
    912 				/* prevent driver loading or deferred attach */
    913 				load_attach_drv = FALSE;
    914 				break;
    915 			case 'r':
    916 				set_root_devices_dev_dir(optarg);
    917 				if (zone_pathcheck(root_dir) !=
    918 				    DEVFSADM_SUCCESS)
    919 					devfsadm_exit(1);
    920 					/*NOTREACHED*/
    921 				break;
    922 			case 's':
    923 				/* suppress.  don't create/remove links/nodes */
    924 				/* useful with -v or -V */
    925 				file_mods = FALSE;
    926 				flush_path_to_inst_enable = FALSE;
    927 				break;
    928 			case 'v':
    929 				/* documented verbose flag */
    930 				add_verbose_id(VERBOSE_MID);
    931 				break;
    932 			case 'V':
    933 				/* undocumented for extra verbose levels */
    934 				add_verbose_id(optarg);
    935 				break;
    936 			default:
    937 				usage();
    938 			}
    939 		}
    940 		if (optind < argc) {
    941 			usage();
    942 		}
    943 	}
    944 	set_lock_root();
    945 }
    946 
    947 void
    948 usage(void)
    949 {
    950 	if (strcmp(prog, DEVLINKS) == 0) {
    951 		err_print(DEVLINKS_USAGE);
    952 	} else if (strcmp(prog, DRVCONFIG) == 0) {
    953 		err_print(DRVCONFIG_USAGE);
    954 	} else if ((strcmp(prog, DEVFSADM) == 0) ||
    955 	    (strcmp(prog, DEVFSADMD) == 0)) {
    956 		err_print(DEVFSADM_USAGE);
    957 	} else {
    958 		err_print(COMPAT_LINK_USAGE);
    959 	}
    960 
    961 	devfsadm_exit(1);
    962 	/*NOTREACHED*/
    963 }
    964 
    965 static void
    966 devi_tree_walk(struct dca_impl *dcip, int flags, char *ev_subclass)
    967 {
    968 	char *msg, *name;
    969 	struct mlist	mlist = {0};
    970 	di_node_t	node;
    971 
    972 	vprint(CHATTY_MID, "devi_tree_walk: root=%s, minor=%s, driver=%s,"
    973 	    " error=%d, flags=%u\n", dcip->dci_root,
    974 	    dcip->dci_minor ? dcip->dci_minor : "<NULL>",
    975 	    dcip->dci_driver ? dcip->dci_driver : "<NULL>", dcip->dci_error,
    976 	    dcip->dci_flags);
    977 
    978 	assert(dcip->dci_root);
    979 
    980 	if (dcip->dci_flags & DCA_LOAD_DRV) {
    981 		node = di_init_driver(dcip->dci_driver, flags);
    982 		msg = DRIVER_FAILURE;
    983 		name = dcip->dci_driver;
    984 	} else {
    985 		node = di_init(dcip->dci_root, flags);
    986 		msg = DI_INIT_FAILED;
    987 		name = dcip->dci_root;
    988 	}
    989 
    990 	if (node == DI_NODE_NIL) {
    991 		dcip->dci_error = errno;
    992 		/*
    993 		 * Rapid hotplugging (commonly seen during USB testing),
    994 		 * may remove a device before the create event for it
    995 		 * has been processed. To prevent alarming users with
    996 		 * a superfluous message, we suppress error messages
    997 		 * for ENXIO and hotplug.
    998 		 */
    999 		if (!(errno == ENXIO && (dcip->dci_flags & DCA_HOT_PLUG)))
   1000 			err_print(msg, name, strerror(dcip->dci_error));
   1001 		return;
   1002 	}
   1003 
   1004 	if (dcip->dci_flags & DCA_FLUSH_PATHINST)
   1005 		flush_path_to_inst();
   1006 
   1007 	dcip->dci_arg = &mlist;
   1008 
   1009 	vprint(CHATTY_MID, "walking device tree\n");
   1010 
   1011 	(void) di_walk_minor(node, NULL, DI_CHECK_ALIAS, dcip,
   1012 	    check_minor_type);
   1013 
   1014 	process_deferred_links(dcip, DCA_CREATE_LINK);
   1015 
   1016 	dcip->dci_arg = NULL;
   1017 
   1018 	/*
   1019 	 * Finished creating devfs files and dev links.
   1020 	 * Log sysevent.
   1021 	 */
   1022 	if (ev_subclass)
   1023 		build_and_enq_event(EC_DEV_ADD, ev_subclass, dcip->dci_root,
   1024 		    node, dcip->dci_minor);
   1025 
   1026 	/* Add new device to device allocation database */
   1027 	if (system_labeled && update_devdb) {
   1028 		_update_devalloc_db(&devlist, 0, DA_ADD, NULL, root_dir);
   1029 		update_devdb = 0;
   1030 	}
   1031 
   1032 	di_fini(node);
   1033 }
   1034 
   1035 static void
   1036 process_deferred_links(struct dca_impl *dcip, int flags)
   1037 {
   1038 	struct mlist	*dep;
   1039 	struct minor	*mp, *smp;
   1040 
   1041 	vprint(CHATTY_MID, "processing deferred links\n");
   1042 
   1043 	dep = dcip->dci_arg;
   1044 
   1045 	/*
   1046 	 * The list head is not used during the deferred create phase
   1047 	 */
   1048 	dcip->dci_arg = NULL;
   1049 
   1050 	assert(dep);
   1051 	assert((dep->head == NULL) ^ (dep->tail != NULL));
   1052 	assert(flags == DCA_FREE_LIST || flags == DCA_CREATE_LINK);
   1053 
   1054 	for (smp = NULL, mp = dep->head; mp; mp = mp->next) {
   1055 		if (flags == DCA_CREATE_LINK)
   1056 			(void) check_minor_type(mp->node, mp->minor, dcip);
   1057 		free(smp);
   1058 		smp = mp;
   1059 	}
   1060 
   1061 	free(smp);
   1062 }
   1063 
   1064 /*
   1065  * Called in non-daemon mode to take a snap shot of the devinfo tree.
   1066  * Then it calls the appropriate functions to build /devices and /dev.
   1067  * It also flushes path_to_inst.
   1068  * Except in the devfsadm -i (single driver case), the flags used by devfsadm
   1069  * needs to match DI_CACHE_SNAPSHOT_FLAGS. That will make DINFOCACHE snapshot
   1070  * updated.
   1071  */
   1072 void
   1073 process_devinfo_tree()
   1074 {
   1075 	uint_t		flags;
   1076 	struct dca_impl	dci;
   1077 	char		name[MAXNAMELEN];
   1078 	char		*fcn = "process_devinfo_tree: ";
   1079 
   1080 	vprint(CHATTY_MID, "%senter\n", fcn);
   1081 
   1082 	dca_impl_init("/", NULL, &dci);
   1083 
   1084 	lock_dev();
   1085 
   1086 	/*
   1087 	 * Update kernel driver.conf cache when devfsadm/drvconfig
   1088 	 * is invoked to build /devices and /dev.
   1089 	 */
   1090 	if (load_attach_drv == TRUE)
   1091 		update_drvconf((major_t)-1);
   1092 
   1093 	if (single_drv == TRUE) {
   1094 		/*
   1095 		 * load a single driver, but walk the entire devinfo tree
   1096 		 */
   1097 		if (load_attach_drv == FALSE)
   1098 			err_print(DRV_LOAD_REQD);
   1099 
   1100 		vprint(CHATTY_MID, "%sattaching driver (%s)\n", fcn, driver);
   1101 
   1102 		dci.dci_flags |= DCA_LOAD_DRV;
   1103 		(void) snprintf(name, sizeof (name), "%s", driver);
   1104 		dci.dci_driver = name;
   1105 		flags = DINFOCPYALL | DINFOPATH;
   1106 
   1107 	} else if (load_attach_drv == TRUE) {
   1108 		/*
   1109 		 * Load and attach all drivers, then walk the entire tree.
   1110 		 * If the cache flag is set, use DINFOCACHE to get cached
   1111 		 * data.
   1112 		 */
   1113 		if (use_snapshot_cache == TRUE) {
   1114 			flags = DINFOCACHE;
   1115 			vprint(CHATTY_MID, "%susing snapshot cache\n", fcn);
   1116 		} else {
   1117 			vprint(CHATTY_MID, "%sattaching all drivers\n", fcn);
   1118 			flags = DI_CACHE_SNAPSHOT_FLAGS;
   1119 			if (cleanup) {
   1120 				/*
   1121 				 * remove dangling entries from /etc/devices
   1122 				 * files.
   1123 				 */
   1124 				flags |= DINFOCLEANUP;
   1125 			}
   1126 		}
   1127 	} else {
   1128 		/*
   1129 		 * For devlinks, disks, ports, tapes and devfsadm -n,