net.link.tap.up_on_open sysctl は if_tap が読み込まれてから2017年09月29日 13時59分04秒

昔に tap デバイスを紹介した時には、kldload で明示的に読み込んでいたが、わざわざ手動で読み込んでいなくても、ifconfig が読み込んでくれる。

ただ、 net.link.tap.up_on_open は if_tap が読み込まれていないと失敗してしまう。

$ sysctl net.link.tap.up_on_open=1
sysctl: unknown oid 'net.link.tap.up_on_open'
ifconfig で tap0 を作る。
$ ifconfig tap0 create
$ sysctl net.link.tap.up_on_open=1
net.link.tap.up_on_open: 0 -> 1
今度は、大丈夫。

起動時の設定として読み込むには /boot/loader.conf に

if_tap_load="YES"
/etc/sysctl.conf に
net.link.tap.up_on_open=1
とする。

前回

FreeBSD の一時スワップデバイスは tmpfs を nfs で export して swapon2017年09月25日 12時52分37秒

mdconfig の swapon はかなりオーバヘッドが多い。と言うか、ほとんどがオーバヘッドだ。

それに引き換え、あまり推奨されていない筈のNFS ファイルの swapon は、swap pager と NFS、そしてディスクの IO の値が一致する。ネットワークの帯域に多少は心配があっての、ファイルやデバイスへのアクセスは優秀で、ほぼ 100% の様だ。

これらを総合すると、swap 領域の圧迫の一時的な対処法は、別機からのサポートのようだ。メモリに余裕のあるシステムから、tmpfs を nfs エクスポートし、そこのファイルを直接 swapon をする。

また、大量のページングが発生している状況だと、スワップ領域も細切れになり、また、仮装メモリと実メモリのマッピングも随分と断片化する。ディスクが主体のスワップよりも、ネットワークと tmpfs のメモリアクセスの方が数倍も早くなる場合が多い。

NFS の export の部分を若干省略するが、大体の作業。

nfs-server $ mount -t swap dummy /mnt/tmp
nfs-server $ dd if=/dev/zero of=/mnt/tmp/swap bs=1M count=1 seek=9999
nfs-server $ vi /etc/export
nfs-server $ sh /etc/rc.d/nfsd onestart
swapping-machine $ mount -t nfs nfs-server:/mnt/tmp /mnt/swap
swapping-machine $ swapon /mnt/swap/swap

FreeBSD の mdconfig のでスワップファイルは非効率2017年09月20日 06時15分21秒

スワップ領域にするのに一番適しているのは、デバイス。一時的な利用などにより、物理メモリが足りなくて、さらにスワップデバイスも容量が逼迫してしまうときもある。そのような時には、ファイルを通してスワップをすることも可能だ。
$ dd if=/dev/zero of=/mnt/scratch/swap bs=1M count=1 seek=10000
$ mdconfig -a -t vnode -f /mnt/scratch/swap
md1
$ swapon /dev/md1

ただ、これは本当に一時凌ぎの様だ。まずは、root に成れなくてはならない。そして、読み書きの様子を観察をしていると、ファイルへのアクセスは多いのだが、swapin や swapon は大して多くならない。mdconfig を通して、ファイルとしてアクセスするオーバーヘッドがかなり大きい様だ。10 MB/s のディスクアクセスでも、実際のページングになるのは 1 MB/s あたり。ディスクのアクセス効率は、十から二十パーセントからぐらいのようだ。

FreeBSD で NFS ファイルにスワップする2017年09月15日 11時56分57秒

FreeBSD では長らくの間、NFS ファイルをスワップに指定できるようになっている。FreeBSD の古いドキュメントを見付けると、4.x 以前はとても遅かったといった記述や、NFS はネットワークに左右されるので、勧められないとの記述もあることはある。

取り敢えず実例。NFS の export と mount の位置はあまり関係なく、個々の設定による。

$ mount -t nfs x.x.x.x:/swap /mnt/swap
$ dd if=/dev/zero of=/mnt/swap/swap1 count=1 seek=1200
$ swapon /mnt/swap/swap1
swapon にそのままファイルのパスを指定すれば良い。dd にて空のファイルを先に作った。
$ swapctl -l
$ systat -swap
Device:       1024-blocks     Used:
/dev/#NODEV     1229824    109580
Disk      1K-blocks   Used /0%  /10  /20  /30  /40  /50  /60  /70  /80  /90  /10
[NFS swap]  1229696 109580 XXXXX

sswapctl や systat などで、スワップの割り当てや利用量をみられる。しかし、残念ながらファイル名は表示されないので、覚えておかなければいけない。
$ swapoff /mnt/swap/swap1
スワップ領域を外す場合は、ファイル名で指定する。複数の NFS ファイルで複数の領域を割り当てる事は出来るが、swapoff はファイル名で指定なので、忘れたら swapoff 出来なくなる。

shutdown 時には、nfs の umount や swapoff -a のタイミングが結構微妙な様なので、出来るならば shutdown 前に swapoff をしておいた方が良さそうだ。

cd: ..: Permission denied by newvers.sh2017年09月13日 11時10分32秒

FreeBSD で一般ユーザで buildkernel をするとエラーが出るようになった。11.1-RELEASE を作ったときは、自分のアカウントで出来たから、current と 11-STABLE が影響の対象だと思う。uyota で buildkernel をすると、無限ループに陥る。root で buildkernel をすると問題はない。

少し実験をする。make buildkernel から問題のあるコマンドだけを抜き取っった。newvers.sh が原因のようだ。

% MAKE=/usr/obj/usr/src/make.i386/bmake sh /usr/src/sys/conf/newvers.sh  GENERIC
cd: ..: Permission denied
cd: ..: Permission denied
sh に -x を渡して、実行されているコマンドを見る。
env MAKE=/usr/obj/usr/src/make.i386/bmake sh -x /usr/src/sys/conf/newvers.sh  GENERIC

+ [ -z '' ]
+ dirname /usr/src/sys/conf/newvers.sh
+ SYSDIR=/usr/src/sys/conf/..
...
+ findvcs .git
+ local savedir
+ pwd
+ savedir=/usr/src
+ cd /usr/src/sys/conf/../..
+ pwd
+ [ /usr/src '!=' / ]
+ [ -e ./.git ]
+ cd ..
+ pwd
+ [ /usr '!=' / ]
+ [ -e ./.git ]
+ cd ..
cd: ..: Permission denied
findvcs で無限ループに陥っているようだ。どうも /usr からは / へ .. で移動できていない様だ。取り合えず、該当する部分を見てみる。
findvcs()
{
        local savedir

        savedir=$(pwd)
        cd ${SYSDIR}/..
        while [ $(pwd) != "/" ]; do
                if [ -e "./$1" ]; then
while ループの pwd が成功しないため、while ループが無限ループに陥っている。

今まで目撃したことの無かった現象なので、気になったのでテスト。

% cd /usr/src
% df .
Filesystem  1K-blocks    Used   Avail Capacity  Mounted on
/dev/da2s2f   5061628 2584592 2072108    56%    /usr/src
% cd ..
% cd ..
..: Permission denied.
% df -k .
Filesystem   1024-blocks    Used   Avail Capacity  Mounted on
/dev/ada0s3d     7103150 1625446 4909452    25%    /usr
% pwd -P
/usr
% pwd
/usr
% cd ..
..: Permission denied.
% ls -ld /usr
drwxr-xr-x  19 root  wheel  512 Jun 18 13:42 /usr
% ls -ld /
drwxr-xr-x  23 root  wheel  1024 Sep 26 21:39 /
/usr/src から、/usr へは問題なく cd .. が出来ているが、/usr から / へは出来ていないようだ。ディレクトリへのアクセス権限も問題ない。

原因は分からないが、該当箇所を /usr と比較することで、一時的な回避は出来る。buildkernel は /usr/src から行うので、/usr までみれば十分だ。

        while [ $(pwd) != "/usr" ]; do

FreeBSD の /usr/bin/ld: cannot find -lgcc_s の修正の仕方2017年07月11日 13時21分27秒

FreeBSD で /usr/bin/ld: cannot find -lgcc_s がでて困っていた時のまとめ。

/usr/lib 以下のシンボリックリンクの貼り方が変わったのが原因のようだ。そこで、修正するには以前の様なシンボリックリンクに変えれば良い。

$ cd /usr/lib
$ ls -l *.so | nawk '$NF ~ /..\/..\/lib/{cmd="ln -sf " substr($NF, 6) " " $(NF-2);system(cmd)}'
なお、このコマンドは、root で作業。

前回

FreeBSD の libgcc_s シンボリックリンクを作り直す2017年07月09日 13時30分59秒

/usr/lib からのシンボリックリンクが変わった為に、一般ユーザからファイルが読めなくなっている。そこで、リンクを針直してみた。

ここは root で作業。 まずは、print で実行コマンドの点検。

$ cd /usr/lib
$ ls -l *.so | nawk '$NF ~ /..\/..\/lib/{cmd="ln -sf " substr($NF, 6) " " $(NF-2);print cmd}
ln -sf /lib/lib80211.so.1 lib80211.so
ln -sf /lib/libalias.so.7 libalias.so
ln -sf /lib/libavl.so.2 libavl.so
ln -sf /lib/libbegemot.so.4 libbegemot.so
ln -sf /lib/libbsdxml.so.4 libbsdxml.so
ln -sf /lib/libcam.so.7 libcam.so
print を system コマンドに変えて、再度実行。
$ ls -l *.so | nawk '$NF ~ /..\/..\/lib/{cmd="ln -sf " substr($NF, 6) " " $(NF-2);system(cmd)}'
$
この後、/usr/bin/ld: cannot find -gcc_s のエラーは出なくなった。

前回次回

/usr/lib/libgcc_s.so へのアクセス2017年07月07日 11時55分49秒

libgcc_s.so が見付けられないのは /usr/lib からのシンボリックリンクが変わったからの様に見られる。
% ls -sld /usr/lib/libgcc_s.so /lib/libgcc_s.so.1
46 -r--r--r--  1 root  wheel  45468 Jul  3 20:51 /lib/libgcc_s.so.1
 0 lrwxr-xr-x  1 root  wheel     23 Jul  3 20:51 /usr/lib/libgcc_s.so -> ../../lib/libgcc_s.so.1

head でどうしたらファイルが読めるか実験をする。

% head -c5 /usr/lib/libgcc_s.so
head: /usr/lib/libgcc_s.so: Permission denied
% head -c5 `realpath /usr/lib/libgcc_s.so`
ELF%
head -c5 `ls -l /usr/lib/libgcc_s.so| nawk '{print $NF}'`
head: ../../lib/libgcc_s.so.1: No such file or directory
realpath で展開した後ならファイルを読めるが、シンボリックリンクを辿ると、駄目な様だ。realpath は realpath ライブラリ関数を呼ぶだけのコマンド。シンボリックリンクを展開し、実ファイルに展開できる。

まあ、最後のコマンドではリンクを手元で展開しては正しいファイルのパスでは無くなるが…。

stat と lstat はシステム関数で、こちらもそれに対応する stat コマンドが存在する。-L をつけると lstat の動作になり、シンボリックリンクを表示する。

% stat -L /usr/lib/libgcc_s.so
stat: /usr/lib/libgcc_s.so: stat: Permission denied

前回次回

libgcc_s が見付けられない理由を truss で追跡2017年07月05日 12時07分56秒

root では見付けられる /lib/libgcc_s.so.1 をなぜ uyota アカウントでは見付けられないのかを更に追跡。truss を使ってシステムコールを探る。
% truss /usr/bin/ld --eh-frame-hdr -dynamic-linker /libexec/ld-elf.so.1 --hash-style=both
--enable-new-dtags -m elf_i386_fbsd -o a.out /usr/lib/crt1.o /usr/lib/crti.o
/usr/lib/crtbegin.o -L/usr/lib a.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc
--as-needed -lgcc_s --no-as-needed /usr/lib/crtend.o /usr/lib/crtn.o | & grep gcc_s
open("/usr/lib/libgcc_s.so",O_RDONLY,0666)       ERR#13 'Permission denied'
open("/usr/lib/libgcc_s.a",O_RDONLY,0666)        ERR#2 'No such file or directory'
open("/usr/bin/../libdata/libgcc_s.so",O_RDONLY,0666) ERR#2 'No such file or directory'
open("/usr/bin/../libdata/libgcc_s.a",O_RDONLY,0666) ERR#2 'No such file or directory'
open("//lib/libgcc_s.so",O_RDONLY,0666)          ERR#2 'No such file or directory'
open("//lib/libgcc_s.a",O_RDONLY,0666)           ERR#2 'No such file or directory'
open("//usr/lib/libgcc_s.so",O_RDONLY,0666)      ERR#13 'Permission denied'
open("//usr/lib/libgcc_s.a",O_RDONLY,0666)       ERR#2 'No such file or directory'
-lgcc_swrite(2,"-lgcc_s",7)                              = 7 (0x7)
libgcc_s が読み込みように開けない。

同じコマンドを root で実行。

# truss /usr/bin/ld --eh-frame-hdr -dynamic-linker /libexec/ld-elf.so.1 --hash-style=both
--enable-new-dtags -m elf_i386_fbsd -o a.out /usr/lib/crt1.o /usr/lib/crti.o
/usr/lib/crtbegin.o -L/usr/lib a.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc
--as-needed -lgcc_s --no-as-needed /usr/lib/crtend.o /usr/lib/crtn.o | & grep gcc_s
open("/usr/lib/libgcc_s.so",O_RDONLY,0666)       = 9 (0x9)
open("/usr/lib/libgcc_s.so",O_RDONLY,0666)       = 3 (0x3)
こちらでは問題なく開いている。

最初に libgcc_s を調べたときもそうだったが、読み出しの権限は与えられている。

% ls -sld /usr/lib/libgcc_s.so /lib/libgcc_s.so.1
46 -r--r--r--  1 root  wheel  45468 Jun 30 02:51 /lib/libgcc_s.so.1
 0 lrwxr-xr-x  1 root  wheel     23 Jun 30 02:51 /usr/lib/libgcc_s.so -> ../../lib/libgcc_s.so.1
% head /usr/lib/libgcc_s.so
head: /usr/lib/libgcc_s.so: Permission denied
上記は、FreeBSD 11.1-RELEASE と、11.0-RELEASE のシンボリックリンクだった。

気になったので、10.2-RELEASE でも ls。

% ls -sld /usr/lib/libgcc_s.so
 0 lrwxr-xr-x  1 root  wheel     18 Feb 21 2016 /usr/lib/libgcc_s.so -> /lib/libgcc_s.so.1
% head /usr/lib/libgcc_s.so
?ELF...
10.x-RELEASE の時は、絶対パスだったのが、11.x-RELEASE になって、相対パスに変わっている。

前回次回

FreeBSD 11.1-RELEASE の top から Laundry が加わった2017年06月15日 12時41分32秒

FreeBSD 11.1-RELEASE のリリースが間近なので、11-STABLE を追っている。11.1-BETA になり、ベータリリースは順次すすんでいるようだ。コミットの数もだいぶ減って、あれこれ重要な変更のみになっている。

11.1-BETA を動かしていて気が付いたのだが、top から Cached の名前が消えて、Laundry になっている。

CPU:  1.0% user,  0.0% nice,  1.4% system,  0.1% interrupt, 97.5% idle
Mem: 215M Active, 54M Inact, 57M Laundry, 125M Wired, 51M Buf, 6880K Free
Swap: 1024M Total, 68M Used, 956M Free, 6% Inuse

気になったので、ちょこっと探してみたところ、バージョン 290833 によるものだ。Laundry は number of dirty bytes inactive とある。PQ_LAUNDRY によると新しいページのキューで、使用済みのメモリを取っておくものの様だ。