Home | History | Annotate | Line # | 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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
     23  * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
     24  * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
     25  */
     26 
     27 #include <assert.h>
     28 #include <fcntl.h>
     29 #include <poll.h>
     30 #include <stdio.h>
     31 #include <stdlib.h>
     32 #include <string.h>
     33 #include <zlib.h>
     34 #include <libgen.h>
     35 #include <sys/spa.h>
     36 #include <sys/stat.h>
     37 #include <sys/processor.h>
     38 #include <sys/zfs_context.h>
     39 #include <sys/rrwlock.h>
     40 #include <sys/zmod.h>
     41 #include <sys/utsname.h>
     42 #include <sys/systeminfo.h>
     43 
     44 #ifdef __NetBSD__
     45 #include <sys/dkio.h>
     46 #include <sys/ioctl.h>
     47 #endif
     48 
     49 /*
     50  * Emulation of kernel services in userland.
     51  */
     52 
     53 #ifndef __FreeBSD__
     54 int aok;
     55 #endif
     56 uint64_t physmem;
     57 vnode_t *rootdir = (vnode_t *)0xabcd1234;
     58 char hw_serial[HW_HOSTID_LEN];
     59 #ifdef illumos
     60 kmutex_t cpu_lock;
     61 #endif
     62 
     63 /* If set, all blocks read will be copied to the specified directory. */
     64 char *vn_dumpdir = NULL;
     65 
     66 struct utsname utsname = {
     67 	"userland", "libzpool", "1", "1", "na"
     68 };
     69 
     70 /* this only exists to have its address taken */
     71 struct proc p0;
     72 
     73 /*
     74  * =========================================================================
     75  * threads
     76  * =========================================================================
     77  */
     78 /*ARGSUSED*/
     79 kthread_t *
     80 zk_thread_create(void (*func)(), void *arg)
     81 {
     82 	thread_t tid;
     83 
     84 	VERIFY(thr_create(0, 0, (void *(*)(void *))func, arg, THR_DETACHED,
     85 	    &tid) == 0);
     86 
     87 	return ((void *)(uintptr_t)tid);
     88 }
     89 
     90 /*
     91  * =========================================================================
     92  * kstats
     93  * =========================================================================
     94  */
     95 /*ARGSUSED*/
     96 kstat_t *
     97 kstat_create(char *module, int instance, char *name, char *class,
     98     uchar_t type, ulong_t ndata, uchar_t ks_flag)
     99 {
    100 	return (NULL);
    101 }
    102 
    103 /*ARGSUSED*/
    104 void
    105 kstat_named_init(kstat_named_t *knp, const char *name, uchar_t type)
    106 {}
    107 
    108 /*ARGSUSED*/
    109 void
    110 kstat_install(kstat_t *ksp)
    111 {}
    112 
    113 /*ARGSUSED*/
    114 void
    115 kstat_delete(kstat_t *ksp)
    116 {}
    117 
    118 /*
    119  * =========================================================================
    120  * mutexes
    121  * =========================================================================
    122  */
    123 void
    124 zmutex_init(kmutex_t *mp)
    125 {
    126 	mp->m_owner = NULL;
    127 	mp->initialized = B_TRUE;
    128 	(void) _mutex_init(&mp->m_lock, USYNC_THREAD, NULL);
    129 }
    130 
    131 void
    132 zmutex_destroy(kmutex_t *mp)
    133 {
    134 	ASSERT(mp->initialized == B_TRUE);
    135 	ASSERT(mp->m_owner == NULL);
    136 	(void) _mutex_destroy(&(mp)->m_lock);
    137 	mp->m_owner = (void *)-1UL;
    138 	mp->initialized = B_FALSE;
    139 }
    140 
    141 int
    142 zmutex_owned(kmutex_t *mp)
    143 {
    144 	ASSERT(mp->initialized == B_TRUE);
    145 
    146 	return (mp->m_owner == curthread);
    147 }
    148 
    149 void
    150 mutex_enter(kmutex_t *mp)
    151 {
    152 	ASSERT(mp->initialized == B_TRUE);
    153 	ASSERT(mp->m_owner != (void *)-1UL);
    154 	ASSERT(mp->m_owner != curthread);
    155 	VERIFY(mutex_lock(&mp->m_lock) == 0);
    156 	ASSERT(mp->m_owner == NULL);
    157 	mp->m_owner = curthread;
    158 }
    159 
    160 int
    161 mutex_tryenter(kmutex_t *mp)
    162 {
    163 	ASSERT(mp->initialized == B_TRUE);
    164 	ASSERT(mp->m_owner != (void *)-1UL);
    165 	if (0 == mutex_trylock(&mp->m_lock)) {
    166 		ASSERT(mp->m_owner == NULL);
    167 		mp->m_owner = curthread;
    168 		return (1);
    169 	} else {
    170 		return (0);
    171 	}
    172 }
    173 
    174 void
    175 mutex_exit(kmutex_t *mp)
    176 {
    177 	ASSERT(mp->initialized == B_TRUE);
    178 	ASSERT(mutex_owner(mp) == curthread);
    179 	mp->m_owner = NULL;
    180 	VERIFY(mutex_unlock(&mp->m_lock) == 0);
    181 }
    182 
    183 void *
    184 mutex_owner(kmutex_t *mp)
    185 {
    186 	ASSERT(mp->initialized == B_TRUE);
    187 	return (mp->m_owner);
    188 }
    189 
    190 /*
    191  * =========================================================================
    192  * rwlocks
    193  * =========================================================================
    194  */
    195 /*ARGSUSED*/
    196 void
    197 rw_init(krwlock_t *rwlp, char *name, int type, void *arg)
    198 {
    199 	rwlock_init(&rwlp->rw_lock, USYNC_THREAD, NULL);
    200 	rwlp->rw_owner = NULL;
    201 	rwlp->initialized = B_TRUE;
    202 	rwlp->rw_count = 0;
    203 }
    204 
    205 void
    206 rw_destroy(krwlock_t *rwlp)
    207 {
    208 	ASSERT(rwlp->rw_count == 0);
    209 	rwlock_destroy(&rwlp->rw_lock);
    210 	rwlp->rw_owner = (void *)-1UL;
    211 	rwlp->initialized = B_FALSE;
    212 }
    213 
    214 void
    215 rw_enter(krwlock_t *rwlp, krw_t rw)
    216 {
    217 	//ASSERT(!RW_LOCK_HELD(rwlp));
    218 	ASSERT(rwlp->initialized == B_TRUE);
    219 	ASSERT(rwlp->rw_owner != (void *)-1UL);
    220 	ASSERT(rwlp->rw_owner != curthread);
    221 
    222 	if (rw == RW_READER) {
    223 		VERIFY(rw_rdlock(&rwlp->rw_lock) == 0);
    224 		ASSERT(rwlp->rw_count >= 0);
    225 		atomic_add_int(&rwlp->rw_count, 1);
    226 	} else {
    227 		VERIFY(rw_wrlock(&rwlp->rw_lock) == 0);
    228 		ASSERT(rwlp->rw_count == 0);
    229 		rwlp->rw_count = -1;
    230 		rwlp->rw_owner = curthread;
    231 	}
    232 }
    233 
    234 void
    235 rw_exit(krwlock_t *rwlp)
    236 {
    237 	ASSERT(rwlp->initialized == B_TRUE);
    238 	ASSERT(rwlp->rw_owner != (void *)-1UL);
    239 
    240 	if (rwlp->rw_owner == curthread) {
    241 		/* Write locked. */
    242 		ASSERT(rwlp->rw_count == -1);
    243 		rwlp->rw_count = 0;
    244 		rwlp->rw_owner = NULL;
    245 	} else {
    246 		/* Read locked. */
    247 		ASSERT(rwlp->rw_count > 0);
    248 		atomic_add_int(&rwlp->rw_count, -1);
    249 	}
    250 	VERIFY(rw_unlock(&rwlp->rw_lock) == 0);
    251 }
    252 
    253 int
    254 rw_tryenter(krwlock_t *rwlp, krw_t rw)
    255 {
    256 	int rv;
    257 
    258 	ASSERT(rwlp->initialized == B_TRUE);
    259 	ASSERT(rwlp->rw_owner != (void *)-1UL);
    260 	ASSERT(rwlp->rw_owner != curthread);
    261 
    262 	if (rw == RW_READER)
    263 		rv = rw_tryrdlock(&rwlp->rw_lock);
    264 	else
    265 		rv = rw_trywrlock(&rwlp->rw_lock);
    266 
    267 	if (rv == 0) {
    268 		ASSERT(rwlp->rw_owner == NULL);
    269 		if (rw == RW_READER) {
    270 			ASSERT(rwlp->rw_count >= 0);
    271 			atomic_add_int(&rwlp->rw_count, 1);
    272 		} else {
    273 			ASSERT(rwlp->rw_count == 0);
    274 			rwlp->rw_count = -1;
    275 			rwlp->rw_owner = curthread;
    276 		}
    277 		return (1);
    278 	}
    279 
    280 	return (0);
    281 }
    282 
    283 /*ARGSUSED*/
    284 int
    285 rw_tryupgrade(krwlock_t *rwlp)
    286 {
    287 	ASSERT(rwlp->initialized == B_TRUE);
    288 	ASSERT(rwlp->rw_owner != (void *)-1UL);
    289 
    290 	return (0);
    291 }
    292 
    293 int
    294 rw_lock_held(krwlock_t *rwlp)
    295 {
    296 
    297 	return (rwlp->rw_count != 0);
    298 }
    299 
    300 /*
    301  * =========================================================================
    302  * condition variables
    303  * =========================================================================
    304  */
    305 /*ARGSUSED*/
    306 void
    307 cv_init(kcondvar_t *cv, char *name, int type, void *arg)
    308 {
    309 	VERIFY(cond_init(cv, name, NULL) == 0);
    310 }
    311 
    312 void
    313 cv_destroy(kcondvar_t *cv)
    314 {
    315 	VERIFY(cond_destroy(cv) == 0);
    316 }
    317 
    318 void
    319 cv_wait(kcondvar_t *cv, kmutex_t *mp)
    320 {
    321 	ASSERT(mutex_owner(mp) == curthread);
    322 	mp->m_owner = NULL;
    323 	int ret = cond_wait(cv, &mp->m_lock);
    324 	VERIFY(ret == 0 || ret == EINTR);
    325 	mp->m_owner = curthread;
    326 }
    327 
    328 clock_t
    329 cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)
    330 {
    331 	int error;
    332 	struct timespec ts;
    333 	struct timeval tv;
    334 	clock_t delta;
    335 
    336 	abstime += ddi_get_lbolt();
    337 top:
    338 	delta = abstime - ddi_get_lbolt();
    339 	if (delta <= 0)
    340 		return (-1);
    341 
    342 	if (gettimeofday(&tv, NULL) != 0)
    343 		assert(!"gettimeofday() failed");
    344 
    345 	ts.tv_sec = tv.tv_sec + delta / hz;
    346 	ts.tv_nsec = tv.tv_usec * 1000 + (delta % hz) * (NANOSEC / hz);
    347 	ASSERT(ts.tv_nsec >= 0);
    348 
    349 	if (ts.tv_nsec >= NANOSEC) {
    350 		ts.tv_sec++;
    351 		ts.tv_nsec -= NANOSEC;
    352 	}
    353 
    354 	ASSERT(mutex_owner(mp) == curthread);
    355 	mp->m_owner = NULL;
    356 	error = pthread_cond_timedwait(cv, &mp->m_lock, &ts);
    357 	mp->m_owner = curthread;
    358 
    359 	if (error == EINTR)
    360 		goto top;
    361 
    362 	if (error == ETIMEDOUT)
    363 		return (-1);
    364 
    365 	ASSERT(error == 0);
    366 
    367 	return (1);
    368 }
    369 
    370 /*ARGSUSED*/
    371 clock_t
    372 cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res,
    373     int flag)
    374 {
    375 	int error;
    376 	timestruc_t ts;
    377 	hrtime_t delta;
    378 
    379 	ASSERT(flag == 0 || flag == CALLOUT_FLAG_ABSOLUTE);
    380 
    381 top:
    382 	delta = tim;
    383 	if (flag & CALLOUT_FLAG_ABSOLUTE)
    384 		delta -= gethrtime();
    385 
    386 	if (delta <= 0)
    387 		return (-1);
    388 
    389 	ts.tv_sec = delta / NANOSEC;
    390 	ts.tv_nsec = delta % NANOSEC;
    391 
    392 	ASSERT(mutex_owner(mp) == curthread);
    393 	mp->m_owner = NULL;
    394 	error = pthread_cond_timedwait(cv, &mp->m_lock, &ts);
    395 	mp->m_owner = curthread;
    396 
    397 	if (error == ETIMEDOUT)
    398 		return (-1);
    399 
    400 	if (error == EINTR)
    401 		goto top;
    402 
    403 	ASSERT(error == 0);
    404 
    405 	return (1);
    406 }
    407 
    408 void
    409 cv_signal(kcondvar_t *cv)
    410 {
    411 	VERIFY(cond_signal(cv) == 0);
    412 }
    413 
    414 void
    415 cv_broadcast(kcondvar_t *cv)
    416 {
    417 	VERIFY(cond_broadcast(cv) == 0);
    418 }
    419 
    420 /*
    421  * =========================================================================
    422  * vnode operations
    423  * =========================================================================
    424  */
    425 /*
    426  * Note: for the xxxat() versions of these functions, we assume that the
    427  * starting vp is always rootdir (which is true for spa_directory.c, the only
    428  * ZFS consumer of these interfaces).  We assert this is true, and then emulate
    429  * them by adding '/' in front of the path.
    430  */
    431 
    432 /*ARGSUSED*/
    433 int
    434 vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
    435 {
    436 	int fd;
    437 	int dump_fd;
    438 	vnode_t *vp;
    439 	int old_umask;
    440 	char realpath[MAXPATHLEN];
    441 	struct stat64 st;
    442 
    443 	/*
    444 	 * If we're accessing a real disk from userland, we need to use
    445 	 * the character interface to avoid caching.  This is particularly
    446 	 * important if we're trying to look at a real in-kernel storage
    447 	 * pool from userland, e.g. via zdb, because otherwise we won't
    448 	 * see the changes occurring under the segmap cache.
    449 	 * On the other hand, the stupid character device returns zero
    450 	 * for its size.  So -- gag -- we open the block device to get
    451 	 * its size, and remember it for subsequent VOP_GETATTR().
    452 	 */
    453 	if (strncmp(path, "/dev/", 5) == 0) {
    454 		char *dsk;
    455 #ifdef __NetBSD__
    456 		/*
    457 		 * For NetBSD, we've been passed in a block device name
    458 		 * but need to convert to the character device name.
    459 		 * XXX a bit ugly...
    460 		 */
    461 		char rawpath[MAXPATHLEN];
    462 
    463 		snprintf(rawpath, sizeof(rawpath), "/dev/r%s", path + 5);
    464 		path = rawpath;	/* gets strdup()'d below */
    465 #endif	/* __NetBSD__ */
    466 		fd = open64(path, O_RDONLY);
    467 		if (fd == -1)
    468 			return (errno);
    469 		if (fstat64(fd, &st) == -1) {
    470 			close(fd);
    471 			return (errno);
    472 		}
    473 #ifdef __NetBSD__
    474 		if (st.st_size == 0) {
    475 			off_t dsize;
    476 
    477 			if (ioctl(fd, DIOCGMEDIASIZE, &dsize) == 0)
    478 				st.st_size = dsize;
    479 		}
    480 #endif	/* __NetBSD__ */
    481 		close(fd);
    482 		(void) sprintf(realpath, "%s", path);
    483 		dsk = strstr(path, "/dsk/");
    484 		if (dsk != NULL)
    485 			(void) sprintf(realpath + (dsk - path) + 1, "r%s",
    486 			    dsk + 1);
    487 	} else {
    488 		(void) sprintf(realpath, "%s", path);
    489 		if (!(flags & FCREAT) && stat64(realpath, &st) == -1)
    490 			return (errno);
    491 	}
    492 
    493 	if (flags & FCREAT)
    494 		old_umask = umask(0);
    495 
    496 	/*
    497 	 * The construct 'flags - FREAD' conveniently maps combinations of
    498 	 * FREAD and FWRITE to the corresponding O_RDONLY, O_WRONLY, and O_RDWR.
    499 	 */
    500 	fd = open64(realpath, flags - FREAD, mode);
    501 
    502 	if (flags & FCREAT)
    503 		(void) umask(old_umask);
    504 
    505 	if (vn_dumpdir != NULL) {
    506 		char dumppath[MAXPATHLEN];
    507 		(void) snprintf(dumppath, sizeof (dumppath),
    508 		    "%s/%s", vn_dumpdir, basename(realpath));
    509 		dump_fd = open64(dumppath, O_CREAT | O_WRONLY, 0666);
    510 		if (dump_fd == -1)
    511 			return (errno);
    512 	} else {
    513 		dump_fd = -1;
    514 	}
    515 
    516 	if (fd == -1)
    517 		return (errno);
    518 
    519 	if (fstat64(fd, &st) == -1) {
    520 		close(fd);
    521 		return (errno);
    522 	}
    523 
    524 	(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
    525 
    526 	*vpp = vp = umem_zalloc(sizeof (vnode_t), UMEM_NOFAIL);
    527 
    528 	vp->v_fd = fd;
    529 	vp->v_size = st.st_size;
    530 	vp->v_path = spa_strdup(path);
    531 	vp->v_dump_fd = dump_fd;
    532 
    533 	return (0);
    534 }
    535 
    536 /*ARGSUSED*/
    537 int
    538 vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2,
    539     int x3, vnode_t *startvp, int fd)
    540 {
    541 	char *realpath = umem_alloc(strlen(path) + 2, UMEM_NOFAIL);
    542 	int ret;
    543 
    544 	ASSERT(startvp == rootdir);
    545 	(void) sprintf(realpath, "/%s", path);
    546 
    547 	/* fd ignored for now, need if want to simulate nbmand support */
    548 	ret = vn_open(realpath, x1, flags, mode, vpp, x2, x3);
    549 
    550 	umem_free(realpath, strlen(path) + 2);
    551 
    552 	return (ret);
    553 }
    554 
    555 /*ARGSUSED*/
    556 int
    557 vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
    558     int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp)
    559 {
    560 	ssize_t iolen, split;
    561 
    562 	if (uio == UIO_READ) {
    563 		iolen = pread64(vp->v_fd, addr, len, offset);
    564 		if (vp->v_dump_fd != -1) {
    565 			int status =
    566 			    pwrite64(vp->v_dump_fd, addr, iolen, offset);
    567 			ASSERT(status != -1);
    568 		}
    569 	} else {
    570 		/*
    571 		 * To simulate partial disk writes, we split writes into two
    572 		 * system calls so that the process can be killed in between.
    573 		 */
    574 		int sectors = len >> SPA_MINBLOCKSHIFT;
    575 		split = (sectors > 0 ? rand() % sectors : 0) <<
    576 		    SPA_MINBLOCKSHIFT;
    577 		iolen = pwrite64(vp->v_fd, addr, split, offset);
    578 		iolen += pwrite64(vp->v_fd, (char *)addr + split,
    579 		    len - split, offset + split);
    580 	}
    581 
    582 	if (iolen == -1)
    583 		return (errno);
    584 	if (residp)
    585 		*residp = len - iolen;
    586 	else if (iolen != len)
    587 		return (EIO);
    588 	return (0);
    589 }
    590 
    591 void
    592 vn_close(vnode_t *vp, int openflag, cred_t *cr, kthread_t *td)
    593 {
    594 	close(vp->v_fd);
    595 	if (vp->v_dump_fd != -1)
    596 		close(vp->v_dump_fd);
    597 	spa_strfree(vp->v_path);
    598 	umem_free(vp, sizeof (vnode_t));
    599 }
    600 
    601 /*
    602  * At a minimum we need to update the size since vdev_reopen()
    603  * will no longer call vn_openat().
    604  */
    605 int
    606 fop_getattr(vnode_t *vp, vattr_t *vap)
    607 {
    608 	struct stat64 st;
    609 
    610 	if (fstat64(vp->v_fd, &st) == -1) {
    611 		close(vp->v_fd);
    612 		return (errno);
    613 	}
    614 #ifdef __NetBSD__
    615 	if (st.st_size == 0) {
    616 		off_t dsize;
    617 
    618 		if (ioctl(vp->v_fd, DIOCGMEDIASIZE, &dsize) == 0)
    619 			st.st_size = dsize;
    620 	}
    621 #endif	/* __NetBSD__ */
    622 
    623 	vap->va_size = st.st_size;
    624 	return (0);
    625 }
    626 
    627 #ifdef ZFS_DEBUG
    628 
    629 /*
    630  * =========================================================================
    631  * Figure out which debugging statements to print
    632  * =========================================================================
    633  */
    634 
    635 static char *dprintf_string;
    636 static int dprintf_print_all;
    637 
    638 int
    639 dprintf_find_string(const char *string)
    640 {
    641 	char *tmp_str = dprintf_string;
    642 	int len = strlen(string);
    643 
    644 	/*
    645 	 * Find out if this is a string we want to print.
    646 	 * String format: file1.c,function_name1,file2.c,file3.c
    647 	 */
    648 
    649 	while (tmp_str != NULL) {
    650 		if (strncmp(tmp_str, string, len) == 0 &&
    651 		    (tmp_str[len] == ',' || tmp_str[len] == '\0'))
    652 			return (1);
    653 		tmp_str = strchr(tmp_str, ',');
    654 		if (tmp_str != NULL)
    655 			tmp_str++; /* Get rid of , */
    656 	}
    657 	return (0);
    658 }
    659 
    660 void
    661 dprintf_setup(int *argc, char **argv)
    662 {
    663 	int i, j;
    664 
    665 	/*
    666 	 * Debugging can be specified two ways: by setting the
    667 	 * environment variable ZFS_DEBUG, or by including a
    668 	 * "debug=..."  argument on the command line.  The command
    669 	 * line setting overrides the environment variable.
    670 	 */
    671 
    672 	for (i = 1; i < *argc; i++) {
    673 		int len = strlen("debug=");
    674 		/* First look for a command line argument */
    675 		if (strncmp("debug=", argv[i], len) == 0) {
    676 			dprintf_string = argv[i] + len;
    677 			/* Remove from args */
    678 			for (j = i; j < *argc; j++)
    679 				argv[j] = argv[j+1];
    680 			argv[j] = NULL;
    681 			(*argc)--;
    682 		}
    683 	}
    684 
    685 	if (dprintf_string == NULL) {
    686 		/* Look for ZFS_DEBUG environment variable */
    687 		dprintf_string = getenv("ZFS_DEBUG");
    688 	}
    689 
    690 	/*
    691 	 * Are we just turning on all debugging?
    692 	 */
    693 	if (dprintf_find_string("on"))
    694 		dprintf_print_all = 1;
    695 
    696 	if (dprintf_string != NULL)
    697 		zfs_flags |= ZFS_DEBUG_DPRINTF;
    698 }
    699 
    700 int
    701 sysctl_handle_64(SYSCTL_HANDLER_ARGS)
    702 {
    703 	return (0);
    704 }
    705 
    706 /*
    707  * =========================================================================
    708  * debug printfs
    709  * =========================================================================
    710  */
    711 void
    712 __dprintf(const char *file, const char *func, int line, const char *fmt, ...)
    713 {
    714 	const char *newfile;
    715 	va_list adx;
    716 
    717 	/*
    718 	 * Get rid of annoying "../common/" prefix to filename.
    719 	 */
    720 	newfile = strrchr(file, '/');
    721 	if (newfile != NULL) {
    722 		newfile = newfile + 1; /* Get rid of leading / */
    723 	} else {
    724 		newfile = file;
    725 	}
    726 
    727 	if (dprintf_print_all ||
    728 	    dprintf_find_string(newfile) ||
    729 	    dprintf_find_string(func)) {
    730 		/* Print out just the function name if requested */
    731 		flockfile(stdout);
    732 		if (dprintf_find_string("pid"))
    733 			(void) printf("%d ", getpid());
    734 		if (dprintf_find_string("tid"))
    735 			(void) printf("%lu ", thr_self());
    736 #if 0
    737 		if (dprintf_find_string("cpu"))
    738 			(void) printf("%u ", getcpuid());
    739 #endif
    740 		if (dprintf_find_string("time"))
    741 			(void) printf("%llu ", gethrtime());
    742 		if (dprintf_find_string("long"))
    743 			(void) printf("%s, line %d: ", newfile, line);
    744 		(void) printf("%s: ", func);
    745 		va_start(adx, fmt);
    746 		(void) vprintf(fmt, adx);
    747 		va_end(adx);
    748 		funlockfile(stdout);
    749 	}
    750 }
    751 
    752 #endif /* ZFS_DEBUG */
    753 
    754 /*
    755  * =========================================================================
    756  * cmn_err() and panic()
    757  * =========================================================================
    758  */
    759 static char ce_prefix[CE_IGNORE][10] = { "", "NOTICE: ", "WARNING: ", "" };
    760 static char ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" };
    761 
    762 void
    763 vpanic(const char *fmt, va_list adx)
    764 {
    765 	(void) fprintf(stderr, "error: ");
    766 	(void) vfprintf(stderr, fmt, adx);
    767 	(void) fprintf(stderr, "\n");
    768 
    769 	abort();	/* think of it as a "user-level crash dump" */
    770 }
    771 
    772 void
    773 panic(const char *fmt, ...)
    774 {
    775 	va_list adx;
    776 
    777 	va_start(adx, fmt);
    778 	vpanic(fmt, adx);
    779 	va_end(adx);
    780 }
    781 
    782 void
    783 vcmn_err(int ce, const char *fmt, va_list adx)
    784 {
    785 	if (ce == CE_PANIC)
    786 		vpanic(fmt, adx);
    787 	if (ce != CE_NOTE) {	/* suppress noise in userland stress testing */
    788 		(void) fprintf(stderr, "%s", ce_prefix[ce]);
    789 		(void) vfprintf(stderr, fmt, adx);
    790 		(void) fprintf(stderr, "%s", ce_suffix[ce]);
    791 	}
    792 }
    793 
    794 /*PRINTFLIKE2*/
    795 void
    796 cmn_err(int ce, const char *fmt, ...)
    797 {
    798 	va_list adx;
    799 
    800 	va_start(adx, fmt);
    801 	vcmn_err(ce, fmt, adx);
    802 	va_end(adx);
    803 }
    804 
    805 /*
    806  * =========================================================================
    807  * kobj interfaces
    808  * =========================================================================
    809  */
    810 struct _buf *
    811 kobj_open_file(char *name)
    812 {
    813 	struct _buf *file;
    814 	vnode_t *vp;
    815 
    816 	/* set vp as the _fd field of the file */
    817 	if (vn_openat(name, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0, rootdir,
    818 	    -1) != 0)
    819 		return ((void *)-1UL);
    820 
    821 	file = umem_zalloc(sizeof (struct _buf), UMEM_NOFAIL);
    822 	file->_fd = (intptr_t)vp;
    823 	return (file);
    824 }
    825 
    826 int
    827 kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
    828 {
    829 	ssize_t resid;
    830 
    831 	vn_rdwr(UIO_READ, (vnode_t *)file->_fd, buf, size, (offset_t)off,
    832 	    UIO_SYSSPACE, 0, 0, 0, &resid);
    833 
    834 	return (size - resid);
    835 }
    836 
    837 void
    838 kobj_close_file(struct _buf *file)
    839 {
    840 	vn_close((vnode_t *)file->_fd, 0, NULL, NULL);
    841 	umem_free(file, sizeof (struct _buf));
    842 }
    843 
    844 int
    845 kobj_get_filesize(struct _buf *file, uint64_t *size)
    846 {
    847 	struct stat64 st;
    848 	vnode_t *vp = (vnode_t *)file->_fd;
    849 
    850 	if (fstat64(vp->v_fd, &st) == -1) {
    851 		vn_close(vp, 0, NULL, NULL);
    852 		return (errno);
    853 	}
    854 	*size = st.st_size;
    855 	return (0);
    856 }
    857 
    858 /*
    859  * =========================================================================
    860  * misc routines
    861  * =========================================================================
    862  */
    863 
    864 void
    865 delay(clock_t ticks)
    866 {
    867 	poll(0, 0, ticks * (1000 / hz));
    868 }
    869 
    870 #if 0
    871 /*
    872  * Find highest one bit set.
    873  *	Returns bit number + 1 of highest bit that is set, otherwise returns 0.
    874  */
    875 int
    876 highbit64(uint64_t i)
    877 {
    878 	int h = 1;
    879 
    880 	if (i == 0)
    881 		return (0);
    882 	if (i & 0xffffffff00000000ULL) {
    883 		h += 32; i >>= 32;
    884 	}
    885 	if (i & 0xffff0000) {
    886 		h += 16; i >>= 16;
    887 	}
    888 	if (i & 0xff00) {
    889 		h += 8; i >>= 8;
    890 	}
    891 	if (i & 0xf0) {
    892 		h += 4; i >>= 4;
    893 	}
    894 	if (i & 0xc) {
    895 		h += 2; i >>= 2;
    896 	}
    897 	if (i & 0x2) {
    898 		h += 1;
    899 	}
    900 	return (h);
    901 }
    902 #endif
    903 
    904 static int random_fd = -1, urandom_fd = -1;
    905 
    906 static int
    907 random_get_bytes_common(uint8_t *ptr, size_t len, int fd)
    908 {
    909 	size_t resid = len;
    910 	ssize_t bytes;
    911 
    912 	ASSERT(fd != -1);
    913 
    914 	while (resid != 0) {
    915 		bytes = read(fd, ptr, resid);
    916 		ASSERT3S(bytes, >=, 0);
    917 		ptr += bytes;
    918 		resid -= bytes;
    919 	}
    920 
    921 	return (0);
    922 }
    923 
    924 int
    925 random_get_bytes(uint8_t *ptr, size_t len)
    926 {
    927 	return (random_get_bytes_common(ptr, len, random_fd));
    928 }
    929 
    930 int
    931 random_get_pseudo_bytes(uint8_t *ptr, size_t len)
    932 {
    933 	return (random_get_bytes_common(ptr, len, urandom_fd));
    934 }
    935 
    936 int
    937 ddi_strtoul(const char *hw_serial, char **nptr, int base, unsigned long *result)
    938 {
    939 	char *end;
    940 
    941 	*result = strtoul(hw_serial, &end, base);
    942 	if (*result == 0)
    943 		return (errno);
    944 	return (0);
    945 }
    946 
    947 int
    948 ddi_strtoull(const char *str, char **nptr, int base, u_longlong_t *result)
    949 {
    950 	char *end;
    951 
    952 	*result = strtoull(str, &end, base);
    953 	if (*result == 0)
    954 		return (errno);
    955 	return (0);
    956 }
    957 
    958 #ifndef __FreeBSD__
    959 /* ARGSUSED */
    960 cyclic_id_t
    961 cyclic_add(cyc_handler_t *hdlr, cyc_time_t *when)
    962 {
    963 	return (1);
    964 }
    965 
    966 /* ARGSUSED */
    967 void
    968 cyclic_remove(cyclic_id_t id)
    969 {
    970 }
    971 
    972 /* ARGSUSED */
    973 int
    974 cyclic_reprogram(cyclic_id_t id, hrtime_t expiration)
    975 {
    976 	return (1);
    977 }
    978 #endif
    979 
    980 /*
    981  * =========================================================================
    982  * kernel emulation setup & teardown
    983  * =========================================================================
    984  */
    985 static int
    986 umem_out_of_memory(void)
    987 {
    988 	char errmsg[] = "out of memory -- generating core dump\n";
    989 
    990 	write(fileno(stderr), errmsg, sizeof (errmsg));
    991 	abort();
    992 	return (0);
    993 }
    994 
    995 void
    996 kernel_init(int mode)
    997 {
    998 	extern uint_t rrw_tsd_key;
    999 
   1000 	umem_nofail_callback(umem_out_of_memory);
   1001 
   1002 	physmem = sysconf(_SC_PHYS_PAGES);
   1003 
   1004 	dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
   1005 	    (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
   1006 
   1007 	(void) snprintf(hw_serial, sizeof (hw_serial), "%lu",
   1008 	    (mode & FWRITE) ? (unsigned long)gethostid() : 0);
   1009 
   1010 	VERIFY((random_fd = open("/dev/random", O_RDONLY)) != -1);
   1011 	VERIFY((urandom_fd = open("/dev/urandom", O_RDONLY)) != -1);
   1012 
   1013 	system_taskq_init();
   1014 
   1015 #ifdef illumos
   1016 	mutex_init(&cpu_lock, NULL, MUTEX_DEFAULT, NULL);
   1017 #endif
   1018 
   1019 	spa_init(mode);
   1020 
   1021 	tsd_create(&rrw_tsd_key, rrw_tsd_destroy);
   1022 }
   1023 
   1024 void
   1025 kernel_fini(void)
   1026 {
   1027 	spa_fini();
   1028 
   1029 	system_taskq_fini();
   1030 
   1031 	close(random_fd);
   1032 	close(urandom_fd);
   1033 
   1034 	random_fd = -1;
   1035 	urandom_fd = -1;
   1036 }
   1037 
   1038 int
   1039 z_uncompress(void *dst, size_t *dstlen, const void *src, size_t srclen)
   1040 {
   1041 	int ret;
   1042 	uLongf len = *dstlen;
   1043 
   1044 	if ((ret = uncompress(dst, &len, src, srclen)) == Z_OK)
   1045 		*dstlen = (size_t)len;
   1046 
   1047 	return (ret);
   1048 }
   1049 
   1050 int
   1051 z_compress_level(void *dst, size_t *dstlen, const void *src, size_t srclen,
   1052     int level)
   1053 {
   1054 	int ret;
   1055 	uLongf len = *dstlen;
   1056 
   1057 	if ((ret = compress2(dst, &len, src, srclen, level)) == Z_OK)
   1058 		*dstlen = (size_t)len;
   1059 
   1060 	return (ret);
   1061 }
   1062 
   1063 uid_t
   1064 crgetuid(cred_t *cr)
   1065 {
   1066 	return (0);
   1067 }
   1068 
   1069 uid_t
   1070 crgetruid(cred_t *cr)
   1071 {
   1072 	return (0);
   1073 }
   1074 
   1075 gid_t
   1076 crgetgid(cred_t *cr)
   1077 {
   1078 	return (0);
   1079 }
   1080 
   1081 int
   1082 crgetngroups(cred_t *cr)
   1083 {
   1084 	return (0);
   1085 }
   1086 
   1087 gid_t *
   1088 crgetgroups(cred_t *cr)
   1089 {
   1090 	return (NULL);
   1091 }
   1092 
   1093 int
   1094 zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr)
   1095 {
   1096 	return (0);
   1097 }
   1098 
   1099 int
   1100 zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr)
   1101 {
   1102 	return (0);
   1103 }
   1104 
   1105 int
   1106 zfs_secpolicy_destroy_perms(const char *name, cred_t *cr)
   1107 {
   1108 	return (0);
   1109 }
   1110 
   1111 ksiddomain_t *
   1112 ksid_lookupdomain(const char *dom)
   1113 {
   1114 	ksiddomain_t *kd;
   1115 
   1116 	kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL);
   1117 	kd->kd_name = spa_strdup(dom);
   1118 	return (kd);
   1119 }
   1120 
   1121 void
   1122 ksiddomain_rele(ksiddomain_t *ksid)
   1123 {
   1124 	spa_strfree(ksid->kd_name);
   1125 	umem_free(ksid, sizeof (ksiddomain_t));
   1126 }
   1127 
   1128 /*
   1129  * Do not change the length of the returned string; it must be freed
   1130  * with strfree().
   1131  */
   1132 char *
   1133 kmem_asprintf(const char *fmt, ...)
   1134 {
   1135 	int size;
   1136 	va_list adx;
   1137 	char *buf;
   1138 
   1139 	va_start(adx, fmt);
   1140 	size = vsnprintf(NULL, 0, fmt, adx) + 1;
   1141 	va_end(adx);
   1142 
   1143 	buf = kmem_alloc(size, KM_SLEEP);
   1144 
   1145 	va_start(adx, fmt);
   1146 	size = vsnprintf(buf, size, fmt, adx);
   1147 	va_end(adx);
   1148 
   1149 	return (buf);
   1150 }
   1151 
   1152 /* ARGSUSED */
   1153 int
   1154 zfs_onexit_fd_hold(int fd, minor_t *minorp)
   1155 {
   1156 	*minorp = 0;
   1157 	return (0);
   1158 }
   1159 
   1160 /* ARGSUSED */
   1161 void
   1162 zfs_onexit_fd_rele(int fd)
   1163 {
   1164 }
   1165 
   1166 /* ARGSUSED */
   1167 int
   1168 zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data,
   1169     uint64_t *action_handle)
   1170 {
   1171 	return (0);
   1172 }
   1173 
   1174 /* ARGSUSED */
   1175 int
   1176 zfs_onexit_del_cb(minor_t minor, uint64_t action_handle, boolean_t fire)
   1177 {
   1178 	return (0);
   1179 }
   1180 
   1181 /* ARGSUSED */
   1182 int
   1183 zfs_onexit_cb_data(minor_t minor, uint64_t action_handle, void **data)
   1184 {
   1185 	return (0);
   1186 }
   1187 
   1188 #ifdef __FreeBSD__
   1189 /* ARGSUSED */
   1190 int
   1191 zvol_create_minors(const char *name)
   1192 {
   1193 	return (0);
   1194 }
   1195 #endif
   1196 
   1197 #ifdef illumos
   1198 void
   1199 bioinit(buf_t *bp)
   1200 {
   1201 	bzero(bp, sizeof (buf_t));
   1202 }
   1203 
   1204 void
   1205 biodone(buf_t *bp)
   1206 {
   1207 	if (bp->b_iodone != NULL) {
   1208 		(*(bp->b_iodone))(bp);
   1209 		return;
   1210 	}
   1211 	ASSERT((bp->b_flags & B_DONE) == 0);
   1212 	bp->b_flags |= B_DONE;
   1213 }
   1214 
   1215 void
   1216 bioerror(buf_t *bp, int error)
   1217 {
   1218 	ASSERT(bp != NULL);
   1219 	ASSERT(error >= 0);
   1220 
   1221 	if (error != 0) {
   1222 		bp->b_flags |= B_ERROR;
   1223 	} else {
   1224 		bp->b_flags &= ~B_ERROR;
   1225 	}
   1226 	bp->b_error = error;
   1227 }
   1228 
   1229 
   1230 int
   1231 geterror(struct buf *bp)
   1232 {
   1233 	int error = 0;
   1234 
   1235 	if (bp->b_flags & B_ERROR) {
   1236 		error = bp->b_error;
   1237 		if (!error)
   1238 			error = EIO;
   1239 	}
   1240 	return (error);
   1241 }
   1242 #endif
   1243