Lint most manpages

Reviewed-by: Richard Laager <rlaager@wiktel.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Nguyen <tony.nguyen@delphix.com>
Reviewed-by: Ryan Moeller <ryan@iXsystems.com>
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Closes #12129
This commit is contained in:
наб
2021-05-27 02:46:40 +02:00
committed by Brian Behlendorf
parent 4a98300feb
commit f84fe3fc87
58 changed files with 2716 additions and 2698 deletions
+205 -211
View File
@@ -1,3 +1,4 @@
.\"
.\" 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
@@ -7,17 +8,17 @@
.\" source. A copy of the CDDL is also available via the Internet at
.\" http://www.illumos.org/license/CDDL.
.\"
.\"
.\" Copyright (c) 2016, 2019 by Delphix. All Rights Reserved.
.\" Copyright (c) 2019, 2020 by Christian Schwarz. All Rights Reserved.
.\" Copyright 2020 Joyent, Inc.
.\"
.Dd January 26, 2021
.Dd May 27, 2021
.Dt ZFS-PROGRAM 8
.Os
.
.Sh NAME
.Nm zfs-program
.Nd executes ZFS channel programs
.Nd execute ZFS channel programs
.Sh SYNOPSIS
.Nm zfs
.Cm program
@@ -26,7 +27,8 @@
.Op Fl m Ar memory-limit
.Ar pool
.Ar script
.\".Op Ar optional arguments to channel program
.Op Ar script arguments
.
.Sh DESCRIPTION
The ZFS channel program interface allows ZFS administrative operations to be
run programmatically as a Lua script.
@@ -37,22 +39,22 @@ Channel programs may only be run with root privileges.
.Pp
A modified version of the Lua 5.2 interpreter is used to run channel program
scripts.
The Lua 5.2 manual can be found at:
.Bd -centered -offset indent
The Lua 5.2 manual can be found at
.Lk http://www.lua.org/manual/5.2/
.Ed
.Pp
The channel program given by
.Ar script
will be run on
.Ar pool ,
and any attempts to access or modify other pools will cause an error.
.
.Sh OPTIONS
.Bl -tag -width "-t"
.It Fl j
Display channel program output in JSON format. When this flag is specified and
standard output is empty - channel program encountered an error. The details of
such an error will be printed to standard error in plain text.
Display channel program output in JSON format.
When this flag is specified and standard output is empty -
channel program encountered an error.
The details of such an error will be printed to standard error in plain text.
.It Fl n
Executes a read-only channel program, which runs faster.
The program cannot change on-disk state by calling functions from the
@@ -78,15 +80,17 @@ All remaining argument strings will be passed directly to the Lua script as
described in the
.Sx LUA INTERFACE
section below.
.
.Sh LUA INTERFACE
A channel program can be invoked either from the command line, or via a library
call to
.Fn lzc_channel_program .
.
.Ss Arguments
Arguments passed to the channel program are converted to a Lua table.
If invoked from the command line, extra arguments to the Lua script will be
accessible as an array stored in the argument table with the key 'argv':
.Bd -literal -offset indent
.Bd -literal -compact -offset indent
args = ...
argv = args["argv"]
-- argv == {1="arg1", 2="arg2", ...}
@@ -95,7 +99,7 @@ argv = args["argv"]
If invoked from the libZFS interface, an arbitrary argument list can be
passed to the channel program, which is accessible via the same
"..." syntax in Lua:
.Bd -literal -offset indent
.Bd -literal -compact -offset indent
args = ...
-- args == {"foo"="bar", "baz"={...}, ...}
.Ed
@@ -108,37 +112,35 @@ in
in a C array passed to a channel program will be stored in
.Va arr[1]
when accessed from Lua.
.
.Ss Return Values
Lua return statements take the form:
.Bd -literal -offset indent
return ret0, ret1, ret2, ...
.Ed
.Dl return ret0, ret1, ret2, ...
.Pp
Return statements returning multiple values are permitted internally in a
channel program script, but attempting to return more than one value from the
top level of the channel program is not permitted and will throw an error.
However, tables containing multiple values can still be returned.
If invoked from the command line, a return statement:
.Bd -literal -offset indent
.Bd -literal -compact -offset indent
a = {foo="bar", baz=2}
return a
.Ed
.Pp
Will be output formatted as:
.Bd -literal -offset indent
.Bd -literal -compact -offset indent
Channel program fully executed with return value:
return:
baz: 2
foo: 'bar'
.Ed
.
.Ss Fatal Errors
If the channel program encounters a fatal error while running, a non-zero exit
status will be returned.
If more information about the error is available, a singleton list will be
returned detailing the error:
.Bd -literal -offset indent
error: "error string, including Lua stack trace"
.Ed
.Dl error: \&"error string, including Lua stack trace"
.Pp
If a fatal error is returned, the channel program may have not executed at all,
may have partially executed, or may have fully executed but failed to pass a
@@ -162,6 +164,7 @@ return an error code and the channel program continues executing.
See the
.Sx ZFS API
section below for function-specific details on error return codes.
.
.Ss Lua to C Value Conversion
When invoking a channel program via the libZFS interface, it is necessary to
translate arguments and return values from Lua values to their C equivalents,
@@ -171,37 +174,37 @@ There is a correspondence between nvlist values in C and Lua tables.
A Lua table which is returned from the channel program will be recursively
converted to an nvlist, with table values converted to their natural
equivalents:
.Bd -literal -offset indent
string -> string
number -> int64
boolean -> boolean_value
nil -> boolean (no value)
table -> nvlist
.Ed
.TS
cw3 l c l .
string -> string
number -> int64
boolean -> boolean_value
nil -> boolean (no value)
table -> nvlist
.TE
.Pp
Likewise, table keys are replaced by string equivalents as follows:
.Bd -literal -offset indent
string -> no change
number -> signed decimal string ("%lld")
boolean -> "true" | "false"
.Ed
.TS
cw3 l c l .
string -> no change
number -> signed decimal string ("%lld")
boolean -> "true" | "false"
.TE
.Pp
Any collision of table key strings (for example, the string "true" and a
true boolean value) will cause a fatal error.
.Pp
Lua numbers are represented internally as signed 64-bit integers.
.
.Sh LUA STANDARD LIBRARY
The following Lua built-in base library functions are available:
.Bd -literal -offset indent
assert rawlen
collectgarbage rawget
error rawset
getmetatable select
ipairs setmetatable
next tonumber
pairs tostring
rawequal type
.Ed
.TS
cw3 l l l l .
assert rawlen collectgarbage rawget
error rawset getmetatable select
ipairs setmetatable next tonumber
pairs tostring rawequal type
.TE
.Pp
All functions in the
.Em coroutine ,
@@ -214,15 +217,13 @@ manual.
.Pp
The following functions base library functions have been disabled and are
not available for use in channel programs:
.Bd -literal -offset indent
dofile
loadfile
load
pcall
print
xpcall
.Ed
.TS
cw3 l l l l l l .
dofile loadfile load pcall print xpcall
.TE
.
.Sh ZFS API
.
.Ss Function Arguments
Each API function takes a fixed set of required positional arguments and
optional keyword arguments.
@@ -231,22 +232,17 @@ For example, the destroy function takes a single positional string argument
argument.
When using parentheses to specify the arguments to a Lua function, only
positional arguments can be used:
.Bd -literal -offset indent
zfs.sync.destroy("rpool@snap")
.Ed
.Dl Sy zfs.sync.destroy Ns Pq \&"rpool@snap"
.Pp
To use keyword arguments, functions must be called with a single argument that
is a Lua table containing entries mapping integers to positional arguments and
strings to keyword arguments:
.Bd -literal -offset indent
zfs.sync.destroy({1="rpool@snap", defer=true})
.Ed
.Dl Sy zfs.sync.destroy Ns Pq {1="rpool@snap", defer=true}
.Pp
The Lua language allows curly braces to be used in place of parenthesis as
syntactic sugar for this calling convention:
.Bd -literal -offset indent
zfs.sync.snapshot{"rpool@snap", defer=true}
.Ed
.Dl Sy zfs.sync.snapshot Ns {"rpool@snap", defer=true}
.
.Ss Function Return Values
If an API function succeeds, it returns 0.
If it fails, it returns an error code and the channel program continues
@@ -261,13 +257,11 @@ Lua table, or Nil if no error details were returned.
Different keys will exist in the error details table depending on the function
and error case.
Any such function may be called expecting a single return value:
.Bd -literal -offset indent
errno = zfs.sync.promote(dataset)
.Ed
.Dl errno = Sy zfs.sync.promote Ns Pq dataset
.Pp
Or, the error details can be retrieved:
.Bd -literal -offset indent
errno, details = zfs.sync.promote(dataset)
.Bd -literal -compact -offset indent
.No errno, details = Sy zfs.sync.promote Ns Pq dataset
if (errno == EEXIST) then
assert(details ~= Nil)
list_of_conflicting_snapshots = details
@@ -276,48 +270,46 @@ end
.Pp
The following global aliases for API function error return codes are defined
for use in channel programs:
.Bd -literal -offset indent
EPERM ECHILD ENODEV ENOSPC
ENOENT EAGAIN ENOTDIR ESPIPE
ESRCH ENOMEM EISDIR EROFS
EINTR EACCES EINVAL EMLINK
EIO EFAULT ENFILE EPIPE
ENXIO ENOTBLK EMFILE EDOM
E2BIG EBUSY ENOTTY ERANGE
ENOEXEC EEXIST ETXTBSY EDQUOT
EBADF EXDEV EFBIG
.Ed
.TS
cw3 l l l l l l l .
EPERM ECHILD ENODEV ENOSPC ENOENT EAGAIN ENOTDIR
ESPIPE ESRCH ENOMEM EISDIR EROFS EINTR EACCES
EINVAL EMLINK EIO EFAULT ENFILE EPIPE ENXIO
ENOTBLK EMFILE EDOM E2BIG EBUSY ENOTTY ERANGE
ENOEXEC EEXIST ETXTBSY EDQUOT EBADF EXDEV EFBIG
.TE
.
.Ss API Functions
For detailed descriptions of the exact behavior of any zfs administrative
For detailed descriptions of the exact behavior of any ZFS administrative
operations, see the main
.Xr zfs 8
manual page.
.Bl -tag -width "xx"
.It Em zfs.debug(msg)
.It Fn zfs.debug msg
Record a debug message in the zfs_dbgmsg log.
A log of these messages can be printed via mdb's "::zfs_dbgmsg" command, or
can be monitored live by running:
.Bd -literal -offset indent
dtrace -n 'zfs-dbgmsg{trace(stringof(arg0))}'
.Ed
can be monitored live by running
.Dl dtrace -n 'zfs-dbgmsg{trace(stringof(arg0))}'
.Pp
msg (string)
.Bd -ragged -compact -offset "xxxx"
.Bl -tag -compact -width "property (string)"
.It Ar msg Pq string
Debug message to be printed.
.Ed
.It Em zfs.exists(dataset)
.El
.It Fn zfs.exists dataset
Returns true if the given dataset exists, or false if it doesn't.
A fatal error will be thrown if the dataset is not in the target pool.
That is, in a channel program running on rpool,
zfs.exists("rpool/nonexistent_fs") returns false, but
zfs.exists("somepool/fs_that_may_exist") will error.
.Sy zfs.exists Ns Pq \&"rpool/nonexistent_fs"
returns false, but
.Sy zfs.exists Ns Pq \&"somepool/fs_that_may_exist"
will error.
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
.Bl -tag -compact -width "property (string)"
.It Ar dataset Pq string
Dataset to check for existence.
Must be in the target pool.
.Ed
.It Em zfs.get_prop(dataset, property)
.El
.It Fn zfs.get_prop dataset property
Returns two values.
First, a string, number or table containing the property value for the given
dataset.
@@ -326,22 +318,25 @@ dataset in which it was set or nil if it is readonly).
Throws a Lua error if the dataset is invalid or the property doesn't exist.
Note that Lua only supports int64 number types whereas ZFS number properties
are uint64.
This means very large values (like guid) may wrap around and appear negative.
This means very large values (like GUIDs) may wrap around and appear negative.
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
.Bl -tag -compact -width "property (string)"
.It Ar dataset Pq string
Filesystem or snapshot path to retrieve properties from.
.Ed
.Pp
property (string)
.Bd -ragged -compact -offset "xxxx"
.It Ar property Pq string
Name of property to retrieve.
All filesystem, snapshot and volume properties are supported except
for 'mounted' and 'iscsioptions.'
Also supports the 'written@snap' and 'written#bookmark' properties and
the '<user|group><quota|used>@id' properties, though the id must be in numeric
form.
.Ed
All filesystem, snapshot and volume properties are supported except for
.Sy mounted
and
.Sy iscsioptions .
Also supports the
.Sy written@ Ns Ar snap
and
.Sy written# Ns Ar bookmark
properties and the
.Ao Sy user Ns | Ns Sy group Ac Ns Ao Sy quota Ns | Ns Sy used Ac Ns Sy @ Ns Ar id
properties, though the id must be in numeric form.
.El
.El
.Bl -tag -width "xx"
.It Sy zfs.sync submodule
@@ -350,86 +345,73 @@ They are executed in "syncing context".
.Pp
The available sync submodule functions are as follows:
.Bl -tag -width "xx"
.It Em zfs.sync.destroy(dataset, [defer=true|false])
.It Sy zfs.sync.destroy Ns Pq Ar dataset , Op Ar defer Ns = Ns Sy true Ns | Ns Sy false
Destroy the given dataset.
Returns 0 on successful destroy, or a nonzero error code if the dataset could
not be destroyed (for example, if the dataset has any active children or
clones).
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
.Bl -tag -compact -width "newbookmark (string)"
.It Ar dataset Pq string
Filesystem or snapshot to be destroyed.
.Ed
.Pp
[optional] defer (boolean)
.Bd -ragged -compact -offset "xxxx"
.It Op Ar defer Pq boolean
Valid only for destroying snapshots.
If set to true, and the snapshot has holds or clones, allows the snapshot to be
marked for deferred deletion rather than failing.
.Ed
.It Em zfs.sync.inherit(dataset, property)
.El
.It Fn zfs.sync.inherit dataset property
Clears the specified property in the given dataset, causing it to be inherited
from an ancestor, or restored to the default if no ancestor property is set.
The
.Ql zfs inherit -S
.Nm zfs Cm inherit Fl S
option has not been implemented.
Returns 0 on success, or a nonzero error code if the property could not be
cleared.
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
.Bl -tag -compact -width "newbookmark (string)"
.It Ar dataset Pq string
Filesystem or snapshot containing the property to clear.
.Ed
.Pp
property (string)
.Bd -ragged -compact -offset "xxxx"
.It Ar property Pq string
The property to clear.
Allowed properties are the same as those for the
.Nm zfs Cm inherit
command.
.Ed
.It Em zfs.sync.promote(dataset)
.El
.It Fn zfs.sync.promote dataset
Promote the given clone to a filesystem.
Returns 0 on successful promotion, or a nonzero error code otherwise.
If EEXIST is returned, the second return value will be an array of the clone's
snapshots whose names collide with snapshots of the parent filesystem.
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
.Bl -tag -compact -width "newbookmark (string)"
.It Ar dataset Pq string
Clone to be promoted.
.Ed
.It Em zfs.sync.rollback(filesystem)
.El
.It Fn zfs.sync.rollback filesystem
Rollback to the previous snapshot for a dataset.
Returns 0 on successful rollback, or a nonzero error code otherwise.
Rollbacks can be performed on filesystems or zvols, but not on snapshots
or mounted datasets.
EBUSY is returned in the case where the filesystem is mounted.
.Pp
filesystem (string)
.Bd -ragged -compact -offset "xxxx"
.Bl -tag -compact -width "newbookmark (string)"
.It Ar filesystem Pq string
Filesystem to rollback.
.Ed
.It Em zfs.sync.set_prop(dataset, property, value)
.El
.It Fn zfs.sync.set_prop dataset property value
Sets the given property on a dataset.
Currently only user properties are supported.
Returns 0 if the property was set, or a nonzero error code otherwise.
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
.Bl -tag -compact -width "newbookmark (string)"
.It Ar dataset Pq string
The dataset where the property will be set.
.Ed
.Pp
property (string)
.Bd -ragged -compact -offset "xxxx"
.It Ar property Pq string
The property to set.
Only user properties are supported.
.Ed
.Pp
value (string)
.Bd -ragged -compact -offset "xxxx"
.It Ar value Pq string
The value of the property to be set.
.Ed
.It Em zfs.sync.snapshot(dataset)
.El
.It Fn zfs.sync.snapshot dataset
Create a snapshot of a filesystem.
Returns 0 if the snapshot was successfully created,
and a nonzero error code otherwise.
@@ -437,132 +419,142 @@ and a nonzero error code otherwise.
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"
.Bl -tag -compact -width "newbookmark (string)"
.It Ar dataset Pq string
Name of snapshot to create.
.Ed
.It Em zfs.sync.bookmark(source, newbookmark)
.El
.It Fn zfs.sync.bookmark source newbookmark
Create a bookmark of an existing source snapshot or bookmark.
Returns 0 if the new bookmark was successfully created,
and a nonzero error code otherwise.
.Pp
Note: Bookmarking requires the corresponding pool feature to be enabled.
.Pp
source (string)
.Bd -ragged -compact -offset "xxxx"
.Bl -tag -compact -width "newbookmark (string)"
.It Ar source Pq string
Full name of the existing snapshot or bookmark.
.Ed
.Pp
newbookmark (string)
.Bd -ragged -compact -offset "xxxx"
.It Ar newbookmark Pq string
Full name of the new bookmark.
.El
.Ed
.El
.It Sy zfs.check submodule
For each function in the zfs.sync submodule, there is a corresponding zfs.check
For each function in the
.Sy zfs.sync
submodule, there is a corresponding
.Sy zfs.check
function which performs a "dry run" of the same operation.
Each takes the same arguments as its zfs.sync counterpart and returns 0 if the
operation would succeed, or a non-zero error code if it would fail, along with
any other error details.
Each takes the same arguments as its
.Sy zfs.sync
counterpart and returns 0 if the operation would succeed,
or a non-zero error code if it would fail, along with any other error details.
That is, each has the same behavior as the corresponding sync function except
for actually executing the requested change.
For example,
.Em zfs.check.destroy("fs")
.Fn zfs.check.destroy \&"fs"
returns 0 if
.Em zfs.sync.destroy("fs")
.Fn zfs.sync.destroy \&"fs"
would successfully destroy the dataset.
.Pp
The available zfs.check functions are:
.Bl -tag -width "xx"
.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.set_property(dataset, property, value)
.It Em zfs.check.snapshot(dataset)
The available
.Sy zfs.check
functions are:
.Bl -tag -compact -width "xx"
.It Sy zfs.check.destroy Ns Pq Ar dataset , Op Ar defer Ns = Ns Sy true Ns | Ns Sy false
.It Fn zfs.check.promote dataset
.It Fn zfs.check.rollback filesystem
.It Fn zfs.check.set_property dataset property value
.It Fn zfs.check.snapshot dataset
.El
.It Sy zfs.list submodule
The zfs.list submodule provides functions for iterating over datasets and
properties.
Rather than returning tables, these functions act as Lua iterators, and are
generally used as follows:
.Bd -literal -offset indent
for child in zfs.list.children("rpool") do
.Bd -literal -compact -offset indent
.No for child in Fn zfs.list.children \&"rpool" No do
...
end
.Ed
.Pp
The available zfs.list functions are:
The available
.Sy zfs.list
functions are:
.Bl -tag -width "xx"
.It Em zfs.list.clones(snapshot)
.It Fn zfs.list.clones snapshot
Iterate through all clones of the given snapshot.
.Pp
snapshot (string)
.Bd -ragged -compact -offset "xxxx"
.Bl -tag -compact -width "snapshot (string)"
.It Ar snapshot Pq string
Must be a valid snapshot path in the current pool.
.Ed
.It Em zfs.list.snapshots(dataset)
.El
.It Fn zfs.list.snapshots dataset
Iterate through all snapshots of the given dataset.
Each snapshot is returned as a string containing the full dataset name, e.g.
"pool/fs@snap".
Each snapshot is returned as a string containing the full dataset name,
e.g. "pool/fs@snap".
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
.Bl -tag -compact -width "snapshot (string)"
.It Ar dataset Pq string
Must be a valid filesystem or volume.
.Ed
.It Em zfs.list.children(dataset)
.El
.It Fn zfs.list.children dataset
Iterate through all direct children of the given dataset.
Each child is returned as a string containing the full dataset name, e.g.
"pool/fs/child".
Each child is returned as a string containing the full dataset name,
e.g. "pool/fs/child".
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
.Bl -tag -compact -width "snapshot (string)"
.It Ar dataset Pq string
Must be a valid filesystem or volume.
.Ed
.It Em zfs.list.bookmarks(dataset)
Iterate through all bookmarks of the given dataset. Each bookmark is returned
as a string containing the full dataset name, e.g. "pool/fs#bookmark".
.El
.It Fn zfs.list.bookmarks dataset
Iterate through all bookmarks of the given dataset.
Each bookmark is returned as a string containing the full dataset name,
e.g. "pool/fs#bookmark".
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
.Bl -tag -compact -width "snapshot (string)"
.It Ar dataset Pq string
Must be a valid filesystem or volume.
.Ed
.It Em zfs.list.holds(snapshot)
Iterate through all user holds on the given snapshot. Each hold is returned
.El
.It Fn zfs.list.holds snapshot
Iterate through all user holds on the given snapshot.
Each hold is returned
as a pair of the hold's tag and the timestamp (in seconds since the epoch) at
which it was created.
.Pp
snapshot (string)
.Bd -ragged -compact -offset "xxxx"
.Bl -tag -compact -width "snapshot (string)"
.It Ar snapshot Pq string
Must be a valid snapshot.
.Ed
.It Em zfs.list.properties(dataset)
.El
.It Fn zfs.list.properties dataset
An alias for zfs.list.user_properties (see relevant entry).
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
.Bl -tag -compact -width "snapshot (string)"
.It Ar dataset Pq string
Must be a valid filesystem, snapshot, or volume.
.Ed
.It Em zfs.list.user_properties(dataset)
Iterate through all user properties for the given dataset. For each
step of the iteration, output the property name, its value, and its source.
.El
.It Fn zfs.list.user_properties dataset
Iterate through all user properties for the given dataset.
For each step of the iteration, output the property name, its value,
and its source.
Throws a Lua error if the dataset is invalid.
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
.Bl -tag -compact -width "snapshot (string)"
.It Ar dataset Pq string
Must be a valid filesystem, snapshot, or volume.
.Ed
.It Em zfs.list.system_properties(dataset)
.El
.It Fn zfs.list.system_properties dataset
Returns an array of strings, the names of the valid system (non-user defined)
properties for the given dataset.
Throws a Lua error if the dataset is invalid.
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
.Bl -tag -compact -width "snapshot (string)"
.It Ar dataset Pq string
Must be a valid filesystem, snapshot or volume.
.Ed
.El
.El
.El
.
.Sh EXAMPLES
.
.Ss Example 1
The following channel program recursively destroys a filesystem and all its
snapshots and children in a naive manner.
@@ -579,6 +571,7 @@ function destroy_recursive(root)
end
destroy_recursive("pool/somefs")
.Ed
.
.Ss Example 2
A more verbose and robust version of the same channel program, which
properly detects and reports errors, and also takes the dataset to destroy
@@ -617,6 +610,7 @@ results["succeeded"] = succeeded
results["failed"] = failed
return results
.Ed
.
.Ss Example 3
The following function performs a forced promote operation by attempting to
promote the given clone and destroying any conflicting snapshots.