chiark / gitweb /
Found on davenant in /usr/local/lib (in use on anarres).
[chiark-utils.git] / backup / full
diff --git a/backup/full b/backup/full
new file mode 100755 (executable)
index 0000000..d3efa17
--- /dev/null
@@ -0,0 +1,166 @@
+#!/usr/bin/perl
+
+BEGIN {
+    $etc= '/etc/backup';
+    require "$etc/settings.pl";
+    require 'backuplib.pl';
+}
+
+$|=1;
+
+print "Configuration check ...\n" or die $!;
+system 'checkallused'; $? and die $?;
+
+printdate();
+
+unlink 'TAPEID';
+system "mt -f $tape setblk $blocksizebytes"; $? and die $?;
+system "dd if=$tape bs=${blocksize}b count=10 | tar -b$blocksize -vvxf - TAPEID";
+
+setstatus "FAILED during startup";
+
+if (open T, "TAPEID") {
+    unlink 'really-TAPEID';
+} elsif (open T, "really-TAPEID") {
+} else {
+    die "No TAPEID.\n";
+}
+
+chomp($tapeid= <T>);
+$tapeid =~ m/[^0-9a-zA-Z]/ and die "Bad TAPEID ($&).\n";
+$tapeid =~ m/[0-9a-zA-Z]/ or die "Empty TAPEID.\n";
+close T;
+
+setstatus "FAILED at tape identity check";
+
+if (open L, "last-tape") {
+    chomp($lasttape= <L>);
+    close L;
+} else {
+    undef $lasttape;
+}
+
+die "Tape $tapeid same as last time.\n" if $tapeid eq $lasttape;
+
+undef $fsys;
+open D, "$etc/tape.$tapeid" or die "Unknown tape $tapeid ($!).\n";
+for (;;) {
+    $_= <D> or die; chomp; s/\s+$//;
+    last if m/^end$/;
+    next unless m/\S/;
+    next if m/^\#/;
+    if (m/^filesystems (\w+)$/) {
+       $fsys= $1;
+    } elsif (m/^next (\w+)$/) {
+       $next= $1;
+    } elsif (m/^incremental$/) {
+       $incremental= 1;
+    } else {
+       die "unknown entry in tape $tapeid at line $.: $_\n";
+    }
+}
+close D or die $!;
+
+if ($incremental) {
+    die "incremental tape $tapeid has next or filesystems\n"
+       if defined($next) || defined($fsys);
+    print STDERR "Incremental tape $tapeid.\n\n";
+    setstatus "FAILED during incremental startup";
+    exec "increm $tapeid";
+    die $!;
+}
+
+readfsys("$fsys");
+openlog();
+
+$doing= "dump of $fsys to tape $tapeid in drive $tape";
+print LOG "$doing:\n" or die $!;
+
+system "mt -f $tape rewind"; $? and die $?;
+system "mt -f $tape retension"; $? and die $?;
+
+open T, ">TAPEID" or die $!;
+print T "$tapeid\n" or die $!;
+close T or die $!;
+
+system "tar -b$blocksize -vvcf TAPEID.tar TAPEID"; $? and die $?;
+system "dd if=TAPEID.tar of=$ntape bs=${blocksize}b count=10"; $? and die $?;
+
+unlink 'this-md5sums';
+
+print "Doing $doing ...\n" or die $!;
+
+unlink 'p';
+system 'mknod p p'; $? and die $?;
+
+setstatus "FAILED during dump";
+
+sub closepipes () {
+    close(DUMPOR); close(TEEOR); close(BUFOR); close(FINDOR);
+    close(DUMPOW); close(TEEOW); close(BUFOW); close(FINDOW);
+}
+
+for $tf (@fsys) {
+    printdate();
+    pipe(FINDOR,FINDOW) or die $!;
+    pipe(DUMPOR,DUMPOW) or die $!;
+    pipe(TEEOR,TEEOW) or die $!;
+    pipe(BUFOR,BUFOW) or die $!;
+    parsefsys();
+    if ($tm eq 'dump') {
+       $dumpcmd= "dump 0bfu $softblocksizekb - $atf";
+       $dumpin= '</dev/null';
+    } else {
+       startprocess '</dev/null','>&FINDOW',$rstr."find $atf -xdev -noleaf -print0";
+       $dumpcmd= "cpio -Hustar -o0C$softblocksizebytes";
+       $dumpin= '<&FINDOR';
+    }
+    startprocess '<p','>>this-md5sums','md5sum';
+    startprocess $dumpin,'>&DUMPOW',$rstr.$dumpcmd;
+    startprocess '<&DUMPOR','>&TEEOW','tee p';
+    startprocess '<&TEEOR','>&BUFOW','writebuffer';
+    startprocess '<&BUFOR','>/dev/null'
+       ,"dd ibs=$softblocksizebytes obs=$blocksizebytes of=$ntape";
+    closepipes();
+    endprocesses();
+}
+
+setstatus "FAILED during check";
+
+system "mt -f $tape rewind"; $? and die $?;
+system "mt -f $ntape fsf 1"; $? and die $?;
+
+open S,"this-md5sums" or die $!;
+for $tf (@fsys) {
+    printdate();
+    chomp($orgsum= <S>);
+    $orgsum =~ m/^[0-9a-fA-F]{32}$/i or die "orgsum \`$orgsum' ?";
+    chomp($csum= `readbuffer <$ntape | md5sum`);
+    $orgsum eq $csum or die "MISMATCH $tf $csum $orgsum\n";
+    print "checksum ok $csum\t$tf\n" or die $!;
+    print LOG "checksum ok $csum\t$tf\n" or die $!;
+}
+printdate();
+system "mt -f $tape rewind"; $? and die $?;
+
+setstatus "FAILED during cleanup";
+
+open IAN,">increm-advance.new" or die $!;
+print IAN "1\n" or die $!;
+close IAN or die $!;
+
+open TN,">next-full.new" or die $!;
+print TN "$next\n" or die $!;
+close TN or die $!;
+
+unlink 'last-tape','next-full';
+rename 'TAPEID','last-tape' or die $!;
+rename 'this-md5sums',"md5sums.$fsys" or die $!;
+rename 'log',"log.$fsys" or die $!;
+rename 'next-full.new',"next-full" or die $!;
+rename 'increm-advance.new',"increm-advance" or die $!;
+
+print "$doing completed.\nNext dump tape is $next.\n" or die $!;
+
+setstatus "Successful ($tapeid $fsys, next $next)";
+exit 0;