74 |
use POSIX qw/strftime/; |
use POSIX qw/strftime/; |
75 |
use File::Which; |
use File::Which; |
76 |
use File::Path; |
use File::Path; |
77 |
|
use File::Slurp; |
78 |
use Data::Dumper; ### FIXME |
use Data::Dumper; ### FIXME |
79 |
|
|
80 |
die("BackupPC::Lib->new failed\n") if ( !(my $bpc = BackupPC::Lib->new) ); |
die("BackupPC::Lib->new failed\n") if ( !(my $bpc = BackupPC::Lib->new) ); |
152 |
our $ShareName = $opts{s}; |
our $ShareName = $opts{s}; |
153 |
our $view = BackupPC::View->new($bpc, $Host, \@Backups); |
our $view = BackupPC::View->new($bpc, $Host, \@Backups); |
154 |
|
|
155 |
|
# database |
156 |
|
|
157 |
|
my $dsn = $Conf{SearchDSN}; |
158 |
|
my $db_user = $Conf{SearchUser} || ''; |
159 |
|
|
160 |
|
my $dbh = DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 0} ); |
161 |
|
|
162 |
|
my $sth_inc_size = $dbh->prepare(qq{ |
163 |
|
update backups set |
164 |
|
inc_size = ?, |
165 |
|
parts = ?, |
166 |
|
inc_deleted = false |
167 |
|
where id = ? }); |
168 |
|
my $sth_backup_parts = $dbh->prepare(qq{ |
169 |
|
insert into backup_parts ( |
170 |
|
backup_id, |
171 |
|
part_nr, |
172 |
|
tar_size, |
173 |
|
size, |
174 |
|
md5, |
175 |
|
items |
176 |
|
) values (?,?,?,?,?,?) |
177 |
|
}); |
178 |
|
|
179 |
# |
# |
180 |
# This constant and the line of code below that uses it are borrowed |
# This constant and the line of code below that uses it are borrowed |
181 |
# from Archive::Tar. Thanks to Calle Dybedahl and Stephen Zander. |
# from Archive::Tar. Thanks to Calle Dybedahl and Stephen Zander. |
210 |
my $tar_path = $tar_dir . '/' . $tar_file . '.tmp'; |
my $tar_path = $tar_dir . '/' . $tar_file . '.tmp'; |
211 |
$tar_path =~ s#//#/#g; |
$tar_path =~ s#//#/#g; |
212 |
|
|
213 |
print STDERR "working dir: $tar_dir, max uncompressed size $max_file_size bytes, tar $tar_file\n" if ($opts{d}); |
my $sth = $dbh->prepare(qq{ |
214 |
|
SELECT |
215 |
|
backups.id |
216 |
|
FROM backups |
217 |
|
JOIN shares on shares.id = shareid |
218 |
|
JOIN hosts on hosts.id = shares.hostid |
219 |
|
WHERE hosts.name = ? and shares.name = ? and backups.num = ? |
220 |
|
}); |
221 |
|
$sth->execute($Host, $ShareName, $Num); |
222 |
|
my ($backup_id) = $sth->fetchrow_array; |
223 |
|
$sth->finish; |
224 |
|
|
225 |
|
print STDERR "backup_id: $backup_id working dir: $tar_dir, max uncompressed size $max_file_size bytes, tar $tar_file\n" if ($opts{d}); |
226 |
|
|
227 |
|
|
228 |
my $fh; |
my $fh; |
229 |
my $part = 0; |
my $part = 0; |
230 |
my $no_files = 0; |
my $no_files = 0; |
231 |
|
my $items_in_part = 0; |
232 |
|
|
233 |
sub new_tar_part { |
sub new_tar_part { |
234 |
if ($fh) { |
if ($fh) { |
242 |
TarWrite($fh, undef); |
TarWrite($fh, undef); |
243 |
|
|
244 |
close($fh) || die "can't close archive part $part: $!"; |
close($fh) || die "can't close archive part $part: $!"; |
245 |
|
|
246 |
|
my $file = $tar_path . '/' . $part; |
247 |
|
|
248 |
|
my $md5 = read_file( $file . '.md5' ) || die "can't read md5sum file ${file}.md5"; |
249 |
|
$md5 =~ s/\s.*$//; |
250 |
|
|
251 |
|
my $size = (stat( $file . '.tar.gz' ))[7] || die "can't stat ${file}.tar.gz"; |
252 |
|
|
253 |
|
$sth_backup_parts->execute( |
254 |
|
$backup_id, |
255 |
|
$part, |
256 |
|
$current_tar_size, |
257 |
|
$size, |
258 |
|
$md5, |
259 |
|
$items_in_part, |
260 |
|
); |
261 |
|
|
262 |
} |
} |
263 |
|
|
264 |
$part++; |
$part++; |
289 |
|
|
290 |
open($fh, $cmd) or die "can't open $cmd: $!"; |
open($fh, $cmd) or die "can't open $cmd: $!"; |
291 |
binmode($fh); |
binmode($fh); |
292 |
|
|
293 |
$current_tar_size = 0; |
$current_tar_size = 0; |
294 |
|
$items_in_part = 0; |
295 |
} |
} |
296 |
|
|
297 |
new_tar_part(); |
new_tar_part(); |
340 |
exit(1); |
exit(1); |
341 |
} |
} |
342 |
|
|
343 |
|
$sth_inc_size->finish; |
344 |
|
$sth_backup_parts->finish; |
345 |
|
|
346 |
|
$dbh->commit || die "can't commit changes to database"; |
347 |
|
$dbh->disconnect(); |
348 |
|
|
349 |
exit(0); |
exit(0); |
350 |
|
|
351 |
########################################################################### |
########################################################################### |
545 |
sub seedCache($$$) { |
sub seedCache($$$) { |
546 |
my ($host, $share, $dumpNo) = @_; |
my ($host, $share, $dumpNo) = @_; |
547 |
|
|
|
my $dsn = $Conf{SearchDSN}; |
|
|
my $db_user = $Conf{SearchUser} || ''; |
|
|
|
|
548 |
print STDERR curr_time(), "getting files for $host:$share increment $dumpNo..." if ($opts{v}); |
print STDERR curr_time(), "getting files for $host:$share increment $dumpNo..." if ($opts{v}); |
549 |
my $sql = q{ |
my $sql = q{ |
550 |
SELECT path,size |
SELECT path,size |
554 |
WHERE hosts.name = ? and shares.name = ? and backupnum = ? |
WHERE hosts.name = ? and shares.name = ? and backupnum = ? |
555 |
}; |
}; |
556 |
|
|
|
my $dbh = DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 1} ); |
|
557 |
my $sth = $dbh->prepare($sql); |
my $sth = $dbh->prepare($sql); |
558 |
$sth->execute($host, $share, $dumpNo); |
$sth->execute($host, $share, $dumpNo); |
559 |
my $count = $sth->rows; |
my $count = $sth->rows; |
564 |
} |
} |
565 |
|
|
566 |
$sth->finish(); |
$sth->finish(); |
|
$dbh->disconnect(); |
|
567 |
|
|
568 |
return $count; |
return $count; |
569 |
} |
} |
609 |
new_tar_part(); |
new_tar_part(); |
610 |
} |
} |
611 |
|
|
612 |
print STDERR "A $tarPath [$size] tell: $current_tar_size\n" if ($opts{d}); |
#print STDERR "A $tarPath [$size] tell: $current_tar_size\n" if ($opts{d}); |
613 |
|
$items_in_part++; |
614 |
|
|
615 |
if ( defined($PathRemove) |
if ( defined($PathRemove) |
616 |
&& substr($tarPath, 0, length($PathRemove)) eq $PathRemove ) { |
&& substr($tarPath, 0, length($PathRemove)) eq $PathRemove ) { |
683 |
TarWrite($fh, \$data); |
TarWrite($fh, \$data); |
684 |
$size += length($data); |
$size += length($data); |
685 |
TarWritePad($fh, $size); |
TarWritePad($fh, $size); |
686 |
|
|
687 |
|
$items_in_part++; |
688 |
} |
} |
689 |
$f->close; |
$f->close; |
690 |
$FileCnt++; |
$FileCnt++; |