/[BackupPC]/trunk/bin/BackupPC_tarIncCreate
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_tarIncCreate

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

revision 100 by dpavlin, Tue Aug 30 20:29:26 2005 UTC revision 170 by dpavlin, Mon Oct 10 14:14:28 2005 UTC
# Line 1  Line 1 
1  #!/usr/bin/perl  #!/usr/bin/perl
2  #============================================================= -*-perl-*-  #============================================================= -*-perl-*-
3  #  #
4  # BackupPC_tarCreate: create a tar archive of an existing dump  # BackupPC_tarIncCreate: create a tar archive of an existing incremental dump
5  # for restore on a client.  #
6  #  #
7  # DESCRIPTION  # DESCRIPTION
8  #    #  
9  #   Usage: BackupPC_tarCreate [options] files/directories...  #   Usage: BackupPC_tarIncCreate [options]
10  #  #
11  #   Flags:  #   Flags:
12  #     Required options:  #     Required options:
# Line 31  Line 31 
31  #  #
32  # AUTHOR  # AUTHOR
33  #   Craig Barratt  <cbarratt@users.sourceforge.net>  #   Craig Barratt  <cbarratt@users.sourceforge.net>
34    #   Ivan Klaric <iklaric@gmail.com>
35    #   Dobrica Pavlinusic <dpavlin@rot13.org>
36  #  #
37  # COPYRIGHT  # COPYRIGHT
38  #   Copyright (C) 2001-2003  Craig Barratt  #   Copyright (C) 2001-2003  Craig Barratt
# Line 68  use BackupPC::Attrib qw(:all); Line 70  use BackupPC::Attrib qw(:all);
70  use BackupPC::FileZIO;  use BackupPC::FileZIO;
71  use BackupPC::View;  use BackupPC::View;
72  use BackupPC::SearchLib;  use BackupPC::SearchLib;
73  use Data::Dumper;  use Time::HiRes qw/time/;
74    use POSIX qw/strftime/;
75    use Data::Dumper;       ### FIXME
76    
77  die("BackupPC::Lib->new failed\n") if ( !(my $bpc = BackupPC::Lib->new) );  die("BackupPC::Lib->new failed\n") if ( !(my $bpc = BackupPC::Lib->new) );
78  my $TopDir = $bpc->TopDir();  my $TopDir = $bpc->TopDir();
79  my $BinDir = $bpc->BinDir();  my $BinDir = $bpc->BinDir();
80  my %Conf   = $bpc->Conf();  my %Conf   = $bpc->Conf();
 my @DBCache;  
 my $db_done = 0;  
81  my %opts;  my %opts;
82    my $in_backup_increment;
83    
84    
85  if ( !getopts("th:n:p:r:s:b:w:", \%opts) || @ARGV < 1 ) {  if ( !getopts("th:n:p:r:s:b:w:v", \%opts) ) {
86      print STDERR <<EOF;      print STDERR <<EOF;
87  usage: $0 [options] files/directories...  usage: $0 [options]
88    Required options:    Required options:
89       -h host         host from which the tar archive is created       -h host         host from which the tar archive is created
90       -n dumpNum      dump number from which the tar archive is created       -n dumpNum      dump number from which the tar archive is created
# Line 94  usage: $0 [options] files/directories... Line 98  usage: $0 [options] files/directories...
98       -p pathAdd      new path prefix       -p pathAdd      new path prefix
99       -b BLOCKS       BLOCKS x 512 bytes per record (default 20; same as tar)       -b BLOCKS       BLOCKS x 512 bytes per record (default 20; same as tar)
100       -w writeBufSz   write buffer size (default 1048576 = 1MB)       -w writeBufSz   write buffer size (default 1048576 = 1MB)
101         -v              verbose output
102  EOF  EOF
103      exit(1);      exit(1);
104  }  }
# Line 160  my(%HardLinkExtraFiles, @HardLinks); Line 165  my(%HardLinkExtraFiles, @HardLinks);
165  #  #
166  binmode(STDOUT);  binmode(STDOUT);
167  my $fh = *STDOUT;  my $fh = *STDOUT;
168  if ( $ShareName eq "*" ) {  
169      my $PathRemoveOrig = $PathRemove;  if (seedCache($Host, $ShareName, $Num)) {
170      my $PathAddOrig    = $PathAdd;          archiveWrite($fh, '/');
171      foreach $ShareName ( $view->shareList($Num) ) {          archiveWriteHardLinks($fh);
         #print(STDERR "Doing share ($ShareName)\n");  
         $PathRemove = "/" if ( !defined($PathRemoveOrig) );  
         ($PathAdd = "/$ShareName/$PathAddOrig") =~ s{//+}{/}g;  
         foreach my $dir ( @ARGV ) {  
             archiveWrite($fh, $dir);  
         }  
         archiveWriteHardLinks($fh);  
     }  
172  } else {  } else {
173      foreach my $dir ( @ARGV ) {          print STDERR "NOTE: no files found for $Host:$ShareName, increment $Num\n" if ($opts{v});
         archiveWrite($fh, $dir);  
     }  
     archiveWriteHardLinks($fh);  
174  }  }
175    
176  #  #
# Line 390  sub TarWriteFileInfo Line 384  sub TarWriteFileInfo
384  }  }
385    
386  #  #
387  # returns 1 if a given directory has files somewhere under it  # seed cache of files in this increment
 # in a given dump of a given share  
388  #  #
389  sub checkSubDirs($$$$) {  sub seedCache($$$) {
390          my ($dir, $share, $host, $dumpNo) = @_;          my ($host, $share, $dumpNo) = @_;
391          my $ret;  
392          my $dsn = $Conf{SearchDSN};          my $dsn = $Conf{SearchDSN};
393          my $db_user = $Conf{SearchUser} || '';          my $db_user = $Conf{SearchUser} || '';
         my $search_sql;  
394                    
395          print(STDERR $dir);          print STDERR curr_time(), "getting files for $host:$share increment $dumpNo..." if ($opts{v});
396          # erase first dot          my $sql = q{
397          if (substr($dir, 0, 1) == '.')                  SELECT path
398          {                  FROM files
399                  $dir = substr($dir, 1, length($dir));                          JOIN shares on shares.id = shareid
400          }                          JOIN hosts on hosts.id = shares.hostid
401          # erase first slash                  WHERE hosts.name = ? and shares.name = ? and backupnum = ?
402          if (substr($dir, 0, 1) == '/')          };
403          {  
404                  $dir = substr($dir, 1, length($dir));                    my $dbh = DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 1} );      
405          }          my $sth = $dbh->prepare($sql);  
406          # erase last slash          $sth->execute($host, $share, $dumpNo);
407          if (substr($dir, length($dir)-1, 1) == '/')          my $count = $sth->rows;
408          {          print STDERR " found $count items\n" if ($opts{v});
409                  $dir = substr($dir, 0, length($dir)-1);          while (my $row = $sth->fetchrow_arrayref) {
410          }  #print STDERR "+ ", $row->[0],"\n";
411                    $in_backup_increment->{ $row->[0] }++;
         if (! $db_done)  
         {  
                 print STDERR "doing db...";  
                 my $search_sql = q{  
                                 SELECT hosts.name, shares.name, startfiles.name, COUNT(files.*) AS subfiles  
                                 FROM files startfiles  
                                          INNER JOIN shares ON (shares.id=startfiles.shareid)  
                                          INNER JOIN hosts ON  (hosts.id=shares.hostid)  
                                          INNER JOIN backups ON (  
                                                 backups.num=startfiles.backupnum AND  
                                                 backups.hostid=hosts.id AND backups.shareid=shares.id  
                                          )  
                                          LEFT JOIN files ON  (  
                                                 files.backupnum=startfiles.backupnum AND  
                                                 files.shareid=startfiles.shareid AND  
                                                 files.path LIKE startfiles.path || '/%' AND                
                                                 files.type<>startfiles.type AND                  
                                                 files.id <> startfiles.id  
                                         )                
                                 WHERE                            
                                         hosts.name=? AND                  
                                         shares.name=? AND            
                                         startfiles.type=? AND            
                                         startfiles.backupnum=?  
                                 GROUP BY hosts.name, shares.name, startfiles.name, startfiles.backupnum;  
                         };        
                 my $dbh = DBI->connect($dsn, $db_user, "", { RaiseError => 1, AutoCommit => 1} );        
                 my $sth = $dbh->prepare($search_sql);    
                 $sth->execute($host, $share, BPC_FTYPE_DIR, $dumpNo);  
                 print STDERR "done\n";  
                 while (my @r_data = $sth->fetchrow_array())  
                 {  
                         $DBCache[$r_data[0]][$r_data[1]][$r_data[2]] = 1;  
                 }  
                   
                 $sth->finish();  
   
                 $DBCache[$host][$share][$dir] = $ret;            
                 $dbh->disconnect();      
                 $db_done = 1;  
412          }          }
413            
414            $sth->finish();
415            $dbh->disconnect();
416    
417          if ($DBCache[$host][$share][$dir] != undef && $DBCache[$host][$share][$dir] == 1)          return $count;
         {  
                 return 1;  
         }  
         return 0;  
418  }  }
419    
420  my $Attr;  my $Attr;
# Line 473  sub TarWriteFile Line 424  sub TarWriteFile
424  {  {
425      my($hdr, $fh, $tarPathOverride) = @_;      my($hdr, $fh, $tarPathOverride) = @_;
426    
   
427      my $tarPath = $hdr->{relPath};      my $tarPath = $hdr->{relPath};
428      $tarPath = $tarPathOverride if ( defined($tarPathOverride) );      $tarPath = $tarPathOverride if ( defined($tarPathOverride) );
429    
430      $tarPath =~ s{//+}{/}g;      $tarPath =~ s{//+}{/}g;
431    
432    #print STDERR "? $tarPath\n";
433        return unless ($in_backup_increment->{$tarPath});
434    #print STDERR "A $tarPath\n";
435    
436      if ( defined($PathRemove)      if ( defined($PathRemove)
437              && substr($tarPath, 0, length($PathRemove)) eq $PathRemove ) {              && substr($tarPath, 0, length($PathRemove)) eq $PathRemove ) {
438          substr($tarPath, 0, length($PathRemove)) = $PathAdd;          substr($tarPath, 0, length($PathRemove)) = $PathAdd;
# Line 493  sub TarWriteFile Line 448  sub TarWriteFile
448                    
449                                    
450          $hdr->{name} .= "/" if ( $hdr->{name} !~ m{/$} );          $hdr->{name} .= "/" if ( $hdr->{name} !~ m{/$} );
451          # check if it has files under it in the database                  TarWriteFileInfo($fh, $hdr);
452                  if ( checkSubDirs($hdr->{path}, $ShareName, $Host, $Num) != 0 )          $DirCnt++;
                 {  
                 TarWriteFileInfo($fh, $hdr);  
                         $DirCnt++;  
                 }  
453      } elsif ( $hdr->{type} == BPC_FTYPE_FILE ) {      } elsif ( $hdr->{type} == BPC_FTYPE_FILE ) {
454          #          #
455          # Regular file: write the header and file          # Regular file: write the header and file
# Line 538  sub TarWriteFile Line 489  sub TarWriteFile
489              $hdr->{linkname} .= $data;              $hdr->{linkname} .= $data;
490          }          }
491                  $f->close;                  $f->close;
                 #  
                 # Check @ARGV and the list of hardlinked files we have explicity  
                 # dumped to see if we have dumped this file or not  
                 #  
492                  my $done = 0;                  my $done = 0;
493                  my $name = $hdr->{linkname};                  my $name = $hdr->{linkname};
494                  $name =~ s{^\./}{/};                  $name =~ s{^\./}{/};
495                  if ( $HardLinkExtraFiles{$name} ) {                  if ( $HardLinkExtraFiles{$name} ) {
                     $done = 1;  
                 } else {  
                     foreach my $arg ( @ARGV ) {  
                         $arg =~ s{^\./+}{/};  
                         $arg =~ s{/+$}{};  
                         $done = 1 if ( $name eq $arg || $name =~ /^\Q$arg\// );  
                     }  
                 }  
                 if ( $done ) {  
496                      #                      #
497                      # Target file will be or was written, so just remember                      # Target file will be or was written, so just remember
498                      # the hardlink so we can dump it later.                      # the hardlink so we can dump it later.
# Line 621  sub TarWriteFile Line 559  sub TarWriteFile
559          $ErrorCnt++;          $ErrorCnt++;
560      }      }
561  }  }
562    
563    my $t_fmt = '%Y-%m-%d %H:%M:%S';
564    sub curr_time {
565            return strftime($t_fmt,localtime());
566    }

Legend:
Removed from v.100  
changed lines
  Added in v.170

  ViewVC Help
Powered by ViewVC 1.1.26