xen-backup.sh
について解説する。このスクリプトの大まかな流れは以下の通り:
- バックアップ設定ファイルの読み込み: 182行目
- バックアップを実行するかどうかの検査: 183行目~215行目
- DomU設定の解析: 217行目~228行目
- ディスクイメージのマウント@ローカル: 230行目~254行目
- ディスクイメージのマウント@リモートDom0: 256行目~263行目
- Rsyncによるバックアップ: 265行目~266行目
- ディスクイメージのアンマウント@リモートDom0: 268行目~274行目
- ディスクイメージのアンマウント@ローカル: 277行目~280行目
バックアップを実行するかどうかの検査
DomUの状態を表示するコマンド
virsh domstate DomU名を使って、以下の各項目を検査する。
- 対象DomUが、ローカルDom0でホストされいるか?
- 対象DomUが、ローカルDom0で正常に実行されているか?
- 自分自身が
DOM0S
に含まれているか?
DomU設定の解析
コマンド
virsh dumpxml DomU名で対象となるDomUの設定(XML形式)を得て、ディスクイメージ情報を抽出する。
このとき、関数
get_value_from_config
を呼び出す。115: get_value_from_config() 116: { 117: local xml=$1 num=$2 elem=$3 attr=$4 118: echo "cat /domain/devices/disk[$num]/$elem/@$attr" | \ 119: xmllint --shell $xml | \ 120: awk -F\" '/^ +'$attr'/{print $2}' 121: }この中では
xmllint
コマンドを使用している。ディスクイメージに対する設定項目/domain/devices/disk
は、複数指定される可能性があることに注意。ディスクイメージのマウント@ローカル
各ディスクイメージをローカルにマウントする。
マウントする前に、ディスクイメージのスナップショットを撮っている(『XenとLVM・その3・スナップショットLVの利用』参照)。
238: lvcreate --snapshot --name=$snapshot_name --size=$SNAPSHOT_SIZE ${disk_source[$i]} 239: add_close_command "lvremove -f /dev/$vgname/$snapshot_name" 240: analyze_disk /dev/$vgname/$snapshot_nameマウント時と反対の動作をバックアップ後に実施する必要があるため、
add_close_command
関数(34行目~38行目)を使って記録する。実際の解析は、
analyze_disk
関数(124行目~175行目)を使っている。analyze_disk関数
マウント時の動作は、リモート側でも実行する必要があるため、
add_open_command
関数(14行目~19行目)で実行および記録する。与えられたデバイス
$the_disk
に対して、131: part_type=`parted -s $the_disk print | awk '/^Partition Table:/{print $3}'`でパーティションの種類を得ている。これがDOSパーティションなら、パーティション毎に分割し、それぞれに対して処理する必要がある。
134: add_open_command "kpartx -a -p $PSEP $the_disk" 135: add_close_command "kpartx -d -p $PSEP $the_disk"ここで、
kpartx
コマンドに対するオプション「-p 区切文字
」を指定していることに注意。例えば、/dev/VolGroup00/LogVolDomU
に対して、kpartx -a /dev/VolGroup00/LogVolDomU1を実行すると、パーティションごとに
/dev/mapper/LogVolDomU1 /dev/mapper/LogVolDomU1等のデバイスが作成されるが、元のデバイス名の最後が数字の場合、例えば
/dev/VolGroup00/LogVolDomU1
の場合は、/dev/mapper/LogVolDomU1p1 /dev/mapper/LogVolDomU1p1の様に区切文字「p」が挿入される。オプション「
-p 区切文字
」を指定すれば、どちらの場合も区切文字が挿入されるので都合が良い。なお、「kpartx -a -p 区切文字
」で作成したデバイスは、「-p
」を指定して「kpartx -d -p 区切文字
」としないと削除できない(この辺りの動作は、kpartx
のmanpageにも触れられていない)。136: while read device[$num] fs_type[$num] mount_point[$num]; do 137: ((num++)) 138: done <<EOF 139: $(parted -s $the_disk print | awk '/^ *[0-9]+ /{print $1" "$6" "$7}') 140: EOFこの部分は、一見
parted -s $the_disk print | awk '/^ *[0-9]+ /{print $1" "$6" "$7}' | while read device[$num] fs_type[$num] mount_point[$num]; do ((num++)) doneの様に書き直せそうだが、期待通りの動作とならない。なぜなら、
read
コマンドをパイプの後で使うと、read
コマンドがサブシェルで実行され、サブシェルの変数には代入されるが、元のシェルの変数には反映されないため。最終的に、
mount
コマンドでマウントされるデバイスにまで分割できたら、add_fs_table
関数(52行目~57行目)で記録しておく。ディレクトリ階層の高い順にマウントする必要があるため、すべてのマウントポイントを解析し終えてからマウントする(252行目~254行目)。ディスクイメージのマウント@リモートDom0
リモートDom0に対して、SSH経由でマウントを実行する。
258: ssh -T $remote_dom0 <<EOF 259: ##### COMMANDS FOR TARGET TO OPEN 260: `exec_open_commands | sed 's/-'$$'//'` 261: mkdir -p $target_prefix 262: `mount_fs_all $target_prefix | sed 's/-'$$'//'` 263: EOF入力がTTYでないことを明示するため、
ssh
コマンドには、「-T
」オプションを与えている。Rsyncによるバックアップ
266: rsync -avz --delete -e ssh $source_prefix/ $remote_dom0:$target_prefix引数「
$source_prefix/
」の最後のスラッシュは必須。省略すると、期待通りに動作しない。『A backup script for Xen DomUs, part 1』
『A backup script for Xen DomUs, part 2』
0 件のコメント:
コメントを投稿