« 01月30日の行動 | メイン | 本日の体操 »

2007年01月30日

[技術] MacのBackup3.0で作成したバックアップからのリストア(復旧)

Backup3.0に関する機能ついての以下言及している内容はどうもガセのようだ。
ちゃんと差分を重ねてリストアできると思います。嘘ついて、すみません。(_o_)


Mac Bookのハードディスクがクラッシュした。保証期間内で、こちらに落ち度はないので、もちろん無償交換だ。メールやドキュメントは、.Mac(ドットマック)サービスに入ると使えるBackup3.0を使って、毎日バックアップを取っていたので、復旧は楽観視していた。しかし、実際にBackup3.0を使って、リストアを始めるといろいろな不都合が明らかになった。

去年の6月にMac Bookにしてから、一応バックアップはほぼ毎日取っていたのだが、初日にフルバックアップを取って、その後は差分バックアップをとるようにしていた。ところがいざバックアップからリストアしようとすると、Backup3.0は最初のフルバックアップから一括してリストアすることができない。200近くあるバックアップをフルバックアップから日付順にひとつひとつリストアしなければいけない。がーん、200回もリストア操作をするのはちょっと無理!(で、一括でできないか、いろいろ試行錯誤しているうちにすべてのリストアがエラーになり、おかしくなってしまい、OSもインストールするハメに orz)

ということで、どうすっか?と、少し考えた。Max OS Xって、Unix系だから、なんとか、Backupファイルを自前で操作できるかもしれないと思い、調べた。で、結論から言うと、それは可能だった。

Backup3.0で作成されたバックアップアーカイブは、実際はディレクトリで、そのディレクトリ以下にはバックアップされたファイルに関する情報を格納したファイルやバックアップされたファイルを固めたバイナリファイルなどが格納されている。そして、Backup.SparseimageもしくはBackup.bmgというファイルに実際のバックアップデータが格納されている。で、このバイナリファイルを展開して、通常のファイルとして扱うには、hdiutilというコマンドを使う。

% hdiutil attach Backup.sparseimage -moutpoint /Users/tmp/extract

とやると、/Users/tmp/extract にファイルが展開(解凍)される。(マウントポイントの/Users/tmp/extract事前に作成しておく必要がある)

ここまで、わかったので、あとはスクリプトを作成して、最初のフルバックアップから最新の差分バックアップまで一括して復元することにした。(ただし、途中で削除してしまい、本来の状態なら、復元する必要ないファイルも復元されてしまうが、GUI操作を200回近くするよりも、そちらのほうがましという判断をした)

今回限りのつもりで作成したので、スクリプトはエラー処理等はまったく行わず、また、スクリプト内にマウントポイントなどを直接記述するようなつくりになっているので、はずかしいから、ここではスクリプトそのものは載せない。その代わり、部分的に載せる事にする。(この情報だけで、Perl&Macな人なら、あとは自前のスクリプトを余裕でつくれるでしょう)

#!/usr/bin/perl
use warning;
use strict;
use File::Find;

# バックアップファイルがあるディレクトリ
# 例えば、./Fullbackup/Contents/Contens/Backup.sparseimageという階層に
# Backup.spaseimage または Backup.dmgファイルが格納されている
my $backupdir = '/Users/tmp/backup';

# バックアップイメージの展開先
my $mountpoint = '/Users/tmp/extract';

# バックアップイメージの展開先に対応するデバイス
# マウントされるデバイスはあらかじめしらべておく
my $mountdevice = '/dev/disk1s2';

# 展開したファイルを復旧する先
my $restoredir = '/Users/tmp/restore';

my @dirs = qw/$backupdir/;
find sub {  do_restore($_, $mountpoint, $mountdevice, $restoredir)
                  if (m/Backup.spaseimage/)  }, @dirs;

sub do_restore {
    my ($backupimage, $mountpoint, $mountdevice, $restoredir) = @_;
    do_mount($backupimage, $mountpoint);
    do_copy($mountpoint, $restoredir);
    do_unmount($mountdevice);
}

sub do_mount {
    my ($backupimage, $mountpoint;
    system("/usr/bin/hdiutil", "attach", $backupimage, "-mountpoint", $mountpoint);
}

sub do_copy {
    my ($src, $dst) = @_;
    system("/bin/cp", "-r", $src, $dst);
}

sub do_unmount {
    my $dev = shift;
    system("/usr/bin/hdiutil", "detach", $dev);
}

ということで、上記のサブルーチンを使って、一括リストア用のスクリプトを作成できるとはずだ。とりあえず、一括リストアしたら、そこから、自分のホームディレクトリをリストアした内容で上書きすれば よい。例えば、ユーザ名がyoshiなら、以下のようなコマンドを実行する。

% cp -r /Users/tmp/restore/Users/yoshi/* /Users/yoshi/

投稿者 nekobara : 2007年01月30日 23:38


コメント