예제 #1
0
	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
예제 #2
0
	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
예제 #3
0
	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
예제 #4
0
 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
예제 #5
0
 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
예제 #6
0
파일: util.py 프로젝트: lihuiba/SoftSAN
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
예제 #7
0
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
예제 #8
0
	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
예제 #9
0
 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
예제 #10
0
파일: mds.py 프로젝트: MatheMatrix/SoftSAN
 def ChunkServerInfo(self, arg):
     # print arg
     cksinfo = message2object(arg)
     cksinfo.guid = Guid.toStr(self.service.peerGuid())
     self.tdb.putChunkServer(cksinfo)
예제 #11
0
파일: rpc.py 프로젝트: MatheMatrix/SoftSAN
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)
예제 #12
0
파일: rpc.py 프로젝트: lihuiba/SoftSAN
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)
예제 #13
0
파일: mds.py 프로젝트: lihuiba/SoftSAN
	def ChunkServerInfo(self, arg):
		# print arg
		cksinfo=message2object(arg)
		cksinfo.guid=Guid.toStr(self.service.peerGuid())
		self.tdb.putChunkServer(cksinfo)
예제 #14
0
	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