2015年4月18日土曜日

partedでext3ファイルシステムとパーティションを縮めたかった、、、

既存のext3ファイルシステムを消さずに縮め、空いた領域を別のLVMの既存論理ボリュームに追加したい。

ふとした理由で、そう思った。もちろん王道はフルバックアップ、パーティション切り直し、リストアだけど、そうしたくなかったので、データはそのまま、Linuxの既存パーティションとファイルシステムを縮めて、空いた領域に新しいパーティションを切りたかった。そして、そいつを既存の別領域のLVMに流し込めるから。
とりあえず、練習のために、Virtual Box上のCentOS 5.11に、仮想HDD(hdb) 10GBを追加して、そこに適当にパーティションを切って、LVMの論理ボリュームも作成して、適当にゴミデータをダミーで置いて、適当にマウントして、準備完了。
以下、dfの出力。(hdbだけ抜粋。)

Filesystem           1K-ブロック    使用   使用可 使用% マウント位置
/dev/hdb1             4806124   2158884   2403104  48% /mnt_test1
/dev/hdb2               961192     690312     222052  76% /mnt_test2
/dev/mapper/VolGroup01-LogVol02
                             3096336   1415636   1523416  49% /mnt_test3
/dev/mapper/VolGroup01-LogVol03
                              1455376   707700      673744  52% /mnt_test4

練習のダミー環境として、

hdb1  ext3 5GB
hdb2  ext3 1GB
LVMのLogVol02 ext3 3GB
LVMのLogVol03 ext3 1.5GBぐらい残り全部

を置いて、ここから「hdb1を減らして空いたところに、hdb3パーティションを作成し、そいつをLogVo102に継ぎ足す」というのを練習としてやろうとした。

もちろん、ポイントは「既存パーティション/dev/hdb1の縮小」。それが出来た後の、
・LVMの既存ボリュームグループVolGroup01への/dev/hdb3の追加(vgextendコマンド)、
・既存論理ボリュームLogVol02の拡張(lvextendコマンド)、
・そしてLVM上の既存ファイルシステム(ext3)の拡張(resize2fsコマンド)
の手順は、検索すればあちこちに載ってたので、以降、記載は省略。

でも、ここからが長かった。

【注意】こちらに記載の手順を参考に作業をされて、ご使用のシステムに何か起こっても全く保証できませんので、そこはご承知おきください。

ファイルシステムとパーティションの縮小が同時に出来るGNU parted

と、ネットに書いてあった。ファイルシステムの縮小は、resize2fs、パーティション縮小はfdiskでもできるような記載もあったが、fdiskの確からしい情報がなかなか見つからない。また、fdiskはgptのディスクに対応していないと言う。そういう中で、partedの記載が数点見つかったので、これでやってみることにした。RedHatのサイトにも載ってたので。

手元のCentOS5.11にrpmとしてインストールされていたのは、GNU Parted 1.8.1。こいつで、やってみた。

=================================
$parted /dev/hdb1
GNU Parted 1.8.1
/dev/hdb を使用
GNU Parted へようこそ! コマンド一覧を見るには 'help' と入力してください。
                                                                         
(parted) p
モデル: VBOX HARDDISK (ide)
ディスク /dev/hdb: 10.7GB
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: gpt
番号  開始    終了    サイズ  ファイルシステム  名前     フラグ
 1    17.4kB  5000MB  5000MB  ext3              primary       
 2    5000MB  6000MB  1000MB  ext3              primary       
 3    6000MB  10.7GB  4737MB                    primary       
                                
(parted) resize              ← resizeコマンドでhdb1を縮小しに行く
                                                                         
パーティション番号? 1
                                                                         
開始?  [17.4kB]?    ←ここは、他のサイトにも書いてあるが動かさない(何も入力せず)。動かすとパーティションが破壊される。
                                                                         
終了?  [5000MB]? 2500MB  ←半分の2500MBにしようとする
                                                                         
エラー: ファイルシステムは互換性のない機能が有効になっています。
=================================

「エラー: ファイルシステムは互換性のない機能が有効になっています。」
がっくり、、。しかたなく、またネットで情報を漁る。だが、これがなかなか有効な情報が見つからない。やっと見つけたのが以下の2つ(ありがとうござます)。1つ目はすぐに見つかった日本語サイト。
・1つ目日本語サイト
http://d.hatena.ne.jp/tksmashiw/20080215

で、この記述のおかげで、「ext3ファイルシステムの機能のいくつかを止めないとpartedが動かないようだ」ということを理解。しかし、記載のとおり、dir_indexとresize_inodeを無効化してからpartedを試しても、相変わらず「ファイルシステムは互換性のない機能が有効になっています。」と吐きやがる。しかたないから片っ端から無効にしてやろうと思ったが、tune2fsコマンドでは、オプションのうち、ext_attrの無効化について、
Invalid filesystem option set: ^ext_attr
と言って受け付けない。

そこからだいぶ探して、以下のサイトにたどり着く(英語)。

・2つ目英語サイト
http://techynfreesouls.blogspot.jp/2009/02/resizing-ext3-partition-using-parted.html

この記述のおかげで、tune2fsコマンドだけでなく、debugfsコマンドがあって、そっちで他の機能は無効化できることを理解。
このサイトのとおり4つの機能を無効化してから、再度partedでパーティション縮小を実行。

==================================
$parted /dev/hdb
GNU Parted 1.8.1
/dev/hdb を使用
GNU Parted へようこそ! コマンド一覧を見るには 'help' と入力してください。
                                                                         
(parted) p
モデル: VBOX HARDDISK (ide)
ディスク /dev/hdb: 10.7GB
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: gpt
番号  開始    終了    サイズ  ファイルシステム  名前     フラグ
 1    17.4kB  5000MB  5000MB  ext2              primary       
 2    5000MB  6000MB  1000MB  ext3              primary       
 3    6000MB  10.7GB  4737MB                    primary       

                                                                         
(parted) resize
                                                                         
パーティション番号? 1
                                                                         
開始?  [17.4kB]?
                                                                         
終了?  [5000MB]? 3000MB
                                                                         
警告: A resize operation on this file system will use EXPERIMENTAL code
that MAY CORRUPT it (although no one has reported any such damage yet).
You should at least backup your data first, and run 'e2fsck -f' afterwards.
                                                                         
OK/取消(C)/Cancel? OK
                                                                         

You found a bug in GNU Parted! Here's what you have to do:
Don't panic! The bug has most likely not affected any of your data.
Help us to fix this bug by doing the following:
Check whether the bug has already been fixed by checking
the last version of GNU Parted that you can find at:
 http://ftp.gnu.org/gnu/parted/
Please check this version prior to bug reporting.
If this has not been fixed yet or if you don't know how to check,
please visit the GNU Parted website:
 http://www.gnu.org/software/parted
for further information.
Your report should contain the version of this release (1.8.1)
along with the error message below, the output of
 parted DEVICE unit co print unit s print
and additional information about your setup you consider important.
ブロック 760900 は何も参照していません。おかしいです。
==================================

バグって止まった、、、、。はぁ、、、がっくり、、、、。
つうことは、partedのバージョンが古いからバグってるということか、、、。

しかたないので、新しいpartedをコンパイル、実行

CentOS5のyumで探しても、1.8.1のrpmしか見つからない。
仕方ないので、GNUから新しいpartedのsrcを持ってきてコンパイルする。
最新は、parted-3.2のようだが、少し古いCentOS5ということもあって、ライブラリ類も古いから少し前の方が良いかな?なんて思ってparted-3.0を持ってきた。(後から思うと、なんでそんなことしたんだろう、、、。)
make installして、とりあえず実行。新しいバージョンなら、ext3のdir_index等の拡張機能も対応していると踏んで、特に無効化せず。そしたら、
「partedが、resizeコマンドを受け付けない(コマンドリストから、resizeコマンドがなくなってる)」
はぁ????
さすがにあせった。慌てて、GNU本家の英語ドキュメントを漁る。そしたら、resizeコマンドはなくなっていて、「resizepartコマンド」になったらしい。(その代わり、ファイルシステムの縮小はサポートせず、パーティションの縮小しかやらなくなっていた。ファイルシステムの縮小は、別途resize2fsでやれ、とのこと。)
気を取り直して、resizepartコマンドを叩き込むと、これまた受け付けない、、、、。helpコマンドでコマンドリストを見たら、
「resizepartコマンドも無い」
もう、何がなんだかわからなくなってきた。

最新のpartedをコンパイル、実行

少し落ち着いてから、GNU本家の英語ドキュメントをもう一度見ると、ドキュメント冒頭にかかれた対応バージョンが、「Ver.3.2」であった。マイナーバージョンの差でコマンド増減するか??とは思ったが、ダメもとでparted-3.0のアンインストール後、parted-3.2を持ってきてコンパイル・インストールし、helpコマンドでコマンドリストをみると、
「resizepartコマンドがある!!!!」
================================
GNU Parted 3.2
/dev/hdb を使用
GNU Parted へようこそ! コマンド一覧を見るには 'help' と入力してください。
                                                                         
(parted) h
  align-check TYPE N            パーティション N のアライメント(TYPE: min|opt)をチェックする
  help [コマンド]               ヘルプ表示。コマンド指定でそのヘルプを表示
  mklabel,mktable ラベルの種類  新しいラベル(パーティションテーブル)を作る
  mkpart パーティションの種類 [ファイルシステムの種類] 開始 終了
                    パーティションを作る
  name NUMBER 名前              パーティションに名前をつける
  print [devices|free|list,all|NUMBER]
                     パーティションテーブルや、利用可能なデバイス、空き領域、
                     見つかった全てのパーティション、あるいは特定のパーティションについて表示する
  quit                          プログラムを終了する
  rescue 開始 終了              開始、終了で指定した範囲付近にあるパーティションを復活させる
  resizepart NUMBER END         パーティション NUMBER を END にリサイズする
  rm NUMBER                     パーティションを削除する
  select デバイス               操作するデバイスを選択
  disk_set FLAG STATE           選択したデバイスの FLAG を変更
  disk_toggle [FLAG]            選択したデバイスの FLAG の状態をトグル
  set NUMBER フラグ 状態        ファイルシステムのフラグと状態を設定する
  toggle [NUMBER [FLAG]]        パーティションのフラグの状態を反転する
  unit UNIT                     デフォルトの単位を UNIT にする
  version                       GNU Parted のバージョンと著作権情報を表示
=================================
あーつかれた。
とりあえず、こいつを実行してみる。
(もちろん、resizepartコマンドになって、ファイルシステムの縮小に対応していないので、この前に、resize2fsコマンドでext3ファイルシステムは、少し小さめの3GBに縮めてある。resizepartコマンドで、パーティションを3.5GBまで縮めた後、再度resize2fsコマンドでパーティション上限の3.5GBまで拡張する算段。こうすることで、パーティション終端の厳密な数値を入力しないで済むから。この終端の数値を間違えると、ファイルシステムが破壊されそうなので。)

=================================
(parted) resi zepart
                                                                         
パーティション番号? 1
                                                                         
終了?  [5000MB]? 3500MB
警告: パーティションを縮小するとデータを失うかもしれませんが、それでも実行しますか?
                                                                         
                                                                         
はい(Y)/Yes/いいえ(N)/No? Y
エラー: パーティション 64 (/dev/hdb 上)


できませんでした。おそらく、使用中だったのが原因だと思われます。そのため、古いパーティション情報がそのまま使われます。さらなる変更をする前に再起動してください。
                                                                         
無視(I)/Ignore/取消(C)/Cancel? C
=================================
「使用中」とかメッセージ吐いてきたが、もちろんマウントはしていない。
あーあ。またかよ。パーティションぶっ壊れたわ。と思ったが、そのあと、該当パーティションの/dev/hdb1をマウントして、dfで見ると、hdb1が見える。前述のとおり、resize2fsコマンドで、

=================================
$resize2fs /dev/hdb1
resize2fs 1.39 (29-May-2006)
Filesystem at /dev/hdb1 is mounted on /mnt_test1; on-line resizing required
Performing an on-line resize of /dev/hdb1 to 854488 (4k) blocks.
The filesystem on /dev/hdb1 is now 854488 blocks long.
=================================
として、パーティションサイズ上限まで再拡張してみると、正常に実行でき、下記のとおりマウント後のdf出力は、約3.5GBになっている。(パーティション縮小に失敗していたら、5GBのままのはずだが、ちゃんと縮小されている)

=================================
$df
Filesystem           1K-ブロック    使用   使用可 使用% マウント位置
/dev/hdb1              3363464   2149348   1046916  68% /mnt_test1
=================================

e2fsckの結果も正常だ。とりあえず、出来たように見える。

同様の事例がないか、検索すると、以下が見つかった。(ありがとうござます)

http://everlastingrecordarea.blogspot.jp/2014/08/blog-post_50.html

ちょっとメッセージは違うが、「おそらく、使用中だったのが原因だと思われます。そのため、古いパーティション情報がそのまま使われます。さらなる変更をする前に再起動してください。」という部分は同じだ。このサイトでも、そのまま続行している。そんなもんなんだろうか。

CentOSのgnomeのターミナル上から実行してるけど、もしかしたら、シングルユーザモードとかでやったら、メッセージ出ないのかもしれない。(やってないから全く根拠なしだが)

まあ、他の人のお役に立つかどうかは分かりませんが、GNU partedの情報がなかなかネットで見つからなかったので、書いてみました。繰り返しになりますが、こちらに記載の手順を参考に作業をされて、お使いのシステムに何か起こっても全く保証できませんので、そこはご承知おきください。