SPARC Solarisでx86 HDDを使う †最近USB接続のマスストレージデバイスが増えてきており、非常に便利である。 x86 Solarisの場合は、USB機器の接続/切り離しさえきちんと行なえば、 通常のSCSI HDDと同様に扱うことができて問題は少ない。 しかし、SPARC Solarisではそれほど簡単ではないのでなんとかしよう、という話。 USBデバイスの操作方法 †本題に入る前に、USB接続のストレージデバイスの扱い方について。 USB接続のHDDエンクロージャ・FLASHメモリ・デジカメ・メモリカードリーダ等は USBマスストレージデバイスのドライバであるsca2usbaドライバが割り付けられる。 sca2usbaドライバによってこれらのデバイスはSCSIデバイスとほぼ同様に扱うことができる。 USBマスストレージデバイスが挿入されているかは、cfgadmコマンドで確認することができる。 cfgadm -c disconnectを実行するとデバイスの切断操作が実施され、 安全にUSBプラグから抜くことができるようになる。 切断操作は行なったが物理的にはまだ抜いていない場合に再度システムに挿入状態を認識させるには、 cfgadm -c configureを実行する。 間違えてデバイスを抜いてしまった場合、運がよければ再度挿入することでシステムに認識される。 もしダメなら、cfgadm -c disconnectして強制的に切断操作を行なわなければならないが、 本当に運が悪いとリブート以外には直らない場合もあるようだ。 用語 †ここでちょっと用語の整理
ここからわかるように、MBRはx86の用語、ディスクラベルはUNIXの用語である。
以上はSPARC Solaris用のデバイスドライバである。いずれもディスクラベルを理解できるが、MBRは理解できない。
以上はx86 Solaris用のデバイスドライバである。いずれもMBRを理解でき、またfdiskパーティション内にあるディスクラベルを理解できる。 また、これらのドライバは一切ファイルシステムを理解しない。 しかし逆にpcfsファイルシステムドライバは(たとえSPARC Solaris用のpcfsドライバであっても)MBRを理解することができる。 x86 Solarisでのパーティション命名規則 †x86 Solarisでは、cmdkドライバまたはsdドライバによって認識されるパーティションは /dev/r?dsk/cNdNpNまたは/dev/r?dsk/cNdNsNという名前が付けられる。 p0はディスク全体を表す。MBRはHDD先頭にあるから、 PC用のATA HDDではp0の先頭にMBRがあることになる。 p1,p2,..はfdiskパーティションを表す。 fdiskパーティションはブートセクタから始まる一連の領域を指す。 Solaris用のfdiskパーティションの場合、 ブートセクタの次にさらにディスクラベルが格納されている。 s0,s1,..は、Solaris用のfdiskパーティションが存在し、 かつディスクラベルがある場合に、 そのディスクラベルによって定義される領域(=スライス)を指す。 s0がrootファイルシステムが入っているスライス、 s1がswapスライス、s2がディスク全体を表すのがUNIXの慣習である。 ただし、リムーバブルデバイスについては、 ディスクラベルが存在していない場合、 s0およびs2がディスク全体を表すスライスとなる。 通常はSolaris用のfdiskパーティション内の領域がスライスとなるが、 s2スライスだけは例外でHDD全体を指す。 16個までのスライスを定義でき、/export/homeなどのスライスはs8以降に配置される。 SPARC Solarisでのパーティション命名規則 †s0,s1,..はHDD先頭にディスクラベルが存在する場合に、 そのディスクラベルによって定義されるパーティション(=スライス)を表す。 ただし、リムーバブルデバイスについては、 ディスクラベルが存在していない場合、 s0およびs2がディスク全体を表すスライスとなる。 通常はSolaris用のfdiskパーティション内の領域がスライスとなるが、 s2スライスだけは例外でHDD全体を指す。 8個までのスライスを定義でき、/export/homeなどのスライスはs6以降に配置される。 SPARC Solarisでfdiskパーティションを扱えない理由 †パーティション命名規則を比較してみると、 SPARC SolarisはHDDについてはディスクラベルによるパーティション認識しかできないことがわかる (パーティションテーブルが作成されていなければ、ディスク全体をあらわすスライスすら定義されない)。 このため、PC用のHDDをSPARC Solarisに接続すると、 HDD先頭にディスクラベルがない(代わりにMBRがある)ため いっさいのスライスが定義されず、 "Corrupt label; wrong magic number"とエラーが表示される。 これでも一応デバイスファイルは作成されているが、アクセスすると結局I/O Errorになってしまう。 このため、SPARC Solarisのpcfsドライバ自体はMBRを理解できるにも関わらず、 sd/dadドライバの制約によりPC用のHDDに入っているFAT領域を マウントすることができない。 (なお、FLASHメモリやその他のリムーバブルデバイスについては s0およびs2経由でディスク全体にアクセスできる。 この場合は問題なくFAT領域をマウントできる)。 なので、PCに接続していたHDD(やかつてのMO)をSPARC Solarisに接続する際は 「とりあえずformatしてパーティション切りなおし、 んでもってufsでnewfs」がお約束であった。 ディスクラベルとMBRの同居 †ならば、「MBRとしてもディスクラベルとしても通用するデータ」を HDDの先頭セクタに書いてしまえば、 MBRを期待しているx86 SolarisやWindowsといったOSも、 ディスクラベルを期待しているSPARC Solarisも、 同様にそのHDDを使えることになる。 問題はそういうデータが本当に作れるかだが、実は以下の条件下で可能である。
USB接続のストレージデバイスなら、これらはさほど大きな制約ではないだろう。 以降にその手順を示す。 手順 †おおまかな手順は、
である。バックアップ必須。 1, Windowsで区画作成&論理フォーマット ストレージデバイスをWindowsに接続し、Windows9x系ならfdisk+format、 2000系ならディスクアドミニストレータで区画作成&論理フォーマットする。 まっさらの状態から基本領域を1つだけ定義し、FATで論理フォーマットするのが肝である。 2, MBRのバックアップ この状態でのfdiskパーティションの確認と、MBRのバックアップを行う。 ストレージデバイスの先頭セクタにアクセスする手段が必要なので、 それ用のツールないしx86 SolarisやLinuxが必要である。 (この時にCHSパラメータを調べておくとあとで役に立つ) x86 Solarisの例(966*2580=2492280セクタ長の基本領域にFAT32を作成) # fdisk /dev/rdsk/c1t0d0p0
Total disk size is 969 cylinders
Cylinder size is 2580 (512 byte) blocks
Cylinders
Partition Status Type Start End Length %
========= ====== ============ ===== === ====== ===
1 Win95 FAT32 0 965 966 100
# dd count=1 < /dev/rdsk/c1t0d0p0 > mbr.dos
# cfgadm -c disconnect usb0/1
3, ディスクラベルの書き込み 今度はSPARC Solarisに接続し、formatコマンドでディスクラベルを書き込む。 ディスクラベルに情報を埋め込むため、 CHSパラメータを要求される場合があるかもしれない。 # format format> partition partition> print Current partition table (original): Total disk cylinders available: 2479 + 2 (reserved cylinders) Part Tag Flag Cylinders Size Blocks 0 root wm 0 - 130 64.48MB (131/0/0) 132048 1 swap wu 131 - 391 128.46MB (261/0/0) 263088 2 backup wu 0 - 2478 1.19GB (2479/0/0) 2498832 3 unassigned wm 0 0 (0/0/0) 0 4 unassigned wm 0 0 (0/0/0) 0 5 unassigned wm 0 0 (0/0/0) 0 6 usr wm 392 - 2478 1.00GB (2087/0/0) 2103696 7 unassigned wm 0 0 (0/0/0) 0 partition> label partition> quit format> currrent Current Disk = c2t0d0 <temp cyl 2479 alt 2 hd 16 sec 63> /pci@1f,0/usb@c,3/storage@1/disk@0,0 format> quit ここでの肝は、ディスク全体を示す"backup"というタグがついたスライスが Part=2に作成されるようにすることである。 (といっても自動的にこうなるので、特に気にする必要もない)。 partiotionサブコマンドのprintサブコマンドで提示された パーティションテーブルを確認し、"label"サブコマンドにてディスクラベルを書き込んでやる。 5, ディスクラベルのバックアップ ディスクラベルを変更したのでいったんシステムから論理的に切り離し、 その後再接続できることを確認し、またディスクラベルのバックアップを行なう # cfgadm -y -c disconnect usb0/1 # cfgadm -c configure usb0/1 # dd count=1 < /dev/rdsk/c2t0d0s2 > mbr.dkl 6, 新しい先頭セクタをでっち上げる MBRとディスクラベルが同居したデータを作る。
# perl dklabel.pl mbr.dlk mbr.dos 7, 先頭セクタに書き込む # dd count=1 < mbr.new > /dev/rdsk/c2t0d0s2 # cfgadm -y -c disconnect usb0/1 # cfgadm -c configure usb0/1 ディスクラベルを変更したのでいったんシステムから論理的に切り離す。 ディスクラベルが有効で、VTOCが正しく含まれているかprtvtocコマンドで確認する。 ディスク全体を表すスライスはs2からs1に変更されている点は注意。 # prtvtoc /dev/rdsk/c2t0d0s1
* Dimensions:
* 512 bytes/sector
* 63 sectors/track
* 16 tracks/cylinder
* 1008 sectors/cylinder
* 2481 cylinders
* 2479 accessible cylinders
(中略)
* First Sector Last
* Partition Tag Flags Sector Count Sector Mount Directory
1 5 01 0 2498832 2498831
3 2 00 0 132048 132047
また、MBRも有効で、fdiskパーティションが正しく表現できているか fdiskコマンドで確認する(fdiskコマンドはSPARC Solarisにも入っている)。 # fdisk /dev/rdsk/c2t0d0s1
Total disk size is 2479 cylinders
Cylinder size is 1008 (512 byte) blocks
Cylinders
Partition Status Type Start End Length %
========= ====== ============ ===== === ====== ===
1 Win95 FAT32 0 2470 2471 100
シリンダサイズとか開始/終了シリンダ番号がさっきと違う気がするが、 今どきの大容量HDDならLBAを使っているはずなので、 多分ディスクジオメトリを元にLBAから逆算した結果なのだろう。 8, SPARC Solarisでpcfsのマウント くどいようだが、新しいディスクラベルではs1スライスがHDD全体を表す。 # mount -F pcfs /dev/dsk/c2t0d0s1:c /mnt # ls /mnt 9, x86 Solarisでpcfsのマウント x86 Solarisでは依然p0がディスク全体を表す。 # mount -F pcfs /dev/dsk/c2t0d0p0:c /mnt # ls /mnt |