ページ

2012-12-23

Linux boxにUSBストレージを接続したとき勝手に同期するようにする

同期とはなんだか難しそうだと思ったあなた!正しいと思います。

そんな「同期」ですが、今日の話は難しくありません。
簡単に書くと、udevデーモンにデバイス固有の設定を入れて、つないだときにrsyncを走らせましょうという話です。

必要なもの

  • 適当なLinux box(今回はDebian squeeze)
  • 適当なUSB storage
今回はSheevaPlugとKobo gloを利用。
udevは若干変わっているので、最近のUbuntuでも大丈夫だと思うが、RHEL(特に5)だとちょっとわからない。
ただし、GNOMEが動いていたりすると、そっちで勝手にマウントされそうなので、無効にしておいたほうがいいかも。

デバイスを特定する

つないだら、まずは普通にdmesgコマンドでログを見るか、fdisk -lでデバイスを調べる。
今回のkoboはsdaとして認識された。
(このSheevaPlugはルートがSDカードだからmmcblk0なのだけど、sdaがシステムになっているデバイスが多いと思うので、この下のコマンド達をパスまでコピペしないよう注意。)

/dev/sdaがデバイスだとわかったので、devadmコマンドのinfo -q path -n /dev/XXXを使って、sysfsでのパスを特定する。
$ sudo udevadm info -q path -n /dev/sda
/devices/platform/orion-ehci.0/usb1/1-1/1-1:1.0/host11/target11:0:0/11:0:0:0/block/sda

そうしたら、udevadmコマンドのinfo -p [パス] -aを使って、デバイスに関する情報を表示する。
(もちろん、この2つのコマンドは$()とかを使って1行で実行してもよい)
$ sudo udevadm info -p /devices/platform/orion-ehci.0/usb1/1-1/1-1:1.0/host11/target11:0:0/11:0:0:0/block/sda -a

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/platform/orion-ehci.0/usb1/1-1/1-1:1.0/host11/target11:0:0/11:0:0:0/block/sda':
    KERNEL=="sda"
    SUBSYSTEM=="block"
(略)
  looking at parent device '/devices/platform/orion-ehci.0/usb1/1-1':
    KERNELS=="1-1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}=="Self-powered"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="c0"
    ATTRS{bMaxPower}=="  2mA"
    ATTRS{urbnum}=="229"
    ATTRS{idVendor}=="2237"
    ATTRS{idProduct}=="4173"
    ATTRS{bcdDevice}=="0110"
    ATTRS{bDeviceClass}=="00"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{speed}=="480"
    ATTRS{busnum}=="1"
    ATTRS{devnum}=="13"
    ATTRS{version}==" 2.00"
    ATTRS{maxchild}=="0"
    ATTRS{quirks}=="0x0"
    ATTRS{authorized}=="1"
    ATTRS{manufacturer}=="Kobo"
    ATTRS{product}=="eReader"
    ATTRS{serial}=="XXXXXXXXXXXXX"
(略)

  looking at parent device '/devices/platform/orion-ehci.0':
    KERNELS=="orion-ehci.0"
    SUBSYSTEMS=="platform"
    DRIVERS=="orion-ehci"
    ATTRS{modalias}=="platform:orion-ehci"

  looking at parent device '/devices/platform':
    KERNELS=="platform"
    SUBSYSTEMS==""
    DRIVERS==""
重要なのは「ATTRS{serial}」というところ。これをキーにデバイスを決定する。
ただし、万が一でも誤爆しないよう念の為「ATTRS{manufacturer}」と「ATTRS{product}=="eReader"」も使うことにした。なので、今回使う情報は以下。
  • ATTRS{manufacturer}=="Kobo"
  • ATTRS{product}=="eReader"
  • ATTRS{serial}=="XXXXXXXXXXXXX"

同じ種類のデバイスをひとつしか持っていないときは、USBデバイスの種類を特定するかぎである「ATTRS{idVendor}」「ATTRS{idProduct}」
を使ってもよいと思う。

udevの設定をする(1) - デバイスに名前をつける

まずは、調べた情報を使って、/dev以下に勝手なシンボリックリンクを置く。今回はkoboなので/dev/kobo。

/etc/udev/rules.dに以下のように設定ファイルを配置すればOK。

/etc/udev/rules.d/92-kobo.rules
KERNEL=="sd*", ACTION=="add", \
  ATTRS{manufacturer}=="Kobo", ATTRS{product}=="eReader", \
  ATTRS{serial}=="XXXXXXXXXXXXX" \
  NAME="%k", SYMLINK="kobo"

あとは、デバイスをつなぐと、/dev/koboが作られる。
$ ls -l /dev/kobo /dev/sda
lrwxrwxrwx 1 root root      3 Dec 23 18:19 /dev/kobo -> sda
brw-rw---- 1 root floppy 8, 0 Dec 23 18:19 /dev/sda

udevadmのman pageを見ると「The udev daemon detects changes automatically」って書いてあるけど、もし認識しなかったら以下のコマンドを叩いてみるといいかも。
$ sudo udevadm control --reload-rules

fstabの設定

/dev/koboがつながったときに、マウントできるようにする。

まずマウントするためのディレクトリを作る。
$ sudo mkdir /media/kobo

koboの内部ストレージは、パーティションなしでデバイスまるまるマウントすればいいので、以下のような行を
/etc/fstabに追加する。

/dev/kobo        /media/kobo     vfat   rw,codepage=932,iocharset=utf8 0 0

マウントできることを確かめる。
$ sudo mount /media/kobo
$ df -h

ディスク容量が表示されたら、umountしてデバイスを外す(本当は切り離しもやったほうがいいんだろうけど…)
$ sudo umount /media/kobo

自動同期するスクリプトを用意する

マウントしてrsyncし、アンマウントしてメールを送るだけの簡単なスクリプトを用意して、
/usr/local/bin/synckobo.shに配置する。


デバイスをつないで、マウントされてない状態で、スクリプトを叩いて同期できたらOK.
見慣れない"--modify-window=1"については、「rsync FAQ」を参照。vfatならつけておくのが幸せだと思う。

udevの設定をする(2) - 接続時にスクリプトを実行する

さきほど作った設定ファイルに「RUN」を追加する。

KERNEL=="sd*", ACTION=="add", \
  ATTRS{manufacturer}=="Kobo", ATTRS{product}=="eReader", \
  ATTRS{serial}=="XXXXXXXXXXXXX" \
  NAME="%k", SYMLINK="kobo", \
  RUN="/usr/local/bin/synckobo.sh"

接続して同期されれば成功!

0 件のコメント:

コメントを投稿