web-dev-qa-db-ja.com

sysfsを介してトランスポートを識別できますか?

スクリプトを書いていますが、特定のブロックデバイスの トランスポートクラス (fc-「ファイバーチャネル」、scsi、iscsiなど)を識別できるようにすることに興味があります。この情報はRHELのls -l /dev/disk/by-pathを介して取得できますが、可能であれば(移植性など、さまざまな理由で)sysfsにクエリを実行したいと思います。例えば:

[root@localhost sde]# ls -l /dev/disk/by-path
total 0
lrwxrwxrwx 1 root root  9 Jul 21 16:39 pci-0000:01:00.0-scsi-0:2:0:0 -> ../../sda
lrwxrwxrwx 1 root root 10 Jul 21 16:39 pci-0000:01:00.0-scsi-0:2:0:0-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 Jul 21 16:39 pci-0000:01:00.0-scsi-0:2:0:0-part2 -> ../../sda2
lrwxrwxrwx 1 root root 10 Jul 21 16:39 pci-0000:01:00.0-scsi-0:2:0:0-part3 -> ../../sda3
lrwxrwxrwx 1 root root  9 Jul 21 16:39 pci-0000:01:00.0-scsi-0:2:1:0 -> ../../sdb
lrwxrwxrwx 1 root root 10 Jul 21 16:39 pci-0000:01:00.0-scsi-0:2:1:0-part1 -> ../../sdb1
lrwxrwxrwx 1 root root  9 Jul 21 16:39 pci-0000:01:00.0-scsi-0:2:2:0 -> ../../sdc
lrwxrwxrwx 1 root root 10 Jul 21 16:39 pci-0000:01:00.0-scsi-0:2:2:0-part1 -> ../../sdc1
lrwxrwxrwx 1 root root  9 Jul 21 16:39 pci-0000:1a:00.0-fc-0x500601663ee0025f:0x0000000000000000 -> ../../sdd
lrwxrwxrwx 1 root root  9 Jul 21 16:39 pci-0000:1a:00.0-fc-0x500601663ee0025f:0x0015000000000000 -> ../../sde
lrwxrwxrwx 1 root root  9 Jul 21 16:39 pci-0000:1a:00.0-fc-0x5006016e3ee0025f:0x0000000000000000 -> ../../sdf
lrwxrwxrwx 1 root root  9 Jul 21 16:39 pci-0000:1a:00.0-fc-0x5006016e3ee0025f:0x0015000000000000 -> ../../sdg
lrwxrwxrwx 1 root root  9 Jul 21 16:39 pci-0000:1a:00.1-fc-0x500601653ee0025f:0x0000000000000000 -> ../../sdj
lrwxrwxrwx 1 root root  9 Jul 21 16:39 pci-0000:1a:00.1-fc-0x500601653ee0025f:0x0015000000000000 -> ../../sdk
lrwxrwxrwx 1 root root  9 Jul 21 16:39 pci-0000:1a:00.1-fc-0x5006016d3ee0025f:0x0000000000000000 -> ../../sdh
lrwxrwxrwx 1 root root  9 Jul 21 16:39 pci-0000:1a:00.1-fc-0x5006016d3ee0025f:0x0015000000000000 -> ../../sdi

しかし、/sys/block/sdeを見ると、特に役立つものは何も見つかりません。

[root@localhost sde]# ls -l /sys/block/sde
total 0
-r--r--r-- 1 root root 4096 Oct 14 16:51 dev
lrwxrwxrwx 1 root root    0 Oct 14 16:51 device -> ../../devices/pci0000:00/0000:00:07.0/0000:1a:00.0/Host5/rport-5:0-2/target5:0:0/5:0:0:21
drwxr-xr-x 2 root root    0 Jul 21 12:39 holders
drwxr-xr-x 3 root root    0 Jul 21 12:39 queue
-r--r--r-- 1 root root 4096 Oct 14 16:51 range
-r--r--r-- 1 root root 4096 Oct 14 16:51 removable
-r--r--r-- 1 root root 4096 Oct 14 16:51 size
drwxr-xr-x 2 root root    0 Jul 21 12:39 slaves
-r--r--r-- 1 root root 4096 Oct 14 16:51 stat
lrwxrwxrwx 1 root root    0 Oct 14 16:51 subsystem -> ../../block
--w------- 1 root root 4096 Oct 14 16:51 uevent

たとえそれが私を正しい方向に押しやるだけであっても、どんな助けでもありがたいです。私の理想的な解決策は、onlysysfsデータを使用することです。

5
Bratchley

より良い答えが得られない限り、これを解決策として取り上げます。これは非常に間接的ですが、機能しているように見えます。基本的に、私はudevd/dev/disk/by-pathのパスを作成できたという事実から判断しました、それはsysfsになければなりません私の知る限り、udevが実際に行うのはそれだけです。sysfs情報を取得し、それを利用して構成済みのアクションを実行します。

調べてみると、これらのリンクは、ID_PATHbashスクリプトによって設定された/lib/udev/id_path変数の内容によって作成されているように見えます。その中に、特定のブロックデバイスのソースコントローラーのsysfsエントリのすぐ下にあるさまざまなディレクトリの存在をチェックすることによってトランスポートを決定する方法を基本的にレイアウトするcaseステートメントを見つけました。

                    */rport-[0-9]*:[0-9]*-[0-9]*/*)
                            handle_fc "$D"
                            ;;
                    */end_device-[0-9]*:[0-9]*:[0-9]*/*)
                            handle_sas "$D"
                            ;;
                    */fw-Host[0-9]*/*)
                            handle_firewire "$D"
                            ;;
                    */session[0-9]*/*)
                            handle_iscsi "$D"
                            D=
                            ;;
                    */Host[0-9]*/[0-9]*:[0-9]*:[0-9]*:[0-9]*)
                            handle_scsi "$D"
                            ;;
                    */usb[0-9]*/[0-9]*/*)
                            handle_usb "$D"
                            ;;
                    */pci[0-9]*:[0-9]*)
                            handle_pci "$D"
                            ;;
                    */serio[0-9]*)
                            handle_serio "$D"
                            ;;
                    */platform/*)
                            handle_platform "$D"
                            ;;
                    */devices)
                            D=
                            ;;

ファイバーチャネルテストを複製してコマンドラインでこれをテストしたところ、肯定的な結果が得られました。

## INTERNAL DRIVE:
[root@localhost sde]# ls -ld /sys/block/sda/device/../../../rport* 2>/dev/null | wc -l
0

## FIBRE CHANNEL BLOCK DEVICE:
[root@localhost sde]# ls -ld /sys/block/sde/device/../../../rport* 2>/dev/null | wc -l
4

基本的に、デバイスの短い名前(sda、sdb、sdeなど)を取得し、物理デバイスを入力してから、ブロックデバイスのソースコントローラーに到達するまで..を入力します。コントローラのsysfsエントリに直接の子としてrport*ディレクトリがある場合、それはブロックデバイスがファイバチャネル経由で着信していることを意味します。

これは、iscsiの最初のスイッチケース(*/rport-[0-9]*:[0-9]*-[0-9]*/*))のチェックを複製するだけです。また、コントローラーで「session [0-9]」ディレクトリを探すことで、成功を複製することもできました。

[root@files2 ~]# ls -ld /sys/block/sda/device/../../../session[0-9]
drwxr-xr-x. 6 root root 0 Oct 15 13:50 /sys/block/sda/device/../../../session1
[root@files2 ~]#

私のスクリプトはPythonで記述されますが、これらのディレクトリをチェックするだけで十分なようです。先に進み、これをソリューションとしてマークします(とにかく許可されたら)。

3
Bratchley

私のFedora19システム以外でこれをテストするシステムはありませんが、これは始まりかもしれません:

$ ls -l /sys/block/sda/subsystem/sda
lrwxrwxrwx. 1 root root 0 Oct 14 21:41 /sys/block/sda/subsystem/sda -> ../../devices/pci0000:00/0000:00:1f.2/ata1/Host0/target0:0:0/0:0:0:0/block/sda/

私のシステムには/dev/disk/by-pathがないことに注意するのも興味深いです。

1
rickhg12hs