今まで3回にわたって、HDL-GS500の故障からデータ救出までを書きました。
救出データのバックアップが終わりましたので、今回はHDL-GS500を再初期化しました。これで1.0TBのHDL-GS500になりました。
再初期化の前にtar2diskを一部修正
データ救出用として暫定修正していたtar2diskを、通常使用できるように修正しました。
- disk2cyl( )は、データ救出のために500GBに固定していた設定を解除。ディスクのセクター数からモデルを自動識別するように修正。セクターの計算式を見直し、遠回りしていた計算をシンプルにしました。
- partition( )は、全てのパーティションの開始位置を、アライメント調整した値に修正しました。
修正版tar2disk再初期化用
#!/bin/sh # # tar2disk: tar ball をディスクに展開 # # usage: tar2disk sda #///// 2012/10/01 sfdiskをシリンダ指定から、セクタ指定へ変更。///// #///// 2012/11/06 全パーティションのアライメント調整。///// mnt=./mnt sddev=/dev/hdb # ##### 初期化する環境に合わせて変更してください ##### PATH=$PATH:/sbin # # 16進->10進変換 # hex2dec() { expr 1 + `printf "%d" $1` } # # モデルごとの制限セクタ数 # sector160=`hex2dec 0x12A05FBF` sector250=`hex2dec 0x1D1A9C7F` sector300=`hex2dec 0x22ECB57F` sector320=`hex2dec 0x2540BF7F` sector400=`hex2dec 0x2E90F73F` sector500=`hex2dec 0x3A353900` sector750=`hex2dec 0x574FCD9F` sector1000=`hex2dec 0x74706DAF` #cyl_end=379 # sda5 の終了セクタ cyl_end=6088641 #/////シリンダ値をセクタ値に変更///// # # ディスク名からモデルで丸められたセクタ数を得る #///// 2012/10/01 セクタ数を返すように修正 ///// #///// 2012/11/06 修復時の500GB固定を解除、計算式最適化。///// disk2cyl() { local disk=$1 local sector=`cat /sys/block/$disk/size` #///// local sector=976566529 ///// if [ $sector -lt $sector160 ]; then echo -n error exit 1 elif [ $sector -lt $sector250 ]; then expr $sector160 - $cyl_end elif [ $sector -lt $sector300 ]; then expr $sector250 - $cyl_end elif [ $sector -lt $sector320 ]; then expr $sector300 - $cyl_end elif [ $sector -lt $sector400 ]; then expr $sector320 - $cyl_end elif [ $sector -lt $sector500 ]; then expr $sector400 - $cyl_end elif [ $sector -lt $sector750 ]; then expr $sector500 - $cyl_end elif [ $sector -lt $sector1000 ]; then expr $sector750 - $cyl_end else expr $sector1000 - $cyl_end fi return 0 } # # パーティションを切る #///// 2012/10/01 シリンダ指定からセクタ指定へ変更 sda6の開始セクタは暫定値///// #///// 2012/11/06 全パーティションのアライメント調整。///// partition() { local disk=$1 local c5=417687 # 26*255*63-2 local cyl=`disk2cyl $disk` local ext=`expr $cyl + $c5 + 10` dd if=/dev/zero of=/dev/$disk bs=512 count=2 || exit 1 sfdisk -f -uS /dev/$disk <<EOF || exit 1 2048,626536,L 628584,833328,L 1461912,4209032,S 5670944,$ext,E 5670952,$c5,L 6088640,$cyl,L EOF } # # format #///// 2012/10/01 ブロックサイズを4096バイトに変更。///// format() { local i=$1 if [ $i -eq 1 ]; then [ $flag_reset -eq 1 ] && return 0 mke2fs -b 4096 -j -m1 $sddev$i || return 1 elif [ $i -eq 2 ]; then mke2fs -b 4096 -j -m1 $sddev$i || return 1 elif [ $i -eq 5 ]; then mke2fs -b 4096 -j -N 100000 \ -O dir_index,filetype,sparse_super $sddev$i || return 1 else [ ! -f /sbin/mkfs.xfs ] && cp -a ${SCRIPT_PATH}/mkfs.xfs /sbin/ mkfs.xfs -f $sddev$i || return 1 fi return 0 } # # fw_install # fw_install() { touch verify_on_boot cp -a ../sd?.tgz ../tar2disk ./.landisk/ mkdir ./.landisk/mnt } # # 初期化後updateの為にflag fileをtouchする # set_reset_flag() { touch ./.landisk/reset_ok } # # ディスクを 0 クリアする # sanitize_disk() { local i=$1 echo "--- sanitize disk" dd if=/dev/zero of=$sddev$i bs=1M || return 1 } # # install_logを 作成する # set_install_log() { local end_time local j local mac_addr=`/sbin/ifconfig eth0 | sed -n 's/^.*HWaddr \([0-9A-F:]*\)[ ]*$/\1/p'` local log_dir="$mnt/factory_log" local install_log="$log_dir/install.log" mount ${sddev}5 $mnt || return 1 if [ ! -d $log_dir ]; then mkdir $log_dir || return 1 fi end_time=`date` echo "Mac Address: $mac_addr" > $install_log echo "Install Start: $START_TIME" >> $install_log echo "Install End: $end_time" >> $install_log for j in 1 2 3 4 5 6 7 8 9 10; do sync umount $mnt && break || sleep 1 done } # # factorylogの退避 # bk_factory_log() { local factory_tgz=$topdir/factory_log.tar.gz if [ ! -f $factory_tgz ]; then mount ${sddev}5 $mnt || return 1 tar cpzf $factory_tgz -C $mnt factory_log umount $mnt fi } # # factorylogの書き戻し # restore_factory_log() { local factory_tgz=$topdir/factory_log.tar.gz if [ -f $factory_tgz ]; then tar xpzf $factory_tgz echo `LANG=C date`: reset_script: >> factory_log/powerlog rm -f $factory_tgz fi } # # smartチェックを行う # smart_check() { local disk=$1 local RESULT_SMARTCTL=0 local RESULT_SMARTCTL_BIT0=0 local RESULT_SMARTCTL_BIT1=0 local RESULT_SMARTCTL_BIT2=0 local RESULT_SMARTCTL_BIT3=0 [ ! -f /usr/sbin/smartctl ] && cp -a ${SCRIPT_PATH}/smartctl /usr/sbin/ /usr/sbin/smartctl --smart=on --offlineauto=on --saveauto=on \ /dev/${disk} /usr/sbin/smartctl -a /dev/${disk} RESULT_SMARTCTL=$? RESULT_SMARTCTL_BIT0=$((${RESULT_SMARTCTL} & 1)) RESULT_SMARTCTL_BIT1=$((${RESULT_SMARTCTL} & 2)) RESULT_SMARTCTL_BIT2=$((${RESULT_SMARTCTL} & 4)) RESULT_SMARTCTL_BIT3=$((${RESULT_SMARTCTL} & 8)) if [ ${RESULT_SMARTCTL_BIT0} -ne 0 ]; then echo "*** FAILED TO ENABLE S.M.A.R.T. DISK=${disk} ***" echo "*** COMMAND LINE PARSE ERROR ***" return 1 fi if [ ${RESULT_SMARTCTL_BIT1} -ne 0 ]; then echo "*** FAILED TO ENABLE S.M.A.R.T. DISK=${disk} ***" echo "*** DEVICE OPEN FAILED ***" return 1 fi if [ ${RESULT_SMARTCTL_BIT2} -ne 0 ]; then echo "*** FAILED TO ENABLE S.M.A.R.T. DISK=${disk} ***" echo "*** S.M.A.R.T. COMMAND FAILED ***" return 1 fi if [ ${RESULT_SMARTCTL_BIT3} -ne 0 ]; then echo "*** S.M.A.R.T ERROR DETECTED DISK=${disk} ***" echo "*** STATUS: DISK FAILING ***" return 1 fi return 0 } # # メイン # disk=$1 mode=$2 topdir=`pwd` if [ "$disk" = "" ]; then echo usage: tar2disk sda 1>&2 exit -1 fi if [ "x$mode" == "xreset" ]; then flag_install=0 flag_reset=1 flag_reset_full=0 elif [ "x$mode" == "xreset_full" ]; then flag_install=0 flag_reset=1 flag_reset_full=1 else flag_install=1 flag_reset=0 flag_reset_full=0 fi for i in 1 2 5 6; do umount $sddev$i done if [ $flag_install -eq 1 ]; then smart_check $disk || exit 1 partition $disk fi mkswap /dev/${disk}3 swapon /dev/${disk}3 trap "swapoff /dev/${disk}3" 0 for i in 1 2 5 6; do cd $topdir echo --- partitioning $i [ $i -eq 6 -a $flag_reset_full -eq 1 ] && sanitize_disk $i [ $i -eq 5 -a $flag_reset -eq 1 ] && bk_factory_log echo --- format partition format $i || exit 1 mount $sddev$i $mnt || exit 1 echo --- extracting tar ball cd $mnt || exit 1 tar zxf ../sd$i.tgz || exit 1 [ $i -eq 1 -a $flag_install -eq 1 ] && fw_install [ $i -eq 1 -a $flag_reset -eq 1 ] && set_reset_flag [ $i -eq 5 -a $flag_reset -eq 1 ] && restore_factory_log cd $topdir || exit 1 echo --- unmounting for j in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do sync umount $mnt && break || sleep 1 done [ "$?" -ne 0 ] && exit 1 done [ $flag_install -eq 1 ] && set_install_log exit 0
作業の準備
バックアップが終わったHDL-GS500からHDDを取り出し、USB-SATA変換アダプタ経由でPCに接続しました。このとき間違いを避けるために、元々PCに搭載しているHDDの接続を取り外しておくと、とても安全に作業できます。
- はじめる前にtar2diskの9行目は、初期化する環境に合わせて変更が必要です。
sddev=/dev/hdb # ##### 初期化する環境に合わせて変更してください #####
例えば、/dev/sdcなら、9行目をsddev=/dev/sdcに変更します。
HDDの再初期化
knoppix DVDを起動して端末を立ち上げsu -でrootになります。
最初の状態として、
/dev/sdcには、再初期化するHDDが /dev/sddには、USBメモリが接続されている状態とします。
USBメモリを、マウントポイントを作成してマウントします。
# mkdir /media/usb # mount /dev/sdd1 /media/usb
USBメモリのtar2diskを実行します。
# cd /media/usb/hdd1/.landisk # ./tar2disk sdcこれでHDDが初期化されます。
シリアルコンソールから、sfdiskした結果です。HDDのセクターサイズをtar2diskが自動認識して、計算どおり1.0TBでパーティショニングできました。
# sfdisk -uS -l /dev/hdb Disk /dev/hdb: 121601 cylinders, 255 heads, 63 sectors/track Warning: extended partition does not start at a cylinder boundary. DOS and Linux will interpret the contents differently. Units = sectors of 512 bytes, counting from 0 Device Boot Start End #sectors Id System /dev/hdb1 2048 628583 626536 83 Linux /dev/hdb2 628584 1461911 833328 83 Linux /dev/hdb3 1461912 5670943 4209032 82 Linux swap / Solaris /dev/hdb4 5670944 1953525167 1947854224 5 Extended /dev/hdb5 5670952 6088638 417687 83 Linux /dev/hdb6 6088640 1953525166 1947436527 83 Linux
再初期化後にHDDに書き込まれたtar2diskは、9行目の修正部分を元のsddev=/dev/hdbに戻しておきます。HDL-GS500の内部から見たHDDのデバイス・ノードは/dev/hdbになっています。
sddev=/dev/hdb # ##### 初期化する環境に合わせて変更してください #####この作業を忘れると、Webメニューのシステム初期化を実行する場合に失敗します。
再初期化したHDDでは、第1パーティション(今回の状態ならsdc1)の.landiskディレクトリが、tar2diskの保存場所です。
作業完了
修正後にHDL-GS500を再組立すると作業完了です。
HDL-GS500の、1.0TB化が完了しました。
tar2diskのオプションについて
Webメニューのシステム初期化では、tar2diskに以下のオプションをつけて実行しているようです。
通常の初期化を行う場合
# ./tar2disk hdb reset
内蔵HDDの完全消去を行う場合は
# ./tar2disk hdb reset_full
最後に今回のトラブル談
HDL-GS500のトラブルが解決した後、作業用PCにトラブル発生。
..
その日の夜、言いようのない睡魔に襲われながら、再初期化の作業を始めていました。
エラーを出して途中で止まるtar2disk。
「何でやろぅ?おかしいなぁ…」
あまりにも眠たくて、考えようとしても全く頭が働かない。
何度も深い眠りの淵に引き込まれそうになりながら、作業を続けようとしていました。
「もうあかん、今日は無理や…」
とうとう睡魔に勝てず、その夜の作業は諦めて早々に寝ることに。
翌日の夕食後、おもむろに作業を再開。
原因を探るために、前日の作業ログを、以前のログと見比べる。
「何故だかpartitioning 1のinodesの数値が大きい?
Superblock backups stored on blocks:のブロックも多い???」
嫌な予感が…
--- partitioning 1 --- format partition mke2fs 1.42.2 (9-Apr-2012) Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 6561792 inodes, 26216064 blocks 262160 blocks (1.00%) reserved for the super user First data block=0 Maximum filesystem blocks=0 801 block groups 32768 blocks per group, 32768 fragments per group 8192 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872 Allocating group tables: done Writing inode tables: done Creating journal (32768 blocks): done Writing superblocks and filesystem accounting information: done --- extracting tar ball --- unmounting --- partitioning 2 --- format partition mke2fs 1.42.2 (9-Apr-2012) mke2fs: Device size reported to be zero. Invalid partition specified, or partition table wasn't reread after running fdisk, due to a modified partition being busy and in use. You may need to reboot to re-read your partition table.
tar2diskを見直して、ようやく原因に気づく。
「えぇ~っ、」
「やってしもた~」
諦めの妖精と、執着の妖精たちが、頭の中で踊りだしていました。
少し時間をおいてから、昨晩の様子を思い返すと。
作業PCのHDDを取り外さずに、USB-SATA変換アダプタ経由で、再初期化用のHDDをPCに接続していました。
そして、9行目の修正を忘れて、前の作業のときに設定していたsdaのままで実行。
sddev=/dev/sda # ##### 初期化する環境に合わせて変更してください #####
つまり、USB-HDDではなく作業用PC のCドライブに書き込んでいたのです。
シェルスクリプトは、指示されたとおりにCドライブをext3でフォーマット後、tarボールを展開していました。その結果、作業PC のCドライブを飛ばしてしまったのでした。
「Windowsが立ち上がらない。困った!」
もう後の祭りです。
ほとんどのファイルは、別ドライブにバックアップを取ったつもりでしたが。マイドキュメントのバックアップが、あまり出来ていなかったことがわかりました。
そのため、データ救出、WindowsXPの再インストール、アプリケーションのインストール、嵐のようなアップデートと再起動の繰り返し等。余計な用事がいっぱい増えてしまい、今まで手間取っていました。データの救出にはTestDiskとPhotoRecを使いました。ほとんどのデジカメ画像が救出できましたが、長年可愛がってきたExcelファイルを幾つか失いました。 残念 X(
0 件のコメント :
コメントを投稿