22
22
/*
23
23
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24
24
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
25
- * Copyright (c) 2013 by Delphix. All rights reserved.
25
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
26
26
* Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved.
27
27
* Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
28
28
* Copyright (c) 2013 Martin Matuska. All rights reserved.
@@ -865,7 +865,8 @@ zfs_which_resv_prop(zfs_handle_t *zhp, zfs_prop_t *resv_prop)
865
865
*/
866
866
nvlist_t *
867
867
zfs_valid_proplist (libzfs_handle_t * hdl , zfs_type_t type , nvlist_t * nvl ,
868
- uint64_t zoned , zfs_handle_t * zhp , const char * errbuf )
868
+ uint64_t zoned , zfs_handle_t * zhp , zpool_handle_t * zpool_hdl ,
869
+ const char * errbuf )
869
870
{
870
871
nvpair_t * elem ;
871
872
uint64_t intval ;
@@ -1061,8 +1062,8 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
1061
1062
int maxbs = SPA_MAXBLOCKSIZE ;
1062
1063
char buf [64 ];
1063
1064
1064
- if (zhp != NULL ) {
1065
- maxbs = zpool_get_prop_int (zhp -> zpool_hdl ,
1065
+ if (zpool_hdl != NULL ) {
1066
+ maxbs = zpool_get_prop_int (zpool_hdl ,
1066
1067
ZPOOL_PROP_MAXBLOCKSIZE , NULL );
1067
1068
}
1068
1069
/*
@@ -1581,7 +1582,8 @@ zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props)
1581
1582
zhp -> zfs_name );
1582
1583
1583
1584
if ((nvl = zfs_valid_proplist (hdl , zhp -> zfs_type , props ,
1584
- zfs_prop_get_int (zhp , ZFS_PROP_ZONED ), zhp , errbuf )) == NULL )
1585
+ zfs_prop_get_int (zhp , ZFS_PROP_ZONED ), zhp , zhp -> zpool_hdl ,
1586
+ errbuf )) == NULL )
1585
1587
goto error ;
1586
1588
1587
1589
/*
@@ -3241,9 +3243,23 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
3241
3243
else
3242
3244
ost = DMU_OST_ZFS ;
3243
3245
3246
+ /* open zpool handle for prop validation */
3247
+ char pool_path [MAXNAMELEN ];
3248
+ (void ) strlcpy (pool_path , path , sizeof (pool_path ));
3249
+
3250
+ /* truncate pool_path at first slash */
3251
+ char * p = strchr (pool_path , '/' );
3252
+ if (p != NULL )
3253
+ * p = '\0' ;
3254
+
3255
+ zpool_handle_t * zpool_handle = zpool_open (hdl , pool_path );
3256
+
3244
3257
if (props && (props = zfs_valid_proplist (hdl , type , props ,
3245
- zoned , NULL , errbuf )) == 0 )
3258
+ zoned , NULL , zpool_handle , errbuf )) == 0 ) {
3259
+ zpool_close (zpool_handle );
3246
3260
return (-1 );
3261
+ }
3262
+ zpool_close (zpool_handle );
3247
3263
3248
3264
if (type == ZFS_TYPE_VOLUME ) {
3249
3265
/*
@@ -3298,8 +3314,6 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
3298
3314
/* check for failure */
3299
3315
if (ret != 0 ) {
3300
3316
char parent [ZFS_MAXNAMELEN ];
3301
- char buf [64 ];
3302
-
3303
3317
(void ) parent_name (path , parent , sizeof (parent ));
3304
3318
3305
3319
switch (errno ) {
@@ -3313,14 +3327,6 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
3313
3327
"parent '%s' is not a filesystem" ), parent );
3314
3328
return (zfs_error (hdl , EZFS_BADTYPE , errbuf ));
3315
3329
3316
- case EDOM :
3317
- zfs_nicenum (SPA_MAXBLOCKSIZE , buf , sizeof (buf ));
3318
- zfs_error_aux (hdl , dgettext (TEXT_DOMAIN ,
3319
- "volume block size must be power of 2 from "
3320
- "512B to %s" ), buf );
3321
-
3322
- return (zfs_error (hdl , EZFS_BADPROP , errbuf ));
3323
-
3324
3330
case ENOTSUP :
3325
3331
zfs_error_aux (hdl , dgettext (TEXT_DOMAIN ,
3326
3332
"pool must be upgraded to set this "
@@ -3516,7 +3522,7 @@ zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
3516
3522
type = ZFS_TYPE_FILESYSTEM ;
3517
3523
}
3518
3524
if ((props = zfs_valid_proplist (hdl , type , props , zoned ,
3519
- zhp , errbuf )) == NULL )
3525
+ zhp , zhp -> zpool_hdl , errbuf )) == NULL )
3520
3526
return (-1 );
3521
3527
}
3522
3528
@@ -3660,11 +3666,23 @@ zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, nvlist_t *props)
3660
3666
}
3661
3667
}
3662
3668
3669
+ /*
3670
+ * get pool handle for prop validation. assumes all snaps are in the
3671
+ * same pool, as does lzc_snapshot (below).
3672
+ */
3673
+ char pool [MAXNAMELEN ];
3674
+ elem = nvlist_next_nvpair (snaps , NULL );
3675
+ (void ) strlcpy (pool , nvpair_name (elem ), sizeof (pool ));
3676
+ pool [strcspn (pool , "/@" )] = '\0' ;
3677
+ zpool_handle_t * zpool_hdl = zpool_open (hdl , pool );
3678
+
3663
3679
if (props != NULL &&
3664
3680
(props = zfs_valid_proplist (hdl , ZFS_TYPE_SNAPSHOT ,
3665
- props , B_FALSE , NULL , errbuf )) == NULL ) {
3681
+ props , B_FALSE , NULL , zpool_hdl , errbuf )) == NULL ) {
3682
+ zpool_close (zpool_hdl );
3666
3683
return (-1 );
3667
3684
}
3685
+ zpool_close (zpool_hdl );
3668
3686
3669
3687
ret = lzc_snapshot (snaps , props , & errors );
3670
3688
0 commit comments