Home | History | Annotate | Download | only in common
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #include <assert.h>
     27 #include <fcntl.h>
     28 #include <poll.h>
     29 #include <stdio.h>
     30 #include <stdlib.h>
     31 #include <string.h>
     32 #include <zlib.h>
     33 #include <sys/spa.h>
     34 #include <sys/stat.h>
     35 #include <sys/processor.h>
     36 #include <sys/zfs_context.h>
     37 #include <sys/zmod.h>
     38 #include <sys/utsname.h>
     39 #include <sys/systeminfo.h>
     40 
     41 /*
     42  * Emulation of kernel services in userland.
     43  */
     44 
     45 uint64_t physmem;
     46 vnode_t *rootdir = (vnode_t *)0xabcd1234;
     47 char hw_serial[HW_HOSTID_LEN];
     48 
     49 struct utsname utsname = {
     50 	"userland", "libzpool", "1", "1", "na"
     51 };
     52 
     53 /* this only exists to have its address taken */
     54 struct proc p0;
     55 
     56 /*
     57  * =========================================================================
     58  * threads
     59  * =========================================================================
     60  */
     61 /*ARGSUSED*/
     62 kthread_t *
     63 zk_thread_create(void (*func)(), void *arg)
     64 {
     65 	thread_t tid;
     66 
     67 	VERIFY(thr_create(0, 0, (void *(*)(void *))func, arg, THR_DETACHED,
     68 	    &tid) == 0);
     69 
     70 	return ((void *)(uintptr_t)tid);
     71 }
     72 
     73 /*
     74  * =========================================================================
     75  * kstats
     76  * =========================================================================
     77  */
     78 /*ARGSUSED*/
     79 kstat_t *
     80 kstat_create(char *module, int instance, char *name, char *class,
     81     uchar_t type, ulong_t ndata, uchar_t ks_flag)
     82 {
     83 	return (NULL);
     84 }
     85 
     86 /*ARGSUSED*/
     87 void
     88 kstat_install(kstat_t *ksp)
     89 {}
     90 
     91 /*ARGSUSED*/
     92 void
     93 kstat_delete(kstat_t *ksp)
     94 {}
     95 
     96 /*
     97  * =========================================================================
     98  * mutexes
     99  * =========================================================================
    100  */
    101 void
    102 zmutex_init(kmutex_t *mp)
    103 {
    104 	mp->m_owner = NULL;
    105 	mp->initialized = B_TRUE;
    106 	(void) _mutex_init(&mp->m_lock, USYNC_THREAD, NULL);
    107 }
    108 
    109 void
    110 zmutex_destroy(kmutex_t *mp)
    111 {
    112 	ASSERT(mp->initialized == B_TRUE);
    113 	ASSERT(mp->m_owner == NULL);
    114 	(void) _mutex_destroy(&(mp)->m_lock);
    115 	mp->m_owner = (void *)-1UL;
    116 	mp->initialized = B_FALSE;
    117 }
    118 
    119 void
    120 mutex_enter(kmutex_t *mp)
    121 {
    122 	ASSERT(mp->initialized == B_TRUE);
    123 	ASSERT(mp->m_owner != (void *)-1UL);
    124 	ASSERT(mp->m_owner != curthread);
    125 	VERIFY(mutex_lock(&mp->m_lock) == 0);
    126 	ASSERT(mp->m_owner == NULL);
    127 	mp->m_owner = curthread;
    128 }
    129 
    130 int
    131 mutex_tryenter(kmutex_t *mp)
    132 {
    133 	ASSERT(mp->initialized == B_TRUE);
    134 	ASSERT(mp->m_owner != (void *)-1UL);
    135 	if (0 == mutex_trylock(&mp->m_lock)) {
    136 		ASSERT(mp->m_owner == NULL);
    137 		mp->m_owner = curthread;
    138 		return (1);
    139 	} else {
    140 		return (0);
    141 	}
    142 }
    143 
    144 void
    145 mutex_exit(kmutex_t *mp)
    146 {
    147 	ASSERT(mp->initialized == B_TRUE);
    148 	ASSERT(mutex_owner(mp) == curthread);
    149 	mp->m_owner = NULL;
    150 	VERIFY(mutex_unlock(&mp->m_lock) == 0);
    151 }
    152 
    153 void *
    154 mutex_owner(kmutex_t *mp)
    155 {
    156 	ASSERT(mp->initialized == B_TRUE);
    157 	return (mp->m_owner);
    158 }
    159 
    160 /*
    161  * =========================================================================
    162  * rwlocks
    163  * =========================================================================
    164  */
    165 /*ARGSUSED*/
    166 void
    167 rw_init(krwlock_t *rwlp, char *name, int type, void *arg)
    168 {
    169 	rwlock_init(&rwlp->rw_lock, USYNC_THREAD, NULL);
    170 	rwlp->rw_owner = NULL;
    171 	rwlp->initialized = B_TRUE;
    172 }
    173 
    174 void
    175 rw_destroy(krwlock_t *rwlp)
    176 {
    177 	rwlock_destroy(&rwlp->rw_lock);
    178 	rwlp->rw_owner = (void *)-1UL;
    179 	rwlp->initialized = B_FALSE;
    180 }
    181 
    182 void
    183 rw_enter(krwlock_t *rwlp, krw_t rw)
    184 {
    185 	ASSERT(!RW_LOCK_HELD(rwlp));
    186 	ASSERT(rwlp->initialized == B_TRUE);
    187 	ASSERT(rwlp->rw_owner != (void *)-1UL);
    188 	ASSERT(rwlp->rw_owner != curthread);
    189 
    190 	if (rw == RW_READER)
    191 		VERIFY(rw_rdlock(&rwlp->rw_lock) == 0);
    192 	else
    193 		VERIFY(rw_wrlock(&rwlp->rw_lock) == 0);
    194 
    195 	rwlp->rw_owner = curthread;
    196 }
    197 
    198 void
    199 rw_exit(krwlock_t *rwlp)
    200 {
    201 	ASSERT(rwlp->initialized == B_TRUE);
    202 	ASSERT(rwlp->rw_owner != (void *)-1UL);
    203 
    204 	rwlp->rw_owner = NULL;
    205 	VERIFY(rw_unlock(&rwlp->rw_lock) == 0);
    206 }
    207 
    208 int
    209 rw_tryenter(krwlock_t *rwlp, krw_t rw)
    210 {
    211 	int rv;
    212 
    213 	ASSERT(rwlp->initialized == B_TRUE);
    214 	ASSERT(rwlp->rw_owner != (void *)-1UL);
    215 
    216 	if (rw == RW_READER)
    217 		rv = rw_tryrdlock(&rwlp->rw_lock);
    218 	else
    219 		rv = rw_trywrlock(&rwlp->rw_lock);
    220 
    221 	if (rv == 0) {
    222 		rwlp->rw_owner = curthread;
    223 		return (1);
    224 	}
    225 
    226 	return (0);
    227 }
    228 
    229 /*ARGSUSED*/
    230 int
    231 rw_tryupgrade(krwlock_t *rwlp)
    232 {
    233 	ASSERT(rwlp->initialized == B_TRUE);
    234 	ASSERT(rwlp->rw_owner != (void *)-1UL);
    235 
    236 	return (0);
    237 }
    238 
    239 /*
    240  * =========================================================================
    241  * condition variables
    242  * =========================================================================
    243  */
    244 /*ARGSUSED*/
    245 void
    246 cv_init(kcondvar_t *cv, char *name, int type, void *arg)
    247 {
    248 	VERIFY(cond_init(cv, type, NULL) == 0);
    249 }
    250 
    251 void
    252 cv_destroy(kcondvar_t *cv)
    253 {
    254 	VERIFY(cond_destroy(cv) == 0);
    255 }
    256 
    257 void
    258 cv_wait(kcondvar_t *cv, kmutex_t *mp)
    259 {
    260 	ASSERT(mutex_owner(mp) == curthread);
    261 	mp->m_owner = NULL;
    262 	int ret = cond_wait(cv, &mp->m_lock);
    263 	VERIFY(ret == 0 || ret == EINTR);
    264 	mp->m_owner = curthread;
    265 }
    266 
    267 clock_t
    268 cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)
    269 {
    270 	int error;
    271 	timestruc_t ts;
    272 	clock_t delta;
    273 
    274 top:
    275 	delta = abstime - ddi_get_lbolt();
    276 	if (delta <= 0)
    277 		return (-1);
    278 
    279 	ts.tv_sec = delta / hz;
    280 	ts.tv_nsec = (delta % hz) * (NANOSEC / hz);
    281 
    282 	ASSERT(mutex_owner(mp) == curthread);
    283 	mp->m_owner = NULL;
    284 	error = cond_reltimedwait(cv, &mp->m_lock, &ts);
    285 	mp->m_owner = curthread;
    286 
    287 	if (error == ETIME)
    288 		return (-1);
    289 
    290 	if (error == EINTR)
    291 		goto top;
    292 
    293 	ASSERT(error == 0);
    294 
    295 	return (1);
    296 }
    297 
    298 void
    299 cv_signal(kcondvar_t *cv)
    300 {
    301 	VERIFY(cond_signal(cv) == 0);
    302 }
    303 
    304 void
    305 cv_broadcast(kcondvar_t *cv)
    306 {
    307 	VERIFY(cond_broadcast(cv) == 0);
    308 }
    309 
    310 /*
    311  * =========================================================================
    312  * vnode operations
    313  * =========================================================================
    314  */
    315 /*
    316  * Note: for the xxxat() versions of these functions, we assume that the
    317  * starting vp is always rootdir (which is true for spa_directory.c, the only
    318  * ZFS consumer of these interfaces).  We assert this is true, and then emulate
    319  * them by adding '/' in front of the path.
    320  */
    321 
    322 /*ARGSUSED*/
    323 int
    324 vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
    325 {
    326 	int fd;
    327 	vnode_t *vp;
    328 	int old_umask;
    329 	char realpath[MAXPATHLEN];
    330 	struct stat64 st;
    331 
    332 	/*
    333 	 * If we're accessing a real disk from userland, we need to use
    334 	 * the character interface to avoid caching.  This is particularly
    335 	 * important if we're trying to look at a real in-kernel storage
    336 	 * pool from userland, e.g. via zdb, because otherwise we won't
    337 	 * see the changes occurring under the segmap cache.
    338 	 * On the other hand, the stupid character device returns zero
    339 	 * for its size.  So -- gag -- we open the block device to get
    340 	 * its size, and remember it for subsequent VOP_GETATTR().
    341 	 */
    342 	if (strncmp(path, "/dev/", 5) == 0) {
    343 		char *dsk;
    344 		fd = open64(path, O_RDONLY);
    345 		if (fd == -1)
    346 			return (errno);
    347 		if (fstat64(fd, &st) == -1) {
    348 			close(fd);
    349 			return (errno);
    350 		}
    351 		close(fd);
    352 		(void) sprintf(realpath, "%s", path);
    353 		dsk = strstr(path, "/dsk/");
    354 		if (dsk != NULL)
    355 			(void) sprintf(realpath + (dsk - path) + 1, "r%s",
    356 			    dsk + 1);
    357 	} else {
    358 		(void) sprintf(realpath, "%s", path);
    359 		if (!(flags & FCREAT) && stat64(realpath, &st) == -1)
    360 			return (errno);
    361 	}
    362 
    363 	if (flags & FCREAT)
    364 		old_umask = umask(0);
    365 
    366 	/*
    367 	 * The construct 'flags - FREAD' conveniently maps combinations of
    368 	 * FREAD and FWRITE to the corresponding O_RDONLY, O_WRONLY, and O_RDWR.
    369 	 */
    370 	fd = open64(realpath, flags - FREAD, mode);
    371 
    372 	if (flags & FCREAT)
    373 		(void) umask(old_umask);
    374 
    375 	if (fd == -1)
    376 		return (errno);
    377 
    378 	if (fstat64(fd, &st) == -1) {
    379 		close(fd);
    380 		return (errno);
    381 	}
    382 
    383 	(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
    384 
    385 	*vpp = vp = umem_zalloc(sizeof (vnode_t), UMEM_NOFAIL);
    386 
    387 	vp->v_fd = fd;
    388 	vp->v_size = st.st_size;
    389 	vp->v_path = spa_strdup(path);
    390 
    391 	return (0);
    392 }
    393 
    394 /*ARGSUSED*/
    395 int
    396 vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2,
    397     int x3, vnode_t *startvp, int fd)
    398 {
    399 	char *realpath = umem_alloc(strlen(path) + 2, UMEM_NOFAIL);
    400 	int ret;
    401 
    402 	ASSERT(startvp == rootdir);
    403 	(void) sprintf(realpath, "/%s", path);
    404 
    405 	/* fd ignored for now, need if want to simulate nbmand support */
    406 	ret = vn_open(realpath, x1, flags, mode, vpp, x2, x3);
    407 
    408 	umem_free(realpath, strlen(path) + 2);
    409 
    410 	return (ret);
    411 }
    412 
    413 /*ARGSUSED*/
    414 int
    415 vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
    416 	int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp)
    417 {
    418 	ssize_t iolen, split;
    419 
    420 	if (uio == UIO_READ) {
    421 		iolen = pread64(vp->v_fd, addr, len, offset);
    422 	} else {
    423 		/*
    424 		 * To simulate partial disk writes, we split writes into two
    425 		 * system calls so that the process can be killed in between.
    426 		 */
    427 		split = (len > 0 ? rand() % len : 0);
    428 		iolen = pwrite64(vp->v_fd, addr, split, offset);
    429 		iolen += pwrite64(vp->v_fd, (char *)addr + split,
    430 		    len - split, offset + split);
    431 	}
    432 
    433 	if (iolen == -1)
    434 		return (errno);
    435 	if (residp)
    436 		*residp = len - iolen;
    437 	else if (iolen != len)
    438 		return (EIO);
    439 	return (0);
    440 }
    441 
    442 void
    443 vn_close(vnode_t *vp)
    444 {
    445 	close(vp->v_fd);
    446 	spa_strfree(vp->v_path);
    447 	umem_free(vp, sizeof (vnode_t));
    448 }
    449 
    450 /*
    451  * At a minimum we need to update the size since vdev_reopen()
    452  * will no longer call vn_openat().
    453  */
    454 int
    455 fop_getattr(vnode_t *vp, vattr_t *vap)
    456 {
    457 	struct stat64 st;
    458 
    459 	if (fstat64(vp->v_fd, &st) == -1) {
    460 		close(vp->v_fd);
    461 		return (errno);
    462 	}
    463 
    464 	vap->va_size = st.st_size;
    465 	return (0);
    466 }
    467 
    468 #ifdef ZFS_DEBUG
    469 
    470 /*
    471  * =========================================================================
    472  * Figure out which debugging statements to print
    473  * =========================================================================
    474  */
    475 
    476 static char *dprintf_string;
    477 static int dprintf_print_all;
    478 
    479 int
    480 dprintf_find_string(const char *string)
    481 {
    482 	char *tmp_str = dprintf_string;
    483 	int len = strlen(string);
    484 
    485 	/*
    486 	 * Find out if this is a string we want to print.
    487 	 * String format: file1.c,function_name1,file2.c,file3.c
    488 	 */
    489 
    490 	while (tmp_str != NULL) {
    491 		if (strncmp(tmp_str, string, len) == 0 &&
    492 		    (tmp_str[len] == ',' || tmp_str[len] == '\0'))
    493 			return (1);
    494 		tmp_str = strchr(tmp_str, ',');
    495 		if (tmp_str != NULL)
    496 			tmp_str++; /* Get rid of , */
    497 	}
    498 	return (0);
    499 }
    500 
    501 void
    502 dprintf_setup(int *argc, char **argv)
    503 {
    504 	int i, j;
    505 
    506 	/*
    507 	 * Debugging can be specified two ways: by setting the
    508 	 * environment variable ZFS_DEBUG, or by including a
    509 	 * "debug=..."  argument on the command line.  The command
    510 	 * line setting overrides the environment variable.
    511 	 */
    512 
    513 	for (i = 1; i < *argc; i++) {
    514 		int len = strlen("debug=");
    515 		/* First look for a command line argument */
    516 		if (strncmp("debug=", argv[i], len) == 0) {
    517 			dprintf_string = argv[i] + len;
    518 			/* Remove from args */
    519 			for (j = i; j < *argc; j++)
    520 				argv[j] = argv[j+1];
    521 			argv[j] = NULL;
    522 			(*argc)--;
    523 		}
    524 	}
    525 
    526 	if (dprintf_string == NULL) {
    527 		/* Look for ZFS_DEBUG environment variable */
    528 		dprintf_string = getenv("ZFS_DEBUG");
    529 	}
    530 
    531 	/*
    532 	 * Are we just turning on all debugging?
    533 	 */
    534 	if (dprintf_find_string("on"))
    535 		dprintf_print_all = 1;
    536 }
    537 
    538 /*
    539  * =========================================================================
    540  * debug printfs
    541  * =========================================================================
    542  */
    543 void
    544 __dprintf(const char *file, const char *func, int line, const char *fmt, ...)
    545 {
    546 	const char *newfile;
    547 	va_list adx;
    548 
    549 	/*
    550 	 * Get rid of annoying "../common/" prefix to filename.
    551 	 */
    552 	newfile = strrchr(file, '/');
    553 	if (newfile != NULL) {
    554 		newfile = newfile + 1; /* Get rid of leading / */
    555 	} else {
    556 		newfile = file;
    557 	}
    558 
    559 	if (dprintf_print_all ||
    560 	    dprintf_find_string(newfile) ||
    561 	    dprintf_find_string(func)) {
    562 		/* Print out just the function name if requested */
    563 		flockfile(stdout);
    564 		if (dprintf_find_string("pid"))
    565 			(void) printf("%d ", getpid());
    566 		if (dprintf_find_string("tid"))
    567 			(void) printf("%u ", thr_self());
    568 		if (dprintf_find_string("cpu"))
    569 			(void) printf("%u ", getcpuid());
    570 		if (dprintf_find_string("time"))
    571 			(void) printf("%llu ", gethrtime());
    572 		if (dprintf_find_string("long"))
    573 			(void) printf("%s, line %d: ", newfile, line);
    574 		(void) printf("%s: ", func);
    575 		va_start(adx, fmt);
    576 		(void) vprintf(fmt, adx);
    577 		va_end(adx);
    578 		funlockfile(stdout);
    579 	}
    580 }
    581 
    582 #endif /* ZFS_DEBUG */
    583 
    584 /*
    585  * =========================================================================
    586  * cmn_err() and panic()
    587  * =========================================================================
    588  */
    589 static char ce_prefix[CE_IGNORE][10] = { "", "NOTICE: ", "WARNING: ", "" };
    590 static char ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" };
    591 
    592 void
    593 vpanic(const char *fmt, va_list adx)
    594 {
    595 	(void) fprintf(stderr, "error: ");
    596 	(void) vfprintf(stderr, fmt, adx);
    597 	(void) fprintf(stderr, "\n");
    598 
    599 	abort();	/* think of it as a "user-level crash dump" */
    600 }
    601 
    602 void
    603 panic(const char *fmt, ...)
    604 {
    605 	va_list adx;
    606 
    607 	va_start(adx, fmt);
    608 	vpanic(fmt, adx);
    609 	va_end(adx);
    610 }
    611 
    612 void
    613 vcmn_err(int ce, const char *fmt, va_list adx)
    614 {
    615 	if (ce == CE_PANIC)
    616 		vpanic(fmt, adx);
    617 	if (ce != CE_NOTE) {	/* suppress noise in userland stress testing */
    618 		(void) fprintf(stderr, "%s", ce_prefix[ce]);
    619 		(void) vfprintf(stderr, fmt, adx);
    620 		(void) fprintf(stderr, "%s", ce_suffix[ce]);
    621 	}
    622 }
    623 
    624 /*PRINTFLIKE2*/
    625 void
    626 cmn_err(int ce, const char *fmt, ...)
    627 {
    628 	va_list adx;
    629 
    630 	va_start(adx, fmt);
    631 	vcmn_err(ce, fmt, adx);
    632 	va_end(adx);
    633 }
    634 
    635 /*
    636  * =========================================================================
    637  * kobj interfaces
    638  * =========================================================================
    639  */
    640 struct _buf *
    641 kobj_open_file(char *name)
    642 {
    643 	struct _buf *file;
    644 	vnode_t *vp;
    645 
    646 	/* set vp as the _fd field of the file */
    647 	if (vn_openat(name, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0, rootdir,
    648 	    -1) != 0)
    649 		return ((void *)-1UL);
    650 
    651 	file = umem_zalloc(sizeof (struct _buf), UMEM_NOFAIL);
    652 	file->_fd = (intptr_t)vp;
    653 	return (file);
    654 }
    655 
    656 int
    657 kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
    658 {
    659 	ssize_t resid;
    660 
    661 	vn_rdwr(UIO_READ, (vnode_t *)file->_fd, buf, size, (offset_t)off,
    662 	    UIO_SYSSPACE, 0, 0, 0, &resid);
    663 
    664 	return (size - resid);
    665 }
    666 
    667 void
    668 kobj_close_file(struct _buf *file)
    669 {
    670 	vn_close((vnode_t *)file->_fd);
    671 	umem_free(file, sizeof (struct _buf));
    672 }
    673 
    674 int
    675 kobj_get_filesize(struct _buf *file, uint64_t *size)
    676 {
    677 	struct stat64 st;
    678 	vnode_t *vp = (vnode_t *)file->_fd;
    679 
    680 	if (fstat64(vp->v_fd, &st) == -1) {
    681 		vn_close(vp);
    682 		return (errno);
    683 	}
    684 	*size = st.st_size;
    685 	return (0);
    686 }
    687 
    688 /*
    689  * =========================================================================
    690  * misc routines
    691  * =========================================================================
    692  */
    693 
    694 void
    695 delay(clock_t ticks)
    696 {
    697 	poll(0, 0, ticks * (1000 / hz));
    698 }
    699 
    700 /*
    701  * Find highest one bit set.
    702  *	Returns bit number + 1 of highest bit that is set, otherwise returns 0.
    703  * High order bit is 31 (or 63 in _LP64 kernel).
    704  */
    705 int
    706 highbit(ulong_t i)
    707 {
    708 	register int h = 1;
    709 
    710 	if (i == 0)
    711 		return (0);
    712 #ifdef _LP64
    713 	if (i & 0xffffffff00000000ul) {
    714 		h += 32; i >>= 32;
    715 	}
    716 #endif
    717 	if (i & 0xffff0000) {
    718 		h += 16; i >>= 16;
    719 	}
    720 	if (i & 0xff00) {
    721 		h += 8; i >>= 8;
    722 	}
    723 	if (i & 0xf0) {
    724 		h += 4; i >>= 4;
    725 	}
    726 	if (i & 0xc) {
    727 		h += 2; i >>= 2;
    728 	}
    729 	if (i & 0x2) {
    730 		h += 1;
    731 	}
    732 	return (h);
    733 }
    734 
    735 static int random_fd = -1, urandom_fd = -1;
    736 
    737 static int
    738 random_get_bytes_common(uint8_t *ptr, size_t len, int fd)
    739 {
    740 	size_t resid = len;
    741 	ssize_t bytes;
    742 
    743 	ASSERT(fd != -1);
    744 
    745 	while (resid != 0) {
    746 		bytes = read(fd, ptr, resid);
    747 		ASSERT3S(bytes, >=, 0);
    748 		ptr += bytes;
    749 		resid -= bytes;
    750 	}
    751 
    752 	return (0);
    753 }
    754 
    755 int
    756 random_get_bytes(uint8_t *ptr, size_t len)
    757 {
    758 	return (random_get_bytes_common(ptr, len, random_fd));
    759 }
    760 
    761 int
    762 random_get_pseudo_bytes(uint8_t *ptr, size_t len)
    763 {
    764 	return (random_get_bytes_common(ptr, len, urandom_fd));
    765 }
    766 
    767 int
    768 ddi_strtoul(const char *hw_serial, char **nptr, int base, unsigned long *result)
    769 {
    770 	char *end;
    771 
    772 	*result = strtoul(hw_serial, &end, base);
    773 	if (*result == 0)
    774 		return (errno);
    775 	return (0);
    776 }
    777 
    778 /*
    779  * =========================================================================
    780  * kernel emulation setup & teardown
    781  * =========================================================================
    782  */
    783 static int
    784 umem_out_of_memory(void)
    785 {
    786 	char errmsg[] = "out of memory -- generating core dump\n";
    787 
    788 	write(fileno(stderr), errmsg, sizeof (errmsg));
    789 	abort();
    790 	return (0);
    791 }
    792 
    793 void
    794 kernel_init(int mode)
    795 {
    796 	umem_nofail_callback(umem_out_of_memory);
    797 
    798 	physmem = sysconf(_SC_PHYS_PAGES);
    799 
    800 	dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
    801 	    (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
    802 
    803 	(void) snprintf(hw_serial, sizeof (hw_serial), "%ld",
    804 	    (mode & FWRITE) ? gethostid() : 0);
    805 
    806 	VERIFY((random_fd = open("/dev/random", O_RDONLY)) != -1);
    807 	VERIFY((urandom_fd = open("/dev/urandom", O_RDONLY)) != -1);
    808 
    809 	system_taskq_init();
    810 
    811 	spa_init(mode);
    812 }
    813 
    814 void
    815 kernel_fini(void)
    816 {
    817 	spa_fini();
    818 
    819 	system_taskq_fini();
    820 
    821 	close(random_fd);
    822 	close(urandom_fd);
    823 
    824 	random_fd = -1;
    825 	urandom_fd = -1;
    826 }
    827 
    828 int
    829 z_uncompress(void *dst, size_t *dstlen, const void *src, size_t srclen)
    830 {
    831 	int ret;
    832 	uLongf len = *dstlen;
    833 
    834 	if ((ret = uncompress(dst, &len, src, srclen)) == Z_OK)
    835 		*dstlen = (size_t)len;
    836 
    837 	return (ret);
    838 }
    839 
    840 int
    841 z_compress_level(void *dst, size_t *dstlen, const void *src, size_t srclen,
    842     int level)
    843 {
    844 	int ret;
    845 	uLongf len = *dstlen;
    846 
    847 	if ((ret = compress2(dst, &len, src, srclen, level)) == Z_OK)
    848 		*dstlen = (size_t)len;
    849 
    850 	return (ret);
    851 }
    852 
    853 uid_t
    854 crgetuid(cred_t *cr)
    855 {
    856 	return (0);
    857 }
    858 
    859 gid_t
    860 crgetgid(cred_t *cr)
    861 {
    862 	return (0);
    863 }
    864 
    865 int
    866 crgetngroups(cred_t *cr)
    867 {
    868 	return (0);
    869 }
    870 
    871 gid_t *
    872 crgetgroups(cred_t *cr)
    873 {
    874 	return (NULL);
    875 }
    876 
    877 int
    878 zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr)
    879 {
    880 	return (0);
    881 }
    882 
    883 int
    884 zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr)
    885 {
    886 	return (0);
    887 }
    888 
    889 int
    890 zfs_secpolicy_destroy_perms(const char *name, cred_t *cr)
    891 {
    892 	return (0);
    893 }
    894 
    895 ksiddomain_t *
    896 ksid_lookupdomain(const char *dom)
    897 {
    898 	ksiddomain_t *kd;
    899 
    900 	kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL);
    901 	kd->kd_name = spa_strdup(dom);
    902 	return (kd);
    903 }
    904 
    905 void
    906 ksiddomain_rele(ksiddomain_t *ksid)
    907 {
    908 	spa_strfree(ksid->kd_name);
    909 	umem_free(ksid, sizeof (ksiddomain_t));
    910 }
    911 
    912 /*
    913  * Do not change the length of the returned string; it must be freed
    914  * with strfree().
    915  */
    916 char *
    917 kmem_asprintf(const char *fmt, ...)
    918 {
    919 	int size;
    920 	va_list adx;
    921 	char *buf;
    922 
    923 	va_start(adx, fmt);
    924 	size = vsnprintf(NULL, 0, fmt, adx) + 1;
    925 	va_end(adx);
    926 
    927 	buf = kmem_alloc(size, KM_SLEEP);
    928 
    929 	va_start(adx, fmt);
    930 	size = vsnprintf(buf, size, fmt, adx);
    931 	va_end(adx);
    932 
    933 	return (buf);
    934 }
    935