xref: /illumos-gate/usr/src/uts/common/fs/dev/sdev_comm.c (revision d3d50737)
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
sdev_devfsadm_lockinit(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
sdev_devfsadm_lockdestroy(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
sdev_wait4lookup(struct sdev_node * dv,int cmd)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
sdev_unblock_others(struct sdev_node * dv,uint_t cmd)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
sdev_start_devfsadmd()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
sdev_open_upcall_door()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
sdev_release_door()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
sdev_ki_call_devfsadmd(sdev_door_arg_t * argp,sdev_door_res_t * resultp)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
sdev_devfsadm_revoked(void)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
sdev_config_all_thread(struct sdev_node * dv)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
sdev_devfsadmd_thread(struct sdev_node * ddv,struct sdev_node * dv,struct cred * cred)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
devname_filename_register(char * name)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