From 1c10ae76c0cb31326c320e7cef1d3f24a1f47125 Mon Sep 17 00:00:00 2001 From: Mike Gerdts Date: Tue, 13 Mar 2018 16:07:01 +0000 Subject: [PATCH] 9286 want refreservation=auto Reviewed by: Allan Jude Reviewed by: Matthew Ahrens Reviewed by: John Kennedy Reviewed by: Andy Stormont Approved by: Richard Lowe --- usr/src/lib/libzfs/common/libzfs_dataset.c | 80 ++++++++++++++++++++- usr/src/lib/libzfs/common/libzfs_util.c | 33 ++++++++- usr/src/man/man1m/zfs.1m | 44 ++++++++++-- usr/src/pkg/manifests/system-test-zfstest.mf | 9 +++ usr/src/test/zfs-tests/runfiles/delphix.run | 5 +- usr/src/test/zfs-tests/runfiles/omnios.run | 5 +- usr/src/test/zfs-tests/runfiles/openindiana.run | 5 +- .../functional/reservation/reservation_019_pos.sh | 65 +++++++++++++++++ .../functional/reservation/reservation_020_pos.sh | 66 +++++++++++++++++ .../functional/reservation/reservation_021_neg.sh | 74 +++++++++++++++++++ .../functional/reservation/reservation_022_pos.sh | 84 ++++++++++++++++++++++ 11 files changed, 457 insertions(+), 13 deletions(-) create mode 100644 usr/src/test/zfs-tests/tests/functional/reservation/reservation_019_pos.sh create mode 100644 usr/src/test/zfs-tests/tests/functional/reservation/reservation_020_pos.sh create mode 100644 usr/src/test/zfs-tests/tests/functional/reservation/reservation_021_neg.sh create mode 100644 usr/src/test/zfs-tests/tests/functional/reservation/reservation_022_pos.sh diff --git a/usr/src/lib/libzfs/common/libzfs_dataset.c b/usr/src/lib/libzfs/common/libzfs_dataset.c index 23e689cb9f..011c2653a1 100644 --- a/usr/src/lib/libzfs/common/libzfs_dataset.c +++ b/usr/src/lib/libzfs/common/libzfs_dataset.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright (c) 2018, Joyent, Inc. All rights reserved. * Copyright (c) 2011, 2016 by Delphix. All rights reserved. * Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved. * Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved. @@ -1387,7 +1387,6 @@ badlabel: switch (prop) { case ZFS_PROP_RESERVATION: - case ZFS_PROP_REFRESERVATION: if (intval > volsize) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' is greater than current " @@ -1398,6 +1397,17 @@ badlabel: } break; + case ZFS_PROP_REFRESERVATION: + if (intval > volsize && intval != UINT64_MAX) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "'%s' is greater than current " + "volume size"), propname); + (void) zfs_error(hdl, EZFS_BADPROP, + errbuf); + goto error; + } + break; + case ZFS_PROP_VOLSIZE: if (intval % blocksize != 0) { zfs_nicenum(blocksize, buf, @@ -1499,6 +1509,61 @@ zfs_add_synthetic_resv(zfs_handle_t *zhp, nvlist_t *nvl) return (1); } +/* + * Helper for 'zfs {set|clone} refreservation=auto'. Must be called after + * zfs_valid_proplist(), as it is what sets the UINT64_MAX sentinal value. + * Return codes must match zfs_add_synthetic_resv(). + */ +static int +zfs_fix_auto_resv(zfs_handle_t *zhp, nvlist_t *nvl) +{ + uint64_t volsize; + uint64_t resvsize; + zfs_prop_t prop; + nvlist_t *props; + + if (!ZFS_IS_VOLUME(zhp)) { + return (0); + } + + if (zfs_which_resv_prop(zhp, &prop) != 0) { + return (-1); + } + + if (prop != ZFS_PROP_REFRESERVATION) { + return (0); + } + + if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(prop), &resvsize) != 0) { + /* No value being set, so it can't be "auto" */ + return (0); + } + if (resvsize != UINT64_MAX) { + /* Being set to a value other than "auto" */ + return (0); + } + + props = fnvlist_alloc(); + + fnvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), + zfs_prop_get_int(zhp, ZFS_PROP_VOLBLOCKSIZE)); + + if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(ZFS_PROP_VOLSIZE), + &volsize) != 0) { + volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE); + } + + resvsize = zvol_volsize_to_reservation(volsize, props); + fnvlist_free(props); + + (void) nvlist_remove_all(nvl, zfs_prop_to_name(prop)); + if (nvlist_add_uint64(nvl, zfs_prop_to_name(prop), resvsize) != 0) { + (void) no_memory(zhp->zfs_hdl); + return (-1); + } + return (1); +} + void zfs_setprop_error(libzfs_handle_t *hdl, zfs_prop_t prop, int err, char *errbuf) @@ -1664,6 +1729,12 @@ zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props) goto error; } } + + if (added_resv != 1 && + (added_resv = zfs_fix_auto_resv(zhp, nvl)) == -1) { + goto error; + } + /* * Check how many properties we're setting and allocate an array to * store changelist pointers for postfix(). @@ -3666,6 +3737,7 @@ zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props) if (props) { zfs_type_t type; + if (ZFS_IS_VOLUME(zhp)) { type = ZFS_TYPE_VOLUME; } else { @@ -3674,6 +3746,10 @@ zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props) if ((props = zfs_valid_proplist(hdl, type, props, zoned, zhp, zhp->zpool_hdl, errbuf)) == NULL) return (-1); + if (zfs_fix_auto_resv(zhp, props) == -1) { + nvlist_free(props); + return (-1); + } } ret = lzc_clone(target, zhp->zfs_name, props); diff --git a/usr/src/lib/libzfs/common/libzfs_util.c b/usr/src/lib/libzfs/common/libzfs_util.c index c73485acfe..3cf83eee9e 100644 --- a/usr/src/lib/libzfs/common/libzfs_util.c +++ b/usr/src/lib/libzfs/common/libzfs_util.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright (c) 2018 Joyent, Inc. * Copyright (c) 2011, 2017 by Delphix. All rights reserved. * Copyright 2016 Igor Kozhukhov * Copyright (c) 2017 Datto Inc. @@ -1184,6 +1184,7 @@ zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop, const char *propname; char *value; boolean_t isnone = B_FALSE; + boolean_t isauto = B_FALSE; if (type == ZFS_TYPE_POOL) { proptype = zpool_prop_get_type(prop); @@ -1219,8 +1220,9 @@ zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop, (void) nvpair_value_string(elem, &value); if (strcmp(value, "none") == 0) { isnone = B_TRUE; - } else if (zfs_nicestrtonum(hdl, value, ivalp) - != 0) { + } else if (strcmp(value, "auto") == 0) { + isauto = B_TRUE; + } else if (zfs_nicestrtonum(hdl, value, ivalp) != 0) { goto error; } } else if (datatype == DATA_TYPE_UINT64) { @@ -1250,6 +1252,31 @@ zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop, prop == ZFS_PROP_SNAPSHOT_LIMIT)) { *ivalp = UINT64_MAX; } + + /* + * Special handling for setting 'refreservation' to 'auto'. Use + * UINT64_MAX to tell the caller to use zfs_fix_auto_resv(). + * 'auto' is only allowed on volumes. + */ + if (isauto) { + switch (prop) { + case ZFS_PROP_REFRESERVATION: + if ((type & ZFS_TYPE_VOLUME) == 0) { + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "'%s=auto' only allowed on " + "volumes"), nvpair_name(elem)); + goto error; + } + *ivalp = UINT64_MAX; + break; + default: + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "'auto' is invalid value for '%s'"), + nvpair_name(elem)); + goto error; + } + } + break; case PROP_TYPE_INDEX: diff --git a/usr/src/man/man1m/zfs.1m b/usr/src/man/man1m/zfs.1m index 6d5ca9efff..c24db19a2d 100644 --- a/usr/src/man/man1m/zfs.1m +++ b/usr/src/man/man1m/zfs.1m @@ -27,6 +27,7 @@ .\" Copyright (c) 2014 by Adam Stevko. All rights reserved. .\" Copyright (c) 2014 Integros [integros.com] .\" Copyright 2017 Nexenta Systems, Inc. +.\" Copyright 2018 Joyent, Inc. .\" .Dd December 6, 2017 .Dt ZFS 1M @@ -1345,7 +1346,7 @@ Limits the amount of space a dataset can consume. This property enforces a hard limit on the amount of space used. This hard limit does not include space used by descendents, including file systems and snapshots. -.It Sy refreservation Ns = Ns Em size Ns | Ns Sy none +.It Sy refreservation Ns = Ns Em size Ns | Ns Sy none Ns | Ns Sy auto The minimum amount of space guaranteed to a dataset, not including its descendents. When the amount of space used is below this value, the dataset is treated as if @@ -1363,6 +1364,22 @@ this reservation to accommodate the current number of .Qq referenced bytes in the dataset. .Pp +If +.Sy refreservation +is set to +.Sy auto , +a volume is thick provisioned +.Po or +.Qq not sparse +.Pc . +.Sy refreservation Ns = Ns Sy auto +is only supported on volumes. +See +.Sy volsize +in the +.Sx Native Properties +section for more information about sparse volumes. +.Pp This property can also be referred to by its shortened column name, .Sy refreserv . .It Sy reservation Ns = Ns Em size Ns | Ns Sy none @@ -1577,22 +1594,39 @@ Extreme care should be used when adjusting the volume size. Though not recommended, a .Qq sparse volume .Po also known as -.Qq thin provisioning +.Qq thin provisioned .Pc can be created by specifying the .Fl s option to the .Nm zfs Cm create Fl V -command, or by changing the reservation after the volume has been created. +command, or by changing the value of the +.Sy refreservation +property +.Po or +.Sy reservation +property on pool version 8 or earlier +.Pc +after the volume has been created. A .Qq sparse volume -is a volume where the reservation is less then the volume size. +is a volume where the value of +.Sy refreservation +is less than the size of the volume plus the space required to store its +metadata. Consequently, writes to a sparse volume can fail with .Er ENOSPC when the pool is low on space. For a sparse volume, changes to .Sy volsize -are not reflected in the reservation. +are not reflected in the +.Sy refreservation. +A volume that is not sparse is said to be +.Qq thick provisioned . +A sparse volume can become thick provisioned by setting +.Sy refreservation +to +.Sy auto . .It Sy vscan Ns = Ns Sy on Ns | Ns Sy off Controls whether regular files should be scanned for viruses when a file is opened and closed. diff --git a/usr/src/pkg/manifests/system-test-zfstest.mf b/usr/src/pkg/manifests/system-test-zfstest.mf index 87ed0ee18b..faf818c66f 100644 --- a/usr/src/pkg/manifests/system-test-zfstest.mf +++ b/usr/src/pkg/manifests/system-test-zfstest.mf @@ -13,6 +13,7 @@ # Copyright (c) 2012, 2017 by Delphix. All rights reserved. # Copyright 2015, 2016 Nexenta Systems, Inc. All rights reserved. # Copyright 2016, OmniTI Computer Consulting, Inc. All rights reserved. +# Copyright 2018 Joyent, Inc. # set name=pkg.fmri value=pkg:/system/test/zfstest@$(PKGVERS) @@ -2397,6 +2398,14 @@ file path=opt/zfs-tests/tests/functional/reservation/reservation_017_pos \ mode=0555 file path=opt/zfs-tests/tests/functional/reservation/reservation_018_pos \ mode=0555 +file path=opt/zfs-tests/tests/functional/reservation/reservation_019_pos \ + mode=0555 +file path=opt/zfs-tests/tests/functional/reservation/reservation_020_pos \ + mode=0555 +file path=opt/zfs-tests/tests/functional/reservation/reservation_021_neg \ + mode=0555 +file path=opt/zfs-tests/tests/functional/reservation/reservation_022_pos \ + mode=0555 file path=opt/zfs-tests/tests/functional/reservation/setup mode=0555 file path=opt/zfs-tests/tests/functional/rootpool/cleanup mode=0555 file path=opt/zfs-tests/tests/functional/rootpool/rootpool_002_neg mode=0555 diff --git a/usr/src/test/zfs-tests/runfiles/delphix.run b/usr/src/test/zfs-tests/runfiles/delphix.run index ef84f99f68..ff77d8f1f2 100644 --- a/usr/src/test/zfs-tests/runfiles/delphix.run +++ b/usr/src/test/zfs-tests/runfiles/delphix.run @@ -12,6 +12,7 @@ # # Copyright (c) 2012, 2018 by Delphix. All rights reserved. # Copyright 2016, OmniTI Computer Consulting, Inc. All rights reserved. +# Copyright 2018 Joyent, Inc. # [DEFAULT] @@ -515,7 +516,9 @@ tests = ['reservation_001_pos', 'reservation_002_pos', 'reservation_003_pos', 'reservation_007_pos', 'reservation_008_pos', 'reservation_009_pos', 'reservation_010_pos', 'reservation_011_pos', 'reservation_012_pos', 'reservation_013_pos', 'reservation_014_pos', 'reservation_015_pos', - 'reservation_016_pos', 'reservation_017_pos', 'reservation_018_pos'] + 'reservation_016_pos', 'reservation_017_pos', 'reservation_018_pos', + 'reservation_019_pos', 'reservation_020_pos', 'reservation_021_neg', + 'reservation_022_pos'] [/opt/zfs-tests/tests/functional/rootpool] tests = ['rootpool_002_neg', 'rootpool_003_neg', 'rootpool_007_pos'] diff --git a/usr/src/test/zfs-tests/runfiles/omnios.run b/usr/src/test/zfs-tests/runfiles/omnios.run index 030f4ffa54..ebf446f61a 100644 --- a/usr/src/test/zfs-tests/runfiles/omnios.run +++ b/usr/src/test/zfs-tests/runfiles/omnios.run @@ -12,6 +12,7 @@ # # Copyright (c) 2013, 2017 by Delphix. All rights reserved. # Copyright 2016, OmniTI Computer Consulting, Inc. All rights reserved. +# Copyright 2018 Joyent, Inc. # [DEFAULT] @@ -484,7 +485,9 @@ tests = ['reservation_001_pos', 'reservation_002_pos', 'reservation_003_pos', 'reservation_007_pos', 'reservation_008_pos', 'reservation_009_pos', 'reservation_010_pos', 'reservation_011_pos', 'reservation_012_pos', 'reservation_013_pos', 'reservation_014_pos', 'reservation_015_pos', - 'reservation_016_pos', 'reservation_017_pos', 'reservation_018_pos'] + 'reservation_016_pos', 'reservation_017_pos', 'reservation_018_pos', + 'reservation_019_pos', 'reservation_020_pos', 'reservation_021_neg', + 'reservation_022_pos'] [/opt/zfs-tests/tests/functional/rootpool] tests = ['rootpool_002_neg', 'rootpool_003_neg', 'rootpool_007_pos'] diff --git a/usr/src/test/zfs-tests/runfiles/openindiana.run b/usr/src/test/zfs-tests/runfiles/openindiana.run index 40f5008319..2d8af0bf69 100644 --- a/usr/src/test/zfs-tests/runfiles/openindiana.run +++ b/usr/src/test/zfs-tests/runfiles/openindiana.run @@ -12,6 +12,7 @@ # # Copyright (c) 2012, 2017 by Delphix. All rights reserved. # Copyright 2016, OmniTI Computer Consulting, Inc. All rights reserved. +# Copyright 2018 Joyent, Inc. # [DEFAULT] @@ -484,7 +485,9 @@ tests = ['reservation_001_pos', 'reservation_002_pos', 'reservation_003_pos', 'reservation_007_pos', 'reservation_008_pos', 'reservation_009_pos', 'reservation_010_pos', 'reservation_011_pos', 'reservation_012_pos', 'reservation_013_pos', 'reservation_014_pos', 'reservation_015_pos', - 'reservation_016_pos', 'reservation_017_pos', 'reservation_018_pos'] + 'reservation_016_pos', 'reservation_017_pos', 'reservation_018_pos', + 'reservation_019_pos', 'reservation_020_pos', 'reservation_021_neg', + 'reservation_022_pos'] [/opt/zfs-tests/tests/functional/rootpool] tests = ['rootpool_002_neg', 'rootpool_003_neg', 'rootpool_007_pos'] diff --git a/usr/src/test/zfs-tests/tests/functional/reservation/reservation_019_pos.sh b/usr/src/test/zfs-tests/tests/functional/reservation/reservation_019_pos.sh new file mode 100644 index 0000000000..5c63d63a82 --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/reservation/reservation_019_pos.sh @@ -0,0 +1,65 @@ +#!/usr/bin/bash -p +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018 Joyent, Inc. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# A thin provisioned volume can become thick provisioned with 'zfs set +# refreservation=auto'. +# +# STRATEGY: +# 1) Create a sparse value. +# 2) Use zfs set refreservation=auto to make it thick provisioned. +# 3) Verify that refreservation is now the size predicted by +# volsize_to_reservation(). +# + +verify_runnable "global" + +function cleanup +{ + if datasetexists $TESTPOOL/$TESTVOL; then + log_must zfs destroy -f $TESTPOOL/$TESTVOL + fi +} + +log_onexit cleanup + +log_assert "A thin provisioned volume can become thick provisioned with" \ + "'zfs set refreservation=auto'." + +space_avail=$(get_prop available $TESTPOOL) +(( vol_size = (space_avail / 2) & ~(1024 * 1024 - 1) )) + +vol=$TESTPOOL/$TESTVOL + +# Create sparse vol and verify +log_must zfs create -V $vol_size -s $vol +resv=$(get_prop refreservation $vol) +log_must test $resv -eq 0 + +# Set refreservation +log_must zfs set refreservation=auto $vol + +# Verify +resv=$(get_prop refreservation $vol) +expected=$(volsize_to_reservation $vol $vol_size) +log_must test $resv -eq $expected + +log_pass "Setting refreservation=auto set refreservation to expected value" diff --git a/usr/src/test/zfs-tests/tests/functional/reservation/reservation_020_pos.sh b/usr/src/test/zfs-tests/tests/functional/reservation/reservation_020_pos.sh new file mode 100644 index 0000000000..554f496b07 --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/reservation/reservation_020_pos.sh @@ -0,0 +1,66 @@ +#!/usr/bin/bash -p +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018 Joyent, Inc. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# Cloning a thick provisioned volume results in a sparse volume +# +# STRATEGY: +# 1) Create a thick provisioned volume. +# 2) Snapshot and clone it. +# 3) Verify that the clone is sparse. +# + +verify_runnable "global" + +function cleanup +{ + if datasetexists $TESTPOOL/$TESTVOL; then + # Destroy first vol and descendants in one go. + log_must zfs destroy -Rf $TESTPOOL/$TESTVOL + fi +} + +log_onexit cleanup + +log_assert "Cloning a thick provisioned volume results in a sparse volume" + +space_avail=$(get_prop available $TESTPOOL) +(( vol_size = (space_avail / 4) & ~(1024 * 1024 - 1) )) + +vol=$TESTPOOL/$TESTVOL +snap=$vol@clone +vol2=$TESTPOOL/$TESTVOL2 + +# Create sparse vol and verify +log_must zfs create -V $vol_size $vol +resv=$(get_prop refreservation $vol) +expected=$(volsize_to_reservation $vol $vol_size) +log_must test $resv -eq $expected + +# Clone it +log_must zfs snapshot $snap +log_must zfs clone $snap $vol2 + +# Verify +resv=$(get_prop refreservation $vol2) +log_must test $resv -eq 0 + +log_pass "Cloning a thick provisioned volume results in a sparse volume" diff --git a/usr/src/test/zfs-tests/tests/functional/reservation/reservation_021_neg.sh b/usr/src/test/zfs-tests/tests/functional/reservation/reservation_021_neg.sh new file mode 100644 index 0000000000..249cb6e2ae --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/reservation/reservation_021_neg.sh @@ -0,0 +1,74 @@ +#!/usr/bin/bash -p +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018 Joyent, Inc. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# The use of refreservation=auto on a filesystem does not change the +# refreservation and results in an error. +# +# STRATEGY: +# 1) Create a filesystem +# 2) Verify that zfs set refreservation=auto fails without changing +# refreservation from none. +# 3) Set refreservation to a valid value. +# 4) Verify that zfs set refreservation=auto fails without changing +# refreservation from the previous value. +# + +verify_runnable "both" + +fs=$TESTPOOL/$TESTFS/$(basename $0).$$ + +function cleanup +{ + if datasetexists "$fs"; then + log_must zfs destroy -f "$fs" + fi +} + +log_onexit cleanup + +log_assert "refreservation=auto on a filesystem generates an error without" \ + "changing refreservation" + +space_avail=$(get_prop available $TESTPOOL) +(( fs_size = space_avail / 4 )) + +# Create a filesystem with no refreservation +log_must zfs create $fs +resv=$(get_prop refreservation $fs) +log_must test $resv -eq 0 + +# Verify that refreservation=auto fails without altering refreservation +log_mustnot zfs set refreservation=auto $fs +resv=$(get_prop refreservation $fs) +log_must test $resv -eq 0 + +# Set refreservation and verify +log_must zfs set refreservation=$fs_size $fs +resv=$(get_prop refreservation $fs) +log_must test $resv -eq $fs_size + +# Verify that refreservation=auto fails without altering refreservation +log_mustnot zfs set refreservation=auto $fs +resv=$(get_prop refreservation $fs) +log_must test $resv -eq $fs_size + +log_pass "refreservation=auto does not work on filesystems, as expected" diff --git a/usr/src/test/zfs-tests/tests/functional/reservation/reservation_022_pos.sh b/usr/src/test/zfs-tests/tests/functional/reservation/reservation_022_pos.sh new file mode 100644 index 0000000000..7909d0e794 --- /dev/null +++ b/usr/src/test/zfs-tests/tests/functional/reservation/reservation_022_pos.sh @@ -0,0 +1,84 @@ +#!/usr/bin/bash -p +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018 Joyent, Inc. +# + +. $STF_SUITE/include/libtest.shlib +. $STF_SUITE/tests/functional/reservation/reservation.shlib + +# +# DESCRIPTION: +# +# Cloning a volume with -o refreservation=auto creates a thick provisioned +# volume +# +# STRATEGY: +# 1) Create a sparse volume. +# 2) Snapshot and clone it, using clone -o refreservation=auto. +# 3) Verify that the clone has refreservation that matches the size predicted by +# volsize_to_reservation(). +# 4) Snapshot this second volume and clone it, using clone -o +# refreservation=auto. +# 5) Verify that the second clone has refreservation that matches the size +# predicted by volsize_to_reservation(). +# + +verify_runnable "global" + +function cleanup +{ + if datasetexists $TESTPOOL/$TESTVOL; then + # Destroy first vol and descendants in one go. + log_must zfs destroy -Rf $TESTPOOL/$TESTVOL + fi +} + +log_onexit cleanup + +log_assert "Cloning a volume with -o refreservation=auto creates a thick" \ + "provisioned volume" + +space_avail=$(get_prop available $TESTPOOL) +(( vol_size = (space_avail / 4) & ~(1024 * 1024 - 1) )) + +vol=$TESTPOOL/$TESTVOL +vol2=$TESTPOOL/$TESTVOL2 +vol3=$TESTPOOL/$TESTVOL2-again + +# Create sparse vol and verify +log_must zfs create -s -V $vol_size $vol +resv=$(get_prop refreservation $vol) +log_must test $resv -eq 0 + +# Clone it +snap=$vol@clone +log_must zfs snapshot $snap +log_must zfs clone -o refreservation=auto $snap $vol2 + +# Verify it is thick provisioned +resv=$(get_prop refreservation $vol2) +expected=$(volsize_to_reservation $vol2 $vol_size) +log_must test $resv -eq $expected + +# Clone the thick provisioned volume +snap=$vol2@clone +log_must zfs snapshot $snap +log_must zfs clone -o refreservation=auto $snap $vol3 + +# Verify new newest clone is also thick provisioned +resv=$(get_prop refreservation $vol3) +expected=$(volsize_to_reservation $vol3 $vol_size) +log_must test $resv -eq $expected + +log_pass "Cloning a thick provisioned volume results in a sparse volume" -- 2.11.4.GIT