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