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 2020 Joyent, Inc. 25 * Copyright 2017 RackTop Systems. 26 * Copyright 2026 Oxide Computer Company 27 */ 28 29 #include <assert.h> 30 #include <fcntl.h> 31 #include <poll.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include <zlib.h> 36 #include <libgen.h> 37 #include <sys/spa.h> 38 #include <sys/stat.h> 39 #include <sys/processor.h> 40 #include <sys/zfs_context.h> 41 #include <zfs_fletcher.h> 42 #include <sys/rrwlock.h> 43 #include <sys/zmod.h> 44 #include <sys/utsname.h> 45 #include <sys/systeminfo.h> 46 #include <libzutil.h> 47 #include <sys/crypto/common.h> 48 #include <sys/crypto/impl.h> 49 #include <sys/crypto/api.h> 50 #include <sys/sha2.h> 51 #include <crypto/aes/aes_impl.h> 52 53 extern void system_taskq_init(void); 54 extern void system_taskq_fini(void); 55 56 /* 57 * Emulation of kernel services in userland. 58 */ 59 60 pgcnt_t physmem; 61 vnode_t *rootdir = (vnode_t *)0xabcd1234; 62 char hw_serial[HW_HOSTID_LEN]; 63 kmutex_t cpu_lock; 64 vmem_t *zio_arena = NULL; 65 66 /* If set, all blocks read will be copied to the specified directory. */ 67 char *vn_dumpdir = NULL; 68 69 struct utsname utsname = { 70 "userland", "libzpool", "1", "1", "na" 71 }; 72 73 /* 74 * ========================================================================= 75 * vnode operations 76 * ========================================================================= 77 */ 78 /* 79 * Note: for the xxxat() versions of these functions, we assume that the 80 * starting vp is always rootdir (which is true for spa_directory.c, the only 81 * ZFS consumer of these interfaces). We assert this is true, and then emulate 82 * them by adding '/' in front of the path. 83 */ 84 85 /*ARGSUSED*/ 86 int 87 vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3) 88 { 89 int fd; 90 int dump_fd; 91 vnode_t *vp; 92 int old_umask; 93 char realpath[MAXPATHLEN]; 94 struct stat64 st; 95 96 /* 97 * If we're accessing a real disk from userland, we need to use 98 * the character interface to avoid caching. This is particularly 99 * important if we're trying to look at a real in-kernel storage 100 * pool from userland, e.g. via zdb, because otherwise we won't 101 * see the changes occurring under the segmap cache. 102 * On the other hand, the stupid character device returns zero 103 * for its size. So -- gag -- we open the block device to get 104 * its size, and remember it for subsequent VOP_GETATTR(). 105 */ 106 if (strncmp(path, "/dev/", 5) == 0) { 107 char *dsk; 108 fd = open64(path, O_RDONLY); 109 if (fd == -1) 110 return (errno); 111 if (fstat64(fd, &st) == -1) { 112 close(fd); 113 return (errno); 114 } 115 close(fd); 116 (void) sprintf(realpath, "%s", path); 117 dsk = strstr(path, "/dsk/"); 118 if (dsk != NULL) 119 (void) sprintf(realpath + (dsk - path) + 1, "r%s", 120 dsk + 1); 121 } else { 122 (void) sprintf(realpath, "%s", path); 123 if (!(flags & FCREAT) && stat64(realpath, &st) == -1) 124 return (errno); 125 } 126 127 if (flags & FCREAT) 128 old_umask = umask(0); 129 130 /* 131 * The construct 'flags - FREAD' conveniently maps combinations of 132 * FREAD and FWRITE to the corresponding O_RDONLY, O_WRONLY, and O_RDWR. 133 */ 134 fd = open64(realpath, flags - FREAD, mode); 135 136 if (flags & FCREAT) 137 (void) umask(old_umask); 138 139 if (vn_dumpdir != NULL) { 140 char dumppath[MAXPATHLEN]; 141 (void) snprintf(dumppath, sizeof (dumppath), 142 "%s/%s", vn_dumpdir, basename(realpath)); 143 dump_fd = open64(dumppath, O_CREAT | O_WRONLY, 0666); 144 if (dump_fd == -1) 145 return (errno); 146 } else { 147 dump_fd = -1; 148 } 149 150 if (fd == -1) 151 return (errno); 152 153 if (fstat64(fd, &st) == -1) { 154 close(fd); 155 return (errno); 156 } 157 158 (void) fcntl(fd, F_SETFD, FD_CLOEXEC); 159 160 *vpp = vp = umem_zalloc(sizeof (vnode_t), UMEM_NOFAIL); 161 162 vp->v_fd = fd; 163 vp->v_size = st.st_size; 164 vp->v_path = spa_strdup(path); 165 vp->v_dump_fd = dump_fd; 166 167 return (0); 168 } 169 170 /*ARGSUSED*/ 171 int 172 vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, 173 int x3, vnode_t *startvp, int fd) 174 { 175 char *realpath = umem_alloc(strlen(path) + 2, UMEM_NOFAIL); 176 int ret; 177 178 ASSERT(startvp == rootdir); 179 (void) sprintf(realpath, "/%s", path); 180 181 /* fd ignored for now, need if want to simulate nbmand support */ 182 ret = vn_open(realpath, x1, flags, mode, vpp, x2, x3); 183 184 umem_free(realpath, strlen(path) + 2); 185 186 return (ret); 187 } 188 189 /*ARGSUSED*/ 190 int 191 vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset, 192 int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp) 193 { 194 ssize_t iolen, split; 195 196 if (uio == UIO_READ) { 197 iolen = pread64(vp->v_fd, addr, len, offset); 198 if (vp->v_dump_fd != -1) { 199 int status = 200 pwrite64(vp->v_dump_fd, addr, iolen, offset); 201 ASSERT(status != -1); 202 } 203 } else { 204 /* 205 * To simulate partial disk writes, we split writes into two 206 * system calls so that the process can be killed in between. 207 */ 208 int sectors = len >> SPA_MINBLOCKSHIFT; 209 split = (sectors > 0 ? rand() % sectors : 0) << 210 SPA_MINBLOCKSHIFT; 211 iolen = pwrite64(vp->v_fd, addr, split, offset); 212 iolen += pwrite64(vp->v_fd, (char *)addr + split, 213 len - split, offset + split); 214 } 215 216 if (iolen == -1) 217 return (errno); 218 if (residp) 219 *residp = len - iolen; 220 else if (iolen != len) 221 return (EIO); 222 return (0); 223 } 224 225 void 226 vn_close(vnode_t *vp) 227 { 228 close(vp->v_fd); 229 if (vp->v_dump_fd != -1) 230 close(vp->v_dump_fd); 231 spa_strfree(vp->v_path); 232 umem_free(vp, sizeof (vnode_t)); 233 } 234 235 /* 236 * At a minimum we need to update the size since vdev_reopen() 237 * will no longer call vn_openat(). 238 */ 239 int 240 fop_getattr(vnode_t *vp, vattr_t *vap) 241 { 242 struct stat64 st; 243 244 if (fstat64(vp->v_fd, &st) == -1) { 245 close(vp->v_fd); 246 return (errno); 247 } 248 249 vap->va_size = st.st_size; 250 return (0); 251 } 252 253 #ifdef ZFS_DEBUG 254 255 /* 256 * ========================================================================= 257 * Figure out which debugging statements to print 258 * ========================================================================= 259 */ 260 261 static char *dprintf_string; 262 static int dprintf_print_all; 263 264 int 265 dprintf_find_string(const char *string) 266 { 267 char *tmp_str = dprintf_string; 268 int len = strlen(string); 269 270 /* 271 * Find out if this is a string we want to print. 272 * String format: file1.c,function_name1,file2.c,file3.c 273 */ 274 275 while (tmp_str != NULL) { 276 if (strncmp(tmp_str, string, len) == 0 && 277 (tmp_str[len] == ',' || tmp_str[len] == '\0')) 278 return (1); 279 tmp_str = strchr(tmp_str, ','); 280 if (tmp_str != NULL) 281 tmp_str++; /* Get rid of , */ 282 } 283 return (0); 284 } 285 286 void 287 dprintf_setup(int *argc, char **argv) 288 { 289 int i, j; 290 291 /* 292 * Debugging can be specified two ways: by setting the 293 * environment variable ZFS_DEBUG, or by including a 294 * "debug=..." argument on the command line. The command 295 * line setting overrides the environment variable. 296 */ 297 298 for (i = 1; i < *argc; i++) { 299 int len = strlen("debug="); 300 /* First look for a command line argument */ 301 if (strncmp("debug=", argv[i], len) == 0) { 302 dprintf_string = argv[i] + len; 303 /* Remove from args */ 304 for (j = i; j < *argc; j++) 305 argv[j] = argv[j+1]; 306 argv[j] = NULL; 307 (*argc)--; 308 } 309 } 310 311 if (dprintf_string == NULL) { 312 /* Look for ZFS_DEBUG environment variable */ 313 dprintf_string = getenv("ZFS_DEBUG"); 314 } 315 316 /* 317 * Are we just turning on all debugging? 318 */ 319 if (dprintf_find_string("on")) 320 dprintf_print_all = 1; 321 322 if (dprintf_string != NULL) 323 zfs_flags |= ZFS_DEBUG_DPRINTF; 324 } 325 326 /* 327 * ========================================================================= 328 * debug printfs 329 * ========================================================================= 330 */ 331 void 332 __dprintf(const char *file, const char *func, int line, const char *fmt, ...) 333 { 334 const char *newfile; 335 va_list adx; 336 337 /* 338 * Get rid of annoying "../common/" prefix to filename. 339 */ 340 newfile = strrchr(file, '/'); 341 if (newfile != NULL) { 342 newfile = newfile + 1; /* Get rid of leading / */ 343 } else { 344 newfile = file; 345 } 346 347 if (dprintf_print_all || 348 dprintf_find_string(newfile) || 349 dprintf_find_string(func)) { 350 /* Print out just the function name if requested */ 351 flockfile(stdout); 352 if (dprintf_find_string("pid")) 353 (void) printf("%d ", getpid()); 354 if (dprintf_find_string("tid")) 355 (void) printf("%u ", thr_self()); 356 if (dprintf_find_string("cpu")) 357 (void) printf("%u ", getcpuid()); 358 if (dprintf_find_string("time")) 359 (void) printf("%llu ", gethrtime()); 360 if (dprintf_find_string("long")) 361 (void) printf("%s, line %d: ", newfile, line); 362 (void) printf("%s: ", func); 363 va_start(adx, fmt); 364 (void) vprintf(fmt, adx); 365 va_end(adx); 366 funlockfile(stdout); 367 } 368 } 369 370 #endif /* ZFS_DEBUG */ 371 372 /* 373 * ========================================================================= 374 * kobj interfaces 375 * ========================================================================= 376 */ 377 struct _buf * 378 kobj_open_file(char *name) 379 { 380 struct _buf *file; 381 vnode_t *vp; 382 383 /* set vp as the _fd field of the file */ 384 if (vn_openat(name, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0, rootdir, 385 -1) != 0) 386 return ((void *)-1UL); 387 388 file = umem_zalloc(sizeof (struct _buf), UMEM_NOFAIL); 389 file->_fd = (intptr_t)vp; 390 return (file); 391 } 392 393 int 394 kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off) 395 { 396 ssize_t resid; 397 398 vn_rdwr(UIO_READ, (vnode_t *)file->_fd, buf, size, (offset_t)off, 399 UIO_SYSSPACE, 0, 0, 0, &resid); 400 401 return (size - resid); 402 } 403 404 void 405 kobj_close_file(struct _buf *file) 406 { 407 vn_close((vnode_t *)file->_fd); 408 umem_free(file, sizeof (struct _buf)); 409 } 410 411 int 412 kobj_get_filesize(struct _buf *file, uint64_t *size) 413 { 414 struct stat64 st; 415 vnode_t *vp = (vnode_t *)file->_fd; 416 417 if (fstat64(vp->v_fd, &st) == -1) { 418 vn_close(vp); 419 return (errno); 420 } 421 *size = st.st_size; 422 return (0); 423 } 424 425 /* 426 * ========================================================================= 427 * misc routines 428 * ========================================================================= 429 */ 430 431 /* 432 * Find lowest one bit set. 433 * Returns bit number + 1 of lowest bit that is set, otherwise returns 0. 434 * This is basically a reimplementation of ffsll(), which is GNU specific. 435 */ 436 int 437 lowbit64(uint64_t i) 438 { 439 register int h = 64; 440 if (i == 0) 441 return (0); 442 443 if (i & 0x00000000ffffffffULL) 444 h -= 32; 445 else 446 i >>= 32; 447 448 if (i & 0x0000ffff) 449 h -= 16; 450 else 451 i >>= 16; 452 453 if (i & 0x00ff) 454 h -= 8; 455 else 456 i >>= 8; 457 458 if (i & 0x0f) 459 h -= 4; 460 else 461 i >>= 4; 462 463 if (i & 0x3) 464 h -= 2; 465 else 466 i >>= 2; 467 468 if (i & 0x1) 469 h -= 1; 470 471 return (h); 472 } 473 474 int 475 highbit64(uint64_t i) 476 { 477 int h = 1; 478 479 if (i == 0) 480 return (0); 481 if (i & 0xffffffff00000000ULL) { 482 h += 32; i >>= 32; 483 } 484 if (i & 0xffff0000) { 485 h += 16; i >>= 16; 486 } 487 if (i & 0xff00) { 488 h += 8; i >>= 8; 489 } 490 if (i & 0xf0) { 491 h += 4; i >>= 4; 492 } 493 if (i & 0xc) { 494 h += 2; i >>= 2; 495 } 496 if (i & 0x2) { 497 h += 1; 498 } 499 return (h); 500 } 501 502 /* 503 * ========================================================================= 504 * kernel emulation setup & teardown 505 * ========================================================================= 506 */ 507 static int 508 umem_out_of_memory(void) 509 { 510 char errmsg[] = "out of memory -- generating core dump\n"; 511 512 write(fileno(stderr), errmsg, sizeof (errmsg)); 513 abort(); 514 return (0); 515 } 516 517 void 518 kernel_init(int mode) 519 { 520 extern uint_t rrw_tsd_key; 521 522 umem_nofail_callback(umem_out_of_memory); 523 524 physmem = sysconf(_SC_PHYS_PAGES); 525 526 dprintf_zfs("physmem = %llu pages (%.2f GB)\n", physmem, 527 (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30)); 528 529 (void) snprintf(hw_serial, sizeof (hw_serial), "%ld", 530 (mode & FWRITE) ? get_system_hostid() : 0); 531 532 system_taskq_init(); 533 534 mutex_init(&cpu_lock, NULL, MUTEX_DEFAULT, NULL); 535 536 spa_init(mode); 537 538 fletcher_4_init(); 539 540 tsd_create(&rrw_tsd_key, rrw_tsd_destroy); 541 } 542 543 void 544 kernel_fini(void) 545 { 546 fletcher_4_fini(); 547 548 spa_fini(); 549 550 system_taskq_fini(); 551 } 552 553 /* ARGSUSED */ 554 uint32_t 555 zone_get_hostid(void *zonep) 556 { 557 /* 558 * We're emulating the system's hostid in userland. 559 */ 560 return (strtoul(hw_serial, NULL, 10)); 561 } 562 563 int 564 z_uncompress(void *dst, size_t *dstlen, const void *src, size_t srclen) 565 { 566 int ret; 567 uLongf len = *dstlen; 568 569 if ((ret = uncompress(dst, &len, src, srclen)) == Z_OK) 570 *dstlen = (size_t)len; 571 572 return (ret); 573 } 574 575 int 576 z_uncompress_sleep(void *dst, size_t *dstlen, const void *src, size_t srclen) 577 { 578 return (z_uncompress(dst, dstlen, src, srclen)); 579 } 580 581 int 582 z_compress_level(void *dst, size_t *dstlen, const void *src, size_t srclen, 583 int level) 584 { 585 int ret; 586 uLongf len = *dstlen; 587 588 if ((ret = compress2(dst, &len, src, srclen, level)) == Z_OK) 589 *dstlen = (size_t)len; 590 591 return (ret); 592 } 593 594 int 595 zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr) 596 { 597 return (0); 598 } 599 600 int 601 zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr) 602 { 603 return (0); 604 } 605 606 int 607 zfs_secpolicy_destroy_perms(const char *name, cred_t *cr) 608 { 609 return (0); 610 } 611 612 /* ARGSUSED */ 613 int 614 zfs_onexit_fd_hold(int fd, minor_t *minorp) 615 { 616 *minorp = 0; 617 return (0); 618 } 619 620 /* ARGSUSED */ 621 void 622 zfs_onexit_fd_rele(int fd) 623 { 624 } 625 626 /* ARGSUSED */ 627 int 628 zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data, 629 uint64_t *action_handle) 630 { 631 return (0); 632 } 633 634 /* ARGSUSED */ 635 int 636 zfs_onexit_del_cb(minor_t minor, uint64_t action_handle, boolean_t fire) 637 { 638 return (0); 639 } 640 641 /* ARGSUSED */ 642 int 643 zfs_onexit_cb_data(minor_t minor, uint64_t action_handle, void **data) 644 { 645 return (0); 646 } 647 648 void 649 bioinit(buf_t *bp) 650 { 651 bzero(bp, sizeof (buf_t)); 652 } 653 654 void 655 biodone(buf_t *bp) 656 { 657 if (bp->b_iodone != NULL) { 658 (*(bp->b_iodone))(bp); 659 return; 660 } 661 ASSERT((bp->b_flags & B_DONE) == 0); 662 bp->b_flags |= B_DONE; 663 } 664 665 void 666 bioerror(buf_t *bp, int error) 667 { 668 ASSERT(bp != NULL); 669 ASSERT(error >= 0); 670 671 if (error != 0) { 672 bp->b_flags |= B_ERROR; 673 } else { 674 bp->b_flags &= ~B_ERROR; 675 } 676 bp->b_error = error; 677 } 678 679 680 int 681 geterror(struct buf *bp) 682 { 683 int error = 0; 684 685 if (bp->b_flags & B_ERROR) { 686 error = bp->b_error; 687 if (!error) 688 error = EIO; 689 } 690 return (error); 691 } 692 693 int 694 crypto_create_ctx_template(crypto_mechanism_t *mech, 695 crypto_key_t *key, crypto_ctx_template_t *tmpl, int kmflag) 696 { 697 return (0); 698 } 699 700 crypto_mech_type_t 701 crypto_mech2id(const char *name) 702 { 703 return (CRYPTO_MECH_INVALID); 704 } 705 706 int 707 crypto_mac(crypto_mechanism_t *mech, crypto_data_t *data, 708 crypto_key_t *key, crypto_ctx_template_t impl, 709 crypto_data_t *mac, crypto_call_req_t *cr) 710 { 711 return (0); 712 } 713 714 int 715 crypto_encrypt(crypto_mechanism_t *mech, crypto_data_t *plaintext, 716 crypto_key_t *key, crypto_ctx_template_t tmpl, 717 crypto_data_t *ciphertext, crypto_call_req_t *cr) 718 { 719 return (0); 720 } 721 722 /* This could probably be a weak reference */ 723 int 724 crypto_decrypt(crypto_mechanism_t *mech, crypto_data_t *plaintext, 725 crypto_key_t *key, crypto_ctx_template_t tmpl, 726 crypto_data_t *ciphertext, crypto_call_req_t *cr) 727 { 728 return (0); 729 } 730 731 732 int 733 crypto_digest_final(crypto_context_t context, crypto_data_t *digest, 734 crypto_call_req_t *cr) 735 { 736 return (0); 737 } 738 739 int 740 crypto_digest_update(crypto_context_t context, crypto_data_t *data, 741 crypto_call_req_t *cr) 742 { 743 return (0); 744 } 745 746 int 747 crypto_digest_init(crypto_mechanism_t *mech, crypto_context_t *ctxp, 748 crypto_call_req_t *crq) 749 { 750 return (0); 751 } 752 753 void 754 crypto_destroy_ctx_template(crypto_ctx_template_t tmpl) 755 { 756 } 757 758 extern int crypto_mac_init(crypto_mechanism_t *mech, crypto_key_t *key, 759 crypto_ctx_template_t tmpl, crypto_context_t *ctxp, 760 crypto_call_req_t *cr) 761 { 762 return (0); 763 } 764 765 extern int crypto_mac_update(crypto_context_t ctx, crypto_data_t *data, 766 crypto_call_req_t *cr) 767 { 768 return (0); 769 } 770 771 extern int crypto_mac_final(crypto_context_t ctx, crypto_data_t *data, 772 crypto_call_req_t *cr) 773 { 774 return (0); 775 } 776