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