/[sysadmin-cookbook]/recepies/zfs/zfs-replicate-pool.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /recepies/zfs/zfs-replicate-pool.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 268 - (hide annotations)
Mon Sep 5 22:18:01 2011 UTC (12 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 2795 byte(s)
added sleep 0.1 s for netcat to start, verify snapshot creation
1 dpavlin 267 #!/usr/bin/perl
2     use warnings;
3     use strict;
4    
5     use Net::OpenSSH;
6     use Data::Dump qw(dump);
7     use List::Util qw(first);
8 dpavlin 268 use Time::Hires;
9 dpavlin 267
10     my $arh = Net::OpenSSH->new('root@10.60.0.204');
11     my $dev = Net::OpenSSH->new('root@10.60.0.202');
12    
13     sub on {
14     my ($ssh,$command) = @_;
15     warn "## ", $ssh->get_host, "> $command\n";
16     if ( $command =~ m/zfs list/ ) {
17     map {
18     chomp; $_;
19     } $ssh->capture($command);
20     } else {
21     $ssh->capture($command);
22     }
23     }
24    
25     print on $arh => 'zpool status';
26     print on $dev => 'zpool status';
27    
28     my @arh = on $arh => 'zfs list -H -o name';
29     my @dev = on $dev => 'zfs list -H -o name';
30    
31     warn "# ",dump( \@arh, \@dev );
32    
33     my $from_pool = $arh[0];
34     my $to_pool = $dev[0];
35    
36     sub snapshots_from {
37     my ($ssh) = @_;
38     my $host = $ssh->get_host;
39    
40     my $snapshot;
41    
42     my @snapshots = on $ssh => 'zfs list -H -t snapshot -o name';
43     die $ssh->error if $ssh->error;
44     foreach my $s (@snapshots) {
45     my ($fs,$name) = split(/\@/,$s);
46     push @{ $snapshot->{$fs} }, $name;
47     }
48    
49 dpavlin 268 # warn "snapshots_from $host ",dump($snapshot),$/;
50 dpavlin 267
51     return $snapshot;
52     }
53    
54     foreach my $fs ( @arh ) {
55    
56     my $name = $fs;
57     $name =~ s{^$from_pool/}{} || next; # FIXME skip top-level fs
58     warn "? $name";
59    
60     my $arh_snapshot = snapshots_from $arh;
61     if ( ! exists( $arh_snapshot->{$fs} ) ) {
62    
63     my $snapshot = $fs . '@send';
64     print on $arh => "zfs snapshot $snapshot";
65     die $arh->error if $arh->error;
66     $arh_snapshot = snapshots_from $arh;
67     }
68    
69     my $max_snapshot = $#{ $arh_snapshot->{$fs} };
70     warn "$max_snapshot snapshots of $fs on arh\n";
71    
72     my $to_dev = "$to_pool/$name";
73    
74     foreach my $i ( 0 .. $max_snapshot ) {
75     my $snap = $arh_snapshot->{$fs}->[$i] || die "no snap";
76    
77     my $dev_snapshot = snapshots_from $dev;
78     if ( exists $dev_snapshot->{$to_dev} ) {
79     if ( first { /^\Q$snap\E$/ } @{ $dev_snapshot->{$to_dev} } ) {
80     warn "+ $name exists\n";
81     next;
82     } else {
83     warn "- $name missing\n";
84     }
85     } else {
86     warn "$name not found on target yet";
87     }
88    
89     my $snapshot;
90     if ( $i == 0 ) {
91     $snapshot = "$from_pool/$name\@$snap";
92     } else {
93     my $prev = $arh_snapshot->{$fs}->[$i-1] || die "no prev";
94     $snapshot = "-i $from_pool/$name\@$prev $from_pool/$name\@$snap";
95     }
96    
97     warn "zfs transfer $snapshot -> $to_dev";
98    
99     my $t = time();
100    
101     my $recv = "nc -w 5 -l -p 8888 | zfs receive $to_dev";
102     warn ">> $recv\n";
103     my ($rin1,$pid1) = $dev->pipe_in($recv);
104     warn ">> pid: $pid1";
105    
106 dpavlin 268 sleep 0.1; # FIXME wait for netcat to start
107    
108 dpavlin 267 my $send = "zfs send $snapshot | nc -q 0 -w 5 10.60.0.202 8888";
109     warn "<< $send\n";
110     $arh->system($send);
111    
112     $t = time() - $t;
113     warn "took $t seconds to complete\n";
114    
115     $dev->system("zfs set readonly=on $to_pool/$name") if $i == 0;
116     die $dev->error if $dev->error;
117    
118 dpavlin 268 $dev_snapshot = snapshots_from $dev;
119     die "can't find new snapshot $snap" unless $dev_snapshot->{$to_dev};
120    
121 dpavlin 267 }
122    
123     }

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26