1-- Recursively snapshot every dataset with a given property
2--
3-- Usage: zfs program <pool> autosnap.lua -- [-n] [-p <property>] <snapshot>
4
5results = {}
6
7args = ...
8argv = args["argv"]
9usage = [[
10
11
12usage: zfs program <pool> autosnap.lua -- [-n] [-p <property>] <snapshot>
13
14	-n: performs checks only, does not take snapshots
15	-p <property>: property to check. [default: com.sun:auto-snapshot]
16	<snapshot>: root snapshot to create [example: tank/data@backup]
17]]
18
19property = "com.sun:auto-snapshot"
20noop = false
21root_snap = nil
22
23for i, arg in ipairs(argv) do
24	if arg == "-n" then
25		noop = true
26	elseif arg == "-p" then
27	elseif argv[i-1] == "-p" then
28		property = arg
29	else
30		root_snap = arg
31	end
32end
33
34if root_snap == nil or property == nil then
35	error(usage)
36end
37
38root_ds_name = ""
39snap_name = ""
40for i = 1, #root_snap do
41	if root_snap:sub(i, i) == "@" then
42		root_ds_name = root_snap:sub(1, i-1)
43		snap_name = root_snap:sub(i+1, root_snap:len())
44	end
45end
46
47function auto_snap(root)
48	auto, source = zfs.get_prop(root, property)
49	if auto == "true" then
50		ds_snap_name = root .. "@" .. snap_name
51		err = 0
52		if noop then
53			err = zfs.check.snapshot(ds_snap_name)
54		else
55			err = zfs.sync.snapshot(ds_snap_name)
56		end
57		results[ds_snap_name] = err
58	end
59	for child in zfs.list.children(root) do
60		auto_snap(child)
61	end
62end
63
64auto_snap(root_ds_name)
65err_txt = ""
66for ds, err in pairs(results) do
67	if err ~= 0 then
68		err_txt = err_txt .. "failed to create " .. ds .. ": " .. err .. "\n"
69	end
70end
71if err_txt ~= "" then
72	error(err_txt)
73end
74
75return results
76