コード例 #1
0
ファイル: ukai_core.py プロジェクト: keiichishima/ukai2
 def __init__(self, config):
     self._metadata_dict = {}
     self._data_dict = {}
     self._config = config
     self._node_error_state_set = UKAINodeErrorStateSet()
     self._open_image_set = set()
     self._rpc_trans = UKAIXMLRPCTranslation()
コード例 #2
0
ファイル: ukai_core.py プロジェクト: keiichishima/ukai
 def __init__(self, config):
     self._metadata_dict = {}
     self._data_dict = {}
     self._config = config
     self._node_error_state_set = UKAINodeErrorStateSet()
     self._rpc_trans = UKAIXMLRPCTranslation()
     self._writers = UKAIWriters()
     self._open_count = UKAIOpenImageCount()
     self._fh = 0
     ukai_db_client.connect(self._config)
コード例 #3
0
ファイル: ukai_core.py プロジェクト: keiichishima/ukai2
class UKAICore(object):
    ''' UKAI core processing.
    '''

    def __init__(self, config):
        self._metadata_dict = {}
        self._data_dict = {}
        self._config = config
        self._node_error_state_set = UKAINodeErrorStateSet()
        self._open_image_set = set()
        self._rpc_trans = UKAIXMLRPCTranslation()

    @property
    def metadata_server(self):
        return self._config.get('metadata_server')

    @property
    def core_server(self):
        return self._config.get('core_server')

    @property
    def core_port(self):
        return self._config.get('core_port')

    ''' Filesystem I/O processing.
    '''
    def getattr(self, path):
        ret = 0
        st = None
        if path == '/':
            st = dict(st_mode=(stat.S_IFDIR | 0755), st_ctime=0,
                      st_mtime=0, st_atime=0, st_nlink=2)
        else:
            image_name = path[1:]
            if self._exists(image_name):
                st = dict(st_mode=(stat.S_IFREG | 0644), st_ctime=0,
                          st_mtime=0, st_atime=0, st_nlink=1,
                          st_size=self._metadata_dict[image_name].size)
            else:
                ret = errno.ENOENT
        return ret, st

    def open(self, path, flags):
        ret = 0
        image_name = path[1:]
        if not self._exists(image_name):
            return errno.ENOENT
        if image_name in self._open_image_set:
            return errno.EBUSY
        else:
            self._open_image_set.add(image_name)

        return 0

    def release(self, path):
        image_name = path[1:]
        if image_name in self._open_image_set:
            self._open_image_set.remove(image_name)
        return 0

    def read(self, path, size, offset):
        image_name = path[1:]
        if not self._exists(image_name):
            return errno.ENOENT, None
        image_data = self._data_dict[image_name]
        data = image_data.read(size, offset)
        return 0, self._rpc_trans.encode(data)

    def readdir(self, path):
        return ['.', '..'] + self._metadata_dict.keys()

    def statfs(self, path):
        ''' TODO: the values are fake right now.
        '''
        return dict(f_bsize=512, f_blocks=4096, f_bavail=2048)

    def truncate(self, path, length):
        return errno.EPERM

    def unlink(self, path):
        return errno.EPERM

    def write(self, path, encoded_data, offset):
        image_name = path[1:]
        if not self._exists(image_name):
            return errno.ENOENT, None
        image_data = self._data_dict[image_name]
        return 0, image_data.write(self._rpc_trans.decode(encoded_data),
                                   offset)

    def _exists(self, image_name):
        if image_name not in self._metadata_dict:
            return False
        if image_name not in self._data_dict:
            return False
        return True


    ''' Proxy server processing.
    '''
    def proxy_read(self, image_name, block_size, block_index, offset,
                   size):
        data = ukai_local_read(image_name, block_size, block_index,
                               offset, size, self._config)
        return self._rpc_trans.encode(zlib.compress(data))

    def proxy_write(self, image_name, block_size, block_index, offset,
                    encoded_data):
        data = zlib.decompress(self._rpc_trans.decode(encoded_data))
        return ukai_local_write(image_name, block_size, block_index,
                                offset, data, self._config)

    def proxy_allocate_dataspace(self, image_name, block_size, block_index):
        return ukai_local_allocate_dataspace(image_name, block_size,
                                             block_index, self._config)

    def proxy_update_metadata(self, image_name, encoded_metadata):
        metadata_raw = json.loads(zlib.decompress(self._rpc_trans.decode(
                    encoded_metadata)))
        if image_name in self._metadata_dict:
            self._metadata_dict[image_name].metadata = metadata_raw
        else:
            metadata = UKAIMetadata(image_name, self._config, metadata_raw)
            self._metadata_dict[image_name] = metadata
            self._data_dict[image_name] = UKAIData(metadata,
                                                   self._node_error_state_set,
                                                   self._config)
            UKAIStatistics[image_name] = UKAIImageStatistics()

        return 0

    ''' Controll processing.
    '''
    def ctl_create_image(self, image_name, size, block_size=None,
                         location=None, hypervisor=None):
        assert image_name is not None
        assert size > 0

        if block_size is None:
            defaults = self._config.get('create_default')
            block_size = defaults['block_size']
        assert block_size > 0
        assert size > block_size
        assert size % block_size == 0
        block_count = size / block_size

        if location is None:
            location = self._config.get('core_server')
        if hypervisor is None:
            hypervisor = self._config.get('core_server')

        ukai_metadata_create(image_name, size, block_size,
                             location, hypervisor, self._config)

    def ctl_add_image(self, image_name):
        if image_name in self._metadata_dict:
            return errno.EEXIST
        metadata = UKAIMetadata(image_name, self._config)
        self._metadata_dict[image_name] = metadata
        data = UKAIData(metadata=metadata,
                        node_error_state_set=self._node_error_state_set,
                        config=self._config)
        self._data_dict[image_name] = data
        UKAIStatistics[image_name] = UKAIImageStatistics()
        return 0

    def ctl_remove_image(self, image_name):
        if image_name not in self._metadata_dict:
            return errno.ENOENT
        del self._metadata_dict[image_name]
        del self._data_dict[image_name]
        del UKAIStatistics[image_name]
        return 0

    def ctl_get_metadata(self, image_name):
        if image_name not in self._metadata_dict:
            return errno.ENOENT, None
        return 0, json.dumps(self._metadata_dict[image_name].metadata)

    def ctl_add_location(self, image_name, location,
                         start_index=0, end_index=-1,
                         sync_status=UKAI_OUT_OF_SYNC):
        if image_name not in self._metadata_dict:
            return errno.ENOENT
        metadata = self._metadata_dict[image_name]
        metadata.add_location(location, start_index, end_index, sync_status)
        return 0

    def ctl_remove_location(self, image_name, location,
                            start_index=0, end_index=-1):
        if image_name not in self._metadata_dict:
            return errno.ENOENT
        metadata = self._metadata_dict[image_name]
        metadata.remove_location(location, start_index, end_index)
        return 0 

    def ctl_add_hypervisor(self, image_name, hypervisor):
        if image_name not in self._metadata_dict:
            return errno.ENOENT
        metadata = self._metadata_dict[image_name]
        metadata.add_hypervisor(hypervisor)
        return 0

    def ctl_remove_hypervisor(self, image_name, hypervisor):
        if image_name not in self._metadata_dict:
            return errno.ENOENT
        metadata = self._metadata_dict[image_name]
        metadata.remove_hypervisor(hypervisor)
        return 0

    def ctl_synchronize(self, image_name, start_index=0, end_index=-1,
                        verbose=False):
        if image_name not in self._metadata_dict:
            return errno.ENOENT
        metadata = self._metadata_dict[image_name]
        data = self._data_dict[image_name]
        if end_index == -1:
            end_index = (metadata.size / metadata.block_size) - 1
        for block_index in range(start_index, end_index + 1):
            if verbose is True:
                print 'Syncing block %d (from %d to %d)' % (block_index,
                                                            start_index,
                                                            end_index)
            if data.synchronize_block(block_index) is True:
                metadata.flush()
        return 0

    def ctl_get_node_error_state_set(self):
        return self._node_error_state_set.get_list()
コード例 #4
0
ファイル: ukai_core.py プロジェクト: keiichishima/ukai
class UKAICore(object):
    ''' The UKAICore class implements core processing of the UKAI
    filesystem.
    '''

    def __init__(self, config):
        self._metadata_dict = {}
        self._data_dict = {}
        self._config = config
        self._node_error_state_set = UKAINodeErrorStateSet()
        self._rpc_trans = UKAIXMLRPCTranslation()
        self._writers = UKAIWriters()
        self._open_count = UKAIOpenImageCount()
        self._fh = 0
        ukai_db_client.connect(self._config)

    ''' Filesystem I/O processing.
    '''
    def getattr(self, path):
        ret = 0
        st = None
        if path == '/':
            st = dict(st_mode=(stat.S_IFDIR | 0755), st_ctime=0,
                      st_mtime=0, st_atime=0, st_nlink=2)
        else:
            image_name = path[1:]
            metadata = self._get_metadata(image_name)
            if metadata is not None:
                st = dict(st_mode=(stat.S_IFREG | 0644), st_ctime=0,
                          st_mtime=0, st_atime=0, st_nlink=1,
                          st_size=metadata['used_size'])
            else:
                ret = errno.ENOENT
        return ret, json.dumps(st)

    def open(self, path, flags):
      try:
          lock.acquire()
          ret = 0
          image_name = path[1:]
          metadata = self._get_metadata(image_name)
          if metadata is None:
              return errno.ENOENT, None
          self._fh += 1
          if (flags & 3) != os.O_RDONLY:
              if self._writers.add_writer(image_name, self._fh) == errno.EBUSY:
                  return errno.EBUSY, None
          if self._open_count.increment(image_name) == 1:
              self._add_image(image_name)
          return 0, self._fh
      finally:
          lock.release()

    def release(self, path, fh):
      try:
          lock.acquire()
          image_name = path[1:]
          self._writers.remove_writer(image_name, fh)
          if self._open_count.decrement(image_name) == 0:
              self._remove_image(image_name)
          return 0
      finally:
          lock.release()

    def read(self, path, str_size, str_offset):
        image_name = path[1:]
	size = int(str_size)
	offset = int(str_offset)
        if not self._exists(image_name):
            return errno.ENOENT, None
        image_data = self._data_dict[image_name]
        data = image_data.read(size, offset)
        return 0, self._rpc_trans.encode(data)

    def readdir(self, path):
        return ['.', '..'] + self._metadata_dict.keys()

    def statfs(self, path):
        ''' TODO: the values are fake right now.
        '''
        return dict(f_bsize=512, f_blocks=4096, f_bavail=2048)

    def truncate(self, path, str_length):
        image_name = path[1:]
        length = int(str_length)
        if not self._exists(image_name):
            return errno.ENOENT
        image_metadata = self._metadata_dict[image_name]
        if image_metadata.size < length:
            return errno.EINVAL
        image_metadata.used_size = length
        image_metadata.flush()
        return 0

    def unlink(self, path):
        return errno.EPERM

    def write(self, path, encoded_data, str_offset):
        image_name = path[1:]
	offset = int(str_offset)
        if not self._exists(image_name):
            return errno.ENOENT, None
        image_data = self._data_dict[image_name]
        return 0, image_data.write(self._rpc_trans.decode(encoded_data),
                                   offset)

    def _get_metadata(self, image_name):
        return ukai_db_client.get_metadata(image_name)

    def _add_image(self, image_name):
        assert image_name not in self._metadata_dict
        metadata = UKAIMetadata(image_name, self._config)
        ukai_db_client.join_reader(image_name, self._config.get('id'))
        self._metadata_dict[image_name] = metadata
        data = UKAIData(metadata=metadata,
                        node_error_state_set=self._node_error_state_set,
                        config=self._config)
        self._data_dict[image_name] = data
        UKAIStatistics[image_name] = UKAIImageStatistics()

    def _remove_image(self, image_name):
        assert image_name in self._metadata_dict
        ukai_db_client.leave_reader(image_name, self._config.get('id'))
        del self._metadata_dict[image_name]
        del self._data_dict[image_name]
        del UKAIStatistics[image_name]

    def _exists(self, image_name):
        if image_name not in self._metadata_dict:
            return False
        if image_name not in self._data_dict:
            return False
        return True


    ''' Proxy server processing.
    '''
    def proxy_read(self, image_name, str_block_size, str_block_index,
                   str_offset, str_size):
        block_size = int(str_block_size)
        block_index = int(str_block_index)
        offset = int(str_offset)
        size = int(str_size)
        data = ukai_local_read(image_name, block_size, block_index,
                               offset, size, self._config)
        return self._rpc_trans.encode(zlib.compress(data))

    def proxy_write(self, image_name, str_block_size, str_block_index,
                    str_offset, encoded_data):
        block_size = int(str_block_size)
        block_index = int(str_block_index)
        offset = int(str_offset)
        data = zlib.decompress(self._rpc_trans.decode(encoded_data))
        return ukai_local_write(image_name, block_size, block_index,
                                offset, data, self._config)

    def proxy_allocate_dataspace(self, image_name, block_size, block_index):
        return ukai_local_allocate_dataspace(image_name, block_size,
                                             block_index, self._config)

    def proxy_deallocate_dataspace(self, image_name, block_index):
        return ukai_local_deallocate_dataspace(image_name, block_index,
                                               self._config)

    def proxy_update_metadata(self, image_name, encoded_metadata):
        metadata_raw = json.loads(zlib.decompress(self._rpc_trans.decode(
                    encoded_metadata)))
        if image_name in self._metadata_dict:
            self._metadata_dict[image_name].metadata = metadata_raw
        else:
            metadata = UKAIMetadata(image_name, self._config, metadata_raw)
            self._metadata_dict[image_name] = metadata
            self._data_dict[image_name] = UKAIData(metadata,
                                                   self._node_error_state_set,
                                                   self._config)
            UKAIStatistics[image_name] = UKAIImageStatistics()

        return 0

    def proxy_destroy_image(self, image_name):
        return ukai_local_destroy_image(image_name, self._config)


    ''' Controll processing.
    '''
    def ctl_create_image(self, image_name, str_size, block_size=None,
                         location=None):
        assert image_name is not None
        size = int(str_size)
        assert size > 0

        if block_size is None:
            defaults = self._config.get('create_default')
            block_size = defaults['block_size']
        assert block_size > 0
        assert size > block_size
        assert size % block_size == 0
        block_count = size / block_size

        if location is None:
            location = self._config.get('core_server')

        ukai_metadata_create(image_name, size, block_size,
                             location, self._config)

    def ctl_destroy_image(self, image_name):
        assert image_name is not None

        ukai_data_destroy(image_name, self._config)
        ukai_metadata_destroy(image_name, self._config)

    def ctl_get_metadata(self, image_name):
        metadata = self._get_metadata(image_name)
        if metadata is None:
            return errno.ENOENT, None
        return 0, json.dumps(metadata)

    def ctl_add_location(self, image_name, location,
                         start_index=0, end_index=-1,
                         sync_status=UKAI_OUT_OF_SYNC):
        metadata = None
        if image_name in self._metadata_dict:
            # the image is in use on this node.
            metadata = self._metadata_dict[image_name]
        else:
            # XXX need to check if no one is using this image.
            metadata_raw = self._get_metadata(image_name)
            if metadata_raw is None:
                return errno.ENOENT
            metadata = UKAIMetadata(image_name, self._config, metadata_raw)
        metadata.add_location(location, start_index, end_index, sync_status)
        return 0

    def ctl_remove_location(self, image_name, location,
                            start_index=0, end_index=-1):
        metadata = None
        if image_name in self._metadata_dict:
            # the image is in use on this node.
            metadata = self._metadata_dict[image_name]
        else:
            # XXX need to check if no one is using this image.
            metadata_raw = self._get_metadata(image_name)
            if metadata_raw is None:
                return errno.ENOENT
            metadata = UKAIMetadata(image_name, self._config, metadata_raw)
        metadata.remove_location(location, start_index, end_index)
        ukai_data_location_destroy(image_name, location, self._config)
        return 0 

    def ctl_add_hypervisor(self, image_name, hypervisor):
        metadata = None
        if image_name in self._metadata_dict:
            # the image is in use on this node.
            metadata = self._metadata_dict[image_name]
        else:
            # XXX need to check if no one is using this image.
            metadata_raw = self._get_metadata(image_name)
            if metadata_raw is None:
                return errno.ENOENT
            metadata = UKAIMetadata(image_name, self._config, metadata_raw)
        metadata.add_hypervisor(hypervisor)
        return 0

    def ctl_remove_hypervisor(self, image_name, hypervisor):
        metadata = None
        if image_name in self._metadata_dict:
            # the image is in use on this node.
            metadata = self._metadata_dict[image_name]
        else:
            # XXX need to check if no one is using this image.
            metadata_raw = self._get_metadata(image_name)
            if metadata_raw is None:
                return errno.ENOENT
            metadata = UKAIMetadata(image_name, self._config, metadata_raw)
        metadata.remove_hypervisor(hypervisor)
        return 0

    def ctl_synchronize(self, image_name, start_index=0, end_index=-1,
                        verbose=False):
        metadata = None
        if image_name in self._metadata_dict:
            # the image is in use on this node.
            metadata = self._metadata_dict[image_name]
            data = self._data_dict[image_name]
        else:
            # XXX need to check if no one is using this image.
            metadata_raw = self._get_metadata(image_name)
            if metadata_raw is None:
                return errno.ENOENT
            metadata = UKAIMetadata(image_name, self._config, metadata_raw)
            data = UKAIData(metadata, self._node_error_state_set, self._config)
        if end_index == -1:
            end_index = (metadata.size / metadata.block_size) - 1
        for block_index in range(start_index, end_index + 1):
            if verbose is True:
                print 'Syncing block %d (from %d to %d)' % (block_index,
                                                            start_index,
                                                            end_index)
            if data.synchronize_block(block_index) is True:
                metadata.flush()
        return 0

    def ctl_get_node_error_state_set(self):
        return self._node_error_state_set.get_list()

    def ctl_get_image_names(self):
        return ukai_db_client.get_image_names()

    def ctl_diag(self):
        print self._open_count._images
        print self._writers._images
	print self._metadata_dict
        return 0
コード例 #5
0
            fh.seek(self._metadata.block_size - 1)
            fh.write('\0')
            fh.close()
        else:
            remote = xmlrpclib.ServerProxy(
                'http://%s:%d/' % (node, self._config.get('core_port')))
            remote.proxy_allocate_dataspace(self._metadata.name,
                                            self._metadata.block_size, blk_idx)


if __name__ == '__main__':
    from ukai_node_error_state import UKAINodeErrorStateSet

    ukai_config.set('data_root', './test/local/data')
    ukai_config.set('metadata_root', './test/local/metadata')
    ness = UKAINodeErrorStateSet()

    meta = UKAIMetadata('./test/local/metadata/test')
    fh = UKAIData(meta, ness)
    data = 'Hello World!'
    offset = 0
    print 'offset %d' % offset
    fh.write(data, offset)
    ver = fh.read(len(data), offset)
    if ver != data:
        print 'error at offset %d' % offset

    offset = meta.block_size - (len(data) / 2)
    print 'offset %d' % offset
    fh.write(data, offset)
    ver = fh.read(len(data), offset)