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