diff --git a/README.md b/README.md index a10cdaa..64e76a9 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,17 @@ Removal can easily be done via: patch -p1 -R < /path/to/patchfile +## truncate-ephemeral_patch + +This patch changes Nova ephemeral image prealloc behaviour by running truncate instead of fallocate. This improves performance with ephemeral images on Quobyte volumes. +This change is compatible with other backends with a possible performance impact. + +### Usage + +This patch can be applied by navigating to the Nova project root directory and running: + + patch -p0 < /path/to/patchfile + ## xattr-removal_patch Backports of performance optimizations that remove the usage of xattr from the Nova driver and mount Quobyte volumes without xattr support, in order to improve iops. This patch comes in two flavors: diff --git a/truncate_ephemeral_patch/Mitaka/truncate-ephemeral_Mitaka.patch b/truncate_ephemeral_patch/Mitaka/truncate-ephemeral_Mitaka.patch new file mode 100644 index 0000000..2ca9819 --- /dev/null +++ b/truncate_ephemeral_patch/Mitaka/truncate-ephemeral_Mitaka.patch @@ -0,0 +1,35 @@ +diff --git nova/tests/unit/virt/libvirt/test_imagebackend.py nova/tests/unit/virt/libvirt/test_imagebackend.py +index ac83f50..e8e242b 100644 +--- nova/tests/unit/virt/libvirt/test_imagebackend.py ++++ nova/tests/unit/virt/libvirt/test_imagebackend.py +@@ -115,9 +115,8 @@ class _ImageTestCase(object): + image.cache(fake_fetch, self.TEMPLATE_PATH, self.SIZE) + + self.assertEqual(fake_processutils.fake_execute_get_log(), +- ['fallocate -l 1 %s.fallocate_test' % self.PATH, +- 'fallocate -n -l %s %s' % (self.SIZE, self.PATH), +- 'fallocate -n -l %s %s' % (self.SIZE, self.PATH)]) ++ ['truncate -s %s %s' % (self.SIZE, self.PATH), ++ 'truncate -s %s %s' % (self.SIZE, self.PATH)]) + + def test_prealloc_image_without_write_access(self): + CONF.set_override('preallocate_images', 'space') +diff --git nova/virt/libvirt/imagebackend.py nova/virt/libvirt/imagebackend.py +index 06a9c8f..fd73b32 100644 +--- nova/virt/libvirt/imagebackend.py ++++ nova/virt/libvirt/imagebackend.py +@@ -256,9 +256,11 @@ class Image(object): + if os.path.exists(base) and size > self.get_disk_size(base): + self.resize_image(size) + +- if (self.preallocate and self._can_fallocate() and +- os.access(self.path, os.W_OK)): +- utils.execute('fallocate', '-n', '-l', size, self.path) ++ if (self.preallocate and os.access(self.path, os.W_OK)): ++ LOG.debug('Truncating new image at %(path)s to virtual size ' ++ '(patched for Quobyte).', ++ {'path': self.path}) ++ utils.execute('truncate', '-s', size, self.path) + + def _can_fallocate(self): + """Check once per class, whether fallocate(1) is available, diff --git a/truncate_ephemeral_patch/Ocata/truncate-ephemeral_Ocata.patch b/truncate_ephemeral_patch/Ocata/truncate-ephemeral_Ocata.patch new file mode 100644 index 0000000..b9bb9df --- /dev/null +++ b/truncate_ephemeral_patch/Ocata/truncate-ephemeral_Ocata.patch @@ -0,0 +1,35 @@ +diff --git nova/tests/unit/virt/libvirt/test_imagebackend.py nova/tests/unit/virt/libvirt/test_imagebackend.py +index b3cc277..2c6dff9 100644 +--- nova/tests/unit/virt/libvirt/test_imagebackend.py ++++ nova/tests/unit/virt/libvirt/test_imagebackend.py +@@ -120,9 +120,8 @@ class _ImageTestCase(object): + image.cache(fake_fetch, self.TEMPLATE_PATH, self.SIZE) + + self.assertEqual(fake_processutils.fake_execute_get_log(), +- ['fallocate -l 1 %s.fallocate_test' % self.PATH, +- 'fallocate -n -l %s %s' % (self.SIZE, self.PATH), +- 'fallocate -n -l %s %s' % (self.SIZE, self.PATH)]) ++ ['truncate -s %s %s' % (self.SIZE, self.PATH), ++ 'truncate -s %s %s' % (self.SIZE, self.PATH)]) + + def test_prealloc_image_without_write_access(self): + CONF.set_override('preallocate_images', 'space') +diff --git nova/virt/libvirt/imagebackend.py nova/virt/libvirt/imagebackend.py +index 8dd227e..eaf5c81 100644 +--- nova/virt/libvirt/imagebackend.py ++++ nova/virt/libvirt/imagebackend.py +@@ -232,9 +232,11 @@ class Image(object): + if os.path.exists(base) and size > self.get_disk_size(base): + self.resize_image(size) + +- if (self.preallocate and self._can_fallocate() and +- os.access(self.path, os.W_OK)): +- utils.execute('fallocate', '-n', '-l', size, self.path) ++ if (self.preallocate and os.access(self.path, os.W_OK)): ++ LOG.debug('Truncating new image at %(path)s to virtual size ' ++ '(patched for Quobyte).', ++ {'path': self.path}) ++ utils.execute('truncate', '-s', size, self.path) + + def _can_fallocate(self): + """Check once per class, whether fallocate(1) is available, diff --git a/truncate_ephemeral_patch/Pike/truncate-ephemeral_Pike.patch b/truncate_ephemeral_patch/Pike/truncate-ephemeral_Pike.patch new file mode 100644 index 0000000..6cfea3f --- /dev/null +++ b/truncate_ephemeral_patch/Pike/truncate-ephemeral_Pike.patch @@ -0,0 +1,35 @@ +diff --git nova/tests/unit/virt/libvirt/test_imagebackend.py nova/tests/unit/virt/libvirt/test_imagebackend.py +index a083a2c..9757ff8 100644 +--- nova/tests/unit/virt/libvirt/test_imagebackend.py ++++ nova/tests/unit/virt/libvirt/test_imagebackend.py +@@ -120,9 +120,8 @@ class _ImageTestCase(object): + image.cache(fake_fetch, self.TEMPLATE_PATH, self.SIZE) + + self.assertEqual(fake_processutils.fake_execute_get_log(), +- ['fallocate -l 1 %s.fallocate_test' % self.PATH, +- 'fallocate -n -l %s %s' % (self.SIZE, self.PATH), +- 'fallocate -n -l %s %s' % (self.SIZE, self.PATH)]) ++ ['truncate -s %s %s' % (self.SIZE, self.PATH), ++ 'truncate -s %s %s' % (self.SIZE, self.PATH)]) + + def test_prealloc_image_without_write_access(self): + CONF.set_override('preallocate_images', 'space') +diff --git nova/virt/libvirt/imagebackend.py nova/virt/libvirt/imagebackend.py +index bc7f05c..737a1a9 100644 +--- nova/virt/libvirt/imagebackend.py ++++ nova/virt/libvirt/imagebackend.py +@@ -246,9 +246,11 @@ class Image(object): + if os.path.exists(base) and size > self.get_disk_size(base): + self.resize_image(size) + +- if (self.preallocate and self._can_fallocate() and +- os.access(self.path, os.W_OK)): +- utils.execute('fallocate', '-n', '-l', size, self.path) ++ if (self.preallocate and os.access(self.path, os.W_OK)): ++ LOG.debug('Truncating new image at %(path)s to virtual size ' ++ '(patched for Quobyte).', ++ {'path': self.path}) ++ utils.execute('truncate', '-s', size, self.path) + + def _can_fallocate(self): + """Check once per class, whether fallocate(1) is available,