summaryrefslogtreecommitdiffstats
path: root/contrib/zcp/autosnap.lua
diff options
context:
space:
mode:
authorClint Armstrong <[email protected]>2019-07-30 19:02:19 -0400
committerBrian Behlendorf <[email protected]>2019-07-30 16:02:19 -0700
commitf489458ad7e7214df455ac00af621e9b4369361d (patch)
tree29d2eaf83f88d067f0da59e877bf316d1979f9b1 /contrib/zcp/autosnap.lua
parent1ba4f3e7b4e15b2262802909bee50355e439c67e (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.lua75
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