古くなったSATA SSDが時々リブートで見えなくなったり、ついには稼働中にI/Oエラーを起こしたりするようになったので交換することにしました。
新しいSSDにProxmox VEをクリーンインストールした後、ダメモトで旧ドライブをUSBマスストレージコントローラ経由で接続したところ、認識成功。見えているうちにデータを復元することにします。
仮想マシンの定義ファイルは /etc/pve/ 以下にあるのだが
Proxmox VE の仮想マシン定義ファイルは /etc/pve/nodes/{hostname}/qemu-server/ 以下にテキストの定義ファイルとして置かれています。これをバックアップするため以下のコマンドを実行しました。
cd /mnt/oldroot
tar cvzf ~/old.etc.pve.tar.gz ./etc/pve
cd ~
tar xvzf old.etc.pve.tar.gz
そうするとあら不思議... 空のディレクトリが。/etc/pve は普通のディレクトリではなく、pmxcfs による分散設定ファイルシステムになっています。実体は /var/lib/pve-cluster/config.db に保存されていました。
ドライブが読めなくなる前にDBファイルを保存します。
cd /mnt/oldroot
tar cvzf ~/old.var.lib.pve-cluster.tar.gz ./var/lib/pve-cluster
cd ~
tar xvzf old.var.lib.pve-cluster.tar.gz
sqlite3で覗いてみます。
% sqlite3 config.db SQLite version 3.51.0 2025-06-12 13:14:41 Enter ".help" for usage hints. sqlite> select * from tree; 0|0|46624809|0|1777877202|8|__version__| 6|0|7|0|1682337809|8|datacenter.cfg|keyboard: en-us 8|0|8|0|1682337874|4|virtual-guest| 9|0|9|0|1682337875|4|priv| 11|0|11|0|1682337875|4|nodes| 12|11|12|0|1682337875|4|pve| 13|12|13|0|1682337875|4|lxc| 14|12|14|0|1682337875|4|qemu-server| 15|12|15|0|1682337875|4|openvz| 16|12|16|0|1682337875|4|priv| 17|9|17|0|1682337875|4|lock| 24|0|25|0|1682337875|8|pve-www.key|-----BEGIN RSA PRIVATE KEY----- ...
なるほど、6つ目のフィールドがファイル名で、7つ目のフィールドにファイルコンテンツがあるだけの模様。ただ手作業でファイルをひとつひとつリカバリするのも面倒です。
opencode + Local LLM で DB 構造を解析させリカバリプログラムを書かせる
もう、やることが決まってしまった作業は退屈なだけです。
これぐらいのタスクなら軽量の Local LLM でも十分こなせます。外部のAPIサービスに投げない理由は、DBのなかにシークレットなどの情報が混ざっているかもしれないので、手許で推論します。
Mac に先の sqlite3 データベースをコピー、また適当に python venv を用意して、opencode を起動。プロンプトしました。推論にはローカル LM Studio で動く Qwen 3.6 35B-A3B を使用しました。
you will find config.db file which is in sqlite3 format. inspect its "tree" table and build a python script that recover files in the database. use venv/bin/python
呼吸していたら、動く recover.py が出てきました。(大したものでもないですが gist においておきます)
このスクリプトを実行したら確かに DB 内のファイルが recovered/ サブディレクトリに階層構造つきで書き出されました。
% find recovered recovered recovered/mapping recovered/mapping/directory.cfg recovered/authkey.pub recovered/pve-www.key recovered/sdn recovered/nodes recovered/nodes/pve recovered/nodes/pve/pve-ssl.pem recovered/nodes/pve/ssh_known_hosts recovered/nodes/pve/openvz recovered/nodes/pve/pve-ssl.key recovered/nodes/pve/lxc recovered/nodes/pve/qemu-server recovered/nodes/pve/qemu-server/237.conf recovered/nodes/pve/qemu-server/104.conf recovered/nodes/pve/qemu-server/105.conf recovered/nodes/pve/qemu-server/200.conf recovered/nodes/pve/qemu-server/102.conf recovered/nodes/pve/qemu-server/231.conf recovered/nodes/pve/qemu-server/103.conf recovered/nodes/pve/qemu-server/100.conf recovered/nodes/pve/qemu-server/249.conf recovered/nodes/pve/qemu-server/232.conf recovered/nodes/pve/qemu-server/245.conf recovered/nodes/pve/qemu-server/101.conf recovered/nodes/pve/qemu-server/235.conf ...
VM定義ファイルを新環境に展開
経験上、これで qemu-server/XXX.conf ファイルを書き込んであげればVMが出てくるのを知っています。
% cd recovered/nodes/pve/qemu-server/
% scp * "root@{PVE}:/etc/pve/nodes/pve/qemu-server/"
root@{PVE}'s password:
100.conf 100% 537 113.0KB/s 00:00
101.conf 100% 421 110.6KB/s 00:00
102.conf 100% 575 129.4KB/s 00:00
103.conf 100% 417 84.1KB/s 00:00
104.conf 100% 462 102.1KB/s 00:00
105.conf 100% 462 99.0KB/s 00:00
106.conf 100% 485 103.6KB/s 00:00
200.conf 100% 253 54.6KB/s 00:00
... qemu-server/XXX.conf が復元できれば、Proxmox VE は VM を再認識します。
Proxmox VE のコンソールを確認したところ、仮想マシンがホスト上に表示されるようになりました。
NVMeドライブ上のLVMプールを新環境に追加
仮想マシンのディスク本体は起動ドライブとは別の NVMe ドライブにあるので無事です。ただし、VM定義だけではディスク実体にアクセスできないため、NVMe上のLVM Volume Groupを新しい PVE 環境へ再登録します。
root@pve:~# pvesm add lvm NVMe1_ZP4000GM30023_SERIAL123 --vgname NVMe1_ZP4000GM30023_SERIAL123 \ --content images
ネットワーク設定も単純だったこともあり、過去のドライブ上のISOメディアやUSBデバイスの接続など、イレギュラーな設定が入っているものをのぞけば、これでVMが起動できるところまで復元できました。
古いドライブからVMを救出する場合
- 古いドライブを pvesm add lvm コマンドにて新しい名前で登録
(デフォルトの LVM 名がコンフリクトする) - sed などで VM定義のなかのディスクイメージのプール名を編集
- qm move_disk で新しいドライブへマイグレーションさせる
今回はこのニーズがないため、この記事では扱いません。
まとめ
Proxmox VE の仮想マシンデータのリカバリを、面倒くさい部分は生成AIで自動化して済ませました。仮想ディスク本体が別ストレージに残っている場合、VM定義ファイルを DB から抜き出してしまえば優勝です。
手間のかかる部分をスクリプト生成・実行で済ませたので何も困ることはありませんでしたが、復元作業よりも、このエントリを書くことのほうに時間がかかりました。
次の投稿ネタまでに、作業記録の記事化をどう自動化するかを考えたほうがいいのかもしれません。
0 件のコメント:
コメントを投稿