Category Archives: FreeBSD

FreeBSD 12のbhyveにWindows10をインストールする:その2(vm-bhyve使用)

Pocket

前回までで仮想マシンをインストールする準備が整った。
さっそくWindows10のインストールに取り掛かるが、準備すべきものがある。

  1. Windows10インストールイメージ
  2. TigerVNC(Viewer)

一つ目は言わずもがな。
https://www.microsoft.com/ja-jp/software-download/windows10

二つ目は、GUI操作のため。
Windowsのような、GUI操作が必須のOSをbhyve上の仮想マシンとして動かす場合には、VNCでその画面を見ることになる。
ただ、bhyveのVNCは癖があるようで、VNC viewerによっては途中で切れてしまうんである。
WindowsでもProであればリモートデスクトップという手もあるが、それにしたってインストールの時にはVNCで繋ぐほかない。
TigerVNCなら問題なく接続できるのでこれを準備しておくこと。
https://tigervnc.org/
https://github.com/TigerVNC/tigervnc/releases

2019/5/12時点では1.9.0が最新だからしてバイナリはこちら。Viewerでよい。
https://bintray.com/tigervnc/stable/tigervnc/1.9.0

初回には少し混乱したので記しておくが、VNCで接続する先のIPアドレスは、bhyveホストのIPアドレスである。
仮想マシンが自立して起動すると、そっちはそっちで独自のIPアドレスを取得する。

VNCはbhyveが用意する仮想マシンへのGUIアクセスなのでbhyveホストに接続する必要があるわけ。
一方で、仮想マシンそのものでリモートデスクトップやら、VNC Serverを用意すれば、そのときは当然、仮想マシンのIPアドレスを接続先として指定することになる。

ではISOの準備から。

仮想マシンインストール準備(インストーラ = ISO)

インストーラの準備。
ISOイメージを登録する。VirtualBoxでもそういう操作あるよね。

ISOイメージがあるなら$vm_dir/.isoに移す
sudo vmとして確認する
sudo vm とすれば、ダウンロードしてそこに置いてくれる。ちょっと驚き。

仮想マシンインストール準備(仮想マシン設定)

前提。
仮想マシンは$vm_dir/(仮想マシン名)/に置かれる。
設定ファイルは$vm_dir/(仮想マシン名)/(仮想マシン名).confである。
なお仮想マシンのログは$vm_dir/(仮想マシン名)/vm-bhyve.log。

仮想マシン置き場が/vmで、仮想マシン名がwin10だと、
/vm/win10/win10.confなどとなる。

で、vm createでまず仮想マシンの枠を作る。
このとき、-tでテンプレートを指定し、-sでディスクイメージのサイズを指定できる。
デフォルトだと20Gなので余程のことがない限り指定は必須。
作った仮想マシンはvm listで確認。

vm configureで設定(win10.conf)を変更。
vi操作で書き換える。
以下のように。

WindowsなのでBIOSはuefi。

graphicsをYesにするとVNCで接続できる。
デフォルトではbhyveホストのIPアドレス:5900で待ち受け。
変更したければそれぞれgraphics_listen、graphics_portで指定する。
また、解像度は800×600。graphics_res=”WxH”で変更できる。
graphics_waitを設定しておくと、VNC接続するまでゲストの起動を待ってくれる。
設定しなくても、仮想マシンをインストールモードで立ち上げたときには待ってくれるが、それは初回だけ。
Windowsのようにインストール時に複数回再起動するものはwaitしてもらったほうがいいだろうと。

Windows10homeの場合はcpuを1。(後述)

network0_typeにはe1000を指定。
インストールが無事に済んだらvirtioに変更するが、まずはe1000で。

network0_switchで本仮想マシンを繋ぐ仮想スイッチを指定する。
vm-bhyveのデフォルト、publicにしておく。
なお、起動した暁には、仮想マシンにはtapX(Xは数字)インタフェースが割り当てられ、publicに接続される。

disk0_type=”ahci-hd”としていて、本来ならディスクイメージをzfsのボリュームにしてvirtio-blkと指定したいが、以下の通りahci-hdしかダメ。
https://github.com/churchers/vm-bhyve/wiki/Supported-Guest-Examples
“the disk emulation needs to be ahci-hd.”

vm-bhyveは標準で仮想マシンの時刻をUTCに設定するので、utctime=”no”とする。
xhci_mouse=”yes”にしておかないと、後々VNCで接続したときにまともにマウスが動かない。

仮想マシンインストール

さあインストール。vmにinstallサブコマンドを与えて起動。
状態はvm listで確認。
bhyveホスト側では$vm_dirにあるvm-bhyve.logをtailして状況を確認しつつ進めるがよいだろう。

lockedの通り、VNC待ち。
TigerVNCで接続し、インストールを進める。
繰り返すがこのときの接続先はbhyveホスト。

インストール後(ネットワークドライバの変更他)

無事にインストールが済んだら、ネットワークドライバを変更する。
ネットワークドライバの変更なのでVNCから接続しておく。
ドライバの配布先には、仮想マシンから直接、行ってしまってよい。

場所はここだが、「virtio-win fedora」あたりで検索すれば辿り着けるはず。
https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/

5/12時点では0.1.164が最新。
https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.164-2/virtio-win-0.1.164.iso

Dにマウントしたら、以下のパスがドライバの場所。パスの通りWindows10, 64bitね。
こちらに強制的に変更する。ネットワークが切断されるがお構いなしで。
D:\NetKVM\w10\amd64

シャットダウンしたら、bhyve側の設定ファイルでネットワークタイプをe1000からvirtio-netに変更する。
graphics_waitも忘れずに削除。

ゲストWindowsに与えるCPU数

Windows10の場合、割り当てられるCPUは、Homeだと1つ、Proだと2つまで。
コア/スレッドはHomeだと32、Proだと256。

コアを二つ以上与えようとしても、vm-bhyveでの指定はCPU数でのみ可能。
1.3からはより細かい設定ができるようになるそうだが、pkgからインストールするvm-bhyveは1.2なので1のままにしておく。

https://github.com/churchers/vm-bhyve/wiki/Guest-Example:-Windows

なお/boot/loader.confに以下の設定をすることで、CPU一つあたりのコア数を指定できるが、手元ではうまく動かないので特に説明はしない。

上記パラメータの詳しい説明はこちら。
https://forums.freebsd.org/threads/bhyve-cpu-vcpu-cores-nad-threads.60169/

ホスト起動時に仮想マシンも起動させるには。

/etc/rc.confに以下の行を追加。
複数ある場合にはスペースを置いて起動させたい順に記載。
vm_delayは、複数の仮想マシンを起動する場合のインターバルを秒で指定。

No tags for this post.

FreeBSD 12のbhyveにWindows10をインストールする:その1(vm-bhyve使用)

Pocket

bhyveはFreeBSDで動く、つまりType 2のハイパーバイザ。

FreeBSDにはjailがある。
jailのいいところは、カーネルを共有しつつユーザランドだけ分けることで、オーバーヘッドを抑えられるところ。
悪いところはOSに制限が発生するところ。要するにLinuxやWindows、FreeBSDでも他のバージョンを動かせないところ。

仮想化は何かの目的、たとえばアプリケーションを動かすためのもので、いまどきOS依存のアプリケーションは少ない。
とはいうものの、FreeBSDは年々、本体はともかく裾野のリソースが先細りで、ports/packageがなくなったり、あったとしても情報は少なくて、まるっとLinuxごと動かしたいなと感じることがある。
もちろんWindowsについては当然FreeBSDでは動かないアプリなんて山ほどある。

そういった点では、用途に合わせて最適なOS(とアプリケーション)を使い慣れたFreeBSD上で動かせるのはかなりのメリット。
というのも、バックアップが簡単にできるからである。
ZFS上にイメージを作れば、スナップショットにロールバックはお手の物である。
壊し放題である。
ESXiなどのType 1ハイパーバイザでは、これができない。できるかもしれないけど知らない。

Windowsを物理PC上で使っていて、壊れたとする。バックアップがあったとしても、復旧が面倒。
Linuxについてはバックアップからの復旧は比較的簡単だが、俺様なんか滅多にLinuxを使わなくて操作をすぐ忘れるという点でやはり復旧が面倒。

以上のような背景があったところに、このたび宅鯖をハードウェア仮想化対応のCPUに変えたので、遅まきながらbhyveを導入する。
以下ではWindows10をインストールする。

まずはvm-bhyveを

bhyveの導入には、まず公式のFreeBSD handbookを参照するが、いろいろと面倒くさそうである。
https://www.freebsd.org/doc/handbook/virtualization-host-bhyve.html

遅れて導入すると、いろいろと環境が整っているものである。
bhyveの場合には、vm-bhyveというツールがあればこのへんは一挙解決。
virtualboxを使ったことがあれば、それをイメージしながら進めると理解しやすい。

ただ後述するが、Windowsのイメージそのものにはzfsボリュームを使えない。(ZFS上にイメージを置くことはできる)
https://github.com/churchers/vm-bhyve
https://github.com/churchers/vm-bhyve/wiki/Running-Windows

大きな流れ

  1. vm-bhyveのインストール
  2. 初期設定
  3. 初期設定(ネットワーク)
  4. 仮想マシンインストール準備(インストーラ = ISO)
  5. 仮想マシンインストール準備(仮想マシン設定)【次回】
  6. 仮想マシンインストール【次回】

vm-bhyveのインストール

pkgでインストールできる。
vm-bhyveのほか、仮想OS用のfirmwareもインストールしておく。

どんなファイルがインストールされたかは、pkg listで確認できる。
コマンドとしては/usr/local/sbin/vmを使う。
実行にはroot権限が必要。
service -lで表示されるサービス名もvm。

仮想マシン他置き場を作る。

もちろんZFSで作るよな。
ここで作った置き場には、仮想マシンのほか、ISOイメージ、テンプレート、すべての仮想マシンに共通の設定ファイルが置かれる。
ルート直下に/vmを作った。
なお本記事で”$vm_dir”と記載をする場合にはこの仮想マシン置き場を指す。

vm-bhyveの初期設定

まず/etc/rc.confへの書き込み。
ホスト起動時にvm-bhyveも起動するように。
また、先に作った仮想マシン置き場をvm-bhyveに知らせるために。

次にvm init。仮想マシン置き場にいろいろとファイル/ディレクトリが作られるとともに、必要なカーネルモジュールがロードされる。
vm initはホストが起動する都度、実行される必要がある。
この場合、vm initはカーネルモジュールのロードと、ネットワーク設定(tap)を行う。
/etc/rc.confにvm_enableをしてあれば、気にする必要なない。

仮想マシン置き場に、OSごとのテンプレートファイルもコピーする。
/usr/local/share/examples/vm-bhyve/にあるやつね。(さきほどpkg infoでも出てきた)

以上で初期設定終わり。
つぎは初期設定(ネットワーク)

初期設定(ネットワーク)

仮想マシン用ネットワークの結線を行う。
まず、仮想マシンの繋がる仮想スイッチを作り、仮想スイッチとホストマシンのネットワークインタフェースを繋ぐ。

外界 <–> ホストのインタフェース <–> 仮想スイッチ
というネットワークを作る。

先々、仮想マシンを作ると
外界 <–> ホストのインタフェース <–> 仮想スイッチ <–> 仮想マシン
というネットワークになる。
仕組み的なことをいうと、仮想スイッチはbridgeで、仮想マシンのインタフェースはtapになる。

以下の例では、publicという名前の仮想スイッチ(オプションなしでのcreateなのでbridgeインタフェース)を作成している。
名前は、vm-bhyveのテンプレートで仮想スイッチを”public”にしているからで、気に入らなければ別の名前でもよい。
# その場合は$vm_dir/.templatesにあるファイルを書き換えておくとよい。
addで仮想スイッチに物理インタフェースを追加。
物理インタフェースは、もちろんのことホストマシンのインタフェースに合わせること。

これで以下のようなネットワーク構成になった。
外界 <–> ホストのインタフェース(re0) <–> 仮想スイッチ(vm-public)

これですべての初期設定が完了。

No tags for this post.

[zfs] zfsnap2を使った日々のzfs snapshot(削除編)

Pocket

zfsnap2(以降、zfsnap)をperiodicで自動取得する方法はこちらで触れた。
同期時でも触れた通り、zfsnapには自動削除するperiodic scriptもある。
が、実はそのままでは動かない。
変更内容を本記事で示す。

結論

付属のスクリプトではdestroyするfsの指定がないので補う。
具体的には以下の個所。

 
<         xPREFIXx/zfsnap destroy $OPTIONS -p "hourly- daily- weekly- monthly- reboot- $xPERIODICx_zfsnap_delete_prefixes" $xPERIODICx_zfsnap_delete_fs -r $xPERIODICx_zfsnap_delete_recursive_fs
---
>         xPREFIXx/zfsnap destroy $OPTIONS -p "hourly- daily- weekly- monthly- reboot- $xPERIODICx_zfsnap_delete_prefixes"

 

 

同時に、/etc/periodic.confで$xPERIODICx_zfsnap_delete_fs、$xPERIODICx_zfsnap_delete_recursive_fsの指定も行うこと。

結果

dailyの削除スクリプト例(dailyのみ)

 
#!/bin/sh

# This file is licensed under the BSD-3-Clause license.
# See the AUTHORS and LICENSE files for more information.

# If there is a global system configuration file, suck it in.
if [ -r /etc/defaults/periodic.conf ]; then
    . /etc/defaults/periodic.conf
    source_periodic_confs
fi

# daily_zfsnap_delete_enable   - Delete old snapshots periodicaly (values: YES | NO)
# daily_zfsnap_delete_flags    - <code>zfsnap destroy</code> flags
# daily_zfsnap_delete_verbose  - Verbose output (values: YES | NO)
# daily_zfsnap_delete_prefixes - Space-separated list of prefixes of expired zfsnap snapshots to delete
#                                     'hourly-', 'daily-', 'weekly-', 'monthly-', and 'reboot-' prefixes are hardcoded
# daily_zfsnap_delete_fs                - Space-separated ZFS filesystems to create non-recursive snapshots
# daily_zfsnap_delete_recursive_fs      - Space-separated ZFS filesystems to create recursive snapshots

case &quot;${daily_zfsnap_delete_enable-&quot;NO&quot;}&quot; in
    [Yy][Ee][Ss])
        OPTIONS=&quot;$daily_zfsnap_delete_flags&quot;

        case &quot;${daily_zfsnap_delete_verbose-&quot;NO&quot;}&quot; in
            [Yy][Ee][Ss]) OPTIONS=&quot;$OPTIONS -v&quot; ;;
        esac

        /usr/local/sbin/zfsnap destroy $OPTIONS -p &quot;hourly- daily- weekly- monthly- reboot- $daily_zfsnap_delete_prefixes&quot; $daily_zfsnap_delete_fs -r $daily_zfsnap_delete_recursive_fs
        exit $?
        ;;

    *)
        exit 0
        ;;
esac

# vim: set ts=4 sw=4:

/etc/periodic.confの例(dailyのみ)

# zfsnap_daily
daily_zfsnap_enable="YES"
daily_zfsnap_recursive_fs="vault"
daily_zfsnap_verbose="YES"
daily_zfsnap_flags="-s -S -z"
daily_zfsnap_ttl="1w1d"
daily_zfsnap_delete_enable="YES"
daily_zfsnap_delete_flags="-s -S"
daily_zfsnap_delete_verbose="YES"
daily_zfsnap_delete_recursive_fs="vault"

上手くいけばdaily outputで以下のような内容が通知される。

/sbin/zfs destroy vault/chamber@daily-2018-12-21_04.00.00--1w1d ... DONE
/sbin/zfs destroy vault/itunes@daily-2018-12-21_04.00.00--1w1d ... DONE
/sbin/zfs destroy vault@daily-2018-12-21_04.00.00--1w1d ... DONE
No tags for this post.

[zfs]ディスク交換、zpool容量の拡張

Pocket

HDDがいっぱいになってきたので容量の大きい別のHDDに移した。
zfsなのでmirrorをしつつ入れ替えができる。
その時のメモ。

端的に言えばディスク交換後zpool online -eをすればよい。
以下、経緯。

ディスク追加

2.5TのHDD, ada1上に作られたzpool、vaultがあり、残容量は150Gである。
もともとzfsは残容量が少なくなると格段にパフォーマンスが落ちると言われていて、これはちょっと危険な状態である。

ada1 at ahcich1 bus 0 scbus1 target 0 lun 0
ada1: <WDC WD25EZRX-00MMMB0 80.00A80> ATA8-ACS SATA 3.x device
ada1: Serial Number WD-WMAWZ0230443
ada1: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada1: Command Queueing enabled
ada1: 2384658MB (4883781168 512 byte sectors)
ada1: quirks=0x1<4K>

# zpool status
  pool: vault
 state: ONLINE
  scan: none requested
config:

        NAME           STATE     READ WRITE CKSUM
        vault          ONLINE       0     0     0
          gpt/disk_01  ONLINE       0     0     0

# zfs list
NAME            USED  AVAIL  REFER  MOUNTPOINT
vault          2.05T   150G    88K  /vault
vault/chamber  1017G   150G  1017G  /chamber
vault/itunes   1.06T   150G  1.05T  /itunes

そこで、zpoolにmirrorとして容量の大きいディスクを追加し、その後オリジナルのディスクを外す、という手順。

追加するのは以下のディスク。3T。
2.5Tから3Tじゃ焼け石に水ですがね…。

ada2 at ahcich2 bus 0 scbus2 target 0 lun 0
ada2: <WDC WD30EZRX-00D8PB0 80.00A80> ACS-2 ATA SATA 3.x device
ada2: Serial Number WD-WMC4N0765033
ada2: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada2: Command Queueing enabled
ada2: 2861588MB (5860533168 512 byte sectors)
ada2: quirks=0x1<4K>

既存のzpoolにmirrorとしてディスクを追加するには、zpool attachを使う。
zpool attachに続けてzpool名、既存ディスク、追加ディスクの順で指定。
以下の例では、ディスクの指定をada2などのデバイス名ではなくGPT名で行っている。


# zpool attach vault gpt/disk_01 gpt/disk_02

以下のようにzpoolがmirror構成になり、resilveringが始まる。

# zpool status
  pool: vault
status: One or more devices is currently being resilvered.  The pool will
        continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
 scrub: resilver in progress for 0h0m, 0.01% done, 7h1m to go
config:

        NAME             STATE     READ WRITE CKSUM
        vault            ONLINE       0     0     0
          mirror-0       ONLINE       0     0     0
            gpt/disk_01  ONLINE       0     0     0
            gpt/disk_02  ONLINE       0     0     0

しばらく待つと;

  pool: vault
 state: ONLINE
  scan: resilvered 2.04T in 6h48m with 0 errors on Sun Dec 16 19:15:11 2018
config:

        NAME             STATE     READ WRITE CKSUM
        vault            ONLINE       0     0     0
          mirror-0       ONLINE       0     0     0
            gpt/disk_01  ONLINE       0     0     0
            gpt/disk_02  ONLINE       0     0     0

resilvering終了。

 

旧ディスクの除去

2.5Tと3Tのディスクでmirrorを構成しているので、当然ながら残容量に変化はない。

NAME            USED  AVAIL  REFER  MOUNTPOINT
vault          2.05T   150G    88K  /vault
vault/chamber  1017G   150G  1017G  /chamber
vault/itunes   1.06T   150G  1.05T  /itunes

では旧ディスクを外す。
mirrorからディスクを外すにはdetachを使う。
zpool detachに続けてzpool名、ディスク名を指定。

# zpool detach vault gpt/disk_01
# zpool status
  pool: vault
 state: ONLINE
  scan: resilvered 2.04T in 6h48m with 0 errors on Sun Dec 16 19:15:11 2018
config:

        NAME          STATE     READ WRITE CKSUM
        vault         ONLINE       0     0     0
          gpt/disk_02 ONLINE       0     0     0

errors: No known data errors

ご覧の通りmirror構成が解除される。

容量の拡張

さてこの状態ではまだ残容量が増えない。

NAME            USED  AVAIL  REFER  MOUNTPOINT
vault          2.05T   150G    88K  /vault
vault/chamber  1017G   150G  1017G  /chamber
vault/itunes   1.06T   150G  1.05T  /itunes

ただ物理ディスクは3Tなので、zpoolに「安心して容量を増やしたまえ」と通知する。
通知にはzpool online -eを使う。
zpool onlineは物理ディスクを有効にするコマンドだが、-eを付ければ、使用可能な領域をすべて使うようにできる。
manを以下に引用する。

     zpool online [-e] pool device ...

         Brings the specified physical device online.

         This command is not applicable to spares or cache devices.

         -e      Expand the device to use all available space. If the device
                 is part of a mirror or raidz then all devices must be
                 expanded before the new space will become available to the
                 pool.

ご覧の通り残容量が増えた。
たったの450Gだけど。

# zpool online -e vault gpt/disk_02
$ zfs list
NAME            USED  AVAIL  REFER  MOUNTPOINT
vault          2.05T   599G    88K  /vault
vault/chamber  1017G   599G  1017G  /chamber
vault/itunes   1.06T   599G  1.05T  /itunes

No tags for this post.

[zfs] zfsnap2を使った日々のzfs snapshot(取得編)

Pocket

zfsnap2(面倒くさいので以降zfsnap)のおかげで気軽にzfs snapshotできるようになった。
あとはこれをcronに仕込んで日々、snapshotを取得、削除するだけである。

zfsnapをpkg、あるいはportsからインストールすると、cron用のシェルスクリプトも付いてくる。
これを加工してperiodic用のディレクトリに放り込めば、あとは全部、zfsnapがやってくれる。

基本はここを見ながら。
https://github.com/zfsnap/zfsnap/wiki/zfSnap-periodic.conf

なお、本稿で扱う周期、契機は日週月次に限る。

全体の流れ

  1. スナップショットの方針を決める
  2. cron用シェルスクリプトを日・週・月ごとのperiodicディレクトリにコピーし、ファイル名を変更する
  3. スクリプトの内容を修正する
  4. /etc/periodic.confにバックアップ方針に沿った設定を書き加える

では早速。

スナップショット方針を決める

ここでは簡単に、あるzpool丸ごとに対して;

  • 毎日のスナップショットは1週間と1日、保存する
  • 毎週のスナップショットは1か月と1日、保存する
  • 毎月のスナップショットは1年と1週間、保存する

とする

[補足]periodicから実行されるときのsnapname

zfsnap付属のスクリプトを使うと、snapnameの頭にdaily, weekly, monthlyと付く。
もちろん変更可能だが、本稿ではそのまま使う。

zfsnapのcron用スクリプトはどこにある

cron用スクリプトは、zfsnapインストール時にshareにコピーされる。
例えば以下のようにして探す

$ pkg list|grep zfsnap
/usr/local/etc/bash_completion.d/zfsnap.sh
/usr/local/man/man8/zfsnap.8.gz
/usr/local/sbin/zfsnap
/usr/local/share/doc/zfsnap/AUTHORS
/usr/local/share/doc/zfsnap/NEWS
/usr/local/share/doc/zfsnap/PORTABILITY
/usr/local/share/doc/zfsnap/README.md
/usr/local/share/examples/zfsnap/completion/zfsnap-completion.bash
/usr/local/share/examples/zfsnap/completion/zfsnap-completion.tcsh
/usr/local/share/examples/zfsnap/completion/zfsnap-completion.zsh
/usr/local/share/examples/zfsnap/periodic/xPERIODICx_zfsnap.sh
/usr/local/share/examples/zfsnap/periodic/xPERIODICx_zfsnap_delete.sh
/usr/local/share/licenses/zfsnap2-2.0.0.b3/BSD3CLAUSE
/usr/local/share/licenses/zfsnap2-2.0.0.b3/LICENSE
/usr/local/share/licenses/zfsnap2-2.0.0.b3/catalog.mk
/usr/local/share/zfsnap/commands/destroy.sh
/usr/local/share/zfsnap/commands/recurseback.sh
/usr/local/share/zfsnap/commands/snapshot.sh
/usr/local/share/zfsnap/core.sh
/usr/local/share/zsh/site-functions/_zfsnap

上記のうち以下が狙いのスクリプトである。
スナップショット取得用、削除用の2種類。
なお削除用はそのままでは期待する動作にならないので別記事で扱う。
/usr/local/share/examples/zfsnap/periodic/xPERIODICx_zfsnap.sh
/usr/local/share/examples/zfsnap/periodic/xPERIODICx_zfsnap_delete.sh

スクリプトのコピーとファイル名の変更

さてこれを、日・週・月のperiodicディレクトリにコピーし設定していくが、まずは日次で試す。
日ごとのperiodicディレクトリは/usr/local/etc/periodic/dailyである。
ここにコピーし、ファイル名を変える。
ファイル名のxPERIODICxを、日次・週次・月次、どの周期用かに合わせて変える。
具体的にはそれぞれdaily, weekly, monthlyに。
以下の例では日次のスクリプトなので、dailyに変えている。
prefixの番号は好きなようにしたまえ。


$ cd /usr/local/etc/periodic/daily
$ sudo cp /usr/local/share/examples/zfsnap/periodic/* .
$ sudo mv ./xPERIODICx_zfsnap.sh ./500.daily_zfsnap.sh
$ sudo mv ./xPERIODICx_zfsnap_delete.sh  ./500.daily_zfsnap_delete.sh
$ ls
411.pkg-backup                  500.daily_zfsnap_delete.sh      998.ntpdate
490.status-pkg-changes          500.daily_zfsnap.sh             smart

スクリプトの修正

スクリプト(取得用)の内容は以下の通りである。
変える場所はxPERIODICxとxPREFIXxである。
xPERIODICxは周期に合わせて、xPREFIXxはzfsnapの置いてあるパス、つまり/usr/local/sbin/zfsnapに。


#!/bin/sh

# This file is licensed under the BSD-3-Clause license.
# See the AUTHORS and LICENSE files for more information.

# If there is a global system configuration file, suck it in.
if [ -r /etc/defaults/periodic.conf ]; then
    . /etc/defaults/periodic.conf
    source_periodic_confs
fi

# xPERIODICx_zfsnap_enable          - Enable xPERIODICx snapshots (values: YES | NO)
# xPERIODICx_zfsnap_flags           - <code>zfsnap snapshot</code> flags
# xPERIODICx_zfsnap_fs              - Space-separated ZFS filesystems to create non-recursive snapshots
# xPERIODICx_zfsnap_recursive_fs    - Space-separated ZFS filesystems to create recursive snapshots
# xPERIODICx_zfsnap_ttl             - Explicit TTL value
# xPERIODICx_zfsnap_verbose         - Verbose output (values: YES | NO)
# xPERIODICx_zfsnap_enable_prefix   - Create snapshots with prefix (values: YES | NO) (Default = YES)
# xPERIODICx_zfsnap_prefix          - set prefix for snapshots (Default = xPERIODICx)

case &quot;${xPERIODICx_zfsnap_enable-&quot;NO&quot;}&quot; in
    [Yy][Ee][Ss])
        OPTIONS=&quot;$xPERIODICx_zfsnap_flags&quot;

        case &quot;${xPERIODICx_zfsnap_verbose-&quot;NO&quot;}&quot; in
            [Yy][Ee][Ss]) OPTIONS=&quot;$OPTIONS -v&quot; ;;
        esac

        case &quot;${xPERIODICx_zfsnap_enable_prefix-&quot;YES&quot;}&quot; in
            [Yy][Ee][Ss]) OPTIONS=&quot;$OPTIONS -p ${xPERIODICx_zfsnap_prefix:-&quot;xPERIODICx-&quot;}&quot; ;;
        esac

        case 'xPERIODICx' in
            'hourly')
                default_ttl='3d'
                ;;
            'daily'|'reboot')
                default_ttl='1w'
                ;;
            'weekly')
                default_ttl='1m'
                ;;
            'monthly')
                default_ttl='6m'
                ;;
            *)
                printf '%s\n' &quot;ERR: Unexpected error&quot; &gt;&amp;2
                exit 1
                ;;
        esac

        xPREFIXx/zfsnap snapshot $OPTIONS -a ${xPERIODICx_zfsnap_ttl:-&quot;$default_ttl&quot;} $xPERIODICx_zfsnap_fs -r $xPERIODICx_zfsnap_recursive_fs
        exit $?
        ;;

    *)
        exit 0
        ;;
esac

# vim: set ts=4 sw=4:

vimなら:%s/xPERIODICx/daily/g などとコマンド叩いて一括置換する。
以下が修正後。


#!/bin/sh

# This file is licensed under the BSD-3-Clause license.
# See the AUTHORS and LICENSE files for more information.

# If there is a global system configuration file, suck it in.
if [ -r /etc/defaults/periodic.conf ]; then
    . /etc/defaults/periodic.conf
    source_periodic_confs
fi

# daily_zfsnap_enable          - Enable daily snapshots (values: YES | NO)
# daily_zfsnap_flags           - <code>zfsnap snapshot</code> flags
# daily_zfsnap_fs              - Space-separated ZFS filesystems to create non-recursive snapshots
# daily_zfsnap_recursive_fs    - Space-separated ZFS filesystems to create recursive snapshots
# daily_zfsnap_ttl             - Explicit TTL value
# daily_zfsnap_verbose         - Verbose output (values: YES | NO)
# daily_zfsnap_enable_prefix   - Create snapshots with prefix (values: YES | NO) (Default = YES)
# daily_zfsnap_prefix          - set prefix for snapshots (Default = daily)

case &quot;${daily_zfsnap_enable-&quot;NO&quot;}&quot; in
    [Yy][Ee][Ss])
        OPTIONS=&quot;$daily_zfsnap_flags&quot;

        case &quot;${daily_zfsnap_verbose-&quot;NO&quot;}&quot; in
            [Yy][Ee][Ss]) OPTIONS=&quot;$OPTIONS -v&quot; ;;
        esac

        case &quot;${daily_zfsnap_enable_prefix-&quot;YES&quot;}&quot; in
            [Yy][Ee][Ss]) OPTIONS=&quot;$OPTIONS -p ${daily_zfsnap_prefix:-&quot;daily-&quot;}&quot; ;;
        esac

        case 'daily' in
            'hourly')
                default_ttl='3d'
                ;;
            'daily'|'reboot')
                default_ttl='1w'
                ;;
            'weekly')
                default_ttl='1m'
                ;;
            'monthly')
                default_ttl='6m'
                ;;
            *)
                printf '%s\n' &quot;ERR: Unexpected error&quot; &gt;&amp;2
                exit 1
                ;;
        esac

        /usr/local/sbin/zfsnap snapshot $OPTIONS -a ${daily_zfsnap_ttl:-&quot;$default_ttl&quot;} $daily_zfsnap_fs
 -r $daily_zfsnap_recursive_fs
        exit $?
        ;;

    *)
        exit 0
        ;;
esac

# vim: set ts=4 sw=4:

削除用も同じようにしたら、periodic.confに指示を書き入れる。

/etc/periodic.confにおけるzfsnap設定の書式

/etc/periodic.confは無ければ作る。

zfsnapのperiodic向け書式は以下の通り。
https://github.com/zfsnap/zfsnap/wiki/zfSnap-periodic.conf

以下、日次のものとして記す。
週、月次の場合はdailyをそれぞれweekly, monthlyに変えればよい。

snapshot取得の有効化

daily_zfsnap_enable
YES/NOで指定

共通オプション(generic option)

daily_zfsnap_flags
例えばscrub, resilver中は避け、日付シリアルの秒を切り捨て、というような設定をここで行う。。
-v, -dを指定しないこと。
初めて作るときにはテスト実行オプションを付けて試験する。

zfs, zpoolの指定

daily_zfsnap_fs
daily_zfsnap_recursive_fs
recursiveとなっているのは、当然ながら子孫も含めて再帰的に取得される
複数あるなら、スペースを空けて列挙

冗長アウトプット指定

daily_zfsnap_verbose
YES/NOで指定

保存期間指定

daily_zfsnap_ttl
指定がなければ日次は1週間、週次は1か月、月次は6か月になる。

スナップショット削除有効化

daily_zfsnap_delete_enable
YES/NOで指定

periodic.conf例

ということで、periodic.confに追加したのは以下の通り。


# zfsnap_daily
daily_zfsnap_enable="YES"
daily_zfsnap_recursive_fs="vault"
daily_zfsnap_verbose="YES"
daily_zfsnap_delete_enable="YES"
daily_zfsnap_flags="-n -s -S -z"
daily_zfsnap_ttl="1w1d"

試験

zfsnap_flagsに-nを付けた状態で試験。


$ sudo /usr/local/etc/periodic/daily/500.daily_zfsnap.sh
/sbin/zfs snapshot  vault/chamber@daily-2018-12-03_02.14.00--1w1d
/sbin/zfs snapshot  vault/itunes@daily-2018-12-03_02.14.00--1w1d

大丈夫そうなので-nを外す。

最終的なperiodic.confの結果

週次、月次で同じようにperiodic用のスクリプトを作成する。


$ pwd
/usr/local/etc/periodic
$ find ./ -name '*zfsnap*'
./weekly/999.weekly_zfsnap.sh
./weekly/999.weekly_zfsnap_delete.sh
./daily/500.daily_zfsnap.sh
./daily/500.daily_zfsnap_delete.sh
./monthly/910.monthly_zfsnap.sh
./monthly/910.monthly_zfsnap_delete.sh

最終的なperiodic.confの結果は以下の通り。


# zfsnap_weekly
weekly_zfsnap_enable="YES"
weekly_zfsnap_recursive_fs="vault"
weekly_zfsnap_verbose="YES"
weekly_zfsnap_delete_enable="YES"
weekly_zfsnap_flags="-s -S -z"
weekly_zfsnap_ttl="1m1d"
# zfsnap_daily
daily_zfsnap_enable="YES"
daily_zfsnap_recursive_fs="vault"
daily_zfsnap_verbose="YES"
daily_zfsnap_delete_enable="YES"
daily_zfsnap_flags="-s -S -z"
daily_zfsnap_ttl="1w1d"
# zfsnap_monthly
monthly_zfsnap_enable="YES"
monthly_zfsnap_recursive_fs="vault"
monthly_zfsnap_verbose="YES"
monthly_zfsnap_delete_enable="YES"
monthly_zfsnap_flags="-s -S -z"
monthly_zfsnap_ttl="1y1d"

翌日以降、root宛には以下のようなメールが届くので、結果はここで確認する。

/sbin/zfs snapshot -r vault@daily-2018-12-02_04.47.0<wbr />0--1w1d ... DONE
No tags for this post.

[zfs][zpool] らくらくスナップショットzfsnap2

Pocket

zfsは本当に本当に便利で助かるのだが、それでも面倒なことはある。
私にとって面倒なのは、スナップショット作成とスナップショットの差分転送である。

スナップショットの簡素化について。
スナップショットを作成する際には、ファイルシステムやボリュームに続けてスナップショットの名前、スナップネームを指定する必要がある。
スナップネームはスナップショットを特定するために必要なものなので文句を言う筋合いはないのだが、いちいち名前を付けるのが面倒なんである。日付でもなんでも自動的に付けてほしい。

なんとか改善したくていろいろ調べてみた。

スナップショット取得補助ツール

スナップショット関連ではzfstools, zfsnap2, zapの三つを調べた。
結論から言うと、zfsnap2を選択した。

zfstools

https://github.com/bdrewery/zfstools
https://www.freshports.org/sysutils/zfstools/
よさそうだけどruby依存なのでその一点で対象外に。
このツールのためだけにrubyを入れますか、という話で。
なるべく依存の少ないツールがよい。

zap

https://www.freshports.org/sysutils/zap
https://github.com/Jehops/zap
よさそうだけど、zfsに独自のプロパティ(zap:)を設定する必要があるっぽい。
独自プロパティの設定が、zfsとして許容されている作法であっても、対象のファイルシステムに何らかの手を加えるのは躊躇する

zfsnap2

https://www.freshports.org/sysutils/zfsnap2
https://github.com/zfsnap/zfsnap
単純なシェルスクリプト。
よさそう。

zfsnap2 お手軽snapshot

まず、zfsnap2は、取得すると日付シリアルをsnapnameに付けてくれる。
例えば。

 
vault/chamber@2018-11-11_09.48.00--1y
 

ご覧の通り2018/11/11 09:48:00と日付をsnapnameに付ける
なお、末尾に1yと書いてあるがこれは1年という意味である。
これは何かというと(次項につづく)

zfsnap2 snapshot削除の仕組みとTTL

snapshotは取得するだけでなく、消す方の面倒を見ることも重要。
zfsnap2は、取得したタイムスタンプとTTL(Time To Live)をsnapnameに含めておくのがアイデア(他みも同じようなツールあるかもしれないけど)。
先ほどの例でいえば、末尾の1yがそれ。1yだから1 year、1年ですな。

vault/chamber@2018-11-11_09.48.00--1y

上記の通り、取得日付、保存期間をsnapname自体に持たせるので、ツール側では状態を記憶しておく必要がない。
削除を指示されたら、zfsnap2はその都度、snapnameだけを見て判断・処理をするということ。
何より人間もsnapnameから保存期限を判断できる。これはよい。

とりあえず使う

管理者権限でzfsnap snapshotに続けてzfs/zpoolを指定するだけ。
日付も付けてくれる。

# zfsnap snapshot zroot/var/tmp
$ zfs list -t snapshot|grep 'zroot/var/tmp'
zroot/var/tmp@20181120                   56K      -    88K  -
zroot/var/tmp@2018-12-01_22.19.13--1m      0      -    88K  -

zfsnap書式概要

詳細はman等するとして、概要を示す。
書式は以下の通り。

zfsnap コマンド <共通オプション> <個別オプション> zpool/zfs

zfsnapのコマンド

コマンドにはsnapshot, destroy, recursebackの三つがある。
それらに続けてzpool, zfsを指定する。こちらの指定は複数でもよい。
共通オプション(generic option)は、その名の通り、共通的なオプション。
個別オプションはzpool, zfsごとのオプションである。

コマンドのsnapshot, destroyは当然ながらそれぞれsnapshot作成、削除。
recursebackは、zfs rollbackの拡張で、rollbackの際、指定のdataset配下すべてをrollbackするもの。
本稿では扱わない。

共通オプション(generic option)

主なものだけ示す

-s  : resilver中は作業しない
-S : scrub中は作業しない
-z : 日付シリアルの秒切り捨て(18:06:15を18:06:00にする)
-n : dry run。テスト実行。ファイルシステムに変更を加えない。
-v : 冗長output

-s, -Sは常時付けておいたほうがいいかな。

個別オプション

個別オプションなので、これに続けて指定されたzpool/zfsにのみ効果がある。
主なものだけ示す

-a : TTL。指定がなければ1m = 1か月
-r : 再帰オプション。再帰的にsnapshotを取得
-R : 非再帰オプション。再帰的なsnapshotを取得「しない」

TTLオプション

以下のうち、必要なものだけをズラズラ書けばよい

y : 年(365日)
m : 月(30日)
w : 週(7日)
d : 日
h : 時
M : 分
s : 秒

1週間と1日なら-a 1w1d。
2か月なら-a 2m。

実行例

以上を踏まえて;
resilver, scrub中は実行せず、日付シリアルの秒切り捨て、冗長アウトプットでsnapshotをテスト実行。
対象zfsその1はzroot/usrで、再帰的に取得し、TTLは1週間と1日。その2はzroot/ROOTで、再帰的に取得「せず」、TTLは1分。
という実行例。

# zfsnap snapshot -sSvzn -a1w1d -r zroot/usr -R -a1M zroot/ROOT
/sbin/zfs snapshot -r zroot/usr@2018-12-01_22.33.00--1w1d
/sbin/zfs snapshot  zroot/ROOT@2018-12-01_22.33.00--1M

よさそうなのでテスト実行オプションを省いて本番実行すると;

# zfsnap snapshot -sSvz -a1w1d -r zroot/usr -R -a1M zroot/ROOT
/sbin/zfs snapshot -r zroot/usr@2018-12-01_22.34.00--1w1d ... DONE
/sbin/zfs snapshot  zroot/ROOT@2018-12-01_22.34.00--1M ... DONE

zfs listで結果を確認。zroot/usrにのみ配下にもスナップショットが出来ている。

$ zfs list -t snapshot | grep '2018-12-01'
zroot/ROOT@2018-12-01_22.34.00--1M             0      -    88K  -
zroot/usr@2018-12-01_22.34.00--1w1d            0      -    88K  -
zroot/usr/home@2018-12-01_22.34.00--1w1d       0      -  5.97M  -
zroot/usr/ports@2018-12-01_22.34.00--1w1d      0      -    88K  -
zroot/usr/src@2018-12-01_22.34.00--1w1d        0      -    88K  -

では削除のほうも。
zroot/ROOT、zroot/usr配下のTTL切れsnapshotを削除
ただしzroot/ROOTは非再帰的、zroot/usrは再帰的に。
テスト実行。

# zfsnap destroy -sSvn -R zroot/ROOT -r zroot/usr
/sbin/zfs destroy zroot/ROOT@2018-12-01_22.34.00--1M

期限切れはzroot/ROOT@2018-12-01_22.34.00–1Mのみ。
じゃ、それで本番実行

# zfsnap destroy -sSv -R zroot/ROOT -r zroot/usr
/sbin/zfs destroy zroot/ROOT@2018-12-01_22.34.00--1M ... DONE

以上。

No tags for this post.

[ZFS][zpool]zpoolのHDDをスタンバイモードにして消費電力を減らそう

Pocket

我が家のNASサーバーはFreeBSDの入ったHP microserverである。
HP microserverにはHDDを4つ入れることができる。
たいへん便利なのだが、HDDが4つとも24時間動きっぱなしというのは精神衛生上、よろしくない。

実は、HDD4つのうちメインで使っているのはOSの入っているものと、Samba共有しているものの2つだけで、残りの2つはバックアップ用である。
少なくとも、残りの2本はバックアップを取得するときだけ動いてくれればよいので、それ以外の間は、HDD内円盤の回転を止めておきたい(スピンダウン)。

しかしSamba共有しているもの、バックアップ用のHDD(要するにOSの入っているHDD)以外はすべてzfsのzpoolを構成しているものである。
気軽にスピンダウンしてしまってよいものだろうか。

というのが調査を始めたきっかけである。

ああ、それと、頻繁に止めたり動かしたりすることがHDDに悪い、というのは重々承知の上。

結論(camcontrol standbyしろ)

結論から言うと、camcontrolでディスクを止めろ。
ディスク停止には、”standby”で。”idle”はやめておけ。

ATAデバイスのモード

ATAデバイスには4つのPower Modeがあり、条件によりそれぞれを行き来する。

  1. Active
  2. Idle
  3. Standby
  4. Sleep

Activeモードは、通常のデータのやり取りができる状態のこと。
それ以外は、Idle > Standby > Sleep の順に消費電力が下がり、反応速度も遅くなる。
詳細は以下書類(PDF注意)の4.18.3 Power modesを参照されたし。
http://www.t13.org/Documents/UploadedDocuments/docs2007/e07163r2-Comments_on_ATA8-ACS_revision_4a.pdf

これを踏まえて、任意のタイミング、あるいは、一定時間アクセスがないタイミングでIdle/Standby/Sleepに遷移させられれば目的が達成できる。
FreeBSDにおいて、Power modeの遷移にはcamcontrolコマンドを使う。
しかしその前に、zfs/zpoolで使えるPower Modeを調べねばならない。

zfsにはStandby

FreeBSD Forumにあるcamcontrol standby weirdnessというスレッドを見ると、以下のような記述がある。要するにStandbyを使えと。Idleだとzfsは当該ディスクをlost/defect/detachedと判断し、zpoolはdegradedになるか、unavailableになるという。

First of all: ZFS is fine with disks that go into STANDBY (accessing a zpool with disks in STANDBY will wake them up and ZFS will wait for it). ZFS cannot handle disks that are in IDLE mode (it considers the disks lost/defect/detached and the zpool will go degraded or even unavailable).

https://forums.freebsd.org/threads/camcontrol-standby-weirdness.59296/#post-340121

自分で試す気にはならないので、そのまま受け取る。

camcontrolによるstabdby操作

再びFreeBSD Forum。[AHCI] Spinning down ada(4) disksというスレッドの以下のポストを参照
https://forums.freebsd.org/threads/ahci-spinning-down-ada-4-disks.8841/page-2#post-98640

camcontrol standby adaXとすればよい。
またcamcontrol standby adaX -T sssとすれば、ただちにstandbyモードに移行し、その後もsss秒、アクセスがなければstandbyモードに移行することができる。
以下なら/dev/ada3をすぐにstandbyモードに移行させるとともに、20分の間アクセスがなければやはりstandbyモードに遷移するようタイマー設定している。今すぐはstandbyモードにしなくてもいいけど、タイマーだけ設定したい、という方法はないみたいだ。

# camcontrol standby ada3 -T 12000

しかし上記のコマンドを実行したとしても、応答はない。なしのつぶてである。
standbyモードに移ったのか。かくなる上はHDDの回転数はいかほどか、耳を澄ますほかはない。
そんなご無体な、とgoogle先生に訴えたところ、FreeNASのフォーラムに以下のポストを発見。

Spinning Down your Drives and Checking Power States. (New Script)

上記にあるスクリプトを使えば、power modeを知ることができる。
本記事の末尾に転載しておく。
get_drive_status.shとして保存しておいた。
実行してみると;

$ sudo drivestatus.sh
ada0:  FF
ada0: Running
ada1:  FF
ada1: Running
ada2:  FF
ada2: Running
ada3:  FF
ada3: Running

camcontrolでstandbyにしておいて再実行。

$ sudo drivestatus.sh
ada0:  FF
ada0: Running
ada1:  00
ada1: Standby
ada2:  00
ada2: Standby
ada3:  00
ada3: Standby

/dev/ada0はOSのあるHDDだからActiveですな。

運用方法(なにかが変)

よしこれで解決。
と思ったのだが、タイマー満了してもpower modeがstandbyに移らないのである。
その割に、そのディスクのディレクトリにアクセスすると、ファイル一覧の表示に待たされたりするのである。

先に引用した彼も同じことに悩んでいる。

But, then, when the disk is idle for > 1800sec (monitor with “zpool iostat 60”), it will not spin down. Huh?

https://forums.freebsd.org/threads/camcontrol-standby-weirdness.59296/#post-339820

この彼は、zpool iostat でディスクへの読み書きをモニターできるので、何分かアクセスがなければidleモードに移すスクリプトを書いた、と言っている。
常駐スクリプトを運用するのが面倒なので、cronジョブでstandbyさせるようにした。

結果

ワットチェッカーなんてものは持っていないので、単純に温度で確認した。
以下がそのグラフ。
ある日を境に、(OSのある/dev/ada0を除いて)温度が劇的に下がっていて、現時点ではまあ満足。

power mode確認スクリプト

#!/bin/bash
#
# Created by: Motorahead
# Date: 02/19/2016
# Checks For Running Status of Connected ADA Devices

# Look for Connected Devices
DEVICELIST=($( camcontrol devlist | grep -o 'ada[0-9]' ))

# Checks Drive Status, but only outputs relative field $10
STATUS(){
camcontrol cmd ${LIST} -a "E5 00 00 00 00 00 00 00 00 00 00 00" -r - | awk '{print $10}'
}

# Loop through each device found in ${DEVICELIST}
for LIST in ${DEVICELIST[@]}; do
        echo -n "${LIST}:  "
        STATUS
# If the Output is 00, then the drive is in Standby. If it's FF, then it's active.
        if [[ "$(STATUS)" == "FF" ]]; then
                echo "${LIST}: Running"
        elif [[ "$(STATUS)" -eq "00" ]]; then
                echo "${LIST}: Standby"
        else
                echo "${LIST} is in a unrecognized state."
    fi
done

No tags for this post.

[zfs][zpool] zfsの別ディスクへの移行

Pocket

zpoolを容量の多い別HDDに移したのでメモ。
一度、同じようなことはやっているが、時間も経っているので。
最初に書いておくが移行元でまずscrubしておくこと。

流れとしては以下の通り。

  1. 移行元HDD
    1. scrubしておく
    2. snapshot
  2. 移行先HDD
    1. GPTでzfsのパーティションを作成
    2. zpool作成
  3. zfs send, recvで丸々コピー

以下、実作業に触れる前に補足。

方針についての補足

なぜmirrorにしないのか

上記の方法のほかには、追加のディスクをmirrorとしてzpoolに追加し、resilveringが終わったら旧ディスクを外してexpandという手がある。
が、その手は採らない。
実は、zpool statusをする都度、以下のメッセージが表示されていた。
旧ディスクは512Bセクタになっていると文句を言っているのである。
ディスクを交換するか、新Poolに移せ、と。

  pool: vault
 state: ONLINE
status: One or more devices are configured to use a non-native block size.
        Expect reduced performance.
action: Replace affected devices with devices that support the
        configured block size, or migrate data to a properly configured
        pool.
  scan: scrub repaired 0 in 8h3m with 0 errors on Sun Nov  4 04:16:39 2018
config:

        NAME        STATE     READ WRITE CKSUM
        vault       ONLINE       0     0     0
          ada1      ONLINE       0     0     0  block size: 512B configured, 4096B native

 

512Bセクタのpoolにmirrorを追加したら、やっぱり512Bになるんではと心配になったので、mirrorではなく新規ディスクの新規Poolに移す。

なぜディスクをまるっと使わずgptでパーティションを切るのか

zpoolは、わざわざgptパーティションにしなくても、ディスクをまるっと使ってzpoolに指定できる。
できるのだが、/dev/ada2なんて名前よりも、gptラベルでpoolを作成したいのである。
これの有利な点は、例えば当該ディスクの物理的な位置で名前を付けることができる点である。
具体的には、slot_1とか名前を付けておくと、ディスク交換の時に楽。
幸いにもFreeBSDにおいては、gptパーティションを切ってもディスクをそのまま使っても、いずれもパフォーマンスに違いはない。
それならgptにしましょう。

https://www.freebsd.org/doc/handbook/zfs-zpool.html
There is no performance penalty on FreeBSD when using a partition rather than a whole disk.
(2018/11/09)

ではさっそく作業を。

実作業(移行元ディスクの準備)

scrubをしておく。

zpool scrub で。
かなり時間がかかるので覚悟しておくように。
なおscrubは最低3か月に一回が推奨
https://www.freebsd.org/doc/handbook/zfs-term.html#zfs-term-scrub
recommended at least once every three months

作業直前にsnapshot。

pool内に複数のディレクトリがある場合、最上階層でsnapshot -r(recursive)すればよい。
たとえばvaultというpoolにchamber, itunesがある場合に;

vault
vault/chamber
vault/chamber@20170503
vault/itunes
vault/itunes@20170503

※zfs list -t allの出力を一部削除したもの

zfs snapshot vault@20181109とすれば;

vault
vault@20181109
vault/chamber
vault/chamber@20180503
vault/chamber@20181109
vault/itunes
vault/itunes@20180503
vault/itunes@20181109

※zfs list -t allの出力を一部削除したもの

となる。いちいち各ディレクトリ配下でコマンドを叩かなくてよい。

 

移行先作業

GPTパーティションの作成

以下のようなディスク

ada3 at ahcich3 bus 0 scbus3 target 0 lun 0
ada3: ACS-3 ATA SATA 3.x device
ada3: Serial Number WD-WCC7K3PU64NE
ada3: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada3: Command Queueing enabled
ada3: 3815447MB (7814037168 512 byte sectors)

GPTスキームをcreateし、全領域をfreebsd-zfsに割り当てる。
このとき、-lオプションでラベルを付ける。
同じくgpart showに-lオプションを付ければ名前を確認できる。

# gpart create -s GPT ada3
ada3 created
# gpart add -l slot_4 -t freebsd-zfs /dev/ada3
ada3p1 added
$ gpart show ada3
          40  7814037088  ada3  GPT  (3.6T)
          40  7814037088     1  freebsd-zfs  (3.6T)

$ gpart show -l /dev/ada3
          40  7814037088  ada3  GPT  (3.6T)
          40  7814037088     1  slot_4  (3.6T)

zpoolの作成

/dev/ada3ではなくGPTラベルで指定する。
GPTラベルで指定するときは、gpt/<GPTラベル>というように指定する。

# zpool create warehouse gpt/slot_4
# zpool status warehouse
  pool: warehouse
 state: ONLINE
  scan: none requested
config:
        NAME               STATE     READ WRITE CKSUM
        warehouse          ONLINE       0     0     0
          gpt/slot_4  ONLINE       0     0     0

プロパティの変更

zfsを作成する前に。
圧縮モードをlz4にする。lz4はCPU負荷の割には非常に効率が良いので積極的に有効にしたい。
また、atime(アクセスタイムの記録)もoffに。これがonだと差分snapshotが失敗するから、というのが一つと、これをoffにするとパフォーマンスが上がる(can result in significant performance gains)から。
zfs get <プロパティ名> で現在の値を取得。
zfs set <プロパティ名>=<値> で値のセット。
圧縮モードのプロパティ名はcompression、atimeはatime。

$ zfs get compression warehouse
NAME       PROPERTY     VALUE     SOURCE
warehouse  compression  off       default
$ zfs get atime warehouse
NAME       PROPERTY   VALUE     SOURCE
warehouse  atime      on        default

# zfs set compression=lz4 warehouse
# zfs set atime=off warehouse
$ zfs get compression warehouse
NAME       PROPERTY     VALUE     SOURCE
warehouse  compression  lz4       local
$ zfs get atime warehouse
NAME       PROPERTY   VALUE     SOURCE
warehouse  atime      off       local

ディレクトリの用意とsend/recv

# zfs create warehouse/itunes
# zfs create warehouse/chamber

このとき、勝手にマウントされないようにすべきだった。-uを付ければよかったかな。
いずれにせよzfs set mountpointで後から変えられる。

sendに-Rを付けると、子孫やスナップショットもまとめてsendされる。

# zfs send -R vault/chamber@20181109 | zfs receive warehouse/chamber
# zfs send -R vault/itunes@20181109 | zfs receive warehouse/itunes

かかった時間、容量は以下の通り。うーむ。ちょっとかかったかな。

 991GiB 3:09:00 [89.5MiB/s]
1.10TiB 3:58:24 [80.3MiB/s] 

このとき適当にhtopを叩いた結果。CPU負荷はそんなんでもないので、ボトルネックは別のところにあるように思われる。

  1  [|||||||||||||||||||||                47.6%]   Tasks: 43, 0 thr; 2 running
  2  [|||||||||||||||||                    37.7%]   Load average: 0.91 1.77 1.86 
  Mem[||||||||||||||||||||||||||||||||642M/1.84G]   Uptime: 12:03:30
  Swp[|||||||||                        176M/907M]

なおCPUはAMDのTurionである。

compression=lz4の結果は.
プロパティused(HDD上の容量)とlogicalused(圧縮前容量)で調べられる。

warehouse  used                  2.00T                    -
warehouse  logicalused           2.02T                    -

本来なら2.02Tのところ、2.00Tで済んでる。

これで引っ越し完了。

以上

[メモ][FreeBSD] 複数Jailのpkg upgradeを一気に済ませたい

Pocket

メモ。

jailのpkg操作は、いちいちそのjailの中に入らなくてもpkg -j <jail名 or jail ID> …というように-jオプションを付与すればできる。

しかしjailの指定は、個々に行う必要がある。
たとえばpkg -j * upgradeというように、ワイルドカードを使うようなことは、もってのほかのようである。
jailなんてどんどん増えていくのに、いちいち-jで指定していくのもなあ。
仕方ないんで、やっつけでパイプを繋いで実現。

以上

[メモ][FreeBSD] owncloud + nginx + php-fpm + MySQLのインストール

Pocket

owncloudは自家製dropboxのようなもの。
以下、メモ。

owncloudの構成

owncloudはphpで作られている。
そしてインタフェースはhttps。
したがって、動作にはowncloudのほかに、php, webサーバが必要。
さらにバックエンド用のデータベースソフトウェアも必要である。

packageのowncloud

owncloudはバックエンドのDBにMySQL, SQLiteなどが選べる。
個人用ならSQLiteでも大丈夫そうだが、packageに用意されているowncloudはMySQLが有効、SQLiteが無効になっている。
SQLite版owncloudが欲しければportsからコンパイルする必要がある。
これまた面倒なのでpackageのものを使った。
packageからowncloudをインストールすると、phpは勝手に入るが、webサーバ、MySQLは別にインストールする必要がある。
ここではwebサーバにnginxを選んだ。
ではMySQLは。

MySQLのバージョン選定

いや、MySQLはMySQLに決まっているんだが、実はpackageを探すと、5.1, 5.5, 5.6の三つがあるのだ。

果たしてどれを選べばよいのであろうか。

MySQL 5.1 vs. 5.5 vs. 5.6 Performance Comparison


以上のURL他を見たところ、最新の5.6で良さそうなのでmysql56-server-5.6.24をインストールしておいた。

owncloudのインストール

packageで入れるだけ。
いっしょにnginx, mysql5.6も入れる。

MySQLの設定

owncloudのデータベースを受け持つMySQLの設定
システム起動時にMySQLも自動的に起動するように設定。

すぐ起動

mysql_secure_installationでセキュリティを高めておくと同時にスーパーユーザのパスワードも設定。

データベースの作成
USERはユーザ名に、CHANGE_THIS_PASSWORDはパスワードに書き換えること。

phpの設定

owncloudはphpで書かれている。そのphpの設定。
とはいえ、特別、何かすることはない。

/usr/local/etcにあるphp.ini-production を、php.ini としてコピー

次に/usr/local/etc/php/extensions.ini に以下の記載があることを確認する(デフォルトで記載があるはず)

php-fpmの設定

そのままでは静的コンテンツしか扱わないnginxが、phpを実行できるようにするための設定。
php-fpmがデーモンとして動作し、nginxからの要求に応じてphpを実行して結果を返す。
したがってphp-fpmとnginxがどう通信するかを規定したり、システム起動時にphp-fpmが自動的に起動するような指定が必要。

まずはphp-fpmの設定。
/usr/local/etc/php-fpm.confに以下があればよい。
それ以外はむしろ冗長だし、見にくくなるので削ってしまってよい。

システム起動時のphp-fpm起動設定
/etc/rc.conf内ではphp-fpmではなくphp_fpmとなることに注意(ハイフンではなくアンダースコア)

nginxの設定…の前に、SSLの準備

SSLのためにはサーバの鍵が必要。
手前味噌だが、ここにあるスクリプトを使ってくれい。

秘密鍵、証明書、DHパラメータ、三つのファイルを作成して、/usr/local/etc/sslあたりに入れる。

nginxの設定

以下、二つのサイトを参考にしつつ作成。

https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=nginx-1.8.0&openssl=1.0.1l&hsts=yes&profile=intermediate
https://doc.owncloud.org/server/7.0/admin_manual/installation/nginx_configuration.html

出来たのが以下。

nginxの起動設定とサービススタート

nginx, php-fpmを起動し、https://<サーバアドレス>にブラウザで繋げばOK

その他参考

https://doc.owncloud.org/server/7.0/admin_manual/configuration/database_configuration.html

No tags for this post.