Subversion Repositories general

Compare Revisions

Ignore whitespace Rev 1153 → Rev 1154

/fsbackup/trunk/fsbackup.pl
11,7 → 11,7
# -c - clean - очиска хранилища с инкрементальным бэкапом и создание нового бэкапа.
 
#############################################
use constant DB_DEF_CACHE_SIZE => 4096000; # Размер кэша для размежения хэша в памяти
use constant DB_DEF_CACHE_SIZE => 40960000; # Размер кэша для размежения хэша в памяти
 
use POSIX;
use File::Find;
23,6 → 23,7
use constant VERB_ERROR => 1; # Output all errors and warnings.
use constant VERB_ALL => 2; # Output all the available data.
 
my $version = "2.0";
my $list_lines_cnt = 0;
my $del_lines_cnt = 0;
my $cur_time = time();
74,9 → 75,11
die "Usage: fsbackup.pl [-n|-f|-h|-c] config_name\n";
}
 
 
require "$config";
 
$cfg_move_old_backup=1 if(!defined($cfg_move_old_backup));
$cfg_exit_on_empty=1 if(!defined($cfg_exit_on_empty));
 
if ( ! -d $cfg_cache_dir){
die "\$cfg_cache_dir ($cfg_cache_dir) not found. Set \$cfg_cache_dir varisble in fsbackup.pl\n";
}
169,38 → 172,31
 
#----------- Вычисляем уровень инкрементальности.
if ($cfg_increment_level != 0 && $cfg_backup_style eq "backup"){
$cur_increment_level=0;
if(open(INCREMENT_LEVEL, "<$cfg_cache_dir/$cfg_backup_name/.increment_level")) {
$cur_increment_level = <INCREMENT_LEVEL>;
$cur_increment_level++;
close (INCREMENT_LEVEL);
}
else {
print "Can't open increment level file ($cfg_cache_dir/$cfg_backup_name/.increment_level).\n";
$cur_increment_level = 0;
}
 
if ( $cfg_type eq "local"){
opendir( DIR, "$cfg_local_path");
while ($cur_dir = readdir DIR){
if ($cur_dir =~ /\-0\.tar${arc_ext}$/){
$cur_increment_level++;
}
}
closedir (DIR);
if ($cur_increment_level >= $cfg_increment_level){
$cur_increment_level=0;
}
 
} elsif ( $cfg_type eq "remote_ssh"){
 
open (DIR, "$prog_ssh -l $cfg_remote_login $cfg_remote_host 'ls $cfg_remote_path/' |") || print "SSH connection failed: $?\n";
while (<DIR>){
$cur_dir = $_;
if ($cur_dir =~ /\-0\.tar${arc_ext}$/){
$cur_increment_level++;
}
}
close (DIR);
} elsif ( $cfg_type eq "remote_ftp"){
foreach $cur_dir ($ftp->ls()){
if ($cur_dir =~ /\-0\.tar${arc_ext}$/){
$cur_increment_level++;
}
}
}
if ($cur_increment_level >= $cfg_increment_level){
if ($cur_increment_level == 0){
$cfg_new_flag=1;
$cfg_clean_flag=1;
}
if(open(INCREMENT_LEVEL, ">$cfg_cache_dir/$cfg_backup_name/.increment_level")) {
print INCREMENT_LEVEL $cur_increment_level;
close (INCREMENT_LEVEL);
}
else {
print "Can't save increment level to file ($cfg_cache_dir/$cfg_backup_name/.increment_level).\n";
}
print "Current increment number: $cur_increment_level\n" if ($cfg_verbose == &VERB_ALL);
}
################################################
248,6 → 244,11
open (DIRS, ">$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.dir")|| print "Can't create list file ($cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.dir).\n";
flock (DIRS, 2);
 
open (META, ">$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.meta")|| print "Can't create meta file ($cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.meta).\n";
print META "fsbackup $version\n";
print META "increment level: $cur_increment_level\n";
close(META);
 
# Считываем список подлежащих бэкапу директорий в память.
 
while(<DATA>){
340,7 → 341,8
#------------
# Архивируем и передаем в хранилище.
 
if ($list_lines_cnt == 0 && $del_lines_cnt == 0){
if ($cfg_exit_on_empty == 1 && $list_lines_cnt == 0 && $del_lines_cnt == 0){
print "$cfg_exit_on_empty\n";
print "WARNING: Nothing to backup.\n" if ($cfg_verbose >= &VERB_ALL);
exit;
}
362,7 → 364,7
if ($cfg_clean_flag == 1){ # Удалить старые копии
if ($cfg_save_old_backup == 0){
system( "$prog_rm -f $cfg_local_path/*");
} else {
} elsif($cfg_move_old_backup == 1) {
if (! -d "$cfg_local_path/OLD"){
system( "mkdir $cfg_local_path/OLD");
}
371,13 → 373,14
# system( "$prog_rm -f $cfg_local_path/*");
}
}
system( "cp -f $cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.meta $cfg_local_path/$backup_file_base.meta") == 0 || print "Local FS .meta copy failed: $?\n";
system( "cp -f $cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.list $cfg_local_path/$backup_file_base.list") == 0 || print "Local FS .list copy failed: $?\n";
system( "cp -f $cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.dir $cfg_local_path/$backup_file_base.dir") == 0 || print "Local FS .dir copy failed: $?\n";
system( "cp -f $cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.del $cfg_local_path/$backup_file_base.del") == 0 || print "Local FS .del copy failed: $?\n";
system( "cp -f $cfg_cache_dir/$cfg_backup_name/.hash $cfg_local_path/$backup_file_base.hash") == 0 || print "Local FS .hash copy failed: $?\n";
#system( "cp -f $cfg_cache_dir/$cfg_backup_name/.hash $cfg_local_path/$backup_file_base.hash") == 0 || print "Local FS .hash copy failed: $?\n";
# Обрабатываем разбиение на тома
for ($arc_block_level=0; $arc_block_level <= $#volume_position; $arc_block_level++){
my $tmp_list_file = crate_tmp_list($arc_block_level, $volume_position[$arc_block_level], $volume_position[$arc_block_level+1], "$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.list");
my $tmp_list_file = create_tmp_list($arc_block_level, $volume_position[$arc_block_level], $volume_position[$arc_block_level+1], "$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.list");
system( "$prog_tar -c -f - -T $tmp_list_file $prog_gzip_filter $prog_pgp_filter > $cfg_local_path/$backup_file_base-$arc_block_level.tar${arc_ext}") == 0 || print "Local FS tar backup failed: $?\n";
}
}
424,7 → 427,7
system( "cat $cfg_cache_dir/$cfg_backup_name/.hash | $prog_ssh -l $cfg_remote_login $cfg_remote_host 'cat - > $cfg_remote_path/.hash'") == 0 || print "SSH connection failed (cache .hash): $?\n";
# Обрабатываем разбиение на тома
for ($arc_block_level=0; $arc_block_level <= $#volume_position; $arc_block_level++){
my $tmp_list_file = crate_tmp_list($arc_block_level, $volume_position[$arc_block_level], $volume_position[$arc_block_level+1], "$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.list");
my $tmp_list_file = create_tmp_list($arc_block_level, $volume_position[$arc_block_level], $volume_position[$arc_block_level+1], "$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.list");
system( "$prog_tar -c -f - -T $tmp_list_file $prog_gzip_filter $prog_pgp_filter| $prog_ssh -l $cfg_remote_login $cfg_remote_host 'cat - > $cfg_remote_path/$backup_file_base-$arc_block_level.tar${arc_ext}'") == 0 || print "SSH connection failed (tar): $?\n";
}
}
468,7 → 471,7
$ftp->put("$cfg_cache_dir/$cfg_backup_name/.hash", ".hash")|| print "Can't PUT new .hash file to remote FTP server\n";
# Обрабатываем разбиение на тома
for ($arc_block_level=0; $arc_block_level <= $#volume_position; $arc_block_level++){
my $tmp_list_file = crate_tmp_list($arc_block_level, $volume_position[$arc_block_level], $volume_position[$arc_block_level+1], "$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.list");
my $tmp_list_file = create_tmp_list($arc_block_level, $volume_position[$arc_block_level], $volume_position[$arc_block_level+1], "$cfg_cache_dir/$cfg_backup_name/$cfg_backup_name.list");
$ftp->delete("$backup_file_base-$arc_block_level.tar${arc_ext}");
open (TAR,"$prog_tar -c -f - -T $tmp_list_file $prog_gzip_filter $prog_pgp_filter|")|| print "tar failed: $?\n";
flock(TAR,1);
504,12 → 507,10
($tmp, $tmp, $stat_mode, $tmp, $stat_uid, $stat_gid, $tmp, $stat_size, $tmp, $stat_mtime, $stat_time) = stat($file_fullpath);
$stat_mode = sprintf ("%04o", $stat_mode & 07777);
$file_fullpath_esc =~ s/^\/(.*)$/$1/;
$stat_uid = getpwuid($stat_uid);
$stat_gid = getgrgid($stat_gid);
my ($sec,$min,$hour,$mday,$mon,$year) = localtime($stat_time);
$stat_time = sprintf ("%4.4d%2.2d%2.2d%2.2d%2.2d.%2.2d",
$year+1900,$mon+1,$mday,$hour,$min,$sec);
print DIRS "mkdir '$file_fullpath_esc'\n";
print DIRS "mkdir -p '$file_fullpath_esc'\n";
print DIRS "chmod $stat_mode '$file_fullpath_esc'\n";
print DIRS "chown $stat_uid:$stat_gid '$file_fullpath_esc'\n";
print DIRS "touch -t $stat_time '$file_fullpath_esc'\n";
521,6 → 522,8
$cur_backup_size = $stat_size + int(length($file_fullpath)/100.0 + 1)*512 + 1536;
push @volume_position, $list_lines_cnt;
}
$active_hash_new{$file_fullpath} = "D";
check_update($file_fullpath, "D", $file_fullpath, $stat_size);
}
} else {
if ($cfg_stopdir_prune == 1){
561,7 → 564,7
sub check_update{
my ($file, $checksum, $filesum, $stat_size) = @_;
if ( $active_hash_last{$filesum} ne $checksum){
if (($active_hash_last{$filesum} ne $checksum) && ($checksum ne "D")){
if ($cfg_backup_style ne "hash"){
$file =~ s/^\/(.*)$/$1/;
print LIST "$file\n";
583,10 → 586,18
}
$list_lines_cnt++;
}
delete $active_hash_last{$filesum};
if (defined $dbobj_last){
$dbobj_last->del($filesum);
if(($active_hash_last{$filesum} eq "D") && ($checksum ne "D")
|| ($active_hash_last{$filesum} ne "D") && ($checksum eq "D"))
{
# if old entry was a directory and now it's file or link or vice versa, leave it in hash
# to add it later to the delete list
}
else {
delete $active_hash_last{$filesum};
if (defined $dbobj_last){
$dbobj_last->del($filesum);
}
}
}
 
###############################################
661,7 → 672,7
###############################################
# Содание списка файлов для помещения в определенный том многотомного архива.
 
sub crate_tmp_list{
sub create_tmp_list{
my ($arc_block_level, $position1, $position2, $full_list_path) = @_;
my ($tmp_list_path, $pos_counter);
 
738,7 → 749,7
 
Backup planner running from C<crontab>. For example:
 
18 4 * * * /usr/local/fsbackup/create_backup.sh
18 4 * * * /root/backup/fsbackup/create_backup.sh
 
=item C<install.pl>
 
778,7 → 789,7
 
Name of backup, single word.
 
=item B<$cfg_cache_dir> = '/usr/local/fsbackup/cache'
=item B<$cfg_cache_dir> = '/root/backup/fsbackup/cache'
 
Path of internal cache directory for local backup method.