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