WalB
Cybozu製のバックアップOSS。
・用語集
- ldev
ログデバイス
- ddev
データデバイス
- wdev
ldevとddevをまとめたもの
- wlog
ldevの内容を書きだしたもの
- wldev
ldevをラップしているデバイス
Lから始まる
・WalBの導入
ここからはパブリックリポジトリの「walb-linux/walb-driver」ではなくプライベートリポジトリである「miyagaw61/walb」を使用していきます。
パス名など、ご注意ください。
install/clone
sudo apt -y update
sudo apt -y upgrade
sudo apt -y install git
sudo apt -y install gcc
sudo apt -y install make
sudo apt -y install linux-headers-`uname -r`
cd /path/to
git clone git@github.com:walb-linux/walb-driver
git clone git@github.com:walb-linux/walb-tools
uname -aの結果と照らし合わせ、適切なブランチに変更
cd /path/to/walb-driver
git branch -a
git checkout -b for-4.3 origin/for-4.3
make
cd /path/to/walb-driver/module
make
insmod walb-mod.ko
makeでwalb-mod.koが生成されるのでinsmodする。
ユーザランドツール「walbctl」の生成
cd /path/to/walb-driver/tools
make
ln -s walbctl /usr/local/bin/walbctl
カーネルモジュールの配置、modules.depの生成
生成したドライバを/lib/modules以下に配置する
sudo mkdir -p /lib/modules/`uname -r`/kernel/drivers/block/walb
cd /path/to/walb-driver/module
sudo cp -p walb-mod.ko /lib/modules/`uname -r`/kernel/drivers/block/walb/
depmodで、依存関係のリストを作成する
sudo depmod `uname -r`
・(depmod)
/lib/modules以下を走査して依存関係のリストを生成する。
そのリストは、/lib/modules/uname -r
/modules.depというパスになる。
modules.depに書かれた依存関係は、modprobe
コマンドでモジュールがロードされた時に解決される。
depmodについてはこちらを参考:http://kazmax.zpp.jp/cmd/d/depmod.8.html
modules.depについてはこちらを参考:http://kwkw.wiki.fc2.com/wiki/Linux%E3%81%AE%E3%82%AB%E3%83%BC%E3%83%8D%E3%83%AB%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB
walb-toolsのbuild
依存パッケージのインストール。
sudo apt -y install libaio-dev libsnappy-dev liblzma-dev zlib1g-dev
make。
この時 ENABLE_EXEC_PROTOCOL=1 を指定しないと、後述の -allow-exec オプションを使用できないので注意。
尚、オプション無しで make してしまった場合には、一度 make clean する必要がある。
cd /path/to/walb-tools
make -j 8 DEBUG=0 ENABLE_EXEC_PROTOCOL=1
binsrcディレクトリ内にバイナリ群が生成される。
次のコマンドでバイナリだけを/usr/local/binにシンボリックリンクを作成する。
cd walb-tools.git/binsrc
ls -F | grep -o ".*\*$" | sed -E "s/\*//g" | while read line; do sudo ln -s $(realpath $line) /usr/local/bin/$line ;done
pythonツールの導入
python2.7を導入。
sudo apt -y install python2.7
ツールのsetupを行う。
cd walb-tools.git/python
sudo python2.7 setup.py install
前提知識
論理ボリューム(LV)とは
walb-toolsのコマンド一覧
・walb-storage
-b: storageディレクトリを指定
-l: ログのパスを指定
-archive: archiveのIP:Portを指定
-p: 自身(storage)のlisten portを指定
-bg: 同時に実行できるバックグラウンドの最大タスク数
-proxy: proxyのIP:Portを指定
-fg: 同時に実行できるフォアグラウンドの最大タスク数
-id: ログに出てくる自身の名前
-allow-exec: execコマンドを受け付ける
・walb-proxy
-b: /mnt/tutorial/data/p0/
-l: /mnt/tutorial/data/p0.log
-p: 自身(proxy)のlisten portを指定
-bg: 同時に実行できるバックグラウンドの最大タスク数
-fg: 同時に実行できるフォアグラウンドの最大タスク数
-id: ログに出てくる自身の名前
-allow-exec: execコマンドを受け付ける
・walb-archive
-b: /mnt/tutorial/data/a0/
-vg: VGの名前を指定
-l: /mnt/tutorial/data/a0.log
-p: 自身(archive)のlisten portを指定
-fg: 同時に実行できるフォアグラウンドの最大タスク数
-id: ログに出てくる自身の名前
-allow-exec: execコマンドを受け付ける
walb-tools/doc/tutorial.ja.md
・umountせずにwalbc.del_restored
を実行したときのエラーメッセージが違う
未確認
2018-04-25 05:57:30.064 ERROR walbc error: c2aDelRestoredClient:child process has returned non-zero:1280
cmd:/sbin/lvremove
args:-f tutorial/wr_vol_4
stderr: Logical volume tutorial/wr_vol_4 contains a filesystem in use.
<<<STACKTRACE>>> 0x40ca69 0x427911 0x413790 0x4055e5 0x7fb2abcd3830 0x406a49
del-restored retry 0 command error ['/home/miyagaw61/src/github.com/miyagaw61/walb-tools/binsrc/walbc', '-id', 'ctl', '-a', 'localhost', '-p', '10200', 'del-restored', 'vol', '4'] 1
2018-04-25 05:57:31.097 ERROR walbc error: c2aDelRestoredClient:child process has returned non-zero:1280
cmd:/sbin/lvremove
args:-f tutorial/wr_vol_4
stderr: Logical volume tutorial/wr_vol_4 contains a filesystem in use.
<<<STACKTRACE>>> 0x40ca69 0x427911 0x413790 0x4055e5 0x7f685174a830 0x406a49
del-restored retry 1 command error ['/home/miyagaw61/src/github.com/miyagaw61/walb-tools/binsrc/walbc', '-id', 'ctl', '-a', 'localhost', '-p', '10200', 'del-restored', 'vol', '4'] 1
2018-04-25 05:57:32.131 ERROR walbc error: c2aDelRestoredClient:child process has returned non-zero:1280
cmd:/sbin/lvremove
args:-f tutorial/wr_vol_4
stderr: Logical volume tutorial/wr_vol_4 contains a filesystem in use.
<<<STACKTRACE>>> 0x40ca69 0x427911 0x413790 0x4055e5 0x7fc6866d5830 0x406a49
del-restored retry 2 command error ['/home/miyagaw61/src/github.com/miyagaw61/walb-tools/binsrc/walbc', '-id', 'ctl', '-a', 'localhost', '-p', '10200', 'del-restored', 'vol', '4'] 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/walblib/__init__.py", line 2574, in del_restored
self._del_snapshot(ax, vol, gid, False)
File "/usr/local/lib/python2.7/dist-packages/walblib/__init__.py", line 2564, in _del_snapshot
raise Exception(cmd + ': exceeds max retry times', ax.name, vol, gid)
Exception: ('del-restored: exceeds max retry times', 'a0', 'vol', 4)
・mergeとapplyに「手順」のネストを増やす、もしくは、「試してみる」と言及する
* 手順
* wdiffの一覧表示
mergeを試してみる。
* wdiff の一覧表示
TEST
・ddの仕様変更(もしくはtypo)
1m
1M
・typo
(誤)
sudo pvcreate test /dev/loop0
sudo pvcreate vg0 /dev/loop1
sudo pvcreate vg1 /dev/loop2
sudo pvcreate vg2 /dev/loop3
(正)
sudo pvcreate /dev/loop0
sudo pvcreate /dev/loop1
sudo pvcreate /dev/loop2
sudo pvcreate /dev/loop3
コードリーディング
・ディレクトリ構造
scenario0.py
シナリオ0のスクリプト
stest_util.py
stestのためのutil
common.py
汎用的なライブラリ
config0.py
stestを行うための環境を自動で決め打ちで作成してくれるスクリプト
・stest:引数無実行でエラー
wdev.format_ldev()
で失敗してるっぽい
$ sudo python2 scenario0.py
count 1
test ['n1', 'n2', 'n3', 'n4b', 'n5', 'n6', 'n7', 'n8', 'n9', 'n10', 'n11a', 'n11b', 'n12', 'n13', 'n14', 'm1', 'm2', 'm3', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9', 'e10', 'e11', 'e12', 'e13', 'e14', 'e15', 'e16', 'e17',
'r1', 'r2', 'r3', 'r4']
useTp False
packet-repeater: no process found
walb-storage: no process found
walb-proxy: no process found
walb-archive: no process found
Traceback (most recent call last):
File "scenario0.py", line 1425, in <module>
main()
File "scenario0.py", line 1411, in main
setup_test(useTp)
File "/home/miyagaw61/src/github.com/taisei-miyagawa/walb-tools/stest/common.py", line 65, in setup_test
recreate_walb_dev(wdev)
File "/home/miyagaw61/src/github.com/taisei-miyagawa/walb-tools/stest/common.py", line 320, in recreate_walb_dev
wdev.format_ldev()
File "/usr/local/lib/python2.7/dist-packages/walblib/__init__.py", line 841, in format_ldev
self.run_wdevc(args)
File "/usr/local/lib/python2.7/dist-packages/walblib/__init__.py", line 820, in run_wdevc
return self.runCommand([self.wdevcPath] + cmdArgs)
File "/usr/local/lib/python2.7/dist-packages/walblib/__init__.py", line 190, in run_local_command
stderr=stderr, close_fds=True)
File "/usr/lib/python2.7/subprocess.py", line 711, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1343, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
config0.py
を読むとわかるが、
・./stest/tmp/s0
・./stest/tmp/s1
・./stest/tmp/s2
・./stest/tmp/p0
・./stest/tmp/p1
・./stest/tmp/p2
・./stest/tmp/a0
・./stest/tmp/a1
・./stest/tmp/a2
を事前に作成しておく必要がある。
$ sudo mkdir -p ./stest/tmp/{s0,s1,s2,p0,p1,p2,a0,a1,a2}
再び実行
$ sudo python2 scenario0.py
count 1
test ['n1', 'n2', 'n3', 'n4b', 'n5', 'n6', 'n7', 'n8', 'n9', 'n10', 'n11a', 'n11b', 'n12', 'n13', 'n14', 'm1', 'm2', 'm3', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9', 'e10', 'e11', 'e12', 'e13', 'e14', 'e15', 'e16', 'e17',
'r1', 'r2', 'r3', 'r4']
useTp False
packet-repeater: no process found
walb-storage: no process found
walb-proxy: no process found
walb-archive: no process found
Traceback (most recent call last):
File "scenario0.py", line 1425, in <module>
main()
File "scenario0.py", line 1411, in main
setup_test(useTp)
File "/home/miyagaw61/src/github.com/taisei-miyagawa/walb-tools/stest/common.py", line 65, in setup_test
recreate_walb_dev(wdev)
File "/home/miyagaw61/src/github.com/taisei-miyagawa/walb-tools/stest/common.py", line 320, in recreate_walb_dev
wdev.format_ldev()
File "/usr/local/lib/python2.7/dist-packages/walblib/__init__.py", line 841, in format_ldev
self.run_wdevc(args)
File "/usr/local/lib/python2.7/dist-packages/walblib/__init__.py", line 820, in run_wdevc
return self.runCommand([self.wdevcPath] + cmdArgs)
File "/usr/local/lib/python2.7/dist-packages/walblib/__init__.py", line 190, in run_local_command
stderr=stderr, close_fds=True)
File "/usr/lib/python2.7/subprocess.py", line 711, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1343, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
同じエラー。
ソースコードを読み進めるとわかるが、./binsrc
も必要らしい。
ということで、../binsrc
を./binsrc
にコピー。
walb-tools/stest/tmp/{s0,s1,s2,p0,p1,p2,a0,a1,a2}
は実行すると消えるため、再び作成。
$ cp -a ../binsrc/ ./
$ sudo mkdir -p ./stest/tmp/{s0,s1,s2,p0,p1,p2,a0,a1,a2}
再び実行。
$ sudo python2 scenario0.py
count 1
test ['n1', 'n2', 'n3', 'n4b', 'n5', 'n6', 'n7', 'n8', 'n9', 'n10', 'n11a', 'n11b', 'n12', 'n13', 'n14', 'm1', 'm2', 'm3', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9', 'e10', 'e11', 'e12', 'e13', 'e14', 'e15', 'e16', 'e17',
'r1', 'r2', 'r3', 'r4']
useTp False
packet-repeater: no process found
walb-storage: no process found
walb-proxy: no process found
walb-archive: no process found
2018-05-02 08:48:49.631 ERROR wdevc:open failed: /dev/walb/control (throwOpenError:48) <libc_error> 2 No such file or directory
Traceback (most recent call last):
File "scenario0.py", line 1425, in <module>
main()
File "scenario0.py", line 1411, in main
setup_test(useTp)
File "/home/miyagaw61/src/github.com/taisei-miyagawa/walb-tools/stest/common.py", line 65, in setup_test
recreate_walb_dev(wdev)
File "/home/miyagaw61/src/github.com/taisei-miyagawa/walb-tools/stest/common.py", line 321, in recreate_walb_dev
wdev.create()
File "/usr/local/lib/python2.7/dist-packages/walblib/__init__.py", line 863, in create
self.run_wdevc(args)
File "/usr/local/lib/python2.7/dist-packages/walblib/__init__.py", line 820, in run_wdevc
return self.runCommand([self.wdevcPath] + cmdArgs)
File "/usr/local/lib/python2.7/dist-packages/walblib/__init__.py", line 194, in run_local_command
raise Exception("command error %s %d\n" % (args, ret))
Exception: command error ['/home/miyagaw61/src/github.com/taisei-miyagawa/walb-tools/stest/binsrc/wdevc', 'create-wdev', '/dev/test/log', '/dev/test/data', '-n', '0'] 1
相変わらずエラーは出るがエラーメッセージは変わった。
久しぶりにやったらエラーが変わってた
$ sudo python2 scenario0.py
[sudo] password for miyagaw61:
count 1
test ['n1', 'n2', 'n3', 'n4b', 'n5', 'n6', 'n7', 'n8', 'n9', 'n10', 'n11a', 'n11b', 'n12', 'n13', 'n14', 'm1', 'm2', 'm3', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9', 'e10', 'e11', 'e12', 'e13', 'e14', 'e15', 'e16', 'e17',
'r1', 'r2', 'r3', 'r4']
useTp False
packet-repeater: no process found
walb-storage: no process found
walb-proxy: no process found
walb-archive: no process found
/dev/test/log does not exist.
あ、これまた最初からディスク用意しないといけないやつか...
$ cd ~/docs/walb-stest
$ sudo losetup /dev/loop0 disk0
$ sudo losetup /dev/loop1 disk1
$ sudo losetup /dev/loop2 disk2
$ sudo losetup /dev/loop3 disk3
$ sudo pvcreate /dev/loop0
すでにtestに紐づいてるよ
VGは消えないのか。
$ cd walb-tools.git/stest/
$ sudo python2 scenario0.py
あれ?エラー出ずに終わった。
・./stest/tmp/s0.log
・./stest/tmp/s1.log
・./stest/tmp/s2.log
・./stest/tmp/p0.log
・./stest/tmp/p1.log
・./stest/tmp/ ・
./stest/tmp/
・./stest/tmp/ ・
./stest/tmp/
・./stest/tmp/ ・
./stest/tmp/
・./stest/tmp/ ・
./stest/tmp/
・`./stest/tmp/
原因判明!!
insmod walb-mod.koをせずにstestを実行するとこのエラーが出るっぽい!!
指摘
Pythonのソースコード追いかける以上の確認手段が無いのでPython側のライブラリリファレンスもあればという所ですね...
わかります
全体を通して思ったことは割とソースコードを追わなければ分からない部分が多かった点と, Pythonリファレンスとは別にステート移動用の関数についての説明が別に欲しいという点です.
わかります
・exec protocol commandが実行出来ないために手順が進まなかった.
exec protocol commandとは...?
-allow-execのRCEのアレらしい。完了。
* ServerクラスがServerParamsの2クラスへと変更されていることで, ある程度__init__.pyを内容まで含めて読む必要があった
* Deviceクラスの最初の引数の意図(name引数→何の名前?)がチュートリアルからは分からなかった.
walblibのコードはまだ読んでいないのでこの疑問は抱きませんでした。
* ボリュームの初期化の節ではs0をstandby状態にしているが, その直後の状態の確認の節で確認した際に見えるproxy, archiveがそれぞれClearのままで混乱した.
コードが一行かかれているだけなのでそこまでわかりませんでした。
* フルバックアップはwalbc.stop(s0, VOL)だけではstorageがSyncReadyになるだけなので, Archiveも操作しなければならないことを明示しておらず, ここも分からなかった.
Archiveは操作しませんでした
https://github.com/walb-linux/walb-tools/blob/master/doc/prepare-wdev.md
Deviceクラスの第一引数の説明が古いです. (nameであるべき所がIDになっている)
https://github.com/walb-linux/walb-tools/blob/master/doc/python.md
任意のコマンド実行については現在デフォルトで制限されている旨を書いたほうが良いかなと
https://github.com/walb-linux/walb-tools/blob/master/doc/server-config.md
チュートリアルと同じくPython部分の情報が古いです
tutorial.ja.md以外のドキュメントの話。
https://github.com/walb-linux/walb-tools/blob/master/doc/spec.md
基本的に説明がソースコードを読むことに投げられているので, 簡単にでも--helpオプションの実行結果なんかに変えたほうが良い気がします(いずれにせよ詳細な説明があるのであれば良いと思います.)
コードの話。
https://github.com/walb-linux/walb-tools/blob/master/doc/term.md
確か用語一覧ファイルについてはtutorial.mdではword.mdとされる予定だったのでは.
tutorial.mdにはword.mdの記述はありませんでした
tutorial.ja.mdにはありましたが、未完だったので作るとよさそうです。
* ipythonを用いてチュートリアルを進めていますが, 私は最初このipythonを終了しても良いものかどうかの判断が付きませんでした. 自動化するにはpythonコードでconfig, 実行出来るのは非常に良いインターフェースだと思いますが, これがあくまでインターフェースであると理解してもらうには「どこからどこまでをPythonが触っているのか」を明らかにならないとわからないと思います.
完了
* 内部的な話ですが, Pythonのコードとして__init__.pyに全て直書きするのは一般的にもあまりよくない形だと思われます. コード自体は綺麗に書かれているように思うので, 単にクラスごとにファイルを分ける程度でも良いのでリファクタリングしたほうが良いと思います. (同時にPython3への対応もやりやすくなります. )
わかります(しかしコードの話)。
* walblibは実際にちゃんと区分けしようとするとグローバル変数で依存しているものがいくつも存在するので, 片手間でリファクタリングするのは少し危なそう.
たしかに
・