summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--contrib/Makefile.am4
-rw-r--r--contrib/zcp/Makefile.am1
-rw-r--r--contrib/zcp/autosnap.lua75
4 files changed, 79 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac
index 0522185e4..973ae307c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -135,6 +135,7 @@ AC_CONFIG_FILES([
contrib/initramfs/scripts/local-top/Makefile
contrib/pyzfs/Makefile
contrib/pyzfs/setup.py
+ contrib/zcp/Makefile
module/Makefile
module/avl/Makefile
module/nvpair/Makefile
diff --git a/contrib/Makefile.am b/contrib/Makefile.am
index 81926a83e..9a82f82ee 100644
--- a/contrib/Makefile.am
+++ b/contrib/Makefile.am
@@ -1,2 +1,2 @@
-SUBDIRS = bash_completion.d dracut initramfs pyzfs
-DIST_SUBDIRS = bash_completion.d dracut initramfs pyzfs
+SUBDIRS = bash_completion.d dracut initramfs pyzfs zcp
+DIST_SUBDIRS = bash_completion.d dracut initramfs pyzfs zcp
diff --git a/contrib/zcp/Makefile.am b/contrib/zcp/Makefile.am
new file mode 100644
index 000000000..54d65f891
--- /dev/null
+++ b/contrib/zcp/Makefile.am
@@ -0,0 +1 @@
++EXTRA_DIST = autosnap.lua
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