1789Sahrens /*
2789Sahrens  * CDDL HEADER START
3789Sahrens  *
4789Sahrens  * The contents of this file are subject to the terms of the
51544Seschrock  * Common Development and Distribution License (the "License").
61544Seschrock  * 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*8662SJordan.Vaughan@Sun.com  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23789Sahrens  * Use is subject to license terms.
24789Sahrens  */
25789Sahrens 
26789Sahrens #include <assert.h>
273886Sahl #include <fcntl.h>
28789Sahrens #include <poll.h>
29789Sahrens #include <stdio.h>
30789Sahrens #include <stdlib.h>
313886Sahl #include <string.h>
323886Sahl #include <zlib.h>
33789Sahrens #include <sys/spa.h>
343886Sahl #include <sys/stat.h>
35789Sahrens #include <sys/processor.h>
363886Sahl #include <sys/zfs_context.h>
373886Sahl #include <sys/zmod.h>
383975Sek110237 #include <sys/utsname.h>
39*8662SJordan.Vaughan@Sun.com #include <sys/systeminfo.h>
402856Snd150628 
41789Sahrens /*
42789Sahrens  * Emulation of kernel services in userland.
43789Sahrens  */
44789Sahrens 
45789Sahrens uint64_t physmem;
46789Sahrens vnode_t *rootdir = (vnode_t *)0xabcd1234;
47*8662SJordan.Vaughan@Sun.com char hw_serial[HW_HOSTID_LEN];
483975Sek110237 
493975Sek110237 struct utsname utsname = {
503975Sek110237 	"userland", "libzpool", "1", "1", "na"
513975Sek110237 };
52789Sahrens 
53789Sahrens /*
54789Sahrens  * =========================================================================
55789Sahrens  * threads
56789Sahrens  * =========================================================================
57789Sahrens  */
58789Sahrens /*ARGSUSED*/
59789Sahrens kthread_t *
60789Sahrens zk_thread_create(void (*func)(), void *arg)
61789Sahrens {
62789Sahrens 	thread_t tid;
63789Sahrens 
64789Sahrens 	VERIFY(thr_create(0, 0, (void *(*)(void *))func, arg, THR_DETACHED,
65789Sahrens 	    &tid) == 0);
66789Sahrens 
67789Sahrens 	return ((void *)(uintptr_t)tid);
68789Sahrens }
69789Sahrens 
70789Sahrens /*
71789Sahrens  * =========================================================================
723403Sbmc  * kstats
733403Sbmc  * =========================================================================
743403Sbmc  */
753403Sbmc /*ARGSUSED*/
763403Sbmc kstat_t *
773403Sbmc kstat_create(char *module, int instance, char *name, char *class,
783403Sbmc     uchar_t type, ulong_t ndata, uchar_t ks_flag)
793403Sbmc {
803403Sbmc 	return (NULL);
813403Sbmc }
823403Sbmc 
833403Sbmc /*ARGSUSED*/
843403Sbmc void
853403Sbmc kstat_install(kstat_t *ksp)
863403Sbmc {}
873403Sbmc 
883403Sbmc /*ARGSUSED*/
893403Sbmc void
903403Sbmc kstat_delete(kstat_t *ksp)
913403Sbmc {}
923403Sbmc 
933403Sbmc /*
943403Sbmc  * =========================================================================
95789Sahrens  * mutexes
96789Sahrens  * =========================================================================
97789Sahrens  */
98789Sahrens void
99789Sahrens zmutex_init(kmutex_t *mp)
100789Sahrens {
101789Sahrens 	mp->m_owner = NULL;
1024831Sgw25295 	mp->initialized = B_TRUE;
103789Sahrens 	(void) _mutex_init(&mp->m_lock, USYNC_THREAD, NULL);
104789Sahrens }
105789Sahrens 
106789Sahrens void
107789Sahrens zmutex_destroy(kmutex_t *mp)
108789Sahrens {
1094831Sgw25295 	ASSERT(mp->initialized == B_TRUE);
110789Sahrens 	ASSERT(mp->m_owner == NULL);
111789Sahrens 	(void) _mutex_destroy(&(mp)->m_lock);
112789Sahrens 	mp->m_owner = (void *)-1UL;
1134831Sgw25295 	mp->initialized = B_FALSE;
114789Sahrens }
115789Sahrens 
116789Sahrens void
117789Sahrens mutex_enter(kmutex_t *mp)
118789Sahrens {
1194831Sgw25295 	ASSERT(mp->initialized == B_TRUE);
120789Sahrens 	ASSERT(mp->m_owner != (void *)-1UL);
121789Sahrens 	ASSERT(mp->m_owner != curthread);
1222856Snd150628 	VERIFY(mutex_lock(&mp->m_lock) == 0);
123789Sahrens 	ASSERT(mp->m_owner == NULL);
124789Sahrens 	mp->m_owner = curthread;
125789Sahrens }
126789Sahrens 
127789Sahrens int
128789Sahrens mutex_tryenter(kmutex_t *mp)
129789Sahrens {
1304831Sgw25295 	ASSERT(mp->initialized == B_TRUE);
131789Sahrens 	ASSERT(mp->m_owner != (void *)-1UL);
132789Sahrens 	if (0 == mutex_trylock(&mp->m_lock)) {
133789Sahrens 		ASSERT(mp->m_owner == NULL);
134789Sahrens 		mp->m_owner = curthread;
135789Sahrens 		return (1);
136789Sahrens 	} else {
137789Sahrens 		return (0);
138789Sahrens 	}
139789Sahrens }
140789Sahrens 
141789Sahrens void
142789Sahrens mutex_exit(kmutex_t *mp)
143789Sahrens {
1444831Sgw25295 	ASSERT(mp->initialized == B_TRUE);
145789Sahrens 	ASSERT(mutex_owner(mp) == curthread);
146789Sahrens 	mp->m_owner = NULL;
1472856Snd150628 	VERIFY(mutex_unlock(&mp->m_lock) == 0);
148789Sahrens }
149789Sahrens 
150789Sahrens void *
151789Sahrens mutex_owner(kmutex_t *mp)
152789Sahrens {
1534831Sgw25295 	ASSERT(mp->initialized == B_TRUE);
154789Sahrens 	return (mp->m_owner);
155789Sahrens }
156789Sahrens 
157789Sahrens /*
158789Sahrens  * =========================================================================
159789Sahrens  * rwlocks
160789Sahrens  * =========================================================================
161789Sahrens  */
162789Sahrens /*ARGSUSED*/
163789Sahrens void
164789Sahrens rw_init(krwlock_t *rwlp, char *name, int type, void *arg)
165789Sahrens {
166789Sahrens 	rwlock_init(&rwlp->rw_lock, USYNC_THREAD, NULL);
167789Sahrens 	rwlp->rw_owner = NULL;
1684831Sgw25295 	rwlp->initialized = B_TRUE;
169789Sahrens }
170789Sahrens 
171789Sahrens void
172789Sahrens rw_destroy(krwlock_t *rwlp)
173789Sahrens {
174789Sahrens 	rwlock_destroy(&rwlp->rw_lock);
175789Sahrens 	rwlp->rw_owner = (void *)-1UL;
1764831Sgw25295 	rwlp->initialized = B_FALSE;
177789Sahrens }
178789Sahrens 
179789Sahrens void
180789Sahrens rw_enter(krwlock_t *rwlp, krw_t rw)
181789Sahrens {
182789Sahrens 	ASSERT(!RW_LOCK_HELD(rwlp));
1834831Sgw25295 	ASSERT(rwlp->initialized == B_TRUE);
184789Sahrens 	ASSERT(rwlp->rw_owner != (void *)-1UL);
185789Sahrens 	ASSERT(rwlp->rw_owner != curthread);
186789Sahrens 
187789Sahrens 	if (rw == RW_READER)
1886689Smaybee 		VERIFY(rw_rdlock(&rwlp->rw_lock) == 0);
189789Sahrens 	else
1906689Smaybee 		VERIFY(rw_wrlock(&rwlp->rw_lock) == 0);
191789Sahrens 
192789Sahrens 	rwlp->rw_owner = curthread;
193789Sahrens }
194789Sahrens 
195789Sahrens void
196789Sahrens rw_exit(krwlock_t *rwlp)
197789Sahrens {
1984831Sgw25295 	ASSERT(rwlp->initialized == B_TRUE);
199789Sahrens 	ASSERT(rwlp->rw_owner != (void *)-1UL);
200789Sahrens 
201789Sahrens 	rwlp->rw_owner = NULL;
2026689Smaybee 	VERIFY(rw_unlock(&rwlp->rw_lock) == 0);
203789Sahrens }
204789Sahrens 
205789Sahrens int
206789Sahrens rw_tryenter(krwlock_t *rwlp, krw_t rw)
207789Sahrens {
208789Sahrens 	int rv;
209789Sahrens 
2104831Sgw25295 	ASSERT(rwlp->initialized == B_TRUE);
211789Sahrens 	ASSERT(rwlp->rw_owner != (void *)-1UL);
212789Sahrens 
213789Sahrens 	if (rw == RW_READER)
214789Sahrens 		rv = rw_tryrdlock(&rwlp->rw_lock);
215789Sahrens 	else
216789Sahrens 		rv = rw_trywrlock(&rwlp->rw_lock);
217789Sahrens 
218789Sahrens 	if (rv == 0) {
219789Sahrens 		rwlp->rw_owner = curthread;
220789Sahrens 		return (1);
221789Sahrens 	}
222789Sahrens 
223789Sahrens 	return (0);
224789Sahrens }
225789Sahrens 
226789Sahrens /*ARGSUSED*/
227789Sahrens int
228789Sahrens rw_tryupgrade(krwlock_t *rwlp)
229789Sahrens {
2304831Sgw25295 	ASSERT(rwlp->initialized == B_TRUE);
231789Sahrens 	ASSERT(rwlp->rw_owner != (void *)-1UL);
232789Sahrens 
233789Sahrens 	return (0);
234789Sahrens }
235789Sahrens 
236789Sahrens /*
237789Sahrens  * =========================================================================
238789Sahrens  * condition variables
239789Sahrens  * =========================================================================
240789Sahrens  */
241789Sahrens /*ARGSUSED*/
242789Sahrens void
243789Sahrens cv_init(kcondvar_t *cv, char *name, int type, void *arg)
244789Sahrens {
2452856Snd150628 	VERIFY(cond_init(cv, type, NULL) == 0);
246789Sahrens }
247789Sahrens 
248789Sahrens void
249789Sahrens cv_destroy(kcondvar_t *cv)
250789Sahrens {
2512856Snd150628 	VERIFY(cond_destroy(cv) == 0);
252789Sahrens }
253789Sahrens 
254789Sahrens void
255789Sahrens cv_wait(kcondvar_t *cv, kmutex_t *mp)
256789Sahrens {
257789Sahrens 	ASSERT(mutex_owner(mp) == curthread);
258789Sahrens 	mp->m_owner = NULL;
2592856Snd150628 	int ret = cond_wait(cv, &mp->m_lock);
2602856Snd150628 	VERIFY(ret == 0 || ret == EINTR);
261789Sahrens 	mp->m_owner = curthread;
262789Sahrens }
263789Sahrens 
264789Sahrens clock_t
265789Sahrens cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)
266789Sahrens {
267789Sahrens 	int error;
268789Sahrens 	timestruc_t ts;
269789Sahrens 	clock_t delta;
270789Sahrens 
271789Sahrens top:
272789Sahrens 	delta = abstime - lbolt;
273789Sahrens 	if (delta <= 0)
274789Sahrens 		return (-1);
275789Sahrens 
276789Sahrens 	ts.tv_sec = delta / hz;
277789Sahrens 	ts.tv_nsec = (delta % hz) * (NANOSEC / hz);
278789Sahrens 
279789Sahrens 	ASSERT(mutex_owner(mp) == curthread);
280789Sahrens 	mp->m_owner = NULL;
281789Sahrens 	error = cond_reltimedwait(cv, &mp->m_lock, &ts);
282789Sahrens 	mp->m_owner = curthread;
283789Sahrens 
284789Sahrens 	if (error == ETIME)
285789Sahrens 		return (-1);
286789Sahrens 
287789Sahrens 	if (error == EINTR)
288789Sahrens 		goto top;
289789Sahrens 
290789Sahrens 	ASSERT(error == 0);
291789Sahrens 
292789Sahrens 	return (1);
293789Sahrens }
294789Sahrens 
295789Sahrens void
296789Sahrens cv_signal(kcondvar_t *cv)
297789Sahrens {
2982856Snd150628 	VERIFY(cond_signal(cv) == 0);
299789Sahrens }
300789Sahrens 
301789Sahrens void
302789Sahrens cv_broadcast(kcondvar_t *cv)
303789Sahrens {
3042856Snd150628 	VERIFY(cond_broadcast(cv) == 0);
305789Sahrens }
306789Sahrens 
307789Sahrens /*
308789Sahrens  * =========================================================================
309789Sahrens  * vnode operations
310789Sahrens  * =========================================================================
311789Sahrens  */
312789Sahrens /*
313789Sahrens  * Note: for the xxxat() versions of these functions, we assume that the
314789Sahrens  * starting vp is always rootdir (which is true for spa_directory.c, the only
315789Sahrens  * ZFS consumer of these interfaces).  We assert this is true, and then emulate
316789Sahrens  * them by adding '/' in front of the path.
317789Sahrens  */
318789Sahrens 
319789Sahrens /*ARGSUSED*/
320789Sahrens int
321789Sahrens vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
322789Sahrens {
323789Sahrens 	int fd;
324789Sahrens 	vnode_t *vp;
325789Sahrens 	int old_umask;
326789Sahrens 	char realpath[MAXPATHLEN];
327789Sahrens 	struct stat64 st;
328789Sahrens 
329789Sahrens 	/*
330789Sahrens 	 * If we're accessing a real disk from userland, we need to use
331789Sahrens 	 * the character interface to avoid caching.  This is particularly
332789Sahrens 	 * important if we're trying to look at a real in-kernel storage
333789Sahrens 	 * pool from userland, e.g. via zdb, because otherwise we won't
334789Sahrens 	 * see the changes occurring under the segmap cache.
335789Sahrens 	 * On the other hand, the stupid character device returns zero
336789Sahrens 	 * for its size.  So -- gag -- we open the block device to get
337789Sahrens 	 * its size, and remember it for subsequent VOP_GETATTR().
338789Sahrens 	 */
339789Sahrens 	if (strncmp(path, "/dev/", 5) == 0) {
340789Sahrens 		char *dsk;
341789Sahrens 		fd = open64(path, O_RDONLY);
342789Sahrens 		if (fd == -1)
343789Sahrens 			return (errno);
344789Sahrens 		if (fstat64(fd, &st) == -1) {
345789Sahrens 			close(fd);
346789Sahrens 			return (errno);
347789Sahrens 		}
348789Sahrens 		close(fd);
349789Sahrens 		(void) sprintf(realpath, "%s", path);
350789Sahrens 		dsk = strstr(path, "/dsk/");
351789Sahrens 		if (dsk != NULL)
352789Sahrens 			(void) sprintf(realpath + (dsk - path) + 1, "r%s",
353789Sahrens 			    dsk + 1);
354789Sahrens 	} else {
355789Sahrens 		(void) sprintf(realpath, "%s", path);
356789Sahrens 		if (!(flags & FCREAT) && stat64(realpath, &st) == -1)
357789Sahrens 			return (errno);
358789Sahrens 	}
359789Sahrens 
360789Sahrens 	if (flags & FCREAT)
361789Sahrens 		old_umask = umask(0);
362789Sahrens 
363789Sahrens 	/*
364789Sahrens 	 * The construct 'flags - FREAD' conveniently maps combinations of
365789Sahrens 	 * FREAD and FWRITE to the corresponding O_RDONLY, O_WRONLY, and O_RDWR.
366789Sahrens 	 */
367789Sahrens 	fd = open64(realpath, flags - FREAD, mode);
368789Sahrens 
369789Sahrens 	if (flags & FCREAT)
370789Sahrens 		(void) umask(old_umask);
371789Sahrens 
372789Sahrens 	if (fd == -1)
373789Sahrens 		return (errno);
374789Sahrens 
375789Sahrens 	if (fstat64(fd, &st) == -1) {
376789Sahrens 		close(fd);
377789Sahrens 		return (errno);
378789Sahrens 	}
379789Sahrens 
380789Sahrens 	(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
381789Sahrens 
382789Sahrens 	*vpp = vp = umem_zalloc(sizeof (vnode_t), UMEM_NOFAIL);
383789Sahrens 
384789Sahrens 	vp->v_fd = fd;
385789Sahrens 	vp->v_size = st.st_size;
386789Sahrens 	vp->v_path = spa_strdup(path);
387789Sahrens 
388789Sahrens 	return (0);
389789Sahrens }
390789Sahrens 
3915331Samw /*ARGSUSED*/
392789Sahrens int
393789Sahrens vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2,
3945331Samw     int x3, vnode_t *startvp, int fd)
395789Sahrens {
396789Sahrens 	char *realpath = umem_alloc(strlen(path) + 2, UMEM_NOFAIL);
397789Sahrens 	int ret;
398789Sahrens 
399789Sahrens 	ASSERT(startvp == rootdir);
400789Sahrens 	(void) sprintf(realpath, "/%s", path);
401789Sahrens 
4025331Samw 	/* fd ignored for now, need if want to simulate nbmand support */
403789Sahrens 	ret = vn_open(realpath, x1, flags, mode, vpp, x2, x3);
404789Sahrens 
405789Sahrens 	umem_free(realpath, strlen(path) + 2);
406789Sahrens 
407789Sahrens 	return (ret);
408789Sahrens }
409789Sahrens 
410789Sahrens /*ARGSUSED*/
411789Sahrens int
412789Sahrens vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
413789Sahrens 	int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp)
414789Sahrens {
415789Sahrens 	ssize_t iolen, split;
416789Sahrens 
417789Sahrens 	if (uio == UIO_READ) {
418789Sahrens 		iolen = pread64(vp->v_fd, addr, len, offset);
419789Sahrens 	} else {
420789Sahrens 		/*
421789Sahrens 		 * To simulate partial disk writes, we split writes into two
422789Sahrens 		 * system calls so that the process can be killed in between.
423789Sahrens 		 */
424789Sahrens 		split = (len > 0 ? rand() % len : 0);
425789Sahrens 		iolen = pwrite64(vp->v_fd, addr, split, offset);
426789Sahrens 		iolen += pwrite64(vp->v_fd, (char *)addr + split,
427789Sahrens 		    len - split, offset + split);
428789Sahrens 	}
429789Sahrens 
430789Sahrens 	if (iolen == -1)
431789Sahrens 		return (errno);
432789Sahrens 	if (residp)
433789Sahrens 		*residp = len - iolen;
434789Sahrens 	else if (iolen != len)
435789Sahrens 		return (EIO);
436789Sahrens 	return (0);
437789Sahrens }
438789Sahrens 
439789Sahrens void
440789Sahrens vn_close(vnode_t *vp)
441789Sahrens {
442789Sahrens 	close(vp->v_fd);
443789Sahrens 	spa_strfree(vp->v_path);
444789Sahrens 	umem_free(vp, sizeof (vnode_t));
445789Sahrens }
446789Sahrens 
447789Sahrens #ifdef ZFS_DEBUG
448789Sahrens 
449789Sahrens /*
450789Sahrens  * =========================================================================
451789Sahrens  * Figure out which debugging statements to print
452789Sahrens  * =========================================================================
453789Sahrens  */
454789Sahrens 
455789Sahrens static char *dprintf_string;
456789Sahrens static int dprintf_print_all;
457789Sahrens 
458789Sahrens int
459789Sahrens dprintf_find_string(const char *string)
460789Sahrens {
461789Sahrens 	char *tmp_str = dprintf_string;
462789Sahrens 	int len = strlen(string);
463789Sahrens 
464789Sahrens 	/*
465789Sahrens 	 * Find out if this is a string we want to print.
466789Sahrens 	 * String format: file1.c,function_name1,file2.c,file3.c
467789Sahrens 	 */
468789Sahrens 
469789Sahrens 	while (tmp_str != NULL) {
470789Sahrens 		if (strncmp(tmp_str, string, len) == 0 &&
471789Sahrens 		    (tmp_str[len] == ',' || tmp_str[len] == '\0'))
472789Sahrens 			return (1);
473789Sahrens 		tmp_str = strchr(tmp_str, ',');
474789Sahrens 		if (tmp_str != NULL)
475789Sahrens 			tmp_str++; /* Get rid of , */
476789Sahrens 	}
477789Sahrens 	return (0);
478789Sahrens }
479789Sahrens 
480789Sahrens void
481789Sahrens dprintf_setup(int *argc, char **argv)
482789Sahrens {
483789Sahrens 	int i, j;
484789Sahrens 
485789Sahrens 	/*
486789Sahrens 	 * Debugging can be specified two ways: by setting the
487789Sahrens 	 * environment variable ZFS_DEBUG, or by including a
488789Sahrens 	 * "debug=..."  argument on the command line.  The command
489789Sahrens 	 * line setting overrides the environment variable.
490789Sahrens 	 */
491789Sahrens 
492789Sahrens 	for (i = 1; i < *argc; i++) {
493789Sahrens 		int len = strlen("debug=");
494789Sahrens 		/* First look for a command line argument */
495789Sahrens 		if (strncmp("debug=", argv[i], len) == 0) {
496789Sahrens 			dprintf_string = argv[i] + len;
497789Sahrens 			/* Remove from args */
498789Sahrens 			for (j = i; j < *argc; j++)
499789Sahrens 				argv[j] = argv[j+1];
500789Sahrens 			argv[j] = NULL;
501789Sahrens 			(*argc)--;
502789Sahrens 		}
503789Sahrens 	}
504789Sahrens 
505789Sahrens 	if (dprintf_string == NULL) {
506789Sahrens 		/* Look for ZFS_DEBUG environment variable */
507789Sahrens 		dprintf_string = getenv("ZFS_DEBUG");
508789Sahrens 	}
509789Sahrens 
510789Sahrens 	/*
511789Sahrens 	 * Are we just turning on all debugging?
512789Sahrens 	 */
513789Sahrens 	if (dprintf_find_string("on"))
514789Sahrens 		dprintf_print_all = 1;
515789Sahrens }
516789Sahrens 
517789Sahrens /*
518789Sahrens  * =========================================================================
519789Sahrens  * debug printfs
520789Sahrens  * =========================================================================
521789Sahrens  */
522789Sahrens void
523789Sahrens __dprintf(const char *file, const char *func, int line, const char *fmt, ...)
524789Sahrens {
525789Sahrens 	const char *newfile;
526789Sahrens 	va_list adx;
527789Sahrens 
528789Sahrens 	/*
529789Sahrens 	 * Get rid of annoying "../common/" prefix to filename.
530789Sahrens 	 */
531789Sahrens 	newfile = strrchr(file, '/');
532789Sahrens 	if (newfile != NULL) {
533789Sahrens 		newfile = newfile + 1; /* Get rid of leading / */
534789Sahrens 	} else {
535789Sahrens 		newfile = file;
536789Sahrens 	}
537789Sahrens 
538789Sahrens 	if (dprintf_print_all ||
539789Sahrens 	    dprintf_find_string(newfile) ||
540789Sahrens 	    dprintf_find_string(func)) {
541789Sahrens 		/* Print out just the function name if requested */
542789Sahrens 		flockfile(stdout);
543789Sahrens 		if (dprintf_find_string("pid"))
544789Sahrens 			(void) printf("%d ", getpid());
545789Sahrens 		if (dprintf_find_string("tid"))
546789Sahrens 			(void) printf("%u ", thr_self());
547789Sahrens 		if (dprintf_find_string("cpu"))
548789Sahrens 			(void) printf("%u ", getcpuid());
549789Sahrens 		if (dprintf_find_string("time"))
550789Sahrens 			(void) printf("%llu ", gethrtime());
551789Sahrens 		if (dprintf_find_string("long"))
552789Sahrens 			(void) printf("%s, line %d: ", newfile, line);
553789Sahrens 		(void) printf("%s: ", func);
554789Sahrens 		va_start(adx, fmt);
555789Sahrens 		(void) vprintf(fmt, adx);
556789Sahrens 		va_end(adx);
557789Sahrens 		funlockfile(stdout);
558789Sahrens 	}
559789Sahrens }
560789Sahrens 
561789Sahrens #endif /* ZFS_DEBUG */
562789Sahrens 
563789Sahrens /*
564789Sahrens  * =========================================================================
565789Sahrens  * cmn_err() and panic()
566789Sahrens  * =========================================================================
567789Sahrens  */
568789Sahrens static char ce_prefix[CE_IGNORE][10] = { "", "NOTICE: ", "WARNING: ", "" };
569789Sahrens static char ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" };
570789Sahrens 
571789Sahrens void
572789Sahrens vpanic(const char *fmt, va_list adx)
573789Sahrens {
574789Sahrens 	(void) fprintf(stderr, "error: ");
575789Sahrens 	(void) vfprintf(stderr, fmt, adx);
576789Sahrens 	(void) fprintf(stderr, "\n");
577789Sahrens 
578789Sahrens 	abort();	/* think of it as a "user-level crash dump" */
579789Sahrens }
580789Sahrens 
581789Sahrens void
582789Sahrens panic(const char *fmt, ...)
583789Sahrens {
584789Sahrens 	va_list adx;
585789Sahrens 
586789Sahrens 	va_start(adx, fmt);
587789Sahrens 	vpanic(fmt, adx);
588789Sahrens 	va_end(adx);
589789Sahrens }
590789Sahrens 
5913713Sahrens void
5923713Sahrens vcmn_err(int ce, const char *fmt, va_list adx)
5933713Sahrens {
5943713Sahrens 	if (ce == CE_PANIC)
5953713Sahrens 		vpanic(fmt, adx);
5963713Sahrens 	if (ce != CE_NOTE) {	/* suppress noise in userland stress testing */
5973713Sahrens 		(void) fprintf(stderr, "%s", ce_prefix[ce]);
5983713Sahrens 		(void) vfprintf(stderr, fmt, adx);
5993713Sahrens 		(void) fprintf(stderr, "%s", ce_suffix[ce]);
6003713Sahrens 	}
6013713Sahrens }
6023713Sahrens 
603789Sahrens /*PRINTFLIKE2*/
604789Sahrens void
605789Sahrens cmn_err(int ce, const char *fmt, ...)
606789Sahrens {
607789Sahrens 	va_list adx;
608789Sahrens 
609789Sahrens 	va_start(adx, fmt);
6103713Sahrens 	vcmn_err(ce, fmt, adx);
611789Sahrens 	va_end(adx);
612789Sahrens }
613789Sahrens 
614789Sahrens /*
615789Sahrens  * =========================================================================
6161544Seschrock  * kobj interfaces
6171544Seschrock  * =========================================================================
6181544Seschrock  */
6191544Seschrock struct _buf *
6201544Seschrock kobj_open_file(char *name)
6211544Seschrock {
6221544Seschrock 	struct _buf *file;
6231544Seschrock 	vnode_t *vp;
6241544Seschrock 
6251544Seschrock 	/* set vp as the _fd field of the file */
6265331Samw 	if (vn_openat(name, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0, rootdir,
6275331Samw 	    -1) != 0)
6281544Seschrock 		return ((void *)-1UL);
6291544Seschrock 
6301544Seschrock 	file = umem_zalloc(sizeof (struct _buf), UMEM_NOFAIL);
6311544Seschrock 	file->_fd = (intptr_t)vp;
6321544Seschrock 	return (file);
6331544Seschrock }
6341544Seschrock 
6351544Seschrock int
6361544Seschrock kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
6371544Seschrock {
6381544Seschrock 	ssize_t resid;
6391544Seschrock 
6401544Seschrock 	vn_rdwr(UIO_READ, (vnode_t *)file->_fd, buf, size, (offset_t)off,
6411544Seschrock 	    UIO_SYSSPACE, 0, 0, 0, &resid);
6421544Seschrock 
6433912Slling 	return (size - resid);
6441544Seschrock }
6451544Seschrock 
6461544Seschrock void
6471544Seschrock kobj_close_file(struct _buf *file)
6481544Seschrock {
6491544Seschrock 	vn_close((vnode_t *)file->_fd);
6501544Seschrock 	umem_free(file, sizeof (struct _buf));
6511544Seschrock }
6521544Seschrock 
6531544Seschrock int
6543912Slling kobj_get_filesize(struct _buf *file, uint64_t *size)
6551544Seschrock {
6561544Seschrock 	struct stat64 st;
6573912Slling 	vnode_t *vp = (vnode_t *)file->_fd;
6583912Slling 
6591544Seschrock 	if (fstat64(vp->v_fd, &st) == -1) {
6601544Seschrock 		vn_close(vp);
6611544Seschrock 		return (errno);
6621544Seschrock 	}
6633912Slling 	*size = st.st_size;
6641544Seschrock 	return (0);
6651544Seschrock }
6661544Seschrock 
6671544Seschrock /*
6681544Seschrock  * =========================================================================
669789Sahrens  * misc routines
670789Sahrens  * =========================================================================
671789Sahrens  */
672789Sahrens 
673789Sahrens void
674789Sahrens delay(clock_t ticks)
675789Sahrens {
676789Sahrens 	poll(0, 0, ticks * (1000 / hz));
677789Sahrens }
678789Sahrens 
679789Sahrens /*
680789Sahrens  * Find highest one bit set.
681789Sahrens  *	Returns bit number + 1 of highest bit that is set, otherwise returns 0.
682789Sahrens  * High order bit is 31 (or 63 in _LP64 kernel).
683789Sahrens  */
684789Sahrens int
685789Sahrens highbit(ulong_t i)
686789Sahrens {
687789Sahrens 	register int h = 1;
688789Sahrens 
689789Sahrens 	if (i == 0)
690789Sahrens 		return (0);
691789Sahrens #ifdef _LP64
692789Sahrens 	if (i & 0xffffffff00000000ul) {
693789Sahrens 		h += 32; i >>= 32;
694789Sahrens 	}
695789Sahrens #endif
696789Sahrens 	if (i & 0xffff0000) {
697789Sahrens 		h += 16; i >>= 16;
698789Sahrens 	}
699789Sahrens 	if (i & 0xff00) {
700789Sahrens 		h += 8; i >>= 8;
701789Sahrens 	}
702789Sahrens 	if (i & 0xf0) {
703789Sahrens 		h += 4; i >>= 4;
704789Sahrens 	}
705789Sahrens 	if (i & 0xc) {
706789Sahrens 		h += 2; i >>= 2;
707789Sahrens 	}
708789Sahrens 	if (i & 0x2) {
709789Sahrens 		h += 1;
710789Sahrens 	}
711789Sahrens 	return (h);
712789Sahrens }
713789Sahrens 
7145688Sbonwick static int random_fd = -1, urandom_fd = -1;
7155688Sbonwick 
716789Sahrens static int
7175688Sbonwick random_get_bytes_common(uint8_t *ptr, size_t len, int fd)
718789Sahrens {
719789Sahrens 	size_t resid = len;
720789Sahrens 	ssize_t bytes;
721789Sahrens 
722789Sahrens 	ASSERT(fd != -1);
723789Sahrens 
724789Sahrens 	while (resid != 0) {
725789Sahrens 		bytes = read(fd, ptr, resid);
7265688Sbonwick 		ASSERT3S(bytes, >=, 0);
727789Sahrens 		ptr += bytes;
728789Sahrens 		resid -= bytes;
729789Sahrens 	}
730789Sahrens 
731789Sahrens 	return (0);
732789Sahrens }
733789Sahrens 
734789Sahrens int
735789Sahrens random_get_bytes(uint8_t *ptr, size_t len)
736789Sahrens {
7375688Sbonwick 	return (random_get_bytes_common(ptr, len, random_fd));
738789Sahrens }
739789Sahrens 
740789Sahrens int
741789Sahrens random_get_pseudo_bytes(uint8_t *ptr, size_t len)
742789Sahrens {
7435688Sbonwick 	return (random_get_bytes_common(ptr, len, urandom_fd));
744789Sahrens }
745789Sahrens 
7463975Sek110237 int
7473975Sek110237 ddi_strtoul(const char *hw_serial, char **nptr, int base, unsigned long *result)
7483975Sek110237 {
7493975Sek110237 	char *end;
7503975Sek110237 
7513975Sek110237 	*result = strtoul(hw_serial, &end, base);
7523975Sek110237 	if (*result == 0)
7533975Sek110237 		return (errno);
7543975Sek110237 	return (0);
7553975Sek110237 }
7563975Sek110237 
757789Sahrens /*
758789Sahrens  * =========================================================================
759789Sahrens  * kernel emulation setup & teardown
760789Sahrens  * =========================================================================
761789Sahrens  */
762789Sahrens static int
763789Sahrens umem_out_of_memory(void)
764789Sahrens {
765789Sahrens 	char errmsg[] = "out of memory -- generating core dump\n";
766789Sahrens 
767789Sahrens 	write(fileno(stderr), errmsg, sizeof (errmsg));
768789Sahrens 	abort();
769789Sahrens 	return (0);
770789Sahrens }
771789Sahrens 
772789Sahrens void
773789Sahrens kernel_init(int mode)
774789Sahrens {
775789Sahrens 	umem_nofail_callback(umem_out_of_memory);
776789Sahrens 
777789Sahrens 	physmem = sysconf(_SC_PHYS_PAGES);
778789Sahrens 
779789Sahrens 	dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
780789Sahrens 	    (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
781789Sahrens 
782*8662SJordan.Vaughan@Sun.com 	(void) snprintf(hw_serial, sizeof (hw_serial), "%ld", gethostid());
7833975Sek110237 
7845688Sbonwick 	VERIFY((random_fd = open("/dev/random", O_RDONLY)) != -1);
7855688Sbonwick 	VERIFY((urandom_fd = open("/dev/urandom", O_RDONLY)) != -1);
7865688Sbonwick 
7877837SMatthew.Ahrens@Sun.COM 	system_taskq_init();
7887837SMatthew.Ahrens@Sun.COM 
789789Sahrens 	spa_init(mode);
790789Sahrens }
791789Sahrens 
792789Sahrens void
793789Sahrens kernel_fini(void)
794789Sahrens {
795789Sahrens 	spa_fini();
7965688Sbonwick 
7975688Sbonwick 	close(random_fd);
7985688Sbonwick 	close(urandom_fd);
7995688Sbonwick 
8005688Sbonwick 	random_fd = -1;
8015688Sbonwick 	urandom_fd = -1;
802789Sahrens }
8033886Sahl 
8043886Sahl int
8053886Sahl z_uncompress(void *dst, size_t *dstlen, const void *src, size_t srclen)
8063886Sahl {
8073886Sahl 	int ret;
8083886Sahl 	uLongf len = *dstlen;
8093886Sahl 
8103886Sahl 	if ((ret = uncompress(dst, &len, src, srclen)) == Z_OK)
8113886Sahl 		*dstlen = (size_t)len;
8123886Sahl 
8133886Sahl 	return (ret);
8143886Sahl }
8153886Sahl 
8163886Sahl int
8173886Sahl z_compress_level(void *dst, size_t *dstlen, const void *src, size_t srclen,
8183886Sahl     int level)
8193886Sahl {
8203886Sahl 	int ret;
8213886Sahl 	uLongf len = *dstlen;
8223886Sahl 
8233886Sahl 	if ((ret = compress2(dst, &len, src, srclen, level)) == Z_OK)
8243886Sahl 		*dstlen = (size_t)len;
8253886Sahl 
8263886Sahl 	return (ret);
8273886Sahl }
8284543Smarks 
8294543Smarks uid_t
8304543Smarks crgetuid(cred_t *cr)
8314543Smarks {
8324543Smarks 	return (0);
8334543Smarks }
8344543Smarks 
8354543Smarks gid_t
8364543Smarks crgetgid(cred_t *cr)
8374543Smarks {
8384543Smarks 	return (0);
8394543Smarks }
8404543Smarks 
8414543Smarks int
8424543Smarks crgetngroups(cred_t *cr)
8434543Smarks {
8444543Smarks 	return (0);
8454543Smarks }
8464543Smarks 
8474543Smarks gid_t *
8484543Smarks crgetgroups(cred_t *cr)
8494543Smarks {
8504543Smarks 	return (NULL);
8514543Smarks }
8524543Smarks 
8534543Smarks int
8544543Smarks zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr)
8554543Smarks {
8564543Smarks 	return (0);
8574543Smarks }
8584543Smarks 
8594543Smarks int
8604543Smarks zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr)
8614543Smarks {
8624543Smarks 	return (0);
8634543Smarks }
8644543Smarks 
8654543Smarks int
8664543Smarks zfs_secpolicy_destroy_perms(const char *name, cred_t *cr)
8674543Smarks {
8684543Smarks 	return (0);
8694543Smarks }
8705959Smarks 
8715959Smarks ksiddomain_t *
8725959Smarks ksid_lookupdomain(const char *dom)
8735959Smarks {
8745959Smarks 	ksiddomain_t *kd;
8755959Smarks 
8765959Smarks 	kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL);
8775959Smarks 	kd->kd_name = spa_strdup(dom);
8785959Smarks 	return (kd);
8795959Smarks }
8805959Smarks 
8815959Smarks void
8825959Smarks ksiddomain_rele(ksiddomain_t *ksid)
8835959Smarks {
8845959Smarks 	spa_strfree(ksid->kd_name);
8855959Smarks 	umem_free(ksid, sizeof (ksiddomain_t));
8865959Smarks }
887