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 /* 223c5e027bSEric Taylor * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23facf4a8dSllai1 * Use is subject to license terms. 24facf4a8dSllai1 */ 25facf4a8dSllai1 26facf4a8dSllai1 /* 27facf4a8dSllai1 * routines to invoke user level name lookup services 28facf4a8dSllai1 */ 29facf4a8dSllai1 30facf4a8dSllai1 #include <sys/types.h> 31facf4a8dSllai1 #include <sys/param.h> 32facf4a8dSllai1 #include <sys/t_lock.h> 33facf4a8dSllai1 #include <sys/systm.h> 34facf4a8dSllai1 #include <sys/sysmacros.h> 35facf4a8dSllai1 #include <sys/user.h> 36facf4a8dSllai1 #include <sys/time.h> 37facf4a8dSllai1 #include <sys/vfs.h> 38facf4a8dSllai1 #include <sys/vnode.h> 39facf4a8dSllai1 #include <sys/file.h> 40facf4a8dSllai1 #include <sys/fcntl.h> 41facf4a8dSllai1 #include <sys/flock.h> 42facf4a8dSllai1 #include <sys/kmem.h> 43facf4a8dSllai1 #include <sys/uio.h> 44facf4a8dSllai1 #include <sys/errno.h> 45facf4a8dSllai1 #include <sys/stat.h> 46facf4a8dSllai1 #include <sys/cred.h> 47facf4a8dSllai1 #include <sys/dirent.h> 48facf4a8dSllai1 #include <sys/pathname.h> 49facf4a8dSllai1 #include <sys/cmn_err.h> 50facf4a8dSllai1 #include <sys/debug.h> 51facf4a8dSllai1 #include <sys/mode.h> 52facf4a8dSllai1 #include <sys/policy.h> 53facf4a8dSllai1 #include <sys/disp.h> 54facf4a8dSllai1 #include <sys/door.h> 55facf4a8dSllai1 #include <fs/fs_subr.h> 56facf4a8dSllai1 #include <sys/mount.h> 57facf4a8dSllai1 #include <sys/fs/snode.h> 58facf4a8dSllai1 #include <sys/fs/dv_node.h> 59facf4a8dSllai1 #include <sys/fs/sdev_impl.h> 60facf4a8dSllai1 #include <sys/sunndi.h> 61facf4a8dSllai1 #include <sys/sunddi.h> 62facf4a8dSllai1 #include <sys/sunmdi.h> 63facf4a8dSllai1 #include <sys/conf.h> 64facf4a8dSllai1 #include <sys/modctl.h> 65facf4a8dSllai1 #include <sys/ddi.h> 66facf4a8dSllai1 67facf4a8dSllai1 /* default timeout to wait for devfsadm response in seconds */ 68facf4a8dSllai1 #define DEV_DEVFSADM_STARTUP (1 * 60) 69facf4a8dSllai1 #define DEV_NODE_WAIT_TIMEOUT (5 * 60) 70facf4a8dSllai1 71facf4a8dSllai1 /* atomic bitset for devfsadm status */ 72facf4a8dSllai1 volatile uint_t devfsadm_state; 73facf4a8dSllai1 74facf4a8dSllai1 static kmutex_t devfsadm_lock; 75facf4a8dSllai1 static kcondvar_t devfsadm_cv; 76facf4a8dSllai1 77facf4a8dSllai1 static int dev_node_wait_timeout = DEV_NODE_WAIT_TIMEOUT; 78facf4a8dSllai1 static int dev_devfsadm_startup = DEV_DEVFSADM_STARTUP; 79facf4a8dSllai1 80facf4a8dSllai1 /* 81facf4a8dSllai1 * Door used to communicate with devfsadmd 82facf4a8dSllai1 */ 83facf4a8dSllai1 static door_handle_t sdev_upcall_door = NULL; /* Door for upcalls */ 84facf4a8dSllai1 static char *sdev_door_upcall_filename = NULL; 85facf4a8dSllai1 static int sdev_upcall_door_revoked = 0; 86facf4a8dSllai1 static int sdev_door_upcall_filename_size; 87facf4a8dSllai1 88facf4a8dSllai1 static int sdev_devfsadm_revoked(void); 89facf4a8dSllai1 static int sdev_ki_call_devfsadmd(sdev_door_arg_t *, sdev_door_res_t *); 90facf4a8dSllai1 91facf4a8dSllai1 void 92facf4a8dSllai1 sdev_devfsadm_lockinit(void) 93facf4a8dSllai1 { 94facf4a8dSllai1 mutex_init(&devfsadm_lock, NULL, MUTEX_DEFAULT, NULL); 95facf4a8dSllai1 cv_init(&devfsadm_cv, NULL, CV_DEFAULT, NULL); 96facf4a8dSllai1 } 97facf4a8dSllai1 98facf4a8dSllai1 void 99facf4a8dSllai1 sdev_devfsadm_lockdestroy(void) 100facf4a8dSllai1 { 101facf4a8dSllai1 mutex_destroy(&devfsadm_lock); 102facf4a8dSllai1 cv_destroy(&devfsadm_cv); 103facf4a8dSllai1 } 104facf4a8dSllai1 105facf4a8dSllai1 /* 106facf4a8dSllai1 * Wait for node to be created 107facf4a8dSllai1 */ 108facf4a8dSllai1 int 109facf4a8dSllai1 sdev_wait4lookup(struct sdev_node *dv, int cmd) 110facf4a8dSllai1 { 111facf4a8dSllai1 clock_t expire; 112facf4a8dSllai1 clock_t rv; 113*d3d50737SRafael Vanoni clock_t wakeup = drv_usectohz(2 * 1000000); 114facf4a8dSllai1 int rval = ENOENT; 115facf4a8dSllai1 int is_lookup = (cmd == SDEV_LOOKUP); 116facf4a8dSllai1 117facf4a8dSllai1 ASSERT(cmd == SDEV_LOOKUP || cmd == SDEV_READDIR); 118facf4a8dSllai1 ASSERT(MUTEX_HELD(&dv->sdev_lookup_lock)); 119facf4a8dSllai1 120facf4a8dSllai1 /* tick value at which wait expires */ 121facf4a8dSllai1 expire = ddi_get_lbolt() + 122facf4a8dSllai1 drv_usectohz(dev_node_wait_timeout * 1000000); 123facf4a8dSllai1 124facf4a8dSllai1 sdcmn_err6(("wait4lookup %s %s, %ld %d\n", 125facf4a8dSllai1 is_lookup ? "lookup" : "readdir", 126facf4a8dSllai1 dv->sdev_name, expire - ddi_get_lbolt(), dv->sdev_state)); 127facf4a8dSllai1 128facf4a8dSllai1 if (SDEV_IS_LGWAITING(dv)) { 129facf4a8dSllai1 /* devfsadm nodes */ 130facf4a8dSllai1 while (DEVNAME_DEVFSADM_IS_RUNNING(devfsadm_state) && 131facf4a8dSllai1 !sdev_devfsadm_revoked()) { 132facf4a8dSllai1 /* wait 2 sec and check devfsadm completion */ 133*d3d50737SRafael Vanoni rv = cv_reltimedwait_sig(&dv->sdev_lookup_cv, 134*d3d50737SRafael Vanoni &dv->sdev_lookup_lock, wakeup, TR_CLOCK_TICK); 135facf4a8dSllai1 136facf4a8dSllai1 if (is_lookup && (rv > 0)) { 137facf4a8dSllai1 /* was this node constructed ? */ 138facf4a8dSllai1 if (dv->sdev_state == SDEV_READY) { 139facf4a8dSllai1 rval = 0; 140facf4a8dSllai1 } 141facf4a8dSllai1 sdcmn_err6(("%s: wait done, %screated %d\n", 142facf4a8dSllai1 dv->sdev_name, rval ? "not " : "", 143facf4a8dSllai1 dv->sdev_state)); 144facf4a8dSllai1 break; 145facf4a8dSllai1 } else if (rv == 0) { 146facf4a8dSllai1 /* interrupted */ 147facf4a8dSllai1 sdcmn_err6(("%s: wait interrupted\n", 148facf4a8dSllai1 dv->sdev_name)); 149facf4a8dSllai1 break; 150facf4a8dSllai1 } else if ((rv == -1) && 151facf4a8dSllai1 (ddi_get_lbolt() >= expire)) { 152facf4a8dSllai1 sdcmn_err6(("%s: wait time is up\n", 153facf4a8dSllai1 dv->sdev_name)); 154facf4a8dSllai1 break; 155facf4a8dSllai1 } 156facf4a8dSllai1 sdcmn_err6(("%s: wait " 157facf4a8dSllai1 "rv %ld state 0x%x expire %ld\n", 158facf4a8dSllai1 dv->sdev_name, rv, devfsadm_state, 159facf4a8dSllai1 expire - ddi_get_lbolt())); 160facf4a8dSllai1 } 161facf4a8dSllai1 } else { 162facf4a8dSllai1 /* 163facf4a8dSllai1 * for the nodes created by 164facf4a8dSllai1 * devname_lookup_func callback 165facf4a8dSllai1 * or plug-in modules 166facf4a8dSllai1 */ 167facf4a8dSllai1 while (SDEV_IS_LOOKUP(dv) || SDEV_IS_READDIR(dv)) { 168facf4a8dSllai1 cv_wait(&dv->sdev_lookup_cv, &dv->sdev_lookup_lock); 169facf4a8dSllai1 } 170facf4a8dSllai1 rval = 0; 171facf4a8dSllai1 } 172facf4a8dSllai1 173facf4a8dSllai1 sdcmn_err6(("wait4lookup unblocking %s state 0x%x %d\n", 174facf4a8dSllai1 dv->sdev_name, devfsadm_state, dv->sdev_state)); 175facf4a8dSllai1 176facf4a8dSllai1 if (is_lookup) { 177facf4a8dSllai1 SDEV_UNBLOCK_OTHERS(dv, SDEV_LOOKUP); 178facf4a8dSllai1 } else { 179facf4a8dSllai1 SDEV_UNBLOCK_OTHERS(dv, SDEV_READDIR); 180facf4a8dSllai1 } 181facf4a8dSllai1 182facf4a8dSllai1 return (rval); 183facf4a8dSllai1 } 184facf4a8dSllai1 185facf4a8dSllai1 void 186facf4a8dSllai1 sdev_unblock_others(struct sdev_node *dv, uint_t cmd) 187facf4a8dSllai1 { 188facf4a8dSllai1 ASSERT(MUTEX_HELD(&dv->sdev_lookup_lock)); 189facf4a8dSllai1 190facf4a8dSllai1 SDEV_CLEAR_LOOKUP_FLAGS(dv, cmd); 191facf4a8dSllai1 if (SDEV_IS_LGWAITING(dv)) { 192facf4a8dSllai1 SDEV_CLEAR_LOOKUP_FLAGS(dv, SDEV_LGWAITING); 193facf4a8dSllai1 } 194facf4a8dSllai1 cv_broadcast(&dv->sdev_lookup_cv); 195facf4a8dSllai1 } 196facf4a8dSllai1 197facf4a8dSllai1 /* 198facf4a8dSllai1 * In the case devfsadmd is down, it is re-started by syseventd 199facf4a8dSllai1 * upon receiving an event subscribed to by devfsadmd. 200facf4a8dSllai1 */ 201facf4a8dSllai1 static int 202facf4a8dSllai1 sdev_start_devfsadmd() 203facf4a8dSllai1 { 204facf4a8dSllai1 int se_err = 0; 205facf4a8dSllai1 sysevent_t *ev; 206facf4a8dSllai1 sysevent_id_t eid; 207facf4a8dSllai1 208facf4a8dSllai1 ev = sysevent_alloc(EC_DEVFS, ESC_DEVFS_START, EP_DDI, SE_SLEEP); 209facf4a8dSllai1 ASSERT(ev); 210facf4a8dSllai1 if ((se_err = log_sysevent(ev, SE_SLEEP, &eid)) != 0) { 211facf4a8dSllai1 switch (se_err) { 212facf4a8dSllai1 case SE_NO_TRANSPORT: 213facf4a8dSllai1 cmn_err(CE_WARN, "unable to start devfsadm - " 214facf4a8dSllai1 "syseventd may not be responding\n"); 215facf4a8dSllai1 break; 216facf4a8dSllai1 default: 217facf4a8dSllai1 cmn_err(CE_WARN, "unable to start devfsadm - " 218facf4a8dSllai1 "sysevent error %d\n", se_err); 219facf4a8dSllai1 break; 220facf4a8dSllai1 } 221facf4a8dSllai1 } 222facf4a8dSllai1 223facf4a8dSllai1 sysevent_free(ev); 224facf4a8dSllai1 return (se_err); 225facf4a8dSllai1 } 226facf4a8dSllai1 227facf4a8dSllai1 static int 228facf4a8dSllai1 sdev_open_upcall_door() 229facf4a8dSllai1 { 230facf4a8dSllai1 int error; 231facf4a8dSllai1 clock_t rv; 232facf4a8dSllai1 clock_t expire; 233facf4a8dSllai1 234facf4a8dSllai1 ASSERT(sdev_upcall_door == NULL); 235facf4a8dSllai1 236*d3d50737SRafael Vanoni /* timeout expires this many ticks in the future */ 237*d3d50737SRafael Vanoni expire = ddi_get_lbolt() + drv_usectohz(dev_devfsadm_startup * 1000000); 238facf4a8dSllai1 239facf4a8dSllai1 if (sdev_door_upcall_filename == NULL) { 240facf4a8dSllai1 if ((error = sdev_start_devfsadmd()) != 0) { 241facf4a8dSllai1 return (error); 242facf4a8dSllai1 } 243facf4a8dSllai1 244facf4a8dSllai1 /* wait for devfsadmd start */ 245facf4a8dSllai1 mutex_enter(&devfsadm_lock); 246facf4a8dSllai1 while (sdev_door_upcall_filename == NULL) { 247facf4a8dSllai1 sdcmn_err6(("waiting for dev_door creation, %ld\n", 248facf4a8dSllai1 expire - ddi_get_lbolt())); 249facf4a8dSllai1 rv = cv_timedwait_sig(&devfsadm_cv, &devfsadm_lock, 250facf4a8dSllai1 expire); 251facf4a8dSllai1 sdcmn_err6(("dev_door wait rv %ld\n", rv)); 252facf4a8dSllai1 if (rv <= 0) { 253facf4a8dSllai1 sdcmn_err6(("devfsadmd startup error\n")); 254facf4a8dSllai1 mutex_exit(&devfsadm_lock); 255facf4a8dSllai1 return (EBADF); 256facf4a8dSllai1 } 257facf4a8dSllai1 } 258facf4a8dSllai1 sdcmn_err6(("devfsadmd is ready\n")); 259facf4a8dSllai1 mutex_exit(&devfsadm_lock); 260facf4a8dSllai1 } 261facf4a8dSllai1 262facf4a8dSllai1 if ((error = door_ki_open(sdev_door_upcall_filename, 263facf4a8dSllai1 &sdev_upcall_door)) != 0) { 264facf4a8dSllai1 sdcmn_err6(("upcall_lookup: door open error %d\n", 265facf4a8dSllai1 error)); 266facf4a8dSllai1 return (error); 267facf4a8dSllai1 } 268facf4a8dSllai1 269facf4a8dSllai1 return (0); 270facf4a8dSllai1 } 271facf4a8dSllai1 272facf4a8dSllai1 static void 273facf4a8dSllai1 sdev_release_door() 274facf4a8dSllai1 { 275facf4a8dSllai1 if (sdev_upcall_door) { 276facf4a8dSllai1 door_ki_rele(sdev_upcall_door); 277facf4a8dSllai1 sdev_upcall_door = NULL; 278facf4a8dSllai1 } 279facf4a8dSllai1 if (sdev_door_upcall_filename) { 280facf4a8dSllai1 kmem_free(sdev_door_upcall_filename, 281facf4a8dSllai1 sdev_door_upcall_filename_size); 282facf4a8dSllai1 sdev_door_upcall_filename = NULL; 283facf4a8dSllai1 } 284facf4a8dSllai1 } 285facf4a8dSllai1 286facf4a8dSllai1 static int 287facf4a8dSllai1 sdev_ki_call_devfsadmd(sdev_door_arg_t *argp, sdev_door_res_t *resultp) 288facf4a8dSllai1 { 289facf4a8dSllai1 door_arg_t darg, save_arg; 290facf4a8dSllai1 int error; 291facf4a8dSllai1 int retry; 292facf4a8dSllai1 293facf4a8dSllai1 if (((sdev_upcall_door == NULL) && 294facf4a8dSllai1 ((error = sdev_open_upcall_door()) != 0)) || 295facf4a8dSllai1 sdev_devfsadm_revoked()) { 296facf4a8dSllai1 sdcmn_err6(("call_devfsadm: upcall lookup error\n")); 297facf4a8dSllai1 return (error); 298facf4a8dSllai1 } 299facf4a8dSllai1 300facf4a8dSllai1 ASSERT(argp); 301facf4a8dSllai1 darg.data_ptr = (char *)argp; 302facf4a8dSllai1 darg.data_size = sizeof (struct sdev_door_arg); 303facf4a8dSllai1 darg.desc_ptr = NULL; 304facf4a8dSllai1 darg.desc_num = 0; 305facf4a8dSllai1 darg.rbuf = (char *)(resultp); 306facf4a8dSllai1 darg.rsize = sizeof (struct sdev_door_res); 307facf4a8dSllai1 308facf4a8dSllai1 ASSERT(sdev_upcall_door); 309facf4a8dSllai1 save_arg = darg; 310facf4a8dSllai1 for (retry = 0; ; retry++) { 311facf4a8dSllai1 sdcmn_err6(("call devfsadm: upcall lookup, retry %d\n", retry)); 312323a81d9Sjwadams if ((error = door_ki_upcall_limited(sdev_upcall_door, &darg, 313323a81d9Sjwadams NULL, SIZE_MAX, 0)) == 0) { 314facf4a8dSllai1 sdcmn_err6(("call devfsadm: upcall lookup ok\n")); 315facf4a8dSllai1 break; 316facf4a8dSllai1 } 317facf4a8dSllai1 318facf4a8dSllai1 /* 319facf4a8dSllai1 * handle door call errors 320facf4a8dSllai1 */ 321facf4a8dSllai1 if (sdev_devfsadm_revoked()) { 322facf4a8dSllai1 sdcmn_err6(("upcall lookup door revoked, " 323facf4a8dSllai1 "error %d\n", error)); 324facf4a8dSllai1 return (error); 325facf4a8dSllai1 } 326facf4a8dSllai1 327facf4a8dSllai1 switch (error) { 328facf4a8dSllai1 case EINTR: 329facf4a8dSllai1 /* return error here? */ 330facf4a8dSllai1 sdcmn_err6(("sdev_ki_call_devfsadm: EINTR\n")); 331facf4a8dSllai1 delay(hz); 332facf4a8dSllai1 break; 333facf4a8dSllai1 case EAGAIN: 334facf4a8dSllai1 sdcmn_err6(("sdev_ki_call_devfsadm: EAGAIN\n")); 335facf4a8dSllai1 delay(2 * hz); 336facf4a8dSllai1 break; 337facf4a8dSllai1 case EBADF: 338facf4a8dSllai1 if (retry > 4) { 339facf4a8dSllai1 sdcmn_err6(("sdev_ki_call_devfsadm: EBADF\n")); 340facf4a8dSllai1 return (EBADF); 341facf4a8dSllai1 } 342facf4a8dSllai1 sdcmn_err6(( 343facf4a8dSllai1 "sdev_ki_call_devfsadm: EBADF, re-binding\n")); 344facf4a8dSllai1 sdev_release_door(); 345facf4a8dSllai1 delay(retry * hz); 346facf4a8dSllai1 error = sdev_open_upcall_door(); 347facf4a8dSllai1 if (error != 0) { 348facf4a8dSllai1 sdcmn_err6(("sdev_ki_call_devfsadm: " 349facf4a8dSllai1 "EBADF lookup error %d\n", error)); 350facf4a8dSllai1 if (!sdev_devfsadm_revoked()) 351facf4a8dSllai1 cmn_err(CE_NOTE, 352facf4a8dSllai1 "?unable to invoke devfsadm - " 353facf4a8dSllai1 "please run manually\n"); 354facf4a8dSllai1 return (EBADF); 355facf4a8dSllai1 } 356facf4a8dSllai1 break; 357facf4a8dSllai1 case EINVAL: 358facf4a8dSllai1 default: 359facf4a8dSllai1 cmn_err(CE_CONT, 360facf4a8dSllai1 "?sdev: door_ki_upcall unexpected result %d\n", 361facf4a8dSllai1 error); 362facf4a8dSllai1 return (error); 363facf4a8dSllai1 } 364facf4a8dSllai1 365facf4a8dSllai1 darg = save_arg; 366facf4a8dSllai1 } 367facf4a8dSllai1 368facf4a8dSllai1 if (!error) { 369bc1009abSjg ASSERT((struct sdev_door_res *)(intptr_t)darg.rbuf == resultp); 370facf4a8dSllai1 if (resultp->devfsadm_error != 0) { 371facf4a8dSllai1 sdcmn_err6(("sdev_ki_call_devfsadmd: result %d\n", 372facf4a8dSllai1 resultp->devfsadm_error)); 373facf4a8dSllai1 error = resultp->devfsadm_error; 374facf4a8dSllai1 } 375facf4a8dSllai1 } else { 376facf4a8dSllai1 sdcmn_err6(("sdev_ki_call_devfsadmd with error %d\n", error)); 377facf4a8dSllai1 } 378facf4a8dSllai1 379facf4a8dSllai1 return (error); 380facf4a8dSllai1 } 381facf4a8dSllai1 382facf4a8dSllai1 static int 383facf4a8dSllai1 sdev_devfsadm_revoked(void) 384facf4a8dSllai1 { 385facf4a8dSllai1 struct door_info info; 386facf4a8dSllai1 int rv; 387facf4a8dSllai1 extern int sys_shutdown; 388facf4a8dSllai1 389facf4a8dSllai1 if (sys_shutdown) { 390facf4a8dSllai1 sdcmn_err6(("dev: shutdown observed\n")); 391facf4a8dSllai1 return (1); 392facf4a8dSllai1 } 393facf4a8dSllai1 394facf4a8dSllai1 if (sdev_upcall_door && !sdev_upcall_door_revoked) { 395facf4a8dSllai1 rv = door_ki_info(sdev_upcall_door, &info); 396facf4a8dSllai1 if ((rv == 0) && info.di_attributes & DOOR_REVOKED) { 397facf4a8dSllai1 sdcmn_err6(("lookup door: revoked\n")); 398facf4a8dSllai1 sdev_upcall_door_revoked = 1; 399facf4a8dSllai1 } 400facf4a8dSllai1 } 401facf4a8dSllai1 402facf4a8dSllai1 return (sdev_upcall_door_revoked); 403facf4a8dSllai1 } 404facf4a8dSllai1 405facf4a8dSllai1 /*ARGSUSED*/ 406facf4a8dSllai1 static void 407facf4a8dSllai1 sdev_config_all_thread(struct sdev_node *dv) 408facf4a8dSllai1 { 409facf4a8dSllai1 int32_t error = 0; 410facf4a8dSllai1 sdev_door_arg_t *argp; 411facf4a8dSllai1 sdev_door_res_t result; 412facf4a8dSllai1 413facf4a8dSllai1 argp = kmem_zalloc(sizeof (sdev_door_arg_t), KM_SLEEP); 414facf4a8dSllai1 argp->devfsadm_cmd = DEVFSADMD_RUN_ALL; 415facf4a8dSllai1 416facf4a8dSllai1 error = sdev_ki_call_devfsadmd(argp, &result); 417facf4a8dSllai1 if (!error) { 418facf4a8dSllai1 sdcmn_err6(("devfsadm result error: %d\n", 419facf4a8dSllai1 result.devfsadm_error)); 420facf4a8dSllai1 if (!result.devfsadm_error) { 421facf4a8dSllai1 DEVNAME_DEVFSADM_SET_RUN(devfsadm_state); 422facf4a8dSllai1 } else { 423facf4a8dSllai1 DEVNAME_DEVFSADM_SET_STOP(devfsadm_state); 424facf4a8dSllai1 } 425facf4a8dSllai1 } else { 426facf4a8dSllai1 DEVNAME_DEVFSADM_SET_STOP(devfsadm_state); 427facf4a8dSllai1 } 428facf4a8dSllai1 429facf4a8dSllai1 kmem_free(argp, sizeof (sdev_door_arg_t)); 430facf4a8dSllai1 done: 431facf4a8dSllai1 sdcmn_err6(("sdev_config_all_thread: stopping, devfsadm state 0x%x\n", 432facf4a8dSllai1 devfsadm_state)); 433facf4a8dSllai1 thread_exit(); 434facf4a8dSllai1 } 435facf4a8dSllai1 436facf4a8dSllai1 /* 437facf4a8dSllai1 * launch an asynchronous thread to do the devfsadm dev_config_all 438facf4a8dSllai1 */ 439facf4a8dSllai1 /*ARGSUSED*/ 440facf4a8dSllai1 void 441facf4a8dSllai1 sdev_devfsadmd_thread(struct sdev_node *ddv, struct sdev_node *dv, 442facf4a8dSllai1 struct cred *cred) 443facf4a8dSllai1 { 444facf4a8dSllai1 ASSERT(i_ddi_io_initialized()); 445facf4a8dSllai1 DEVNAME_DEVFSADM_SET_RUNNING(devfsadm_state); 446facf4a8dSllai1 (void) thread_create(NULL, 0, sdev_config_all_thread, dv, 0, 447facf4a8dSllai1 &p0, TS_RUN, MINCLSYSPRI); 448facf4a8dSllai1 } 449facf4a8dSllai1 450facf4a8dSllai1 int 4513c5e027bSEric Taylor devname_filename_register(char *name) 452facf4a8dSllai1 { 453facf4a8dSllai1 int error = 0; 454facf4a8dSllai1 char *strbuf; 455facf4a8dSllai1 char *namep; 456facf4a8dSllai1 int n; 457facf4a8dSllai1 458facf4a8dSllai1 strbuf = kmem_zalloc(MOD_MAXPATH, KM_SLEEP); 459facf4a8dSllai1 460facf4a8dSllai1 if (copyinstr(name, strbuf, MOD_MAXPATH, 0)) { 461facf4a8dSllai1 sdcmn_err6(("error copyin \n")); 462facf4a8dSllai1 error = EFAULT; 463facf4a8dSllai1 } else { 464facf4a8dSllai1 sdcmn_err6(("file %s is registering\n", strbuf)); 465facf4a8dSllai1 /* handling the daemon re-start situations */ 466facf4a8dSllai1 n = strlen(strbuf) + 1; 467facf4a8dSllai1 namep = i_ddi_strdup(strbuf, KM_SLEEP); 468facf4a8dSllai1 mutex_enter(&devfsadm_lock); 469facf4a8dSllai1 sdev_release_door(); 470facf4a8dSllai1 sdev_door_upcall_filename_size = n; 471facf4a8dSllai1 sdev_door_upcall_filename = namep; 472facf4a8dSllai1 sdcmn_err6(("size %d file name %s\n", 473facf4a8dSllai1 sdev_door_upcall_filename_size, 474facf4a8dSllai1 sdev_door_upcall_filename)); 475facf4a8dSllai1 cv_broadcast(&devfsadm_cv); 476facf4a8dSllai1 mutex_exit(&devfsadm_lock); 477facf4a8dSllai1 } 478facf4a8dSllai1 479facf4a8dSllai1 kmem_free(strbuf, MOD_MAXPATH); 480facf4a8dSllai1 return (error); 481facf4a8dSllai1 } 482