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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26