def do_stat(path): serr = None for i in range(0, _STAT_ATTEMPTS): try: stats = os.stat(path) except OSError as err: if err.errno == errno.EIO: # Retry EIO assuming it is a transient error from FUSE after a # short random sleep serr = err sleep(random.uniform(0.001, 0.005)) continue if err.errno in (errno.ENOENT, errno.ESTALE): stats = None else: raise FileConnectorFileSystemOSError( err.errno, '%s, os.stat("%s")[%d attempts]' % ( err.strerror, path, i)) if i > 0: logging.warn("fs_utils.do_stat():" " os.stat('%s') retried %d times (%s)", path, i, 'success' if stats else 'failure') return stats else: raise FileConnectorFileSystemOSError( serr.errno, '%s, os.stat("%s")[%d attempts]' % ( serr.strerror, path, _STAT_ATTEMPTS))
def do_fchown(fd, uid, gid): try: os.fchown(fd, uid, gid) except OSError as err: raise FileConnectorFileSystemOSError( err.errno, '%s, os.fchown(%s, %s, %s)' % ( err.strerror, fd, uid, gid))
def do_fstat(fd): try: stats = os.fstat(fd) except OSError as err: raise FileConnectorFileSystemOSError( err.errno, '%s, os.fstat(%s)' % (err.strerror, fd)) return stats
def do_chown(path, uid, gid): try: os.chown(path, uid, gid) except OSError as err: raise FileConnectorFileSystemOSError( err.errno, '%s, os.chown("%s", %s, %s)' % ( err.strerror, path, uid, gid))
def do_rename(old_path, new_path): try: os.rename(old_path, new_path) except OSError as err: raise FileConnectorFileSystemOSError( err.errno, '%s, os.rename("%s", "%s")' % ( err.strerror, old_path, new_path))
def do_listdir(path): try: buf = os.listdir(path) except OSError as err: raise FileConnectorFileSystemOSError( err.errno, '%s, os.listdir("%s")' % (err.strerror, path)) return buf
def do_read(fd, n): try: buf = os.read(fd, n) except OSError as err: raise FileConnectorFileSystemOSError( err.errno, '%s, os.write("%s", ...)' % (err.strerror, fd)) return buf
def _write_metadata(self, path, metadata, fd=None): meta_dir_path, meta_file_path = self._get_metadata_dir(path) # create metadata dir if it doesn't exist # TODO error handling if not os.path.exists(meta_dir_path): mkdirs(meta_dir_path) metastr = serialize_metadata(metadata) tmpfile = meta_file_path + '_' + uuid4().hex try: with open(tmpfile, 'wt') as f: f.write(metastr) except IOError as err: if err.errno in (errno.ENOSPC, errno.EDQUOT): do_log_rl("_write_metadata failed: %s : %s", err, meta_file_path) raise DiskFileNoSpace() else: raise FileConnectorFileSystemIOError( err.errno, '_write_metadata failed: %s : %s' % (err, meta_file_path)) try: do_rename(tmpfile, meta_file_path) except OSError as err: # TODO better error handling raise FileConnectorFileSystemOSError( err.errno, "%s, rename('%s', '%s')" % ( err.strerror, tmpfile, meta_file_path))
def delete_metadata(self, path): meta_dir_path, meta_file_path = self._get_metadata_dir(path) try: do_rmtree(meta_dir_path) except OSError as err: raise FileConnectorFileSystemOSError( err.errno, "%s, do_rmtree('%s')" % ( err.strerror, meta_dir_path))
def do_fdatasync(fd): try: os.fdatasync(fd) except AttributeError: do_fsync(fd) except OSError as err: raise FileConnectorFileSystemOSError( err.errno, '%s, os.fsync("%s")' % (err.strerror, fd))
def do_open(path, flags, **kwargs): try: fd = os.open(path, flags, **kwargs) except OSError as err: raise FileConnectorFileSystemOSError( err.errno, '%s, os.open("%s", %x, %r)' % ( err.strerror, path, flags, kwargs)) return fd
def do_unlink(path, log=True): try: os.unlink(path) except OSError as err: if err.errno not in (errno.ENOENT, errno.ESTALE): raise FileConnectorFileSystemOSError( err.errno, '%s, os.unlink("%s")' % (err.strerror, path)) else: logging.warn("fs_utils: os.unlink failed on non-existent path: %s", path)
def do_ismount(path): """ Test whether a path is a mount point. This is code hijacked from C Python 2.6.8, adapted to remove the extra lstat() system call. """ try: s1 = os.lstat(path) except os.error as err: if err.errno == errno.ENOENT: # It doesn't exist -- so not a mount point :-) return False else: raise FileConnectorFileSystemOSError( err.errno, '%s, os.lstat("%s")' % (err.strerror, path)) if stat.S_ISLNK(s1.st_mode): # A symlink can never be a mount point return False try: s2 = os.lstat(os.path.join(path, '..')) except os.error as err: raise FileConnectorFileSystemOSError( err.errno, '%s, os.lstat("%s")' % (err.strerror, os.path.join(path, '..'))) dev1 = s1.st_dev dev2 = s2.st_dev if dev1 != dev2: # path/.. on a different device as path return True ino1 = s1.st_ino ino2 = s2.st_ino if ino1 == ino2: # path/.. is the same i-node as path return True return False
def do_close(fd): try: os.close(fd) except OSError as err: if err.errno in (errno.ENOSPC, errno.EDQUOT): filename = get_filename_from_fd(fd) do_log_rl("do_close(%d) failed: %s : %s", fd, err, filename) raise DiskFileNoSpace() else: raise FileConnectorFileSystemOSError( err.errno, '%s, os.close(%s)' % (err.strerror, fd))
def do_write(fd, buf): try: cnt = os.write(fd, buf) except OSError as err: filename = get_filename_from_fd(fd) if err.errno in (errno.ENOSPC, errno.EDQUOT): do_log_rl("do_write(%d, msg[%d]) failed: %s : %s", fd, len(buf), err, filename) raise DiskFileNoSpace() else: raise FileConnectorFileSystemOSError( err.errno, '%s, os.write("%s", ...)' % (err.strerror, fd)) return cnt
def mkdirs(path): """ Ensures the path is a directory or makes it if not. Errors if the path exists but is a file or on permissions failure. :param path: path to create """ try: os.makedirs(path) except OSError as err: if err.errno == errno.EEXIST and os.path.isdir(path): return elif err.errno in (errno.ENOSPC, errno.EDQUOT): do_log_rl("mkdirs(%s) failed: %s", path, err) raise DiskFileNoSpace() else: raise FileConnectorFileSystemOSError( err.errno, '%s, os.makedirs("%s")' % (err.strerror, path))
def do_lseek(fd, pos, how): try: os.lseek(fd, pos, how) except OSError as err: raise FileConnectorFileSystemOSError( err.errno, '%s, os.fsync("%s")' % (err.strerror, fd))
def do_rmdir(path): try: os.rmdir(path) except OSError as err: raise FileConnectorFileSystemOSError( err.errno, '%s, os.rmdir("%s")' % (err.strerror, path))