summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Hanselmann <public@hansmi.ch>2018-07-27 17:00:27 +0200
committerMichael Hanselmann <public@hansmi.ch>2018-07-27 19:53:14 +0200
commit4991e72186e64152ea32286a8e2e73ebf651f30f (patch)
treeebb0258eb9e67d10ec2e3d25fc80786b4de2c782
parentd5e4a0362a08ca3c0e7a33ea8caafccb22b906b2 (diff)
Support mknod API
Gluster supports the mknod(2) API to create special files such as character and block devices. Add it to the "gfapi.Volume" class. Change-Id: Ie62245441997111b0cf6e44b2a14a1ad7b6d7d56 Signed-off-by: Michael Hanselmann <public@hansmi.ch>
-rw-r--r--gluster/gfapi/api.py6
-rw-r--r--gluster/gfapi/gfapi.py17
-rw-r--r--test/functional/libgfapi-python-tests.py7
-rw-r--r--test/unit/gluster/test_gfapi.py14
4 files changed, 44 insertions, 0 deletions
diff --git a/gluster/gfapi/api.py b/gluster/gfapi/api.py
index 971e98c..e4f0b14 100644
--- a/gluster/gfapi/api.py
+++ b/gluster/gfapi/api.py
@@ -515,3 +515,9 @@ glfs_get_volumeid = gfapi_prototype('glfs_get_volumeid', ctypes.c_int,
ctypes.c_void_p,
ctypes.c_char_p,
ctypes.c_size_t)
+
+glfs_mknod = gfapi_prototype('glfs_mknod', ctypes.c_int,
+ ctypes.c_void_p,
+ ctypes.c_char_p,
+ ctypes.c_uint32,
+ ctypes.c_uint32)
diff --git a/gluster/gfapi/gfapi.py b/gluster/gfapi/gfapi.py
index 5078c00..ee1fd36 100644
--- a/gluster/gfapi/gfapi.py
+++ b/gluster/gfapi/gfapi.py
@@ -1823,3 +1823,20 @@ class Volume(object):
if errors:
raise Error(errors)
+
+ @validate_mount
+ def mknod(self, path, mode, dev):
+ """
+ Create special or ordinary file; see mknod(2) for more details.
+
+ :param path: Path of file to be created.
+ :param mode: Operation to be performed on the given range
+ :param dev: Major and minor numbers for newly created device special
+ file; use os.makedev to build value. Ignored for other
+ types.
+ :raises: OSError on failure
+ """
+ ret = api.glfs_mknod(self.fs, decode_to_bytes(path), mode, dev)
+ if ret < 0:
+ err = ctypes.get_errno()
+ raise OSError(err, os.strerror(err))
diff --git a/test/functional/libgfapi-python-tests.py b/test/functional/libgfapi-python-tests.py
index be2801f..a699d8c 100644
--- a/test/functional/libgfapi-python-tests.py
+++ b/test/functional/libgfapi-python-tests.py
@@ -815,6 +815,13 @@ class FileOpsTest(unittest.TestCase):
self.assertEqual(src_stat.st_mode, dest_stat.st_mode)
self.assertEqual(src_stat.st_mtime, dest_stat.st_mtime)
+ def test_mknod(self):
+ self.vol.mknod("dev", stat.S_IFCHR | 0o644, os.makedev(1, 3))
+ st = self.vol.stat("dev")
+ self.assertTrue(stat.S_ISCHR(st.st_mode))
+ self.assertEqual(os.major(st.st_rdev), 1)
+ self.assertEqual(os.minor(st.st_rdev), 3)
+
class DirOpsTest(unittest.TestCase):
diff --git a/test/unit/gluster/test_gfapi.py b/test/unit/gluster/test_gfapi.py
index d35d7e1..a8c0035 100644
--- a/test/unit/gluster/test_gfapi.py
+++ b/test/unit/gluster/test_gfapi.py
@@ -1188,3 +1188,17 @@ class TestVolume(unittest.TestCase):
int(mtime))
self.assertEqual(mock_glfs_utimens.call_args[0][2][1].tv_nsec,
int(math.modf(mtime)[0] * 1e9))
+
+ def test_mknod_success(self):
+ mock_glfs_mknod = Mock()
+ mock_glfs_mknod.return_value = 0
+
+ with patch("gluster.gfapi.api.glfs_mknod", mock_glfs_mknod):
+ self.vol.mknod("testdev", 0o644, os.makedev(1, 3))
+
+ def test_mknod_fail_exception(self):
+ mock_glfs_mknod = Mock()
+ mock_glfs_mknod.return_value = -1
+
+ with patch("gluster.gfapi.api.glfs_mknod", mock_glfs_mknod):
+ self.assertRaises(OSError, self.vol.mknod, "testdev", 0o644, 0)