TL;DR
xargsでddコマンドを並列に走らせます。
低レベルフォーマットとは
ディスク全体に書き込みを行ってリセットすることです。「ゼロフィリング」とか「物理フォーマット」という呼び方もあるそうです。今回はディスクの全てのビットに0を書き込む方法を使います。
ライブ環境を起動する
isoをコピーしたUSBディスクなどから、ライブ環境を起動します。ループバックデバイスのサイズを見るに、メモリは900MB以上あれば足りそうです。インストールメディアの作り方は下記参照。
ライブ環境が起動したら、とりあえずキーボード配列を変更しておきましょう。
# loadkeys jp106
ディスクを確認します。
# fdisk -l
サイズなどをもとに、初期化するディスクのデバイス名を確認しておきましょう。USBであれば/dev/sda
など、NVMeストレージであれば/dev/nvme0n1
などです。
ちょっとだけbashスクリプトを書く
vimが入っているので、それを使って少しbashスクリプトを書きます。
今回は、次のような低レベルフォーマットを考えましょう。
- デバイス名は
/dev/nvme1n1
- サイズは32GB
- 512bytesのブロックごとに行う
- 8スレッドで並列実行する
# vim low_level_format.sh
of=/dev/nvme1n1
thread=8
disk_size=$((32*(2**30)))
block_size=512
entire_blocks=$((disk_size/block_size))
blocks_per_thread=$((entire_blocks/thread)))
echo {0..$entire_blocks..blocks_per_thread} | \
xargs -n1 | \
xargs -t -P$thread -n1 \
dd if=/dev/zero of=$of bs=$block_size count=$blocks_per_thread seek={}
Linuxはデバイスをファイルとして抽象化しているので、出力はof=/dev/nvme1n1
とします。その後、色々定数を計算します。
echoで出力しているのは、各スレッドが書き込みを始めるブロックが、先頭から何ブロック目か、という値です。
これは空白区切りで出てくるので、1つ目のxargsで行区切りに変換して、2つ目のxargsでddを実行するそれぞれのスレッドにskip
という引数として与えます。
2つ目のxargsのオプションのそれぞれの意味は、次のとおりです。
- -t:実行するコマンドを表示
- -P:並行するスレッド数を指定
- -n:関数に渡す引数の数を指定
並列化で本当に早くなったのか
並列化する前のコマンドと、時間を比較してみます。
# time ( dd if=/dev/zero of=/dev/nvme1n1 bs=512 )
# time ( source low_level_format.sh )
並列化前 | 並列化後 |
---|---|
3分12秒83 | 52秒111 |
確かに、高速になりましたが、8倍とまではいきませんでした。
データの書き込みのボトルネックがCPU側からSSD側に移ったものと考えられます。
この後、1TBのSSDの低レベルフォーマットを同様の方法で並列に行ってみたところ、42分17秒14というタイムでした。意外とすぐ終わりました。
おわりに
かなり熱を持つので、ちゃんとPCを冷やしながら作業をしましょう。
執筆時点では冬で外気温が2℃ほどだったので、窓を開けながら作業していました。寒かったです。