プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

QNAP NAS のボリューム再構築

元々、QNAP の NAS (TS-251+) をファイルサーバーとして運用していたのですが、 以前の記事に書いたように 2台体制にして、相互でバックアップを取るようにしようと思い立ってから、かれこれ数か月が経ちました。

やっとある程度形になったので、設定内容をメモにまとめておきます。

構成検討

同じ QNAP 製の NAS でそろえた大きな動機の一つが、購入時のこちらの記事でも触れているように、既存の Netgear Ready Nas Ultra 2 の iSCSIターゲットのバックアップ体制がいまひとつだったためです。

QNAP だと ISCSI 領域を別の NAS にスナップショットとして保存できる機能があるので、不具合時に復旧が簡単かな?と思った次第です。 ちなみに Ready Nas Ultra 2 だとディスク全体をファイルとして保存することしかできませんでした。 もっとも、(調べてないですが)Netgear の NAS でも最新のなら、いろいろとあるのかもしれません。 そういう意味では機種選定のタイミングは大きいですね。

iSCSI に関するテストでわかったこと

さて、iSCSI 領域(LUN)のスナップショットを使いたいので、まずはいろいろと試してみました。

その際 iSCSI ターゲットに割り当てている LUN に対してスナップショットを作成して、スナップショットから iSCSI ターゲットとして復元しようとする際は、 一度、LUNを再作成する必要があることに気づきました。

今回の場合、これは、結構大きな問題になります。 というのも、iSCSI LUN のサイズ分、空き容量を用意しておかないと実際のトラブル時に復旧に支障がでるかもしれない、というためです。

もちろん、既存の(トラブルのあった)iSCSI LUN を削除すればよいのでしょうが、トラブル時は何があるかわかりませんので、 なるべくデータ復元や復旧の見通しが立つまでは元の領域には手をつけたくありません。

ということで、これを踏まえて構成を考えてみることにしました。

設定内容

NAS が2台あるといろんな構成が取れると思いますが、今回は上記を踏まえて、 1台はファイルサーバー(兼仮想マシン類のホスト)、1台はiSCSIターゲットにして運用します。

NAS1 NAS2
モデル QNAP TS-251+ QNAP TS-231P
HDD 4GB HDD x2, RAID1 2GB HDD x2, RAID1
用途 ファイルサーバー
Container Station
Virtualization Station
iSCSI ターゲット
ボリューム/LUN データボリューム(500GB, シック)
iSCSI LUN のスナップショット (スナップショットボールト)
データボリューム( 450GB, シン)
iSCSI LUN, 1.25TB(ブロックベースLUN, シン)
保護されるスナップショット領域 10% 10%

iSCSI ターゲットのある NAS2 は、データボリューム、iSCSI LUN ともに、シンとします。 iSCSI LUN は今のところ空き領域が大きい使い方のため、シックだともったいないかなと思うためです。

また、NAS2は、オーバーアロケーションになっています。

f:id:junichim:20181209201033p:plain

なので、警告はきちんと有効にして物理容量を超えないように気をつけないといけないです。 物理容量を超えてくるようになったら、容量の大きなHDDに交換とする予定です。

NAS1 のボリューム再構築について

さて、NAS2のほうは新規に購入したやつなので、領域だけ作って、あとは必要なデータをコピーすれば終わりです。 問題は、現在も運用中のNAS1ですね。

ボリュームサイズが無駄に大きいので、ボリュームを一度整理しました。 ここでは、その再構築の際に気づいたことを書いておきます。

あ、再構築作業の前にはくれぐれもバックアップをしっかりと取ってから行いましょう。

データボリューム

既存のNAS1のデータボリュームは、シックボリュームで、おおよそ1.3TBでした(スクリーンショット取り忘れました)。 でも、実際に使っているのは約300GB程度です。 無駄ですね。こちらの記事の際の作業で深く考えずにやってしまったミスですね。

なので、一度ボリュームを削除して、再作成します。 なお、このボリュームはシステムボリュームなので、必要があれば、こちらの記事などを参考に、元々の設定に戻しておきます(今回はアプリの再インストールのみでホームフォルダは再作成しませんでした)。

データボリューム再作成後は、

  • Web フォルダ(デフォルトフォルダのひとつ)の『ネットワークドライブの非表示』にチェックを入れる f:id:junichim:20181209202305p:plain
  • Public フォルダ(デフォルトフォルダのひとつ)に everyone read/write 権限を追加
  • データ保存用の共有フォルダの作成

などを行っておきます(自分用に便利に使うための設定でそれ以外の意図ではないです)。

Container Station

システムボリュームを再設定したため、システムボリュームにインストールされていたアプリケーションも削除されます。この一つが Container Station です。

復旧はこちらの記事にあるように、 Container Station のデータ領域を NAS1 に書き戻し後、そのフォルダを指定して Container Station を起動すればOKです。

Virtualization Station

Virtualization Station もシステムボリュームにインストールされるアプリのため、仮想マシンの再設定が必要です。 この仮想マシンの復旧が一番手間取りました。

本来は、仮想マシンを Virtualization Station からエクスポートしておき、システムボリューム再構築後、インポートするべきでした。これだとあっという間に終わったはずです、きっと。

でも、仮想マシンだからデータさえあれば簡単に復旧できるだろうとタカをくくって、エクスポート/インポートを試したり、それを使った検証をしていなかったためはまりました。

インポートについて

QNAP の Virtualization Station の場合、仮想マシンのインポートは

www.qnap.com

という形式のファイルしか受け付けてくれません。

で、仮想マシンフォルダに残っているのは .img ファイルのみでした(多分、仮想 Hdd イメージかな?)。

やられました。

.img ファイルからの復活について

まあ、同じようなことで困っている人はきっといるだろうと思って調べてみると、

VM image not recognized when importing - QNAP NAS Community Forum

やっぱりいました。

で、上記を参考に Virtualization Station で新規に仮想マシンを追加すると、設定画面で

f:id:junichim:20181209203649p:plain

おお、こんなオプションがあるんですね。

ここに、残っていた .img ファイルが保存されているフォルダを指定して、他のパラメータを入力していきます。

  • OS Ubuntu 16.04
  • メモリ 1GB
  • イメージ:既存のもの
  • NIC 追加

NIC の追加については、このVMがSoftEther VPN Server を動かすためのものであり、プロミスキャスモードのNICを割り当てるために行うものです。詳しくはこちらの記事を参考にしてください。

で、上記の設定を行ったVMを追加して起動したら、問題なく立ち上がりました。

バックアップ体制

最後にバックアップについてまとめておきます。

バックアップは Hybrid Backup Sync というアプリで行います。というのもバックアップ周りでQNAPに問い合わせしたら、Backup Station は古いから Hybrid Backup Sync 使え、と返事が来たためです。

まあ、設定する内容は Backup Station と大きく変わらないので、設定したことがあれば大丈夫かと思います。

今回は

  • Rsync による同期:NAS1 のデータフォルダ ---> NAS2 のバックアップ領域
  • LUNのスナップショットレプリカ:NAS2 の LUN ---> NAS1

となるように設定しました。 ほかにも念のため、お役目から解放されて余ってる Ready NAS Ultra 2 に定期的にデータをコピーしています。

まとめ

データなので、バックアップをとるのに時間がとられましたが、何度も設定を変えながらボリュームやLUNを作成・削除していると、 だんだんストレージの設定が柔軟だということの便利さ、というのがなんとなくわかってきました。

上記の作業も慣れればたいして手間のかからない作業です(データバックアップが一番時間がかかります)。 まあ、慣れたころにやらかすので、気をつけないといけないですが。

ご参考になれば。

trim_osc.py の更新失敗

OpenStreetmap のタイルサーバーの運用ですが、またエラーで更新が止まってしまいました。トホホ。

しかし、今回は、こちらの記事で設定したメール通知のおかげですぐに気づくことができたのが不幸中の幸いでしょうかね? ですが、実際に対応が完了するまでにおおよそ一か月以上かかってしまいました。せっかく通知が来たのに時間がかかるとは難しいもんですね。

一応、原因調査や対策時のメモを残しておきます。

症状

出力されていたエラーは次のようなものです。

[2018-10-29 22:06:01] 4620 start import from seq-nr 53056, replag is 27 day(s) and 14 hour(s)
[2018-10-29 22:06:01] 4620 downloading diff
[2018-10-29 22:17:43] 4620 filtering diff
Traceback (most recent call last):
  File "/home/osm/src/regional/trim_osc.py", line 131, in 
    for nd in root.xpath('//way[@id={}]/nd'.format(row[0])):
  File "src/lxml/lxml.etree.pyx", line 1587, in lxml.etree._Element.xpath (src/lxml/lxml.etree.c:61854)
  File "src/lxml/xpath.pxi", line 307, in lxml.etree.XPathElementEvaluator.__call__ (src/lxml/lxml.etree.c:178516)
  File "src/lxml/xpath.pxi", line 227, in lxml.etree._XPathEvaluatorBase._handle_result (src/lxml/lxml.etree.c:177421)
lxml.etree.XPathEvalError: Invalid expression
[2018-10-29 22:20:04] 4620 [error] Trim_osc error
[2018-10-29 22:20:04] 4620 resetting state
osm@map:/var/log/tiles$

詳細は置いといて、 trim_osc.py 内部の処理でこけているようです。

オープンソースなんでこちらを調べるのも一つの手なのですが、Githubのリポジトリを見ると、既にいくつかコミットがあります。なので、とりあえず最新版を pull して動作するか試してみます。

更新

ということで、更新します。

osm@map:~/src/regional$ git fetch
osm@map:~/src/regional$ git merge origin/master

試します。

[2018-10-09 09:06:02] 653 start import from seq-nr 53056, replag is 7 day(s) and 1 hour(s)
[2018-10-09 09:06:02] 653 downloading diff
[2018-10-09 09:07:13] 653 filtering diff
Traceback (most recent call last):
  File "/home/osm/src/regional/trim_osc.py", line 9, in 
    import psycopg2
ImportError: No module named 'psycopg2'
[2018-10-09 09:07:14] 653 [error] Trim_osc error
[2018-10-09 09:07:14] 653 resetting state

あれ?今度は別のエラーで落ちてます。

リポジトリを見ると

Force python3 · Zverik/regional@2271549 · GitHub

このコミットで python3 を使うようになったみたいです。 なるほど、多分、 psycopg2 の python3 用モジュールが無いんでしょうね。

ということで、python3 用モジュールをインストールしてやって再度試します。 ただし、 python3 のほうは pip 経由でモジュールをインストールしてみます(pipのほうがaptよりも新しいバージョンがインストールされるっぽいので)

mor@map:~$ sudo apt-get update
mor@map:~$ sudo apt-get install pip3
mor@map:~$ su - osm
osm@map:~$ pip3 install shapely
osm@map:~$ pip3 install psycopg2
osm@map:~$ pip3 install lxml

pip でのインストールの場合、ユーザーごとにインストールされるようなので、実際にデータの更新をしているユーザー(osm)に切り替えてインストールします。 なお、インストールしたモジュールは、最初に設定した時のものと同じです。

で、再度試してみると。。。あれ?同じくエラーがでますね。

trim_osc.py の調査と修正

さて、最新版にしただけだと、エラーが解決できなかったので、頑張って処理を追いかけてみました。

上述したように、最新のリポジトリ(この時点では、)にアップして、動かしたころ、

osm@map:~/tmp/osmosis_test3$ ~/src/regional/trim_osc.py -d gis -p region.poly -z -v changes.osc.gz trimed.osc.gz
/home/osm/.local/lib/python3.5/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: .
  """)
Traceback (most recent call last):
  File "shapely/speedups/_speedups.pyx", line 234, in shapely.speedups._speedups.geos_linearring_from_py
AttributeError: 'list' object has no attribute '__array_interface__'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/osm/src/regional/trim_osc.py", line 82, in 
    tpoly = poly_parse(options.poly)
  File "/home/osm/src/regional/trim_osc.py", line 42, in poly_parse
    result = Polygon(poly)
  File "/home/osm/.local/lib/python3.5/site-packages/shapely/geometry/polygon.py", line 240, in __init__
    ret = geos_polygon_from_py(shell, holes)
  File "/home/osm/.local/lib/python3.5/site-packages/shapely/geometry/polygon.py", line 494, in geos_polygon_from_py
    ret = geos_linearring_from_py(shell)
  File "shapely/speedups/_speedups.pyx", line 319, in shapely.speedups._speedups.geos_linearring_from_py
TypeError: object of type 'map' has no len()
osm@map:~/tmp/osmosis_test3$ 

のようなエラーになりました。

エラーが shapely の部分で起きていたので、ライブラリを apt でインストールしたものに切り替えても試したのですが、結論としては、微妙に呼んでるライブラリなどが違うけど、大筋同じエラーになっていました。

元に戻って、スタックトレースをよく見ていくと、trim_osc.py の引数で与えている領域指定のファイル(polyのファイル)の処理で落ちているようです。

とりあえずbounding box を使い、poly を迂回して実行できるか試します。

osm@map:~/tmp/osmosis_test3$ ~/src/regional/trim_osc.py -d gis -b 136.202763 34.482312 136.6553727 34.4756217  -z -v changes.osc.gz trimed.osc.gz
/home/osm/.local/lib/python3.5/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary ple
ase use "pip install psycopg2-binary" instead. For details see: .
  """)
Traceback (most recent call last):
  File "/home/osm/src/regional/trim_osc.py", line 161, in 
    for nd in root.xpath('//way[@id={}]/nd'.format(row[0])):
  File "src/lxml/etree.pyx", line 1577, in lxml.etree._Element.xpath
  File "src/lxml/xpath.pxi", line 307, in lxml.etree.XPathElementEvaluator.__call__
  File "src/lxml/xpath.pxi", line 227, in lxml.etree._XPathEvaluatorBase._handle_result
lxml.etree.XPathEvalError: Error in xpath expression

やはり落ちます。しかも、今回の作業のきっかけとなった最初のエラーと似たような箇所(xpath の処理)で落ちています。

ここまでの経緯を整理すると、最新版の trim_osc.py は2つの問題がありそうに思えます。

  • poly でポリゴンがつくれない
  • xpath でエラーになる

後者の xpath の問題は、今回のきっかけでも出てきましたね(まったく同じではないかもしれませんが)。

いろいろと調べると、どうも、昔、MLで指摘されていたようで、大きなファイルの場合 xpath に述語(predicate、四角いかっこでの指定)を与えて実行してもエラーとなる場合があったようです。

[lxml] lxml.etree.XPathEvalError: Invalid expression for correct XPath expression on large XML file

残念ながら、上記の ML では、問題の指摘以後、特に動きはなかったようです。

xpath 現象の確認

後者の問題を確かめるため、今回問題となった xml ファイルをダウンロードして、python3 のコンソールで同様にxpathを呼び出してエラーになるのを確認します。

その後、テキストエディタを使い、先頭の60行程度で別ファイルとして保存し、同じくコンソールで動かしてみると、同じようにxpathを指定しても正しく動きます。

ということで、ここはファイルサイズが大きい場合の xpath の述語の処理が怪しいと検討をつけ、 xpath の処理を述語を使わない形に修正しました(修正内容を Pull Request しておいたので、詳しくはそちらを参照)。 これで、動かすと、なんと、最後まで処理が進みました!

これで一個解決です。

ポリゴンファイルの確認

こちらの処理は

Polygon(poly)

という部分で落ちています。よくよく見てみると、python3 では mapの戻り値は map オブジェクトであり、listではないとのことです。 でも、Polygonのコンストラクタはtupleのリストが与えられることを想定しています。

きっとこれが原因ですね。

というわけで、poly を作るところで、

51c51
<             poly.append(map(lambda x: float(x.strip()), l.split()[:2]))
---
>             poly.append(list(map(lambda x: float(x.strip()), l.split()[:2])))

のように、map を list に変換して情報を格納するようにしたら、問題なく動作するようになりました。

めでたしめでたし。

余談

一応、上記の修正内容は Pull Request で送ってるのですが、今日時点(2018/12/4)でまだ取り込んでもらえていません。 まあ、進捗は GitHub上のリポジトリ を見ればわかるので、そちらを追いかけてください。

Windows, 共有リソースへの別ユーザー名でのアクセスについて

時々必要になって、毎回調べてるのでメモ書き残します。

※ こちらに書いてあることと同じです。

blog.livedoor.jp

困っていること

Windows 10 (他のバージョンでも同じはず)のエクスプローラとかで、ネットワーク上の共有フォルダを表示させる時にユーザー名・パスワードを入力するときがあると思います。

f:id:junichim:20181203093416p:plain

一度、ユーザー名を入力して、表示可能になると、別のユーザー名で表示させようとしても、最初に入力したユーザー名で接続されてしまい、どうすればユーザーを切り替えられるのか迷います。 なお、『資格情報を記憶する』にはチェックは入れていません。

状況確認

コマンドプロンプトで試してみます。

C:\Users\mor>net use \\homeserver /user:new_user_name
システム エラー 1219 が発生しました。

同じユーザーによる、サーバーまたは共有リソースへの複数のユーザー名での複数の接続は許可されません。サーバーまたは共有リソースへの以前の接続をすべて切断してから、再試行してください。

C:\Users\mor>

というエラーが表示されます。

これは、すでに共有リソースへの接続が存在しているために発生します。net use コマンドで表示させると、

C:\Users\mor>net use
新しい接続は記憶されます。


ステータス  ローカル名 リモート名                ネットワーク名

-------------------------------------------------------------------------------
OK                     \\homeserver\IPC$         Microsoft Windows Network
コマンドは正常に終了しました。

という感じですね。

解決方法

一度共有リソースを削除してやればよいとのことです。


C:\Users\mor>net use \\homeserver /delete
\\homeserver が削除されました。

再確認


C:\Users\mor>net use
新しい接続は記憶されます。

一覧にエントリが存在しません。


C:\Users\mor>

この状態で、再度エクスプローラから接続すると、再びユーザー名・パスワードの入力画面が表示されました。

めでたしめでたし。