xref: /freebsd/sys/contrib/openzfs/man/man8/zfs-program.8 (revision 61145dc2b94f12f6a47344fb9aac702321880e43)
1.\" SPDX-License-Identifier: CDDL-1.0
2.\"
3.\" This file and its contents are supplied under the terms of the
4.\" Common Development and Distribution License ("CDDL"), version 1.0.
5.\" You may only use this file in accordance with the terms of version
6.\" 1.0 of the CDDL.
7.\"
8.\" A full copy of the text of the CDDL should have accompanied this
9.\" source.  A copy of the CDDL is also available via the Internet at
10.\" http://www.illumos.org/license/CDDL.
11.\"
12.\" Copyright (c) 2016, 2019 by Delphix. All Rights Reserved.
13.\" Copyright (c) 2019, 2020 by Christian Schwarz. All Rights Reserved.
14.\" Copyright 2020 Joyent, Inc.
15.\"
16.Dd May 27, 2021
17.Dt ZFS-PROGRAM 8
18.Os
19.
20.Sh NAME
21.Nm zfs-program
22.Nd execute ZFS channel programs
23.Sh SYNOPSIS
24.Nm zfs
25.Cm program
26.Op Fl jn
27.Op Fl t Ar instruction-limit
28.Op Fl m Ar memory-limit
29.Ar pool
30.Ar script
31.Op Ar script arguments
32.
33.Sh DESCRIPTION
34The ZFS channel program interface allows ZFS administrative operations to be
35run programmatically as a Lua script.
36The entire script is executed atomically, with no other administrative
37operations taking effect concurrently.
38A library of ZFS calls is made available to channel program scripts.
39Channel programs may only be run with root privileges.
40.Pp
41A modified version of the Lua 5.2 interpreter is used to run channel program
42scripts.
43The Lua 5.2 manual can be found at
44.Lk http://www.lua.org/manual/5.2/
45.Pp
46The channel program given by
47.Ar script
48will be run on
49.Ar pool ,
50and any attempts to access or modify other pools will cause an error.
51.
52.Sh OPTIONS
53.Bl -tag -width "-t"
54.It Fl j , -json
55Display channel program output in JSON format.
56When this flag is specified and standard output is empty -
57channel program encountered an error.
58The details of such an error will be printed to standard error in plain text.
59.It Fl n
60Executes a read-only channel program, which runs faster.
61The program cannot change on-disk state by calling functions from the
62zfs.sync submodule.
63The program can be used to gather information such as properties and
64determining if changes would succeed (zfs.check.*).
65Without this flag, all pending changes must be synced to disk before a
66channel program can complete.
67.It Fl t Ar instruction-limit
68Limit the number of Lua instructions to execute.
69If a channel program executes more than the specified number of instructions,
70it will be stopped and an error will be returned.
71The default limit is 10 million instructions, and it can be set to a maximum of
72100 million instructions.
73.It Fl m Ar memory-limit
74Memory limit, in bytes.
75If a channel program attempts to allocate more memory than the given limit, it
76will be stopped and an error returned.
77The default memory limit is 10 MiB, and can be set to a maximum of 100 MiB.
78.El
79.Pp
80All remaining argument strings will be passed directly to the Lua script as
81described in the
82.Sx LUA INTERFACE
83section below.
84.
85.Sh LUA INTERFACE
86A channel program can be invoked either from the command line, or via a library
87call to
88.Fn lzc_channel_program .
89.
90.Ss Arguments
91Arguments passed to the channel program are converted to a Lua table.
92If invoked from the command line, extra arguments to the Lua script will be
93accessible as an array stored in the argument table with the key 'argv':
94.Bd -literal -compact -offset indent
95args = ...
96argv = args["argv"]
97-- argv == {1="arg1", 2="arg2", ...}
98.Ed
99.Pp
100If invoked from the libzfs interface, an arbitrary argument list can be
101passed to the channel program, which is accessible via the same
102.Qq Li ...
103syntax in Lua:
104.Bd -literal -compact -offset indent
105args = ...
106-- args == {"foo"="bar", "baz"={...}, ...}
107.Ed
108.Pp
109Note that because Lua arrays are 1-indexed, arrays passed to Lua from the
110libzfs interface will have their indices incremented by 1.
111That is, the element
112in
113.Va arr[0]
114in a C array passed to a channel program will be stored in
115.Va arr[1]
116when accessed from Lua.
117.
118.Ss Return Values
119Lua return statements take the form:
120.Dl return ret0, ret1, ret2, ...
121.Pp
122Return statements returning multiple values are permitted internally in a
123channel program script, but attempting to return more than one value from the
124top level of the channel program is not permitted and will throw an error.
125However, tables containing multiple values can still be returned.
126If invoked from the command line, a return statement:
127.Bd -literal -compact -offset indent
128a = {foo="bar", baz=2}
129return a
130.Ed
131.Pp
132Will be output formatted as:
133.Bd -literal -compact -offset indent
134Channel program fully executed with return value:
135    return:
136        baz: 2
137        foo: 'bar'
138.Ed
139.
140.Ss Fatal Errors
141If the channel program encounters a fatal error while running, a non-zero exit
142status will be returned.
143If more information about the error is available, a singleton list will be
144returned detailing the error:
145.Dl error: \&"error string, including Lua stack trace"
146.Pp
147If a fatal error is returned, the channel program may have not executed at all,
148may have partially executed, or may have fully executed but failed to pass a
149return value back to userland.
150.Pp
151If the channel program exhausts an instruction or memory limit, a fatal error
152will be generated and the program will be stopped, leaving the program partially
153executed.
154No attempt is made to reverse or undo any operations already performed.
155Note that because both the instruction count and amount of memory used by a
156channel program are deterministic when run against the same inputs and
157filesystem state, as long as a channel program has run successfully once, you
158can guarantee that it will finish successfully against a similar size system.
159.Pp
160If a channel program attempts to return too large a value, the program will
161fully execute but exit with a nonzero status code and no return value.
162.Pp
163.Em Note :
164ZFS API functions do not generate Fatal Errors when correctly invoked, they
165return an error code and the channel program continues executing.
166See the
167.Sx ZFS API
168section below for function-specific details on error return codes.
169.
170.Ss Lua to C Value Conversion
171When invoking a channel program via the libzfs interface, it is necessary to
172translate arguments and return values from Lua values to their C equivalents,
173and vice-versa.
174.Pp
175There is a correspondence between nvlist values in C and Lua tables.
176A Lua table which is returned from the channel program will be recursively
177converted to an nvlist, with table values converted to their natural
178equivalents:
179.TS
180cw3 l c l .
181	string	->	string
182	number	->	int64
183	boolean	->	boolean_value
184	nil	->	boolean (no value)
185	table	->	nvlist
186.TE
187.Pp
188Likewise, table keys are replaced by string equivalents as follows:
189.TS
190cw3 l c l .
191	string	->	no change
192	number	->	signed decimal string ("%lld")
193	boolean	->	"true" | "false"
194.TE
195.Pp
196Any collision of table key strings (for example, the string "true" and a
197true boolean value) will cause a fatal error.
198.Pp
199Lua numbers are represented internally as signed 64-bit integers.
200.
201.Sh LUA STANDARD LIBRARY
202The following Lua built-in base library functions are available:
203.TS
204cw3 l l l l .
205	assert	rawlen	collectgarbage	rawget
206	error	rawset	getmetatable	select
207	ipairs	setmetatable	next	tonumber
208	pairs	tostring	rawequal	type
209.TE
210.Pp
211All functions in the
212.Em coroutine ,
213.Em string ,
214and
215.Em table
216built-in submodules are also available.
217A complete list and documentation of these modules is available in the Lua
218manual.
219.Pp
220The following functions base library functions have been disabled and are
221not available for use in channel programs:
222.TS
223cw3 l l l l l l .
224	dofile	loadfile	load	pcall	print	xpcall
225.TE
226.
227.Sh ZFS API
228.
229.Ss Function Arguments
230Each API function takes a fixed set of required positional arguments and
231optional keyword arguments.
232For example, the destroy function takes a single positional string argument
233(the name of the dataset to destroy) and an optional "defer" keyword boolean
234argument.
235When using parentheses to specify the arguments to a Lua function, only
236positional arguments can be used:
237.Dl Sy zfs.sync.destroy Ns Pq \&"rpool@snap"
238.Pp
239To use keyword arguments, functions must be called with a single argument that
240is a Lua table containing entries mapping integers to positional arguments and
241strings to keyword arguments:
242.Dl Sy zfs.sync.destroy Ns Pq {1="rpool@snap", defer=true}
243.Pp
244The Lua language allows curly braces to be used in place of parenthesis as
245syntactic sugar for this calling convention:
246.Dl Sy zfs.sync.snapshot Ns {"rpool@snap", defer=true}
247.
248.Ss Function Return Values
249If an API function succeeds, it returns 0.
250If it fails, it returns an error code and the channel program continues
251executing.
252API functions do not generate Fatal Errors except in the case of an
253unrecoverable internal file system error.
254.Pp
255In addition to returning an error code, some functions also return extra
256details describing what caused the error.
257This extra description is given as a second return value, and will always be a
258Lua table, or Nil if no error details were returned.
259Different keys will exist in the error details table depending on the function
260and error case.
261Any such function may be called expecting a single return value:
262.Dl errno = Sy zfs.sync.promote Ns Pq dataset
263.Pp
264Or, the error details can be retrieved:
265.Bd -literal -compact -offset indent
266.No errno, details = Sy zfs.sync.promote Ns Pq dataset
267if (errno == EEXIST) then
268    assert(details ~= Nil)
269    list_of_conflicting_snapshots = details
270end
271.Ed
272.Pp
273The following global aliases for API function error return codes are defined
274for use in channel programs:
275.TS
276cw3 l l l l l l l .
277	EPERM	ECHILD	ENODEV	ENOSPC	ENOENT	EAGAIN	ENOTDIR
278	ESPIPE	ESRCH	ENOMEM	EISDIR	EROFS	EINTR	EACCES
279	EINVAL	EMLINK	EIO	EFAULT	ENFILE	EPIPE	ENXIO
280	ENOTBLK	EMFILE	EDOM	E2BIG	EBUSY	ENOTTY	ERANGE
281	ENOEXEC	EEXIST	ETXTBSY	EDQUOT	EBADF	EXDEV	EFBIG
282.TE
283.
284.Ss API Functions
285For detailed descriptions of the exact behavior of any ZFS administrative
286operations, see the main
287.Xr zfs 8
288manual page.
289.Bl -tag -width "xx"
290.It Fn zfs.debug msg
291Record a debug message in the zfs_dbgmsg log.
292A log of these messages can be printed via mdb's "::zfs_dbgmsg" command, or
293can be monitored live by running
294.Dl dtrace -n 'zfs-dbgmsg{trace(stringof(arg0))}'
295.Pp
296.Bl -tag -compact -width "property (string)"
297.It Ar msg Pq string
298Debug message to be printed.
299.El
300.It Fn zfs.exists dataset
301Returns true if the given dataset exists, or false if it doesn't.
302A fatal error will be thrown if the dataset is not in the target pool.
303That is, in a channel program running on rpool,
304.Sy zfs.exists Ns Pq \&"rpool/nonexistent_fs"
305returns false, but
306.Sy zfs.exists Ns Pq \&"somepool/fs_that_may_exist"
307will error.
308.Pp
309.Bl -tag -compact -width "property (string)"
310.It Ar dataset Pq string
311Dataset to check for existence.
312Must be in the target pool.
313.El
314.It Fn zfs.get_prop dataset property
315Returns two values.
316First, a string, number or table containing the property value for the given
317dataset.
318Second, a string containing the source of the property (i.e. the name of the
319dataset in which it was set or nil if it is readonly).
320Throws a Lua error if the dataset is invalid or the property doesn't exist.
321Note that Lua only supports int64 number types whereas ZFS number properties
322are uint64.
323This means very large values (like GUIDs) may wrap around and appear negative.
324.Pp
325.Bl -tag -compact -width "property (string)"
326.It Ar dataset Pq string
327Filesystem or snapshot path to retrieve properties from.
328.It Ar property Pq string
329Name of property to retrieve.
330All filesystem, snapshot and volume properties are supported except for
331.Sy mounted
332and
333.Sy iscsioptions .
334Also supports the
335.Sy written@ Ns Ar snap
336and
337.Sy written# Ns Ar bookmark
338properties and the
339.Ao Sy user Ns | Ns Sy group Ac Ns Ao Sy quota Ns | Ns Sy used Ac Ns Sy @ Ns Ar id
340properties, though the id must be in numeric form.
341.El
342.El
343.Bl -tag -width "xx"
344.It Sy zfs.sync submodule
345The sync submodule contains functions that modify the on-disk state.
346They are executed in "syncing context".
347.Pp
348The available sync submodule functions are as follows:
349.Bl -tag -width "xx"
350.It Sy zfs.sync.destroy Ns Pq Ar dataset , Op Ar defer Ns = Ns Sy true Ns | Ns Sy false
351Destroy the given dataset.
352Returns 0 on successful destroy, or a nonzero error code if the dataset could
353not be destroyed (for example, if the dataset has any active children or
354clones).
355.Pp
356.Bl -tag -compact -width "newbookmark (string)"
357.It Ar dataset Pq string
358Filesystem or snapshot to be destroyed.
359.It Op Ar defer Pq boolean
360Valid only for destroying snapshots.
361If set to true, and the snapshot has holds or clones, allows the snapshot to be
362marked for deferred deletion rather than failing.
363.El
364.It Fn zfs.sync.inherit dataset property
365Clears the specified property in the given dataset, causing it to be inherited
366from an ancestor, or restored to the default if no ancestor property is set.
367The
368.Nm zfs Cm inherit Fl S
369option has not been implemented.
370Returns 0 on success, or a nonzero error code if the property could not be
371cleared.
372.Pp
373.Bl -tag -compact -width "newbookmark (string)"
374.It Ar dataset Pq string
375Filesystem or snapshot containing the property to clear.
376.It Ar property Pq string
377The property to clear.
378Allowed properties are the same as those for the
379.Nm zfs Cm inherit
380command.
381.El
382.It Fn zfs.sync.promote dataset
383Promote the given clone to a filesystem.
384Returns 0 on successful promotion, or a nonzero error code otherwise.
385If EEXIST is returned, the second return value will be an array of the clone's
386snapshots whose names collide with snapshots of the parent filesystem.
387.Pp
388.Bl -tag -compact -width "newbookmark (string)"
389.It Ar dataset Pq string
390Clone to be promoted.
391.El
392.It Fn zfs.sync.rollback filesystem
393Rollback to the previous snapshot for a dataset.
394Returns 0 on successful rollback, or a nonzero error code otherwise.
395Rollbacks can be performed on filesystems or zvols, but not on snapshots
396or mounted datasets.
397EBUSY is returned in the case where the filesystem is mounted.
398.Pp
399.Bl -tag -compact -width "newbookmark (string)"
400.It Ar filesystem Pq string
401Filesystem to rollback.
402.El
403.It Fn zfs.sync.set_prop dataset property value
404Sets the given property on a dataset.
405Currently only user properties are supported.
406Returns 0 if the property was set, or a nonzero error code otherwise.
407.Pp
408.Bl -tag -compact -width "newbookmark (string)"
409.It Ar dataset Pq string
410The dataset where the property will be set.
411.It Ar property Pq string
412The property to set.
413.It Ar value Pq string
414The value of the property to be set.
415.El
416.It Fn zfs.sync.snapshot dataset
417Create a snapshot of a filesystem.
418Returns 0 if the snapshot was successfully created,
419and a nonzero error code otherwise.
420.Pp
421Note: Taking a snapshot will fail on any pool older than legacy version 27.
422To enable taking snapshots from ZCP scripts, the pool must be upgraded.
423.Pp
424.Bl -tag -compact -width "newbookmark (string)"
425.It Ar dataset Pq string
426Name of snapshot to create.
427.El
428.It Fn zfs.sync.rename_snapshot dataset oldsnapname newsnapname
429Rename a snapshot of a filesystem or a volume.
430Returns 0 if the snapshot was successfully renamed,
431and a nonzero error code otherwise.
432.Pp
433.Bl -tag -compact -width "newbookmark (string)"
434.It Ar dataset Pq string
435Name of the snapshot's parent dataset.
436.It Ar oldsnapname Pq string
437Original name of the snapshot.
438.It Ar newsnapname Pq string
439New name of the snapshot.
440.El
441.It Fn zfs.sync.bookmark source newbookmark
442Create a bookmark of an existing source snapshot or bookmark.
443Returns 0 if the new bookmark was successfully created,
444and a nonzero error code otherwise.
445.Pp
446Note: Bookmarking requires the corresponding pool feature to be enabled.
447.Pp
448.Bl -tag -compact -width "newbookmark (string)"
449.It Ar source Pq string
450Full name of the existing snapshot or bookmark.
451.It Ar newbookmark Pq string
452Full name of the new bookmark.
453.El
454.El
455.It Sy zfs.check submodule
456For each function in the
457.Sy zfs.sync
458submodule, there is a corresponding
459.Sy zfs.check
460function which performs a "dry run" of the same operation.
461Each takes the same arguments as its
462.Sy zfs.sync
463counterpart and returns 0 if the operation would succeed,
464or a non-zero error code if it would fail, along with any other error details.
465That is, each has the same behavior as the corresponding sync function except
466for actually executing the requested change.
467For example,
468.Fn zfs.check.destroy \&"fs"
469returns 0 if
470.Fn zfs.sync.destroy \&"fs"
471would successfully destroy the dataset.
472.Pp
473The available
474.Sy zfs.check
475functions are:
476.Bl -tag -compact -width "xx"
477.It Sy zfs.check.destroy Ns Pq Ar dataset , Op Ar defer Ns = Ns Sy true Ns | Ns Sy false
478.It Fn zfs.check.promote dataset
479.It Fn zfs.check.rollback filesystem
480.It Fn zfs.check.set_property dataset property value
481.It Fn zfs.check.snapshot dataset
482.El
483.It Sy zfs.list submodule
484The zfs.list submodule provides functions for iterating over datasets and
485properties.
486Rather than returning tables, these functions act as Lua iterators, and are
487generally used as follows:
488.Bd -literal -compact -offset indent
489.No for child in Fn zfs.list.children \&"rpool" No do
490    ...
491end
492.Ed
493.Pp
494The available
495.Sy zfs.list
496functions are:
497.Bl -tag -width "xx"
498.It Fn zfs.list.clones snapshot
499Iterate through all clones of the given snapshot.
500.Pp
501.Bl -tag -compact -width "snapshot (string)"
502.It Ar snapshot Pq string
503Must be a valid snapshot path in the current pool.
504.El
505.It Fn zfs.list.snapshots dataset
506Iterate through all snapshots of the given dataset.
507Each snapshot is returned as a string containing the full dataset name,
508e.g. "pool/fs@snap".
509.Pp
510.Bl -tag -compact -width "snapshot (string)"
511.It Ar dataset Pq string
512Must be a valid filesystem or volume.
513.El
514.It Fn zfs.list.children dataset
515Iterate through all direct children of the given dataset.
516Each child is returned as a string containing the full dataset name,
517e.g. "pool/fs/child".
518.Pp
519.Bl -tag -compact -width "snapshot (string)"
520.It Ar dataset Pq string
521Must be a valid filesystem or volume.
522.El
523.It Fn zfs.list.bookmarks dataset
524Iterate through all bookmarks of the given dataset.
525Each bookmark is returned as a string containing the full dataset name,
526e.g. "pool/fs#bookmark".
527.Pp
528.Bl -tag -compact -width "snapshot (string)"
529.It Ar dataset Pq string
530Must be a valid filesystem or volume.
531.El
532.It Fn zfs.list.holds snapshot
533Iterate through all user holds on the given snapshot.
534Each hold is returned
535as a pair of the hold's tag and the timestamp (in seconds since the epoch) at
536which it was created.
537.Pp
538.Bl -tag -compact -width "snapshot (string)"
539.It Ar snapshot Pq string
540Must be a valid snapshot.
541.El
542.It Fn zfs.list.properties dataset
543An alias for zfs.list.user_properties (see relevant entry).
544.Pp
545.Bl -tag -compact -width "snapshot (string)"
546.It Ar dataset Pq string
547Must be a valid filesystem, snapshot, or volume.
548.El
549.It Fn zfs.list.user_properties dataset
550Iterate through all user properties for the given dataset.
551For each step of the iteration, output the property name, its value,
552and its source.
553Throws a Lua error if the dataset is invalid.
554.Pp
555.Bl -tag -compact -width "snapshot (string)"
556.It Ar dataset Pq string
557Must be a valid filesystem, snapshot, or volume.
558.El
559.It Fn zfs.list.system_properties dataset
560Returns an array of strings, the names of the valid system (non-user defined)
561properties for the given dataset.
562Throws a Lua error if the dataset is invalid.
563.Pp
564.Bl -tag -compact -width "snapshot (string)"
565.It Ar dataset Pq string
566Must be a valid filesystem, snapshot or volume.
567.El
568.El
569.El
570.
571.Sh EXAMPLES
572.
573.Ss Example 1
574The following channel program recursively destroys a filesystem and all its
575snapshots and children in a naive manner.
576Note that this does not involve any error handling or reporting.
577.Bd -literal -offset indent
578function destroy_recursive(root)
579    for child in zfs.list.children(root) do
580        destroy_recursive(child)
581    end
582    for snap in zfs.list.snapshots(root) do
583        zfs.sync.destroy(snap)
584    end
585    zfs.sync.destroy(root)
586end
587destroy_recursive("pool/somefs")
588.Ed
589.
590.Ss Example 2
591A more verbose and robust version of the same channel program, which
592properly detects and reports errors, and also takes the dataset to destroy
593as a command line argument, would be as follows:
594.Bd -literal -offset indent
595succeeded = {}
596failed = {}
597
598function destroy_recursive(root)
599    for child in zfs.list.children(root) do
600        destroy_recursive(child)
601    end
602    for snap in zfs.list.snapshots(root) do
603        err = zfs.sync.destroy(snap)
604        if (err ~= 0) then
605            failed[snap] = err
606        else
607            succeeded[snap] = err
608        end
609    end
610    err = zfs.sync.destroy(root)
611    if (err ~= 0) then
612        failed[root] = err
613    else
614        succeeded[root] = err
615    end
616end
617
618args = ...
619argv = args["argv"]
620
621destroy_recursive(argv[1])
622
623results = {}
624results["succeeded"] = succeeded
625results["failed"] = failed
626return results
627.Ed
628.
629.Ss Example 3
630The following function performs a forced promote operation by attempting to
631promote the given clone and destroying any conflicting snapshots.
632.Bd -literal -offset indent
633function force_promote(ds)
634   errno, details = zfs.check.promote(ds)
635   if (errno == EEXIST) then
636       assert(details ~= Nil)
637       for i, snap in ipairs(details) do
638           zfs.sync.destroy(ds .. "@" .. snap)
639       end
640   elseif (errno ~= 0) then
641       return errno
642   end
643   return zfs.sync.promote(ds)
644end
645.Ed
646