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