通过将trim与unmap指令提供的功能叫discard - search: DISCARD SUPPORT IN QEMU-KVM
对于SSD, trim指令允许操作系统在SSD上将不再使用的数据通知到SSD底层并在其内部将数据擦除掉。
虚机的vdisk与SSD类似, 也存在若不及时删除数据的话会造成数据越来越大, 这样virtio-scsi虚拟磁盘上出现了一个类似trim的指令叫unmap.
1, 虚机定义增加额外的discard="unmap" (sda)
NOTE: 只对virtio-scsi驱动有效: glance image-update --property hw_scsi_model=virtio-scsi --property hw_disk_bus=scsi
2, 虚机内部挂载磁盘时增加对discard的支持: mount -o discard /dev/sda1 /sda
3, 测试脚本
$ for _ in {1..3}; do
/bin/dd if=/dev/urandom of=/sda/file.$RANDOM bs=1M count=100 && sync
/bin/dd if=/dev/urandom of=/sdb/file.$RANDOM bs=1M count=100 && sync
/bin/rm -f /sda/file.* /sdb/file.* && sync
4, 使用fstrim命令手动一次性触发discard操作: /mntpoint. 或者如果使用上面脚试脚本后应该在host机器上用下列命令观察到自动trim
$ du -h sd{a,b}.img
34M sda.img
138M sdb.img
另外, ceph驱动也支持trim, 除了使用virtio-scsi驱动(glance image-update --property hw_scsi_model=virtio-scsi --property hw_disk_bus=scsi), 也需要编辑nova.conf的[libvirt]段添加hw_disk_discard = unmap (注: cinder通过[ceph] section中report_discard_supported = True 来支持discard, so it is possible to configure Cinder per backend.), 这时虚机的libvirt xml配置文件应该有所反应, 或者 , 在虚机里面查看/sys/block/sdb/queue/discard_*, 见:
https://ceph.io/geen-categorie/openstack-and-ceph-rbd-discard/
http://www.sebastien-han.fr/blog/2016/05/11/OpenStack-Cinder-discard-support-for-Ceph-in-Mitaka/
# $cinder/cinder/volume/manager.py
1759 # Add discard flag to connection_info if not set in the driver and
1760 # configured to be reported.
1761 if conn_info['data'].get('discard') is None:
1762 discard_supported = (self.driver.configuration
1763 .safe_get('report_discard_supported'))
1764 if discard_supported:
1765 conn_info['data']['discard'] = True
# $nova/nova/virt/libvirt/volume/volume.py
93 # Configure usage of discard
94 if data.get('discard', False) is True:
95 conf.driver_discard = 'unmap'
#./nova/virt/libvirt/imagebackend.py
82 class Image(object):
86 def __init__(self, path, source_type, driver_format, is_block_dev=False):
...
105 self.discard_mode = CONF.libvirt.hw_disk_discard
148 def libvirt_info(self, ...):
166 info.driver_discard = self.discard_mode
# $nova/nova/virt/libvirt/config.py
1009 if self.driver_discard is not None:
1010 drv.set("discard", self.driver_discard)
# $nova/virt/libvirt/driver.py
1765 def attach_volume(self, ...)
...
1792 disk_info = blockinfo.get_info_from_bdm(
1793 instance, CONF.libvirt.virt_type, instance.image_meta, bdm)
1794 if disk_info['bus'] == 'scsi':
1795 disk_info['unit'] = self._get_scsi_controller_max_unit(guest) + 1
1797 conf = self._get_volume_config(connection_info, disk_info)
1798
1799 self._check_discard_for_attach_volume(conf, instance)
1748 def _check_discard_for_attach_volume(self, conf, instance):
1749 """Perform some checks for volumes configured for discard support.
1750
1751 If discard is configured for the volume, and the guest is using a
1752 configuration known to not work, we will log a message explaining
1753 the reason why.
1754 """
1755 if conf.driver_discard == 'unmap' and conf.target_bus == 'virtio':
1756 LOG.debug('Attempting to attach volume %(id)s with discard '
1757 'support enabled to an instance using an '
1758 'unsupported configuration. target_bus = '
1759 '%(bus)s. Trim commands will not be issued to '
1760 'the storage device.',
1761 {'bus': conf.target_bus,
1762 'id': conf.serial},
1763 instance=instance)