]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Implemented zpool sync command
authorAlek P <alek-p@users.noreply.github.com>
Fri, 19 May 2017 19:33:11 +0000 (12:33 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 19 May 2017 19:33:11 +0000 (12:33 -0700)
This addition will enable us to sync an open TXG to the main pool
on demand. The functionality is similar to 'sync(2)' but 'zpool sync'
will return when data has hit the main storage instead of potentially
just the ZIL as is the case with the 'sync(2)' cmd.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Signed-off-by: Alek Pinchuk <apinchuk@datto.com>
Closes #6122

20 files changed:
cmd/zpool/zpool_main.c
configure.ac
include/libzfs.h
include/libzfs_core.h
include/sys/fs/zfs.h
lib/libzfs/libzfs_pool.c
lib/libzfs_core/libzfs_core.c
man/man8/zpool.8
module/zfs/zfs_ioctl.c
tests/runfiles/linux.run
tests/zfs-tests/include/libtest.shlib
tests/zfs-tests/tests/functional/clean_mirror/clean_mirror_common.kshlib
tests/zfs-tests/tests/functional/cli_root/Makefile.am
tests/zfs-tests/tests/functional/cli_root/zpool_create/create-o_ashift.ksh
tests/zfs-tests/tests/functional/cli_root/zpool_sync/Makefile.am [new file with mode: 0644]
tests/zfs-tests/tests/functional/cli_root/zpool_sync/cleanup.ksh [new file with mode: 0755]
tests/zfs-tests/tests/functional/cli_root/zpool_sync/setup.ksh [new file with mode: 0755]
tests/zfs-tests/tests/functional/cli_root/zpool_sync/zpool_sync_001_pos.ksh [new file with mode: 0755]
tests/zfs-tests/tests/functional/cli_root/zpool_sync/zpool_sync_002_neg.ksh [new file with mode: 0755]
tests/zfs-tests/tests/functional/upgrade/upgrade_userobj_001_pos.ksh

index 0d06dcc05de5add3cade7f86225666e231ad6534..f99145da9632f46bdc7361da4f9ebf59dedf5463 100644 (file)
@@ -27,6 +27,7 @@
  * Copyright (c) 2012 by Cyril Plisko. All rights reserved.
  * Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved.
  * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
+ * Copyright (c) 2017 Datto Inc.
  */
 
 #include <assert.h>
@@ -100,6 +101,8 @@ static int zpool_do_events(int, char **);
 static int zpool_do_get(int, char **);
 static int zpool_do_set(int, char **);
 
+static int zpool_do_sync(int, char **);
+
 /*
  * These libumem hooks provide a reasonable set of defaults for the allocator's
  * debugging facilities.
@@ -143,6 +146,7 @@ typedef enum {
        HELP_GET,
        HELP_SET,
        HELP_SPLIT,
+       HELP_SYNC,
        HELP_REGUID,
        HELP_REOPEN
 } zpool_help_t;
@@ -272,6 +276,7 @@ static zpool_command_t command_table[] = {
        { NULL },
        { "get",        zpool_do_get,           HELP_GET                },
        { "set",        zpool_do_set,           HELP_SET                },
+       { "sync",       zpool_do_sync,          HELP_SYNC               },
 };
 
 #define        NCOMMAND        (ARRAY_SIZE(command_table))
@@ -358,6 +363,8 @@ get_usage(zpool_help_t idx)
                    "[<device> ...]\n"));
        case HELP_REGUID:
                return (gettext("\treguid <pool>\n"));
+       case HELP_SYNC:
+               return (gettext("\tsync [pool] ...\n"));
        }
 
        abort();
@@ -2693,6 +2700,45 @@ error:
        return (err ? 1 : 0);
 }
 
+/*
+ * zpool sync [-f] [pool] ...
+ *
+ * -f (undocumented) force uberblock (and config including zpool cache file)
+ *    update.
+ *
+ * Sync the specified pool(s).
+ * Without arguments "zpool sync" will sync all pools.
+ * This command initiates TXG sync(s) and will return after the TXG(s) commit.
+ *
+ */
+static int
+zpool_do_sync(int argc, char **argv)
+{
+       int ret;
+       boolean_t force = B_FALSE;
+
+       /* check options */
+       while ((ret  = getopt(argc, argv, "f")) != -1) {
+               switch (ret) {
+               case 'f':
+                       force = B_TRUE;
+                       break;
+               case '?':
+                       (void) fprintf(stderr, gettext("invalid option '%c'\n"),
+                           optopt);
+                       usage(B_FALSE);
+               }
+       }
+
+       argc -= optind;
+       argv += optind;
+
+       /* if argc == 0 we will execute zpool_sync_one on all pools */
+       ret = for_each_pool(argc, argv, B_FALSE, NULL, zpool_sync_one, &force);
+
+       return (ret);
+}
+
 typedef struct iostat_cbdata {
        uint64_t cb_flags;
        int cb_name_flags;
index 2b3957b3b5767216804ad48e81855ec78fec2a80..100ab81d99f6b1cc4d2c37f383a5af2679e965c4 100644 (file)
@@ -223,6 +223,7 @@ AC_CONFIG_FILES([
        tests/zfs-tests/tests/functional/cli_root/zpool_scrub/Makefile
        tests/zfs-tests/tests/functional/cli_root/zpool_set/Makefile
        tests/zfs-tests/tests/functional/cli_root/zpool_status/Makefile
+       tests/zfs-tests/tests/functional/cli_root/zpool_sync/Makefile
        tests/zfs-tests/tests/functional/cli_root/zpool_upgrade/Makefile
        tests/zfs-tests/tests/functional/cli_user/Makefile
        tests/zfs-tests/tests/functional/cli_user/misc/Makefile
index 08c7813edeba961a505de056fe5f1dcedf3be832..c634ccd863bdc33744fd06268afc25b113da37b7 100644 (file)
@@ -26,6 +26,7 @@
  * Copyright (c) 2013 Steven Hartland. All rights reserved.
  * Copyright (c) 2016, Intel Corporation.
  * Copyright 2016 Nexenta Systems, Inc.
+ * Copyright (c) 2017 Datto Inc.
  */
 
 #ifndef        _LIBZFS_H
@@ -264,6 +265,8 @@ extern int zpool_clear(zpool_handle_t *, const char *, nvlist_t *);
 extern int zpool_reguid(zpool_handle_t *);
 extern int zpool_reopen(zpool_handle_t *);
 
+extern int zpool_sync_one(zpool_handle_t *, void *);
+
 extern int zpool_vdev_online(zpool_handle_t *, const char *, int,
     vdev_state_t *);
 extern int zpool_vdev_offline(zpool_handle_t *, const char *, boolean_t);
index 0dfbca72bd24940152e18d61c084c88090c58a02..f71d4b20575b72e6016a25739f950bdd9f72d611 100644 (file)
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2017 Datto Inc.
  */
 
 #ifndef        _LIBZFS_CORE_H
@@ -89,6 +90,8 @@ boolean_t lzc_exists(const char *);
 
 int lzc_rollback(const char *, char *, int);
 
+int lzc_sync(const char *, nvlist_t *, nvlist_t **);
+
 #ifdef __cplusplus
 }
 #endif
index d59489de67c3daed05bb587f14011d5c5eb84209..7414eee5a2604a1b315e3e7bf81f7fc2c82d8194 100644 (file)
@@ -24,6 +24,7 @@
  * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2017 Datto Inc.
  */
 
 /* Portions Copyright 2010 Robert Milkowski */
@@ -1020,6 +1021,7 @@ typedef enum zfs_ioc {
        ZFS_IOC_GET_BOOKMARKS,
        ZFS_IOC_DESTROY_BOOKMARKS,
        ZFS_IOC_RECV_NEW,
+       ZFS_IOC_POOL_SYNC,
 
        /*
         * Linux - 3/64 numbers reserved.
index 28ccf8f4d62e28443952774315f1183c7093074a..f36c65fda9557c4a6bf8d812b85972ba2de68c68 100644 (file)
@@ -24,6 +24,7 @@
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
  * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
+ * Copyright (c) 2017 Datto Inc.
  */
 
 #include <ctype.h>
@@ -3288,6 +3289,27 @@ zpool_reopen(zpool_handle_t *zhp)
        return (zpool_standard_error(hdl, errno, msg));
 }
 
+/* call into libzfs_core to execute the sync IOCTL per pool */
+int
+zpool_sync_one(zpool_handle_t *zhp, void *data)
+{
+       int ret;
+       libzfs_handle_t *hdl = zpool_get_handle(zhp);
+       const char *pool_name = zpool_get_name(zhp);
+       boolean_t *force = data;
+       nvlist_t *innvl = fnvlist_alloc();
+
+       fnvlist_add_boolean_value(innvl, "force", *force);
+       if ((ret = lzc_sync(pool_name, innvl, NULL)) != 0) {
+               nvlist_free(innvl);
+               return (zpool_standard_error_fmt(hdl, ret,
+                   dgettext(TEXT_DOMAIN, "sync '%s' failed"), pool_name));
+       }
+       nvlist_free(innvl);
+
+       return (0);
+}
+
 #if defined(__sun__) || defined(__sun)
 /*
  * Convert from a devid string to a path.
index 17f9931a06c44100253923feaa5af7a071ed80d1..8e36d84598155228c3c2c564a3452e7e0210d999 100644 (file)
@@ -22,6 +22,7 @@
 /*
  * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
  * Copyright (c) 2013 Steven Hartland. All rights reserved.
+ * Copyright (c) 2017 Datto Inc.
  */
 
 /*
@@ -126,17 +127,20 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name,
 {
        zfs_cmd_t zc = {"\0"};
        int error = 0;
-       char *packed;
-       size_t size;
+       char *packed = NULL;
+       size_t size = 0;
 
        ASSERT3S(g_refcount, >, 0);
        VERIFY3S(g_fd, !=, -1);
 
-       (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
+       if (name != NULL)
+               (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
 
-       packed = fnvlist_pack(source, &size);
-       zc.zc_nvlist_src = (uint64_t)(uintptr_t)packed;
-       zc.zc_nvlist_src_size = size;
+       if (source != NULL) {
+               packed = fnvlist_pack(source, &size);
+               zc.zc_nvlist_src = (uint64_t)(uintptr_t)packed;
+               zc.zc_nvlist_src_size = size;
+       }
 
        if (resultp != NULL) {
                *resultp = NULL;
@@ -340,6 +344,18 @@ lzc_exists(const char *dataset)
        return (ioctl(g_fd, ZFS_IOC_OBJSET_STATS, &zc) == 0);
 }
 
+/*
+ * outnvl is unused.
+ * It was added to preserve the function signature in case it is
+ * needed in the future.
+ */
+/*ARGSUSED*/
+int
+lzc_sync(const char *pool_name, nvlist_t *innvl, nvlist_t **outnvl)
+{
+       return (lzc_ioctl(ZFS_IOC_POOL_SYNC, pool_name, innvl, NULL));
+}
+
 /*
  * Create "user holds" on snapshots.  If there is a hold on a snapshot,
  * the snapshot can not be destroyed.  (However, it can be marked for deletion
@@ -440,11 +456,7 @@ lzc_release(nvlist_t *holds, nvlist_t **errlist)
 int
 lzc_get_holds(const char *snapname, nvlist_t **holdsp)
 {
-       int error;
-       nvlist_t *innvl = fnvlist_alloc();
-       error = lzc_ioctl(ZFS_IOC_GET_HOLDS, snapname, innvl, holdsp);
-       fnvlist_free(innvl);
-       return (error);
+       return (lzc_ioctl(ZFS_IOC_GET_HOLDS, snapname, NULL, holdsp));
 }
 
 /*
index 8b793623e176722662c534140faa114a3dc92db9..ff3db440dad52f9df1b048389a55169ece138b2d 100644 (file)
@@ -3,6 +3,7 @@
 .\" Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
 .\" Copyright (c) 2013 by Delphix. All rights reserved.
 .\" Copyright (c) 2012 Cyril Plisko. All Rights Reserved.
+.\" Copyright (c) 2017 Datto Inc.
 .\" The contents of this file are subject to the terms of the Common Development
 .\" and Distribution License (the "License"). You may not use this file except
 .\" in compliance with the License. You can obtain a copy of the license at
@@ -15,7 +16,7 @@
 .\" CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your
 .\" own identifying information:
 .\" Portions Copyright [yyyy] [name of copyright owner]
-.TH zpool 8 "May 11, 2016" "ZFS pool 28, filesystem 5" "System Administration Commands"
+.TH zpool 8 "April 12, 2017" "ZFS pool 28, filesystem 5" "System Administration Commands"
 .SH NAME
 zpool \- configures ZFS storage pools
 .SH SYNOPSIS
@@ -162,6 +163,11 @@ zpool \- configures ZFS storage pools
 \fBzpool status\fR [\fB-c\fR \fBSCRIPT\fR] [\fB-gLPvxD\fR] [\fB-T\fR d | u] [\fIpool\fR] ... [\fIinterval\fR [\fIcount\fR]]
 .fi
 
+.LP
+.nf
+\fBzpool sync\fR [\fBpool\fR] ...
+.fi
+
 .LP
 .nf
 \fBzpool upgrade\fR
@@ -2240,6 +2246,20 @@ Specify \fBu\fR for a printed representation of the internal representation of t
 
 .RE
 
+.sp
+.ne 2
+.na
+\fB\fBzpool sync\fR\fR [\fBpool\fR] ...
+.ad
+.sp .6
+.RS 4n
+This command forces all in-core dirty data to be written to the primary pool
+storage and not the ZIL. It will also update administrative information
+including quota reporting.
+Without arguments, \fBzpool sync\fR will sync all pools on the system.
+Otherwise, it will sync only the specified pool(s).
+.RE
+
 .sp
 .ne 2
 .na
index 268e797146fc65b47748145232e7a6b5bd531707..c6a5321239a23b510f56276a56eff80fc60a825c 100644 (file)
@@ -34,6 +34,7 @@
  * Copyright 2016 Toomas Soome <tsoome@me.com>
  * Copyright (c) 2016 Actifio, Inc. All rights reserved.
  * Copyright (c) 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
+ * Copyright (c) 2017 Datto Inc.
  */
 
 /*
@@ -5466,6 +5467,7 @@ zfs_ioc_hold(const char *pool, nvlist_t *args, nvlist_t *errlist)
 static int
 zfs_ioc_get_holds(const char *snapname, nvlist_t *args, nvlist_t *outnvl)
 {
+       ASSERT3P(args, ==, NULL);
        return (dsl_dataset_get_holds(snapname, outnvl));
 }
 
@@ -5823,6 +5825,44 @@ out:
        return (error);
 }
 
+/*
+ * Sync the currently open TXG to disk for the specified pool.
+ * This is somewhat similar to 'zfs_sync()'.
+ * For cases that do not result in error this ioctl will wait for
+ * the currently open TXG to commit before returning back to the caller.
+ *
+ * innvl: {
+ *  "force" -> when true, force uberblock update even if there is no dirty data.
+ *             In addition this will cause the vdev configuration to be written
+ *             out including updating the zpool cache file. (boolean_t)
+ * }
+ *
+ * onvl is unused
+ */
+/* ARGSUSED */
+static int
+zfs_ioc_pool_sync(const char *pool, nvlist_t *innvl, nvlist_t *onvl)
+{
+       int err;
+       boolean_t force;
+       spa_t *spa;
+
+       if ((err = spa_open(pool, &spa, FTAG)) != 0)
+               return (err);
+
+       force = fnvlist_lookup_boolean_value(innvl, "force");
+       if (force) {
+               spa_config_enter(spa, SCL_CONFIG, FTAG, RW_WRITER);
+               vdev_config_dirty(spa->spa_root_vdev);
+               spa_config_exit(spa, SCL_CONFIG, FTAG);
+       }
+       txg_wait_synced(spa_get_dsl(spa), 0);
+
+       spa_close(spa, FTAG);
+
+       return (err);
+}
+
 static zfs_ioc_vec_t zfs_ioc_vec[ZFS_IOC_LAST - ZFS_IOC_FIRST];
 
 static void
@@ -5995,6 +6035,10 @@ zfs_ioctl_init(void)
            zfs_ioc_recv_new, zfs_secpolicy_recv_new, DATASET_NAME,
            POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
 
+       zfs_ioctl_register("sync", ZFS_IOC_POOL_SYNC,
+           zfs_ioc_pool_sync, zfs_secpolicy_none, POOL_NAME,
+           POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_FALSE);
+
        /* IOCTLS that use the legacy function signature */
 
        zfs_ioctl_register_legacy(ZFS_IOC_POOL_FREEZE, zfs_ioc_pool_freeze,
index 0e46220234347c64c2554e49cc6902bfce8afefe..d2148d7adb584652024304f03b44a4c2a60dcf01 100644 (file)
@@ -319,6 +319,9 @@ tests = ['zpool_upgrade_001_pos', 'zpool_upgrade_002_pos',
     'zpool_upgrade_007_pos', 'zpool_upgrade_008_pos',
     'zpool_upgrade_009_neg']
 
+[tests/functional/cli_root/zpool_sync]
+tests = ['zpool_sync_001_pos', 'zpool_sync_002_neg']
+
 # DISABLED:
 # zfs_share_001_neg - requires additional dependencies
 # zfs_unshare_001_neg - requires additional dependencies
index 4ad375e9db88c734bf56274af4f1c5ab841f9c1b..5a9da2735074494e92965fce243d898e1db8244b 100644 (file)
@@ -26,6 +26,7 @@
 # Copyright (c) 2012, 2016 by Delphix. All rights reserved.
 # Copyright 2016 Nexenta Systems, Inc.
 # Copyright (c) 2017 Lawrence Livermore National Security, LLC.
+# Copyright (c) 2017 Datto Inc.
 #
 
 . ${STF_TOOLS}/include/logapi.shlib
@@ -3203,29 +3204,23 @@ function get_objnum
 }
 
 #
-# Synchronize all the data in pool
+# Sync data to the pool
 #
 # $1 pool name
+# $2 boolean to force uberblock (and config including zpool cache file) update
 #
-function sync_pool #pool
+function sync_pool #pool <force>
 {
        typeset pool=${1:-$TESTPOOL}
+       typeset force=${2:-false}
 
-       log_must $SYNC
-       log_must sleep 2
-       # Flush all the pool data.
-       typeset -i ret
-       zpool scrub $pool >/dev/null 2>&1
-       ret=$?
-       (( $ret != 0 )) && \
-       log_fail "zpool scrub $pool failed."
-
-       while ! is_pool_scrubbed $pool; do
-               if is_pool_resilvered $pool ; then
-                       log_fail "$pool should not be resilver completed."
-               fi
-               log_must sleep 2
-       done
+       if [[ $force == true ]]; then
+               log_must zpool sync -f $pool
+       else
+               log_must zpool sync $pool
+       fi
+
+       return 0
 }
 
 #
index 7703c1241542ce6c7bf100dcda6d665ab1b2d375..3d371e6143f860d651aa06e94085d93f944793cd 100644 (file)
 
 #
 # Copyright (c) 2013, 2016 by Delphix. All rights reserved.
+# Copyright (c) 2017 Datto Inc.
 #
 
+. $STF_SUITE/include/libtest.shlib
 . $STF_SUITE/tests/functional/clean_mirror/default.cfg
 
 # Most of the code related to the clearing of mirrors is duplicated in all
 # the contents of the mirror.
 # This code is sourced into each of these test cases.
 
-#
-# Synchronize all the data in pool
-#
-# $1 pool name
-#
-function sync_pool #pool
-{
-       typeset pool=$1
-
-       log_must sync
-       log_must sleep 2
-       # Flush all the pool data.
-       typeset -i ret
-       zpool scrub $pool >/dev/null 2>&1
-       ret=$?
-       (( $ret != 0 )) && \
-               log_fail "zpool scrub $pool failed."
-
-       while ! is_pool_scrubbed $pool; do
-               if is_pool_resilvered $pool ; then
-                       log_fail "$pool should not be resilver completed."
-               fi
-               log_must sleep 2
-       done
-}
-
 function overwrite_verify_mirror
 {
        typeset AFFECTED_DEVICE=$1
index f2e3fd0dfae5ab02ed36eec5f3bd3f8775809c44..ff09514856228b399641767e25de473161740e64 100644 (file)
@@ -45,4 +45,5 @@ SUBDIRS = \
        zpool_scrub \
        zpool_set \
        zpool_status \
+       zpool_sync \
        zpool_upgrade
index 33ff4534d9c39a9cbcd0cdcc387f6c024d14295b..6449c8a913ed913a398435fbb2136e6e1055105b 100755 (executable)
@@ -22,6 +22,7 @@
 
 #
 # Copyright 2016, loli10K. All rights reserved.
+# Copyright (c) 2017 Datto Inc.
 #
 
 . $STF_SUITE/include/libtest.shlib
@@ -48,30 +49,22 @@ function cleanup
 }
 
 #
-# FIXME: Ugly hack to force a $1 number of txg syncs.
-# This is used on Linux because we can't force it via sync(1) like on Illumos.
-# This could eventually (an hopefully) be replaced by a 'zpool sync' command.
+# Commit the specified number of TXGs to the provided pool
+# We use 'zpool sync' here because we can't force it via sync(1) like on illumos
 # $1 pool name
 # $2 number of txg syncs
 #
 function txg_sync
 {
        typeset pool=$1
-       typeset count=$2
+       typeset -i count=$2
        typeset -i i=0;
 
        while [ $i -lt $count ]
        do
-               zfs snapshot $pool@sync$$$i
-               if [[ $? -ne 0 ]]
-               then
-                       log_fail "Failed to sync pool $pool (snapshot $i)"
-                       return 1
-               fi
+               log_must sync_pool $pool true
                ((i = i + 1))
        done
-
-       return 0
 }
 
 #
@@ -118,7 +111,7 @@ do
                    "$ashift (current = $pprop)"
        fi
        # force 128 txg sync to fill the uberblock ring
-       log_must eval "txg_sync $TESTPOOL 128"
+       txg_sync $TESTPOOL 128
        verify_device_uberblocks $disk ${ubcount[$i]}
        if [[ $? -ne 0 ]]
        then
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_sync/Makefile.am b/tests/zfs-tests/tests/functional/cli_root/zpool_sync/Makefile.am
new file mode 100644 (file)
index 0000000..7f5f67d
--- /dev/null
@@ -0,0 +1,6 @@
+pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/cli_root/zpool_sync
+dist_pkgdata_SCRIPTS = \
+       cleanup.ksh \
+       setup.ksh \
+       zpool_sync_001_pos.ksh \
+       zpool_sync_002_neg.ksh
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_sync/cleanup.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_sync/cleanup.ksh
new file mode 100755 (executable)
index 0000000..89c1462
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+verify_runnable "global"
+
+default_cleanup
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_sync/setup.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_sync/setup.ksh
new file mode 100755 (executable)
index 0000000..181e62b
--- /dev/null
@@ -0,0 +1,34 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+verify_runnable "global"
+
+DISK=${DISKS%% *}
+
+default_setup $DISK
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_sync/zpool_sync_001_pos.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_sync/zpool_sync_001_pos.ksh
new file mode 100755 (executable)
index 0000000..4761bac
--- /dev/null
@@ -0,0 +1,88 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# 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.
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2017 Datto Inc.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# Verify 'zpool sync' can sync txgs to the pool(s) main vdevs.
+#
+# STRATEGY:
+# 1. Create a pool
+# 2. Use zdb to obtain current txg
+# 3. Create a file in the pool if we're not using force sync
+# 4. Use zpool sync to sync pool
+# 5. Verify the new txg is now bigger than the saved one
+#
+
+verify_runnable "global"
+
+function get_txg {
+       typeset -i txg=$(zdb -u $1 | sed -n 's/^.*txg = \(.*\)$/\1/p')
+       echo $txg
+}
+
+set -A args "sync $TESTPOOL" "sync -f $TESTPOOL" "sync" "sync -f"
+
+log_assert "Verify 'zpool sync' can sync a pool"
+
+typeset -i i=0
+typeset -i orig_txg=0
+typeset -i new_txg=0
+while [[ $i -lt ${#args[*]} ]]; do
+       orig_txg=$(get_txg $TESTPOOL)
+       if ! [[ "${args[i]}" =~ "-f" ]]; then
+               log_must touch /$TESTPOOL/$i
+       fi
+       log_must zpool ${args[i]}
+       new_txg=$(get_txg $TESTPOOL)
+       if [[ $orig_txg -ge $new_txg ]]; then
+               log_fail "'zpool ${args[i]}' failed: txg $orig_txg >= $new_txg"
+       fi
+       ((i = i + 1))
+done
+
+# sync_pool is implemented using 'zpool sync' so let's test it as well
+
+# make sure we can use sync_pool with force sync explicitly not used
+orig_txg=$(get_txg $TESTPOOL)
+log_must touch /$TESTPOOL/$i
+log_must sync_pool $TESTPOOL false
+new_txg=$(get_txg $TESTPOOL)
+if [[ $orig_txg -ge $new_txg ]]; then
+       log_fail "'sync_pool $TESTPOOL false' failed: txg $orig_txg >= $new_txg"
+fi
+
+# make sure we can use sync_pool with force sync explicitly enabled
+orig_txg=$(get_txg $TESTPOOL)
+log_must sync_pool $TESTPOOL true
+new_txg=$(get_txg $TESTPOOL)
+if [[ $orig_txg -ge $new_txg ]]; then
+       log_fail "'sync_pool $TESTPOOL true' failed: txg $orig_txg >= $new_txg"
+fi
+
+# make sure we can use sync_pool with force sync implicitly not used
+orig_txg=$(get_txg $TESTPOOL)
+log_must touch /$TESTPOOL/$i
+log_must sync_pool $TESTPOOL
+new_txg=$(get_txg $TESTPOOL)
+if [[ $orig_txg -ge $new_txg ]]; then
+       log_fail "'sync_pool $TESTPOOL' failed: txg $orig_txg >= $new_txg"
+fi
+
+log_pass "'zpool sync' syncs pool as expected."
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_sync/zpool_sync_002_neg.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_sync/zpool_sync_002_neg.ksh
new file mode 100755 (executable)
index 0000000..e35a291
--- /dev/null
@@ -0,0 +1,44 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# 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.
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2017 Datto Inc.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# A badly formed parameter passed to 'zpool sync' should
+# return an error.
+#
+# STRATEGY:
+# 1. Create an array containing bad 'zpool sync' parameters.
+# 2. For each element, execute the sub-command.
+# 3. Verify it returns an error.
+#
+
+verify_runnable "global"
+
+set -A args "1" "-a" "-?" "--%" "-123456" "0.5" "-o" "-b" "-b no" "-z 2"
+
+log_assert "Execute 'zpool sync' using invalid parameters."
+
+typeset -i i=0
+while [[ $i -lt ${#args[*]} ]]; do
+       log_mustnot zpool sync ${args[i]}
+       ((i = i + 1))
+done
+
+log_pass "Invalid parameters to 'zpool sync' fail as expected."
index 49b6d18220a89b22863d43496a81b8d21b6a9dce..dda594f4e2ab0b0072a99100867f337d7512fb47 100755 (executable)
@@ -22,6 +22,7 @@
 
 #
 # Copyright (c) 2013 by Jinshan Xiong. No rights reserved.
+# Copyright (c) 2017 Datto Inc.
 #
 
 . $STF_SUITE/include/libtest.shlib
@@ -71,7 +72,7 @@ zfs userspace -o objused -H $TESTPOOL | head -n 1 | grep -q "-" ||
 
 # Create a file in fs1 should trigger dataset upgrade
 log_must mkfile 1m $TESTDIR/fs1/tf
-sync_pool
+log_must sleep 1 # upgrade done in the background so let's give it a sec
 
 # Make sure userobj accounting is working for fs1
 zfs userspace -o objused -H $TESTPOOL/fs1 | head -n 1 | grep -q "-" &&
@@ -79,7 +80,7 @@ zfs userspace -o objused -H $TESTPOOL/fs1 | head -n 1 | grep -q "-" &&
 
 # Mount a dataset should trigger upgrade
 log_must zfs mount $TESTPOOL/fs2
-sync_pool
+log_must sleep 1 # upgrade done in the background so let's give it a sec
 
 # Make sure userobj accounting is working for fs2
 zfs userspace -o objused -H $TESTPOOL/fs2 | head -n 1 | grep -q "-" &&
@@ -91,6 +92,7 @@ zfs userspace -o objused -H $TESTPOOL | head -n 1 | grep -q "-" ||
        log_fail "userobj accounting should be disabled for $TESTPOOL"
 
 # Manual upgrade root dataset
+# uses an ioctl which will wait for the upgrade to be done before returning
 log_must zfs set version=current $TESTPOOL
 zfs userspace -o objused -H $TESTPOOL | head -n 1 | grep -q "-" &&
        log_fail "userobj accounting should be enabled for $TESTPOOL"