diff -urP amanda-2.4.2p2/DILOG/conf/debian-2.1-2.2.13-ncr53c8xx.OLD/amanda.conf amanda-2.4.2p2-changed/DILOG/conf/debian-2.1-2.2.13-ncr53c8xx.OLD/amanda.conf --- amanda-2.4.2p2/DILOG/conf/debian-2.1-2.2.13-ncr53c8xx.OLD/amanda.conf Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/DILOG/conf/debian-2.1-2.2.13-ncr53c8xx.OLD/amanda.conf Fri Feb 25 13:57:25 2000 @@ -0,0 +1,300 @@ +# +# amanda.conf - sample Amanda configuration file. +# +# If your configuration is called, say, "UrbanetInternalSet1", then this file +# normally goes in /etc/amanda/UrbanetInternalSet1/amanda.conf. +# +# for explanation of the parameters refer to amanda(8) and +# /usr/doc/amanda/WHATS.NEW.gz + +org "UrbanetInternalSet1" # your organization name for reports +mailto "amanda" # space separated list of operators at your site +dumpuser "amanda" # the user to run dumps under +# +inparallel 4 # maximum dumpers that will run in parallel +netusage 600 # maximum net bandwidth for Amanda, in KB per sec + +# a filesystem is due for a full backup once every <dumpcycle> days +dumpcycle 1 weeks # the number of days in the normal dump cycle +tapecycle 15 tapes # the number of tapes in rotation + +bumpsize 100 MB # minimum savings (threshold) to bump level 1 -> 2 +bumpdays 1 # minimum days at each level +bumpmult 4 # threshold = bumpsize * (level-1)**bumpmult + +etimeout 2400 # number of seconds per filesystem for estimates. + +runtapes 1 # max number of tapes to be used in a single run +tpchanger "chg-scsi" # the tape-changer glue script, see TAPE.CHANGERS +tapedev "0" # changer configuration 0 +changerfile "/usr/local/amanda/etc/amanda/uis/changer.conf" + +tapetype SONY-DDS3-125m-nolabel # what kind of tape it is (see tapetypes below) +labelstr "^UrbanetInternalSet[0-9][0-9]*$" # label constraint regex: all tapes must match + +diskdir "/space" # where the holding disk is +disksize 1300 MB # how much space can we use on it + +# Amanda needs a few MB of diskspace for the log and debug files, +# as well as a database. This stuff can grow large, so the conf directory +# isn't usually appropriate. We use /usr/adm. Create an amanda directory +# under there. You need a separate infofile and logfile for each +# configuration, so create subdirectories for each conf and put the files +# there. Specify the filenames below. + +infofile "/usr/local/amanda/var/lib/UrbanetInternalSet1/curinfo" # database filename +logfile "/usr/local/amanda/var/log/UrbanetInternalSet1/log" # log filename + +# where the index files live +indexdir "/usr/local/amanda/var/lib/UrbanetInternalSet1/index" + +# where the append tape file is +currenttape "/usr/local/amanda/etc/amanda/uis/current-tape-for-append" + +appendmode 1 + +# tapetypes +# +# Define the type of tape you use here, and use it in "tapetype" above. +# Some typical types of tapes are included here. The tapetype tells amanda +# how many MB will fit on the tape, how big the filemarks are, and how +# fast the tape device is. +# +# For completeness Amanda should calculate the inter-record gaps too, but it +# doesn't. For EXABYTE and DAT tapes this is ok. Anyone using 9 tracks for +# amanda and need IRG calculations? Drop me a note if so. + +define tapetype QIC-60 { + comment "Archive Viper" + length 60 mbytes + filemark 100 kbytes # don't know a better value + speed 100 kbytes # dito +} + +define tapetype DEC-DLT2000 { + comment "DEC Differential Digital Linear Tape 2000" + length 15000 mbytes + filemark 8 kbytes + speed 1250 kbytes +} + +# goluboff@butch.Colorado.EDU +# in amanda-users (Thu Dec 26 01:55:38 MEZ 1996) +define tapetype DLT { + comment "DLT tape drives" + length 20000 mbytes # 20 Gig tapes + filemark 2000 kbytes # I don't know what this means + speed 1500 kbytes +} + +define tapetype SURESTORE-1200E { + comment "HP AutoLoader" + length 3900 mbytes + filemark 100 kbytes + speed 500 kbytes +} + +define tapetype EXB-8500 { + comment "Exabyte EXB-8500 drive on decent machine" + length 4200 mbytes + filemark 48 kbytes + speed 474 kbytes +} + +define tapetype EXB-8200 { + comment "Exabyte EXB-8200 drive on decent machine" + length 2200 mbytes + filemark 2130 kbytes + speed 240 kbytes +} + +define tapetype HP-DAT { + comment "DAT tape drives" + length 1900 mbytes # these numbers are not accurate + filemark 100 kbytes # but you get the idea + speed 500 kbytes +} + +define tapetype DAT { + comment "DAT tape drives" + length 1000 mbytes # these numbers are not accurate + filemark 100 kbytes # but you get the idea + speed 100 kbytes +} + +define tapetype MIMSY-MEGATAPE { + comment "Megatape (Exabyte based) drive through Emulex on Vax 8600" + length 2200 mbytes + filemark 2130 kbytes + speed 170 kbytes # limited by the Emulex bus interface, ugh +} + +define tapetype SONY-DDS2-60m-nolabel { + comment "DAT tape drives" + length 1350 mbytes + filemark 500 kbytes + speed 300 kbytes +} + +define tapetype SONY-DDS3-125m-nolabel { + comment "DAT tape drives" + length 12000 mbytes + filemark 500 kbytes + speed 1100 kbytes +} + +# dumptypes +# +# These are referred to by the disklist file. The dumptype specifies +# certain "options" for dumping including: +# index - keep an index of the files backed up +# compress-fast - (default) compress on the client using fast algorithm +# compress-best - compress using the best (and slowww) algorithm +# no-compress - don't compress the dump output +# srvcompress - Compress dumps on the tape host instead of client +# machines. This may be useful when a fast tape host +# is backing up slow clients. +# record - (default) record the dump in /etc/dumpdates +# no-record - don't record the dump, for testing +# no-hold - don't go to the holding disk, good for dumping +# the holding disk partition itself. +# skip-full - Skip the disk when a level 0 is due, to allow +# full backups outside Amanda, eg when the machine +# is in single-user mode. +# skip-incr - Skip the disk when the level 0 is NOT due. This +# is used in archive configurations, where only full +# dumps are done and the tapes saved. +# no-full - Do a level 1 every night. This can be used, for +# example, for small root filesystems that only change +# slightly relative to a site-wide prototype. Amanda +# then backs up just the changes. +# +# Also, the dumptype specifies the priority level, where "low", "medium" and +# "high" are the allowed levels. These are only really used when Amanda has +# no tape to write to because of some error. In that "degraded mode", as +# many incrementals as will fit on the holding disk are done, higher priority +# first, to insure the important disks are dumped first. + +define dumptype always-full { + comment "Full dump of this filesystem always" + options no-compress + priority high + dumpcycle 0 + maxcycle 0 +} + +define dumptype comp-user-tar { + program "GNUTAR" + comment "partitions dumped with tar" + options compress-fast, index, exclude-list "/etc/amanda/exclude.gtar" + priority medium +} + +define dumptype comp-root-tar { + program "GNUTAR" + comment "Root partitions with compression" + options compress-fast, index, exclude-list "/etc/amanda/exclude.gtar" + priority low +} + +define dumptype user-tar { + program "GNUTAR" + comment "partitions dumped with tar" + options no-compress, index, exclude-list "/etc/amanda/exclude.gtar" + priority high +} + +define dumptype high-tar { + program "GNUTAR" + comment "partitions dumped with tar" + options no-compress, index, exclude-list "/etc/amanda/exclude.gtar" + priority high +} + +define dumptype root-tar { + program "GNUTAR" + comment "Root partitions dumped with tar" + options no-compress, index, exclude-list "/etc/amanda/exclude.gtar" + priority low +} + +define dumptype comp-user { + comment "Non-root partitions on reasonably fast machines" + options compress-fast + priority medium +} + +define dumptype nocomp-user { + comment "Non-root partitions on slow machines" + options no-compress + priority medium +} + +define dumptype holding-disk { + comment "The master-host holding disk itself" + options no-hold + priority medium +} + +define dumptype comp-root { + comment "Root partitions with compression" + options compress-fast + priority low +} + +define dumptype nocomp-root { + comment "Root partitions without compression" + options no-compress + priority low +} + +define dumptype comp-high { + comment "very important partitions on fast machines" + options compress-best + priority high +} + +define dumptype nocomp-high { + comment "very important partitions on slow machines" + options no-compress + priority high +} + +define dumptype nocomp-test { + comment "test dump without compression, no /etc/dumpdates recording" + options no-compress, no-record + priority medium +} + +define dumptype comp-test { + comment "test dump with compression, no /etc/dumpdates recording" + options compress-fast, no-record + priority medium +} + +define dumptype usr-tar { + root-tar + priority medium + comment "/usr tar" +} + +define dumptype boot-tar { + root-tar + priority medium + comment "/boot tar" +} + +define dumptype no-home-root-tar { + root-tar + comment "/ without home root tar" + priority high + exclude list "/etc/amanda/exclude-home" +} + +define dumptype user-tar-spec { + root-tar + comment "user tar with special exclusions" + priority high + exclude list "/etc/amanda/exclude-spec" +} + diff -urP amanda-2.4.2p2/DILOG/conf/debian-2.1-2.2.13-ncr53c8xx.OLD/changer.conf amanda-2.4.2p2-changed/DILOG/conf/debian-2.1-2.2.13-ncr53c8xx.OLD/changer.conf --- amanda-2.4.2p2/DILOG/conf/debian-2.1-2.2.13-ncr53c8xx.OLD/changer.conf Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/DILOG/conf/debian-2.1-2.2.13-ncr53c8xx.OLD/changer.conf Fri Feb 25 13:57:26 2000 @@ -0,0 +1,21 @@ +number_configs 1 +eject 0 # Tapedrives need an eject command +sleep 200 # Seconds to wait until the tape gets ready +cleanmax 15 # How many times could a cleaning tape get used +changerdev /dev/sg2 +# +# Next comes the data for drive 0 +# +config 0 +drivenum 0 +dev /dev/nst0 +scsitapedev /dev/sg1 +startuse 0 # The slots associated with the drive 0 +enduse 6 # +statfile /usr/local/amanda/var/lib/tape0-slot # The file where the actual slot is stored +cleancart 7 # the slot where the cleaningcartridge for drive 0 is located +cleanfile /usr/local/amanda/var/lib/tape0-clean # The file where the cleanings are recorded +usagecount /usr/local/amanda/var/lib/totaltime +tapestatus /usr/local/amanda/var/lib/tapestatus # here will some status infos be stored +#labelfile /usr/local/amanda/var/lib/labelfile # Use this if you have an barcode reader + diff -urP amanda-2.4.2p2/DILOG/conf/debian-2.1-2.2.13-ncr53c8xx.OLD/disklist amanda-2.4.2p2-changed/DILOG/conf/debian-2.1-2.2.13-ncr53c8xx.OLD/disklist --- amanda-2.4.2p2/DILOG/conf/debian-2.1-2.2.13-ncr53c8xx.OLD/disklist Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/DILOG/conf/debian-2.1-2.2.13-ncr53c8xx.OLD/disklist Fri Feb 25 13:57:26 2000 @@ -0,0 +1,11 @@ +#debian / no-home-root-tar +debian /home user-tar +debian /boot boot-tar + +defian /usr user-tar +defian /boot user-tar +defian /mfs/ROOT user-tar +defian /mfs/TEMP user-tar +defian / no-home-root-tar # also no usr +defian /home user-tar-spec # without schaefer/SOUNDS +###define /home/schaefer/SOUNDS user-tar diff -urP amanda-2.4.2p2/DILOG/conf/golid-2.0.27-aha1542.OLD/amanda.conf amanda-2.4.2p2-changed/DILOG/conf/golid-2.0.27-aha1542.OLD/amanda.conf --- amanda-2.4.2p2/DILOG/conf/golid-2.0.27-aha1542.OLD/amanda.conf Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/DILOG/conf/golid-2.0.27-aha1542.OLD/amanda.conf Fri Feb 25 13:58:26 2000 @@ -0,0 +1,361 @@ +# +# amanda.conf - sample Amanda configuration file. +# +# If your configuration is called, say, "DilogNewEngSet1", then this file +# normally goes in /etc/amanda/DilogNewEngSet1/amanda.conf. +# +# for explanation of the parameters refer to amanda(8) and +# /usr/doc/amanda/WHATS.NEW.gz + +org "DilogNewEngSet1" # your organization name for reports +mailto "amanda" # space separated list of operators at your site +dumpuser "amanda" # the user to run dumps under +# +inparallel 4 # maximum dumpers that will run in parallel +netusage 600 Kbps # maximum net bandwidth for Amanda, in KB per sec + +# a filesystem is due for a full backup once every <dumpcycle> days +dumpcycle 1 weeks # the number of days in the normal dump cycle +runspercycle 1 weeks # the number of amdump runs in dumpcycle days +tapecycle 6 tapes # the number of tapes in rotation + +bumpsize 100 MB # minimum savings (threshold) to bump level 1 -> 2 +bumpdays 1 # minimum days at each level +bumpmult 4 # threshold = bumpsize * (level-1)**bumpmult + +etimeout 2400 # number of seconds per filesystem for estimates. + +runtapes 1 # max number of tapes to be used in a single run +tpchanger "chg-scsi" # the tape-changer glue script, see TAPE.CHANGERS +tapedev "0" # changer configuration 0 +changerfile "/usr/local/amanda/etc/amanda/dne/changer.conf" + +tapetype SONY-DDS3-125m-nolabel # what kind of tape it is (see tapetypes below) +labelstr "^DilogNewEngSet[0-9][0-9]*$" # label constraint regex: all tapes must match + +holdingdisk hd1 { + comment "main holding disk" + directory "/scratch/amanda" # where the holding disk is + use -80 Mb # how much space can we use on it + # a negative value mean: + # use all space except that value + chunksize -1 # size of chunk if you want big dump to be + # dumped on multiple files on holding disks + # N Kb/Mb/Gb split disks in chunks of size N + # 0 split disks in INT_MAX/1024 Kb chunks + # -1 same as -INT_MAX/1024 (see below) + # -N Kb/Mb/Gb dont split, dump larger + # filesystems directly to tape + # (example: -2 Gb) + # chunksize 2 Gb + } +holdingdisk hd2 { + comment "secondary holding disk" + directory "/spare/amanda" + use -80 Mb + chunksize -1 + } + +# If amanda cannot find a tape on which to store backups, it will run +# as many backups as it can to the holding disks. In order to save +# space for unattended backups, by default, amanda will only perform +# incremental backups in this case, i.e., it will reserve 100% of the +# holding disk space for the so-called degraded mode backups. +# However, if you specify a different value for the `reserve' +# parameter, amanda will not degrade backups if they will fit in the +# non-reserved portion of the holding disk. + +# reserve 30 # percent + +# This means save at least 30% of the holding disk space for degraded +# mode backups. + +# Amanda needs a few MB of diskspace for the log and debug files, +# as well as a database. This stuff can grow large, so the conf directory +# isn't usually appropriate. We use /usr/adm. Create an amanda directory +# under there. You need a separate infofile and logfile for each +# configuration, so create subdirectories for each conf and put the files +# there. Specify the filenames below. + +infofile "/usr/local/amanda/var/lib/DilogNewEngSet1/curinfo" # database filename +logfile "/usr/local/amanda/var/log/DilogNewEngSet1/log" # log filename + +# where the index files live +indexdir "/usr/local/amanda/var/lib/DilogNewEngSet1/index" + +# where the append tape file is +currenttape "/usr/local/amanda/etc/amanda/dne/current-tape-for-append" + +appendmode 1 + +# tapetypes +# +# Define the type of tape you use here, and use it in "tapetype" above. +# Some typical types of tapes are included here. The tapetype tells amanda +# how many MB will fit on the tape, how big the filemarks are, and how +# fast the tape device is. +# +# For completeness Amanda should calculate the inter-record gaps too, but it +# doesn't. For EXABYTE and DAT tapes this is ok. Anyone using 9 tracks for +# amanda and need IRG calculations? Drop me a note if so. + +define tapetype QIC-60 { + comment "Archive Viper" + length 60 mbytes + filemark 100 kbytes # don't know a better value + speed 100 kbytes # dito +} + +define tapetype DEC-DLT2000 { + comment "DEC Differential Digital Linear Tape 2000" + length 15000 mbytes + filemark 8 kbytes + speed 1250 kbytes +} + +# goluboff@butch.Colorado.EDU +# in amanda-users (Thu Dec 26 01:55:38 MEZ 1996) +define tapetype DLT { + comment "DLT tape drives" + length 20000 mbytes # 20 Gig tapes + filemark 2000 kbytes # I don't know what this means + speed 1500 kbytes +} + +define tapetype SURESTORE-1200E { + comment "HP AutoLoader" + length 3900 mbytes + filemark 100 kbytes + speed 500 kbytes +} + +define tapetype EXB-8500 { + comment "Exabyte EXB-8500 drive on decent machine" + length 4200 mbytes + filemark 48 kbytes + speed 474 kbytes +} + +define tapetype EXB-8200 { + comment "Exabyte EXB-8200 drive on decent machine" + length 2200 mbytes + filemark 2130 kbytes + speed 240 kbytes +} + +define tapetype HP-DAT { + comment "DAT tape drives" + length 1900 mbytes # these numbers are not accurate + filemark 100 kbytes # but you get the idea + speed 500 kbytes +} + +define tapetype DAT { + comment "DAT tape drives" + length 1000 mbytes # these numbers are not accurate + filemark 100 kbytes # but you get the idea + speed 100 kbytes +} + +define tapetype MIMSY-MEGATAPE { + comment "Megatape (Exabyte based) drive through Emulex on Vax 8600" + length 2200 mbytes + filemark 2130 kbytes + speed 170 kbytes # limited by the Emulex bus interface, ugh +} + +define tapetype SONY-DDS2-60m-nolabel { + comment "DAT tape drives" + length 1350 mbytes + filemark 500 kbytes + speed 300 kbytes +} + +define tapetype SONY-DDS3-125m-nolabel { + comment "DAT tape drives" + length 12000 mbytes + filemark 500 kbytes + speed 1100 kbytes +} + +# dumptypes +# +# These are referred to by the disklist file. The dumptype specifies +# certain "options" for dumping including: +# index - keep an index of the files backed up +# compress-fast - (default) compress on the client using fast algorithm +# compress-best - compress using the best (and slowww) algorithm +# no-compress - don't compress the dump output +# srvcompress - Compress dumps on the tape host instead of client +# machines. This may be useful when a fast tape host +# is backing up slow clients. +# record - (default) record the dump in /etc/dumpdates +# no-record - don't record the dump, for testing +# no-hold - don't go to the holding disk, good for dumping +# the holding disk partition itself. +# skip-full - Skip the disk when a level 0 is due, to allow +# full backups outside Amanda, eg when the machine +# is in single-user mode. +# skip-incr - Skip the disk when the level 0 is NOT due. This +# is used in archive configurations, where only full +# dumps are done and the tapes saved. +# no-full - Do a level 1 every night. This can be used, for +# example, for small root filesystems that only change +# slightly relative to a site-wide prototype. Amanda +# then backs up just the changes. +# +# Also, the dumptype specifies the priority level, where "low", "medium" and +# "high" are the allowed levels. These are only really used when Amanda has +# no tape to write to because of some error. In that "degraded mode", as +# many incrementals as will fit on the holding disk are done, higher priority +# first, to insure the important disks are dumped first. + +define dumptype always-full { + comment "Full dump of this filesystem always" + options no-compress + priority high + dumpcycle 0 + maxcycle 0 +} + +define dumptype comp-user-tar { + program "GNUTAR" + comment "partitions dumped with tar" + options compress-fast, index, exclude-list "/etc/amanda/exclude.gtar" + priority medium +} + +define dumptype comp-root-tar { + program "GNUTAR" + comment "Root partitions with compression" + options compress-fast, index, exclude-list "/etc/amanda/exclude.gtar" + priority low +} + +define dumptype user-tar { + program "GNUTAR" + comment "partitions dumped with tar" + options no-compress, index, exclude-list "/etc/amanda/exclude.gtar" + priority high +} + +define dumptype high-tar { + program "GNUTAR" + comment "partitions dumped with tar" + options no-compress, index, exclude-list "/etc/amanda/exclude.gtar" + priority high +} + +define dumptype root-tar { + program "GNUTAR" + comment "Root partitions dumped with tar" + options no-compress, index, exclude-list "/etc/amanda/exclude.gtar" + priority low +} + +define dumptype comp-user { + comment "Non-root partitions on reasonably fast machines" + options compress-fast + priority medium +} + +define dumptype nocomp-user { + comment "Non-root partitions on slow machines" + options no-compress + priority medium +} + +define dumptype holding-disk { + comment "The master-host holding disk itself" + options no-hold + priority medium +} + +define dumptype comp-root { + comment "Root partitions with compression" + options compress-fast + priority low +} + +define dumptype nocomp-root { + comment "Root partitions without compression" + options no-compress + priority low +} + +define dumptype comp-high { + comment "very important partitions on fast machines" + options compress-best + priority high +} + +define dumptype nocomp-high { + comment "very important partitions on slow machines" + options no-compress + priority high +} + +define dumptype nocomp-test { + comment "test dump without compression, no /etc/dumpdates recording" + options no-compress, no-record + priority medium +} + +define dumptype comp-test { + comment "test dump with compression, no /etc/dumpdates recording" + options compress-fast, no-record + priority medium +} + +define dumptype usr-tar { + root-tar + priority medium + comment "/usr tar" +} + +define dumptype boot-tar { + root-tar + priority medium + comment "/boot tar" +} + +define dumptype user-tar-spec { + root-tar + comment "user tar with special exclusions" + priority high + exclude list "/etc/amanda/exclude-spec" +} + +define dumptype root-tar-spec { + root-tar + comment "user tar with special exclusions" + priority high + exclude list "/etc/amanda/exclude-root-spec" +} + +define dumptype user-tar-spec2 { + root-tar + comment "user tar with special exclusions 2" + priority high + exclude list "/etc/amanda/exclude-spec2" +} + +define dumptype user-tar-spec3 { + root-tar + comment "user tar with special exclusions 3" + priority high + exclude list "/etc/amanda/exclude-spec3" +} + +define dumptype user-smb-tar { + root-tar + comment "user partitions dumped with smbtar" + priority medium + exclude list "/etc/amanda/exclude-smb-tar" +} + +define dumptype user-smb-tar-no-incr { + user-smb-tar + skip-incr +} + diff -urP amanda-2.4.2p2/DILOG/conf/golid-2.0.27-aha1542.OLD/changer.conf amanda-2.4.2p2-changed/DILOG/conf/golid-2.0.27-aha1542.OLD/changer.conf --- amanda-2.4.2p2/DILOG/conf/golid-2.0.27-aha1542.OLD/changer.conf Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/DILOG/conf/golid-2.0.27-aha1542.OLD/changer.conf Fri Feb 25 13:58:26 2000 @@ -0,0 +1,21 @@ +number_configs 1 +eject 0 # Tapedrives need an eject command +sleep 200 # Seconds to wait until the tape gets ready +cleanmax 15 # How many times could a cleaning tape get used +changerdev /dev/sg2 +# +# Next comes the data for drive 0 +# +config 0 +drivenum 0 +dev /dev/nst0 +scsitapedev /dev/sg1 +startuse 0 # The slots associated with the drive 0 +enduse 6 # +statfile /usr/local/amanda/var/lib/tape0-slot # The file where the actual slot is stored +cleancart 7 # the slot where the cleaningcartridge for drive 0 is located +cleanfile /usr/local/amanda/var/lib/tape0-clean # The file where the cleanings are recorded +usagecount /usr/local/amanda/var/lib/totaltime +tapestatus /usr/local/amanda/var/lib/tapestatus # here will some status infos be stored +#labelfile /usr/local/amanda/var/lib/labelfile # Use this if you have an barcode reader + diff -urP amanda-2.4.2p2/DILOG/conf/golid-2.0.27-aha1542.OLD/disklist amanda-2.4.2p2-changed/DILOG/conf/golid-2.0.27-aha1542.OLD/disklist --- amanda-2.4.2p2/DILOG/conf/golid-2.0.27-aha1542.OLD/disklist Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/DILOG/conf/golid-2.0.27-aha1542.OLD/disklist Fri Feb 25 13:58:26 2000 @@ -0,0 +1,30 @@ +golid / root-tar-spec +golid /usr user-tar +golid /users user-tar +golid /usr/src user-tar +golid /scratch/world user-tar +golid /spare user-tar-spec + +# Some of those are symlinks. +sun1 / root-tar +sun1 /d2 user-tar +sun1 /usr user-tar + +pc5 / user-tar +pc5 /usr user-tar +pc5 /dos user-tar + +# SMB backups +#golid //paul/paul user-smb-tar + +# Incremental doesn't work on those because Patrick also backups them +# completely. +golid //alphie1/product user-smb-tar-no-incr +#golid //alphie1/sales user-smb-tar +golid //alphie1/dilog user-smb-tar-no-incr +#golid //alphie1/accounts user-smb-tar +#golid //alphie1/karin user-smb-tar + +debian / user-tar +debian /boot user-tar + diff -urP amanda-2.4.2p2/DILOG/conf/urbanet-2.2.x-debian-2.1/etc/amanda/uis/amanda.conf amanda-2.4.2p2-changed/DILOG/conf/urbanet-2.2.x-debian-2.1/etc/amanda/uis/amanda.conf --- amanda-2.4.2p2/DILOG/conf/urbanet-2.2.x-debian-2.1/etc/amanda/uis/amanda.conf Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/DILOG/conf/urbanet-2.2.x-debian-2.1/etc/amanda/uis/amanda.conf Fri Mar 10 15:52:16 2000 @@ -0,0 +1,359 @@ +# +# amanda.conf - sample Amanda configuration file. +# +# If your configuration is called, say, "UrbanetInternalSet1", then this file +# normally goes in /etc/amanda/UrbanetInternalSet1/amanda.conf. +# +# for explanation of the parameters refer to amanda(8) and +# /usr/doc/amanda/WHATS.NEW.gz + +org "UrbanetInternalSet1" # your organization name for reports +mailto "amanda" # space separated list of operators at your site +dumpuser "amanda" # the user to run dumps under +# +inparallel 4 # maximum dumpers that will run in parallel +netusage 600 # maximum net bandwidth for Amanda, in KB per sec + +# a filesystem is due for a full backup once every <dumpcycle> days +dumpcycle 4 weeks # the number of days in the normal dump cycle +runspercycle 28 # the number of amdump runs in dumpcycle days +tapecycle 14 tapes # the number of tapes in rotation + +bumpsize 100 MB # minimum savings (threshold) to bump level 1 -> 2 +bumpdays 1 # minimum days at each level +bumpmult 4 # threshold = bumpsize * (level-1)**bumpmult + +etimeout 2400 # number of seconds per filesystem for estimates. + +dtimeout 1800 # number of idle seconds before a dump is aborted. + +tapebufs 40 # Allocate 1.2 MB buffers for taper + +runtapes 2 # max number of tapes to be used in a single run +tpchanger "chg-scsi" # the tape-changer glue script, see TAPE.CHANGERS +tapedev "0" # changer configuration 0 +changerfile "/usr/local/amanda/etc/amanda/uis/changer.conf" + +tapetype SONY-DDS3-125m-nolabel # what kind of tape it is (see tapetypes below) +labelstr "^UrbanetInternalSet[0-9][0-9]*$" # label constraint regex: all tapes must match + +holdingdisk hd1 { + comment "main holding disk" + directory "/amanda/space" # where the holding disk is + use -80 Mb # how much space can we use on it + # a negative value mean: + # use all space except that value + #chunksize -1 # size of chunk if you want big dump to be + # dumped on multiple files on holding disks + # N Kb/Mb/Gb split disks in chunks of size N + # 0 split disks in INT_MAX/1024 Kb chunks + # -1 same as -INT_MAX/1024 (see below) + # -N Kb/Mb/Gb dont split, dump larger + # filesystems directly to tape + # (example: -2 Gb) + chunksize 2 Gb +} + +# If amanda cannot find a tape on which to store backups, it will run +# as many backups as it can to the holding disks. In order to save +# space for unattended backups, by default, amanda will only perform +# incremental backups in this case, i.e., it will reserve 100% of the +# holding disk space for the so-called degraded mode backups. +# However, if you specify a different value for the `reserve' +# parameter, amanda will not degrade backups if they will fit in the +# non-reserved portion of the holding disk. + +reserve 30 # percent + +# This means save at least 30% of the holding disk space for degraded +# mode backups. + +# Amanda needs a few MB of diskspace for the log and debug files, +# as well as a database. This stuff can grow large, so the conf directory +# isn't usually appropriate. We use /usr/adm. Create an amanda directory +# under there. You need a separate infofile and logfile for each +# configuration, so create subdirectories for each conf and put the files +# there. Specify the filenames below. + +infofile "/usr/local/amanda/var/lib/UrbanetInternalSet1/curinfo" # database filename +logfile "/usr/local/amanda/var/log/UrbanetInternalSet1/log" # log filename + +# where the index files live +indexdir "/usr/local/amanda/var/lib/UrbanetInternalSet1/index" + +# where the append tape file is +currenttape "/usr/local/amanda/etc/amanda/uis/current-tape-for-append" + +appendmode 1 + +# tapetypes +# +# Define the type of tape you use here, and use it in "tapetype" above. +# Some typical types of tapes are included here. The tapetype tells amanda +# how many MB will fit on the tape, how big the filemarks are, and how +# fast the tape device is. +# +# For completeness Amanda should calculate the inter-record gaps too, but it +# doesn't. For EXABYTE and DAT tapes this is ok. Anyone using 9 tracks for +# amanda and need IRG calculations? Drop me a note if so. + +define tapetype QIC-60 { + comment "Archive Viper" + length 60 mbytes + filemark 100 kbytes # don't know a better value + speed 100 kbytes # dito +} + +define tapetype DEC-DLT2000 { + comment "DEC Differential Digital Linear Tape 2000" + length 15000 mbytes + filemark 8 kbytes + speed 1250 kbytes +} + +# goluboff@butch.Colorado.EDU +# in amanda-users (Thu Dec 26 01:55:38 MEZ 1996) +define tapetype DLT { + comment "DLT tape drives" + length 20000 mbytes # 20 Gig tapes + filemark 2000 kbytes # I don't know what this means + speed 1500 kbytes +} + +define tapetype SURESTORE-1200E { + comment "HP AutoLoader" + length 3900 mbytes + filemark 100 kbytes + speed 500 kbytes +} + +define tapetype EXB-8500 { + comment "Exabyte EXB-8500 drive on decent machine" + length 4200 mbytes + filemark 48 kbytes + speed 474 kbytes +} + +define tapetype EXB-8200 { + comment "Exabyte EXB-8200 drive on decent machine" + length 2200 mbytes + filemark 2130 kbytes + speed 240 kbytes +} + +define tapetype HP-DAT { + comment "DAT tape drives" + length 1900 mbytes # these numbers are not accurate + filemark 100 kbytes # but you get the idea + speed 500 kbytes +} + +define tapetype DAT { + comment "DAT tape drives" + length 1000 mbytes # these numbers are not accurate + filemark 100 kbytes # but you get the idea + speed 100 kbytes +} + +define tapetype MIMSY-MEGATAPE { + comment "Megatape (Exabyte based) drive through Emulex on Vax 8600" + length 2200 mbytes + filemark 2130 kbytes + speed 170 kbytes # limited by the Emulex bus interface, ugh +} + +define tapetype SONY-DDS2-60m-nolabel { + comment "DAT tape drives" + length 1350 mbytes + filemark 500 kbytes + speed 300 kbytes +} + +define tapetype SONY-DDS3-125m-nolabel { + comment "DAT tape drives" + length 12000 mbytes + filemark 500 kbytes + speed 1100 kbytes +} + +# dumptypes +# +# These are referred to by the disklist file. The dumptype specifies +# certain "options" for dumping including: +# index - keep an index of the files backed up +# compress-fast - (default) compress on the client using fast algorithm +# compress-best - compress using the best (and slowww) algorithm +# no-compress - don't compress the dump output +# srvcompress - Compress dumps on the tape host instead of client +# machines. This may be useful when a fast tape host +# is backing up slow clients. +# record - (default) record the dump in /etc/dumpdates +# no-record - don't record the dump, for testing +# no-hold - don't go to the holding disk, good for dumping +# the holding disk partition itself. +# skip-full - Skip the disk when a level 0 is due, to allow +# full backups outside Amanda, eg when the machine +# is in single-user mode. +# skip-incr - Skip the disk when the level 0 is NOT due. This +# is used in archive configurations, where only full +# dumps are done and the tapes saved. +# no-full - Do a level 1 every night. This can be used, for +# example, for small root filesystems that only change +# slightly relative to a site-wide prototype. Amanda +# then backs up just the changes. +# +# Also, the dumptype specifies the priority level, where "low", "medium" and +# "high" are the allowed levels. These are only really used when Amanda has +# no tape to write to because of some error. In that "degraded mode", as +# many incrementals as will fit on the holding disk are done, higher priority +# first, to insure the important disks are dumped first. + +define dumptype always-full { + comment "Full dump of this filesystem always" + options no-compress + priority high + dumpcycle 0 + maxcycle 0 +} + +define dumptype comp-user-tar { + program "GNUTAR" + comment "partitions dumped with tar" + options compress-fast, index, exclude-list "/etc/amanda/exclude.gtar" + priority medium +} + +define dumptype comp-root-tar { + program "GNUTAR" + comment "Root partitions with compression" + options compress-fast, index, exclude-list "/etc/amanda/exclude.gtar" + priority low +} + +define dumptype user-tar { + program "GNUTAR" + comment "partitions dumped with tar" + options no-compress, index, exclude-list "/etc/amanda/exclude.gtar" + priority high +} + +define dumptype high-tar { + program "GNUTAR" + comment "partitions dumped with tar" + options no-compress, index, exclude-list "/etc/amanda/exclude.gtar" + priority high +} + +define dumptype root-tar { + program "GNUTAR" + comment "Root partitions dumped with tar" + options no-compress, index, exclude-list "/etc/amanda/exclude.gtar" + priority low +} + +define dumptype comp-user { + comment "Non-root partitions on reasonably fast machines" + options compress-fast + priority medium +} + +define dumptype nocomp-user { + comment "Non-root partitions on slow machines" + options no-compress + priority medium +} + +define dumptype holding-disk { + comment "The master-host holding disk itself" + options no-hold + priority medium +} + +define dumptype comp-root { + comment "Root partitions with compression" + options compress-fast + priority low +} + +define dumptype nocomp-root { + comment "Root partitions without compression" + options no-compress + priority low +} + +define dumptype comp-high { + comment "very important partitions on fast machines" + options compress-best + priority high +} + +define dumptype nocomp-high { + comment "very important partitions on slow machines" + options no-compress + priority high +} + +define dumptype nocomp-test { + comment "test dump without compression, no /etc/dumpdates recording" + options no-compress, no-record + priority medium +} + +define dumptype comp-test { + comment "test dump with compression, no /etc/dumpdates recording" + options compress-fast, no-record + priority medium +} + +define dumptype usr-tar { + root-tar + priority medium + comment "/usr tar" +} + +define dumptype boot-tar { + root-tar + priority medium + comment "/boot tar" +} + +define dumptype user-tar-spec { + root-tar + comment "user tar with special exclusions" + priority high + exclude list "/etc/amanda/exclude-spec" +} + +define dumptype root-tar-spec { + root-tar + comment "user tar with special exclusions" + priority high + exclude list "/etc/amanda/exclude-root-spec" +} + +define dumptype user-tar-spec2 { + root-tar + comment "user tar with special exclusions 2" + priority high + exclude list "/etc/amanda/exclude-spec2" +} + +define dumptype user-tar-spec3 { + root-tar + comment "user tar with special exclusions 3" + priority high + exclude list "/etc/amanda/exclude-spec3" +} + +define dumptype user-smb-tar { + root-tar + comment "user partitions dumped with smbtar" + priority medium + exclude list "/etc/amanda/exclude-smb-tar" +} + +define dumptype user-smb-tar-no-incr { + user-smb-tar + skip-incr +} + diff -urP amanda-2.4.2p2/DILOG/conf/urbanet-2.2.x-debian-2.1/etc/amanda/uis/changer.conf amanda-2.4.2p2-changed/DILOG/conf/urbanet-2.2.x-debian-2.1/etc/amanda/uis/changer.conf --- amanda-2.4.2p2/DILOG/conf/urbanet-2.2.x-debian-2.1/etc/amanda/uis/changer.conf Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/DILOG/conf/urbanet-2.2.x-debian-2.1/etc/amanda/uis/changer.conf Fri Mar 10 15:49:34 2000 @@ -0,0 +1,24 @@ +number_configs 1 +eject 0 # Tapedrives need an eject command +sleep 200 # Seconds to wait until the tape gets ready +cleanmax 15 # How many times could a cleaning tape get used +# Assuming a drive, a tape and a changer on the bus in that order. +#changerdev /dev/sg2 +changerdev /dev/sg3 +# +# Next comes the data for drive 0 +# +config 0 +drivenum 0 +dev /dev/nst0 +#scsitapedev /dev/sg1 +scsitapedev /dev/sg2 +startuse 0 # The slots associated with the drive 0 +enduse 6 # +statfile /usr/local/amanda/var/lib/tape0-slot # The file where the actual slot is stored +cleancart 7 # the slot where the cleaningcartridge for drive 0 is located +cleanfile /usr/local/amanda/var/lib/tape0-clean # The file where the cleanings are recorded +usagecount /usr/local/amanda/var/lib/totaltime +tapestatus /usr/local/amanda/var/lib/tapestatus # here will some status infos be stored +#labelfile /usr/local/amanda/var/lib/labelfile # Use this if you have an barcode reader + diff -urP amanda-2.4.2p2/DILOG/conf/urbanet-2.2.x-debian-2.1/etc/amanda/uis/disklist amanda-2.4.2p2-changed/DILOG/conf/urbanet-2.2.x-debian-2.1/etc/amanda/uis/disklist --- amanda-2.4.2p2/DILOG/conf/urbanet-2.2.x-debian-2.1/etc/amanda/uis/disklist Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/DILOG/conf/urbanet-2.2.x-debian-2.1/etc/amanda/uis/disklist Fri Mar 10 16:49:41 2000 @@ -0,0 +1,3 @@ +#debian / user-tar +#debian /boot user-tar +#debian /usr/local/amanda user-tar diff -urP amanda-2.4.2p2/DILOG/crontabs/crontab.example amanda-2.4.2p2-changed/DILOG/crontabs/crontab.example --- amanda-2.4.2p2/DILOG/crontabs/crontab.example Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/DILOG/crontabs/crontab.example Fri Mar 10 15:30:53 2000 @@ -0,0 +1,15 @@ +# Verifies that everything is fine only on week-day. Mail if any problem. +0 17 * * 1-5 /usr/local/amanda/sbin/amcheck -m uis + +# Backup +45 0 * * * /usr/local/amanda/sbin/amdump uis + +# Clean drive and display error statistics, once a week +# DRIVE MUST BE CLEANED EVERY 20 HOURS OF USAGE. If +# backuping 7 systems of 1 GB, this is 7 GB, and thus this +# is 2 hours/day. Every week is enough. +05 14 * * 1 /usr/local/amanda/scripts/clean_and_check_tape.sh uis /usr/local/amanda var/lib/tapestatus + +# On friday, print a summary of usage. It's probably a good time to +# move the tapes in a safe place with the printed information. +10 12 * * 5 /usr/local/amanda/scripts/summary.sh uis diff -urP amanda-2.4.2p2/Makefile.am amanda-2.4.2p2-changed/Makefile.am --- amanda-2.4.2p2/Makefile.am Tue Apr 3 21:55:19 2001 +++ amanda-2.4.2p2-changed/Makefile.am Fri Aug 3 07:59:26 2001 @@ -8,12 +8,13 @@ if WANT_CLIENT CLIENT_SUBDIRS = client-src +AMRIO_SUBDIRS += remote-io-src endif if WANT_TAPE TAPE_SUBDIRS = tape-src endif if WANT_SERVER -SERVER_SUBDIRS = server-src changer-src +SERVER_SUBDIRS = server-src changer-src scripts endif if WANT_RESTORE RESTORE_SUBDIRS += restore-src @@ -34,7 +35,8 @@ $(RESTORE_SUBDIRS) \ $(RECOVER_SUBDIRS) \ $(PLOT_SUBDIRS) \ - man docs example + $(AMRIO_SUBDIRS) \ + man docs example scripts pkgdata_DATA = \ COPYRIGHT \ Only in amanda-2.4.2p2: Makefile.in diff -urP amanda-2.4.2p2/changer-src/chg-scsi-chio.c amanda-2.4.2p2-changed/changer-src/chg-scsi-chio.c --- amanda-2.4.2p2/changer-src/chg-scsi-chio.c Tue Jun 13 00:57:32 2000 +++ amanda-2.4.2p2-changed/changer-src/chg-scsi-chio.c Fri Aug 3 08:59:42 2001 @@ -639,7 +639,7 @@ if(read_conffile(CONFFILE_NAME)) { fprintf(stderr, "%s: could not find config file \"%s\"", - changer_dev, conffile); + changer_dev, CONFFILE_NAME); exit(1); } diff -urP amanda-2.4.2p2/changer-src/patch-aha1542 amanda-2.4.2p2-changed/changer-src/patch-aha1542 --- amanda-2.4.2p2/changer-src/patch-aha1542 Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/changer-src/patch-aha1542 Mon Feb 21 13:45:49 2000 @@ -0,0 +1,105 @@ +--- chg-scsi.c Thu Sep 9 21:53:13 1999 ++++ chg-scsi.c Mon Feb 21 13:43:02 2000 +@@ -97,6 +97,8 @@ + extern int IEE; + extern int DTE; + ++static int My_Tape_Ready(char *tapedev, OpenFiles_T *pTapeDev, int wait); ++ + + /*----------------------------------------------------------------------------*/ + /* Some stuff for our own configurationfile */ +@@ -1108,7 +1110,7 @@ + } + + if (need_sleep) +- if (Tape_Ready(scsitapedevice, need_sleep) == -1) ++ if (My_Tape_Ready(tape_device, pTapeDev, need_sleep) == -1) + { + printf("tape not ready\n"); + endstatus = 2; +@@ -1176,7 +1178,7 @@ + put_current_slot(changer_file, slot_offset); + + if (need_sleep) +- if (Tape_Ready(scsitapedevice, need_sleep) == -1) ++ if (My_Tape_Ready(tape_device, pTapeDev, need_sleep) == -1) + { + printf("tape not ready\n"); + endstatus = 2; +@@ -1239,6 +1241,75 @@ + dbclose(); + return endstatus; + } ++ ++static int My_Tape_Ready(char *tapedev, OpenFiles_T *pTapeDev, int wait) { ++ /* closing can be ready because of the way Linux handles tape changes, ++ * which is BTW a good way. ++ */ ++ if (pTapeDev) { ++ if (pTapeDev->fd != -1) { ++ close(pTapeDev->fd); /* ignored */ ++ pTapeDev->fd = open(tapedev, O_RDONLY); ++ } ++ ++ if (pTapeDev->fd == -1) { ++ return -1; ++ } ++ } ++ ++ do { ++ int f; ++ ++ if (pTapeDev) { ++ if (pTapeDev->fd != -1) { ++ close(pTapeDev->fd); /* ignored */ ++ pTapeDev->fd = open(tapedev, O_RDONLY); ++ } ++ ++ if (pTapeDev->fd == -1) { ++ return -1; ++ } ++ } ++ ++ f = pTapeDev ? pTapeDev->fd : open(tapedev, O_RDONLY); ++ ++ if (f != -1) { ++ int res = -1; ++#include <sys/mtio.h> ++ struct mtop mt; ++ ++ /* BUGS ++ * - We need that here because it internally would ++ * sleep 30 seconds. We can't assume it and we can't ++ * count the time portably, so ... ++ */ ++ ++ mt.mt_op = MTREW; ++ mt.mt_count = 1; ++ ++ if (!ioctl(f, MTIOCTOP, &mt)) { ++ res = 0; ++ } ++ if (!pTapeDev) { ++ close(f); ++ } ++ ++ if (res == 0) { ++ return res; ++ } ++ } ++ sleep(5); ++ if (wait > 5) { ++ wait -= 5; ++ } ++ else { ++ wait = 0; ++ } ++ } while (wait); ++ ++ return -1; ++} ++ + /* + * Local variables: + * indent-tabs-mode: nil diff -urP amanda-2.4.2p2/client-src/sendbackup-gnutar.c amanda-2.4.2p2-changed/client-src/sendbackup-gnutar.c --- amanda-2.4.2p2/client-src/sendbackup-gnutar.c Thu Mar 15 03:17:36 2001 +++ amanda-2.4.2p2-changed/client-src/sendbackup-gnutar.c Fri Aug 3 08:14:55 2001 @@ -434,7 +434,6 @@ * dumps will think the file has changed. */ "--atime-preserve", #endif - "--sparse", "--ignore-failed-read", "--totals", efile ? "--exclude-from" : skip_argument, diff -urP amanda-2.4.2p2/client-src/sendsize.c amanda-2.4.2p2-changed/client-src/sendsize.c --- amanda-2.4.2p2/client-src/sendsize.c Thu Mar 15 03:17:37 2001 +++ amanda-2.4.2p2-changed/client-src/sendsize.c Fri Aug 3 08:15:04 2001 @@ -1211,7 +1211,6 @@ * dumps will think the file has changed. */ "--atime-preserve", #endif - "--sparse", "--ignore-failed-read", "--totals", efile ? "--exclude-from" : skip_argument, Only in amanda-2.4.2p2: configure diff -urP amanda-2.4.2p2/configure.in amanda-2.4.2p2-changed/configure.in --- amanda-2.4.2p2/configure.in Tue Apr 3 02:44:41 2001 +++ amanda-2.4.2p2-changed/configure.in Fri Aug 3 08:05:54 2001 @@ -255,6 +255,23 @@ ] ) +AC_ARG_WITH(amrio, + [ --without-amrio do not build amrio], + [ + case "$withval" in + y | ye | yes) + if ${NO_CLIENT_MODE-false}; then + AC_MSG_ERROR([*** --without-client and --with-amrio are incompatible]) + fi + NO_AMRIO_MODE=false;; + n | no) NO_AMRIO_MODE=true;; + *) + AC_MSG_ERROR([*** You must not supply an argument to --with-amrio option.]) + ;; + esac + ] +) + AC_ARG_WITH(index-server, [ --with-index-server=HOST default amanda index server [`uname -n`]], [ @@ -2500,6 +2517,7 @@ AM_CONDITIONAL(WANT_RESTORE, test x"$NO_RESTORE_MODE" != x"true") AM_CONDITIONAL(WANT_SERVER, test x"$NO_SERVER_MODE" != x"true") AM_CONDITIONAL(WANT_RECOVER, test x"$NO_RECOVER_MODE" != x"true" && test x"$NO_CLIENT_MODE" != x"true") +AM_CONDITIONAL(WANT_AMRIO, test x"$NO_AMRIO_MODE" != x"true" && test x"$NO_CLIENT_MODE" != x"true") AM_CONDITIONAL(WANT_TAPE, test x"$NO_SERVER_MODE" != x"true" || test x"$NO_RESTORE_MODE" != x"true") AM_CONDITIONAL(WANT_AMPLOT, test x"$NO_AMPLOT_MODE" != x"true") AM_CONDITIONAL(WANT_CHG_SCSI, test x"$NO_SCSI_CHANGER_MODE" != x"true") @@ -2539,11 +2557,17 @@ man/amrmtape.8 man/amtoc.8 \ man/amverify.8 man/Makefile \ man/amstatus.8 man/amreport.8 \ + man/amrio.8 man/amcompare.8 \ man/amgetconf.8 \ \ docs/Makefile \ \ recover-src/Makefile \ + \ + remote-io-src/Makefile \ + remote-io-src/amcompare \ + \ + scripts/Makefile \ \ restore-src/Makefile \ \ diff -urP amanda-2.4.2p2/docs/AMRESTORE amanda-2.4.2p2-changed/docs/AMRESTORE --- amanda-2.4.2p2/docs/AMRESTORE Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/docs/AMRESTORE Fri Aug 3 11:47:16 2001 @@ -0,0 +1,58 @@ +AUTHOR + Marc SCHAEFER <schaefer@dilog.ch> + +GOAL + Make so that amrestore (and thus amidxtaped and amrio) can restore + a specified file without needing to scan the whole tape, and with + the support of autochangers. + +DESCRIPTION + With this patch, new arguments are implemented for amrecover: + -T + -F + -N + They set three parameters, a tape label, a file number, and a config name. + The new amrestore, when these flags are specified will load + skip + to the right tape. This will use amtape to locate the requested tape, + then open the tape device, rewind, verify the label, skip to the + right file, send output to stdio, close the tape. This is notably + supported by amrio, when compiled with ENABLE_SMART_AMRESTORE + (see source). + +ASSUMPTIONS + +LICENSE + This patch is (C) Distributed Logic SA, released under the same license + as Amanda. This patch has no warranty and is provided as is. + +THANKS + To all the Amanda authors + +NOTES + - Using amtape means we will still remain a quite small standalone + utility, when -[TFN] are not used. + - We need to reverify the label after tape open since there is + a window from the return of amtape to the device opening. + +SERIOUS-BUGS + +BUGS + +TODO + - finish implementation + - test with amrio + +CHANGELOG + 15/02/2000 schaefer Started documentation. Modified manpage. + Started implementation. + 16/02/2000 schaefer Now three arguments. Finished implementation. + 15/03/2000 schaefer Documented the new amrestore options in + the manual. Fixed amidxtaped.c to + use the right device also when using special + options. + + + + + + diff -urP amanda-2.4.2p2/docs/AMRIO amanda-2.4.2p2-changed/docs/AMRIO --- amanda-2.4.2p2/docs/AMRIO Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/docs/AMRIO Sat Aug 4 14:37:40 2001 @@ -0,0 +1,67 @@ +AUTHOR + Marc SCHAEFER <schaefer@dilog.ch> + +GOAL + Allows a remote client to pipe the specified backup to a tar --compare + command, for example, without intermediate files. The command also + locates the right tape and file (quickly), through extensions to + the remote tape protocol/amrestore (only compiled in if + ENABLE_SMART_AMRESTORE is set). This is now also supported within + amrecover. + +DESCRIPTION + With this patch, a new command is implemented: amrio. This command + allows to search for a specified tape and file, and then pipe + the result to any command, including tar --compare. + +ASSUMPTIONS + +LICENSE + This patch is (C) Distributed Logic SA, released under the same license + as Amanda. This patch has no warranty and is provided as is. + +THANKS + To all the Amanda authors + +NOTES + +SERIOUS-BUGS + +BUGS + - If autochanger is manual, ENABLE_SMART_AMRESTORE will not work. + - If extracting from file, amrecover/amrio shouldn't do the + magic positionning tricks (or amrestore should be more intelligent). + Infact, we just need to ensure amtape is not used if tape label + starts with /, the file being 0. + - amrecover is less efficient (no file seeks) than amrio. + - amrio runs as root and will create debug in /tmp/amanda. This might + cause problems for the next normal Amanda run, or if the local machine + is also the server (running with backup UID). The symptom is amrio + (called e.g. by amcompare) failing. + Run chown backup.backup /tmp/backup to fix the problem. + +TODO + - Add checking on the header that it's the right label, file, etc. + - Check that with amrestore it works also with files in different files. + +CHANGELOG + 02/02/2000 schaefer Started implementation of new amrio client command + which can be used already now to verify the data + with tar --compare. + 14/02/2000 schaefer Added amrio.sh script to verify a level 0 backup + 15/02/2000 schaefer Removed unneeded debugging. + 16/02/2000 schaefer Fixed amrio.sh to require a leading / (makes + specifying of root fs easier). Now also passing + configname to amrestore. Modified the option names. + 21/02/2000 schaefer Integrated amrio to the Amanda Makefile. + 15/03/2000 schaefer Fixed Makefile.DIS (to be used if automake is not + available). Created manpage. Moved amrio.sh + to DILOG/scripts/verify_full.sh. Added support + configure.in. + 16/03/2000 schaefer Fixed configure.in (tested on potato), incorporated. + Manpage copying when installing. + 10/04/2000 schaefer Replaced verify_full.sh by amcompare, using autoconf + and in-text value replacements. + 12/04/2000 schaefer If !ENABLE_SMART_RESTORE, send 6 arguments like + before. Also fixed comments. Implemented + smart restoring in recover-src/extract_list.c. diff -urP amanda-2.4.2p2/docs/BUGS amanda-2.4.2p2-changed/docs/BUGS --- amanda-2.4.2p2/docs/BUGS Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/docs/BUGS Tue Mar 28 15:44:50 2000 @@ -0,0 +1,43 @@ +AUTHOR + Marc SCHAEFER <schaefer@dilog.ch> + +GOAL + Fix a few Amanda bugs. + +DESCRIPTION + With this patch, Amanda will have a few problems fixed. For the + list of fixed problems, look at the NOTES section. Note that + some Amanda bugs might be fixed by our other enhancements. The + known cases will be listed also in the NOTES section. This + is not the place for fixes for bugs introduced by our + patches. However, bugs fixed by other of our patches should + be referenced here. + +ASSUMPTIONS + +LICENSE + This patch is (C) Distributed Logic SA, released under the same license + as Amanda. This patch has no warranty and is provided as is. + +THANKS + To all the Amanda authors + +NOTES + - Fixes the server-src/amlabel.c amfree() which caused a SIGSEGV + - The missing of freeing of the sort array in server-src/find.c, + sort_find_result(), is fixed in TAPE_APPEND patch. + +SERIOUS-BUGS + +BUGS + +TODO + - document that our future amrecover positionning enhancement will fix + the out-of-order flush bug too. + +CHANGELOG + 15/03/2000 schaefer Created this file. Implemented amlabel fix. + 17/03/2000 schaefer Fixed changer-src/chg-scsi-chio.c, using a non + declared conffile variable. + 28/03/2000 schaefer sort_find_result() in server-src/find.c should really + free the array (fixed in TAPE_APPEND). \ No newline at end of file diff -urP amanda-2.4.2p2/docs/DILOG_DEBIAN_CHANGES amanda-2.4.2p2-changed/docs/DILOG_DEBIAN_CHANGES --- amanda-2.4.2p2/docs/DILOG_DEBIAN_CHANGES Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/docs/DILOG_DEBIAN_CHANGES Thu Jun 29 09:34:26 2000 @@ -0,0 +1,71 @@ +AUTHOR + Marc SCHAEFER <schaefer@dilog.ch> + +GOAL + Standard configuration for DILOG on Debian + +DESCRIPTION + This file contains generic installation instructions, including + tricks. + +ASSUMPTIONS + +LICENSE + This patch is (C) Distributed Logic SA, released under the same license + as Amanda. This patch has no warranty and is provided as is. + +THANKS + to all the Amanda authors + +NOTES + - For 2.2.x + Tekram: + - modified changer-src/scsi-linux.c, undef LINUX_CHG, this fixes the + tape not ready issue (and maybe check cond detection) + - Also you have to change the NORMAL_TIMEOUT in + /usr/src/linux/drivers/scsi/scsi_ioctl.c from (10 * HZ) to + (5 * 60 * HZ). + - For 2.0.x + AHA1542: + - apply patch changer-src/patch-aha1542, do not apply the above fix. + - chown amanda.amanda /dev/sg[12] (tape/changer, if disk @ 0) + - ./configure --prefix=/usr/local/amanda --with-user=amanda \ + --with-group=amanda + - (make; su -c 'make install') + - permission fix (/usr/local/amanda, amanda.amanda, 750) + - .amandahosts on server and clients + - inetd services on the server: + +amandaidx stream tcp nowait backup /usr/sbin/tcpd /usr/lib/amanda/amindexd +amidxtape stream tcp nowait backup /usr/sbin/tcpd /usr/lib/amanda/amidxtaped- on the clients + + - on all the clients (possibly the server, too) +amanda dgram udp wait backup /usr/sbin/tcpd /usr/lib/amanda/amandad + + - firewall rules on those ports (3 for server, 1 for client, UDP) + + - crontab: + 0 17 * * 1-5 /usr/local/amanda/sbin/amcheck -m uis + 45 0 * * 2-7 /usr/local/amanda/sbin/amdump uis + 10 12 * * 5 /usr/local/amanda/scripts/summary.sh uis + 05 14 * * * /usr/local/amanda/scripts/clean_and_check_tape.sh uis /usr/local/amanda var/lib/tapestatus + + - scripts see ../scripts + + - config examples see ../DILOG/conf + + - Note that if you want to dump fs bigger than 2 GB on Linux, + you need to set chunksize to 0 in amanda.conf + + +SERIOUS-BUGS + +BUGS + +TODO + +CHANGELOG + 25/02/2000 schaefer Created from the old DEBIAN_CHANGES file, imported + scripts and configurations. + 20/03/2000 schaefer Moved scripts; added comments. + 16/05/2000 schaefer Added option for list_tape.sh script to show + the actual tape location as seen by mt. + 29/06/2000 schaefer Added spec-1/2/3 and -no-tmp in dump-types. \ No newline at end of file diff -urP amanda-2.4.2p2/docs/SPARSE amanda-2.4.2p2-changed/docs/SPARSE --- amanda-2.4.2p2/docs/SPARSE Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/docs/SPARSE Wed Feb 2 13:54:09 2000 @@ -0,0 +1,33 @@ +AUTHOR + Marc SCHAEFER <schaefer@dilog.ch> + +GOAL + Make so that tar produces verifiable archives + +DESCRIPTION + With this patch, Amanda will not use the --sparse option to tar, + since it seems broken in all recent and old GNU tar releases, at + least on Linux, possibly on Solaris too. + +ASSUMPTIONS + +LICENSE + This patch is (C) Distributed Logic SA, released under the same license + as Amanda. This patch has no warranty and is provided as is. + +THANKS + To all the Amanda authors + +NOTES + - Removed --sparse option from sendsize and sendbackup since tar has + a bug. + +SERIOUS-BUGS + +BUGS + +TODO + +CHANGELOG + 02/02/2000 schaefer Removed --sparse options in the sendsize and sendbackup + files, since tar has a bug with these options. diff -urP amanda-2.4.2p2/docs/TAPE_APPEND amanda-2.4.2p2-changed/docs/TAPE_APPEND --- amanda-2.4.2p2/docs/TAPE_APPEND Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/docs/TAPE_APPEND Tue May 16 10:45:01 2000 @@ -0,0 +1,166 @@ +AUTHOR + Marc SCHAEFER <schaefer@dilog.ch> + +GOAL + Allow Amanda to append to a previous's day tape (recurses) + +DESCRIPTION + With this patch, Amanda will from now on append to the last used + tape, except if it cannot be found, or if the amadmin conf newtape + command was used. The currenttape file path must be specified in + amanda.conf, and the appendmode variable should not be set to 0 + (see examples/amanda.conf.in). The major change are: + - the addition of a current-tape-for-append file + - tape success log now done to a special tape.<LABEL> file (find no + longer parses all log files unless that file is not found). + +ASSUMPTIONS + - The end marker on tape needs to be removed, else common-src/fileheader.c + and restore-src/amrestore.c may be confused. The end marker will + be added at each Amanda backup end. + +LICENSE + This patch is (C) Distributed Logic SA, released under the same license + as Amanda. This patch has no warranty and is provided as is. + +THANKS + John R. Jackson <jrj@gandalf.cc.purdue.edu> + Many cleanup suggestions. + Jean-Louis Martineau <martinea@IRO.UMontreal.CA> + Discovered why amadmin conf find doesn't work, and proposed a + solution. + (and to all the Amanda authors). + +NOTES + - We change server-src/taper.c to NOT write a label nor modify tapelist + if can_append(tape) is TRUE. Additionnally, allows a !reusable_tape(tape) + to be appended to. That function seems to only be used inside taper.c + (by first_tape() and next_tape(), although not declared static. + Remember: rolling and labelling is done the first time only, not when + appending. It is done again when the tape is *reused* (labelled). + The handler for the new data structures is the child (the taper + writer). + - Implemented can_append(tape) in tapefile.c. + A tape can be appened if it is top of tapelist, and is in the + current_tape file. If a discrepancy occurs, the current_tape file is + removed. + - Defined functions current_tape_information_{create|update|erase|read}() + and implemented in tapefile.[ch] + - We keep the tape in the list as already used (this ensures the + best compatibility) but we have a special file curr_tape, + where we store + label of the tape [name label] + file number where to add [name written_files] + blocks used on tape [name written_blocks] + last time of use (initial is on tape label) [name last_used] + - In theory there should be no other problem since e.g. when amflush + runs it can dump multiple-day backups. + - Added new command amadmin newtape to not append. + - Modified amcheck.c and amtape.c so that the taper scan algorithm + supports appending. + - Added new currenttape amanda.conf configuration, which allows to set + the name/location of the currenttape file. Defaults to + current-tape-for-append. + - Added append {yes|no}, default no to the dumptype. + - server-src/taper.c adds log entries to tape.<LABEL>. Relabelling the tape + deletes the file. + - Modified server-src/find.c to use the new tape.<LABEL> log (needed + since previous version expected one tape per log file). + - Modified taper.c so that it uses a normal filemark skip command + but doesn't write a filemark on the first file when appending. + THIS NEEDS VERY GOOD TESTING (since it introduces many possibilities + of problems compared to our previous version). We had to do that since + only Linux supports a position before filemark command apparently. + Using EOM wouldn't work (cannot have more than one TAPEEND, see + ASSUMPTIONS above). + - Modified find.c so that it goes back to the old log parsing if a + tape.<LABEL> doesn't exist (with a warning). This assumes that no + tape was appended after it was already used with all data valid. + This will be the case (except if the user creates the + current-tape-for-append file manually). + - Removed the possibility to specify append mode from dumptype to + dumptype: it was not implemented and was not really easy (needed + to e.g. reorder dumps, etc). Instead, added a global appendmode + enable/disable toggle, and added it to documentation, which is + now used. + +SERIOUS-BUGS + +BUGS + - At this time, the planner doesn't use the current tape information, + and thus believes it has a full tape for the I/O. If this is fixed, + there is the risk that the remaining room be under-estimated if + the append tape cannot be found at taper time. + - written_blocks in current-tape-for-append file is right now, + but percentage computation wasn't updated. However size of + written data is right. + - The tape.<LABEL> file is never deleted except if the tape is + re-written (reused, not appended). If the tape is lost, maybe + we should delete the file. + - Doesn't work with HAVE_LIBVTBLC nor with HAVE_LINUX_ZFTAPE_H. + At all. + - Should really ensure that the tape writable test is NEVER done + on an appendable tape. + - Had to do a lot of similar fixes in taper.c, amtape.c and + amcheck.c. Those functions should really be merged by the Amanda team. + - The label on tape will reflect the date the tape was initially + written (however the respective files will have the right dates), + including the unique TAPEEND marker. + - current_tape_information structure is never freed (?). + - amrio/amrestore. if still rewinding, quickly ends with no error. + Should only say success if gets GOOD from other side + check. + +TODO + - use agets() instead of fgets(), after investigation that when + using USE_DBMALLOC this doesn't break the writing. + - use common-src/token.c for the current tape file parsing instead of + ad hoc manual handling. + - the tape log should have all events, not just the one we need. + - see if there is not a double-work between amrio and amrecover. + - maybe a selfcheck could be implemented: after append finishes, + verify the tape TOC compared to database (ie to see if previous + file headers are there). Also document that user should compare + the last before file manually if doubts. + - Add conditions based on initial time of use, bytes used, + number of files to not do the append (e.g. don't do it + if more than 2 days used). Should be configurable, too. + - Maybe the append/not append config could be in the tape type ? + +CHANGELOG + 26/01/2000 schaefer Released patch set. + 27/01/2000 schaefer Changed the licensing information. + 02/02/2000 schaefer Now using standard tape move (and we don't do a + filemark at first append I/O anymore). + Now going back to parsing log files in find.c if + a tape label file was not found. + Added more documentation. + Added global appendmode enable/disable. + Fixed texts (new/append) depending on global enable. + 04/02/2000 schaefer Fixed append bug (would destroy the last backup), + bug introduced by the use of standard tape moves. + 18/02/2000 schaefer taper: moving message was there twice. Updated + AHA1542 patch. Fixed bug which would not append + if a new tape was listed in the tapelist (e.g. + just after label). This involved modifying + server-src/tapefile.c's lookup_last_reusable_tape(); + 21/02/2000 schaefer taper: fixed a possibly dangerous window between + two uses of can_append() in label. + Also now using correct total_tape_used in taper, so + that summary is right. + 22/02/2000 schaefer taper: don't fail on a new tape if can't append. + 01/03/2000 schaefer taper: now implemented the label verification just + after we open the device for good, this ensures + better data safety. + 02/03/2000 schaefer fixed typo. + 28/03/2000 schaefer Now destroying the current tape file + during writes. Removed the update() function + too, and simplified taper.c. Should ensure a stable + state even if a fatal error (e.g. reboot) occurs. + filenum now only incremented if not the first + file while in append. Implemented unique sorting + in sort_find_result(). Added freeing of the list + used for sorting. + 15/05/2000 schaefer Fixed off-by-one `amanda des tape' error. + 16/05/2000 schaefer Fixed amadmin conf info/find discrepancy which was + created by an empty schedule and one too many + filemark because of end label. \ No newline at end of file diff -urP amanda-2.4.2p2/example/amanda.conf.chg-scsi.in amanda-2.4.2p2-changed/example/amanda.conf.chg-scsi.in --- amanda-2.4.2p2/example/amanda.conf.chg-scsi.in Tue Jun 13 00:58:12 2000 +++ amanda-2.4.2p2-changed/example/amanda.conf.chg-scsi.in Fri Aug 3 08:16:56 2001 @@ -159,6 +159,12 @@ #tapelist "/usr/adm/amanda/@DEFAULT_CONFIG@/tapelist" # list of used tapes # tapelist is stored, by default, in the directory that contains amanda.conf +# This is used to remember which tape can be appended to. It is +# mandatory to specify the full path. +currenttape "/usr/adm/amanda/@DEFAULT_CONFIG@/current-tape-for-append" + +# Enable or disable append mode, defaults to enabled. +appendmode 1 # tapetypes diff -urP amanda-2.4.2p2/man/Makefile.am amanda-2.4.2p2-changed/man/Makefile.am --- amanda-2.4.2p2/man/Makefile.am Mon Nov 20 21:17:15 2000 +++ amanda-2.4.2p2-changed/man/Makefile.am Fri Aug 3 08:18:10 2001 @@ -34,6 +34,10 @@ RESTORE_MAN_PAGES = amrestore.8 endif +if WANT_CLIENT +AMRIO_MAN_PAGES = amrio.8 amcompare.8 +endif + # not autoconf-generated: EXTRA_DIST = amplot.8 amrestore.8 amtape.8 @@ -41,6 +45,7 @@ $(COMMON_MAN_PAGES) \ $(SERVER_MAN_PAGES) \ $(RECOVER_MAN_PAGES) \ + $(AMRIO_MAN_PAGES) \ $(RESTORE_MAN_PAGES) install-data-hook: diff -urP amanda-2.4.2p2/man/amadmin.8.in amanda-2.4.2p2-changed/man/amadmin.8.in --- amanda-2.4.2p2/man/amadmin.8.in Sat Nov 18 00:41:01 2000 +++ amanda-2.4.2p2-changed/man/amadmin.8.in Fri Aug 3 08:20:06 2001 @@ -115,6 +115,17 @@ .B force command. .TP +.P1 newtape +Tells Amanda to start with a new tape on the next run. This simply +deletes the file +.B current_tape-for-append +in the configuration directory. This is only useful if append mode was +enabled in the configuration file. Note that the only reason to do +this is if e.g. you think that that tape was already too much used, +or won't be enough for the next dump. +If the tape arrives at end or has an error, the file will be retried +on the next tape anyway as usual. +.TP .P3 reuse tapelabel [ ... ] The tapes listed will be available for reuse at their point in the tape cycle. diff -urP amanda-2.4.2p2/man/amcompare.8.in amanda-2.4.2p2-changed/man/amcompare.8.in --- amanda-2.4.2p2/man/amcompare.8.in Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/man/amcompare.8.in Mon Apr 10 10:54:32 2000 @@ -0,0 +1,47 @@ +.\" +.de EX +.if t .ft C +.nf +.. +.de EE +.fi +.if t .ft +.. +.TH AMCOMPARE 8 +.SH NAME +amcompare \- compare level 0 backup with data on disk +.SH SYNOPSIS +.B amcompare +.B config +.B computer +.B fs +.B server +[ +.B date +] +.SH DESCRIPTION +.B amcompare + +lists all the file on the local specified filesystem and compares it +with the backuped files list (e.g. if there are any files missing on +tape). It also runs a tar --compare, which will spot any differences +from the files on disk with the files on tape. It is done by using +temporary files in the Amanda temporary files, and there should be +enough space there. + +You can only run it from the client host. This uses amrio. The date +is optionnal. It must be specified in YYYY-MM-DD format. Only +works for level 0 +.B tar +dumps. + +.SH EXAMPLE +.EX +amcompare des sun1 / debian +.SH AUTHOR +Marc SCHAEFER <schaefer@dilog.ch> +.br +Distributed Logic SA +.SH "SEE ALSO" +amanda(8), +amrio(8) diff -urP amanda-2.4.2p2/man/amrestore.8 amanda-2.4.2p2-changed/man/amrestore.8 --- amanda-2.4.2p2/man/amrestore.8 Sun Dec 3 21:39:59 2000 +++ amanda-2.4.2p2-changed/man/amrestore.8 Fri Aug 3 11:46:55 2001 @@ -25,6 +25,14 @@ [ .B \-h ] +[ +.B \-T +label +.B \-F +filenum +.B \-N +config +] .I tapedevice | .I holdingfile @@ -194,6 +202,23 @@ may also be used to compress the result. .B Amrecover uses the header to determine the restore program to use. +.TP +.B -T +Label search. +The specified tape label is searched with +.B amtape +.TP +.B -F +Fast file search. +amrestore seeks to the specified file number in an efficient manner. +.TP +.B -N +Configuration. ++The specified configuration is used (required by the +.B -T +and +.B -F +options). .SH EXAMPLES The following does an interactive restore of disk .I rz3g diff -urP amanda-2.4.2p2/man/amrio.8.in amanda-2.4.2p2-changed/man/amrio.8.in --- amanda-2.4.2p2/man/amrio.8.in Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/man/amrio.8.in Mon Apr 10 10:52:31 2000 @@ -0,0 +1,82 @@ +.\" +.de EX +.if t .ft C +.nf +.. +.de EE +.fi +.if t .ft +.. +.TH AMRIO 8 +.SH NAME +amrio \- restores an Amanda backup to stdout +.SH SYNOPSIS +.B amrio +[ +.B [\-C] +config +] +[ +.B [\-s] +index-server +] +[ +.B [\-t] +tape-server +] +[ +.B \-d +tape-device +] +[ +.B \-D +dump-date +] +.B \-H +host +.B \-F +disk +.B \-L +level +.SH DESCRIPTION +.B amrio +extracts files from the tape mounted on +.I tapedevice +that match +.IR hostname , +.I diskname +and +.I datestamp +patterns given on the command line. +The tape must be in a format written by the +.B amdump +or +.B amflush +program. +.LP +amrio will automatically determine the tape label, tape file and tell +a remote +.B amidxtaped +(and of course +.B amrestore +) to retrieve the specified file quickly, using a tape changer device, +if appropriate, and fast medium seek commands to position to the right file. +The data will then, including header, be piped to stdout. + +Make sure you specify the no-rewind +.I tapedevice +. + +.SH EXAMPLES +See the amcompare shell script which verifies a tar +backup. +.SH AUTHOR +Marc SCHAEFER <schaefer@dilog.ch> +.br +Distributed Logic SA +.SH "SEE ALSO" +amanda(8), +amdump(8), +amflush(8), +restore(8), +amcompare(8) diff -urP amanda-2.4.2p2/recover-src/extract_list.c amanda-2.4.2p2-changed/recover-src/extract_list.c --- amanda-2.4.2p2/recover-src/extract_list.c Wed Mar 21 21:55:23 2001 +++ amanda-2.4.2p2-changed/recover-src/extract_list.c Fri Aug 3 11:49:13 2001 @@ -29,6 +29,10 @@ * implements the "extract" command in amrecover */ +#define ENABLE_SMART_AMRESTORE /* tape file option for quick & smart + * amrestore. + */ + #include "amanda.h" #include "version.h" #include "amrecover.h" @@ -1027,7 +1031,11 @@ /* start up connection to tape server and set commands to initiate transfer of dump image. Return tape server socket on success, -1 on error. */ +#ifdef ENABLE_SMART_AMRESTORE +static int extract_files_setup P((const char *the_tape, int the_file)) +#else /* !ENABLE_SMART_AMRESTORE */ static int extract_files_setup P((void)) +#endif /* !ENABLE_SMART_AMRESTORE */ { struct servent *sp; int my_port; @@ -1036,6 +1044,19 @@ char *service_name = NULL; char *line = NULL; char *clean_datestamp, *ch, *ch1; +#ifdef ENABLE_SMART_AMRESTORE + char string_the_file[20]; /* should be enough, checked below anyway */ + + ap_snprintf(string_the_file, sizeof(string_the_file), "%d", the_file); +#endif /* ENABLE_SMART_AMRESTORE */ + +#ifdef ENABLE_SMART_AMRESTORE + fprintf(stderr, + "extract_file_setup(): will request tape %s file %d.\n", + the_tape, + the_file); + fflush(stderr); +#endif /* ENABLE_SMART_AMRESTORE */ service_name = stralloc2("amidxtape", SERVICE_SUFFIX); @@ -1116,6 +1137,34 @@ } *ch = '\0'; /* send to the tape server what tape file we want */ + +#ifdef ENABLE_SMART_AMRESTORE + /* 12 args: + * "-T" + * "tape_label" + * "-F" + * "tape file number" + * "-N" + * "config name" + * "-h" + * "-p" + * "tape device" + * "hostname" + * "diskname" + * "datestamp" + * BUGS + * - level is ignored. + */ + send_to_tape_server(tape_server_socket, "12"); + send_to_tape_server(tape_server_socket, "-T"); + send_to_tape_server(tape_server_socket, the_tape); + + send_to_tape_server(tape_server_socket, "-F"); + send_to_tape_server(tape_server_socket, string_the_file); + + send_to_tape_server(tape_server_socket, "-N"); + send_to_tape_server(tape_server_socket, config); +#else /* !ENABLE_SMART_AMRESTORE */ /* 6 args: * "-h" * "-p" @@ -1125,6 +1174,7 @@ * "datestamp" */ send_to_tape_server(tape_server_socket, "6"); +#endif /* !ENABLE_SMART_AMRESTORE */ send_to_tape_server(tape_server_socket, "-h"); send_to_tape_server(tape_server_socket, "-p"); send_to_tape_server(tape_server_socket, dump_device_name); @@ -1523,14 +1573,25 @@ } else { dump_device_name = newstralloc(dump_device_name, tape_device_name); +#ifndef ENABLE_SMART_AMRESTORE printf("Load tape %s now\n", elist->tape); if (!okay_to_continue()) return; +#endif /* !ENABLE_SMART_AMRESTORE */ } dump_datestamp = newstralloc(dump_datestamp, elist->date); /* connect to the tape handler daemon on the tape drive server */ +#ifdef ENABLE_SMART_AMRESTORE + /* We must use 0 as file number, it will be less efficient than + * amrio, but it's not that bad either. Ideas: use amrio once + * the file name/level are known ? + */ + if ((tape_server_socket = extract_files_setup(elist->tape, + 0)) == -1) +#else /* !ENABLE_SMART_AMRESTORE */ if ((tape_server_socket = extract_files_setup()) == -1) +#endif /* !ENABLE_SMART_AMRESTORE */ { fprintf(stderr, "amrecover - can't talk to tape server\n"); return; diff -urP amanda-2.4.2p2/remote-io-src/Makefile.DIS amanda-2.4.2p2-changed/remote-io-src/Makefile.DIS --- amanda-2.4.2p2/remote-io-src/Makefile.DIS Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/remote-io-src/Makefile.DIS Wed Mar 15 15:13:12 2000 @@ -0,0 +1,7 @@ +all: amrio + +amrio: amrio.c amrio.h Makefile.DIS + gcc -DHAVE_CONFIG_H -I. -I../config -I../common-src -I../client-src -I../tape-src -g -O2 amrio.c -o amrio -lfl ../client-src/.libs/libamclient.a -lm -lnsl ../tape-src/.libs/libamtape.a ../common-src/.libs/libamanda.a + +clean: + rm amrio diff -urP amanda-2.4.2p2/remote-io-src/Makefile.am amanda-2.4.2p2-changed/remote-io-src/Makefile.am --- amanda-2.4.2p2/remote-io-src/Makefile.am Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/remote-io-src/Makefile.am Mon Apr 10 10:43:21 2000 @@ -0,0 +1,40 @@ +# Makefile for Amanda remote I/O program + +INCLUDES = -I$(top_srcdir)/common-src -I$(top_srcdir)/client-src \ + -I$(top_srcdir)/tape-src + +if WANT_LIBTOOL +LIB_EXTENSION = la +else +LIB_EXTENSION = a +endif + +sbin_PROGRAMS = amrio + +sbin_SCRIPTS = amcompare + +LDADD = @LEXLIB@ \ + ../client-src/libamclient.$(LIB_EXTENSION) \ + ../tape-src/libamtape.$(LIB_EXTENSION) \ + ../common-src/libamanda.$(LIB_EXTENSION) + +amrio_SOURCES = amrio.c + +noinst_HEADERS = amrio.h + +YFLAGS = -d + +install-exec-hook: + @list="$(sbin_PROGRAMS)"; \ + for p in $$list; do \ + pa=$(DESTDIR)$(sbindir)/`echo $$p|sed '$(transform)'`; \ + echo chown $(BINARY_OWNER) $$pa; \ + chown $(BINARY_OWNER) $$pa; \ + echo chgrp $(SETUID_GROUP) $$pa; \ + chgrp $(SETUID_GROUP) $$pa; \ + echo chmod o-rwx $$pa; \ + chmod o-rwx $$pa; \ + done + +amcompare: + chmod a+x $@ diff -urP amanda-2.4.2p2/remote-io-src/Makefile.in amanda-2.4.2p2-changed/remote-io-src/Makefile.in --- amanda-2.4.2p2/remote-io-src/Makefile.in Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/remote-io-src/Makefile.in Mon Apr 10 11:19:42 2000 @@ -0,0 +1,477 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# Makefile for Amanda remote I/O program + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AMANDA_DBGDIR = @AMANDA_DBGDIR@ +AMANDA_TMPDIR = @AMANDA_TMPDIR@ +AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@ +AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@ +AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@ +AMPLOT_COMPRESS = @AMPLOT_COMPRESS@ +AR = @AR@ +AS = @AS@ +AWK = @AWK@ +AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@ +BINARY_OWNER = @BINARY_OWNER@ +CAT = @CAT@ +CC = @CC@ +CHIO = @CHIO@ +CHS = @CHS@ +CLIENT_LOGIN = @CLIENT_LOGIN@ +CLIENT_SCRIPTS_OPT = @CLIENT_SCRIPTS_OPT@ +COMPRESS = @COMPRESS@ +CONFIG_DIR = @CONFIG_DIR@ +DB_EXT = @DB_EXT@ +DD = @DD@ +DEFAULT_CHANGER_DEVICE = @DEFAULT_CHANGER_DEVICE@ +DEFAULT_CONFIG = @DEFAULT_CONFIG@ +DEFAULT_RAW_TAPE_DEVICE = @DEFAULT_RAW_TAPE_DEVICE@ +DEFAULT_SERVER = @DEFAULT_SERVER@ +DEFAULT_TAPE_DEVICE = @DEFAULT_TAPE_DEVICE@ +DEFAULT_TAPE_SERVER = @DEFAULT_TAPE_SERVER@ +DLLTOOL = @DLLTOOL@ +DUMP = @DUMP@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GETCONF = @GETCONF@ +GNUPLOT = @GNUPLOT@ +GNUTAR = @GNUTAR@ +GREP = @GREP@ +GZIP = @GZIP@ +LD = @LD@ +LEX = @LEX@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +LN_S = @LN_S@ +LTALLOCA = @LTALLOCA@ +LTLIBOBJS = @LTLIBOBJS@ +MAILER = @MAILER@ +MAKEINFO = @MAKEINFO@ +MT = @MT@ +MTX = @MTX@ +MT_FILE_FLAG = @MT_FILE_FLAG@ +NM = @NM@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PCAT = @PCAT@ +PERL = @PERL@ +PRINT = @PRINT@ +RANLIB = @RANLIB@ +RESTORE = @RESTORE@ +SAMBA_CLIENT = @SAMBA_CLIENT@ +SERVICE_SUFFIX = @SERVICE_SUFFIX@ +SETUID_GROUP = @SETUID_GROUP@ +SHELL = @SHELL@ +SNAPSHOT_STAMP = @SNAPSHOT_STAMP@ +USE_VERSION_SUFFIXES = @USE_VERSION_SUFFIXES@ +VDUMP = @VDUMP@ +VERSION = @VERSION@ +VERSION_COMMENT = @VERSION_COMMENT@ +VERSION_MAJOR = @VERSION_MAJOR@ +VERSION_MINOR = @VERSION_MINOR@ +VERSION_PATCH = @VERSION_PATCH@ +VERSION_SUFFIX = @VERSION_SUFFIX@ +VRESTORE = @VRESTORE@ +VXDUMP = @VXDUMP@ +VXRESTORE = @VXRESTORE@ +XFSDUMP = @XFSDUMP@ +XFSRESTORE = @XFSRESTORE@ +YACC = @YACC@ +ac_c = @ac_c@ +ac_n = @ac_n@ + +INCLUDES = -I$(top_srcdir)/common-src -I$(top_srcdir)/client-src -I$(top_srcdir)/tape-src + +@WANT_LIBTOOL_TRUE@LIB_EXTENSION = la +@WANT_LIBTOOL_FALSE@LIB_EXTENSION = a + +sbin_PROGRAMS = amrio + +sbin_SCRIPTS = amcompare + +LDADD = @LEXLIB@ ../client-src/libamclient.$(LIB_EXTENSION) ../tape-src/libamtape.$(LIB_EXTENSION) ../common-src/libamanda.$(LIB_EXTENSION) + + +amrio_SOURCES = amrio.c + +noinst_HEADERS = amrio.h + +YFLAGS = -d +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = ../config/config.h +CONFIG_CLEAN_FILES = +sbin_PROGRAMS = amrio$(EXEEXT) +PROGRAMS = $(sbin_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I../config +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +amrio_OBJECTS = amrio.$(OBJEXT) +amrio_LDADD = $(LDADD) +amrio_DEPENDENCIES = ../client-src/libamclient.$(LIB_EXTENSION) \ +../tape-src/libamtape.$(LIB_EXTENSION) \ +../common-src/libamanda.$(LIB_EXTENSION) +amrio_LDFLAGS = +SCRIPTS = $(sbin_SCRIPTS) + +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +HEADERS = $(noinst_HEADERS) + +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +DEP_FILES = .deps/amrio.P +SOURCES = $(amrio_SOURCES) +OBJECTS = $(amrio_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .obj .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu remote-io-src/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-sbinPROGRAMS: + +clean-sbinPROGRAMS: + -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) + +distclean-sbinPROGRAMS: + +maintainer-clean-sbinPROGRAMS: + +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(sbindir) + @list='$(sbin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(sbin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +# FIXME: We should only use cygpath when building on Windows, +# and only if it is available. +.c.obj: + $(COMPILE) -c `cygpath -w $<` + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + -rm -f *.$(OBJEXT) + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +amrio$(EXEEXT): $(amrio_OBJECTS) $(amrio_DEPENDENCIES) + @rm -f amrio$(EXEEXT) + $(LINK) $(amrio_LDFLAGS) $(amrio_OBJECTS) $(amrio_LDADD) $(LIBS) + +install-sbinSCRIPTS: $(sbin_SCRIPTS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(sbindir) + @list='$(sbin_SCRIPTS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed '$(transform)'`; \ + else if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(sbindir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(sbindir)/`echo $$p|sed '$(transform)'`; \ + else :; fi; fi; \ + done + +uninstall-sbinSCRIPTS: + @$(NORMAL_UNINSTALL) + list='$(sbin_SCRIPTS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed '$(transform)'`; \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = remote-io-src + +distdir: $(DISTFILES) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(top_distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu remote-io-src/Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) + +-include $(DEP_FILES) + +mostlyclean-depend: + +clean-depend: + +distclean-depend: + -rm -rf .deps + +maintainer-clean-depend: + +%.o: %.c + @echo '$(COMPILE) -c $<'; \ + $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.c + @echo '$(LTCOMPILE) -c $<'; \ + $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-sbinPROGRAMS install-sbinSCRIPTS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-sbinPROGRAMS uninstall-sbinSCRIPTS +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(HEADERS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(sbindir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-sbinPROGRAMS mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags mostlyclean-depend \ + mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-sbinPROGRAMS clean-compile clean-libtool clean-tags \ + clean-depend clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-sbinPROGRAMS distclean-compile \ + distclean-libtool distclean-tags distclean-depend \ + distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-sbinPROGRAMS \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-depend \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-sbinPROGRAMS distclean-sbinPROGRAMS \ +clean-sbinPROGRAMS maintainer-clean-sbinPROGRAMS uninstall-sbinPROGRAMS \ +install-sbinPROGRAMS mostlyclean-compile distclean-compile \ +clean-compile maintainer-clean-compile mostlyclean-libtool \ +distclean-libtool clean-libtool maintainer-clean-libtool \ +uninstall-sbinSCRIPTS install-sbinSCRIPTS tags mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir \ +mostlyclean-depend distclean-depend clean-depend \ +maintainer-clean-depend info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +install-exec-hook: + @list="$(sbin_PROGRAMS)"; \ + for p in $$list; do \ + pa=$(DESTDIR)$(sbindir)/`echo $$p|sed '$(transform)'`; \ + echo chown $(BINARY_OWNER) $$pa; \ + chown $(BINARY_OWNER) $$pa; \ + echo chgrp $(SETUID_GROUP) $$pa; \ + chgrp $(SETUID_GROUP) $$pa; \ + echo chmod o-rwx $$pa; \ + chmod o-rwx $$pa; \ + done + +amcompare: + chmod a+x $@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff -urP amanda-2.4.2p2/remote-io-src/amcompare.in amanda-2.4.2p2-changed/remote-io-src/amcompare.in --- amanda-2.4.2p2/remote-io-src/amcompare.in Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/remote-io-src/amcompare.in Mon Apr 10 11:19:50 2000 @@ -0,0 +1,51 @@ +#! /bin/sh + +case $# in + 4|5) ;; + *) echo "$0 config computer fs server [date]" >&2 + echo "$0: Example: $0 uis defian /usr debian 2000-02-14" + echo "$0: bad args." >&2 + exit 2;; +esac + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +AMRIO=@sbindir@/amrio + +TMP_DIRECTORY=@AMANDA_TMPDIR@ +TMP_FILE_1=$TMP_DIRECTORY/list_1_$$ +TMP_FILE_2=$TMP_DIRECTORY/list_2_$$ +TMP_FILE_3=$TMP_DIRECTORY/list_3_$$ + +mkdir -p $TMP_DIRECTORY +rm -f $TMP_FILE_1 $TMP_FILE_2 $TMP_FILE_3 + +COMPUTER=$2 +CONFIG=$1 +FS=$3 +SERVER=$4 + +case $FS in + /*) ;; + *) echo "$0: fs must start with /" >&2 + exit 2;; +esac + +if [ $# != 5 ]; then + DATE= +else + DATE="-D $5" +fi + +$AMRIO $CONFIG -s $SERVER -t $SERVER -d /dev/nst0 -H $COMPUTER -F $FS -L 0 $DATE | (cd $FS && dd bs=4k skip=8 | tar -b 64 --compare -f - -v) 2> $TMP_FILE_2 > $TMP_FILE_1 + +# On Solaris 2.4, we have tested with GNU tar, and it works only with +# the -b 64 option. On Linux (tar 1.12) it looks there is no problem +# without. + +(cd $FS && find . -mount -print | sort) > $TMP_FILE_3 + +egrep -v 'is new' $TMP_FILE_2 +sed 's%/$%%' < $TMP_FILE_1 | sort | diff - $TMP_FILE_3 + +rm -f $TMP_FILE_1 $TMP_FILE_2 $TMP_FILE_3 diff -urP amanda-2.4.2p2/remote-io-src/amrio.c amanda-2.4.2p2-changed/remote-io-src/amrio.c --- amanda-2.4.2p2/remote-io-src/amrio.c Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/remote-io-src/amrio.c Fri Aug 3 11:48:12 2001 @@ -0,0 +1,940 @@ +/* + * Amanda, The Advanced Maryland Automatic Network Disk Archiver + * Copyright (c) 1991-1998 University of Maryland at College Park + * All Rights Reserved. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of U.M. not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. U.M. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M. + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Authors: the Amanda Development Team. Its members are listed in a + * file named AUTHORS, in the root directory of this distribution. + */ +/* + * $Id: amanda-2.4.2p2-append-patch,v 1.4 2001/08/16 12:03:56 msc Exp $ + * + * a program for getting back a complete Amanda file (file == backup), for + * specific restore, or for verification through e.g. tar --compare, using + * the Amanda remote tape protocol and indexes. + */ + +#define ENABLE_SMART_AMRESTORE /* tape file option for quick & smart + * amrestore. + */ + +#include "amanda.h" +#include "version.h" +#ifdef HAVE_NETINET_IN_SYSTM_H +#include <netinet/in_systm.h> +#endif +#include <netinet/in.h> +#ifdef HAVE_NETINET_IP_H +#include <netinet/ip.h> +#endif +#include "amrio.h" +#include "getfsent.h" +#include "dgram.h" + +#if defined(KRB4_SECURITY) +#include "krb4-security.h" +#endif +#include "util.h" + +#define USAGE "Usage: amrio [[-C] <config>] [-s <index-server>] [-t <tape-server>] [-d <tape-device>] [-D dump-date] -H host -F disk -L level\n" + +static char * set_dump P((const char *host, const char *disk, const char *date, const char *level, int *the_file)); +static int extract_file_data P((int fd)); +static int extract_file_setup P((const char *the_tape, int the_file)); +static int converse P((char *cmd)); +static int exchange P((char *cmd)); +static int send_command P((char *cmd)); +static int get_reply_line P((void)); +static char *reply_line P((void)); +static void quit P((void)); +static void send_to_tape_server_my P((int tss, const char *cmd)); + +/* The following is normally set by Makefile */ +#ifndef DEFAULT_CONFIG +#define DEFAULT_CONFIG "uis" +#endif /* !DEFAULT_CONFIG */ + +#ifndef DEFAULT_SERVER +#define DEFAULT_SERVER "localhost" +#endif /* !DEFAULT_SERVER */ + +char *config = NULL; +char *server_name = NULL; +int server_socket; +char *server_line = NULL; +char *dump_datestamp = NULL; /* date we are restoring */ +char *dump_hostname = NULL; /* which machine we are restoring */ +char *disk_name = NULL; /* disk we are restoring */ +char *tape_server_name = NULL; +int tape_server_socket; +char *tape_device_name = NULL; +char *backup_dump_level = NULL; + +/* gets a "line" from server and put in server_line */ +/* server_line is terminated with \0, \r\n is striped */ +/* returns -1 if error */ + +int get_line () +{ + char *line = NULL; + char *part = NULL; + int len; + + while(1) { + if((part = areads(server_socket)) == NULL) { + int save_errno = errno; + + if(server_line) { + fputs(server_line, stderr); /* show the last line read */ + fputc('\n', stderr); + errno = save_errno; + } + if(errno != 0) { + fprintf(stderr, "%s: ", get_pname()); + errno = save_errno; + perror("Error reading line from server"); + } else { + fprintf(stderr, "%s: Unexpected server end of file\n", + get_pname()); + } + amfree(line); + amfree(server_line); + return -1; + } + if(line) { + strappend(line, part); + amfree(part); + } else { + line = part; + part = NULL; + } + if((len = strlen(line)) > 0 && line[len-1] == '\r') { + line[len-1] = '\0'; + server_line = newstralloc(server_line, line); + amfree(line); + return 0; + } + /* + * Hmmm. We got a "line" from areads(), which means it saw + * a '\n' (or EOF, etc), but there was not a '\r' before it. + * Put a '\n' back in the buffer and loop for more. + */ + strappend(line, "\n"); + } +} + + +/* get reply from server and print to screen */ +/* handle multi-line reply */ +/* return -1 if error */ +/* return code returned by server always occupies first 3 bytes of global + variable server_line */ +int grab_reply (show) +int show; +{ + do { + if (get_line() == -1) { + return -1; + } + if(show) fprintf(stderr, "%s\n", server_line); + } while (server_line[3] == '-'); + if(show) fflush(stderr); + + return 0; +} + + +/* get 1 line of reply */ +/* returns -1 if error, 0 if last (or only) line, 1 if more to follow */ +static int get_reply_line () +{ + if (get_line() == -1) + return -1; + return server_line[3] == '-'; +} + + +/* returns pointer to returned line */ +static char *reply_line () +{ + return server_line; +} + + + +/* returns 0 if server returned an error code (ie code starting with 5) + and non-zero otherwise */ +int server_happy () +{ + return server_line[0] != '5'; +} + + +static int send_command(cmd) +char *cmd; +{ + int l, n, s; + char *end; + + /* + * NOTE: this routine is called from sigint_handler, so we must be + * **very** careful about what we do since there is no way to know + * our state at the time the interrupt happened. For instance, + * do not use any stdio routines here. + */ + for (l = 0, n = strlen(cmd); l < n; l += s) + if ((s = write(server_socket, cmd + l, n - l)) < 0) { + perror("amrio: Error writing to server"); + return -1; + } + end = "\r\n"; + for (l = 0, n = strlen(end); l < n; l += s) + if ((s = write(server_socket, end + l, n - l)) < 0) { + perror("amrio: Error writing to server"); + return -1; + } + return 0; +} + + +/* send a command to the server, get reply and print to screen */ +static int converse(cmd) +char *cmd; +{ + if (send_command(cmd) == -1) return -1; + if (grab_reply(1) == -1) return -1; + return 0; +} + + +/* same as converse() but reply not echoed to stderr */ +static int exchange(cmd) +char *cmd; +{ + if (send_command(cmd) == -1) return -1; + if (grab_reply(0) == -1) return -1; + return 0; +} + +char *localhost = NULL; + +int main(argc, argv) +int argc; +char **argv; +{ + struct sockaddr_in server; + struct sockaddr_in myname; + struct servent *sp; + struct hostent *hp; + int i; + time_t timer; + char *lineread = NULL; + struct sigaction act, oact; + extern char *optarg; + extern int optind; + char cwd[STR_SIZE], *dn_guess = NULL, *mpt_guess = NULL; + char *service_name; + char *line = NULL; + int fd; + + for(fd = 3; fd < FD_SETSIZE; fd++) { + /* + * Make sure nobody spoofs us with a lot of extra open files + * that would cause an open we do to get a very high file + * descriptor, which in turn might be used as an index into + * an array (e.g. an fd_set). + */ + close(fd); + } + + set_pname("amrio"); + + if (geteuid() != 0) { + error("amrio must be run by root"); /* why ? BSD security ? */ + } + + localhost = alloc(MAX_HOSTNAME_LENGTH+1); + if (gethostname(localhost, MAX_HOSTNAME_LENGTH) != 0) { + error("cannot determine local host name\n"); + } + localhost[MAX_HOSTNAME_LENGTH] = '\0'; + + config = newstralloc(config, DEFAULT_CONFIG); + server_name = newstralloc(server_name, DEFAULT_SERVER); +#ifdef DEFAULT_TAPE_SERVER + tape_server_name = newstralloc(tape_server_name, DEFAULT_TAPE_SERVER); + tape_device_name = newstralloc(tape_device_name, DEFAULT_TAPE_DEVICE); +#else + amfree(tape_server_name); + amfree(tape_device_name); +#endif + + if (argc > 1 && argv[1][0] != '-') + { + /* + * If the first argument is not an option flag, then we assume + * it is a configuration name to match the syntax of the other + * Amanda utilities. + */ + char **new_argv; + + new_argv = (char **) malloc ((argc + 1 + 1) * sizeof (*new_argv)); + if (new_argv == NULL) + { + (void)fprintf(stderr, "%s: no memory for argument list\n", + get_pname()); + exit(1); + } + new_argv[0] = argv[0]; + new_argv[1] = "-C"; + for (i = 1; i < argc; i++) + { + new_argv[i + 1] = argv[i]; + } + new_argv[i + 1] = NULL; + argc++; + argv = new_argv; + } + + while ((i = getopt(argc, argv, "C:s:t:d:U:D:H:F:L:")) != EOF) + { + switch (i) + { + case 'C': + config = newstralloc(config, optarg); + break; + + case 's': + server_name = newstralloc(server_name, optarg); + break; + + case 't': + tape_server_name = newstralloc(tape_server_name, optarg); + break; + + case 'd': + tape_device_name = newstralloc(tape_device_name, optarg); + break; + + case 'D': + dump_datestamp = newstralloc(dump_datestamp, optarg); + break; + + case 'H': + dump_hostname = newstralloc(dump_hostname, optarg); + break; + + case 'F': + disk_name = newstralloc(disk_name, optarg); + break; + + case 'L': + backup_dump_level = newstralloc(backup_dump_level, optarg); + break; + + case 'U': + case '?': + (void)printf(USAGE); + return 0; + } + } + if (optind != argc) + { + (void)fprintf(stderr, USAGE); + exit(1); + } + + if (!dump_datestamp) { + time_t timer; + char dump_date[STR_SIZE]; + + /* set the date of extraction to be today */ + (void)time(&timer); + strftime(dump_date, sizeof(dump_date), "%Y-%m-%d", localtime(&timer)); + fprintf(stderr, "Setting restore date to today (%s)\n", dump_date); + dump_datestamp = newstralloc(dump_datestamp, dump_date); + } + + if (!dump_datestamp + || !dump_hostname + || !disk_name + || !backup_dump_level) { + (void)fprintf(stderr, USAGE); + exit(1); + } + + dbopen(); + + service_name = stralloc2("amandaidx", SERVICE_SUFFIX); + + fprintf(stderr, "AMRIO Version %s. Contacting server on %s ...\n", + version(), server_name); + if ((sp = getservbyname(service_name, "tcp")) == NULL) + { + perror("amrio: amandaidx/tcp unknown protocol"); + dbprintf(("%s/tcp unknown protocol\n", service_name)); + dbclose(); + exit(1); + } + if ((hp = gethostbyname(server_name)) == NULL) + { + (void)fprintf(stderr, "%s: %s is an unknown host\n", + get_pname(), server_name); + dbprintf(("%s is an unknown host\n", server_name)); + dbclose(); + exit(1); + } + memset((char *)&server, 0, sizeof(server)); + memcpy((char *)&server.sin_addr, hp->h_addr, hp->h_length); + server.sin_family = hp->h_addrtype; + server.sin_port = sp->s_port; + if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) + + { + perror("amrio: Error creating socket"); + dbprintf(("Error creating socket\n")); + dbclose(); + exit(1); + } + + /* + * Bind our end of the socket to a privileged port. + */ + if ((hp = gethostbyname(localhost)) == NULL) + { + (void)fprintf(stderr, "%s: %s is an unknown host\n", + get_pname(), localhost); + dbprintf(("%s is an unknown host\n", localhost)); + dbclose(); + exit(1); + } + memset((char *)&myname, 0, sizeof(myname)); + memcpy((char *)&myname.sin_addr, hp->h_addr, hp->h_length); + myname.sin_family = hp->h_addrtype; + if (bind_portrange(server_socket, &myname, 512, IPPORT_RESERVED - 1) != 0) + { + int save_errno = errno; + + perror("amrio: Error binding socket"); + dbprintf(("Error binding socket: %s\n", strerror(save_errno))); + dbclose(); + exit(1); + } + if (ntohs(myname.sin_port) >= IPPORT_RESERVED) { + (void)fprintf(stderr, "%s: can't get a reserved udp port\n", + get_pname()); + dbprintf(("can't get a reserved udp port\n")); + dbclose(); + exit(1); + } + +#if 0 + /* + * We may need root privilege again later for a reserved port to + * the tape server, so we will drop down now but might have to + * come back later. + */ + setegid(getgid()); + seteuid(getuid()); +#endif + + if (connect(server_socket, (struct sockaddr *)&server, sizeof(server)) + == -1) + { + perror("amrio: Error connecting to server"); + dbprintf(("Error connecting to server\n")); + dbclose(); + exit(1); + } + + /* get server's banner */ + if (grab_reply(1) == -1) + exit(1); + if (!server_happy()) + { + dbclose(); + aclose(server_socket); + exit(1); + } + + /* do the security thing */ +#if defined(KRB4_SECURITY) +#if 0 /* not yet implemented */ + if(krb4_auth) + { + line = get_krb_security(); + } else +#endif /* 0 */ +#endif + { + line = get_bsd_security(); + } + if (converse(line) == -1) + exit(1); + if (!server_happy()) + exit(1); + memset(line, '\0', strlen(line)); + amfree(line); + + line = stralloc2("SCNF ", config); + if (converse(line) == -1) + exit(1); + amfree(line); + + if (server_happy()) + { + char *the_tape = NULL; + int the_file = 0; + + /* set host we are restoring to this host by default */ + if ((the_tape = set_dump(dump_hostname, + disk_name, + dump_datestamp, + backup_dump_level, + &the_file)) + && server_happy()) { + int result = 1; + + if (tape_server_name == NULL) { + tape_server_name = newstralloc(tape_server_name, server_name); + } + if (tape_device_name == NULL) { + result = 0; + if ((send_command("TAPE") != -1) + && (get_reply_line() == -1)) { + char *l = reply_line(); + + if (!server_happy()) { + fprintf(stderr, "%s\n", l); + } + else { + tape_device_name = newstralloc(tape_device_name, l+4); + result = 1; + } + + amfree(l); + } + } + + if (result) { + int fd; + + fd = extract_file_setup(the_tape, the_file); + if (fd != -1) { + extract_file_data(fd); /* res ignored */ + aclose(fd); + (void)converse("QUIT"); + } + else { + fprintf(stderr, "amrio: can't talk to tape server.\n"); + result = 0; + } + } + + if (result) { + fprintf(stderr, "amrio: presumably has succeeded.\n"); + } + } + else { + fprintf(stderr, "amrio: server returned error: %s.\n", server_line); + } + } + + dbclose(); + + aclose(server_socket); + return 0; +} + +/* sets a date, mapping given date into standard form if needed */ +static char *set_dump(host, disk, date, level, the_file) +const char *host; +const char *disk; +const char *date; +const char *level; +int *the_file; +{ + char *cmd = NULL; + char *the_tape = NULL; + + cmd = stralloc2("DATE ", date); /* not really useful here */ + if (converse(cmd) != -1) { + cmd = newstralloc2(cmd, "HOST ", host); + if (converse(cmd) != -1) { + cmd = newstralloc2(cmd, "DISK ", disk); + if (converse(cmd) != -1) { + /* find the appropriate tape with the date/level/disk/host */ + cmd = newstralloc(cmd, "DHST"); + if (send_command(cmd) != -1) { + int count = get_line(); + + if ((count != -1) + && (server_line[3] == '-') + && (server_line[0] == '2')) { + int found = 0; + int error = 0; + int finished = 0; + + /* ASSUMPTION + * - Data is returned first first (if multiple + * DAY/LEVEL backup). + */ +#define SET_DUMP_TOKENS 6 + while (!finished && !error) { + char *tokens[SET_DUMP_TOKENS]; + + count = get_line(); + + if (count != -1) { + if (server_line[3] != '-') { + finished = 1; + } + else if (!found) { + int token; + + if ((token = split(server_line, + tokens, + SET_DUMP_TOKENS, + " ")) == (SET_DUMP_TOKENS + - 1)) { + found = !strcmp(tokens[2], + date) + && !strcmp(tokens[3], + level); + if (found) { + the_tape = stralloc(tokens[4]); + *the_file = atoi(tokens[5]); + + fprintf(stderr, "FOUND: tape %s file %d.\n", + the_tape, *the_file); + } + } + else { + fprintf(stderr, "can't tokenize %d.\n", token); + error = 1; + } + + /* BUGS + * - do we need to free anything ? + */ + } + } + else { + error = 1; + } + + } + + if (error) { + amfree(the_tape); /* also sets ptr to NULL */ + } + } + } + } + } + } + amfree(cmd); + + return the_tape; +} + +/* TODO + * - Maybe do it with two processes for efficiency (or + * the user can pipe to the buffer command). + */ +static int extract_file_data(fd) +int fd; +{ + char buffer[TAPE_BLOCK_BYTES]; + int finished = 0; + int result = 0; + + /* This is designed so that + * ./amrio uis -s debian -t debian -d /dev/nst0 -D 2000-01-31 -H defian \ + * -F / -L 0 | (cd /; dd bs=4k skip=8 | tar --compare -f -) + * works. + */ + + while (!finished) { + char *tmp = buffer; + int tmp_read; + int size_written; + int size_read = 0; + + while (size_read < sizeof(buffer) && !finished) { + tmp_read = read(fd, tmp, (TAPE_BLOCK_BYTES - size_read)); + if (tmp_read < 0) { + perror("read()"); + finished = 1; + } + else if (tmp_read == 0) { + result = 1; + finished = 1; + } + else { + size_read += tmp_read; + tmp += tmp_read; + } + } + + tmp = buffer; + + while (size_read) { + size_written = write(STDOUT_FILENO, tmp, size_read); + if (size_written <= 0) { + perror("write()"); + finished = 1; + } + else { + if (size_written <= size_read) { + size_read -= size_written; + tmp += size_written; + } + else { + fprintf(stderr, "ERROR: incoherency (%d vs %d).\n", + size_written, size_read); + } + } + + if (finished) { + break; + } + } + } + + return result; +} + +/* start up connection to tape server and set commands to initiate + transfer of dump image. + Return tape server socket on success, -1 on error. */ +static int extract_file_setup (the_tape, the_file) +const char *the_tape; +int the_file; +{ + struct sockaddr_in tape_server; + struct sockaddr_in myname; + struct servent *sp; + struct hostent *hp; + int tape_server_socket; + char *disk_regex = NULL; + char *service_name = NULL; + char *line = NULL; + char *clean_datestamp, *ch, *ch1; +#ifdef ENABLE_SMART_AMRESTORE + char string_the_file[20]; /* should be enough, checked below anyway */ + + ap_snprintf(string_the_file, sizeof(string_the_file), "%d", the_file); +#endif /* ENABLE_SMART_AMRESTORE */ + fprintf(stderr, +#ifdef ENABLE_SMART_AMRESTORE + "extract_file_setup(): will request tape %s file %d.\n", +#else /* !ENABLE_SMART_AMRESTORE */ + "extract_file_setup(): should really request tape %s file %d.\n", +#endif /* !ENABLE_SMART_AMRESTORE */ + the_tape, + the_file); + fflush(stderr); + + service_name = stralloc2("amidxtape", SERVICE_SUFFIX); + + /* get tape server details */ + if ((sp = getservbyname(service_name, "tcp")) == NULL) + { + fprintf(stderr, "%s/tcp unknown protocol - config error?\n", service_name); + amfree(service_name); + return -1; + } + amfree(service_name); + if ((hp = gethostbyname(tape_server_name)) == NULL) + { + fprintf(stderr, "%s is an unknown host\n", tape_server_name); + return -1; + } + memset((char *)&tape_server, 0, sizeof(tape_server)); + memcpy((char *)&tape_server.sin_addr, hp->h_addr, hp->h_length); + tape_server.sin_family = hp->h_addrtype; + tape_server.sin_port = sp->s_port; + + /* contact the tape server */ + if ((tape_server_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) + { + perror("Error creating socket"); + exit(1); + } + if ((hp = gethostbyname(localhost)) == NULL) + { + (void)fprintf(stderr, "%s: %s is an unknown host\n", + get_pname(), localhost); + dbprintf(("%s is an unknown host\n", localhost)); + dbclose(); + exit(1); + } + memset((char *)&myname, 0, sizeof(myname)); + memcpy((char *)&myname.sin_addr, hp->h_addr, hp->h_length); + myname.sin_family = hp->h_addrtype; + seteuid(0); /* it either works ... */ + setegid(0); + if (bind_portrange(tape_server_socket, &myname, 512, IPPORT_RESERVED - 1) != 0) + { + perror("amrecover: Error binding socket"); + exit(2); + } + if (ntohs(myname.sin_port) >= IPPORT_RESERVED) { + (void)fprintf(stderr, "%s: can't get a reserved udp port\n", + get_pname()); + dbprintf(("can't get a reserved udp port\n")); + dbclose(); + exit(1); + } + + setegid(getgid()); + seteuid(getuid()); /* put it back */ + if (connect(tape_server_socket, (struct sockaddr *)&tape_server, + sizeof(struct sockaddr_in)) == -1) + { + perror("Error connecting to tape server"); + exit(2); + } + + /* do the security thing */ +#if defined(KRB4_SECURITY) +#if 0 /* not yet implemented */ + if(krb4_auth) + { + line = get_krb_security(); + } +#endif /* 0 */ +#endif + { + line = get_bsd_security(); + } + send_to_tape_server_my(tape_server_socket, line); + memset(line, '\0', strlen(line)); + amfree(line); + + disk_regex = alloc(strlen(disk_name) * 2 + 3); + + ch = disk_name; + ch1 = disk_regex; + + /* we want to force amrestore to only match disk_name exactly */ + *(ch1++) = '^'; + + /* We need to escape some characters first... NT compatibilty crap */ + for (; *ch != 0; ch++, ch1++) { + switch (*ch) { /* done this way in case there are more */ + case '$': + *(ch1++) = '\\'; + /* no break; we do want to fall through... */ + default: + *ch1 = *ch; + } + } + + /* we want to force amrestore to only match disk_name exactly */ + *(ch1++) = '$'; + + *ch1 = '\0'; + + clean_datestamp = stralloc(dump_datestamp); + for(ch=ch1=clean_datestamp;*ch1 != '\0';ch1++) { + if(*ch1 != '-') { + *ch = *ch1; + ch++; + } + } + *ch = '\0'; + /* send to the tape server what tape file we want */ + +#ifdef ENABLE_SMART_AMRESTORE + /* 12 args: + * "-T" + * "tape_label" + * "-F" + * "tape file number" + * "-N" + * "config name" + * "-h" + * "-p" + * "tape device" + * "hostname" + * "diskname" + * "datestamp" + * BUGS + * - level is ignored. + */ + send_to_tape_server_my(tape_server_socket, "12"); + send_to_tape_server_my(tape_server_socket, "-T"); + send_to_tape_server_my(tape_server_socket, the_tape); + + send_to_tape_server_my(tape_server_socket, "-F"); + send_to_tape_server_my(tape_server_socket, string_the_file); + + send_to_tape_server_my(tape_server_socket, "-N"); + send_to_tape_server_my(tape_server_socket, config); +#else /* !ENABLE_SMART_AMRESTORE */ + /* 6 args: + * "-h" + * "-p" + * "tape device" + * "hostname" + * "diskname" + * "datestamp" + */ + send_to_tape_server_my(tape_server_socket, "6"); +#endif /* !ENABLE_SMART_AMRESTORE */ + send_to_tape_server_my(tape_server_socket, "-h"); + send_to_tape_server_my(tape_server_socket, "-p"); + send_to_tape_server_my(tape_server_socket, tape_device_name); + send_to_tape_server_my(tape_server_socket, dump_hostname); + send_to_tape_server_my(tape_server_socket, disk_regex); + send_to_tape_server_my(tape_server_socket, clean_datestamp); + + dbprintf(("Started amidxtaped with arguments \"-h -p %s %s %s %s\"\n", + tape_device_name, dump_hostname, disk_regex, clean_datestamp)); + + amfree(disk_regex); + + return tape_server_socket; +} + +static void send_to_tape_server_my(tss, cmd) +int tss; +const char *cmd; +{ + int l, n, s; + char *end; + + for (l = 0, n = strlen(cmd); l < n; l += s) + if ((s = write(tss, cmd + l, n - l)) < 0) + { + perror("Error writing to tape server"); + exit(101); + } + end = "\r\n"; + for (l = 0, n = strlen(end); l < n; l += s) + if ((s = write(tss, end + l, n - l)) < 0) + { + perror("Error writing to tape server"); + exit(101); + } +} + diff -urP amanda-2.4.2p2/remote-io-src/amrio.h amanda-2.4.2p2-changed/remote-io-src/amrio.h --- amanda-2.4.2p2/remote-io-src/amrio.h Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/remote-io-src/amrio.h Mon Jan 31 12:04:34 2000 @@ -0,0 +1,34 @@ +/* + * Amanda, The Advanced Maryland Automatic Network Disk Archiver + * Copyright (c) 1991-1998 University of Maryland at College Park + * All Rights Reserved. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of U.M. not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. U.M. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M. + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Authors: the Amanda Development Team. Its members are listed in a + * file named AUTHORS, in the root directory of this distribution. + */ +/* + * $Id: amanda-2.4.2p2-append-patch,v 1.4 2001/08/16 12:03:56 msc Exp $ + * + * data structures and declarations for amrio + */ + +#include "amanda.h" + +extern int server_happy P((void)); \ No newline at end of file diff -urP amanda-2.4.2p2/restore-src/amidxtaped.c amanda-2.4.2p2-changed/restore-src/amidxtaped.c --- amanda-2.4.2p2/restore-src/amidxtaped.c Tue Jun 13 00:58:43 2000 +++ amanda-2.4.2p2-changed/restore-src/amidxtaped.c Fri Aug 3 11:42:57 2001 @@ -276,9 +276,17 @@ /* rewind tape */ /* the first non-option argument is the tape device */ + /* in addition to this, the next argument shall not start with - */ for (i = 1; i <= amrestore_nargs; i++) if (amrestore_args[i][0] != '-') - break; + if ((i >= amrestore_nargs) /* evaluation order counts */ + || (amrestore_args[i + 1][0] != '-')) { + /* If current argument is not an option AND either this is + * the last argument OR the next one is not an option. + */ + break; + } + if (i > amrestore_nargs) { dbprintf(("Couldn't find tape in arguments\n")); diff -urP amanda-2.4.2p2/restore-src/amrestore.c amanda-2.4.2p2-changed/restore-src/amrestore.c --- amanda-2.4.2p2/restore-src/amrestore.c Sun Dec 3 21:56:44 2000 +++ amanda-2.4.2p2-changed/restore-src/amrestore.c Sat Aug 4 14:30:30 2001 @@ -43,12 +43,17 @@ * -C write compressed with COMPRESS_BEST_OPT * -r raw, write file as is on tape (with header, possibly compressed) * -h write the header too + * -T tape label + * -F file number + * -N config */ #include "amanda.h" #include "tapeio.h" #include "fileheader.h" +static int search_label(const char *tape_label, const char *config_name); + #define CREAT_MODE 0640 char buffer[TAPE_BLOCK_BYTES]; @@ -399,7 +404,7 @@ * Print usage message and terminate. */ { - error("Usage: amrestore [-r|-c] [-p] [-h] tape-device|holdingfile [hostname [diskname [datestamp [hostname [diskname [datestamp ... ]]]]]]"); + error("Usage: amrestore [-r|(-c|-C)] [-h] [-p] tape-device|holdingfile [-T tapelabel -F file -N config] [hostname [diskname [datestamp ... ]]]"); } @@ -430,6 +435,10 @@ amwait_t compress_status; int tapedev; int fd; + int locate_mode = 0; + char *tape_label = NULL; + char *config_name = NULL; + int tape_file = 1; for(fd = 3; fd < FD_SETSIZE; fd++) { /* @@ -449,18 +458,44 @@ signal(SIGPIPE, handle_sigpipe); /* handle options */ - while( (opt = getopt(argc, argv, "cCd:rpkh")) != -1) { + while( (opt = getopt(argc, argv, "cCd:rpkhT:F:N:")) != -1) { switch(opt) { case 'c': compflag = 1; break; case 'C': compflag = 1; compress_type = COMPRESS_BEST_OPT; break; case 'r': rawflag = 1; break; case 'p': pipeflag = 1; break; case 'h': headerflag = 1; break; + case 'T': + tape_label = newstralloc(tape_label, optarg); + locate_mode |= 1; + break; + case 'F': + tape_file = atoi(optarg); + locate_mode |= 2; + break; + case 'N': + config_name = newstralloc(config_name, optarg); + locate_mode |= 4; + break; default: usage(); } } + if (locate_mode) { + if (locate_mode == 7) { + fprintf(stderr, "%s: seeking label %s file %d config %s.\n", + get_pname(), + tape_label, + tape_file, + config_name); + } + else { + usage(); + } + } + + if(compflag && rawflag) { fprintf(stderr, "Cannot specify both -r (raw) and -c (compressed) output.\n"); @@ -473,8 +508,38 @@ } else tapename = argv[optind++]; + if (locate_mode) { + if (!search_label(tape_label, config_name)) { + error("couldn't locate tape `%s'", tape_label); + } + } + if((tapedev = tape_open(tapename, 0)) < 0) error("could not open tape %s: %s", tapename, strerror(errno)); + else if (locate_mode) { + char *stamp = NULL; + char *label = NULL; + + /* rdlabel also does a rewind before reading */ + if (tapefd_rdlabel(tapedev, &stamp, &label) != NULL) { + error("can't read label: %s", strerror(errno)); + } + else if (!match(label, tape_label)) { + error("non matching label: expected `%s' got `%s'", + tape_label, + label); + } + /* it's safer to rewind again */ + else if (tapefd_rewind(tapedev) == -1) { + error("can't rewind: %s", strerror(errno)); + } + else if (tapefd_fsf(tapedev, tape_file)) { + error("can't skip to file %d: %s", tape_file, strerror(errno)); + } + + amfree(stamp); + amfree(label); + } #define ARG_GET_HOST 0 #define ARG_GET_DISK 1 @@ -592,4 +657,54 @@ return 1; } return 0; +} + +static int ok_for_system(const char *str) { + int valid = 1; + + while (*str && valid) { + valid = ((*str >= 'a') && (*str <= 'z')) + || ((*str >= 'A') && (*str <= 'Z')) + || ((*str >= '0') && (*str <= '9')) + || (*str == '_') + || (*str == '-'); + + str++; + } + + return valid; +} + +static int search_label(const char *tape_label, const char *config_name) { + char *command; + int result; + + if (ok_for_system(config_name) && ok_for_system(tape_label)) { + command = vstralloc(sbindir "/amtape ", + config_name, + " label ", + tape_label, + NULL); + + /* we use system() because we don't want to have the taper code + * glued to us, since amrestore is supposed to be able to be client + * only too. + * NOTES + * - argument validity checking is supposed to be done by caller, + * e.g. amidxtaped, for example. Despite that we do some + * checks. + */ + + result = (system(command) == 0); + + amfree(command); + } + else { + error("parameters are dangerous for system: %s, %s", + config_name, + tape_label); + result = 0; + } + + return result; } diff -urP amanda-2.4.2p2/scripts/Makefile.am amanda-2.4.2p2-changed/scripts/Makefile.am --- amanda-2.4.2p2/scripts/Makefile.am Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/scripts/Makefile.am Sat Aug 4 14:31:33 2001 @@ -0,0 +1,20 @@ +# Makefile for DILOG Amanda scripts + +PROGS = clean_and_check_tape.sh eval_length.sh list_tape.sh summary.sh test.sh + +all: + +install-exec-hook: + mkdir -p $(DESTDIR)$(prefix)/scripts + @list="$(PROGS)"; \ + for p in $$list; do \ + pa=$(DESTDIR)$(prefix)/scripts/`echo $$p|sed '$(transform)'`; \ + cp $$p $$pa; \ + echo chown $(BINARY_OWNER) $$pa; \ + chown $(BINARY_OWNER) $$pa; \ + echo chgrp $(SETUID_GROUP) $$pa; \ + chgrp $(SETUID_GROUP) $$pa; \ + echo chmod 555 $$pa; \ + chmod 555 $$pa; \ + done + diff -urP amanda-2.4.2p2/scripts/clean_and_check_tape.sh amanda-2.4.2p2-changed/scripts/clean_and_check_tape.sh --- amanda-2.4.2p2/scripts/clean_and_check_tape.sh Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/scripts/clean_and_check_tape.sh Tue Aug 7 09:49:07 2001 @@ -0,0 +1,26 @@ +#! /bin/sh + +case $# in + 2) ;; + *) echo "$0 config tapestatpath" >&2 + echo "$0: bad args." >&2 + exit 2;; +esac + +CONFIG=$1 +TAPE_STATUS_FILE=$2 + +AMTAPE=/sbin/amtape + +if [ ! -x $AMTAPE ]; then + # Let's hope it's in PATH + AMTAPE=amtape +fi + +if [ -f $TAPE_STATUS_FILE ]; then + cat $TAPE_STATUS_FILE + rm -f $TAPE_STATUS_FILE +fi + +$AMTAPE $CONFIG clean +exit $? diff -urP amanda-2.4.2p2/scripts/eval_length.sh amanda-2.4.2p2-changed/scripts/eval_length.sh --- amanda-2.4.2p2/scripts/eval_length.sh Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/scripts/eval_length.sh Wed Mar 15 14:09:21 2000 @@ -0,0 +1,17 @@ +#! /bin/sh + +TAPE=/dev/nst0 +BYTES=0 + +mt -f $TAPE rewind && (while : +do + dd if=$TAPE of=/dev/null bs=32k 2>&1 + if [ $? != 0 ]; then + break + fi +done) | awk -F+ 'BEGIN { count = 0; } + { count += ($1 * 32768) + $2;} + END { printf "TOTAL BYTES: %s.\n", count; }' + +echo "" +echo "TOTAL BYTES: $BYTES" diff -urP amanda-2.4.2p2/scripts/list_tape.sh amanda-2.4.2p2-changed/scripts/list_tape.sh --- amanda-2.4.2p2/scripts/list_tape.sh Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/scripts/list_tape.sh Tue May 16 14:22:52 2000 @@ -0,0 +1,13 @@ +#! /bin/sh + +TAPE=/dev/nst0 +COUNT=1 +mt -f $TAPE rewind && dd if=$TAPE bs=32k count=1 2>/dev/null | (head -1; cat > /dev/null) && while mt -f $TAPE fsf 1 ; do + if [ $# = 0 ]; then + echo -n "FILE $COUNT " + else + echo -n "FILE $COUNT (real: `mt -f /dev/nst0 status | awk '/^file number/ { print $NF; }'`) " + fi + dd if=$TAPE bs=32k count=1 2>/dev/null | (head -1; cat > /dev/null) + COUNT=`expr $COUNT + 1` +done diff -urP amanda-2.4.2p2/scripts/summary.sh amanda-2.4.2p2-changed/scripts/summary.sh --- amanda-2.4.2p2/scripts/summary.sh Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/scripts/summary.sh Tue Aug 7 09:44:45 2001 @@ -0,0 +1,39 @@ +#! /bin/sh + +if [ $# != 2 ]; then + echo "$0 config printer" >&2 + echo "$0: bad args" >&2 + exit 2 +fi + +AMANDA_CFG_DIR=/etc/amanda/$1 +AMANDA_CFG=$AMANDA_CFG_DIR/amanda.conf +TAPELIST=$AMANDA_CFG_DIR/tapelist + +# NOTES +# - Not using -P option of a2ps, because this seems to fail with CUPS +# or at least SFI CUPS. +FORMATTER="a2ps -o -" +AMADMIN=/usr/sbin/amadmin + +if [ ! -x $AMADMIN ]; then + # Let's hope it's in PATH + AMADMIN=amadmin +fi + +if [ -f $AMANDA_CFG ]; then + TAPELIST=`egrep '^tapelist[ \t]+".+"' $AMANDA_CFG | sed 's/^tapelist[ \t]+"\(.+\).*$/\1/'` + if [ -f $TAPELIST ]; then + (date + echo ' Dumps: lev datestmp tape file origK compK secs' + $AMADMIN $1 info | egrep -v ' -100.0%|dump rates|Incremental|Dumps: lev datestmp tape' + echo + column < $TAPELIST) | $FORMATTER | lpr -P$2 + else + echo "$0: cannot find amanda tapelist $TAPELIST" >&2 + exit 1 + fi +else + echo "$0: cannot find amanda configuration $AMANDA_CFG" >&2 + exit 1 +fi diff -urP amanda-2.4.2p2/scripts/test.sh amanda-2.4.2p2-changed/scripts/test.sh --- amanda-2.4.2p2/scripts/test.sh Thu Jan 1 01:00:00 1970 +++ amanda-2.4.2p2-changed/scripts/test.sh Thu Mar 23 10:53:43 2000 @@ -0,0 +1,10 @@ +#! /bin/sh + +if [ $# != 2 ]; then + echo "$0 conf label" >&2 + echo "$0 dne DilogNewEngSet103" + echo "$0: bad args." + exit 2 +fi + +/usr/sbin/amadmin $1 find | egrep "$2" | sed 's/-//g' | awk '{printf "FILE %d AMANDA: FILE %s %s %s %d\n", $6, $1, $2, $3, $4}' | sort -n +1 -2 diff -urP amanda-2.4.2p2/server-src/amadmin.c amanda-2.4.2p2-changed/server-src/amadmin.c --- amanda-2.4.2p2/server-src/amadmin.c Wed Feb 28 16:27:37 2001 +++ amanda-2.4.2p2-changed/server-src/amadmin.c Fri Aug 3 08:24:54 2001 @@ -45,6 +45,7 @@ void usage P((void)); void force P((int argc, char **argv)); void force_one P((disk_t *dp)); +void newtape P((int argc, char **argv)); void unforce P((int argc, char **argv)); void unforce_one P((disk_t *dp)); void force_bump P((int argc, char **argv)); @@ -157,6 +158,7 @@ else if(strcmp(argv[2],"unforce-bump") == 0) unforce_bump(argc, argv); else if(strcmp(argv[2],"force") == 0) force(argc, argv); else if(strcmp(argv[2],"unforce") == 0) unforce(argc, argv); + else if(strcmp(argv[2],"newtape") == 0) newtape(argc, argv); else if(strcmp(argv[2],"reuse") == 0) reuse(argc, argv); else if(strcmp(argv[2],"no-reuse") == 0) noreuse(argc, argv); else if(strcmp(argv[2],"info") == 0) info(argc, argv); @@ -199,6 +201,8 @@ fprintf(stderr, "\tunforce <hostname> <disks> ...\t# Clear force command.\n"); fprintf(stderr, + "\tnewtape\t\t# Do not append to current tape, start with new.\n"); + fprintf(stderr, "\tforce-bump <hostname> <disks> ...\t# Force bump at next run.\n"); fprintf(stderr, "\tforce-no-bump <hostname> <disks> ...\t# Force no-bump at next run.\n"); @@ -299,6 +303,15 @@ } been_here = 1; return; +} + +/* ----------------------------------------------- */ + +void newtape(argc, argv) +int argc; +char **argv; +{ + current_tape_information_erase(); } /* ----------------------------------------------- */ diff -urP amanda-2.4.2p2/server-src/amcheck.c amanda-2.4.2p2-changed/server-src/amcheck.c --- amanda-2.4.2p2/server-src/amcheck.c Thu Mar 15 03:34:59 2001 +++ amanda-2.4.2p2-changed/server-src/amcheck.c Fri Aug 3 09:31:29 2001 @@ -405,7 +405,7 @@ /* not an exact label match, but a labelstr match */ /* check against tape list */ tp = lookup_tapelabel(label); - if(tp != NULL && !reusable_tape(tp)) + if(tp != NULL && !reusable_tape(tp) && !can_append(tp)) fprintf(errf, " (active tape)\n"); else if(got_match) fprintf(errf, " (labelstr match)\n"); @@ -413,7 +413,8 @@ got_match = 1; first_match = newstralloc(first_match, slotstr); first_match_label = newstralloc(first_match_label, label); - fprintf(errf, " (first labelstr match)\n"); + fprintf(errf, " (first labelstr match%s)\n", + can_append(tp) ? " for append" : ""); if(!backwards || !searchlabel) { found = 2; found_device = newstralloc(found_device, device); @@ -788,7 +789,7 @@ tapebad = 1; } else { tp = lookup_tapelabel(label); - if(tp != NULL && !reusable_tape(tp)) { + if(tp != NULL && !reusable_tape(tp) && !can_append(tp)) { fprintf(outf, "ERROR: cannot overwrite active tape %s\n", label); tapebad = 1; } diff -urP amanda-2.4.2p2/server-src/amtape.c amanda-2.4.2p2-changed/server-src/amtape.c --- amanda-2.4.2p2/server-src/amtape.c Tue Mar 27 00:23:38 2001 +++ amanda-2.4.2p2-changed/server-src/amtape.c Fri Aug 3 09:33:23 2001 @@ -510,7 +510,7 @@ /* not an exact label match, but a labelstr match */ /* check against tape list */ tp = lookup_tapelabel(label); - if(tp != NULL && !reusable_tape(tp)) + if(tp != NULL && !reusable_tape(tp) && !can_append(tp)) fprintf(stderr, " (active tape)\n"); else if(got_match) fprintf(stderr, " (labelstr match)\n"); @@ -518,7 +518,8 @@ got_match = 1; first_match = newstralloc(first_match, slotstr); first_match_label = newstralloc(first_match_label, label); - fprintf(stderr, " (first labelstr match)\n"); + fprintf(stderr, " (first labelstr match%s)\n", + can_append(tp) ? " for append" : ""); if(!backwards || !searchlabel) { found = 2; amfree(datestamp); @@ -552,7 +553,8 @@ fprintf(stderr, "%s: scanning for ", get_pname()); if(searchlabel) fprintf(stderr, "tape label %s or ", searchlabel); - fprintf(stderr, "a new tape.\n"); + fprintf(stderr, "a new%s tape.\n", + getconf_int(CNF_APPENDMODE) ? "/append" : ""); if (searchlabel != NULL) changer_find(scan_init, taperscan_slot,searchlabel); @@ -560,9 +562,12 @@ changer_scan(scan_init, taperscan_slot); if(found == 2) { - fprintf(stderr, "%s: %s: settling for first labelstr match\n", + fprintf(stderr, "%s: %s%s: settling for first labelstr match\n", get_pname(), - searchlabel? "gravity stacker": "looking only for new tape"); + searchlabel? "gravity stacker": "looking only for new tape", + (!searchlabel && getconf_int(CNF_APPENDMODE)) + ? " or append" + : ""); searchlabel = newstralloc(searchlabel, first_match_label); } else if(!found && got_match) { diff -urP amanda-2.4.2p2/server-src/conffile.c amanda-2.4.2p2-changed/server-src/conffile.c --- amanda-2.4.2p2/server-src/conffile.c Thu Jan 4 22:09:16 2001 +++ amanda-2.4.2p2-changed/server-src/conffile.c Fri Aug 3 11:37:29 2001 @@ -75,7 +75,7 @@ DISKDIR, DISKSIZE, INDEXDIR, NETUSAGE, INPARALLEL, TIMEOUT, TPCHANGER, RUNTAPES, DEFINE, DUMPTYPE, TAPETYPE, INTERFACE, - PRINTER, RESERVE, + PRINTER, CURRENTTAPE, APPENDMODE, RESERVE, COLUMNSPEC, /* holding disk */ @@ -159,6 +159,7 @@ static val_t conf_diskdir; static val_t conf_tapetype; static val_t conf_indexdir; +static val_t conf_currenttape; static val_t conf_columnspec; /* ints */ @@ -178,6 +179,7 @@ static val_t conf_dtimeout; static val_t conf_ctimeout; static val_t conf_tapebufs; +static val_t conf_appendmode; static val_t conf_reserve; /* reals */ @@ -203,6 +205,8 @@ static int seen_maxcycle, seen_tapecycle; static int seen_disksize, seen_netusage, seen_inparallel, seen_timeout; static int seen_indexdir, seen_etimeout, seen_dtimeout, seen_ctimeout; +static int seen_currenttape; +static int seen_appendmode; static int seen_tapebufs; static int seen_reserve; static int seen_columnspec; @@ -317,6 +321,8 @@ { "CHANGERFILE", CNF_CHNGRFILE, STRING }, { "LABELSTR", CNF_LABELSTR, STRING }, { "TAPELIST", CNF_TAPELIST, STRING }, + { "CURRENTTAPE", CNF_CURRENTTAPE, STRING }, + { "APPENDMODE", CNF_APPENDMODE, INT }, { "DISKFILE", CNF_DISKFILE, STRING }, { "INFOFILE", CNF_INFOFILE, STRING }, { "LOGDIR", CNF_LOGDIR, STRING }, @@ -396,6 +402,8 @@ case CNF_RUNTAPES: return seen_runtapes; case CNF_MAXDUMPS: return seen_maxdumps; case CNF_TAPELIST: return seen_tapelist; + case CNF_CURRENTTAPE: return seen_currenttape; + case CNF_APPENDMODE: return seen_appendmode; case CNF_INFOFILE: return seen_infofile; case CNF_DISKFILE: return seen_diskfile; /*case CNF_DISKDIR: return seen_diskdir;*/ @@ -447,6 +455,7 @@ case CNF_CTIMEOUT: r = conf_ctimeout.i; break; case CNF_TAPEBUFS: r = conf_tapebufs.i; break; case CNF_RESERVE: r = conf_reserve.i; break; + case CNF_APPENDMODE: r = conf_appendmode.i; break; default: error("error [unknown getconf_int parm: %d]", parm); @@ -488,6 +497,9 @@ case CNF_CHNGRFILE: r = conf_chngrfile.s; break; case CNF_LABELSTR: r = conf_labelstr.s; break; case CNF_TAPELIST: r = conf_tapelist.s; break; + case CNF_CURRENTTAPE: + r = conf_currenttape.s; + break; case CNF_INFOFILE: r = conf_infofile.s; break; case CNF_LOGDIR: r = conf_logdir.s; break; /*case CNF_LOGFILE: r = conf_logfile.s; break;*/ @@ -582,6 +594,10 @@ s = "/dev/rawft0"; #endif conf_rawtapedev.s = newstralloc(conf_rawtapedev.s, s); + conf_currenttape.s + = newstralloc(conf_currenttape.s, + "current-tape-for-append"); + malloc_mark(conf_currenttape.s); malloc_mark(conf_rawtapedev.s); conf_tpchanger.s = newstralloc(conf_tpchanger.s, ""); malloc_mark(conf_tpchanger.s); @@ -630,6 +646,7 @@ conf_dtimeout.i = 1800; conf_ctimeout.i = 30; conf_tapebufs.i = 20; + conf_appendmode.i = 1; /* defaults to enabled */ conf_reserve.i = 100; /* defaults for internal variables */ @@ -646,7 +663,9 @@ seen_maxcycle = seen_tapecycle = 0; seen_disksize = seen_netusage = seen_inparallel = seen_timeout = 0; seen_indexdir = seen_etimeout = seen_dtimeout = seen_ctimeout = 0; + seen_currenttape = 0; seen_tapebufs = 0; + seen_appendmode = 0; seen_reserve = 0; seen_columnspec = 0; line_num = got_parserror = 0; @@ -802,6 +821,8 @@ { "TAPECYCLE", TAPECYCLE }, { "TAPEDEV", TAPEDEV }, { "TAPELIST", TAPELIST }, + { "CURRENTTAPE", CURRENTTAPE }, + { "APPENDMODE", APPENDMODE }, { "TAPETYPE", TAPETYPE }, { "TIMEOUT", TIMEOUT }, /* XXX - historical */ { "TPCHANGER", TPCHANGER }, @@ -850,6 +871,12 @@ case CHNGRFILE: get_simple(&conf_chngrfile, &seen_chngrfile, STRING); break; case LABELSTR: get_simple(&conf_labelstr, &seen_labelstr, STRING); break; case TAPELIST: get_simple(&conf_tapelist, &seen_tapelist, STRING); break; + case CURRENTTAPE: + get_simple(&conf_currenttape, &seen_currenttape, STRING); + break; + case APPENDMODE: + get_simple(&conf_appendmode, &seen_appendmode, INT); + break; case INFOFILE: get_simple(&conf_infofile, &seen_infofile, STRING); break; case LOGDIR: get_simple(&conf_logdir, &seen_logdir, STRING); break; case DISKFILE: get_simple(&conf_diskfile, &seen_diskfile, STRING); break; diff -urP amanda-2.4.2p2/server-src/conffile.h amanda-2.4.2p2-changed/server-src/conffile.h --- amanda-2.4.2p2/server-src/conffile.h Tue Jun 13 00:58:53 2000 +++ amanda-2.4.2p2-changed/server-src/conffile.h Fri Aug 3 11:34:33 2001 @@ -45,7 +45,9 @@ CNF_DISKSIZE, CNF_NETUSAGE, CNF_INPARALLEL, CNF_TIMEOUT, CNF_BUMPSIZE, CNF_BUMPMULT, CNF_BUMPDAYS, CNF_TPCHANGER, CNF_RUNTAPES, CNF_MAXDUMPS, CNF_ETIMEOUT, CNF_DTIMEOUT, CNF_CTIMEOUT, - CNF_TAPEBUFS, CNF_RAWTAPEDEV, CNF_PRINTER, CNF_RESERVE, + CNF_TAPEBUFS, CNF_RAWTAPEDEV, CNF_PRINTER, + CNF_CURRENTTAPE, CNF_APPENDMODE, + CNF_RESERVE, CNF_COLUMNSPEC } confparm_t; diff -urP amanda-2.4.2p2/server-src/find.c amanda-2.4.2p2-changed/server-src/find.c --- amanda-2.4.2p2/server-src/find.c Tue Jun 13 00:59:00 2000 +++ amanda-2.4.2p2-changed/server-src/find.c Thu Aug 16 13:59:58 2001 @@ -42,6 +42,10 @@ void search_holding_disk P((find_result_t **output_find)); char *find_nicedate P((int datestamp)); +static int are_same P((find_result_t *r1, find_result_t *r2)); +static find_result_t *find_dump_orig P((char *lfind_hostname, + int lfind_ndisks, + char **lfind_diskstrs)); static char *find_sort_order = NULL; static int find_nhosts; @@ -49,11 +53,205 @@ static int find_ndisks; static char **find_diskstrs; +/* NOTES + * - Implementation using only the tape.<LABEL> files. Is faster, + * and works with tape appending. + * - We try to access any tape.<LABEL> file, for every <LABEL> + * coming out of the tapelist. + * - If cannot find to access the tape.<LABEL> file, reverts + * to the old log parsing method (which doesn't support appending), + * for compatibility only. + */ find_result_t *find_dump(lfind_hostname, lfind_ndisks, lfind_diskstrs) char *lfind_hostname; int lfind_ndisks; char **lfind_diskstrs; { + int tape, maxtape; + tape_t *tp; + find_result_t *output_find = NULL; + int try_old_method = 0; + + find_hostname = lfind_hostname; + find_ndisks = lfind_ndisks; + find_diskstrs = lfind_diskstrs; + if (find_hostname == NULL) { + find_nhosts = 0; + } + else { + find_nhosts = 1; + } + + maxtape = lookup_nb_tape(); + + for (tape = 1; tape <= maxtape; tape++) { + tp = lookup_tapepos(tape); + if (tp) { + char *tape_log_name = tape_log_file_name(tp->label); + FILE *f; + int filenum = 0; + + f = fopen(tape_log_name, "r"); + if (f) { + while (get_logline(f)) { + if ((curlog == L_SUCCESS) + && (curprog == P_TAPER)) { + char *s; + char ch; + int datestampI; + char *host; + char *host_undo; + char host_undo_ch; + char *disk; + char *disk_undo; + char disk_undo_ch; + int level; + int datestamp; + char *rest; + + filenum++; + + s = curstr; + ch = *s; + s++; + + skip_whitespace(s, ch); + if (ch == '\0') { + fprintf(stderr, "strange log line \"%s\"\n", curstr); + fflush(stderr); + continue; + } + + host = s - 1; + skip_non_whitespace(s, ch); + host_undo = s - 1; + host_undo_ch = *host_undo; + *host_undo = '\0'; + + skip_whitespace(s, ch); + if (ch == '\0') { + fprintf(stderr, "strange log line \"%s\"\n", curstr); + fflush(stderr); + continue; + } + + disk = s - 1; + skip_non_whitespace(s, ch); + disk_undo = s - 1; + disk_undo_ch = *disk_undo; + *disk_undo = '\0'; + + skip_whitespace(s, ch); + if (ch == '\0' || sscanf(s - 1, "%d", &datestampI) != 1) { + fprintf(stderr, "strange log line \"%s\"\n", curstr); + fflush(stderr); + continue; + } + skip_integer(s, ch); + + if (datestampI < 100) { /* old log didn't have datestamp */ + level = datestampI; + datestampI = datestamp; + } + else { + skip_whitespace(s, ch); + if (ch == '\0' || sscanf(s - 1, "%d", &level) != 1) { + fprintf(stderr, "strange log line \"%s\"\n", curstr); + fflush(stderr); + continue; + } + skip_integer(s, ch); + } + + skip_whitespace(s, ch); + if (ch == '\0') { + fprintf(stderr, "strange log line \"%s\"\n", curstr); + fflush(stderr); + continue; + } + rest = s - 1; + if ((s = strchr(s, '\n')) != NULL) { + *s = '\0'; + } + + if (find_match(host, disk)) { + find_result_t *new_output_find = + (find_result_t *) alloc(sizeof(find_result_t)); + + new_output_find->next = output_find; + new_output_find->datestamp = datestampI; + new_output_find->datestamp_aux = 0; /* @@@ */ + new_output_find->hostname = stralloc(host); + new_output_find->diskname = stralloc(disk); + new_output_find->level = level; + new_output_find->label = stralloc(tp->label); + new_output_find->filenum = filenum; + new_output_find->status=stralloc("OK"); + + output_find = new_output_find; + } + } + } + + fclose(f); /* result ignored */ + } + else { + fprintf(stderr, "find_dump: %s: can't access %s\n", + strerror(errno), + tape_log_name); + fflush(stderr); + try_old_method = 1; + } + + amfree(tape_log_name); + } + } + + if (try_old_method) { + find_result_t *other_output_find; + + fprintf(stderr, "find_dump: for compatibility, now also parsing log files.\n"); + fflush(stderr); + + other_output_find = find_dump_orig(lfind_hostname, + lfind_ndisks, + lfind_diskstrs); + if (other_output_find) { + if (output_find) { + find_result_t *last = output_find; + + /* Add this at end of the normal list + * NOTES + * - Old things are going to be at bottom, and there will be + * duplicates: caller is supposed to sort them. + */ + + while (last->next != NULL) { + last = last->next; + } + + last->next = other_output_find; + } + else { + /* No results, thus give what we have found. */ + output_find = other_output_find; + } + } + } + else { + search_holding_disk(&output_find); + } + + return output_find; +} + +static find_result_t *find_dump_orig(lfind_hostname, + lfind_ndisks, + lfind_diskstrs) +char *lfind_hostname; +int lfind_ndisks; +char **lfind_diskstrs; +{ char *conf_logdir, *logfile = NULL; int tape, maxtape, seq, logs; tape_t *tp; @@ -332,6 +530,8 @@ find_result_t **array_find_result = NULL; int nb_result=0; int no_result; + int i; + int actual_results = 0; find_sort_order = sort_order; /* qsort core dump if nothing to sort */ @@ -357,6 +557,22 @@ qsort(array_find_result,nb_result,sizeof(find_result_t *), find_compare); + /* remove duplicates */ + for (i = 0; i < nb_result; i++) { + if ((i == (nb_result - 1)) /* evaluation order counts */ + || !are_same(array_find_result[i], array_find_result[i + 1])) { + array_find_result[actual_results] + = array_find_result[i]; + actual_results++; + } + else { + array_find_result[i]->next = NULL; + free_find_result(&array_find_result[i]); + } + } + + nb_result = actual_results; + /* put the sorted result in the list */ for(no_result=0; no_result<nb_result-1; no_result++) { @@ -365,6 +581,7 @@ array_find_result[nb_result-1]->next=NULL; *output_find=array_find_result[0]; + amfree(array_find_result); } void print_find_result(output_find) @@ -722,4 +939,15 @@ } } return(NULL); +} + +static int are_same P((find_result_t *r1, find_result_t *r2)) { + return !strcmp(r1->diskname, r2->diskname) + && !strcmp(r1->hostname, r2->hostname) + && !strcmp(r1->label, r2->label) + && (r1->filenum == r2->filenum) + && (r1->level == r2->level) + && (r1->datestamp == r2->datestamp) + && (r1->datestamp_aux == r2->datestamp_aux) + && ((r1->status == r2->status) || !strcmp(r1->status, r2->status)); } diff -urP amanda-2.4.2p2/server-src/tapefile.c amanda-2.4.2p2-changed/server-src/tapefile.c --- amanda-2.4.2p2/server-src/tapefile.c Tue Jun 13 00:59:03 2000 +++ amanda-2.4.2p2-changed/server-src/tapefile.c Fri Aug 3 09:41:20 2001 @@ -29,6 +29,7 @@ * routines to read and write the amanda active tape list */ #include "amanda.h" +#include "arglist.h" #include "tapefile.h" #include "conffile.h" @@ -39,8 +40,6 @@ static tape_t *insert P((tape_t *list, tape_t *tp)); static time_t stamp2time P((int datestamp)); - - int read_tapelist(tapefile) char *tapefile; { @@ -154,6 +153,7 @@ int s; int tapecycle = getconf_int(CNF_TAPECYCLE); char *labelstr = getconf_str (CNF_LABELSTR); + tape_t *tmp = NULL; /* * The idea here is we keep the last "several" reusable tapes we @@ -165,6 +165,27 @@ for(s = 0; s <= skip; s++) { tpsave[s] = NULL; } + + /* tape append support + * NOTES + * - This will be a bit suboptimal, especially if the + * function is called in a loop. + */ + tmp = tape_list; + if (tmp) { /* tmp is the last one, the candidate for appending */ + if (!can_append(tmp)) { + tmp = NULL; + } + } + + if (skip != 0) { + if (tmp) { + skip--; + tmp = NULL; + } + } + /* end tape append support */ + for(tp = tape_list; tp != NULL; tp = tp->next) { if(tp->reuse == 1 && match (labelstr, tp->label)) { count++; @@ -179,6 +200,10 @@ if(count < tapecycle - skip) tp = NULL; else tp = tpsave[skip - s]; amfree(tpsave); + + if (tmp) { + return tmp; + } return tp; } @@ -373,4 +398,335 @@ tm.tm_mday = ((datestamp % 100) ); return mktime(&tm); +} + +int tape_is_first_in_tapelist(tp) +tape_t *tp; +{ + return tp && (tape_list == tp); +} + +#define CURRENT_TAPE_FILE getconf_str(CNF_CURRENTTAPE) + +current_tape_information_t current_tape_information + = { NULL, 0, 0, 0 }; + +int current_tape_information_read () +{ + FILE *f; + int result = 0; /* failed */ + + f = fopen(CURRENT_TAPE_FILE, "r"); + if (f) { + int finished = 0; + + current_tape_information_free(); + + while (!finished) { + char buffer[200]; + int len; + + if (!(finished = !fgets(buffer, sizeof(buffer), f))) { + int len = strlen(buffer); + + /* remove final \n if present */ + if (len && (buffer[len - 1] == '\n')) { + len--; + buffer[len] = '\0'; + } + + if (len) { + char *parameter = buffer; + + while (*parameter && !isspace(*parameter)) { + parameter++; + } + + if (*parameter) { + char *temp; + *parameter = '\0'; /* end of object identifier buffer */ + + parameter++; + while (*parameter && isspace(*parameter)) { + parameter++; + } + + temp = parameter; + + while (*temp && !isspace(*temp)) { + temp++; + } + + *temp = '\0'; + } + + /* parameter is now the argument */ + + if (*buffer && *parameter) { + char *temp; + + if (!strcasecmp(buffer, "label")) { + current_tape_information.label + = stralloc(parameter); + if (current_tape_information.label == NULL) { + fprintf(stderr, + "taper: _read(): stralloc()\n", + parameter); + fflush(stderr); + finished = 1; + } + } + else if (!strcasecmp(buffer, "written_files")) { + current_tape_information.written_files + = strtoul(parameter, &temp, 0); + /* *parameter != 0 is implicit */ + if (*temp) { + current_tape_information.written_files = 0; + } + } + else if (!strcasecmp(buffer, "written_blocks")) { + current_tape_information.written_blocks + = strtoul(parameter, &temp, 0); + /* *parameter != 0 is implicit */ + if (*temp) { + current_tape_information.written_blocks = 0; + } + } + else if (!strcasecmp(buffer, "last_used")) { + current_tape_information.last_used + = strtoul(parameter, &temp, 0); + /* *parameter != 0 is implicit */ + if (*temp) { + current_tape_information.last_used = 0; + } + } + else { + fprintf(stderr, + "taper: _read(): unknown name %s\n", + buffer); + fflush(stderr); + finished = 1; + } + } + else if (*buffer || *parameter) { + fprintf(stderr, + "taper: _read(): syntax error: /%s/%s/\n", + buffer, + parameter); + fflush(stderr); + finished = 1; + } /* else empty line, ignored */ + } /* we ignore empty lines */ + } + } + + fclose(f); /* result ignored */ + if (current_tape_information_valid()) { + result = 1; + } + else { +#if 0 + current_tape_information_erase(); +#endif + } + } + + if (!result) { + current_tape_information_free(); + } + + return result; +} + +int current_tape_information_erase () +{ + current_tape_information_free(); + + return unlink(CURRENT_TAPE_FILE) ? 0 : 1; +} + +int current_tape_information_create () +{ + FILE *f; + int result = 0; /* failed */ + + f = fopen(CURRENT_TAPE_FILE, "w"); + if (f) { + if (current_tape_information_valid()) { + fprintf(f, "label %s\n" + "written_files %lu\n" + "written_blocks %lu\n" + "last_used %lu\n", + current_tape_information.label, + current_tape_information.written_files, + current_tape_information.written_blocks, + current_tape_information.last_used); /* result ignored */ + } + else { + fprintf(stderr, "taper: _update() incorrect\n"); + fflush(stderr); + } + + if (fclose(f) == 0) { + result = 1; + } + else { + perror("taper(): _update() fclose()"); + } + } + else { + perror("taper(): _update() fopen()"); + } + + if (!result) { + current_tape_information_free(); + } + + return result; +} + +void current_tape_information_free () +{ + if (current_tape_information.label) { + amfree(current_tape_information.label); + } + current_tape_information.label = NULL; + current_tape_information.written_files = 0; + current_tape_information.written_blocks = 0; + current_tape_information.last_used = 0; +} + +int current_tape_information_valid () +{ + return current_tape_information.label + && current_tape_information.written_files + && current_tape_information.written_blocks + && current_tape_information.last_used; +} + +int can_append(tp) + tape_t *tp; /* looks strange to use K&R C, doesn't it ? */ +{ + /* NOTES + * - conditions: + * - must be top of tapelist + * - must be the one in the current_tape file. + * - if a discrepancy between the two, remove current_tape and + * log the error. + * TODO + * - use configuration for constraints (see below) + */ + if (getconf_int(CNF_APPENDMODE) == 0) { + ; /* disabled in configuration */ + } + else if (0) { + ; /* constraints do not match --- NOT implemented */ + } + else if (tp == NULL) { + ; + } + else if (tape_is_first_in_tapelist(tp)) { + if (current_tape_information_read()) { + if (!strcmp(current_tape_information.label, + tp->label)) { + return 1; /* success */ + } + else { + fprintf(stderr, + "taper: can_append(): inconsistency (`%s'/`%s); fixed\n", + current_tape_information.label, + tp->label); + fflush(stderr); + current_tape_information_erase(); /* result ignored */ + } + } /* else ignore */ + } + + return 0; /* failure */ +} + +#if 1 +void tape_log_add(label, format, host, disk, datestamp, level, errstr) +const char *label; +const char *format; +const char *host; +const char *disk; +const char *datestamp; +const int level; +const char *errstr; +{ + char *file_name = tape_log_file_name(label); + FILE *f; + + if ((f = fopen(file_name, "a"))) { + fprintf(f, format, host, disk, datestamp, level, errstr); + + if (fclose(f)) { + fprintf(stderr, "tapefile: error closing tape log file %s.\n", + file_name); + fflush(stderr); + } + } + else { + fprintf(stderr, "tapefile: cannot append to tape log file %s.\n", + file_name); + fflush(stderr); + } + + amfree(file_name); +} +#else +void tape_log_add(char *label, const char *format, ...) { + char *file_name = tape_log_file_name(label); + FILE *f; + va_list argp; + + arglist_start(argp, format); + + if ((f = fopen(file_name, "a"))) { + fprintf(f, format, argp); + + if (fclose(f)) { + fprintf(stderr, "tapefile: error closing tape log file %s.\n", + file_name); + fflush(stderr); + } + } + else { + fprintf(stderr, "tapefile: cannot append to tape log file %s.\n", + file_name); + fflush(stderr); + } + + amfree(file_name); +} +#endif + +void tape_log_del(label) +char *label; +{ + char *file_name = tape_log_file_name(label); + + unlink(file_name); /* result ignored */ + + amfree(file_name); +} + +char *tape_log_file_name (label) +const char *label; +{ + char *conf_logdir; + char *file_name; + + conf_logdir = getconf_str(CNF_LOGDIR); + if (*conf_logdir == '/') { + conf_logdir = stralloc(conf_logdir); + } + else { + conf_logdir = stralloc2(config_dir, conf_logdir); + } + + file_name = vstralloc(conf_logdir, "/tape.", label, NULL); + + return file_name; /* must be amfree()d */ } diff -urP amanda-2.4.2p2/server-src/tapefile.h amanda-2.4.2p2-changed/server-src/tapefile.h --- amanda-2.4.2p2/server-src/tapefile.h Tue Jun 13 00:59:03 2000 +++ amanda-2.4.2p2-changed/server-src/tapefile.h Fri Aug 3 09:41:37 2001 @@ -56,4 +56,29 @@ int guess_runs_from_tapelist P((void)); +/* append data structures */ + +typedef struct { + char *label; + int written_files; /* where to append */ + int written_blocks; /* for statistics */ + time_t last_used; +} current_tape_information_t; + +/* tape append private functions + * (to be used by taper child only, like for the data structures, + * and by amadmin.c) + */ + +int current_tape_information_read P((void)); +int current_tape_information_erase P((void)); /* also called from amadmin */ +int current_tape_information_create P((void)); +void current_tape_information_free P((void)); +int current_tape_information_valid P((void)); +int can_append P((tape_t *tp)); + +void tape_log_del P((char *label)); +void tape_log_add P((const char *label, const char *format, const char *host, const char *disk, const char *datestamp, const int level, const char *errstr)); +char *tape_log_file_name P((const char *label)); + #endif /* !TAPEFILE_H */ diff -urP amanda-2.4.2p2/server-src/taper.c amanda-2.4.2p2-changed/server-src/taper.c --- amanda-2.4.2p2/server-src/taper.c Fri Mar 9 20:28:25 2001 +++ amanda-2.4.2p2-changed/server-src/taper.c Fri Aug 3 11:05:01 2001 @@ -44,6 +44,8 @@ #include <vtblc.h> #include <strings.h> +#undef DEBUG_TAPE_APPEND + static int vtbl_no = -1; static int len = 0; static int offset = 0; @@ -88,6 +90,10 @@ char buffer[TAPE_BLOCK_BYTES]; } buffer_t; +static int had_no_error_on_tape = 1; +static int tape_in_append = 0; /* cleared as soon as 1st filemark done */ +static int was_an_append = 0; /* cleared by tape finish only */ + #define nextbuf(p) ((p) == buftable+conf_tapebufs-1? buftable : (p)+1) #define prevbuf(p) ((p) == buftable? buftable+conf_tapebufs-1 : (p)-1) @@ -121,6 +127,12 @@ int end_tape P((int writerr)); int write_filemark P((void)); +/* tape append private functions + * (to be used by taper child only) + */ + +extern current_tape_information_t current_tape_information; + /* * ======================================================================== * GLOBAL STATE @@ -834,6 +846,15 @@ amfree(q); log_add(L_SUCCESS, "%s %s %s %d %s", hostname, diskname, datestamp, level, errstr); + + tape_log_add(label, + "SUCCESS taper %s %s %s %d %s\n", + hostname, + diskname, + datestamp, + level, + errstr); + #ifdef HAVE_LIBVTBLC /* * We have 44 characters available for the label string: @@ -1035,7 +1056,7 @@ case 'Q': end_tape(0); /* XXX check results of end tape ?? */ - clear_tapelist(); + amfree(taper_datestamp); amfree(label); amfree(errstr); @@ -1095,14 +1116,19 @@ * We write the filemark at the start of the file rather than at the end, * so that it can proceed in parallel with the reader's initial filling * up of the buffers. + * Do not write a filemark if we are appending. */ startclock(); - if(!write_filemark()) + if(!tape_in_append && !write_filemark()) goto tape_error; fmwait = stopclock(); - filenum += 1; + if (!tape_in_append) { + filenum += 1; + } + + tape_in_append = 0; do { @@ -1224,6 +1250,12 @@ tape_error: /* got tape error */ + + + /* current tape no longer can be used for appending in any case */ + current_tape_information_erase(); + had_no_error_on_tape = 0; + if(next_tape(1)) syncpipe_put('T'); /* next tape in place, try again */ else syncpipe_put('E'); /* no more tapes, fail */ syncpipe_putstr(errstr); @@ -1627,6 +1659,9 @@ tape_t *tp; static int first_call = 1; + tape_in_append = 0; + was_an_append = 0; + if(have_changer) { amfree(tapedev); if ((tapedev = taper_scan()) == NULL) { @@ -1666,10 +1701,14 @@ fflush(stderr); amfree(olddatestamp); + /* no error assumed since starting. */ + + had_no_error_on_tape = 1; + /* check against tape list */ if (strcmp(tapedev, "/dev/null") != 0) { tp = lookup_tapelabel(label); - if(tp != NULL && !reusable_tape(tp)) { + if(tp != NULL && !reusable_tape(tp) && !can_append(tp)) { errstr = newvstralloc(errstr, "cannot overwrite active tape ", label, NULL); @@ -1685,72 +1724,208 @@ } } - if((tape_fd = tape_open(tapedev, O_WRONLY)) == -1) { - if(errno == EACCES) { - errstr = newstralloc(errstr, - "writing label: tape is write protected"); - } else { - errstr = newstralloc2(errstr, - "writing label: ", strerror(errno)); - } - return 0; - } - - if((result = tapefd_wrlabel(tape_fd, taper_datestamp, label)) != NULL) { - errstr = newstralloc(errstr, result); - return 0; - } - - fprintf(stderr, "taper: wrote label `%s' date `%s'\n", label, taper_datestamp); - fflush(stderr); - -#ifdef HAVE_LIBVTBLC - /* store time for the first volume entry */ - time(&raw_time); - tape_timep = localtime(&raw_time); - strftime(start_datestr, 20, "%T %D", tape_timep); - fprintf(stderr, "taper: got vtbl start time: %s\n", start_datestr); - fflush(stderr); -#endif /* HAVE_LIBVTBLC */ - - /* write tape list */ - - /* XXX add cur_tape number to tape list structure */ if (strcmp(tapedev, "/dev/null") != 0) { - remove_tapelabel(label); - add_tapelabel(atoi(taper_datestamp), label); + if (can_append(tp)) { + /* NOTES + * - if this tape is to be appended to, do not write any label, + * nor roll (again) the tape list. + * - rolling was already done the first time the tape was used. + */ + + total_tape_used = current_tape_information.written_blocks * 1024.0; + total_tape_fm = current_tape_information.written_files; + filenum = current_tape_information.written_files; + +#ifdef DEBUG_TAPE_APPEND + fprintf(stderr, "taper: appending to tape labelled `%s' fm %lu\n", + label, + total_tape_fm); + fflush(stderr); +#endif /* DEBUG_TAPE_APPEND */ + + if ((tape_fd = tape_open(tapedev, O_WRONLY)) == -1) { + errstr = newstralloc2(errstr, + "opening tape: ", strerror(errno)); + } + else { +#ifdef DEBUG_TAPE_APPEND + fprintf(stderr, "taper: rewinding (for label verify)\n"); + fflush(stderr); +#endif /* DEBUG_TAPE_APPEND */ + + /* rewind tape */ + if (tapefd_rewind(tape_fd) == 0) { + char *lb = NULL; + char *ds = NULL; - if(cur_tape == 0) { - conf_tapelist_old = stralloc2(conf_tapelist, ".yesterday"); - } else { - char cur_str[NUM_STR_SIZE]; +#ifdef DEBUG_TAPE_APPEND + fprintf(stderr, "taper: verifying label\n"); + fflush(stderr); +#endif /* DEBUG_TAPE_APPEND */ - ap_snprintf(cur_str, sizeof(cur_str), "%d", cur_tape - 1); - conf_tapelist_old = vstralloc(conf_tapelist, - ".today.", cur_str, NULL); - } - if(rename(conf_tapelist, conf_tapelist_old) != 0) { - if(errno != ENOENT) - error("could not rename \"%s\" to \"%s\": %s", - conf_tapelist, conf_tapelist_old, strerror(errno)); - } - amfree(conf_tapelist_old); - if(write_tapelist(conf_tapelist)) { - error("could not write tapelist: %s", strerror(errno)); - } - } + if ((tapefd_rdlabel(tape_fd, &ds, &lb) == NULL) + && !strcmp(label, lb)) { + amfree(ds); + amfree(lb); +#ifdef DEBUG_TAPE_APPEND + fprintf(stderr, "taper: rewinding\n"); + fflush(stderr); +#endif /* DEBUG_TAPE_APPEND */ + + /* rewind tape */ + if (tapefd_rewind(tape_fd) == 0) { + /* skip to the right position. We will need not to + * set the filemark. + */ + /* skip to the right position */ +#ifdef DEBUG_TAPE_APPEND + fprintf(stderr, "taper: moving to file %lu\n", + total_tape_fm); + fflush(stderr); +#endif /* DEBUG_TAPE_APPEND */ + if (tapefd_fsf(tape_fd, total_tape_fm) == 0) { + log_add(L_START, "datestamp %s label %s tape %d", + taper_datestamp, label, cur_tape); + log_add(L_INFO, + "datestamp %s label %s tape %d IS AN APPEND", + taper_datestamp, + label, + cur_tape); + tape_in_append = 1; + was_an_append = 1; + /* Erase, so that in case of error, we + * have a stable state. can_append() will + * not be used during the time we write. + */ + current_tape_information_erase(); + return 1; + } + else { + errstr = newstralloc2(errstr, + "moving to file: ", + strerror(errno)); + } + } + else { + errstr = newstralloc2(errstr, + "rewinding tape: ", + strerror(errno)); + } + } + else { + if (lb) { + errstr = newstralloc(errstr, + "label not matching for append"); + } + else { + errstr = newstralloc2(errstr, + "error verifying label: ", + strerror(errno)); + } + amfree(ds); + amfree(lb); + } + } + else { + errstr = newstralloc2(errstr, + "rewinding tape (for label verify): ", + strerror(errno)); + } + + close(tape_fd); + tape_fd = -1; + } + + return 0; + } + /* Do an additional check in case someone deleted the file with + * amadmin CONF newtape in between so we don't erase an active tape! + * Either it's a new tape, or it's reusable. + */ + else if ((tp == NULL) || reusable_tape(tp)) { + tape_log_del(label); + /* XXX add cur_tape number to tape list structure */ + if((tape_fd = tape_open(tapedev, O_WRONLY)) == -1) { + if(errno == EACCES) { + errstr = newstralloc(errstr, + "writing label: tape is write protected"); + } else { + errstr = newstralloc2(errstr, + "writing label: ", strerror(errno)); + } + return 0; + } + + if((result = tapefd_wrlabel(tape_fd, taper_datestamp, label)) != NULL) { + errstr = newstralloc(errstr, result); + return 0; + } - log_add(L_START, "datestamp %s label %s tape %d", - taper_datestamp, label, cur_tape); - if (first_call && strcmp(tapedev, "/dev/null") == 0) { - first_call = 0; - log_add(L_WARNING, "tapedev is %s, dumps will be thrown away", tapedev); - } + fprintf(stderr, "taper: wrote label `%s' date `%s'\n", label, taper_datestamp); + fflush(stderr); - total_tape_used=0.0; - total_tape_fm = 0; +#ifdef HAVE_LIBVTBLC + /* store time for the first volume entry */ + time(&raw_time); + tape_timep = localtime(&raw_time); + strftime(start_datestr, 20, "%T %D", tape_timep); + fprintf(stderr, "taper: got vtbl start time: %s\n", start_datestr); + fflush(stderr); +#endif /* HAVE_LIBVTBLC */ - return 1; + /* NOTES + * - This is the initial labelling. When appending to tape, no + * labelling should occur. + */ + + current_tape_information_erase(); /* result ignored */ + + /* write tape list */ + + /* XXX add cur_tape number to tape list structure */ + if (strcmp(tapedev, "/dev/null") != 0) { + remove_tapelabel(label); + add_tapelabel(atoi(taper_datestamp), label); + + if(cur_tape == 0) { + conf_tapelist_old = stralloc2(conf_tapelist, ".yesterday"); + } else { + char cur_str[NUM_STR_SIZE]; + + ap_snprintf(cur_str, sizeof(cur_str), "%d", cur_tape - 1); + conf_tapelist_old = vstralloc(conf_tapelist, + ".today.", + cur_str, + NULL); + } + if(rename(conf_tapelist, conf_tapelist_old) != 0) { + error("could not rename \"%s\" to \"%s\": %s", + conf_tapelist, conf_tapelist_old, strerror(errno)); + } + + amfree(conf_tapelist_old); + if(write_tapelist(conf_tapelist)) + error("could not write tapelist: %s", strerror(errno)); + } + + log_add(L_START, "datestamp %s label %s tape %d", + taper_datestamp, label, cur_tape); + + if (first_call && strcmp(tapedev, "/dev/null") == 0) { + first_call = 0; + log_add(L_WARNING, "tapedev is %s, dumps will be thrown away", tapedev); + } + + total_tape_used=0.0; + total_tape_fm = 0; + + return 1; + } + else { + fprintf(stderr, "taper: internal incoherency; danger avoided.\n"); + return 0; + } + } } int first_tape(new_datestamp) @@ -1763,10 +1938,11 @@ taper_datestamp = newstralloc(taper_datestamp, new_datestamp); + /* append */ + filenum = 0; if(!label_tape()) return 0; - filenum = 0; return 1; } @@ -1778,11 +1954,12 @@ if(++cur_tape >= runtapes) return 0; + /* append */ + filenum = 0; if(!label_tape()) { return 0; } - filenum = 0; return 1; } @@ -1807,16 +1984,49 @@ total_tape_fm); fflush(stderr); if(! writerror) { - if(! write_filemark()) { - rc = 1; - goto common_exit; - } - - if((result = tapefd_wrendmark(tape_fd, taper_datestamp)) != NULL) { - errstr = newstralloc(errstr, result); - rc = 1; - goto common_exit; - } + /* Fixes a bug with tape append that + * would make amadmin conf info and find + * diverge because of an additional + * filemark when schedule is empty. + */ + if (!tape_in_append) { + if(! write_filemark()) { + rc = 1; + goto common_exit; + } + + if ((result = tapefd_wrendmark(tape_fd, taper_datestamp)) + != NULL) { + errstr = newstralloc(errstr, result); + rc = 1; + goto common_exit; + } + } + + if (!was_an_append) { + clear_tapelist(); + } + + was_an_append = 0; + + if (had_no_error_on_tape) { + /* NOTES + * - create the current_tape information, if no error on + * that tape. + */ + current_tape_information.label = stralloc(label); + if (current_tape_information.label) { + current_tape_information.written_files = total_tape_fm; + current_tape_information.written_blocks + = (total_tape_used + 1023.0) / 1024.0; + current_tape_information.last_used = time(NULL); + current_tape_information_create(); /* result ignored */ + } + else { + fprintf(stderr, "taper: no memory for append\n"); + fflush(stderr); + } + } } } @@ -2045,7 +2255,7 @@ /* not an exact label match, but a labelstr match */ /* check against tape list */ tp = lookup_tapelabel(label); - if(tp != NULL && !reusable_tape(tp)) { + if(tp != NULL && !reusable_tape(tp) && !can_append(tp)) { fprintf(stderr, " (active tape)\n"); fflush(stderr); } @@ -2057,7 +2267,8 @@ got_match = 1; first_match = newstralloc(first_match, slotstr); first_match_label = newstralloc(first_match_label, label); - fprintf(stderr, " (first labelstr match)\n"); + fprintf(stderr, " (first labelstr match%s)\n", + can_append(tp) ? " for append" : ""); fflush(stderr); if(!backwards || !searchlabel) { found = 2;