simba/scripts/backup

100 lines
2.8 KiB
Plaintext
Raw Normal View History

#!/usr/bin/perl
use warnings;
use strict;
use Simba::CA;
2007-11-15 21:15:56 +01:00
use POSIX qw(strftime);
use Getopt::Long;
2008-07-15 23:17:14 +02:00
use Filesys::Statvfs;
use File::stat;
my @filesets;
GetOptions('filesets=i' => \@filesets);
@filesets = split(/,/,join(',',@filesets));
$ENV{PATH} = "/usr/bin";
2007-11-15 21:15:56 +01:00
my $now = strftime('%Y-%m-%dT%H:%M:%S', localtime());
open(my $log, '>>', '/var/log/simba/ca.log.' . $now);
2007-06-18 03:00:29 +02:00
$log->autoflush(1);
my $ca = Simba::CA->new({
dbi_file => $ENV{SIMBA_DB_CONN} || "$ENV{HOME}/.dbi/simba",
fh_log => $log,
(@filesets ? ( filesets => \@filesets ) : ()),
});
2008-07-13 22:01:25 +02:00
$ca->log_level(9);
# Try to find all devices suitable for backup and mount them.
# We do this by trying to find a matching device for each subdirectory
# of /backup. Another way might be to check all USB disks.
my $st = stat("/backup/");
my $base_device = $st->dev;
for (glob("/backup/*")) {
my $st = stat($_);
my $dir_device = $st->dev;
2010-05-20 11:25:20 +02:00
$ca->log(0, "checking $_");
if ($base_device == $dir_device) {
# not a mount point
(my $basedir = $_) =~ s{^/backup/}{};
if (-e "/dev/disk/by-id/$basedir") {
# matching device exists
2010-05-20 11:25:20 +02:00
$ca->log(0, "mounting /dev/disk/by-id/$basedir on $_");
system("/bin/mount", "-o", "nodev,noexec,nomand,nosuid", "/dev/disk/by-id/$basedir", $_);
}
}
}
2008-07-15 23:17:14 +02:00
# find the backup dir with the most free space available.
# other strategies are possible, like round robin, or daily, weekly,
# etc. backups.
my @backup_dirs = map {
$_ = $1 if m{(.*)/.*}; # basedir and detaint
my($bsize, $frsize, $blocks, $bfree, $bavail,
$files, $ffree, $favail, $flag, $namemax)
= statvfs($_);
2010-04-24 22:23:58 +02:00
my $available_bytes = $bsize * $bavail;
my $avg_file_size = $bavail * ($blocks - $bfree) / ($files - $ffree);
my $available_bytes_by_files = $avg_file_size * $favail;
$available_bytes = $available_bytes_by_files if $available_bytes_by_files < $available_bytes;
[ $_, $available_bytes ]
2008-07-15 23:17:14 +02:00
} glob("/backup/*/active");
my $sum_free = 0;
$sum_free += $_->[1] for (@backup_dirs);
my $rnd = rand() * $sum_free;
my $count_free = 0;
my $backup_dir;
for(@backup_dirs) {
$count_free += $_->[1];
2010-04-24 22:23:58 +02:00
$ca->log(3, "considering base $_->[0] (est. $_->[1] bytes)\n");
if ($count_free >= $rnd) {
$backup_dir = $_->[0];
2010-04-24 22:23:58 +02:00
$ca->log(3, "using base $_->[0]\n");
last;
}
}
unless ($backup_dir) {
2009-06-28 22:21:14 +02:00
$ca->log(0, "no backup directory found");
exit(1);
}
$ca->basedir($backup_dir);
2008-07-15 23:17:14 +02:00
# umount all potential backup dirs again, except the one we are actually
# using
for (@backup_dirs) {
next if $_->[0] eq $backup_dir;
$ca->log(0, "unmounting $_->[0]");
system("/bin/umount", $_->[0]);
}
chdir($backup_dir); # prevent accidental umount
$ca->run();
# umount backup dir
chdir("/");
$ca->log(0, "unmounting $backup_dir");
system("/bin/umount", $backup_dir);