]>
Commit | Line | Data |
---|---|---|
aaeeeebe DM |
1 | #!/usr/bin/perl -w |
2 | # | |
3 | # Copyright (C) 2007-2009 Proxmox Server Solutions GmbH | |
4 | # | |
5 | # Copyright: vzdump is under GNU GPL, the GNU General Public License. | |
6 | # | |
7 | # This program is free software; you can redistribute it and/or modify | |
8 | # it under the terms of the GNU General Public License as published by | |
9 | # the Free Software Foundation; version 2 dated June, 1991. | |
10 | # | |
11 | # This program is distributed in the hope that it will be useful, | |
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | # GNU General Public License for more details. | |
15 | # | |
16 | # You should have received a copy of the GNU General Public License | |
17 | # along with this program; if not, write to the | |
18 | # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, | |
19 | # MA 02110-1301, USA. | |
20 | # | |
21 | # Author: Dietmar Maurer <dietmar@proxmox.com> | |
22 | # | |
23 | ||
24 | use strict; | |
25 | use Getopt::Long; | |
26 | use Sys::Syslog; | |
27 | use PVE::VZDump; | |
28 | ||
29 | $ENV{LANG} = "C"; # avoid locale related issues/warnings | |
30 | ||
31 | # by default we set --rsyncable for gzip | |
32 | $ENV{GZIP} = "--rsyncable" if !$ENV{GZIP}; | |
33 | ||
34 | # just to be sure that we have a resonable path | |
35 | $ENV{PATH} = "/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"; | |
36 | ||
37 | my $cmdline = join (' ', 'vzdump', @ARGV); | |
38 | ||
39 | openlog ('vzdump', 'cons,pid', 'daemon'); | |
40 | ||
41 | $SIG{INT} = $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{PIPE} = sub { | |
42 | die "interrupted by signal\n"; | |
43 | }; | |
44 | ||
45 | my @std_opts = ( | |
46 | 'all', | |
47 | 'exclude=s@', | |
48 | 'exclude-path=s@', | |
49 | 'stdexcludes', | |
50 | 'compress', | |
51 | 'mailto=s@', | |
52 | 'quiet', | |
53 | 'stop', | |
54 | 'suspend', | |
55 | 'snapshot', | |
56 | 'size=i', | |
57 | 'node=i', | |
58 | 'bwlimit=i', | |
59 | 'ionice=i', | |
60 | 'lockwait=i', | |
61 | 'stopwait=i', | |
62 | 'tmpdir=s', | |
63 | 'dumpdir=s', | |
64 | 'maxfiles=i', | |
65 | 'script=s', | |
66 | 'storage=s', | |
67 | 'stdout', | |
68 | ); | |
69 | ||
70 | sub print_usage { | |
71 | my $msg = shift; | |
72 | ||
73 | print STDERR "ERROR: $msg\n\n" if $msg; | |
74 | ||
75 | print STDERR "usage: $0 OPTIONS [--all | VMID]\n\n"; | |
76 | print STDERR "\t--exclude VMID\t\texclude VMID (assumes --all)\n"; | |
77 | print STDERR "\t--exclude-path REGEX\texclude certain files/directories\n"; print STDERR "\t--stdexcludes\t\texclude temorary files and logs\n\n"; | |
78 | ||
79 | print STDERR "\t--compress\t\tcompress dump file (gzip)\n"; | |
80 | print STDERR "\t--dumpdir DIR\t\tstore resulting files in DIR\n"; | |
81 | print STDERR "\t--maxfiles N\t\tmaximal number of backup files per VM\n"; | |
82 | print STDERR "\t--script FILENAME\texecute hook script\n"; | |
83 | print STDERR "\t--stdout write to stdout, not to a file\n"; | |
84 | print STDERR "\t--storage STORAGE_ID\tstore resulting files to STORAGE_ID (PVE only)\n"; | |
85 | print STDERR "\t--tmpdir DIR\t\tstore temporary files in DIR\n\n"; | |
86 | ||
87 | print STDERR "\t--mailto EMAIL\t\tsend notification mail to EMAIL.\n"; | |
88 | print STDERR "\t--quiet\t\t\tbe quiet.\n"; | |
89 | print STDERR "\t--stop\t\t\tstop/start VM if running\n"; | |
90 | print STDERR "\t--suspend\t\tsuspend/resume VM when running\n"; | |
91 | print STDERR "\t--snapshot\t\tuse LVM snapshot when running\n"; | |
92 | print STDERR "\t--size MB\t\tLVM snapshot size\n\n"; | |
93 | ||
94 | print STDERR "\t--node CID\t\tonly run on pve cluster node CID\n"; | |
95 | print STDERR "\t--lockwait MINUTES\tmaximal time to wait for the global lock\n"; | |
96 | print STDERR "\t--stopwait MINUTES\tmaximal time to wait until a VM is stopped\n"; | |
97 | print STDERR "\t--bwlimit KBPS\t\tlimit I/O bandwidth; KBytes per second\n"; | |
98 | print STDERR "\t--ionice PRI\t\tset ionice priority (0-8)\n\n"; | |
99 | ||
100 | print STDERR "\n"; | |
101 | } | |
102 | ||
103 | my $opts = {}; | |
104 | if (!GetOptions ($opts, @std_opts)) { | |
105 | print_usage (); | |
106 | exit (-1); | |
107 | } | |
108 | ||
109 | if ($opts->{node}) { | |
110 | PVE::VZDump::check_bin ('pveca'); | |
111 | ||
112 | my $info = `pveca -i`; | |
113 | chomp $info; | |
114 | die "unable to parse pveca info" if $info !~ m/^(\d+)\s+\S+\s+\S+\s+\S+$/; | |
115 | my $cid = $1; | |
116 | ||
117 | # silent exit if we run on wrong node | |
118 | exit (0) if $cid != $opts->{node}; | |
119 | } | |
120 | ||
121 | $opts->{all} = 1 if $opts->{exclude}; | |
122 | ||
123 | if ($opts->{all} && $#ARGV >= 0) { | |
124 | print_usage (); | |
125 | exit (-1); | |
126 | } | |
127 | ||
128 | if (!$opts->{all} && $#ARGV == -1) { | |
129 | print_usage (); | |
130 | exit (-1); | |
131 | } | |
132 | ||
133 | open STDOUT, '>/dev/null' if $opts->{quiet} && !$opts->{stdout}; | |
134 | open STDERR, '>/dev/null' if $opts->{quiet}; | |
135 | ||
136 | if ($opts->{stdout}) { | |
137 | ||
138 | open my $saved_stdout, ">&STDOUT" | |
139 | || die "can't dup STDOUT: $!\n"; | |
140 | ||
141 | open STDOUT, '>&STDERR' || | |
142 | die "unable to redirect STDOUT: $!\n"; | |
143 | ||
144 | $opts->{stdout} = $saved_stdout; | |
145 | ||
146 | die "you can only backup a single VM with option --stdout\n" | |
147 | if scalar(@ARGV) != 1; | |
148 | } | |
149 | ||
150 | $opts->{vmids} = PVE::VZDump::check_vmids (@ARGV) if !$opts->{all}; | |
151 | ||
152 | $opts->{exclude} = PVE::VZDump::check_vmids (@{$opts->{exclude}}) if $opts->{exclude}; | |
153 | ||
154 | my $vzdump = PVE::VZDump->new ($cmdline, $opts); | |
155 | ||
156 | $vzdump->getlock (); # only one process allowed | |
157 | ||
158 | # parameters are OK - now start real work and log everything | |
159 | ||
160 | eval { | |
161 | if (defined($opts->{ionice})) { | |
162 | if ($opts->{ionice} > 7) { | |
163 | PVE::VZDump::run_command (undef, "ionice -c3 -p $$"); | |
164 | } else { | |
165 | PVE::VZDump::run_command (undef, "ionice -c2 -n$opts->{ionice} -p $$"); | |
166 | } | |
167 | } | |
168 | $vzdump->exec_backup(); | |
169 | }; | |
170 | my $err = $@; | |
171 | ||
172 | if ($err) { | |
173 | PVE::VZDump::debugmsg ('err', $err, undef, 1); | |
174 | exit (-1); | |
175 | } | |
176 | ||
177 | exit 0; | |
178 | ||
179 | __END__ | |
180 | ||
181 | =head1 NAME | |
182 | ||
183 | vzdump - backup utility for virtual machine | |
184 | ||
185 | =head1 SYNOPSIS | |
186 | ||
187 | vzdump OPTIONS [--all | <VMID>] | |
188 | ||
189 | --exclude VMID exclude VMID (assumes --all) | |
190 | ||
191 | --exclude-path REGEX exclude certain files/directories. You | |
192 | can use this option more than once to specify | |
193 | multiple exclude paths | |
194 | ||
195 | --stdexcludes exclude temporary files and logs | |
196 | ||
197 | --compress compress dump file (gzip) | |
198 | ||
199 | --storage STORAGE_ID store resulting files to STORAGE_ID (PVE only) | |
200 | ||
201 | --script execute hook script | |
202 | ||
203 | --dumpdir DIR store resulting files in DIR | |
204 | ||
205 | --stdout write to stdout, not to a file. You can only | |
206 | backup a single VM when using this mode. | |
207 | ||
208 | --maxfiles N maximal number of backup files per VM. | |
209 | ||
210 | --tmpdir DIR store temporary files in DIR. --suspend and --stop | |
211 | are using this directory to store a copy of the VM. | |
212 | ||
213 | --mailto EMAIL send notification mail to EMAIL. You can use | |
214 | this option more than once to specify multiple | |
215 | receivers | |
216 | ||
217 | --stop stop/start VM if running | |
218 | ||
219 | --suspend suspend/resume VM when running | |
220 | ||
221 | --snapshot use LVM snapshot when running | |
222 | ||
223 | --size MB LVM snapshot size (default 1024) | |
224 | ||
225 | --bwlimit KBPS limit I/O bandwidth; KBytes per second | |
226 | ||
227 | --ionice PRI set ionice priority (0-8). default is 7 (lowest 'best | |
228 | effort' priority). Value 8 uses the ionice | |
229 | 'idle' scheduling class. | |
230 | ||
231 | --lockwait MINUTES maximal time to wait for the global | |
232 | lock. vzdump uses a global lock file to make | |
233 | sure that only one instance is running | |
234 | (running several instance puts too much load | |
235 | on a server). Default is 180 (3 hours). | |
236 | ||
237 | --stopwait MINUTES maximal time to wait until a VM is stopped. | |
238 | ||
239 | =head1 DESCRIPTION | |
240 | ||
241 | vzdump is an utility to make consistent snapshots of running virtual | |
242 | machines (VMs). It basically creates a tar archive of the VM private area, | |
243 | which also includes the VM configuration files. vzdump currently | |
244 | supports OpenVZ and QemuServer VMs. | |
245 | ||
246 | There are several ways to provide consistency: | |
247 | ||
248 | =over 2 | |
249 | ||
250 | =item C<stop> mode | |
251 | ||
252 | Stop the VM during backup. This results in a very long downtime. | |
253 | ||
254 | =item C<suspend> mode | |
255 | ||
256 | For OpenVZ, this mode uses rsync to copy the VM to a temporary | |
257 | location (see option --tmpdir). Then the VM is suspended and a second | |
258 | rsync copies changed files. After that, the VM is started (resume) | |
259 | again. This results in a minimal downtime, but needs additional space | |
260 | to hold the VM copy. | |
261 | ||
262 | For QemuServer, this mode work like C<stop> mode, but uses | |
263 | suspend/resume instead of stop/start. | |
264 | ||
265 | =item C<snapshot> mode | |
266 | ||
267 | This mode uses LVM2 snapshots. There is no downtime, but snapshot mode | |
268 | needs LVM2 and some free space on the corresponding volume group to | |
269 | create the LVM snapshot. | |
270 | ||
271 | =back | |
272 | ||
273 | =head1 BACKUP FILE NAMES | |
274 | ||
275 | Newer version of vzdump encodes the virtual machine type and the | |
276 | backup time into the filename, for example | |
277 | ||
278 | vzdump-openvz-105-2009_10_09-11_04_43.tar | |
279 | ||
280 | That way it is possible to store several backup into the same | |
281 | directory. The parameter C<maxfiles> can be used to specify the maximal | |
282 | number of backups to keep. | |
283 | ||
284 | =head1 RESTORE | |
285 | ||
286 | The resulting tar files can be restored with the following programs. | |
287 | ||
288 | =over 1 | |
289 | ||
290 | =item vzrestore: OpenVZ restore utility | |
291 | ||
292 | =item qmrestore: QemuServer restore utility | |
293 | ||
294 | =back | |
295 | ||
296 | For details see the corresponding manual pages. | |
297 | ||
298 | =head1 CONFIGURATION | |
299 | ||
300 | Global configuration is stored in /etc/vzdump.conf. | |
301 | ||
302 | tmpdir: DIR | |
303 | dumpdir: DIR | |
304 | storage: STORAGE_ID | |
305 | mode: snapshot|suspend|stop | |
306 | bwlimit: KBPS | |
307 | ionize: PRI | |
308 | lockwait: MINUTES | |
309 | stopwait: MINUTES | |
310 | size: MB | |
311 | maxfiles: N | |
312 | script: FILENAME | |
313 | ||
314 | =head1 HOOK SCRIPT | |
315 | ||
316 | You can specify a hook script with option C<--script>. This script is called at various phases of the backup process, with parameters accordingly set. You can find an example in the documentation directory (C<hook-script.pl>). | |
317 | ||
318 | =head1 EXCLUSIONS (OpenVZ only) | |
319 | ||
320 | vzdump skips the following files wit option --stdexcludes | |
321 | ||
322 | /var/log/.+ | |
323 | /tmp/.+ | |
324 | /var/tmp/.+ | |
325 | /var/run/.+pid | |
326 | ||
327 | You can manually specify exclude paths, for example: | |
328 | ||
329 | > vzdump --exclude-path C</tmp/.+> --exclude-path C</var/tmp/.+> 777 | |
330 | ||
331 | (only excludes tmp directories) | |
332 | ||
333 | Configuration files are also stored inside the backup archive (/etc/vzdump), and will be correctly restored. | |
334 | ||
335 | =head1 LIMITATIONS | |
336 | ||
337 | VZDump does not save ACLs. | |
338 | ||
339 | =head1 EXAMPLES | |
340 | ||
341 | Simply dump VM 777 - no snapshot, just archive the VM private area and configuration files to the default dump directory (usually /vz/dump/). | |
342 | ||
343 | > vzdump 777 | |
344 | ||
345 | Use rsync and suspend/resume to create an snapshot (minimal downtime). | |
346 | ||
347 | > vzdump --suspend 777 | |
348 | ||
349 | Backup all VMs and send notification mails to root. | |
350 | ||
351 | > vzdump --suspend --all --mailto root | |
352 | ||
353 | Use LVM2 to create snapshots (no downtime). | |
354 | ||
355 | > vzdump --dumpdir /mnt/backup --snapshot 777 | |
356 | ||
357 | Backup all VMs excluding VM 101 and 102 | |
358 | ||
359 | > vzdump --suspend --exclude 101 --exclude 102 | |
360 | ||
361 | Restore an OpenVZ machine to VM 600 | |
362 | ||
363 | > vzrestore /mnt/backup/vzdump-openvz-777.tar 600 | |
364 | ||
365 | Restore an Qemu/KVM machine to VM 601 | |
366 | ||
367 | > qmrestore /mnt/backup/vzdump-qemu-888.tar 601 | |
368 | ||
369 | =head1 SEE ALSO | |
370 | ||
371 | vzrestore(1) qmrestore(1) | |
372 | ||
373 | =head1 AUTHOR | |
374 | ||
375 | Dietmar Maurer <dietmar@proxmox.com> | |
376 | ||
377 | Many thanks to Proxmox Server Solutions (www.proxmox.com) for sponsoring | |
378 | this work. | |
379 | ||
380 | =head1 COPYRIGHT AND DISCLAIMER | |
381 | ||
382 | Copyright (C) 2007-2009 Proxmox Server Solutions GmbH | |
383 | ||
384 | Copyright: vzdump is under GNU GPL, the GNU General Public License. | |
385 | ||
386 | This program is free software; you can redistribute it and/or modify | |
387 | it under the terms of the GNU General Public License as published by | |
388 | the Free Software Foundation; version 2 dated June, 1991. | |
389 | ||
390 | This program is distributed in the hope that it will be useful, | |
391 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
392 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
393 | GNU General Public License for more details. | |
394 | ||
395 | You should have received a copy of the GNU General Public License | |
396 | along with this program; if not, write to the | |
397 | Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, | |
398 | MA 02110-1301, USA. | |
399 |