diff options
-rw-r--r-- | nova/tests/test_libvirt.py | 27 | ||||
-rwxr-xr-x | nova/virt/libvirt/driver.py | 96 | ||||
-rwxr-xr-x | nova/virt/libvirt/utils.py | 38 |
3 files changed, 70 insertions, 91 deletions
diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py index 981cb20bd..cb8be6361 100644 --- a/nova/tests/test_libvirt.py +++ b/nova/tests/test_libvirt.py @@ -2875,21 +2875,29 @@ class LibvirtConnTestCase(test.TestCase): # NOTE(vish): verifies destroy doesn't raise if the instance disappears conn._destroy(instance) - def test_available_least_handles_missing(self): + def test_disk_over_committed_size_total(self): # Ensure destroy calls managedSaveRemove for saved instance. conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) def list_instances(): - return ['fake'] + return ['fake1', 'fake2'] self.stubs.Set(conn, 'list_instances', list_instances) + fake_disks = {'fake1': [{'type': 'qcow2', 'path': '/somepath/disk1', + 'virt_disk_size': '10737418240', + 'backing_file': '/somepath/disk1', + 'disk_size':'83886080'}], + 'fake2': [{'type': 'raw', 'path': '/somepath/disk2', + 'virt_disk_size': '10737418240', + 'backing_file': '/somepath/disk2', + 'disk_size':'10737418240'}]} + def get_info(instance_name): - raise exception.InstanceNotFound(instance_id='fake') + return jsonutils.dumps(fake_disks.get(instance_name)) self.stubs.Set(conn, 'get_instance_disk_info', get_info) - result = conn.get_disk_available_least() - space = fake_libvirt_utils.get_fs_info(CONF.instances_path)['free'] - self.assertEqual(result, space / 1024 ** 3) + result = conn.get_disk_over_committed_size_total() + self.assertEqual(result, 10653532160) def test_cpu_info(self): conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True) @@ -3455,11 +3463,8 @@ class HostStateTestCase(test.TestCase): def get_cpu_info(self): return HostStateTestCase.cpu_info - def get_local_gb_total(self): - return 100 - - def get_local_gb_used(self): - return 20 + def get_local_gb_info(self): + return {'total': 100, 'used': 20, 'free': 80} def get_memory_mb_total(self): return 497 diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index f8b4017b1..97c1166fc 100755 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -2422,23 +2422,25 @@ class LibvirtDriver(driver.ComputeDriver): return self._conn.getInfo()[1] @staticmethod - def get_local_gb_total(): - """Get the total hdd size(GB) of physical computer. - - :returns: - The total amount of HDD(GB). - Note that this value shows a partition where - NOVA-INST-DIR/instances mounts. + def get_local_gb_info(): + """Get local storage info of the compute node in GB. + :returns: A dict containing: + :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) """ if CONF.libvirt_images_type == 'lvm': - vg_total = libvirt_utils.volume_group_total_space( + info = libvirt_utils.get_volume_group_info( CONF.libvirt_images_volume_group) - return vg_total / (1024 ** 3) else: - stats = libvirt_utils.get_fs_info(CONF.instances_path) - return stats['total'] / (1024 ** 3) + info = libvirt_utils.get_fs_info(CONF.instances_path) + + for (k, v) in info.iteritems(): + info[k] = v / (1024 ** 3) + + return info def get_vcpu_used(self): """Get vcpu usage number of physical computer. @@ -2504,24 +2506,6 @@ class LibvirtDriver(driver.ComputeDriver): # Convert it to MB return self.get_memory_mb_total() - avail / 1024 - def get_local_gb_used(self): - """Get the free hdd size(GB) of physical computer. - - :returns: - The total usage of HDD(GB). - Note that this value shows a partition where - NOVA-INST-DIR/instances mounts. - - """ - - if CONF.libvirt_images_type == 'lvm': - vg_used = libvirt_utils.volume_group_used_space( - CONF.libvirt_images_volume_group) - return vg_used / (1024 ** 3) - else: - stats = libvirt_utils.get_fs_info(CONF.instances_path) - return stats['used'] / (1024 ** 3) - def get_hypervisor_type(self): """Get hypervisor type. @@ -2693,17 +2677,35 @@ class LibvirtDriver(driver.ComputeDriver): :param nodename: ignored in this driver :returns: dictionary containing resource info """ + + def _get_disk_available_least(): + """Return total real disk available least size. + + The size of available disk, when block_migration command given + disk_over_commit param is FALSE. + + The size that deducted real instance disk size from the total size + of the virtual disk of all instances. + + """ + disk_free_gb = disk_info_dict['free'] + disk_over_committed = self.get_disk_over_committed_size_total() + # Disk available least size + available_least = disk_free_gb * (1024 ** 3) - disk_over_committed + return (available_least / (1024 ** 3)) + + disk_info_dict = self.get_local_gb_info() dic = {'vcpus': self.get_vcpu_total(), 'memory_mb': self.get_memory_mb_total(), - 'local_gb': self.get_local_gb_total(), + 'local_gb': disk_info_dict['total'], 'vcpus_used': self.get_vcpu_used(), 'memory_mb_used': self.get_memory_mb_used(), - 'local_gb_used': self.get_local_gb_used(), + 'local_gb_used': disk_info_dict['used'], 'hypervisor_type': self.get_hypervisor_type(), 'hypervisor_version': self.get_hypervisor_version(), 'hypervisor_hostname': self.get_hypervisor_hostname(), 'cpu_info': self.get_cpu_info(), - 'disk_available_least': self.get_disk_available_least()} + 'disk_available_least': _get_disk_available_least()} return dic def check_can_live_migrate_destination(self, ctxt, instance_ref, @@ -3232,22 +3234,11 @@ class LibvirtDriver(driver.ComputeDriver): 'disk_size': dk_size}) return jsonutils.dumps(disk_info) - def get_disk_available_least(self): - """Return disk available least size. - - The size of available disk, when block_migration command given - disk_over_commit param is FALSE. - - The size that deducted real nstance disk size from the total size - of the virtual disk of all instances. - - """ - # available size of the disk - dk_sz_gb = self.get_local_gb_total() - self.get_local_gb_used() - + def get_disk_over_committed_size_total(self): + """Return total over committed disk size for all instances.""" # Disk size that all instance uses : virtual_size - disk_size instances_name = self.list_instances() - instances_sz = 0 + disk_over_committed_size = 0 for i_name in instances_name: try: disk_infos = jsonutils.loads( @@ -3255,7 +3246,7 @@ class LibvirtDriver(driver.ComputeDriver): for info in disk_infos: i_vt_sz = int(info['virt_disk_size']) i_dk_sz = int(info['disk_size']) - instances_sz += i_vt_sz - i_dk_sz + disk_over_committed_size += i_vt_sz - i_dk_sz except OSError as e: if e.errno == errno.ENOENT: LOG.error(_("Getting disk size of %(i_name)s: %(e)s") % @@ -3267,9 +3258,7 @@ class LibvirtDriver(driver.ComputeDriver): pass # NOTE(gtt116): give change to do other task. greenthread.sleep(0) - # Disk available least size - available_least_size = dk_sz_gb * (1024 ** 3) - instances_sz - return (available_least_size / 1024 / 1024 / 1024) + return disk_over_committed_size def unfilter_instance(self, instance_ref, network_info): """See comments of same method in firewall_driver.""" @@ -3572,9 +3561,10 @@ class HostState(object): data["vcpus"] = self.driver.get_vcpu_total() data["vcpus_used"] = self.driver.get_vcpu_used() data["cpu_info"] = jsonutils.loads(self.driver.get_cpu_info()) - data["disk_total"] = self.driver.get_local_gb_total() - data["disk_used"] = self.driver.get_local_gb_used() - data["disk_available"] = data["disk_total"] - data["disk_used"] + disk_info_dict = self.driver.get_local_gb_info() + data["disk_total"] = disk_info_dict['total'] + data["disk_used"] = disk_info_dict['used'] + data["disk_available"] = disk_info_dict['free'] data["host_memory_total"] = self.driver.get_memory_mb_total() data["host_memory_free"] = (data["host_memory_total"] - self.driver.get_memory_mb_used()) diff --git a/nova/virt/libvirt/utils.py b/nova/virt/libvirt/utils.py index 20af11ddc..cf3fd9d26 100755 --- a/nova/virt/libvirt/utils.py +++ b/nova/virt/libvirt/utils.py @@ -205,7 +205,8 @@ def create_lvm_image(vg, lv, size, sparse=False): :size: size of image in bytes :sparse: create sparse logical volume """ - free_space = volume_group_free_space(vg) + vg_info = get_volume_group_info(vg) + free_space = vg_info['free'] def check_size(vg, lv, size): if size > free_space: @@ -232,33 +233,14 @@ def create_lvm_image(vg, lv, size, sparse=False): execute(*cmd, run_as_root=True, attempts=3) -def volume_group_free_space(vg): - """Return available space on volume group in bytes. - - :param vg: volume group name - """ - out, err = execute('vgs', '--noheadings', '--nosuffix', - '--units', 'b', '-o', 'vg_free', vg, - run_as_root=True) - return int(out.strip()) - - -def volume_group_total_space(vg): - """Return total space on volume group in bytes. - - :param vg: volume group name - """ - - out, err = execute('vgs', '--noheadings', '--nosuffix', - '--units', 'b', '-o', 'vg_size', vg, - run_as_root=True) - return int(out.strip()) - - -def volume_group_used_space(vg): - """Return available space on volume group in bytes. +def get_volume_group_info(vg): + """Return free/used/total space info for a volume group in bytes :param vg: volume group name + :returns: A dict containing: + :total: How big the filesystem is (in bytes) + :free: How much space is free (in bytes) + :used: How much space is used (in bytes) """ out, err = execute('vgs', '--noheadings', '--nosuffix', @@ -270,7 +252,9 @@ def volume_group_used_space(vg): if len(info) != 2: raise RuntimeError(_("vg %s must be LVM volume group") % vg) - return int(info[0]) - int(info[1]) + return {'total': int(info[0]), + 'free': int(info[1]), + 'used': int(info[0]) - int(info[1])} def list_logical_volumes(vg): |