From c7ce3beec168cfc530da9e8d11fc1a0e8c80bcce Mon Sep 17 00:00:00 2001 From: Mohammed Junaid Date: Tue, 25 Jun 2013 07:50:28 +0530 Subject: object-storage: Use fchown instead of chown. This is a step towards making fd based system calls where ever possible to avoid path lookups. Signed-off-by: Mohammed Junaid Change-Id: I482ea29ebe0859d0a5307ff25ecb5945d54bc7ca Reviewed-on: http://review.gluster.org/5251 Reviewed-by: Peter Portante Tested-by: Peter Portante --- gluster/swift/common/DiskDir.py | 5 +++-- gluster/swift/common/DiskFile.py | 4 ++-- gluster/swift/common/fs_utils.py | 9 +++++++++ test/unit/common/test_fs_utils.py | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/gluster/swift/common/DiskDir.py b/gluster/swift/common/DiskDir.py index c5793f5..364c95e 100644 --- a/gluster/swift/common/DiskDir.py +++ b/gluster/swift/common/DiskDir.py @@ -16,7 +16,8 @@ import os import errno -from gluster.swift.common.fs_utils import dir_empty, rmdirs, mkdirs, os_path +from gluster.swift.common.fs_utils import dir_empty, rmdirs, mkdirs, os_path, \ + do_chown from gluster.swift.common.utils import validate_account, validate_container, \ get_container_details, get_account_details, create_container_metadata, \ create_account_metadata, DEFAULT_GID, get_container_metadata, \ @@ -454,7 +455,7 @@ class DiskDir(DiskCommon): if not self._dir_exists: mkdirs(self.datadir) # If we create it, ensure we own it. - os.chown(self.datadir, self.uid, self.gid) + do_chown(self.datadir, self.uid, self.gid) metadata = get_container_metadata(self.datadir) metadata[X_TIMESTAMP] = timestamp write_metadata(self.datadir, metadata) diff --git a/gluster/swift/common/DiskFile.py b/gluster/swift/common/DiskFile.py index a3f7987..c7138d4 100644 --- a/gluster/swift/common/DiskFile.py +++ b/gluster/swift/common/DiskFile.py @@ -22,7 +22,7 @@ from swift.common.utils import renamer from swift.common.exceptions import DiskFileNotExist from gluster.swift.common.exceptions import AlreadyExistsAsDir from gluster.swift.common.fs_utils import mkdirs, rmdirs, do_open, do_close, \ - do_unlink, do_chown, os_path, do_fsync + do_unlink, do_chown, os_path, do_fsync, do_fchown from gluster.swift.common.utils import read_metadata, write_metadata, \ validate_object, create_object_metadata from gluster.swift.common.utils import X_CONTENT_LENGTH, X_CONTENT_TYPE, \ @@ -234,9 +234,9 @@ class Gluster_DiskFile(DiskFile): tmp_path = os.path.join(tmp_path, dir_name) self._create_dir_object(tmp_path) + do_fchown(fd, self.uid, self.gid) newpath = os.path.join(self.datadir, self._obj) renamer(self.tmppath, newpath) - do_chown(newpath, self.uid, self.gid) self.metadata = metadata self.data_file = newpath self.filter_metadata() diff --git a/gluster/swift/common/fs_utils.py b/gluster/swift/common/fs_utils.py index de450a5..b3f58b7 100644 --- a/gluster/swift/common/fs_utils.py +++ b/gluster/swift/common/fs_utils.py @@ -74,6 +74,15 @@ def do_chown(path, uid, gid): return True +def do_fchown(fd, uid, gid): + try: + os.fchown(fd, uid, gid) + except OSError as err: + logging.exception("fchown failed on %d err: %s", fd, err.strerror) + raise + return True + + def do_stat(path): try: #Check for fd. diff --git a/test/unit/common/test_fs_utils.py b/test/unit/common/test_fs_utils.py index 559c7db..175a362 100644 --- a/test/unit/common/test_fs_utils.py +++ b/test/unit/common/test_fs_utils.py @@ -363,6 +363,45 @@ class TestFsUtils(unittest.TestCase): else: self.fail("Expected OSError") + def test_fchown(self): + tmpdir = mkdtemp() + try: + fd, tmpfile = mkstemp(dir=tmpdir) + buf = os.stat(tmpfile) + if buf.st_uid == 0: + raise SkipTest + else: + try: + fs.do_fchown(fd, 20000, 20000) + except OSError as ex: + if ex.errno != errno.EPERM: + self.fail("Expected OSError") + else: + self.fail("Expected OSError") + finally: + os.close(fd) + shutil.rmtree(tmpdir) + + def test_fchown_err(self): + tmpdir = mkdtemp() + try: + fd, tmpfile = mkstemp(dir=tmpdir) + fd_rd = os.open(tmpfile, os.O_RDONLY) + buf = os.stat(tmpfile) + if buf.st_uid == 0: + raise SkipTest + else: + try: + fs.do_fchown(fd_rd, 20000, 20000) + except OSError as ex: + if ex.errno != errno.EPERM: + self.fail("Expected OSError") + else: + self.fail("Expected OSError") + finally: + os.close(fd_rd) + os.close(fd) + shutil.rmtree(tmpdir) def test_do_fsync(self): tmpdir = mkdtemp() -- cgit