2012年12月4日火曜日

HDL-GS500を、1.0TBに換装して再初期化する。

今まで3回にわたって、HDL-GS500の故障からデータ救出までを書きました。

  1. HDL-GS500が故障。
  2. 壊れたHDDを、Advanced FormatのHDDに交換。
  3. GNU ddrescueを使って、壊れたHDDからデーターを救出。
救出データのバックアップが終わりましたので、今回はHDL-GS500を再初期化しました。
これで1.0TBのHDL-GS500になりました。


再初期化の前にtar2diskを一部修正

データ救出用として暫定修正していたtar2diskを、通常使用できるように修正しました。

  • disk2cyl( )は、データ救出のために500GBに固定していた設定を解除。ディスクのセクター数からモデルを自動識別するように修正。セクターの計算式を見直し、遠回りしていた計算をシンプルにしました。
  • partition( )は、全てのパーティションの開始位置を、アライメント調整した値に修正しました。

修正版tar2disk再初期化用

  1. #!/bin/sh
  2. #
  3. # tar2disk: tar ball をディスクに展開
  4. #
  5. # usage: tar2disk sda
  6. #///// 2012/10/01 sfdiskをシリンダ指定から、セクタ指定へ変更。/////
  7. #///// 2012/11/06 全パーティションのアライメント調整。/////
  8. mnt=./mnt
  9. sddev=/dev/hdb # ##### 初期化する環境に合わせて変更してください #####
  10.  
  11. PATH=$PATH:/sbin
  12.  
  13. #
  14. # 16進->10進変換
  15. #
  16. hex2dec() {
  17. expr 1 + `printf "%d" $1`
  18. }
  19.  
  20. #
  21. # モデルごとの制限セクタ数
  22. #
  23. sector160=`hex2dec 0x12A05FBF`
  24. sector250=`hex2dec 0x1D1A9C7F`
  25. sector300=`hex2dec 0x22ECB57F`
  26. sector320=`hex2dec 0x2540BF7F`
  27. sector400=`hex2dec 0x2E90F73F`
  28. sector500=`hex2dec 0x3A353900`
  29. sector750=`hex2dec 0x574FCD9F`
  30. sector1000=`hex2dec 0x74706DAF`
  31.  
  32. #cyl_end=379 # sda5 の終了セクタ
  33. cyl_end=6088641 #/////シリンダ値をセクタ値に変更/////
  34.  
  35. #
  36. # ディスク名からモデルで丸められたセクタ数を得る
  37. #///// 2012/10/01 セクタ数を返すように修正 /////
  38. #///// 2012/11/06 修復時の500GB固定を解除、計算式最適化。/////
  39. disk2cyl() {
  40. local disk=$1
  41. local sector=`cat /sys/block/$disk/size`
  42. #///// local sector=976566529 /////
  43. if [ $sector -lt $sector160 ]; then
  44. echo -n error
  45. exit 1
  46. elif [ $sector -lt $sector250 ]; then
  47. expr $sector160 - $cyl_end
  48. elif [ $sector -lt $sector300 ]; then
  49. expr $sector250 - $cyl_end
  50. elif [ $sector -lt $sector320 ]; then
  51. expr $sector300 - $cyl_end
  52. elif [ $sector -lt $sector400 ]; then
  53. expr $sector320 - $cyl_end
  54. elif [ $sector -lt $sector500 ]; then
  55. expr $sector400 - $cyl_end
  56. elif [ $sector -lt $sector750 ]; then
  57. expr $sector500 - $cyl_end
  58. elif [ $sector -lt $sector1000 ]; then
  59. expr $sector750 - $cyl_end
  60. else
  61. expr $sector1000 - $cyl_end
  62. fi
  63. return 0
  64. }
  65.  
  66. #
  67. # パーティションを切る
  68. #///// 2012/10/01 シリンダ指定からセクタ指定へ変更 sda6の開始セクタは暫定値/////
  69. #///// 2012/11/06 全パーティションのアライメント調整。/////
  70. partition() {
  71. local disk=$1
  72. local c5=417687 # 26*255*63-2
  73. local cyl=`disk2cyl $disk`
  74. local ext=`expr $cyl + $c5 + 10`
  75.  
  76. dd if=/dev/zero of=/dev/$disk bs=512 count=2 || exit 1
  77. sfdisk -f -uS /dev/$disk <<EOF || exit 1
  78. 2048,626536,L
  79. 628584,833328,L
  80. 1461912,4209032,S
  81. 5670944,$ext,E
  82. 5670952,$c5,L
  83. 6088640,$cyl,L
  84. EOF
  85. }
  86.  
  87.  
  88. #
  89. # format
  90. #///// 2012/10/01 ブロックサイズを4096バイトに変更。/////
  91. format() {
  92. local i=$1
  93.  
  94. if [ $i -eq 1 ]; then
  95. [ $flag_reset -eq 1 ] && return 0
  96. mke2fs -b 4096 -j -m1 $sddev$i || return 1
  97. elif [ $i -eq 2 ]; then
  98. mke2fs -b 4096 -j -m1 $sddev$i || return 1
  99. elif [ $i -eq 5 ]; then
  100. mke2fs -b 4096 -j -N 100000 \
  101. -O dir_index,filetype,sparse_super $sddev$i || return 1
  102. else
  103. [ ! -f /sbin/mkfs.xfs ] && cp -a ${SCRIPT_PATH}/mkfs.xfs /sbin/
  104. mkfs.xfs -f $sddev$i || return 1
  105. fi
  106. return 0
  107. }
  108.  
  109.  
  110. #
  111. # fw_install
  112. #
  113. fw_install() {
  114. touch verify_on_boot
  115. cp -a ../sd?.tgz ../tar2disk ./.landisk/
  116. mkdir ./.landisk/mnt
  117. }
  118.  
  119.  
  120. #
  121. # 初期化後updateの為にflag fileをtouchする
  122. #
  123. set_reset_flag() {
  124. touch ./.landisk/reset_ok
  125. }
  126.  
  127.  
  128. #
  129. # ディスクを 0 クリアする
  130. #
  131. sanitize_disk() {
  132. local i=$1
  133. echo "--- sanitize disk"
  134. dd if=/dev/zero of=$sddev$i bs=1M || return 1
  135. }
  136.  
  137.  
  138. #
  139. # install_logを 作成する
  140. #
  141. set_install_log() {
  142. local end_time
  143. local j
  144. local mac_addr=`/sbin/ifconfig eth0 | sed -n 's/^.*HWaddr \([0-9A-F:]*\)[ ]*$/\1/p'`
  145. local log_dir="$mnt/factory_log"
  146. local install_log="$log_dir/install.log"
  147.  
  148. mount ${sddev}5 $mnt || return 1
  149. if [ ! -d $log_dir ]; then
  150. mkdir $log_dir || return 1
  151. fi
  152. end_time=`date`
  153. echo "Mac Address: $mac_addr" > $install_log
  154. echo "Install Start: $START_TIME" >> $install_log
  155. echo "Install End: $end_time" >> $install_log
  156. for j in 1 2 3 4 5 6 7 8 9 10; do
  157. sync
  158. umount $mnt && break || sleep 1
  159. done
  160. }
  161.  
  162. #
  163. # factorylogの退避
  164. #
  165. bk_factory_log() {
  166. local factory_tgz=$topdir/factory_log.tar.gz
  167. if [ ! -f $factory_tgz ]; then
  168. mount ${sddev}5 $mnt || return 1
  169. tar cpzf $factory_tgz -C $mnt factory_log
  170. umount $mnt
  171. fi
  172. }
  173.  
  174. #
  175. # factorylogの書き戻し
  176. #
  177. restore_factory_log() {
  178. local factory_tgz=$topdir/factory_log.tar.gz
  179. if [ -f $factory_tgz ]; then
  180. tar xpzf $factory_tgz
  181. echo `LANG=C date`: reset_script: >> factory_log/powerlog
  182. rm -f $factory_tgz
  183. fi
  184. }
  185.  
  186.  
  187. #
  188. # smartチェックを行う
  189. #
  190. smart_check() {
  191. local disk=$1
  192. local RESULT_SMARTCTL=0
  193. local RESULT_SMARTCTL_BIT0=0
  194. local RESULT_SMARTCTL_BIT1=0
  195. local RESULT_SMARTCTL_BIT2=0
  196. local RESULT_SMARTCTL_BIT3=0
  197. [ ! -f /usr/sbin/smartctl ] && cp -a ${SCRIPT_PATH}/smartctl /usr/sbin/
  198.  
  199. /usr/sbin/smartctl --smart=on --offlineauto=on --saveauto=on \
  200. /dev/${disk}
  201. /usr/sbin/smartctl -a /dev/${disk}
  202. RESULT_SMARTCTL=$?
  203. RESULT_SMARTCTL_BIT0=$((${RESULT_SMARTCTL} & 1))
  204. RESULT_SMARTCTL_BIT1=$((${RESULT_SMARTCTL} & 2))
  205. RESULT_SMARTCTL_BIT2=$((${RESULT_SMARTCTL} & 4))
  206. RESULT_SMARTCTL_BIT3=$((${RESULT_SMARTCTL} & 8))
  207.  
  208. if [ ${RESULT_SMARTCTL_BIT0} -ne 0 ]; then
  209. echo "*** FAILED TO ENABLE S.M.A.R.T. DISK=${disk} ***"
  210. echo "*** COMMAND LINE PARSE ERROR ***"
  211. return 1
  212. fi
  213. if [ ${RESULT_SMARTCTL_BIT1} -ne 0 ]; then
  214. echo "*** FAILED TO ENABLE S.M.A.R.T. DISK=${disk} ***"
  215. echo "*** DEVICE OPEN FAILED ***"
  216. return 1
  217. fi
  218. if [ ${RESULT_SMARTCTL_BIT2} -ne 0 ]; then
  219. echo "*** FAILED TO ENABLE S.M.A.R.T. DISK=${disk} ***"
  220. echo "*** S.M.A.R.T. COMMAND FAILED ***"
  221. return 1
  222. fi
  223. if [ ${RESULT_SMARTCTL_BIT3} -ne 0 ]; then
  224. echo "*** S.M.A.R.T ERROR DETECTED DISK=${disk} ***"
  225. echo "*** STATUS: DISK FAILING ***"
  226. return 1
  227. fi
  228. return 0
  229. }
  230.  
  231.  
  232. #
  233. # メイン
  234. #
  235. disk=$1
  236. mode=$2
  237. topdir=`pwd`
  238.  
  239. if [ "$disk" = "" ]; then
  240. echo usage: tar2disk sda 1>&2
  241. exit -1
  242. fi
  243.  
  244. if [ "x$mode" == "xreset" ]; then
  245. flag_install=0
  246. flag_reset=1
  247. flag_reset_full=0
  248. elif [ "x$mode" == "xreset_full" ]; then
  249. flag_install=0
  250. flag_reset=1
  251. flag_reset_full=1
  252. else
  253. flag_install=1
  254. flag_reset=0
  255. flag_reset_full=0
  256. fi
  257.  
  258. for i in 1 2 5 6; do
  259. umount $sddev$i
  260. done
  261.  
  262. if [ $flag_install -eq 1 ]; then
  263. smart_check $disk || exit 1
  264. partition $disk
  265. fi
  266.  
  267. mkswap /dev/${disk}3
  268. swapon /dev/${disk}3
  269. trap "swapoff /dev/${disk}3" 0
  270.  
  271. for i in 1 2 5 6; do
  272. cd $topdir
  273. echo --- partitioning $i
  274. [ $i -eq 6 -a $flag_reset_full -eq 1 ] && sanitize_disk $i
  275. [ $i -eq 5 -a $flag_reset -eq 1 ] && bk_factory_log
  276. echo --- format partition
  277. format $i || exit 1
  278. mount $sddev$i $mnt || exit 1
  279.  
  280. echo --- extracting tar ball
  281. cd $mnt || exit 1
  282. tar zxf ../sd$i.tgz || exit 1
  283. [ $i -eq 1 -a $flag_install -eq 1 ] && fw_install
  284. [ $i -eq 1 -a $flag_reset -eq 1 ] && set_reset_flag
  285. [ $i -eq 5 -a $flag_reset -eq 1 ] && restore_factory_log
  286. cd $topdir || exit 1
  287. echo --- unmounting
  288. for j in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
  289. sync
  290. umount $mnt && break || sleep 1
  291. done
  292. [ "$?" -ne 0 ] && exit 1
  293. done
  294.  
  295. [ $flag_install -eq 1 ] && set_install_log
  296. exit 0


作業の準備

バックアップが終わったHDL-GS500からHDDを取り出し、USB-SATA変換アダプタ経由でPCに接続しました。このとき間違いを避けるために、元々PCに搭載しているHDDの接続を取り外しておくと、とても安全に作業できます。

  • はじめる前にtar2diskの9行目は、初期化する環境に合わせて変更が必要です。
  • sddev=/dev/hdb   # ##### 初期化する環境に合わせて変更してください #####
    
  • 初期化するHDDのデバイス・ノードは、dmesgなどで確認します。
    例えば、/dev/sdcなら、9行目をsddev=/dev/sdcに変更します。
  • 再セットアップ用ファイルsd1.tgz, sd2.tgz, sd5.tgz, sd6.tgz, tar2diskが入ったUSBメモリ(1回目のときに保存したもの)は、tar2diskの内容を今回の修正版に変更しておきます。

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の再インストール、アプリケーションのインストール、嵐のようなアップデートと再起動の繰り返し等。余計な用事がいっぱい増えてしまい、今まで手間取っていました。

データの救出にはTestDiskPhotoRecを使いました。ほとんどのデジカメ画像が救出できましたが、長年可愛がってきたExcelファイルを幾つか失いました。 残念 X(

「気をつけよう、眠たい時のPC作業」

0 件のコメント :