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 /*
2210097SEric.Taylor@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
232621Sllai1 * Use is subject to license terms.
242621Sllai1 */
252621Sllai1
262621Sllai1 /*
272621Sllai1 * routines to invoke user level name lookup services
282621Sllai1 */
292621Sllai1
302621Sllai1 #include <sys/types.h>
312621Sllai1 #include <sys/param.h>
322621Sllai1 #include <sys/t_lock.h>
332621Sllai1 #include <sys/systm.h>
342621Sllai1 #include <sys/sysmacros.h>
352621Sllai1 #include <sys/user.h>
362621Sllai1 #include <sys/time.h>
372621Sllai1 #include <sys/vfs.h>
382621Sllai1 #include <sys/vnode.h>
392621Sllai1 #include <sys/file.h>
402621Sllai1 #include <sys/fcntl.h>
412621Sllai1 #include <sys/flock.h>
422621Sllai1 #include <sys/kmem.h>
432621Sllai1 #include <sys/uio.h>
442621Sllai1 #include <sys/errno.h>
452621Sllai1 #include <sys/stat.h>
462621Sllai1 #include <sys/cred.h>
472621Sllai1 #include <sys/dirent.h>
482621Sllai1 #include <sys/pathname.h>
492621Sllai1 #include <sys/cmn_err.h>
502621Sllai1 #include <sys/debug.h>
512621Sllai1 #include <sys/mode.h>
522621Sllai1 #include <sys/policy.h>
532621Sllai1 #include <sys/disp.h>
542621Sllai1 #include <sys/door.h>
552621Sllai1 #include <fs/fs_subr.h>
562621Sllai1 #include <sys/mount.h>
572621Sllai1 #include <sys/fs/snode.h>
582621Sllai1 #include <sys/fs/dv_node.h>
592621Sllai1 #include <sys/fs/sdev_impl.h>
602621Sllai1 #include <sys/sunndi.h>
612621Sllai1 #include <sys/sunddi.h>
622621Sllai1 #include <sys/sunmdi.h>
632621Sllai1 #include <sys/conf.h>
642621Sllai1 #include <sys/modctl.h>
652621Sllai1 #include <sys/ddi.h>
662621Sllai1
672621Sllai1 /* default timeout to wait for devfsadm response in seconds */
682621Sllai1 #define DEV_DEVFSADM_STARTUP (1 * 60)
692621Sllai1 #define DEV_NODE_WAIT_TIMEOUT (5 * 60)
702621Sllai1
712621Sllai1 /* atomic bitset for devfsadm status */
722621Sllai1 volatile uint_t devfsadm_state;
732621Sllai1
742621Sllai1 static kmutex_t devfsadm_lock;
752621Sllai1 static kcondvar_t devfsadm_cv;
762621Sllai1
772621Sllai1 static int dev_node_wait_timeout = DEV_NODE_WAIT_TIMEOUT;
782621Sllai1 static int dev_devfsadm_startup = DEV_DEVFSADM_STARTUP;
792621Sllai1
802621Sllai1 /*
812621Sllai1 * Door used to communicate with devfsadmd
822621Sllai1 */
832621Sllai1 static door_handle_t sdev_upcall_door = NULL; /* Door for upcalls */
842621Sllai1 static char *sdev_door_upcall_filename = NULL;
852621Sllai1 static int sdev_upcall_door_revoked = 0;
862621Sllai1 static int sdev_door_upcall_filename_size;
872621Sllai1
882621Sllai1 static int sdev_devfsadm_revoked(void);
892621Sllai1 static int sdev_ki_call_devfsadmd(sdev_door_arg_t *, sdev_door_res_t *);
902621Sllai1
912621Sllai1 void
sdev_devfsadm_lockinit(void)922621Sllai1 sdev_devfsadm_lockinit(void)
932621Sllai1 {
942621Sllai1 mutex_init(&devfsadm_lock, NULL, MUTEX_DEFAULT, NULL);
952621Sllai1 cv_init(&devfsadm_cv, NULL, CV_DEFAULT, NULL);
962621Sllai1 }
972621Sllai1
982621Sllai1 void
sdev_devfsadm_lockdestroy(void)992621Sllai1 sdev_devfsadm_lockdestroy(void)
1002621Sllai1 {
1012621Sllai1 mutex_destroy(&devfsadm_lock);
1022621Sllai1 cv_destroy(&devfsadm_cv);
1032621Sllai1 }
1042621Sllai1
1052621Sllai1 /*
1062621Sllai1 * Wait for node to be created
1072621Sllai1 */
1082621Sllai1 int
sdev_wait4lookup(struct sdev_node * dv,int cmd)1092621Sllai1 sdev_wait4lookup(struct sdev_node *dv, int cmd)
1102621Sllai1 {
1112621Sllai1 clock_t expire;
1122621Sllai1 clock_t rv;
113*11066Srafael.vanoni@sun.com clock_t wakeup = drv_usectohz(2 * 1000000);
1142621Sllai1 int rval = ENOENT;
1152621Sllai1 int is_lookup = (cmd == SDEV_LOOKUP);
1162621Sllai1
1172621Sllai1 ASSERT(cmd == SDEV_LOOKUP || cmd == SDEV_READDIR);
1182621Sllai1 ASSERT(MUTEX_HELD(&dv->sdev_lookup_lock));
1192621Sllai1
1202621Sllai1 /* tick value at which wait expires */
1212621Sllai1 expire = ddi_get_lbolt() +
1222621Sllai1 drv_usectohz(dev_node_wait_timeout * 1000000);
1232621Sllai1
1242621Sllai1 sdcmn_err6(("wait4lookup %s %s, %ld %d\n",
1252621Sllai1 is_lookup ? "lookup" : "readdir",
1262621Sllai1 dv->sdev_name, expire - ddi_get_lbolt(), dv->sdev_state));
1272621Sllai1
1282621Sllai1 if (SDEV_IS_LGWAITING(dv)) {
1292621Sllai1 /* devfsadm nodes */
1302621Sllai1 while (DEVNAME_DEVFSADM_IS_RUNNING(devfsadm_state) &&
1312621Sllai1 !sdev_devfsadm_revoked()) {
1322621Sllai1 /* wait 2 sec and check devfsadm completion */
133*11066Srafael.vanoni@sun.com rv = cv_reltimedwait_sig(&dv->sdev_lookup_cv,
134*11066Srafael.vanoni@sun.com &dv->sdev_lookup_lock, wakeup, TR_CLOCK_TICK);
1352621Sllai1
1362621Sllai1 if (is_lookup && (rv > 0)) {
1372621Sllai1 /* was this node constructed ? */
1382621Sllai1 if (dv->sdev_state == SDEV_READY) {
1392621Sllai1 rval = 0;
1402621Sllai1 }
1412621Sllai1 sdcmn_err6(("%s: wait done, %screated %d\n",
1422621Sllai1 dv->sdev_name, rval ? "not " : "",
1432621Sllai1 dv->sdev_state));
1442621Sllai1 break;
1452621Sllai1 } else if (rv == 0) {
1462621Sllai1 /* interrupted */
1472621Sllai1 sdcmn_err6(("%s: wait interrupted\n",
1482621Sllai1 dv->sdev_name));
1492621Sllai1 break;
1502621Sllai1 } else if ((rv == -1) &&
1512621Sllai1 (ddi_get_lbolt() >= expire)) {
1522621Sllai1 sdcmn_err6(("%s: wait time is up\n",
15310097SEric.Taylor@Sun.COM dv->sdev_name));
1542621Sllai1 break;
1552621Sllai1 }
1562621Sllai1 sdcmn_err6(("%s: wait "
1572621Sllai1 "rv %ld state 0x%x expire %ld\n",
1582621Sllai1 dv->sdev_name, rv, devfsadm_state,
1592621Sllai1 expire - ddi_get_lbolt()));
1602621Sllai1 }
1612621Sllai1 } else {
1622621Sllai1 /*
1632621Sllai1 * for the nodes created by
1642621Sllai1 * devname_lookup_func callback
1652621Sllai1 * or plug-in modules
1662621Sllai1 */
1672621Sllai1 while (SDEV_IS_LOOKUP(dv) || SDEV_IS_READDIR(dv)) {
1682621Sllai1 cv_wait(&dv->sdev_lookup_cv, &dv->sdev_lookup_lock);
1692621Sllai1 }
1702621Sllai1 rval = 0;
1712621Sllai1 }
1722621Sllai1
1732621Sllai1 sdcmn_err6(("wait4lookup unblocking %s state 0x%x %d\n",
1742621Sllai1 dv->sdev_name, devfsadm_state, dv->sdev_state));
1752621Sllai1
1762621Sllai1 if (is_lookup) {
1772621Sllai1 SDEV_UNBLOCK_OTHERS(dv, SDEV_LOOKUP);
1782621Sllai1 } else {
1792621Sllai1 SDEV_UNBLOCK_OTHERS(dv, SDEV_READDIR);
1802621Sllai1 }
1812621Sllai1
1822621Sllai1 return (rval);
1832621Sllai1 }
1842621Sllai1
1852621Sllai1 void
sdev_unblock_others(struct sdev_node * dv,uint_t cmd)1862621Sllai1 sdev_unblock_others(struct sdev_node *dv, uint_t cmd)
1872621Sllai1 {
1882621Sllai1 ASSERT(MUTEX_HELD(&dv->sdev_lookup_lock));
1892621Sllai1
1902621Sllai1 SDEV_CLEAR_LOOKUP_FLAGS(dv, cmd);
1912621Sllai1 if (SDEV_IS_LGWAITING(dv)) {
1922621Sllai1 SDEV_CLEAR_LOOKUP_FLAGS(dv, SDEV_LGWAITING);
1932621Sllai1 }
1942621Sllai1 cv_broadcast(&dv->sdev_lookup_cv);
1952621Sllai1 }
1962621Sllai1
1972621Sllai1 /*
1982621Sllai1 * In the case devfsadmd is down, it is re-started by syseventd
1992621Sllai1 * upon receiving an event subscribed to by devfsadmd.
2002621Sllai1 */
2012621Sllai1 static int
sdev_start_devfsadmd()2022621Sllai1 sdev_start_devfsadmd()
2032621Sllai1 {
2042621Sllai1 int se_err = 0;
2052621Sllai1 sysevent_t *ev;
2062621Sllai1 sysevent_id_t eid;
2072621Sllai1
2082621Sllai1 ev = sysevent_alloc(EC_DEVFS, ESC_DEVFS_START, EP_DDI, SE_SLEEP);
2092621Sllai1 ASSERT(ev);
2102621Sllai1 if ((se_err = log_sysevent(ev, SE_SLEEP, &eid)) != 0) {
2112621Sllai1 switch (se_err) {
2122621Sllai1 case SE_NO_TRANSPORT:
2132621Sllai1 cmn_err(CE_WARN, "unable to start devfsadm - "
2142621Sllai1 "syseventd may not be responding\n");
2152621Sllai1 break;
2162621Sllai1 default:
2172621Sllai1 cmn_err(CE_WARN, "unable to start devfsadm - "
2182621Sllai1 "sysevent error %d\n", se_err);
2192621Sllai1 break;
2202621Sllai1 }
2212621Sllai1 }
2222621Sllai1
2232621Sllai1 sysevent_free(ev);
2242621Sllai1 return (se_err);
2252621Sllai1 }
2262621Sllai1
2272621Sllai1 static int
sdev_open_upcall_door()2282621Sllai1 sdev_open_upcall_door()
2292621Sllai1 {
2302621Sllai1 int error;
2312621Sllai1 clock_t rv;
2322621Sllai1 clock_t expire;
2332621Sllai1
2342621Sllai1 ASSERT(sdev_upcall_door == NULL);
2352621Sllai1
236*11066Srafael.vanoni@sun.com /* timeout expires this many ticks in the future */
237*11066Srafael.vanoni@sun.com expire = ddi_get_lbolt() + drv_usectohz(dev_devfsadm_startup * 1000000);
2382621Sllai1
2392621Sllai1 if (sdev_door_upcall_filename == NULL) {
2402621Sllai1 if ((error = sdev_start_devfsadmd()) != 0) {
2412621Sllai1 return (error);
2422621Sllai1 }
2432621Sllai1
2442621Sllai1 /* wait for devfsadmd start */
2452621Sllai1 mutex_enter(&devfsadm_lock);
2462621Sllai1 while (sdev_door_upcall_filename == NULL) {
2472621Sllai1 sdcmn_err6(("waiting for dev_door creation, %ld\n",
2482621Sllai1 expire - ddi_get_lbolt()));
2492621Sllai1 rv = cv_timedwait_sig(&devfsadm_cv, &devfsadm_lock,
2502621Sllai1 expire);
2512621Sllai1 sdcmn_err6(("dev_door wait rv %ld\n", rv));
2522621Sllai1 if (rv <= 0) {
2532621Sllai1 sdcmn_err6(("devfsadmd startup error\n"));
2542621Sllai1 mutex_exit(&devfsadm_lock);
2552621Sllai1 return (EBADF);
2562621Sllai1 }
2572621Sllai1 }
2582621Sllai1 sdcmn_err6(("devfsadmd is ready\n"));
2592621Sllai1 mutex_exit(&devfsadm_lock);
2602621Sllai1 }
2612621Sllai1
2622621Sllai1 if ((error = door_ki_open(sdev_door_upcall_filename,
2632621Sllai1 &sdev_upcall_door)) != 0) {
2642621Sllai1 sdcmn_err6(("upcall_lookup: door open error %d\n",
2652621Sllai1 error));
2662621Sllai1 return (error);
2672621Sllai1 }
2682621Sllai1
2692621Sllai1 return (0);
2702621Sllai1 }
2712621Sllai1
2722621Sllai1 static void
sdev_release_door()2732621Sllai1 sdev_release_door()
2742621Sllai1 {
2752621Sllai1 if (sdev_upcall_door) {
2762621Sllai1 door_ki_rele(sdev_upcall_door);
2772621Sllai1 sdev_upcall_door = NULL;
2782621Sllai1 }
2792621Sllai1 if (sdev_door_upcall_filename) {
2802621Sllai1 kmem_free(sdev_door_upcall_filename,
2812621Sllai1 sdev_door_upcall_filename_size);
2822621Sllai1 sdev_door_upcall_filename = NULL;
2832621Sllai1 }
2842621Sllai1 }
2852621Sllai1
2862621Sllai1 static int
sdev_ki_call_devfsadmd(sdev_door_arg_t * argp,sdev_door_res_t * resultp)2872621Sllai1 sdev_ki_call_devfsadmd(sdev_door_arg_t *argp, sdev_door_res_t *resultp)
2882621Sllai1 {
2892621Sllai1 door_arg_t darg, save_arg;
2902621Sllai1 int error;
2912621Sllai1 int retry;
2922621Sllai1
2932621Sllai1 if (((sdev_upcall_door == NULL) &&
2942621Sllai1 ((error = sdev_open_upcall_door()) != 0)) ||
2952621Sllai1 sdev_devfsadm_revoked()) {
2962621Sllai1 sdcmn_err6(("call_devfsadm: upcall lookup error\n"));
2972621Sllai1 return (error);
2982621Sllai1 }
2992621Sllai1
3002621Sllai1 ASSERT(argp);
3012621Sllai1 darg.data_ptr = (char *)argp;
3022621Sllai1 darg.data_size = sizeof (struct sdev_door_arg);
3032621Sllai1 darg.desc_ptr = NULL;
3042621Sllai1 darg.desc_num = 0;
3052621Sllai1 darg.rbuf = (char *)(resultp);
3062621Sllai1 darg.rsize = sizeof (struct sdev_door_res);
3072621Sllai1
3082621Sllai1 ASSERT(sdev_upcall_door);
3092621Sllai1 save_arg = darg;
3102621Sllai1 for (retry = 0; ; retry++) {
3112621Sllai1 sdcmn_err6(("call devfsadm: upcall lookup, retry %d\n", retry));
3126997Sjwadams if ((error = door_ki_upcall_limited(sdev_upcall_door, &darg,
3136997Sjwadams NULL, SIZE_MAX, 0)) == 0) {
3142621Sllai1 sdcmn_err6(("call devfsadm: upcall lookup ok\n"));
3152621Sllai1 break;
3162621Sllai1 }
3172621Sllai1
3182621Sllai1 /*
3192621Sllai1 * handle door call errors
3202621Sllai1 */
3212621Sllai1 if (sdev_devfsadm_revoked()) {
3222621Sllai1 sdcmn_err6(("upcall lookup door revoked, "
3232621Sllai1 "error %d\n", error));
3242621Sllai1 return (error);
3252621Sllai1 }
3262621Sllai1
3272621Sllai1 switch (error) {
3282621Sllai1 case EINTR:
3292621Sllai1 /* return error here? */
3302621Sllai1 sdcmn_err6(("sdev_ki_call_devfsadm: EINTR\n"));
3312621Sllai1 delay(hz);
3322621Sllai1 break;
3332621Sllai1 case EAGAIN:
3342621Sllai1 sdcmn_err6(("sdev_ki_call_devfsadm: EAGAIN\n"));
3352621Sllai1 delay(2 * hz);
3362621Sllai1 break;
3372621Sllai1 case EBADF:
3382621Sllai1 if (retry > 4) {
3392621Sllai1 sdcmn_err6(("sdev_ki_call_devfsadm: EBADF\n"));
3402621Sllai1 return (EBADF);
3412621Sllai1 }
3422621Sllai1 sdcmn_err6((
3432621Sllai1 "sdev_ki_call_devfsadm: EBADF, re-binding\n"));
3442621Sllai1 sdev_release_door();
3452621Sllai1 delay(retry * hz);
3462621Sllai1 error = sdev_open_upcall_door();
3472621Sllai1 if (error != 0) {
3482621Sllai1 sdcmn_err6(("sdev_ki_call_devfsadm: "
3492621Sllai1 "EBADF lookup error %d\n", error));
3502621Sllai1 if (!sdev_devfsadm_revoked())
3512621Sllai1 cmn_err(CE_NOTE,
3522621Sllai1 "?unable to invoke devfsadm - "
3532621Sllai1 "please run manually\n");
3542621Sllai1 return (EBADF);
3552621Sllai1 }
3562621Sllai1 break;
3572621Sllai1 case EINVAL:
3582621Sllai1 default:
3592621Sllai1 cmn_err(CE_CONT,
3602621Sllai1 "?sdev: door_ki_upcall unexpected result %d\n",
3612621Sllai1 error);
3622621Sllai1 return (error);
3632621Sllai1 }
3642621Sllai1
3652621Sllai1 darg = save_arg;
3662621Sllai1 }
3672621Sllai1
3682621Sllai1 if (!error) {
3693133Sjg ASSERT((struct sdev_door_res *)(intptr_t)darg.rbuf == resultp);
3702621Sllai1 if (resultp->devfsadm_error != 0) {
3712621Sllai1 sdcmn_err6(("sdev_ki_call_devfsadmd: result %d\n",
3722621Sllai1 resultp->devfsadm_error));
3732621Sllai1 error = resultp->devfsadm_error;
3742621Sllai1 }
3752621Sllai1 } else {
3762621Sllai1 sdcmn_err6(("sdev_ki_call_devfsadmd with error %d\n", error));
3772621Sllai1 }
3782621Sllai1
3792621Sllai1 return (error);
3802621Sllai1 }
3812621Sllai1
3822621Sllai1 static int
sdev_devfsadm_revoked(void)3832621Sllai1 sdev_devfsadm_revoked(void)
3842621Sllai1 {
3852621Sllai1 struct door_info info;
3862621Sllai1 int rv;
3872621Sllai1 extern int sys_shutdown;
3882621Sllai1
3892621Sllai1 if (sys_shutdown) {
3902621Sllai1 sdcmn_err6(("dev: shutdown observed\n"));
3912621Sllai1 return (1);
3922621Sllai1 }
3932621Sllai1
3942621Sllai1 if (sdev_upcall_door && !sdev_upcall_door_revoked) {
3952621Sllai1 rv = door_ki_info(sdev_upcall_door, &info);
3962621Sllai1 if ((rv == 0) && info.di_attributes & DOOR_REVOKED) {
3972621Sllai1 sdcmn_err6(("lookup door: revoked\n"));
3982621Sllai1 sdev_upcall_door_revoked = 1;
3992621Sllai1 }
4002621Sllai1 }
4012621Sllai1
4022621Sllai1 return (sdev_upcall_door_revoked);
4032621Sllai1 }
4042621Sllai1
4052621Sllai1 /*ARGSUSED*/
4062621Sllai1 static void
sdev_config_all_thread(struct sdev_node * dv)4072621Sllai1 sdev_config_all_thread(struct sdev_node *dv)
4082621Sllai1 {
4092621Sllai1 int32_t error = 0;
4102621Sllai1 sdev_door_arg_t *argp;
4112621Sllai1 sdev_door_res_t result;
4122621Sllai1
4132621Sllai1 argp = kmem_zalloc(sizeof (sdev_door_arg_t), KM_SLEEP);
4142621Sllai1 argp->devfsadm_cmd = DEVFSADMD_RUN_ALL;
4152621Sllai1
4162621Sllai1 error = sdev_ki_call_devfsadmd(argp, &result);
4172621Sllai1 if (!error) {
4182621Sllai1 sdcmn_err6(("devfsadm result error: %d\n",
4192621Sllai1 result.devfsadm_error));
4202621Sllai1 if (!result.devfsadm_error) {
4212621Sllai1 DEVNAME_DEVFSADM_SET_RUN(devfsadm_state);
4222621Sllai1 } else {
4232621Sllai1 DEVNAME_DEVFSADM_SET_STOP(devfsadm_state);
4242621Sllai1 }
4252621Sllai1 } else {
4262621Sllai1 DEVNAME_DEVFSADM_SET_STOP(devfsadm_state);
4272621Sllai1 }
4282621Sllai1
4292621Sllai1 kmem_free(argp, sizeof (sdev_door_arg_t));
4302621Sllai1 done:
4312621Sllai1 sdcmn_err6(("sdev_config_all_thread: stopping, devfsadm state 0x%x\n",
4322621Sllai1 devfsadm_state));
4332621Sllai1 thread_exit();
4342621Sllai1 }
4352621Sllai1
4362621Sllai1 /*
4372621Sllai1 * launch an asynchronous thread to do the devfsadm dev_config_all
4382621Sllai1 */
4392621Sllai1 /*ARGSUSED*/
4402621Sllai1 void
sdev_devfsadmd_thread(struct sdev_node * ddv,struct sdev_node * dv,struct cred * cred)4412621Sllai1 sdev_devfsadmd_thread(struct sdev_node *ddv, struct sdev_node *dv,
4422621Sllai1 struct cred *cred)
4432621Sllai1 {
4442621Sllai1 ASSERT(i_ddi_io_initialized());
4452621Sllai1 DEVNAME_DEVFSADM_SET_RUNNING(devfsadm_state);
4462621Sllai1 (void) thread_create(NULL, 0, sdev_config_all_thread, dv, 0,
4472621Sllai1 &p0, TS_RUN, MINCLSYSPRI);
4482621Sllai1 }
4492621Sllai1
4502621Sllai1 int
devname_filename_register(char * name)45110097SEric.Taylor@Sun.COM devname_filename_register(char *name)
4522621Sllai1 {
4532621Sllai1 int error = 0;
4542621Sllai1 char *strbuf;
4552621Sllai1 char *namep;
4562621Sllai1 int n;
4572621Sllai1
4582621Sllai1 strbuf = kmem_zalloc(MOD_MAXPATH, KM_SLEEP);
4592621Sllai1
4602621Sllai1 if (copyinstr(name, strbuf, MOD_MAXPATH, 0)) {
4612621Sllai1 sdcmn_err6(("error copyin \n"));
4622621Sllai1 error = EFAULT;
4632621Sllai1 } else {
4642621Sllai1 sdcmn_err6(("file %s is registering\n", strbuf));
46510097SEric.Taylor@Sun.COM /* handling the daemon re-start situations */
46610097SEric.Taylor@Sun.COM n = strlen(strbuf) + 1;
46710097SEric.Taylor@Sun.COM namep = i_ddi_strdup(strbuf, KM_SLEEP);
46810097SEric.Taylor@Sun.COM mutex_enter(&devfsadm_lock);
46910097SEric.Taylor@Sun.COM sdev_release_door();
47010097SEric.Taylor@Sun.COM sdev_door_upcall_filename_size = n;
47110097SEric.Taylor@Sun.COM sdev_door_upcall_filename = namep;
47210097SEric.Taylor@Sun.COM sdcmn_err6(("size %d file name %s\n",
47310097SEric.Taylor@Sun.COM sdev_door_upcall_filename_size,
47410097SEric.Taylor@Sun.COM sdev_door_upcall_filename));
47510097SEric.Taylor@Sun.COM cv_broadcast(&devfsadm_cv);
47610097SEric.Taylor@Sun.COM mutex_exit(&devfsadm_lock);
4772621Sllai1 }
4782621Sllai1
4792621Sllai1 kmem_free(strbuf, MOD_MAXPATH);
4802621Sllai1 return (error);
4812621Sllai1 }
482