Change in vdsm[ovirt-3.4]: qemuimg: Create qcow2 compat 0.10 images

nsoffer at redhat.com nsoffer at redhat.com
Wed Sep 17 19:27:32 UTC 2014


Hello Federico Simoncelli, Allon Mureinik,

I'd like you to do a code review.  Please visit

    http://gerrit.ovirt.org/33022

to review the following change.

Change subject: qemuimg: Create qcow2 compat 0.10 images
......................................................................

qemuimg: Create qcow2 compat 0.10 images

Recent qemu versions introduced a new default qcow2 format (1.1), which
is not compatible with older versions of qemu. For example, EL6 host
cannot create snapshots if an image was created on EL7 host.

This patch uses the "compat" option to create images in the older format
(0.10), which are are compatible with different versions of qemu.

The "compat" option is not available on older qemu-img, so we have to
use the "-o ?" option to detect the availability of the "compat" option
before creating an image. This is the same method used by libvirt.

When all supported platforms provide the "compat" option, we can remove
the "compat" detection code. Chanding the compat version will require
a new storage domain format.

Note: this patch adds qemuimgTests.py since this file does not exists in
3.4. Only the tests relevant to this fix were backported.

Change-Id: Iffd45b394c49e8b12fb7a4cbaa5c7a3519a2cc1c
Bug-Url: https://bugzilla.redhat.com/1142691
Signed-off-by: Nir Soffer <nsoffer at redhat.com>
Reviewed-on: http://gerrit.ovirt.org/32836
Reviewed-by: Allon Mureinik <amureini at redhat.com>
Reviewed-by: Federico Simoncelli <fsimonce at redhat.com>
---
M lib/vdsm/qemuImg.py
A tests/qemuimgTests.py
2 files changed, 109 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/22/33022/1

diff --git a/lib/vdsm/qemuImg.py b/lib/vdsm/qemuImg.py
index e13524c..b99188c 100644
--- a/lib/vdsm/qemuImg.py
+++ b/lib/vdsm/qemuImg.py
@@ -33,6 +33,12 @@
     RAW = "raw"
     VMDK = "vmdk"
 
+
+# Recent qemu-img supports two incompatible qcow2 versions. We use 0.10 format
+# so hosts with older qemu can consume images created by newer versions.
+# See https://bugzilla.redhat.com/1139707
+QCOW2_COMPAT = '0.10'
+
 __iregex = {
     'format':       re.compile("^file format: (?P<value>\w+)$"),
     'virtualsize':  re.compile("^virtual size: "
@@ -93,6 +99,8 @@
 
     if format:
         cmd.extend(("-f", format))
+        if format == FORMAT.QCOW2 and _supports_qcow2_compat():
+            cmd.extend(('-o', 'compat=' + QCOW2_COMPAT))
 
     if backing:
         cmd.extend(("-b", backing))
@@ -111,6 +119,24 @@
         raise QImgError(rc, out, err)
 
 
+def _supports_qcow2_compat():
+    """
+    TODO: Remove this when qemu versions providing the "compat" option are
+    available on all platforms.
+    """
+    cmd = [_qemuimg.cmd, "create", "-f", FORMAT.QCOW2, "-o", "?", "/dev/null"]
+
+    rc, out, err = utils.execCmd(cmd, raw=True)
+
+    if rc != 0:
+        raise QImgError(rc, out, err)
+
+    # Supported options:
+    # compat           Compatibility level (0.10 or 1.1)
+
+    return '\ncompat ' in out
+
+
 def check(image, format=None):
     cmd = [_qemuimg.cmd, "check"]
 
diff --git a/tests/qemuimgTests.py b/tests/qemuimgTests.py
new file mode 100644
index 0000000..587eb00
--- /dev/null
+++ b/tests/qemuimgTests.py
@@ -0,0 +1,83 @@
+#
+# Copyright 2014 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+from testlib import VdsmTestCase as TestCaseBase
+from vdsm import qemuImg
+from vdsm import utils
+
+
+class FakeExecCmd(object):
+
+    def __init__(self, *calls):
+        self.calls = list(calls)
+        self.saved = None
+
+    def __call__(self, cmd, **kw):
+        call = self.calls.pop(0)
+        return call(cmd, **kw)
+
+    def __enter__(self):
+        self.saved = utils.execCmd
+        utils.execCmd = self
+
+    def __exit__(self, t=None, v=None, tb=None):
+        utils.execCmd = self.saved
+
+
+class QemuimgCreateTests(TestCaseBase):
+
+    def test_no_format(self):
+
+        def create_no_format(cmd, **kw):
+            assert cmd == [qemuImg._qemuimg.cmd, 'create', 'image']
+            return 0, '', ''
+
+        with FakeExecCmd(create_no_format):
+            qemuImg.create('image')
+
+    def test_qcow2_compat_not_supported(self):
+
+        def qcow2_compat_not_supported(cmd, **kw):
+            assert cmd == [qemuImg._qemuimg.cmd, 'create', '-f', 'qcow2', '-o',
+                           '?', '/dev/null']
+            return 0, 'Supported options:\nsize ...\n', ''
+
+        def create_qcow2_no_compat(cmd, **kw):
+            assert cmd == [qemuImg._qemuimg.cmd, 'create', '-f', 'qcow2',
+                           'image']
+            return 0, '', ''
+
+        with FakeExecCmd(qcow2_compat_not_supported, create_qcow2_no_compat):
+            qemuImg.create('image', format='qcow2')
+
+    def test_qcow2_compat_supported(self):
+
+        def qcow2_compat_supported(cmd, **kw):
+            assert cmd == [qemuImg._qemuimg.cmd, 'create', '-f', 'qcow2', '-o',
+                           '?', '/dev/null']
+            return 0, 'Supported options:\ncompat ...\n', ''
+
+        def create_qcow2_compat(cmd, **kw):
+            assert cmd == [qemuImg._qemuimg.cmd, 'create', '-f', 'qcow2', '-o',
+                           'compat=0.10', 'image']
+            return 0, '', ''
+
+        with FakeExecCmd(qcow2_compat_supported, create_qcow2_compat):
+            qemuImg.create('image', format='qcow2')


-- 
To view, visit http://gerrit.ovirt.org/33022
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iffd45b394c49e8b12fb7a4cbaa5c7a3519a2cc1c
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.4
Gerrit-Owner: Nir Soffer <nsoffer at redhat.com>
Gerrit-Reviewer: Allon Mureinik <amureini at redhat.com>
Gerrit-Reviewer: Federico Simoncelli <fsimonce at redhat.com>


More information about the vdsm-patches mailing list