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