udevのルールの書き方を整理してみたお話。

目標

私のパソコン(MBP)には、Arch Linuxが入っています。MBPのモニタのバックライトは、/sys/class/backlight/gmux_backlight/brightnessに値を書き込むと変更できます。ですが、rootでないと書き換えができません。こんな不便なことはないですよね?なら書き込めるようにしちゃいましょうか。

方針

udevでモニタが認識されたときに権限を書き換えてやれば良さそうですね。ですが、パーミッションを666にするのはあまり頭が良くないので、所有者をroot:adminに設定して、パーミッションを664に設定していきます。

udevルールの書き方

この節はあまり見やすくないと思います。

これは、サンプルのudevルールです。

KERNEL=="hdb", NAME="my_spare_disk"

udevルールの記述は、マッチングのルールを設定する部分とそのマッチングしたものに対する処理を連ねて書きます。またルールの部分には正規表現が使えます。

マッチングルールには、KERNEL(デバイスカーネル名でマッチングを行う)とSUBSYSTEM(サブシステム名でマッチングを行う), DRIVER(デバイスに用いられるドライバの名前でマッチングを行う), ATTR{params}(sysfsのparamsというattributesでマッチングを行う)という4種類のルールがあります。また、マッチングする親の子供を選びたいときには、KERNELS, SUBSYSTEMS, DRIVERS, ATTRSというルールもあります。

また、処理には、NAME(/devに格納される時の名前), SYMLINK(/devに格納される時の別名), OWNER, GROUP, MODE, RUNなどがあります。カーネルでの名前は%kで、連番は%nで取得することができます。

手順

1. 変更したいデバイスを特定する

KERNELやSUBSYSTEMに適切な値を入れれば、そのデバイスの情報を書き換えることができることがわかりました。が、どんな値を入れればいいのでしょうか?ここで、udevadm infoというコマンドを使って調べます。

% udevadm info -a -p /sys/class/backlight/gmux_backlight 

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/pnp0/00:03/backlight/gmux_backlight':
    KERNEL=="gmux_backlight"
    SUBSYSTEM=="backlight"
    DRIVER==""
    ATTR{actual_brightness}=="200"
    ATTR{bl_power}=="0"
    ATTR{brightness}=="200"
    ATTR{max_brightness}=="1023"
    ATTR{type}=="platform"

  looking at parent device '/devices/pnp0/00:03':
    KERNELS=="00:03"
    SUBSYSTEMS=="pnp"
    DRIVERS=="apple-gmux"
    ATTRS{id}=="APP000b"
    ATTRS{options}==""

  looking at parent device '/devices/pnp0':
    KERNELS=="pnp0"
    SUBSYSTEMS==""
    DRIVERS==""

looking at device '/devices/pnp0/00:03/backlight/gmux_backlight'の部分を見ると、 KERNEL=="gmux_backlight", SUBSYSTEM=="backlight"という情報が得られましたね。また、KERNELS=="00:03", SUBSYSTEMS=="pnp", DRIVERS=="apple-gmux", ATTRS{id}=="APP000b"という情報も使えます。

2. ルールを書く

先程調べた情報を元に、こんなルールを書きます(/etc/udev/rules.d/20-backlight.rulesとして保存した)。

KERNEL=="gmux_backlight", SUBSYSTEM=="backlight", \
    KERNELS=="00:03", SUBSYSTEMS=="pnp", DRIVERS=="apple-gmux", ATTRS{id}=="APP000b", \
    RUN+="/etc/udev/scripts/set-backlight-permission.sh"

/etc/udev/scripts/set-backlight-perssion.shは、以下のような内容になっています。

#!/bin/sh

mkdir /tmp/test

chgrp admin /sys/class/backlight/gmux_backlight/brightness
chmod 0664 /sys/class/backlight/gmux_backlight/brightness

chgrp admin /sys/class/backlight/gmux_backlight/actual_brightness
chmod 0664 /sys/class/backlight/gmux_backlight/actual_brightness

chgrp admin /sys/class/backlight/gmux_backlight/max_brightness
chmod 0664 /sys/class/backlight/gmux_backlight/max_brightness

3. 再起動する

これで再起動すると、brightnessがadminグループのユーザからいじれるようになっているはずです。

参考