(ノートPCで)「べつにサスペンドできなくてもいいや」みたいなことを 書いたばかりだが、翻ってできちゃってわーいな話。
NetBSDユーザとしては、できないのがずっと当たり前だったので、 サスペンドとか別になくてもいいじゃんと思い続けること20年余。 ちょうど、Type-Cが長いこと使えなくても、MicroSDみたいな外部補助記憶が 使えなくても別になんとも思ってこなかったiPhoneユーザに近いか。
サスペンドできた。
sysctl -w hw.acpi.sleep.state=3
でよい。
「ThinkPadならできるよ」 と書いてあったので念の為試したらx280ではできちゃった。ポイントがいくつか。
外付けのUSBデバイスとかあるとカーネルにサスペンドを拒否される。 これは分かるのだが、RAIDframeも該当した。 NetBSDではzpoolデバイスに RAIDframe を指定して使っているので、今回も /dev/raid28d で zpoolを作って使っていたが、サスペンドできない!
NetBSDのZFSだとデバイス名がずれたときに自動認識してくれないので 少し不安だが、デバイス接続順を変えて試したところ zpool import -f プール名 と明示的に指定するとインポートできるようなのでRAIDframe経由せずに 再構築した。
manやWeb情報をみると /etc/apm のしたにスクリプトを作るといいよってのが まだ残っていて騙されてしまったが、もうapmdないものね。powerdですよ。
/etc/powerd/scripts/ を見ると、スクリプトが置いてあるので調整。
後者について、えっと、「スリープボタンてどこよ?」
ThinkPad X280のキーボードには刻印ないっす。探したら、 「ThinkPadをキーボードでスリープ状態にする」がみつかり、 [Fn]+[4$] で行けるとわかった。そこで sleep_button スクリプトを修正。
--- sleep_button.orig 2017-07-13 22:51:15.000000000 +0900 +++ sleep_button 2024-08-27 12:46:37.806733805 +0900 @@ -11,7 +11,24 @@ case "${2}" in pressed) if /sbin/sysctl -q hw.acpi.sleep.state; then + ncons=`wsconscfg -g` + wsconscfg -s 1 + sleep 1 /sbin/sysctl -w hw.acpi.sleep.state=3 + ################### + if=iwm0 + PATH=/usr/local/bin/DT:$PATH + #ifconfig $if down up + #/etc/rc.d/wpa_supplicant restart + ### echo "$@" > /tmp/args.powerd + repeat=10 + while [ $((--repeat)) -gt 0 ]; do + sleep 2 + ifconfig $if | grep -q 'status: active' && break + done + wsconscfg -s $ncons + svc -t /service/*vpn* + ################### elif /sbin/sysctl -q machdep.xen.suspend; then /sbin/sysctl -w machdep.xen.suspend=1 else
もともとある hw.acpi.sleep.state=3 の前後に、 仮想コンソールの切り替えと復帰とWi-Fiが戻ったらVPNもつなぎ直すのを入れた。
これでばっちり。
おまけ。
OpenBSDではバッテリ情報を sysctl 変数から取る必要があったので いちいち面倒でこんな表示が出るスクリプトを作って使っていた。
battery
AC Offline: Battery remaining 66.0%
Discharging at 7.89(31.61/47.77) - 4h00m to go
NetBSDだと envstat(8) で情報が出るが、逆に情報量多すぎて見づらいし、 残り時間を知りたい。てことで、OpenBSDで使っていたbatteryスクリプトを NetBSDにも対応。コチラどうぞ。
#!/bin/sh case `uname` in OpenBSD) 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 } ;; NetBSD) curstat=`envstat` getval() { case $1 in lastfull) echo "$curstat"|awk '/last full cap:/{print $4}' ;; remain) echo "$curstat"|awk '/charge:/{print $2}' ;; rate) echo "$curstat"|awk '/rate:.*[0-9]/{print $3}' ;; power) echo "$curstat"|awk '/connected:/{print $2}' ;; esac } ;; esac for v in remain lastfull rate power; do eval $v=`getval $v` done # echo $remain $lastfull $rate $power percent=`echo "100*$remain/$lastfull"|bc -l|cut -d. -f1` case $rate in 0.0*|"") rate=0 ;; esac case $power in Off|FALSE) 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|TRUE) 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 # hw.sensors.acpibat0.volt0=11.40 VDC (voltage) # hw.sensors.acpibat0.volt1=11.75 VDC (current voltage) # hw.sensors.acpibat0.power0=6.59 W (rate) # hw.sensors.acpibat0.watthour0=46.74 Wh (last full capacity) # hw.sensors.acpibat0.watthour1=2.34 Wh (warning capacity) # hw.sensors.acpibat0.watthour2=0.20 Wh (low capacity) # hw.sensors.acpibat0.watthour3=30.78 Wh (remaining capacity), OK # hw.sensors.acpibat0.watthour4=48.10 Wh (design capacity) # hw.sensors.acpibat0.raw0=1 (battery discharging), OK # hw.sensors.acpibat0.raw1=24 (discharge cycles)
電源をつないだときの表示はこんな感じ。
battery
AC ONline: Battery remaining 63.0%
Rate 40.926 to 17.220 (30.550/47.770) - 0h25m to full