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 

21from sm_typing import override 

22 

23import os 

24import VDI 

25import util 

26import scsiutil 

27import xs_errors 

28 

29MAX_TIMEOUT = 15 

30 

31 

32class RAWVDI(VDI.VDI): 

33 @override 

34 def load(self, vdi_uuid) -> None: 

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

36 raise xs_errors.XenError('SRUnavailable') 

37 

38 self.uuid = vdi_uuid 

39 self.location = vdi_uuid 

40 self.managed = False 

41 self.vdi_type = "phy" 

42 try: 

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

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

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

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

47 except: 

48 pass 

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

50 self.managed = True 

51 

52 def _query(self, path, id): 

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

54 self.location = self.uuid 

55 self.vendor = scsiutil.getmanufacturer(path) 

56 self.serial = scsiutil.getserial(path) 

57 self.LUNid = id 

58 self.size = scsiutil.getsize(path) 

59 self.SCSIid = scsiutil.getSCSIid(path) 

60 self.path = path 

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

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

63 sm_config['SCSIid'] = self.SCSIid 

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

65 self.sm_config = sm_config 

66 

67 @override 

68 def introduce(self, sr_uuid, vdi_uuid) -> str: 

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

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

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

72 vdi_uuid = self.uuid 

73 self.sr.vdis[vdi_uuid] = self 

74 

75 try: 

76 util._getVDI(self.sr, vdi_uuid) 

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

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

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

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

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

82 except: 

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

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

85 

86 @override 

87 def create(self, sr_uuid, vdi_uuid, size) -> str: 

88 VDIs = util._getVDIs(self.sr) 

89 self.sr._loadvdis() 

90 smallest = 0 

91 v = {} 

92 for vdi in VDIs: 

93 if not vdi['managed'] \ 

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

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

96 if not smallest: 

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

98 v = vdi 

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

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

101 v = vdi 

102 if smallest > 0: 

103 self.managed = True 

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

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

106 raise xs_errors.XenError('SRNoSpace') 

107 

108 @override 

109 def delete(self, sr_uuid, vdi_uuid, data_only=False) -> None: 

110 try: 

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

112 if not vdi['managed']: 

113 return 

114 sm_config = vdi['sm_config'] 

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

116 except: 

117 pass 

118 

119 @override 

120 def attach(self, sr_uuid, vdi_uuid) -> str: 

121 self.sr._loadvdis() 

122 if vdi_uuid not in self.sr.vdis: 

123 raise xs_errors.XenError('VDIUnavailable') 

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

125 self.sr.refresh() 

126 if 'SCSIid' in self.sm_config: 

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

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

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

130 for dev in devs: 

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

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

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

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

135 raise xs_errors.XenError('VDIUnavailable') 

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

137 

138 @override 

139 def detach(self, sr_uuid, vdi_uuid) -> None: 

140 self.sr._loadvdis() 

141 if 'SCSIid' in self.sm_config: 

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

143 if vdi_uuid not in self.sr.vdis: 

144 raise xs_errors.XenError('VDIUnavailable') 

145 

146 def _set_managed(self, vdi_uuid, managed): 

147 try: 

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

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

150 except: 

151 raise xs_errors.XenError('VDIUnavailable')