109 |
} |
} |
110 |
|
|
111 |
if ( $opts{h} !~ /^([\w\.\s-]+)$/ ) { |
if ( $opts{h} !~ /^([\w\.\s-]+)$/ ) { |
112 |
print(STDERR "$0: bad host name '$opts{h}'\n"); |
die "$0: bad host name '$opts{h}'\n"; |
|
exit(1); |
|
113 |
} |
} |
114 |
my $Host = $opts{h}; |
my $Host = $opts{h}; |
115 |
|
|
116 |
if ( $opts{n} !~ /^(-?\d+)$/ ) { |
if ( $opts{n} !~ /^(-?\d+)$/ ) { |
117 |
print(STDERR "$0: bad dump number '$opts{n}'\n"); |
die "$0: bad dump number '$opts{n}'\n"; |
|
exit(1); |
|
118 |
} |
} |
119 |
my $Num = $opts{n}; |
my $Num = $opts{n}; |
120 |
|
|
130 |
my $SpecialCnt = 0; |
my $SpecialCnt = 0; |
131 |
my $ErrorCnt = 0; |
my $ErrorCnt = 0; |
132 |
my $current_tar_size = 0; |
my $current_tar_size = 0; |
133 |
|
my $total_increment_size = 0; |
134 |
|
|
135 |
my $i; |
my $i; |
136 |
$Num = $Backups[@Backups + $Num]{num} if ( -@Backups <= $Num && $Num < 0 ); |
$Num = $Backups[@Backups + $Num]{num} if ( -@Backups <= $Num && $Num < 0 ); |
138 |
last if ( $Backups[$i]{num} == $Num ); |
last if ( $Backups[$i]{num} == $Num ); |
139 |
} |
} |
140 |
if ( $i >= @Backups ) { |
if ( $i >= @Backups ) { |
141 |
print(STDERR "$0: bad backup number $Num for host $Host\n"); |
die "$0: bad backup number $Num for host $Host\n"; |
|
exit(1); |
|
142 |
} |
} |
143 |
|
|
144 |
my $PathRemove = $1 if ( $opts{r} =~ /(.+)/ ); |
my $PathRemove = $1 if ( $opts{r} =~ /(.+)/ ); |
145 |
my $PathAdd = $1 if ( $opts{p} =~ /(.+)/ ); |
my $PathAdd = $1 if ( $opts{p} =~ /(.+)/ ); |
146 |
if ( $opts{s} !~ /^([\w\s\.\/\$-]+)$/ && $opts{s} ne "*" ) { |
if ( $opts{s} !~ /^([\w\s\.\/\$-]+)$/ && $opts{s} ne "*" ) { |
147 |
print(STDERR "$0: bad share name '$opts{s}'\n"); |
die "$0: bad share name '$opts{s}'\n"; |
|
exit(1); |
|
148 |
} |
} |
149 |
our $ShareName = $opts{s}; |
our $ShareName = $opts{s}; |
150 |
our $view = BackupPC::View->new($bpc, $Host, \@Backups); |
our $view = BackupPC::View->new($bpc, $Host, \@Backups); |
161 |
inc_size = ?, |
inc_size = ?, |
162 |
parts = ?, |
parts = ?, |
163 |
inc_deleted = false |
inc_deleted = false |
164 |
where id = ? }); |
where id = ? |
165 |
|
}); |
166 |
my $sth_backup_parts = $dbh->prepare(qq{ |
my $sth_backup_parts = $dbh->prepare(qq{ |
167 |
insert into backup_parts ( |
insert into backup_parts ( |
168 |
backup_id, |
backup_id, |
205 |
|
|
206 |
my $tar_file = BackupPC::SearchLib::getGzipName($Host, $ShareName, $Num) || die "can't getGzipName($Host, $ShareName, $Num)"; |
my $tar_file = BackupPC::SearchLib::getGzipName($Host, $ShareName, $Num) || die "can't getGzipName($Host, $ShareName, $Num)"; |
207 |
|
|
208 |
my $tar_path = $tar_dir . '/' . $tar_file . '.tmp'; |
my $tar_path_final = $tar_dir . '/' . $tar_file; |
209 |
|
my $tar_path = $tar_path_final . '.tmp'; |
210 |
|
|
211 |
$tar_path =~ s#//#/#g; |
$tar_path =~ s#//#/#g; |
212 |
|
|
213 |
my $sth = $dbh->prepare(qq{ |
my $sth = $dbh->prepare(qq{ |
231 |
my $items_in_part = 0; |
my $items_in_part = 0; |
232 |
|
|
233 |
sub new_tar_part { |
sub new_tar_part { |
234 |
|
my $arg = {@_}; |
235 |
|
|
236 |
if ($fh) { |
if ($fh) { |
237 |
return if ($current_tar_size == 0); |
return if ($current_tar_size == 0); |
238 |
|
|
239 |
print STDERR "# closing part $part\n" if ($opts{d}); |
print STDERR " $part" if ($opts{v}); |
240 |
|
|
241 |
# finish tar archive |
# |
242 |
|
# Finish with two null 512 byte headers, |
243 |
|
# and then round out a full block. |
244 |
|
# |
245 |
my $data = "\0" x ($tar_header_length * 2); |
my $data = "\0" x ($tar_header_length * 2); |
246 |
TarWrite($fh, \$data); |
TarWrite($fh, \$data); |
247 |
TarWrite($fh, undef); |
TarWrite($fh, undef); |
264 |
$items_in_part, |
$items_in_part, |
265 |
); |
); |
266 |
|
|
267 |
|
$total_increment_size += int( ( $size + 1023 ) / 1024 ) * 1024; |
268 |
|
|
269 |
|
if ($arg->{close}) { |
270 |
|
|
271 |
|
if ($part == 1) { |
272 |
|
print STDERR " single"; |
273 |
|
rename "${tar_path}/1.tar.gz", "${tar_path_final}/.tar.gz" || die "can't move tar ${tar_path}: $! "; |
274 |
|
rename "${tar_path}/1.md5", "${tar_path_final}/.md5" || die "can't move md5 ${tar_path}: $! "; |
275 |
|
} else { |
276 |
|
print STDERR " [last]"; |
277 |
|
rename "${tar_path}", "${tar_path_final}" || die "can't move tar ${tar_path}: $! "; |
278 |
|
} |
279 |
|
|
280 |
|
$sth_inc_size->execute( |
281 |
|
$total_increment_size, |
282 |
|
$part, |
283 |
|
$backup_id |
284 |
|
); |
285 |
|
|
286 |
|
print STDERR ", $total_increment_size bytes\n" if ($opts{v}); |
287 |
|
|
288 |
|
return; |
289 |
|
} |
290 |
|
|
291 |
} |
} |
292 |
|
|
293 |
$part++; |
$part++; |
300 |
rmtree($tar_path); |
rmtree($tar_path); |
301 |
} |
} |
302 |
mkdir($tar_path) || die "can't create directory $tar_path: $!"; |
mkdir($tar_path) || die "can't create directory $tar_path: $!"; |
303 |
|
|
304 |
|
sub abort_cleanup { |
305 |
|
print STDERR "ABORTED: cleanup temp dir"; |
306 |
|
rmtree($tar_path); |
307 |
|
$dbh->rollback; |
308 |
|
exit 1; |
309 |
|
} |
310 |
|
|
311 |
|
$SIG{'INT'} = \&abort_cleanup; |
312 |
|
$SIG{'QUIT'} = \&abort_cleanup; |
313 |
|
$SIG{'__DIE__'} = \&abort_cleanup; |
314 |
|
|
315 |
} |
} |
316 |
|
|
317 |
my $file = $tar_path . '/' . $part; |
my $file = $tar_path . '/' . $part; |
345 |
$no_files = 1; |
$no_files = 1; |
346 |
} |
} |
347 |
|
|
348 |
# |
new_tar_part( close => 1 ); |
|
# Finish with two null 512 byte headers, and then round out a full |
|
|
# block. |
|
|
# |
|
|
my $data = "\0" x ($tar_header_length * 2); |
|
|
TarWrite($fh, \$data); |
|
|
TarWrite($fh, undef); |
|
|
|
|
|
if (! close($fh)) { |
|
|
rmtree($tar_path); |
|
|
die "can't close archive\n"; |
|
|
} |
|
349 |
|
|
350 |
# remove temporary files if there are no files |
# remove temporary files if there are no files |
351 |
if ($no_files) { |
if ($no_files) { |
366 |
# Got errors, with no files or directories; exit with non-zero |
# Got errors, with no files or directories; exit with non-zero |
367 |
# status |
# status |
368 |
# |
# |
369 |
cleanup(); |
die "got errors or no files\n"; |
|
exit(1); |
|
370 |
} |
} |
371 |
|
|
372 |
$sth_inc_size->finish; |
$sth_inc_size->finish; |
375 |
$dbh->commit || die "can't commit changes to database"; |
$dbh->commit || die "can't commit changes to database"; |
376 |
$dbh->disconnect(); |
$dbh->disconnect(); |
377 |
|
|
378 |
exit(0); |
exit; |
379 |
|
|
380 |
########################################################################### |
########################################################################### |
381 |
# Subroutines |
# Subroutines |
462 |
my $done = $WriteBufSz - length($WriteBuf); |
my $done = $WriteBufSz - length($WriteBuf); |
463 |
if ( syswrite($fh, $WriteBuf . substr($$dataRef, 0, $done)) |
if ( syswrite($fh, $WriteBuf . substr($$dataRef, 0, $done)) |
464 |
!= $WriteBufSz ) { |
!= $WriteBufSz ) { |
465 |
print(STDERR "Unable to write to output file ($!)\n"); |
die "Unable to write to output file ($!)\n"; |
|
exit(1); |
|
466 |
} |
} |
467 |
while ( $done + $WriteBufSz <= length($$dataRef) ) { |
while ( $done + $WriteBufSz <= length($$dataRef) ) { |
468 |
if ( syswrite($fh, substr($$dataRef, $done, $WriteBufSz)) |
if ( syswrite($fh, substr($$dataRef, $done, $WriteBufSz)) |
469 |
!= $WriteBufSz ) { |
!= $WriteBufSz ) { |
470 |
print(STDERR "Unable to write to output file ($!)\n"); |
die "Unable to write to output file ($!)\n"; |
|
exit(1); |
|
471 |
} |
} |
472 |
$done += $WriteBufSz; |
$done += $WriteBufSz; |
473 |
} |
} |
572 |
sub seedCache($$$) { |
sub seedCache($$$) { |
573 |
my ($host, $share, $dumpNo) = @_; |
my ($host, $share, $dumpNo) = @_; |
574 |
|
|
575 |
print STDERR curr_time(), "getting files for $host:$share increment $dumpNo..." if ($opts{v}); |
print STDERR curr_time(), "$host:$share #$dumpNo" if ($opts{v}); |
576 |
my $sql = q{ |
my $sql = q{ |
577 |
SELECT path,size |
SELECT path,size |
578 |
FROM files |
FROM files |
584 |
my $sth = $dbh->prepare($sql); |
my $sth = $dbh->prepare($sql); |
585 |
$sth->execute($host, $share, $dumpNo); |
$sth->execute($host, $share, $dumpNo); |
586 |
my $count = $sth->rows; |
my $count = $sth->rows; |
587 |
print STDERR " found $count items\n" if ($opts{v}); |
print STDERR " $count items, parts:" if ($opts{v}); |
588 |
while (my $row = $sth->fetchrow_arrayref) { |
while (my $row = $sth->fetchrow_arrayref) { |
589 |
#print STDERR "+ ", $row->[0],"\n"; |
#print STDERR "+ ", $row->[0],"\n"; |
590 |
$in_backup_increment->{ $row->[0] } = $row->[1]; |
$in_backup_increment->{ $row->[0] } = $row->[1]; |
632 |
# is this file too large to fit into MaxArchiveFileSize? |
# is this file too large to fit into MaxArchiveFileSize? |
633 |
|
|
634 |
if ( ($current_tar_size + tar_overhead($tarPath) + $size) > $max_file_size ) { |
if ( ($current_tar_size + tar_overhead($tarPath) + $size) > $max_file_size ) { |
635 |
print STDERR "# tar file $current_tar_size + $tar_header_length + $size > $max_file_size, splitting\n" if ($opts{d}); |
print STDERR "# tar file $current_tar_size + $tar_header_length + $size > $max_file_size, splitting\n" if ($opts{d}); |
636 |
new_tar_part(); |
new_tar_part(); |
637 |
} |
} |
638 |
|
|