X-Git-Url: http://git.rot13.org/?p=BackupPC.git;a=blobdiff_plain;f=bin%2FBackupPC;h=3f1fa2b1bbb5b93216087e47460826eab58d8d2f;hp=bec909d2e161462a6c600f9d7752bacd9a3bd89e;hb=a7e968ce327855f2ba2624ca8517069a936c9b5b;hpb=3ec73efe5ee035c9cda24dc70500157e455d9c84 diff --git a/bin/BackupPC b/bin/BackupPC index bec909d..3f1fa2b 100755 --- a/bin/BackupPC +++ b/bin/BackupPC @@ -29,7 +29,7 @@ # Craig Barratt # # COPYRIGHT -# Copyright (C) 2001 Craig Barratt +# Copyright (C) 2001-2003 Craig Barratt # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -47,13 +47,14 @@ # #======================================================================== # -# Version 2.0.0beta2, released 13 Apr 2003. +# Version 2.1.0_CVS, released 3 Jul 2003. # # See http://backuppc.sourceforge.net. # #======================================================================== use strict; +no utf8; use vars qw(%Status %Info $Hosts); use lib "/usr/local/BackupPC/lib"; use BackupPC::Lib; @@ -299,6 +300,7 @@ sub Main_Initialize $Info{ConfigModTime} = $bpc->ConfigMTime(); $Info{pid} = $$; $Info{startTime} = time; + $Info{ConfigLTime} = time; $Info{Version} = $bpc->{Version}; # @@ -476,7 +478,7 @@ sub Main_TryToRun_Bg_or_User_Queue next; } push(@args, $req->{doFull} ? "-f" : "-i") - if ( !$req->{restore} ); + if (( !$req->{restore} ) && ( !$req->{archive} )); $UserQueueOn{$req->{host}} = 0; } elsif ( $nJobs < $Conf{MaxBackups} && (@CmdQueue + $nJobs) @@ -537,6 +539,10 @@ sub Main_TryToRun_Bg_or_User_Queue $progName = "BackupPC_restore"; $type = "restore"; push(@args, $req->{hostIP}, $req->{host}, $req->{reqFileName}); + } elsif ( $req->{archive} ) { + $progName = "BackupPC_archive"; + $type = "archive"; + push(@args, $req->{user}, $req->{host}, $req->{reqFileName}); } else { $progName = "BackupPC_dump"; $type = "backup"; @@ -596,13 +602,7 @@ sub Main_Select = localtime(time); my($currHours) = $hour + $min / 60 + $sec / 3600; if ( $bpc->ConfigMTime() != $Info{ConfigModTime} ) { - my($mesg) = $bpc->ConfigRead() - || "Re-read config file because mtime changed"; - print(LOG $bpc->timeStamp, "$mesg\n"); - %Conf = $bpc->Conf(); - $Info{ConfigModTime} = $bpc->ConfigMTime(); - umask($Conf{UmaskMode}); - ServerSocketInit(); + ServerReload("Re-read config file because mtime changed"); } my $delta = -1; foreach my $t ( @{$Conf{WakeupSchedule} || [0..23]} ) { @@ -650,23 +650,9 @@ sub Main_Process_Signal # Process signals # if ( $SigName eq "HUP" ) { - my($mesg) = $bpc->ConfigRead() - || "Re-read config file because of a SIG_HUP"; - print(LOG $bpc->timeStamp, "$mesg\n"); - $Info{ConfigModTime} = $bpc->ConfigMTime(); - %Conf = $bpc->Conf(); - umask($Conf{UmaskMode}); - ServerSocketInit(); - HostsUpdate(0); - $NextWakeup = 0; + ServerReload("Re-read config file because of a SIG_HUP"); } elsif ( $SigName ) { - print(LOG $bpc->timeStamp, "Got signal $SigName... cleaning up\n"); - foreach my $host ( keys(%Jobs) ) { - kill(2, $Jobs{$host}{pid}); - } - StatusWrite(); - unlink("$TopDir/log/BackupPC.pid"); - exit(1); + ServerShutdown("Got signal $SigName... cleaning up"); } $SigName = ""; } @@ -845,9 +831,12 @@ sub Main_Check_Job_Messages delete($Status{$host}{errorTime}); $Status{$host}{endTime} = time; } elsif ( $mesg =~ /^nothing to do/ ) { - $Status{$host}{state} = "Status_idle"; - $Status{$host}{reason} = "Reason_nothing_to_do"; - $Status{$host}{startTime} = time; + if ( $Status{$host}{reason} ne "Reason_backup_failed" + && $Status{$host}{reason} ne "Reason_restore_failed" ) { + $Status{$host}{state} = "Status_idle"; + $Status{$host}{reason} = "Reason_nothing_to_do"; + $Status{$host}{startTime} = time; + } $Status{$host}{dhcpCheckCnt}-- if ( $Status{$host}{dhcpCheckCnt} > 0 ); } elsif ( $mesg =~ /^no ping response/ @@ -871,7 +860,14 @@ sub Main_Check_Job_Messages $Status{$host}{error} = $1; $Status{$host}{errorTime} = time; $Status{$host}{endTime} = time; - print(LOG $bpc->timeStamp, "backup failed on $host ($1)\n"); + print(LOG $bpc->timeStamp, "Backup failed on $host ($1)\n"); + } elsif ( $mesg =~ /^restore failed: (.*)/ ) { + $Status{$host}{state} = "Status_idle"; + $Status{$host}{reason} = "Reason_restore_failed"; + $Status{$host}{error} = $1; + $Status{$host}{errorTime} = time; + $Status{$host}{endTime} = time; + print(LOG $bpc->timeStamp, "Restore failed on $host ($1)\n"); } elsif ( $mesg =~ /^log\s+(.*)/ ) { print(LOG $bpc->timeStamp, "$1\n"); } elsif ( $mesg =~ /^BackupPC_stats = (.*)/ ) { @@ -1021,7 +1017,7 @@ sub Main_Check_Client_Messages if ( $CmdJob ne $host && defined($Status{$host}) && defined($Jobs{$host}) ) { print(LOG $bpc->timeStamp, - "Stopping current backup of $host," + "Stopping current $Jobs{$host}{type} of $host," . " request by $user (backoff=$backoff)\n"); kill(2, $Jobs{$host}{pid}); # @@ -1033,11 +1029,20 @@ sub Main_Check_Client_Messages ##close($Jobs{$host}{fh}); ##delete($Jobs{$host}); - $Status{$host}{state} = "Status_idle"; - $Status{$host}{reason} = "Reason_backup_canceled_by_user"; + $Status{$host}{state} = "Status_idle"; + if ( $Jobs{$host}{type} eq "restore" ) { + $Status{$host}{reason} + = "Reason_restore_canceled_by_user"; + } elsif ( $Jobs{$host}{type} eq "archive" ) { + $Status{$host}{reason} + = "Reason_archive_canceled_by_user"; + } else { + $Status{$host}{reason} + = "Reason_backup_canceled_by_user"; + } $Status{$host}{activeJob} = 0; $Status{$host}{startTime} = time; - $reply = "ok: backup of $host cancelled"; + $reply = "ok: $Jobs{$host}{type} of $host cancelled"; } elsif ( $BgQueueOn{$host} || $UserQueueOn{$host} ) { print(LOG $bpc->timeStamp, "Stopping pending backup of $host," @@ -1102,6 +1107,36 @@ sub Main_Check_Client_Messages $UserQueueOn{$hostIP} = 1; $reply = "ok: requested backup of $host"; } + } elsif ( $cmd =~ /^archive (\S+)\s+(\S+)\s+(\S+)/ ) { + my $user = $1; + my $archivehost = $2; + my $reqFileName = $3; + $host = $bpc->uriUnesc($archivehost); + if ( !defined($Status{$host}) ) { + print(LOG $bpc->timeStamp, + "User $user requested archive of unknown archive host" + . " $host"); + $reply = "archive error: unknown archive host $host"; + } else { + print(LOG $bpc->timeStamp, + "User $user requested archive on $host" + . " ($host)\n"); + if ( defined($Jobs{$host}) ) { + $reply = "Archive currently running on $host, please try later"; + } else { + unshift(@UserQueue, { + host => $host, + hostIP => $user, + reqFileName => $reqFileName, + reqTime => time, + dhcp => 0, + archive => 1, + userReq => 1, + }); + $UserQueueOn{$host} = 1; + $reply = "ok: requested archive on $host"; + } + } } elsif ( $cmd =~ /^restore (\S+)\s+(\S+)\s+(\S+)\s+(\S+)/ ) { my $hostIP = $1; $host = $2; @@ -1187,6 +1222,15 @@ sub Main_Check_Client_Messages QueueLink($host); } elsif ( $cmd =~ /^log\s+(.*)/ ) { print(LOG $bpc->timeStamp, "$1\n"); + } elsif ( $cmd =~ /^server\s+(\w+)/ ) { + my($type) = $1; + if ( $type eq 'reload' ) { + ServerReload("Reloading server configuration..."); + } elsif ( $type eq 'shutdown' ) { + $reply = "Shutting down...\n"; + syswrite($Clients{$client}{fh}, $reply, length($reply)); + ServerShutdown("Server shutting down..."); + } } elsif ( $cmd =~ /^quit/ || $cmd =~ /^exit/ ) { $nbytes = 0; last; @@ -1426,8 +1470,9 @@ sub catch_signal print(LOG "Fatal error: unhandled signal $SigName\n"); unlink("$TopDir/log/BackupPC.pid"); confess("Got new signal $SigName... quitting\n"); + } else { + $SigName = shift; } - $SigName = shift; } # @@ -1505,3 +1550,46 @@ sub ServerSocketInit $ServerInetPort = $Conf{ServerPort}; } } + +# +# Reload the server. Used by Main_Process_Signal when $SigName eq "HUP" +# or when the command "server reload" is received. +# +sub ServerReload +{ + my($mesg) = @_; + $mesg = $bpc->ConfigRead() || $mesg; + print(LOG $bpc->timeStamp, "$mesg\n"); + $Info{ConfigModTime} = $bpc->ConfigMTime(); + %Conf = $bpc->Conf(); + umask($Conf{UmaskMode}); + ServerSocketInit(); + HostsUpdate(0); + $NextWakeup = 0; + $Info{ConfigLTime} = time; +} + +# +# Gracefully shutdown the server. Used by Main_Process_Signal when +# $SigName ne "" && $SigName ne "HUP" or when the command +# "server shutdown" is received. +# +sub ServerShutdown +{ + my($mesg) = @_; + print(LOG $bpc->timeStamp, "$mesg\n"); + if ( keys(%Jobs) ) { + foreach my $host ( keys(%Jobs) ) { + kill(2, $Jobs{$host}{pid}); + } + sleep(1); + foreach my $host ( keys(%Jobs) ) { + kill(9, $Jobs{$host}{pid}); + } + %Jobs = (); + } + StatusWrite(); + unlink("$TopDir/log/BackupPC.pid"); + exit(1); +} +