hdidとかhdiutilとかその辺の話 (コマンドラインからディスクイメージをマウント)

Macでは普通にディスクイメージ(isoとか)をダブルクリックすれば自動でマウントされますが、まぁターミナルからそのままマウントしたいということもあると思います。今日、あるダウンロードしたisoイメージをコマンドラインからマウントしようとして、linuxと同じように次のようにしてみました。

$ sudo mkdir /Volumes/hoge
$ mount -o loop -t udf hoge.iso /Volumes/hoge
$ mount: -o loop: option not supported

見てのとおりloopなんてオプションはないと言われてしまいます。最初はえっ、と思いましたが、それもそのはずMac OS Xlinuxじゃないですね。ということで、じゃぁどうすればいいんだろうと思ってmanページを適当に探ってみたところ、macにはディスク関連で以下のようなコマンドがあることが分かりました。

  1. hdid
  2. hdiutil
  3. diskutil
  4. mount
  5. umount

なんかいろいろあって少し混乱したので以下にまとめます。


まず、そもそもディスクイメージがどうやって使えるようになるるかということですが、

For example, when you double-click a disk image in the Mac OS X Finder,two separate things happen. First, the image is "attached" to the
system just like an external drive. Then, the kernel and Disk Arbitration probe the new device for recognized file structures. If any file structures are understood, the associated volumes will mount andappear in the Finder.


(以下拙訳)
例えば、Mac OS XのFinderでイメージディスクをダブルクリックしたとき、2つの独立した出来事が起ります。初めに、イメージはシステムにただ拡張ドライブのようにシステムに「アタッチ」されます。それから、カーネルとディスク仲裁者(いい訳が分りません)がファイルシステムを認識するためにその新しいデバイスを調べます。もし何かファイルシステムが分れば、その関連付けられたボリュームはマウントされ、Finderに現れます。

http://developer.apple.com/Mac/library/documentation/Darwin/Reference/ManPages/man1/hdiutil.1.html

つまり、イメージはまずアタッチされ/dev以下に関連付けられてからマウントされるということです。
mountコマンドとumountコマンドは名前のとおりマウントに関連するものなので、コマンドからイメージをマウントするにはアタッチしなければなりません。これをするのがhdidコマンドです。
hdidの基本的な使い方は、

hdid [options] image

となっていて、実際は、

hdid hoge.img

とするだけでアタッチした上に(Mac OS X 10.3からは)親切にも/Volumes以下にマウントまでしてくれます(もちろん適切なイメージだった場合です)。もしアタッチだけしたい場合(つまり/dev/disk1等にイメージを対応させるだけの場合)は、-nomountオプションをつければokです。-nomountオプションを付けた場合は、mountを使うことでマウントできます。

$ hdid -nomount hoge.img
$ /dev/disk1               <= /dev/disk1にアタッチされた
$ sudo mkdir /Volumes/hoge
$ fstype /dev/disk1
$ udf			             <= ファイルタイプを調べる
$ sudo mount -r -t udf /dev/disk1 /Volumes/hoge

ファイルタイプを調べるのは、後述のdiskutilコマンドを使って、

diskutil info /dev/disk1

としてもできます。ここで、この場合ファイルタイプはudfなので、普通にmountしようとすると、read/writeでマウントしようとするので、

mount_udf: /dev/disk1 on /Volumes/hoge: Permission denied

としてできません(少しはまりました…)。これは-rオプションを付けてread only でマウントすれば大丈夫です。


ですが、hdidコマンドのmanページを見ると次のように書いてあります。

As of Mac OS X 10.4, hdid calls through to hdiutil attach. hdid exists primarily for backwards compatibility. Generally, hdiutil attach should be used nstead of hdid.


(以下拙訳)
Mac OS X 10.4から、hdid は hdiutil attachを呼びます。hdidは主として過去との互換性のために存在します。一般的に、hdiutil attach はhdid の代わりに呼ばれるべきです。

http://developer.apple.com/Mac/library/documentation/Darwin/Reference/ManPages/man8/hdid.8.html#//apple_ref/doc/man/8/hdid

ということで、hdidの代わりにhdiutil attachコマンドを使えと書いてます。このhdiutilコマンドは、ディスクイメージに対するコマンドで、attach,detach,verify,crteae,convert,compact,burnなどさまざまなことができます。hdiutilの基本的な使い方は

hdiutil verb [oprions]

となっていて、

hdiutil attach hoge.iso

とすればさっきのhdidのコマンドと同じ意味になります。hdiutilの方がオプションが多いです。ちなみに、"a poorly-named synonym"として

hdiutil mount hoge.iso

でも同じ意味になります。


さて、次はマウントしたディスクイメージの取り出しについてです。アタッチ、マウント、としたので、取り出しも当然2段階です。アンマウントそれか
ら、デタッチ、という順番になります。まず、普通にumountコマンドを使った場合、アンマウントだけされます。つまり、またmountでマウントすることが可能です。

$ sudo umount /dev/disk1

hdiutilを使うこともできます。

$ hdiutil unmount /dev/disk1

また、diskutilコマンドを使って次のようにすることもできます。

$ diskutil umount /dev/disk1 

このdiskutilコマンドは、ローカルなディスクに対するコマンドで、このアンマウント以外にも、ディスクの検証や修正、修理などができます。この3つのコマンドはどれも同じことをしているようですが、umountのmanページには以下の記述があります。

NOTES
Due to the complex and interwoven nature of Mac OS X, umount may fail often. It is recommended that diskutil(1) (as in, ``diskutil unmount /mnt'') be used instead.


(以下拙訳)
注釈
複雑で織り合わされたMac OS Xの機能のため、umountはしばしば失敗します。 (``diskutil umount /mnt'' のように) diskutil(1) を代わりに使うことを推奨します。

http://developer.apple.com/Mac/library/documentation/Darwin/Reference/ManPages/man8/umount.8.html#//apple_ref/doc/man/8/umount

ということなので、アンマウントにはdiskutil umountを使った方がいいみたいです。次に、デタッチですがこれには2つコマンドがあります。一つは先程のdiskutilを使う方法で、

$ diskutil eject /dev/disk1

とすればできます。ejectということでディスクを取り出している訳ですね。もう一つは、最初の方に出てきたhdiutilを使う方法で、

$ hdiutil detach[eject] /dev/disk1

とすればできます。この場合、アンマウントをした上でデタッチしてくれます。
ということで、結果的にまとめると単にディスクイメージをマウント/アンマウント*1したい場合には

$ hdiutil attach[mount] hoge.iso
$ hdiutil detach[eject] /dev/disk1

みたいにするのが一番楽だと思います(ダブルクリックの方が一般的には簡単かもしれませんw)。
ここでひとついっておくと、hdid,hdiutil,diskutilコマンドには管理者権限は必要ありません。つまりsudoで実行する必要はないです。これについては調べてみましたが、よく分りませんでした。もともと自動マウントするためにシステム起動時に/sbin/autodiskmountが実行されるということなので、それを利用してるのでしょうか?知ってる方いましたら教えてください…

*1:ここでのマウント/アンマウントは単にディスクを利用できる状態にする/しない という意味です