MacBookを閉じたまま運用するカーネル機能拡張

今まで、InsomniaXをAppleScriptGUIスクリプティング)で操作しようとしたり、kernel.logを監視してスリープ状態を検出したり、カーネル機能拡張の作り方・使い方を調べたりと、試行錯誤を続けていた。その根底には、たった1つの欲求があった。それは...

MacBookのディスプレイが閉じた状態でも、Wake on Demandなネットワークアクセスを可能な状態にしておきたい!*1

そして、実際にアップルのIOKitチュートリアルでサンプルMyDriverを作ってみて、シンプルなカーネル機能拡張だけで、それが実現できそうだと実感した。

...ということで、さっそくClamshellWakeプロジェクト zarigani/ClamshellWake - GitHub の開始。

仕様

  • MacBookでディスプレイを閉じた瞬間のスリープだけを無効にする。
  • ディスプレイを閉じている間は、省エネルギー環境設定にしたがってスリープする。
  • ディスプレイを閉じてスリープ中でも「ネットワークアクセスによってスリープを解除」できる。(省エネルギー環境設定で有効な場合)

つまり、ディスプレイを開いている時とまったく同じ挙動になる。

ログ

  • ClamshellWake.kextは、kernel.logに動作状況を出力する。
Jul 26 04:59:09 zari-MacBook kernel[0]: ClamshellWake: Starting
Jul 26 04:59:09 zari-MacBook kernel[0]: ClamshellWake:   Sending event 0x40
Jul 26 04:59:09 zari-MacBook kernel[0]: ClamshellWake: Clamshell State Changed
Jul 26 05:03:21 zari-MacBook kernel[0]: ClamshellWake: Clamshell State Changed
Jul 26 05:03:21 zari-MacBook kernel[0]: ClamshellWake: kClamshellStateBit set - lid was opened
Jul 26 05:03:21 zari-MacBook kernel[0]: ClamshellWake:   Sending event 0x400
Jul 26 05:03:21 zari-MacBook kernel[0]: ClamshellWake: Clamshell State Changed
Jul 26 05:03:21 zari-MacBook kernel[0]: ClamshellWake: kClamshellStateBit not set - lid was closed 
Jul 26 05:03:21 zari-MacBook kernel[0]: ClamshellWake:   Sending event 0x40
Jul 26 05:03:21 zari-MacBook kernel[0]: ClamshellWake: Clamshell State Changed
...(中略)...
Jul 26 05:31:25 bebe-MacBook kernel[0]: ClamshellWake: Stopping
Jul 26 05:31:25 bebe-MacBook kernel[0]: ClamshellWake:   Sending event 0x82

使い方

ClamshellWake.kextをいちいちコマンドでkextload・kextunloadするのは面倒なので、AppleScriptベースのClamshellWake.appを用意した。

  • 任意の場所にClamshellWake.appをコピーするだけでインストールは完了。(ClamshellWake.appには、ClamshellWake.kextが含まれている)
  • ClamshellWake.appを起動すると、ClamshellWake.kextが有効になる。(kextload)
  • ClamshellWake.appを終了すると、ClamshellWake.kextも無効になる。(kextunload)

ClamshellWake.appのAppleScript部分


property pw : ""
property clamshellwake_path : "/tmp/ClamshellWake.kext"

--起動時にkextloadする
on run
if pw = "" then my save_password() my init_root_wheel() my kextload(clamshellwake_path) display dialog "起動しました。(kextload)" buttons {"OK"} default button "OK" with title "ClamshellWake.kextの状態" with icon note giving up after 3
end run

--Dockアイコンをクリックして管理者パスワードの変更
on reopen
my save_password() end reopen

--終了時にkextunlodする
on quit
if my kextstat() then
if pw = "" then my save_password() my kextunload(clamshellwake_path) end if
display dialog "停止しました。(kextunload)" buttons {"OK"} default button "OK" with title "ClamshellWake.kextの状態" with icon note giving up after 3
tell application "System Events" to keystroke tab using {command down} --素早く終了させるため
continue quit
end quit



on save_password() activate
display dialog "管理者パスワードを入力してください。" default answer "" with hidden answer
set pw to result's text returned
end save_password

on init_root_wheel() try
do shell script "rm -R " & clamshellwake_path password pw with administrator privileges
end try
do shell script "cp -R " & my bundle_path("Resources/ClamshellWake.kext") & " /tmp" password pw with administrator privileges
do shell script "chown -R root:wheel " & clamshellwake_path password pw with administrator privileges
end init_root_wheel

on bundle_path(in_path) (path to me)'s POSIX path & "Contents/" & in_path
end bundle_path

on kextload(kext_path) do shell script "kextload " & kext_path password pw with administrator privileges
end kextload

on kextunload(kext_path) do shell script "kextunload " & kext_path password pw with administrator privileges
end kextunload

on kextstat() try
do shell script "kextstat|grep com.bebekoubou.driver.ClamshellWake"
true
on error
false
end try
end kextstat

未来予想図

  • 現状のMacBookは、このままOSX 10.6 Snow Leopardとして使い続けて、Lionには新しいマシンを用意した方が良さそうな予感。
  • そして、新しいマシンを用意できた暁には、OSX 10.7 Lionを初期化インストールして使い始めたい。
  • 現状のMacBookには、要・不要問わず、とにかくいろんなものがインストールされていて、複雑になり過ぎた。
  • 素のLionの軽快さを体感ながら、時間をかけて必要なモノを少しずつ移行する、段階的な移行を目指したい。


その時、ClamshellWake.kextは、素晴らしい環境を提供してくれそう。

  • ディスプレイを閉じていても、いつでもファイル共有・画面共有できる安心感は大きいのだ。
  • iPadでは面倒な処理も、画面共有でMacBookを操作して処理することもできるのだ。

*1:外部ディスプレイを接続すればOSX標準のクラムシェルモードで試用できるのだけど、外部ディスプレイが接続されていない状況でも同様に使いたいのだ。

*2:OSX 10.6 Snow Leopardでも、十分な機能を発揮できていないのだけど。

*3:出荷時32ビットカーネルのマシンは、Lionでも32ビットカーネルらしい。特集:builder的Lionのみどころ--64ビット化、マルチタッチ、Apple ID - builder