ストレージの自動マウントをSystemdで行う(AutoFSではなく)

Posted by 雅楽斎 on Saturday, June 20, 2020

TOC

経緯

元々、SBC/Single Board ComputerであるNanoPi M4V2で運用している細々としたサーバー群ではUSB接続のHDDを巨大ファイル置き場として使用し、キャッシュ等の大容量が必要な場合は使用してきました。

接続されていない場合はサーバー機能を使わず、縮退体制で運用することを視野に入れてこの構成にしていますが、どうも起動OS起動時にapt-cacher-ngサーバーが(キャッシュを格納している外付けストレージへの書き込みに失敗して)起動しないという症状が治らず1OS起動の度にSSHログインして手動でapt-cacher-ngを起動するという手間が必要でした。

それならば現在使用しているAutoFSをそのまま使うのではなく、Systemdで具備する自動マウントの仕組みを使ってみようというのがこの記事のテーマです。

参考までに起こっていた想定外の動作の概要

apt-cacher-ng自体の導入と運用の概要は以前記載した通りです。2

LAN内に設置するAPTのPull through proxyでAPTパッケージの重複ダウンロードを回避

MicroSD運用しているNanoPi M4V2にAutoFSで外付けHDDを接続している方法についてはこちらをご参照ください。

NanoPi M4V2に外付けHDDを繋ぐ(AutoFSを使う)

で、AutoFSとapt-cacher-ngはどちらもsystemdでサービス管理をしています。OS起動時にどちらも実行されるようになってはいますが、apt-cacher-ngは起動に失敗します。

nanopim4v2 systemd[1]: Starting Apt-Cacher NG software download proxy...
nanopim4v2 apt-cacher-ng[1505]: WARNING: No configuration was read from file:sfnet_mirrors
nanopim4v2 apt-cacher-ng[1505]: Error: Cannot create any directory in /autofs/usbhdd1/var/apt-cacher/
nanopim4v2 systemd[1]: apt-cacher-ng.service: Main process exited, code=exited, status=1/FAILURE
nanopim4v2 systemd[1]: apt-cacher-ng.service: Failed with result 'exit-code'.
nanopim4v2 systemd[1]: Failed to start Apt-Cacher NG software download proxy.
nanopim4v2 systemd[1]: apt-cacher-ng.service: Service hold-off time over, scheduling restart.
nanopim4v2 systemd[1]: apt-cacher-ng.service: Scheduled restart job, restart counter is at 5.
nanopim4v2 systemd[1]: Stopped Apt-Cacher NG software download proxy.
nanopim4v2 systemd[1]: apt-cacher-ng.service: Start request repeated too quickly.
nanopim4v2 systemd[1]: apt-cacher-ng.service: Failed with result 'exit-code'.
nanopim4v2 systemd[1]: Failed to start Apt-Cacher NG software download proxy.

正確には起動失敗を5回繰り返すことでリトライオーバーして起動しないので手動で起動する、というのが実際に起こっている状態です。

直接の不具合原因

AutoFSとapt-cacher-ngはどちらもsystemdで管理しているというのは先に書いた通りですが、systemdでどのように管理しているかを確認してみると

$ systemctl list-dependencies
default.target
● ├─cpufrequtils.service
(snip)
● └─multi-user.target
●   ├─apt-cacher-ng.service
●   ├─armbian-firstrun-config.service
●   ├─autofs.service
●   ├─chrony.service
(snip)

どちらもmulti-user.targetにあるので並列で起動しますが、apt-cacher-ngの起動時にキャッシュディレクトリに指定しているAutoFSでのマウントが終わっていない3のがそもそもの原因です。

特定の場所がマウントされてから実行するようにする

apt-cacher-ngのサービス定義が書かれている/lib/systemd/system/apt-cacher-ng.serviceを見てみたところ…

[Unit] Description=Apt-Cacher NG software download proxy After=network.target RequiresMountsFor=/var/cache/apt-cacher-ng

という記載があり、どうも実行するのにRequiresMountsForに書かれたパスがマウントされている必要がありそうなオプションが指定されているので、シンプルにこれをAutoFSでマウントしているパスに書き換えれば問題解決ではないかと思ったものの…

nanopim4v2 systemd[1]: Starting Apt-Cacher NG software download proxy...
nanopim4v2 apt-cacher-ng[1516]: WARNING: No configuration was read from file:sfnet_mirrors
nanopim4v2 apt-cacher-ng[1516]: Error: Cannot create any directory in /autofs/usbhdd1/var/apt-cacher/
nanopim4v2 systemd[1]: apt-cacher-ng.service: Main process exited, code=exited, status=1/FAILURE
nanopim4v2 systemd[1]: apt-cacher-ng.service: Failed with result 'exit-code'.
nanopim4v2 systemd[1]: Failed to start Apt-Cacher NG software download proxy.
nanopim4v2 systemd[1]: apt-cacher-ng.service: Service hold-off time over, scheduling restart.
nanopim4v2 systemd[1]: apt-cacher-ng.service: Scheduled restart job, restart counter is at 4.
nanopim4v2 systemd[1]: Stopped Apt-Cacher NG software download proxy.
nanopim4v2 systemd[1]: Starting Apt-Cacher NG software download proxy...
nanopim4v2 apt-cacher-ng[1523]: WARNING: No configuration was read from file:sfnet_mirrors
nanopim4v2 systemd[1]: Started Apt-Cacher NG software download proxy.

結果的に成功しているんですが、同じエラーが4回起きた後に5回目で間に合って結果成功しているので、これはオプション効いてないなと。

ちなみに、サービス定義ファイルの書き換え後は以下の手順でリロードします。

# systemctl daemon-reload
# systemctl restart apt-cacher-ng.service

また、systemdに反映されている設定値はsystemctl show サービス名で確認が可能です。

$ systemctl show apt-cacher-ng.service | grep RequiresMountsFor
RequiresMountsFor=/autofs/usbhdd1/var/apt-cacher

結局、仕様理解不足なのかバグなのかわかりませんがこの手順では修正できませんでした。

既存のAutoFS設定を無効化

現在、autofsでのマウントを有効にしているので、一旦設定を削除します。/etc/auto.master.d/usbhdd1.autofsに記載している/etc/auto.usbhdd1の内容を以下のようにコメントアウト。

# /autofs/usbhdd1 -fstype=btrfs,rw :/dev/disk/by-uuid/f8d82e32-10ac-4c08-8969-457cf1ba04ac

設定が外れていることを確認します。

# automount -m

autofs dump map information
===========================

global options: none configured

Mount point: /-

source(s):

  instance type(s): file
  map: /etc/auto.usbhdd1

  no keys found in map

AutoFSのサービスを再起動します。

# systemctl restart autofs.service

必要な値と設定ファイルの記述

手順で参考にしたのはこちらです。

Automatic mounts with systemd · Tomáš Tomeček

SystemdでAutomountをする際に必要な値として以下のものがあります。

  • Description 任意
  • What マウント元のデバイスファイルまたはUUID
  • Where マウント先のディレクトリ
  • Type ファイルシステム
  • systemdが検索するときに使う名前(マウント先のパスを置換した文字列)

今回は以下のようにします。

項目設定値
DescriptionUSB HDD1
Whatf8d82e32-10ac-4c08-8969-457cf1ba04ac
Where/autofs/usbhdd1
Typebtrfs
名前autofs-usbhdd1

参考サイトと同じように作業するので、作成するファイルは以下の2つです。

  • /lib/systemd/system/autofs-usbhdd1.mount
  • /lib/systemd/system/autofs-usbhdd1.automount

それぞれの内容は以下の通り。まずは/lib/systemd/system/autofs-usbhdd1.mount

[Unit]
Description=USB HDD1

[Mount]
What=/dev/disk/by-uuid/f8d82e32-10ac-4c08-8969-457cf1ba04ac
Where=/autofs/usbhdd1
Type=btrfs
Options=defaults

[Install]
WantedBy=multi-user.target

次に/lib/systemd/system/autofs-usbhdd1.automount

[Unit]
Description=Automount USB HDD1

[Automount]
Where=/autofs/usbhdd1

[Install]
WantedBy=multi-user.target

これら2ファイルを作ったら、systemdにリロードさせます。

# systemctl daemon-reload

.mountを無効に、.automountを有効にしたら、automountを開始します。

# systemctl disable autofs-usbhdd1.mount
# systemctl enable autofs-usbhdd1.automount
Created symlink /etc/systemd/system/multi-user.target.wants/autofs-usbhdd1.automount → /lib/systemd/system/autofs-usbhdd1.automount.
# systemctl is-enabled autofs-usbhdd1.mount
disabled
# systemctl is-enabled autofs-usbhdd1.automount
enabled
# systemctl start autofs-usbhdd1.automount

Automountのボリュームをlsして、マウントさせます。

$ ls /autofs/usbhdd1 >/dev/null

状態を確認します。

$ systemctl status autofs-usbhdd1.automount
● autofs-usbhdd1.automount - Automount USB HDD1
   Loaded: loaded (/lib/systemd/system/autofs-usbhdd1.automount; enabled; vendor
   Active: active (waiting) since Sat 2020-06-20 14:54:08 JST; 56s ago
    Where: /autofs/usbhdd1

 6月 20 14:54:08 nanopim4v2 systemd[1]: Set up automount Automount USB HDD1.
$ systemctl status autofs-usbhdd1.mount
● autofs-usbhdd1.mount - USB HDD1
   Loaded: loaded (/lib/systemd/system/autofs-usbhdd1.mount; disabled; vendor pr
   Active: inactive (dead) since Sat 2020-06-20 14:52:11 JST; 3min 21s ago
    Where: /autofs/usbhdd1
     What: /dev/disk/by-uuid/f8d82e32-10ac-4c08-8969-457cf1ba04ac

確認できました。

Automountを待ち合わせるsystemdのサービス定義の変更

現在運用中のサービスのうち、Docker、apt-cacher-ng、SyncthingでUSB接続のHDDを使っているため、この3つのsystemd定義ファイルに以下の行を書き足します。Syncthing以外のDockerとapt-cacher-ngの各ファイルは/lib/systemd/systemから/etc/systemd/systemにコピーしてから、下記の変更を行います。4

--- /lib/systemd/system/docker.service.org      2020-06-01 18:11:34.000000000 +0900
+++ /lib/systemd/system/docker.service  2020-06-20 14:59:48.049440128 +0900
@@ -2,7 +2,7 @@
 Description=Docker Application Container Engine
 Documentation=https://docs.docker.com
 BindsTo=containerd.service
-After=network-online.target firewalld.service containerd.service
+After=network-online.target firewalld.service containerd.service autofs-usbhdd1.mount
 Wants=network-online.target
 Requires=docker.socket
--- /lib/systemd/system/apt-cacher-ng.service.org       2020-06-20 15:02:00.852951987 +0900
+++ /lib/systemd/system/apt-cacher-ng.service   2020-06-20 15:02:47.996781476 +0900
@@ -1,6 +1,6 @@
 [Unit]
 Description=Apt-Cacher NG software download proxy
-After=network.target
+After=network.target autofs-usbhdd1.mount
 RequiresMountsFor=/var/cache/apt-cacher-ng

 [Service]
--- /home/hogehoge/.config/systemd/user/syncthing.service.org   2020-06-20 15:09:08.838546360 +0900
+++ /home/hogehoge/.config/systemd/user/syncthing.service       2020-06-20 15:09:27.499009171 +0900
@@ -1,6 +1,7 @@
 [Unit]
 Description=Syncthing - Open Source Continuous File Synchronization
 Documentation=man:syncthing(1)
+After=autofs-usbhdd1.mount

 [Service]
 ExecStart=/usr/bin/syncthing -no-browser -no-restart -logflags=0

サービス定義の変更を反映します。

# systemctl daemon-reload

OSを再起動

# shutdown -r now

再起動したら、それぞれのサービスの状態を確認します。

$ systemctl status autofs-usbhdd1.automount
● autofs-usbhdd1.automount - Automount USB HDD1
   Loaded: loaded (/lib/systemd/system/autofs-usbhdd1.automount; enabled; vendor
   Active: active (running) since Sat 2020-06-20 15:13:24 JST; 6min ago
    Where: /autofs/usbhdd1
$ systemctl status autofs-usbhdd1.mount
● autofs-usbhdd1.mount - USB HDD1
   Loaded: loaded (/lib/systemd/system/autofs-usbhdd1.mount; disabled; vendor pr
   Active: active (mounted) since Sat 2020-06-20 15:13:26 JST; 6min ago
    Where: /autofs/usbhdd1
     What: /dev/sda1
  Process: 752 ExecMount=/bin/mount /dev/disk/by-uuid/f8d82e32-10ac-4c08-8969-45
    Tasks: 0 (limit: 4473)
   CGroup: /system.slice/autofs-usbhdd1.mount
$ systemctl status docker.service
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: e
   Active: active (running) since Sat 2020-06-20 15:13:41 JST; 6min ago
     Docs: https://docs.docker.com
 Main PID: 1455 (dockerd)
    Tasks: 29
   CGroup: /system.slice/docker.service
           ├─1455 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/contain
           └─1861 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8

 6月 20 15:13:35 nanopim4v2 dockerd[1455]: time="2020-06-20T15:13:35.620365413+0
 6月 20 15:13:35 nanopim4v2 dockerd[1455]: time="2020-06-20T15:13:35.620815159+0
 6月 20 15:13:35 nanopim4v2 dockerd[1455]: time="2020-06-20T15:13:35.622975514+0
 6月 20 15:13:36 nanopim4v2 dockerd[1455]: time="2020-06-20T15:13:36.611202838+0
 6月 20 15:13:40 nanopim4v2 dockerd[1455]: time="2020-06-20T15:13:40.593788524+0
 6月 20 15:13:40 nanopim4v2 dockerd[1455]: time="2020-06-20T15:13:40.965999907+0
 6月 20 15:13:41 nanopim4v2 dockerd[1455]: time="2020-06-20T15:13:41.000822838+0
 6月 20 15:13:41 nanopim4v2 systemd[1]: Started Docker Application Container Eng
 6月 20 15:13:41 nanopim4v2 dockerd[1455]: time="2020-06-20T15:13:41.310436710+0
 6月 20 15:14:39 nanopim4v2 dockerd[1455]: time="2020-06-20T15:14:39.776425219+0
 $ systemctl status apt-cacher-ng.service
● apt-cacher-ng.service - Apt-Cacher NG software download proxy
   Loaded: loaded (/lib/systemd/system/apt-cacher-ng.service; enabled; vendor pr
   Active: active (running) since Sat 2020-06-20 15:13:31 JST; 7min ago
 Main PID: 1316 (apt-cacher-ng)
    Tasks: 5 (limit: 4473)
   CGroup: /system.slice/apt-cacher-ng.service
           └─1316 /usr/sbin/apt-cacher-ng SocketPath=/run/apt-cacher-ng/socket -

 6月 20 15:13:29 nanopim4v2 systemd[1]: Starting Apt-Cacher NG software download
 6月 20 15:13:30 nanopim4v2 apt-cacher-ng[1316]: WARNING: No configuration was r
 6月 20 15:13:31 nanopim4v2 systemd[1]: Started Apt-Cacher NG software download
$ systemctl status --user syncthing.service
● syncthing.service - Syncthing - Open Source Continuous File Synchronization
   Loaded: loaded (/home/hogehoge/.config/systemd/user/syncthing.service; enable
   Active: active (running) since Sat 2020-06-20 15:14:41 JST; 6min ago
     Docs: man:syncthing(1)
 Main PID: 2402 (syncthing)
   CGroup: /user.slice/user-1000.slice/user@1000.service/syncthing.service
           ├─2402 /usr/bin/syncthing -no-browser -no-restart -logflags=0
           └─2609 /usr/bin/syncthing -no-browser -no-restart -logflags=0

 6月 20 15:14:45 nanopim4v2 syncthing[2402]: [BBJS6] INFO: Completed initial sca
 6月 20 15:14:46 nanopim4v2 syncthing[2402]: [BBJS6] INFO: Completed initial sca
 6月 20 15:14:46 nanopim4v2 syncthing[2402]: [BBJS6] INFO: Completed initial sca
 6月 20 15:14:53 nanopim4v2 syncthing[2402]: [BBJS6] INFO: Established secure co
 6月 20 15:14:53 nanopim4v2 syncthing[2402]: [BBJS6] INFO: Device 
 6月 20 15:14:59 nanopim4v2 syncthing[2402]: [BBJS6] INFO: New NAT port mapping:
 6月 20 15:14:59 nanopim4v2 syncthing[2402]: [BBJS6] INFO: Detected 2 NAT servic
 6月 20 15:15:04 nanopim4v2 syncthing[2402]: [BBJS6] INFO: quic://0.0.0.0:22000
 6月 20 15:15:04 nanopim4v2 syncthing[2402]: [BBJS6] INFO: quic://0.0.0.0:22000
 6月 20 15:16:04 nanopim4v2 syncthing[2402]: [BBJS6] INFO: Joined relay relay://

Automountで指定したマウントの後に、待ち合わせるサービスの起動が始まっていることがわかります。いつになくスッキリしました。

スポンサーリンク


  1. というより直し方がわからず [return]
  2. AutoFSでマウントしているキャッシュディレクトリのパスのみ異なります。 [return]
  3. というよりも辞書順で並列に起動していくとapt-cacher-ngの方が先に起動するので、起動に失敗するのが自然 [return]
  4. Syncthingは一般ユーザーのサービスとして起動しているため、ファイルのパスが異なります。 [return]

comments powered by Disqus