前回は、systemctl を使って unit ファイルの名前や有効/無効状態、12種類の unit の名称と役割、unit の依存関係と control group についてザックリと調べてみた。
/etc/systemd や /lib/systemd、/run/systemd 以下に設定ファイルがない unit もあり、どういう状態になっているか試行錯誤して確認を進めてみた。今回は unit の type 毎にもう少し細かく調べてみた。
automount、mount
これらは、仮想含む filesystem を mount する unit である。
$ systemctl list-unit-files *mount UNIT FILE STATE proc-sys-fs-binfmt_misc.automount static -.mount generated dev-hugepages.mount static dev-mqueue.mount static media-cdrom0.mount generated proc-sys-fs-binfmt_misc.mount static sys-fs-fuse-connections.mount static sys-kernel-config.mount static sys-kernel-debug.mount static 9 unit files listed.
- systemd では、path 区切り文字が '/' から '-' に置き換えられている。なので、UNIT FILE の proc-sys-fs-binfmt_misc は /proc/sys/fs/binfmt_misc に対応する。
- STATE が generated の行は動的生成された unit、static の行は設定ファイルが存在する unit。
- 動的生成された unit は、-.mount と media-cdrom0.mount の2つ。/etc/fstab から動的生成されている。
- -.mount は '/' (root fs) を mount する unit。今の環境では '/' (root fs) のみだが、/usr や /var や /home を分けている場合には複数存在しているはず。
- media-cdrom0.mount は /dev/sr0 を mount する unit。DVD drive を1台接続しているので、install の際に /etc/fstab に entry が作成されていた。
binfmt_misc
- automount と mount と2つあるのは何故だろう。
- /proc/sys/fs/binfmt_misc:JF: Linux Kernel 2.6 Documentation: binfmt_misc.txt。kernel module でも binfmt_misc.ko が読み込まれている。
いろんな (お好みの) バイナリフォーマットのカーネルサポート v1.1
===============================================================このカーネルでは、シェルからその名前をタイプするだけで、ほとんどのプログラムを (制限は下を参照) 起動することができます。この中には、例えばコンパイル済みの Java(TM)、Python、Emacs プログラムが含まれます。
これをできるようにするには、どのバイナリをどのインタプリタで起動するかを binfmt_misc に教えてやらなければなりません。binfmt_misc は、指定された
マジックバイトシーケンスとファイルの先頭の何バイトかを (特定のビットはマスクして) 比較し、バイナリタイプを判定します。binfmt_misc は「.com」や
「.exe」といったファイル名の拡張子も認識することができます。
- script は、最初の行に '#!/bin/sh' とか指定すると、どの script 言語で実行すれば良いか分かる。
- それに対して binary は、別環境のものをそのまま実行することは出来ない。(windows の exe は linux では実行できない)
- binfmt_misc は、間に qemu 等の別環境を実行する為の binary を登録しておく事で、Host 環境と同じように別環境の binary を実行することができる。現在の環境では python と qemu が登録されていた。
$ ls /proc/sys/fs/binfmt_misc python2.7 qemu-armeb qemu-mips64 qemu-ppc64abi32 qemu-sparc python3.5 qemu-cris qemu-mips64el qemu-ppc64le qemu-sparc32plus qemu-aarch64 qemu-m68k qemu-mipsel qemu-s390x qemu-sparc64 qemu-alpha qemu-microblaze qemu-ppc qemu-sh4 register qemu-arm qemu-mips qemu-ppc64 qemu-sh4eb status $ ls /var/lib/binfmts python2.7 qemu-armeb qemu-mips64 qemu-ppc64abi32 qemu-sparc python3.5 qemu-cris qemu-mips64el qemu-ppc64le qemu-sparc32plus qemu-aarch64 qemu-m68k qemu-mipsel qemu-s390x qemu-sparc64 qemu-alpha qemu-microblaze qemu-ppc qemu-sh4 qemu-arm qemu-mips qemu-ppc64 qemu-sh4eb $ dpkg -S /var/lib/binfmts binfmt-support: /var/lib/binfmts $ ls /usr/share/binfmts python2.7 python3.5 $ dpkg -S /usr/share/binfmts binfmt-support, python3.5-minimal, python2.7-minimal: /usr/share/binfmts
HugePages
- /dev/hugepages:Hugepages - Debian Wiki、Oracle Database 管理者リファレンス : HugePages
When a process uses some memory, the CPU is marking the RAM as used by that process. For efficiency, the CPU allocate RAM by chunks of 4K bytes (it's the default value on many platforms). Those chunks are named pages. Those pages can be swapped to disk, etc.
Since the process address space are virtual, the CPU and the operating system have to remember which page belong to which process, and where it is stored. Obviously, the more pages you have, the more time it takes to find where the memory is mapped. When a process uses 1GB of memory, that's 262144 entries to look up (1GB / 4K). If one Page Table Entry consume 8bytes, that's 2MB (262144 * 8) to look-up.
Most current CPU architectures support bigger pages (so the CPU/OS have less entries to look-up), those are named Huge pages (on Linux), Super Pages (on BSD) or Large Pages (on Windows), but it all the same thing.
- 最近の PC では memory size が大きいので、memory 管理 table が 4kiB pages だと table が大きくなる。Page size を amd64 なら 2MiB か 1GiB pages (CPU依存)にする事により効率を上げる。他の OS でも同様の考えを導入している。
$ grep flags /proc/cpuinfo | head -1 | perl -pe 's/ /\n/g' | grep -e 'pse$' -e 'pdpe1gb$' pse $ grep Huge /proc/meminfo AnonHugePages: 0 kB ShmemHugePages: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB
https://tech.hylogics.com/entry/qemu_memorytuningtech.hylogics.com
mqueue
- POSIX message queue : Ubuntu Manpage: mq_overview - POSIX メッセージキューの概要
- process 間の通信規格の一つ。
- Linuxのプロセス間通信 - Qiita:こちらには mqueue についての記載がない。
- 2009-03-27:こちらには sample 付きで事例があったので、試しにやってみた。
- そのままでは動作しなかったので少し変更した。mq_open の引数に &attr が必要。
$ diff -u mqread.c.orig mqread.c --- mqread.c.orig 2019-03-17 22:43:59.444848284 +0900 +++ mqread.c 2019-03-17 22:32:00.550998379 +0900 @@ -22,15 +22,21 @@ memset(&attr, 0, sizeof(attr)); + attr.mq_flags = 0; + attr.mq_maxmsg = 10; + attr.mq_msgsize = 1024; + attr.mq_curmsgs = 0; + mq_unlink("/mq1"); mq_unlink("/mq2"); + if ((fd1 = mq_open("/mq1", O_RDONLY|O_NONBLOCK|O_CREAT|O_EXCL, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1) { + S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, &attr)) == -1) { perror("open /mq1"); exit(-1); } if ((fd2 = mq_open("/mq2", O_WRONLY|O_NONBLOCK|O_CREAT|O_EXCL, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1) { + S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, &attr)) == -1) { perror("open /mq2"); exit(-1); }
-
- compile & run。-lrt が必要。
$ gcc -lrt -g -o mqread mqread.c $ gcc -lrt -g -o mqwrite mqwrite.c $ ./mqread // 別端末で実行しておく $ time ./mqwrite 1000000 write loop= 500000 real 0m6.822s user 0m0.716s sys 0m3.436s
- POSIX message priority queue example written in C/C++ · GitHub:こちらの sample は変更せずに動作した。結果は省略。
- 別の program として、あるいは別 thread で動作させている process 間で通信をするのに便利な機能である事が分かった。
Filesystem in Userspace (FUSE)
Filesystem in Userspace (FUSE) はUnix系コンピュータオペレーティングシステム用のソフトウェアインタフェースである。権限を持たないユーザがカーネルコードを修正することなく独自のファイルシステムを作成できる機能を提供する。これは、ファイルシステムのコードをユーザ空間で実行することでなされるもので、その際FUSEモジュールは実際のカーネルインタフェースへの「橋渡し」しか提供しない。
ja.wikipedia.org
/sys/fs/fuse/connections 以下に数字の directory が存在するが、gvfsd で使用されている。
$ systemctl list-units *mount UNIT LOAD ACTIVE SUB DESCRIPTION proc-sys-fs-binfmt_misc.automount loaded active running Arbitrary Executable File Formats File System Automount Point -.mount loaded active mounted Root Mount dev-hugepages.mount loaded active mounted Huge Pages File System dev-mqueue.mount loaded active mounted POSIX Message Queue File System proc-sys-fs-binfmt_misc.mount loaded active mounted Arbitrary Executable File Formats File System run-user-1000-gvfs.mount loaded active mounted /run/user/1000/gvfs run-user-1000.mount loaded active mounted /run/user/1000 run-user-110-gvfs.mount loaded active mounted /run/user/110/gvfs run-user-110.mount loaded active mounted /run/user/110 sys-fs-fuse-connections.mount loaded active mounted FUSE Control File System sys-kernel-debug.mount loaded active mounted Debug File System LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type. 11 loaded units listed. Pass --all to see loaded but inactive units, too. To show all installed unit files use 'systemctl list-unit-files'.
unit file は存在していないが、動的生成されて run-user-*-gvfs.mount が実行されている模様。
Configfs
/sys/kernel/config.mount は Configfs。これは、unit は存在しているが有効にはなっていない。
$ systemctl list-unit-files *config*mount UNIT FILE STATE sys-kernel-config.mount static 1 unit files listed. $ systemctl list-units *config*mount 0 loaded units listed. Pass --all to see loaded but inactive units, too. To show all installed unit files use 'systemctl list-unit-files'.
ただ、Wikipedia を見ても用途が良く分からなかった。
en.wikipedia.org
こちらの sample を見ると、configfs + α で kernel や module と直接やりとり出来る virtual filesystem である事が分かる。
wiki.bit-hive.com
次の page を見て、組み込み用途で便利な機能だという事が分かった位。
Zynq + Yocto で USB デバイスをつくってみた - Qiita
電気回路/zynq/Device Tree Overlay - 武内@筑波大
FPGA+SoC+LinuxでDevice Tree Overlayを試してみた - Qiita
後でもう少し調べてみる。
Debugfs
/sys/kernel/debug.mount は、Debugfs。
en.wikipedia.org
debugfs is a simple-to-use RAM-based file system specially designed for debugging purposes.
debug 用途の virtual filesystem。module ではなく、kernel 組み込みになっている。
$ cat /boot/config-4.9.0-8-amd64 | grep CONFIG_DEBUG_FS CONFIG_DEBUG_FS=y
日本語では、こちらの page がわかりやすい。
https://qiita.com/satoru_takeuchi/items/d2760c32a88376e1bc4aqiita.com
なんとなく Configfs と被る部分がありそう。実際に上の page では情報の取得・設定に使用しているし。単純に、使いやすい方を使うやり方なのだろうか。それとも、Debugfs が主流で Configfs は傍流、だから標準では読み込まれないのだろうか。
結果
automount、mount の unit について一通り調べてみた。
どちらかというと、kernel の機能を調べているような感じだが、これを通して linux kernel についての理解が深められたらと思う。