Print this page
8115 parallel zfs mount


   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;


 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


 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 }


   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  * Copyright 2017 RackTop Systems.
  26  */
  27 
  28 #include <assert.h>
  29 #include <fcntl.h>
  30 #include <poll.h>
  31 #include <stdio.h>
  32 #include <stdlib.h>
  33 #include <string.h>
  34 #include <zlib.h>
  35 #include <libgen.h>
  36 #include <sys/spa.h>
  37 #include <sys/stat.h>
  38 #include <sys/processor.h>
  39 #include <sys/zfs_context.h>
  40 #include <sys/rrwlock.h>
  41 #include <sys/zmod.h>
  42 #include <sys/utsname.h>
  43 #include <sys/systeminfo.h>
  44 
  45 extern void system_taskq_init(void);
  46 extern void system_taskq_fini(void);
  47 
  48 /*
  49  * Emulation of kernel services in userland.
  50  */
  51 
  52 pgcnt_t physmem;

  53 vnode_t *rootdir = (vnode_t *)0xabcd1234;
  54 char hw_serial[HW_HOSTID_LEN];
  55 kmutex_t cpu_lock;
  56 vmem_t *zio_arena = NULL;
  57 
  58 /* If set, all blocks read will be copied to the specified directory. */
  59 char *vn_dumpdir = NULL;
  60 
  61 struct utsname utsname = {
  62         "userland", "libzpool", "1", "1", "na"
  63 };
  64 



  65 /*
  66  * =========================================================================








































































































































































































































































































































  67  * vnode operations
  68  * =========================================================================
  69  */
  70 /*
  71  * Note: for the xxxat() versions of these functions, we assume that the
  72  * starting vp is always rootdir (which is true for spa_directory.c, the only
  73  * ZFS consumer of these interfaces).  We assert this is true, and then emulate
  74  * them by adding '/' in front of the path.
  75  */
  76 
  77 /*ARGSUSED*/
  78 int
  79 vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
  80 {
  81         int fd;
  82         int dump_fd;
  83         vnode_t *vp;
  84         int old_umask;
  85         char realpath[MAXPATHLEN];
  86         struct stat64 st;


 346                 if (dprintf_find_string("tid"))
 347                         (void) printf("%u ", thr_self());
 348                 if (dprintf_find_string("cpu"))
 349                         (void) printf("%u ", getcpuid());
 350                 if (dprintf_find_string("time"))
 351                         (void) printf("%llu ", gethrtime());
 352                 if (dprintf_find_string("long"))
 353                         (void) printf("%s, line %d: ", newfile, line);
 354                 (void) printf("%s: ", func);
 355                 va_start(adx, fmt);
 356                 (void) vprintf(fmt, adx);
 357                 va_end(adx);
 358                 funlockfile(stdout);
 359         }
 360 }
 361 
 362 #endif /* ZFS_DEBUG */
 363 
 364 /*
 365  * =========================================================================


















































 366  * kobj interfaces
 367  * =========================================================================
 368  */
 369 struct _buf *
 370 kobj_open_file(char *name)
 371 {
 372         struct _buf *file;
 373         vnode_t *vp;
 374 
 375         /* set vp as the _fd field of the file */
 376         if (vn_openat(name, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0, rootdir,
 377             -1) != 0)
 378                 return ((void *)-1UL);
 379 
 380         file = umem_zalloc(sizeof (struct _buf), UMEM_NOFAIL);
 381         file->_fd = (intptr_t)vp;
 382         return (file);
 383 }
 384 
 385 int


 399         vn_close((vnode_t *)file->_fd);
 400         umem_free(file, sizeof (struct _buf));
 401 }
 402 
 403 int
 404 kobj_get_filesize(struct _buf *file, uint64_t *size)
 405 {
 406         struct stat64 st;
 407         vnode_t *vp = (vnode_t *)file->_fd;
 408 
 409         if (fstat64(vp->v_fd, &st) == -1) {
 410                 vn_close(vp);
 411                 return (errno);
 412         }
 413         *size = st.st_size;
 414         return (0);
 415 }
 416 
 417 /*
 418  * =========================================================================






















































































































 419  * kernel emulation setup & teardown
 420  * =========================================================================
 421  */
 422 static int
 423 umem_out_of_memory(void)
 424 {
 425         char errmsg[] = "out of memory -- generating core dump\n";
 426 
 427         write(fileno(stderr), errmsg, sizeof (errmsg));
 428         abort();
 429         return (0);
 430 }
 431 
 432 void
 433 kernel_init(int mode)
 434 {
 435         extern uint_t rrw_tsd_key;
 436 
 437         umem_nofail_callback(umem_out_of_memory);
 438 
 439         physmem = sysconf(_SC_PHYS_PAGES);
 440 
 441         dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
 442             (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
 443 
 444         (void) snprintf(hw_serial, sizeof (hw_serial), "%ld",
 445             (mode & FWRITE) ? gethostid() : 0);
 446 



 447         system_taskq_init();
 448 
 449         mutex_init(&cpu_lock, NULL, MUTEX_DEFAULT, NULL);
 450 
 451         spa_init(mode);
 452 
 453         tsd_create(&rrw_tsd_key, rrw_tsd_destroy);
 454 }
 455 
 456 void
 457 kernel_fini(void)
 458 {
 459         spa_fini();
 460 
 461         system_taskq_fini();






 462 }
 463 
 464 int
 465 z_uncompress(void *dst, size_t *dstlen, const void *src, size_t srclen)
 466 {
 467         int ret;
 468         uLongf len = *dstlen;
 469 
 470         if ((ret = uncompress(dst, &len, src, srclen)) == Z_OK)
 471                 *dstlen = (size_t)len;
 472 
 473         return (ret);
 474 }
 475 
 476 int
 477 z_compress_level(void *dst, size_t *dstlen, const void *src, size_t srclen,
 478     int level)
 479 {
 480         int ret;
 481         uLongf len = *dstlen;
 482 
 483         if ((ret = compress2(dst, &len, src, srclen, level)) == Z_OK)
 484                 *dstlen = (size_t)len;
 485 
 486         return (ret);
 487 }
 488 


















 489 int












 490 zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr)
 491 {
 492         return (0);
 493 }
 494 
 495 int
 496 zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr)
 497 {
 498         return (0);
 499 }
 500 
 501 int
 502 zfs_secpolicy_destroy_perms(const char *name, cred_t *cr)
 503 {
 504         return (0);
 505 }
 506 









































 507 /* ARGSUSED */
 508 int
 509 zfs_onexit_fd_hold(int fd, minor_t *minorp)
 510 {
 511         *minorp = 0;
 512         return (0);
 513 }
 514 
 515 /* ARGSUSED */
 516 void
 517 zfs_onexit_fd_rele(int fd)
 518 {
 519 }
 520 
 521 /* ARGSUSED */
 522 int
 523 zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data,
 524     uint64_t *action_handle)
 525 {
 526         return (0);
 527 }
 528 
 529 /* ARGSUSED */
 530 int
 531 zfs_onexit_del_cb(minor_t minor, uint64_t action_handle, boolean_t fire)
 532 {
 533         return (0);
 534 }
 535 
 536 /* ARGSUSED */
 537 int
 538 zfs_onexit_cb_data(minor_t minor, uint64_t action_handle, void **data)
 539 {
 540         return (0);













































 541 }