From 1d4faef7a5e4864af3024cc521ea243c4d90cff6 Mon Sep 17 00:00:00 2001 From: Clint Armstrong Date: Tue, 30 Jul 2019 19:02:19 -0400 Subject: [PATCH] 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 Reviewed-by: Brian Behlendorf Signed-off-by: Clint Armstrong Closes #8443 Closes #9050 --- configure.ac | 1 + contrib/Makefile.am | 4 +-- contrib/zcp/Makefile.am | 1 + contrib/zcp/autosnap.lua | 75 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 contrib/zcp/Makefile.am create mode 100644 contrib/zcp/autosnap.lua diff --git a/configure.ac b/configure.ac index a3ac134ff..46a27f7f1 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 autosnap.lua -- [-n] [-p ] + +results = {} + +args = ... +argv = args["argv"] +usage = [[ + + +usage: zfs program autosnap.lua -- [-n] [-p ] + + -n: performs checks only, does not take snapshots + -p : property to check. [default: com.sun:auto-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