如何通过API上传qcow2镜像至libvirt存储并保留压缩特性
使用libvirt-python上传qcow2镜像后物理文件被扩展为虚拟大小的问题
我尝试通过libvirt-python模块,结合qemu-img info输出的信息,用XML创建存储卷后通过流上传qcow2镜像。操作完成后磁盘可正常使用,但libvirt会将物理文件大小扩展至与虚拟大小一致。
实现代码
import libvirt import pathlib conn = libvirt.open("qemu:///system") template_pool = conn.storagePoolLookupByName("default") image_filename = "fedora-cloud-base-38-x86_64.qcow2" spool_file = pathlib.Path("Fedora-Cloud-Base-38-1.6.x86_64.qcow2") # 大小来自`qemu-img info --output=json Fedora-Cloud-Base-38-1.6.x86_64.qcow2`的输出 image_size = 497291264 image_vsize = 5368709120 stgvol_xml = f""" <volume> <name>{image_filename}</name> <allocation>{ image_size }</allocation> <capacity unit="bytes">{image_vsize}</capacity> </volume>""" stgvol = template_pool.createXML(stgvol_xml, 0) def stream_handler(stream, data, file_): return file_.read(data) stream = conn.newStream(0) stgvol.upload(stream, 0, 0) with spool_file.open(mode="rb") as f: stream.sendAll(stream_handler, f) stream.finish()
测试镜像信息
测试使用Fedora Cloud Base 38的qcow2镜像,刚下载完成时SHA256哈希验证通过,已分配大小为475MB,与qemu-img info输出一致:
ls -lsh Fedora-Cloud-Base-38-1.6.x86_64.qcow2 475M -rw-r--r-- 1 dcode primarygroup 475M Jun 3 10:05 Fedora-Cloud-Base-38-1.6.x86_64.qcow2 sha256sum Fedora-Cloud-Base-38-1.6.x86_64.qcow2 d334670401ff3d5b4129fcc662cf64f5a6e568228af59076cc449a4945318482 Fedora-Cloud-Base-38-1.6.x86_64.qcow2 qemu-img info Fedora-Cloud-Base-38-1.6.x86_64.qcow2 image: Fedora-Cloud-Base-38-1.6.x86_64.qcow2 file format: qcow2 virtual size: 5 GiB (5368709120 bytes) disk size: 474 MiB cluster_size: 65536 Format specific information: compat: 0.10 compression type: zlib refcount bits: 16
上传后的异常现象
镜像上传到存储池后,文件被扩展为完整虚拟大小的稀疏镜像,哈希值发生改变,但qemu-img info显示的镜像信息保持不变:
ls -lsh Fedora-Cloud-Base-38-1.6.x86_64.qcow2 475M -rw-------. 1 root root 5.0G Jun 3 15:10 Fedora-Cloud-Base-38-1.6.x86_64.qcow2 sha256sum Fedora-Cloud-Base-38-1.6.x86_64.qcow2 2327ccac1781e9ff561737eb986f9863ff65827fe53efd565e6c2b801273625f Fedora-Cloud-Base-38-1.6.x86_64.qcow2 qemu-img info Fedora-Cloud-Base-38-1.6.x86_64.qcow2 image: Fedora-Cloud-Base-38-1.6.x86_64.qcow2 file format: qcow2 virtual size: 5 GiB (5368709120 bytes) disk size: 474 MiB cluster_size: 65536 Format specific information: compat: 0.10 compression type: zlib refcount bits: 16
临时方案与尝试
- 曾使用带
--compress选项的virt-sparsify命令处理生成的磁盘,可将文件大小缩减至接近原始值,但无法得到与原文件一致的哈希值。且代码可能无法直接访问libvirt存储池,这并非理想方案。 - 尝试过libvirt-python示例中的sparsestream.py,但未理解其原理,且判断这并非稀疏性问题,而是镜像压缩特性的保留问题。
内容的提问来源于stack exchange,提问作者dcode
相关产品推荐
相关产品推荐

