privsep: Handle ENOENT when checking for direct IO support
We've seen a recent issue that suggest direct IO support checks can fail in other valid ways than EINVAL, namely, failures with ENOENT or the FileNotFoundError exception, which is a Python 3-only exception type, can occur. While we can't test for this without breaking Python 2.7 support, we can mimic this by looking for checking for the errno attribute of the OSError exception. Do this. Change-Id: I8aab86bb62cbc8ad538c706af037a30437c7964d Closes-Bug: #1788922
This commit is contained in:
parent
8ee44744e6
commit
ecfcf86538
|
@ -51,7 +51,7 @@ def supports_direct_io(dirpath):
|
|||
LOG.debug("Path '%(path)s' supports direct I/O",
|
||||
{'path': dirpath})
|
||||
except OSError as e:
|
||||
if e.errno == errno.EINVAL:
|
||||
if e.errno in (errno.EINVAL, errno.ENOENT):
|
||||
LOG.debug("Path '%(path)s' does not support direct I/O: "
|
||||
"'%(ex)s'", {'path': dirpath, 'ex': e})
|
||||
hasDirectIO = False
|
||||
|
|
|
@ -34,6 +34,8 @@ class SupportDirectIOTestCase(test.NoDBTestCase):
|
|||
self.addCleanup(delattr, os, 'O_DIRECT')
|
||||
self.einval = OSError()
|
||||
self.einval.errno = errno.EINVAL
|
||||
self.enoent = OSError()
|
||||
self.enoent.errno = errno.ENOENT
|
||||
self.test_path = os.path.join('.', '.directio.test')
|
||||
self.io_flags = os.O_CREAT | os.O_WRONLY | os.O_DIRECT
|
||||
|
||||
|
@ -100,7 +102,7 @@ class SupportDirectIOTestCase(test.NoDBTestCase):
|
|||
self.mock_close.assert_called_once_with(3)
|
||||
self.mock_unlink.assert_called_once_with(self.test_path)
|
||||
|
||||
def test_supports_direct_io_with_oserror_in_open(self):
|
||||
def test_supports_direct_io_with_oserror_in_open_einval(self):
|
||||
self.mock_open.side_effect = self.einval
|
||||
|
||||
self.assertFalse(nova.privsep.utils.supports_direct_io('.'))
|
||||
|
@ -109,3 +111,13 @@ class SupportDirectIOTestCase(test.NoDBTestCase):
|
|||
self.mock_write.assert_not_called()
|
||||
self.mock_close.assert_not_called()
|
||||
self.mock_unlink.assert_called_once_with(self.test_path)
|
||||
|
||||
def test_supports_direct_io_with_oserror_in_open_enoent(self):
|
||||
self.mock_open.side_effect = self.enoent
|
||||
|
||||
self.assertFalse(nova.privsep.utils.supports_direct_io('.'))
|
||||
|
||||
self.mock_open.assert_called_once_with(self.test_path, self.io_flags)
|
||||
self.mock_write.assert_not_called()
|
||||
self.mock_close.assert_not_called()
|
||||
self.mock_unlink.assert_called_once_with(self.test_path)
|
||||
|
|
Loading…
Reference in New Issue