俺様サーバー構築記 - ZFSをarchisoに埋め込む; やり直し@VirtualBox(UEFI)

（2020.06.15. 追記ここから）
ZFSを使う場合は、ちょっと古いカーネルを利用した方が良さそうです。そのためLTS版カーネルによるarchisoを作成する事にしました。その手順は下記になりますので、そちらをご覧ください。
[俺様サーバー構築記 - ZFSをarchisoに埋め込む(linux-lts)@VirtualBox(UEFI)](https://qiita.com/katz_engineer/items/70e6a75581c60426c836)
（2020.06.15. 追記ここまで）

「[俺様サーバー構築記 - 基本方針](https://qiita.com/katz_engineer/items/dbabcff4e14e9db2b10f)」に基づいて ArchLinux+ZFS をインストールしてきた[ノートパソコン~~三代目~~3台目](https://qiita.com/katz_engineer/items/d4a82d279f77d7ec8bde)ですが。実は、先日、やらかしまして…

```pacman -Syu``` した時に、その途中で電源が切れてしまいました:sweat: やべぇ！ってんで直前に撮った命綱のスナップショットにロールバックしようと、[最初にインストーラを焼いたUSBメモリ](https://qiita.com/katz_engineer/items/6f6ef6171f1fdcc4ec23)から起動…できませんでした:scream:

どういう訳か、起動できなくなっていたようです。壊れたか、別の理由があるのか。まぁ内容も古いし作り直そうかと。…思ったのですが、その手順も微妙に変わった模様:sob:

仕方ありません。やり直しました。

折角なので Win10 上の VirtualBox に作成してUSBメモリへの焼き付けも試みてみました。

# 参考文献

- [俺様サーバー構築記 - ZFS の上に Arch Linux をインストール@VirtualBox(UEFI)](https://qiita.com/katz_engineer/items/2c013369a51d3fd2f69e)
- [俺様サーバー構築記 - ZFSをarchisoに埋め込む@デスクトップパソコン(BIOS)](https://qiita.com/katz_engineer/items/6f6ef6171f1fdcc4ec23)
- [インストールガイド - ArchWiki](https://wiki.archlinux.jp/index.php/%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%82%AC%E3%82%A4%E3%83%89)

# download

[Arch Linux をダウンロード](https://www.archlinux.jp/download/)のページから、適当なミラーを選択しましょう。私は何も考えずにリストの最上位 jaist.ac.jp を選択しました。

そして今日の時点での ArchLinux インストーラー最新版をダウンロードします。今回は archlinux-2019.12.01-x86_64.iso です。

# VirtualBox

Windows10 にインストールしてあった VirtualBox を使用し、新規作成します。
私の VirtualBox のバージョンは 6.0.14 r133895 (Qt5.6.2) でした。

仮想マシンはごく普通の設定です。強いて言えば、メモリが若干多めですかね。今時はこの程度でも普通だと思いますが。サーバにするならむしろ少ないくらいですか。
タイプ: Linux
バージョン: Arch Linux (64-bit)
メモリーサイズ: 4096MB
仮想ハードディスクを作成する
　ファイルサイズ: 100.00GB
　ハードディスクのタイプ: VDI (VirtualBox Disk Image)
　物理ハードディスクにあるストレージ: 可変サイズ

以上で作成した後、設定によって少々いじります。
システム:
　拡張機能: EFIを有効化(一部のOSのみ)
　プロセッサー数: 2
ストレージ:
　コントローラー: （ダウンロードした archlinux-2019.12.01-x86_64.iso を選択）
オーディオ: オーディオを無効にする
ネットワーク: ネットワークアダプターを有効化、割り当て=NAT （ホストマシンはノートパソコンで無線LANを使用しているので、ブリッジではゲストのネットワークがうまくつながらない）

そして起動！ここからがインストールの本番です。

# 待つ

画面真っ黒のまま、しばらく待たされるんですよね～… いつまで経っても改善されません。これ、慣れないと心臓に悪い。何とかなりませんかねぇ。

# インストールの準備

## 署名の検証

省略します。最初は ArchLinux 環境が無いって事で。

## キーボード

```console
# loadkeys jp106
```

## コンソールフォント

コンソールフォントはそのまま変更しません。日本語が表示されればそれなりに便利そうだけども、当面は必要無いと判断。

## 起動モードの確認

VirtualBox仮想マシンの設定で UEFI にしましたが、念の為。

```console
# ls /sys/firmware/efi/efivars
（表示省略）
```

## パーティション

一応 HDD を確認しておきます。

```console
# ls /dev/sd*
/dev/sda
```

lsblkコマンドを使うと、多少整理されて見えます。

```console
# lsblk
NAME  MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
loop0   7:0    0 524.5M  1 loop /run/archiso/sfs/airootfs
sda     8:0    0   100G  0 disk
sr0    11:0    1   639M  0 rom  /run/archiso/bootmnt
```

ディスク構成が複雑な場合は ```/dev/disk/by-id``` を見ると、ファイル名（＝デバイスID）からもう少し情報を得られる可能性があるんですが。今回は VirtualBox なので省略します。

デバイスを確認した所で、HDDにパーティションを切ります。UEFIなので、EFIシステムパーティションが必要です。それとルートディレクトリのパーティション。まぁ、すぐに廃棄するのでいい加減で大丈夫です。

[パーティショニング - ArchWiki](https://wiki.archlinux.jp/index.php/パーティショニング#.E3.82.B9.E3.83.AF.E3.83.83.E3.83.97)の[パーティションの大きさはどうすればいいですか？]に下記のような記述があります。

> 大容量のメモリ（1024MB 以上）を積んでいるときは、スワップパーティションは小さく、または作らなくてもかまわないでしょう。2GB 以上の物理 RAM を持っているなら、スワップパーティションがないほうが一般的に良いパフォーマンスを発揮すると思われます。

これを信じてスワップパーティションは作りません。

また[以前](https://qiita.com/katz_engineer/items/6f6ef6171f1fdcc4ec23#%E3%83%91%E3%83%BC%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%B3)も書きましたが、一応、HDDフォーマットの前に ```wipefs``` コマンドを実行します。

```console
# wipefs -a /dev/sda
# sgdisk -Z /dev/sda
GPT data structures destroyed! You may now partition the disk using fdisk or
other utilities.
# sgdisk -n "0::+512M" -t 0:ef00 -c 0:"EFI System" /dev/sda
Creating new GPT entries in memory.
Setting name!
partNum is 0
The operation has completed successfully.
# sgdisk -n "0::" -t 0:bf00 -c 0:"Solaris root" /dev/sda
Setting name!
partNum is 1
The operation has completed successfully.
```

確認。

```console
# sgdisk -p /dev/sda
Disk /dev/sda: 209715200 sectors, 100.0 GiB
Model: VBOX HARDDISK
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): C8D9AEB5-644D-4B8F-8654-678B4B8ACD76
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 209715166
Partitions will be aligned on 2048-sectr boundaries
Total free space is 2014 sectors (1007.0 KiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         1050623   512.0 MiB   EF00  EFI System
   2         1050624       209715166   99.5 GiB    BF00  Solaris root
# ls -l /dev/sd*
brw-rw---- 1 root disk 8, 0 Dec 24 08:35 /dev/sda
brw-rw---- 1 root disk 8, 1 Dec 24 08:35 /dev/sda1
brw-rw---- 1 root disk 8, 2 Dec 24 08:35 /dev/sda2
```

## パーティションのフォーマット

EFIパーティションはFAT32。ルートは…ハッキリ言って何でもいい。すぐにzfsで再インストールしますので。

```console
# mkfs.fat -F32 /dev/sda1
mkfs.fat 4.1 (2017-01-24)
# mkfs.ext4 /dev/sda2
mke2fs 1.45.4 (23-Sep-2019)
Creating filesystem with 26083067 4k blocks and 6520832 inodes
Filesystem UUID: 1b5fe8d9-9118-4cd5-be9c-3c2d2b293ac9
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
        4096000, 7962624, 11239424, 20480000, 23887872

Allocating group tables: done
Writing inode tables: done
Creating journal (131072 blocks): done
Writing superblocks and filesystem accounting information: done
```

## パーティションのマウント

```console
# mount /dev/sda2 /mnt
# mkdir /mnt/boot
# mount /dev/sda1 /mnt/boot
```

## インターネットへの接続

ネットワーク環境が確立しているかどうか、外部へのpingによって確認します。

```console
# ping -c2 archlinux.jp
PING archlinux.jp (160.16.119.98) 56(84) bytes of data.
64 bytes from tk2-235-27344.vs.sakura.ne.jp (160.16.119.98): icmp_seq=1 ttl=51 time=10.9 ms
64 bytes from tk2-235-27344.vs.sakura.ne.jp (160.16.119.98): icmp_seq=2 ttl=51 time=18.6 ms

--- archlinux.jp ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1028ms
rtt min/avg/max/mdev = 10.884/14.754/18.625/3.870 ms
```

## システムクロックの更新

ntpサーバは自分で設定したい。日本ならntp.nict.jpが鉄板です。特殊事情が無ければこの一択。システム推奨なんか知りませ～ん。

```console
# cd /etc/systemd
# sed -i -e"s/^#NTP=/NTP=ntp.nict.jp/" timesyncd.conf
# timedatectl set-ntp true
# timedatectl status
                      Local time: Tue 2019-12-24 08:50:49 UTC
                  Universal time: Tue 2019-12-24 08:50:49 UTC
                        RTC time: Tue 2019-12-24 08:50:49
                       Time zone: UTC (UTC, +0000)
       System clock synchronized: yes
systemd-timesyncd.service active: active
                 RTC in local TZ: no
# systemctl status systemd-timesyncd
  systemd-timesyncd.service - Network Time Synchronization
   Loaded: loaded (/usr/lib/systemd/system/systemd-timesyncd.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2019-12-24 08:50:30 UTC; 1min 33s ago
     Docs: man:systemd-timesyncd.service(8)
 Main PID: 866 (systemd-timesyn)
   Status: "Initial synchronization to time server 133.243.238.243:123 (ntp.nict.jp)."
    Tasks: 2 (limit: 4670)
   Memory: 1.4M
   CGroup: /system.slice/systemd-timesyncd.service
           └─866 /usr/lib/systemd/systemd-timesyncd

Dec 24 08:50:30 archiso systemd[1]: Starting Network Time Synchronization...
Dec 24 08:50:30 archiso systemd[1]: Started Network Time Synchronization.
Dec 24 08:50:32 archiso systemd-timesyncd[866]: Initial syncronization to time server 133.243.238.243:123 (ntp.nict.jp).
```

# インストール

## ミラーの選択

日本ならJapanをリスト先頭に持ってきましょう。っていうか Japan だけ抜き出しました。

```console
# cd /etc/pacman.d
# sed -i -ne"/^#.*Japan$/,+1 p" mirrorlist
```

## ベースシステムのインストール

UEFIブートに必要なパッケージも同時に落としてきます。

今時は、CPUのデバッグ用パッチもOSが面倒を見るらしい。その為のパッケージ intel-ucode も落としておきます。

とりあえず現時点で必要最小限のパッケージはこれだけ。他に必要なパッケージは、必要に迫られた時に追加する事にします。

※ ArchWiki を見ると、パッケージの構成が少し変わったようです。
※特にテキストエディタが入っていません。何でも良いんですが、個人的な好みで vi を入れます。
※ man も入らないようです。インストールセットには要らないだろうと判断してそのままです。

```console
# pacstrap /mnt base linux linux-firmware vi dosfstools efibootmgr intel-ucode
〈表示省略〉
```

# システムの設定

## fstab

```console
# genfstab -U /mnt >>/mnt/etc/fstab
# cat /mnt/etc/fstab
# Static information about the filesystems.
# See fstab(5) for details.

# <file system> <dir> <type> <options> <dump> <pass>
# /dev/sda2
UUID=1b5fe8d9-9118-4cd5-be9c-3c2d2b293ac9       /               ext4           rw,relatime    0 1

# /dev/sda1
UUID=EC46-153B          /boot           vfat           rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro        0 2
```

## chroot、タイムゾーン

```console
# arch-chroot /mnt
# ln -s /usr/share/zoneinfo/Japan /etc/localtime
# hwclock --systohc --utc
```

## ロケール

```console
# sed -i -e"s/^#\(ja_JP\.\)/\1/" /etc/locale.gen
# locale-gen
Generating locales...
  ja_JP.EUC-JP... done
  ja_JP.UTF-8... done
Generation complete.
# echo LANG=C >/etc/locale.conf
# echo KEYMAP=jp106 >/etc/vconsole.conf
```

日本語フォントが入っていない場合は LANG=C にしておきましょう。文字化けが非常に鬱陶しい事になります。正しくは en_US.UTF-8 らしいですけども、まあいいかなと。

## ホストネーム

マシンに名前を付けます。こういうのはセンスが出ますよね。なんて思うのは私だけ？

```console
# echo 〈ホスト名〉 >/etc/hostname
```

ArchWiki では同じ名前を /etc/hosts にも記述する事になってますけど、今回はインストーラですし、要らないでしょう。

## Initramfs

```console
# mkinitcpio -p linux
〈表示省略〉
但し、途中で警告が出た:
==> WARNING: Possibly missing firmware for module: wd719x
==> WARNING: Possibly missing firmware for module: aic94xx
良くわからないが、ひとまず無視
```

##　Rootパスワード

```console
# passwd
New password: 〈root用パスワード〉
Retype new password: 〈root用パスワード〉
passwd: password updated successfully
```

## ブートローダー

UEFI起動の場合、systemdがブートローダを持っているらしい。

参考文献:

* [1.1 EFI ブートマネージャのインストール - 1 インストール - systemd-boot - ArchWiki](https://wiki.archlinux.jp/index.php/Systemd-boot#EFI_.E3.83.96.E3.83.BC.E3.83.88.E3.83.9E.E3.83.8D.E3.83.BC.E3.82.B8.E3.83.A3.E3.81.AE.E3.82.A4.E3.83.B3.E3.82.B9.E3.83.88.E3.83.BC.E3.83.AB)

```console
# bootctl --path=/boot install
Created "/boot/EFI".
Created "/boot/EFI/systemd".
Created "/boot/EFI/BOOT".
Created "/boot/loader".
Created "/boot/loader/entries".
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" to "/boot/EFI/systemd/systemd-bootx64.efi"
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" to "/boot/EFI/BOOT/BOOTX64.EFI".
Created "/boot/f4127869934740bb9da39f6475438a89".
Random seed file /boot/loader/random-seed successfully written (512 bytes).
Not installing system token, since we are running in a virtualized environment.
Created EFI boot entry "Linux Boot Manager".
```

更にIntelのマイクロコードのアップデートを有効にします。

参考文献:

* [systemd-boot - サンプル - マイクロコードのアップデート - ArchWiki](https://wiki.archlinux.jp/index.php/マイクロコード#systemd-boot)
* [標準的な root インストール - systemd-boot - ArchWiki](https://wiki.archlinux.jp/index.php/Systemd-boot#.E6.A8.99.E6.BA.96.E7.9A.84.E3.81.AA_root_.E3.82.A4.E3.83.B3.E3.82.B9.E3.83.88.E3.83.BC.E3.83.AB)

```console
# cat >/boot/loader/entries/entry.conf <<___
> title   Arch Linux
> linux   /vmlinuz-linux
> initrd  /intel-ucode.img
> initrd  /initramfs-linux.img
> options root=PARTUUID=$(blkid --match-tag PARTUUID -o value /dev/sda2)
> ___
```

## ネットワーク

デバイス名の固定は考えません。すぐにzfsで再インストールしますので。と言っても systemd を使うと勝手に固定してくれるようですが。

```console
# cat >/etc/systemd/network/all.network <<___
> [Match]
> Name=*
>
> [Network]
> DHCP=ipv4
> ___
# systemctl enable systemd-networkd
Created symlink /etc/systemd/system/dbus-org.freedesktop.network1.service -> /usr/lib/systemd/system/systemd-networkd.service.
Created symlink /etc/systemd/system/multi-user.target.wants/systemd-networkd.service -> /usr/lib/systemd/system/systemd-networkd.service.
Created symlink /etc/systemd/system/sockets.target.wants/systemd-networkd.socket -> /usr/lib/systemd/system/systemd-networkd.socket.
Created symlink /etc/systemd/system/network-online.target.wants/systemd-networkd-wait-online.service -> /usr/lib/systemd/system/systemd-networkd-wait-online.service.
```

なお /mnt/etc/resolv.conf は arch-chroot によって /etc/resolv.conf に置き換えられているようです。そのため exit してから設定しないと、設定前の何も無い状態に書き戻されてしまいます。インストール手順としてちょっと歪な気がしますが、arch-chrootをexitした後にresolv.confを修正します。

```console
# exit
exit
arch-chroot /mnt  12.62s user 2.81s system 2% cpu 12:04.39 total
# cp {,/mnt}/etc/resolv.conf
# vi /mnt/etc/resolv.conf
〈必要に応じて修正〉
```

## 再起動

仮想マシンをシャットダウン。

```console
# umount -R /mnt
# shutdown -h now
```

そして、VirtualBoxのストレージからインストールメディアを除去した後に再起動します。

# rootログイン

再起動してログイン画面になったら、rootユーザーでログインします。パスワードは先ほどpasswdコマンドで設定した通り。

```console

Arch Linux 4.14.9-1-ARCH (tty1)

〈ホスト名〉 login: root
Password: 〈root用パスワード〉
```

# archzfsパッケージをarchisoに埋め込む

さてここからが今回の手順の目玉。

参考文献: [8.1 archzfs パッケージを archiso に埋め込む - 8
ヒントとテクニック - ZFS - ArchWiki](https://wiki.archlinux.jp/index.php/ZFS#archzfs_.E3.83.91.E3.83.83.E3.82.B1.E3.83.BC.E3.82.B8.E3.82.92_archiso_.E3.81.AB.E5.9F.8B.E3.82.81.E8.BE.BC.E3.82.80)

まずはarchisoパッケージをダウンロード。

```console
# pacman -Syy
〈省略〉
# pacman -S archiso --noconfirm --noprogressbar
```

次に、[ArchWiki](https://wiki.archlinux.jp/index.php/ZFS#archzfs_.E3.83.91.E3.83.83.E3.82.B1.E3.83.BC.E3.82.B8.E3.82.92_archiso_.E3.81.AB.E5.9F.8B.E3.82.81.E8.BE.BC.E3.82.80)には「プロセスを開始」って書いてあるんだけど…意味がよくわかりません。とりあえず書いてあるコピーコマンドを実行。

```console
# cp -r /usr/share/archiso/configs/releng /root/media
```

packages.x86_64 ファイルに追記。ここではダイナミックカーネルモジュールをサポートしているバージョンを選択します。いえ zfs-linux-git で何度かやったんですがね、結構頻繁にダメになるんですよ、 zfs のバージョンとカーネルバージョンの不一致で。あまりにも面倒なので zfs-dkms を使う事にしました。

zfs を使う時には spl (Solaris Porting Layer) も入れる必要があります。また dkms を使う時には linux-headers をインストールしておく必要があります。

```console
# cd /root/media
# cat >>packages.x86_64 <<___
> linux-headers
> zfs-dkms
> ___
```

pacman.conf ファイルに追記。

```console
# cat >>pacman.conf <<'___'
>
> [archzfs]
> SigLevel = Never
> Server = http://archzfs.com/$repo/x86_64
> ___
```

イメージ作成。ここで、結構な時間が掛かります。

```console
# ./build.sh -v
（省略）
[mkarchiso] INFO: Done! | 743M out/archlinux-2019.12.24-x86_64.iso
```

# USBメモリへの焼き付け

ホストマシンの USB 端子に USB メモリを挿して、仮想マシンに接続します。それは手作業で。

接続できたらゲストマシンで確認。

```console
# ls /dev/sd*
/dev/sda  /dev/sda1  /dev/sda2  /dev/sdb  /dev/sdb1  /dev/sdb2
```

USBメモリを挿した後に下記コマンドを実行して、焼き付けるべきデバイスが /dev/sdb である事を確認します。以前入れたモノが表示に影響してますかね。

```console
# lsblk -dpo NAME,FSTYPE,LABEL,UUID /dev/sdb
NAME     FSTYPE  LABEL       UUID
/dev/sdb iso9660 ARCH_201901 2019-01-13-11-36-23-00
```

完成したisoイメージファイルをUSBメモリに焼き付けます。

```console
# ls out
archlinux-2019.12.24-x86_64.iso
# dd bs=4M if=out/archlinux-2019.12.24-x86_64.iso of=/dev/sdb status=progress && sync
708837376 bytes (709 MB, 676 MiB) copied, 2 s, 352 MB/s[ 2457.727593] INFO: task systemd-udevd:264 blocked for more than 122 secondes.
[ 2457.732177]       Not tainted 5.4.6-arch1-1 #1
[ 2457.734542] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.

185+1 records in
185+1 records out
779091968 bytes (779 MB, 743 MiB) copied, 259.159 s, 3.0 MB/s
```

これでUSBメモリに焼けたハズ。

これで ArchLinux をシャットダウン。

```console
# shutdown -h now
```

VirtualBox その他ホストマシンで起動していたアプリも全部終了し、ホストマシンをそのままUSBメモリから起動してみます。

まずは ArchLinux の起動を確認。それから zfs を確認します。

```console
# modprobe zfs
```

何も表示されなければOKです！やったね :thumbsup_tone1: