--- psinib.pl 2003/07/15 17:40:32 1.9 +++ psinib.pl 2003/10/12 21:46:42 1.15 @@ -24,6 +24,7 @@ use Fcntl qw(LOCK_EX LOCK_NB); use Digest::MD5; use File::Basename; +use Getopt::Long; # configuration my $LOG_TIME_FMT = '%Y-%m-%d %H:%M:%S'; # strftime format for logfile @@ -34,6 +35,7 @@ # store backups in which directory my $BACKUP_DEST = '/backup/isis_backup'; +#my $BACKUP_DEST = '/tmp/backup/'; # files to ignore in backup my @ignore = ('.md5sum', '.backupignore', 'backupignore.txt'); @@ -50,13 +52,19 @@ sleep 1; redo if ++$c < 10; # no response for 10 sec, bail out - print STDERR "can't take lock on $LOG -- another $0 running?\n"; + xlog("ABORT","can't take lock on $LOG -- another $0 running?"); exit 1; } # taint path: nmblookup should be there! $ENV{'PATH'} = "/usr/bin:/bin"; +my $use_ping = 1; # deault: use ping to verify that host is up + +my $result = GetOptions( + "ping!" => \$use_ping, "backupdest!" => \$BACKUP_DEST, +); + my $mounts = shift @ARGV || 'mountscript'; # die "usage: $0 mountscript"; @@ -64,9 +72,12 @@ my @in_backup; # shares which are backeduped this run -my $p = new Net::Ping->new("tcp", 2); -# ping will try tcp connect to netbios-ssn (139) -$p->{port_num} = getservbyname("netbios-ssn", "tcp"); +my $ping; +if ($use_ping) { + $ping = new Net::Ping->new("tcp", 2); + # ping will try tcp connect to netbios-ssn (139) + $ping->{port_num} = getservbyname("netbios-ssn", "tcp"); +} my $backup_ok = 0; @@ -81,7 +92,7 @@ next if !/^\s*smbmount\s/; my (undef,$share,undef,$opt) = split(/\s+/,$_,4); - my ($user,$passwd,$workgroup); + my ($user,$passwd,$workgroup,$ip); foreach (split(/,/,$opt)) { my ($n,$v) = split(/=/,$_,2); @@ -97,6 +108,8 @@ } } elsif ($n =~ m#workgroup#i) { $workgroup = $v; + } elsif ($n =~ m#ip#i) { + $ip = $v; } } @@ -121,14 +134,15 @@ print "working on $share\n"; - - my $ip = get_ip($share); + # try to nmblookup IP + $ip = get_ip($share) if (! $ip); if ($ip) { xlog($share,"IP is $ip"); - if ($p->ping($ip)) { - snap_share($share,$user,$passwd,$workgroup); - $backup_ok++; + if (($use_ping && $ping->ping($ip)) || 1) { + if (snap_share($share,$user,$passwd,$workgroup)) { + $backup_ok++; + } } } } @@ -227,7 +241,7 @@ if (-l $bc && $real_bl && $real_bl eq $bc) { print "$share allready backuped...\n"; - return; + return 1; } die "You should really create BACKUP_DEST [$BACKUP_DEST] by hand! " if (!-e $BACKUP_DEST); @@ -255,6 +269,7 @@ my %file_atime; my %file_mtime; #my %file_md5; + %file_md5 = (); my @smb_files; my %smb_size; @@ -316,7 +331,7 @@ } elsif (-d $pf) { push @dirs,$pr; } else { - print STDERR "unknown type: $pf\n"; + print STDERR "not file or directory: $pf\n"; } } else { print STDERR "ignored: $pr\n"; @@ -324,7 +339,8 @@ } } - xlog($share,($#files+1)." files and ".($#dirs+1)." dirs on local disk before backup"); + # local dir always include / + xlog($share,($#files+1)." files and ".($#dirs)." dirs on local disk before backup"); # read smb filesystem @@ -339,10 +355,10 @@ my $pf = norm_dir($d,"smb:$share/"); # path full my $D = $smb->opendir($pf); if (! $D) { - xlog($share,"FATAL: $share: $!"); + xlog($share,"FATAL: $share [$pf]: $!"); # remove failing dir delete $smb_dirs[$di]; - next; + return 0; # failed } $di++; @@ -362,7 +378,7 @@ } elsif ($item->[0] == main::SMBC_DIR) { push @smb_dirs,$pr; } else { - print STDERR "unknown type: $pf\n"; + print STDERR "not file or directory [",$item->[0],"]: $pf\n"; } } else { print STDERR "smb ignored: $pr\n"; @@ -370,7 +386,7 @@ } } - xlog($share,($#smb_files+1)." files and ".($#smb_dirs+1)." dirs on remote share"); + xlog($share,($#smb_files+1)." files and ".($#smb_dirs)." dirs on remote share"); # sync dirs my $lc = List::Compare->new(\@dirs, \@smb_dirs); @@ -402,16 +418,16 @@ foreach my $f (@_) { #print "smb_copy $from/$f -> $to/$f\n"; - if (! open(F,"> $to/$f")) { - print STDERR "can't open new file $to/$f: $!\n"; - next; - } - my $md5 = Digest::MD5->new; my $fd = $smb->open("$from/$f"); if (! $fd) { - print STDERR "can't open smb file $from/$f: $!\n"; + xlog("WARNING","can't open smb file $from/$f: $!"); + next; + } + + if (! open(F,"> $to/$f")) { + xlog("WARNING","can't open new file $to/$f: $!"); next; } @@ -485,6 +501,7 @@ # remove files foreach (sort @files2erase) { unlink "$bc/$_" || warn "unlink $_: $!\n"; + delete $file_md5{$_}; } # remove not needed dirs (after files) @@ -497,13 +514,21 @@ unlink "$bc/$_/.md5sum" if (-e "$bc/$_/.md5sum"); } + # erase stale entries in .md5sum + my @md5_files = keys %file_md5; + $lc = List::Compare->new(\@md5_files, \@smb_files); + foreach my $file ($lc->get_Lonly) { + xlog("NOTICE","removing stale '$file' from .md5sum"); + delete $file_md5{$file}; + } + # create .md5sum my $last_dir = ''; my $md5; foreach my $f (sort { $file_md5{$a} cmp $file_md5{$b} } keys %file_md5) { my $dir = dirname($f); my $file = basename($f); -print "$f -- $dir / $file<--\n"; +#print "$f -- $dir / $file<--\n"; if ($dir ne $last_dir) { close($md5) if ($md5); open($md5, ">> $bc/$dir/.md5sum") || warn "can't create $bc/$dir/.md5sum: $!"; @@ -512,7 +537,7 @@ } print $md5 $file_md5{$f}," $file\n"; } - close($md5); + close($md5) if ($md5); # create leatest link #print "ln -s $bc $real_bl\n"; @@ -525,8 +550,9 @@ xlog($share,"failed to create latest symlink $bl -> $bc...") if (readlink($bl) ne $bc || ! -l $bl); xlog($share,"backup completed..."); -} + return 1; +} __END__ #------------------------------------------------------------------------- @@ -652,6 +678,19 @@ linking same files (other alternative would be to erase that dir and find second-oldest directory, but this seemed like more correct approach). +=head2 I can't connect to any share + +Please verify that nmblookup (which is part of samba package) is in /bin or +/usr/bin. Also verify that nmblookup returns IP address for your server +using: + + $ nmblookup tvhouse + querying tvhouse on 192.168.34.255 + 192.168.34.30 tvhouse<00> + +If you don't get any output, your samba might not listen to correct interface +(see interfaces in smb.conf). + =head1 AUTHOR Dobrica Pavlinusic