3度目のOpenBSD

ついに、晴れて憧れのOpenBSDユーザになれた。 2005年以来の3度目の挑戦で成功。

前々からOpenBSDに至高感は感じていた。 去年WIDE合宿にゲストスピーカー(BSD BoF)参加したときに、 次の話者の加藤朗先生がOpenBSD w/ ThinkPad X1 Carbon でプレゼンされているのを見てから、やはりカッコいいなあとの思いが倍増した。 そして、今年導入した2019年版ThinkPad Xシリーズで軒並み NetBSD が使えないのを機に、 15年ぶりにOpenBSDチャレンジしたら、いとも簡単に実用域まで設定できた。 変化に驚きつつ、OpenBSDユーザに収まることとした。 いまのところまだエンドユーザモードだが。

NetBSDから見たOpenBSD

ほとんどいないと思うが「NetBSDユーザの前提知識」を 持った上でのOpenBSDの利点を挙げてみる。

いまいちな点

逆にOpenBSDで残念なところ。 でもそれを補って余りあるのでヨシ。

最初にやるべき設定

初期インストール直後にやらねばならぬことがいくつかあるのでまとめた。

doas

sudo要らない。doas.conf(5) を参照して自分ユーザを足しておく。

ファームウェアアップデート

無線チップなど、いくつかのデバイスがそのままでは使えないのでこれ。

doas fw_update
doas shutdown -r now

これでdrmやWi-Fiデバイスが使えるようになる……はず。ちなみに ThinkPad X390 では内蔵無線LANは使えなかった。しかたなく urtwn (ちっちゃいUSB無線LANプラグ)を使った。

apmdフラグ

ラップトップPCなら、apmdのフラグを -A に変えておく。 /etc/rc.conf.local に

apmd_flags="-A"

を足す。そのへん、rcctl(8) コマンドで設定可能。 上記なら rcctl set apmd flags -A で。

login.conf

プロセスのリソースリミットが低すぎる。 Javaなんかはこのままじゃ動かないだろう。 datasize-max=infinity でよかろう。

Xのキーマップ設定

コンソールで使う場合に以下は必須である。

これは、/etc/X11/xorg.conf あたりに書いた方がいいのかもしれないが、 せっかく zero-configuration でXが映っているのでなんとなく .xinitrc に書いてみた。以下を ~/.xinitrc に追加する。

setxkbmap -option ctrl:nocaps
xinput set-prop "/dev/wsmouse" "WS Pointer Wheel Emulation" 1
xinput set-prop "/dev/wsmouse" "WS Pointer Wheel Emulation Axes" 6 7 4 5
xinput set-prop "/dev/wsmouse" "WS Pointer Wheel Emulation Button" 2
xinput set-prop "/dev/wsmouse" "WS Pointer Wheel Emulation Timeout" 50
xinput set-prop "/dev/wsmouse" "WS Pointer Wheel Emulation Inertia" 3

これで十分。

Xを上げてないときのコンソールは、NetBSDと同じでいいのかな。 あ微妙に違う。/etc/wsconsctl.conf に以下を記述。

keyboard.encoding=us.swapctrlcaps

同じことは /etc/kbdtype に

us.swapctrlcaps

とだけ書いても得られる。

サンプルスクリプト

apm

サスペンド/復帰のときに、/etc/apm/ 内にある指定した名称の プログラム(スクリプト)が呼ばれる。詳しくはapmd(8)参照。

resume

#!/bin/sh
wifi=${WIFI:-urtwn0}

upscript=/etc/apm/wifi-reconn.sh

(trial=3
 while [ $trial -gt 0 ]; do
   if $upscript; then
     break
   else
     sleep 3
     trial=$((trial-1))
   fi
 done
)

↑で呼び出している wifi-reconn.sh:

#!/bin/sh
retry=10
mydir=`dirname $0`
static=$mydir/ssid

if [ -e $static ]; then
  ssids=`cat $static`
else
  ssids=`egrep -ql '^ *(join|nwid)' /etc/hostname.*|sed 's/.*\.//'`
fi

for wlif in $ssids
do
  echo i=$wlif
  sh /etc/netstart $wlif
  ifconfig $wlif | grep -q 'status: active' && exit 0
  for ssid in `egrep '^ *(join|nwid)' /etc/hostname.$wlif|awk '{print $2}'`
  do
    echo Trying.........................$ssid
    i=$retry
    ifconfig $wlif nwid $ssid
    while [ $i -gt 0 ]; do
      ifconfig $wlif | grep -q 'status: active' &&; exit 0
      i=$((i-1))
      sleep 1
    done
  done
done
exit 1

hotplug

ストレージクラスのUSBデバイスを挿したとき/抜いたときに マウント/アンマウントするスクリプトを作った。これはそれぞれ attach, detach という名前のスクリプトにする。実例は hotplugd(8) に書いてある。

attach

#!/bin/ksh
#
# $Header$

DEVCLASS=$1
DEVNAME=$2

# (echo `date`: args="$*" disk=$DEVNAME) >> /tmp/attach.args 2>&1
[[ $DEVCLASS != 2 ]] && exit 0

case $DEVNAME in
sd[123])
        echo Mounting $DEVNAME >> /tmp/attach.args
        disklabel $DEVNAME | grep i:.*MSDOS > /dev/null
        [[ $? -eq 0 ]] && mount /dev/"$DEVNAME"i
        ;;
cd[01234])
        disklabel $DEVNAME | grep -i 'ISO9660' > /dev/null 2>&1
        [[ $? -eq 0 ]] && mount /dev/${DEVNAME}a
esac

detach

#!/bin/ksh
#
# $Header$

DEVCLASS=$1
DEVNAME=$2

[[ $DEVCLASS != 2 ]] && exit 0
case $DEVNAME in
  [cs]d[0-9])
        umount /dev/${DEVNAME}i
        exit 0
        ;;
esac

msdosfsもISO9660もぶすっと挿して、すぱっと抜いておっけー。

バッテリー情報

apm(8)コマンドでバッテリー情報出てくるが、 「あと何分でフル充電?」とか欲しいのでこんなシェルスクリプトを作ってみた。

battery

#!/bin/sh

getval() {
  case $1 in
    lastfull)	fld=acpibat0.watthour0 ;;
    remain)	fld=acpibat0.watthour3 ;;
    rate)	fld=acpibat0.power0 ;;
    power)	fld=acpiac0.indicator0 ;;
  esac
  sysctl -n hw.sensors.$fld | cut -d' ' -f1
}
for v in remain lastfull rate power; do
  eval $v=`getval $v`
done
percent=`echo "100*$remain/$lastfull"|bc -l|cut -d. -f1`
case $rate in
  0.0*)	rate=0 ;;
esac
case $power in
  Off)
	printf "AC Offline: Battery remaining %5.1f%%\n" $percent
	if [ x"$rate" = x"0" ]; then
	  echo Unknown lifetime
	else
  	  life=`echo "$remain/$rate"|bc -l`
	  hour=${life%.*} dmin=${life#*.}
	  min=`echo "0.$dmin * 60" | bc -l | cut -d. -f1`
	  printf "Discharging at %.2f(%.2f/%.2f) - ${hour:-0}h%02dm to go\n" $rate $remain $lastfull $min
	fi
	;;
  On)
	printf "AC ONline: Battery remaining %5.1f%%\n" $percent
	if [ x"$rate" = x"0" ]; then
	  echo "Last full capacity: ${lastfull}Wh"
	else
	  tf=`echo "$lastfull - $remain"|bc -l`
  	  tofull=`echo "$tf/$rate"|bc -l`
	  hour=${tofull%.*} dmin=${tofull#*.}
	  min=`echo "0.$dmin * 60" | bc -l | cut -d. -f1`
	  printf "Rate $rate to $tf ($remain/$lastfull) - "
	  printf "${hour:-0}h%02dm to full\n" $min
	fi
	;;
esac

出力はこんな感じ。

# オフライン時
battery
AC Offline: Battery remaining  99.0%
Discharging at 7.73(45.45/45.87) - 5h52m to go
# オンライン時
AC ONline: Battery remaining  92.0%
Rate 13.89 to 3.49 (42.38/45.87) - 0h15m to full

FreeBSD 2.2.8Rとかあたりの時代に戻った気分。やっぱこうでなくっちゃ!