Cover V12, I04
apr2003.tar

Listing 4 amufsdump

#!/usr/local/bin/perl -wT
# -*- perl -*-
#ufsdump a filesystem snapshot for amanda
#usage: /usr/local/etc/amufsdump 0usf 1048576 - /dev/rdsk/c1t0d0s6

#JRCB 21-oct-02

#1. Initialise
#2. Secure input 
#3. Delete old snapshot if exists
#4. Create snapshot
#5. ufsdump snapshot
#6. Delete snapshot
#No signal handling as interrupting "fssnap ... /" (or /var) hangs system

### 1. Initialise
use Sys::Hostname;
$DF="/usr/bin/df";
$HOST = hostname();
$BSDIR="/share/backingstore/$HOST";
$FSSNAP="/usr/lib/fs/ufs/fssnap";
$LOCK_EX = 2;
$LOCK_UN = 8;
$LOCKFILE = ">/var/run/fssnap.lock";
$PGREP="/usr/bin/pgrep";
$UFSDUMP="/usr/sbin/ufsdump";
$XNTPD="PATH=/usr/bin /etc/init.d/xntpd";

### 2. Secure input
#Suid: untaint PATH
$ENV{PATH}="";
$ENV{IFS}=" ";

$DUMPMAN = "dumpman";
die "Must run as $DUMPMAN" unless ($< == getpwnam ($DUMPMAN));

#Ensure we are called with appropriate 4 arguments as called from amdump
($OPTS, $SIZE, $TAPEDEV, $RAWDEV) = 
    ("@ARGV" =~ m!^(\w+) (\d+) (-) (/dev/rdsk/c\d+t\d+d\d+s\d+)$!) or 
    die "@ARGV.  Usage eg: amufsdump 0usf 1048576 - /dev/rdsk/c0t0d0s0";

#Skip snapshot if just getting dump size
#  amandad calls sendsize which calls amufsdump with RAW DEVICE
if ($OPTS =~ /S/){
    system($UFSDUMP, $OPTS, $SIZE, $TAPEDEV, $RAWDEV);
    exit;
}

#Get mount point of raw device to dump, eg /var
($BLKDEV = $RAWDEV) =~ s/rdsk/dsk/;
$DF_T = `$DF $BLKDEV`;
($MNTPT) = ($DF_T =~ m!^(/\S*)!) or die "df output tainted. $!";

#Open lockfile (just need to open once then lock and unlock as required)
open(LOCKFILE) or die $!;

#Flock access to fssnap (and /etc/init.d/xntpd) to avoid concurrent access by 2 amufsdumps
sub lock($)
{
    $CMND = shift @_;
    flock(LOCKFILE, $LOCK_EX) or die $!;
    $FSSNAPOUT_T = `$CMND`;
    warn "Error with: $CMND\n" if ($?>>8);
    flock(LOCKFILE, $LOCK_UN) or die $!;
    return $FSSNAPOUT_T;
}

### 3. Delete old snapshot if exists
#Set the (real) uid (was dumpman) to the (effective) euid (root)
$< = $>; 
$FSSNAP_I_T = lock("$FSSNAP -i -o mountpoint $MNTPT");
lock("$FSSNAP -d $MNTPT") if ($FSSNAP_I_T =~ m!^/\S*$!);

### 4. Create new snapshot
#Stop xntpd if running because...
#  network time protocol daemon runs in realtime mode, blocks locking filesystem)
`$PGREP xntpd > /dev/null`;
if ($MNTPT eq "/" or $MNTPT eq "/var" and ($? >> 8) == 0){
    $FSSNAPDEV_T = lock("$XNTPD stop; $FSSNAP -o unlink,bs=$BSDIR $MNTPT; $XNTPD start");
} else {
    $FSSNAPDEV_T = lock("$FSSNAP -o unlink,bs=$BSDIR $MNTPT");
}
($FSSNAPDEV) = ($FSSNAPDEV_T =~ m!^(/dev/fssnap/\d+)!) or die "fssnap output tainted. $!";

### 5. Ufsdump filesytstem (N option writes raw device of front filesystem in dumpdates)
#Eg: /usr/local/etc/amufsdump 0usf 1048576 - /dev/rdsk/c0t0d0s3 by
#    /usr/sbin/ufsdump N0usf /dev/rdsk/c0t0d0s3 1048576 - /dev/fssnap/1
system($UFSDUMP, "N$OPTS", $RAWDEV, $SIZE, $TAPEDEV, $FSSNAPDEV);

### 6. Delete snapshot
lock("$FSSNAP -d $MNTPT");