Canvio Plus 750GB の FreeBSD ufs をまず復旧2018年04月02日 13時22分29秒

東芝の Canvio Plus 750GB External USB 2.0 Portable Hard Drive が誤動作を起こし始めた。新しいディスクは注文した。fsck の直せない ufs の復旧が第一の課題。

このディスクは ufs と zfs で使っている。zfs は raid-z の一部。こちらには大量の写真や家族の動画が入っている。これは、新しいハードディスクを購入してから、zpool replace で交換する必要があるので、こちらの復旧作業は後回し。

この ufs はホームディレクトリとして利用している一番重要なデータ。こちらは、時おり ufs_copy でディスクをファイルシステム毎バックアップしている。ディスクは何度も移り変わっているが、既に十年、十五年以上前に作ったファイルシステムなので、29GB のみ。作成当時はディスク一台で、全てのファイルが入っていたが、既に写真などの大容量は別途保管して、それこそ日頃のメールやブラウザの履歴などが入っている。zfs のバックアップに週に一度ぐらい気の向いたときにバックアップを取っている。

別の zfs には二、三日前に取ったホームディレクトリのバックアップはある。ただ、税金申告の期限が迫っているので、あれこれ更新していたものがあるので、出来れば故障したディスクから復旧したい。手元を漁ると I-O DATA の HDPS-U に 30GB のスペースがすぐに融通できるのでそれを使う事にした。これは、実家に帰っていた時に、写真が入りきらなくなった時に、譲り受けた機械。父の手書きで、2009 年と日付が書いてある。

ディスクの復旧は recoverdisk。dd よりも優れている。recover_disk はファイルブロックサイズを大きめで始める。エラーがあるとエラー箇所を一度飛ばし、そのままコピーを終端まで終らせる。その後で、ブロックサイズを小さくして、エラーのあった箇所を再試行する。-w オプションを付けると、経過とエラー箇所をファイルに書き出す。

$ recoverdisk -w home.err /dev/label/home.eli /dev/da0s2
最終的に読めなかったブロックは六つぐらい。fsck が先に進めないので、このブロックはシステム情報が管理されているのだろう。その後、壊れたディスクを読み出しのみの mount -r でマウントを試みた。
$ mount -r /dev/label/home.eli /home
これでもマウント出来ない。

このファイルシステムは完全に壊れてしまった様だ。直せないのなら、更に壊しても、新たに失うものは無いので、強制復旧を試みる。そして、ufs のメタデータだったとの推測から、古いディスクイメージからこの故障セクタのみを写すという荒技を試すことにした。

$ mdconfig -a -t vnode -f /mnt/backup/20180301/home.ufs -oreadonly
md1
$ recoverdisk -r home.err /dev/md1 /dev/da0s2
$ fsck_ufs -y /dev/da0s2
$ fsck_ufs -y /dev/da0s2
$ mount -r /dev/da0s2 /home
mdconfig で古いディスクイメージを読み出しのみで設定する。ファイルのままでも処理できるが、間違えた時にダメージを回避するため md デバイスを利用。さっきの recoverdisk に home.err を渡して、破損セクタだけをコピーする。fsck を動かしたら、ファイルシステムを修正したので、再度 fsck を行うように指示された。

この後、mount は成功し、zfs のバックアップを元に復旧度合を確かめた。特にファイルの損失もなく、こちらの方が新しいので、ディスクからの普及には成功したとの結論に至った。

前回次回

東芝の Canvio Plus 750GB が故障した2018年04月01日 14時36分11秒

東芝の Canvio Plus 750GB External USB 2.0 Portable Hard Drive が故障直前の様だ。いきなり FreeBSD が panic を起こした。 fsck を試すと、読めないセクタがある。

東芝の Canvio Connect II を購入したのは 2016年02月18日 となっている。これよりも大分前から使っていたが、購入した時期はまったく覚えていない。私の両親は、電器製品には必ずと言って程購入日を本体に書き込んでいた。子供の頃はなぜそんな事をするのか不思議だったのを思い出した。

現状では、この外付けディスクを繋ぐだけで、cam のエラーが連発する。そのまま五分ぐらいでも放置しておくと安定してくるようで、一旦cam エラーは止まる。

このディスクには ufs と zfs が納められている。fsck がファイルシステムの復旧を出来ないので、ufs は致命的な損傷を受けている模様。zfs は raid-z の一部なのだが、今のところは zfs を壊さないように、ファイルシステムは外してある。

ufs は実は私のホームディレクトリ。取り敢えず、この ufs の復旧は急を要す。また、写真なども多いので、新しい外付けのディスクは注文した。

次回

vm.kmem_size_max が大きすぎても ZFS が動かない2017年12月21日 13時05分20秒

vm.kmem_size_max を大きくしすぎても ZFS が動かないようだ。メモリが 2GB の古い機種の /boot/loader.conf で
vm.kmem_size_max="1024m"
と設定してた。

時おり、以下の様なエラーを出して、操作不能になっていた。この状態になると、ファイルシステム自体にはダメージは無いが、システムの状態がおかしくなり再起動が必要になる。

taskqueue_start_threads: kthread_add(zio_free_issue_6): error 12vm_thread_new: kstack allocation failed
taskqueue_start_threads: kthread_add(zio_free_issue_7): error 12vm_thread_new: kstack allocation failed
kthread_add(zio_free_intr): error 12vm_thread_new: kstack allocation failed
kthread_add(zio_claim_issue): error 12vm_thread_new: kstack allocation failed
kthread_add(zio_claim_intr): error 12vm_thread_new: kstack allocation failed
kthread_add(zio_ioctl_issue): error 12vm_thread_new: kstack allocation failed
taskqueue_start_threads: kthread_add(zio_ioctl_intr): error 12vm_thread_new: kstack allocation failed
そこで、/boot/loader.conf でメモリの割り当てを半分にしてみた。
vm.kmem_size_max="512m"
この後は、もっとたくさんの zpool や zfs を扱える様になって、以前の様に、操作に失敗する事は無くなったようだ。

ただし、以前は 300MB まで増えていた ARC キャッシュが 50MB 前後の利用量に落されているようだ。

badsect を行い、 fsck をかける2017年05月20日 13時21分48秒

折角なので、badsect を試してみる。このファイルシステムは、書き込み用にマウント出来ないので、newfs をした。もしかしたら、-f で強制的に、マウントして試しても良かったのかも知れない。

まず、ディレクトリを作る。そして、badsect にディレクトリ名と fsck にて問題があるとされたセクタを指定する。

# mkdir .BAD
# badsect .BAD 20468153 20468154
Don't forget to run ``fsck /dev/ada0s2e''
初めて使うので知らなかったが、fsck を行うように出た。

折角なので、各種コマンドがどの様にファイルを見つけるか実験。

# find .BAD/
.BAD/
.BAD/20468153
.BAD/20468154
# ls -l .BAD/
ls: 20468153: Bad file descriptor
ls: 20468154: Bad file descriptor
total 0
# file .BAD/*
file: No match.
Don't forget to run ``fsck /dev/ada0s2e''
ls は認識するが、表示形式が他のファイルとは全く違う。find はファイルとして見つけた。file はファイルの存在自体を見つけられていない。

次に fsck をかける。

# fsck_ufs -y /dev/ada0s2e
** /dev/ada0s2e
** Last Mounted on /usr/local
** Phase 1 - Check Blocks and Sizes

HOLD BAD BLOCK? yes

INCORRECT BLOCK COUNT I=1219937 (0 should be 8)
CORRECT? yes


HOLD BAD BLOCK? yes

2558519 DUP I=1219938
UNEXPECTED SOFT UPDATE INCONSISTENCY

INCORRECT BLOCK COUNT I=1219938 (0 should be 8)
CORRECT? yes

INTERNAL ERROR: dups with softupdates
UNEXPECTED SOFT UPDATE INCONSISTENCY
** Phase 1b - Rescan For More DUPS
2558519 DUP I=1219937
UNEXPECTED SOFT UPDATE INCONSISTENCY

** Phase 2 - Check Pathnames
DUP/BAD  I=1219937  OWNER=root MODE=100600
SIZE=4096 MTIME=Jun 16 23:23 2017 
FILE=/.BAD/20468153

UNEXPECTED SOFT UPDATE INCONSISTENCY

REMOVE? yes

DUP/BAD  I=1219938  OWNER=root MODE=100600
SIZE=4096 MTIME=Jun 16 23:23 2017 
FILE=/.BAD/20468154

UNEXPECTED SOFT UPDATE INCONSISTENCY

REMOVE? yes

** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
BAD/DUP FILE I=1219937  OWNER=root MODE=100600
SIZE=4096 MTIME=Jun 16 23:23 2017 
CLEAR? yes

** Phase 5 - Check Cyl groups
FREE BLK COUNT(S) WRONG IN SUPERBLK
SALVAGE? yes

SUMMARY INFORMATION BAD
SALVAGE? yes

BLK(S) MISSING IN BIT MAPS
SALVAGE? yes

282705 files, 2127437 used, 408434 free (66 frags, 51046 blocks, 0.0% fragmentation)

***** FILE SYSTEM MARKED DIRTY *****

***** FILE SYSTEM WAS MODIFIED *****

***** PLEASE RERUN FSCK *****
不良セクタを認識し、特別な処理をしたようだ。この後、また fsck をかけるように出る。
# fsck_ufs -y /dev/ada0s2e
** /dev/ada0s2e
** Last Mounted on /usr/local
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Cyl groups
282705 files, 2127437 used, 408434 free (66 frags, 51046 blocks, 0.0% fragmentation)

***** FILE SYSTEM MARKED CLEAN *****
今度は正常に終了したようだ。

前回

badsect ではマウントできないファイルシステムは回避できない2017年05月19日 17時44分47秒

FreeBSD には badsect という不良セクタを回避するプログラムがある。不良セクタが出ていたので試そうとしたが、今回は無理なケースだった。これはファイルをあらかじめ作成して、以降の利用を防ぐので、ファイルシステムが機能しないと使えない。

fsck を何度かけても、特定の場所で失敗する。

$ fsck_yfs -y /dev/ada0s2e
** /dev/ada0s2e
** Last Mounted on /usr/local
** Phase 1 - Check Blocks and Sizes

CANNOT READ BLK: 20468128
UNEXPECTED SOFT UPDATE INCONSISTENCY

CONTINUE? yes

THE FOLLOWING DISK SECTORS COULD NOT BE READ: 20468153, 20468154,
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Cyl groups
215141 files, 2680121 used, 2396958 free (27470 frags, 296186 blocks, 0.5% fragmentation)

***** FILE SYSTEM STILL DIRTY *****

***** PLEASE RERUN FSCK *****
本来なら、
$ mkdir .BAD
$ badsect .BAD 20468153 20468154
なのだろう。

しかし、かなりのダメージがあるようで、

# mount -onoatime /dev/ada0s2e /mnt/ufs
mount: /dev/ada0s2e: R/W mount of /usr/local denied.
Filesystem is not clean - run fsck.: Operation not permitted
と失敗する。

ここから復帰するには、newfs は避けられない様に見える。

次回

FreeBSD で lockd を後から起動したら mount をやり直す2017年04月24日 21時04分27秒

NFS v3 では、ファイルのロックは NFS 自体の実装では提供されていないので、別途 lockd デーモンを起動する。もし、NFS を
$ sh /etc/rc.d/nfsd onestart
等のように、手動で NFS を起動した場合に、lockd の起動を忘れることがある。

lockd デーモンも同じように起動する。

$ sh /etc/rc.d/nfsd onestart
lockd と nfsd デーモンは独立しているので、片方だけ起動しても自動的には起動しない。

lockd デーモンを起動する前に、既に mount されたファイルシステムには、ファイルロックが有効にはならないようだ。一度、umount して、mount すると、ロックが有効になった。

ZFS を NFS で export する2016年06月03日 12時35分29秒

FreeBSD 上の ZFS を NFS で公開する方法は幾つかあるようだ。zfs share を用いた方法から、/etc/export のみで行う古典的な方法などがある。

一番簡単なのは古典的な方法。/etc/export に UFS と同じように記述する。NFS v3 を用いての記述例。以下の zfs はいわゆる legacy mount 形式を使っている。

$ cat /etc/export
/mnt/zfs -alldirs -network 10.0.0.0/8
$ sh /etc/rc.d/nfsd onestart
/mnt/zfs に zfs がマウントされている。ロックなどが必要でなければ、nfsd のみ起動。
$ mount | grep zfs
zfs on /mnt/zfs (zfs, NFS exported, local, noatime, nfsv4acls)

zpool の修復を試みての結論2016年03月25日 12時36分11秒

ここ数日の間、zpool が破損して resilver を繰り返していたので、復旧を試みていた。

HRS's Web Page の ZFS のトラブル続きは結構古いが、ここが細かな説明などでも相変わらず的を得ていて、参考になる。

UFS では、fsck でかなりの問題は解決できて、それこそ書き込み中のファイルでもない限りは他所への影響は限定的だった。

ZFS では、派手な失敗を犯すと派手に壊れていくようだ。zpool status -v で影響のあったファイルを削除し、エラーが出たディレクトリを別に退避したり、バックアップのあるファイルの削除を行ったりと、回復を試みた。

最終的には、resilier を繰り返すよりも、バックアップをして、zpool を destroy で一度破壊して、再構築した方が早かった。致命的なダメージを与えた zpool は下手に、修復を試みるよりもさっさと諦めて、作り直した方が手っ取り早く、また安全。

七年近く使っていた zpool だったので、プール自体はそのまま保持しようと思ったのと、折角なので zpool を観察してみたかったのもある。そこでの最終結論は上記の通り。派手に壊れた zpool は再構築が一番。

FreeBSD の USB 接続の注意点2016年03月16日 09時22分42秒

FreeBSD で外付けのハードディスクを幾つか使っている。そのなかで起きた問題は大きく分けて三つ。
  1. USB を抜く時に隣の線を動かして、一時的に断線する。
  2. 外付けの電源が抜けてしまい停止する。
  3. USB を抜いた時にバスのスキャンが掛かり、デバイスが一時的に外れてしまう。

最初のは人為的なミス。気を付けはしているが、どうしても避けられない。動作中に機械を動かしたり、接続し直したりするときに間違って起きたり、スイッチが意図に反して切れてしまったりする。

三つ目は抜き差しを繰り返したり、二台、三台と USB 機器を接続していると起きるようだ。必ず起きるわけでは無いが、起きると困るので、ファイルを移動しているときなどは慎重になるようになった。

これらで、ZFS も UFS も落したことがあるが、UFS の方が障害時に安全で被害も少ないのが個人的な印象。ただ、UFS は一デバイスに収まっているので、被害が限定的になりやすいのも事実。UFS は作業中のファイルだけが壊れ、時間こそ掛かるが、fsck でほぼ事足りる。ZFS は柔軟で拡張性も高いが、raidz でも複数のデバイスが一気に落ちると、自動修正の所為で逆に脆いようだ。デバイスが一気に消えて、一部の繋がっているデバイスで更に無理をしようとするので、触っていないファイルまで被害が及んだりする。その後の scrub 等が厄介だ。

個人的な利用の範囲なので、それなりに偏った環境だとは思う。だが、逆にスナップショットや raidz で、複数の履歴を保持しているZFS でこそバックアップをしっかり取っておきたいと思う。

zfs send でスナップショットを一気に送る2016年02月29日 13時33分29秒

zfs send で一気に送ったファイルシステムもあれば、全てのスナップショットを複製したい場合もある。そんな時に使うのが大文字の -I オプション。二つの間にあるスナップショットの全てを一度に移動できる。ただし、これは必ず二つスナップショットを指定しないといけないので、最初のスナップショットは別に送る必要がありそうだ。当該機は、FreeBSD 10.2-RELEASE。

年に一つ、二つ保存しているファイルシステムをこのように送れる。-n を使って、試行。

# zfs send -n -v -I 2010_02_27 zfs/export@2015_11_23
send from @2010_02_27 to zfs/export@2012_07_22 estimated size is 61.2G
send from @2012_07_22 to zfs/export@2013_11_21 estimated size is 15.3G
send from @2013_11_21 to zfs/export@2014_07_20 estimated size is 9.17G
send from @2014_07_20 to zfs/export@2014_11_21 estimated size is 1.71G
send from @2014_11_21 to zfs/export@2015_02_24 estimated size is 2.25G
send from @2015_02_24 to zfs/export@2015_07_20 estimated size is 3.79G
send from @2015_07_20 to zfs/export@2015_11_23 estimated size is 2.44G
total estimated size is 95.8G

実際に送るときは、二段回式。

# zfs send zfs/export@2010_02_27 | zfs receive bkup/export@2010_02_27
# zfs send -I 2010_02_27 zfs/export@2015_11_23 | zfs receive bkup/export
一つ目のコマンドと、二つ目のコマンドでは receive の方の引数が、若干変わる。