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 2008 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/zfs_znode.h> 42 #include <sys/zap.h> 43 #include <sys/spa.h> 44 #include <sys/spa_impl.h> 45 #include <sys/vdev.h> 46 #include <sys/vdev_impl.h> 47 #include <sys/dmu.h> 48 #include <sys/dsl_dir.h> 49 #include <sys/dsl_dataset.h> 50 #include <sys/dsl_prop.h> 51 #include <sys/dsl_deleg.h> 52 #include <sys/dmu_objset.h> 53 #include <sys/ddi.h> 54 #include <sys/sunddi.h> 55 #include <sys/sunldi.h> 56 #include <sys/policy.h> 57 #include <sys/zone.h> 58 #include <sys/nvpair.h> 59 #include <sys/pathname.h> 60 #include <sys/mount.h> 61 #include <sys/sdt.h> 62 #include <sys/fs/zfs.h> 63 #include <sys/zfs_ctldir.h> 64 #include <sys/zfs_dir.h> 65 #include <sys/zvol.h> 66 #include <sharefs/share.h> 67 #include <sys/dmu_objset.h> 68 69 #include "zfs_namecheck.h" 70 #include "zfs_prop.h" 71 #include "zfs_deleg.h" 72 73 extern struct modlfs zfs_modlfs; 74 75 extern void zfs_init(void); 76 extern void zfs_fini(void); 77 78 ldi_ident_t zfs_li = NULL; 79 dev_info_t *zfs_dip; 80 81 typedef int zfs_ioc_func_t(zfs_cmd_t *); 82 typedef int zfs_secpolicy_func_t(zfs_cmd_t *, cred_t *); 83 84 typedef struct zfs_ioc_vec { 85 zfs_ioc_func_t *zvec_func; 86 zfs_secpolicy_func_t *zvec_secpolicy; 87 enum { 88 NO_NAME, 89 POOL_NAME, 90 DATASET_NAME 91 } zvec_namecheck; 92 boolean_t zvec_his_log; 93 } zfs_ioc_vec_t; 94 95 /* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */ 96 void 97 __dprintf(const char *file, const char *func, int line, const char *fmt, ...) 98 { 99 const char *newfile; 100 char buf[256]; 101 va_list adx; 102 103 /* 104 * Get rid of annoying "../common/" prefix to filename. 105 */ 106 newfile = strrchr(file, '/'); 107 if (newfile != NULL) { 108 newfile = newfile + 1; /* Get rid of leading / */ 109 } else { 110 newfile = file; 111 } 112 113 va_start(adx, fmt); 114 (void) vsnprintf(buf, sizeof (buf), fmt, adx); 115 va_end(adx); 116 117 /* 118 * To get this data, use the zfs-dprintf probe as so: 119 * dtrace -q -n 'zfs-dprintf \ 120 * /stringof(arg0) == "dbuf.c"/ \ 121 * {printf("%s: %s", stringof(arg1), stringof(arg3))}' 122 * arg0 = file name 123 * arg1 = function name 124 * arg2 = line number 125 * arg3 = message 126 */ 127 DTRACE_PROBE4(zfs__dprintf, 128 char *, newfile, char *, func, int, line, char *, buf); 129 } 130 131 static void 132 history_str_free(char *buf) 133 { 134 kmem_free(buf, HIS_MAX_RECORD_LEN); 135 } 136 137 static char * 138 history_str_get(zfs_cmd_t *zc) 139 { 140 char *buf; 141 142 if (zc->zc_history == NULL) 143 return (NULL); 144 145 buf = kmem_alloc(HIS_MAX_RECORD_LEN, KM_SLEEP); 146 if (copyinstr((void *)(uintptr_t)zc->zc_history, 147 buf, HIS_MAX_RECORD_LEN, NULL) != 0) { 148 history_str_free(buf); 149 return (NULL); 150 } 151 152 buf[HIS_MAX_RECORD_LEN -1] = '\0'; 153 154 return (buf); 155 } 156 157 /* 158 * zfs_check_version 159 * 160 * Return non-zero if the spa version is less than requested version. 161 */ 162 static int 163 zfs_check_version(const char *name, int version) 164 { 165 166 spa_t *spa; 167 168 if (spa_open(name, &spa, FTAG) == 0) { 169 if (spa_version(spa) < version) { 170 spa_close(spa, FTAG); 171 return (1); 172 } 173 spa_close(spa, FTAG); 174 } 175 return (0); 176 } 177 178 /* 179 * zpl_earlier_version 180 * 181 * Return TRUE if the ZPL version is less than requested version. 182 */ 183 static boolean_t 184 zpl_earlier_version(const char *name, int version) 185 { 186 objset_t *os; 187 boolean_t rc = B_TRUE; 188 189 if (dmu_objset_open(name, DMU_OST_ANY, 190 DS_MODE_USER | DS_MODE_READONLY, &os) == 0) { 191 uint64_t zplversion; 192 193 if (zfs_get_zplprop(os, ZFS_PROP_VERSION, &zplversion) == 0) 194 rc = zplversion < version; 195 dmu_objset_close(os); 196 } 197 return (rc); 198 } 199 200 static void 201 zfs_log_history(zfs_cmd_t *zc) 202 { 203 spa_t *spa; 204 char *buf; 205 206 if ((buf = history_str_get(zc)) == NULL) 207 return; 208 209 if (spa_open(zc->zc_name, &spa, FTAG) == 0) { 210 if (spa_version(spa) >= SPA_VERSION_ZPOOL_HISTORY) 211 (void) spa_history_log(spa, buf, LOG_CMD_NORMAL); 212 spa_close(spa, FTAG); 213 } 214 history_str_free(buf); 215 } 216 217 /* 218 * Policy for top-level read operations (list pools). Requires no privileges, 219 * and can be used in the local zone, as there is no associated dataset. 220 */ 221 /* ARGSUSED */ 222 static int 223 zfs_secpolicy_none(zfs_cmd_t *zc, cred_t *cr) 224 { 225 return (0); 226 } 227 228 /* 229 * Policy for dataset read operations (list children, get statistics). Requires 230 * no privileges, but must be visible in the local zone. 231 */ 232 /* ARGSUSED */ 233 static int 234 zfs_secpolicy_read(zfs_cmd_t *zc, cred_t *cr) 235 { 236 if (INGLOBALZONE(curproc) || 237 zone_dataset_visible(zc->zc_name, NULL)) 238 return (0); 239 240 return (ENOENT); 241 } 242 243 static int 244 zfs_dozonecheck(const char *dataset, cred_t *cr) 245 { 246 uint64_t zoned; 247 int writable = 1; 248 249 /* 250 * The dataset must be visible by this zone -- check this first 251 * so they don't see EPERM on something they shouldn't know about. 252 */ 253 if (!INGLOBALZONE(curproc) && 254 !zone_dataset_visible(dataset, &writable)) 255 return (ENOENT); 256 257 if (dsl_prop_get_integer(dataset, "zoned", &zoned, NULL)) 258 return (ENOENT); 259 260 if (INGLOBALZONE(curproc)) { 261 /* 262 * If the fs is zoned, only root can access it from the 263 * global zone. 264 */ 265 if (secpolicy_zfs(cr) && zoned) 266 return (EPERM); 267 } else { 268 /* 269 * If we are in a local zone, the 'zoned' property must be set. 270 */ 271 if (!zoned) 272 return (EPERM); 273 274 /* must be writable by this zone */ 275 if (!writable) 276 return (EPERM); 277 } 278 return (0); 279 } 280 281 int 282 zfs_secpolicy_write_perms(const char *name, const char *perm, cred_t *cr) 283 { 284 int error; 285 286 error = zfs_dozonecheck(name, cr); 287 if (error == 0) { 288 error = secpolicy_zfs(cr); 289 if (error) 290 error = dsl_deleg_access(name, perm, cr); 291 } 292 return (error); 293 } 294 295 static int 296 zfs_secpolicy_setprop(const char *name, zfs_prop_t prop, cred_t *cr) 297 { 298 /* 299 * Check permissions for special properties. 300 */ 301 switch (prop) { 302 case ZFS_PROP_ZONED: 303 /* 304 * Disallow setting of 'zoned' from within a local zone. 305 */ 306 if (!INGLOBALZONE(curproc)) 307 return (EPERM); 308 break; 309 310 case ZFS_PROP_QUOTA: 311 if (!INGLOBALZONE(curproc)) { 312 uint64_t zoned; 313 char setpoint[MAXNAMELEN]; 314 /* 315 * Unprivileged users are allowed to modify the 316 * quota on things *under* (ie. contained by) 317 * the thing they own. 318 */ 319 if (dsl_prop_get_integer(name, "zoned", &zoned, 320 setpoint)) 321 return (EPERM); 322 if (!zoned || strlen(name) <= strlen(setpoint)) 323 return (EPERM); 324 } 325 break; 326 } 327 328 return (zfs_secpolicy_write_perms(name, zfs_prop_to_name(prop), cr)); 329 } 330 331 int 332 zfs_secpolicy_fsacl(zfs_cmd_t *zc, cred_t *cr) 333 { 334 int error; 335 336 error = zfs_dozonecheck(zc->zc_name, cr); 337 if (error) 338 return (error); 339 340 /* 341 * permission to set permissions will be evaluated later in 342 * dsl_deleg_can_allow() 343 */ 344 return (0); 345 } 346 347 int 348 zfs_secpolicy_rollback(zfs_cmd_t *zc, cred_t *cr) 349 { 350 int error; 351 error = zfs_secpolicy_write_perms(zc->zc_name, 352 ZFS_DELEG_PERM_ROLLBACK, cr); 353 if (error == 0) 354 error = zfs_secpolicy_write_perms(zc->zc_name, 355 ZFS_DELEG_PERM_MOUNT, cr); 356 return (error); 357 } 358 359 int 360 zfs_secpolicy_send(zfs_cmd_t *zc, cred_t *cr) 361 { 362 return (zfs_secpolicy_write_perms(zc->zc_name, 363 ZFS_DELEG_PERM_SEND, cr)); 364 } 365 366 int 367 zfs_secpolicy_share(zfs_cmd_t *zc, cred_t *cr) 368 { 369 if (!INGLOBALZONE(curproc)) 370 return (EPERM); 371 372 if (secpolicy_nfs(cr) == 0) { 373 return (0); 374 } else { 375 vnode_t *vp; 376 int error; 377 378 if ((error = lookupname(zc->zc_value, UIO_SYSSPACE, 379 NO_FOLLOW, NULL, &vp)) != 0) 380 return (error); 381 382 /* Now make sure mntpnt and dataset are ZFS */ 383 384 if (vp->v_vfsp->vfs_fstype != zfsfstype || 385 (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource), 386 zc->zc_name) != 0)) { 387 VN_RELE(vp); 388 return (EPERM); 389 } 390 391 VN_RELE(vp); 392 return (dsl_deleg_access(zc->zc_name, 393 ZFS_DELEG_PERM_SHARE, cr)); 394 } 395 } 396 397 static int 398 zfs_get_parent(const char *datasetname, char *parent, int parentsize) 399 { 400 char *cp; 401 402 /* 403 * Remove the @bla or /bla from the end of the name to get the parent. 404 */ 405 (void) strncpy(parent, datasetname, parentsize); 406 cp = strrchr(parent, '@'); 407 if (cp != NULL) { 408 cp[0] = '\0'; 409 } else { 410 cp = strrchr(parent, '/'); 411 if (cp == NULL) 412 return (ENOENT); 413 cp[0] = '\0'; 414 } 415 416 return (0); 417 } 418 419 int 420 zfs_secpolicy_destroy_perms(const char *name, cred_t *cr) 421 { 422 int error; 423 424 if ((error = zfs_secpolicy_write_perms(name, 425 ZFS_DELEG_PERM_MOUNT, cr)) != 0) 426 return (error); 427 428 return (zfs_secpolicy_write_perms(name, ZFS_DELEG_PERM_DESTROY, cr)); 429 } 430 431 static int 432 zfs_secpolicy_destroy(zfs_cmd_t *zc, cred_t *cr) 433 { 434 return (zfs_secpolicy_destroy_perms(zc->zc_name, cr)); 435 } 436 437 /* 438 * Must have sys_config privilege to check the iscsi permission 439 */ 440 /* ARGSUSED */ 441 static int 442 zfs_secpolicy_iscsi(zfs_cmd_t *zc, cred_t *cr) 443 { 444 return (secpolicy_zfs(cr)); 445 } 446 447 int 448 zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr) 449 { 450 char parentname[MAXNAMELEN]; 451 int error; 452 453 if ((error = zfs_secpolicy_write_perms(from, 454 ZFS_DELEG_PERM_RENAME, cr)) != 0) 455 return (error); 456 457 if ((error = zfs_secpolicy_write_perms(from, 458 ZFS_DELEG_PERM_MOUNT, cr)) != 0) 459 return (error); 460 461 if ((error = zfs_get_parent(to, parentname, 462 sizeof (parentname))) != 0) 463 return (error); 464 465 if ((error = zfs_secpolicy_write_perms(parentname, 466 ZFS_DELEG_PERM_CREATE, cr)) != 0) 467 return (error); 468 469 if ((error = zfs_secpolicy_write_perms(parentname, 470 ZFS_DELEG_PERM_MOUNT, cr)) != 0) 471 return (error); 472 473 return (error); 474 } 475 476 static int 477 zfs_secpolicy_rename(zfs_cmd_t *zc, cred_t *cr) 478 { 479 return (zfs_secpolicy_rename_perms(zc->zc_name, zc->zc_value, cr)); 480 } 481 482 static int 483 zfs_secpolicy_promote(zfs_cmd_t *zc, cred_t *cr) 484 { 485 char parentname[MAXNAMELEN]; 486 objset_t *clone; 487 int error; 488 489 error = zfs_secpolicy_write_perms(zc->zc_name, 490 ZFS_DELEG_PERM_PROMOTE, cr); 491 if (error) 492 return (error); 493 494 error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, 495 DS_MODE_USER | DS_MODE_READONLY, &clone); 496 497 if (error == 0) { 498 dsl_dataset_t *pclone = NULL; 499 dsl_dir_t *dd; 500 dd = clone->os->os_dsl_dataset->ds_dir; 501 502 rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER); 503 error = dsl_dataset_hold_obj(dd->dd_pool, 504 dd->dd_phys->dd_origin_obj, FTAG, &pclone); 505 rw_exit(&dd->dd_pool->dp_config_rwlock); 506 if (error) { 507 dmu_objset_close(clone); 508 return (error); 509 } 510 511 error = zfs_secpolicy_write_perms(zc->zc_name, 512 ZFS_DELEG_PERM_MOUNT, cr); 513 514 dsl_dataset_name(pclone, parentname); 515 dmu_objset_close(clone); 516 dsl_dataset_rele(pclone, FTAG); 517 if (error == 0) 518 error = zfs_secpolicy_write_perms(parentname, 519 ZFS_DELEG_PERM_PROMOTE, cr); 520 } 521 return (error); 522 } 523 524 static int 525 zfs_secpolicy_receive(zfs_cmd_t *zc, cred_t *cr) 526 { 527 int error; 528 529 if ((error = zfs_secpolicy_write_perms(zc->zc_name, 530 ZFS_DELEG_PERM_RECEIVE, cr)) != 0) 531 return (error); 532 533 if ((error = zfs_secpolicy_write_perms(zc->zc_name, 534 ZFS_DELEG_PERM_MOUNT, cr)) != 0) 535 return (error); 536 537 return (zfs_secpolicy_write_perms(zc->zc_name, 538 ZFS_DELEG_PERM_CREATE, cr)); 539 } 540 541 int 542 zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr) 543 { 544 int error; 545 546 if ((error = zfs_secpolicy_write_perms(name, 547 ZFS_DELEG_PERM_SNAPSHOT, cr)) != 0) 548 return (error); 549 550 error = zfs_secpolicy_write_perms(name, 551 ZFS_DELEG_PERM_MOUNT, cr); 552 553 return (error); 554 } 555 556 static int 557 zfs_secpolicy_snapshot(zfs_cmd_t *zc, cred_t *cr) 558 { 559 560 return (zfs_secpolicy_snapshot_perms(zc->zc_name, cr)); 561 } 562 563 static int 564 zfs_secpolicy_create(zfs_cmd_t *zc, cred_t *cr) 565 { 566 char parentname[MAXNAMELEN]; 567 int error; 568 569 if ((error = zfs_get_parent(zc->zc_name, parentname, 570 sizeof (parentname))) != 0) 571 return (error); 572 573 if (zc->zc_value[0] != '\0') { 574 if ((error = zfs_secpolicy_write_perms(zc->zc_value, 575 ZFS_DELEG_PERM_CLONE, cr)) != 0) 576 return (error); 577 } 578 579 if ((error = zfs_secpolicy_write_perms(parentname, 580 ZFS_DELEG_PERM_CREATE, cr)) != 0) 581 return (error); 582 583 error = zfs_secpolicy_write_perms(parentname, 584 ZFS_DELEG_PERM_MOUNT, cr); 585 586 return (error); 587 } 588 589 static int 590 zfs_secpolicy_umount(zfs_cmd_t *zc, cred_t *cr) 591 { 592 int error; 593 594 error = secpolicy_fs_unmount(cr, NULL); 595 if (error) { 596 error = dsl_deleg_access(zc->zc_name, ZFS_DELEG_PERM_MOUNT, cr); 597 } 598 return (error); 599 } 600 601 /* 602 * Policy for pool operations - create/destroy pools, add vdevs, etc. Requires 603 * SYS_CONFIG privilege, which is not available in a local zone. 604 */ 605 /* ARGSUSED */ 606 static int 607 zfs_secpolicy_config(zfs_cmd_t *zc, cred_t *cr) 608 { 609 if (secpolicy_sys_config(cr, B_FALSE) != 0) 610 return (EPERM); 611 612 return (0); 613 } 614 615 /* 616 * Just like zfs_secpolicy_config, except that we will check for 617 * mount permission on the dataset for permission to create/remove 618 * the minor nodes. 619 */ 620 static int 621 zfs_secpolicy_minor(zfs_cmd_t *zc, cred_t *cr) 622 { 623 if (secpolicy_sys_config(cr, B_FALSE) != 0) { 624 return (dsl_deleg_access(zc->zc_name, 625 ZFS_DELEG_PERM_MOUNT, cr)); 626 } 627 628 return (0); 629 } 630 631 /* 632 * Policy for fault injection. Requires all privileges. 633 */ 634 /* ARGSUSED */ 635 static int 636 zfs_secpolicy_inject(zfs_cmd_t *zc, cred_t *cr) 637 { 638 return (secpolicy_zinject(cr)); 639 } 640 641 static int 642 zfs_secpolicy_inherit(zfs_cmd_t *zc, cred_t *cr) 643 { 644 zfs_prop_t prop = zfs_name_to_prop(zc->zc_value); 645 646 if (prop == ZPROP_INVAL) { 647 if (!zfs_prop_user(zc->zc_value)) 648 return (EINVAL); 649 return (zfs_secpolicy_write_perms(zc->zc_name, 650 ZFS_DELEG_PERM_USERPROP, cr)); 651 } else { 652 if (!zfs_prop_inheritable(prop)) 653 return (EINVAL); 654 return (zfs_secpolicy_setprop(zc->zc_name, prop, cr)); 655 } 656 } 657 658 /* 659 * Returns the nvlist as specified by the user in the zfs_cmd_t. 660 */ 661 static int 662 get_nvlist(uint64_t nvl, uint64_t size, nvlist_t **nvp) 663 { 664 char *packed; 665 int error; 666 nvlist_t *list = NULL; 667 668 /* 669 * Read in and unpack the user-supplied nvlist. 670 */ 671 if (size == 0) 672 return (EINVAL); 673 674 packed = kmem_alloc(size, KM_SLEEP); 675 676 if ((error = xcopyin((void *)(uintptr_t)nvl, packed, size)) != 0) { 677 kmem_free(packed, size); 678 return (error); 679 } 680 681 if ((error = nvlist_unpack(packed, size, &list, 0)) != 0) { 682 kmem_free(packed, size); 683 return (error); 684 } 685 686 kmem_free(packed, size); 687 688 *nvp = list; 689 return (0); 690 } 691 692 static int 693 put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl) 694 { 695 char *packed = NULL; 696 size_t size; 697 int error; 698 699 VERIFY(nvlist_size(nvl, &size, NV_ENCODE_NATIVE) == 0); 700 701 if (size > zc->zc_nvlist_dst_size) { 702 error = ENOMEM; 703 } else { 704 packed = kmem_alloc(size, KM_SLEEP); 705 VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE, 706 KM_SLEEP) == 0); 707 error = xcopyout(packed, (void *)(uintptr_t)zc->zc_nvlist_dst, 708 size); 709 kmem_free(packed, size); 710 } 711 712 zc->zc_nvlist_dst_size = size; 713 return (error); 714 } 715 716 static int 717 zfs_ioc_pool_create(zfs_cmd_t *zc) 718 { 719 int error; 720 nvlist_t *config, *props = NULL; 721 char *buf; 722 723 if (error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size, 724 &config)) 725 return (error); 726 727 if (zc->zc_nvlist_src_size != 0 && (error = 728 get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size, &props))) { 729 nvlist_free(config); 730 return (error); 731 } 732 733 buf = history_str_get(zc); 734 735 error = spa_create(zc->zc_name, config, props, buf); 736 737 if (buf != NULL) 738 history_str_free(buf); 739 740 nvlist_free(config); 741 742 if (props) 743 nvlist_free(props); 744 745 return (error); 746 } 747 748 static int 749 zfs_ioc_pool_destroy(zfs_cmd_t *zc) 750 { 751 int error; 752 zfs_log_history(zc); 753 error = spa_destroy(zc->zc_name); 754 return (error); 755 } 756 757 static int 758 zfs_ioc_pool_import(zfs_cmd_t *zc) 759 { 760 int error; 761 nvlist_t *config, *props = NULL; 762 uint64_t guid; 763 764 if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size, 765 &config)) != 0) 766 return (error); 767 768 if (zc->zc_nvlist_src_size != 0 && (error = 769 get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size, &props))) { 770 nvlist_free(config); 771 return (error); 772 } 773 774 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) != 0 || 775 guid != zc->zc_guid) 776 error = EINVAL; 777 else if (zc->zc_cookie) 778 error = spa_import_faulted(zc->zc_name, config, 779 props); 780 else 781 error = spa_import(zc->zc_name, config, props); 782 783 nvlist_free(config); 784 785 if (props) 786 nvlist_free(props); 787 788 return (error); 789 } 790 791 static int 792 zfs_ioc_pool_export(zfs_cmd_t *zc) 793 { 794 int error; 795 zfs_log_history(zc); 796 error = spa_export(zc->zc_name, NULL); 797 return (error); 798 } 799 800 static int 801 zfs_ioc_pool_configs(zfs_cmd_t *zc) 802 { 803 nvlist_t *configs; 804 int error; 805 806 if ((configs = spa_all_configs(&zc->zc_cookie)) == NULL) 807 return (EEXIST); 808 809 error = put_nvlist(zc, configs); 810 811 nvlist_free(configs); 812 813 return (error); 814 } 815 816 static int 817 zfs_ioc_pool_stats(zfs_cmd_t *zc) 818 { 819 nvlist_t *config; 820 int error; 821 int ret = 0; 822 823 error = spa_get_stats(zc->zc_name, &config, zc->zc_value, 824 sizeof (zc->zc_value)); 825 826 if (config != NULL) { 827 ret = put_nvlist(zc, config); 828 nvlist_free(config); 829 830 /* 831 * The config may be present even if 'error' is non-zero. 832 * In this case we return success, and preserve the real errno 833 * in 'zc_cookie'. 834 */ 835 zc->zc_cookie = error; 836 } else { 837 ret = error; 838 } 839 840 return (ret); 841 } 842 843 /* 844 * Try to import the given pool, returning pool stats as appropriate so that 845 * user land knows which devices are available and overall pool health. 846 */ 847 static int 848 zfs_ioc_pool_tryimport(zfs_cmd_t *zc) 849 { 850 nvlist_t *tryconfig, *config; 851 int error; 852 853 if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size, 854 &tryconfig)) != 0) 855 return (error); 856 857 config = spa_tryimport(tryconfig); 858 859 nvlist_free(tryconfig); 860 861 if (config == NULL) 862 return (EINVAL); 863 864 error = put_nvlist(zc, config); 865 nvlist_free(config); 866 867 return (error); 868 } 869 870 static int 871 zfs_ioc_pool_scrub(zfs_cmd_t *zc) 872 { 873 spa_t *spa; 874 int error; 875 876 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 877 return (error); 878 879 mutex_enter(&spa_namespace_lock); 880 error = spa_scrub(spa, zc->zc_cookie, B_FALSE); 881 mutex_exit(&spa_namespace_lock); 882 883 spa_close(spa, FTAG); 884 885 return (error); 886 } 887 888 static int 889 zfs_ioc_pool_freeze(zfs_cmd_t *zc) 890 { 891 spa_t *spa; 892 int error; 893 894 error = spa_open(zc->zc_name, &spa, FTAG); 895 if (error == 0) { 896 spa_freeze(spa); 897 spa_close(spa, FTAG); 898 } 899 return (error); 900 } 901 902 static int 903 zfs_ioc_pool_upgrade(zfs_cmd_t *zc) 904 { 905 spa_t *spa; 906 int error; 907 908 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 909 return (error); 910 911 if (zc->zc_cookie < spa_version(spa) || zc->zc_cookie > SPA_VERSION) { 912 spa_close(spa, FTAG); 913 return (EINVAL); 914 } 915 916 spa_upgrade(spa, zc->zc_cookie); 917 spa_close(spa, FTAG); 918 919 return (error); 920 } 921 922 static int 923 zfs_ioc_pool_get_history(zfs_cmd_t *zc) 924 { 925 spa_t *spa; 926 char *hist_buf; 927 uint64_t size; 928 int error; 929 930 if ((size = zc->zc_history_len) == 0) 931 return (EINVAL); 932 933 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 934 return (error); 935 936 if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) { 937 spa_close(spa, FTAG); 938 return (ENOTSUP); 939 } 940 941 hist_buf = kmem_alloc(size, KM_SLEEP); 942 if ((error = spa_history_get(spa, &zc->zc_history_offset, 943 &zc->zc_history_len, hist_buf)) == 0) { 944 error = xcopyout(hist_buf, 945 (char *)(uintptr_t)zc->zc_history, 946 zc->zc_history_len); 947 } 948 949 spa_close(spa, FTAG); 950 kmem_free(hist_buf, size); 951 return (error); 952 } 953 954 static int 955 zfs_ioc_dsobj_to_dsname(zfs_cmd_t *zc) 956 { 957 int error; 958 959 if (error = dsl_dsobj_to_dsname(zc->zc_name, zc->zc_obj, zc->zc_value)) 960 return (error); 961 962 return (0); 963 } 964 965 static int 966 zfs_ioc_obj_to_path(zfs_cmd_t *zc) 967 { 968 objset_t *osp; 969 int error; 970 971 if ((error = dmu_objset_open(zc->zc_name, DMU_OST_ZFS, 972 DS_MODE_USER | DS_MODE_READONLY, &osp)) != 0) 973 return (error); 974 error = zfs_obj_to_path(osp, zc->zc_obj, zc->zc_value, 975 sizeof (zc->zc_value)); 976 dmu_objset_close(osp); 977 978 return (error); 979 } 980 981 static int 982 zfs_ioc_vdev_add(zfs_cmd_t *zc) 983 { 984 spa_t *spa; 985 int error; 986 nvlist_t *config, **l2cache, **spares; 987 uint_t nl2cache = 0, nspares = 0; 988 989 error = spa_open(zc->zc_name, &spa, FTAG); 990 if (error != 0) 991 return (error); 992 993 error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size, 994 &config); 995 (void) nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_L2CACHE, 996 &l2cache, &nl2cache); 997 998 (void) nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_SPARES, 999 &spares, &nspares); 1000 1001 /* 1002 * A root pool with concatenated devices is not supported. 1003 * Thus, can not add a device to a root pool. 1004 * 1005 * Intent log device can not be added to a rootpool because 1006 * during mountroot, zil is replayed, a seperated log device 1007 * can not be accessed during the mountroot time. 1008 * 1009 * l2cache and spare devices are ok to be added to a rootpool. 1010 */ 1011 if (spa->spa_bootfs != 0 && nl2cache == 0 && nspares == 0) { 1012 spa_close(spa, FTAG); 1013 return (EDOM); 1014 } 1015 1016 if (error == 0) { 1017 error = spa_vdev_add(spa, config); 1018 nvlist_free(config); 1019 } 1020 spa_close(spa, FTAG); 1021 return (error); 1022 } 1023 1024 static int 1025 zfs_ioc_vdev_remove(zfs_cmd_t *zc) 1026 { 1027 spa_t *spa; 1028 int error; 1029 1030 error = spa_open(zc->zc_name, &spa, FTAG); 1031 if (error != 0) 1032 return (error); 1033 error = spa_vdev_remove(spa, zc->zc_guid, B_FALSE); 1034 spa_close(spa, FTAG); 1035 return (error); 1036 } 1037 1038 static int 1039 zfs_ioc_vdev_set_state(zfs_cmd_t *zc) 1040 { 1041 spa_t *spa; 1042 int error; 1043 vdev_state_t newstate = VDEV_STATE_UNKNOWN; 1044 1045 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 1046 return (error); 1047 switch (zc->zc_cookie) { 1048 case VDEV_STATE_ONLINE: 1049 error = vdev_online(spa, zc->zc_guid, zc->zc_obj, &newstate); 1050 break; 1051 1052 case VDEV_STATE_OFFLINE: 1053 error = vdev_offline(spa, zc->zc_guid, zc->zc_obj); 1054 break; 1055 1056 case VDEV_STATE_FAULTED: 1057 error = vdev_fault(spa, zc->zc_guid); 1058 break; 1059 1060 case VDEV_STATE_DEGRADED: 1061 error = vdev_degrade(spa, zc->zc_guid); 1062 break; 1063 1064 default: 1065 error = EINVAL; 1066 } 1067 zc->zc_cookie = newstate; 1068 spa_close(spa, FTAG); 1069 return (error); 1070 } 1071 1072 static int 1073 zfs_ioc_vdev_attach(zfs_cmd_t *zc) 1074 { 1075 spa_t *spa; 1076 int replacing = zc->zc_cookie; 1077 nvlist_t *config; 1078 int error; 1079 1080 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 1081 return (error); 1082 1083 if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size, 1084 &config)) == 0) { 1085 error = spa_vdev_attach(spa, zc->zc_guid, config, replacing); 1086 nvlist_free(config); 1087 } 1088 1089 spa_close(spa, FTAG); 1090 return (error); 1091 } 1092 1093 static int 1094 zfs_ioc_vdev_detach(zfs_cmd_t *zc) 1095 { 1096 spa_t *spa; 1097 int error; 1098 1099 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) 1100 return (error); 1101 1102 error = spa_vdev_detach(spa, zc->zc_guid, B_FALSE); 1103 1104 spa_close(spa, FTAG); 1105 return (error); 1106 } 1107 1108 static int 1109 zfs_ioc_vdev_setpath(zfs_cmd_t *zc) 1110 { 1111 spa_t *spa; 1112 char *path = zc->zc_value; 1113 uint64_t guid = zc->zc_guid; 1114 int error; 1115 1116 error = spa_open(zc->zc_name, &spa, FTAG); 1117 if (error != 0) 1118 return (error); 1119 1120 error = spa_vdev_setpath(spa, guid, path); 1121 spa_close(spa, FTAG); 1122 return (error); 1123 } 1124 1125 /* 1126 * inputs: 1127 * zc_name name of filesystem 1128 * zc_nvlist_dst_size size of buffer for property nvlist 1129 * 1130 * outputs: 1131 * zc_objset_stats stats