def test_optimal_size_cow_leaf_empty(self):
     # verify optimal size equals to actual size + one chunk.
     with self.make_volume(size=GIB, format=sc.COW_FORMAT) as vol:
         chunk_size = 1024 * constants.MEGAB
         check = qemuimg.check(vol.getVolumePath(), qemuimg.FORMAT.QCOW2)
         actual_size = check['offset'] + chunk_size
         self.assertEqual(vol.optimal_size(), actual_size)
Exemple #2
0
 def test_check(self):
     with namedTemporaryDir() as tmpdir:
         path = os.path.join(tmpdir, 'test.qcow2')
         qemuimg.create(path, size=1048576, format=qemuimg.FORMAT.QCOW2)
         info = qemuimg.check(path)
         # The exact value depends on qcow2 internals
         self.assertEqual(int, type(info['offset']))
Exemple #3
0
 def test_check(self):
     with namedTemporaryDir() as tmpdir:
         path = os.path.join(tmpdir, 'test.qcow2')
         qemuimg.create(path, size=1048576, format=qemuimg.FORMAT.QCOW2)
         info = qemuimg.check(path)
         # The exact value depends on qcow2 internals
         self.assertEqual(int, type(info['offset']))
Exemple #4
0
 def test_optimal_size_cow_leaf_empty(self):
     # verify optimal size equals to actual size + one chunk.
     with self.make_volume(size=GIB, format=sc.COW_FORMAT) as vol:
         chunk_size = 1024 * constants.MEGAB
         check = qemuimg.check(vol.getVolumePath(), qemuimg.FORMAT.QCOW2)
         actual_size = check['offset'] + chunk_size
         self.assertEqual(vol.optimal_size(), actual_size)
Exemple #5
0
    def test_offset_without_stats(self):
        def call(cmd, **kw):
            out = ["No errors were found on the image.",
                   "Image end offset: 4271243264"]
            return 0, out, []

        with MonkeyPatchScope([(utils, "execCmd", call)]):
            check = qemuimg.check('unused')
            self.assertEquals(4271243264, check['offset'])
Exemple #6
0
    def test_commit(self, qcow2_compat, base, top, use_base):
        size = 1048576
        with namedTemporaryDir() as tmpdir:
            chain = []
            parent = None
            # Create a chain of 4 volumes.
            for i in range(4):
                vol = os.path.join(tmpdir, "vol%d.img" % i)
                format = (qemuimg.FORMAT.RAW
                          if i == 0 else qemuimg.FORMAT.QCOW2)
                make_image(vol, size, format, i, qcow2_compat, parent)
                orig_offset = qemuimg.check(vol)["offset"] if i > 0 else None
                chain.append((vol, orig_offset))
                parent = vol

            base_vol = chain[base][0]
            top_vol = chain[top][0]
            op = qemuimg.commit(top_vol,
                                topFormat=qemuimg.FORMAT.QCOW2,
                                base=base_vol if use_base else None)
            with utils.closing(op):
                op.wait_for_completion()

            base_fmt = (qemuimg.FORMAT.RAW
                        if base == 0 else qemuimg.FORMAT.QCOW2)
            for i in range(base, top + 1):
                offset = i * 1024
                pattern = 0xf0 + i
                # The base volume must have the data from all the volumes
                # merged into it.
                qemu_pattern_verify(base_vol,
                                    base_fmt,
                                    offset=offset,
                                    len=1024,
                                    pattern=pattern)
                if i > base:
                    # internal and top volumes should keep the data, we
                    # may want to wipe this data when deleting the volumes
                    # later.
                    vol, orig_offset = chain[i]
                    actual_offset = qemuimg.check(vol)["offset"]
                    self.assertEqual(actual_offset, orig_offset)
Exemple #7
0
    def test_offset_with_stats(self):
        def call(cmd, **kw):
            out = ["No errors were found on the image.",
                   "65157/98304 = 66.28% allocated, 0.00% fragmented, 0.00% "
                   "compressed clusters",
                   "Image end offset: 4271243264"]
            return 0, out, []

        with MonkeyPatchScope([(utils, "execCmd", call)]):
            check = qemuimg.check('unused')
            self.assertEquals(4271243264, check['offset'])
Exemple #8
0
    def test_offset_without_stats(self):
        def call(cmd, **kw):
            out = [
                "No errors were found on the image.",
                "Image end offset: 4271243264"
            ]
            return 0, out, []

        with MonkeyPatchScope([(commands, "execCmd", call)]):
            check = qemuimg.check('unused')
            self.assertEquals(4271243264, check['offset'])
Exemple #9
0
    def test_offset_with_stats(self):
        def call(cmd, **kw):
            out = [
                "No errors were found on the image.",
                "65157/98304 = 66.28% allocated, 0.00% fragmented, 0.00% "
                "compressed clusters", "Image end offset: 4271243264"
            ]
            return 0, out, []

        with MonkeyPatchScope([(commands, "execCmd", call)]):
            check = qemuimg.check('unused')
            self.assertEquals(4271243264, check['offset'])
Exemple #10
0
    def optimal_size(self):
        """
        Return the optimal size of the volume.

        Returns:
            optimal size is the minimum of the volume maximum size and the
            volume actual size plus padding. For leaf volumes, the padding
            is one chunk, and for internal volumes the padding is
            `MIN_PADDING`.
            Size is returned in bytes.

        Note:
            the volume must be prepared when calling this helper.
        """
        if self.getFormat() == sc.RAW_FORMAT:
            virtual_size = self.getSize() * sc.BLOCK_SIZE
            self.log.debug("RAW format, using virtual size: %s", virtual_size)
            return virtual_size

        # Read actual size.
        check = qemuimg.check(self.getVolumePath(), qemuimg.FORMAT.QCOW2)
        actual_size = check['offset']

        # Add padding.
        if self.isLeaf():
            # For leaf volumes, the padding is one chunk.
            chnuk_size_mb = int(config.get("irs",
                                           "volume_utilization_chunk_mb"))
            padding = chnuk_size_mb * constants.MEGAB
            self.log.debug("Leaf volume, using padding: %s", padding)

            potential_optimal_size = actual_size + padding

        else:
            # For internal volumes, using minimal padding.
            padding = MIN_PADDING
            self.log.debug("Internal volume, using padding: %s", padding)

            potential_optimal_size = actual_size + padding

            # Limit optimal size to the minimal volume size.
            potential_optimal_size = max(sc.MIN_CHUNK, potential_optimal_size)

        # Limit optimal size by maximum size.
        max_size = self.max_size(self.getSize() * sc.BLOCK_SIZE,
                                 self.getFormat())
        optimal_size = min(potential_optimal_size, max_size)
        self.log.debug("COW format, actual_size: %s, max_size: %s, "
                       "optimal_size: %s",
                       actual_size, max_size, optimal_size)
        return optimal_size
Exemple #11
0
    def optimal_size(self):
        """
        Return the optimal size of the volume.

        Returns:
            optimal size is the minimum of the volume maximum size and the
            volume actual size plus padding. For leaf volumes, the padding
            is one chunk, and for internal volumes the padding is
            `MIN_PADDING`.
            Size is returned in bytes.

        Note:
            the volume must be prepared when calling this helper.
        """
        if self.getFormat() == sc.RAW_FORMAT:
            virtual_size = self.getSize() * sc.BLOCK_SIZE
            self.log.debug("RAW format, using virtual size: %s", virtual_size)
            return virtual_size

        # Read actual size.
        check = qemuimg.check(self.getVolumePath(), qemuimg.FORMAT.QCOW2)
        actual_size = check['offset']

        # Add padding.
        if self.isLeaf():
            # For leaf volumes, the padding is one chunk.
            chnuk_size_mb = int(
                config.get("irs", "volume_utilization_chunk_mb"))
            padding = chnuk_size_mb * constants.MEGAB
            self.log.debug("Leaf volume, using padding: %s", padding)

            potential_optimal_size = actual_size + padding

        else:
            # For internal volumes, using minimal padding.
            padding = MIN_PADDING
            self.log.debug("Internal volume, using padding: %s", padding)

            potential_optimal_size = actual_size + padding

            # Limit optimal size to the minimal volume size.
            potential_optimal_size = max(sc.MIN_CHUNK, potential_optimal_size)

        # Limit optimal size by maximum size.
        max_size = self.max_size(self.getSize() * sc.BLOCK_SIZE,
                                 self.getFormat())
        optimal_size = min(potential_optimal_size, max_size)
        self.log.debug(
            "COW format, actual_size: %s, max_size: %s, "
            "optimal_size: %s", actual_size, max_size, optimal_size)
        return optimal_size
Exemple #12
0
 def shrinkToOptimalSize(self):
     """
     Reduce a logical volume to the actual
     disk size, adding round up to next
     closest volume utilization chunk
     """
     volParams = self.getVolumeParams()
     if volParams['volFormat'] == volume.COW_FORMAT:
         self.prepare()
         try:
             check = qemuimg.check(self.getVolumePath(),
                                   qemuimg.FORMAT.QCOW2)
         finally:
             self.teardown(self.sdUUID, self.volUUID)
         volActualSize = check['offset']
         volExtendSizeMB = int(
             config.get("irs", "volume_utilization_chunk_mb"))
         volExtendSize = volExtendSizeMB * constants.MEGAB
         volUtil = int(config.get("irs", "volume_utilization_percent"))
         finalSize = (volActualSize + volExtendSize * volUtil * 0.01)
         finalSize += volExtendSize - (finalSize % volExtendSize)
         self.log.debug('Shrink qcow volume: %s to : %s bytes',
                        self.volUUID, finalSize)
         self.reduce((finalSize + BLOCK_SIZE - 1) / BLOCK_SIZE)
Exemple #13
0
 def shrinkToOptimalSize(self):
     """
     Reduce a logical volume to the actual
     disk size, adding round up to next
     closest volume utilization chunk
     """
     volParams = self.getVolumeParams()
     if volParams['volFormat'] == sc.COW_FORMAT:
         self.prepare()
         try:
             check = qemuimg.check(self.getVolumePath(),
                                   qemuimg.FORMAT.QCOW2)
         finally:
             self.teardown(self.sdUUID, self.volUUID)
         volActualSize = check['offset']
         volExtendSizeMB = int(config.get(
                               "irs", "volume_utilization_chunk_mb"))
         volExtendSize = volExtendSizeMB * constants.MEGAB
         volUtil = int(config.get("irs", "volume_utilization_percent"))
         finalSize = (volActualSize + volExtendSize * volUtil * 0.01)
         finalSize += volExtendSize - (finalSize % volExtendSize)
         self.log.debug('Shrink qcow volume: %s to : %s bytes',
                        self.volUUID, finalSize)
         self.reduce((finalSize + BLOCK_SIZE - 1) / BLOCK_SIZE)