Merge pull request #1156 from efiop/master

dvc: use ctypes instead of cffi
This commit is contained in:
Ruslan Kuprieiev
2018-09-23 12:53:52 +03:00
committed by GitHub
5 changed files with 61 additions and 100 deletions
-88
View File
@@ -1,88 +0,0 @@
import platform
from cffi import FFI
WINDOWS_SRC = """
int reflink(char *src, char *dst)
{
return -1;
}
"""
DARWIN_SRC = """
#include <AvailabilityMacros.h>
/* NOTE: sys/clonefile.h is available since OS X 10.12 */
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
#include <sys/clonefile.h> /* for clonefile(2) */
#include <errno.h>
int reflink(char *src, char *dst)
{
return clonefile(src, dst, 0);
}
#else
int reflink(char *src, char *dst)
{
return -1;
}
#endif
"""
LINUX_SRC = """
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <sys/ioctl.h>
#include <assert.h>
#include <errno.h>
int reflink(char *src, char *dst)
{
int ret = -1;
#ifdef FICLONE
int src_fd = -1;
int dst_fd = -1;
src_fd = open(src, O_RDONLY);
if (src_fd < 0)
return ret;
dst_fd = open(dst, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
if (src_fd < 0) {
close(src_fd);
return ret;
}
ret = ioctl(dst_fd, FICLONE, src_fd);
if (ret != 0)
unlink(dst);
out:
if (src_fd >= 0)
close(src_fd);
if (dst_fd >= 0)
close(dst_fd);
#endif
return ret;
}
"""
ffibuilder = FFI()
ffibuilder.cdef("""
int reflink(char *src, char *dst);
""")
system = platform.system()
if system == 'Windows':
src = WINDOWS_SRC
elif system == 'Linux':
src = LINUX_SRC
elif system == 'Darwin':
src = DARWIN_SRC
else:
raise NotImplementedError
ffibuilder.set_source("reflink", src)
if __file__ == '__main__':
ffibuilder.compile(verbose=True)
+1 -1
View File
@@ -108,7 +108,7 @@ class RemoteLOCAL(RemoteBase):
os.path.relpath(cache),
os.path.relpath(path)))
return
except Exception as exc:
except DvcException as exc:
msg = 'Cache type \'{}\' is not supported: {}'
Logger.debug(msg.format(self.cache_types[0], str(exc)))
del self.cache_types[0]
+60 -7
View File
@@ -1,5 +1,4 @@
import os
import ctypes
if os.name == 'nt':
import ntfsutils.hardlink as winlink
@@ -19,6 +18,7 @@ class System(object):
@staticmethod
def symlink(source, link_name):
import ctypes
if System.is_unix():
return os.symlink(source, link_name)
@@ -33,17 +33,70 @@ class System(object):
if func(link_name, source, flags) == 0:
raise ctypes.WinError()
@staticmethod
def _reflink_darwin(src, dst):
import ctypes
clonefile = ctypes.CDLL('libc.dylib').clonefile
clonefile.argtypes = [ctypes.c_char_p,
ctypes.c_char_p,
ctypes.c_int]
clonefile.restype = ctypes.c_int
return clonefile(ctypes.c_char_p(src.encode('utf-8')),
ctypes.c_char_p(src.encode('utf-8')),
ctypes.c_int(0))
@staticmethod
def _reflink_windows(src, dst):
return -1
@staticmethod
def _reflink_linux(src, dst):
import os
import fcntl
FICLONE = 0x40049409
s = open(src, 'r')
d = open(dst, 'w+')
try:
ret = fcntl.ioctl(d.fileno(), FICLONE, s.fileno())
except IOError:
s.close()
d.close()
os.unlink(dst)
raise
s.close()
d.close()
if ret != 0:
os.unlink(dst)
return ret
@staticmethod
def reflink(source, link_name):
from dvc.reflink import reflink
import platform
from dvc.exceptions import DvcException
ret = reflink(source, link_name)
system = platform.system()
try:
if system == 'Windows':
ret = System._reflink_windows(source, link_name)
elif system == 'Darwin':
ret = System._reflink_darwin(source, link_name)
elif system == 'Linux':
ret = System._reflink_linux(source, link_name)
else:
ret = -1
except IOError:
ret = -1
if ret != 0:
raise DvcException("Failed to reflink '{}' -> '{}' returned "
"non-zero code '{}'".format(source,
link_name,
ret))
raise DvcException('Reflink is not supported')
# FIXME
# Temporary fix while waiting for the PR to be merged and released:
-1
View File
@@ -23,4 +23,3 @@ wheel>=0.31.1
futures>=3.2.0; python_version == "2.7"
grandalf==0.6
asciicanvas==0.0.3
cffi>=1.0.0
-3
View File
@@ -24,7 +24,6 @@ install_requires = [
"requests>=2.18.4",
"grandalf==0.6",
"asciicanvas==0.0.3",
"cffi>=1.0.0",
]
# Extra dependencies for remote integrations
@@ -61,7 +60,6 @@ setup(
# NOTE: https://github.com/inveniosoftware/troubleshooting/issues/1
':python_version=="2.7"': ['futures'],
},
setup_requires=['cffi>=1.0.0'],
keywords='data science, data version control, machine learning',
classifiers=[
'Development Status :: 4 - Beta',
@@ -75,5 +73,4 @@ setup(
'console_scripts': ['dvc = dvc.main:main']
},
zip_safe=False,
cffi_modules=["dvc/reflink_ffi.py:ffibuilder"]
)