1*789Sahrens /*
2*789Sahrens  * CDDL HEADER START
3*789Sahrens  *
4*789Sahrens  * The contents of this file are subject to the terms of the
5*789Sahrens  * Common Development and Distribution License, Version 1.0 only
6*789Sahrens  * (the "License").  You may not use this file except in compliance
7*789Sahrens  * with the License.
8*789Sahrens  *
9*789Sahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*789Sahrens  * or http://www.opensolaris.org/os/licensing.
11*789Sahrens  * See the License for the specific language governing permissions
12*789Sahrens  * and limitations under the License.
13*789Sahrens  *
14*789Sahrens  * When distributing Covered Code, include this CDDL HEADER in each
15*789Sahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*789Sahrens  * If applicable, add the following below this CDDL HEADER, with the
17*789Sahrens  * fields enclosed by brackets "[]" replaced with your own identifying
18*789Sahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
19*789Sahrens  *
20*789Sahrens  * CDDL HEADER END
21*789Sahrens  */
22*789Sahrens /*
23*789Sahrens  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*789Sahrens  * Use is subject to license terms.
25*789Sahrens  */
26*789Sahrens 
27*789Sahrens #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*789Sahrens 
29*789Sahrens #include <assert.h>
30*789Sahrens #include <sys/zfs_context.h>
31*789Sahrens #include <poll.h>
32*789Sahrens #include <string.h>
33*789Sahrens #include <stdio.h>
34*789Sahrens #include <stdlib.h>
35*789Sahrens #include <fcntl.h>
36*789Sahrens #include <sys/stat.h>
37*789Sahrens #include <sys/spa.h>
38*789Sahrens #include <sys/processor.h>
39*789Sahrens 
40*789Sahrens /*
41*789Sahrens  * Emulation of kernel services in userland.
42*789Sahrens  */
43*789Sahrens 
44*789Sahrens uint64_t physmem;
45*789Sahrens vnode_t *rootdir = (vnode_t *)0xabcd1234;
46*789Sahrens 
47*789Sahrens /*
48*789Sahrens  * =========================================================================
49*789Sahrens  * threads
50*789Sahrens  * =========================================================================
51*789Sahrens  */
52*789Sahrens /*ARGSUSED*/
53*789Sahrens kthread_t *
54*789Sahrens zk_thread_create(void (*func)(), void *arg)
55*789Sahrens {
56*789Sahrens 	thread_t tid;
57*789Sahrens 
58*789Sahrens 	VERIFY(thr_create(0, 0, (void *(*)(void *))func, arg, THR_DETACHED,
59*789Sahrens 	    &tid) == 0);
60*789Sahrens 
61*789Sahrens 	return ((void *)(uintptr_t)tid);
62*789Sahrens }
63*789Sahrens 
64*789Sahrens /*
65*789Sahrens  * =========================================================================
66*789Sahrens  * mutexes
67*789Sahrens  * =========================================================================
68*789Sahrens  */
69*789Sahrens void
70*789Sahrens zmutex_init(kmutex_t *mp)
71*789Sahrens {
72*789Sahrens 	mp->m_owner = NULL;
73*789Sahrens 	(void) _mutex_init(&mp->m_lock, USYNC_THREAD, NULL);
74*789Sahrens }
75*789Sahrens 
76*789Sahrens void
77*789Sahrens zmutex_destroy(kmutex_t *mp)
78*789Sahrens {
79*789Sahrens 	ASSERT(mp->m_owner == NULL);
80*789Sahrens 	(void) _mutex_destroy(&(mp)->m_lock);
81*789Sahrens 	mp->m_owner = (void *)-1UL;
82*789Sahrens }
83*789Sahrens 
84*789Sahrens void
85*789Sahrens mutex_enter(kmutex_t *mp)
86*789Sahrens {
87*789Sahrens 	ASSERT(mp->m_owner != (void *)-1UL);
88*789Sahrens 	ASSERT(mp->m_owner != curthread);
89*789Sahrens 	(void) mutex_lock(&mp->m_lock);
90*789Sahrens 	ASSERT(mp->m_owner == NULL);
91*789Sahrens 	mp->m_owner = curthread;
92*789Sahrens }
93*789Sahrens 
94*789Sahrens int
95*789Sahrens mutex_tryenter(kmutex_t *mp)
96*789Sahrens {
97*789Sahrens 	ASSERT(mp->m_owner != (void *)-1UL);
98*789Sahrens 	if (0 == mutex_trylock(&mp->m_lock)) {
99*789Sahrens 		ASSERT(mp->m_owner == NULL);
100*789Sahrens 		mp->m_owner = curthread;
101*789Sahrens 		return (1);
102*789Sahrens 	} else {
103*789Sahrens 		return (0);
104*789Sahrens 	}
105*789Sahrens }
106*789Sahrens 
107*789Sahrens void
108*789Sahrens mutex_exit(kmutex_t *mp)
109*789Sahrens {
110*789Sahrens 	ASSERT(mutex_owner(mp) == curthread);
111*789Sahrens 	mp->m_owner = NULL;
112*789Sahrens 	(void) mutex_unlock(&mp->m_lock);
113*789Sahrens }
114*789Sahrens 
115*789Sahrens void *
116*789Sahrens mutex_owner(kmutex_t *mp)
117*789Sahrens {
118*789Sahrens 	return (mp->m_owner);
119*789Sahrens }
120*789Sahrens 
121*789Sahrens /*
122*789Sahrens  * =========================================================================
123*789Sahrens  * rwlocks
124*789Sahrens  * =========================================================================
125*789Sahrens  */
126*789Sahrens /*ARGSUSED*/
127*789Sahrens void
128*789Sahrens rw_init(krwlock_t *rwlp, char *name, int type, void *arg)
129*789Sahrens {
130*789Sahrens 	rwlock_init(&rwlp->rw_lock, USYNC_THREAD, NULL);
131*789Sahrens 	rwlp->rw_owner = NULL;
132*789Sahrens }
133*789Sahrens 
134*789Sahrens void
135*789Sahrens rw_destroy(krwlock_t *rwlp)
136*789Sahrens {
137*789Sahrens 	rwlock_destroy(&rwlp->rw_lock);
138*789Sahrens 	rwlp->rw_owner = (void *)-1UL;
139*789Sahrens }
140*789Sahrens 
141*789Sahrens void
142*789Sahrens rw_enter(krwlock_t *rwlp, krw_t rw)
143*789Sahrens {
144*789Sahrens 	ASSERT(!RW_LOCK_HELD(rwlp));
145*789Sahrens 	ASSERT(rwlp->rw_owner != (void *)-1UL);
146*789Sahrens 	ASSERT(rwlp->rw_owner != curthread);
147*789Sahrens 
148*789Sahrens 	if (rw == RW_READER)
149*789Sahrens 		(void) rw_rdlock(&rwlp->rw_lock);
150*789Sahrens 	else
151*789Sahrens 		(void) rw_wrlock(&rwlp->rw_lock);
152*789Sahrens 
153*789Sahrens 	rwlp->rw_owner = curthread;
154*789Sahrens }
155*789Sahrens 
156*789Sahrens void
157*789Sahrens rw_exit(krwlock_t *rwlp)
158*789Sahrens {
159*789Sahrens 	ASSERT(rwlp->rw_owner != (void *)-1UL);
160*789Sahrens 
161*789Sahrens 	rwlp->rw_owner = NULL;
162*789Sahrens 	(void) rw_unlock(&rwlp->rw_lock);
163*789Sahrens }
164*789Sahrens 
165*789Sahrens int
166*789Sahrens rw_tryenter(krwlock_t *rwlp, krw_t rw)
167*789Sahrens {
168*789Sahrens 	int rv;
169*789Sahrens 
170*789Sahrens 	ASSERT(rwlp->rw_owner != (void *)-1UL);
171*789Sahrens 
172*789Sahrens 	if (rw == RW_READER)
173*789Sahrens 		rv = rw_tryrdlock(&rwlp->rw_lock);
174*789Sahrens 	else
175*789Sahrens 		rv = rw_trywrlock(&rwlp->rw_lock);
176*789Sahrens 
177*789Sahrens 	if (rv == 0) {
178*789Sahrens 		rwlp->rw_owner = curthread;
179*789Sahrens 		return (1);
180*789Sahrens 	}
181*789Sahrens 
182*789Sahrens 	return (0);
183*789Sahrens }
184*789Sahrens 
185*789Sahrens /*ARGSUSED*/
186*789Sahrens int
187*789Sahrens rw_tryupgrade(krwlock_t *rwlp)
188*789Sahrens {
189*789Sahrens 	ASSERT(rwlp->rw_owner != (void *)-1UL);
190*789Sahrens 
191*789Sahrens 	return (0);
192*789Sahrens }
193*789Sahrens 
194*789Sahrens /*
195*789Sahrens  * =========================================================================
196*789Sahrens  * condition variables
197*789Sahrens  * =========================================================================
198*789Sahrens  */
199*789Sahrens /*ARGSUSED*/
200*789Sahrens void
201*789Sahrens cv_init(kcondvar_t *cv, char *name, int type, void *arg)
202*789Sahrens {
203*789Sahrens 	(void) cond_init(cv, type, NULL);
204*789Sahrens }
205*789Sahrens 
206*789Sahrens void
207*789Sahrens cv_destroy(kcondvar_t *cv)
208*789Sahrens {
209*789Sahrens 	(void) cond_destroy(cv);
210*789Sahrens }
211*789Sahrens 
212*789Sahrens void
213*789Sahrens cv_wait(kcondvar_t *cv, kmutex_t *mp)
214*789Sahrens {
215*789Sahrens 	ASSERT(mutex_owner(mp) == curthread);
216*789Sahrens 	mp->m_owner = NULL;
217*789Sahrens 	(void) cond_wait(cv, &mp->m_lock);
218*789Sahrens 	mp->m_owner = curthread;
219*789Sahrens }
220*789Sahrens 
221*789Sahrens clock_t
222*789Sahrens cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)
223*789Sahrens {
224*789Sahrens 	int error;
225*789Sahrens 	timestruc_t ts;
226*789Sahrens 	clock_t delta;
227*789Sahrens 
228*789Sahrens top:
229*789Sahrens 	delta = abstime - lbolt;
230*789Sahrens 	if (delta <= 0)
231*789Sahrens 		return (-1);
232*789Sahrens 
233*789Sahrens 	ts.tv_sec = delta / hz;
234*789Sahrens 	ts.tv_nsec = (delta % hz) * (NANOSEC / hz);
235*789Sahrens 
236*789Sahrens 	ASSERT(mutex_owner(mp) == curthread);
237*789Sahrens 	mp->m_owner = NULL;
238*789Sahrens 	error = cond_reltimedwait(cv, &mp->m_lock, &ts);
239*789Sahrens 	mp->m_owner = curthread;
240*789Sahrens 
241*789Sahrens 	if (error == ETIME)
242*789Sahrens 		return (-1);
243*789Sahrens 
244*789Sahrens 	if (error == EINTR)
245*789Sahrens 		goto top;
246*789Sahrens 
247*789Sahrens 	ASSERT(error == 0);
248*789Sahrens 
249*789Sahrens 	return (1);
250*789Sahrens }
251*789Sahrens 
252*789Sahrens void
253*789Sahrens cv_signal(kcondvar_t *cv)
254*789Sahrens {
255*789Sahrens 	(void) cond_signal(cv);
256*789Sahrens }
257*789Sahrens 
258*789Sahrens void
259*789Sahrens cv_broadcast(kcondvar_t *cv)
260*789Sahrens {
261*789Sahrens 	(void) cond_broadcast(cv);
262*789Sahrens }
263*789Sahrens 
264*789Sahrens /*
265*789Sahrens  * =========================================================================
266*789Sahrens  * vnode operations
267*789Sahrens  * =========================================================================
268*789Sahrens  */
269*789Sahrens /*
270*789Sahrens  * Note: for the xxxat() versions of these functions, we assume that the
271*789Sahrens  * starting vp is always rootdir (which is true for spa_directory.c, the only
272*789Sahrens  * ZFS consumer of these interfaces).  We assert this is true, and then emulate
273*789Sahrens  * them by adding '/' in front of the path.
274*789Sahrens  */
275*789Sahrens 
276*789Sahrens /*ARGSUSED*/
277*789Sahrens int
278*789Sahrens vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
279*789Sahrens {
280*789Sahrens 	int fd;
281*789Sahrens 	vnode_t *vp;
282*789Sahrens 	int old_umask;
283*789Sahrens 	char realpath[MAXPATHLEN];
284*789Sahrens 	struct stat64 st;
285*789Sahrens 
286*789Sahrens 	/*
287*789Sahrens 	 * If we're accessing a real disk from userland, we need to use
288*789Sahrens 	 * the character interface to avoid caching.  This is particularly
289*789Sahrens 	 * important if we're trying to look at a real in-kernel storage
290*789Sahrens 	 * pool from userland, e.g. via zdb, because otherwise we won't
291*789Sahrens 	 * see the changes occurring under the segmap cache.
292*789Sahrens 	 * On the other hand, the stupid character device returns zero
293*789Sahrens 	 * for its size.  So -- gag -- we open the block device to get
294*789Sahrens 	 * its size, and remember it for subsequent VOP_GETATTR().
295*789Sahrens 	 */
296*789Sahrens 	if (strncmp(path, "/dev/", 5) == 0) {
297*789Sahrens 		char *dsk;
298*789Sahrens 		fd = open64(path, O_RDONLY);
299*789Sahrens 		if (fd == -1)
300*789Sahrens 			return (errno);
301*789Sahrens 		if (fstat64(fd, &st) == -1) {
302*789Sahrens 			close(fd);
303*789Sahrens 			return (errno);
304*789Sahrens 		}
305*789Sahrens 		close(fd);
306*789Sahrens 		(void) sprintf(realpath, "%s", path);
307*789Sahrens 		dsk = strstr(path, "/dsk/");
308*789Sahrens 		if (dsk != NULL)
309*789Sahrens 			(void) sprintf(realpath + (dsk - path) + 1, "r%s",
310*789Sahrens 			    dsk + 1);
311*789Sahrens 	} else {
312*789Sahrens 		(void) sprintf(realpath, "%s", path);
313*789Sahrens 		if (!(flags & FCREAT) && stat64(realpath, &st) == -1)
314*789Sahrens 			return (errno);
315*789Sahrens 	}
316*789Sahrens 
317*789Sahrens 	if (flags & FCREAT)
318*789Sahrens 		old_umask = umask(0);
319*789Sahrens 
320*789Sahrens 	/*
321*789Sahrens 	 * The construct 'flags - FREAD' conveniently maps combinations of
322*789Sahrens 	 * FREAD and FWRITE to the corresponding O_RDONLY, O_WRONLY, and O_RDWR.
323*789Sahrens 	 */
324*789Sahrens 	fd = open64(realpath, flags - FREAD, mode);
325*789Sahrens 
326*789Sahrens 	if (flags & FCREAT)
327*789Sahrens 		(void) umask(old_umask);
328*789Sahrens 
329*789Sahrens 	if (fd == -1)
330*789Sahrens 		return (errno);
331*789Sahrens 
332*789Sahrens 	if (fstat64(fd, &st) == -1) {
333*789Sahrens 		close(fd);
334*789Sahrens 		return (errno);
335*789Sahrens 	}
336*789Sahrens 
337*789Sahrens 	(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
338*789Sahrens 
339*789Sahrens 	*vpp = vp = umem_zalloc(sizeof (vnode_t), UMEM_NOFAIL);
340*789Sahrens 
341*789Sahrens 	vp->v_fd = fd;
342*789Sahrens 	vp->v_size = st.st_size;
343*789Sahrens 	vp->v_path = spa_strdup(path);
344*789Sahrens 
345*789Sahrens 	return (0);
346*789Sahrens }
347*789Sahrens 
348*789Sahrens int
349*789Sahrens vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2,
350*789Sahrens     int x3, vnode_t *startvp)
351*789Sahrens {
352*789Sahrens 	char *realpath = umem_alloc(strlen(path) + 2, UMEM_NOFAIL);
353*789Sahrens 	int ret;
354*789Sahrens 
355*789Sahrens 	ASSERT(startvp == rootdir);
356*789Sahrens 	(void) sprintf(realpath, "/%s", path);
357*789Sahrens 
358*789Sahrens 	ret = vn_open(realpath, x1, flags, mode, vpp, x2, x3);
359*789Sahrens 
360*789Sahrens 	umem_free(realpath, strlen(path) + 2);
361*789Sahrens 
362*789Sahrens 	return (ret);
363*789Sahrens }
364*789Sahrens 
365*789Sahrens /*ARGSUSED*/
366*789Sahrens int
367*789Sahrens vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
368*789Sahrens 	int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp)
369*789Sahrens {
370*789Sahrens 	ssize_t iolen, split;
371*789Sahrens 
372*789Sahrens 	if (uio == UIO_READ) {
373*789Sahrens 		iolen = pread64(vp->v_fd, addr, len, offset);
374*789Sahrens 	} else {
375*789Sahrens 		/*
376*789Sahrens 		 * To simulate partial disk writes, we split writes into two
377*789Sahrens 		 * system calls so that the process can be killed in between.
378*789Sahrens 		 */
379*789Sahrens 		split = (len > 0 ? rand() % len : 0);
380*789Sahrens 		iolen = pwrite64(vp->v_fd, addr, split, offset);
381*789Sahrens 		iolen += pwrite64(vp->v_fd, (char *)addr + split,
382*789Sahrens 		    len - split, offset + split);
383*789Sahrens 	}
384*789Sahrens 
385*789Sahrens 	if (iolen == -1)
386*789Sahrens 		return (errno);
387*789Sahrens 	if (residp)
388*789Sahrens 		*residp = len - iolen;
389*789Sahrens 	else if (iolen != len)
390*789Sahrens 		return (EIO);
391*789Sahrens 	return (0);
392*789Sahrens }
393*789Sahrens 
394*789Sahrens void
395*789Sahrens vn_close(vnode_t *vp)
396*789Sahrens {
397*789Sahrens 	close(vp->v_fd);
398*789Sahrens 	spa_strfree(vp->v_path);
399*789Sahrens 	umem_free(vp, sizeof (vnode_t));
400*789Sahrens }
401*789Sahrens 
402*789Sahrens #ifdef ZFS_DEBUG
403*789Sahrens 
404*789Sahrens /*
405*789Sahrens  * =========================================================================
406*789Sahrens  * Figure out which debugging statements to print
407*789Sahrens  * =========================================================================
408*789Sahrens  */
409*789Sahrens 
410*789Sahrens static char *dprintf_string;
411*789Sahrens static int dprintf_print_all;
412*789Sahrens 
413*789Sahrens int
414*789Sahrens dprintf_find_string(const char *string)
415*789Sahrens {
416*789Sahrens 	char *tmp_str = dprintf_string;
417*789Sahrens 	int len = strlen(string);
418*789Sahrens 
419*789Sahrens 	/*
420*789Sahrens 	 * Find out if this is a string we want to print.
421*789Sahrens 	 * String format: file1.c,function_name1,file2.c,file3.c
422*789Sahrens 	 */
423*789Sahrens 
424*789Sahrens 	while (tmp_str != NULL) {
425*789Sahrens 		if (strncmp(tmp_str, string, len) == 0 &&
426*789Sahrens 		    (tmp_str[len] == ',' || tmp_str[len] == '\0'))
427*789Sahrens 			return (1);
428*789Sahrens 		tmp_str = strchr(tmp_str, ',');
429*789Sahrens 		if (tmp_str != NULL)
430*789Sahrens 			tmp_str++; /* Get rid of , */
431*789Sahrens 	}
432*789Sahrens 	return (0);
433*789Sahrens }
434*789Sahrens 
435*789Sahrens void
436*789Sahrens dprintf_setup(int *argc, char **argv)
437*789Sahrens {
438*789Sahrens 	int i, j;
439*789Sahrens 
440*789Sahrens 	/*
441*789Sahrens 	 * Debugging can be specified two ways: by setting the
442*789Sahrens 	 * environment variable ZFS_DEBUG, or by including a
443*789Sahrens 	 * "debug=..."  argument on the command line.  The command
444*789Sahrens 	 * line setting overrides the environment variable.
445*789Sahrens 	 */
446*789Sahrens 
447*789Sahrens 	for (i = 1; i < *argc; i++) {
448*789Sahrens 		int len = strlen("debug=");
449*789Sahrens 		/* First look for a command line argument */
450*789Sahrens 		if (strncmp("debug=", argv[i], len) == 0) {
451*789Sahrens 			dprintf_string = argv[i] + len;
452*789Sahrens 			/* Remove from args */
453*789Sahrens 			for (j = i; j < *argc; j++)
454*789Sahrens 				argv[j] = argv[j+1];
455*789Sahrens 			argv[j] = NULL;
456*789Sahrens 			(*argc)--;
457*789Sahrens 		}
458*789Sahrens 	}
459*789Sahrens 
460*789Sahrens 	if (dprintf_string == NULL) {
461*789Sahrens 		/* Look for ZFS_DEBUG environment variable */
462*789Sahrens 		dprintf_string = getenv("ZFS_DEBUG");
463*789Sahrens 	}
464*789Sahrens 
465*789Sahrens 	/*
466*789Sahrens 	 * Are we just turning on all debugging?
467*789Sahrens 	 */
468*789Sahrens 	if (dprintf_find_string("on"))
469*789Sahrens 		dprintf_print_all = 1;
470*789Sahrens }
471*789Sahrens 
472*789Sahrens /*
473*789Sahrens  * =========================================================================
474*789Sahrens  * debug printfs
475*789Sahrens  * =========================================================================
476*789Sahrens  */
477*789Sahrens void
478*789Sahrens __dprintf(const char *file, const char *func, int line, const char *fmt, ...)
479*789Sahrens {
480*789Sahrens 	const char *newfile;
481*789Sahrens 	va_list adx;
482*789Sahrens 
483*789Sahrens 	/*
484*789Sahrens 	 * Get rid of annoying "../common/" prefix to filename.
485*789Sahrens 	 */
486*789Sahrens 	newfile = strrchr(file, '/');
487*789Sahrens 	if (newfile != NULL) {
488*789Sahrens 		newfile = newfile + 1; /* Get rid of leading / */
489*789Sahrens 	} else {
490*789Sahrens 		newfile = file;
491*789Sahrens 	}
492*789Sahrens 
493*789Sahrens 	if (dprintf_print_all ||
494*789Sahrens 	    dprintf_find_string(newfile) ||
495*789Sahrens 	    dprintf_find_string(func)) {
496*789Sahrens 		/* Print out just the function name if requested */
497*789Sahrens 		flockfile(stdout);
498*789Sahrens 		if (dprintf_find_string("pid"))
499*789Sahrens 			(void) printf("%d ", getpid());
500*789Sahrens 		if (dprintf_find_string("tid"))
501*789Sahrens 			(void) printf("%u ", thr_self());
502*789Sahrens 		if (dprintf_find_string("cpu"))
503*789Sahrens 			(void) printf("%u ", getcpuid());
504*789Sahrens 		if (dprintf_find_string("time"))
505*789Sahrens 			(void) printf("%llu ", gethrtime());
506*789Sahrens 		if (dprintf_find_string("long"))
507*789Sahrens 			(void) printf("%s, line %d: ", newfile, line);
508*789Sahrens 		(void) printf("%s: ", func);
509*789Sahrens 		va_start(adx, fmt);
510*789Sahrens 		(void) vprintf(fmt, adx);
511*789Sahrens 		va_end(adx);
512*789Sahrens 		funlockfile(stdout);
513*789Sahrens 	}
514*789Sahrens }
515*789Sahrens 
516*789Sahrens #endif /* ZFS_DEBUG */
517*789Sahrens 
518*789Sahrens /*
519*789Sahrens  * =========================================================================
520*789Sahrens  * cmn_err() and panic()
521*789Sahrens  * =========================================================================
522*789Sahrens  */
523*789Sahrens static char ce_prefix[CE_IGNORE][10] = { "", "NOTICE: ", "WARNING: ", "" };
524*789Sahrens static char ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" };
525*789Sahrens 
526*789Sahrens void
527*789Sahrens vpanic(const char *fmt, va_list adx)
528*789Sahrens {
529*789Sahrens 	(void) fprintf(stderr, "error: ");
530*789Sahrens 	(void) vfprintf(stderr, fmt, adx);
531*789Sahrens 	(void) fprintf(stderr, "\n");
532*789Sahrens 
533*789Sahrens 	abort();	/* think of it as a "user-level crash dump" */
534*789Sahrens }
535*789Sahrens 
536*789Sahrens void
537*789Sahrens panic(const char *fmt, ...)
538*789Sahrens {
539*789Sahrens 	va_list adx;
540*789Sahrens 
541*789Sahrens 	va_start(adx, fmt);
542*789Sahrens 	vpanic(fmt, adx);
543*789Sahrens 	va_end(adx);
544*789Sahrens }
545*789Sahrens 
546*789Sahrens /*PRINTFLIKE2*/
547*789Sahrens void
548*789Sahrens cmn_err(int ce, const char *fmt, ...)
549*789Sahrens {
550*789Sahrens 	va_list adx;
551*789Sahrens 
552*789Sahrens 	va_start(adx, fmt);
553*789Sahrens 	if (ce == CE_PANIC)
554*789Sahrens 		vpanic(fmt, adx);
555*789Sahrens 	if (ce != CE_NOTE) {	/* suppress noise in userland stress testing */
556*789Sahrens 		(void) fprintf(stderr, "%s", ce_prefix[ce]);
557*789Sahrens 		(void) vfprintf(stderr, fmt, adx);
558*789Sahrens 		(void) fprintf(stderr, "%s", ce_suffix[ce]);
559*789Sahrens 	}
560*789Sahrens 	va_end(adx);
561*789Sahrens }
562*789Sahrens 
563*789Sahrens /*
564*789Sahrens  * =========================================================================
565*789Sahrens  * misc routines
566*789Sahrens  * =========================================================================
567*789Sahrens  */
568*789Sahrens 
569*789Sahrens void
570*789Sahrens delay(clock_t ticks)
571*789Sahrens {
572*789Sahrens 	poll(0, 0, ticks * (1000 / hz));
573*789Sahrens }
574*789Sahrens 
575*789Sahrens /*
576*789Sahrens  * Find highest one bit set.
577*789Sahrens  *	Returns bit number + 1 of highest bit that is set, otherwise returns 0.
578*789Sahrens  * High order bit is 31 (or 63 in _LP64 kernel).
579*789Sahrens  */
580*789Sahrens int
581*789Sahrens highbit(ulong_t i)
582*789Sahrens {
583*789Sahrens 	register int h = 1;
584*789Sahrens 
585*789Sahrens 	if (i == 0)
586*789Sahrens 		return (0);
587*789Sahrens #ifdef _LP64
588*789Sahrens 	if (i & 0xffffffff00000000ul) {
589*789Sahrens 		h += 32; i >>= 32;
590*789Sahrens 	}
591*789Sahrens #endif
592*789Sahrens 	if (i & 0xffff0000) {
593*789Sahrens 		h += 16; i >>= 16;
594*789Sahrens 	}
595*789Sahrens 	if (i & 0xff00) {
596*789Sahrens 		h += 8; i >>= 8;
597*789Sahrens 	}
598*789Sahrens 	if (i & 0xf0) {
599*789Sahrens 		h += 4; i >>= 4;
600*789Sahrens 	}
601*789Sahrens 	if (i & 0xc) {
602*789Sahrens 		h += 2; i >>= 2;
603*789Sahrens 	}
604*789Sahrens 	if (i & 0x2) {
605*789Sahrens 		h += 1;
606*789Sahrens 	}
607*789Sahrens 	return (h);
608*789Sahrens }
609*789Sahrens 
610*789Sahrens static int
611*789Sahrens random_get_bytes_common(uint8_t *ptr, size_t len, char *devname)
612*789Sahrens {
613*789Sahrens 	int fd = open(devname, O_RDONLY);
614*789Sahrens 	size_t resid = len;
615*789Sahrens 	ssize_t bytes;
616*789Sahrens 
617*789Sahrens 	ASSERT(fd != -1);
618*789Sahrens 
619*789Sahrens 	while (resid != 0) {
620*789Sahrens 		bytes = read(fd, ptr, resid);
621*789Sahrens 		ASSERT(bytes >= 0);
622*789Sahrens 		ptr += bytes;
623*789Sahrens 		resid -= bytes;
624*789Sahrens 	}
625*789Sahrens 
626*789Sahrens 	close(fd);
627*789Sahrens 
628*789Sahrens 	return (0);
629*789Sahrens }
630*789Sahrens 
631*789Sahrens int
632*789Sahrens random_get_bytes(uint8_t *ptr, size_t len)
633*789Sahrens {
634*789Sahrens 	return (random_get_bytes_common(ptr, len, "/dev/random"));
635*789Sahrens }
636*789Sahrens 
637*789Sahrens int
638*789Sahrens random_get_pseudo_bytes(uint8_t *ptr, size_t len)
639*789Sahrens {
640*789Sahrens 	return (random_get_bytes_common(ptr, len, "/dev/urandom"));
641*789Sahrens }
642*789Sahrens 
643*789Sahrens /*
644*789Sahrens  * =========================================================================
645*789Sahrens  * kernel emulation setup & teardown
646*789Sahrens  * =========================================================================
647*789Sahrens  */
648*789Sahrens static int
649*789Sahrens umem_out_of_memory(void)
650*789Sahrens {
651*789Sahrens 	char errmsg[] = "out of memory -- generating core dump\n";
652*789Sahrens 
653*789Sahrens 	write(fileno(stderr), errmsg, sizeof (errmsg));
654*789Sahrens 	abort();
655*789Sahrens 	return (0);
656*789Sahrens }
657*789Sahrens 
658*789Sahrens void
659*789Sahrens kernel_init(int mode)
660*789Sahrens {
661*789Sahrens 	umem_nofail_callback(umem_out_of_memory);
662*789Sahrens 
663*789Sahrens 	physmem = sysconf(_SC_PHYS_PAGES);
664*789Sahrens 
665*789Sahrens 	dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
666*789Sahrens 	    (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
667*789Sahrens 
668*789Sahrens 	spa_init(mode);
669*789Sahrens }
670*789Sahrens 
671*789Sahrens void
672*789Sahrens kernel_fini(void)
673*789Sahrens {
674*789Sahrens 	spa_fini();
675*789Sahrens }
676