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 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/types.h> 29 #include <sys/param.h> 30 #include <sys/errno.h> 31 #include <sys/uio.h> 32 #include <sys/buf.h> 33 #include <sys/modctl.h> 34 #include <sys/open.h> 35 #include <sys/file.h> 36 #include <sys/kmem.h> 37 #include <sys/conf.h> 38 #include <sys/cmn_err.h> 39 #include <sys/stat.h> 40 #include <sys/zfs_ioctl.h> 41 #include <sys/zap.h> 42 #include <sys/spa.h> 43 #include <sys/vdev.h> 44 #include <sys/dmu.h> 45 #include <sys/dsl_dir.h> 46 #include <sys/dsl_dataset.h> 47 #include <sys/dsl_prop.h> 48 #include <sys/ddi.h> 49 #include <sys/sunddi.h> 50 #include <sys/sunldi.h> 51 #include <sys/policy.h> 52 #include <sys/zone.h> 53 #include <sys/nvpair.h> 54 #include <sys/pathname.h> 55 #include <sys/mount.h> 56 #include <sys/sdt.h> 57 #include <sys/fs/zfs.h> 58 #include <sys/zfs_ctldir.h> 59 #include <sys/zvol.h> 60 61 #include "zfs_namecheck.h" 62 #include "zfs_prop.h" 63 64 extern struct modlfs zfs_modlfs; 65 66 extern void zfs_init(void); 67 extern void zfs_fini(void); 68 69 ldi_ident_t zfs_li = NULL; 70 dev_info_t *zfs_dip; 71 72 typedef int zfs_ioc_func_t(zfs_cmd_t *); 73 typedef int zfs_secpolicy_func_t(const char *, cred_t *); 74 75 typedef struct zfs_ioc_vec { 76 zfs_ioc_func_t *zvec_func; 77 zfs_secpolicy_func_t *zvec_secpolicy; 78 enum { 79 no_name, 80 pool_name, 81 dataset_name 82 } zvec_namecheck; 83 } zfs_ioc_vec_t; 84 85 /* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */ 86 void 87 __dprintf(const char *file, const char *func, int line, const char *fmt, ...) 88 { 89 const char *newfile; 90 char buf[256]; 91 va_list adx; 92 93 /* 94 * Get rid of annoying "../common/" prefix to filename. 95 */ 96 newfile = strrchr(file, '/'); 97 if (newfile != NULL) { 98 newfile = newfile + 1; /* Get rid of leading / */ 99 } else { 100 newfile = file; 101 } 102 103 va_start(adx, fmt); 104 (void) vsnprintf(buf, sizeof (buf), fmt, adx); 105 va_end(adx); 106 107 /* 108 * To get this data, use the zfs-dprintf probe as so: 109 * dtrace -q -n 'zfs-dprintf \ 110 * /stringof(arg0) == "dbuf.c"/ \ 111 * {printf("%s: %s", stringof(arg1), stringof(arg3))}' 112 * arg0 = file name 113 * arg1 = function name 114 * arg2 = line number 115 * arg3 = message 116 */ 117 DTRACE_PROBE4(zfs__dprintf, 118 char *, newfile, char *, func, int, line, char *, buf); 119 } 120 121 /* 122 * Policy for top-level read operations (list pools). Requires no privileges, 123 * and can be used in the local zone, as there is no associated dataset. 124 */ 125 /* ARGSUSED */ 126 static int 127 zfs_secpolicy_none(const char *unused1, cred_t *cr) 128 { 129 return (0); 130 } 131 132 /* 133 * Policy for dataset read operations (list children, get statistics). Requires 134 * no privileges, but must be visible in the local zone. 135 */ 136 /* ARGSUSED */ 137 static int 138 zfs_secpolicy_read(const char *dataset, cred_t *cr) 139 { 140 if (INGLOBALZONE(curproc) || 141 zone_dataset_visible(dataset, NULL)) 142 return (0); 143 144 return (ENOENT); 145 } 146 147 static int 148 zfs_dozonecheck(const char *dataset, cred_t *cr) 149 { 150 uint64_t zoned; 151 int writable = 1; 152 153 /* 154 * The dataset must be visible by this zone -- check this first 155 * so they don't see EPERM on something they shouldn't know about. 156 */ 157 if (!INGLOBALZONE(curproc) && 158 !zone_dataset_visible(dataset, &writable)) 159 return (ENOENT); 160 161 if (dsl_prop_get_integer(dataset, "zoned", &zoned, NULL)) 162 return (ENOENT); 163 164 if (INGLOBALZONE(curproc)) { 165 /* 166 * If the fs is zoned, only root can access it from the 167 * global zone. 168 */ 169 if (secpolicy_zfs(cr) && zoned) 170 return (EPERM); 171 } else { 172 /* 173 * If we are in a local zone, the 'zoned' property must be set. 174 */ 175 if (!zoned) 176 return (EPERM); 177 178 /* must be writable by this zone */ 179 if (!writable) 180 return (EPERM); 181 } 182 return (0); 183 } 184 185 /* 186 * Policy for dataset write operations (create children, set properties, etc). 187 * Requires SYS_MOUNT privilege, and must be writable in the local zone. 188 */ 189 int 190 zfs_secpolicy_write(const char *dataset, cred_t *cr) 191 { 192 int error; 193 194 if (error = zfs_dozonecheck(dataset, cr)) 195 return (error); 196 197 return (secpolicy_zfs(cr)); 198 } 199 200 /* 201 * Policy for operations that want to write a dataset's parent: 202 * create, destroy, snapshot, clone, restore. 203 */ 204 static int 205 zfs_secpolicy_parent(const char *dataset, cred_t *cr) 206 { 207 char parentname[MAXNAMELEN]; 208 char *cp; 209 210 /* 211 * Remove the @bla or /bla from the end of the name to get the parent. 212 */ 213 (void) strncpy(parentname, dataset, sizeof (parentname)); 214 cp = strrchr(parentname, '@'); 215 if (cp != NULL) { 216 cp[0] = '\0'; 217 } else { 218 cp = strrchr(parentname, '/'); 219 if (cp == NULL) 220 return (ENOENT); 221 cp[0] = '\0'; 222 223 } 224 225 return (zfs_secpolicy_write(parentname, cr)); 226 } 227 228 /* 229 * Policy for pool operations - create/destroy pools, add vdevs, etc. Requires 230 * SYS_CONFIG privilege, which is not available in a local zone. 231 */ 232 /* ARGSUSED */ 233 static int 234 zfs_secpolicy_config(const char *unused, cred_t *cr) 235 { 236 if (secpolicy_sys_config(cr, B_FALSE) != 0) 237 return (EPERM); 238 239 return (0); 240 } 241 242 /* 243 * Policy for fault injection. Requires all privileges. 244 */ 245 /* ARGSUSED */ 246 static int 247 zfs_secpolicy_inject(const char *unused, cred_t *cr) 248 { 249 return (secpolicy_zinject(cr)); 250 } 251 252 /* 253 * Returns the nvlist as specified by the user in the zfs_cmd_t. 254 */ 255 static int 256 get_nvlist(zfs_cmd_t *zc, nvlist_t **nvp) 257 { 258 char *packed; 259 size_t size; 260 int error; 261 nvlist_t *config = NULL; 262 263 /* 264 * Read in and unpack the user-supplied nvlist. 265 */ 266 if ((size = zc->zc_nvlist_src_size) == 0) 267 return (EINVAL); 268 269 packed = kmem_alloc(size, KM_SLEEP); 270 271 if ((error = xcopyin((void *)(uintptr_t)zc->zc_nvlist_src, packed, 272 size)) != 0) { 273 kmem_free(packed, size); 274 return (error); 275 } 276 277 if ((error = nvlist_unpack(packed, size, &config, 0)) != 0) { 278 kmem_free(packed, size); 279 return (error); 280 } 281 282 kmem_free(packed, size); 283 284 *nvp = config; 285 return (0); 286 } 287 288 static int 289 put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl) 290 { 291 char *packed = NULL; 292 size_t size; 293 int error; 294 295 VERIFY(nvlist_size(nvl, &size, NV_ENCODE_NATIVE) == 0); 296 297 if (size > zc->zc_nvlist_dst_size) { 298 error = ENOMEM; 299 } else { 300 VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE, 301 KM_SLEEP) == 0); 302 error = xcopyout(packed, (void *)(uintptr_t)zc->zc_nvlist_dst, 303 size); 304 kmem_free(packed, size); 305 } 306 307 zc->zc_nvlist_dst_size = size; 308 return (error); 309 } 310 311 static int 312 zfs_ioc_pool_create(zfs_cmd_t *zc) 313 { 314 int error; 315 nvlist_t *config; 316 317 if ((error = get_nvlist(zc, &config)) != 0) 318 return (error); 319 320 error = spa_create(zc->zc_name, config, zc->zc_value[0] == '\0' ? 321 NULL : zc->zc_value); 322 323 nvlist_free(config); 324 325 return (error); 326 } 327 328 static int 329 zfs_ioc_pool_destroy(zfs_cmd_t *zc) 330 { 331 return (spa_destroy(zc->zc_name)); 332 } 333 334 static int 335 zfs_ioc_pool_import(zfs_cmd_t *zc) 336 { 337 int error; 338 nvlist_t *config; 339 uint64_t guid; 340 341 if ((error = get_nvlist(zc, &config)) != 0) 342 return (error); 343 344 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) != 0 || 345 guid != zc->zc_guid) 346 error = EINVAL; 347 else 348 error = spa_import(zc->zc_name, config, 349 zc->zc_value[0] == '\0' ? NULL : zc->zc_value); 350 351 nvlist_free(config); 352 353 return (error); 354 } 355 356 static int 357 zfs_ioc_pool_export(zfs_cmd_t *zc) 358 { 359 return (spa_export(zc->zc_name, NULL)); 360 } 361 362 static int 363 zfs_ioc_pool_configs(zfs_cmd_t *zc) 364 { 365 nvlist_t *configs; 366 int error; 367 368 if ((configs = spa_all_configs(&zc->zc_cookie)) == NULL) 369 return (EEXIST); 370 371 error = put_nvlist(zc, configs); 372 373 nvlist_free(configs); 374 375 return (error); 376 } 377 378 static int 379 zfs_ioc_pool_stats(zfs_cmd_t *zc) 380 { 381 nvlist_t *config; 382 int error; 383 int ret = 0; 384 385 error = spa_get_stats(zc->zc_name, &config, zc->zc_value, 386 sizeof (zc->zc_value)); 387 388 if (config != NULL) { 389 ret = put_nvlist(zc, config); 390 nvlist_free(config); 391 392 /* 393 * The config may be present even if 'error' is non-zero. 394 * In this case we return success, and preserve the real errno 395 * in 'zc_cookie'. 396 */ 397 zc->zc_cookie = error; 398 } else { 399 ret = error; 400 } 401 402 return (ret); 403 } 404 405 /* 406 * Try to import the given pool, returning pool stats as appropriate so that 407 * user land knows which devices are available and overall pool health. 408 */ 409 static int 410 zfs_ioc_pool_tryimport(zfs_cmd_t *zc) 411 { 412 nvlist_t *tryconfig, *config; 413 int error; 414 415 if ((error = get_nvlist(zc, &tryconfig)) != 0) 416 return (error); 417 418 config = spa_tryimport(tryconfig); 419 420 nvlist_free(tryconfig); 421 422 if (config == NULL) 423 return (EINVAL); 424 425 error = put_nvlist(zc, config); 426 nvlist_free(config); 427 428 return (error); 429 } 430 431 static int 432 zfs_ioc_pool_scrub(zfs_cmd_t *zc) 433 { 434 spa_t *spa; 435 int error; 436 437 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 438 return (error); 439 440 error = spa_scrub(spa, zc->zc_cookie, B_FALSE); 441 442 spa_close(spa, FTAG); 443 444 return (error); 445 } 446 447 static int 448 zfs_ioc_pool_freeze(zfs_cmd_t *zc) 449 { 450 spa_t *spa; 451 int error; 452 453 error = spa_open(zc->zc_name, &spa, FTAG); 454 if (error == 0) { 455 spa_freeze(spa); 456 spa_close(spa, FTAG); 457 } 458 return (error); 459 } 460 461 static int 462 zfs_ioc_pool_upgrade(zfs_cmd_t *zc) 463 { 464 spa_t *spa; 465 int error; 466 467 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 468 return (error); 469 470 spa_upgrade(spa); 471 472 spa_close(spa, FTAG); 473 474 return (error); 475 } 476 477 static int 478 zfs_ioc_pool_get_history(zfs_cmd_t *zc) 479 { 480 spa_t *spa; 481 char *hist_buf; 482 uint64_t size; 483 int error; 484 485 if ((size = zc->zc_history_len) == 0) 486 return (EINVAL); 487 488 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 489 return (error); 490 491 hist_buf = kmem_alloc(size, KM_SLEEP); 492 if ((error = spa_history_get(spa, &zc->zc_history_offset, 493 &zc->zc_history_len, hist_buf)) == 0) { 494 error = xcopyout(hist_buf, (char *)(uintptr_t)zc->zc_history, 495 zc->zc_history_len); 496 } 497 498 spa_close(spa, FTAG); 499 kmem_free(hist_buf, size); 500 return (error); 501 } 502 503 static int 504 zfs_ioc_pool_log_history(zfs_cmd_t *zc) 505 { 506 spa_t *spa; 507 char *history_str = NULL; 508 size_t size; 509 int error; 510 511 size = zc->zc_history_len; 512 if (size == 0 || size > HIS_MAX_RECORD_LEN) 513 return (EINVAL); 514 515 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 516 return (error); 517 518 /* add one for the NULL delimiter */ 519 size++; 520 history_str = kmem_alloc(size, KM_SLEEP); 521 if ((error = xcopyin((void *)(uintptr_t)zc->zc_history, history_str, 522 size)) != 0) { 523 spa_close(spa, FTAG); 524 kmem_free(history_str, size); 525 return (error); 526 } 527 history_str[size - 1] = '\0'; 528 529 error = spa_history_log(spa, history_str, zc->zc_history_offset); 530 531 spa_close(spa, FTAG); 532 kmem_free(history_str, size); 533 534 return (error); 535 } 536 537 static int 538 zfs_ioc_vdev_add(zfs_cmd_t *zc) 539 { 540 spa_t *spa; 541 int error; 542 nvlist_t *config; 543 544 error = spa_open(zc->zc_name, &spa, FTAG); 545 if (error != 0) 546 return (error); 547 548 if ((error = get_nvlist(zc, &config)) == 0) { 549 error = spa_vdev_add(spa, config); 550 nvlist_free(config); 551 } 552 553 spa_close(spa, FTAG); 554 return (error); 555 } 556 557 static int 558 zfs_ioc_vdev_remove(zfs_cmd_t *zc) 559 { 560 spa_t *spa; 561 int error; 562 563 error = spa_open(zc->zc_name, &spa, FTAG); 564 if (error != 0) 565 return (error); 566 error = spa_vdev_remove(spa, zc->zc_guid, B_FALSE); 567 spa_close(spa, FTAG); 568 return (error); 569 } 570 571 static int 572 zfs_ioc_vdev_online(zfs_cmd_t *zc) 573 { 574 spa_t *spa; 575 int error; 576 577 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 578 return (error); 579 error = vdev_online(spa, zc->zc_guid); 580 spa_close(spa, FTAG); 581 return (error); 582 } 583 584 static int 585 zfs_ioc_vdev_offline(zfs_cmd_t *zc) 586 { 587 spa_t *spa; 588 int istmp = zc->zc_cookie; 589 int error; 590 591 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 592 return (error); 593 error = vdev_offline(spa, zc->zc_guid, istmp); 594 spa_close(spa, FTAG); 595 return (error); 596 } 597 598 static int 599 zfs_ioc_vdev_attach(zfs_cmd_t *zc) 600 { 601 spa_t *spa; 602 int replacing = zc->zc_cookie; 603 nvlist_t *config; 604 int error; 605 606 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 607 return (error); 608 609 if ((error = get_nvlist(zc, &config)) == 0) { 610 error = spa_vdev_attach(spa, zc->zc_guid, config, replacing); 611 nvlist_free(config); 612 } 613 614 spa_close(spa, FTAG); 615 return (error); 616 } 617 618 static int 619 zfs_ioc_vdev_detach(zfs_cmd_t *zc) 620 { 621 spa_t *spa; 622 int error; 623 624 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 625 return (error); 626 627 error = spa_vdev_detach(spa, zc->zc_guid, B_FALSE); 628 629 spa_close(spa, FTAG); 630 return (error); 631 } 632 633 static int 634 zfs_ioc_vdev_setpath(zfs_cmd_t *zc) 635 { 636 spa_t *spa; 637 char *path = zc->zc_value; 638 uint64_t guid = zc->zc_guid; 639 int error; 640 641 error = spa_open(zc->zc_name, &spa, FTAG); 642 if (error != 0) 643 return (error); 644 645 error = spa_vdev_setpath(spa, guid, path); 646 spa_close(spa, FTAG); 647 return (error); 648 } 649 650 static int 651 zfs_ioc_objset_stats(zfs_cmd_t *zc) 652 { 653 objset_t *os = NULL; 654 int error; 655 nvlist_t *nv; 656 657 retry: 658 error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, 659 DS_MODE_STANDARD | DS_MODE_READONLY, &os); 660 if (error != 0) { 661 /* 662 * This is ugly: dmu_objset_open() can return EBUSY if 663 * the objset is held exclusively. Fortunately this hold is 664 * only for a short while, so we retry here. 665 * This avoids user code having to handle EBUSY, 666 * for example for a "zfs list". 667 */ 668 if (error == EBUSY) { 669 delay(1); 670 goto retry; 671 } 672 return (error); 673 } 674 675 dmu_objset_fast_stat(os, &zc->zc_objset_stats); 676 677 if (zc->zc_nvlist_dst != 0 && 678 (error = dsl_prop_get_all(os, &nv)) == 0) { 679 dmu_objset_stats(os, nv); 680 if (dmu_objset_type(os) == DMU_OST_ZVOL) 681 VERIFY(zvol_get_stats(os, nv) == 0); 682 error = put_nvlist(zc, nv); 683 nvlist_free(nv); 684 } 685 686 spa_altroot(dmu_objset_spa(os), zc->zc_value, sizeof (zc->zc_value)); 687 688 dmu_objset_close(os); 689 return (error); 690 } 691 692 static int 693 zfs_ioc_dataset_list_next(zfs_cmd_t *zc) 694 { 695 objset_t *os; 696 int error; 697 char *p; 698 699 retry: 700 error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, 701 DS_MODE_STANDARD | DS_MODE_READONLY, &os); 702 if (error != 0) { 703 /* 704 * This is ugly: dmu_objset_open() can return EBUSY if 705 * the objset is held exclusively. Fortunately this hold is 706 * only for a short while, so we retry here. 707 * This avoids user code having to handle EBUSY, 708 * for example for a "zfs list". 709 */ 710 if (error == EBUSY) { 711 delay(1); 712 goto retry; 713 } 714 if (error == ENOENT) 715 error = ESRCH; 716 return (error); 717 } 718 719 p = strrchr(zc->zc_name, '/'); 720 if (p == NULL || p[1] != '\0') 721 (void) strlcat(zc->zc_name, "/", sizeof (zc->zc_name)); 722 p = zc->zc_name + strlen(zc->zc_name); 723 724 do { 725 error = dmu_dir_list_next(os, 726 sizeof (zc->zc_name) - (p - zc->zc_name), p, 727 NULL, &zc->zc_cookie); 728 if (error == ENOENT) 729 error = ESRCH; 730 } while (error == 0 && !INGLOBALZONE(curproc) && 731 !zone_dataset_visible(zc->zc_name, NULL)); 732 733 /* 734 * If it's a hidden dataset (ie. with a '$' in its name), don't 735 * try to get stats for it. Userland will skip over it. 736 */ 737 if (error == 0 && strchr(zc->zc_name, '$') == NULL) 738 error = zfs_ioc_objset_stats(zc); /* fill in the stats */ 739 740 dmu_objset_close(os); 741 return (error); 742 } 743 744 static int 745 zfs_ioc_snapshot_list_next(zfs_cmd_t *zc) 746 { 747 objset_t *os; 748 int error; 749 750 retry: 751 error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, 752 DS_MODE_STANDARD | DS_MODE_READONLY, &os); 753 if (error != 0) { 754 /* 755 * This is ugly: dmu_objset_open() can return EBUSY if 756 * the objset is held exclusively. Fortunately this hold is 757 * only for a short while, so we retry here. 758 * This avoids user code having to handle EBUSY, 759 * for example for a "zfs list". 760 */ 761 if (error == EBUSY) { 762 delay(1); 763 goto retry; 764 } 765 if (error == ENOENT) 766 error = ESRCH; 767 return (error); 768 } 769 770 /* 771 * A dataset name of maximum length cannot have any snapshots, 772 * so exit immediately. 773 */ 774 if (strlcat(zc->zc_name, "@", sizeof (zc->zc_name)) >= MAXNAMELEN) { 775 dmu_objset_close(os); 776 return (ESRCH); 777 } 778 779 error = dmu_snapshot_list_next(os, 780 sizeof (zc->zc_name) - strlen(zc->zc_name), 781 zc->zc_name + strlen(zc->zc_name), NULL, &zc->zc_cookie); 782 if (error == ENOENT) 783 error = ESRCH; 784 785 if (error == 0) 786 error = zfs_ioc_objset_stats(zc); /* fill in the stats */ 787 788 dmu_objset_close(os); 789 return (error); 790 } 791 792 static int 793 zfs_set_prop_nvlist(const char *name, dev_t dev, cred_t *cr, nvlist_t *nvl) 794 { 795 nvpair_t *elem; 796 int error; 797 const char *propname; 798 zfs_prop_t prop; 799 uint64_t intval; 800 char *strval; 801 802 elem = NULL; 803 while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) { 804 propname = nvpair_name(elem); 805 806 if ((prop = zfs_name_to_prop(propname)) == 807 ZFS_PROP_INVAL) { 808 /* 809 * If this is a user-defined property, it must be a 810 * string, and there is no further validation to do. 811 */ 812 if (!zfs_prop_user(propname) || 813 nvpair_type(elem) != DATA_TYPE_STRING) 814 return (EINVAL); 815 816 VERIFY(nvpair_value_string(elem, &strval) == 0); 817 error = dsl_prop_set(name, propname, 1, 818 strlen(strval) + 1, strval); 819 if (error == 0) 820 continue; 821 else 822 break; 823 } 824 825 /* 826 * Check permissions for special properties. 827 */ 828 switch (prop) { 829 case ZFS_PROP_ZONED: 830 /* 831 * Disallow setting of 'zoned' from within a local zone. 832 */ 833 if (!INGLOBALZONE(curproc)) 834 return (EPERM); 835 break; 836 837 case ZFS_PROP_QUOTA: 838 if (error = zfs_dozonecheck(name, cr)) 839 return (error); 840 841 if (!INGLOBALZONE(curproc)) { 842 uint64_t zoned; 843 char setpoint[MAXNAMELEN]; 844 int dslen; 845 /* 846 * Unprivileged users are allowed to modify the 847 * quota on things *under* (ie. contained by) 848 * the thing they own. 849 */ 850 if (dsl_prop_get_integer(name, "zoned", &zoned, 851 setpoint)) 852 return (EPERM); 853 if (!zoned) /* this shouldn't happen */ 854 return (EPERM); 855 dslen = strlen(name); 856 if (dslen <= strlen(setpoint)) 857 return (EPERM); 858 } 859 } 860 861 switch (prop) { 862 case ZFS_PROP_QUOTA: 863 if ((error = nvpair_value_uint64(elem, &intval)) != 0 || 864 (error = dsl_dir_set_quota(name, 865 intval)) != 0) 866 return (error); 867 break; 868 869 case ZFS_PROP_RESERVATION: 870 if ((error = nvpair_value_uint64(elem, &intval)) != 0 || 871 (error = dsl_dir_set_reservation(name, 872 intval)) != 0) 873 return (error); 874 break; 875 876 case ZFS_PROP_VOLSIZE: 877 if ((error = nvpair_value_uint64(elem, &intval)) != 0 || 878 (error = zvol_set_volsize(name, dev, 879 intval)) != 0) 880 return (error); 881 break; 882 883 case ZFS_PROP_VOLBLOCKSIZE: 884 if ((error = nvpair_value_uint64(elem, &intval)) != 0 || 885 (error = zvol_set_volblocksize(name, 886 intval)) != 0) 887 return (error); 888 break; 889 890 default: 891 if (nvpair_type(elem) == DATA_TYPE_STRING) { 892 if (zfs_prop_get_type(prop) != 893 prop_type_string) 894 return (EINVAL); 895 VERIFY(nvpair_value_string(elem, &strval) == 0); 896 if ((error = dsl_prop_set(name, 897 nvpair_name(elem), 1, strlen(strval) + 1, 898 strval)) != 0) 899 return (error); 900 } else if (nvpair_type(elem) == DATA_TYPE_UINT64) { 901 const char *unused; 902 903 VERIFY(nvpair_value_uint64(elem, &intval) == 0); 904 905 switch (zfs_prop_get_type(prop)) { 906 case prop_type_number: 907 break; 908 case prop_type_boolean: 909 if (intval > 1) 910 return (EINVAL); 911 break; 912 case prop_type_string: 913 return (EINVAL); 914 case prop_type_index: 915 if (zfs_prop_index_to_string(prop, 916 intval, &unused) != 0) 917 return (EINVAL); 918 break; 919 default: 920 cmn_err(CE_PANIC, "unknown property " 921 "type"); 922 break; 923 } 924 925 if ((error = dsl_prop_set(name, propname, 926 8, 1, &intval)) != 0) 927 return (error); 928 } else { 929 return (EINVAL); 930 } 931 break; 932 } 933 } 934 935 return (0); 936 } 937 938 static int 939 zfs_ioc_set_prop(zfs_cmd_t *zc) 940 { 941 nvlist_t *nvl; 942 int error; 943 zfs_prop_t prop; 944 945 /* 946 * If zc_value is set, then this is an attempt to inherit a value. 947 * Otherwise, zc_nvlist refers to a list of properties to set. 948 */ 949 if (zc->zc_value[0] != '\0') { 950 if (!zfs_prop_user(zc->zc_value) && 951 ((prop = zfs_name_to_prop(zc->zc_value)) == 952 ZFS_PROP_INVAL || 953 !zfs_prop_inheritable(prop))) 954 return (EINVAL); 955 956 return (dsl_prop_set(zc->zc_name, zc->zc_value, 0, 0, NULL)); 957 } 958 959 if ((error = get_nvlist(zc, &nvl)) != 0) 960 return (error); 961 962 error = zfs_set_prop_nvlist(zc->zc_name, zc->zc_dev, 963 (cred_t *)(uintptr_t)zc->zc_cred, nvl); 964 nvlist_free(nvl); 965 return (error); 966 } 967 968 static int 969 zfs_ioc_create_minor(zfs_cmd_t *zc) 970 { 971 return (zvol_create_minor(zc->zc_name, zc->zc_dev)); 972 } 973 974 static int 975 zfs_ioc_remove_minor(zfs_cmd_t *zc) 976 { 977 return (zvol_remove_minor(zc->zc_name)); 978 } 979 980 /* 981 * Search the vfs list for a specified resource. Returns a pointer to it 982 * or NULL if no suitable entry is found. The caller of this routine 983 * is responsible for releasing the returned vfs pointer. 984 */ 985 static vfs_t * 986 zfs_get_vfs(const char *resource) 987 { 988 struct vfs *vfsp; 989 struct vfs *vfs_found = NULL; 990 991 vfs_list_read_lock(); 992 vfsp = rootvfs; 993 do { 994 if (strcmp(refstr_value(vfsp->vfs_resource), resource) == 0) { 995 VFS_HOLD(vfsp); 996 vfs_found = vfsp; 997 break; 998 } 999 vfsp = vfsp->vfs_next; 1000 } while (vfsp != rootvfs); 1001 vfs_list_unlock(); 1002 return (vfs_found); 1003 } 1004 1005 static void 1006 zfs_create_cb(objset_t *os, void *arg, dmu_tx_t *tx) 1007 { 1008 zfs_create_data_t *zc = arg; 1009 zfs_create_fs(os, (cred_t *)(uintptr_t)zc->zc_cred, tx); 1010 } 1011 1012 static int 1013 zfs_ioc_create(zfs_cmd_t *zc) 1014 { 1015 objset_t *clone; 1016 int error = 0; 1017 zfs_create_data_t cbdata = { 0 }; 1018 void (*cbfunc)(objset_t *os, void *arg, dmu_tx_t *tx); 1019 dmu_objset_type_t type = zc->zc_objset_type; 1020 1021 switch (type) { 1022 1023 case DMU_OST_ZFS: 1024 cbfunc = zfs_create_cb; 1025 break; 1026 1027 case DMU_OST_ZVOL: 1028 cbfunc = zvol_create_cb; 1029 break; 1030 1031 default: 1032 cbfunc = NULL; 1033 } 1034 if (strchr(zc->zc_name, '@')) 1035 return (EINVAL); 1036 1037 if (zc->zc_nvlist_src != NULL && 1038 (error = get_nvlist(zc, &cbdata.zc_props)) != 0) 1039 return (error); 1040 1041 cbdata.zc_cred = (cred_t *)(uintptr_t)zc->zc_cred; 1042 cbdata.zc_dev = (dev_t)zc->zc_dev; 1043 1044 if (zc->zc_value[0] != '\0') { 1045 /* 1046 * We're creating a clone of an existing snapshot. 1047 */ 1048 zc->zc_value[sizeof (zc->zc_value) - 1] = '\0'; 1049 if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0) { 1050 nvlist_free(cbdata.zc_props); 1051 return (EINVAL); 1052 } 1053 1054 error = dmu_objset_open(zc->zc_value, type, 1055 DS_MODE_STANDARD | DS_MODE_READONLY, &clone); 1056 if (error) { 1057 nvlist_free(cbdata.zc_props); 1058 return (error); 1059 } 1060 error = dmu_objset_create(zc->zc_name, type, clone, NULL, NULL); 1061 dmu_objset_close(clone); 1062 } else { 1063 if (cbfunc == NULL) { 1064 nvlist_free(cbdata.zc_props); 1065 return (EINVAL); 1066 } 1067 1068 if (type == DMU_OST_ZVOL) { 1069 uint64_t volsize, volblocksize; 1070 1071 if (cbdata.zc_props == NULL || 1072 nvlist_lookup_uint64(cbdata.zc_props, 1073 zfs_prop_to_name(ZFS_PROP_VOLSIZE), 1074 &volsize) != 0) { 1075 nvlist_free(cbdata.zc_props); 1076 return (EINVAL); 1077 } 1078 1079 if ((error = nvlist_lookup_uint64(cbdata.zc_props, 1080 zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), 1081 &volblocksize)) != 0 && error != ENOENT) { 1082 nvlist_free(cbdata.zc_props); 1083 return (EINVAL); 1084 } 1085 1086 if (error != 0) 1087 volblocksize = zfs_prop_default_numeric( 1088 ZFS_PROP_VOLBLOCKSIZE); 1089 1090 if ((error = zvol_check_volblocksize( 1091 volblocksize)) != 0 || 1092 (error = zvol_check_volsize(volsize, 1093 volblocksize)) != 0) { 1094 nvlist_free(cbdata.zc_props); 1095 return (error); 1096 } 1097 } 1098 1099 error = dmu_objset_create(zc->zc_name, type, NULL, cbfunc, 1100 &cbdata); 1101 } 1102 1103 /* 1104 * It would be nice to do this atomically. 1105 */ 1106 if (error == 0) { 1107 if ((error = zfs_set_prop_nvlist(zc->zc_name, 1108 zc->zc_dev, (cred_t *)(uintptr_t)zc->zc_cred, 1109 cbdata.zc_props)) != 0) 1110 (void) dmu_objset_destroy(zc->zc_name); 1111 } 1112 1113 nvlist_free(cbdata.zc_props); 1114 return (error); 1115 } 1116 1117 static int 1118 zfs_ioc_snapshot(zfs_cmd_t *zc) 1119 { 1120 if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0) 1121 return (EINVAL); 1122 return (dmu_objset_snapshot(zc->zc_name, 1123 zc->zc_value, zc->zc_cookie)); 1124 } 1125 1126 static int 1127 zfs_unmount_snap(char *name, void *arg) 1128 { 1129 char *snapname = arg; 1130 char *cp; 1131 vfs_t *vfsp = NULL; 1132 1133 /* 1134 * Snapshots (which are under .zfs control) must be unmounted 1135 * before they can be destroyed. 1136 */ 1137 1138 if (snapname) { 1139 (void) strcat(name, "@"); 1140 (void) strcat(name, snapname); 1141 vfsp = zfs_get_vfs(name); 1142 cp = strchr(name, '@'); 1143 *cp = '\0'; 1144 } else if (strchr(name, '@')) { 1145 vfsp = zfs_get_vfs(name); 1146 } 1147 1148 if (vfsp) { 1149 /* 1150 * Always force the unmount for snapshots. 1151 */ 1152 int flag = MS_FORCE; 1153 int err; 1154 1155 if ((err = vn_vfswlock(vfsp->vfs_vnodecovered)) != 0) { 1156 VFS_RELE(vfsp); 1157 return (err); 1158 } 1159 VFS_RELE(vfsp); 1160 if ((err = dounmount(vfsp, flag, kcred)) != 0) 1161 return (err); 1162 } 1163 return (0); 1164 } 1165 1166 static int 1167 zfs_ioc_destroy_snaps(zfs_cmd_t *zc) 1168 { 1169 int err; 1170 1171 if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0) 1172 return (EINVAL); 1173 err = dmu_objset_find(zc->zc_name, 1174 zfs_unmount_snap, zc->zc_value, DS_FIND_CHILDREN); 1175 if (err) 1176 return (err); 1177 return (dmu_snapshots_destroy(zc->zc_name, zc->zc_value)); 1178 } 1179 1180 static int 1181 zfs_ioc_destroy(zfs_cmd_t *zc) 1182 { 1183 if (strchr(zc->zc_name, '@') && zc->zc_objset_type == DMU_OST_ZFS) { 1184 int err = zfs_unmount_snap(zc->zc_name, NULL); 1185 if (err) 1186 return (err); 1187 } 1188 1189 return (dmu_objset_destroy(zc->zc_name)); 1190 } 1191 1192 static int 1193 zfs_ioc_rollback(zfs_cmd_t *zc) 1194 { 1195 return (dmu_objset_rollback(zc->zc_name)); 1196 } 1197 1198 static int 1199 zfs_ioc_rename(zfs_cmd_t *zc) 1200 { 1201 zc->zc_value[sizeof (zc->zc_value) - 1] = '\0'; 1202 if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0) 1203 return (EINVAL); 1204 1205 if (strchr(zc->zc_name, '@') != NULL && 1206 zc->zc_objset_type == DMU_OST_ZFS) { 1207 int err = zfs_unmount_snap(zc->zc_name, NULL); 1208 if (err) 1209 return (err); 1210 } 1211 1212 return (dmu_objset_rename(zc->zc_name, zc->zc_value)); 1213 } 1214 1215 static int 1216 zfs_ioc_recvbackup(zfs_cmd_t *zc) 1217 { 1218 file_t *fp; 1219 int error, fd; 1220 offset_t new_off; 1221 1222 fd = zc->zc_cookie; 1223 fp = getf(fd); 1224 if (fp == NULL) 1225 return (EBADF); 1226 error = dmu_recvbackup(zc->zc_value, &zc->zc_begin_record, 1227 &zc->zc_cookie, (boolean_t)zc->zc_guid, fp->f_vnode, 1228 fp->f_offset); 1229 1230 new_off = fp->f_offset + zc->zc_cookie; 1231 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &new_off) == 0) 1232 fp->f_offset = new_off; 1233 1234 releasef(fd); 1235 return (error); 1236 } 1237 1238 static int 1239 zfs_ioc_sendbackup(zfs_cmd_t *zc) 1240 { 1241 objset_t *fromsnap = NULL; 1242 objset_t *tosnap; 1243 file_t *fp; 1244 int error; 1245 1246 error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, 1247 DS_MODE_STANDARD | DS_MODE_READONLY, &tosnap); 1248 if (error) 1249 return (error); 1250 1251 if (zc->zc_value[0] != '\0') { 1252 char buf[MAXPATHLEN]; 1253 char *cp; 1254 1255 (void) strncpy(buf, zc->zc_name, sizeof (buf)); 1256 cp = strchr(buf, '@'); 1257 if (cp) 1258 *(cp+1) = 0; 1259 (void) strncat(buf, zc->zc_value, sizeof (buf)); 1260 error = dmu_objset_open(buf, DMU_OST_ANY, 1261 DS_MODE_STANDARD | DS_MODE_READONLY, &fromsnap); 1262 if (error) { 1263 dmu_objset_close(tosnap); 1264 return (error); 1265 } 1266 } 1267 1268 fp = getf(zc->zc_cookie); 1269 if (fp == NULL) { 1270 dmu_objset_close(tosnap); 1271 if (fromsnap) 1272 dmu_objset_close(fromsnap); 1273 return (EBADF); 1274 } 1275 1276 error = dmu_sendbackup(tosnap, fromsnap, fp->f_vnode); 1277 1278 releasef(zc->zc_cookie); 1279 if (fromsnap) 1280 dmu_objset_close(fromsnap); 1281 dmu_objset_close(tosnap); 1282 return (error); 1283 } 1284 1285 static int 1286 zfs_ioc_inject_fault(zfs_cmd_t *zc) 1287 { 1288 int id, error; 1289 1290 error = zio_inject_fault(zc->zc_name, (int)zc->zc_guid, &id, 1291 &zc->zc_inject_record); 1292 1293 if (error == 0) 1294 zc->zc_guid = (uint64_t)id; 1295 1296 return (error); 1297 } 1298 1299 static int 1300 zfs_ioc_clear_fault(zfs_cmd_t *zc) 1301 { 1302 return (zio_clear_fault((int)zc->zc_guid)); 1303 } 1304 1305 static int 1306 zfs_ioc_inject_list_next(zfs_cmd_t *zc) 1307 { 1308 int id = (int)zc->zc_guid; 1309 int error; 1310 1311 error = zio_inject_list_next(&id, zc->zc_name, sizeof (zc->zc_name), 1312 &zc->zc_inject_record); 1313 1314 zc->zc_guid = id; 1315 1316 return (error); 1317 } 1318 1319 static int 1320 zfs_ioc_error_log(zfs_cmd_t *zc) 1321 { 1322 spa_t *spa; 1323 int error; 1324 size_t count = (size_t)zc->zc_nvlist_dst_size; 1325 1326 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 1327 return (error); 1328 1329 error = spa_get_errlog(spa, (void *)(uintptr_t)zc->zc_nvlist_dst, 1330 &count); 1331 if (error == 0) 1332 zc->zc_nvlist_dst_size = count; 1333 else 1334 zc->zc_nvlist_dst_size = spa_get_errlog_size(spa); 1335 1336 spa_close(spa, FTAG); 1337 1338 return (error); 1339 } 1340 1341 static int 1342 zfs_ioc_clear(zfs_cmd_t *zc) 1343 { 1344 spa_t *spa; 1345 vdev_t *vd; 1346 int error; 1347 1348 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 1349 return (error); 1350 1351 spa_config_enter(spa, RW_WRITER, FTAG); 1352 1353 if (zc->zc_guid == 0) { 1354 vd = NULL; 1355 } else if ((vd = spa_lookup_by_guid(spa, zc->zc_guid)) == NULL) { 1356 spa_config_exit(spa, FTAG); 1357 spa_close(spa, FTAG); 1358 return (ENODEV); 1359 } 1360 1361 vdev_clear(spa, vd); 1362 1363 spa_config_exit(spa, FTAG); 1364 1365 spa_close(spa, FTAG); 1366 1367 return (0); 1368 } 1369 1370 static int 1371 zfs_ioc_bookmark_name(zfs_cmd_t *zc) 1372 { 1373 spa_t *spa; 1374 int error; 1375 nvlist_t *nvl; 1376 1377 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 1378 return (error); 1379 1380 VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP) == 0); 1381 1382 error = spa_bookmark_name(spa, &zc->zc_bookmark, nvl); 1383 if (error == 0) 1384 error = put_nvlist(zc, nvl); 1385 nvlist_free(nvl); 1386 1387 spa_close(spa, FTAG); 1388 1389 return (error); 1390 } 1391 1392 static int 1393 zfs_ioc_promote(zfs_cmd_t *zc) 1394 { 1395 char *cp; 1396 1397 /* 1398 * We don't need to unmount *all* the origin fs's snapshots, but 1399 * it's easier. 1400 */ 1401 cp = strchr(zc->zc_value, '@'); 1402 if (cp) 1403 *cp = '\0'; 1404 (void) dmu_objset_find(zc->zc_value, 1405 zfs_unmount_snap, NULL, DS_FIND_SNAPSHOTS); 1406 return (dsl_dataset_promote(zc->zc_name)); 1407 } 1408 1409 static zfs_ioc_vec_t zfs_ioc_vec[] = { 1410 { zfs_ioc_pool_create, zfs_secpolicy_config, pool_name }, 1411 { zfs_ioc_pool_destroy, zfs_secpolicy_config, pool_name }, 1412 { zfs_ioc_pool_import, zfs_secpolicy_config, pool_name }, 1413 { zfs_ioc_pool_export, zfs_secpolicy_config, pool_name }, 1414 { zfs_ioc_pool_configs, zfs_secpolicy_none, no_name }, 1415 { zfs_ioc_pool_stats, zfs_secpolicy_read, pool_name }, 1416 { zfs_ioc_pool_tryimport, zfs_secpolicy_config, no_name }, 1417 { zfs_ioc_pool_scrub, zfs_secpolicy_config, pool_name }, 1418 { zfs_ioc_pool_freeze, zfs_secpolicy_config, no_name }, 1419 { zfs_ioc_pool_upgrade, zfs_secpolicy_config, pool_name }, 1420 { zfs_ioc_pool_get_history, zfs_secpolicy_config, pool_name }, 1421 { zfs_ioc_pool_log_history, zfs_secpolicy_config, pool_name }, 1422 { zfs_ioc_vdev_add, zfs_secpolicy_config, pool_name }, 1423 { zfs_ioc_vdev_remove, zfs_secpolicy_config, pool_name }, 1424 { zfs_ioc_vdev_online, zfs_secpolicy_config, pool_name }, 1425 { zfs_ioc_vdev_offline, zfs_secpolicy_config, pool_name }, 1426 { zfs_ioc_vdev_attach, zfs_secpolicy_config, pool_name }, 1427 { zfs_ioc_vdev_detach, zfs_secpolicy_config, pool_name }, 1428 { zfs_ioc_vdev_setpath, zfs_secpolicy_config, pool_name }, 1429 { zfs_ioc_objset_stats, zfs_secpolicy_read, dataset_name }, 1430 { zfs_ioc_dataset_list_next, zfs_secpolicy_read, dataset_name }, 1431 { zfs_ioc_snapshot_list_next, zfs_secpolicy_read, dataset_name }, 1432 { zfs_ioc_set_prop, zfs_secpolicy_write, dataset_name }, 1433 { zfs_ioc_create_minor, zfs_secpolicy_config, dataset_name }, 1434 { zfs_ioc_remove_minor, zfs_secpolicy_config, dataset_name }, 1435 { zfs_ioc_create, zfs_secpolicy_parent, dataset_name }, 1436 { zfs_ioc_destroy, zfs_secpolicy_parent, dataset_name }, 1437 { zfs_ioc_rollback, zfs_secpolicy_write, dataset_name }, 1438 { zfs_ioc_rename, zfs_secpolicy_write, dataset_name }, 1439 { zfs_ioc_recvbackup, zfs_secpolicy_write, dataset_name }, 1440 { zfs_ioc_sendbackup, zfs_secpolicy_write, dataset_name }, 1441 { zfs_ioc_inject_fault, zfs_secpolicy_inject, no_name }, 1442 { zfs_ioc_clear_fault, zfs_secpolicy_inject, no_name }, 1443 { zfs_ioc_inject_list_next, zfs_secpolicy_inject, no_name }, 1444 { zfs_ioc_error_log, zfs_secpolicy_inject, pool_name }, 1445 { zfs_ioc_clear, zfs_secpolicy_config, pool_name }, 1446 { zfs_ioc_bookmark_name, zfs_secpolicy_inject, pool_name }, 1447 { zfs_ioc_promote, zfs_secpolicy_write, dataset_name }, 1448 { zfs_ioc_destroy_snaps, zfs_secpolicy_write, dataset_name }, 1449 { zfs_ioc_snapshot, zfs_secpolicy_write, dataset_name } 1450 }; 1451 1452 static int 1453 zfsdev_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) 1454 { 1455 zfs_cmd_t *zc; 1456 uint_t vec; 1457 int error, rc; 1458 1459 if (getminor(dev) != 0) 1460 return (zvol_ioctl(dev, cmd, arg, flag, cr, rvalp)); 1461 1462 vec = cmd - ZFS_IOC; 1463 1464 if (vec >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0])) 1465 return (EINVAL); 1466 1467 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP); 1468 1469 error = xcopyin((void *)arg, zc, sizeof (zfs_cmd_t)); 1470 1471 if (error == 0) { 1472 zc->zc_cred = (uintptr_t)cr; 1473 zc->zc_dev = dev; 1474 error = zfs_ioc_vec[vec].zvec_secpolicy(zc->zc_name, cr); 1475 } 1476 1477 /* 1478 * Ensure that all pool/dataset names are valid before we pass down to 1479 * the lower layers. 1480 */ 1481 if (error == 0) { 1482 zc->zc_name[sizeof (zc->zc_name) - 1] = '\0'; 1483 switch (zfs_ioc_vec[vec].zvec_namecheck) { 1484 case pool_name: 1485 if (pool_namecheck(zc->zc_name, NULL, NULL) != 0) 1486 error = EINVAL; 1487 break; 1488 1489 case dataset_name: 1490 if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0) 1491 error = EINVAL; 1492 break; 1493 1494 case no_name: 1495 break; 1496 } 1497 } 1498 1499 if (error == 0) 1500 error = zfs_ioc_vec[vec].zvec_func(zc); 1501 1502 rc = xcopyout(zc, (void *)arg, sizeof (zfs_cmd_t)); 1503 if (error == 0) 1504 error = rc; 1505 1506 kmem_free(zc, sizeof (zfs_cmd_t)); 1507 return (error); 1508 } 1509 1510 static int 1511 zfs_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1512 { 1513 if (cmd != DDI_ATTACH) 1514 return (DDI_FAILURE); 1515 1516 if (ddi_create_minor_node(dip, "zfs", S_IFCHR, 0, 1517 DDI_PSEUDO, 0) == DDI_FAILURE) 1518 return (DDI_FAILURE); 1519 1520 zfs_dip = dip; 1521 1522 ddi_report_dev(dip); 1523 1524 return (DDI_SUCCESS); 1525 } 1526 1527 static int 1528 zfs_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1529 { 1530 if (spa_busy() || zfs_busy() || zvol_busy()) 1531 return (DDI_FAILURE); 1532 1533 if (cmd != DDI_DETACH) 1534 return (DDI_FAILURE); 1535 1536 zfs_dip = NULL; 1537 1538 ddi_prop_remove_all(dip); 1539 ddi_remove_minor_node(dip, NULL); 1540 1541 return (DDI_SUCCESS); 1542 } 1543 1544 /*ARGSUSED*/ 1545 static int 1546 zfs_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 1547 { 1548 switch (infocmd) { 1549 case DDI_INFO_DEVT2DEVINFO: 1550 *result = zfs_dip; 1551 return (DDI_SUCCESS); 1552 1553 case DDI_INFO_DEVT2INSTANCE: 1554 *result = (void *)0; 1555 return (DDI_SUCCESS); 1556 } 1557 1558 return (DDI_FAILURE); 1559 } 1560 1561 /* 1562 * OK, so this is a little weird. 1563 * 1564 * /dev/zfs is the control node, i.e. minor 0. 1565 * /dev/zvol/[r]dsk/pool/dataset are the zvols, minor > 0. 1566 * 1567 * /dev/zfs has basically nothing to do except serve up ioctls, 1568 * so most of the standard driver entry points are in zvol.c. 1569 */ 1570 static struct cb_ops zfs_cb_ops = { 1571 zvol_open, /* open */ 1572 zvol_close, /* close */ 1573 zvol_strategy, /* strategy */ 1574 nodev, /* print */ 1575 nodev, /* dump */ 1576 zvol_read, /* read */ 1577 zvol_write, /* write */ 1578 zfsdev_ioctl, /* ioctl */ 1579 nodev, /* devmap */ 1580 nodev, /* mmap */ 1581 nodev, /* segmap */ 1582 nochpoll, /* poll */ 1583 ddi_prop_op, /* prop_op */ 1584 NULL, /* streamtab */ 1585 D_NEW | D_MP | D_64BIT, /* Driver compatibility flag */ 1586 CB_REV, /* version */ 1587 zvol_aread, /* async read */ 1588 zvol_awrite, /* async write */ 1589 }; 1590 1591 static struct dev_ops zfs_dev_ops = { 1592 DEVO_REV, /* version */ 1593 0, /* refcnt */ 1594 zfs_info, /* info */ 1595 nulldev, /* identify */ 1596 nulldev, /* probe */ 1597 zfs_attach, /* attach */ 1598 zfs_detach, /* detach */ 1599 nodev, /* reset */ 1600 &zfs_cb_ops, /* driver operations */ 1601 NULL /* no bus operations */ 1602 }; 1603 1604 static struct modldrv zfs_modldrv = { 1605 &mod_driverops, "ZFS storage pool version " ZFS_VERSION_STRING, 1606 &zfs_dev_ops 1607 }; 1608 1609 static struct modlinkage modlinkage = { 1610 MODREV_1, 1611 (void *)&zfs_modlfs, 1612 (void *)&zfs_modldrv, 1613 NULL 1614 }; 1615 1616 int 1617 _init(void) 1618 { 1619 int error; 1620 1621 spa_init(FREAD | FWRITE); 1622 zfs_init(); 1623 zvol_init(); 1624 1625 if ((error = mod_install(&modlinkage)) != 0) { 1626 zvol_fini(); 1627 zfs_fini(); 1628 spa_fini(); 1629 return (error); 1630 } 1631 1632 error = ldi_ident_from_mod(&modlinkage, &zfs_li); 1633 ASSERT(error == 0); 1634 1635 return (0); 1636 } 1637 1638 int 1639 _fini(void) 1640 { 1641 int error; 1642 1643 if (spa_busy() || zfs_busy() || zvol_busy() || zio_injection_enabled) 1644 return (EBUSY); 1645 1646 if ((error = mod_remove(&modlinkage)) != 0) 1647 return (error); 1648 1649 zvol_fini(); 1650 zfs_fini(); 1651 spa_fini(); 1652 1653 ldi_ident_release(zfs_li); 1654 zfs_li = NULL; 1655 1656 return (error); 1657 } 1658 1659 int 1660 _info(struct modinfo *modinfop) 1661 { 1662 return (mod_info(&modlinkage, modinfop)); 1663 } 1664