summaryrefslogtreecommitdiff
path: root/nova/image
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2017-09-06 16:36:02 +0000
committerGerrit Code Review <review@openstack.org>2017-09-06 16:36:02 +0000
commit0a36453a81b827bb4d3f4ee39626109129f6c821 (patch)
treefc7caffc1df419dc3c44ee66132f91913dee3cff /nova/image
parent8c48863d7c680faa12181f42a89996f0d56ae04a (diff)
parent641798f75f50e7b4db3c7a8ccefcb8b590228893 (diff)
downloadnova-0a36453a81b827bb4d3f4ee39626109129f6c821.tar.gz
Merge "Glance download: only fsync files"
Diffstat (limited to 'nova/image')
-rw-r--r--nova/image/glance.py20
1 files changed, 19 insertions, 1 deletions
diff --git a/nova/image/glance.py b/nova/image/glance.py
index 16188f9354..456a8f8591 100644
--- a/nova/image/glance.py
+++ b/nova/image/glance.py
@@ -22,6 +22,7 @@ import inspect
import itertools
import os
import random
+import stat
import sys
import time
@@ -47,6 +48,7 @@ from nova import objects
from nova.objects import fields
from nova import service_auth
+
LOG = logging.getLogger(__name__)
CONF = nova.conf.CONF
@@ -272,6 +274,22 @@ class GlanceImageServiceV2(object):
return _images
+ @staticmethod
+ def _safe_fsync(fh):
+ """Performs os.fsync on a filehandle only if it is supported.
+
+ fsync on a pipe, FIFO, or socket raises OSError with EINVAL. This
+ method discovers whether the target filehandle is one of these types
+ and only performs fsync if it isn't.
+
+ :param fh: Open filehandle (not a path or fileno) to maybe fsync.
+ """
+ fileno = fh.fileno()
+ mode = os.fstat(fileno).st_mode
+ # A pipe answers True to S_ISFIFO
+ if not any(check(mode) for check in (stat.S_ISFIFO, stat.S_ISSOCK)):
+ os.fsync(fileno)
+
def download(self, context, image_id, data=None, dst_path=None):
"""Calls out to Glance for data and writes data."""
if CONF.glance.allowed_direct_url_schemes and dst_path is not None:
@@ -371,7 +389,7 @@ class GlanceImageServiceV2(object):
# subsequent host crash we don't have running instances
# using a corrupt backing file.
data.flush()
- os.fsync(data.fileno())
+ self._safe_fsync(data)
data.close()
def create(self, context, image_meta, data=None):