模块中 host_passes 函数分析
requested_disk 为创建虚机需要申请的磁盘。
host_state.free_disk_mb 为compute主机空闲磁盘,数据来源:nova.scheduler.host_manager.HostState.__init__() 中的compute
free_gb = compute.free_disk_gb # compute host vm instance所在磁盘的空闲空间
least_gb = compute.disk_available_least # compute host 计算获取如下
在nova.scheduler.host_manager.HostState.update_from_compute_node() 中更新
host_state.free_disk_mb 以min(free_gb,least_gb )最新值。
重点是free_disk_mb 在过滤中至关重要。
compute.disk_available_least 计算详见nova.virt.libvirt.driver.LibvirtDriver.get_available_resource()
通过os.ovfs() 获取compute host主机中instance所在目录的文件系统的磁盘情况: 总磁盘空间、空闲磁盘空间、可用磁盘空间
可用空间 减去 compute host在主机上已经创建的虚机申请的磁盘大小减去已使用的磁盘大小。
详见: nova.virt.libvirt.driver.LibvirtDriver._get_disk_over_committed_size_total()
nova.virt.libvirt.driver.LibvirtDriver._get_instance_disk_info()
如下是分析工程中间数据:
在 libvirt 通过虚拟化层获取资源信息
根据nova.conf中libvirt的libvirt.images_type的配置项,不同及时磁盘空间的方式不同:
nova.virt.libvirt.driver.LibvirtDriver._get_local_gb_info
if CONF.libvirt.images_type == 'lvm':
info = lvm.get_volume_group_info(
CONF.libvirt.images_volume_group)
elif CONF.libvirt.images_type == 'rbd':
info = LibvirtDriver._get_rbd_driver().get_pool_info()
else:
info = libvirt_utils.get_fs_info(CONF.instances_path)
for (k, v) in six.iteritems(info):
info[k] = v / units.Gi // units.Gi=1024**3 即单位从B转为GB
return info
:total: How big the overall usable filesystem is (in gigabytes)
:free: How much space is free (in gigabytes)
:used: How much space is used (in gigabytes)
缺省是default值,libvirt_utils.get_fs_info(CONF.instances_path) conf.instances_path=/var/lib/nova
libvirt_utils.get_fs_info(CONF.instances_path):
""" :free: How much space is free (in bytes)
:used: How much space is used (in bytes)
:total: How big the filesystem is (in bytes)
"""
hddinfo = os.statvfs(path)
total = hddinfo.f_frsize * hddinfo.f_blocks = 4096*4474556 = 18327781376 = 17.07 = 17
free = hddinfo.f_frsize * hddinfo.f_bavail = 4096*2537172 = 10392256512 = 9.68 = 9
used = hddinfo.f_frsize * (hddinfo.f_blocks - hddinfo.f_bfree) = 4096*(4474556-2770234)=6980902912 = 6.50 = 6
return {'total': total,
'free': free,
'used': used}
>>> os.statvfs(path) // https://docs.python.org/2/library/statvfs.html 在v3.0版本中已经废弃 用于返回包含文件描述符fd的文件的文件系统的信息。
posix.statvfs_result( f_bsize=4096, // Preferred file system block size. 文件系统块大小
f_frsize=4096, // Fundamental file system block size. 分栈大小
f_blocks=4474556, 18327781376B // Total number of blocks in the filesystem. 文件系统数据块总数
f_bfree=2770234, 11346878464B // Total number of free blocks. 可用块数
f_bavail=2537172, 10392256512B // Free blocks available to non-super user. 非超级用户可获取的块数
f_files=1146880, // Total number of file nodes. 文件结点总数
f_ffree=1060196, // Total number of free file nodes. 可用文件结点数
f_favail=1060196, // Free nodes available to non-super user. 非超级用户的可用文件结点数
f_flag=4096, // Flags. System dependent: see statvfs() man page. 挂载标记
f_namemax=255) // Maximum file name length. 文件名最大长度
nova.virt.libvirt.driver.LibvirtDriver.get_available_resource() 获取磁盘
data["local_gb"] = disk_info_dict['total'] = 18327781376/(1024**3) = 17.07
data["local_gb_used"] = disk_info_dict['used'] = 6980902912/(1024**3) = 6.50
disk_free_gb = disk_info_dict['free'] = 10392256512/(1024**3) = 9.68
disk_over_committed = self._get_disk_over_committed_size_total() =
available_least = disk_free_gb * units.Gi - disk_over_committed =
data['disk_available_least'] = available_least / units.Gi =
#
nova.virt.libvirt.driver.LibvirtDriver._get_disk_over_committed_size_total()
"""Return total over committed disk size for all instances."""
# Disk size that all instance uses : virtual_size - disk_size
#
nova.virt.libvirt.driver.LibvirtDriver._get_instance_disk_info()
"""Get the non-volume disk information from the domain xml
:param str instance_name: the name of the instance (domain)
:param str xml: the libvirt domain xml for the instance
:param dict block_device_info: block device info for BDMs
:returns disk_info: list of dicts with keys:
* 'type': the disk type (str)
* 'path': the disk path (str)
* 'virt_disk_size': the virtual disk size (int)
* 'backing_file': backing file of a disk image (str)
* 'disk_size': physical disk size (int)
* 'over_committed_disk_size': virt_disk_size - disk_size or 0
"""
数据库中的数据
free_disk_gb 13
disk_available_least 7
local_gb_used 4
local_gb 17
df中的数据
[root@vStack ~]# df
文件系统 1K-块 已用 可用 已用% 挂载点
devtmpfs 4064616 0 4064616 0% /dev
tmpfs 4075884 16 4075868 1% /dev/shm
tmpfs 4075884 235544 3840340 6% /run
tmpfs 4075884 0 4075884 0% /sys/fs/cgroup
/dev/mapper/vstack_vstack-root 17898224 6826160 10139816 41% / 17898224*1024=18327781376 6826160*1024=6989987840 10139816*1024=10383171584
/dev/sdc 20961280 33032 20928248 1% /srv/node/sdc
/dev/sda1 487634 116596 341342 26% /boot
tmpfs 815180 0 815180 0% /run/user/0
[root@vStack ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs 3.9G 16K 3.9G 1% /dev/shm
tmpfs 3.9G 231M 3.7G 6% /run
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/mapper/vstack_vstack-root 18G 6.6G 9.7G 41% /
/dev/sdc 20G 33M 20G 1% /srv/node/sdc
/dev/sda1 477M 114M 334M 26% /boot
tmpfs 797M 0 797M 0% /run/user/0
确认 host_stat中 free_disk_mb 中的数据来源:nova.scheduler.host_manager.HostState.__init__() 中的compute
free_gb = compute.free_disk_gb
least_gb = compute.disk_available_least
nova.scheduler.host_manager.HostState.update_from_compute_node() 中 更新 host_state.free_disk_mb 以min(free_gb,least_gb )最新值。
跟踪 compute.disk_available_least 值来源 nova.virt.libvirt.driver.LibvirtDriver.get_available_resource()
通过os.ovfs() 获取compute host主机中instance所在目录的文件系统的磁盘情况。
设置 compute host的 系统磁盘的可用大小 减去 compute host中已有vm的disk_over_committed_size=virt_disk_size - disk_size 虚机申请的大小减去现有磁盘文件的大小(已计算过)
终于知道创建虚机时,磁盘不足的原因了。
|
|