俺様サーバー構築記 - ZFS の上に Arch Linux と無線LANをインストール; やり直し(Linux-LTS)@ノートパソコン(UEFI+wifi)

「[俺様サーバー構築記 - 基本方針](https://qiita.com/katz_engineer/items/dbabcff4e14e9db2b10f)」に基づく作業の続き。[以前](https://qiita.com/katz_engineer/items/d4a82d279f77d7ec8bde)インストールした[ノートパソコン3台目](https://qiita.com/katz_engineer/items/9157870d0b65bd1a99ae#%E5%89%8D%E6%9B%B8%E3%81%8D%E3%83%9E%E3%82%B7%E3%83%B3%E3%82%B9%E3%83%9A%E3%83%83%E3%82%AF)です。悪名高かった HP Pavilion TouchSmart 10-e013AU

こいつに[LTS版Linux + ZFS](https://qiita.com/katz_engineer/items/70e6a75581c60426c836)でインストールをやり直します。が… [前回](https://qiita.com/katz_engineer/items/3ec8f7bfd3051e60586b)も書きましたが、インストーラをLTS版にする必要は無さそうですな。LTS版カーネルによるインストーラ作成手順に意味が無い訳では無いですけど。カーネル改変でzfsが対応していない期間にインストーラを作成できない事になったら大変ですし。

参考文献1: [俺様サーバー構築記 - ZFS の上に Arch Linux と無線LANをインストール@ノートパソコン3台目(UEFI)](https://qiita.com/katz_engineer/items/d4a82d279f77d7ec8bde)
参考文献2: [俺様サーバー構築記 - ZFSをarchisoに埋め込む(linux-lts)@VirtualBox(UEFI)](https://qiita.com/katz_engineer/items/70e6a75581c60426c836)


# 前書き：マシンスペック

再掲。

機種：HP Pavilion TouchSmart 10-e013AU
型番: F6C99PA#ABJ
CPU: AMD A4-1200 APU with Radeon(TM) HD Graphics
クロック: 1.00GHz
メモリ: 2GB
HDD: 320GB

64ビットCPUですが、メモリは2GB。ギリギリですな。それでも、snapshot機能が捨て難いのでZFSでフォーマットします。btrfs？ちょっと主流から外れ過ぎてる気がします。

# インストールの準備

何はともあれ、ローカルに溜め込んだファイルが無いか確認。あればどこかに保存します。完全にフォーマットからやり直して、ローカルの内容を全部吹っ飛ばすつもりなので。

それとマシン名も確認。同じ名前で作成します。マシン名も有限な資源の一つ。特に、何らかの規則で自分だけの微笑ましい名前を付けてる場合は重要…

ブートメディアは、現時点ではUSBメモリになってる筈。もし違うようならBIOS画面で設定します。

ここまでやってから、[前回のZFS関連ツールを埋め込んだarchisoを焼き付けたUSBメモリ](https://qiita.com/katz_engineer/items/70e6a75581c60426c836)をマシンに挿して電源を入れ、BIOSでブートメディアを設定。
そして起動すると、いつもの Arch Linux インストールメディアのメニューが出ます。いつも通りに選択して起動。

## キーボード

```console
# loadkeys jp106
```

## コンソールフォント

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

## 起動モードの確認

EFIだという事はわかっていますが念の為。

```console
# ls /sys/firmware/efi/efivars
〈沢山表示されるけど省略〉
```

## パーティション

HDDを確認しておきます。何だか訳の分からないパーティションになってますが。

```console
# ls /dev/sd*
/dev/sda  /dev/sda1  /dev/sda9  /dev/sdb  /dev/sdb1  /dev/sdb2  /dev/sdc  /dev/sdc1  /dev/sdc2
```

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

```console
# lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
loop0    7:0    0   621M  1 loop /run/archiso/sfs/airootfs
sda      8:0    0 298.1G  0 disk
├─sda1   8:1    0 298.1G  0 part
├─sda9   8:9    0     8M  0 part
sdb      8:16   1  14.7G  0 disk
├─sdb1   8:17   1   512M  0 part
└─sdb2   8:18   1  14.2G  0 part
sdc      8:32   1   7.3G  0 disk
├─sdc1   8:33   1   736M  0 part /run/archiso/bootmnt
└─sdc2   8:34   1    64M  0 part
```

```/dev/sdb``` とその眷属（```/dev/sdb1``` ```/dev/sdb2```）は、今まで起動用に使っていたUSBメモリですね。```/dev/sdb1``` にGRUBを入れていて、```/dev/sdb2```はFAT32でフォーマットしてある外部記憶装置扱いの部分です。

```/dev/sdc``` とその眷属（```/dev/sdc1``` ```/dev/sdc2```）が起動する時に使用したUSBメモリです。mountコマンドの結果にそれが表れます。

```console
# mount | grep /dev/sd
/dev/sdc1 on /run/archiso/bootmnt type iso9660 (ro,relatime,nojoliet,check=s,map=n,blocksize=2048)
```

```/dev/disk/by-id``` を見ると、ファイル名（＝デバイスID）からもう少し情報を得られる可能性があります。どのようなデバイスなのかによって命名されるらしいので。BIOS画面などから得たHDDの商品名などと突き合わせればハッキリするでしょう。

```console
# ls -l /dev/disk/by-id
total 0
lrwxrwxrwx 1 root root  9 Jun 27 12:09 ata-ST320LT012-1DG14C_S3P11L17 -> ../../sda
lrwxrwxrwx 1 root root 10 Jun 27 12:09 ata-ST320LT012-1DG14C_S3P11L17-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 Jun 27 12:09 ata-ST320LT012-1DG14C_S3P11L17-part9 -> ../../sda2
lrwxrwxrwx 1 root root  9 Jun 27 12:09 usb-058f_6387_17082208002200-0:0 -> ../../sdc
lrwxrwxrwx 1 root root 10 Jun 27 12:09 usb-058f_6387_17082208002200-0:0-part1 -> ../../sdc1
lrwxrwxrwx 1 root root 10 Jun 27 12:09 usb-058f_6387_17082208002200-0:0-part2 -> ../../sdc2
lrwxrwxrwx 1 root root  9 Jun 27 12:09 usb-SanDisk__Cruzer_Fit_4C530000180129117161-0:0 -> ../../sdb
lrwxrwxrwx 1 root root 10 Jun 27 12:09 usb-SanDisk__Cruzer_Fit_4C530000180129117161-0:0-part1 -> ../../sdb1
lrwxrwxrwx 1 root root 10 Jun 27 12:09 usb-SanDisk__Cruzer_Fit_4C530000180129117161-0:0-part2 -> ../../sdb2
lrwxrwxrwx 1 root root  9 Jun 27 12:09 wwn-0x5000c5006d071946 -> ../../sda
lrwxrwxrwx 1 root root 10 Jun 27 12:09 wwn-0x5000c5006d071946-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 Jun 27 12:09 wwn-0x5000c5006d071946-part9 -> ../../sda9
```

最後の```wwn-```何とかいうデバイス名の正体が不明ですが、今回は関係無いので放置！

という訳で ```/dev/sda``` がHDDです。このマシンにはDVDドライブはありません。

デバイスを確認した所で、HDDにパーティションを切ります…が、
[1.11 性能が今ひとつなんだけど。 - ZFS on Linux FAQ](https://www.nosuz.jp/ZFSonLinux/faq_ja.html#PerformanceConsideration)という記事を発見。

> ディスク全体を使ってpoolを作成する: ディスク全体を指す名前を使ってzpool createを実行します。こうするとZFSは、正しい配置になるように自動的にパーティションを作成します。さらにwholedisk設定のおかげで他のZFS実装との相互運用性も改善されます。

ZFSに詳しい方にとっては常識なのだと思いますけども。そういう訳でパーティションを一切作りません。ブートに関しては外部メディアに頼る事にします。内蔵HDDだけでは完結しなくてちょっと悔しいですが。詳しくは後述。

HDDフォーマットの前に ```wipefs``` コマンドを実行します。

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

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

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

```console
# wipefs -a /dev/sda
/dev/sda: 8 bytes were erased at offset 0x00000200 (gpt): 45 46 49 20 50 41 52 54
/dev/sda: 8 bytes were erased at offset 0x4a85d55e00 (gpt): 45 46 49 20 50 41 52 54
/dev/sda: 2 bytes were erased at offset 0x000001fe (PMBR): 55 aa
/dev/sda: calling ioctl to re-read partition table: Success
```

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

いよいよ ZFS です。
参考文献：[3 ディスクのフォーマット - ZFS に Arch Linux をインストール - ArchWiki](https://wiki.archlinux.jp/index.php/ZFS_に_Arch_Linux_をインストール#.E3.83.87.E3.82.A3.E3.82.B9.E3.82.AF.E3.81.AE.E3.83.95.E3.82.A9.E3.83.BC.E3.83.9E.E3.83.83.E3.83.88)

まず、ZFS モジュールがロードされていることを確認。
下記コマンドで、結果が何も表示されなければ成功です。わかりにくい…

```console
# modprobe zfs
```

どうしても画面に反応が欲しいなら wc -l で出力行数を数えましょう。
0 だけが表示されれば成功です。問題があればエラーメッセージも表示される筈です。

```console
# modprobe zfs | wc -l
0
```

zpool を作成します。

このzpoolの名前なんですが、ArchWikiにはzpoolと書いてあります。コマンド名と同じというのも混乱の元ですし、そもそもOracle製のマニュアルに書いてある実行例ではtankなんですよね。FreeNASもtankです。
という訳で、ArchWikiとは違いますがここではtankと名付けます。

そしてもう1点。
デバイスの指定にはidを使え、とArchWikiに書かれています。しかしデバイス名からidを取得するコマンドが無い。SCSI関係のコマンドで取得できるようですが。
```ls -l /dev/disk/by-id``` を見ればわかるんですが、シンボリックリンク先が相対パスになっているのがまた残念。
それでも目で見ればわかるんですが、ファイル名が長いですし、コマンドで取得します。

```console
# cd /dev/disk/by-id
# ls ata-* | while read d; do if [ "$(readlink -f $d)" = "/dev/sda” ]; then echo "/dev/disk/by-id/$d"; fi; done | xargs -t zpool create -f tank
zpool create -f tank ata-ST320LT012-1DG14C_S3P11L17
# zpool status
  pool: tank
 state: ONLINE
  scan: none requested
config:

        NAME                              STATE    READ WRITE CKSUM
        tank                              ONLINE      0     0     0
          ata-ST320LT012-1DG14C_S3P11L17  ONLINE      0     0     0

errors: No known data errors
```

最後のエラー「No known data errors」は「既知のエラーは何も無い」という意味です。だったら「Success」とか「ok」とか表示してくれればいいのに…

メインのファイルシステムとして tank/main を作成します。
また tank のマウントポイントは削除しますが、念の為noneではなくlegacyにしておきます。

```console
# zfs create -o mountpoint=/ tank/main
cannot mount '/': directory is not empty
filesystem successfully created, but not mounted
# zfs set mountpoint=legacy tank
# zfs list
NAME        USED  AVAIL  REFER  MOUNTPOINT
tank        552K   289G    96K  legacy
tank/main    96K   289G    96K  /
```

## サブファイルシステム

サブファイルシステムを作ります。

今回のノートパソコンではなくて、サーバとして建てたデスクトップマシンの為の設定ではありますが。今までの経験からユーザデータは分離した方が何かと都合が良い事がわかりました。システムがぶっ壊れた場合にもユーザデータを保護できるよう、システムとユーザの領域を分離します。その為にノートパソコンでもサブファイルシステムを用意します。

参考文献: [俺様サーバー構築記 - 待機系構築を睨んだディレクトリ構造の変更@デスクトップパソコン; やり直し](https://qiita.com/katz_engineer/items/e1d27692e9e5dd4e11c9)

以下の4つのディレクトリをサブファイルシステムにします。

- ```/home```
- ```/opt```
- ```/srv```
- ```/var/opt```

後日検討してもっと増える可能性もあります。例えば ```/usr``` ディレクトリは元々複数マシン間で共有対象となるコマンドなどの置き場所として FHS で仕様化されていますが、今回の用途では共有不要と考えました。その辺で判断が変わる可能性が無きにしも非ず。

参考文献: [重ね重ね・ArchLinux インストール覚書](https://qiita.com/katz_engineer/items/3c4bafd3aeb32aa2eaf0)

しかしマウントポイントは、なぜかうまく効いてくれません。理由がわからなくて、諦めました… ```genfstab``` の都合で設定しておきますが、後で ```/etc/fstab``` を作成したらlegacyに変更します。

```console
# for d in /home /opt /srv /var/opt; do zfs create -p tank/sub0$d -o mountpoint=$d; done
cannot mount '/srv': directory is not empty
filesystem successfully created, but not mounted
```

プロパティは```/var```のみ要求される物があるようです。

参考文献: [俺様サーバー構築記 - systemd-journald](https://qiita.com/katz_engineer/items/7b3f490749272663db7c)

```console
# zfs set xattr=sa acltype=posixacl tank/sub0/var
```

## ブート用の設定

ルートファイルシステムに bootfs プロパティを設定します。

```console
# zpool set bootfs=tank/main tank
```

プール tank をエクスポートして、```/mnt``` 以下にインポートし直します。

```console
# zpool export tank
# zpool import -d /dev/disk/by-id -R /mnt tank
```

ここで、マウントポイントの /mnt を確認します。

```console
# mount | grep tank
tank/main on /mnt type zfs (rw,xattr,noacl)
tank/sub0/home on /mnt/home type zfs (rw,xattr,noacl)
tank/sub0/var/opt on /mnt/var/opt type zfs (rw,xattr,posixacl)
tank/sub0/opt on /mnt/opt type zfs (rw,xattr,noacl)
tank/sub0/srv on /mnt/srv type zfs (rw,xattr,noacl)
```

最後に、新しいシステムに zpool.cache ファイルをコピーします。そしてイヤらしい事に、 ```/etc/zfs/zpool.cache``` は存在するんですが中身がありません。最初はこれに気付かなくてエライ目に遭いました。

```console
# ls -l /etc/zfs/zpool.cache
-rw-r--r-- 1 root root 0 Jun 27 12:28 /etc/zfs/zpool.cache
# zpool set cachefile=/etc/zfs/zpool.cache tank
# ls -l /etc/zfs/zpool.cache
-rw-r--r-- 1 root root 1480 Jun 27 12:30 /etc/zfs/zpool.cache
# cp --parents /etc/zfs/zpool.cache /mnt
```

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

bootパーティションが無いのでマウントはしません。ディレクトリを作るだけです。

```console
# mkdir /mnt/boot
```

## 無線LAN

ここで無線LANを設定します。

### ドライバーの状態を確認する

```console
# lspci -k | grep -i wireless
01:00.0 Network controller: Ralink corp. RT3290 Wireless 802.11n 1T/1R PCIe
$ lspci -ks 01:00.0
01:00.0 Network controller: Ralink corp. RT3290 Wireless 802.11n 1T/1R PCIe
        DeviceName: Ralink RT3290LE 802.11bgn Wi-Fi Adapter
        Subsystem: Hewlette-Packard Company Ralink RT3290LE 802.11bgn 1x1 Wi-Fi and Bluetooth 4.0 Combo Adapter
        Kernel driver in use: rt2800pci
        Kernel modules: rt2800pci
```

無線LANインターフェイスが作成されているか確認。

```console
# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eno1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN mode DEFAULT group default qlen 1000
    link/ether 00:11:22:33:44:b2 brd ff:ff:ff:ff:ff:ff
3: wlan0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DEFAULT group default qlen 1000
    link/ether 00:11:22:33:44:c5 brd ff:ff:ff:ff:ff:ff
```

無線インターフェイスを起こして確認。

```console
# ip link set wlan0 up
# ip link show wlan0
3: wlan0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DEFAULT group default qlen 1000
    link/ether 00:11:22:33:44:c5 brd ff:ff:ff:ff:ff:ff
```

```<``` ```>``` で囲まれた部分に ```UP``` の文字が見えたら起きています。その後に続く文字列の中の ```status DOWN``` は無視しましょう。

### ワイヤレス管理

#### 情報を取得する

```console
# iw dev
phy#0
        Interface wlan0
                ifindex 3
                wdev 0x1
                addr 00:11:22:33:44:c5
                type managed
                txpower 20.00 dBm
# iw dev wlan0 link
Not connected.
```

#### アクセスポイント検索

```console
# iw dev wlan0 scan | grep SSID
        SSID: 〈我が家のアクセスポイントのSSID〉
        〈以下省略〉
```

#### 関連付け

参考文献：[WPA supplicant - ArchWiki](https://wiki.archlinux.jp/index.php/WPA_supplicant)

```/etc/wpa_supplicant/wpa_supplicant.conf``` は存在しません。

```console
# ls -a /etc/wpa_supplicant/
.  ..
```

必要な内容で作成し、コマンドを実行します。

```console
# cat >/etc/wpa_supplicant/wpa_supplicant.conf <<___
\`heredoc> ctrl_interface=/run/wpa_supplicant
\`heredoc> update_config=1
\`heredoc> ___
# wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf 
Successfully initialized wpa_supplicant
```

```wpa_cli``` コマンドを使って操作します。

```console
# wpa_cli
wpa_cli v2.9
Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi> and contributors

This software may be distributed under the terms of the BSD license.
See README for more details.


Selected interface 'wlan0'

Interactive mode

> scan
OK
<3>CTRL-EVENT-SCAN-STARTED
<3>CTRL-EVENT-SCAN-RESULTS
<3>WPS-AP-AVAILABLE
<3>CTRL-EVENT-NETWORK-NOT-FOUND
> scan_results
bssid / frequency / signal level / flags / ssid
aa:bb:cc:dd:0b:1c       2457    -66     [WPA2-PSK-CCMP][ESS]       〈我が家のSSID〉
　　〈省略〉
> add_network
0
> set_network 0 ssid "〈我が家のSSID〉"
OK
> set_network 0 psk "〈我が家のSSIDのパスワード〉"
OK
> enable_network 0
OK
<3>CTRL-EVENT-SCAN-STARTED
<3>CTRL-EVENT-SCAN-RESULTS
<3>WPS-AP-AVAILABLE
<3>SME: Trying to authenticate with aa:bb:cc:dd:0b:1c (SSID='〈我が家のSSID〉' freq=2457 MHz)
<3>Trying to associate with aa:bb:cc:dd:0b:1c (SSID='〈我が家のSSID〉' freq=2457 MHz)
<3>Associated with aa:bb:cc:dd:0b:1c
<3>CTRL-EVENT-SUBNET-STATUS-UPDATE status=0
<3>CTRL-EVENT-REGDOM-CHANGE init=COUNTRY_IE type=COUNTRY alpha2=JP
<3>WPA: Key negotiation completed with aa:bb:cc:dd:0b:1c [PTK=CCMP GTK=CCMP]
<3>CTRL-EVENT-CONNECTED - Connection to aa:bb:cc:dd:0b:1c completed [id=0 id_str=]
> save_config
OK
> quit
```

#### ネットワーク

IPv4で接続する為の設定です。

```console
# cat >/etc/systemd/network/all.network <<___
\`heredoc> [Match]
\`heredoc> Name=*
\`heredoc> 
\`heredoc> [Network]
\`heredoc> DHCP=ipv4
\`heredoc> ___
# systemctl start systemd-networkd
# ip addr show wlan0
3: wlo1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:11:22:33:44:c5 brd ff:ff:ff:ff:ff:ff
    inet 172.16.2.9/16 brd 172.16.255.255 scope global dynamic wlan0
       valid_lft 86181sec preferred_lft 86181sec
    inet6 fe80::5635:30ff:fe9b:f8c5/64 scope link
       valid_lft forever preferred_lft forever 
```

家庭内無線LANに接続できました！

最後に名前解決を設定します。

参考文献: [必要なサービスと設定 - 基本的な使い方 - systemd-networkd - ArchWiki](https://wiki.archlinux.jp/index.php/Systemd-networkd#.E5.BF.85.E8.A6.81.E3.81.AA.E3.82.B5.E3.83.BC.E3.83.93.E3.82.B9.E3.81.A8.E8.A8.AD.E5.AE.9A)

```console
# systemctl start systemd-resolved
```

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

ネットワーク環境が確立しているかどうか、外部への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=54 time=13.9 ms
64 bytes from tk2-235-27344.vs.sakura.ne.jp (160.16.119.98): icmp_seq=2 ttl=54 time=9.14 ms

--- archlinux.jp ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 9.142/11.531/13.920/2.389 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: Sat 2020-06-27 13:05:11 UTC
           Universal time: Sat 2020-06-27 13:05:11 UTC
                 RTC time: Sat 2020-06-27 13:05:11
                Time zone: UTC (UTC, +0000)
System clock synchronized: yes
              NTP service: 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 Sat 2020-06-27 13:04:51 UTC; 1min 5s ago
     Docs: man:systemd-timesyncd.service(8)
 Main PID: 1867 (systemd-timesyn)
   Status: "Initial synchronization to time server 133.243.238.163:123 (ntp.nict.jp)."
    Tasks: 2 (limit: 1986)
   Memory: 1.7M
   CGroup: /system.slice/systemd-timesyncd.service
           └─1867 /usr/lib/systemd/systemd-timesyncd

Jun 27 13:04:49 archiso systemd[1]: Starting Network Time Synchronization...
Jun 27 13:04:51 archiso systemd[1]: Started Network Time Synchronization.
Jun 27 13:05:10 archiso systemd-timesyncd[1867]: Initial synchronization to time server 133.243.238.163:123 (ntp.nict.jp).
```

# インストール

## ミラーの選択

日本ならJapanをリスト先頭に持ってきましょう。っていうか、Japanだけ抜き出しました。下手に編集などするよりもコマンドが簡単なので。

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

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

このマシンは UEFI ですが、今回はブートローダとして GRUB を使います。その為 efibootmgr もインストールします。

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

ZFSと無線LANの関連パッケージも落とします。

今回は普段使いの為のインストールなので、manなどもインストールしておきます。マニュアルだいじ。超だいじ。

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

```console
# pacstrap /mnt base linux-lts zfs-linux-lts linux-firmware vi intel-ucode grub efibootmgr iw wpa_supplicant man-db man-pages texinfo
```

# システムの設定

## pacman.conf

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

## fstab

```console
# genfstab -U -p . >>etc/fstab
```

fstabを作成した後は、各サブファイルシステムのマウントポイントをlegacyにしておきます。mountpointを設定しておいても、なぜかうまくいかないので。原因がわからなくて諦めました…

```console
# for d in /home /opt /srv /var/opt; do zfs set mountpoint=legacy tank/sub0$d; done
```

## hostid

zfsインストールに当たってはhostidが必要らしいです。ここで設定しておきましょう。
参考文献：[最初に起動した後 - ZFS に Arch Linux をインストール - ArchWiki](https://wiki.archlinux.jp/index.php/ZFS_に_Arch_Linux_をインストール#.E6.9C.80.E5.88.9D.E3.81.AB.E8.B5.B7.E5.8B.95.E3.81.97.E3.81.9F.E5.BE.8C)
ここに「/etc/hostid に hostid を書き出してから initramfs イメージを再生成する方法もあります」と書かれているので、その為の仕込みをします。

```console
# ls etc/hostid
ls: cannot access 'etc/hostid': No such file or directory
# hostid >etc/hostid
```

## chroot、タイムゾーン

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

## ロケール

どの文字コードを有効にしても良いんですが。私は日本語系を全て有効にしました。個人的な好みでEUCは必須。最近の世界の流れも無視できないのでUTF-8も有効に。

```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 にしておきましょう。文字化けが非常に鬱陶しい事になります。

## ホストネーム

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

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

## Initramfs

ZFS対応の為に```/etc/mkinitcpio.conf```を修正します。
もしも /usr のデータセットを別に作成した場合は zfs フックの後に usr フックが必要らしい。今回は作っていないので不要。
また、ext3 や ext4 のファイルシステムを使用する場合は、末尾に fsck フックを入れます。今回は ZFS だけなので不要。

```console
# sed -i -e"s/^HOOKS=.*$/HOOKS=(base udev autodetect modconf block keyboard zfs filesystems)/" /etc/mkinitcpio.conf
```

initramfsを再生成。

```console
# mkinitcpio -p linux-lts
〈表示省略〉
但し、途中で警告が出た:
==> 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
```

## ブートローダー

### GRUBをインストール

今回は UEFI である事に注意。ESP (EFI System Partition) は外部のUSBメモリに作成し、そこに GRUB をインストールします。起動用メディアを別に用意しなければならないのも業腹ですが、仕方ありませんな。

以前から使っていた小さなUSBメモリをUSB端子に挿しっ放しにしてあるので、これをそのまま流用します。

```console
# lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
loop0    7:0    0   621M  1 loop
sda      8:0    0 298.1G  0 disk
├─sda1   8:1    0 298.1G  0 part
├─sda9   8:9    0     8M  0 part
sdb      8:16   1  14.7G  0 disk
├─sdb1   8:17   1   512M  0 part
└─sdb2   8:18   1  14.2G  0 part
sdc      8:32   1   7.3G  0 disk
├─sdc1   8:33   1   736M  0 part
└─sdc2   8:34   1    64M  0 part
```

該当のUSBメモリは```/dev/sdb```です。ここにGRUBを上書きインストールします。

参考文献: [3 UEFI システム - GRUB - ArchWiki](https://wiki.archlinux.jp/index.php/GRUB#UEFI_.E3.82.B7.E3.82.B9.E3.83.86.E3.83.A0)

boot用USBメモリをここでマウントします。

```console
# exit
exit
# wipefs -a /dev/sdb
/dev/sdb: 8 bytes were erased at offset 0x00000200 (gpt): 45 46 49 20 50 41 52 54
/dev/sdb: 8 bytes were erased at offset 0x3ad3ffe00 (gpt): 45 46 49 20 50 41 52 54
/dev/sdb: 2 bytes were erased at offset 0x000001fe (PMBR): 55 aa
/dev/sdb: calling ioctl to re-read partition table: Success
# sgdisk -n0::+512M -t0:0xEF00 -n0:: /dev/sdb
Creating new GPT entries in memory.
The operation has completed successfully.
# sgdisk -p /dev/sdb
Disk /dev/sdb: 30842880 sectors, 14.7 GiB
Model: Cruzer Fit
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 8482C0B6-DBE0-4505-A50F-B32FB349B2FC
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 30842846
Partitions will be aligned on 2048-sector 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
   2         1050624        30842846   14.2 GiB   8300
# mkfs.fat -F32 /dev/sdb1
mkfs.fat 4.1 (2017-01-24)
# mkdir -p /mnt/boot/efi
# mount /dev/sdb1 /mnt/boot/efi
```

USBメモリの余った領域は、FAT32でフォーマットして自由に使えるように解放します。FAT32なら、万が一の場合はWindowsマシンでも読み出せますので。

```console
# mkfs.fat -F32 /dev/sdb2
mkfs.fat 4.1 (2017-01-24)
```

前準備が終わったのでGRUBをインストールします。

```console
# arch-chroot /mnt
# grub-install --target=x86_64-efi --efi-directory=/boot/efi --boot-directory=/boot/efi --bootloader-id=grub
Installing for x86_64-efi platform.
Installation finished. No error reported.
```

### 設定ファイル

```console
# cd /dev/disk/by-id/
# ls ata-* | while read d; do if [ "$(readlink -f $d)" = "/dev/sda" ]; then echo "/dev/$d"; fi; done | xargs -t ln -s /dev/sda
ln -s /dev/sda /dev/ata-ST320LT012-1DG14C_S3P11L17
# cd /boot/efi/grub
# grub-mkconfig -o grub.org
Generating grub configuration file ...
Found Linux image: /boot/vmlinuz-linux-lts
Found initrd image: /boot/intel-ucode.img /boot/initramfs-Linux-lts.img
/usr/bin/grub-probe: error: unknown filesystem.
/usr/bin/grub-probe: error: unknown filesystem.
Found fallback initrd image(s) in /boot: initramfs-linux-lts-fallback.img
/usr/bin/grub-probe: error: unknown filesystem.
done
# cp grub.org grub.cfg
# vi grub.cfg
〈編集〉
# diff -U0 grub.org grub.cfg
--- grub.org    2020-06-27 22:40:34.000000000 +0900
+++ grub.cfg    2020-06-27 22:43:14.000000000 +0900
@@ -84 +84,2 @@
-       insmod gzio
+       search --set --label tank
+       insmod zfs
@@ -87 +88 @@
-       linux /main@/boot/vmlinuz-linux-lts root=ZFS=/main rw  loglevel=3 quiet
+       linux /main@/boot/vmlinuz-linux-lts zfs=tank/main rw
@@ -95 +96,2 @@
-               insmod gzio
+               search --set --label tank
+               insmod zfs
@@ -98 +100 @@
-               linux /main@/boot/vmlinuz-linux-lts root=ZFS=/main rw  loglevel=3 quiet
+               linux /main@/boot/vmlinuz-linux-lts zfs=tank/main rw
@@ -105 +107,2 @@
-               insmod gzio
+               search --set --label tank
+               insmod zfs
@@ -108 +111 @@
-               linux /main@/boot/vmlinuz-linux-lts root=ZFS=/main rw  loglevel=3 quiet
+               linux /main@/boot/vmlinuz-linux-lts zfs=tank/main rw
# rm grub.org
# sync
# cd
# umount /boot/efi
```

## ネットワーク

ネットワークを有効にします。同時に名前解決も有効に。

```console
# 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.
# systemctl enable systemd-resolved
Created symlink /etc/systemd/system/dbus-org.freedesktop.resolve1.service -> /usr/lib/systemd/system/systemd-resolved.service.
Created symlink /etc/systemd/system/multi-user.target.wants/systemd-resolved.service -> /usr/lib/systemd/system/systemd-resolved.service.
```

起動時に無線LANが自動接続されるように設定。

```console
# systemctl enable wpa_supplicant@wlo1
Created symlink /etc/systemd/system/multi-user.target.wants/wpa_supplicant@wlo1.service → /usr/lib/systemd/system/wpa_supplicant@.service.
# exit
exit
arch-chroot .  66.27s user 19.31s system 6% cpu 22:17.14 total
# cp /etc/wpa_supplicant/wpa_supplicant.conf /mnt/etc/wpa_supplicant/wpa_supplicant-wlo1.conf
```

NICのデバイス名についてですが。
systemdを使用すると、デバイス名を固定してくれるようです。

参考文献：[CentOS 7のネットワーク名「enp1s0」という文字列の謎に迫る](https://qiita.com/fetaro/items/b61282130fa638de4528)

従って面倒な設定は省きます。
とするとやる事はDHCPクライアントの設定になりますが、最初の無線LAN設定時に用意したファイルをコピーするだけです。

```console
# cp --parents /etc/systemd/network/all.network /mnt
```

現在はデフォルトで ```/etc/nsswitch.conf``` の hosts: 行に resolve が書かれているようですので、それを確認。

```console
# grep "^hosts:" /mnt/etc/nsswitch.conf | grep resolve
hosts: files mymachines myhostname resolve [!UNAVAIL=return] dns
```

## 再起動

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

```console
# cd
# zfs umount -a
# zpool export tank
# shutdown -h now
```

そして、インストールメディアであるUSBメモリを外した後に電源を入れます。GRUBをインストールしたUSBメモリはそのままにして、GRUBから起動するようにします。

# 最初に起動した後

ここまで問題が無ければ、再起動すると最初にGRUBのメニュー画面が表示されます。数秒放置するか、Enterキーを押すと起動します。

## rootログイン

rootユーザーでログインします。パスワードは先ほどpasswdコマンドで設定した通り。

```console

Arch Linux 5.4.49-1-lts (tty1)

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

## ZFS の設定

```console
# systemctl enable zfs.target
Created symlink /etc/systemd/system/multi-user.target.wants/zfs.target -> /usr/lib/systemd/system/zfs.target.
# zpool set cachefile=/etc/zfs/zpool.cache tank
```

最後の cachefile の設定は、自動でマウントさせたいプールごとに実行する必要があるとの事。今回は tank のみです。

念の為に ```shutdown -h now```→電源入れ直して、再起動を確認できればOK。
も一つ念を入れて、再起動・ログイン後にzfsを確認：

```console
# mount | grep zfs
tank/main on / type zfs (rw,relatime,xattr,noacl)
tank/sub0/home on /home type zfs (rw,relatime,xattr,noacl)
tank/sub0/opt on /opt type zfs (rw,relatime,xattr,noacl)
tank/sub0/var/opt on /var/opt type zfs (rw,relatime,xattr,posixacl)
tank/sub0/srv on /srv type zfs (rw,relatime,xattr,noacl)
```

更にインターネット接続を確認：

```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=54 time=12.3 ms
64 bytes from tk2-235-27344.vs.sakura.ne.jp (160.16.119.98): icmp_seq=2 ttl=54 time=10.6 ms

--- archlinux.jp ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 10.587/11.424/12.262/0.837 ms
```

これで大丈夫でしょう。やったね :thumbsup_tone1: