Improved fallocate and posix_fadvise no-ops when unavailable.
This commit is contained in:
parent
93ce826e41
commit
179eeb29f7
@ -45,19 +45,9 @@ logging.thread = eventlet.green.thread
|
||||
logging.threading = eventlet.green.threading
|
||||
logging._lock = logging.threading.RLock()
|
||||
|
||||
|
||||
libc = ctypes.CDLL(ctypes.util.find_library('c'))
|
||||
try: # Not portable, and not available before linux 2.6.23.
|
||||
sys_fallocate = libc.fallocate
|
||||
except AttributeError:
|
||||
def sys_fallocate(fd, mode, offset, len_):
|
||||
pass
|
||||
try: # Not yet available on all OSs, or linux before 2.5.60.
|
||||
posix_fadvise = libc.posix_fadvise
|
||||
except AttributeError:
|
||||
def posix_fadvise(fd, offset, len_, advice):
|
||||
pass
|
||||
|
||||
# These are lazily pulled from libc elsewhere
|
||||
_sys_fallocate = None
|
||||
_posix_fadvise = None
|
||||
|
||||
# Used by hash_path to offer a bit more security when generating hashes for
|
||||
# paths. It simply appends this value to all paths; guessing the hash a path
|
||||
@ -65,6 +55,22 @@ except AttributeError:
|
||||
HASH_PATH_SUFFIX = os.environ.get('SWIFT_HASH_PATH_SUFFIX', 'endcap')
|
||||
|
||||
|
||||
def load_libc_function(func_name):
|
||||
"""
|
||||
Attempt to find the function in libc, otherwise return a no-op func.
|
||||
|
||||
:param func_name: name of the function to pull from libc.
|
||||
"""
|
||||
try:
|
||||
libc = ctypes.CDLL(ctypes.util.find_library('c'))
|
||||
return getattr(libc, func_name)
|
||||
except AttributeError:
|
||||
print "Unable to locate %s in libc. Leaving as a no-op." % func_name
|
||||
def noop_libc_function(*args):
|
||||
return 0
|
||||
return noop_libc_function
|
||||
|
||||
|
||||
def get_param(req, name, default=None):
|
||||
"""
|
||||
Get parameters from an HTTP request ensuring proper handling UTF-8
|
||||
@ -88,9 +94,12 @@ def fallocate(fd, size):
|
||||
:param fd: file descriptor
|
||||
:param size: size to allocate (in bytes)
|
||||
"""
|
||||
global _sys_fallocate
|
||||
if _sys_fallocate is None:
|
||||
_sys_fallocate = load_libc_function('fallocate')
|
||||
if size > 0:
|
||||
# 1 means "FALLOC_FL_KEEP_SIZE", which means it pre-allocates invisibly
|
||||
ret = sys_fallocate(fd, 1, 0, ctypes.c_uint64(size))
|
||||
ret = _sys_fallocate(fd, 1, 0, ctypes.c_uint64(size))
|
||||
# XXX: in (not very thorough) testing, errno always seems to be 0?
|
||||
err = ctypes.get_errno()
|
||||
if ret and err not in (0, errno.ENOSYS):
|
||||
@ -105,8 +114,11 @@ def drop_buffer_cache(fd, offset, length):
|
||||
:param offset: start offset
|
||||
:param length: length
|
||||
"""
|
||||
global _posix_fadvise
|
||||
if _posix_fadvise is None:
|
||||
_posix_fadvise = load_libc_function('posix_fadvise')
|
||||
# 4 means "POSIX_FADV_DONTNEED"
|
||||
ret = posix_fadvise(fd, ctypes.c_uint64(offset),
|
||||
ret = _posix_fadvise(fd, ctypes.c_uint64(offset),
|
||||
ctypes.c_uint64(length), 4)
|
||||
if ret != 0:
|
||||
print "posix_fadvise(%s, %s, %s, 4) -> %s" % (fd, offset, length, ret)
|
||||
|
@ -241,6 +241,11 @@ class TestUtils(unittest.TestCase):
|
||||
'\x06\xfb\xf0\xb5\x14\xe5\x19\x9d\xfcN\x00\xf4.\xb5\xea\x83')
|
||||
self.assertRaises(ValueError, utils.hash_path, 'a', object='o')
|
||||
|
||||
def test_load_libc_function(self):
|
||||
self.assert_(callable(
|
||||
utils.load_libc_function('printf')))
|
||||
self.assert_(callable(
|
||||
utils.load_libc_function('some_not_real_function')))
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user