FALLOC_FL_PUNCH_HOLE = 0x02
FALLOC_FL_NO_HIDE_STALE = 0x04
+CEPH_SETATTR_MODE = 0x1
+CEPH_SETATTR_UID = 0x2
+CEPH_SETATTR_GID = 0x4
+CEPH_SETATTR_MTIME = 0x8
+CEPH_SETATTR_ATIME = 0x10
+CEPH_SETATTR_SIZE = 0x20
+CEPH_SETATTR_CTIME = 0x40
+CEPH_SETATTR_BTIME = 0x200
+
cdef extern from "Python.h":
# These are in cpython/string.pxd, but use "object" types instead of
# PyObject*, which invokes assumptions in cpython that we need to
int ceph_statx(ceph_mount_info *cmount, const char *path, statx *stx, unsigned want, unsigned flags)
int ceph_statfs(ceph_mount_info *cmount, const char *path, statvfs *stbuf)
+ int ceph_setattrx(ceph_mount_info *cmount, const char *relpath, statx *stx, int mask, int flags)
+ int ceph_fsetattrx(ceph_mount_info *cmount, int fd, statx *stx, int mask)
int ceph_mds_command(ceph_mount_info *cmount, const char *mds_spec, const char **cmd, size_t cmdlen,
const char *inbuf, size_t inbuflen, char **outbuf, size_t *outbuflen,
char **outs, size_t *outslen)
return dict_result
+ def setattrx(self, path, dict_stx, mask, flags):
+ """
+ Set a file's attributes.
+
+ :param path: the path to the file/directory to set the attributes of.
+ :param mask: a mask of all the CEPH_SETATTR_* values that have been set in the statx struct.
+ :param stx: a dict of statx structure that must include attribute values to set on the file.
+ :param flags: mask of AT_* flags (only AT_ATTR_NOFOLLOW is respected for now)
+ """
+
+ self.require_state("mounted")
+ path = cstr(path, 'path')
+ if not isinstance(dict_stx, dict):
+ raise TypeError('dict_stx must be a dict')
+ if not isinstance(mask, int):
+ raise TypeError('mask must be a int')
+ if not isinstance(flags, int):
+ raise TypeError('flags must be a int')
+
+ cdef statx stx
+
+ if (mask & CEPH_SETATTR_MODE):
+ stx.stx_mode = dict_stx["mode"]
+ if (mask & CEPH_SETATTR_UID):
+ stx.stx_uid = dict_stx["uid"]
+ if (mask & CEPH_SETATTR_GID):
+ stx.stx_gid = dict_stx["gid"]
+ if (mask & CEPH_SETATTR_MTIME):
+ stx.stx_mtime = to_timespec(dict_stx["mtime"].timestamp())
+ if (mask & CEPH_SETATTR_ATIME):
+ stx.stx_atime = to_timespec(dict_stx["atime"].timestamp())
+ if (mask & CEPH_SETATTR_CTIME):
+ stx.stx_ctime = to_timespec(dict_stx["ctime"].timestamp())
+ if (mask & CEPH_SETATTR_SIZE):
+ stx.stx_size = dict_stx["size"]
+ if (mask & CEPH_SETATTR_BTIME):
+ stx.stx_btime = to_timespec(dict_stx["btime"].timestamp())
+
+ cdef:
+ char* _path = path
+ int _mask = mask
+ int _flags = flags
+ dict_result = dict()
+
+ with nogil:
+ ret = ceph_setattrx(self.cluster, _path, &stx, _mask, _flags)
+ if ret < 0:
+ raise make_ex(ret, "error in setattrx: %s" % path)
+
+ def fsetattrx(self, fd, dict_stx, mask):
+ """
+ Set a file's attributes.
+
+ :param path: the path to the file/directory to set the attributes of.
+ :param mask: a mask of all the CEPH_SETATTR_* values that have been set in the statx struct.
+ :param stx: a dict of statx structure that must include attribute values to set on the file.
+ """
+
+ self.require_state("mounted")
+ if not isinstance(fd, int):
+ raise TypeError('fd must be a int')
+ if not isinstance(dict_stx, dict):
+ raise TypeError('dict_stx must be a dict')
+ if not isinstance(mask, int):
+ raise TypeError('mask must be a int')
+
+ cdef statx stx
+
+ if (mask & CEPH_SETATTR_MODE):
+ stx.stx_mode = dict_stx["mode"]
+ if (mask & CEPH_SETATTR_UID):
+ stx.stx_uid = dict_stx["uid"]
+ if (mask & CEPH_SETATTR_GID):
+ stx.stx_gid = dict_stx["gid"]
+ if (mask & CEPH_SETATTR_MTIME):
+ stx.stx_mtime = to_timespec(dict_stx["mtime"].timestamp())
+ if (mask & CEPH_SETATTR_ATIME):
+ stx.stx_atime = to_timespec(dict_stx["atime"].timestamp())
+ if (mask & CEPH_SETATTR_CTIME):
+ stx.stx_ctime = to_timespec(dict_stx["ctime"].timestamp())
+ if (mask & CEPH_SETATTR_SIZE):
+ stx.stx_size = dict_stx["size"]
+ if (mask & CEPH_SETATTR_BTIME):
+ stx.stx_btime = to_timespec(dict_stx["btime"].timestamp())
+
+ cdef:
+ int _fd = fd
+ int _mask = mask
+ dict_result = dict()
+
+ with nogil:
+ ret = ceph_fsetattrx(self.cluster, _fd, &stx, _mask)
+ if ret < 0:
+ raise make_ex(ret, "error in fsetattrx")
+
def symlink(self, existing, newname):
"""
Creates a symbolic link.
def test_replication():
fd = cephfs.open(b'/file-rep', 'w', 0o755)
assert_raises(TypeError, cephfs.get_file_replication, "fd")
+ l_dict = cephfs.get_layout(fd)
+ assert('pool_name' in l_dict.keys())
cnt = cephfs.get_file_replication(fd)
- assert_equal(cnt, 3)
+ get_rep_cnt_cmd = "ceph osd pool get " + l_dict["pool_name"] + " size"
+ s=os.popen(get_rep_cnt_cmd).read().strip('\n')
+ size=int(s.split(" ")[-1])
+ assert_equal(cnt, size)
cnt = cephfs.get_path_replication(b'/file-rep')
- assert_equal(cnt, 3)
+ assert_equal(cnt, size)
cephfs.close(fd)
cephfs.unlink(b'/file-rep')
assert_equal([b"asdf", b"zxcvb"], list(buf))
cephfs.close(fd)
cephfs.unlink(b'file-1')
+
+@with_setup(setup_test)
+def test_setattrx():
+ fd = cephfs.open(b'file-setattrx', 'w', 0o655)
+ cephfs.write(fd, b"1111", 0)
+ cephfs.close(fd)
+ st = cephfs.statx(b'file-setattrx', libcephfs.CEPH_STATX_MODE, 0)
+ mode = st["mode"] | stat.S_IXUSR
+ assert_raises(TypeError, cephfs.setattrx, b'file-setattrx', "dict", 0, 0)
+
+ time.sleep(1)
+ statx_dict = dict()
+ statx_dict["mode"] = mode
+ statx_dict["uid"] = 9999
+ statx_dict["gid"] = 9999
+ dt = datetime.now()
+ statx_dict["mtime"] = dt
+ statx_dict["atime"] = dt
+ statx_dict["ctime"] = dt
+ statx_dict["size"] = 10
+ statx_dict["btime"] = dt
+ cephfs.setattrx(b'file-setattrx', statx_dict, libcephfs.CEPH_SETATTR_MODE | libcephfs.CEPH_SETATTR_UID |
+ libcephfs.CEPH_SETATTR_GID | libcephfs.CEPH_SETATTR_MTIME |
+ libcephfs.CEPH_SETATTR_ATIME | libcephfs.CEPH_SETATTR_CTIME |
+ libcephfs.CEPH_SETATTR_SIZE | libcephfs.CEPH_SETATTR_BTIME, 0)
+ st1 = cephfs.statx(b'file-setattrx', libcephfs.CEPH_STATX_MODE | libcephfs.CEPH_STATX_UID |
+ libcephfs.CEPH_STATX_GID | libcephfs.CEPH_STATX_MTIME |
+ libcephfs.CEPH_STATX_ATIME | libcephfs.CEPH_STATX_CTIME |
+ libcephfs.CEPH_STATX_SIZE | libcephfs.CEPH_STATX_BTIME, 0)
+ assert_equal(mode, st1["mode"])
+ assert_equal(9999, st1["uid"])
+ assert_equal(9999, st1["gid"])
+ assert_equal(int(dt.timestamp()), int(st1["mtime"].timestamp()))
+ assert_equal(int(dt.timestamp()), int(st1["atime"].timestamp()))
+ assert_equal(int(dt.timestamp()), int(st1["ctime"].timestamp()))
+ assert_equal(int(dt.timestamp()), int(st1["btime"].timestamp()))
+ assert_equal(10, st1["size"])
+ cephfs.unlink(b'file-setattrx')
+
+@with_setup(setup_test)
+def test_fsetattrx():
+ fd = cephfs.open(b'file-fsetattrx', 'w', 0o655)
+ cephfs.write(fd, b"1111", 0)
+ st = cephfs.statx(b'file-fsetattrx', libcephfs.CEPH_STATX_MODE, 0)
+ mode = st["mode"] | stat.S_IXUSR
+ assert_raises(TypeError, cephfs.fsetattrx, fd, "dict", 0, 0)
+
+ time.sleep(1)
+ statx_dict = dict()
+ statx_dict["mode"] = mode
+ statx_dict["uid"] = 9999
+ statx_dict["gid"] = 9999
+ dt = datetime.now()
+ statx_dict["mtime"] = dt
+ statx_dict["atime"] = dt
+ statx_dict["ctime"] = dt
+ statx_dict["size"] = 10
+ statx_dict["btime"] = dt
+ cephfs.fsetattrx(fd, statx_dict, libcephfs.CEPH_SETATTR_MODE | libcephfs.CEPH_SETATTR_UID |
+ libcephfs.CEPH_SETATTR_GID | libcephfs.CEPH_SETATTR_MTIME |
+ libcephfs.CEPH_SETATTR_ATIME | libcephfs.CEPH_SETATTR_CTIME |
+ libcephfs.CEPH_SETATTR_SIZE | libcephfs.CEPH_SETATTR_BTIME)
+ st1 = cephfs.statx(b'file-fsetattrx', libcephfs.CEPH_STATX_MODE | libcephfs.CEPH_STATX_UID |
+ libcephfs.CEPH_STATX_GID | libcephfs.CEPH_STATX_MTIME |
+ libcephfs.CEPH_STATX_ATIME | libcephfs.CEPH_STATX_CTIME |
+ libcephfs.CEPH_STATX_SIZE | libcephfs.CEPH_STATX_BTIME, 0)
+ assert_equal(mode, st1["mode"])
+ assert_equal(9999, st1["uid"])
+ assert_equal(9999, st1["gid"])
+ assert_equal(int(dt.timestamp()), int(st1["mtime"].timestamp()))
+ assert_equal(int(dt.timestamp()), int(st1["atime"].timestamp()))
+ assert_equal(int(dt.timestamp()), int(st1["ctime"].timestamp()))
+ assert_equal(int(dt.timestamp()), int(st1["btime"].timestamp()))
+ assert_equal(10, st1["size"])
+ cephfs.close(fd)
+ cephfs.unlink(b'file-fsetattrx')