2013年7月11日木曜日

Btrfs の resize

別記事で Btrfs 化について書きましたが、実験環境とは別に 20G のパーティションに別途 Fedora19 をインストール済みでしたので、これを 10G に縮小する操作を行ってみました。Btrfs は未だ開発途上という状況なので、最悪の場合は、ぶっ壊れるかもねという心象がありますが、まあ、壊れてもさしてダメージが無い環境なので。

縮小操作は、man btrfs の通りで、いたって簡単でした。
# btrfs filesystem resize 9g /
システムデータしか入ってないこともあり、処理は殆ど一瞬で終わりました。サイズ指定は、いったん 9g にしていますが、パーティションを 10G に縮小後に、パーティションサイズまで resize するために、適当に 1G ほど余裕をとりました。
パーティション縮小は fdisk -u で行い、システム再起動後に次のように操作を行いました。
# btrfs filesystem resize max /
Resize '/' of 'max'

# df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda10      10240000 2441692   6037316  29% /
devtmpfs         4011116       0   4011116   0% /dev
tmpfs            4017612     156   4017456   1% /dev/shm
tmpfs            4017612     780   4016832   1% /run
tmpfs            4017612       0   4017612   0% /sys/fs/cgroup
tmpfs            4017612      44   4017568   1% /tmp

# btrfs filesystem balance /
Done, had to relocate 7 out of 7 chunks

# df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda10      10240000 2442728   7569272  25% /
devtmpfs         4011116       0   4011116   0% /dev
tmpfs            4017612     156   4017456   1% /dev/shm
tmpfs            4017612     780   4016832   1% /run
tmpfs            4017612       0   4017612   0% /sys/fs/cgroup
tmpfs            4017612      48   4017564   1% /tmp
balance という操作が肝で、これを行わないと、空きが少なく見えます(たぶん、balance しなくても、逼迫してくれば使われるのかな??)。

2019-11-16追記
Btrfs raid1 のサイズ拡張を行ったのですが、前述の balance 操作ではダメでした。検索してみると、先人の方がおられましたのでメモ。
https://qiita.com/takaki@github/items/5d96d80dc78b09ea600b
明示的に devid を指定することで、うまくいきました。実施した環境は CentOS7 です。
man btrfs-filesystem を読んでみると、デフォルトの devid は 1 であると記載あるようです。むしろ、devid 指定必須のほうが、分かり易いのではと思ってしまった。先人の方の情報に辿りつくまで、無駄に時間を使ってしまいました。最初から man をちゃんと読めばよかったというのもありますが。

2013年7月7日日曜日

Fedora19 のルートファイルシステムを Btrfs 化する

先日、Fedora19 が正式リリースされましたが、1パーティションに btrfs でインストールしたいと思ったのですが、インストーラでは指定できないようでした。何回か試行錯誤しましたが、まず ext4 でインストールしておいて、そのあと Live メディアから起動して、内容をバックアップして、mkfs.btrfs 後に書き戻すという方法で成功しましたので、自分用のメモも兼ねてご紹介です。

今回は、まっさらな SSD を使って、sda1 にインストールしました。インストーラからパーティションを切っても問題ないと思いますが、事前に 10G ほど sda1 を確保してからインストールしました。10G とは小さめですが、btrfs の透過圧縮機能をあてにしたサイズです。わたしの場合、これまでは Fedora を ext4 に入れるとしたら 20G くらいは割り当てていましたが、圧縮機能があれば半分の 10G くらいでも、わたしの用途では十分かなと。
ソフトウェアの選択を Development and Creative Workstation にして、ext4 にインストールした直後だと、約6G ほど消費した状態でした。

btrfs 化は、ライブメディア Fedora-Live-Desktop-x86_64-19-1.iso を利用して、次のように行いました。
※まずは、ライブメディアを起動して、ターミナルを開く
※root 権限を得る
# sudo bash

※ext4 のバックアップツールとして dump をインストール
# yum install dump

※別の HDD 等にバックアップを行う。わたしの場合は別の ext4 領域を使いました。
# mkdir /mnt_sdb1
# mount /dev/sdb1 /mnt_sdb1
# dump -y -0uf /mnt_sdb1/dump.sda1 /dev/sda1  ※ここで -y は LZO 圧縮するオプションです

※btrfs ファイルシステム作成
# mkfs.btrfs -f /dev/sda1

※バックアップデータを書き戻す
# mkdir /mnt_sda1
# mount -t btrfs -o compress-force=lzo /dev/sda1 /mnt_sda1
# cd /mnt_sda1
# restore -rf /mnt_sdb1/dump.sda1

※/etc/fstab に書かれている UUID とファイルシステム種別等を書き換える
# cd /mnt_sda1
# blkid /dev/sda1
/dev/sda1: UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" UUID_SUB="yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy" TYPE="btrfs"
# vi etc/fstab
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx / btrfs defaults,compress-force=lzo 1 1

※initramfs の再作成と GRUB2 の再インストールのため環境設定
# mount -t devtmpfs devtmpfs /mnt_sda1/dev
# mount -t devpts devpts /mnt_sda1/dev/pts
# mount -t sysfs sysfs /mnt_sda1/sys
# mount -t proc proc /mnt_sda1/proc

※initramfs の再作成
# chroot /mnt_sda1 /bin/bash
# ls /boot/initramfs-3*  
/boot/initramfs-3.9.5-301.fc19.x86_64.img  ※カーネルバージョン確認
# dracut -f /boot/initramfs-3.9.5-301.fc19.x86_64.img  3.9.5-301.fc19.x86_64

※GRUB2 の再インストール
# grub2-mkconfig > /boot/grub2/grub.cfg
# grub2-install /dev/sda
# exit  ※chroot を抜ける
# 
ライブ DVD を抜けて、sda から起動できれば成功です。
現在の私の環境での、ディスク空き状況は次の通りです。
# cat /etc/redhat-release 
Fedora release 19 (Schrödinger’s Cat)
# df -kT /
Filesystem     Type  1K-blocks    Used Available Use% Mounted on
/dev/sda1      btrfs  10240000 3888960   5950044  40% /

2013-07-08追記
btrfs は swapfile には対応していないそうなので、ご注意を。
https://btrfs.wiki.kernel.org/index.php/FAQ#Does_btrfs_support_swap_files.3F
実際、fallocate , mkswap までは出来ますが、swapon でエラー(invalid argument)になるようです。わたしのマシンはメモリを 8G 積んでおり、swap の必要性を感じませんので、swap レスでいいやと思いましたが、用途によっては zram を使ってもいいかもしれません。
もちろん、別途swapパーティションを作ってもいいわけですが。

2013-10-12追記
まだアルファ版ですが、Fedora 20 でもインストール時には btrfs は指定できず、上記の手順でいけました。

2013-12-07追記
CentOS 6.5 でも、同様の手順で出来ました。Btrfs は RHEL 6.5 においても、まだ Technology Preview 扱いとなっており、安定性がクエスチョンですが、SSD の節約に compress-force=lzo が役立ちます。

2014-04-27追記
RHEL7 beta をインストールしたのですが、やはりインストーラからは btrfs を指定できず。Fedora 19/20 と同様に、いったん ext4 でインストールしたあとに btrfs 化しました。
ただし、今回は試しに btrfs-convert を使ってみました。使い方はいたって簡単で、レスキューモードで起動後に、ext4 としてインストールしたパーティションを指定して実行するだけです。あっという間に変換が完了します。変換すると UUID が変わってしまうので、この記事の手順の fstab の変更の箇所から同様に操作して、btrfs 化に成功しました。
compress-force=lzo を活用したければ、やはりバックアップからリストアしないといけませんが、透過圧縮を使わないなら btrfs-convert のほうが手っ取り早いかと思います。btrfs-convert の仕組みは、次の URL に解説があります。すごい、賢いです。
https://btrfs.wiki.kernel.org/index.php/Conversion_from_Ext3
このように、変換前のイメージが、サブボリューム ext2_saved に保持される方式になっているので、btrfs-convert を利用した場合には、ext2_saved の削除をお忘れなく。

2013年6月29日土曜日

zfs-fuse を使って CentOS 5 でも透過圧縮を利用

CentOS 5 で運用しているサーバで、容量を稼ぐのに透過圧縮可能なファイルシステムを使いたいのですが、ZFS on Linux は非対応(カーネルが古くコンパイル不可)なので、zfs-fuse を利用しようかと思います。しかし、CentOS 5 の fuse は、NFS export に対応していません。
そこで、一工夫して、透過圧縮指定した ZFS 領域にスパースファイルを作って XFS 化して、loop マウントすることで、NFS export することにしました。
※まず圧縮指定
# zfs set compression=gzip-1 tank5/test
# zfs get compression tank5/test
NAME        PROPERTY     VALUE     SOURCE
tank5/test  compression  gzip-1    local

※スパースファイル作成。CentOS 5 では truncate が用意されてないので dd 利用
# dd if=/dev/zero of=/tank5/test/sparsefile bs=1M seek=4096 count=0
0+0 records in
0+0 records out
0 bytes (0 B) copied, 2.2e-05 seconds, 0.0 kB/s

# ls -lsh /tank5/test/sparsefile 
512 -rw-r--r-- 1 root root 4.0G Jun 29 10:21 /tank5/test/sparsefile

※ext4 でもいいけれど、XFS を試したいという気持ちもありまして
# mkfs -t xfs /tank5/test/sparsefile 
meta-data=/tank5/test/sparsefile isize=256    agcount=8, agsize=131072 blks
         =                       sectsz=512   attr=0
data     =                       bsize=4096   blocks=1048576, imaxpct=25
         =                       sunit=0      swidth=0 blks, unwritten=1
naming   =version 2              bsize=4096  
log      =internal log           bsize=4096   blocks=2560, version=1
         =                       sectsz=512   sunit=0 blks, lazy-count=0
realtime =none                   extsz=4096   blocks=0, rtextents=0

# mount -t xfs -o loop /tank5/test/sparsefile /mnt_temp
# df
...
/tank5/test/sparsefile
                       4184064      4384   4179680   1% /mnt_temp

※テスト書き込み
# dd if=/dev/sda of=/mnt_temp/test.dd bs=1M count=500 conv=fsync
500+0 records in
500+0 records out
524288000 bytes (524 MB) copied, 16.7982 seconds, 31.2 MB/s
# ls -lsh /tank5/test/sparsefile 
211M -rw-r--r-- 1 root root 4.0G Jun 29 10:24 /tank5/test/sparsefile
この実験では、500M が 211M に圧縮されました。書き込み速度は、zfs-fuse の遅さに引きずられますが、NFS (NW が 100Mbps の環境) 経由で利用する予定なので、十分そうです。
なお、NFS のセッティング方法等は、普通にやればいいので割愛します。

2013-06-30追記
XFS のサイズ拡張(xfs_growfs)を試してみました。マウントしたまま可能でした。
スパースファイルの拡張、loop デバイスのサイズ拡張、xfs_growfs の順に行います。
※losetup -c も初めてなので、予め loop デバイスのサイズを確認
# grep loop0 /proc/partitions 
   7        0    4194304 loop0

※スパースファイルの拡張、サイズ指定を誤っても変なところに書き込まないように if=/dev/null でね
# dd if=/dev/null of=/tank5/test/sparsefile bs=1M seek=8192 count=0
0+0 records in
0+0 records out
0 bytes (0 B) copied, 1.646e-05 s, 0.0 kB/s
# ls -lsh /tank5/test/sparsefile 
236M -rw-r--r-- 1 root root 8.0G Jun 30 06:06 /tank5/test/sparsefile

※loop デバイスのサイズ認識は自動ではないので、変化なし
# grep loop0 /proc/partitions 
   7        0    4194304 loop0
# df /mnt_temp
Filesystem           1K-blocks      Used Available Use% Mounted on
/tank5/test/sparsefile
                       4184064    545056   3639008  14% /mnt_temp

※loop デバイスのサイズ再認識を実行
# losetup -c /dev/loop0 
# grep loop0 /proc/partitions 
   7        0    8388608 loop0
# df /mnt_temp
Filesystem           1K-blocks      Used Available Use% Mounted on
/tank5/test/sparsefile
                       4184064    545056   3639008  14% /mnt_temp

※XFS のサイズ拡張を実行
# xfs_growfs /mnt_temp
meta-data=/dev/loop0             isize=256    agcount=8, agsize=131072 blks
         =                       sectsz=512   attr=0, projid32bit=0
data     =                       bsize=4096   blocks=1048576, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0
log      =internal               bsize=4096   blocks=2560, version=1
         =                       sectsz=512   sunit=0 blks, lazy-count=0
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 1048576 to 2097152
# df /mnt_temp
Filesystem           1K-blocks      Used Available Use% Mounted on
/tank5/test/sparsefile
                       8378368    545312   7833056   7% /mnt_temp
実験の範囲では大丈夫そうです。

2013-07-03追記
サイズ拡張の検証を、間違って CentOS 6 でやってしまっていました。通常、CentOS 6 を使うことが多いもので・・・
で、残念ながら、CentOS 5 では losetup -c オプションは使えず、いちおう 2.6.18-348.el5 のソースも見てみましたが、サイズ拡張を行うためのインターフェースが未実装でした。したがって、マウントしたまま拡張は不可でした。もちろん、いったんアンマウントしてから、スパースファイル拡張して、再度マウントすればいけます。

2013-08-09追記
この形態で実際使い始めたのですが、ファイル削除の際に一工夫すると、より効果的に運用できます。具体的には次のように、削除対象ファイルをゼロ埋め後に削除するようにします。
# find remove-target-dir -type f -exec shred -n 0 -z -u {} \;
これで不要となったブロックについて、XFS から ZFS へゼロ書き込みが行われ、ZFS 側の圧縮機能により元データが使用していたブロックの大半が回収されることになります。したがって、シン・プロビジョニング(Thin Provisioning)が、より効果的に行えることになります。
なお、上記の find 後には、抜けがら(通常ファイル以外のディレクトリその他のことを言ってます:-)が残りますので、最後に rm -rf remove-target-dir もお忘れなく。

2013-10-22追記
オラクル社提供の UEK を使うことで、CentOS 5 でも ZFS on Linux や btrfs が利用できました。
こちらの記事を参照。
人気ブログランキングへ にほんブログ村 IT技術ブログへ