core
make TAGS and cscope
FreeBSDから移植したOpenBSD用のMakefile。なおオリジナルな奴はOpenBSDに即したきめ細かい配慮がなされた作りになってる。勿論、その分は複雑だ。
CURDIR = /usr/src/OpenBSD-7.1/sys dofiles: cd ${CURDIR} find conf dev arch/i386 kern lib sys -name '*.[chSsly]' -a -type f > cscope.files rm -f TAGS xargs etags -a < cscope.files cscope -k -buq -p4 -v
使いそうな部分だけのTAGSとcscopeを作ってみた。findで複数PATHを指定する所とxargsを単独で使う所が目から鱗ですよ。TAGSは作成の度に追加されちゃうので、事前に削除する事。
cscopeのスイッチは、カーネルモード(turns off the use of the default include dir)、 cross-reference、 Display the last n file path components、らしい。
core
普通にcoreと言ったら、ユーザーランドのマナーの悪いやつが出すアレだ。
#include <stdlib.h> #include <stdio.h> int sum = 0; int add(int a, int b) { return a + b; } int main(int argc, char* argv[]) { int a = atoi(argv[1]); int b = atoi(argv[2]); sum = add(a, b); printf("sum=%d\n", sum); return 0; }
こんな変哲も無いやつでも、使いかたを誤ると即coreだ。
vbox$ ./a.out Segmentation fault (core dumped) vbox$ gdb -q a.out a.out.core Reading symbols from a.out... [New process 123861] Core was generated by `a.out'. Program terminated with signal SIGSEGV, Segmentation fault. #0 _libc_strtol (nptr=0x0, endptr=0x0, base=10) at /usr/src/lib/libc/stdlib/strtol.c:68 68 c = (unsigned char) *s++;
お決まりの臨場はさておき、coreファイルって何者?
vbox$ readelf -a a.out.core ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: CORE (Core file) Machine: Intel 80386 :
普通のアプリと同様な形式でした。なんて事が昔の某本に説明されてたなあ。こういうマニアックな本は大好きであります。
kvm
vbox$ fuser -f /home/sakae /home/sakae: 35377c 6823c 29165c 37714c vbox# fuser -N /var/crash/bsd.0 -M /var/crash/bsd.0.core -f /home/sakae fuser: can't read process at f57b95f8
ちなみにfuserコマンドは指定したファイルがどのプロセスから利用されてるか調べるやつ。例では、ksh,tmux等が使ってるって分る。PIDの後ろのcはcurrent working directoryって目印を示す。
290 if ((kf = kvm_getfiles(kd, KERN_FILE_BYPID, -1, sizeof(*kf), (gdb) 292 errx(1, "%s", kvm_geterr(kd)); (gdb) fuser: can't read process at f57b95f8 [Inferior 1 (process 96325) exited with code 01]
どのあたりのルーチン?
(gdb) s kvm_getfiles (kd=0x7fc9a780, op=2, arg=-1, esize=624, cnt=0xcf7d85a4) at /usr/src/lib/libkvm/kvm_file2.c:140 140 if (ISALIVE(kd)) {
この際だからkvmのライブラリィーを見て億
vbox$ pwd /usr/src/lib/libkvm vbox$ ls *.[ch] kvm.c kvm_file.h kvm_mips64.c kvm_proc2.c kvm_alpha.c kvm_file2.c kvm_ntfs.c kvm_riscv64.c kvm_amd64.c kvm_getloadavg.c kvm_powerpc.c kvm_sh.c kvm_arm.c kvm_hppa.c kvm_powerpc64.c kvm_sparc64.c kvm_arm64.c kvm_i386.c kvm_private.h kvm_udf.c kvm_cd9660.c kvm_m88k.c kvm_proc.c
ふーん、arch特有なものと共通なものの寄せ集めなのね。
で、大量にあるカーネルの情報を効率よく取り出す為に、
NAME kvm_nlist – retrieve symbol table names from a kernel image SYNOPSIS #include <kvm.h> #include <nlist.h> int kvm_nlist(kvm_t *kd, struct nlist *nl);
こんな関数が用意されてる。こいつの元ネタは
vbox$ ls -l /var/db/kvm_bsd.db -rw-r----- 1 root kmem 2613248 May 17 13:39 /var/db/kvm_bsd.db vbox$ file /var/db/kvm_bsd.db /var/db/kvm_bsd.db: writable, regular file, no read permission
こんなDBが用意されてる。 kvm_mkdb
を使って、構成するんだな。
add disk for swap
前回やったsavecoreの失敗。SWAPエリアが足りない疑惑を思い付いた。ならばSWAP用に豪華にDISKを増設しちゃえ。VirtualBOXにDISKを増設。See Also add disk mycase
メモリーを2Gにしてるんで、セオリー通りにその2倍プラス余裕を持たせる事にして、5Gにした。普段はSWAPしたら負けよと思っているんで、既存のシステムは雀の涙の設定だ。
vbox$ cat /etc/fstab 374dfbdba8ac84a9.b none swap sw 374dfbdba8ac84a9.a / ffs rw,wxallowed 1 1 /dev/wd1c /EXTd ffs rw 1 1 swap /tmp mfs rw,nodev,nosuid,-s=1024m 0 0 vbox$ df -h Filesystem Size Used Avail Capacity Mounted on /dev/wd0a 3.7G 1.8G 1.7G 52% / /dev/wd1c 7.7G 4.2G 3.1G 57% /EXTd
SWAPな情報が出ていないので、改めて専用コマンドで確認
vbox$ pstat -T 70/7030 open files 1536 vnodes 0M/133M swap space vbox$ swapctl -l Device 512-blocks Used Avail Capacity Priority /dev/wd0b 273041 0 273041 0% 0
じゃ追加したDISKがちゃんと認識されてるか確認。
vbox$ dmesg | grep wd wd0 at pciide0 channel 0 drive 0: <VBOX HARDDISK> wd0: 128-sector PIO, LBA, 4096MB, 8388608 sectors wd1 at pciide0 channel 0 drive 1: <VBOX HARDDISK> wd1: 128-sector PIO, LBA, 8192MB, 16777216 sectors wd0(pciide0:0:0): using PIO mode 4, Ultra-DMA mode 2 wd1(pciide0:0:1): using PIO mode 4, Ultra-DMA mode 2 wd2 at pciide0 channel 1 drive 1: <VBOX HARDDISK> wd2: 128-sector PIO, LBA, 5120MB, 10485760 sectors wd2(pciide0:1:1): using PIO mode 4, Ultra-DMA mode 2 root on wd0a (374dfbdba8ac84a9.a) swap on wd0b dump on wd0b
目出度く、wd2として認識された。IDEなセカンダリィーの2番目に位置するって言う位置付けだ。
少しDISKの扱い方法を調査。
make disk
まず、fdiskの登場で、DISKの全エリアをOpenBSD用にセットアップ
vbox# fdisk -i wd2 Do you wish to write new MBR? [n] y Writing MBR at offset 0. vbox# fdisk -e wd2 Enter 'help' for information wd2: 1> p Disk: wd2 geometry: 652/255/63 [10485760 Sectors] Offset: 0 Signature: 0xAA55 Starting Ending LBA Info: #: id C H S - C H S [ start: size ] ------------------------------------------------------------------------------- 0: 00 0 0 0 - 0 0 0 [ 0: 0 ] unused 1: 00 0 0 0 - 0 0 0 [ 0: 0 ] unused 2: 00 0 0 0 - 0 0 0 [ 0: 0 ] unused *3: A6 0 1 2 - 652 180 40 [ 64: 10485696 ] OpenBSD wd2: 1> w Writing MBR at offset 0. wd2: 1> q
次はラベルエディタを手動モードで起動して(Install時の用法)エリアを作成。全部をswap用にした。
vbox# disklabel -E wd2 Label editor (enter '?' for help at any prompt) wd2> p OpenBSD area: 64-10485760; size: 10485696; free: 10485696 # size offset fstype [fsize bsize cpg] c: 10485760 0 unused wd2> a b offset: [64] size: [10485696] FS type: [swap] wd2*> w wd2> q No label changes.
後は、ちゃんとSWAPになるかの確認と、boot時に有効になるようにfstabに追加。
vbox# swapctl -a /dev/wd2b vbox# vi /etc/fstab : /dev/wd2b none swap sw
まだこのSWAPは使用されていないので、VirtualBOXレベルでは3Mぐらいの消費であった
swapctl, vnconfig
make core
実際にカーネルのコアを作ってみる。現状のSWAPのエリア状況
vbox# top : Memory: Real: 15M/52M act/tot Free: 1942M Cache: 20M Swap: 0K/5253M
じゃ、やるぞ
ddb{0}> call panic : ddb{0}> boot dump syncing disks...14 11 done WARNING: not updating battery clock dumping to dev 1, offset 8 dump 132 131 130 ... 7 6 5 4 3 2 1 0 area improper rebooting... >> OpenBSD/i386 BOOT 3.44 : avecore: reboot after panic: uvm_fault(0xd58e3960, 0x0, 0, 1) -> e savecore: system went down at Sun Sep 25 15:01:35 2022 savecore: writing core to /var/crash/bsd.3.core savecore: writing kernel to /var/crash/bsd.3 :
確認したけど駄目だった。
vbox# fstat -N bsd.3 -M bsd.3.core fstat: can't read process at f577a274
try2
優先順位を変更出来るみたいなので、、
vbox# swapctl -c -p 1 /dev/wd0b vbox# swapctl -l Device 512-blocks Used Avail Capacity Priority /dev/wd2b 10485696 0 10485696 0% 0 /dev/wd0b 273041 0 273041 0% 1 Total 10758737 0 10758737 0%
やっぱり駄目だわさ。何で?
db{0}> boot dump syncing disks...12 8 done WARNING: not updating battery clock dumping to dev 1, offset 8 dump 132 131 130 129 ... 4 3 2 1 0 area improper
ふと気になった事
vbox# dmesg | grep wd : root on wd0a (374dfbdba8ac84a9.a) swap on wd0b dump on wd0b
よくみると、swapとdumpは別物扱いされてるっぽいぞ。
where msg
上の疑問のメッセージを何処で出している? それはね、 kern/subr_disk.c
void setroot(struct device *bootdv, int part, int exitflags) { : printf("root on %s%c", rootdv->dv_xname, 'a' + part); if (dk && dk->dk_device == rootdv) printf(" (%s.%c)", duid_format(rootduid), 'a' + part); if (swdevt[0].sw_dev != NODEV) printf(" swap on %s%d%c", findblkname(major(swdevt[0].sw_dev)), DISKUNIT(swdevt[0].sw_dev), 'a' + DISKPART(swdevt[0].sw_dev)); if (dumpdev != NODEV) printf(" dump on %s%d%c", findblkname(major(dumpdev)), DISKUNIT(dumpdev), 'a' + DISKPART(dumpdev)); printf("\n"); }
どうもdumpdevは選択の余地が無いっぽい。
How to handle disk at install
ちょっとイジケてインストール中のDISKコマンドの使われ方をみておく。
src/distrib/i386/common/install.md
ask "Use (W)hole disk$_q or (E)dit the MBR?" "$_d" case $resp in [wW]*) echo -n "Setting OpenBSD MBR partition to whole $_disk..." fdisk -iy $_disk >/dev/null echo "done." return ;; : md_prep_disklabel() { local _disk=$1 _f=/tmp/i/fstab.$1 md_prep_fdisk $_disk disklabel_autolayout $_disk $_f || return [[ -s $_f ]] && return # Edit disklabel manually. # Abandon all hope, ye who enter here. disklabel -F $_f -E $_disk }
DISKを全部使う場合は、-iy だ。それから、パーテションのレイアウトは全アーチで共通なので 、それを呼出ているんだな。
src/distrib/miniroot/install.sub
disklabel_autolayout() { : _qst="Use (A)uto layout, (E)dit auto layout, or create (C)ustom layout?" while :; do echo "The auto-allocated layout for $_disk is:" disklabel -h -A $_disk | egrep "^# |^ [a-p]:" ask "$_qst" a case $resp in [aA]*) _op=-w;; [eE]*) _op=-E;; [cC]*) return 0;; *) continue;; esac disklabel -F $_f $_op -A $_disk return done
なる程、よく分ったよ。
disklabel(8)を見ていたら、自動割付の計算値が紹介されてた。
Disks >= 10 Gigabytes / 5% of disk. 150M – 1G swap 10% of disk. 80M – 2x max physical memory /tmp 8% of disk. 120M – 4G /var 13% of disk. 80M – 4G + 2x size of crash dump :
スワップは最低80M以上必要で、実メモリーの2倍。/varは、80Mから4Gの範囲それに、クラッシュ用のエリアが2倍は必要。いわゆる死体は2名様まで受け入れる設備が必要って事だな。なお、死体すなわちkernelコアサイズは、色々だけど。。。
パーテションの切りかたに悩みがあったら、参考にすればよい。