自宅サーバ用として ROCK64 というシングルボードコンピュータを使用しています。無線は搭載されていませんが、GbE で 4 GB RAM、USB 3.0 搭載で秋月電子で 5,000 円前後で購入することが出来ます(Raspberry Pi 4 が出るまでは旧 Raspberry Pi を大きく突き放すスペックでした)。
使用可能な OS は何種類かありますが、現在は Armbian で運用しています。この Armbian は名前の通り Debian ベースの ARM マシン向け OS です。シングルボードコンピュータでは microSD が使われることが多いですが耐久性に難があります。そこで、Armbian では /var/log
に ZRAM が使われています。
ZRAM の状態は zramctl
で確認できますが、デフォルトでは /var/log
への割り当ては 50 MB と、運用によってはかなり少ない割り当てになっています。
$ sudo zramctl NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT /dev/zram1 lzo 1G 29.3M 7.7M 8.5M 4 [SWAP] /dev/zram0 lz4hc 50M 2.8M 655K 1.1M 4 /var/log
この設定を変更するために設定ファイルを探したりすることになったのでメモを残しておきます。
/etc/default/armbian-ramlog
が設定ファイルで、SIZE=
に指定した容量が /var/log
に割り当てられます。
$ cat /etc/default/armbian-ramlog # configuration values for the armbian-ram-logging service # # enable the armbian-ram-logging service? ENABLED=true # # size of the tmpfs mount -- please keep in mind to adjust /etc/default/armbian-zram-config too when increasing SIZE=50M # # use rsync instead of cp -r # requires rsync installed, may provide better performance # due to copying only new and changed files USE_RSYNC=true
設定を変更したら再起動します。
システム稼働中は armbian-ramlog
というサービスが稼働しています。なお、このサービスを再起動しても割当量の変更は行われません。
$ systemctl status armbian-ramlog ● armbian-ramlog.service - Armbian memory supported logging Loaded: loaded (/lib/systemd/system/armbian-ramlog.service; enabled; vendor preset: enabled) Active: active (exited) since Sun 2020-04-19 01:13:48 JST; 5s ago Process: 6108 ExecStart=/usr/lib/armbian/armbian-ramlog start (code=exited, status=0/SUCCESS) Main PID: 6108 (code=exited, status=0/SUCCESS) Apr 19 01:13:45 rock64 systemd[1]: Starting Armbian memory supported logging... Apr 19 01:13:45 rock64 armbian-ramlog[6108]: Mounting /dev/zram0 as /var/log/ Apr 19 01:13:45 rock64 armbian-ramlog[6108]: Sun 19 Apr 2020 01:13:45 AM JST: Loading logs from storage Apr 19 01:13:46 rock64 armbian-ramlog[6108]: sending incremental file list Apr 19 01:13:47 rock64 armbian-ramlog[6108]: sent 1,514 bytes received 28 bytes 1,028.00 bytes/sec Apr 19 01:13:47 rock64 armbian-ramlog[6108]: total size is 1,522,657 speedup is 987.46 Apr 19 01:13:48 rock64 systemd[1]: Started Armbian memory supported logging.
ブロックデバイスの情報は /sys/block
以下に格納されています。
$ ll /sys/block/zram0/ total 0 drwxr-xr-x 7 root root 0 Apr 18 19:29 ./ drwxr-xr-x 14 root root 0 Apr 18 19:29 ../ -r--r--r-- 1 root root 4.0K Apr 19 01:20 alignment_offset lrwxrwxrwx 1 root root 0 Apr 19 01:20 bdi -> ../../bdi/252:0/ -r--r--r-- 1 root root 4.0K Apr 19 01:20 capability --w------- 1 root root 4.0K Apr 19 01:20 compact -rw-r--r-- 1 root root 4.0K Apr 18 19:29 comp_algorithm -r--r--r-- 1 root root 4.0K Apr 19 01:20 debug_stat -r--r--r-- 1 root root 4.0K Apr 18 19:29 dev -r--r--r-- 1 root root 4.0K Apr 19 01:20 discard_alignment -rw-r--r-- 1 root root 4.0K Apr 19 01:21 disksize -r--r--r-- 1 root root 4.0K Apr 19 01:20 ext_range drwxr-xr-x 2 root root 0 Apr 18 19:29 holders/ -r--r--r-- 1 root root 4.0K Apr 19 01:20 inflight -r--r--r-- 1 root root 4.0K Apr 19 01:20 initstate -r--r--r-- 1 root root 4.0K Apr 19 01:20 io_stat -rw-r--r-- 1 root root 4.0K Apr 18 19:29 max_comp_streams --w------- 1 root root 4.0K Apr 19 01:20 mem_limit --w------- 1 root root 4.0K Apr 19 01:20 mem_used_max -r--r--r-- 1 root root 4.0K Apr 18 19:29 mm_stat drwxr-xr-x 2 root root 0 Apr 18 19:29 power/ drwxr-xr-x 2 root root 0 Apr 18 19:29 queue/ -r--r--r-- 1 root root 4.0K Apr 19 01:20 range -r--r--r-- 1 root root 4.0K Apr 19 01:20 removable --w------- 1 root root 4.0K Apr 19 01:20 reset -r--r--r-- 1 root root 4.0K Apr 19 01:20 ro -r--r--r-- 1 root root 4.0K Apr 18 19:29 size drwxr-xr-x 2 root root 0 Apr 18 19:29 slaves/ -r--r--r-- 1 root root 4.0K Apr 19 01:20 stat lrwxrwxrwx 1 root root 0 Apr 18 19:29 subsystem -> ../../../../class/block/ drwxr-xr-x 2 root root 0 Apr 18 19:29 trace/ -rw-r--r-- 1 root root 4.0K Apr 18 19:29 uevent
ZRAM の初期化は起動時に armbian-zram-config
サービスから /usr/lib/armbian/armbian-zram-config
が実行され、その中で設定が行われます。
$ systemctl cat armbian-zram-config # /lib/systemd/system/armbian-zram-config.service # Armbian ZRAM configuration service # Create 1 + number of cores compressed block devices # This service may block the boot process for up to 30 sec [Unit] Description=Armbian ZRAM config DefaultDependencies=no After=local-fs.target Before=armbian-ramlog.target Conflicts=shutdown.target [Service] Type=oneshot ExecStart=/usr/lib/armbian/armbian-zram-config start ExecStop=/usr/lib/armbian/armbian-zram-config stop RemainAfterExit=yes TimeoutStartSec=30sec [Install] WantedBy=sysinit.target
/usr/lib/armbian/armbian-zram-config
の中身はシェルスクリプトで、activate_ramlog_partition
関数によって /var/log
の初期化が行われています。
: 中略 : activate_ramlog_partition() { # /dev/zram0 will be used as a compressed /var/log partition in RAM if # ENABLED=true in /etc/default/armbian-ramlog is set ENABLED=$(awk -F"=" '/^ENABLED/ {print $2}' /etc/default/armbian-ramlog) [[ "$ENABLED" != "true" ]] && return # read size also from /etc/default/armbian-ramlog ramlogsize=$(awk -F"=" '/^SIZE/ {print $2}' /etc/default/armbian-ramlog) disksize=$(sed -e 's/M$/*1048576/' -e 's/K$/*1024/' <<<${ramlogsize:=50M} | bc) # choose RAMLOG_ALGORITHM if defined in /etc/default/armbian-zram-config # otherwise try to choose most efficient compression scheme available. # See https://patchwork.kernel.org/patch/9918897/ if [ "X${RAMLOG_ALGORITHM}" = "X" ]; then for algo in lz4 lz4hc quicklz zlib brotli zstd ; do echo ${algo} >/sys/block/zram0/comp_algorithm 2>/dev/null done else echo ${RAMLOG_ALGORITHM} >/sys/block/zram0/comp_algorithm 2>/dev/null fi echo -n ${disksize} > /sys/block/zram0/disksize # if it fails, select $swap_algo. Workaround for some older kernels if [[ $? == 1 ]]; then echo ${swap_algo} > /sys/block/zram0/comp_algorithm 2>/dev/null echo -n ${disksize} > /sys/block/zram0/disksize fi mkfs.ext4 -O ^has_journal -s 1024 -L log2ram /dev/zram0 algo=$(sed 's/.*\[\([^]]*\)\].*/\1/g' </sys/block/zram0/comp_algorithm) echo -e "### Activated Armbian ramlog partition with ${algo} compression" >>${Log} } # activate_ramlog_partition : 中略 :
上記の関数で mkfs.ext4
を実行しているので /var/log
以下はまっさらな状態になりますが、armbian-ramlog
サービスによってログのバックアップとリストアが行われています。こちらのスクリプトは /usr/lib/armbian/armbian-ramlog
にあります。もう一度 armbian-ramlog
サービスを確認してみます。
$ systemctl cat armbian-ramlog # /lib/systemd/system/armbian-ramlog.service # Armbian ramlog service # Stores logs in (compressed) memory # This service may block the boot process for up to 30 sec [Unit] Description=Armbian memory supported logging DefaultDependencies=no Before=rsyslog.service sysinit.target syslog.target After=armbian-zram-config.service Conflicts=shutdown.target RequiresMountsFor=/var/log /var/log.hdd IgnoreOnIsolate=yes [Service] Type=oneshot ExecStart=/usr/lib/armbian/armbian-ramlog start ExecStop=/usr/lib/armbian/armbian-ramlog stop ExecReload=/usr/lib/armbian/armbian-ramlog write RemainAfterExit=yes TimeoutStartSec=30sec [Install] WantedBy=sysinit.target
/usr/lib/armbian/armbian-ramlog
を見てみると syncToDisk
関数と syncFromDisk
関数で /var/log
と /var/log.hdd
のやり取りをしているのがわかります。
: 中略 : syncToDisk () { isSafe echo -e "\n\n$(date): Syncing logs to storage\n" | $LOG_OUTPUT if [ "$USE_RSYNC" = true ]; then ${NoCache} rsync -aXWv --delete --exclude "lost+found" --exclude armbian-ramlog.log --links $RAM_LOG $HDD_LOG 2>&1 | $LOG_OUTPUT else ${NoCache} cp -rfup $RAM_LOG -T $HDD_LOG 2>&1 | $LOG_OUTPUT fi sync } syncFromDisk () { isSafe echo -e "\n\n$(date): Loading logs from storage\n" | $LOG_OUTPUT if [ "$USE_RSYNC" = true ]; then ${NoCache} rsync -aXWv --delete --exclude "lost+found" --exclude armbian-ramlog.log --exclude *.gz --exclude='*.[0-9]' --links $HDD_LOG $RAM_LOG 2>&1 | $LOG_OUTPUT else ${NoCache} find $HDD_LOG* -maxdepth 1 -type f -not \( -name '*.[0-9]' -or -name '*.xz*' -or -name '*.gz' \) | xargs cp -ut $RAM_LOG fi sync } : 中略 :
syncToDisk
は cron によって一日一回行われているようです。
$ cat /etc/cron.daily/armbian-ram-logging #!/bin/sh /usr/lib/armbian/armbian-ramlog write >/dev/null 2>&1
ZRAM はメモリ上に展開しているためシャットダウンするとデータが消失してしまいます。ルートファイルシステムに含まれる /var/log.hdd
にバックアップを取り、起動時はそこからリストアを行うことで恒久化しているようです。
ログを確実に残しておきたいような場合は /etc/default/armbian-ramlog
の ENABLED
を true
以外にして ZRAM を無効にしておいた方がいいかもしれません。(microSD の寿命を縮めるかもしれませんが)