From ef74fefeba9761cd21b542976e3853ab0f4ce1a5 Mon Sep 17 00:00:00 2001 From: ianmdlvl Date: Sun, 7 Oct 2001 17:17:05 +0000 Subject: [PATCH] From Peter Maydell (/u2/pmaydell/iwjbackup/) as per in davenant:~ian/mail/INBOX on Sun, 03 Jun 2001 18:45:47 +0100 --- backup/Ucam.comp.unix | 251 ++++++++++++++++++++++++++++++++++++++++++ backup/backuplib.pl | 30 ++++- backup/bringup | 5 +- backup/checkallused | 45 ++++---- backup/driver | 16 ++- backup/etc.tgz | Bin 0 -> 1266 bytes backup/expected-diffs | 7 +- backup/fsys.all | 58 +++------- backup/full | 76 ++++++++++--- backup/increm | 33 +++++- backup/increm-advance | 2 +- backup/iwjbackup.txt | 141 ++++++++++++++++++++++++ backup/last-tape | 2 +- backup/lib.tgz | Bin 0 -> 21804 bytes backup/next-full | 2 +- backup/readbuffer | Bin 13591 -> 14346 bytes backup/readbuffer.c | 32 ++++-- backup/settings.pl | 10 +- backup/takedown | 15 +++ backup/tape.b | 3 + backup/tape.c | 3 + backup/tape.d | 3 + backup/tape.e | 3 + backup/var.tgz | Bin 0 -> 1482 bytes backup/whatsthis | 122 ++++++++++++++++++++ backup/writebuffer | Bin 13742 -> 14519 bytes backup/writebuffer.c | 24 +++- 27 files changed, 770 insertions(+), 113 deletions(-) create mode 100644 backup/Ucam.comp.unix create mode 100644 backup/etc.tgz create mode 100644 backup/iwjbackup.txt create mode 100644 backup/lib.tgz create mode 100644 backup/tape.b create mode 100644 backup/tape.c create mode 100644 backup/tape.d create mode 100644 backup/tape.e create mode 100644 backup/var.tgz create mode 100755 backup/whatsthis diff --git a/backup/Ucam.comp.unix b/backup/Ucam.comp.unix new file mode 100644 index 0000000..74bddbd --- /dev/null +++ b/backup/Ucam.comp.unix @@ -0,0 +1,251 @@ +From ijackson@chiark.greenend.org.uk Wed Aug 12 19:36:07 BST 1998 +Article: 742 of ucam.comp.unix +Path: ewrotcd!not-for-mail +From: ijackson@chiark.greenend.org.uk (Ian Jackson) +Newsgroups: ucam.comp.unix,comp.sys.sun.admin +Subject: Buffering programs (was Re: Speeding up network dumps) +Date: 21 Jul 1998 12:23:23 +0100 (BST) +Organization: Linux Unlimited +Lines: 233 +Message-ID: +References: <6oiapl$6k5$1@pegasus.csx.cam.ac.uk> <6ol7kf$cln$2@pegasus.csx.cam.ac.uk> +NNTP-Posting-Host: chiark.greenend.org.uk +X-Server-Date: 21 Jul 1998 11:23:25 GMT +Originator: ijackson@news.chiark.greenend.org.uk ([127.0.0.1]) +Xref: news.chiark.greenend.org.uk ucam.comp.unix:742 comp.sys.sun.admin:14526 + +I said I'd post here the buffering programs that I use, so here they +are. + +They're perfectly functional and (I believe) correct, but they do lack +sophistication. The size of the buffer is a #define, and the +diagnostics lack verbosity. I haven't compiled them on anything but +Linux/i386 libc5, but they ought to work on other reasonable Unices. + +writebuffer is intended for writing to tapes; when its buffer is empty +it will write no more data until it gets 3/4 of its buffer filled, or +EOF. + +readbuffer is intended for reading from tapes; when its buffer becomes +full it stops reading until it's down to 1/4. + +Remember that using shell pipes loses the exit status of all but the +last command, and so can cause failures to go unnoticed. + + +/* + * writebuffer.c + * + * Copyright (C) 1997,1998 Ian Jackson + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this file; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include + +#define BUFFER 16*1024*1024 +#define WAITFILL ((BUFFER*3)/4) + +static inline int min(int a, int b) { return a<=b ? a : b; } + +static void nonblock(int fd) { + int r; + r= fcntl(fd,F_GETFL,0); if (r == -1) { perror("fcntl getfl"); exit(1); } + r |= O_NDELAY; + if (fcntl(fd,F_SETFL,r) == -1) { perror("fcntl setfl"); exit(1); } +} + +int main(void) { + static unsigned char buf[BUFFER]; + + unsigned char *wp, *rp; + int used,r,writing,seeneof; + fd_set readfds; + fd_set writefds; + + used=0; wp=rp=buf; writing=0; seeneof=0; + nonblock(0); nonblock(1); + while (!seeneof || used) { + FD_ZERO(&readfds); if (!seeneof && used+1 WAITFILL) writing=1; + } + if (FD_ISSET(1,&writefds) && used) { + r= write(1,wp,min(used,buf+BUFFER-wp)); + if (r<=0) { + if (!(errno == EAGAIN || errno == EINTR)) { perror("write"); exit(1); } +/*fprintf(stderr,"\t write transient error\n");*/ + } else { +/*fprintf(stderr,"\t wrote %d\n",r);*/ + used-= r; + wp+= r; + if (wp == buf+BUFFER) wp=buf; + } + } + } + exit(0); +} + + +/* + * readbuffer.c + * + * Copyright (C) 1997,1998 Ian Jackson + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this file; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#define BUFFER 16*1024*1024 +#define WAITEMPTY ((BUFFER*1)/4) + +static inline int min(int a, int b) { return a<=b ? a : b; } + +static void nonblock(int fd) { + int r; + r= fcntl(fd,F_GETFL,0); if (r == -1) { perror("fcntl getfl"); exit(1); } + r |= O_NDELAY; + if (fcntl(fd,F_SETFL,r) == -1) { perror("fcntl setfl"); exit(1); } +} + +int main(void) { + static unsigned char buf[BUFFER]; + + unsigned char *wp, *rp; + int used,r,reading,seeneof; + fd_set readfds; + fd_set writefds; + + used=0; wp=rp=buf; reading=1; seeneof=0; + nonblock(0); nonblock(1); + while (!seeneof || used) { + FD_ZERO(&readfds); + if (reading) { + if (used +These opinions are my own. http://www.chiark.greenend.org.uk/~ijackson/ +PGP2 public key id 0x23f5addb, fingerprint 5906F687 BD03ACAD 0D8E602E FCF37657 + + diff --git a/backup/backuplib.pl b/backup/backuplib.pl index d412c94..70d28b3 100644 --- a/backup/backuplib.pl +++ b/backup/backuplib.pl @@ -1,9 +1,14 @@ # +# Assorted useful functions used by the backup scripts. + sub printdate () { print scalar(localtime),"\n"; } +# Set status info -- we write the current status to a file +# so if we hang or crash the last thing written to the file +# will tell us where we were when things went pear-shaped. sub setstatus ($) { open S, ">this-status.new" or die $!; print S $_[0],"\n" or die $!; @@ -11,6 +16,8 @@ sub setstatus ($) { rename "this-status.new","this-status" or die $!; } +# startprocess, endprocesses, killprocesses are +# used to implement the funky pipeline stuff. sub startprocess ($$$) { my ($i,$o,$c) = @_; print LOG " $c\n" or die $!; @@ -42,28 +49,41 @@ sub killprocesses { undef %processes; } +# Read a fsys.foo filesystem group definition file. +# Syntax is: empty lines and those beginning with '#' are ignored. +# Trailing whitespace is ignored. Lines of the form 'prefix foo bar' +# are handled specially, as arex lines 'exclude regexp'; otherwise +# we just shove the line into @fsys and let parsefsys deal with it. sub readfsys ($) { my ($fsnm) = @_; open F, "$etc/fsys.$fsnm" or die "Filesystems $fsnm unknown ($!).\n"; for (;;) { - $_= or die; chomp; s/\s*$//; + $_= or die "unexpected EOF in $etc/fsys.$fsnm\n"; chomp; s/\s*$//; last if m/^end$/; next unless m/\S/; next if m/^\#/; if (m/^prefix\s+(\w+)\s+(\S.*\S)$/) { $prefix{$1}= $2; next; - } elsif (m/^prefix\-df\s+(\w+)\s+(\S.*\S)$/) { - $prefixdf{$1}= $2; - next; } + if (m/^excludedir\s+(\S.*\S)$/) { + push @excldir,$1; + next; + } + if (m/^exclude\s+(\S.*\S)$/) { + push @excl,$1; + next; + } push @fsys,$_; } close F or die $!; } +# Parse a line from a filesystem definition file. We expect the line +# to be in $tf. sub parsefsys () { if ($tf =~ m,^(/\S*)\s+(\w+)$,) { + # Line of form '/file/system dumptype' $atf= $1; $tm= $2; $prefix= ''; @@ -71,6 +91,8 @@ sub parsefsys () { -d _ or die "not a dir: $atf"; $rstr= ''; } elsif ($tf =~ m,^(/\S*)\s+(\w+)\s+(\w+)$,) { + # Line of form '/file/system dumptype prefix' + # (used for remote backups, I think) $atf= $1; $tm= $2; $prefix= $3; diff --git a/backup/bringup b/backup/bringup index 6bcd5d5..ffca871 100755 --- a/backup/bringup +++ b/backup/bringup @@ -1,5 +1,8 @@ #!/bin/sh +# Very simple: extract the default runlevel from /etc/inittab +# and change to it with telinit. runlevel=`sed -ne '/^id:/ s/.*:\([0-9]\):.*/\1/p' /etc/inittab` telinit $runlevel -chvt 11 +# This switches to virtual console 11, but I don't think I want that -- PMM +#chvt 11 diff --git a/backup/checkallused b/backup/checkallused index fd613f3..f50abb7 100755 --- a/backup/checkallused +++ b/backup/checkallused @@ -1,5 +1,9 @@ #!/usr/bin/perl +# Read all the configuration files and check that all filesystems +# are either backed up in both full and incremental dumps or +# listed as exceptions. + BEGIN { $etc= '/etc/backup'; require "$etc/settings.pl"; @@ -38,8 +42,6 @@ for $fsg (sort keys %fsgdone) { for $tf (@fsys) { parsefsys(); $pstr= $prefix ne '' ? "$prefix:$atf" : $atf; - &e("dumped twice ($backed{$pstr}, $fsg): $pstr") - if defined $backed{$pstr}; $backed{$pstr}= $fsg; print " $pstr"; } @@ -59,36 +61,28 @@ print "\n"; for $pfx ('', sort keys %prefix) { $rstr= length($pfx) ? $prefix{$pfx}.' ' : ''; - $dfstr= exists($prefixdf{$pfx}) ? $prefixdf{$pfx} : - 'df --no-sync -xiso9660 -xnfs -xproc'; - $cmd= "$rstr $dfstr"; - open X, "$cmd |" or die $!; - $_= ; m/^Filesystem/ or die "$cmd => $_ ?"; + open X, $rstr." df --no-sync -xnfs |" or die $!; + $_= ; m/^Filesystem/ or die "$_ ?"; $ppstr= length($pfx) ? $pfx : ''; $pstr= length($pfx) ? "$pfx:" : ''; print "mount points: $ppstr:"; while () { chomp; - next if m,^procfs\s,; m,^/dev/(\S+)\s.*\s(/\S*)\s*$, or die "$_ ?"; - ($dev,$mp) = ($1,$2); - $mounted{"$pstr$mp"}="$pstr$dev"; print " $1-$2"; - if (defined($backto= $backed{"$pstr$mp"})) { - if (m,^/dev/\S+\s+\d+\s+(\d+)\s,) { - $usedkb{$backto} += $1; - } else { - $usedkb{$backto} += 0; - $unkkb{$backto} .= " + $pstr$mp"; - } - } + $mounted{"$pstr$2"}="$pstr$1"; print " $1-$2"; } print "\n"; - $!=0; close(X); $? and die "$cmd $? $!"; } +$!=0; close(X); $? and die "$? $!"; -foreach $fsg (keys %usedkb) { - print "filesystem group $fsg: $usedkb{$fsg} 1K-blocks$unkkb{$fsg}\n"; -} +# We check that all mounted filesystems are dumped and all +# filesystems to be dumped are mounted. The expected-diffs +# config file allows us to make exceptions. +# eg: +# #expect disk2 to be mounted but not dumped +# !/disk2 +# # CD may or may not be mounted but should not be dumped in either case +# ?/cdrom open Z,"$etc/expected-diffs" or die $!; for (;;) { @@ -96,7 +90,12 @@ for (;;) { last if m/^end$/; next unless m/^\S/; next if m/^\#/; - if (s/^\!//) { + if (s/^\?//) { + print "non-permanent filesystem expected not to be dumped: $_\n"; + if (defined($mounted{$_})) { + delete $mounted{$_}; + } + } elsif (s/^\!//) { &e("expected not to be dumped, but not a mount point: $_") unless defined($mounted{$_}); print "filesystem expected not to be dumped: $_\n"; diff --git a/backup/driver b/backup/driver index 394b3fb..a9bc37e 100755 --- a/backup/driver +++ b/backup/driver @@ -1,4 +1,5 @@ #!/bin/sh +# This is the driver script that actually runs backups. cd /var/local/backup PATH=/usr/local/lib/backup:$PATH export PATH @@ -11,19 +12,30 @@ fi rm -f this-status p p2 echo 'FAILED to start dump script' >this-status +# Here we go : run 'full', which (name notwithstanding) handles +# both full and incremental backups, according to the ID of the +# tape in the drive. full 2>&1 | tee this-log status=`cat this-status 2>/dev/null` -cat <z z{(D{+I*R`eMvmcsA24*^Z)D;@jH21BOB=iRAGpD4|96$H;y(%yHvI1chwyupOsfLa z8i0(>h*}Sl%mr`;tD^x#EQM+HSjpTv1ocytB%}9`@e)ch=aN8_Bt!_1ye)KQEw$QO z0EEcfq($zNS(TEMmM|P0+j3qEH}e>e>&9&g7?C203SuWwl9N^n!)sgZXS|elUf5z0 zZ4|t=@1oKc1?Mwc+*UOGe=#EqF|_QT6q15+%TB47I#0>f(^GfsSS=8h3!C|sDD4?f zB4x8oUKSHc8ObDnA?WEKw&H&`JAZ?n{P$M-zmGx`=<`29q2YfYF#O-e|HmkM<^Y!I z_HmmF*c5E~fKB<66WEY+?ggY8#!=Lzg*Tl4UAN`G6W04b4$b+$7pzlWxd4lidkL|* z1=ttV{Exe}@n-((`(Lcz|B-{t{a-KG%Kyahe_v4ZKk3%S`}iN${Kw|~zZY!fe`@%@ zFR1ySc5CBZ{MWHS!~fo}mH))>e_v4ZpLA>EUHnI0bN)B?f4yKU|0BcyeSsiSQg$Oo zMRy^<9sI{`5H|dG5q6N?|FP>D{`Z1IE6MBI@A~q)xuafQx&tpEr38+C9$Q5v@?U=Y zbot?AxOSO6qwz}l*Rgd7d6l2T#UB@+K3sv!sq!dkDnKqc5GG4X>HvYv34FP@`m>HI z)WHNkFXZf@4kg@aot(@ex``+|KR<`lQ~2`vvvu_G^6!6!y4>*J32bk~*;;N)+1YTk zUTXZT4w!readQ2pdQMJs=dN^z6kPof`Bc!yrc)UGHG)eW36Xgu8;!YIS`h0T zqKb=XPJm`m2}QSh5FRtV`9e11MezXjb6V0nQl5a)NtRWWmochd)o?Y{=c&j@Gk%FIl;>RBNt=s|9vMg z{=W|x|8M;NkLmw!Gra-StY>KokG#^6Q`X#s6JY$N${G zH~zm5nD_tvMic-0PWWHn|LOA|@(?oo?*oSa`;8|4_dW67ZTN4#|LFyW|ND(aRI>X1 zr$Zb1YyQ{%{u?{)+Wk*`{trD9|L+A?pavZdC{u$DbIL09`h8$sf#Wr~{(7e8H=4^l zorRZKJ_wR_?!;(z=9A6oun51aU3FKFjqaLziiv2*_Y7xN#O c`R@nDsT&v=7#J8B80;7R14hXO#sE+N00a(); $tapeid =~ m/[^0-9a-zA-Z]/ and die "Bad TAPEID ($&).\n"; $tapeid =~ m/[0-9a-zA-Z]/ or die "Empty TAPEID.\n"; @@ -34,6 +43,7 @@ close T; setstatus "FAILED at tape identity check"; +# We don't let the user overwrite the tape used for the last backup. if (open L, "last-tape") { chomp($lasttape= ); close L; @@ -43,13 +53,13 @@ if (open L, "last-tape") { die "Tape $tapeid same as last time.\n" if $tapeid eq $lasttape; -if (defined($tapedesc= readlink "$etc/tape.$tapeid")) { - $tapedesc =~ s/^.*\.//; - $tapedesc .= "($tapeid)"; -} else { - $tapedesc = $tapeid; -} - +# Parse the appropriate tape.nn file. +# Format is: empty lines and lines starting '#' are ignored. Trailing +# whitespace is ignored. File must end with 'end' on a line by itself. +# Either there should be a line 'incremental' to indicate that this is +# a tape for incremental backups, or a pair of lines 'filesystems fsg' +# and 'next tapeid', indicating that this tape is part of a full +# backup, containing the filesystem group fsg. undef $fsys; open D, "$etc/tape.$tapeid" or die "Unknown tape $tapeid ($!).\n"; for (;;) { @@ -69,23 +79,27 @@ for (;;) { } close D or die $!; +# Incremental backups are handled by increm, not us. 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,$tapedesc; + exec "increm $tapeid"; die $!; } +# Read the filesystem group definition (file fsys.nnn) readfsys("$fsys"); openlog(); -$doing= "dump of $fsys to tape $tapedesc in drive $tape"; +$doing= "dump of $fsys to tape $tapeid in drive $tape"; print LOG "$doing:\n" or die $!; +setstatus "FAILED writing tape ID"; +# First write the tape ID to this tape. open T, ">TAPEID" or die $!; -print T "$tapeid\n$tapedesc\n" or die $!; +print T "$tapeid\n" or die $!; close T or die $!; system "tar -b$blocksize -vvcf TAPEID.tar TAPEID"; $? and die $?; @@ -105,6 +119,17 @@ sub closepipes () { close(DUMPOW); close(TEEOW); close(BUFOW); close(FINDOW); } +# work out a find option string that will exclude the required files +# Note that dump pays no attention to exclude options. +$exclopt = ''; +foreach $exc (@excldir) { + $exclopt .= "-regex $exc -prune -o "; +} +foreach $exc (@excl) { + $exclopt .= "-regex $exc -o "; +} + +# For each filesystem to be put on this tape: for $tf (@fsys) { printdate(); pipe(FINDOR,FINDOW) or die $!; @@ -112,14 +137,27 @@ for $tf (@fsys) { pipe(TEEOR,TEEOW) or die $!; pipe(BUFOR,BUFOW) or die $!; parsefsys(); + + # We can back up via dump or cpio if ($tm eq 'dump') { $dumpcmd= "dump 0bfu $softblocksizekb - $atf"; $dumpin= '&FINDOW',$rstr."find $atf -xdev -noleaf -print0"; $dumpcmd= "cpio -Hustar -o0C$softblocksizebytes"; $dumpin= '<&FINDOR'; + } elsif ($tm eq 'zafio') { + # compress-each-file-then-archive using afio + startprocess '&FINDOW',$rstr."find $atf -xdev -noleaf $exclopt -print"; + # don't use verbose flag as this generates 2MB report emails :-> + $dumpcmd = "afio -b $softblocksizebytes -Zo -"; + $dumpin = '<&FINDOR'; } + # This is a funky way of doing a pipeline which pays attention + # to the exit status of all the commands in the pipeline. + # It is roughly equivalent to: + # md5sum

>this-md5sums + # dump <$dumpin | tee p | writebuffer | dd >/dev/null startprocess '>this-md5sums','md5sum'; startprocess $dumpin,'>&DUMPOW',$rstr.$dumpcmd; startprocess '<&DUMPOR','>&TEEOW','tee p'; @@ -130,17 +168,21 @@ for $tf (@fsys) { endprocesses(); } +# The backup should now be complete; verify it + setstatus "FAILED during check"; +# Rewind the tape and skip the TAPEID record system "mt -f $tape rewind"; $? and die $?; system "mt -f $ntape fsf 1"; $? and die $?; +# Check the md5sums match for each filesystem on the tape open S,"this-md5sums" or die $!; for $tf (@fsys) { printdate(); chomp($orgsum= ); $orgsum =~ m/^[0-9a-fA-F]{32}$/i or die "orgsum \`$orgsum' ?"; - chomp($csum= `readbuffer <$ntape | md5sum`); + chomp($csum= `dd if=$ntape ibs=$blocksizebytes | readbuffer | 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 $!; @@ -150,15 +192,21 @@ system "mt -f $tape rewind"; $? and die $?; setstatus "FAILED during cleanup"; +# Write to some status files to indicate what the backup system +# ought to do when next invoked. +# reset incremental backup count to 1. open IAN,">increm-advance.new" or die $!; print IAN "1\n" or die $!; close IAN or die $!; +# Next full backup is whatever the next link in the tape description +# file says it ought to be. open TN,">next-full.new" or die $!; print TN "$next\n" or die $!; close TN or die $!; unlink 'last-tape','next-full'; +# We are the last tape to have been backed up rename 'TAPEID','last-tape' or die $!; rename 'this-md5sums',"md5sums.$fsys" or die $!; rename 'log',"log.$fsys" or die $!; @@ -167,5 +215,5 @@ rename 'increm-advance.new',"increm-advance" or die $!; print "$doing completed.\nNext dump tape is $next.\n" or die $!; -setstatus "Successful: $tapedesc $fsys, next $next"; +setstatus "Successful ($tapeid $fsys, next $next)"; exit 0; diff --git a/backup/increm b/backup/increm index 1d2aaa7..3120430 100755 --- a/backup/increm +++ b/backup/increm @@ -1,5 +1,10 @@ #!/usr/bin/perl +# Do an incremental backup. We are invoked by full if the tape +# description file says that it is for an incremental backup. +# We expect a single commandline argument which is the ID string +# of the tape to use. + BEGIN { $etc= '/etc/backup'; require "$etc/settings.pl"; @@ -8,30 +13,40 @@ BEGIN { $|=1; -@ARGV==2 or die; -($tapeid,$tapedesc)= @ARGV; +@ARGV==1 or die; +$tapeid= $ARGV[0]; -print "Running incremental onto $tapedesc ...\n" or die $!; +print "Running incremental (tape $tapeid) ...\n" or die $!; +# Just check that we weren't passed a bogus ID (the tape description +# file for incrementals is just 'incremental\nend\n') open T,"$etc/tape.$tapeid" or die "Tape $tapeid not found: $!\n"; close T; +# This is only used for the 'next FULL backup is X' message at the end. open NF,"next-full" or die $!; chomp($next= ); close NF or die $!; setstatus "FAILED during incremental"; +# Read the number of the incremental involved +# (ie, (how many files are already on the tape) - 1) open A,"increm-advance" or die $!; chomp($advance= ); close A or die $!; +# better be a decimal number $advance =~ m/^\d+$/ or die "$advance ?"; +# Rewind the tape and if we are the first incremental on the tape then +# write the TAPEID record, otherwise skip forward to the correct point. +# (full will already have checked that this is the right tape before +# it invoked us, so no need to read the existing TAPEID record first.) system "mt -f $ntape rewind"; $? and die $?; if ($advance == 1) { open TI,">TAPEID" or die $!; - print TI "$tapeid\n$tapedesc\n" or die $!; + print TI "$tapeid" or die $!; close TI or die $!; system "tar -b$blocksize -vvcf TAPEID.tar TAPEID"; $? and die $?; @@ -40,6 +55,7 @@ if ($advance == 1) { system "mt -f $ntape fsf $advance"; $? and die $?; } +# Get a list of all filesystems readfsys('all'); openlog(); @@ -51,6 +67,7 @@ sub closepipes () { setstatus "PROBLEMS during incremental dump"; for $tf (@fsys) { + pipe(DUMPOR,DUMPOW) or die $!; pipe(BUFOR,BUFOW) or die $!; parsefsys(); @@ -59,15 +76,21 @@ for $tf (@fsys) { print LOG "Not dumping $atf ($prefix) - not \`dump'.\n" or die $!; next; } + # Same trick as full uses to do a pipeline whilst keeping track + # of all exit statuses: + # dump /dev/null startprocess '&DUMPOW',$rstr."dump 1bfu $softblocksizekb - $atf"; startprocess '<&DUMPOR','>&BUFOW','writebuffer'; startprocess '<&BUFOR','>/dev/null' ,"dd ibs=$softblocksizebytes obs=$blocksizebytes of=$ntape"; closepipes(); endprocesses(); + # advance is a file counter, so it needs to be updated for each + # dump we do to tape. $advance++; } +# Rewind the tape, and increment the counter of incremental backups. system "mt -f $tape rewind"; $? and die $?; open IAN,">increm-advance.new" or die $!; print IAN "$advance\n" or die $!; @@ -77,5 +100,5 @@ rename 'increm-advance.new','increm-advance' or die $!; print LOG "Next FULL dump tape is $next\n" or die $!; print "Next FULL dump tape is $next\n" or die $!; -setstatus "INCREMENTAL successful: $tapedesc, next full is $next"; +setstatus "INCREMENTAL successful (next full is $next)"; exit 0; diff --git a/backup/increm-advance b/backup/increm-advance index 4099407..d00491f 100644 --- a/backup/increm-advance +++ b/backup/increm-advance @@ -1 +1 @@ -23 +1 diff --git a/backup/iwjbackup.txt b/backup/iwjbackup.txt new file mode 100644 index 0000000..9a2775e --- /dev/null +++ b/backup/iwjbackup.txt @@ -0,0 +1,141 @@ +This is a quick summary of IWJ's backup scripts and my config files: +it's a bit patchy and might have the odd ommission. The canonical +source is the sources, as always :-> + +The three tarfiles in this directory should go in the following +places (the paths can probably be configured/hacked, but this is +where they are on my system and on chiark): + +etc.tgz : /etc/backup/ +lib.tgz : /usr/local/lib/backup/ +var.tgz : /var/local/backup/ + +NOTE: these versions are not those used on chiark; they +are somewhat modified by me (couple of extra features and +lots of comments -- all errors in those are mine.) + +NB: you'll probably need to delete some of the files from +var.tgz (in fact, I think you probably don't want any of +them except maybe last-tape (which you want to change anyway). +You'll also need to recompile readbuffer and writebuffer unless +you're using SPARClinux :-> + +Contents of /etc/backup/: +warnings.* : files defining how many warnings you get as the +system is brought down to do backups. The defaults are fine. +settings.pl : generic config file: in particular, the name of +the tape device is set here. +tape.* : each tape you're going to use in the backup cycle +has a name and a config file. Here the tapes are named 'a'-'e', +although longer names should be OK. You need at least two +tapes defined as the system won't write a backup on the same +tape it wrote the last one to. + +Syntax of the tape.* files: +filesystems X +next N +end + +where N is the next tape in the sequence (which should +be circular; I have a->b->c->d->e->a...) and X is a +filesystem-name (list of filesystems might work?). + +Each defined filesystem has a name and a config file +fsys.. These files define what is backed up and how. +The filesystem 'all' must exist; it's used for incremental +backups (and it must exist even if you don't do incrementals). +I don't have any other filesystems defined as everything fits +on one tape. + +Syntax of these files: +Empty lines and lines starting '#' are comments and ignored. +Lines starting 'excludedir' given regexps of things to exclude +(temp dirs, Netscape's cache, etc). +Lines starting 'prefix' give a command prefix necessary to +run things on a remote machine: +prefix +Other lines should be of the form + +for local backups, or + +for remote backups. +The file must end with the word 'end' on a line of its own. + +Valid values for are 'cpio' (uses cpio to produce +tar-format backups), 'dump' (uses dump to dump entire filesystems; + should be a mount-point for this), and [if you +use my version of the scripts] 'zafio' (uses afio to compress +each file as it is backed up). Only 'dump' type backups permit +incremental backups. + +Finally, expected-diffs is a config file to indicate which +filesystems should *not* be backed up. The scripts do a config +check which involves checking that: + * all filesystems to be backed up are present + * all filesystems that are present are backed up +expected-diffs allows you to make exceptions to this; backing +up your CDROM drive is a bit pointless, frex. +The format here is: + + +where is ?, ! or nothing, and + is : for a remote fs or + for a local one +(examples: "mnementh:/cdrom", "/cdrom"). +If is nothing, the scripts will complain if the fs +is mounted. If it is !, they will complain if it is not mounted. +If ? they won't complain either way (useful for devices that are +not always mounted, like /cdrom). '?' is an enhancement only +present in my version of the scripts. + +Useful scripts: (all in /usr/local/lib/backup) +checkallused: this only does a check of the configuration files. +It should give a cryptic summary of the configuration and print +'configuration ok'. If not, fix your config files :-> + +loaded: this tells the scripts that a currently unlabelled tape +should be treated as tape X: eg: +loaded b +will cause it to treat it as tape 'b'. [NB: this won't override +the TAPEID label written on the tape; it's just for use with +previously unused tapes.] + +driver : this is the script to actually run to do a backup. +If run from the command line, give it the argument 'test' +[otherwise it will attempt to run bringup to change runlevel, +on the assumption that it was run from inittab (see below)]. +You'll need to edit this script to send the status report email +to somewhere right for your system. + +takedown : Run this if you want to run a reduced level of system +services during backups. Usage: +takedown +where can be 'now', 'soon' or nothing depending on number +of warning messages desired. [configured via warnings.* files.] + +To use this you'll need to configure init: + * set up runlevel 5 to provide the level of services you want + (by tweaking the symlinks in /etc/rc5.d or equivalent) + * Add the following to /etc/inittab (tweak paths and VC number + if desired): + +# Runlevel 5 is set up to run a reduced level of services during +# backups. (currently this means: no squid, no webserver, no newsserver) +# We also run the backup script automatically on entering runlevel 5: +# (I/O goes to VC 7, which is also the X server, but never mind -- we +# very seldom run X anyway :->) +dm:5:once:/usr/local/lib/backup/driver /dev/tty7 2>&1 + + * takedown can be run from the command line or via cron. + +whatsthis: a simple script I hacked together to display the +TAPEID of the current tape and optionally list its contents. +Usage: +whatsthis [--list [n]] + +WARNING: it's currently hardwired to assume 'cpio' type backups +when listing; it could be trivially hardwired to assume 'zafio' +or with slightly more effort it could be done properly :-> + +That's all I can think of for now -- comments and +questions to Peter Maydell diff --git a/backup/last-tape b/backup/last-tape index 8c1384d..6178079 100644 --- a/backup/last-tape +++ b/backup/last-tape @@ -1 +1 @@ -v2 +b diff --git a/backup/lib.tgz b/backup/lib.tgz new file mode 100644 index 0000000000000000000000000000000000000000..208bae88771c413b0e418cf3990130334d707080 GIT binary patch literal 21804 zcma%BQ;aSQj2-)qZQHhO&mG&gZQHhO+qOM-Z2Q}PANOsOraf(%_N{4h4nZ^&(7l!; z2N38rp0)dyIJ=U9I1@uikuuk*FiCbYPr=e4)STl4tYOMlz$ z#zx*UV9TwyYY7nE0bgVQwm0AAOauz(WVydSFWQL@xevWd3$D<|*B|gc9J=j5Xysn% zv$V5etKPmpIzc7q``FruHJZnYBDb+$BRU`S5HE@$;lXDWl3kGIyfqexkm)6)jIs<*`iKag-ja7<(zO=_{magX4m zCe|1Rl2mBX6Z_eA_cI>XJ77O#Jx`!N$m4$=yAag{!4DhK*4Jp*gQUFWt9038Gc>pQ zb^AH0{ygM=OQQU5d(qzt7dAxa9lo})8O_6uleL{5+w8`Z^0N*1Sk_aGTzLatu0Uw` zCOYo|&bPVGB*D?c!%LML#zfZaNBi4m=mrRrK$?QMOElXLmdQ#s2BOEyIZE{YGtYip zDCO|NoH2L^q4m?PGYYWkM~h8Byl6diHa6eXEp^m3@n~k-thCP@124JlT$t=mBzkQS zz#8H~SkO%g{V)($2x?44n;^vfywyOW#2%y4Gi$6uS%eR>e2?vAyicUJEz;nNL5A98 zbRH?ABpOi!1*zGgFcTesGk{oWI6;W(A!#2zS^^hv74-Z|B57Hc5J)i?MnNxb%0DD> zWn6yf<+e}Z#+8%~dLqe@pyv}y<7!}_4;QVCNZM-L7Kq4KcG~k&FVT2Rc^d#Au!;YS&w52X)|p|PFjsPVhcja zXB(6W3nC(1aTb|CpTI*w=%^nDN3Y_hy8*5f4aL_6pshFHhip|OPAv@@q`JFpe+^m6 zP~CXFGiQCP(z);u*~pgU3o0ObJ%X?ogRTr_5XCLnsh~tv!4m%j))S6O1YW(=S@O5V zCL$p%0}T%)%9{MF9`bmEYKvD0OB~-WI4{_64@tz>N~wrgi5hh+^qyitf(=K80mFmn zWS~`o4;d?og(keixkjIo;DVdL1YrvyE)5W0fLzM+;%Vm%J4eMu3y*BW2Psnil0R;t znNTUJ{`I!_{F=LHx8Khlx;=Ei_j`Nyc)Ne*L1hM`5hO3xRFv^7MvM)CjSw{XV!G6c zH|yUN*!w~+zwSHlxy|vDNFZ>LM|e|^KRCEyx*l4*eXumY+r8Q~=Jay+d44q^Q2P~a zh%Ex=7n#Oy4qlNSp_F76dgnPQ5Iqm0*M>hSA?c9`nH5)pt50{1BrlJ_hM>F;A%`cY z5*l6xsSodpc~z)n+YIzPUBp)T)m(VUZ3=zR2i@CH9=avV>gDrZiREpNZ?|_V)T+1j zF&^wr){PY$Wz6&FW5MkPaa;J+FtR6|3NC-DO-Y?$f5R2PpNoyrWyr8aRyvtyE1Vw; zTrsmahGW>n!@VXDv9<11ueE>Fx7`2Qox2b^d$FcOU1@lUH8O3sz%&6*5Wx?FzBS8J* zUo!hJZv*%wZ86}3(Z=>&kzbFZy@{fgDx*7BvY+RZ_`A{Yrju!DX!ws@3-7GGx?;eP z2WGp&o5s<4r7C?`8#k*dfHIq(Fl>VZtAJndurUuPpZ{SBMkydT{cQh^pr6jCvT(6R zD%}5r3;|HpR_wsA1XtoxXeC!ZQ7Ed{0T!`Bl;`5{W!k&E^N`!+MLDXzR^h(F^vKwaWPGOa`_JA|y<-m!px z@#?}RTHwqa-kr*B_CVdXz`lTr>Q5Dh8Hsjzk#oUWE#2h+`)4l2#bF@%pp3xm{tFLr zmO4)_5_@w)aoq3h{y9Tf5{~n`(c*$Bl9|e<$!i4EZfVtiHy`Zc!S=vOLY!od0df*KFmZ$$^o_lE1=AQ@Tmfcr+9(*sY10tm8MbWP+k8b zjgl5!8%v8n&LUMCn3PGJBZ3sw4xO?KxwKABtv8L<8`LObFK)A4B^RWUW2V9WZPo59 z;n^pySTkDEV>WY$j2Vha9C``GV$p+sm=|^#S+>d~5}1fGJ3;GwZvUCTNL1~ST!y~f zVwI{{!yK(<_OLkv;*O~FeP)XDWgnL?ZrP=zU5bN{Wp{412q4{EuvX%9^1m2krBv&l zg(zipr-1IRu(s9wbWF#P0TH3EqZE+pzL|erK6312MCsU+G7nDi8I9BmA5G8sa|+kPo1dM)YtD5T$v*`=E^PzrUKEe z$e9u0du3my^|^e2@DZB z3*W7;utgjYQu-W zwT|PR^UU~8cE-=lA7>PJipW}?0 zh`D6SxZ2DC1DQ(&#$v+dZ&<`O#J&`5!@XzqORv&%U)E~8Pi9RdKh}|NHue&Uu9kln z6S$eq2bC}T7}ySZg%8C`JsE(%Fr_JsO6(3RHz4mYg1;M%1n(?QsYp}x-^5796*~0- znHjHzQk%-S26YMY@OBRBWL7Y`sQYXzLj@5B0Z z2{M<&+ps!{f@Hr&!2)Rk73SQJDIQxMrBaREdXK2&NG8fyD&-x zpPgyK^!R(-aJ>}0+u zMmv_%b46&(y)N{)mVu`hd>MPm>2s`SWBk5uQNtmhhAT0RAu=EInHfG%1FR4=h72j6 zY588osg%-qRQQ&#@IHy4^-F$oqLHA<+c3iOv?*5^PZWTQ)O+8tC3w#ROli+3g;}#U zG9Jzndin9J22wXPU@^>%gRa2nkzcVYY2S~i$-8PZ<-P5Qc1B0f@mAdmcYVYi!9hnC z6K;McxC}#8myC-TX`3x(; z6ylFTOrjwq>~>2T7qgISsiMatOe%EX_2%qpW5h4dqxqwzr&CF+M*4X~J=4CTR2WII z8B@UbgXK$&2F#Gkq(H3z%u7+ls71+)xP{b(W90}w<`a{NL32E$iSLSLHY=_0SzIG$ zILa&dWgWFq$++k_qbh=+{7HgQ35%S_kP#pKPxV!j7p68%x&Dd$8kbjY9kUoBBnM{b zzsHUGV9s{j>Ig1KX#+%)EBVT-G>CfO7pm1k^#fXMr-XcoEW|)kn5`-&x5U3BQ zUB^cejyqW&ZH`B zi{m>c-la2k3<+KHTGoYHG=;+S>w7BBPUmM9woFUg%u@{rwZCV>!AG2Aog%pA?fXW0 z?&^@|Pw<-yfAmJSG!1>w(iYmx#ow>)%8oMhEIj$0;8zC5CO>LIp7m(xZdsb>XB2h8 zC4o|Jw5_fpLapNAGF8R7;*(8Bgpa=@Us&<15^V9?3Hyf*mzMZAlXswh6iQibrLO%a zL!VmK5sXSeADbtQEB0edVmw{>>no+9FV7S|Zz_a>uqja=Gc~FIs7XAFr+invBM&FT zj~il)c25}EHGD}Gfz(1>KABx2x8^S6Wt9)q(UlHVL`9!z`i&Z#PNwS*r>(=iHE!Z31Fo{Nwzol2dp zj(>lAOwav(c;cf82pr!dVuMP(Rv!Uue&43~{$aZR^N+0!eFA7_S3dy|oN6EY)qdNj z0O}w6)Bx>&{?*@i_DO(Rr)D*~wyD|Q$IeX=9oK1RUT^_{=X+7)a+Kyg>= zpZ|Yn(^Kcd%TEk`q3%~jbe)jvcUF006kDE0C&OWk34ZVMO2=a_(>Xmm9HkHJk zF!d<}2T&M6kO)3*&B}bf2bC9;6*9kAUc|g|)bnQYuG^U?z><|8+>-F%)pJIoO(j@hte&&Dv3Y`@xOk^q&Ent@LiZ(ri)_=7 zD6xjJ>9C5U&r}^z(T{Kqremb_X+~4=q^Le_rp)n zVFFp}p*tVv1J5uR%UjV6sMDNhSqNBnbj&S{npK*$!r@uwdX(!?$B zPtP_}uqVbTTwy)JQj~Ax>VyNT#208wM+rRHS2G6dqk&<;)0m1IkVgPYztc>Hr1*P(VZq+@{!%| zFq+nV7hKITzfN3HpHHb2RCv~#`QqyJUE6PLCjp4@Pn*w2sx*VD_A+A$ORTI?oBl#q zl(gtL_3Fj~ni!U48k=1$0nUo=5vva8Ur>neK;4Y+Ezuj&mQ8&#~$KimJ-0=0U!`q@aV-?PN z)TsLPE99)v;YZtk1uYk?Y4*RM@YJ>N9d}p6@+OX)nWtt}wWs|NxR=2MjkU?w^D~=q z)%vEOHpz@+_RH%Nlw_BT&Wo(bI^!7qAohM-qGd7rl~mJuB#R)RiCFJL4c$?8s7YC8 zH&IP2m_b{O29~SPHnf>VIdM-kpfbC7)5nA+ezm=tKaZk7(JZk&*O+XYCg=3*?Y^I6 zZ@&OnSEql1^#EXRnBA9gv-*-B4#=_=_)v)PMq{`*!?5F zO!_>G&~`I+cRMqiLOHYKxdHg?+j%`)`)S@M-!Q`t;fkt{vH!fzG7kVQdy#ioy0OT! zF8n(GbZ)vx^y;l~8yneFAUNjq?FjHg zX(Z~s(4{Ubo_w|@$t@d2O)=>G$} zB?0P}0BWE8(g2MMfc~u$$(^$3TlYBLhkvg$;8f#vA5f*n(Wc%Hcp%hx{nmdpPW3s7 z|0nFfDKjnrk5`MMx6CA%nFBR8vg26jWGR6bhwI91hkKLfw|%-4WHlzM?an55NzyFc zCHEE<$o>sEp=$^S8NZDP>+&qn1_hrFuQCoWz0)$-?wWfdqtiyVt#8U%(MzmdPcf2? zoRDnFZD}i&Y%BSjTjSA&YhH;GjVzVfDoXA1p2*4aB$y6vQQm21fVydgsh7Yelx&Fk zI-uTt(`GWvj;YCHGofW-5rDo6il5cn;Ij25FxMN7N;YnLO-flW_;B2N=KJgX3-|_f z0=N!O2UF0*mp`6WDO2G?omlKx|7qC^bvEDHxKl!3493E}AjHGLFOo6ML=ETd- znK?y1wSjB7zYpk(6XMyj46O1K>ilQygf8ZOH%9+PicLzjnlmRKsWN8NXYRwSM_KLT z&LFddC5l@veG^x%gkOWwSy)Nb#3JQ+LC4RNJ#EAujX`K5)*Kn`na|OAVUsO2w%Gj* z1G(hUkwGg=m||?rJwraV11$|-lV?$q8#jN@OuYmi84me?;#r$D=DI!6eg)?p_rjr{ zvegkmU4R_9+!W3uI-B+UBL8PPCEMHnZ@0hN~b zP*|IZu?9P^MB?eG-jBvNV4`uvSL)^W$_)g*MWKPjX9iw(DXe8 z_vCgUwON;m9Vj1pYZAQ?@p1)Ji#&X~xg!^h=*1|0O?J=ci^o(m$I4j_s}MjU2gMkX z^BCrQ%W~vWc5nkvijJ??cdK6wP1*0PYzxqZ*}~sYk~V4ZHIfUC)hjW5=Acp2PmK+X z{M$h~ALG4csiN}}~Wt{sN8`v1PBO_eNw zu&M(v8fn4C-&k*I;wh5XEY!CdPP-2tB!h9ntwhP_QQtXbRij%Dj$(x4fYY66%!!^* z&67HxNeRLN5)E%6Bq_XhZj4(fg#910FWr4U3+K)$ju$09ixGG|!tKqs1K~1J5)=2_wm0V|+8+0i^NIDqZmH{DFz*Z&#wL?lvFEG1 zNx1Vv$kSY=U=w^c?FgQI}CLoy(efrKn6A@(VrwQQ&GAJKlRy3-$`C?L##MAX@KpA>AE3P)Ew`UEk)#A5TFa1`~>z4E) zLe((qE;^jclQ*wzfQaP7?F2U6=+U_>DU#WydM*R9l@UNtmoXH2S2z&Js=ZWH}s#QJH;!RO} zs;;}ZkMX)n(#RT2Vl7PcLtIbWNPVFTy}kp@#>9O9?T>3#L?|!*UiHrQoKzHZS@-%< zWKQ0D%&B*DVyqzOm-}6(yM6a21}i(K z#m`ow|HLO7D=)X80F5yLWwdVr?Q7uU2IN-i@4tZ;qd-2QLT;zBoW!n-)`o52W4GvY zsdbGmgvdAimX2c0;opo)b1BH=Nh5ligzIEe{Rr~JnoZ#qY4`hSG<}f+l*#uK!*siD z+cEHladugQrc{YdKzc~b+-Xz>eX(Zx=rnbu4j*(ZjZ?(*LoJpNyZ%g3W)qe_oUN{n ze?hOw5ze{8O)I?ZFSz_a%7_KQa5uA6LRk#FrG7O~#!45-bOtEJPDdtEE5a>H^m)cB z!aoa(E;`(aJKA$)&GbsyXxG^i#R0`Y_hD|oy|ShU3IiH?Is=WjmiSZ3YLw&Y}=$K*|<~qWL-zQd`ikAV#l46 z!y`aZp4c|1i_y<|s++}bmEElhRbuP-B^;ws#zAIJD=t1!Ctl=tRQz~IsqWqGcZ||H z{1_B>cCoLY+1V{rOaa5Hely>8spKxj2nUI3K(-3)(!tbn*v^7FxdHgmPY?w=ttDtn9XtUTni zcB_OPA@v>G=DT}(*^BQ)9y&H0Xy~q=w0)TZ(+@81;CW{>3nFTi25DY>w6HsfC3G6- zLQf=Ci5DY^(HD)>jtgkapiGGmxS%8dYSX}jo@_=6J%@mstXd^;^9m^A6qXCe;LScq zcB>H;(rz{OScru-jDlzW&hD6Xv)Qs-+s!7PTHA)9z}G z-^t<2nA5UhOoDxoTxj+cV~6P^)i9{3X>!H&bZB?OSl#6>wp`FIQudT|p|1QrUkHx3yY#Dh ziEC*OS#f|IXA>XUW~sAOaGE-ICrZVxr-Z+tq!eQK+8zFKdyBu> z8BI-W0SElHqFdQFV6*WBbHzPg=RyheHeg(Xj?RaJ70$dG61b~$9)5!gby zO-)$zII`en$<#UM)Y3u}+I7%aMT6p_)`y8#j{JL7$W{KNlYgSLdgq*|*`)Aw3>3}B zG>80@aPwrB_ZNmUT;l@Teo<7c+@&aGk+>9Jq|g&j$M=F&%eD5f|8*7VfjPnk#g(Y` z+*jaO)e1FAZ4hPBWXyk^u7tlk7T&k9eNwi;DGym4HM!Kb73yTIi6jOf6GCN;AM)y_ z@uxQd9?Bhswyr^z(=0r{!lpN@^Qygckx52>EJT}93RLThD#CxwI$#im$XodJP zrs2BHl}AAEmqp+j18L-C_s7}w%YHo#{B{49F5CKbAIEX^x}WXKe)d{}*n(i-%c3V2n0+#=DR=xYYrSqqX>bS|@@7NCzU`!wqFIK~x!d$sR9@5{%hE8d9zcx_bse6pO2@X2z&SCn&Z z%OR3on`cvBhGOj~AjXb5O?Sccr~~YVScua4WKtE?jj~B4J8z_0gr2Q zH8lvA1`5fN=vG{(^B*;4Rz@u54zmQ?xwWlmSox$;xe2!xVT#V)*bH|=fYnHv_(hUO z0gcwENSjJ69*%yTL=6=EVDNRGa98i`a!zfv8~SP6Y^CJtTE@weID_TX?439^{;c$> zy_hEN)?pjos0;$0-_XW{x!l}ZV&PtFm(K1CNRrj5E{#`g_UkwLK|3+pc0rk(e1?Oe z6hp`abBT0hbo8$N$GpMYGiTp5ts zFGJmp#t%P%#O*w(_v>D_v5CW5pH&;Panj!kvJP_7XSR#1*rb%}vpx{b&BcmOL(^n9 zOXk_i8&NEV^yaTaqGrk<8q?kXIrvUey!br(%|XQCt|YzsS{Ud-MZ17x#ai_ zQgfMbb%I6K6mnWRGv+%QLb2}i%B4Ep`oDEZ^y_F*^nKQry5DLm5d=P?1+1l+bE5xp z%mQQEw*PsEi)}B*SoIWOm`lkd->+I{LA9?lZ6zAlv=qs)vkcs{d!HUL^RFoN87pLh zn=Ab2o6bvIXFZDuq)m;Ye(qZ6rD;uQ?8K;QPE2<^ft7_$zeO=;EdJgaZ?J6LpU?FM zcSA~ye@g81w7$-Jbde-W+AabPJ3@x`Gyw70x0id$oxl6a+JOCxtDh}^?~lgR-9M)n zaR!$CWwrx0+9xaP%r{HACnDYIl{D&BF`@q~bVU!PL!bfV%{(fTWL>UfA$q6NZm*{U za5r~*3;wI$ZGGmymq3GBgdw>AK`3oT8+*;qGqY{l2s0VlY~!qNE_L6Pir8qb`XLI{pq++l)XfW zm`T=v=}5Lw9qgYDm%kj1z2zwD01lb7cFA=l8G%Gl?Z z-88sKmYQa!kJ09pJKF80NbyX^LrXMc_pZZ=M4 zR49mV9HDP6`2lEJp6I*TIF#JuuZ;LyH2G}j=%?oQ)}TAE=VQ+F=Vsh|ZlAQnC-%I_ zamTgG^0?)+_|Qv$9Dl?eUuFLh*vl~(Joj;+BTU7-(pXq}PJtipS&pB&1^zo2c20mF zZi+7dcMJk>ro1STA$t7y5phIjHqvD)5!vIX*;zgpxo2mQ9fnX$$ux zk)jr7i+8<}Oi6S2#XUl>q7b(9Ob_nk5^|PM%d@=1Lp&Y?*KzJvvS2iS;2(m8zS8(+ z?p(X2UoNs<*&CI9b;efP-Px!`1fk%?vFShJ{-}ml&0YFzJl9~-l6QUQan4lnJiR|qNcn6H zi9Xjo_cZzmV0|X#Xv@2PQX{Z?LND^kk#FggYo47Gw)FAwahs%~Fkd0-E5HA(<2=n3 z@-d;4j3ek_)lzQuFs-)!sk}}Z~D(J&oi5U$yWl8bi}nR<_G>wj2=JlNK>>h z;-zmj-!hjjUqdiR-0z-1D6Grum?I&)e0^&ASm$c=$9;9UCvJT>C2aS?TgobBw(#kR zd+QW2slN&SQk{8>;$(2zoq3O@a?-*1|9NUq&|}_!lSbX zo%#$(dy`6eWApJ3oRWECfaHj&Ni{E*=TOiS?|QM$F-!Sanw_xU{OIZnJ6kMws*j%* z|4`;Bx>nssw?e2QX^_Euu_$YBjfnTES?mf}`x;Y9H>-kOvg}gSC~{IzOZg(n$xHD~ zU0pM#{Ca!HJ!tDwOnPj6WkZ}*>NxmMqP7Us{xsJ>DU?7Kc%JTO4;f%EV_ck0H+I!s>o!{nAzxf^({nwcQQWzb-^}Z!k!2S?}?z<`! zFgOG_IyT4+?WW~5GOV5%)Nj4V2+Y^`{+Bdi7@|*|XhZUjAd}aD{H=0;KAIkAul9|1 z5F6zWv{U-tA0QUwoJI$^SAr>$ZK^Uve~&)8h&(A7)DG+~{6K%8KwZ|iQRV^DA>jz$ zq48im;7;S$HA0*7fD!P8rsC^PS@wCW`u#Nk8r2WYTk&om5RTdp>=S=<2YjdeO)xMV zbrvWAzTOH9C_17W@J2&Ol^jFq!SIlMAUgO$Malh6Izk!H991>b#avU$jE;(Y#aH{L zJ4lY&r^d>hs`SR`Aociw37|mpM}4OnRXx>Lk~Q@ce}F%jrz&Ii*Lxtnucz_rIB9)) zOdcSK5~$8Z{^cX6_h=D4*1kUr5U6`s2ym_JJZepn5TN;8i`OP-xMzn2G=*0BrsQ4q zD?Off{?^Oj^Q{B$9IB5vWbkd*QTS+V*8vm`q7I<{yt9u|$&y~cMSPfAw(gzD;>mH? z(|ED1&uKkbmjzAtYCQ^07Da~b4n(3NPt{O1?h)?|M=cF}MJft`a+GwaJzEw9k9D() z4p|3|qw+!hgde~UFi`v9zPFy2AZ-qFEOUrpM9jAzmVVE zQI^;L)z1R;Rd#^CF{0Y70-*);A1#U(i^9j&0|B~BsX`wTB(V}V%i`GaTjhnOWc3On zst`BJ3lImeQ9M6BA`-qmmr@5bQD@S7In9?cei^F@UmX`${C!kM$F2z4?{{>vPn}ha zYd;D!sres^pJ=|y7(>M{Z#f2EmDzX#e;?;!nT9)Jy07*4Qk9;c5Fr@lBe-?Y(!CBWo% z34qvt_~C7)xS(yOBDulyRp1_2BA6O}jcr%T2gmpZvKN$;T0B`C>Wyg0)(~EQ1iTg2 zk0(;qUSx+%yg;*|4LN8D)y$q2cds5grvBAGdSqH{-_(uR^3*xayG&FawN3Mx?X*== zE0l|%2d1U_0zZt@g(%{`CoD)yN^m?2f5yMv|XofCc{E? z^^~(L*Z<3%=l|E)tL-90xwdxz4*1qak@_Vz@gKh!2KioL-3|Xj7`LXMIphZyZc$kO zz7G06{=uB?{pR`pokpJZout_R_bet4`1@k+OH*Y33Juv?3p4zl1@$QIm=YAU3H06$;k*o&SdWoyUA}h{e!2W0D zqg_SaVPA}O(JEMfT9pN#u^A-y9vJhXFx?SE5!KAK&4?!Xhjdo$&VtvUyR{)L3suR4 zO3Q9pZ8nu%mpR^riENB^R@fUR{vIi>V6Z7QGt0AAl~&`yJ}2u`kBBTPRJacaHAVPz z*(oNpEPXP>Q9Q3kNxc^ci=ufHkw#1+2l%gP&)?iRA3-MXbfnRg=m+tba`3IYWI?S$ z^t1=-&`MLM%pSemJcRiJ{(6!G#AxKjH8E;s(owO33+W5yCFX*}DbafqCOptG{c8LrfVBLV&Rfm{O8KB57;vG;=th-j+q|pR%DJ`Tz zW(DF3VJXjCq({;qIB9C^pfBpMzn#MmoPvV$tFMfn*8)hE)fayqIA!e0pTPHuV9uf) zYXr8v1%aX`!R(*j>yq|K?#LX4fJF>>z=AfPbrz0&iEWgxNlUzSgT3B*C=?&M^l+Hh zm#WS|#Xzg@P!X|-&Xj8O`r67tLCpChiiV<>H;sW~9O}}6$c+)spcB%7Lin2)t%x|e zh=uQ5utUrA4nR&?t$;}voVX|NH~LYLWz$ItIo6O%0>H>xnV^%Od%!3lGDDIt zWRD0BLLgTVfWfOGNbOHT5t+gp9f|Ez2|My>N%CknNgA=TIhvj&%BnF6v5P1SG7~e) zA)pp=1Q#KSoe61Ig@+^Nu*mGIfN~Yi9F4*67md(>bXY|nJv^WtN+}P(lY(Ekd@c|Y z^=M%HFj9o7q2kg*7F-9Nu;YfIn7{|0uX#bf0(!hO?|%%K-sF1W`amLZErH{h`JTcS zk9@eJcHO-o_y=*Thk8NynDe*K5tDex=0;*7Gk1F0Cey0fv_aUC=Vq@Ye}S_c&^``B z=U0ks2s{c%lcW<7FVUC+$IV6re|=`#b-yY$-#+E4ZBLnTx!b;Ofe^CKuMLLSg9vLD7PC7DJy~rX-9D$-l)Npf? z0!TxPIb%kZsNzJ3#iGQO-xGquk=xHx6FgEYhFcSl+EB|&J7`A_Qz=GYQYpk9|BJW( z#j62<>@WitBXWr(mmSIR2xxYb3XXGzmz|kt`t&|c@qJo#bNt(W7U91%$U(kpQM-1h zv)^2TEA-}=6G!UMKf}2F5{71YSd1Dx+4bTF5cu?>;F?jbeCHGh*KQ~Q$~QlV{iaNc zor3d(fedA&v?B%TRngX^Uajg~NEHvvdZXV(2ajSFdIi` z$MWDs2o`su0?drJG3SGIk_IxL{-z&rdE-AKB3zExcpRWu$j<~5d=+u}B%w}`5Eh#S zUvP$o4{}19r!Xj1nj9luXHBM8idJYq-HOv2Tc~2r?PfC!ScD0c1~eN5i^yhnFqj!% zS2MDnvVg~W#H$0xoSIiZb!twc!h!nEcq9KYlqHX7)hPpVqtc-2X!u<5fD0p{AWdUR zWCIqFFrPt{CPh0_4EZ!XjP7o>!}esVp&aNaN?}nX+{7A4PKD-#;i|Xl3R8OO)!Vh+ z&Ta1@xgrWt1v{Lp*3PwqL`7@Zz4)UOQ3>T&M zn*UsIz-^~b*FF0WV$Q?4m!1DYWi}ZEK8MZt79`d*oQpiSD^Ob#J6_Bge z&uzgOlr8Y`4I7WJHjq$lnd=B5c$mX}E!sycI0t ztJ#L5XWZ`PUt7pkH_6$)o4kP^!)B%cX)7jJ1EP&tt{EWs_Ibnp?F)EZGYs811Tzap z+DQfrW7Z4D01p)syto=Y1m#RLx!4s>EBw~Mg);Rdp?Z5)Ejbk$Sd(`DpxyfInr?P( z#ZU^)xK*p5YEJm7!enfD6lw13Am6D%iDfvAHqb`rh={QHqe+%&ljH< z(*mU686oW1HftpqOK_;G5C|x^=@&1aO66Ws#TZbLM6+=NyA_EuHPER7|G|MstA)@i z5{ktTGd;*(hxtY0lg3s2`?2AxVY^;F3z(clRR$u-XWw^ouADMT#Xs4&4Eo5J<#w%H zYFuMN!&eT6lAm7fyRZ1HH*1A5k60yQPd9+0uhbS zop6tN4N$>jhYt!2;>1yek?fJ$Y|$T&*1XR_EJg^&63eX7VVK5lJ7)bL9Y-=(48u?rtj+Btz_dv1qiC4FF z({`n*Iz+WP5j&7`=rOhj<_r|wyM5;&TIr~JQ_?N>tnw02(qd9Z>Ou$iZZk@QV$MF5 z;5AL>op$+6o3Ug2G^uUnO=>$;(@;1@_mxd^L8@*WpiRuU+{q##g_~^6u;1$ka@va%+XP7lb$J}{t;xtcN{h-K=5+`VrnQDx&B+MFiPDQe@?J~P-E%r^7 z--x39i-gi>kRJ_w5h+xil!pq81z2gaLMq=Byy`R;$yA%2&o{NOnoh}ToIOm`;TER` zA@JXU3PepLgKWh{!i4HA)uo$sdeiLGrz~anYE+jnK|f^{r$x9Jv4KL;2>;gSFOz|B zrlpZs7D_pRkOXRa1$Og^su@W+@t?oq;0}Hz`qs~Sqti(Yx$RlLI^v21aXYFkd5qtZ zIz7zoN`W2!bUAOFB}LNb5@CWzawl}4dI%zK-QW5Qj8MQy@g%%E8E$i`6U&MjY%LtJ zpxzAwyPi12kTc>1xdQXZr89a40@t5VB7YqAsoYc=MK|*@sA;aJxzuIDgKICPW zws_yCKtqdFSfBS*l0Bdj%0EubE!nlzd_ohN`Xd!HVp9HNFE~c562ee8o+OT;xPr$4 z3>h?44S>#jNY7tpG3(E4GRr!HD7Yp!ZZ4yeF@nksX2zca^Fj`105&Ken7ozh4?-@e zdDZl3X9p;UGxSwJ+^QSK)h4FmD+jh0-p+oFg4%6%A2>sR5oZyP-tss?XYN_x3Uom8 z2wb6+!!pz?SFg&tmM`Jl)cCZgE;ql;#}{X?Uvo*yO`UzH$IXXLho_xA2!r-13-%?B z;(GHnsW(4}ADh?ud?~Q=s5T{r?-P^o^yi33e#8TlLd##TQ9NRXsmhrTgtQLk!#0;0 zPu!<9Lwd^ZIf5Xq$fD1Z1h`x9jNc};~6 z*1~>yi6c`1n=djjv*BH1XMdwT*N%`?gde=IPwkqFLum3b>S5Z-?fJ; zbLVT+rl4jixW=CTZS+(ZIPh#wF~Mi^lj)UrS-%}d_}1v_73xFJ|KA4X#t&8f#Hrpf zK)1~=+M+L<0D&{#iPHo2!6!#)RD*BubvFW~Ku%f9rv!!34p|LYP&mpzT+&ykM}JH^-EA{4q~1kPR8EE@k~ zfs|*m_n$+Et~2(9pGMI)=mpvU4(+^%$b_B(ax6ke~8gdl?9&*cqP4j|}eUoq*` zjb*m}9m(YD5yDS{A&MX)v%b%O3FOckckl4t6`p}hwylgS9ZF#O(Es#)-r?OCK3Uho zj%;Y&@f{p~|KvU#cklGxom2LT!eWkMXx{m634k`ZUI_>2{cP=k!RZ|ZzF&|r(lPf^ zlt{qzJ{tEIKl}q5xGfLFuydFA8`kvm(3h&zJ(RC~qHiDQU4ZL*$n3+;hcdNY zC@U9`r4CEl3soDOX%}wUah`V{rqMX6rgAH*Osfuw`XE&d`-&B zcYe)yPj8BW*|!bku%2{(&3=)$+Is)^Vqd!cZu3*}{E66FU)w)T>#o@5N6xEvVNIa+ z0nle5(2f~h8=tDuM4R_7F)Px-=9ybSJbM^99Ex_q{Op2=_)`^aKPjZdo>aQ3QHguagXvd@AmTT#uBEH#ojNrVHe{m~6f?%A zL&cmAw`b-4R?E(>IcTg)n;<|?&+tA3ncPxUX=;|Q50KDsI+AgFPNqJVxCSV%z-(=O z`p*VHZp^O(eo^bXy|*v(sJ(#)BB~hD(p$`5<$X0)sZ*69epA%EIW_iisb|JF#T?Rf`F^?0N!mQ~1)HM0<#pje`>XWm)vpJ-2M81#&wiKH zPL4r-4t;#wkt)ujA6%RwKgyAKP&4!4?jX+!HynFcu`1{&nK9>9_AXu6@hWdFCi25Q z*qP0AiJ5&wA<+!tKvM<}nJXYW)(K#<)mF=g!#;3;)aDKRc$wWX3oC#H7#uZ5<#x=6 zDGO)oE;1`v(8o`BwP=6d-$C1qKd5+AyqdC1RSQP05p3QXcpTKKos0MzK7Ff?^Hevf zCOw!-03#IY%TNDoU~+^44LIZPbvR~xSFYC)h@xBV+il;#$OIa8<(C~-g6;HMSMpZf zZ$1lbUsm@D_OG~SYpS^Uwfc9Kr$q3jeoXJ*cWoeqC58B~!wRkV z9$2h=J^Zj`$ITtQO)9x`r!|-_2O2v-+}qpxxpS8-Gv0=#@9B9YzZTcm8`EV3WQ!jX zLJ6gh|3Y@8;cz#LVUK!Uv0AY~hGYFt;no??2K26}8m(1rQMKBtQ8ZNTJ!;gb8WCz! z)Tq=5sz%kSRn#7#rD~+Mm?el+F-q-`PcdB)sJ+`0>caYNj2f8Pk>kTj+};0Y})?O@xBIV2vqZJ2x1UNgUH#4H@*65V%P zH{a5;do1nAM+1?A)|S_J@zoq|1kr{@bI|1NmLaYH*~>pP$^Qf?07F?fhfNJ(n=(st zvS%i&8n@HmN_-zA?J2i&V?Jc}i&j16aADeW99C0EnRSwCy0L&x@_*x_lNKeX&`_kA z&=7W&mR@1TGi|4Yy@YpStYXsM)+$-%ASqKJ{%zHnWW^#)#TWWN+&ut=62_;)<9Y`3 zk;k%lshUNZs=e2chrw8fETfYTPHC{j@HG9T4hnf_zSAiTs9$6O77j%U+jqs8)fe)w zR<3+06?5;Xp(z3ZhhX1O2@;d7zZ$sOLfcHj5m43ogr|$FCG$1)T2N ztw8_@b*Ot{59I(ik~2?uvcjeV&II02ps>pl?xNqq;n>}MwJoNEhmRXD38tICQ>I=2 z_SHE4-KNuBt}?oxXWySov)85^o5gpt2`m9L%e<27;!}UB(fQT)xp!Ar!3Z)CxGIQ}^_tYiSd_zTLxHOpsR%bv4z)0WR7SKIl8B@2#qF?4G<` z3T$cntMCw4++ehOuzp2N7g)D2>2~vP6FkE;)3y1@{tXRmnd0ZyuSQA<`gju$kxiS@ z1W<~ub86Dc2RHHu8L zwEy-6DyG1G4eijUgrE7P$BF0W{k^-ehFbTQk!!`;dx!AGX$RB*IB6+3Lq5j;47;Ov zI5>TUin;da+n~@?tt69(omC?3AHrQ?@ODng$E$7M&@?~OP4ETDvkaA-5n|s)w8Bc{ z(vxm$v#H7oxeUBobe2#mv>u(Vb_tjYQ{k=FwgHsL!Ta-anj)&q;pg^FcGvtqy<&&@X9WsZ)Bz~;5zy6J+ zhFUeqvGY)dNP#@4XL@Det}l&CXJ-@H>`hzFc`g>x=dklV7qVB)E{^L_GJI%z%Pj(* z-Ie1O|H^6Cl1k*CGc-?|z{V7mP0>_VkjdA{4Hjotc=iQ}4&1iHHP9&0x;Bi1s;_xx z?u`iF>*c8^=$2Ea`g@$X2@CXl$9W3I%thYwjCzc*Evs}R&7<+{6TopVVw=R&aY@yu zD?pu}bxyA}&L%2;Fw|E++!9Fp1iU37Q;&mVAtLW~M6mGL=J&a`2AuC*PP@fcU{SYF zljPK+S)3)$C?GH-M5CdubH6|fsjn}odyg^{;}e4L9|~@HJ^4F5bnX7m8T8$-(whGT zsc9{bSs<~r>U%1SY>&iKx54*jV`{fsh3LPg?b^Yep*b?(?R6^z#Bp-X;=%e$Q#S*N zu}tQ^u1;f07suV<)e=*rn677gu{Q1Ae0yd^JIx7deCqv`N6{WV)jN^^L&v{X?bXQc zYjKpO{D)p9HjYsBPiy-lp~STUS%NOqt6e#I!c*`0C23CS$@HeI}!? z%YL?pPoQXuCXRzgax?-z`(?IJv{PeP1{e`Qdo9pIj-s(U79te+_LgGx#lIom(=I>l>N zz@eUhi-&14q8w1i`NPWt&eNY+Y6)iJ`~6A}wwRx#n0vhGGm~sWFyN&{>6k%@Q2r!I z;^Ijd(>C=U!RGkdFX{(%!>CzS(zeF`&1&=ZAIUSwKl*DfT z;LS!y-#9OAHh!@(+B%)PuO9BuFgG3%FZOb4CyNxgIsbA5?Mt2Q`l^v z6@vPm{qz0KOog-wH2q4&~$b^Iz0V6y5< z-@|UOL?1p2HqM`JvHNwj%_xA_xL`pWJ6ta|I^oOdlbev&_vs#je6zkEY$Pw=D&To6 zHzhFJH4n7(c2@^{S(;FtaM(oAc+{z`HfF0PH%90_Wo=|Wlc_S+V!~y!7Tslx8wvF~ zbK{xdUQso=eX6ev%Q&8w0@8xEQ2CgrGM}?#L4gJ7OibY1hbJPG zl4)Mvp?P>xHB#Q>!m8xwm3nr+KY#^vtBZ!_20PcPnrlRq<|P;w?G0X&mej;GD`JK( zr%-KtWzmW%XESszeGv z(D|~ssqTjI!8JzNX4$b@iZgSZJtL>t4cOtFp63Pl$Tt=b@=&KMYzei?pD)*3eKcv1 ziv~XlcE#+e+OUgS6_xz>I>xQl*Vn{Y9fm3G?UrI_5dGtD-pVPj0Iw{FS~^_zDxeVD zGi9DmLjEnbycLUAx8L@YRGw3fMV()A7}#@(K9sJlm#mTI?sok>7MoNo|`(^huL z@N)c3i=m9uXN`(Z@t5F>1glR3{fg~nn@MP@ub?$CRZhzDzI)(}+2)+@N;Knn-ZbTs z`-!jF1T{4_MK=Kn>&FasmRyx}GHEB;MQ9yua9w+cw$?8#>Km1i7Et%GaiB(L^a;+% z74SHY{=LZn2~-C_z=O^!%exN|t6isfL_X>4e*{vr#|7zY7R~VXw{>IZl91-*Vm)4J zN0FZG$VaRscoC#&1p$~mM696BiQs1g_lck<>_iZ<_xi;ajxZ3LwTj4-3}w04D*f_- z#6ZG@-RTb<-0-14nx^*Y2`zt_z%m>eWZikQ_D%zT3+#zd+!0X&{;dmay@QONtk1TtAYEJ8_FX|8<4aNg1bq(dk#K}{ zA%w7z!*!hTz(W(Eods!*Am;jefUG6|F?j+?E=OHzQ-ePLyzPSwYBjTN?*b0_!H zl6NLKLVHVscnW>lq_^%x56Y_&K#y{8Zf|TiX7-*mn^9*Vkj=XVRiFM~lSUxW5%|!0 ztOQlV@+x;kOT;J*;WKZ>S1z@R(`kihh6Z59d3bK#tl&a@o_Aw;F`B;tN61>J-~2At zc&f-WPw^Q~acJrDY!857)fe5f^pgIJ0vGw29a`>l5uVh|KO#=x*FKnsxOY=O%)w9x zVOARQ#FiTJ0D1+W4_^p5zX#tm0{*zz%Xve6GA(mz4uU`Z>`mt0b=$Mnz9>q&LC^iR zmJjQ*O#UDl!PmlN9(|G#fb3_@kgGxR{%Axcb3;YAhU~gc`VTA-MWP5+28+dpJfn2X z)x6R@%TO5kg!p8!;lkP?L?j@i6AUdDMZk3}Lbi%iR~kMn3K7l3xgs$HS0{XVAN^v( zu?PxG&1rO6ZWnbGfvc(^n(c{1Vq#CPB3SoXL$;Xzk#G-)W>v~$Qfv)z0wGK$umexa z!T*>@GIQY)JpxilE)D-H6`Guu3ki0Dl}gBy$kYF4IT?~+xnuzdS(ao>9=4)l&r+r0 zzafxTvh=zral(d-K$5+6IFscwWS{pHmj`vO=?3`t-Otf_HS&jm$s_lM3dZ3=BDNZ|FWPaYAI6V;HVd z$-&`Sw%LB9KY-e+l~ItFlv}KqlbAW?G}oF%cab*=7Cjcozk)M(`*b6JrkZ#kb5_)= zVO~cL+&Tm5RZ3{D#LP0tLhGC$gUYu@i@baT%BZqh>RXwFLAM~H{*QRsB&L3RuD86T zzZS25*!6@AbF2_~>4v;vSo;&Yyd;XXtAIst3S#ZhBFnTo7lJ5-ry+4G%Bv0PG>O0i zg4*YI=4kDjZx0io&-u$#M&1)k&CQ=496-_so1>ieEERNY*w($W0gscC^Q=X~w*pmA zrp&Mr_B!!eNYb*IbA7XuhX>TDN;tg|GB>x8iezZ9MeXL>$!#=-4tS|}R^}*5O+u6% zcH6?2?s?jH&k?8l<%26EmyjZWCp}o6>CNQw|1ShqYS#z8g#GWZ)h(ku(`Tk^HO*%! z#xYH3y9^(qE`}qU#1suO{#ik1(Srd16L}SL*V<^KR#q`E@2N)#VlE zA9keXnr)Adp1~s!%|ai&Uqr&16HL3?s%0=b~+Shi#QO%rAuT8lg(br~P?&EUnRnaFannZa7_O5oUE}t`06M>4W zyZHR47jB<+zKdomr2s;4lCzPBz`UIS+i}R?N~Nb`%N|I3YKSU;MMtlQirZ1O)|FvmiXCZBD$ zNjH2+;FNWrv1(h^LPI$)P7+(l?Mw=}htCnmTV4?9jd>UhB~KGlwO7mAOpgr)Z2Q~3 z;=xCp*S_|ANA|AhV5wtSJGUV|4{@jJ1`DnMA0R2;nj2=x!}@*Oo9}m;!!%SU{xiJFvy{-Z{B&`|SX40N{|K@BWxgF)?b#ab>Bd(L;f_#oT7GPTS z;{y~nQlE-8gGwb$l7NY(xYhI51q*+tADJB5&O#6K%@)ou$Mt@sbF9@ZWN1R_CFb`y z3UlW7(90BOc}N=>h#$ma!ac{Ob?CtsYmxVN^U7`ZiXon@@pk5J{Af|s)>QKg^ROG$ z)`FdtHKTt7s}91k+3hdVsq)(8L6^;Bf(8@fO+c78dN0j|SM6g`b(uZan_c<~maaue zsRL;4Du$I|70iEp3)6HOk{0!oFPS=FyQ#pvDkSpanPh9>*kkE*K^*_hW-+c3#wtY zRqa!6P`f~H)pZ`!Q&H-&lr1>-qV%A=ggP!t-3Xcr)lp~MVF&d+r4$vlrCZbYwDL+( zo_p0X6bMN@Z0xTpuN0-uqmByMMSY-n`jtnDg6&*%-GORl@j$h7N3~L0KkaMQeHLoD z-5}1Mne@D7;19*Z9OTmu6tbH9+=fDj>60lK20-mde!DRHa2^osJ|WJ16hF0_>t7F_ zUjcb;h^20UkED<4>DY(*7YPXMLw(jo2SDEh6CaWGG0?-P-z)Mt&~en?DfNfZKeg}O z$-XV4egyT$rT#Q%J^s4ANQn9U1=#NnSshurRJ< z)ml|GlS)obIhJpf-1Q*B?te@pny4F;qHd^E2zya}69tH3*ZUg5h_hEP#kj{{#BZy? z!%=U~+z?m55f zYdz-|&h?zX7qO4s46)bYe0FHK^ns!8E(R$E2> z1;`&qyH`lQ+uvs%KaV~j^U#H%TXtL=R69S4`X|AAU}NJukfrmtsLdz(E}h<~Zr*r$ zXwT2+{M68%jh$-OLr2rObdD+!|;OE;9Q~Ta4kV6~qmD_M09QHm29n|&%&Z2X9rmDp&$(MK51zeM4Ye<{`(dm1 z9AZy?LH?7E4H6&Y2Omf;V&oZYtJji0;kJ79#ol&5^gCrL&kL zM=?jqr!$zJ=Mm@r-nQz2?So>!2Xz(Lzmx2TU$4Hj}u# z*w%w=>t42%<_yU~W`p{@39%u2;cpMkBf{QG8~4-rY9B6boR)YVrE_;4cGl0+?F$cV zczOLi-CaL-y~67UbNZL8p9epGwV!;Vb%c5Q2EwKf<<&WebJp-mxwTx?44uPi-Ko? ze<-*B{9l5P0sn{KD)9FNp9cOH!S4b7C&6cdzeSh|t{+u8$w90^lpWY#EZ}?tu0MC; z+>2}VKAds=_ae`#t)Qvh01D-9x{gvi&a-5?x9>7&tU5(<$l2H%D0MU1zo0Rnk=J!S zU8{H0H#UBT`sZ<`7_?&F(E?fNhnH3NAxF1(ivmLt$MNU3=jUUA_^ zUHD@z{KYQzY;)l`7e3*_?{ncNUHGqE_#a*P2VLy#ap6%HzT1UeHhUj&@y`K&RO!R} zN5I2^KMs70;Aeq%3;sOt9>ISHe5>H^0KZxAe**gj{{+}#+|vsj5WEvODELjlA;BZS zVZk=A-k)Gf%m9xGpT=Tb@G|g(;CBMQRq(rk?-Kkl@Ik?k0mlTBzmtN=-zmX=4jdQ! zIpBoguK-UA{wDB@;C~0675ox#Qt;1!(~Ns>1HMOa5I83|0h||n4{$;7eZYqVp8!50 z_%v``FxlJ?Og66z{vz;1sE1ktheciT$6Nkg^uIp9&j zUjml-v-NAha`YKTK=;v{k)!W7T$ti>3s>}g7I?Sd=YjVK{s-W_g8vy<=5`;=XPMi5 z{|$T_%k)#f`vngG`vl(zEOWL0jleP|`)>uF5}5oPXRl^p9d}p zemn4S!N-AD1vi0ff*$~uxzSJS9slX*e}5a7GYwV$hkzdv{3pOq2!0CqPX&J(_({QE z0RFgOTKi84{x&=K$e0cc17B477@%>HV_?0DcRU3A zB3JDAJz&W>J3iQzx#8h19=zPeH@&%wZ>Du2$Iahx;U56ExZ>uQVenqQHtpJSknP`v z>(=&o#}|#smtNtMF9z=ejtc)a;5!8qA1ZX)w*Vgp-f@s)vYq&s!Nj5UT-8v^?A)u= z?aI?zlD4;VmDV$2rfv%y1b(B)hkzlcG}37^)^X~8ydTku`L z?-5Mv=vl$jz*hv%0DoIB`oTR4?)PoD*!K&*8~7%{$O9dGEq|9wey`vZp`iZk^Lhul99QXkEgTORr2va;$f^P&q zEEwx>*J2xa8(T5zYZcg!?b*w~?m2b_@-!c|f!`MVT9?c$;j0k9Q357;ngb;NsNeyY zypHo#2;jKb<@5Mn)ojmR@E<>@6ym9U5qmi1BJ(|J%UH)}dkMnIv-O2d`}YIu&Bg(` z*-_QEoED2qC)U>vsFkH9%UP8SDFd7I4qvIVI8COfk ziw(PFO*E|W(Q&^8PPJZJ8P*L0zpUYUtyx*Al}judB+=3FJN(jqb8YCF+HMzNUE?3U z-Z4HJx!xf?XdRooiD+eRRpX=n>#2a3&Exe(i*1imvpWJ-Bpe;5zn$96+Q-<5a3~ZA zp*=g#;q#Ab6@DwqA?!4iYCQs@<5ma_m#g(64GKc;9}gmCs#ITJtd_yj@s1KpJJ;ds z;A%dNY_)uv?e>Qzno&%Os_h>c9SKlPadDTU3RER7KiJAyc~FVyV=iDrtKrXD-OCA4fxaoU>DoDJ(yi70vSQSjV*H{ZV(loIn zqEW4^8hOH9W4qlhHyK-gjJxBU#K2qDL{Tq1|2WNoa1g@|2aHFgdC3q~U}C=oMys-_ zO(xTtrxvT)WFnT3PCCSL$yqHnPq3FDaC-p}3QjaJ$sK38)N~drt)^{-#DIW*JOm5; zqZZq6qI`z@(Id9DWc;R4LXWuVN|h8qrn;lC-0aqqQHJgYWVyLqsk$^6x~l`@!vuAJ z;CI`$oF+16Q4cqn*1~<^4nyY2T1%>3@#w~kP;;%kWEZS3hM{#5ky)|>yZ}Mfm^5p! zwF<$=L^Bv{t!hbGs-RXYwa#J%dAz>f038m};-%_R@eJs(u%YWDj_3=0ri{c5Mp!R> zG&sc#{9}6ggK>r#mSt2{nx$q7ZLE+{y0Y3rd|)CbNQOWMK5V6T&r}x|2y!FsV@?KvVkXVu>496xvQKA+4<|1S}H2 zpF+6aDmPD+wObsB`yDt*is7hfiS4EcMH~+17a$!Vu7ds@!m8=Oqu1~hpZ(Bx%6vl?{>SlW*;bmYgFFu7aTn6=#~uT+`{I#0rGrU)TU zT`B;|og;7oTsnbK$Mw=0tvanUYh^o1$tpZv#gr)5mWcL;nV}y+b*5d_sg`S?cwJU0 zkzsc5s>Jo7MmJZfG1ev2(NbBdtuJ93;87E1Wh)S#*pKVvbTX9y5t%sMq-Ro^RHx{A zNv;IcDY#DvIcTOE3S8neWuga)u3eog9+M_gq}ZfzbV=lDv2mi@fa_6OqE4-Rx@8B( zCiVx&edHOZi5tRp5Es5cL{^KlR&T;X_80ybYYQ;G=?_`Xa<#ZZ6088#v@dm#HEqkR zRcfTUvLMPbHlEZ6D? zS}>^dEM4~K@=u&72eMu*(Y1=Mvw@M2pLH*-H?W(puCLbYv5`E?QCJ)7v z`Pd{@TU3+zBk3uajqp)_F+(D1L}zpG2(^ATFQ1vx)>EGt0g@nh^U0%$$z&mK`vbTV zkhdXtn}@pGjBys!)NC>p*EF;dox0m8Ox;bcf=bWiGV|HI@fMs+Hjy^of`nU%*qmm- zUoZ+sJK=$+V7x6e=}cwPgEvSRnS||UN5IVFj==CtAu&}*(gb2x<`VgQ zY$oAkWBEL}fh~%*C4ru1GngE<#jfOMV>$FJiZYXLgC10}Lop0{Dw&639dG0!QbJss zyVx)pQcsY0B2|cS4SNMf>nw>N`(rsKph5P=a$tWl9k+w* z3(@h!AsdO846vN(Os>Ej_CYvEA$EwZx19W8EfL}&upG=+gd?6nDv}kEOxhu~Hk(X3 z3k8sDDv^{&5(PWNCK4x^E+lek;<1&)%jD6Bjm#pBc8D#^CsLTIc8IN;=Q)|o9I}z+ z$pg1KNg8&T4c$}~pUK7M>~P0k>JRAyiy+)JT=P=I>sn7dG-TroSn!ARP=wj?!Yq;u z5>A*cXA+5MI^j$s3)5OfCA%_{D9m7sjcjz32RO`5fuB9>=117IRAwfb?p_ok>{S7Y zt268o_D8yn)5TzZs*uS!Nd!2?y+_zTk-0l@gePG{mV|Zyk&98XPp0jNc*=b7PrHok zBt={l#R>(uLd|0Fc+QS&3P86~ujU8`Kw4fe|3)|zE(uJM*#y$GjU9ojTb+U=5!z7+ z3EK+p6!M|Nxz3JSvdYp@k;&!hf-!AJIU;U;CY?&#*stg*HH#2sDHGXI4o2)y*2Uv6 z#0rUpBrn{kOk1O~}PRcB2KAW(|*m$ukJ7d{n zZu1wiGXZ;SlkM4=Ag-5eweAPI0WjET&7cI2dmp+NW?*9ZN7-5|em$N1*hrBXn%4Df zX)1%P$|~8;!$WZ^0P>VEW(yDLrbu!^DZrH?0m-?xtz~y^H~d9JMYpf#-?bm#4>DfI_0Er!PhLg zhJ!Vi7Y>IOoHR?Yy`b}n0&`?Wr!eLV!eWybCi5XDnabj4QD%BNU|}c6mT#_@OkxjY zalCa+DvMv4Xc5L(W7F zd)OND2XUv_?^mbR>_!l`asV3|>UV*tDg8RD;JyQ3vs|u~>&u3VTYK05@k>F1ar*>% z@YA-~K)*r!euO}WQblU2W~Qd>;eB|&^)17eFXFR&cpmqw^7O+Tddh*PTYldtw9$bF zJo@D5s;;h?Tjt`>c3)t2&AYIv#C*TTgd>m(uV>$dJaiN4WpQ&R{%wR3ku2YgB*%}7sb@mnF>8S-Ht+XRmh>J%P7>A`Xm`V ztJBZRdT@puy?dqKzj_3;IgEWX^4=85Jp(xu{Vura*9)3TLBD6k`ku!LMf>6I7c7Nm zk=h2*_X6Zl^t)QdE;{c(Sw$fm@J<-LGe(7;8+Q)Ve-j)d*Mc0CFL$K4FCx!$<>=ir z{r=fa*O7Zb&O`$)WFD{bICmmeJGt} z=9c@A$n~M$%aB7+=TXdI;&&bliVN)PKL%AOI<7eBgXE}u1Z67<$yFhTqV>_Z(Lpj~ z?^AMy96b+4IR;MmpgBOtr%C-|;@N6MhTiee6r#-aTeh9D9E2W zE`vDZnX_9TJ+}7Z*>mSG`Z|mb;JiSMSw^pat&IEScO$8u?d5kPiJ%ywm0q(%^H|9{ zji6~fss4F7f#$gIyOBim{Nr~qi6$Q)ufP2un(gOzG>N8sf_l9ch^Fy_n>^=1-*656 zDxql(ll-fNzAQAw4ej-uq z@{SNQLGO}!eFFWuYiJr{*SKx`2sFMy>G_1nQGBkgH+^DojQrLYT=KWjdjdpbaH)L+ z@q317D57}95#N18OMS+~7xfh1w}XC;>OoUHuk9c9@i!%?BmLL0XOsQ!F#bq?ZRpqI zCHfyl{r92g7uoYcmwjaawf20B+R`EMcn11j0=Xvr{goMCG^Fvpw*42(e8A+O`S2C^ zr^jSMyuJvTj+QP9Z#z3&PuhuSgbmF=j0UEPlKy}&nMDx zdmfO%oU-2a>E{s#4|YEo;?I-Z9De=Y&Dr#&(&mcIA1!UF z)4$>4^SBvCH`VE$XMyf(I||Q-=+h?soCW%7ru$ULBKnC$4V8+#mwTLx{-(o}_<0Zh1%wyetYsgcGt!tHHWO=ng=WhqS{r$CT z7@r0E1+dvJ^Up(a6!}MyCy_KF^V!C>?DY7yY-($EI#)i}Sj;y%N^J!HazqqYmm;!` zHHe!K87@RLI#Pe?!ZHl&b)qivQaiZ-1lxr=e>7ZX<-EbeZ}if2NNJCYJ-W_I?Sy66 zPx3aZUo2DSghk&3dgzGGzgS(Mnn1sL)X?ixGw3If|3Rc|rwfsGrL8uicLPW>UioW* zM-fk3^zEP@u;?V{M=W|0^g)ZB0sR8#3R1RLKs4>uqrJO8e+l`VL(D&ncocNEM;}MJ z;X$omJv6)*^b+#_%*+1}(oM+c7;ePBk0Ukmq(24vhhG0_ucy3xB*^{6@@LPYzXtm9 z2Ww>rnXfQ^COB`x%I(@S(6O_xQ@K6;gF8C<-NEkecr4*2I(GEOT;)#Zrc275M50_b zSuCatC3iA8oduQ79hffUb80qSDC7%jaw1pCs=2~+DXj|WWJ(p&+4Mw7r4OP8BbzJ< z>AKWFSB}!TJgO_EOOvzZi8(-|?nFLUD&*0Qm!C#SXp&APOG$`~7mIGOlq`^yOQCD>c3O>zekaEN0!-c%Q%tZ7Q%t@rQ&?h_DJEx$DHg*)rdR-PXNm<;VTuKEgsIF- zG=i|SAG7LnN-c+XBWL;gz4%N1^7U*nL-_Jb%Lv!AX@GuU&GGX1M;AraaD1URz#Xf>G4aQVOiwkC$#x$N%-stmp|Y{;ySj`kUkbd;{tD z(?h6pzMX$n>B1AoYL=g!KUF*5rpmv%{nX;GPn}p9pjiCa9c%WfeKql=H%oi#=T9$} zFUy>!1`B9;->RjbBRT#rtiSTrHADMq<4b42ng6_qUY)63gy?Nr^b|#_`W?ID%;GC| zpkYs6w0HQG%c1nHvAFZ%7Z+F$*3O#G@Xr?)PJ?8RzPRu!AU3#9E$xO{P-0lLTXTFt z0W2=O3IS9*T5(Q3Sr5U*=g<7|vH53MgDPEn_;*b2*--abtn$-M#}62L=_XjQSM1m` ztO!LHUM#H_Yt}s`Ex;t|*l}hKAAd(>*S_WnCN9jdX$XVo`Xi57>S@kU~8d0ll>o@5Jk4)!j>qsOHW zU#>gy5%3pYEMJqk8ddM>&Rl~e)5vBXMl)9Z|Hh7P`OTvAX7RhNzq|YVW75BoF<5F0 z!n7#*bkFrwwQr`{H)MjWuSTn#^{U0v zB=T5wN1jKY7hbGe_y$r~vL1Dr@rgg(CF_NMm;Lo}X1;B?x?a#%KP-I!g|QUH9oJ96 zsb)P)2b(osSv>Siaylozdb~V2nJzR=sB$r#@_e{oBYYcY0D?))vzojdo?CY#z8mpF zh@U|G4C2=j{}b`&h_4}XpcuK=;Io|j5&955qn9f1*+@6d*RJ7S1^3foX*R z;m;8(1PHT;6#|6!Ayx_<(5lDU1Jo!HvTIwP20}Y=})`MMguZD+O~TmD(zpqp4Jf zU_3+-;)3;VFD;m(q12pUz4KfY%#l*+gMv9)u%}?XbNzx~?r4?zj$pmB{Fz|A^ITO+ z-S{X~>I%VE32qR)S@2%L_=7MdSnpJ41?#>X60G(AOTk+IV}iBL_X*ZI|E*xH+usS+ zx_wfxY`4@?g0&4#3D)g?Rj_XN+k&+Xzb9Dh@ZW;94!;zvZFoko)@L;qPQ}|@ZxF2Y zxl-_-NPjmAzE1Eq!Q570o(ty8SE^fZK=82O7QuH2ZWEjltXD}Wr7oeuNBNU3cQyI-YqyPc#q&7!FudQ1YaS1SMZgB zvx4=!ofCYu@aF~B3w}iKX2IVO{AR)56?~)M9|_(f_*KC-2|gqEX2EMQH7lw?@Fu}} zz1ItF68_DC9l;U7dTw+HzD4+hg0~CaD_D>FwBRn`&k2qRJ|bA4dQ|Y35TCaAKeF&8 zST+^Bk272&Sg-f3g7tcj3fA`Q7Od?#B3Rqg6|C(!Blt~H=OMv*jVuVhR`~Y|*6Zb? zg0-FhNwBu_X9RB%`L77RN$?ATwVi(~SljuRg7sQEA1ctxdrZ;qMpRD)=tJ0@WiHe$v9PS@=S@p^6q)ofa-w_+u9SwuS5AwoKVO zEPStppSSQUf`1^b{jcDD!RNu{Rn$(w>jeu`T^24{_)!ag$HEuET~>5awZp=57Jk&i zKe6yuEKyT-+`{);_^TGa5H8rr-)iBb7XE^TPh0qwi>qY|7Jk~o-?#9ufj47E!+lE) z9+M9NV@a#Ez+JM_F?b`skQmIbB?ez2-%YgqCdC=2@ulic;B}~HJL;(c-XIvtB2eZe zQd7@Mz;_~E3jSv7x|-fuyGGZe*QUmo%RW!zKeceZa!^+DuTk_O8ec1WIgPJVuFv1B zGCsau_Fr1&237L;H_8}j{>|#Ief~D}sE-4DW%t?&s;~Gsq@MS2vwGFXE$Ra7vvi#o z$v#fw7PZCaN7Qy7M^%rH+tlqoev3-^c)L2`;|}#+AMa2P_&BCM;p1-g?>_EPulo2R z^?M)psI})AJ$uzAANQ%Ne7sX__wj(*;p0Ko<>O&B?Blo^_wks@`goT*?Bm_)1n`?M z2X4f^i?7BlGH0%oZ-qO6E9y$cH@05kUuDg!s}zc=A(6RC@#XL~5Ay{nCHQJp!OKQo zFnl#I?SB&G;Cj?w2)|kJWzX=<*u8{&zN{F&8AtLtcDihAMOkBW%AA7CU!nf(sz-D- z^%(n8#@L*gcA!iO_$1zEwxyB>(z#@=w5?n$Y|G{+l3Dp&JD!}_U!L8z@^x!!Vj_Sq zT{E-O*>tK=P3KC{lG9#r+O`IqP)jHhYz{@*eAv>aCNjxFv=nGB1lpR~oB%l4d~T{< z3I_kbg5_LsdMcMrY0(fxo7%QIUip=|;j?n9O*Bi6({!%T*3@#Y;I$xitZb%5DzmF< zYjVz21$tS`| zWdxeq0$~)K%;u9E6qwv;3&Cb8l`oHH(_o3cBV+1)nY}%v#Odc6;ji>NsC*Wo{_?q786+1qN~MAB~z)wS-MRaULeqZ zQ=r;-*6Ubvl{Hz^S_gudBCdM?b0iS*jPJB@x-`@BW!rMa2rNO%mkFqH(P@sBBIFRz zCdFVto2yJf0~DJ>(GpuO6SSDI=NS4!=Z{#mIct3UVev=99|Yg_mN}}uH8u|^%ls>> zUNyF5W6O*R#{%L2(cQ8uK7su#;~)XkA_Tz6&AC?2RRybZM$DJO2?FOm7G|IclWnq) zPMgIE5_U+XqhW7>?p2fSWG*?Ajs}{&p$WGIFfa}9(a4&GgGW|_;{?cQQ|wJ~Ha&p` zS}?4o16XAf(V$-YpmLft%b(&L_(UL5mG(RZr152L!g3arzAK+gL%fyZceyh-3@oLK zbLnEq^a0#du|!d;P!E|eeTKl@~Rmjfd%LQ=ICY&PZnN;!+=+ z4}1kqbg`gHp{DkmxXqycdV%m6#aaz1@}SHz@iNUq(Iw4V@iNV7(V1q!c$sF&xP60| zXYy!Hgy5edFhMlbgh7O-n4C^$Qx1j@113W#i~txR4lB1cC_a-cVAm2&gy5{4fSbdS zb2Nl?9}4JN+#*g&qM;Bt;r4??7U}Nmk43#{uvfVlO^m#r2f9uXNIupC$tenm zPAtxI7>-pmK;J@5QHkN>WSe|lo6j9j7U7lyo=eo?a_sJ!9M3zlgwF69@LZ%_#B0Ly zl`MfC`W5*e(`0z!#%n^nh}WH}yyrGqjlA#pIiBCtO-mWCs$f`p?U}v^b2kJd;-~qn z$I~H%2Q1c|w#+16lyZ3(FoaJqoFn=v!&?f4l@F>b zx*jvBr9JHqb-Mk11Gl<6J9bB#8b|`UogD*%15n)1eFH zuaF^4_6^0{9i!dYooMmS-oaf1?no@280qUw#JZx*A~!JTCPqdFI-@N@j&=3Ld9ef2 zUKi_#?-}UC;KD9!bZ7)U0_A8eO{U{Cv?+Ebg3iP{-HwqS(-%;ky?y;%LZdIF`)_p< zoww?qfF9@>85|voo6dkUI20Q&odF4*V;wt%A>9Ehahu5BCyI&@B}R{>ZZdlG#+Vi9P8*G^;V3TMJPHv8Z%ry3YI2bS2)XiM+OH5N8_CPL0KD6v6~supdN#r z9YaHyZd~MXK2)R+v7Ip3tx>oHt?W+Ca7Q`@dSX#LG(4%nkv-_zU?SEDGY-(j>5O?6Gqtn&U3L||9%w5dy!DvX2j>p}DqP?-MQA`^YF{6Y9)X$!|=<+~EKUDM< zNeqhj4#F=);V{{1ytiWn^+Hu@HMrxgPzsr5w2U!K<6+%Zv06MDHjbbbj-WFR)f2t& zXl*K&&y9-)M-}*o7Y(A_j-q=V3pbfT|7;Tgnu^ z*5BAOFuJ8a(Ad%#;6=&T$>XjTT+d30k2V@+<!J)_glI9iWHwd{lGki z>kx62D{{Qsu>|~aM4l}$)OwMpXE=ruIo|oW4;54pna{eI;%+^xW@8%N7>XJrT(W)6Vm zow_JB3~c0f<8I4t$URO0FR(sFo^~2J-aqDf{kPbt7pN=4UPL3uJ2E`SJy*Nqo*eDM z+i<5L)B$V)>tNW2NX({qqi;JpPkl@$Tf8a&wkkKjixVh}_+l9PjKT zAg50^b<3=eaUPL2rhdFzBzK>IO?ynK$Gg0ga=bydVV&?zH+}i{Am3+F7IJsu;K0mP z*2i;%_aU+_6J~ML{4OH|rm5p03sd&Ymg-$0(njtdfO$^Fz*`cLo6arAxoEdrg4`!r z$P1=ErW{)n)^9^Upgd2$8xYwK&Ka0>MSa849&0eE$ z&})SnfAwl+jd+NvK#g~&#&Bx<*<<84nJh_bp=K!Rd-;lSsl~l) z&PkpjX{oh}{?^dv!9EV?UaSx1uR?!$3pZ>wnZ10_*x&B$6_1}l|aZmnS`g|DqRsAkh|Hy(~pgz3E&hzal zq%405DbE&>U&&B9Z1L#Mr@{X5} zY|O^Ba-PiokY@k-kx{)5QJbpYjpwtoka2K^=E)5kJD3)-%)2%3Hv zSyKNZXx>yc^t(a7fbtbESpHtGytdCq^&sdasLgD=q;@m&mz{eH+!wd8CiR#ZQ^zStO4>ee{?f?J) diff --git a/backup/readbuffer.c b/backup/readbuffer.c index 4cd31af..2513977 100644 --- a/backup/readbuffer.c +++ b/backup/readbuffer.c @@ -1,4 +1,23 @@ -/**/ +/* + * readbuffer.c + * + * Copyright (C) 1997,1998 Ian Jackson + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this file; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ #include #include @@ -7,9 +26,9 @@ #include #include #include -#include -#define BUFFER 16*1024*1024 +/* was 16MB -- PMM */ +#define BUFFER 6*1024*1024 #define WAITEMPTY ((BUFFER*1)/4) static inline int min(int a, int b) { return a<=b ? a : b; } @@ -21,7 +40,7 @@ static void nonblock(int fd) { if (fcntl(fd,F_SETFL,r) == -1) { perror("fcntl setfl"); exit(1); } } -int main(int argc, const char *const *argv) { +int main(void) { static unsigned char buf[BUFFER]; unsigned char *wp, *rp; @@ -31,11 +50,6 @@ int main(int argc, const char *const *argv) { used=0; wp=rp=buf; reading=1; seeneof=0; nonblock(0); nonblock(1); - if (argv[1] && !strcmp(argv[1],"--mlock")) { - if (mlock(buf,sizeof(buf))) { perror("mlock"); exit(1); } - argv++; argc--; - } - if (argv[1]) { fputs("usage: readbuffer [--mlock]\n",stderr); exit(1); } while (!seeneof || used) { FD_ZERO(&readfds); if (reading) { diff --git a/backup/settings.pl b/backup/settings.pl index 5e9c5d5..4cef23f 100644 --- a/backup/settings.pl +++ b/backup/settings.pl @@ -1,11 +1,17 @@ # chdir '/var/local/backup' or die $!; push(@INC,'/usr/local/lib/backup'); +# huh? AFAICT this adds two entries to the PATH and +# promptly removes them again??? -- PMM $ENV{'PATH'}= '/usr/local/lib/backup:/usr/local/bin:'.$ENV{'PATH'}; $ENV{'PATH'} =~ s,^/usr/local/lib/backup:/usr/local/bin:,,; -$blocksize= 1; +# This sets both blocksizes to 10K. Note that both must be the +# same if using the zftape floppy tape driver, since that requires +# blocks to be the right size, but dd with the obs=10k option +# doesn't pad the final block to the blocksize... +$blocksize= 20; # was 1 -- PMM $blocksizebytes= 512*$blocksize; -$softblocksizekb= 1; +$softblocksizekb= 10; # was 1 -- PMM $softblocksizebytes= 1024*$softblocksizekb; $tapename= 'st0'; $tape= "/dev/$tapename"; diff --git a/backup/takedown b/backup/takedown index 158347b..e41c783 100755 --- a/backup/takedown +++ b/backup/takedown @@ -1,6 +1,18 @@ #!/bin/sh # # Take the system down for backups and then bring it back up. +# Expects a single (possibly empty) argument X which is used to select +# a file /etc/backup/warnings.X. This file will contain lines like: +# T 300 "in 10 minutes" +# T 240 "in 5 minutes" +# T 45 "in 1 minute" +# T 15 "in 15 seconds" +# configuring the frequency of warning messages. If you call the +# files 'warnings.soon', 'warnings.now' and 'warnings.' then +# you can invoke this as: +# takedown lots of warnings +# takedown soon not so many warnings +# takedown now no warning at all set -e cd /etc/backup @@ -30,4 +42,7 @@ END ) & sleep 1 +# We assume that runlevel 5 is set up suitably for doing backups +# (ie non-essential services turned off in an effort to get the +# tape to stream.) telinit 5 diff --git a/backup/tape.b b/backup/tape.b new file mode 100644 index 0000000..ee89381 --- /dev/null +++ b/backup/tape.b @@ -0,0 +1,3 @@ +filesystems all +next c +end diff --git a/backup/tape.c b/backup/tape.c new file mode 100644 index 0000000..0502c06 --- /dev/null +++ b/backup/tape.c @@ -0,0 +1,3 @@ +filesystems all +next d +end diff --git a/backup/tape.d b/backup/tape.d new file mode 100644 index 0000000..2c27037 --- /dev/null +++ b/backup/tape.d @@ -0,0 +1,3 @@ +filesystems all +next e +end diff --git a/backup/tape.e b/backup/tape.e new file mode 100644 index 0000000..09fcda5 --- /dev/null +++ b/backup/tape.e @@ -0,0 +1,3 @@ +filesystems all +next a +end diff --git a/backup/var.tgz b/backup/var.tgz new file mode 100644 index 0000000000000000000000000000000000000000..a17094353c2e52557e8b8888db071c4d6cdb5c67 GIT binary patch literal 1482 zcmV;*1vUB~iwFP+TX8o41MQsKZrer>hIMN`#ay;%DeaLbGzE$zK--I;K=T6Ra%mBk zNP!0@dHW7YSqG*ToyL+}cs>{)DXlp3@9qqDX)foB+1UXle63*y9c zk2Bwsc0g>=F)LmQ`FgZWC|p8EtUJJf%*xzZlwI zE5*1Ez&TTL2JDPJ?Re$wpE%d{fVd{jGOu0i+f7@a&BkQ>OL?6CIai)f@qY>aZjG^Z zowY0YA%S?c`WXuQxdHPdC5G2PAOEZJ_MA2*;$M3{8^=FmoZ|lyye*3?ziq3y$;$%F z(waM%&*x5-uWbFLZtNOvtFqm6sUdqSf2-n zZCx!^rHNOIx-ti!*9J|SrIQz?>OYHDgTZIFurAx8flZkgO&!56ebHYdsMA=u3*02Q z>8*`Q?#=|uz6@?+?vBjiXVM)!!d>M)Sj8jbE=*dLYo{m+cVnw{T;S>8pn~n^jWvx; zp}?OvB_tNocD=Fbf${A*%u#cdch1Mw!k=vcLI7hC_amu*hhgZX`0GV#?-zB$BKV`& zw9TSy8{B}cshu&L~QUbgjMtajY$lUupnA9Rtn=)-A0{O??Lndd&p*jje@ zv6Fn{Pj@$!UngWs=TpDn`O4bqZBJGso(U4 zpxp0eZ+gcH^vsc5`T`Q{Pj@x8gdZq$>p*w^{YX1}-TX3))JV<{KiAOYd%oUF;vo;^ zp``BXX+=s!Ts*X#Wp4?hTKRSa<&P9OAc0xrU6xTlH$V;a;)!m^=#2{`)D_Dq>!wW^sdb@<(E23l+CoXVw}&QDJ~pB~l}^AlR$kb%7%nbi~7mv#kqq zbcGk*N$n^!Ge&S3r-@2JF8o*rQl^4o{Rc5td6$6DK1_PBZGdrTpbtvNHkGWLs@Bd(;1kNWW&obS3 z&e_8A4EC>`!@q}N;6KN{c|IGb$N$*78QVYqA=vQ$9~%E(gtJckwtV~ZKa6u4|6K%{ z{}BX15ClOG1VIo4K@bE%5ClOG1VIo4K@bE%{6E=Tzy|QC=l>qw|G~Icynp|j&t~9V zz_-`_{9pI7A2(~yx&r9Q&wn1g|HY^Gzgz@E&wsvZhWGBcae5yY=1ebv{Py@4OwjY+ z7lBj!ziNgxYxP;z08hog?AH7qj{i8vU5fupFtu{fnOY<0Of3X-rdIknQ>*x#sik?8 k!w7;P2!bF8f*=TjAP9mW2!bF8f*@x903Cyxh5&c~04YKEyZ`_I literal 0 HcmV?d00001 diff --git a/backup/whatsthis b/backup/whatsthis new file mode 100755 index 0000000..00d5dff --- /dev/null +++ b/backup/whatsthis @@ -0,0 +1,122 @@ +#!/usr/bin/perl + +# whatsthis : just read an ID off the tape and display it to the user. +# Peter Maydell +# First rough hack; mostly just code nabbed from full. +# --list assumes the dump type was 'zafio', which is a bit bogus. + +# whatsthis : no args => just print tapeid +# whatsthis --list [n] : print tapeid then list archive n (if n omitted, +# 0 is assumed.) Note that archives are numbered from zero! + +sub rewind(); +sub stopandsay(@); + +$etc='/etc/backup'; +require "$etc/settings.pl"; +require 'backuplib.pl'; + +$| = 1; + +# This isn't intended to be run automatically, so don't bother +# with setting status. + +# If we are run with the argument --list then list the backup to +# stdout. Otherwise just print the tape ID. +$listing = 0; # default : don't list +$listing = 1 if ($ARGV[0] eq '--list'); +$listarchive = 0; +$listarchive = $ARGV[1] if defined $ARGV[1]; + +print "Trying to read tape ID from currently inserted tape...\n"; + +unlink 'TAPEID'; +system "mt -f $ntape setblk $blocksizebytes"; $? and die $?; +system "dd if=$ntape bs=${blocksize}b count=10 | tar -b$blocksize -vvxf - TAPEID"; +$? and stopandsay "Failed to read TAPEID.\n"; + +if (!open(T, "TAPEID")) +{ + stopandsay "Tape has no ID label.\n"; +} + +# OK, there's a TAPEID file, read the ID and check for sanity. +chomp($tapeid= ); +if ($tapeid =~ m/[^0-9a-zA-Z]/) +{ + stopandsay "Tape has a bad (non-alphanumeric) TAPEID ($&).\n"; +} +elsif (! $tapeid =~ m/[0-9a-zA-Z]/) +{ + stopandsay "Empty TAPEID.\n"; +} + +print "TAPEID is $tapeid.\n"; +close T; + +# If we aren't listing the tape contents, we can just rewind the tape +# and exit. +if (!$listing) +{ + rewind(); + exit; +} + +# List the contents of archive $listarchive on the tape. +# We are already at the right place for the first archive +# (after the TAPEID). +# For any other archive, we skip forwards to the start of that archive. +if ($listarchive) +{ + system "mt -f $ntape fsf $listarchive"; + $? and stopandsay "Couldn't skip forward to archive $listarchive."; +} + +# Use file to figure out what the archive type is +# This doesn't seem to work too well, so I'm disabling it -- PMM +#$ftype = `dd if=$ntape ibs=$blocksizebytes | file -`; +#$? and stopandsay "couldn't determine file type: $?"; +$ftype = 'POSIX tar'; + +# What we want to do here is roughly: +# dd if=$ntape ibs=$blocksizebytes | readbuffer | afio ??? +# +# where the afio options are such as to list an archive created with +# afio -b $softblocksizebytes -Zvo + +if ($ftype =~ /POSIX tar/) { + # POSIX tar archive; we read it with cpio + $reader = "cpio -it -C$softblocksizebytes -Hustar"; +} elsif ($ftype =~ /ASCII cpio/) { + $reader = "afio -b $softblocksizebytes -Zt -"; +} elsif ($ftype =~ /dump file/) { + stopandsay "sorry: can't list dump files yet"; +} else { + stopandsay "listing failed: unknown archive type"; +} + +# Now back up so we can read the file again properly +#system "mt -f $ntape bsf 1"; $? and stopandsay "couldn't backspace tape: $?"; + +system "dd if=$ntape ibs=$blocksizebytes | /usr/local/lib/backup/readbuffer | $reader"; +$? and stopandsay "listing failed: $?"; + +# All's well, stop here. +print "Listing complete.\n"; +rewind(); +exit; + + +# Rewind the tape. +sub rewind () +{ + system "mt -f $tape rewind"; $? and die $?; +} + +# Print the given message, rewind the tape and exit failure. +sub stopandsay(@) +{ + print @_; + rewind(); + exit(1); +} diff --git a/backup/writebuffer b/backup/writebuffer index 533cdb417abc71ab86fd4eaa8b7fc156241460d9..67db19632faa0f5509b088289ada36f39717014c 100755 GIT binary patch literal 14519 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

y-CW#E8C1g2Jm&4?81Fb`>(+Cxz2 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 EKdiF;aR2}S diff --git a/backup/writebuffer.c b/backup/writebuffer.c index c4fa9e7..259f6bb 100644 --- a/backup/writebuffer.c +++ b/backup/writebuffer.c @@ -1,4 +1,23 @@ -/**/ +/* + * writebuffer.c + * + * Copyright (C) 1997,1998 Ian Jackson + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this file; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ #include #include @@ -7,7 +26,8 @@ #include #include -#define BUFFER 16*1024*1024 +/* was 16MB -- PMM */ +#define BUFFER 6*1024*1024 #define WAITFILL ((BUFFER*3)/4) static inline int min(int a, int b) { return a<=b ? a : b; } -- 2.30.2