Print this page
3745 zpool create should treat -O mountpoint and -m the same
Submitted by:   Will Andrews <willa@spectralogic.com>
Submitted by:   Alan Somers <alans@spectralogic.com>
Reviewed by:    Matthew Ahrens <mahrens@delphix.com>


 660                 case 'n':
 661                         dryrun = B_TRUE;
 662                         break;
 663                 case 'd':
 664                         enable_all_pool_feat = B_FALSE;
 665                         break;
 666                 case 'R':
 667                         altroot = optarg;
 668                         if (add_prop_list(zpool_prop_to_name(
 669                             ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
 670                                 goto errout;
 671                         if (nvlist_lookup_string(props,
 672                             zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
 673                             &propval) == 0)
 674                                 break;
 675                         if (add_prop_list(zpool_prop_to_name(
 676                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
 677                                 goto errout;
 678                         break;
 679                 case 'm':

 680                         mountpoint = optarg;
 681                         break;
 682                 case 'o':
 683                         if ((propval = strchr(optarg, '=')) == NULL) {
 684                                 (void) fprintf(stderr, gettext("missing "
 685                                     "'=' for -o option\n"));
 686                                 goto errout;
 687                         }
 688                         *propval = '\0';
 689                         propval++;
 690 
 691                         if (add_prop_list(optarg, propval, &props, B_TRUE))
 692                                 goto errout;
 693 
 694                         /*
 695                          * If the user is creating a pool that doesn't support
 696                          * feature flags, don't enable any features.
 697                          */
 698                         if (zpool_name_to_prop(optarg) == ZPOOL_PROP_VERSION) {
 699                                 char *end;
 700                                 u_longlong_t ver;
 701 
 702                                 ver = strtoull(propval, &end, 10);
 703                                 if (*end == '\0' &&
 704                                     ver < SPA_VERSION_FEATURES) {
 705                                         enable_all_pool_feat = B_FALSE;
 706                                 }
 707                         }
 708                         break;
 709                 case 'O':
 710                         if ((propval = strchr(optarg, '=')) == NULL) {
 711                                 (void) fprintf(stderr, gettext("missing "
 712                                     "'=' for -O option\n"));
 713                                 goto errout;
 714                         }
 715                         *propval = '\0';
 716                         propval++;
 717 








 718                         if (add_prop_list(optarg, propval, &fsprops, B_FALSE))
 719                                 goto errout;
 720                         break;
 721                 case ':':
 722                         (void) fprintf(stderr, gettext("missing argument for "
 723                             "'%c' option\n"), optopt);
 724                         goto badusage;
 725                 case '?':
 726                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
 727                             optopt);
 728                         goto badusage;
 729                 }
 730         }
 731 
 732         argc -= optind;
 733         argv += optind;
 734 
 735         /* get pool name and check number of arguments */
 736         if (argc < 1) {
 737                 (void) fprintf(stderr, gettext("missing pool name argument\n"));


 816                             "option to provide a different default\n"));
 817                         goto errout;
 818                 } else if (dirp) {
 819                         int count = 0;
 820 
 821                         while (count < 3 && readdir(dirp) != NULL)
 822                                 count++;
 823                         (void) closedir(dirp);
 824 
 825                         if (count > 2) {
 826                                 (void) fprintf(stderr, gettext("mountpoint "
 827                                     "'%s' exists and is not empty\n"), buf);
 828                                 (void) fprintf(stderr, gettext("use '-m' "
 829                                     "option to provide a "
 830                                     "different default\n"));
 831                                 goto errout;
 832                         }
 833                 }
 834         }
 835 









 836         if (dryrun) {
 837                 /*
 838                  * For a dry run invocation, print out a basic message and run
 839                  * through all the vdevs in the list and print out in an
 840                  * appropriate hierarchy.
 841                  */
 842                 (void) printf(gettext("would create '%s' with the "
 843                     "following layout:\n\n"), poolname);
 844 
 845                 print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
 846                 if (num_logs(nvroot) > 0)
 847                         print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
 848 
 849                 ret = 0;
 850         } else {
 851                 /*
 852                  * Hand off to libzfs.
 853                  */
 854                 if (enable_all_pool_feat) {
 855                         int i;


 860                                 (void) snprintf(propname, sizeof (propname),
 861                                     "feature@%s", feat->fi_uname);
 862 
 863                                 /*
 864                                  * Skip feature if user specified it manually
 865                                  * on the command line.
 866                                  */
 867                                 if (nvlist_exists(props, propname))
 868                                         continue;
 869 
 870                                 if (add_prop_list(propname, ZFS_FEATURE_ENABLED,
 871                                     &props, B_TRUE) != 0)
 872                                         goto errout;
 873                         }
 874                 }
 875                 if (zpool_create(g_zfs, poolname,
 876                     nvroot, props, fsprops) == 0) {
 877                         zfs_handle_t *pool = zfs_open(g_zfs, poolname,
 878                             ZFS_TYPE_FILESYSTEM);
 879                         if (pool != NULL) {
 880                                 if (mountpoint != NULL)
 881                                         verify(zfs_prop_set(pool,
 882                                             zfs_prop_to_name(
 883                                             ZFS_PROP_MOUNTPOINT),
 884                                             mountpoint) == 0);
 885                                 if (zfs_mount(pool, NULL, 0) == 0)
 886                                         ret = zfs_shareall(pool);
 887                                 zfs_close(pool);
 888                         }
 889                 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
 890                         (void) fprintf(stderr, gettext("pool name may have "
 891                             "been omitted\n"));
 892                 }
 893         }
 894 
 895 errout:
 896         nvlist_free(nvroot);
 897         nvlist_free(fsprops);
 898         nvlist_free(props);
 899         return (ret);
 900 badusage:
 901         nvlist_free(fsprops);
 902         nvlist_free(props);
 903         usage(B_FALSE);
 904         return (2);




 660                 case 'n':
 661                         dryrun = B_TRUE;
 662                         break;
 663                 case 'd':
 664                         enable_all_pool_feat = B_FALSE;
 665                         break;
 666                 case 'R':
 667                         altroot = optarg;
 668                         if (add_prop_list(zpool_prop_to_name(
 669                             ZPOOL_PROP_ALTROOT), optarg, &props, B_TRUE))
 670                                 goto errout;
 671                         if (nvlist_lookup_string(props,
 672                             zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
 673                             &propval) == 0)
 674                                 break;
 675                         if (add_prop_list(zpool_prop_to_name(
 676                             ZPOOL_PROP_CACHEFILE), "none", &props, B_TRUE))
 677                                 goto errout;
 678                         break;
 679                 case 'm':
 680                         /* Equivalent to -O mountpoint=optarg */
 681                         mountpoint = optarg;
 682                         break;
 683                 case 'o':
 684                         if ((propval = strchr(optarg, '=')) == NULL) {
 685                                 (void) fprintf(stderr, gettext("missing "
 686                                     "'=' for -o option\n"));
 687                                 goto errout;
 688                         }
 689                         *propval = '\0';
 690                         propval++;
 691 
 692                         if (add_prop_list(optarg, propval, &props, B_TRUE))
 693                                 goto errout;
 694 
 695                         /*
 696                          * If the user is creating a pool that doesn't support
 697                          * feature flags, don't enable any features.
 698                          */
 699                         if (zpool_name_to_prop(optarg) == ZPOOL_PROP_VERSION) {
 700                                 char *end;
 701                                 u_longlong_t ver;
 702 
 703                                 ver = strtoull(propval, &end, 10);
 704                                 if (*end == '\0' &&
 705                                     ver < SPA_VERSION_FEATURES) {
 706                                         enable_all_pool_feat = B_FALSE;
 707                                 }
 708                         }
 709                         break;
 710                 case 'O':
 711                         if ((propval = strchr(optarg, '=')) == NULL) {
 712                                 (void) fprintf(stderr, gettext("missing "
 713                                     "'=' for -O option\n"));
 714                                 goto errout;
 715                         }
 716                         *propval = '\0';
 717                         propval++;
 718 
 719                         /*
 720                          * Mountpoints are checked and then added later.
 721                          * Uniquely among properties, they can be specified
 722                          * more than once, to avoid conflict with -m.
 723                          */
 724                         if (!strcmp(optarg,
 725                             zfs_prop_to_name(ZFS_PROP_MOUNTPOINT)))
 726                                 mountpoint = propval;
 727                         if (add_prop_list(optarg, propval, &fsprops, B_FALSE))
 728                                 goto errout;
 729                         break;
 730                 case ':':
 731                         (void) fprintf(stderr, gettext("missing argument for "
 732                             "'%c' option\n"), optopt);
 733                         goto badusage;
 734                 case '?':
 735                         (void) fprintf(stderr, gettext("invalid option '%c'\n"),
 736                             optopt);
 737                         goto badusage;
 738                 }
 739         }
 740 
 741         argc -= optind;
 742         argv += optind;
 743 
 744         /* get pool name and check number of arguments */
 745         if (argc < 1) {
 746                 (void) fprintf(stderr, gettext("missing pool name argument\n"));


 825                             "option to provide a different default\n"));
 826                         goto errout;
 827                 } else if (dirp) {
 828                         int count = 0;
 829 
 830                         while (count < 3 && readdir(dirp) != NULL)
 831                                 count++;
 832                         (void) closedir(dirp);
 833 
 834                         if (count > 2) {
 835                                 (void) fprintf(stderr, gettext("mountpoint "
 836                                     "'%s' exists and is not empty\n"), buf);
 837                                 (void) fprintf(stderr, gettext("use '-m' "
 838                                     "option to provide a "
 839                                     "different default\n"));
 840                                 goto errout;
 841                         }
 842                 }
 843         }
 844 
 845         /*
 846          * Now that the mountpoint's validity has been checked, ensure that
 847          * the property is set appropriately prior to creating the pool.
 848          */
 849         if (mountpoint != NULL)
 850                 if (add_prop_list(zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
 851                     mountpoint, &fsprops, B_FALSE))
 852                         goto errout;
 853 
 854         if (dryrun) {
 855                 /*
 856                  * For a dry run invocation, print out a basic message and run
 857                  * through all the vdevs in the list and print out in an
 858                  * appropriate hierarchy.
 859                  */
 860                 (void) printf(gettext("would create '%s' with the "
 861                     "following layout:\n\n"), poolname);
 862 
 863                 print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
 864                 if (num_logs(nvroot) > 0)
 865                         print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
 866 
 867                 ret = 0;
 868         } else {
 869                 /*
 870                  * Hand off to libzfs.
 871                  */
 872                 if (enable_all_pool_feat) {
 873                         int i;


 878                                 (void) snprintf(propname, sizeof (propname),
 879                                     "feature@%s", feat->fi_uname);
 880 
 881                                 /*
 882                                  * Skip feature if user specified it manually
 883                                  * on the command line.
 884                                  */
 885                                 if (nvlist_exists(props, propname))
 886                                         continue;
 887 
 888                                 if (add_prop_list(propname, ZFS_FEATURE_ENABLED,
 889                                     &props, B_TRUE) != 0)
 890                                         goto errout;
 891                         }
 892                 }
 893                 if (zpool_create(g_zfs, poolname,
 894                     nvroot, props, fsprops) == 0) {
 895                         zfs_handle_t *pool = zfs_open(g_zfs, poolname,
 896                             ZFS_TYPE_FILESYSTEM);
 897                         if (pool != NULL) {





 898                                 if (zfs_mount(pool, NULL, 0) == 0)
 899                                         ret = zfs_shareall(pool);
 900                                 zfs_close(pool);
 901                         }
 902                 } else if (libzfs_errno(g_zfs) == EZFS_INVALIDNAME) {
 903                         (void) fprintf(stderr, gettext("pool name may have "
 904                             "been omitted\n"));
 905                 }
 906         }
 907 
 908 errout:
 909         nvlist_free(nvroot);
 910         nvlist_free(fsprops);
 911         nvlist_free(props);
 912         return (ret);
 913 badusage:
 914         nvlist_free(fsprops);
 915         nvlist_free(props);
 916         usage(B_FALSE);
 917         return (2);