メッセージ欄

2008年4月の日記

一覧で表示する

今日のボク
2008/04/10(木) 22:15 今日のボク はてブ情報 はてブに登録 はてブ数

今日も雨で大変です。

でも、朝はすんなり起きたんです。えらい。

今日は音楽の授業があって、学校で習った歌を聴かせてくれました。

disklabelの不思議 (3) scsictl
2008/04/09(水) 28:26 NetBSD はてブ情報 はてブに登録 はてブ数

ddなどでディスクをつぶしてon-diskなラベルとin-coreなラベルに齟齬が発生した場合に、USB経由のディスクならば一度抜いて再度挿せばon-diskとin-coreの整合性がとれるという話の続きです。

抜き差しなんてしなくてもscsictlで同じことができるよ、というのをIRCで教えてもらいました。

具体的にはscsictlのdetach, scanを使います。

まずは、on-disk, in-coreで齟齬が発生した状況を作ります。
eeepc# dd if=/dev/zero of=/dev/rsd1d count=1
1+0 records in
1+0 records out
512 bytes transferred in 0.001 secs (512000 bytes/sec)
eeepc# disklabel -r sd1
disklabel: could not read existing label
eeepc# disklabel sd1                        
# /dev/rsd1d:
中略
4 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 a:  31388609        63     4.2BSD      0     0     0  # (Cyl.      0*-  15326*)
 c:  31388609        63     unused      0     0        # (Cyl.      0*-  15326*)
 d:  31388672         0     unused      0     0        # (Cyl.      0 -  15326*)
eeepc#
on-diskはラベルがなく、in-coreは古いラベルを表示しています。

dmesgでみると
sd1 at scsibus1 target 0 lun 0: <Generic, USB SD Reader, 1.00> disk removable
となっていますのでscsictlに与えるdeviceはscsibus1, targetは0, lunは0だとわかります。
eeepc# scsictl /dev/scsibus1 detach 0 0
sd1 detached
sd1が切り離されました。それではdisklabel sd1はどうでしょうか?
eeepc# disklabel sd1
disklabel: /dev/rsd1d: Device not configured
当然、デバイスがないので失敗します。

再度sd1を使えるようにscsictlのscanを実行します。
eeepc# scsictl /dev/scsibus1 scan 0 0  
sd1 at scsibus1 target 0 lun 0: <Generic, USB SD Reader, 1.00> disk removable
sd1: fabricating a geometry
sd1: 15326 MB, 15326 cyl, 64 head, 32 sec, 512 bytes/sect x 31388672 sectors
sd1: fabricating a geometry
sd1がattachされたようなのでdisklabelを見ます。
eeepc# disklabel sd1                   
# /dev/rsd1d:
中略
4 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 a:  31388672         0     4.2BSD      0     0     0  # (Cyl.      0 -  15326*)
 d:  31388672         0     unused      0     0        # (Cyl.      0 -  15326*)
disklabel: boot block size 0
disklabel: super block size 0
ddでつぶされてon-diskなラベルがないため、fictitiousなin-coreラベルが作られました。

なるほど、抜き差し不要でラベルの同期ができるscsictlコマンドは覚えておいて損はないですね。

なお、sd1は次のようなデバイス階層で接続されていました。
mainbus0 (root)
  pci0 at mainbus0 bus 0: configuration mode 1
    ehci0 at pci0 dev 29 function 7: Intel 82801FB/FR USB EHCI Controller (rev. 0x04)
      usb4 at ehci0: USB revision 2.0
        uhub4 at usb4
          umass1 at uhub4 port 3 configuration 1 interface 0
            scsibus1 at umass1: 2 targets, 3 luns per target
              sd1 at scsibus1 target 0 lun 0: <Generic, USB SD Reader, 1.00> disk removable

今日のボク
2008/04/09(水) 20:59 今日のボク はてブ情報 はてブに登録 はてブ数

今日は自由帳と学童の連絡帳を忘れて帰ってきましたよ。

毎日何かを忘れて帰ってくるね。

明日から授業だそうです。

disklabelの不思議 (2) fictitious
2008/04/09(水) 8:31 NetBSD はてブ情報 はてブに登録 はてブ数

藤原さんから
label: fictitious
っていう行が(これは良きにはからったものだよ)という意味になっているかどうか、つまり本当に、「良きにはからった時」だけに表示されるかが気になるのですが、自分では実はまだ確めたことがないのです。
というコメントをいただいたので試してみました。

まず、ddでMBRとラベルをつぶし(dd if=/dev/zero of=/dev/rsd1d bs=512k count=10)、fdisk, disklabel -rで確認します。
eeepc# fdisk sd1
fdisk: primary partition table invalid, no magic in sector 0
fdisk: Cannot determine the number of heads
Disk: /dev/rsd1d
NetBSD disklabel disk geometry:
cylinders: 31, heads: 64, sectors/track: 32 (2048 sectors/cylinder)
total sectors: 64000

BIOS disk geometry:
cylinders: 31, heads: 64, sectors/track: 32 (2048 sectors/cylinder)
total sectors: 64000

Partition table:
0: <UNUSED>
1: <UNUSED>
2: <UNUSED>
3: <UNUSED>
Bootselector disabled.
No active partition.
eeepc#
eeepc# disklabel -r sd1
disklabel: could not read existing label
eeepc#
たしかにon-diskなラベルはありませんね。では、in-coreラベルを作ってもらい、それを表示してもらいましょう。
eeepc# disklabel sd1
# /dev/rsd1d:
type: SCSI
disk: ClipDrive       
label: fictitious
flags: removable
bytes/sector: 512
sectors/track: 32
tracks/cylinder: 64
sectors/cylinder: 2048
cylinders: 31
total sectors: 64000
rpm: 3600
interleave: 1
trackskew: 0
cylinderskew: 0
headswitch: 0           # microseconds
track-to-track seek: 0  # microseconds
drivedata: 0 

4 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 a:     64000         0     4.2BSD      0     0     0  # (Cyl.      0 -     31*)
 d:     64000         0     unused      0     0        # (Cyl.      0 -     31*)
disklabel: boot block size 0
disklabel: super block size 0
eeepc#
おぉ、labelにfictitiousが表示されてます。

それでは、このラベルをon-diskに書いてしまい、disklabel -rで確認してみます。
eeepc# disklabel -i -I sd1
partition> P
4 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 a:     64000         0     4.2BSD      0     0     0  # (Cyl.      0 -     31*)
 d:     64000         0     unused      0     0        # (Cyl.      0 -     31*)
partition> W
Label disk [n]? y
Label written
partition> Q
eeepc#
eeepc# disklabel -r sd1   
# /dev/rsd1d:
type: SCSI
disk: ClipDrive       
label: fictitious
flags: removable
bytes/sector: 512
sectors/track: 32
tracks/cylinder: 64
sectors/cylinder: 2048
cylinders: 31
total sectors: 64000
rpm: 3600
interleave: 1
trackskew: 0
cylinderskew: 0
headswitch: 0           # microseconds
track-to-track seek: 0  # microseconds
drivedata: 0 

4 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 a:     64000         0     4.2BSD      0     0     0  # (Cyl.      0 -     31*)
 d:     64000         0     unused      0     0        # (Cyl.      0 -     31*)
eeepc#
あれ? on-diskラベルでもfictitiousって表示されます。

あぁ、そうでした。label: factitousっていうのをそのままラベルとして書いてしまったので当然on-diskにもその文字列が書き込まれてしまったのですね (sd1はUSBメモリですが、抜き差ししても同じ表示)。

じゃぁ、disklabel -eでlabelを空文字列にしてみると、って試してみたら、on-diskでもin-coreでも空文字列が表示されます。当たり前か。

つまり、disklabelがfictitiousを表示するのはon-diskなラベルが存在しないときだけ、それ以外のときにはon-diskなラベルに書かれたlabelに相当する文字列をそのまま表示する (on-diskにfictitiousって文字列が入っていればそれを表示する)、ということのようです。

利用する上ではdisklabelを書くときにはlabel: fictitiousをそのままにしない (たとえば日付などを入れる) 習慣をつけておくと、後から役に立つかもなぁ、と思いました。

1: makoto fujiwara 『その文字をそのままにしておくと、書いてしまう、なんて思っても見ませんでした。良く分りましたね。すごい。というか書くときに fic...』 (2008/04/09 16:25)

disklabelの不思議
2008/04/08(火) 26:06 NetBSD はてブ情報 はてブに登録 はてブ数

Eee PCで16GBのSDHCカードにNetBSDをインストールしようかと思い、色々試していました。

SDHCカードはUSBのリーダライタ経由で接続し、/dev/sd1として見えていました。

買った状態でのfdisk sd1の結果はこんな感じ。
Disk: /dev/rsd1d
NetBSD disklabel disk geometry:
cylinders: 15326, heads: 64, sectors/track: 32 (2048 sectors/cylinder)
total sectors: 31388672

BIOS disk geometry:
cylinders: 1023, heads: 255, sectors/track: 63 (16065 sectors/cylinder)
total sectors: 31388672

Partition table:
0: Primary DOS with 32 bit FAT - LBA (sysid 12)
    start 8192, size 31380480 (15323 MB, Cyls 0/130/3-1953/217/56)
1: <UNUSED>
2: <UNUSED>
3: <UNUSED>
No active partition.
で、disklabel sd1の結果はこんな感じ。
# /dev/rsd1d:
type: SCSI
disk: USB SD Reader   
label: fictitious
flags: removable
bytes/sector: 512
sectors/track: 32
tracks/cylinder: 64
sectors/cylinder: 2048
cylinders: 15326
total sectors: 31388672
rpm: 3600
interleave: 1
trackskew: 0
cylinderskew: 0
headswitch: 0           # microseconds
track-to-track seek: 0  # microseconds
drivedata: 0 

5 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 d:  31388672         0     unused      0     0        # (Cyl.      0 -  15326*)
 e:  31380480      8192      MSDOS                     # (Cyl.      4 -  15326*)
つまり、fdiskでMS-DOSのパーティションが切ってあって、disklabelでそれが反映された格好になっているわけですね。

その後、fdiskでsysid=169 (つまりNetBSD) のパーティションを切って、disklabelを書いたり、いろいろしていたわけです。

色々試した後、もう一度きれいな状態からやってみたくなり、
# dd if=/dev/zero of=/dev/rsd1d bs=512k count=100
てな感じで、マスターブートレコード (MBR) はもちろん、NetBSDパーティションの先頭もつぶしたつもりになっていました。なにしろ50MBほどゼロでつぶしたので、間違いないだろうと。

fdiskしてみると、たしかにすべてのパーティションがUNUSEDになっています。

ところが、disklabel sd1とやると消したはずのディスクラベルが残っています。本来なら、消えているはずなのに。man disklabelしてみると、次のような記述があります。
On systems that expect to have disks with MBR partitions (see fdisk(8)) disklabel will find, and update if requested, labels in the first 8k of type 169 (NetBSD) MBR labels and within the first 8k of the physical disk. On other systems disklabel will only look at the start of the disk. The offset at which the labels are written is also system dependent.
これは、i386のようなMBRがあるようなシステムでは、disklabelはNetBSDパーティションの先頭8kか物理ディスクの先頭8kを探しますってことで、つまりディスクの先頭かパーティションの先頭にラベルが書かれるわけですよね。

さすがに50MBもつぶせばラベルは消えているはず、と考えて間違いなさそうです。

IRCで困ったと叫んでいるとsdだとそうなったことがあるという話を聞いたり、disklabelのmanを読んでいたり、そういやin-coreとかon-diskとかあったような、などと考えつつ、なんとなくUSBのリーダライタを抜き差しして、再度disklabelを叩いてみました。

すると、さっきとは違う表示です。つまり、古いdisklabelではなく、fdiskの内容を反映した結果が表示されました。その後、あれこれやりつつdisklabel -r sd1とdisklabel sd1の結果の違いに気づいてきました。

その結果、in-core disklabelはkernel内で持っているラベル、on-disk disklabelは物理ディスクに書き込まれているラベル、である前提で考えて、次のように整理できるのではないかと思います。
  • in-core, on-diskは同期していない状態が発生しうる
    • 例えば、on-diskに書かれたラベルをkernelが読み込んでin-coreラベルを形成した後、ddなどでon-diskなラベルがつぶされた場合、disklabel -r sd1は"disklabel: could not read existing label"という結果を返すが、disklabel sd1は直前のdisklabelを表示する
  • in-coreの表示は、良きに計らった表示にしてくれることがある
    • 例えば、買ったばかりのSDHCカードはon-diskなラベルが当然存在せずfdisk的にMS-DOSなパーティションが切ってあるだけだが、disklabel sd1とin-coreなラベルを表示させるとfdiskの情報を反映したラベルが表示される (冒頭のdisklabelの結果がそれ)
    • 例えば、ddで先頭をつぶしてfdisk的にもon-diskラベル的にも何の情報もない状態でdisklabel sd1とやると無理矢理4.2BSDのパーティションがあるかのようなin-coreラベルを表示する(次のような)
    • 良きに計らった表示をしてくれるのはin-coreラベルを最初に作ったときだけで、いったんin-coreなラベルができた後にfdiskなどでパーティションを切ったとしてもその情報はin-coreラベルに自動的には反映されない
# /dev/rsd1d:
type: SCSI
中略
4 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 a:  31388672         0     4.2BSD      0     0     0  # (Cyl.      0 -  15326*)
 d:  31388672         0     unused      0     0        # (Cyl.      0 -  15326*)
disklabel: boot block size 0
disklabel: super block size 0
という感じであってますかね?

1: makoto fujiwara 『label: fictitiousっていう行が(これは良きにはからったものだよ)という意味になっているかどうか、つまり本当に、「...』 (2008/04/09 5:48)

2: Hiroshi Tokuda 『fictitiousの意味を初めて知りました。ということで、disklabelの挙動を調べて今日の日記に書きました。』 (2008/04/09 8:50)