diff options
author | Clint Armstrong <[email protected]> | 2019-07-30 19:02:19 -0400 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2019-07-30 16:02:19 -0700 |
commit | f489458ad7e7214df455ac00af621e9b4369361d (patch) | |
tree | 29d2eaf83f88d067f0da59e877bf316d1979f9b1 /contrib/zcp/autosnap.lua | |
parent | 1ba4f3e7b4e15b2262802909bee50355e439c67e (diff) |
Add channel program for property based snapshots
Channel programs that many users find useful should be included with zfs
in the /contrib directory. This is the first of these contributions. A
channel program to recursively take snapshots of datasets with the
property com.sun:auto-snapshot=true.
Reviewed-by: Kash Pande <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Clint Armstrong <[email protected]>
Closes #8443
Closes #9050
Diffstat (limited to 'contrib/zcp/autosnap.lua')
-rw-r--r-- | contrib/zcp/autosnap.lua | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/contrib/zcp/autosnap.lua b/contrib/zcp/autosnap.lua new file mode 100644 index 000000000..d9ae32ce4 --- /dev/null +++ b/contrib/zcp/autosnap.lua @@ -0,0 +1,75 @@ +-- Recursively snapshot every dataset with a given property +-- +-- Usage: zfs program <pool> autosnap.lua -- [-n] [-p <property>] <snapshot> + +results = {} + +args = ... +argv = args["argv"] +usage = [[ + + +usage: zfs program <pool> autosnap.lua -- [-n] [-p <property>] <snapshot> + + -n: performs checks only, does not take snapshots + -p <property>: property to check. [default: com.sun:auto-snapshot] + <snapshot>: root snapshot to create [example: tank/data@backup] +]] + +property = "com.sun:auto-snapshot" +noop = false +root_snap = nil + +for i, arg in ipairs(argv) do + if arg == "-n" then + noop = true + elseif arg == "-p" then + elseif argv[i-1] == "-p" then + property = arg + else + root_snap = arg + end +end + +if root_snap == nil or property == nil then + error(usage) +end + +root_ds_name = "" +snap_name = "" +for i = 1, #root_snap do + if root_snap:sub(i, i) == "@" then + root_ds_name = root_snap:sub(1, i-1) + snap_name = root_snap:sub(i+1, root_snap:len()) + end +end + +function auto_snap(root) + auto, source = zfs.get_prop(root, property) + if auto == "true" then + ds_snap_name = root .. "@" .. snap_name + err = 0 + if noop then + err = zfs.check.snapshot(ds_snap_name) + else + err = zfs.sync.snapshot(ds_snap_name) + end + results[ds_snap_name] = err + end + for child in zfs.list.children(root) do + auto_snap(child) + end +end + +auto_snap(root_ds_name) +err_txt = "" +for ds, err in pairs(results) do + if err ~= 0 then + err_txt = err_txt .. "failed to create " .. ds .. ": " .. err .. "\n" + end +end +if err_txt ~= "" then + error(err_txt) +end + +return results |