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