Upgrade to Pro — share decks privately, control downloads, hide ads and more …

qcow2 sparsify

qcow2 sparsify

qcow2の肥大したイメージをvirt-sparsifyで縮小
LIBGUESTFS_MEMSIZEで解決

27b9fb2c6ad269533e8a5e45fd6b7c9f?s=128

koedoyoshida

April 10, 2021
Tweet

Transcript

  1. qcow2イメージを縮小してみた 吉田@板橋

  2. 動機 • 大きなkvmマシンイメージを縮小して取り回し を良くしたい。 • 大きな?

  3. サイズ • 2TB以上ある仮想マシンイメージ – # ls /home/vmimages/ – 2464262586368 Mar

    26 20:55 foo.qcow2 – 2444 GB • しかしログインして調べると実容量は – # df – Filesystem 1K-ブロック 使用 使用可 使用% マウント位置 – /dev/hda1 79356392 8846556 66413672 12% / – /dev/hda3 1804851508 375244648 1336446732 22% /project – # df -h – Filesystem サイズ 使用 残り 使用% マウント位置 – /dev/hda1 76G 8.5G 64G 12% / – /dev/hda3 1.7T 358G 1.3T 22% /project • 2TB近く無駄な領域!
  4. qcow2イメージとは • qcowは、ホストされた仮想マシンモニターであるQEMUが使用する ディスクイメージファイルのファイル形式です。[1]「QEMUコピーオン ライト」の略で、実際に必要になるまでストレージの割り当てを遅ら せるディスクストレージ最適化戦略を使用します。 • qcowディスクイメージの主な特徴の1つは、データが追加されると、 この形式のファイルが大きくなる可能性があることです。これによ り、ファイルの一部が空であっても、イメージスペース全体をファイ

    ルに割り当てるrawディスクイメージよりも小さいファイルサイズが 可能になります。 • qcow2は、qcow形式の更新バージョンです。qcow2はAES暗号化を サポートしています。[6]元のバージョンとの違いは、qcow2が複数 のスナップショットをサポートし、それらを保存するためのより新し い、より柔軟なモデルを使用していることです。 • https://en.wikipedia.org/wiki/Qcow
  5. 小さい? • 2TB以上ある仮想マシンイメージ – # ls /home/vmimages/ – 2464262586368 Mar

    26 20:55 foo.qcow2 – 2444 GB • しかしログインして調べると実容量は – # df – Filesystem 1K-ブロック 使用 使用可 使用% マウント位置 – /dev/hda1 79356392 8846556 66413672 12% / – /dev/hda3 1804851508 375244648 1336446732 22% /project – # df -h – Filesystem サイズ 使用 残り 使用% マウント位置 – /dev/hda1 76G 8.5G 64G 12% / – /dev/hda3 1.7T 358G 1.3T 22% /project • 2TB近く無駄な領域!
  6. 縮小したい • virt-sparsify コマンドで縮小可能らしい • libguestfs(RHEL8系)に含まれる – rpm -qf `which

    virt-sparsify` – libguestfs-tools-c-1.40.2- 25.0.1.module+el8+1214+3bec0e59.x86_64
  7. ぐぐる • あまり日本語情報がない • https://milestone-of-se.nesuke.com/sv- basic/linux-basic/resize-kvm-image-sparse-file/ • KVMホスト上で libguestfs-tools-c をインストール

    し、 virt-sparsify というコマンドを使うだけです。な お、ゲストOSは事前にシャットダウンしてから実 行しましょう。 • # yum install libguestfs-tools-c # virt-sparsify before-guest.img after-guest.img
  8. やってみる(1) • # virt-sparsify foo.qcow2 foo_sparsify.qcow2 virt-sparsify: warning: There may

    not be enough free space on /tmp. You may need to set TMPDIR to point to a directory with more free space. • TMPが足りない
  9. やってみる(2) • # export TMPDIR=/home/syoshida/tmp/; time virt-sparsify foo.qcow2 foo_sparsify.qcow2 •

    [ 0.0] Create overlay file in /home/syoshida/tmp/ to protect source disk • [ 0.0] Examine source disk • virt-sparsify: error: libguestfs error: could not create appliance through • libvirt. • Try running qemu directly without libvirt using this environment variable: • export LIBGUESTFS_BACKEND=direct • Original error from libvirt: Cannot access storage file • '/home/syoshida/tmp/libguestfsDpkgQX/overlay1.qcow2' (as uid:107, gid:107): • Permission denied [code=38 int1=13] • If reporting bugs, run virt-sparsify with debugging enabled and include the • complete output: • virt-sparsify -v -x [...] # 何故か動かない LIBGUESTFS_BACKENDと言うのを指定してみるといいらしい?
  10. やってみる(3) # export TMPDIR=/home/syoshida/tmp/; export LIBGUESTFS_BACKEND=direct ; time virt-sparsify foo.qcow2

    foo_sparsify.qcow2 • [ 0.0] Create overlay file in /home/syoshida/tmp/ to protect source disk • [ 0.0] Examine source disk • [ 2.4] Fill free space in /dev/sda1 with zero • 100% ⟦▒▒▒▒▒▒▒▒⟧ 00:00 • [ 114.0] Clearing Linux swap on /dev/sda2 • 100% ⟦▒▒▒▒▒▒▒▒⟧ 00:00 • [ 131.0] Fill free space in /dev/sda3 with zero • ◒ 13% ⟦▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒══════════════════════════════════════════════════════════════════ • ══════════════════════════════════════════════════════════⟧ 35:38 • virt-sparsify: error: libguestfs error: appliance closed the connection • unexpectedly. • This usually means the libguestfs appliance crashed. • Do: • export LIBGUESTFS_DEBUG=1 LIBGUESTFS_TRACE=1 • and run the command again. For further information, read: • http://libguestfs.org/guestfs-faq.1.html#debugging-libguestfs • You can also run 'libguestfs-test-tool' and post the *complete* output • into a bug report or message to the libguestfs mailing list. • If reporting bugs, run virt-sparsify with debugging enabled and include the • complete output: • virt-sparsify -v -x [...] # デバックオプション&トレース取れ?
  11. やってみる(4) #export TMPDIR=/home/syoshida/tmp/; export LIBGUESTFS_BACKEND=direct;export LIBGUESTFS_DEBUG=1 LIBGUESTFS_TRACE=1 ; time virt-sparsify

    foo.qcow2 foo_sparsify.qcow2
  12. Coredump(1) • [ 488.510615] guestfsd invoked oom-killer: gfp_mask=0x6201ca(GFP_HIGHUSER_MOVABLE|__GFP_WRITE), nodemask=(null), order=0,

    oom_score_adj=0 • [ 488.512379] guestfsd cpuset=/ mems_allowed=0 • [ 488.512878] CPU: 0 PID: 215 Comm: guestfsd Not tainted 4.18.0-147.5.1.el8.x86_64 #1 • [ 488.513673] Hardware name: Red Hat KVM, BIOS 1.11.1-4.module+el8+68+4e32959b 04/01/2014 • [ 488.514470] Call Trace: • [ 488.514821] dump_stack+0x5c/0x80 • [ 488.515195] dump_header+0x6e/0x27a • [ 488.515571] ? try_to_free_pages+0xe8/0x1c0 • [ 488.516006] oom_kill_process.cold.29+0xb/0x10 • [ 488.516454] out_of_memory+0x1ba/0x490 • [ 488.516843] __alloc_pages_slowpath+0xc0f/0xce0 • [ 488.517300] __alloc_pages_nodemask+0x245/0x280 • [ 488.517761] pagecache_get_page+0xb5/0x2c0 • [ 488.518183] grab_cache_page_write_begin+0x1f/0x40 • [ 488.518968] ext4_write_begin+0xc4/0x5b0 [ext4] • [ 488.519444] generic_perform_write+0xf4/0x1b0 • [ 488.519901] ? file_update_time+0x5e/0x130 • [ 488.520324] ? __switch_to_asm+0x35/0x70 • [ 488.520724] __generic_file_write_iter+0xfe/0x1c0 • [ 488.521212] ext4_file_write_iter+0xc6/0x3b0 [ext4] • [ 488.521711] new_sync_write+0x124/0x170 • [ 488.522099] vfs_write+0xa5/0x1a0 • [ 488.522446] ksys_write+0x4f/0xb0 • [ 488.522791] do_syscall_64+0x5b/0x1b0 • [ 488.523166] entry_SYSCALL_64_after_hwframe+0x65/0xca • [ 488.523696] RIP: 0033:0x7f809a73fe18 • [ 488.641593] __get_free_pages+0xa/0x30 • [ 488.641980] pgd_alloc+0x1f/0x1a0 • [ 488.642316] mm_init+0x195/0x280 • [ 488.642646] copy_mm+0x137/0x630 • [ 488.642972] ? __lock_task_sighand+0x2c/0x70 • [ 488.643406] copy_process.part.34+0xe53/0x1900 • [ 488.641593] __get_free_pages+0xa/0x30 • [ 488.641980] pgd_alloc+0x1f/0x1a0 • [ 488.642316] mm_init+0x195/0x280 • [ 488.642646] copy_mm+0x137/0x630 • [ 488.642972] ? __lock_task_sighand+0x2c/0x70 • [ 488.643406] copy_process.part.34+0xe53/0x1900 [ 488.643868] _do_fork+0xe3/0x3a0 [ 488.644220] ? generic_file_llseek_size+0xa4/0xf0 [ 488.644699] do_syscall_64+0x5b/0x1b0 [ 488.645071] entry_SYSCALL_64_after_hwframe+0x65/0xca [ 488.645582] RIP: 0033:0x7ff96ca995e2 [ 488.645950] Code: db 0f 85 11 01 00 00 64 4c 8b 0c 25 10 00 00 00 45 31 c0 4d 8d 91 d0 02 00 00 31 d2 31 f6 bf 11 00 20 01 b8 38 00 00 00 0f 05 <48> 3d 00 f0 ff ff 0f 87 aa 00 00 00 89 c5 85 c0 0f 85 b8 00 00 00 [ 488.647801] RSP: 002b:00007ffd0d05c550 EFLAGS: 00000246 ORIG_RAX: 0000000000000038 [ 488.648540] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007ff96ca995e2 [ 488.649254] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000001200011 [ 488.649987] RBP: 0000000000000001 R08: 0000000000000000 R09: 00007ff96d3de740 [ 488.650695] R10: 00007ff96d3dea10 R11: 0000000000000246 R12: 00007ffd0d05c590 [ 488.651401] R13: 00007ffd0d05c610 R14: 0000556ec9161eb9 R15: 0000556ec989cc00 [ 488.654356] Kernel Offset: 0x32800000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) [ 488.655426] Rebooting in 1 seconds.. libguestfs: child_cleanup: 0x55c1b6c27f20: child process died libguestfs: sending SIGTERM to process 9015 libguestfs: qemu maxrss 625156K libguestfs: trace: zero_free_space = -1 (error) virt-sparsify: error: libguestfs error: appliance closed the connection unexpectedly, see earlier error messages If reporting bugs, run virt-sparsify with debugging enabled and include the complete output:
  13. Coredump(2) • libguestfs: trace: close • libguestfs: closing guestfs handle

    0x55c1b6c27f20 (state 0) • libguestfs: command: run: rm • libguestfs: command: run: ¥ -rf /home/syoshida/tmp/libguestfsrXzeyV • libguestfs: command: run: rm • libguestfs: command: run: ¥ -rf /tmp/libguestfs3Cs1um • libguestfs: trace: close • libguestfs: closing guestfs handle 0x55c1b6c22f40 (state 0) • libguestfs: trace: close • libguestfs: closing guestfs handle 0x55c1b6c213f0 (state 0) • libguestfs: trace: close • libguestfs: closing guestfs handle 0x55c1b6c1eaf0 (state 0) • [ 627.158649] [ 163] 0 163 25163 346 212992 0 -1000 systemd-udevd • [ 627.159593] Out of memory and no killable processes... • [ 627.160151] Kernel panic - not syncing: System is deadlocked on memory • [ 627.160151] • [ 627.161014] CPU: 0 PID: 1 Comm: init Not tainted 4.18.0-147.5.1.el8.x86_64 #1 • [ 627.161763] Hardware name: Red Hat KVM, BIOS 1.11.1- 4.module+el8+68+4e32959b 04/01/2014 • [ 627.162615] Call Trace: • [ 627.162893] dump_stack+0x5c/0x80 • [ 627.163261] panic+0xe7/0x247 • [ 627.163583] out_of_memory.cold.32+0x5e/0x80 • [ 627.164040] __alloc_pages_slowpath+0xc0f/0xce0 • [ 627.164543] __alloc_pages_nodemask+0x245/0x280 • [ 627.165036] __get_free_pages+0xa/0x30 • [ 627.165436] pgd_alloc+0x1f/0x1a0 • [ 627.165814] mm_init+0x195/0x280 • [ 627.166161] copy_mm+0x137/0x630 • [ 627.166509] ? __lock_task_sighand+0x2c/0x70 • [ 627.166981] copy_process.part.34+0xe53/0x1900 • [ 627.167451] _do_fork+0xe3/0x3a0 • [ 627.167805] ? __ia32_sys_vfork+0x20/0x20 • [ 627.168247] do_syscall_64+0x5b/0x1b0 • [ 627.168638] entry_SYSCALL_64_after_hwframe+0x65/0xca • [ 627.169183] RIP: 0033:0x7f6714a4b5e2 • [ 627.169583] Code: Bad RIP value. • [ 627.169939] RSP: 002b:00007ffd5f5dc9b0 EFLAGS: 00000246 ORIG_RAX: 0000000000000038 • [ 627.170757] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f6714a4b5e2 • [ 627.171508] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000001200011 [ 627.172284] RBP: 0000000000000001 R08: 0000000000000000 R09: 00007f6715390740 [ 627.173059] R10: 00007f6715390a10 R11: 0000000000000246 R12: 00007ffd5f5dc9f0 [ 627.173804] R13: 00007ffd5f5dca70 R14: 000055899712deb9 R15: 0000558998ce0c00 [ 627.176885] Kernel Offset: 0x20c00000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) [ 627.178040] Rebooting in 1 seconds.. libguestfs: child_cleanup: 0x558ca5ca7e00: child process died libguestfs: sending SIGTERM to process 9654 libguestfs: qemu maxrss 628176K libguestfs: trace: zero_free_space = -1 (error) virt-sparsify: error: libguestfs error: appliance closed the connection unexpectedly, see earlier error messages If reporting bugs, run virt-sparsify with debugging enabled and include the complete output: virt-sparsify -v -x [...] libguestfs: trace: close libguestfs: closing guestfs handle 0x558ca5ca7e00 (state 0) libguestfs: command: run: rm libguestfs: command: run: ¥ -rf /home/syoshida/tmp/libguestfscldGqQ libguestfs: command: run: rm libguestfs: command: run: ¥ -rf /tmp/libguestfs4MUVu9 libguestfs: trace: close libguestfs: closing guestfs handle 0x558ca5ca2f50 (state 0) libguestfs: trace: close libguestfs: closing guestfs handle 0x558ca5ca13f0 (state 0) libguestfs: trace: close libguestfs: closing guestfs handle 0x558ca5c9eaf0 (state 0) https://bugzilla.redhat.com/show_bug.cgi?id=914934 https://bugzilla.redhat.com/show_bug.cgi?id=866994
  14. メモリ不足? • [ 488.510615] guestfsd invoked oom-killer: gfp_mask=0x6201ca(GFP_HIGHUSER_MOVABLE|__GFP_W RITE), nodemask=(null),

    order=0, oom_score_adj=0 • [ 627.159593] Out of memory and no killable processes... • [ 627.160151] Kernel panic - not syncing: System is deadlocked on memory • https://bugzilla.redhat.com/show_bug.cgi?id=914934 – Bug 914934 - oom-killer kills guestfsd when tar-in a lot of data • https://bugzilla.redhat.com/show_bug.cgi?id=866994 – Bug 866994 - tgz-out causes memory leak in guestfsd
  15. メモリ関係を探す • どうやって探したか忘れた

  16. libguestfs プロジェクト • libguestfs プロジェクトは、他にも以下のような有用なツールを作成してい ます。 • virt-edit は、イメージ内のファイルを編集できます。 •

    virt-df は、イメージ内の空き容量を表示できます。 • virt-resize は、イメージの容量を変更できます。 • virt-sysprep は、イメージを配布する準備ができます (例えば、SSH ホスト 鍵の削除、MAC アドレス情報の削除、ユーザーアカウントの削除)。 • virt-sparsify は、イメージをスパース化できます。 • virt-p2v は、物理マシンを KVM で動作するイメージに変換できます。 • virt-v2v は、Xen や VMware のイメージを KVM のイメージに変換できます。 • https://docs.openstack.org/ja/image-guide/modify-images.html#virt-tools
  17. guestfish • guestfish プログラムは、仮想マシンイメージ 内のファイルを編集できる、 libguestfs プロ ジェクトのツールです • https://docs.openstack.org/ja/image-

    guide/modify-images.html#guestfish
  18. LIBGUESTFS_MEMSIZE • https://access.redhat.com/solutions/4030891 • How to increase default LIBGUESTFS_MEMSIZE of

    guestfish in RHEL? • Facing issue with KVM guest as qemu is getting killed due to out of memory. • Default memsize of guestfish is 500M in RHEL, how to increase it? • (後は契約者のみ)
  19. ソースを見てみる • + /* Choose a suitable memory size. Previously

    we tried to choose • + * a minimal memory size, but this isn't really necessary since • + * recent QEMU and KVM don't do anything nasty like locking • + * memory into core any more. Thus we can safely choose a • + * large, generous amount of memory, and it'll just get swapped • + * on smaller systems. • + */ • + str = getenv ("LIBGUESTFS_MEMSIZE"); • + if (str) { • + if (sscanf (str, "%d", &g->memsize) != 1 || g->memsize <= 256) { • + fprintf (stderr, "libguestfs: non-numeric or too small value for LIBGUESTFS_MEMSIZE¥n"); • + goto error; • + } • + } else • + g->memsize = 500; • + • http://git.annexia.org/?p=libguestfs.git;a=commitdiff;h=3d15f7e652340777514ff30c3cfc560a90b6 12ec • デフォルト500Mがハードコードされてるのを確認
  20. やってみる(5) • # export TMPDIR=/home/syoshida/tmp/; export LIBGUESTFS_DEBUG=1 LIBGUESTFS_TRACE=1 ; export

    LIBGUESTFS_MEMSIZE=20480 ;time virt- sparsify foo.qcow2 foo_sparsify.qcow2
  21. 完了! • (略) • [2769.1] Copy to destination and make

    sparse • [4677.7] Sparsify operation completed with no errors. • virt-sparsify: Before deleting the old disk, carefully check that the • target disk boots and works correctly. • real 78m25.609s • user 46m17.532s • sys 700m35.423s • 11時間40分!なお実行したマシンはSSD + EPYC # ps • PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND • 10138 root 20 0 25.2g 20.0g 19080 R 680.1 8.0 27:26.83 qemu-kvm
  22. 結果 • # ls • 2464262586368 Mar 26 20:55 foo.qcow2

    • 373870821376 Mar 26 22:41 foo_sparsify.qcow2 • 2464GBから374GBへ 85%縮小!
  23. 宣伝 • 4/17 Open Source unConference 2021 Online/Spring • https://ospn.connpass.com/event/208385/

    • PyCon JPのスタッフも募集してます! • https://pyconjp.blogspot.com/2021/01/2021- staff-application-start.html