Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1#!/usr/bin/python3 

2# 

3# Copyright (C) Citrix Systems Inc. 

4# 

5# This program is free software; you can redistribute it and/or modify 

6# it under the terms of the GNU Lesser General Public License as published 

7# by the Free Software Foundation; version 2.1 only. 

8# 

9# This program is distributed in the hope that it will be useful, 

10# but WITHOUT ANY WARRANTY; without even the implied warranty of 

11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

12# GNU Lesser General Public License for more details. 

13# 

14# You should have received a copy of the GNU Lesser General Public License 

15# along with this program; if not, write to the Free Software Foundation, Inc., 

16# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 

17# 

18# LUNperVDI: Generic Raw LUN handler, used by HBASR and ISCSISR 

19# 

20 

21import os 

22import VDI 

23import util 

24import scsiutil 

25import xs_errors 

26 

27MAX_TIMEOUT = 15 

28 

29 

30class RAWVDI(VDI.VDI): 

31 def load(self, vdi_uuid): 

32 if not self.sr.attached: 32 ↛ 33line 32 didn't jump to line 33, because the condition on line 32 was never true

33 raise xs_errors.XenError('SRUnavailable') 

34 

35 self.uuid = vdi_uuid 

36 self.location = vdi_uuid 

37 self.managed = False 

38 try: 

39 vdi_ref = self.sr.session.xenapi.VDI.get_by_uuid(vdi_uuid) 

40 self.managed = self.sr.session.xenapi.VDI.get_managed(vdi_ref) 

41 self.sm_config = self.sr.session.xenapi.VDI.get_sm_config(vdi_ref) 

42 self.path = self.sr.mpathmodule.path(self.sm_config['SCSIid']) 

43 except: 

44 pass 

45 if self.sr.cmd == "vdi_introduce": 45 ↛ 46line 45 didn't jump to line 46, because the condition on line 45 was never true

46 self.managed = True 

47 

48 def _query(self, path, id): 

49 self.uuid = scsiutil.gen_uuid_from_string(scsiutil.getuniqueserial(path)) 

50 self.location = self.uuid 

51 self.vendor = scsiutil.getmanufacturer(path) 

52 self.serial = scsiutil.getserial(path) 

53 self.LUNid = id 

54 self.size = scsiutil.getsize(path) 

55 self.SCSIid = scsiutil.getSCSIid(path) 

56 self.path = path 

57 sm_config = util.default(self, "sm_config", lambda: {}) 

58 sm_config['LUNid'] = str(self.LUNid) 

59 sm_config['SCSIid'] = self.SCSIid 

60 sm_config['backend-kind'] = 'vbd' 

61 self.sm_config = sm_config 

62 

63 def introduce(self, sr_uuid, vdi_uuid): 

64 self.sm_config = self.sr.srcmd.params['vdi_sm_config'] 

65 vdi_path = self.sr._getLUNbySMconfig(self.sm_config) 

66 self._query(vdi_path, self.sm_config['LUNid']) 

67 vdi_uuid = self.uuid 

68 self.sr.vdis[vdi_uuid] = self 

69 

70 try: 

71 util._getVDI(self.sr, vdi_uuid) 

72 self.sr.vdis[vdi_uuid]._db_update() 

73 # For reasons I don't understand, VDI._db_update() doesn't set the 

74 # managed flag, so we do that ourselves here. 

75 vdi_ref = self.sr.session.xenapi.VDI.get_by_uuid(vdi_uuid) 

76 self.sr.session.xenapi.VDI.set_managed(vdi_ref, self.managed) 

77 except: 

78 self.sr.vdis[vdi_uuid]._db_introduce() 

79 return super(RAWVDI, self).get_params() 

80 

81 def create(self, sr_uuid, vdi_uuid, size): 

82 VDIs = util._getVDIs(self.sr) 

83 self.sr._loadvdis() 

84 smallest = 0 

85 for vdi in VDIs: 

86 if not vdi['managed'] \ 

87 and int(vdi['virtual_size']) >= int(size) \ 

88 and vdi['uuid'] in self.sr.vdis: 

89 if not smallest: 

90 smallest = int(vdi['virtual_size']) 

91 v = vdi 

92 elif int(vdi['virtual_size']) < smallest: 

93 smallest = int(vdi['virtual_size']) 

94 v = vdi 

95 if smallest > 0: 

96 self.managed = True 

97 self.sr.session.xenapi.VDI.set_managed(v['vdi_ref'], self.managed) 

98 return super(RAWVDI, self.sr.vdis[v['uuid']]).get_params() 

99 raise xs_errors.XenError('SRNoSpace') 

100 

101 def delete(self, sr_uuid, vdi_uuid): 

102 try: 

103 vdi = util._getVDI(self.sr, vdi_uuid) 

104 if not vdi['managed']: 

105 return 

106 sm_config = vdi['sm_config'] 

107 self.sr.session.xenapi.VDI.set_managed(vdi['vdi_ref'], False) 

108 except: 

109 pass 

110 

111 def attach(self, sr_uuid, vdi_uuid): 

112 self.sr._loadvdis() 

113 if vdi_uuid not in self.sr.vdis: 

114 raise xs_errors.XenError('VDIUnavailable') 

115 if not util.pathexists(self.path): 

116 self.sr.refresh() 

117 if 'SCSIid' in self.sm_config: 

118 if self.sr.mpath == 'true': 

119 self.sr.mpathmodule.refresh(self.sm_config['SCSIid'], 0) 

120 devs = os.listdir("/dev/disk/by-scsid/%s" % self.sm_config['SCSIid']) 

121 for dev in devs: 

122 realdev = os.path.realpath("/dev/disk/by-scsid/%s/%s" % (self.sm_config['SCSIid'], dev)) 

123 util.set_scheduler(realdev.split("/")[-1]) 

124 if not util.wait_for_path(self.path, MAX_TIMEOUT): 

125 util.SMlog("Unable to detect LUN attached to host [%s]" % self.sr.path) 

126 raise xs_errors.XenError('VDIUnavailable') 

127 return super(RAWVDI, self).attach(sr_uuid, vdi_uuid) 

128 

129 def detach(self, sr_uuid, vdi_uuid): 

130 self.sr._loadvdis() 

131 if 'SCSIid' in self.sm_config: 

132 self.sr.mpathmodule.reset(self.sm_config['SCSIid'], True) # explicitly unmap 

133 if vdi_uuid not in self.sr.vdis: 

134 raise xs_errors.XenError('VDIUnavailable') 

135 

136 def _set_managed(self, vdi_uuid, managed): 

137 try: 

138 vdi = util._getVDI(self.sr, vdi_uuid) 

139 self.sr.session.xenapi.VDI.set_managed(vdi['vdi_ref'], managed) 

140 except: 

141 raise xs_errors.XenError('VDIUnavailable')