Plan 9とGo言語のブログ

主にPlan 9やGo言語の日々気づいたことを書きます。

12インチMacBookにArch Linuxをインストールした

手元のデスクトップ環境をLinuxに切り替えました。2009年頃からmacOS(当時はMac OS X)を使っていたけど、QEMUFUSEを不自由なく使える方がPlan 9との相性が良いので、Linuxの方がいいかなと思ったのでした。

やったこと

MacBook10,1 (Retina, 12-inch, 2017)にArch Linuxをインストールしました。このハードウェアではネットワークなど一通り使えていますが、バージョンによっては使えないケースもあるようです。MacBook Proの対応状況はState of Linux on the MacBook Pro 2016 & 2017にまとまっていますが、MacBookのものは無いので、近いハードウェアから推測する必要があります。

バックアップを取得

事前にMacBookのバックアップを取得しましょう。Time Machineがいちばんお手軽ですし、Linuxにデータを渡すことも考えるならexFATなディスクにコピーしておくと便利です。

また、macOSインストーラを用意しておくと、困った場合に安心です。Mac App StoreからOSインストーラをダウンロードすると/Applicationsインストーラが作られるので、以下のコマンドを実行します。

% sudo /Applications/Install\ macOS\ Big\ Sur.app/Contents/Resources/createinstallmedia --volume /Volumes/Mobile

詳細は、公式ドキュメントのmacOS の起動可能なインストーラを作成する方法を参照してください。

Arch Linuxインストーラを準備

Arch Linuxのイメージをダウンロードから探して、USB インストールメディアの「BIOSUEFI ブータブル USB」に書かれている手順を実行します。

# macOS
% diskutil unmountDisk /dev/diskX
% sudo dd if=archlinux-2021-04-01-x86_64.iso of=/dev/rdiskX bs=1m

# Linux
% sudo dd if=archlinux-2021-04-01-x86_64.iso of=/dev/sdX bs=4M status=progress
% sudo sync

余談ですがこのISOイメージは、ddコマンドを使ってそのままUSBメモリに書き込むだけで使えるように作られています。xorrisoとUEFIブート再び[その1]に詳細が書かれているけれどハック感があって面白いです。

インストール

上で作ったUSBメモリからインストーラを起動して、セットアップしていきます。事前に以下のドキュメントを読んでおくといいでしょう。

MacBook Proのインストール事例だけどこれも参考になりました。

インストーラを起動するとすぐにプロンプトが表示されるので必要なコマンドを入力していけばいいのですが、MacBookの場合はどうやら画面の下数行*1が見切れてしまっているようで、コマンド入力や結果の確認が困難です。なのでsttyで揃えておくと安全です。

stty cols 138 rows 45

まずインターネットへ接続するためWi-Fiの設定をします。ドキュメントはIwdです。この設定はインストーラにおけるネットワークの設定で、再起動すると消えてしまうので、後でもう一度、同じ設定が必要です。

# iwctl
[iwd]# device list
  wlan0      dc:a9:04:xx:xx:xx       on      phy0      station
[iwd]# station dc:a9:04:xx:xx:xx scan
[iwd]# station dc:a9:04:xx:xx:xx get-networks
[iwd]# station dc:a9:04:xx:xx:xx connect SSID
[iwd]# exit

時刻合わせです。これも再起動すると消えるので、後でもう一度設定します。

# timedatectl set-ntp true

準備ができたらパーティションを分割していきます。GPTで管理するので、fdiskではなくgdiskを使います。分割自体は好みでレイアウトすればいいのですが、最初のEFIパーティションはsystemd-bootで利用するのでそのまま残しておきます。手元では、Linux用のパーティションは特に分割などせず、1つだけ作りました。また、スワップファイルの方が便利そうなので、swapパーティションは作りませんでした*2

# gdisk /dev/nvme0n1
...

パーティションの用意ができたらフォーマットします。ここではBtrfsでフォーマットすることにしました。Btrfsのサブボリュームは通常のパーティションと同じようにマウントできるので、スナップショットを利用しやすいように構成する「Snapper推奨レイアウト」があるようですが、まだBtrfsの運用に慣れていないので、トップレベルのサブボリューム(ID=5)を/にマウントします。

# mkfs.btrfs -L rootfs /dev/nvme0n1p2

インストール先となるパーティション/mnt以下にマウントします。ブートローダはsystemd-bootを使うので、EFIパーティション/mnt/bootにマウントしておかないとpacstrapしたときにカーネルなどが/bootに配置されず手動でコピーするなど必要が出てきます。

# mount /dev/nvme0n1p2 /mnt
# mount /dev/nvme0n1p1 /mnt/boot

そのまま必須パッケージを/mntにインストールします。Btrfsを使うのでbtrfs-progsパッケージも含めておきます。

# pacstrap /mnt base btrfs-progs linux linux-firmware

/etc/fstabを更新します。

# genfstab -U /mnt >>/mnt/etc/fstab

genfstabはBtrfsでフォーマットされたファイルシステムを検出した場合にrelatimeオプションを追加します。Linuxはファイルのアクセス時刻を記録しているので、ファイルを読んだだけでもディスクアクセスが発生します。BtrfsはCoWなファイルシステムなので、ファイルにアクセスするたびにアクセス時刻を更新すると、それだけで複数ページへの更新が発生して効率が悪くなります。マウントの際にrelatimeオプションを与えておくと、ファイルを変更した時だけアクセス時刻が更新されるようになるので、基本的にはこのオプションを設定しておく方が良いと思います。

また、マウント時のオプションで、ページが不要になったときTRIMを行うdiscardオプションもありますが、NVMeの場合はfstrimで定期的にTRIMすることが推奨されているのでdiscardオプションは与えないでおきましょう。

生成した/etc/fstabの確認が終わったらarch-chrootします。

# arch-chroot /mnt

メモ: Btrfsは安定しているのか

ext4ファイルシステムでも困ってはいないけど、スナップショットやCoWなどBtrfsの方が優れている面があります。いくつかのディストリビューションで採用されている反面、相変わらず不安定という話も聞くので、メリットを帳消しにするほど不安定なら、まだ採用したくはありません。

スワップファイルの扱いなど特別な対応が必要なところはあるものの、いくつか記事を読んだ限りでは、単一のディスクを扱う限りは安定していると判断しました。

systemd-boot

ブートローダの選択肢はいくつかありますが、Arch Linuxのドキュメントに、MacBookではいちばん簡単な方法と書かれていたのでsystemd-bootを使いました。ドキュメントはsystemd-bootです。

ここでマイクロコードも一緒にロードしておきましょう。12インチMacBookIntelのCPUなので、パッケージはintel-ucodeです。

# pacman -S intel-ucode
# bootctl --path=/boot install

設定ファイルを2つ作ります。/boot/loader/entries/arch.confカーネル/となるパーティションを設定するものです。UUIDの値は、blkidコマンドで/dev/nvme0n1p2の値を調べました。

title Arch Linux
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options root=UUID=ca7846e4-64bc-4086-ae73-524f5aeb546e rw

ブートしたいカーネルが複数あるなら、このファイルを必要なだけ作ります。次に、ローダ自体の設定です。これは/boot/loader/loader.confに書きます。

default arch
timeout 3
console-mode max
editor no

正しく設定ができていれば、bootctlコマンドで設定した内容を読めるはずです。

# bootctl list
Boot Loader Entries:
        title: Arch Linux (default)
           id: arch.conf
       source: /boot/loader/entries/arch.conf
        linux: /vmlinuz-linux
       initrd: /intel-ucode.img
               /initramfs-linux.img
      options: root=UUID=ca7846e4-64bc-4086-ae73-524f5aeb546e rw

(この時点では、インストーラのエントリがいくつかあるけど再起動すると消える)

systemd-bootに更新があったとき、自動でブートローダも更新できるように/etc/pacman.d/hooks/systemd-boot.hookを設定しておきます。

[Trigger]
Type = Package
Operation = Upgrade
Target = systemd

[Action]
Description = Upgrading systemd-boot...
When = PostTransaction
Exec = /usr/bin/bootctl update

ディスクを暗号化する

ルートパーティションを暗号化する場合は追加でいくつか手順が発生します。暗号化の方法はいろいろありますが、一番簡単な「/boot 以外を素朴に暗号化する」方法を使います。

まずmkfs.btrfsまたはmkfs.ext4する前に、cryptsetupを使って暗号化したディスクを作成します。

# cryptsetup -y -v luksFormat /dev/nvme0n1p2
# cryptsetup open /dev/nvme0n1p2 cryptroot (cryptrootの名前はなんでもいい)

壊れて復旧不能になるのは怖いのでLUKSのヘッダをバックアップします。

# cryptsetup luksHeaderBackup /dev/nvme0n1p2 --header-backup-file luks.img

この後、 /dev/nvme0n1p2 の代わりに /dev/mapper/cryptroot で置き換えてarch-chrootまで進めますが、今のままではブート時に暗号化を解除できないのでいくつか設定が必要です。

まず、一般的には/etc/crypttabパーティションを追加しますが、ルートパーティションの場合はそこには含めません。代わりに/etc/mkinitcpio.confHOOKSkeyboard, keymap, encrypt を追加します。

--- /etc/mkinitcpio.conf.orig
+++ /etc/mkinitcpio.conf
@@ ... @@
-HOOKS=(base udev autodetect modconf block filesystems keyboard fsck)
+HOOKS=(base udev autodetect modconf keyboard keymap block encrypt filesystems fsck)

イメージを再生成します。

# mkinitcpio -p linux

次に、ブート時に暗号を解除させるため、systemd-bootのオプションを設定します。ここでのUUIDは、/dev/nvme0n1p2のUUIDです。

--- /boot/loader/entries/arch.conf.orig
+++ /boot/loader/entries/arch.conf
@@ ... @@
-options root=UUID=ca7846e4-64bc-4086-ae73-524f5aeb546e rw
+options cryptdevice=UUID=ca7846e4-64bc-4086-ae73-524f5aeb546e:cryptroot root=/dev/mapper/cryptroot rw

/etc/fstabからは/dev/mapper以下のディスクを参照するように切り替えます。こちらのUUIDは/dev/mapper/cryptrootのUUIDです。

--- /etc/fstab.orig
+++ /etc/fstab
@@ ... @@
-UUID=ca7846e4-64bc-4086-ae73-524f5aeb546e   /   ext4   rw,realtime   0   1
+UUID=02871ac2-2e51-4f53-96b3-2ddb514c93cf   /   ext4   rw,realtime   0   1

この後は/dev/mapper/cryptrootを使っていきます。これ以外の方法ではLVMを使うなど色々あるので、以下の記事を参照してください。

rootのパスワード

設定しておきます。

# passwd

再起動

ここで一度、再起動します。 root でログインできるようになっているので、ログインして設定を続けます。

ファイルシステムのメンテナンス

定期的にファイルシステムをメンテナンスするタイマーを起動します。マウントオプションのところでも触れましたが、discardオプションではなくfstrimを定期的に実行するよう推奨されるので、systemdのタイマーを有効にします。

# systemctl enable fstrim.timer

また、Btrfsを利用している場合は、定期的なファイルシステムの検査を行うために以下も有効にしておくといいでしょう。@の後にマウントポイントを与えてそれぞれ個別に有効化します。

// ルート(/)にマウントしたファイルシステムを検査
# systemctl enable btrfs-scrib@-.timer

// 他の場所(/home)にマウントしたファイルシステムの場合
# systemctl enable btrfs-scrib@home.timer

ネットワークの設定

上で行ったネットワークの設定をもう一度実施します。こちらは再起動した後で使われるものです。インストーラと異なり、ブート後の環境にはまだiwdパッケージがインストールされていないので、ここで追加しておきます。

# pacman -S iwd

設定自体は上のものと同じですが、以下のコマンドを使うと1行で行なえます。

# iwctl station wlan0 connect <SSID>

SSIDごとに、設定は/var/lib/iwd/<SSID>.<enc>へ保存されます。あとは、ホスト名の設定と、ブート時の再接続を入れておきましょう。それぞれファイルが無ければ作ります。

/etc/hostname

linux-pc

/etc/systemd/network/20-wlan0.network

[Match]
Name=wlan0

[Network]
DHCP=ipv4

コマンドはこのような。

# systemctl enable iwd.service
# systemctl enable systemd-networkd.service
# systemctl enable systemd-resolved.service
# networkctl list

/etc/resolv.conf

systemd-resolvedを使います。systemd-resolvedのマニュアルによると、単にリンクを貼れば良いようです。

$ sudo ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

ブラウザなど、この設定を行わなくても動作するアプリケーションはありますが、DockerやFlatpakで動作させた場合に名前解決ができずエラーとなる場合があるため設定しておきましょう。

時間の設定

NTPとタイムゾーンの設定です。

# ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# hwclock --systohc

# timedatectl set-ntp true
# timedatectl status

デフォルトの設定だと時刻が30秒ほどずれることがあるので、最寄りのNTPサーバを見るように /etc/systemd/timesyncd.conf を編集しておきます。

@@ -17,8 +17,8 @@
 # See timesyncd.conf(5) for details.
 
 [Time]
-#NTP=
-#FallbackNTP=0.arch.pool.ntp.org 1.arch.pool.ntp.org 2.arch.pool.ntp.org 3.arch.pool.ntp.org
+NTP=ntp.nict.jp
+FallbackNTP=0.arch.pool.ntp.org 1.arch.pool.ntp.org 2.arch.pool.ntp.org 3.arch.pool.ntp.org
 #RootDistanceMaxSec=5
 #PollIntervalMinSec=32
 #PollIntervalMaxSec=2048

言語の追加

en_US.UTF-8ja_JP.UTF-8を追加します。

# echo 'en_US.UTF-8 UTF-8' >>/etc/locale.gen
# echo 'ja_JP.UTF-8 UTF-8' >>/etc/locale.gen
# locale-gen

これ以降、/etc/locale.confLANGを設定すると日本語化されますが、フォントがない状態でされても文字が読めなくて困るだけなので、これは後で設定します。

systemd-homed

ホームディレクトリの管理もsystemd-homedを使うようにしました。ドキュメントはsystemd-homedです。ついでにvisudoも入れておきます。vimパッケージもありますが、簡単なテキストの編集にしか使わないのでviパッケージで十分でした。

# systemctl enable systemd-homed.service
# homectl create --member-of wheel lufia
# pacman -S vi sudo
# visudo

ディスクを暗号化している場合

LUKSが使える場合、homectl createはデフォルトで/home/$user.homeにLUKSイメージを作成して、ユーザーがログインする時に暗号を解除してマウントする動作をします*3が、そもそもディスクを暗号化している場合は追加で暗号化する意味はそれほどありません*4。なのでディスク自体を暗号化している場合はイメージを作らないオプションを入れるといいと思います。

# systemctl create --storage=directory --member-of wheel lufia

スワップファイルの追加

swapパーティションを作らなかったので、ここでスワップファイルを設定します。Btrfsファイルシステム上にスワップファイルを用意する場合は、CoWや圧縮などされないようにフラグをセットしておく必要があります。このとき、ファイルサイズが0でなければ有効にならないので、必ず0に切り詰めてからセットしましょう。また、スワップファイルが含まれるサブボリュームはスナップショットを取得できなくなるので、別のサブボリュームに作成します。

# btrfs subvolume list /
# cd /
# btrfs subvolume create swap
# chmod 700 /swap

# touch /swap/swapfile
# chmod 600 /swap/swapfile
# chattr +C /swap/swapfile
# fallocate -l 8G /swap/swapfile
# btrfs property set /swap/swapfile compression none

# mkswap /swap/swapfile
# swapon /swap/swapfile

ext4ファイルシステム上にスワップファイルを用意する場合はフラグ設定を省略すればよいです。

# fallocate -l 8G /swapfile
# chmod 600 /swapfile
# mkswap /swapfile
# swapon /swapfile

ファイルを用意したら/etc/fstabにエントリを追加。

/swap/swapfile   none    swap    defaults    0 0

デスクトップ環境

2021-05-16追加: この後でKDEに切り替えました

blog.lufia.org

Waylandを使おうとしているので、色々と面倒が少なそうなGNOMEをインストールしました。

# pacman -S gnome
# systemctl enable gdm
# pacman -S noto-fonts noto-fonts-cjk

これで特に何もしなくても、再起動すればGNOMEのセッションマネージャが使えます。ログイン後に環境変数XDG_SESSION_TYPEをみると、WaylandかX11のどちらが使われているかを調べられます。XDG_SESSION_TYPEx11の場合、セッションマネージャの右下にある設定ボタンからGNOMEを選んでログインするとwaylandに変わります。

ディスプレイの設定

RetinaディスプレイHiDPIディスプレイとも呼ばれるようです。GNOMEでは、デフォルトでサイズ調整は200%と設定されていたと思いますが、好みに応じてGNOMEの設定アプリから変更しましょう。

言語の設定

上で言語の追加をしましたが、グラフィックスを使えるようになったので、必要ならここで切り替えます。

# echo 'LANG=ja_JP.UTF-8' >/etc/locale.conf

スリープでD3coldへ遷移させない

12インチMacBookでは、D3coldへ遷移すると、うまく復帰できない問題があるそうです。実際に試したところ、スリープから復帰したログイン画面でパスワードを入力しても、先へ進むことができませんでした。そのため、D3coldへの遷移を止めます。

d3cold_allowedファイルへ0を書き込むことで無効となりますが、再起動するたびに入力するのは面倒なので、systemdを使って自動化します。まずはユニットファイルを/etc/systemd/system/d3cold-disable.serviceに作りました。

[Unit]
Description=Disables sleep from stopping nvme hardware on MacBook

[Service]
ExecStart=/sbin/d3cold 0
Type=oneshot
RemainAftrExit=yes

[Install]
WantedBy=multi-user.target

ExecStart=で実行しているコマンドは以下の内容です。

#!/bin/bash

v=${1:-0}
echo $v > /sys/bus/pci/devices/'0000:01:00.0'/d3cold_allowed

これを有効にします。

$ sudo chmod +x /sbin/d3cold
$ sudo systemctl enable d3cold-disable.service

サーマルスロットリング

12インチMacBookファンレスなこともあり、Go自身のコンパイルをしていると突然スリープに落ちたりします。それでは困るので、thermald.serviceを有効にします。

# pacman -S thermald
# systemctl enable thermald.service

thermaldは、基本的に何も設定しなくても適切に動作するらしいですが、MacBookファンレスなこともあって、しばらく負荷をかけると

systemd-logind[299]: Suspend key pressed.

というログがjournaldに記録されてサスペンドします。なので明示的に/etc/thermald/thermal-conf.xmlに設定を書きます。この設定では、CPUパッケージの温度が75℃を越えたら色々な方法で温度を下げます。

<?xml version="1.0"?>
<ThermalConfiguration>
  <Platform>
    <Name>Macbook 2017</Name>
    <ProductName>*</ProductName>
    <Preference>QUIET</Preference>
    <ThermalZones>
      <ThermalZone>
        <Type>x86_pkg_temp</Type>
        <TripPoints>
          <TripPoint>
            <SensorType>x86_pkg_temp</SensorType>
            <Temperature>75000</Temperature>
            <type>passive</type>
            <ControlType>PARALLEL</ControlType>
            <CoolingDevice>
              <index>1</index>
              <type>rapl_controller</type>
              <influence>50</influence>
            </CoolingDevice>
            <CoolingDevice>
              <index>2</index>
              <type>intel_pstate</type>
              <influence>40</influence>
            </CoolingDevice>
            <CoolingDevice>
              <index>3</index>
              <type>intel_powerclamp</type>
              <influence>30</influence>
            </CoolingDevice>
            <CoolingDevice>
              <index>4</index>
              <type>cpufreq</type>
              <influence>20</influence>
            </CoolingDevice>
            <CoolingDevice>
              <index>5</index>
              <type>Processor</type>
              <influence>10</influence>
            </CoolingDevice>
          </TripPoint>
        </TripPoints>
      </ThermalZone>
    </ThermalZones>
  </Platform>
</ThermalConfiguration>

設定については以下の記事に書きました。

blog.lufia.org

CPU 周波数スケーリングによると、他にも便利なものはあるようですが、今のところ特には困っていないのでいいかな。

/sys/devices/system/cpu/cpu?/cpufreq/scaling_governorを読むと、どのgovernorがセットされているか調べられますし、/sys/class/thermal/cooling_device?/typeでデバイスの種類が分かります。

$ grep . /sys/devices/system/cpu/cpu?/cpufreq/scaling_governor
/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor:powersave
/sys/devices/system/cpu/cpu1/cpufreq/scaling_governor:powersave
/sys/devices/system/cpu/cpu2/cpufreq/scaling_governor:powersave
/sys/devices/system/cpu/cpu3/cpufreq/scaling_governor:powersave

$ grep . /sys/class/thermal/cooling_device?/type
/sys/class/thermal/cooling_device0/type:Processor
/sys/class/thermal/cooling_device1/type:Processor
/sys/class/thermal/cooling_device2/type:Processor
/sys/class/thermal/cooling_device3/type:Processor
/sys/class/thermal/cooling_device4/type:intel_powerclamp
/sys/class/thermal/cooling_device5/type:LCD

CPUクロックや温度はlscpu/sys/class/thermal/thermal_zone?/tempで読めます。tempファイルの値は、3330033.3℃のようです。

$ lscpu | grep 'CPU MHz'
CPU MHz:                             2084.082

$ grep . /sys/class/thermal/thermal_zone?/temp
/sys/class/thermal/thermal_zone0/temp:33300
/sys/class/thermal/thermal_zone1/temp:43000

再起動

ここで再起動します。ログイン画面が表示されたら、さきほど作成した一般ユーザーでログインしましょう。

ログイン後は主に個人環境に対する設定を行います。

CapsLockをControlにする

実現方法はいくつかありますが、GNOMEの設定で対応しました。もともとlv3:ralt_switchが含まれていたので、そこに追記した形です。

$ gsettings set org.gnome.desktop.input-sources xkb-options "['lv3:ralt_switch', 'ctrl:nocaps']"

サウンドの設定

MacBookでは追加のドライバが必要です。GitHubから12インチMacBook用のドライバをインストールします。

$ git clone https://github.com/leifliddy/macbook12-audio-driver.git
$ cd macbook12-audio-driver
$ sudo ./install.cirrus.driver.sh

MacBook Pro用のドライバもありますが、こちらは12インチMacBookでは認識しませんでした。

Bluetoothの設定

12インチMacBook用のBluetoothドライバです。インストール方法はサウンドの時と同じ。

$ git clone https://github.com/leifliddy/macbook12-bluetooth-driver.git
$ cd macbook12-bluetooth-driver
$ sudo ./install.bluetooth.sh

手元にはBluetoothキーボードトラックパッドがあるので、それぞれ接続しました。ドキュメントはBluetoothにあります。

$ sudo pacman -S bluez bluez-utils
$ sudo systemctl enable bluetooth
$ bluetoothctl
[bluetooth] agent on
[bluetooth] scan on
[bluetooth] devices
[bluetooth] pair 00:00:00:00:00:00
[agent] PIN code: xxxxxx
Pairing successful
[bluetooth] connect 00:00:00:00:00:00
Connection successful

[bluetooth] pair 11:11:11:11:11:11
Pairing successful
[bluetooth] connect 11:11:11:11:11:11
Connection successful

再起動した後に自動接続されるように、/etc/bluetooth/main.confへ設定をしておきます。

[Policy]
AutoEnable=true

外部ディスプレイを繋いでいるときはスリープしない

クラムシェルとかリッドクローズドと呼ばれているものです。/etc/systemd/logind.confを以下のように変更しました。とはいえ、GNOMEによって電源管理されているようなので、この設定がどの程度有効かは分かりません。

--- /etc/systemd/logind.orig 2021-03-29 22:36:55.053860982 +0900
+++ /etc/systemd/logind.conf  2021-03-29 22:56:55.439920429 +0900
@@ -24,8 +24,8 @@
 #HandleSuspendKey=suspend
 #HandleHibernateKey=hibernate
 #HandleLidSwitch=suspend
-#HandleLidSwitchExternalPower=suspend
-#HandleLidSwitchDocked=ignore
+HandleLidSwitchExternalPower=suspend
+HandleLidSwitchDocked=ignore
 #HandleRebootKey=reboot
 #PowerKeyIgnoreInhibited=no
 #SuspendKeyIgnoreInhibited=no

トラックパッド

Waylandではlibinputが動作していて、トラックパッドを接続した後は特に何も設定する必要はありませんでしたが、タップでクリックなどいくつか変更しています。ここは完全に好みです。

$ gsettings list-recursively org.gnome.desktop.peripherals.touchpad
org.gnome.desktop.peripherals.touchpad tap-button-map 'default'
org.gnome.desktop.peripherals.touchpad click-method 'fingers'
org.gnome.desktop.peripherals.touchpad edge-scrolling-enabled false
org.gnome.desktop.peripherals.touchpad disable-while-typing true
org.gnome.desktop.peripherals.touchpad two-finger-scrolling-enabled true
org.gnome.desktop.peripherals.touchpad send-events 'enabled'
org.gnome.desktop.peripherals.touchpad speed 0.0
org.gnome.desktop.peripherals.touchpad tap-and-drag true
org.gnome.desktop.peripherals.touchpad natural-scroll true
org.gnome.desktop.peripherals.touchpad middle-click-emulation false
org.gnome.desktop.peripherals.touchpad left-handed 'mouse'
org.gnome.desktop.peripherals.touchpad tap-to-click true
org.gnome.desktop.peripherals.touchpad tap-and-drag-lock true

日本語入力

一般的に、IBusまたはFcitxのうちどちらかと、MozcまたはSKKのどちらかを組み合わせて使うことになると思います。Linuxのかな漢字変換の興亡SKKが勧められていたので、ここではibus-skkを使うようにします。Mozcの方が簡単だろうけれど、どのみちPlan 9ではSKKを使うことになるし、合わせておくのもいいかなと思ったのでした。

$ sudo pacman -S ibus-skk skk-jisyo

Waylandを使っているので、IBusを使うための環境変数~/.pam_environmentに追加します。

GTK_IM_MODULE DEFAULT=ibus
XMODIFIERS DEFAULT=@im=ibus
QT_IM_MODULE DEFAULT=ibus

Linux デスクトップの環境変数、どこに設定してますか?によると.pam_environmentは非推奨らしいので、今なら homectl update --setenv の方がいいかもしれない。

$ homectl update lufia --setenv GTK_IM_MODULE=ibus --setenv XMODIFIERS=@im=ibus --setenv QT_IM_MODULE=ibus

また、SKKのキーボードレイアウトは日本語配列になっているので、/usr/share/ibus/component/skk.xmllayoutを変更します。

--- /usr/share/ibus/component/skk.orig   2021-03-21 00:03:32.931254445 +0900
+++ /usr/share/ibus/component/skk.xml 2021-03-21 20:26:27.483580937 +0900
@@ -17,7 +17,7 @@
            <license>GPL</license>
            <author>Daiki Ueno &lt;ueno@unixuser.org&gt;</author>
            <icon>/usr/share/ibus-skk/icons/ibus-skk.svg</icon>
-          <layout>ja</layout>
+           <layout>us</layout>
            <longname>SKK</longname>
            <description>SKK Input Method</description>
            <rank>70</rank>

せっかくなので追加の辞書を入れました。

$ git clone https://github.com/tokuhirom/jawiki-kana-kanji-dict.git
$ cd jawiki-kana-kanji-dict
$ echo ';; -*- coding: utf-8 -*-' >~/.config/ibus-skk/SKK-JISYO.jawiki
$ cat SKK-JISYO.jawiki >>~/.config/ibus-skk/SKK-JISYO.jawiki

あとは、ibus-setupの「入力メソッド」にSKKを追加して、そこへSKK-JISHO.jawikiの辞書も追加すれば終わりです。ただし、SKK-JISHO.jawikiは必ずシステム辞書として追加しましょう。ユーザー辞書として追加しても動作はしますが、候補を確定するときすべてのユーザー辞書へ更新が行なわれるらしく、確定する度に2、3秒待たされることになります。

$ ibus-setup

今の設定はこんな雰囲気。

  1. ~/.config/ibus-skk/user.dict (ユーザー辞書)
  2. /usr/share/skk/SKK-JISHO.L (システム辞書)
  3. ~/.config/ibus-skk/SKK-JISHO.jawiki (システム辞書)
  4. localhost:1178 (サーバ)

参考情報

Firefox

Firefoxを使っているので、言語パックも一緒にインストールします。

$ sudo pacman -S firefox firefox-i18n-ja

標準ではCtrl+Hキーに履歴の表示をトグルするショートカットキーが割り当てられていますが、個人的にはCtrl+Hをバックスペースとして使うのでとてもイライラするので変更します。対応するための方法はいくつかありますが、GNOME側でキーテーマをEmacs風なものに変更すると、FirefoxでもCtrl+Hでバックスペースを入力できるようになります。

$ gsettings set org.gnome.desktop.interface gtk-key-theme 'Emacs'

これで、Ctrl+Aで行頭にカーソルを移動させられたりなど好みの挙動になりました。それぞれのキーに何が割り当てられているかは、/usr/share/themes/Emacs/gtk-3.0/gtk-keys.cssを読むとなんとなく分かると思います。

それから、ページ内検索で何もマッチしないときにビープ音が鳴るのはうるさいので、about:configから無効にします。

accessibility.typeaheadfind.enablesound=false

ターミナル

GNOME Terminalのデフォルトサイズ変更とベルを無効化します。gsettingsでもできるらしいけど、UUIDが入っていて面倒なので、GUIでターミナルの設定→プロファイルの文字タブを選んで変更します。

  • 起動時の端末サイズ: 100x50 *5
  • 端末ベルを鳴らす: off

FirefoxCtrl+CでコピーするけどターミナルではCtrl+Shift+Cでコピーするのは、どちらかに統一したいですね。ターミナルはCtrl+Cで割り込みを発生させるので難しいかなと思っていたけれど割り込みはCtrl+Alt+Cでも起こせたので、以下のコマンドでキーマップを変更しました。

$ gsettings set org.gnome.Terminal.Legacy.Keybindings:/org/gnome/terminal/legacy/keybindings/ copy '<Control>c'
$ gsettings set org.gnome.Terminal.Legacy.Keybindings:/org/gnome/terminal/legacy/keybindings/ paste '<Control>v'

これで、どのアプリでも、Ctrl+CでコピーしてCtrl+Vで貼り付けができる。

また、こちらもビープがうるさいので止めます。GNOMEターミナルの設定→プロファイルから、「端末ベルを鳴らす」のチェックを外します。

クリップボード

クリップボードにはPRIMARY*6CLIPBOARDの2種類あるようで、テキストを選択してマウスの中ボタンで扱うような暗黙的なコピーはPRIMARYを参照して、明示的にコピーをする動作はCLIPBOARDを参照するようです。日本語版のWikiより英語版の方が詳しいのでClipboardのSelectionを読みましょう。GNOMEPrimary Selectionにも色々と書かれています。

Waylandでコマンドラインからクリップボードを操作するためにwl-clipboardを入れておきます。

$ sudo pacman -S wl-clipboard

別件で、最後に選択したテキストがマウスの中ボタンでペーストされてしまうのは誤操作の原因になるので止めてしまいます。

$ gsettings set org.gnome.desktop.interface gtk-enable-primary-paste false

Firefoxは別の設定になるようです。about:configmiddlemouse.pastefalseに切り替えます。

バックアップ

rsyncでコピーする方法がRsync によるフルシステムバックアップで紹介されていますが、rsyncは転送先でそのままファイルとして扱えるため便利ではあるものの、転送先のファイルシステムPOSIX準拠でない場合に色々な問題が発生するのであまり使いたくはありません*7。なのでBorg Backupを使ってみることにしました。exFATでフォーマットされているMOBILEディスクにbackupsディレクトリを作成して、それをBorgのリポジトリにします。borg init -e repokeyで暗号化しています。また、紛失しないようにリポジトリの鍵をエクスポートして保管しておきます。

$ sudo pacman -S borg
$ borg init -e repokey /run/media/lufia/MOBILE/backups
$ borg key export /run/media/lufia/MOBILE/backups repo.key

上では手元のディスクを使いましたが、Google Cloudを使っているならCloud Storage FUSEの方が便利かもしれません。

$ git clone https://aur.archlinux.org/gcsfuse.git
$ cd gcsfuse
$ sudo pacman -S fakeroot # なければ入れる
$ makepkg -si

これで後はバックアップを作成するだけです。毎回コマンドを組み立てるのは面倒なので以下のスクリプトを書きました。

#!/bin/bash

set -eu

if [[ $# -ne 1 ]]
then
    echo usage: $(basename $0) repo >&2
    exit 1
fi
h=$(hostnamectl --static)
d=$(date +%Y-%m%d)
sudo borg create --progress "$1::$h-$d" / --exclude-from ~/lib/borg.exclude

コピーする必要のないファイルもあるので、borg.excludeシステムメンテナンスを参考にこのような内容です。

/dev/*
/proc/*
/sys/*
/tmp/*
/run/*
/mnt/*
/media/*
/lost+found
/var/run/*
/swapfile
/home/*.home
/home/*/.cache
/home/*/.local/share/Trash/*
/home/*/Downloads/*

ところで、systemd-homedを使っていると、/home/$user.homeに大きなファイルが作られています。これはホームディレクトリのLUKSイメージらしく、ユーザーがログインするなどでアクティベートされると/home/$userにマウントされます*8。このイメージは、手元では300GBほどあって、毎回のバックアップで対象とするには大きく時間がかかります。上のスクリプトではどうせ一人しか使わないので、必ずホームディレクトリはマウントされているものとして扱うことにしました。ちなみにアクティベートされたユーザはhomectl listすると分かりますし、homectl activateでアクティベートするようです。

$ homectl list
NAME  UID   GID   STATE  REALNAME HOME        SHELL    
lufia 60331 60331 active lufia    /home/lufia /bin/bash

1 home areas listed.

古いバックアップはpruneで破棄できます。

# 最新3つ残して破棄
$ sudo borg prune --keep-last=3 [-n] /run/media/lufia/MOBILE/backups

# 1年以内のものだけ残して破棄
$ sudo borg prune --keey-within=1y /run/media/lufia/MOBILE/backups

参考情報

日常の利用

感想など

トラックパッドに慣性スクロールが欲しいなど、まだ気になるところはありますが、これならデスクトップ環境として使えると思えるところまで設定しました。購入して電源を入れるだけで快適に使えるmacOSはすごいなと思うものの、一度設定してしまえばLinuxでもそんなに困らないはずだし、癖や好みの話でもあるので、しばらくこのままLinuxデスクトップで生活してみる予定です。

2022年1月追記

業務端末もLinuxにしました。

blog.lufia.org

セキュアブートやTPM2によるパスフレーズ省略についても書きました。

blog.lufia.org

*1:10行程度?

*2:後で知ったけどSwap File vs Swap Partitionによるとパーティションの方が印象良かった

*3:利用しているファイルシステムがBtrfsの場合はサブボリュームを採用するようです

*4:他のユーザーから見られない状態になるので意味はある

*5:Linuxカーネルコード、1行の文字制限を80字から100字まで緩和

*6:SECONDARYもあるらしい

*7:symlinkの未サポートやファイル名のcase-insensitiveなど

*8:イメージの種類によりファイル名の末尾が.homedirなどに変わる