Ejemplo n.º 1
0
    async def setxattr(self, id_, name, value, ctx):
        log.debug('started with %d, %r, %r', id_, name, value)

        # Handle S3QL commands
        if id_ == CTRL_INODE:
            if name == b's3ql_flushcache!':
                self.inodes.flush()
                await self.cache.flush()

            elif name == b's3ql_dropcache!':
                self.inodes.drop()
                await self.cache.drop()

            elif name == b'copy':
                try:
                    tup = parse_literal(value, (int, int))
                except ValueError:
                    log.warning('Received malformed command via control inode')
                    raise FUSEError.EINVAL()
                await self.copy_tree(*tup)

            elif name == b'upload-meta':
                if self.upload_event is not None:
                    self.inodes.flush()
                    self.upload_event.set()
                else:
                    raise FUSEError(errno.ENOTTY)

            elif name == b'lock':
                try:
                    id_ = parse_literal(value, int)
                except ValueError:
                    log.warning('Received malformed command via control inode')
                    raise FUSEError.EINVAL()
                await self.lock_tree(id_)

            elif name == b'rmtree':
                try:
                    tup = parse_literal(value, (int, bytes))
                except ValueError:
                    log.warning('Received malformed command via control inode')
                    raise FUSEError.EINVAL()
                await self.remove_tree(*tup)

            elif name == b'logging':
                try:
                    (lvl, modules) = parse_literal(value, (int, str))
                except (ValueError, KeyError):
                    log.warning('Received malformed command via control inode')
                    raise FUSEError.EINVAL()
                update_logging(lvl, modules.split(',') if modules else None)

            elif name == b'cachesize':
                try:
                    self.cache.cache.max_size = parse_literal(value, int)
                except ValueError:
                    log.warning('Received malformed command via control inode')
                    raise FUSEError.EINVAL()
                log.debug('updated cache size to %d bytes',
                          self.cache.cache.max_size)

            else:
                log.warning('Received unknown command via control inode')
                raise FUSEError(errno.EINVAL)

        # http://code.google.com/p/s3ql/issues/detail?id=385
        elif name in (b'system.posix_acl_access', b'system.posix_acl_default'):
            raise FUSEError(ACL_ERRNO)

        else:
            if self.failsafe or self.inodes[id_].locked:
                raise FUSEError(errno.EPERM)

            if len(value) > deltadump.MAX_BLOB_SIZE:
                raise FUSEError(errno.EINVAL)

            self.db.execute(
                'INSERT OR REPLACE INTO ext_attributes (inode, name_id, value) '
                'VALUES(?, ?, ?)', (id_, self._add_name(name), value))
            self.inodes[id_].ctime_ns = time_ns()