freebsd vm-bhyveメモ

FreeBSD bhyveを使用したvm-bhyve+ZFSを使ったxenserverからの移行に関するメモ、ということでメモベースで。VMware ESXiやxenserverなどでも同様のことができますが、あちら様は営利企業なのでどうしてもお金を稼がないといけないところがあり必要であれば技術は隠します。とはいえ、さすがにxenserver 7.0マシンを放っておくわけには行かなくなったのでFreeBSD vm-bhyve+ZFSにマイグレします。Linuxでは同様の技術にKVMがありますが、これを使わないのは情報は多く出回るにしろ頻繁に使用技術・ソフトが流行り廃りに影響されて年単位で移りゆく恐れがあるからです。そのたびに覚え直すのはめんどい。
FreeBSD bhyveの弱点はBIOSを持たないことなので、ほぼamd64/EFIで起動できるOS決め打ちです。たとえば2001年に発売されたWindows XPはMBRで整理されたパーティションを利用することが前提であり、EFI環境下では使用することはできません。※2021年04月現在では一部OSでのi386環境の起動が可能なようです。公式サイトを確認しましょう。

使用にあたってのイニシャライズ(vm init)やめぼしい部分(/etc/rc.conf、vm switch)についてはGoogle検索ができれば解決できると思われるので暇でもない限りずっと書けないかもしれない。


■ホストマシン再起動時に共通switchがうまく立ち上がらない:例えば仮想マシン間はOK、インターネットやホストマシン含めた物理マシンにpingしても応答がない
→bridgeに正しくホストマシンの物理イーサネットデバイスが追加されていない恐れがある。確認項目としては、/path/to/vm/.config/system.confにおける下記の内容について書き換える。(ここではホストマシンの物理インタフェースをem0とする)

# vm switch add bhyve-public em0 実行時の/path/to/vm/.config/system.conf
01: switch_list="bhyve-public"
02: type_bhyve-public="standard"
03: ports_bhyve-public="public em0"

これを書き換える
01: switch_list="bhyve-public"
02: type_bhyve-public="standard"
03: ports_bhyve-public="em0"

お好みの方法で再起動して、ifconfigコマンドで確かめる。
# shutdown -r now
# reboot
# init 6

01: # ifconfig vm-bhyve-public
02: vm-bhyve-public:
03: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
04:    ether ho:ge:ho:ge:ho:ge
05:    id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
06:    maxage 20 holdcnt 6 proto stp-rstp maxaddr 2000 timeout 1200
07:    root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
08:    member: tap0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
09:            ifmaxaddr 0 port 4 priority 128 path cost 2000000
10:    member: em0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
11:            ifmaxaddr 0 port 1 priority 128 path cost 55
12:    groups: bridge vm-switch viid-e1093@
13:    nd6 options=9<PERFORMNUD,IFDISABLED>


08行目から11行目までみたいに起動しているゲストマシンとホストマシンの物理イーサネットデバイスが表示されていれば成功。ゲストマシンから物理ネットワークのマシンにpingして確かめるのもあり。

上記を見る限り、switch_listにおけるパラメータ:bhyve-publicは02行目および03行目のtype_{switch_name}やports_{switch_name}となるので、そもそも論publicパラメータが入ってくるのは何らかおかしいのかもしれない。


■PCIパススルーで関わるコマンド、ファイルとか。
01: pciconf -lvコマンドでパススルーすべきPCIデバイスを調査し
02: /boot/loader.confにパラメータpptdevs="1/0/0 2/0/0"などの形で書く。128バイトを超えるようならpptdevs1="3/0/0"などとする。グラフィックボードの場合、HDMIデバイスも付いてくるはずなので、まとめてパススルーしておく。しないと失敗する。
03: ここでホストマシンを再起動しておく
04: vm-bhyveの各ゲストマシンのコンフィグにpassthru0="1/0/0"、passthru1="2/0/0"などと書く。/boot/loader.confのpptdevsオプションみたいに複数を同時に書くことはできない。グラフィックボードなど複数の機能を持つのPCIデバイス場合は関連する全てを同一ゲストマシンにパススルーする。(12.2R/amd64ではintel GPUのみできそうだ)
05: vm stop guest-machine-name等で対象のゲストマシンを完全に停止させてから、vm start -f guest-machine-nameなどで起動してみて、pciconf -lvで狙いのPCIデバイスがパススルーできたか確認する。
詳細な記法については他のサイトを見れば分かると思うし、時間があればまとめておきたいなー見たいのはある。けどやらない。
参考にしたURL等:
https://wiki.freebsd.org/bhyve/pci_passthru


■一度設定したsparse-zfsボリュームのサイズ変更を行い、vm-bhyve上のFreeBSDに反映させる。

01: 対象となるFreeBSD VMを落とす。その後vm listコマンド等で対象のVMがStoppedになっていることを確認する。
# vm stop fbsd_vm
※ACPIによりStoppedにならない場合はvm poweroff fbsd_vmなどで強制的に落とせるが…
# vm list

02: sparse-zfsボリュームがdevであればgeomに変更する。下記コマンドではvolmodeはdev
# zfs get volmode zroot/vm/fbsd_vm/disk0.img
NAME                           PROPERTY  VALUE    SOURCE
zroot/vm/fbsd_vm/disk0.img  volmode   dev      local
下記コマンドでgeomに変更する。
# zfs set volmode=geom zroot/vm/fbsd_vm/disk0.img
VMがきっちりシャットダウンできていれば、この時点でgpart showコマンドが通るはず。ダメだったらホストマシンを再起動する。
# gpart show /dev/zvol/zroot/vm/fbsd_vm/disk0.img


03: sparse-zfsボリュームのサイズを変更する。
下記のコマンドで現在のサイズを確認する
# zfs get volsize zroot/vm/fbsd_vm/disk0.img
NAME                           PROPERTY  VALUE    SOURCE
zroot/vm/fbsd_vm/disk0.img  volsize   20G      local
下記のコマンドで40Gに増やす
# zfs set volsize=40g zroot/vm/fbsd_vm/disk0.img


04: この時点でzroot/vm/fbsd_vm/disk0.imgが壊れている判定になるので、リカバリーを行う。行わないとこの後のgpartコマンドによる編集が通らない。またここまでにVMがきっちりPowerOffになっていないとこのコマンドも通らない。
# gpart recover /dev/zvol/fbsd_vm/disk0.img

05: gpartコマンドを使用して、sparse-zfsボリュームのパーティション情報を変更する。
ここでは下記のようにパーティションが切られており、freebsd-ufsを36Gへ、その他をfreebsd-swapに割り当てるものとする。
vtbd0p1: freebsd-boot  512k
vtbd0p2: freebsd-ufs  18G
vtbd0p3: freebsd-swap  2G

まず、vtbd0p3のswapパーティションを消す。
# gpart delete -i 3 /dev/zvol/zroot/vm/fbsd_vm/disk0.img

次にvtbd0p2のfreebsd-ufsを36gにリサイズする。
# gpart resize -i 2 -s 36g /dev/zvol/zroot/vm/fbsd_vm/disk0.img

最後に未割り当ての領域をswapパーティションにする。
# gpart add -t freebsd-swap /dev/zvol/zroot/vm/fbsd_vm/disk0.img

06: fbsd_vmをシングルユーザモードで起動する。
デフォルトでは3秒しか待機時間がないので急いで2を押す
# vm start -f fbsd_vm

07: growfs vtbd0p2コマンドを実行し、しばらく待つ。


■passthruにて、vm-bhyveホストのPCIバスナンバーから別のPCIバスナンバーへ変更する。
passthru0="1/0/0=0:8"


■実マシンからbhyveマシンへデータをコピーする
※特定のディスクデバイス、パーティションとしてマウントされている場合は・・・
LiveCDなどでIPネットワークに接続してから・・・
send# dump -0 -a -f - /path/to/disk/partition | nc -l RECV_IPADDR PORT_NUM
recv# nc -l PORT_NUM -w 120 | restore -rvf -

recv側から先に実行し、展開先にcd移動して120秒以内にsend側のコマンドを実行する。

※ZFSであれば・・・
send# zfs send -r pool@snapshot | nc RECV_IPADDR PORT
recv# nc -l PORT_NUM -w 120 | zfs recv POOL-NAME/PATH



※特定のディレクトリのデータを転送する場合は・・・
send # tar cf - ./ | nc RECV_IPADDR PORT_NUM
recv # nc -l PORT_NUM -w 120 | tar xf - ./


この記事は以上、時々更新するかもしれない。

Python3:空白で区切られた文字列を元にforeachループする

個人的にはかなり使用頻度の高いループ文なので、シェルスクリプトとPython3.7.9と対比させながら進めます。FreeBSDの用語を使用している可能性がありますが、自分用なので特に書き換えは考えていません。なお、foreach文とは書いていますが、シェルスクリプトでもpythonでもforeachと書かないみたいです。ですが一般的にはこちらのほうが通りが良いためあえてforeach文と書きます。

■前提
変数countryには"america brazil china"の文字列が入っています。
これをameria、brazil、chinaの文字列に分割しつつ、ループ文で表示できればこの記事の目標は達成。

■モデル(シェルスクリプト)
01: $ cat country.sh
02: #!/bin/sh
03:
04: country_string="america brazil china"
05:
06: for args in `echo ${country_string} | tr ' ' '\n'`
07: do
08:     echo ${args}
09: done

10: $ sh country.sh
11: america
12: brazil
13: china

シェルスクリプトは環境変数IFS値によってデリミタが異なります。通常では改行(\n)やタブなどが含まれているのでそれをデリミタに使用できる他、IFS値を再設定することにより変更することができます。しかしながら、環境変数のデフォルト値はできるだけ変更しないほうが良いと思われる他、trコマンドにより半角空白をそのままUNIXの改行コード(\n)に変更してしまう手が使えるので、echoコマンドでcountry_string値を出力しパイプでつなぎ、直接入力を半角空白から改行へ書き換えることで、IFS値で分離できる形に変えています。なお、"`"はバッククォートで、その中でシェルコマンドを実行する事ができます。バッククォートで囲まれたコマンドは、その実行結果に置き換えすることができます。
for args in 〜は、環境変数IFS値を元にスプリットした文字を変数argsに代入します。これはdo〜doneの間で使用することができます。今回の場合echo ${args}となっており、単純に出力するだけですが、これがecho "country: ${args}"とすると、1回めのループでは"country: america"と出力されるはずです。

■書き換え(Python3)
01: $ cat country.py
02: country_string="america brazil china"
03:
04: for args in country_string.split(" "):
05:     print( args )
06: $ python3.7 country.py
07: america
08: brazil
09: china


Python3でもforeach文の記法は変わりませんが配列の代わりに文字列をそのまま配列に変換するテクニックが必要になりますので、文字列.split(デリミタ)というようなsplit関数が必須となります。行数としてはこちらのほうが短いので使う分にはシェルスクリプトよりは楽かもしれません。

この記事は以上です。
必要に応じて追記見込みです。

FreeBSD 13-CURRENT(2020年12月)ぐらいにあったsubversion→git切り換えのメモ

詳しい説明等はなんとなく理解してから。
ソースコードのコミッターではなく、CURRENTなソースをコピーして使用するユーザ向け。

■subversion時代のsrcは削除。
# cd /usr/src
# rm -dRv ./* ./.arc* ./.git* ./.c*

■FreeBSD CURRENTのコピー(svnliteコマンドで言うところのsvnlite checkout https://svn.freebsd.org/src/head/)
# cd /usr/src
# git clone https://git.freebsd.org/src.git .
# git config --global pull.ff only

■初回のコピー以降の更新(svnliteコマンドで言うところのsvnlite update)
# cd /usr/src
# git pull


関係URL等
https://wiki.freebsd.org/git
https://github.com/bsdimp/freebsd-git-docs/blob/main/URLs.md
https://github.com/bsdimp/freebsd-git-docs/blob/main/doc-cvt.md
 → Keeping currentを参照

■参照するブランチの切り換え
https://qiita.com/sunstripe2011/items/53ae4184d021e927b3f3

pip@Python3.7/FreeBSDのメモ

python3.7のpipコマンド関係で個人的覚えておきたい事関係。やれるところはできるだけ追加パッケージなしに行いたいところ、FreeBSDを優先するので他で動く保証はない。他で動かすことがあれば別にメモるかもしれないです...また、現行の知識から理解するため、FreeBSD特有の用語を使用したメモを書いている場合もあります。


■ドキュメント
https://pip.pypa.io/en/stable/ (英語)
https://pip.pypa.io/en/stable/reference/ (pipコマンド各オプションのman相当)

■ヘルプを見る
$ pip help
pipコマンドのヘルプ。全てに言えることだが、Generalを常に表示してくれるため、だいたいlessコマンドなどと併用することになる。

$ pip <pipのコマンド> -h
pipのコマンド(install, show, list, search, ...)のオプションを見る。


■パッケージのインストール
$ pip install <パッケージ名>
パッケージのインストール。pkg install <パッケージ名>とほぼ同じ。


■パッケージを検索する。
$ pip search <パッケージ名>
pipのリポジトリで登録されているパッケージを検索する。pkg search <パッケージ名>と同じようにパッケージ名に文字が含まれれば出力されるはずなのだが、現状何をしてもエラー判定となるため、追加で設定が必要かもしれない。


■インストール済みパッケージのアップデート
$  pip list -o | sed -n '3,$p' | cut -f1 -d' ' | xargs -I% pip install -U %
pipコマンドにはpkg upgrade相当のコマンドはないが、pip list -oコマンドによりアップデートできるパッケージが表示されるので、これをシェルスクリプトによるワンライナーでテキスト加工する。バージョンによってはpip upgradeコマンドが存在するらしいのだが、FreeBSD12.2R/Python3.7.9ではエラーが返ってきてしまった。

user@freebsd:~ % pip list -o
Package            Version Latest Type
------------------ ------- ------ -----
chardet            3.0.4   4.0.0  wheel
idna               2.10    3.0    wheel
importlib-metadata 2.1.1   3.3.0  wheel


通常のpip list -oコマンドの出力は上記のような感じ。意味合いとして最新版になっていないものだけ表示するというもの。なお、-oオプションは--outdateで置き換え可能。

user@freebsd:~ % pip list -o | sed -n '3,$p'
chardet            3.0.4   4.0.0  wheel
idna               2.10    3.0    wheel
importlib-metadata 2.1.1   3.3.0  wheel


項目行を抜くために sed -n '3,$p'コマンドを入れる。sedコマンドで3行目以降を出力させる。
  sed → コマンド
  -n → 出力コマンド以外の出力を行わない(後述のpオプションと併用が前提)
  '3,$p' → 3行目から最終行を指定


user@freebsd:~ % pip list -o | sed -n '3,$p' | cut -f1 -d' '
chardet
idna
importlib-metadata


1列目を抜き出したいので、cut -f1 -d' 'コマンドを追加する。
  cut → コマンド
  -f → 抜き出すフィールド。今回は1を指定。
  -d → 区切り文字(delimiter:デリミター)半角空白を使用。
  ※列を抜き出すのはawk '{print $2}'コマンド(このコマンドは2行目を抜き出す)を利用するのも手。


user@freebsd:~ % pip list -o | sed -n '3,$p' | cut -f1 -d' ' | xargs -I% pip install -U %
<省略...>

各行のパッケージ名をpip install -U <パッケージ名>で当て込んでいく。
  xargs → 1行ごとにコマンドを実行させる。
  -I% → 後述の%を入力文字列(行)に置き換える。
  pip install -U %→ pipコマンドにおけるインストール済みパッケージのアップデートコマンド。%は入力文字列(行)の挿入位置、この場合は一番最後。



この記事は以上。
必要に応じて更新を行う予定。

気になった記事のブックマークなど(2025/11)

  過去ログ   走り書き 2025/11/03 おいしい焼肉♪あおぞら沼田店           確約された大勝利の味。 ...