Skip to content

Commit

Permalink
Merge pull request #51 from hadfl/forkcall_error_event
Browse files Browse the repository at this point in the history
ready for 0.8
  • Loading branch information
oetiker committed Jul 26, 2014
2 parents 4586c5b + 82bb0ea commit 80b1056
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 45 deletions.
2 changes: 1 addition & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Dominik Hassler <hadfl[email protected]>
Dominik Hassler <hadfl@cpan.org>
Tobias Oetiker <[email protected]>
2 changes: 1 addition & 1 deletion bin/znapzend
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ this program. If not, see L<http://www.gnu.org/licenses/>.
=head1 AUTHOR
S<Tobias Oetiker E<lt>[email protected]E<gt>>
S<Dominik Hassler> E<lt>hadfl[email protected]E<gt>>
S<Dominik Hassler E<lt>hadfl@cpan.orgE<gt>>
=head1 HISTORY
Expand Down
4 changes: 2 additions & 2 deletions bin/znapzendzetup
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ where 'command' is one of the following:
delete [--dst=key] <src_dataset>
edit [--recursive=on|off] [--mbuffer=<path>|off] [--mbuffersize=<size>] \
edit [--recursive=on|off] [--mbuffer=<path>|off] [--mbuffersize=<size>] \
[--pre-snap-command=<command>|off] \
[--post-snap-command=<command>|off] \
[--tsformat=<format>] --donotask \
Expand Down Expand Up @@ -374,7 +374,7 @@ this program. If not, see L<http://www.gnu.org/licenses/>.
=head1 AUTHOR
S<Tobias Oetiker E<lt>[email protected]E<gt>>
S<Dominik Hassler> E<lt>hadfl[email protected]E<gt>>
S<Dominik Hassler E<lt>hadfl@cpan.orgE<gt>>
=head1 HISTORY
Expand Down
17 changes: 9 additions & 8 deletions bin/znapzendztatz
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ my $zTime = ZnapZend::Time->new();
sub dumpStats {
my $stats = shift;

print ' ' x (5- length($stats->{count})) . $stats->{count};
print ' ' x (14 - length($stats->{usage})) . $stats->{usage};
print ' ' x (7 - length($stats->{count})) . $stats->{count};
print ' ' x (8 - length($stats->{usage})) . $stats->{usage};
print " $stats->{dataset}\n";
}

Expand All @@ -42,7 +42,7 @@ sub collectData {
sub main {
my $opts = {};

GetOptions($opts, qw(help man)) or exit 1;
GetOptions($opts, qw(H help|h man)) or exit 1;

$opts->{help} && do {
pod2usage(-exitval => 'NOEXIT');
Expand All @@ -61,7 +61,7 @@ sub main {
@$backupSets or die "ERROR: no valid znapzend setup found on source\n";

#print header
print "snapshot\ncount space usage dataset\n";
print "COUNT USED DATASET\n" if !$opts->{H};

for my $backupSet (@$backupSets){
my $datasets = $backupSet->{recursive} eq 'on'
Expand Down Expand Up @@ -106,10 +106,11 @@ znapzendztatz - znapzend statistics utility
=head1 SYNOPSIS
B<znapzendztatz> [src_dataset]
B<znapzendztatz> [I<options>...] [src_dataset]
--help
--man
-H do not print headers
--man show man-page and exit
-h,--help display this help and exi
=head1 DESCRIPTION
Expand Down Expand Up @@ -137,7 +138,7 @@ this program. If not, see L<http://www.gnu.org/licenses/>.
=head1 AUTHOR
S<Tobias Oetiker E<lt>[email protected]E<gt>>
S<Dominik Hassler> E<lt>hadfl[email protected]E<gt>>
S<Dominik Hassler E<lt>hadfl@cpan.orgE<gt>>
=head1 HISTORY
Expand Down
97 changes: 76 additions & 21 deletions lib/ZnapZend.pm
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ has daemonize => sub { 0 };
has loglevel => sub { q{debug} };
has logto => sub { q{} };
has pidfile => sub { q{} };
has terminate => sub { 0 };

has backupSets => sub { [] };

Expand Down Expand Up @@ -66,7 +67,8 @@ has zLog => sub {
$log->on(
message => sub {
my ($log, $level, @lines) = @_;
print STDERR $logLevels{$level} . ': ' . join(' ', @lines) . "\n";
print STDERR '[' . localtime . '] ['
. $level . '] ' . join(' ', @lines) . "\n";
}
);

Expand All @@ -93,6 +95,9 @@ has zLog => sub {
my $killThemAll = sub {
my $self = shift;

#set termination flag
$self->terminate(1);

Mojo::IOLoop->reset;

for my $backupSet (@{$self->backupSets}){
Expand Down Expand Up @@ -220,25 +225,49 @@ my $sendWorker = sub {

### RM_COMM_4_TEST ### # remove ### RM_COMM_4_TEST ### comments for testing purpose.
### RM_COMM_4_TEST ### $self->$sendRecvCleanup($backupSet, $timeStamp);
### RM_COMM_4_TEST ### return 0;
### RM_COMM_4_TEST ### return;

#send/receive fork
my $fc = Mojo::IOLoop::ForkCall->new;
my $pid = $fc->run(
$fc->run(
#send/receive worker
$sendRecvCleanup,
#send/receive worker arguments
[$self, $backupSet, $timeStamp],
#send/receive worker callback
sub {
my ($fc, $err, @return) = @_;

my ($fc, $err) = @_;

#############################################################
#TBD: remove && !$self->terminate as it is not used anymore #
#once ForkCall error event gets released! #
#############################################################
$self->zLog->warn('send/receive for ' . $backupSet->{src}
. ' failed: ' . $err) if $err && !$self->terminate;
#send/receive process finished, clear pid from backup set
$backupSet->{send_pid} = 0;
}
);

return $pid;
#spawn event
$fc->on(
spawn => sub {
my ($fc, $pid) = @_;

print STDERR '# send/receive worker for ' . $backupSet->{src}
. " spawned ($pid)\n" if $self->debug;
$backupSet->{send_pid} = $pid;
}
);

#error event
$fc->on(
error => sub {
my ($fc, $err) = @_;

$self->zLog->warn($err) if !$self->terminate;
}
);
};

my $snapWorker = sub {
Expand All @@ -249,33 +278,58 @@ my $snapWorker = sub {
### RM_COMM_4_TEST ### # remove ### RM_COMM_4_TEST ### comments for testing purpose.
### RM_COMM_4_TEST ### $self->$createSnapshot($backupSet, $timeStamp);
### RM_COMM_4_TEST ### $self->$sendWorker($backupSet, $timeStamp);
### RM_COMM_4_TEST ### return 0;
### RM_COMM_4_TEST ### return;

#snapshot fork
my $fc = Mojo::IOLoop::ForkCall->new;
my $pid = $fc->run(
$fc->run(
#snapshot worker
$createSnapshot,
#snapshot worker arguments
[$self, $backupSet, $timeStamp],
#snapshot worker callback
sub {
my ($fc, $err, @return) = @_;
my ($fc, $err) = @_;

#############################################################
#TBD: remove && !$self->terminate as it is not used anymore #
#once ForkCall error event gets released! #
#############################################################
$self->zLog->warn('taking snapshot on ' . $backupSet->{src}
. ' failed: ' . $err) if $err && !$self->terminate;

#snapshot process finished, clear pid from backup set
$backupSet->{snap_pid} = 0;

if ($backupSet->{send_pid}){
$self->zLog->info('last send/receive process still running!'
. 'skipping this round. missed snapshots will be sent next time...');
$self->zLog->info('last send/receive process on ' . $backupSet->{src}
. ' still running! skipping this round...');
}
else{
$backupSet->{send_pid} = $self->$sendWorker($backupSet, $timeStamp);
$self->$sendWorker($backupSet, $timeStamp);
}
}
);

return $pid;
#spawn event
$fc->on(
spawn => sub {
my ($fc, $pid) = @_;

print STDERR '# snapshot worker for ' . $backupSet->{src}
. " spawned ($pid)\n" if $self->debug;
$backupSet->{snap_pid} = $pid;
}
);

#error event
$fc->on(
error => sub {
my ($fc, $err) = @_;

$self->zLog->warn($err) if !$self->terminate;
}
);
};

my $createWorkers = sub {
Expand All @@ -297,19 +351,20 @@ my $createWorkers = sub {

if ($backupSet->{snap_pid}){
$self->zLog->warn('last snapshot process still running! it seems your pre or '
. 'post snapshot script runs too long. snapshot will not be taken this time!');
. 'post snapshot script runs for ages. snapshot will not be taken this time!');
}
else{
$backupSet->{snap_pid} = $self->$snapWorker($backupSet, $timeStamp);
$self->$snapWorker($backupSet, $timeStamp);
}
#get next timestamp when a snapshot has to be taken
$timeStamp = $self->zTime->getNextSnapshotTimestamp($backupSet);

### RM_COMM_4_TEST ### # remove ### RM_COMM_4_TEST ### comments for testing purpose.
### RM_COMM_4_TEST ### return 1;
### RM_COMM_4_TEST ### return;

#get next timestamp when a snapshot has to be taken
$timeStamp = $self->zTime->getNextSnapshotTimestamp($backupSet);

#reset timer for next snapshot if not runonce
!$self->runonce && Mojo::IOLoop->timer($timeStamp - $self->zTime->getLocalTimestamp() => $cb);
Mojo::IOLoop->timer($timeStamp - $self->zTime->getLocalTimestamp() => $cb) if !$self->runonce;
};

#set timer for next snapshot or run immediately if runonce
Expand Down Expand Up @@ -340,7 +395,7 @@ my $daemonize = sub {
if ($pid){

### RM_COMM_4_TEST ### # remove ### RM_COMM_4_TEST ### comments for testing purpose.
### RM_COMM_4_TEST ### return 1;
### RM_COMM_4_TEST ### return;

exit;
}
Expand Down Expand Up @@ -446,7 +501,7 @@ this program. If not, see L<http://www.gnu.org/licenses/>.
=head1 AUTHOR
S<Tobias Oetiker E<lt>[email protected]E<gt>>
S<Dominik Hassler> E<lt>hadfl[email protected]E<gt>>
S<Dominik Hassler E<lt>hadfl@cpan.orgE<gt>>
=head1 HISTORY
Expand Down
23 changes: 17 additions & 6 deletions lib/ZnapZend/Config.pm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ZnapZend::Config;
use Mojo::Base -base;
use ZnapZend::ZFS;
use ZnapZend::Time;
use Text::ParseWords qw(shellwords);

### attributes ###
has debug => sub { 0 };
Expand All @@ -11,11 +12,13 @@ has noaction => sub { 0 };
#mandatory properties
has mandProperties => sub {
{
enabled => 'on|off',
recursive => 'on|off',
src => '###dataset###',
src_plan => '###backupplan###',
tsformat => '###tsformat###',
enabled => 'on|off',
recursive => 'on|off',
src => '###dataset###',
src_plan => '###backupplan###',
tsformat => '###tsformat###',
pre_znap_cmd => '###command###',
post_znap_cmd => '###command###',
}
};

Expand Down Expand Up @@ -78,6 +81,14 @@ my $checkBackupSets = sub {
or die "ERROR: timestamp format not valid. check your syntax\n";
last;
};
/^###command###$/ && do {
last if $backupSet->{$prop} eq 'off';

my $file = (shellwords($backupSet->{$prop}))[0];
$self->zfs->fileExistsAndExec($file)
or die "ERROR: property $prop: executable '$file' does not exist or can't be executed\n";
last;
};
#check if properties are valid
my @values = split /\|/, $self->mandProperties->{$prop}, 2;
my $value = $backupSet->{$prop};
Expand Down Expand Up @@ -319,7 +330,7 @@ this program. If not, see L<http://www.gnu.org/licenses/>.
=head1 AUTHOR
S<Tobias Oetiker E<lt>[email protected]E<gt>>
S<Dominik Hassler> E<lt>hadfl[email protected]E<gt>>
S<Dominik Hassler E<lt>hadfl@cpan.orgE<gt>>
=head1 HISTORY
Expand Down
2 changes: 1 addition & 1 deletion lib/ZnapZend/Time.pm
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ this program. If not, see L<http://www.gnu.org/licenses/>.
=head1 AUTHOR
S<Tobias Oetiker E<lt>[email protected]E<gt>>
S<Dominik Hassler> E<lt>hadfl[email protected]E<gt>>
S<Dominik Hassler E<lt>hadfl@cpan.orgE<gt>>
=head1 HISTORY
Expand Down
6 changes: 3 additions & 3 deletions lib/ZnapZend/ZFS.pm
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ sub snapshotExists {

($remote, $snapshot) = $splitHostDataSet->($snapshot);
my @ssh = $self->$buildRemote($remote,
[qw(zfs list -H -o name -t snapshot -r -d 1), $snapshot]);
[qw(zfs list -H -o name -t snapshot -d 1), $snapshot]);

print STDERR '# ' . join(' ', @ssh) . "\n" if $self->debug;
open my $snapshots, '-|', @ssh
Expand Down Expand Up @@ -181,7 +181,7 @@ sub listSnapshots {

($remote, $dataSet) = $splitHostDataSet->($dataSet);
my @ssh = $self->$buildRemote($remote,
[qw(zfs list -t snapshot -o name -s name -r -d 1), $dataSet]);
[qw(zfs list -t snapshot -o name -s creation -d 1), $dataSet]);

print STDERR '# ' . join(' ', @ssh) . "\n" if $self->debug;
open my $snapshots, '-|', @ssh or die "ERROR: cannot get snapshots on $dataSet\n";
Expand Down Expand Up @@ -617,7 +617,7 @@ this program. If not, see L<http://www.gnu.org/licenses/>.
=head1 AUTHOR
S<Tobias Oetiker E<lt>[email protected]E<gt>>
S<Dominik Hassler> E<lt>hadfl[email protected]E<gt>>
S<Dominik Hassler E<lt>hadfl@cpan.orgE<gt>>
=head1 HISTORY
Expand Down
4 changes: 2 additions & 2 deletions t/zfs
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ org.znapzend:dst_a root\@remote:remote/destination
org.znapzend:dst_fail backup/destfail
org.znapzend:mbuffer $FindBin::Bin/mbuffer
org.znapzend:mbuffer_size 100M
org.znapzend:pre_znap_cmd echo 'pre znap command'
org.znapzend:post_znap_cmd echo 'post znap command'
org.znapzend:pre_znap_cmd /bin/echo 'pre znap command'
org.znapzend:post_znap_cmd /bin/echo 'post znap command'
ZFS_GET_END

exit;
Expand Down

0 comments on commit 80b1056

Please sign in to comment.