def NewChunkList(self, chksizes): volumelist = [] serlist = self.mds.GetChunkServers(5) if len(serlist) == 0: logging.error('Currently not ChunkServer is available') return None for size in chksizes: server = serlist[0] addr = server.ServiceAddress port = server.ServicePort chkclient = self.chkpool.get(self.guid, addr, port) chunks = chkclient.NewChunk(size, 1) if chunks == []: pass volume = Object() volume.size = size volume.assembler = 'chunk' volume.guid = Guid.toStr(chunks.guids[0]) volume.parameters = [volume.guid, '', '', addr, str(port)] path, nodename = self.MountChunk(volume) volume.parameters[1] = path volume.parameters[2] = nodename if path == None: for volume in volumelist: self.UnmountChunk(volume) logging.error('Mount chunk failed') return None volumelist.append(volume) return volumelist
def DeleteChunk(self, req): self.lvm.reload() ret = msg.DeleteChunk_Response() print 'ChunkServer: DeleteChunk' for a_guid in req.guids: str_guid=Guid.toStr(a_guid) lv_name = self.prefix_vol+str_guid lv_path = '/dev/'+self.vgname+'/'+lv_name output = self.lvm.lv_remove(lv_path) if output!=None: ret.error = "Unable to delete chunk {0}:\n{1}".format(str_guid, output) break t=ret.guids.add() Guid.assign(t, a_guid) return ret
def NewChunk(self, req): self.lvm.reload() ret = msg.NewChunk_Response() size = str(req.size)+'M' for i in range(req.count): a_guid = Guid.generate() lv_name = self.prefix_vol+Guid.toStr(a_guid) lv_size = size output = self.lvm.lv_create(self.vgname, lv_name, lv_size) if output!=None: ret.error = str(i) + ':' + output + ' ' break t=ret.guids.add() Guid.assign(t, a_guid) return ret
def DeleteChunk(self, req): self.lvm.reload() ret = msg.DeleteChunk_Response() print "ChunkServer: DeleteChunk" for a_guid in req.guids: str_guid = Guid.toStr(a_guid) lv_name = self.prefix_vol + str_guid lv_path = "/dev/" + self.vgname + "/" + lv_name output = self.lvm.lv_remove(lv_path) if output != None: ret.error = "Unable to delete chunk {0}:\n{1}".format(str_guid, output) break t = ret.guids.add() Guid.assign(t, a_guid) return ret
def NewChunk(self, req): self.lvm.reload() ret = msg.NewChunk_Response() size = str(req.size) + "M" for i in range(req.count): a_guid = Guid.generate() lv_name = self.prefix_vol + Guid.toStr(a_guid) lv_size = size output = self.lvm.lv_create(self.vgname, lv_name, lv_size) if output != None: ret.error = str(i) + ":" + output + " " break t = ret.guids.add() Guid.assign(t, a_guid) return ret
def message2object(message): "receive a PB message, returns its guid and a object describing the message" import guid as Guid, messages_pb2 as msg if not hasattr(message, 'ListFields'): return message fields=message.ListFields() rst=Object() for f in fields: name=f[0].name value=f[1] if isinstance(value, msg.Guid): value=Guid.toStr(value) elif hasattr(value, 'ListFields'): value=message2object(value, '') elif hasattr(value, '_values'): value=[message2object(x) for x in value._values] else: pass #should be a native value like str, int, float, ... setattr(rst, name, value) return rst
def message2object(message): "receive a PB message, returns its guid and a object describing the message" import guid as Guid, messages_pb2 as msg if not hasattr(message, 'ListFields'): return message fields = message.ListFields() rst = Object() for f in fields: name = f[0].name value = f[1] if isinstance(value, msg.Guid): value = Guid.toStr(value) elif hasattr(value, 'ListFields'): value = message2object(value, '') elif hasattr(value, '_values'): value = [message2object(x) for x in value._values] else: pass #should be a native value like str, int, float, ... setattr(rst, name, value) return rst
def AssembleVolume(self, req): self.tgt.reload() ret = msg.AssembleVolume_Response() str_guid = Guid.toStr(req.volume.guid) lv_name = self.prefix_vol+str_guid if not self.lvm.haslv(lv_name): ret.error = "Chunk {0} does not exist!".format(str_guid) return ret target_name = "iqn:softsan_"+str_guid target_id = self.tgt.target_name2target_id(target_name) if target_id != None: ret.access_point = target_name return ret while True: target_id = str(random.randint(0,1024*1024)) if not self.tgt.is_in_targetlist(target_id): break lun_path = '/dev/'+self.vgname+'/'+lv_name if self.tgt.new_target_lun(target_id, target_name, lun_path, 'ALL')!=None: ret.error = "Failed to export chunk {0} with tgt".format(str_guid) return ret ret.access_point = target_name return ret
def AssembleVolume(self, req): self.tgt.reload() ret = msg.AssembleVolume_Response() str_guid = Guid.toStr(req.volume.guid) lv_name = self.prefix_vol + str_guid if not self.lvm.haslv(lv_name): ret.error = "Chunk {0} does not exist!".format(str_guid) return ret target_name = "iqn:softsan_" + str_guid target_id = self.tgt.target_name2target_id(target_name) if target_id != None: ret.access_point = target_name return ret while True: target_id = str(random.randint(0, 1024 * 1024)) if not self.tgt.is_in_targetlist(target_id): break lun_path = "/dev/" + self.vgname + "/" + lv_name if self.tgt.new_target_lun(target_id, target_name, lun_path, "ALL") != None: ret.error = "Failed to export chunk {0} with tgt".format(str_guid) return ret ret.access_point = target_name return ret
def ChunkServerInfo(self, arg): # print arg cksinfo = message2object(arg) cksinfo.guid = Guid.toStr(self.service.peerGuid()) self.tdb.putChunkServer(cksinfo)
def sendRpc(s, guid, token, name, body): '''Guid token messageName bodySize\n''' line = "%s %u %s %u\n" % (Guid.toStr(guid), token, name, len(body)) s.sendall(line) out = s.sendall(body)
def sendRpc(s, guid, token, name, body): '''Guid token messageName bodySize\n''' line="%s %u %s %u\n" % (Guid.toStr(guid), token, name, len(body)) s.sendall(line) out = s.sendall(body)
def ChunkServerInfo(self, arg): # print arg cksinfo=message2object(arg) cksinfo.guid=Guid.toStr(self.service.peerGuid()) self.tdb.putChunkServer(cksinfo)
def CreateVolume(self, volname, volsize, voltype, chksizes, volnames, params): vollist = [] if len(volnames) > 0: volsize = 0 for name in volnames: try: vol = self.mds.ReadVolumeInfo(name) except IOError as ex: if str(ex).find('No such file or directory') > -1: logging.error('Volume '+name+' does not exist') return False else: raise ex if vol.parameters[2] == 'subvolume': logging.error('volume '+name+' is a subvolume of another volume') return False if vol.parameters[3] == 'inactive': logging.warn('Volume '+name+' is inactive') logging.warn('Mounting volume '+name) if not self.MountVolume(name): logging.error('Mount volume '+name+' failed') return False volsize += vol.size vollist.append(vol) if len(chksizes) == 0 and len(volnames) == 0: totsize = volsize while totsize > CHUNKSIZE: chksizes.append(CHUNKSIZE) totsize -= CHUNKSIZE chksizes.append(totsize) if voltype == 'gfs': temlist = [] for chksize in chksizes: temlist.append(chksize) temlist.append(chksize) temlist.append(chksize) chksizes = temlist if len(chksizes) > 0: vollist = self.NewChunkList(chksizes) if vollist == None: logging.error('New Chunk(s) failed') return False volume = Object() volume.size = volsize volume.assembler = voltype volume.subvolumes = vollist volume.guid = Guid.toStr(Guid.generate()) volume.parameters = [volname, '/dev/mapper/'+volname, 'volume', 'active'] volume.parameters.extend(params) if self.dmclient.MapVolume(volume) == False: logging.error('device mapper: create volume '+volname+' failed') if volume.subvolumes[0].assembler == 'chunk': for subvol in volume.subvolumes: self.DeleteVolumeTree(subvol) return False self.mds.WriteVolumeInfo(volume) for vol in vollist: if vol.assembler != 'chunk': vol.parameters[2] = 'subvolume' vol.parameters[3] = 'active' self.mds.WriteVolumeInfo(vol) return True