self.vg_uuid = None
self.vg_thin_pool = None
self.vg_thin_pool_size = 0
+ self.vg_thin_pool_free_space = 0
self._supports_snapshot_lv_activation = None
self._supports_lvchange_ignoreskipactivation = None
else:
return []
+ def _get_thin_pool_free_space(self, vg_name, thin_pool_name):
+ """Returns available thin pool free space.
+
+ :param vg_name: the vg where the pool is placed
+ :param thin_pool_name: the thin pool to gather info for
+ :returns: Free space, calculated after the data_percent value
+
+ """
+ cmd = ['env', 'LC_ALL=C', 'LANG=C', 'lvs', '--noheadings', '--unit=g',
+ '-o', 'size,data_percent', '--separator', ':', '--nosuffix']
+
+ # NOTE(gfidente): data_percent only applies to some types of LV so we
+ # make sure to append the actual thin pool name
+ cmd.append("/dev/%s/%s" % (vg_name, thin_pool_name))
+
+ free_space = 0
+
+ try:
+ (out, err) = self._execute(*cmd,
+ root_helper=self._root_helper,
+ run_as_root=True)
+ if out is not None:
+ out = out.strip()
+ data = out.split(':')
+ consumed_space = float(data[0]) / 100 * (float(data[1]))
+ free_space = float(data[0]) - consumed_space
+ free_space = round(free_space, 2)
+ except putils.ProcessExecutionError as err:
+ LOG.exception(_('Error querying thin pool about data_percent'))
+ LOG.error(_('Cmd :%s') % err.cmd)
+ LOG.error(_('StdOut :%s') % err.stdout)
+ LOG.error(_('StdErr :%s') % err.stderr)
+
+ return free_space
+
@staticmethod
def get_lvm_version(root_helper):
"""Static method to get LVM version from system.
for lv in self.get_all_volumes(self._root_helper, self.vg_name):
if lv['name'] == self.vg_thin_pool:
self.vg_thin_pool_size = lv['size']
+ tpfs = self._get_thin_pool_free_space(self.vg_name,
+ self.vg_thin_pool)
+ self.vg_thin_pool_free_space = tpfs
def _calculate_thin_pool_size(self):
"""Calculates the correct size for a thin pool.
data = " fake-volumes:/dev/sda:10.00g:8.99g\n"
data += " fake-volumes-2:/dev/sdb:10.00g:8.99g\n"
data += " fake-volumes-3:/dev/sdc:10.00g:8.99g\n"
+ elif 'lvs, --noheadings, --unit=g, -o, size,data_percent, ' \
+ '--separator, :' in cmd_string:
+ data = " 9:12\n"
else:
raise AssertionError('unexpected command called: %s' % cmd_string)
for size in ("1g", "1.2g", "1.75g"):
self.assertEqual(size, self.vg.create_thin_pool(size_str=size))
+ def test_thin_pool_free_space(self):
+ # The size of fake-volumes-pool is 9g and the allocated data sums up to
+ # 12% so the calculated free space should be 7.92
+ self.assertEqual(float("7.92"),
+ self.vg._get_thin_pool_free_space("fake-vg",
+ "fake-vg-pool"))
+
def test_volume_create_after_thin_creation(self):
"""Test self.vg.vg_thin_pool is set to pool_name