1789Sahrens /*
2789Sahrens  * CDDL HEADER START
3789Sahrens  *
4789Sahrens  * The contents of this file are subject to the terms of the
5*1544Seschrock  * Common Development and Distribution License (the "License").
6*1544Seschrock  * You may not use this file except in compliance with the License.
7789Sahrens  *
8789Sahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9789Sahrens  * or http://www.opensolaris.org/os/licensing.
10789Sahrens  * See the License for the specific language governing permissions
11789Sahrens  * and limitations under the License.
12789Sahrens  *
13789Sahrens  * When distributing Covered Code, include this CDDL HEADER in each
14789Sahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15789Sahrens  * If applicable, add the following below this CDDL HEADER, with the
16789Sahrens  * fields enclosed by brackets "[]" replaced with your own identifying
17789Sahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
18789Sahrens  *
19789Sahrens  * CDDL HEADER END
20789Sahrens  */
21789Sahrens /*
22*1544Seschrock  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23789Sahrens  * Use is subject to license terms.
24789Sahrens  */
25789Sahrens 
26789Sahrens #pragma ident	"%Z%%M%	%I%	%E% SMI"
27789Sahrens 
28789Sahrens #include <assert.h>
29789Sahrens #include <sys/zfs_context.h>
30789Sahrens #include <poll.h>
31789Sahrens #include <string.h>
32789Sahrens #include <stdio.h>
33789Sahrens #include <stdlib.h>
34789Sahrens #include <fcntl.h>
35789Sahrens #include <sys/stat.h>
36789Sahrens #include <sys/spa.h>
37789Sahrens #include <sys/processor.h>
38789Sahrens 
39789Sahrens /*
40789Sahrens  * Emulation of kernel services in userland.
41789Sahrens  */
42789Sahrens 
43789Sahrens uint64_t physmem;
44789Sahrens vnode_t *rootdir = (vnode_t *)0xabcd1234;
45*1544Seschrock int modrootloaded = 0;
46789Sahrens 
47789Sahrens /*
48789Sahrens  * =========================================================================
49789Sahrens  * threads
50789Sahrens  * =========================================================================
51789Sahrens  */
52789Sahrens /*ARGSUSED*/
53789Sahrens kthread_t *
54789Sahrens zk_thread_create(void (*func)(), void *arg)
55789Sahrens {
56789Sahrens 	thread_t tid;
57789Sahrens 
58789Sahrens 	VERIFY(thr_create(0, 0, (void *(*)(void *))func, arg, THR_DETACHED,
59789Sahrens 	    &tid) == 0);
60789Sahrens 
61789Sahrens 	return ((void *)(uintptr_t)tid);
62789Sahrens }
63789Sahrens 
64789Sahrens /*
65789Sahrens  * =========================================================================
66789Sahrens  * mutexes
67789Sahrens  * =========================================================================
68789Sahrens  */
69789Sahrens void
70789Sahrens zmutex_init(kmutex_t *mp)
71789Sahrens {
72789Sahrens 	mp->m_owner = NULL;
73789Sahrens 	(void) _mutex_init(&mp->m_lock, USYNC_THREAD, NULL);
74789Sahrens }
75789Sahrens 
76789Sahrens void
77789Sahrens zmutex_destroy(kmutex_t *mp)
78789Sahrens {
79789Sahrens 	ASSERT(mp->m_owner == NULL);
80789Sahrens 	(void) _mutex_destroy(&(mp)->m_lock);
81789Sahrens 	mp->m_owner = (void *)-1UL;
82789Sahrens }
83789Sahrens 
84789Sahrens void
85789Sahrens mutex_enter(kmutex_t *mp)
86789Sahrens {
87789Sahrens 	ASSERT(mp->m_owner != (void *)-1UL);
88789Sahrens 	ASSERT(mp->m_owner != curthread);
89789Sahrens 	(void) mutex_lock(&mp->m_lock);
90789Sahrens 	ASSERT(mp->m_owner == NULL);
91789Sahrens 	mp->m_owner = curthread;
92789Sahrens }
93789Sahrens 
94789Sahrens int
95789Sahrens mutex_tryenter(kmutex_t *mp)
96789Sahrens {
97789Sahrens 	ASSERT(mp->m_owner != (void *)-1UL);
98789Sahrens 	if (0 == mutex_trylock(&mp->m_lock)) {
99789Sahrens 		ASSERT(mp->m_owner == NULL);
100789Sahrens 		mp->m_owner = curthread;
101789Sahrens 		return (1);
102789Sahrens 	} else {
103789Sahrens 		return (0);
104789Sahrens 	}
105789Sahrens }
106789Sahrens 
107789Sahrens void
108789Sahrens mutex_exit(kmutex_t *mp)
109789Sahrens {
110789Sahrens 	ASSERT(mutex_owner(mp) == curthread);
111789Sahrens 	mp->m_owner = NULL;
112789Sahrens 	(void) mutex_unlock(&mp->m_lock);
113789Sahrens }
114789Sahrens 
115789Sahrens void *
116789Sahrens mutex_owner(kmutex_t *mp)
117789Sahrens {
118789Sahrens 	return (mp->m_owner);
119789Sahrens }
120789Sahrens 
121789Sahrens /*
122789Sahrens  * =========================================================================
123789Sahrens  * rwlocks
124789Sahrens  * =========================================================================
125789Sahrens  */
126789Sahrens /*ARGSUSED*/
127789Sahrens void
128789Sahrens rw_init(krwlock_t *rwlp, char *name, int type, void *arg)
129789Sahrens {
130789Sahrens 	rwlock_init(&rwlp->rw_lock, USYNC_THREAD, NULL);
131789Sahrens 	rwlp->rw_owner = NULL;
132789Sahrens }
133789Sahrens 
134789Sahrens void
135789Sahrens rw_destroy(krwlock_t *rwlp)
136789Sahrens {
137789Sahrens 	rwlock_destroy(&rwlp->rw_lock);
138789Sahrens 	rwlp->rw_owner = (void *)-1UL;
139789Sahrens }
140789Sahrens 
141789Sahrens void
142789Sahrens rw_enter(krwlock_t *rwlp, krw_t rw)
143789Sahrens {
144789Sahrens 	ASSERT(!RW_LOCK_HELD(rwlp));
145789Sahrens 	ASSERT(rwlp->rw_owner != (void *)-1UL);
146789Sahrens 	ASSERT(rwlp->rw_owner != curthread);
147789Sahrens 
148789Sahrens 	if (rw == RW_READER)
149789Sahrens 		(void) rw_rdlock(&rwlp->rw_lock);
150789Sahrens 	else
151789Sahrens 		(void) rw_wrlock(&rwlp->rw_lock);
152789Sahrens 
153789Sahrens 	rwlp->rw_owner = curthread;
154789Sahrens }
155789Sahrens 
156789Sahrens void
157789Sahrens rw_exit(krwlock_t *rwlp)
158789Sahrens {
159789Sahrens 	ASSERT(rwlp->rw_owner != (void *)-1UL);
160789Sahrens 
161789Sahrens 	rwlp->rw_owner = NULL;
162789Sahrens 	(void) rw_unlock(&rwlp->rw_lock);
163789Sahrens }
164789Sahrens 
165789Sahrens int
166789Sahrens rw_tryenter(krwlock_t *rwlp, krw_t rw)
167789Sahrens {
168789Sahrens 	int rv;
169789Sahrens 
170789Sahrens 	ASSERT(rwlp->rw_owner != (void *)-1UL);
171789Sahrens 
172789Sahrens 	if (rw == RW_READER)
173789Sahrens 		rv = rw_tryrdlock(&rwlp->rw_lock);
174789Sahrens 	else
175789Sahrens 		rv = rw_trywrlock(&rwlp->rw_lock);
176789Sahrens 
177789Sahrens 	if (rv == 0) {
178789Sahrens 		rwlp->rw_owner = curthread;
179789Sahrens 		return (1);
180789Sahrens 	}
181789Sahrens 
182789Sahrens 	return (0);
183789Sahrens }
184789Sahrens 
185789Sahrens /*ARGSUSED*/
186789Sahrens int
187789Sahrens rw_tryupgrade(krwlock_t *rwlp)
188789Sahrens {
189789Sahrens 	ASSERT(rwlp->rw_owner != (void *)-1UL);
190789Sahrens 
191789Sahrens 	return (0);
192789Sahrens }
193789Sahrens 
194789Sahrens /*
195789Sahrens  * =========================================================================
196789Sahrens  * condition variables
197789Sahrens  * =========================================================================
198789Sahrens  */
199789Sahrens /*ARGSUSED*/
200789Sahrens void
201789Sahrens cv_init(kcondvar_t *cv, char *name, int type, void *arg)
202789Sahrens {
203789Sahrens 	(void) cond_init(cv, type, NULL);
204789Sahrens }
205789Sahrens 
206789Sahrens void
207789Sahrens cv_destroy(kcondvar_t *cv)
208789Sahrens {
209789Sahrens 	(void) cond_destroy(cv);
210789Sahrens }
211789Sahrens 
212789Sahrens void
213789Sahrens cv_wait(kcondvar_t *cv, kmutex_t *mp)
214789Sahrens {
215789Sahrens 	ASSERT(mutex_owner(mp) == curthread);
216789Sahrens 	mp->m_owner = NULL;
217789Sahrens 	(void) cond_wait(cv, &mp->m_lock);
218789Sahrens 	mp->m_owner = curthread;
219789Sahrens }
220789Sahrens 
221789Sahrens clock_t
222789Sahrens cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)
223789Sahrens {
224789Sahrens 	int error;
225789Sahrens 	timestruc_t ts;
226789Sahrens 	clock_t delta;
227789Sahrens 
228789Sahrens top:
229789Sahrens 	delta = abstime - lbolt;
230789Sahrens 	if (delta <= 0)
231789Sahrens 		return (-1);
232789Sahrens 
233789Sahrens 	ts.tv_sec = delta / hz;
234789Sahrens 	ts.tv_nsec = (delta % hz) * (NANOSEC / hz);
235789Sahrens 
236789Sahrens 	ASSERT(mutex_owner(mp) == curthread);
237789Sahrens 	mp->m_owner = NULL;
238789Sahrens 	error = cond_reltimedwait(cv, &mp->m_lock, &ts);
239789Sahrens 	mp->m_owner = curthread;
240789Sahrens 
241789Sahrens 	if (error == ETIME)
242789Sahrens 		return (-1);
243789Sahrens 
244789Sahrens 	if (error == EINTR)
245789Sahrens 		goto top;
246789Sahrens 
247789Sahrens 	ASSERT(error == 0);
248789Sahrens 
249789Sahrens 	return (1);
250789Sahrens }
251789Sahrens 
252789Sahrens void
253789Sahrens cv_signal(kcondvar_t *cv)
254789Sahrens {
255789Sahrens 	(void) cond_signal(cv);
256789Sahrens }
257789Sahrens 
258789Sahrens void
259789Sahrens cv_broadcast(kcondvar_t *cv)
260789Sahrens {
261789Sahrens 	(void) cond_broadcast(cv);
262789Sahrens }
263789Sahrens 
264789Sahrens /*
265789Sahrens  * =========================================================================
266789Sahrens  * vnode operations
267789Sahrens  * =========================================================================
268789Sahrens  */
269789Sahrens /*
270789Sahrens  * Note: for the xxxat() versions of these functions, we assume that the
271789Sahrens  * starting vp is always rootdir (which is true for spa_directory.c, the only
272789Sahrens  * ZFS consumer of these interfaces).  We assert this is true, and then emulate
273789Sahrens  * them by adding '/' in front of the path.
274789Sahrens  */
275789Sahrens 
276789Sahrens /*ARGSUSED*/
277789Sahrens int
278789Sahrens vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
279789Sahrens {
280789Sahrens 	int fd;
281789Sahrens 	vnode_t *vp;
282789Sahrens 	int old_umask;
283789Sahrens 	char realpath[MAXPATHLEN];
284789Sahrens 	struct stat64 st;
285789Sahrens 
286789Sahrens 	/*
287789Sahrens 	 * If we're accessing a real disk from userland, we need to use
288789Sahrens 	 * the character interface to avoid caching.  This is particularly
289789Sahrens 	 * important if we're trying to look at a real in-kernel storage
290789Sahrens 	 * pool from userland, e.g. via zdb, because otherwise we won't
291789Sahrens 	 * see the changes occurring under the segmap cache.
292789Sahrens 	 * On the other hand, the stupid character device returns zero
293789Sahrens 	 * for its size.  So -- gag -- we open the block device to get
294789Sahrens 	 * its size, and remember it for subsequent VOP_GETATTR().
295789Sahrens 	 */
296789Sahrens 	if (strncmp(path, "/dev/", 5) == 0) {
297789Sahrens 		char *dsk;
298789Sahrens 		fd = open64(path, O_RDONLY);
299789Sahrens 		if (fd == -1)
300789Sahrens 			return (errno);
301789Sahrens 		if (fstat64(fd, &st) == -1) {
302789Sahrens 			close(fd);
303789Sahrens 			return (errno);
304789Sahrens 		}
305789Sahrens 		close(fd);
306789Sahrens 		(void) sprintf(realpath, "%s", path);
307789Sahrens 		dsk = strstr(path, "/dsk/");
308789Sahrens 		if (dsk != NULL)
309789Sahrens 			(void) sprintf(realpath + (dsk - path) + 1, "r%s",
310789Sahrens 			    dsk + 1);
311789Sahrens 	} else {
312789Sahrens 		(void) sprintf(realpath, "%s", path);
313789Sahrens 		if (!(flags & FCREAT) && stat64(realpath, &st) == -1)
314789Sahrens 			return (errno);
315789Sahrens 	}
316789Sahrens 
317789Sahrens 	if (flags & FCREAT)
318789Sahrens 		old_umask = umask(0);
319789Sahrens 
320789Sahrens 	/*
321789Sahrens 	 * The construct 'flags - FREAD' conveniently maps combinations of
322789Sahrens 	 * FREAD and FWRITE to the corresponding O_RDONLY, O_WRONLY, and O_RDWR.
323789Sahrens 	 */
324789Sahrens 	fd = open64(realpath, flags - FREAD, mode);
325789Sahrens 
326789Sahrens 	if (flags & FCREAT)
327789Sahrens 		(void) umask(old_umask);
328789Sahrens 
329789Sahrens 	if (fd == -1)
330789Sahrens 		return (errno);
331789Sahrens 
332789Sahrens 	if (fstat64(fd, &st) == -1) {
333789Sahrens 		close(fd);
334789Sahrens 		return (errno);
335789Sahrens 	}
336789Sahrens 
337789Sahrens 	(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
338789Sahrens 
339789Sahrens 	*vpp = vp = umem_zalloc(sizeof (vnode_t), UMEM_NOFAIL);
340789Sahrens 
341789Sahrens 	vp->v_fd = fd;
342789Sahrens 	vp->v_size = st.st_size;
343789Sahrens 	vp->v_path = spa_strdup(path);
344789Sahrens 
345789Sahrens 	return (0);
346789Sahrens }
347789Sahrens 
348789Sahrens int
349789Sahrens vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2,
350789Sahrens     int x3, vnode_t *startvp)
351789Sahrens {
352789Sahrens 	char *realpath = umem_alloc(strlen(path) + 2, UMEM_NOFAIL);
353789Sahrens 	int ret;
354789Sahrens 
355789Sahrens 	ASSERT(startvp == rootdir);
356789Sahrens 	(void) sprintf(realpath, "/%s", path);
357789Sahrens 
358789Sahrens 	ret = vn_open(realpath, x1, flags, mode, vpp, x2, x3);
359789Sahrens 
360789Sahrens 	umem_free(realpath, strlen(path) + 2);
361789Sahrens 
362789Sahrens 	return (ret);
363789Sahrens }
364789Sahrens 
365789Sahrens /*ARGSUSED*/
366789Sahrens int
367789Sahrens vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
368789Sahrens 	int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp)
369789Sahrens {
370789Sahrens 	ssize_t iolen, split;
371789Sahrens 
372789Sahrens 	if (uio == UIO_READ) {
373789Sahrens 		iolen = pread64(vp->v_fd, addr, len, offset);
374789Sahrens 	} else {
375789Sahrens 		/*
376789Sahrens 		 * To simulate partial disk writes, we split writes into two
377789Sahrens 		 * system calls so that the process can be killed in between.
378789Sahrens 		 */
379789Sahrens 		split = (len > 0 ? rand() % len : 0);
380789Sahrens 		iolen = pwrite64(vp->v_fd, addr, split, offset);
381789Sahrens 		iolen += pwrite64(vp->v_fd, (char *)addr + split,
382789Sahrens 		    len - split, offset + split);
383789Sahrens 	}
384789Sahrens 
385789Sahrens 	if (iolen == -1)
386789Sahrens 		return (errno);
387789Sahrens 	if (residp)
388789Sahrens 		*residp = len - iolen;
389789Sahrens 	else if (iolen != len)
390789Sahrens 		return (EIO);
391789Sahrens 	return (0);
392789Sahrens }
393789Sahrens 
394789Sahrens void
395789Sahrens vn_close(vnode_t *vp)
396789Sahrens {
397789Sahrens 	close(vp->v_fd);
398789Sahrens 	spa_strfree(vp->v_path);
399789Sahrens 	umem_free(vp, sizeof (vnode_t));
400789Sahrens }
401789Sahrens 
402789Sahrens #ifdef ZFS_DEBUG
403789Sahrens 
404789Sahrens /*
405789Sahrens  * =========================================================================
406789Sahrens  * Figure out which debugging statements to print
407789Sahrens  * =========================================================================
408789Sahrens  */
409789Sahrens 
410789Sahrens static char *dprintf_string;
411789Sahrens static int dprintf_print_all;
412789Sahrens 
413789Sahrens int
414789Sahrens dprintf_find_string(const char *string)
415789Sahrens {
416789Sahrens 	char *tmp_str = dprintf_string;
417789Sahrens 	int len = strlen(string);
418789Sahrens 
419789Sahrens 	/*
420789Sahrens 	 * Find out if this is a string we want to print.
421789Sahrens 	 * String format: file1.c,function_name1,file2.c,file3.c
422789Sahrens 	 */
423789Sahrens 
424789Sahrens 	while (tmp_str != NULL) {
425789Sahrens 		if (strncmp(tmp_str, string, len) == 0 &&
426789Sahrens 		    (tmp_str[len] == ',' || tmp_str[len] == '\0'))
427789Sahrens 			return (1);
428789Sahrens 		tmp_str = strchr(tmp_str, ',');
429789Sahrens 		if (tmp_str != NULL)
430789Sahrens 			tmp_str++; /* Get rid of , */
431789Sahrens 	}
432789Sahrens 	return (0);
433789Sahrens }
434789Sahrens 
435789Sahrens void
436789Sahrens dprintf_setup(int *argc, char **argv)
437789Sahrens {
438789Sahrens 	int i, j;
439789Sahrens 
440789Sahrens 	/*
441789Sahrens 	 * Debugging can be specified two ways: by setting the
442789Sahrens 	 * environment variable ZFS_DEBUG, or by including a
443789Sahrens 	 * "debug=..."  argument on the command line.  The command
444789Sahrens 	 * line setting overrides the environment variable.
445789Sahrens 	 */
446789Sahrens 
447789Sahrens 	for (i = 1; i < *argc; i++) {
448789Sahrens 		int len = strlen("debug=");
449789Sahrens 		/* First look for a command line argument */
450789Sahrens 		if (strncmp("debug=", argv[i], len) == 0) {
451789Sahrens 			dprintf_string = argv[i] + len;
452789Sahrens 			/* Remove from args */
453789Sahrens 			for (j = i; j < *argc; j++)
454789Sahrens 				argv[j] = argv[j+1];
455789Sahrens 			argv[j] = NULL;
456789Sahrens 			(*argc)--;
457789Sahrens 		}
458789Sahrens 	}
459789Sahrens 
460789Sahrens 	if (dprintf_string == NULL) {
461789Sahrens 		/* Look for ZFS_DEBUG environment variable */
462789Sahrens 		dprintf_string = getenv("ZFS_DEBUG");
463789Sahrens 	}
464789Sahrens 
465789Sahrens 	/*
466789Sahrens 	 * Are we just turning on all debugging?
467789Sahrens 	 */
468789Sahrens 	if (dprintf_find_string("on"))
469789Sahrens 		dprintf_print_all = 1;
470789Sahrens }
471789Sahrens 
472789Sahrens /*
473789Sahrens  * =========================================================================
474789Sahrens  * debug printfs
475789Sahrens  * =========================================================================
476789Sahrens  */
477789Sahrens void
478789Sahrens __dprintf(const char *file, const char *func, int line, const char *fmt, ...)
479789Sahrens {
480789Sahrens 	const char *newfile;
481789Sahrens 	va_list adx;
482789Sahrens 
483789Sahrens 	/*
484789Sahrens 	 * Get rid of annoying "../common/" prefix to filename.
485789Sahrens 	 */
486789Sahrens 	newfile = strrchr(file, '/');
487789Sahrens 	if (newfile != NULL) {
488789Sahrens 		newfile = newfile + 1; /* Get rid of leading / */
489789Sahrens 	} else {
490789Sahrens 		newfile = file;
491789Sahrens 	}
492789Sahrens 
493789Sahrens 	if (dprintf_print_all ||
494789Sahrens 	    dprintf_find_string(newfile) ||
495789Sahrens 	    dprintf_find_string(func)) {
496789Sahrens 		/* Print out just the function name if requested */
497789Sahrens 		flockfile(stdout);
498789Sahrens 		if (dprintf_find_string("pid"))
499789Sahrens 			(void) printf("%d ", getpid());
500789Sahrens 		if (dprintf_find_string("tid"))
501789Sahrens 			(void) printf("%u ", thr_self());
502789Sahrens 		if (dprintf_find_string("cpu"))
503789Sahrens 			(void) printf("%u ", getcpuid());
504789Sahrens 		if (dprintf_find_string("time"))
505789Sahrens 			(void) printf("%llu ", gethrtime());
506789Sahrens 		if (dprintf_find_string("long"))
507789Sahrens 			(void) printf("%s, line %d: ", newfile, line);
508789Sahrens 		(void) printf("%s: ", func);
509789Sahrens 		va_start(adx, fmt);
510789Sahrens 		(void) vprintf(fmt, adx);
511789Sahrens 		va_end(adx);
512789Sahrens 		funlockfile(stdout);
513789Sahrens 	}
514789Sahrens }
515789Sahrens 
516789Sahrens #endif /* ZFS_DEBUG */
517789Sahrens 
518789Sahrens /*
519789Sahrens  * =========================================================================
520789Sahrens  * cmn_err() and panic()
521789Sahrens  * =========================================================================
522789Sahrens  */
523789Sahrens static char ce_prefix[CE_IGNORE][10] = { "", "NOTICE: ", "WARNING: ", "" };
524789Sahrens static char ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" };
525789Sahrens 
526789Sahrens void
527789Sahrens vpanic(const char *fmt, va_list adx)
528789Sahrens {
529789Sahrens 	(void) fprintf(stderr, "error: ");
530789Sahrens 	(void) vfprintf(stderr, fmt, adx);
531789Sahrens 	(void) fprintf(stderr, "\n");
532789Sahrens 
533789Sahrens 	abort();	/* think of it as a "user-level crash dump" */
534789Sahrens }
535789Sahrens 
536789Sahrens void
537789Sahrens panic(const char *fmt, ...)
538789Sahrens {
539789Sahrens 	va_list adx;
540789Sahrens 
541789Sahrens 	va_start(adx, fmt);
542789Sahrens 	vpanic(fmt, adx);
543789Sahrens 	va_end(adx);
544789Sahrens }
545789Sahrens 
546789Sahrens /*PRINTFLIKE2*/
547789Sahrens void
548789Sahrens cmn_err(int ce, const char *fmt, ...)
549789Sahrens {
550789Sahrens 	va_list adx;
551789Sahrens 
552789Sahrens 	va_start(adx, fmt);
553789Sahrens 	if (ce == CE_PANIC)
554789Sahrens 		vpanic(fmt, adx);
555789Sahrens 	if (ce != CE_NOTE) {	/* suppress noise in userland stress testing */
556789Sahrens 		(void) fprintf(stderr, "%s", ce_prefix[ce]);
557789Sahrens 		(void) vfprintf(stderr, fmt, adx);
558789Sahrens 		(void) fprintf(stderr, "%s", ce_suffix[ce]);
559789Sahrens 	}
560789Sahrens 	va_end(adx);
561789Sahrens }
562789Sahrens 
563789Sahrens /*
564789Sahrens  * =========================================================================
565*1544Seschrock  * kobj interfaces
566*1544Seschrock  * =========================================================================
567*1544Seschrock  */
568*1544Seschrock struct _buf *
569*1544Seschrock kobj_open_file(char *name)
570*1544Seschrock {
571*1544Seschrock 	struct _buf *file;
572*1544Seschrock 	vnode_t *vp;
573*1544Seschrock 
574*1544Seschrock 	/* set vp as the _fd field of the file */
575*1544Seschrock 	if (vn_openat(name, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0, rootdir) != 0)
576*1544Seschrock 		return ((void *)-1UL);
577*1544Seschrock 
578*1544Seschrock 	file = umem_zalloc(sizeof (struct _buf), UMEM_NOFAIL);
579*1544Seschrock 	file->_fd = (intptr_t)vp;
580*1544Seschrock 	return (file);
581*1544Seschrock }
582*1544Seschrock 
583*1544Seschrock int
584*1544Seschrock kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
585*1544Seschrock {
586*1544Seschrock 	ssize_t resid;
587*1544Seschrock 
588*1544Seschrock 	vn_rdwr(UIO_READ, (vnode_t *)file->_fd, buf, size, (offset_t)off,
589*1544Seschrock 	    UIO_SYSSPACE, 0, 0, 0, &resid);
590*1544Seschrock 
591*1544Seschrock 	return (0);
592*1544Seschrock }
593*1544Seschrock 
594*1544Seschrock void
595*1544Seschrock kobj_close_file(struct _buf *file)
596*1544Seschrock {
597*1544Seschrock 	vn_close((vnode_t *)file->_fd);
598*1544Seschrock 	umem_free(file, sizeof (struct _buf));
599*1544Seschrock }
600*1544Seschrock 
601*1544Seschrock int
602*1544Seschrock kobj_fstat(intptr_t fd, struct bootstat *bst)
603*1544Seschrock {
604*1544Seschrock 	struct stat64 st;
605*1544Seschrock 	vnode_t *vp = (vnode_t *)fd;
606*1544Seschrock 	if (fstat64(vp->v_fd, &st) == -1) {
607*1544Seschrock 		vn_close(vp);
608*1544Seschrock 		return (errno);
609*1544Seschrock 	}
610*1544Seschrock 	bst->st_size = (uint64_t)st.st_size;
611*1544Seschrock 	return (0);
612*1544Seschrock }
613*1544Seschrock 
614*1544Seschrock /*
615*1544Seschrock  * =========================================================================
616789Sahrens  * misc routines
617789Sahrens  * =========================================================================
618789Sahrens  */
619789Sahrens 
620789Sahrens void
621789Sahrens delay(clock_t ticks)
622789Sahrens {
623789Sahrens 	poll(0, 0, ticks * (1000 / hz));
624789Sahrens }
625789Sahrens 
626789Sahrens /*
627789Sahrens  * Find highest one bit set.
628789Sahrens  *	Returns bit number + 1 of highest bit that is set, otherwise returns 0.
629789Sahrens  * High order bit is 31 (or 63 in _LP64 kernel).
630789Sahrens  */
631789Sahrens int
632789Sahrens highbit(ulong_t i)
633789Sahrens {
634789Sahrens 	register int h = 1;
635789Sahrens 
636789Sahrens 	if (i == 0)
637789Sahrens 		return (0);
638789Sahrens #ifdef _LP64
639789Sahrens 	if (i & 0xffffffff00000000ul) {
640789Sahrens 		h += 32; i >>= 32;
641789Sahrens 	}
642789Sahrens #endif
643789Sahrens 	if (i & 0xffff0000) {
644789Sahrens 		h += 16; i >>= 16;
645789Sahrens 	}
646789Sahrens 	if (i & 0xff00) {
647789Sahrens 		h += 8; i >>= 8;
648789Sahrens 	}
649789Sahrens 	if (i & 0xf0) {
650789Sahrens 		h += 4; i >>= 4;
651789Sahrens 	}
652789Sahrens 	if (i & 0xc) {
653789Sahrens 		h += 2; i >>= 2;
654789Sahrens 	}
655789Sahrens 	if (i & 0x2) {
656789Sahrens 		h += 1;
657789Sahrens 	}
658789Sahrens 	return (h);
659789Sahrens }
660789Sahrens 
661789Sahrens static int
662789Sahrens random_get_bytes_common(uint8_t *ptr, size_t len, char *devname)
663789Sahrens {
664789Sahrens 	int fd = open(devname, O_RDONLY);
665789Sahrens 	size_t resid = len;
666789Sahrens 	ssize_t bytes;
667789Sahrens 
668789Sahrens 	ASSERT(fd != -1);
669789Sahrens 
670789Sahrens 	while (resid != 0) {
671789Sahrens 		bytes = read(fd, ptr, resid);
672789Sahrens 		ASSERT(bytes >= 0);
673789Sahrens 		ptr += bytes;
674789Sahrens 		resid -= bytes;
675789Sahrens 	}
676789Sahrens 
677789Sahrens 	close(fd);
678789Sahrens 
679789Sahrens 	return (0);
680789Sahrens }
681789Sahrens 
682789Sahrens int
683789Sahrens random_get_bytes(uint8_t *ptr, size_t len)
684789Sahrens {
685789Sahrens 	return (random_get_bytes_common(ptr, len, "/dev/random"));
686789Sahrens }
687789Sahrens 
688789Sahrens int
689789Sahrens random_get_pseudo_bytes(uint8_t *ptr, size_t len)
690789Sahrens {
691789Sahrens 	return (random_get_bytes_common(ptr, len, "/dev/urandom"));
692789Sahrens }
693789Sahrens 
694789Sahrens /*
695789Sahrens  * =========================================================================
696789Sahrens  * kernel emulation setup & teardown
697789Sahrens  * =========================================================================
698789Sahrens  */
699789Sahrens static int
700789Sahrens umem_out_of_memory(void)
701789Sahrens {
702789Sahrens 	char errmsg[] = "out of memory -- generating core dump\n";
703789Sahrens 
704789Sahrens 	write(fileno(stderr), errmsg, sizeof (errmsg));
705789Sahrens 	abort();
706789Sahrens 	return (0);
707789Sahrens }
708789Sahrens 
709789Sahrens void
710789Sahrens kernel_init(int mode)
711789Sahrens {
712789Sahrens 	umem_nofail_callback(umem_out_of_memory);
713789Sahrens 
714789Sahrens 	physmem = sysconf(_SC_PHYS_PAGES);
715789Sahrens 
716789Sahrens 	dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
717789Sahrens 	    (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
718789Sahrens 
719789Sahrens 	spa_init(mode);
720789Sahrens }
721789Sahrens 
722789Sahrens void
723789Sahrens kernel_fini(void)
724789Sahrens {
725789Sahrens 	spa_fini();
726789Sahrens }
727