--- ZnapZend.pm.dist 2019-11-28 17:07:17.927267363 +0100
+++ ZnapZend.pm 2019-11-28 17:44:33.203399136 +0100
@@ -336,6 +336,22 @@
#from being snapshot/sent by setting property "org.znapzend:enabled"
#to "off" on them
for my $srcDataSet (@$srcSubDataSets){
+
+ # get the value for org.znapzend property
+ my @cmd = (@{$self->zZfs->priv}, qw(zfs get -H -o value org.znapzend:enabled), $srcDataSet);
+ print STDERR '# ' . join(' ', @cmd) . "\n" if $self->debug;
+ open my $prop, '-|', @cmd;
+
+ # if the property does not exist, the command will just return. In this case,
+ # the value is implicit "on"
+ $prop = <$prop> || "on";
+ chomp($prop);
+ if ( $prop eq 'off' ) {
+ $self->zLog->debug('Skipping ' . $srcDataSet . ' due to it being explicitly disabled.');
+ next;
+ }
+
+
my $dstDataSet = $srcDataSet;
$dstDataSet =~ s/^\Q$backupSet->{src}\E/$backupSet->{$dst}/;
--- lib/ZnapZend.pm.dist 2019-11-29 00:29:36.980904411 +0100
+++ lib/ZnapZend.pm 2019-11-29 00:21:08.546796322 +0100
@@ -615,7 +615,13 @@
# removal here is non-recursive to allow for fine-grained control
if ( @dataSetsExplicitelyDisabled ){
$self->zLog->info("Requesting removal of marked datasets: ". join( ", ", @dataSetsExplicitelyDisabled));
- $self->zZfs->destroySnapshots(@dataSetsExplicitelyDisabled, 0);
+
+ # We need to explicitly call destroySnapshots for each dataSet we found
+ # because it is only designed to destroy sets of snapshots _for the same filesystem_.
+ # Since we are/have a top-level recursive snapshot, recurse here too.
+ for my $dataSetToDestroy (@dataSetsExplicitelyDisabled){
+ $self->zZfs->destroySnapshots($dataSetToDestroy, 1);
+ }
}
}
}
As a side note, it think
$self->zZfs->destroySnapshots(@dataSetsExplicitelyDisabled, 0);
should have been:
$self->zZfs->destroySnapshots(\@dataSetsExplicitelyDisabled, 0);
but my "Perl"-ish is rusty :)
Haven't found anything specific from ZoL; but if it follows Oracle ZFS ...
https://docs.oracle.com/cd/E19253-01/819-5461/gazss/index.html
...
User property names must conform to the following conventions:
-They must contain a colon (':') character to distinguish them from native properties.
-They must contain lowercase letters, numbers, or the following punctuation characters: ':', '+','.', '_'.
-The maximum length of a user property name is 256 characters.
The values of user properties must conform to the following conventions:
-They must consist of arbitrary strings that are always inherited and are never validated.
-The maximum length of the user property value is 1024 characters.
So, a json config may bump up to the max length sooner than later.
And regardless, imho, it's nice to be able to review/see the zfs property values in human readable form - without having to jump through hoops to decode a base64 string. And, even if json stored plain-text, it would be challenging to quickly parse visually.
For what it's worth - is this sort of the thought on a json config?
{
"source": {
"enabled": true,
"dataset": "rpool/ROOT/ubuntu",
"snapshot": {
"set_property": "property1=value1,property2=value2",
"tsformat": "%Y-%m-%dT%H:%M:%SZ",
"plan": "1hours=>15minutes,1days=>1hours,1weeks=>1days,1months=>1weeks,1years=>1months",
"recursive": true
},
"send": {
"raw": true,
"compressed": true,
"mbuffer": {
"path": "/usr/bin/mbuffer",
"size": "1G"
},
"znap_cmd": {
"pre": "echo hello",
"post": "echo goodbye"
}
}
},
"destinations": [{
"dataset": "backup_pool/ROOT/ubuntu",
"snapshot": {
"plan": "1weeks=>1days,1months=>1weeks,1years=>1months",
"receive": {
"force": true,
"unmounted": true,
"set_property": "property1=value1,property2=value2"
}
}
},
{
"datasets": "root@bserv:backup_pool/ROOT/ubuntu",
"snapshot": {
"plan": "1months=>1weeks,1years=>1months",
"receive": {
"force": true,
"unmounted": true,
"set_property": "property1=value1,property2=value2"
}
}
},
{
"datasets": "root@bserv2:backup_pool/ROOT/ubuntu",
"snapshot": {
"plan": "1years=>1months",
"receive": {
"force": true,
"unmounted": true,
"set_property": "property1=value1,property2=value2"
}
}
},
{
"datasets": "root@bserv3:backup_pool/ROOT/ubuntu",
"snapshot": {
"plan": "1hours=>15minutes,1days=>1hours",
"receive": {
"force": true,
"unmounted": true,
"set_property": "property1=value1,property2=value2"
}
}
}
]
}
So, the 256 char allowed for zfs property name is quite expansive. What if - a pseudo like json zfs property? Something like
org.znapzend:source:enabled=true
org.znapzend:source:snapshot:plan=1hours=>15minutes,1days=>1hours,1weeks=>1days,1months=>1weeks,1years=>1months
org.znapzend:source:snapshot:tsformat=%Y-%m-%dT%H:%M:%SZ
org.znapzend:source:snapshot:recursive=true
org.znapzend:source:send:raw=true
org.znapzend:source:send:compressed=true
org.znapzend:source:send:mbuffer:path=/usr/bin/buffer
org.znapzend:source:send:mbuffer:size=1G
org.znapzend:source:send:znap_cmd:pre='echo hello'
org.znapzend:source:send:znap_cmd:post='echo goodbye'
org.znapzend:destination:0:dataset=backup_pool/ROOT/ubuntu
org.znapzend:destination:0:snapshot:plan=1weeks=>1days,1months=>1weeks,1years=>1months
org.znapzend:destination:0:receive:force=true
org.znapzend:destination:0:receive:unmounted=true
org.znapzend:destination:1:dataset=root@bserv:backup_pool/ROOT/ubuntu
org.znapzend:destination:1:snapshot:plan=1months=>1weeks,1years=>1months
org.znapzend:destination:1:receive:force=true
org.znapzend:destination:1:receive:unmounted=true
Still reasonably readable and still objecty like in organization.
so what about:
org.znapzend:dst:<name>
org.znapzend:dst:<name>:sendRaw
org.znapzend:dst:<name>:plan
etc....
the current org.znapzend:dst_<name> could be read as org.znapzend:dst:<name> for backwards compatibility