root/zetaback_agent.in

Revision ba545b02dd3de977f1a4125386b55b74cc869924, 5.3 kB (checked in by Eric Sproul <esproul@omniti.com>, 8 years ago)

Use .in files as the source, keeping things safe and making cleaning simpler.

  • Property mode set to 100755
Line 
1 #!/usr/bin/perl
2
3 use strict;
4 use Getopt::Long;
5 use Data::Dumper;
6
7 use vars qw/%conf $version_string
8             $PREFIX $CONF $LIST $FULL $SNAP $ZFS $BASE $RESTORE $VERSION
9             $BUG_6343779/;
10 $version_string = '0.1';
11 $PREFIX = q^__PREFIX__^;
12 $CONF = qq^$PREFIX/etc/zetaback_agent.conf^;
13
14 =pod
15
16 =head1 NAME
17
18 zetaback_agent - client-side component of zetaback.
19
20 =head1 SYNOPSIS
21
22   zetaback_agent -v
23
24   zetaback_agent -l [-c conf]
25
26   zetaback_agent -r [-b <timestamp>] [-c conf] [-z zfs]
27
28   zetaback -f <timestamp> [-c conf] [-z zfs]
29
30   zetaback -i <timestamp> [-c conf] [-z zfs]
31
32   zetaback -d <snap> -z <zfs> [-c conf]
33
34 =cut
35
36 GetOptions(
37   "c=s" => \$CONF,
38   "l"   => \$LIST,
39   "r"   => \$RESTORE,
40   "z=s" => \$ZFS,
41   "d=s" => \$SNAP,
42   "f=s" => \$FULL,
43   "i=s" => \$BASE,
44   "b=s" => \$BUG_6343779,
45   "v"   => \$VERSION,
46 );
47
48 =pod
49
50 =head1 DESCRIPTION
51
52 B<zetaback_agent> handles requests from zetaback and performs the requested
53 operations on a host.  Normally B<zetaback_agent> is only called by
54 zetaback and should never need to be invoked directly.
55
56 =head1 OPTIONS
57
58 The following options are available:
59
60 =over
61
62 =item -c <conf>
63
64 Use the specified file as the configuration file.  The default file, if
65 none is specified is /etc/zetaback_agent.conf.  The prefix of this file
66 may also be specified in the Makefile.
67
68 =item -d <snap>
69
70 Delete the specified snapshot.  Requires the use of -z to specify the
71 ZFS filesystem.
72
73 =item -f <timestamp>
74
75 Perform a full backup.  The name of the backup will include <timestamp>,
76 which is provided by the backup server.
77
78 =item -i <timestamp>
79
80 Perform an incremental backup.  The name of the backup will include
81 <timestamp>, which is provided by the backup server.
82
83 =item -l
84
85 List ZFS filesystems.
86
87 =item -r
88
89 Perform a restore.
90
91 =item -b
92
93 When performing a restore, if -b is specified, it informs the agent that
94 the receive command is an incremental based of the full snapshot with the
95 timestamp specified.  The agent will unmount and rollback the filesystem
96 prior to applying the incremental in order to work around bug 6343779.
97
98 =item -v
99
100 Print the version number and exit.
101
102 =item -z
103
104 Specify a ZFS filesystem to backup, restore, or delete.
105
106 =cut
107
108 if($VERSION) {
109   print "zetaback_agent: $version_string\n";
110   exit 0;
111 }
112
113 =pod
114
115 =head1 CONFIGURATION
116
117 The zetaback_agent configuration file contains a pattern list of ZFS
118 filesystems to be backed up.  The pattern list is a Perl-compatible
119 regular expression (PCRE).  Only one 'pattern=' line is permitted.
120
121 =head1 CONFIGURATION EXAMPLES
122
123 =head2 All ZFS filesystems
124
125 This pattern matches all ZFS filesystems.
126
127   pattern=.
128
129 =head2 Substring match
130
131 This will match anywhere in the name of the ZFS filesystem.  This is
132 helpful for catching all ZFS filesystems in a particular zpool, while
133 excluding any others.
134
135   pattern=zones
136
137 =head2 Left-anchored names
138
139 This pattern matches all ZFS filesystems whose names begin with 'www'.
140
141   pattern=^www
142
143 =head2 Specific ZFS filesystems
144
145 This pattern matches specific ZFS filesystems.
146
147   pattern=(?:data|mirrors|www)
148
149 =cut
150
151 # Read our config in
152 open(CONF, "<$CONF");
153 while(<CONF>) { /^\s*([^#](?:\S*)?)\s*=\s*(\S+)/ && ($conf{lc($1)} = $2); }
154 close(CONF);
155
156 sub zfs_agent_remove_snap {
157   my $target = $ZFS . '@';
158   die "zfs_agent_remove_snap: insufficient args\n" unless($ZFS && $SNAP);
159   if($SNAP eq '__zb_incr' or
160      $SNAP =~ /__zb_full_\d+/) {
161     $target .= $SNAP;
162   }
163   else {
164     die "zfs_agent_remove_snap: illegal snap: $SNAP\n";
165   }
166   `/usr/sbin/zfs destroy $target`;
167 }
168
169 sub zfs_agent_perform_full {
170   my $target = $ZFS . '@__zb_full_' . $FULL;
171   unless($ZFS && $FULL =~ /^\d+$/) {
172     die "zfs_agent_perform_full: bad fs or snap name\n"
173   }
174   `/usr/sbin/zfs snapshot $target`;
175   my @cmd = ("/usr/sbin/zfs", "send", $target);
176   exec { $cmd[0] } @cmd;
177   exit;
178 }
179
180 sub zfs_agent_perform_incremental {
181   my $target = $ZFS . '@__zb_incr';
182   my $base = $ZFS . '@__zb_full_' . $BASE;
183   unless($ZFS && $BASE) {
184     die "zfs_agent_perform_incremental: bad args\n"
185   }
186   `/usr/sbin/zfs snapshot $target`;
187   my @cmd = ("/usr/sbin/zfs", "send", "-i", $base, $target);
188   exec { $cmd[0] } @cmd;
189   exit;
190 }
191
192 sub zfs_agent_list {
193   my %zfs;
194   open(ZFSLIST, "/usr/sbin/zfs list -H |");
195   while(<ZFSLIST>) {
196     chomp;
197     my @line = split /\t/;
198     if($line[0] =~ /$conf{pattern}/) {
199       if($line[0] =~ /(\S+)\@([^\@]+)$/) {
200         $zfs{$1} ||= [];
201         push @{$zfs{$1}}, $2;
202       }
203       else {
204         $zfs{$line[0]} ||= [];
205       }
206     }
207   }
208   close(ZFSLIST);
209
210   foreach my $fs (sort keys %zfs) {
211     print "$fs [".join(',',@{$zfs{$fs}})."]\n";
212   }
213 }
214
215 sub zfs_agent_perform_restore {
216   unless($ZFS && $RESTORE) {
217     die "zfs_agent_perform_restore: bad state\n";
218   }
219   if($BUG_6343779) {
220     # Optionally work around Solaris bug: 6343779
221     my $base = $ZFS . '@__zb_full_' . $BUG_6343779;
222     `/usr/sbin/zfs unmount $ZFS`;
223     `/usr/sbin/zfs rollback $base`;
224   }
225   my @cmd = ("/usr/sbin/zfs", "recv", $ZFS);
226   exec { $cmd[0] } @cmd;
227   exit;
228 }
229
230 if($LIST) { zfs_agent_list(); exit; }
231 if($ZFS && $SNAP) { zfs_agent_remove_snap(); exit; }
232 if($ZFS && $RESTORE) { zfs_agent_perform_restore(); exit; }
233 if($ZFS && $FULL) { zfs_agent_perform_full(); exit; }
234 if($ZFS && $BASE) { zfs_agent_perform_incremental(); exit; }
235
236 =pod
237
238 =head1 FILES
239
240 =over
241
242 =item /etc/zetaback_agent.conf
243
244 The zetaback_agent configuration file.  The location of the file can be
245 specified on the command line with the -c flag.
246
247 =back
248
249 =head1 SEE ALSO
250
251 zetaback(1)
252
253 =cut
Note: See TracBrowser for help on using the browser.