Beispiel #1
0
 def frozen(self, args):
     """Make device readonly"""
     dev = self._get_device(args.path)
     id = dev.config.id
     if id not in self._devices:
         raise IOError('not found')
     messager.call(config.storage_server_address, 'storage.frozen', did = id)
     dev.config.mode = 'frozen'
     dev.flush()
     return 'ok'
Beispiel #2
0
    def offline(self, args):
        """Offline device, data on this device is not available anymore unless
        you online it again. You can decide whether to replicate data first."""
        dev = self._get_device(args.path)
        id = dev.config.id
        if id not in self._devices:
            raise IOError('not found')
        messager.call(config.storage_server_address, 'storage.offline', did = id, replicate = False)
        dev.flush()

        del self._devices[id]
        self._flush()
        return 'ok'
Beispiel #3
0
    def _heartbeat(self):
        """Heartbeat message to storage server
        upstream: devices infos such as size, used change
        downstream: deleted chunks
        """
        while True:
            # Lock
            tmp = self._devices_changed
            self._devices_changed = []
            confs = {}
            # Unlock

            # Read newest status of devs
            # changed = {}
            for did in tmp:
                try:
                    confs[did] = self._lookup_dev(did).config
                except:
                    continue

            rc = messager.call(config.storage_server_address, 'storage.heartbeat', addr = self._addr, confs = confs)
            if rc.needreport:
                # Start another thread to send chunk reports
                thread.start_new_thread(self._send_chunk_reports, ())

            # Delete old chunks
            for did, chunks in rc.deleted_chunks.items():
                try:
                    dev = self._lookup_dev(did)
                except:
                    continue
                self._mark_changed(did)
                self._chunk_shard.delete_chunks(chunks, dev)

            time.sleep(5)
Beispiel #4
0
    def online(self, args):
        """Online device, send reports to storage server
        The 'online' status information is only maintained by storage server.
        """
        dev = self._get_device(args.path)
        id = dev.config.id
        if id not in self._devices:
            self._devices[id] = dev.config.path # Add entry

        if dev.config.type != 'chunk':
            raise IOError('wrong type')

        compressed_report = zlib.compress(pformat(self._get_chunks(dev)))
        messager.call(config.storage_server_address, 'storage.online', conf = dev.config, addr = config.chunk_server_address, payload = compressed_report)
        dev.flush()
        self._flush()
        return 'ok'
Beispiel #5
0
    def delete(self, req):
        """Delete file, store the free chunks to file 'deleted_chunks', tell
        it to storage manager in next hb message
    
        There shall be a .trash dir to store it first, auto delete 30 days later
        
        @file                note that root can't be deleted
        @recursive           bool
        
        return ok
        """
        req.file = os.path.normpath(req.file)
        
        if req.file == '/':
            self._error('attempt to delete root')
    
        parent = self._lookup(os.path.dirname(req.file))
        name = os.path.basename(req.file)
        if not parent or name not in parent.children:
            self._error('no such file or directory')

        obj = self._object_shard.load_object(parent.children[name])
        if obj:
            if obj.type == 'dir':
                if len(obj.children) > 2:
                    if not req.recursive:
                        self._error('dir not empty')
                # Delete dir recursively
                deleted = self._delete_recursive(obj)
        
             #Delete file
            if obj.type == 'file':
                deleted = self._delete_file(obj)
        else:
            # Shall we return error?
            #self._error('file object missing')
            pass
        # Delete entry in parent
        del parent.children[name]
        self._object_shard.store_object(parent)

        # Free chunks to storage, this should be done in another thread
        messager.call(config.storage_server_address, 'storage.free', deleted = deleted)
        return 'ok'
Beispiel #6
0
 def status(self, args):
     """Show storage status
     all       status of the global pool
     local     status of all local devs
     /data/sda status of a local dev
     
     id  # TODO: get disks info on remote chunk servers
                 First lookup in local then in storage server
     """
     if args.path == 'local':
         for did, path in self._devices.items():
             print did, path
     elif args.path == 'all':
         status = messager.call(config.storage_server_address, 'storage.status')
         for k in status.nodes.keys():
             node = status.nodes[k]
             print '%s:%d' % (k[0], k[1]), time.ctime(node.update_time)
             for did in node.devs:
                 print '     ',
                 self._print_device(OODict(status.devices[did].conf))
     else:
         dev = self._get_device(args.path)
         self._print_device(dev.config)