svn commit: r324197 - in head: cddl/contrib/opensolaris/cmd/zfs cddl/contrib/opensolaris/lib/libzfs_core/common sys/cddl/contrib/opensolaris/uts/common/fs/zfs sys/cddl/contrib/opensolaris/uts/commo...

Andriy Gapon avg at FreeBSD.org
Mon Oct 2 11:32:10 UTC 2017


Author: avg
Date: Mon Oct  2 11:32:08 2017
New Revision: 324197
URL: https://svnweb.freebsd.org/changeset/base/324197

Log:
  MFV r323913: 8600 ZFS channel programs - snapshot
  
  illumos/illumos-gate at 2840dce1a029098fb784afd951d5f98089f850d8
  https://github.com/illumos/illumos-gate/commit/2840dce1a029098fb784afd951d5f98089f850d8
  
  https://www.illumos.org/issues/8600
    ZFS channel programs should be able to create snapshots.
    In addition to the base snapshot functionality, this will likely entail adding
    extra logic to handle edge cases which were formerly not possible, such as
    creating then destroying a snapshot in the same transaction sync.
  
  Reviewed by: Matthew Ahrens <mahrens at delphix.com>
  Reviewed by: John Kennedy <john.kennedy at delphix.com>
  Reviewed by: Brad Lewis <brad.lewis at delphix.com>
  Approved by: Robert Mustacchi <rm at joyent.com>
  Author: Chris Williamson <chris.williamson at delphix.com>
  
  MFC after:	5 weeks
  X-MFC after:	r324163

Modified:
  head/cddl/contrib/opensolaris/cmd/zfs/zfs-program.8
  head/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zcp.h
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_global.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_synctask.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
Directory Properties:
  head/cddl/contrib/opensolaris/   (props changed)
  head/sys/cddl/contrib/opensolaris/   (props changed)

Modified: head/cddl/contrib/opensolaris/cmd/zfs/zfs-program.8
==============================================================================
--- head/cddl/contrib/opensolaris/cmd/zfs/zfs-program.8	Mon Oct  2 11:23:31 2017	(r324196)
+++ head/cddl/contrib/opensolaris/cmd/zfs/zfs-program.8	Mon Oct  2 11:32:08 2017	(r324197)
@@ -10,7 +10,7 @@
 .\"
 .\" Copyright (c) 2016, 2017 by Delphix. All rights reserved.
 .\"
-.Dd October 02, 2016
+.Dd October 02, 2017
 .Dt ZFS-PROGRAM 1M
 .Os
 .Sh NAME
@@ -372,6 +372,18 @@ filesystem (string)
 .Bd -ragged -compact -offset "xxxx"
 Filesystem to rollback.
 .Ed
+.It Em zfs.sync.snapshot(dataset)
+Create a snapshot of a filesystem.
+Returns 0 if the snapshot was successfully created,
+and a nonzero error code otherwise.
+.Pp
+Note: Taking a snapshot will fail on any pool older than legacy version 27.
+To enable taking snapshots from ZCP scripts, the pool must be upgraded.
+.Pp
+dataset (string)
+.Bd -ragged -compact -offset "xxxx"
+Name of snapshot to create.
+.Ed
 .El
 .It Sy zfs.check submodule
 For each function in the zfs.sync submodule, there is a corresponding zfs.check
@@ -392,6 +404,7 @@ The available zfs.check functions are:
 .It Em zfs.check.destroy(dataset, [defer=true|false])
 .It Em zfs.check.promote(dataset)
 .It Em zfs.check.rollback(filesystem)
+.It Em zfs.check.snapshot(dataset)
 .El
 .It Sy zfs.list submodule
 The zfs.list submodule provides functions for iterating over datasets and

Modified: head/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c	Mon Oct  2 11:23:31 2017	(r324196)
+++ head/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c	Mon Oct  2 11:32:08 2017	(r324197)
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
  * Copyright (c) 2013 Steven Hartland. All rights reserved.
  * Copyright (c) 2014 Integros [integros.com]
  * Copyright 2017 RackTop Systems.
@@ -160,7 +160,12 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name,
 
 	if (resultp != NULL) {
 		*resultp = NULL;
-		zc.zc_nvlist_dst_size = MAX(size * 2, 128 * 1024);
+		if (ioc == ZFS_IOC_CHANNEL_PROGRAM) {
+			zc.zc_nvlist_dst_size = fnvlist_lookup_uint64(source,
+			    ZCP_ARG_MEMLIMIT);
+		} else {
+			zc.zc_nvlist_dst_size = MAX(size * 2, 128 * 1024);
+		}
 		zc.zc_nvlist_dst = (uint64_t)(uintptr_t)
 		    malloc(zc.zc_nvlist_dst_size);
 #ifdef illumos
@@ -178,7 +183,7 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name,
 		 * If ioctl exited with ENOMEM, we retry the ioctl after
 		 * increasing the size of the destination nvlist.
 		 *
-		 * Channel programs that exit with ENOMEM probably ran over the
+		 * Channel programs that exit with ENOMEM ran over the
 		 * lua memory sandbox; they should not be retried.
 		 */
 		if (errno == ENOMEM && resultp != NULL &&

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c	Mon Oct  2 11:23:31 2017	(r324196)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c	Mon Oct  2 11:32:08 2017	(r324197)
@@ -1134,13 +1134,6 @@ dsl_dataset_snapshot_reserve_space(dsl_dataset_t *ds, 
 	return (0);
 }
 
-typedef struct dsl_dataset_snapshot_arg {
-	nvlist_t *ddsa_snaps;
-	nvlist_t *ddsa_props;
-	nvlist_t *ddsa_errors;
-	cred_t *ddsa_cr;
-} dsl_dataset_snapshot_arg_t;
-
 int
 dsl_dataset_snapshot_check_impl(dsl_dataset_t *ds, const char *snapname,
     dmu_tx_t *tx, boolean_t recv, uint64_t cnt, cred_t *cr)
@@ -1200,7 +1193,7 @@ dsl_dataset_snapshot_check_impl(dsl_dataset_t *ds, con
 	return (0);
 }
 
-static int
+int
 dsl_dataset_snapshot_check(void *arg, dmu_tx_t *tx)
 {
 	dsl_dataset_snapshot_arg_t *ddsa = arg;
@@ -1477,7 +1470,7 @@ dsl_dataset_snapshot_sync_impl(dsl_dataset_t *ds, cons
 	spa_history_log_internal_ds(ds->ds_prev, "snapshot", tx, "");
 }
 
-static void
+void
 dsl_dataset_snapshot_sync(void *arg, dmu_tx_t *tx)
 {
 	dsl_dataset_snapshot_arg_t *ddsa = arg;

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h	Mon Oct  2 11:23:31 2017	(r324196)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h	Mon Oct  2 11:32:08 2017	(r324197)
@@ -244,6 +244,13 @@ typedef struct dsl_dataset_rollback_arg {
 	nvlist_t *ddra_result;
 } dsl_dataset_rollback_arg_t;
 
+typedef struct dsl_dataset_snapshot_arg {
+	nvlist_t *ddsa_snaps;
+	nvlist_t *ddsa_props;
+	nvlist_t *ddsa_errors;
+	cred_t *ddsa_cr;
+} dsl_dataset_snapshot_arg_t;
+
 /*
  * The max length of a temporary tag prefix is the number of hex digits
  * required to express UINT64_MAX plus one for the hyphen.
@@ -276,6 +283,8 @@ uint64_t dsl_dataset_create_sync(dsl_dir_t *pds, const
     dsl_dataset_t *origin, uint64_t flags, cred_t *, dmu_tx_t *);
 uint64_t dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin,
     uint64_t flags, dmu_tx_t *tx);
+void dsl_dataset_snapshot_sync(void *arg, dmu_tx_t *tx);
+int dsl_dataset_snapshot_check(void *arg, dmu_tx_t *tx);
 int dsl_dataset_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t *errors);
 void dsl_dataset_promote_sync(void *arg, dmu_tx_t *tx);
 int dsl_dataset_promote_check(void *arg, dmu_tx_t *tx);

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zcp.h
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zcp.h	Mon Oct  2 11:23:31 2017	(r324196)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zcp.h	Mon Oct  2 11:32:08 2017	(r324197)
@@ -14,7 +14,7 @@
  */
 
 /*
- * Copyright (c) 2016 by Delphix. All rights reserved.
+ * Copyright (c) 2016, 2017 by Delphix. All rights reserved.
  */
 
 #ifndef _SYS_ZCP_H
@@ -136,8 +136,6 @@ typedef struct zcp_lib_info {
 	const zcp_arg_t pargs[4];
 	const zcp_arg_t kwargs[2];
 } zcp_lib_info_t;
-
-int zcp_nvlist_to_lua(lua_State *, nvlist_t *, char *, int);
 
 #ifdef	__cplusplus
 }

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp.c	Mon Oct  2 11:23:31 2017	(r324196)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp.c	Mon Oct  2 11:32:08 2017	(r324197)
@@ -14,7 +14,7 @@
  */
 
 /*
- * Copyright (c) 2016 by Delphix. All rights reserved.
+ * Copyright (c) 2016, 2017 by Delphix. All rights reserved.
  */
 
 /*
@@ -109,10 +109,15 @@
 #define	ETIME	ETIMEDOUT
 #endif
 
+#define	ZCP_NVLIST_MAX_DEPTH 20
+
 uint64_t zfs_lua_check_instrlimit_interval = 100;
 uint64_t zfs_lua_max_instrlimit = ZCP_MAX_INSTRLIMIT;
 uint64_t zfs_lua_max_memlimit = ZCP_MAX_MEMLIMIT;
 
+/*
+ * Forward declarations for mutually recursive functions
+ */
 static int zcp_nvpair_value_to_lua(lua_State *, nvpair_t *, char *, int);
 static int zcp_lua_to_nvlist_impl(lua_State *, int, nvlist_t *, const char *,
     int);
@@ -219,8 +224,6 @@ zcp_cleanup(lua_State *state)
 		zcp_clear_cleanup(state);
 	}
 }
-
-#define	ZCP_NVLIST_MAX_DEPTH 20
 
 /*
  * Convert the lua table at the given index on the Lua stack to an nvlist

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_global.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_global.c	Mon Oct  2 11:23:31 2017	(r324196)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_global.c	Mon Oct  2 11:32:08 2017	(r324197)
@@ -14,7 +14,7 @@
  */
 
 /*
- * Copyright (c) 2016 by Delphix. All rights reserved.
+ * Copyright (c) 2016, 2017 by Delphix. All rights reserved.
  */
 
 #include <sys/zcp_global.h>
@@ -62,7 +62,12 @@ static const zcp_errno_global_t errno_globals[] = {
 	{"EPIPE", EPIPE},
 	{"EDOM", EDOM},
 	{"ERANGE", ERANGE},
+	{"EDEADLK", EDEADLK},
+	{"ENOLCK", ENOLCK},
+	{"ECANCELED", ECANCELED},
+	{"ENOTSUP", ENOTSUP},
 	{"EDQUOT", EDQUOT},
+	{"ENAMETOOLONG", ENAMETOOLONG},
 	{NULL, 0}
 };
 

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_synctask.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_synctask.c	Mon Oct  2 11:23:31 2017	(r324196)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_synctask.c	Mon Oct  2 11:32:08 2017	(r324197)
@@ -39,10 +39,10 @@ typedef int (zcp_synctask_func_t)(lua_State *, boolean
 typedef struct zcp_synctask_info {
 	const char *name;
 	zcp_synctask_func_t *func;
-	zfs_space_check_t space_check;
-	int blocks_modified;
 	const zcp_arg_t pargs[4];
 	const zcp_arg_t kwargs[2];
+	zfs_space_check_t space_check;
+	int blocks_modified;
 } zcp_synctask_info_t;
 
 /*
@@ -91,8 +91,6 @@ static int zcp_synctask_destroy(lua_State *, boolean_t
 static zcp_synctask_info_t zcp_synctask_destroy_info = {
 	.name = "destroy",
 	.func = zcp_synctask_destroy,
-	.space_check = ZFS_SPACE_CHECK_NONE,
-	.blocks_modified = 0,
 	.pargs = {
 	    {.za_name = "filesystem | snapshot", .za_lua_type = LUA_TSTRING},
 	    {NULL, 0}
@@ -100,7 +98,9 @@ static zcp_synctask_info_t zcp_synctask_destroy_info =
 	.kwargs = {
 	    {.za_name = "defer", .za_lua_type = LUA_TBOOLEAN},
 	    {NULL, 0}
-	}
+	},
+	.space_check = ZFS_SPACE_CHECK_NONE,
+	.blocks_modified = 0
 };
 
 /* ARGSUSED */
@@ -140,19 +140,19 @@ zcp_synctask_destroy(lua_State *state, boolean_t sync,
 	return (err);
 }
 
-static int zcp_synctask_promote(lua_State *, boolean_t, nvlist_t *err_details);
+static int zcp_synctask_promote(lua_State *, boolean_t, nvlist_t *);
 static zcp_synctask_info_t zcp_synctask_promote_info = {
 	.name = "promote",
 	.func = zcp_synctask_promote,
-	.space_check = ZFS_SPACE_CHECK_RESERVED,
-	.blocks_modified = 3,
 	.pargs = {
 	    {.za_name = "clone", .za_lua_type = LUA_TSTRING},
 	    {NULL, 0}
 	},
 	.kwargs = {
 	    {NULL, 0}
-	}
+	},
+	.space_check = ZFS_SPACE_CHECK_RESERVED,
+	.blocks_modified = 3
 };
 
 static int
@@ -208,6 +208,58 @@ zcp_synctask_rollback(lua_State *state, boolean_t sync
 	return (err);
 }
 
+static int zcp_synctask_snapshot(lua_State *, boolean_t, nvlist_t *);
+static zcp_synctask_info_t zcp_synctask_snapshot_info = {
+	.name = "snapshot",
+	.func = zcp_synctask_snapshot,
+	.pargs = {
+	    {.za_name = "filesystem at snapname | volume at snapname",
+	    .za_lua_type = LUA_TSTRING},
+	    {NULL, 0}
+	},
+	.kwargs = {
+	    {NULL, 0}
+	},
+	.space_check = ZFS_SPACE_CHECK_NORMAL,
+	.blocks_modified = 3
+};
+
+/* ARGSUSED */
+static int
+zcp_synctask_snapshot(lua_State *state, boolean_t sync, nvlist_t *err_details)
+{
+	int err;
+	dsl_dataset_snapshot_arg_t ddsa = { 0 };
+	const char *dsname = lua_tostring(state, 1);
+	zcp_run_info_t *ri = zcp_run_info(state);
+
+	/*
+	 * We only allow for a single snapshot rather than a list, so the
+	 * error list output is unnecessary.
+	 */
+	ddsa.ddsa_errors = NULL;
+	ddsa.ddsa_props = NULL;
+	ddsa.ddsa_cr = ri->zri_cred;
+	ddsa.ddsa_snaps = fnvlist_alloc();
+	fnvlist_add_boolean(ddsa.ddsa_snaps, dsname);
+
+	/*
+	 * On old pools, the ZIL must not be active when a snapshot is created,
+	 * but we can't suspend the ZIL because we're already in syncing
+	 * context.
+	 */
+	if (spa_version(ri->zri_pool->dp_spa) < SPA_VERSION_FAST_SNAP) {
+		return (ENOTSUP);
+	}
+
+	err = zcp_sync_task(state, dsl_dataset_snapshot_check,
+	    dsl_dataset_snapshot_sync, &ddsa, sync, dsname);
+
+	fnvlist_free(ddsa.ddsa_snaps);
+
+	return (err);
+}
+
 void
 zcp_synctask_wrapper_cleanup(void *arg)
 {
@@ -279,6 +331,7 @@ zcp_load_synctask_lib(lua_State *state, boolean_t sync
 		&zcp_synctask_destroy_info,
 		&zcp_synctask_promote_info,
 		&zcp_synctask_rollback_info,
+		&zcp_synctask_snapshot_info,
 		NULL
 	};
 

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c	Mon Oct  2 11:23:31 2017	(r324196)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c	Mon Oct  2 11:32:08 2017	(r324197)
@@ -27,7 +27,7 @@
  * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  * Copyright (c) 2014, 2016 Joyent, Inc. All rights reserved.
- * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
  * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
  * Copyright (c) 2013 Steven Hartland. All rights reserved.
  * Copyright (c) 2014 Integros [integros.com]
@@ -3795,7 +3795,7 @@ zfs_ioc_channel_program(const char *poolname, nvlist_t
 
 	if (instrlimit == 0 || instrlimit > zfs_lua_max_instrlimit)
 		return (EINVAL);
-	if (memlimit == 0 || memlimit > ZCP_MAX_MEMLIMIT)
+	if (memlimit == 0 || memlimit > zfs_lua_max_memlimit)
 		return (EINVAL);
 
 	return (zcp_eval(poolname, program, instrlimit, memlimit,


More information about the svn-src-all mailing list