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