pdumpfs が事実上一日一回しかバックアップとれないのに不満を感じたのですこしいじりました。
pdumpfs -d <DESTINATION> [-s [-r <REV>]] [-n] [-b <BASE>] [<SOURCE>] pdumpfs <SOURCE> <DESTINATION> <BASE>
通常のバックアップは以下のように行います。
% pdumpfs -d /backup /home/yaegashi % pdumpfs -d /backup /home/takeshi
オリジナルの pdumpfs とは違って、 以下のような ".dump/<バージョン番号>/" のディレクトリに保存します。
/backup/.dump/00000000/yaegashi/... /backup/.dump/00000000/takeshi/...
-s オプションで現在のバージョンに対してシンボリックリンクを作成できます。 -r オプションでシンボリックリンクの名前も指定できます。
% pdumpfs -d /backup -s % pdumpfs -d /backup -s -r "%d-%b-%Y" % ls -l /backup lrwxrwxrwx 1 yaegashi yaegashi 14 Apr 27 15:50 20030427 -> .dump/00000000 lrwxrwxrwx 1 yaegashi yaegashi 14 Apr 27 15:50 27-Apr-2003 -> .dump/00000000
-n オプションで現在のバージョン番号をひとつ進めることができます。
% pdumpfs -d /backup -n
現在作業中のバージョンは .seq というファイルに保存されています。
% cat /backup/.seq 00000000 00000001
次回のバックアップは .dump/00000000/ との差分をとりつつ .dump/00000001/ に対して保存されます。
いまのとこいじってるのは main とそのへんだけです。 もうすこし複雑になってきたら svn にでもつっこむか
require "getopts"
def main
usage unless getopts("ns", "d:", "r:", "b:")
src, dest, base = ARGV
dest ||= $OPT_d
base ||= $OPT_b
revision = $OPT_r
usage unless dest
nodir dest unless File.directory?(dest)
nodir src unless !src or File.directory?(src)
$OPT_n = $OPT_s = true unless $OPT_d
seqfile = File.join dest, ".seq"
lockfile = File.join dest, ".lock"
begin
File.open(seqfile, "w") do |file|
file.puts ".seq 00000000"
end unless File.exists? seqfile
File.symlink seqfile, lockfile
rescue
$stderr.puts $!
$stderr.puts "Cannot acquire lock file #{lockfile}."
$stderr.puts "Remove this file only if you're convinced that there's no other pdumpfs on #{dest}."
exit 1
end
lastseq, curseq = File.open(seqfile) do |file|
file.gets.chomp.split
end
if src
base ||= File.basename(src)
lastdir = File.join dest, ".dump", lastseq, base
curdir = File.join dest, ".dump", curseq, base
File.mkpath curdir
if File.directory? lastdir
update_snapshot src, lastdir, curdir
else
recursive_copy src, curdir
end
end
if $OPT_s
revision ||= "%Y%m%d"
revdir = File.expand_path(Time.now.strftime(revision), dest)
curdir = File.expand_path(".dump/#{curseq}", dest)
linkdir = reldir revdir, curdir
File.mkpath(File.dirname(revdir))
File.unlink revdir if File.exists? revdir
File.symlink linkdir, revdir
end
if $OPT_n
curdir = File.join dest, ".dump", curseq, base
if File.directory? curdir
nextseq = curseq.next
File.open(seqfile, "w") do |file|
file.puts "#{curseq} #{nextseq}"
end
end
end
File.unlink(lockfile)
end
def reldir(src, dst)
s = src.split("/")
d = dst.split("/")
while s.first == d.first
s.shift
d.shift
end
File.join [".."] * (s.length-1) + d
end