2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CentOS7系 xfs ファイルシステム 40G の qcow2 イメージをノンスパース 20G に縮小する

Last updated at Posted at 2019-08-11

CentOS7.5 の iso から、OS を minimal インストールしました。
どこにインストールされたかを確かめます。

# virsh dumpxml centos7.5
...(snip)...
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/home/xxx/libvirt/centos7.5.qcow2'/>
<target dev='vda' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
</disk>
...(snip)...

以下のようになっています。

/home/xxx/libvirt/centos7.5.qcow2

実は、容量の関係で、libvirt のパスを変更していました。
libvirt の image 保存ディレクトリの変更
では、このパスを指定して、情報を見てみます。

# qemu-img info /home/xxx/libvirt/centos7.5.qcow2
image: /home/xxx/libvirt/centos7.5.qcow2
file format: qcow2
virtual size: 40G (42949672960 bytes)
disk size: 40G
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: true
refcount bits: 16
corrupt: false

ここで、容量に注目します。以下のようになっています。

virtual size: 40G
disk size: 40G

ls -ls コマンドでも確認します。

# ls -ls /home/xxx/libvirt/centos7.5.qcow2
41949724 -rw-------. 1 root root 42956488704 2月 9 07:27 /home/xxx/libvirt/centos7.5.qcow2
# ls -lsh /home/xxx/libvirt/centos7.5.qcow2
41G -rw-------. 1 root root 41G 2月 9 07:27 /home/xxx/libvirt/centos7.5.qcow2

しかし、仮想マシンがこんなに容量はいらないと思います。
仮想マシンの中に入って確認したいです。
guestfishコマンドを使います。この際、仮想マシンは停止しておきます。

# guestfish -a /home/xxx/libvirt/centos7.5.qcow2
# guestfish -a /home/xxx/libvirt/centos7.5.qcow2
Welcome to guestfish, the guest filesystem shell for
editing virtual machine filesystems and disk images.
Type: ‘help’ for help on commands
‘man’ to read the manual
‘quit’ to quit the shell
><fs> run
><fs> mount /dev/sda1 /
><fs> df-h
Filesystem Size Used Avail Use% Mounted on
/dev/root 4.0G 397M 3.4G 11% /
tmpfs 147M 104K 146M 1% /run
/dev 362M 0 362M 0% /dev
shmfs 366M 0 366M 0% /dev/shm
/dev/sda1 1014M 143M 872M 15% /sysroot

せいぜい、現在の容量は、多く見積もっても、1G というところでしょうか。
以下のページを参考にします。

# guestfish
Welcome to guestfish, the guest filesystem shell for
editing virtual machine filesystems and disk images.
Type: ‘help’ for help on commands
‘man’ to read the manual
‘quit’ to quit the shell
><fs> add-ro /home/fujiwara/libvirt/centos7.5.qcow2
><fs> run
><fs> list-filesystems
/dev/sda1: xfs
/dev/centos/root: xfs
/dev/centos/swap: swap
><fs> mount /dev/centos/root /
><fs> cat /etc/fstab
#
# /etc/fstab
# Created by anaconda on Fri Feb 8 22:33:46 2019
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root / xfs defaults 0 0
UUID=1c7fbd60-2126-4ca4-81bd-0d530c3b858a /boot xfs defaults 0 0
/dev/mapper/centos-swap swap swap defaults 0 0
><fs> df-h
Filesystem Size Used Avail Use% Mounted on
/dev/root 4.0G 397M 3.4G 11% /
tmpfs 147M 104K 146M 1% /run
/dev 362M 0 362M 0% /dev
shmfs 366M 0 366M 0% /dev/shm
/dev/mapper/centos-root 36G 981M 35G 3% /sysroot
大体わかったので、exit します。
><fs> exit
#

今、virtual size と device size が等しいので、一度 sparse 化(thin-provisioning)しておきたいです。
virt-sparsify コマンドが使えそうです。
以下のサイトを参考にします。

まずは、仮想マシンのイメージ容量を把握します。

$ ls -lh /home/xxx/libvirt/centos7.5.qcow2
-rw-------. 1 qemu qemu 41G 2月 9 08:04 /home/xxx/libvirt/centos7.5.qcow2
$ du -sh /home/xxx/libvirt/centos7.5.qcow2
41G /home/xxx/libvirt/centos7.5.qcow2
``

では、virt-sparsify コマンドで、コピーを作らずにその仮想マシン自体をスパース化します。

```console
# virt-sparsify --in-place /home/xxx/libvirt/centos7.5.qcow2
[ 2.1] Trimming /dev/centos/root
[ 3.5] Clearing Linux swap on /dev/centos/swap
[ 3.8] Trimming /dev/sda1
[ 4.1] Discard space in volgroup centos
[ 4.5] Sparsify in-place operation completed with no errors

では、再度仮想マシンの容量を確認します。

$ ls -lh /home/xxx/libvirt/centos7.5.qcow2
-rw-------. 1 root root 41G 2月 9 09:05 /home/xxx/libvirt/centos7.5.qcow2
$ du -sh /home/xxx/libvirt/centos7.5.qcow2
1.1G /home/xxx/libvirt/centos7.5.qcow2

1.1G に thin-provision されたようです。
qemu-img info コマンドでも確認してみます。

# qemu-img info /home/xxx/libvirt/centos7.5.qcow2
image: /home/xxx/libvirt/centos7.5.qcow2
file format: qcow2
virtual size: 40G (42949672960 bytes)
disk size: 1.1G
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: true
refcount bits: 16
corrupt: false

さて、ここから、仮想イメージをコピーして、例えば、20G の容量のイメージを作りたい、その際、スパース化しない、ということをやりたいです。
これを参考にします。

しかしながら、上記リンクには、expand する方法しか書いてありません。
次のリンクはどうでしょう。
https://blog.maideveloper.com/how-to-shrink-qcow2-file-lvm-volume-xfs-system-type/
https://www.endpoint.com/blog/2015/01/29/shrink-xfs-partition-almost-possible

少なくとも言えることは、CentOS7 のデフォルトのファイルシステムである xfs は、縮小できない、ということです。
従って、小さな領域を作成して、データを移行する必要があります。
うーん、確実にやるには、仮想マシン上で、新しいブロックデバイスを追加して、ファイルシステム作成、ボリューム作成、データコピー、
とかがいいのかもしれない。
以下のリンクを参考にします。
https://blog.dbi-services.com/how-to-reduce-the-size-a-lvm-partition-formatted-with-xfs-filesystem-on-centos7/
まず、最初のところは、別のリンクを参考にします。
https://www.cyberciti.biz/faq/how-to-add-disk-image-to-kvm-virtual-machine-with-virsh-command/
まずは、仮想マシン上のデバイス名を調べます。
以下の通りにやります。
https://blog.dbi-services.com/how-to-reduce-the-size-a-lvm-partition-formatted-with-xfs-filesystem-on-centos7/

# fdisk -l | grep 'Disk /dev/vd[a-z]'
Disk /dev/vda: 42.9GB, 42949672960 bytes, 83886000 sectors

ということは、新たに接続するデバイス名は、vdb とします。
パーティションも知りたいです。

# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
vda 252:0 0 40G 0 disk
|-vda1 252:1 0 1G 0 part /boot
|-vda2 252:2 0 39G 0 part
|-centos-root 253:0 0 35.1G 0 lvm /
|-centos-swap 253:1 0 3.9G 0 lvm [SWAP]

これと同じ構成で、容量を小さくすれば良さそうです。
現在の使用状況を確認します。

# df -h
/dev/mapper/centos-root 36G 982M 35G 3% /
/dev/vda1 1014M 142M 873M 15% /boot

構成を考えます。
上記と同様の構成で、vdb1 に /boot を 1G、vdb2 に centos-root 15G、centos-swap 3G を作ります。
もうちょっと確認します。

# lvdisplay
--- Logical volume ---
LV Path /dev/centos/swap
LV Size <3.88 GiB
--- Logical volume ---
LV Path /dev/centos/root
LV Size <35.12 GiB

以下のコマンドを実行します。
まずは、raw フォーマットで、ディスクを作成します。

$ qemu-img create -f raw xfs_srhink_test-vm-disk1-20G 20G

次に、現在の仮想マシン(容量40G)に作成した 20Gのディスクをアタッチします。

# virsh attach-disk centos7.5 --source /home/xxx/QEMU/xfs_shrink_test-vm-disk1-20G --target vdb --persistent

または、

# virsh attach-disk centos7.5 /home/xxx/QEMU/xfs_srhink_test-vm-disk1-20G vdb --cache none

では、Volume を作成したり、初期化したりしましょう。
手順です。

# fdisk /dev/vdb
n p 1 Enter +1G t 83
n p 2 Enter Enter t 2 8e
w

カーネルに、パーティション情報の変更を教えます。

# partprobe /dev/vdb

確認します。

# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
vda 252:0 0 40G 0 disk
|-vda1 252:1 0 1G 0 part /boot
|-vda2 252:2 0 39G 0 part
|-centos-root 253:0 0 35.1G 0 lvm /
|-centos-swap 253:1 0 3.9G 0 lvm [SWAP]
vdb 252:16 0 20G 0 disk
|-vdb1 252:17 0 1G 0 part
|-vdb2 252:18 0 19G 0 part

今、仮想マシンにいますが、うまくいったら、/dev/vdb から起動させたいわけです。
とにかく、vdb1 からやっていきましょう。
vdb1 が、/boot となるので、Boot Flag をつけます。

# cfdisk

vdb1 を選択し、[Bootable] を選択して Enter、[Write]を選択して Enter、
[Quit]を選択して、Enter
これで、Boot という Flags がつきました。
ファイルシステムを作成します。

# mkfs.xfs /dev/vdb1

grub をインストールします。

# grub2-install /dev/vdb

では、rsync でデータを移行します。

# rsync -aAxX /dev/vda1 /dev/vdb1

次は、/dev/vdb2 です。

# pvcreate /dev/vdb2
(表示)
Physical volume "/dev/vdb2" successfully created.
# pvs
PV VG Fmt Attr PSize PFree
/dev/vda2 centos lvm2 a-- <39.88g 4.00m
/dev/vdb2 lvm2 --- <19.00g <19.00g
# vgcreate centos_ /dev/vdb2
(表示)
Volume group "centos_" successfully created
# vgdisplya centos_
(表示)
--- Volume group ---
VG Name centos_
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 1
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 1
Act PV 1
VG Size <19.00 GiB
PE Size 4.00 MiB
Total PE 4863
Alloc PE / Size 0 / 0
Free PE / Size 4863 / <19.00 GiB
VG UUID xxx-xxx-xxx-xxx-xxx-xxx-xxx
# lvcreate -n root -L 15G centos_
(表示)
Logical volume "root" created.
# lvcreate -n swap -L 3G centos_
(表示)
Logical volume "swap" created.
確認します。
# lvdisplay /dev/centos_
(表示省略)

ファイルシステムを作成します。

# mkfs.xfs /dev/centos_/root
(表示省略)
# mkswap /dev/centos_/swap
(表示省略)

有効にします。

# swapon /dev/centos_/swap
(表示省略)

では、xfsdump でデータを移行します。

# yum install xfsdump

現在のディレクトリを確認します。

# ls /
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
# xfsdump -l 0 -f /tmp/root.xfsdump /

ラベルは、root としました。

# ls -lh /tmp/root.xfsdump

容量は、1.2G と表示されました。

# mkdir /mnt/test
# mount /dev/mapper/centos_-root /mnt/test
# xfsrestore -f /tmp/root.xfsdump -L "root" /mnt/test
(表示)
xfsrestore: Restore Status: SUCCESS
# ls /mnt/test
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var

boot はいらないので、消します(疑わしい)。

# rm -rf /mnt/test/boot

一度再起動します。

# shutdown -r now

/
dev/mapper/centos_-root を/mnt/test にマウントして確認したところ、データが入っていました。
では、もう一度再起動して、起動時に e を押下して、linux16 の行のところの centos を、centos_ にして,起動するかを試してみます。

# cat /proc/mounts
/dev/mapper/centos_-root / xfs rw,seclabelrelatime,attr,inode64,noquota 0 0

うまくいきました。

# df -h

/dev/mapper/centos_-root の容量が 15G で / にマウントされとなっています。
/dev/vdb1 が /boot にマウントされています。
では、一度仮想マシンを停止します。

# shutdown -h now

ホストマシンから、virsh コマンドを使って、今迄利用していたイメージをデタッチします。

# virsh list --all
Id Name State
-------------------------------
- centos7.5 シャットオフ

今、知りたいのは、centos7.5 ドメインが、どの qemu イメージをぶら下げているかです。

# virsh dumpxml centos7.5
...(snip)...
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/home/xxx/libvirt/centos7.5.qcow2'/>
<target dev='vda' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/home/xxx/QEMU/xfs_shrink_test-vm-disk1-20G'/>
<target dev='vdb' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
</disk>

ファイル名が、/home/xxx/libvirt/centos7.5.qcow2 でした。
では、このイメージをcentos7.5 からデタッチします。

# virsh detach-disk --domain vmname /var/lib/libvirt/images/vmname-vdb.qcow2 --persistent

オンラインで切断する場合は、上記に --config --live を追加するとよいようです。
では、デタッチできるから、もう一度確認します。

# virsh dumpxml centos7.5
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/home/xxx/QEMU/xfs_shrink_test-vm-disk1-20G'/>
<target dev='vdb' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
</disk>

起動してみます。
おっと、grubに落ちてしまいました。

grub>ls
(hd0) (hd0,msdos2) (hd0,msdos1)

カーネルとかが/boot に入っていなかったのが原因でした。こういう場合は、以下の方法でマウントして、取り出します。そういえば、rsync でコピーした時に、ちゃんと確認していなかったなぁ。xfsdump/xfsrestore の方がいいかも。まあ、なんとかしましょう。

# guestmount ...
(省略)

起動の印を付け忘れたら、以下の方法で直せます。
困った時は、以下をみて、イメージを /dev/nbd0 として cfdisk ができます。
[link]https://xliska.wordpress.com/2012/09/13/partitioning-qemukvm-disk-images-using-qcow2-format/
カーネルモジュールをロードします。

# modprobe -av nbd
# qemu-nbd -c /dev/nbd0 <qcow2 イメージ>
# cfdisk /dev/nbd0

終わったら、接続を解除します。

# qemu-nbd --disconnect /dev/nbd0

カーネルモジュールをアンロードします。

# modprobe -rv nbd
# vgrename /dev/centos_ /dev/centos

うまく上がらないときは、grub の画面で e を押下して、linux16 のところやらを書き換えて立ち上げてから直します。
最終的に、新しい15Gのイメージで立ち上がるようになりました。
grub.cfg の書き直しは、以下になります。

# grub2-mkconfig -o /boot/grub2/grub.cfg

では、最初の目的である、イメージの縮小はできたのでしょうか。

# ls -lh /home/xxx/QEMU/xfs_shrink_test-vm-disk1-20G
-rw-r--r--. 1 root root 20G 2月 10 02:01 /home/xxx/QEMU/xfs_shrink_test-vm-disk1-20G
# qemu-img info /home/xxx/QEMU/xfs_shrink_test-vm-disk1-20G
image: /home/xxx/QEMU/xfs_shrink_test-vm-disk1-20G
file format: raw
virtual size: 20G (21474836480 bytes)
disk size: 1.3G

容量がほぼ半分になりました。しかし、これは、raw フォーマットになっていますね。
これを、qcow2 フォーマットに変換したいです。
また、今後の運用のオーバーヘッドを鑑みて、スパース化したくないです。
一度、普通にやってみます。

# qemu-img convert -f raw -O qcow2 /home/xxx/QEMU/xfs_shrink_test-vm-disk1-20G /home/xxx/QEMU/xfs_shrink_test-vm-disk1-20G.qcow2
# ls -lh /home/xxx/QEMU/
-rw-r--r--. 1 root root 20G 2月 10 02:01 xfs_shrink_test-vm-disk1-20G
-rw-r--r--. 1 root root 1.4G 2月 10 02:07 xfs_shrink_test-vm-disk1-20G.qcow2

では、スパースサイズを0にして実行してみます。-S 0

# qemu-img convert -S 0 -f raw -O qcow2 /home/xxx/QEMU/xfs_shrink_test-vm-disk1-20G /home/xxx/QEMU/xfs_shrink_test-vm-disk1-20G_non_sparse.qcow2
# ls -lh /home/xxx/QEMU
合計 23G
-rw-r--r--. 1 root root 20G 2月 10 02:01 xfs_shrink_test-vm-disk1-20G
-rw-r--r--. 1 root root 1.4G 2月 10 02:07 xfs_shrink_test-vm-disk1-20G.qcow2
-rw-r--r--. 1 root root 21G 2月 10 02:13 xfs_shrink_test-vm-disk1-20G_non_sparse.qcow2

qemu-img info コマンドでも確認します。

# qemu-img info /home/xxx/QEMU/xfs_shrink_test-vm-disk1-20G_non_sparse.qcow2
image: /home/fujiwara/QEMU/xfs_shrink_test-vm-disk1-20G_non_sparse.qcow2
file format: qcow2
virtual size: 20G (21474836480 bytes)
disk size: 20G
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false

できました。
xfsファイルシステム 40Gのqcow2イメージを、ノンスパースの20Gに縮小できたというところです。
xfsファイルシステムは、縮小できないので、データをダンプ/リストアする必要がありました。
/etc/fstab も、うまくいくまでは、移行前のものと移行後の行を両方書いておきました。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?