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 /* 681 * NB: zvol_get_stats() will read the objset contents, 682 * which we aren't supposed to do with a 683 * DS_MODE_STANDARD open, because it could be 684 * inconsistent. So this is a bit of a workaround... 685 */ 686 if (!zc->zc_objset_stats.dds_inconsistent && 687 dmu_objset_type(os) == DMU_OST_ZVOL) 688 VERIFY(zvol_get_stats(os, nv) == 0); 689 error = put_nvlist(zc, nv); 690 nvlist_free(nv); 691 } 692 693 spa_altroot(dmu_objset_spa(os), zc->zc_value, sizeof (zc->zc_value)); 694 695 dmu_objset_close(os); 696 return (error); 697 } 698 699 static int 700 zfs_ioc_dataset_list_next(zfs_cmd_t *zc) 701 { 702 objset_t *os; 703 int error; 704 char *p; 705 706 retry: 707 error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, 708 DS_MODE_STANDARD | DS_MODE_READONLY, &os); 709 if (error != 0) { 710 /* 711 * This is ugly: dmu_objset_open() can return EBUSY if 712 * the objset is held exclusively. Fortunately this hold is 713 * only for a short while, so we retry here. 714 * This avoids user code having to handle EBUSY, 715 * for example for a "zfs list". 716 */ 717 if (error == EBUSY) { 718 delay(1); 719 goto retry; 720 } 721 if (error == ENOENT) 722 error = ESRCH; 723 return (error); 724 } 725 726 p = strrchr(zc->zc_name, '/'); 727 if (p == NULL || p[1] != '\0') 728 (void) strlcat(zc->zc_name, "/", sizeof (zc->zc_name)); 729 p = zc->zc_name + strlen(zc->zc_name); 730 731 do { 732 error = dmu_dir_list_next(os, 733 sizeof (zc->zc_name) - (p - zc->zc_name), p, 734 NULL, &zc->zc_cookie); 735 if (error == ENOENT) 736 error = ESRCH; 737 } while (error == 0 && !INGLOBALZONE(curproc) && 738 !zone_dataset_visible(zc->zc_name, NULL)); 739 740 /* 741 * If it's a hidden dataset (ie. with a '$' in its name), don't 742 * try to get stats for it. Userland will skip over it. 743 */ 744 if (error == 0 && strchr(zc->zc_name, '$') == NULL) 745 error = zfs_ioc_objset_stats(zc); /* fill in the stats */ 746 747 dmu_objset_close(os); 748 return (error); 749 } 750 751 static int 752 zfs_ioc_snapshot_list_next(zfs_cmd_t *zc) 753 { 754 objset_t *os; 755 int error; 756 757 retry: 758 error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, 759 DS_MODE_STANDARD | DS_MODE_READONLY, &os); 760 if (error != 0) { 761 /* 762 * This is ugly: dmu_objset_open() can return EBUSY if 763 * the objset is held exclusively. Fortunately this hold is 764 * only for a short while, so we retry here. 765 * This avoids user code having to handle EBUSY, 766 * for example for a "zfs list". 767 */ 768 if (error == EBUSY) { 769 delay(1); 770 goto retry; 771 } 772 if (error == ENOENT) 773 error = ESRCH; 774 return (error); 775 } 776 777 /* 778 * A dataset name of maximum length cannot have any snapshots, 779 * so exit immediately. 780 */ 781 if (strlcat(zc->zc_name, "@", sizeof (zc->zc_name)) >= MAXNAMELEN) { 782 dmu_objset_close(os); 783 return (ESRCH); 784 } 785 786 error = dmu_snapshot_list_next(os, 787 sizeof (zc->zc_name) - strlen(zc->zc_name), 788 zc->zc_name + strlen(zc->zc_name), NULL, &zc->zc_cookie); 789 if (error == ENOENT) 790 error = ESRCH; 791 792 if (error == 0) 793 error = zfs_ioc_objset_stats(zc); /* fill in the stats */ 794 795 dmu_objset_close(os); 796 return (error); 797 } 798 799 static int 800 zfs_set_prop_nvlist(const char *name, dev_t dev, cred_t *cr, nvlist_t *nvl) 801 { 802 nvpair_t *elem; 803 int error; 804 const char *propname; 805 zfs_prop_t prop; 806 uint64_t intval; 807 char *strval; 808 809 elem = NULL; 810 while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) { 811 propname = nvpair_name(elem); 812 813 if ((prop = zfs_name_to_prop(propname)) == 814 ZFS_PROP_INVAL) { 815 /* 816 * If this is a user-defined property, it must be a 817 * string, and there is no further validation to do. 818 */ 819 if (!zfs_prop_user(propname) || 820 nvpair_type(elem) != DATA_TYPE_STRING) 821 return (EINVAL); 822 823 VERIFY(nvpair_value_string(elem, &strval) == 0); 824 error = dsl_prop_set(name, propname, 1, 825 strlen(strval) + 1, strval); 826 if (error == 0) 827 continue; 828 else 829 break; 830 } 831 832 /* 833 * Check permissions for special properties. 834 */ 835 switch (prop) { 836 case ZFS_PROP_ZONED: 837 /* 838 * Disallow setting of 'zoned' from within a local zone. 839 */ 840 if (!INGLOBALZONE(curproc)) 841 return (EPERM); 842 break; 843 844 case ZFS_PROP_QUOTA: 845 if (error = zfs_dozonecheck(name, cr)) 846 return (error); 847 848 if (!INGLOBALZONE(curproc)) { 849 uint64_t zoned; 850 char setpoint[MAXNAMELEN]; 851 int dslen; 852 /* 853 * Unprivileged users are allowed to modify the 854 * quota on things *under* (ie. contained by) 855 * the thing they own. 856 */ 857 if (dsl_prop_get_integer(name, "zoned", &zoned, 858 setpoint)) 859 return (EPERM); 860 if (!zoned) /* this shouldn't happen */ 861 return (EPERM); 862 dslen = strlen(name); 863 if (dslen <= strlen(setpoint)) 864 return (EPERM); 865 } 866 } 867 868 switch (prop) { 869 case ZFS_PROP_QUOTA: 870 if ((error = nvpair_value_uint64(elem, &intval)) != 0 || 871 (error = dsl_dir_set_quota(name, 872 intval)) != 0) 873 return (error); 874 break; 875 876 case ZFS_PROP_RESERVATION: 877 if ((error = nvpair_value_uint64(elem, &intval)) != 0 || 878 (error = dsl_dir_set_reservation(name, 879 intval)) != 0) 880 return (error); 881 break; 882 883 case ZFS_PROP_VOLSIZE: 884 if ((error = nvpair_value_uint64(elem, &intval)) != 0 || 885 (error = zvol_set_volsize(name, dev, 886 intval)) != 0) 887 return (error); 888 break; 889 890 case ZFS_PROP_VOLBLOCKSIZE: 891 if ((error = nvpair_value_uint64(elem, &intval)) != 0 || 892 (error = zvol_set_volblocksize(name, 893 intval)) != 0) 894 return (error); 895 break; 896 897 default: 898 if (nvpair_type(elem) == DATA_TYPE_STRING) { 899 if (zfs_prop_get_type(prop) != 900 prop_type_string) 901 return (EINVAL); 902 VERIFY(nvpair_value_string(elem, &strval) == 0); 903 if ((error = dsl_prop_set(name, 904 nvpair_name(elem), 1, strlen(strval) + 1, 905 strval)) != 0) 906 return (error); 907 } else if (nvpair_type(elem) == DATA_TYPE_UINT64) { 908 const char *unused; 909 910 VERIFY(nvpair_value_uint64(elem, &intval) == 0); 911 912 switch (zfs_prop_get_type(prop)) { 913 case prop_type_number: 914 break; 915 case prop_type_boolean: 916 if (intval > 1) 917 return (EINVAL); 918 break; 919 case prop_type_string: 920 return (EINVAL); 921 case prop_type_index: 922 if (zfs_prop_index_to_string(prop, 923 intval, &unused) != 0) 924 return (EINVAL); 925 break; 926 default: 927 cmn_err(CE_PANIC, "unknown property " 928 "type"); 929 break; 930 } 931 932 if ((error = dsl_prop_set(name, propname, 933 8, 1, &intval)) != 0) 934 return (error); 935 } else { 936 return (EINVAL); 937 } 938 break; 939 } 940 } 941 942 return (0); 943 } 944 945 static int 946 zfs_ioc_set_prop(zfs_cmd_t *zc) 947 { 948 nvlist_t *nvl; 949 int error; 950 zfs_prop_t prop; 951 952 /* 953 * If zc_value is set, then this is an attempt to inherit a value. 954 * Otherwise, zc_nvlist refers to a list of properties to set. 955 */ 956 if (zc->zc_value[0] != '\0') { 957 if (!zfs_prop_user(zc->zc_value) && 958 ((prop = zfs_name_to_prop(zc->zc_value)) == 959 ZFS_PROP_INVAL || 960 !zfs_prop_inheritable(prop))) 961 return (EINVAL); 962 963 return (dsl_prop_set(zc->zc_name, zc->zc_value, 0, 0, NULL)); 964 } 965 966 if ((error = get_nvlist(zc, &nvl)) != 0) 967 return (error); 968 969 error = zfs_set_prop_nvlist(zc->zc_name, zc->zc_dev, 970 (cred_t *)(uintptr_t)zc->zc_cred, nvl); 971 nvlist_free(nvl); 972 return (error); 973 } 974 975 static int 976 zfs_ioc_create_minor(zfs_cmd_t *zc) 977 { 978 return (zvol_create_minor(zc->zc_name, zc->zc_dev)); 979 } 980 981 static int 982 zfs_ioc_remove_minor(zfs_cmd_t *zc) 983 { 984 return (zvol_remove_minor(zc->zc_name)); 985 } 986 987 /* 988 * Search the vfs list for a specified resource. Returns a pointer to it 989 * or NULL if no suitable entry is found. The caller of this routine 990 * is responsible for releasing the returned vfs pointer. 991 */ 992 static vfs_t * 993 zfs_get_vfs(const char *resource) 994 { 995 struct vfs *vfsp; 996 struct vfs *vfs_found = NULL; 997 998 vfs_list_read_lock(); 999 vfsp = rootvfs; 1000 do { 1001 if (strcmp(refstr_value(vfsp->vfs_resource), resource) == 0) { 1002 VFS_HOLD(vfsp); 1003 vfs_found = vfsp; 1004 break; 1005 } 1006 vfsp = vfsp->vfs_next; 1007 } while (vfsp != rootvfs); 1008 vfs_list_unlock(); 1009 return (vfs_found); 1010 } 1011 1012 static void 1013 zfs_create_cb(objset_t *os, void *arg, dmu_tx_t *tx) 1014 { 1015 zfs_create_data_t *zc = arg; 1016 zfs_create_fs(os, (cred_t *)(uintptr_t)zc->zc_cred, tx); 1017 } 1018 1019 static int 1020 zfs_ioc_create(zfs_cmd_t *zc) 1021 { 1022 objset_t *clone; 1023 int error = 0; 1024 zfs_create_data_t cbdata = { 0 }; 1025 void (*cbfunc)(objset_t *os, void *arg, dmu_tx_t *tx); 1026 dmu_objset_type_t type = zc->zc_objset_type; 1027 1028 switch (type) { 1029 1030 case DMU_OST_ZFS: 1031 cbfunc = zfs_create_cb; 1032 break; 1033 1034 case DMU_OST_ZVOL: 1035 cbfunc = zvol_create_cb; 1036 break; 1037 1038 default: 1039 cbfunc = NULL; 1040 } 1041 if (strchr(zc->zc_name, '@')) 1042 return (EINVAL); 1043 1044 if (zc->zc_nvlist_src != NULL && 1045 (error = get_nvlist(zc, &cbdata.zc_props)) != 0) 1046 return (error); 1047 1048 cbdata.zc_cred = (cred_t *)(uintptr_t)zc->zc_cred; 1049 cbdata.zc_dev = (dev_t)zc->zc_dev; 1050 1051 if (zc->zc_value[0] != '\0') { 1052 /* 1053 * We're creating a clone of an existing snapshot. 1054 */ 1055 zc->zc_value[sizeof (zc->zc_value) - 1] = '\0'; 1056 if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0) { 1057 nvlist_free(cbdata.zc_props); 1058 return (EINVAL); 1059 } 1060 1061 error = dmu_objset_open(zc->zc_value, type, 1062 DS_MODE_STANDARD | DS_MODE_READONLY, &clone); 1063 if (error) { 1064 nvlist_free(cbdata.zc_props); 1065 return (error); 1066 } 1067 error = dmu_objset_create(zc->zc_name, type, clone, NULL, NULL); 1068 dmu_objset_close(clone); 1069 } else { 1070 if (cbfunc == NULL) { 1071 nvlist_free(cbdata.zc_props); 1072 return (EINVAL); 1073 } 1074 1075 if (type == DMU_OST_ZVOL) { 1076 uint64_t volsize, volblocksize; 1077 1078 if (cbdata.zc_props == NULL || 1079 nvlist_lookup_uint64(cbdata.zc_props, 1080 zfs_prop_to_name(ZFS_PROP_VOLSIZE), 1081 &volsize) != 0) { 1082 nvlist_free(cbdata.zc_props); 1083 return (EINVAL); 1084 } 1085 1086 if ((error = nvlist_lookup_uint64(cbdata.zc_props, 1087 zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), 1088 &volblocksize)) != 0 && error != ENOENT) { 1089 nvlist_free(cbdata.zc_props); 1090 return (EINVAL); 1091 } 1092 1093 if (error != 0) 1094 volblocksize = zfs_prop_default_numeric( 1095 ZFS_PROP_VOLBLOCKSIZE); 1096 1097 if ((error = zvol_check_volblocksize( 1098 volblocksize)) != 0 || 1099 (error = zvol_check_volsize(volsize, 1100 volblocksize)) != 0) { 1101 nvlist_free(cbdata.zc_props); 1102 return (error); 1103 } 1104 } 1105 1106 error = dmu_objset_create(zc->zc_name, type, NULL, cbfunc, 1107 &cbdata); 1108 } 1109 1110 /* 1111 * It would be nice to do this atomically. 1112 */ 1113 if (error == 0) { 1114 if ((error = zfs_set_prop_nvlist(zc->zc_name, 1115 zc->zc_dev, (cred_t *)(uintptr_t)zc->zc_cred, 1116 cbdata.zc_props)) != 0) 1117 (void) dmu_objset_destroy(zc->zc_name); 1118 } 1119 1120 nvlist_free(cbdata.zc_props); 1121 return (error); 1122 } 1123 1124 static int 1125 zfs_ioc_snapshot(zfs_cmd_t *zc) 1126 { 1127 if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0) 1128 return (EINVAL); 1129 return (dmu_objset_snapshot(zc->zc_name, 1130 zc->zc_value, zc->zc_cookie)); 1131 } 1132 1133 static int 1134 zfs_unmount_snap(char *name, void *arg) 1135 { 1136 char *snapname = arg; 1137 char *cp; 1138 vfs_t *vfsp = NULL; 1139 1140 /* 1141 * Snapshots (which are under .zfs control) must be unmounted 1142 * before they can be destroyed. 1143 */ 1144 1145 if (snapname) { 1146 (void) strcat(name, "@"); 1147 (void) strcat(name, snapname); 1148 vfsp = zfs_get_vfs(name); 1149 cp = strchr(name, '@'); 1150 *cp = '\0'; 1151 } else if (strchr(name, '@')) { 1152 vfsp = zfs_get_vfs(name); 1153 } 1154 1155 if (vfsp) { 1156 /* 1157 * Always force the unmount for snapshots. 1158 */ 1159 int flag = MS_FORCE; 1160 int err; 1161 1162 if ((err = vn_vfswlock(vfsp->vfs_vnodecovered)) != 0) { 1163 VFS_RELE(vfsp); 1164 return (err); 1165 } 1166 VFS_RELE(vfsp); 1167 if ((err = dounmount(vfsp, flag, kcred)) != 0) 1168 return (err); 1169 } 1170 return (0); 1171 } 1172 1173 static int 1174 zfs_ioc_destroy_snaps(zfs_cmd_t *zc) 1175 { 1176 int err; 1177 1178 if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0) 1179 return (EINVAL); 1180 err = dmu_objset_find(zc->zc_name, 1181 zfs_unmount_snap, zc->zc_value, DS_FIND_CHILDREN); 1182 if (err) 1183 return (err); 1184 return (dmu_snapshots_destroy(zc->zc_name, zc->zc_value)); 1185 } 1186 1187 static int 1188 zfs_ioc_destroy(zfs_cmd_t *zc) 1189 { 1190 if (strchr(zc->zc_name, '@') && zc->zc_objset_type == DMU_OST_ZFS) { 1191 int err = zfs_unmount_snap(zc->zc_name, NULL); 1192 if (err) 1193 return (err); 1194 } 1195 1196 return (dmu_objset_destroy(zc->zc_name)); 1197 } 1198 1199 static int 1200 zfs_ioc_rollback(zfs_cmd_t *zc) 1201 { 1202 return (dmu_objset_rollback(zc->zc_name)); 1203 } 1204 1205 static int 1206 zfs_ioc_rename(zfs_cmd_t *zc) 1207 { 1208 zc->zc_value[sizeof (zc->zc_value) - 1] = '\0'; 1209 if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0) 1210 return (EINVAL); 1211 1212 if (strchr(zc->zc_name, '@') != NULL && 1213 zc->zc_objset_type == DMU_OST_ZFS) { 1214 int err = zfs_unmount_snap(zc->zc_name, NULL); 1215 if (err) 1216 return (err); 1217 } 1218 1219 return (dmu_objset_rename(zc->zc_name, zc->zc_value)); 1220 } 1221 1222 static int 1223 zfs_ioc_recvbackup(zfs_cmd_t *zc) 1224 { 1225 file_t *fp; 1226 int error, fd; 1227 offset_t new_off; 1228 1229 fd = zc->zc_cookie; 1230 fp = getf(fd); 1231 if (fp == NULL) 1232 return (EBADF); 1233 error = dmu_recvbackup(zc->zc_value, &zc->zc_begin_record, 1234 &zc->zc_cookie, (boolean_t)zc->zc_guid, fp->f_vnode, 1235 fp->f_offset); 1236 1237 new_off = fp->f_offset + zc->zc_cookie; 1238 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &new_off) == 0) 1239 fp->f_offset = new_off; 1240 1241 releasef(fd); 1242 return (error); 1243 } 1244 1245 static int 1246 zfs_ioc_sendbackup(zfs_cmd_t *zc) 1247 { 1248 objset_t *fromsnap = NULL; 1249 objset_t *tosnap; 1250 file_t *fp; 1251 int error; 1252 1253 error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, 1254 DS_MODE_STANDARD | DS_MODE_READONLY, &tosnap); 1255 if (error) 1256 return (error); 1257 1258 if (zc->zc_value[0] != '\0') { 1259 char buf[MAXPATHLEN]; 1260 char *cp; 1261 1262 (void) strncpy(buf, zc->zc_name, sizeof (buf)); 1263 cp = strchr(buf, '@'); 1264 if (cp) 1265 *(cp+1) = 0; 1266 (void) strncat(buf, zc->zc_value, sizeof (buf)); 1267 error = dmu_objset_open(buf, DMU_OST_ANY, 1268 DS_MODE_STANDARD | DS_MODE_READONLY, &fromsnap); 1269 if (error) { 1270 dmu_objset_close(tosnap); 1271 return (error); 1272 } 1273 } 1274 1275 fp = getf(zc->zc_cookie); 1276 if (fp == NULL) { 1277 dmu_objset_close(tosnap); 1278 if (fromsnap) 1279 dmu_objset_close(fromsnap); 1280 return (EBADF); 1281 } 1282 1283 error = dmu_sendbackup(tosnap, fromsnap, fp->f_vnode); 1284 1285 releasef(zc->zc_cookie); 1286 if (fromsnap) 1287 dmu_objset_close(fromsnap); 1288 dmu_objset_close(tosnap); 1289 return (error); 1290 } 1291 1292 static int 1293 zfs_ioc_inject_fault(zfs_cmd_t *zc) 1294 { 1295 int id, error; 1296 1297 error = zio_inject_fault(zc->zc_name, (int)zc->zc_guid, &id, 1298 &zc->zc_inject_record); 1299 1300 if (error == 0) 1301 zc->zc_guid = (uint64_t)id; 1302 1303 return (error); 1304 } 1305 1306 static int 1307 zfs_ioc_clear_fault(zfs_cmd_t *zc) 1308 { 1309 return (zio_clear_fault((int)zc->zc_guid)); 1310 } 1311 1312 static int 1313 zfs_ioc_inject_list_next(zfs_cmd_t *zc) 1314 { 1315 int id = (int)zc->zc_guid; 1316 int error; 1317 1318 error = zio_inject_list_next(&id, zc->zc_name, sizeof (zc->zc_name), 1319 &zc->zc_inject_record); 1320 1321 zc->zc_guid = id; 1322 1323 return (error); 1324 } 1325 1326 static int 1327 zfs_ioc_error_log(zfs_cmd_t *zc) 1328 { 1329 spa_t *spa; 1330 int error; 1331 size_t count = (size_t)zc->zc_nvlist_dst_size; 1332 1333 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 1334 return (error); 1335 1336 error = spa_get_errlog(spa, (void *)(uintptr_t)zc->zc_nvlist_dst, 1337 &count); 1338 if (error == 0) 1339 zc->zc_nvlist_dst_size = count; 1340 else 1341 zc->zc_nvlist_dst_size = spa_get_errlog_size(spa); 1342 1343 spa_close(spa, FTAG); 1344 1345 return (error); 1346 } 1347 1348 static int 1349 zfs_ioc_clear(zfs_cmd_t *zc) 1350 { 1351 spa_t *spa; 1352 vdev_t *vd; 1353 int error; 1354 1355 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 1356 return (error); 1357 1358 spa_config_enter(spa, RW_WRITER, FTAG); 1359 1360 if (zc->zc_guid == 0) { 1361 vd = NULL; 1362 } else if ((vd = spa_lookup_by_guid(spa, zc->zc_guid)) == NULL) { 1363 spa_config_exit(spa, FTAG); 1364 spa_close(spa, FTAG); 1365 return (ENODEV); 1366 } 1367 1368 vdev_clear(spa, vd); 1369 1370 spa_config_exit(spa, FTAG); 1371 1372 spa_close(spa, FTAG); 1373 1374 return (0); 1375 } 1376 1377 static int 1378 zfs_ioc_bookmark_name(zfs_cmd_t *zc) 1379 { 1380 spa_t *spa; 1381 int error; 1382 nvlist_t *nvl; 1383 1384 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 1385 return (error); 1386 1387 VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP) == 0); 1388 1389 error = spa_bookmark_name(spa, &zc->zc_bookmark, nvl); 1390 if (error == 0) 1391 error = put_nvlist(zc, nvl); 1392 nvlist_free(nvl); 1393 1394 spa_close(spa, FTAG); 1395 1396 return (error); 1397 } 1398 1399 static int 1400 zfs_ioc_promote(zfs_cmd_t *zc) 1401 { 1402 char *cp; 1403 1404 /* 1405 * We don't need to unmount *all* the origin fs's snapshots, but 1406 * it's easier. 1407 */ 1408 cp = strchr(zc->zc_value, '@'); 1409 if (cp) 1410 *cp = '\0'; 1411 (void) dmu_objset_find(zc->zc_value, 1412 zfs_unmount_snap, NULL, DS_FIND_SNAPSHOTS); 1413 return (dsl_dataset_promote(zc->zc_name)); 1414 } 1415 1416 static zfs_ioc_vec_t zfs_ioc_vec[] = { 1417 { zfs_ioc_pool_create, zfs_secpolicy_config, pool_name }, 1418 { zfs_ioc_pool_destroy, zfs_secpolicy_config, pool_name }, 1419 { zfs_ioc_pool_import, zfs_secpolicy_config, pool_name }, 1420 { zfs_ioc_pool_export, zfs_secpolicy_config, pool_name }, 1421 { zfs_ioc_pool_configs, zfs_secpolicy_none, no_name }, 1422 { zfs_ioc_pool_stats, zfs_secpolicy_read, pool_name }, 1423 { zfs_ioc_pool_tryimport, zfs_secpolicy_config, no_name }, 1424 { zfs_ioc_pool_scrub, zfs_secpolicy_config, pool_name }, 1425 { zfs_ioc_pool_freeze, zfs_secpolicy_config, no_name }, 1426 { zfs_ioc_pool_upgrade, zfs_secpolicy_config, pool_name }, 1427 { zfs_ioc_pool_get_history, zfs_secpolicy_config, pool_name }, 1428 { zfs_ioc_pool_log_history, zfs_secpolicy_config, pool_name }, 1429 { zfs_ioc_vdev_add, zfs_secpolicy_config, pool_name }, 1430 { zfs_ioc_vdev_remove, zfs_secpolicy_config, pool_name }, 1431 { zfs_ioc_vdev_online, zfs_secpolicy_config, pool_name }, 1432 { zfs_ioc_vdev_offline, zfs_secpolicy_config, pool_name }, 1433 { zfs_ioc_vdev_attach, zfs_secpolicy_config, pool_name }, 1434 { zfs_ioc_vdev_detach, zfs_secpolicy_config, pool_name }, 1435 { zfs_ioc_vdev_setpath, zfs_secpolicy_config, pool_name }, 1436 { zfs_ioc_objset_stats, zfs_secpolicy_read, dataset_name }, 1437 { zfs_ioc_dataset_list_next, zfs_secpolicy_read, dataset_name }, 1438 { zfs_ioc_snapshot_list_next, zfs_secpolicy_read, dataset_name }, 1439 { zfs_ioc_set_prop, zfs_secpolicy_write, dataset_name }, 1440 { zfs_ioc_create_minor, zfs_secpolicy_config, dataset_name }, 1441 { zfs_ioc_remove_minor, zfs_secpolicy_config, dataset_name }, 1442 { zfs_ioc_create, zfs_secpolicy_parent, dataset_name }, 1443 { zfs_ioc_destroy, zfs_secpolicy_parent, dataset_name }, 1444 { zfs_ioc_rollback, zfs_secpolicy_write, dataset_name }, 1445 { zfs_ioc_rename, zfs_secpolicy_write, dataset_name }, 1446 { zfs_ioc_recvbackup, zfs_secpolicy_write, dataset_name }, 1447 { zfs_ioc_sendbackup, zfs_secpolicy_write, dataset_name }, 1448 { zfs_ioc_inject_fault, zfs_secpolicy_inject, no_name }, 1449 { zfs_ioc_clear_fault, zfs_secpolicy_inject, no_name }, 1450 { zfs_ioc_inject_list_next, zfs_secpolicy_inject, no_name }, 1451 { zfs_ioc_error_log, zfs_secpolicy_inject, pool_name }, 1452 { zfs_ioc_clear, zfs_secpolicy_config, pool_name }, 1453 { zfs_ioc_bookmark_name, zfs_secpolicy_inject, pool_name }, 1454 { zfs_ioc_promote, zfs_secpolicy_write, dataset_name }, 1455 { zfs_ioc_destroy_snaps, zfs_secpolicy_write, dataset_name }, 1456 { zfs_ioc_snapshot, zfs_secpolicy_write, dataset_name } 1457 }; 1458 1459 static int 1460 zfsdev_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) 1461 { 1462 zfs_cmd_t *zc; 1463 uint_t vec; 1464 int error, rc; 1465 1466 if (getminor(dev) != 0) 1467 return (zvol_ioctl(dev, cmd, arg, flag, cr, rvalp)); 1468 1469 vec = cmd - ZFS_IOC; 1470 1471 if (vec >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0])) 1472 return (EINVAL); 1473 1474 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP); 1475 1476 error = xcopyin((void *)arg, zc, sizeof (zfs_cmd_t)); 1477 1478 if (error == 0) { 1479 zc->zc_cred = (uintptr_t)cr; 1480 zc->zc_dev = dev; 1481 error = zfs_ioc_vec[vec].zvec_secpolicy(zc->zc_name, cr); 1482 } 1483 1484 /* 1485 * Ensure that all pool/dataset names are valid before we pass down to 1486 * the lower layers. 1487 */ 1488 if (error == 0) { 1489 zc->zc_name[sizeof (zc->zc_name) - 1] = '\0'; 1490 switch (zfs_ioc_vec[vec].zvec_namecheck) { 1491 case pool_name: 1492 if (pool_namecheck(zc->zc_name, NULL, NULL) != 0) 1493 error = EINVAL; 1494 break; 1495 1496 case dataset_name: 1497 if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0) 1498 error = EINVAL; 1499 break; 1500 1501 case no_name: 1502 break; 1503 } 1504 } 1505 1506 if (error == 0) 1507 error = zfs_ioc_vec[vec].zvec_func(zc); 1508 1509 rc = xcopyout(zc, (void *)arg, sizeof (zfs_cmd_t)); 1510 if (error == 0) 1511 error = rc; 1512 1513 kmem_free(zc, sizeof (zfs_cmd_t)); 1514 return (error); 1515 } 1516 1517 static int 1518 zfs_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1519 { 1520 if (cmd != DDI_ATTACH) 1521 return (DDI_FAILURE); 1522 1523 if (ddi_create_minor_node(dip, "zfs", S_IFCHR, 0, 1524 DDI_PSEUDO, 0) == DDI_FAILURE) 1525 return (DDI_FAILURE); 1526 1527 zfs_dip = dip; 1528 1529 ddi_report_dev(dip); 1530 1531 return (DDI_SUCCESS); 1532 } 1533 1534 static int 1535 zfs_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1536 { 1537 if (spa_busy() || zfs_busy() || zvol_busy()) 1538 return (DDI_FAILURE); 1539 1540 if (cmd != DDI_DETACH) 1541 return (DDI_FAILURE); 1542 1543 zfs_dip = NULL; 1544 1545 ddi_prop_remove_all(dip); 1546 ddi_remove_minor_node(dip, NULL); 1547 1548 return (DDI_SUCCESS); 1549 } 1550 1551 /*ARGSUSED*/ 1552 static int 1553 zfs_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 1554 { 1555 switch (infocmd) { 1556 case DDI_INFO_DEVT2DEVINFO: 1557 *result = zfs_dip; 1558 return (DDI_SUCCESS); 1559 1560 case DDI_INFO_DEVT2INSTANCE: 1561 *result = (void *)0; 1562 return (DDI_SUCCESS); 1563 } 1564 1565 return (DDI_FAILURE); 1566 } 1567 1568 /* 1569 * OK, so this is a little weird. 1570 * 1571 * /dev/zfs is the control node, i.e. minor 0. 1572 * /dev/zvol/[r]dsk/pool/dataset are the zvols, minor > 0. 1573 * 1574 * /dev/zfs has basically nothing to do except serve up ioctls, 1575 * so most of the standard driver entry points are in zvol.c. 1576 */ 1577 static struct cb_ops zfs_cb_ops = { 1578 zvol_open, /* open */ 1579 zvol_close, /* close */ 1580 zvol_strategy, /* strategy */ 1581 nodev, /* print */ 1582 nodev, /* dump */ 1583 zvol_read, /* read */ 1584 zvol_write, /* write */ 1585 zfsdev_ioctl, /* ioctl */ 1586 nodev, /* devmap */ 1587 nodev, /* mmap */ 1588 nodev, /* segmap */ 1589 nochpoll, /* poll */ 1590 ddi_prop_op, /* prop_op */ 1591 NULL, /* streamtab */ 1592 D_NEW | D_MP | D_64BIT, /* Driver compatibility flag */ 1593 CB_REV, /* version */ 1594 zvol_aread, /* async read */ 1595 zvol_awrite, /* async write */ 1596 }; 1597 1598 static struct dev_ops zfs_dev_ops = { 1599 DEVO_REV, /* version */ 1600 0, /* refcnt */ 1601 zfs_info, /* info */ 1602 nulldev, /* identify */ 1603 nulldev, /* probe */ 1604 zfs_attach, /* attach */ 1605 zfs_detach, /* detach */ 1606 nodev, /* reset */ 1607 &zfs_cb_ops, /* driver operations */ 1608 NULL /* no bus operations */ 1609 }; 1610 1611 static struct modldrv zfs_modldrv = { 1612 &mod_driverops, "ZFS storage pool version " ZFS_VERSION_STRING, 1613 &zfs_dev_ops 1614 }; 1615 1616 static struct modlinkage modlinkage = { 1617 MODREV_1, 1618 (void *)&zfs_modlfs, 1619 (void *)&zfs_modldrv, 1620 NULL 1621 }; 1622 1623 int 1624 _init(void) 1625 { 1626 int error; 1627 1628 spa_init(FREAD | FWRITE); 1629 zfs_init(); 1630 zvol_init(); 1631 1632 if ((error = mod_install(&modlinkage)) != 0) { 1633 zvol_fini(); 1634 zfs_fini(); 1635 spa_fini(); 1636 return (error); 1637 } 1638 1639 error = ldi_ident_from_mod(&modlinkage, &zfs_li); 1640 ASSERT(error == 0); 1641 1642 return (0); 1643 } 1644 1645 int 1646 _fini(void) 1647 { 1648 int error; 1649 1650 if (spa_busy() || zfs_busy() || zvol_busy() || zio_injection_enabled) 1651 return (EBUSY); 1652 1653 if ((error = mod_remove(&modlinkage)) != 0) 1654 return (error); 1655 1656 zvol_fini(); 1657 zfs_fini(); 1658 spa_fini(); 1659 1660 ldi_ident_release(zfs_li); 1661 zfs_li = NULL; 1662 1663 return (error); 1664 } 1665 1666 int 1667 _info(struct modinfo *modinfop) 1668 { 1669 return (mod_info(&modlinkage, modinfop)); 1670 } 1671