2016年4月30日土曜日

システムバックアップその15

さて、続いてバックアップスクリプトをまとめる処理。

別に難しいことはやっていない。さくっとスクリプトを見てもらおう。
いつも通り、 sudo su - を忘れないように。

# vi 0000_backup
--内容ココから--
#!/bin/sh

BINDIR=`/usr/bin/dirname $0`
cd ${BINDIR}
BINDIR=`/bin/pwd`

DATETIME=`/bin/date +%Y%m%d%H%M%S`

${BINDIR}/0010_mount
${BINDIR}/0020_mkdir
if [ $? -ne 0 ]
then
  echo "Another backup is running or the last backup, has become an error."
  echo "Therefore, there is still a current directory."
  echo "Determine the cause and, take action."
  exit 1
fi
${BINDIR}/0030_create_config
${BINDIR}/0040_create_snapshot
${BINDIR}/0050_create_archive
${BINDIR}/0060_remove_snapshot
${BINDIR}/0070_get_fsmetadata
${BINDIR}/0080_rename_backup ${DATETIME}
${BINDIR}/0090_remove_oldarchive
${BINDIR}/0100_umount

--内容ココまで--
変わっているところとすれば、0020_mkdirを呼び出した後、リターンコードを確認しているところだ。
ファイルシステムのマウントに失敗していた場合は、その後の処理を実行するわけにはいかないので、エラーとして処理を中断させている。
他は特にエラートラップは仕込んでいない。全体的に、エラートラップが弱いので、必要に応じて足してくれ。
もう一箇所、最初の方で日付情報(YYYYMMDDhhmmss)14桁を取得して、それを0080_rename_backupに渡しているところか。
これは単純に、「バックアップ開始時点」の日時を当てたかっただけ。別に、「バックアップ途中時点」の日時でもいいんだけど、なんとなく。

これで実行してみれば、バックアップ処理が一通り流れるはずだ。
# ./0000_backup

後は、これまで手を抜いていたバックアップ対象ファイルシステムの設定ファイル(etc/fsconfig/*)を作って、バックアップ処理はおしまいだ。

今回はここまで。

システムバックアップその14

バックアップ処理もいよいよ大詰め。
次は、ファイルシステムのアンマウントだ。実のところ、バックアップスクリプト自体はこれで終了。
とは言え、まだ設定ファイルが / ファイルシステムしか対応していないし、リストア用のスクリプトも未着だ。
このまま、リストアスクリプトや、実際のリストア手順まで進めていく予定。

というわけでアンマウント処理。例によってスクリプトからだ。
いつも通り、 sudo su - して、スクリプトを作成しよう。
# cd
# cd backup/bin
# vi 0100_umount

--内容ココから--
#!/bin/sh

BINDIR=`/usr/bin/dirname $0`
BINDIR=`/usr/bin/realpath ${BINDIR}`
ETCDIR=`/usr/bin/realpath ${BINDIR}/../etc`

. ${ETCDIR}/config

/bin/umount ${BACKUPPOINT}

--内容ココまで--
どうだろう?ものすごくシンプルだ。
ぶっちゃけ、単純に${BACKUPPOINT}ディレクトリをアンマウントしているだけ。
解説も何も要らないだろう。

じゃ、いつも通り実行パーミッションを付与して実行してみよう。
# chmod +x 0100_umount
# ./0010_mount
# ./0020_mkdir
# ./0030_create_config
# ./0040_create_snapshot
# ./0050_create_archive
# ./0060_remove_snapshot
# ./0070_get_fsmetadata
# ./0080_rename_backup
# ./0090_remove_oldarchive
# ./0100_umount

多分、何も無く終了することだろう。

今回はコレでおしまい。
次は、これまで作ったバックアップスクリプトをまとめる処理だ。

システムバックアップその13

さて、次は「古いバックアップの削除」だ。
バックアップデータをどんどん蓄えていくと、HDDがいくらあっても足りないし、あまりにも古いバックアップは、利用価値がほとんど無い。
そのため、保持世代数を決めておいて、それより古い世代は、自動的に削除するようにしよう。

保持世代数に関しては、設定ファイル上で持っておいて、自由に変更が出来るようにしておきたい。
また、保持世代数はバックアップシステム全体に関する情報のため、バックアップシステムの設定ファイル( etc/config )に持つようにしよう。
いつもどおり、 sudo su - して、configファイルに追記しよう。
# cd
# cd backup/bin
# vi ../etc/config

--以下の内容を追記--
#
# NUMBERS:
# Backup retention number of generations.
# Backup in excess of this number of generations is automatically deleted.
#
NUMBERS=5

--追記ココまで--
変数名は、そのものズバリの${NUMBERS}だ。
中身を見てもらえば分かる通り、とりあえず5世代にしている。
バックアップサイズやバックアップ先の容量を見ながら、必要に合わせて変更して欲しい。
実際には、6世代目のバックアップが完了した後に、古い世代を消す、という処理になるため、バックアップ先には一時的に「保持世代数+1」のバックアップが格納される。その分の容量も見込んで決めて欲しい。
さて、スクリプト本体だ。
いつも通り記載する。
# vi 0090_remove_oldarchive
--スクリプトここから--
#!/bin/sh
 
BINDIR=`/usr/bin/dirname $0`
BINDIR=`/usr/bin/realpath ${BINDIR}`
ETCDIR=`/usr/bin/realpath ${BINDIR}/../etc`
 
. ${ETCDIR}/config
 
N=1
 
for i in `/bin/ls ${BACKUPPOINT} | /bin/grep -e "^[0-9]\{14\}$" | /usr/bin/sort -r`
do
  if [ ${N} -gt ${NUMBERS} ]
  then
    /bin/rm -rf ${BACKUPPOINT}/$i
  fi
 
  N=`/usr/bin/expr ${N} + 1`
done

--ココまで--
前半はいつも通りの変数読み込み。
先ほど設定した${NUMBERS}も、序盤で読み込まれる。
後半は、forループ。
ここでは、ループの条件を、
  • バックアップ先ディレクトリにあるファイル・ディレクトリ(/bin/ls ${BACKUPPOINT})
  • そのうち、数字14桁のみで構成されているファイル・ディレクトリ(/bin/grep -e "^[0-9]\{14\}$")
  • それらを、数字逆順で(/usr/bin/sort -r)
としている。
ぶっちゃけ、バックアップ先ディレクトリに、数字14桁のみのファイルが合った場合、それもバックアップディレクトリと同じ扱いにしている。本来なら、ディレクトリかファイルか?も判定する必要があるだろうけど、完全な手抜きだ。
また、数字14桁固定にしている。バックアップディレクトリは数字14桁のディレクトリ、と決め打ちしているんだ。
逆に言うと、長期保存しておきたいバックアップディレクトリは、数字14桁以外のディレクトリ名にしておけば、削除対象から排除され、手で削除しない限り永遠に残り続ける。

ループの前に1に初期化している変数${N}は、ループカウンタだ。
ループ後半のN=`/usr/bin/expr ${N} + 1`で1つずつカウントアップしている。

このループカウンタと、${NUMBERS}を比較して、ループカウンタ(${N})の方が大きい場合、保持世代数を超えた古いバックアップだと判断(if [ ${N} -gt ${NUMBERS} ])し、削除(/bin/rm -rf ${BACKUPPOINT}/$i)している。

ちょっと複雑に見えるが、実際に動かしてみると大したことはやっていないことが分かる。

出来上がったら、いつも通り実行パーミッションを付与して、動かしてみよう。
現時点では、過去のバックアップは1つしか無いはずだから、何も削除されないはず。
そのため、5回以上実行して、古いバックアップが削除されるのを確認してみよう。
# chmod +x 0090_remove_oldarchive
# ./0010_mount
# ./0020_mkdir
# ./0030_create_config
# ./0040_create_snapshot
# ./0050_create_archive
# ./0060_remove_snapshot
# ./0070_get_fsmetadata
# ./0080_rename_backup
# ./0090_remove_oldarchive
# ls -l /media/backup

(ここでは2世代残っているはず)
# ./0020_mkdir
# ./0030_create_config
# ./0040_create_snapshot
# ./0050_create_archive
# ./0060_remove_snapshot
# ./0070_get_fsmetadata
# ./0080_rename_backup
# ./0090_remove_oldarchive
# ls -l /media/backup

(ここでは3世代残っているはず)
# ./0020_mkdir
# ./0030_create_config
# ./0040_create_snapshot
# ./0050_create_archive
# ./0060_remove_snapshot
# ./0070_get_fsmetadata
# ./0080_rename_backup
# ./0090_remove_oldarchive
# ls -l /media/backup

(ここでは4世代残っているはず)
# ./0020_mkdir
# ./0030_create_config
# ./0040_create_snapshot
# ./0050_create_archive
# ./0060_remove_snapshot
# ./0070_get_fsmetadata
# ./0080_rename_backup
# ./0090_remove_oldarchive
# ls -l /media/backup

(ここでは5世代残っているはず)
# ./0020_mkdir
# ./0030_create_config
# ./0040_create_snapshot
# ./0050_create_archive
# ./0060_remove_snapshot
# ./0070_get_fsmetadata
# ./0080_rename_backup
# ./0090_remove_oldarchive
# ls -l /media/backup

(ここでは一番古い世代が消えて、5世代残っているはず)

どうだろうか?期待した動きはしているだろうか?
後は、元に戻して終わりだ。
# umount /media/backup

次は、いつもテストの最後に実行しているumountをスクリプト化するところだ。
今回はココまで。

Ubuntu 16.04 LTS リリースされてた

この4/21(日本時間4/22)に、Ubuntuの新しいリリース 16.04 LTS がリリースされてた。
http://www.ubuntu.com/
このLTSってのは、Long Term Supportの略で、2年に一回リリースされ、現時点では5年サポートを表明しているリリースだ。
LTSとLTSの間にリリースされるものは、サポート期間が短く、どんどんアップグレードしていくことを想定したリリースなので、色々実験していくのは楽しいが、本格運用には厳しかった。
その点、LTSなら長期間サポートがあり、セキュリティパッチ類もリリースされていくので、長期安定稼働を目指すには持って来いなのだ。

実は、今までは15.10というリリースを使っていたのだが、本当はLTSである16.04を待っていた。
ただ、待っているだけでは時間がもったいないので、まずは15.10を導入し、16.04が出た時点で入れ替えることを考えていた。
(そのため、あまり色々な実験はしてなく、システムバックアップを中心に実装してきていた。)

16.04がリリースされたので、本格的に実験を進めたいと思うが、今のシステムバックアップ・リストアに関する記事だけは整理しておきたい。
これまで書き溜めた分を一気に吐き出すのと、まだ書ききれていない部分を一気に書き上げて、その後は16.04に入れ替えることとする。

一応、このゴールデンウイーク中にそこまでは実施したいと思う。

いじょ。

2016年4月18日月曜日

システムバックアップその12

今度は、バックアップ取得先である current ディレクトリをその時の日時(YYYYMMDDhhmmss)に変更するスクリプトだ。
これはもう、スクリプト見てもらうしかない。(毎回書いているが、sudo su - を…)
# cd
# cd backup/bin
# vi 0080_rename_backup


--ココから--
#!/bin/sh

BINDIR=`/usr/bin/dirname $0`
BINDIR=`/usr/bin/realpath ${BINDIR}`
ETCDIR=`/usr/bin/realpath ${BINDIR}/../etc`

. ${ETCDIR}/config

if [ $# -eq 0 ]
then
  DATETIME=`/bin/date +%Y%m%d%H%M%S`
else
  DATETIME=$1
fi

if [ -e ${BACKUPPOINT}/current ]
then
  /bin/mv ${BACKUPPOINT}/current ${BACKUPPOINT}/${DATETIME}
fi

--ココまで--
新しい所は、「if [ $# -eq 0 ]」かな?
これは、「引数がゼロの場合」という意味だ。
これまで作っていたスクリプトと異なり、0080_rename_backup だけは引数を受け取る形にしている。
引数がある場合は、第1引数の文字列を${DATETIME}に代入、引数が無い場合は、「今の日時」を${DATETIME}に代入している。
そして、current ディレクトリの名前を ${DATETIME} に変更している。
ただこれだけだ。

ではいつも通り実行してみよう。
# chmod +x 0080_rename_backup
# ./0010_mount
# ./0020_mkdir
# ./0030_create_config
# ./0040_create_snapshot
# ./0050_create_archive
# ./0060_remove_snapshot
# ./0070_get_fsmetadata
# ./0080_rename_backup

動いたのが確認できたら、バックアップディレクトリを確認してみよう。
# ls -l /media/backup
今までの current ディレクトリではなく、日時(YYYYMMDDhhmmss)のディレクトリになっているのが確認できるはずだ。

これで問題なく完了だ。
今回は、このディレクトリを削除する必要は無い。このまま残しておこう。

次回は、古いバックアップ世代の削除、だ。

2016年4月8日金曜日

システムバックアップその11

今回は、ファイルシステムのメタ情報の取得だ。
特にリストア処理の中で使うわけではないが、念の為に取得している。
(実は、ext系ファイルシステムを使う上で、気をつけないといけない情報が、このメタ情報に記載されている。リストア処理の中で、この値をチェックしていないため、リストア時にこの値を見ておく必要があるかもしれない。)

例によって、先にスクリプトだ。(毎回書いているが、sudo su - を…)

# cd
# cd backup/bin
# vi 0070_get_fsmetadata


--内容ココから--
#!/bin/sh

BINDIR=`/usr/bin/dirname $0`
BINDIR=`/usr/bin/realpath ${BINDIR}`
ETCDIR=`/usr/bin/realpath ${BINDIR}/../etc`

. ${ETCDIR}/config

# Get Filesystem Metadata
for FSCONFIG in ${ETCDIR}/fsconfig/*
do
  VOLNAME=""
  USELVM=""

  . ${FSCONFIG}

  . ${BACKUPPOINT}/current/config/blkid/${VOLNAME}

  if [    x${TYPE} = "xext2" \
       -o x${TYPE} = "xext3" \
       -o x${TYPE} = "xext4" ]
  then
    if [ x${USELVM} = "xNo" ]
    then
      /sbin/tune2fs -l /dev/${VOLNAME} > ${BACKUPPOINT}/current/config/tune2fs/${VOLNAME}
    fi

    if [ x${USELVM} = "xYes" ]
    then
      /sbin/tune2fs -l /dev/${ROOTVG}/${VOLNAME} > ${BACKUPPOINT}/current/config/tune2fs/${VOLNAME}
    fi
  fi
done


--中身ココまで--
中身は大したことはしていない。
ファイルシステムが ext2/ext3/ext4 の場合に、対象のデバイスに対してtune2fs -lを実行しているだけだ。
実際に実行してみると分かるが、ファイルシステムの細かいパラメータが記載されている。
が、あまり気にしなくていい。

気にしておきたいのは、以下の2つのパラメータだ。
  • Maximum mount count:
    前回fsckを実行してから、マウント回数(Mount count:)がこの値を超えるてマウントする場合、自動的にfsckを実行する。
  • Check interval:
    前回fsckを実行してから、この日数を経過してからマウントする場合、自動的にfsckを実行する。
おそらく、前者は -1 、後者は 0 になっていると思う。
ext2/3/4系でファイルシステムを作成する場合は、この値に気をつけておいた方がいいだろう。
ちなみに、値を変更する場合は、前者は tune2fs -c 回数 デバイスファイル名(ex. tune2fs -c 20 /dev/vg-root/lv-root)、後者は tune2fs -i 日数 デバイスファイル名(ex. tune2fs -i 180 /dev/vg-root/lv-root)のようだ。

では実行してみよう。

# chmod +x 0070_get_fsmetadata
# ./0010_mount
# ./0020_mkdir
# ./0030_create_config
# ./0040_create_snapshot
# ./0050_create_archive
# ./0060_remove_snapshot
# ./0070_get_fsmetadata


問題なく動いたら、ファイルが作成されているか見てみよう。

# ls -l /media/backup/current/config/tune2fs

ぞろぞろとファイルが出てきたかと思う。
中身を見てみると、どのような感じか分かる。

# cat /media/backup/current/config/tune2fs/lv-root

こんな感じで、ext2/ext3/ext4 のメタ情報を取得している。
リストア等で何か問題があったら参照するようにしよう。

じゃぁ、いつも通りゴミ掃除をしてしまおう。

# rm -rf /media/backup/current
# umount /media/backup


次は、バックアップ取得先である current ディレクトリを、日付ディレクトリ(YYYYMMDDhhmmss)に変更する処理だ。
今回は以上。

2016年4月2日土曜日

システムバックアップその10

システムバックアップだけで既に10回目…。
今回作ったマシン、色々な実験をすることが目的であって、システムバックアップが目的じゃない。
システムバックアップは、実験をする上で絶対必須なので、書かざるを得ないというのが背景でココまで書いてきた。
最後まで書ききってから、実験ネタに入りたい。

さて、今度はスナップショットの削除だ。
例によってスクリプトを。
sudo su - して root 権限を取得しておくのを忘れないようにね。

# cd
# cd backup/bin
# vi 0060_remove_snapshot


--ココから--
#!/bin/sh

BINDIR=`/usr/bin/dirname $0`
BINDIR=`/usr/bin/realpath ${BINDIR}`
ETCDIR=`/usr/bin/realpath ${BINDIR}/../etc`

. ${ETCDIR}/config

# Remove Snapshot
for FSCONFIG in ${ETCDIR}/fsconfig/*
do
  VOLNAME=""
  USELVM=""

  . ${FSCONFIG}

  . ${BACKUPPOINT}/current/config/blkid/${VOLNAME}

  if [ x${USELVM} = "xYes" -a x${TYPE} != "xswap" ]
  then
    /bin/sync;/bin/sync;/bin/sync
    /sbin/lvremove -f ${ROOTVG}/${VOLNAME}.snap
  fi
done

--ココまで--
中身の作りは、スナップショット作成のスクリプトとほとんど同じだ。
スナップショット作成で使った lvcreate が、スナップショット削除の lvremove コマンドに置き換わっただけだ。
ただ、これまで一時的に作成したスナップショットを削除した時、「本当に削除していいか?」と聞かれたと思う。
スクリプトでそれを聞かれるのは非常に使い勝手が悪いので、「強制的に削除する」を意味する -f オプションを付与している。

さて、内部で使っている変数は、これまでに出てきたものと同じなので、これまで通り実行テストしてみよう。

# chmod +x 0060_remove_snapshot
# ./0010_mount
# ./0020_mkdir
# ./0030_create_config
# ./0040_create_snapshot
# ./0050_create_archive
# ./0060_remove_snapshot


最後に、「Logical volume "lv-root.snap" successfully removed」と出ただろうか?これで、スナップショットが削除されているはずだ。lvsコマンド等で確認してみよう。

最後に、例によって自動で作成されたファイルを削除して、元に戻しておこう。

# rm -rf /media/backup/current
# umount /media/backup


これでスナップショットの削除処理は完了だ。
今回はココまで。
次回は、ファイルシステムのメタ情報の取得だ。
これは、実はリストアでは必要無い。何かトラブルがあった時のための情報取得だ。