/[BackupPC]/trunk/bin/BackupPC_incPartsUpdate
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/bin/BackupPC_incPartsUpdate

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 274 by dpavlin, Tue Dec 13 22:38:09 2005 UTC revision 312 by dpavlin, Sun Jan 29 15:54:10 2006 UTC
# Line 16  use Archive::Tar::Streamed; Line 16  use Archive::Tar::Streamed;
16  use Algorithm::Diff;  use Algorithm::Diff;
17  use Getopt::Std;  use Getopt::Std;
18  use File::Slurp;  use File::Slurp;
19    use File::Pid;
20    
21    =head1 NAME
22    
23    BackupPC_incPartsUpdate
24    
25    =head1 DESCRIPTION
26    
27    Create C<.tar.gz> increments on disk calling C<BackupPC_tarIncCreate>.
28    
29    Following options are supported (but all are optional):
30    
31    =over 4
32    
33    =item -h hostname
34    
35    Update parts for just single C<hostname>
36    
37    =item -c
38    
39    Force check for tar archives which exist on disk
40    
41    =item -d
42    
43    Turn debugging output
44    
45    =back
46    
47    =cut
48    
49    my %opt;
50    getopts("cdh:", \%opt );
51    
52    my $debug = $opt{d};
53    my $check = $opt{c} && print STDERR "NOTICE: tar archive check forced\n";
54    
55    my $pid_path = abs_path($0);
56    $pid_path =~ s/\W+/_/g;
57    
58    my $pidfile = new File::Pid({
59            file => "/tmp/$pid_path",
60    });
61    
62    if (my $pid = $pidfile->running ) {
63            die "$0 already running: $pid\n";
64    } elsif ($pidfile->pid ne $$) {
65            $pidfile->remove;
66            $pidfile = new File::Pid;
67    }
68    
69    print STDERR "$0 using pid ",$pidfile->pid," file ",$pidfile->file,"\n";
70    $pidfile->write;
71    
72  my $bpc = BackupPC::Lib->new || die "can't create BackupPC::Lib";  my $bpc = BackupPC::Lib->new || die "can't create BackupPC::Lib";
73  my %Conf = $bpc->Conf();  my %Conf = $bpc->Conf();
# Line 34  foreach my $c (qw/gzip md5sum/) { Line 86  foreach my $c (qw/gzip md5sum/) {
86          $bin->{$c} = which($c) || die "$0 needs $c, install it\n";          $bin->{$c} = which($c) || die "$0 needs $c, install it\n";
87  }  }
88    
 my %opt;  
 getopts("cd", \%opt );  
   
 my $debug = $opt{d};  
 my $check = $opt{c} && print STDERR "NOTICE: tar archive check forced\n";  
   
89  $|=1;  $|=1;
90    
91  my $start_t = time();  my $start_t = time();
# Line 84  sub get_backup_id($$$) { Line 130  sub get_backup_id($$$) {
130                  FROM backups                  FROM backups
131                  INNER JOIN shares       ON backups.shareID=shares.ID                  INNER JOIN shares       ON backups.shareID=shares.ID
132                  INNER JOIN hosts        ON backups.hostID = hosts.ID                  INNER JOIN hosts        ON backups.hostID = hosts.ID
133                  where hosts.name = ? and shares.name = ? and backups.num = ?                  WHERE hosts.name = ? and shares.name = ? and backups.num = ?
134          });          });
135          $sth->execute($host, $share, $num);          $sth->execute($host, $share, $num);
136          my ($id) = $sth->fetchrow_array;          my ($id) = $sth->fetchrow_array;
# Line 96  sub get_backup_id($$$) { Line 142  sub get_backup_id($$$) {
142          return $id;          return $id;
143  }  }
144    
145    sub backup_inc_deleted($) {
146            my $backup_id = shift;
147            my $sth_inc_deleted = $dbh->prepare(qq{
148                    update backups set
149                            inc_deleted = true
150                    where id = ?
151            });
152            $sth_inc_deleted->execute($backup_id);
153    }
154    
155  sub tar_check($$$$) {  sub tar_check($$$$) {
156          my ($host,$share,$num,$filename) = @_;          my ($host,$share,$num,$filename) = @_;
# Line 103  sub tar_check($$$$) { Line 158  sub tar_check($$$$) {
158          my $t = time();          my $t = time();
159          print curr_time, " check $host:$share#$num -> $filename";          print curr_time, " check $host:$share#$num -> $filename";
160    
161            # depending on expected returned value this is used like:
162            # my $uncompress_size = get_gzip_size('/full/path/to.gz');
163            # my ($compress_size, $uncompress_size) = get_gzip_size('/path.gz');
164            sub get_gzip_size($) {
165                    my $filename = shift;
166                    die "file $filename problem: $!" unless (-r $filename);
167                    open(my $gzip, $bin->{gzip}." -l $filename |") || die "can't gzip -l $filename: $!";
168                    my $line = <$gzip>;
169                    chomp($line);
170                    $line = <$gzip> if ($line =~ /^\s+compressed/);
171    
172                    my ($comp, $uncomp) = (0,0);
173    
174                    if ($line =~ m/^\s+(\d+)\s+(\d+)\s+\d+\.\d+/) {
175                            if (wantarray) {
176                                    return [ $1, $2 ];
177                            } else {
178                                    return $2;
179                            }
180                    } else {
181                            die "can't find size in line: $line";
182                    }
183            }
184    
185          sub check_part {          sub check_part {
186                  my ($host, $share, $num, $part_nr, $tar_size, $size, $md5, $items) = @_;                  my ($host, $share, $num, $part_nr, $tar_size, $size, $md5, $items) = @_;
187                  my $backup_id = get_backup_id($host, $share, $num);                  my $backup_id = get_backup_id($host, $share, $num);
# Line 165  sub tar_check($$$$) { Line 244  sub tar_check($$$$) {
244    
245                  print "\n\t- $tarfilename";                  print "\n\t- $tarfilename";
246    
247                  my $size = (stat( "$tar_dir/$tarfilename" ))[7] || die "can't stat $tar_dir/$tarfilename";                  my $path = "$tar_dir/$tarfilename";
248    
249                    my $size = (stat( $path ))[7] || die "can't stat $path: $!";
250    
251                  if ($size > $Conf{MaxArchiveSize}) {                  if ($size > $Conf{MaxArchiveSize}) {
252                          print ", part bigger than media $size > $Conf{MaxArchiveSize}\n";                          print ", part bigger than media $size > $Conf{MaxArchiveSize}\n";
# Line 174  sub tar_check($$$$) { Line 255  sub tar_check($$$$) {
255    
256                  print ", $size bytes";                  print ", $size bytes";
257    
                 my $path = "$tar_dir/$tarfilename";  
258    
259                  open(my $fh, "gzip -cd $tar_dir/$tarfilename |") or die "can't open $tar_dir/$tarfilename: $!";                  open(my $fh, "gzip -cd $path |") or die "can't open $path: $!";
260                  binmode($fh);                  binmode($fh);
261                  my $tar = Archive::Tar::Streamed->new($fh);                  my $tar = Archive::Tar::Streamed->new($fh);
262    
263                  my $tar_size = 0;                  my $tar_size_inarc = 0;
264                  my $items = 0;                  my $items = 0;
265    
266                  while(my $entry = $tar->next) {                  while(my $entry = $tar->next) {
267                          push @tar_files, $entry->name;                          push @tar_files, $entry->name;
268                          $items++;                          $items++;
269                          $tar_size += $entry->size;                          $tar_size_inarc += $entry->size;
270    
271                          if ($tar_size > $Conf{MaxArchiveFileSize}) {                          if ($tar_size_inarc > $Conf{MaxArchiveFileSize}) {
272                                  print ", part $tarfilename is too big $tar_size > $Conf{MaxArchiveFileSize}\n";                                  print ", part $tarfilename is too big $tar_size_inarc > $Conf{MaxArchiveFileSize}\n";
273                                  return 0;                                  return 0;
274                          }                          }
275    
276                  }                  }
277    
278                    close($fh);
279    
280                  print ", $items items";                  print ", $items items";
281    
282                    if ($tar_size_inarc == 0 && $items == 0) {
283                            print ", EMPTY tar\n";
284    
285                            my $backup_id = get_backup_id($host, $share, $num);
286                            backup_inc_deleted( $backup_id );
287    
288                            $dbh->commit;
289    
290                            return 1;
291                    }
292    
293                    my $tar_size = get_gzip_size( $path );
294    
295                    # real tar size is bigger because of padding    
296                    if ($tar_size_inarc > $tar_size) {
297                            print ", size of files in tar ($tar_size_inarc) bigger than whole tar ($tar_size)!\n";
298                            return 0;
299                    }
300    
301                  #                  #
302                  # check if md5 exists, and if not, create one                  # check if md5 exists, and if not, create one
303                  #                  #
# Line 280  select Line 381  select
381          hosts.name as host,          hosts.name as host,
382          shares.name as share,          shares.name as share,
383          backups.num as num,          backups.num as num,
384            backups.date,
385          inc_size,          inc_size,
386          parts          parts,
387            count(backup_parts.backup_id) as backup_parts
388  from backups  from backups
389          join shares on backups.hostid = shares.hostid          join shares on backups.hostid = shares.hostid
390                  and shares.id = backups.shareid                  and shares.id = backups.shareid
391          join hosts on shares.hostid = hosts.id          join hosts on shares.hostid = hosts.id
392  where not inc_deleted          full outer join backup_parts on backups.id = backup_parts.backup_id
393    where not inc_deleted and backups.size > 0
394    group by backups.id, hosts.name, shares.name, backups.num, backups.date, inc_size, parts, backup_parts.backup_id
395  order by backups.date  order by backups.date
396    
397  } );  } );
# Line 295  $sth->execute(); Line 400  $sth->execute();
400  my $num_backups = $sth->rows;  my $num_backups = $sth->rows;
401  my $curr_backup = 1;  my $curr_backup = 1;
402    
403    if ($opt{h}) {
404            warn "making increments just for host $opt{h}\n";
405    }
406    
407  while (my $row = $sth->fetchrow_hashref) {  while (my $row = $sth->fetchrow_hashref) {
408    
409            if ($opt{h} && $row->{host} ne $opt{h}) {
410                    warn "skipped $row->{host}\n" if ($debug);
411                    next;
412            }
413    
414          $curr_backup++;          $curr_backup++;
415    
416          my $tar_file = BackupPC::SearchLib::getGzipName($row->{'host'}, $row->{'share'}, $row->{'num'});          my $tar_file = BackupPC::SearchLib::getGzipName($row->{'host'}, $row->{'share'}, $row->{'num'});
# Line 306  while (my $row = $sth->fetchrow_hashref) Line 420  while (my $row = $sth->fetchrow_hashref)
420    
421          print "# size: $size backup.size: ", $row->{inc_size},"\n" if ($opt{d});          print "# size: $size backup.size: ", $row->{inc_size},"\n" if ($opt{d});
422    
423          if ( $row->{'inc_size'} != -1 && $size != -1 && $row->{'inc_size'} >= $size) {          if ( $row->{'inc_size'} != -1 && $size != -1 && $row->{'inc_size'} >= $size && $row->{parts} == $row->{backup_parts}) {
424                  if ($check) {                  if ($check) {
425                          tar_check($row->{'host'}, $row->{'share'}, $row->{'num'}, $tar_file) && next;                          tar_check($row->{'host'}, $row->{'share'}, $row->{'num'}, $tar_file) && next;
426                  } else {                  } else {
# Line 314  while (my $row = $sth->fetchrow_hashref) Line 428  while (my $row = $sth->fetchrow_hashref)
428                  }                  }
429          }          }
430    
431          print curr_time, " creating $curr_backup/$num_backups ", $row->{'host'}, ":", $row->{'share'}, " #", $row->{'num'}, " -> $tar_file";          print curr_time, " creating $curr_backup/$num_backups ", $row->{host}, ":", $row->{share}, " #", $row->{num},
432                    " ", strftime('%Y-%m-%d', localtime($row->{date})), " -> $tar_file";
433    
434          my $t = time();          my $t = time();
435    
436          # re-create archive?          # re-create archive?
437          my $cmd = qq{ $tarIncCreate -h "$row->{'host'}" -s "$row->{'share'}" -n $row->{'num'} -f };          my $cmd = qq[ $tarIncCreate -h "$row->{host}" -s "$row->{share}" -n $row->{num} -f ];
438          print STDERR "## $cmd\n" if ($debug);          print STDERR "## $cmd\n" if ($debug);
439    
440          if (system($cmd) != 0) {          if (system($cmd) != 0) {
441                  print STDERR " FAILED";                  print STDERR " FAILED, marking this backup deleted";
442                    backup_inc_deleted( $row->{backup_id} );
443          }          }
444    
445          print ", dur: ",fmt_time(time() - $t), "\n";          print ", dur: ",fmt_time(time() - $t), "\n";

Legend:
Removed from v.274  
changed lines
  Added in v.312

  ViewVC Help
Powered by ViewVC 1.1.26