pybind/cephfs: Add lchmod python binding

Fixes: https://tracker.ceph.com/issues/49882
Signed-off-by: Kotresh HR <khiremat@redhat.com>
This commit is contained in:
Kotresh HR 2021-03-18 18:21:05 +05:30
parent bb1fd87e3b
commit b2375adce0
4 changed files with 49 additions and 1 deletions

View File

@ -118,6 +118,7 @@ cdef extern from "cephfs/libcephfs.h" nogil:
int ceph_lazyio_synchronize(ceph_mount_info *cmount, int fd, int64_t offset, size_t count)
int ceph_fallocate(ceph_mount_info *cmount, int fd, int mode, int64_t offset, int64_t length)
int ceph_chmod(ceph_mount_info *cmount, const char *path, mode_t mode)
int ceph_lchmod(ceph_mount_info *cmount, const char *path, mode_t mode)
int ceph_fchmod(ceph_mount_info *cmount, int fd, mode_t mode)
int ceph_chown(ceph_mount_info *cmount, const char *path, int uid, int gid)
int ceph_lchown(ceph_mount_info *cmount, const char *path, int uid, int gid)

View File

@ -1102,6 +1102,26 @@ cdef class LibCephFS(object):
if ret < 0:
raise make_ex(ret, "error in chmod {}".format(path.decode('utf-8')))
def lchmod(self, path, mode) -> None:
"""
Change file mode. If the path is a symbolic link, it won't be dereferenced.
:param path: the path of the file. This must be either an absolute path or
a relative path off of the current working directory.
:param mode: the permissions to be set .
"""
self.require_state("mounted")
path = cstr(path, 'path')
if not isinstance(mode, int):
raise TypeError('mode must be an int')
cdef:
char* _path = path
int _mode = mode
with nogil:
ret = ceph_lchmod(self.cluster, _path, _mode)
if ret < 0:
raise make_ex(ret, "error in chmod {}".format(path.decode('utf-8')))
def fchmod(self, fd, mode) :
"""
Change file mode based on fd.

View File

@ -189,6 +189,8 @@ cdef nogil:
pass
int ceph_chmod(ceph_mount_info *cmount, const char *path, mode_t mode):
pass
int ceph_lchmod(ceph_mount_info *cmount, const char *path, mode_t mode):
pass
int ceph_fchmod(ceph_mount_info *cmount, int fd, mode_t mode):
pass
int ceph_chown(ceph_mount_info *cmount, const char *path, int uid, int gid):

View File

@ -1,5 +1,5 @@
# vim: expandtab smarttab shiftwidth=4 softtabstop=4
from nose.tools import assert_raises, assert_equal, assert_greater, with_setup
from nose.tools import assert_raises, assert_equal, assert_not_equal, assert_greater, with_setup
import cephfs as libcephfs
import fcntl
import os
@ -540,6 +540,31 @@ def test_futimens():
cephfs.close(fd)
cephfs.unlink(b'/file-1')
@with_setup(setup_test)
def test_lchmod():
fd = cephfs.open(b'/file-1', 'w', 0o755)
cephfs.write(fd, b'0000', 0)
cephfs.close(fd)
cephfs.symlink(b'/file-1', b'/file-2')
stx_pre_t = cephfs.statx(b'/file-1', libcephfs.CEPH_STATX_MODE, 0)
stx_pre_s = cephfs.statx(b'/file-2', libcephfs.CEPH_STATX_MODE, libcephfs.AT_SYMLINK_NOFOLLOW)
time.sleep(1)
cephfs.lchmod(b'/file-2', 0o400)
stx_post_t = cephfs.statx(b'/file-1', libcephfs.CEPH_STATX_MODE, 0)
stx_post_s = cephfs.statx(b'/file-2', libcephfs.CEPH_STATX_MODE, libcephfs.AT_SYMLINK_NOFOLLOW)
assert_equal(stx_post_t['mode'], stx_pre_t['mode'])
assert_not_equal(stx_post_s['mode'], stx_pre_s['mode'])
stx_post_s_perm_bits = stx_post_s['mode'] & ~stat.S_IFMT(stx_post_s["mode"])
assert_equal(stx_post_s_perm_bits, 0o400)
cephfs.unlink(b'/file-2')
cephfs.unlink(b'/file-1')
@with_setup(setup_test)
def test_fchmod():
fd = cephfs.open(b'/file-fchmod', 'w', 0o655)