Skip to content

Commit

Permalink
Adds Nova emphemeral image truncate performance optimization patch.
Browse files Browse the repository at this point in the history
  • Loading branch information
casusbelli committed Aug 1, 2017
1 parent 07e4dae commit b889ca1
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 0 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
35 changes: 35 additions & 0 deletions truncate_ephemeral_patch/Mitaka/truncate-ephemeral_Mitaka.patch
Original file line number Diff line number Diff line change
@@ -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,
35 changes: 35 additions & 0 deletions truncate_ephemeral_patch/Ocata/truncate-ephemeral_Ocata.patch
Original file line number Diff line number Diff line change
@@ -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,
35 changes: 35 additions & 0 deletions truncate_ephemeral_patch/Pike/truncate-ephemeral_Pike.patch
Original file line number Diff line number Diff line change
@@ -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,

0 comments on commit b889ca1

Please sign in to comment.