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# Clear the attach status for all VDIs in the given SR on this host. 

19# Additionally, reset the paused state if this host is the master. 

20 

21import cleanup 

22import util 

23import lock 

24import XenAPI # pylint: disable=import-error 

25 

26 

27def reset_sr(session, host_uuid, sr_uuid, is_sr_master): 

28 from vhdutil import LOCK_TYPE_SR 

29 from cleanup import LOCK_TYPE_RUNNING 

30 

31 cleanup.abort(sr_uuid) 

32 

33 gc_lock = lock.Lock(LOCK_TYPE_RUNNING, sr_uuid) 

34 sr_lock = lock.Lock(LOCK_TYPE_SR, sr_uuid) 

35 gc_lock.acquire() 

36 sr_lock.acquire() 

37 

38 sr_ref = session.xenapi.SR.get_by_uuid(sr_uuid) 

39 

40 host_ref = session.xenapi.host.get_by_uuid(host_uuid) 

41 host_key = "host_%s" % host_ref 

42 

43 util.SMlog("RESET for SR %s (master: %s)" % (sr_uuid, is_sr_master)) 

44 

45 vdi_recs = session.xenapi.VDI.get_all_records_where( \ 

46 "field \"SR\" = \"%s\"" % sr_ref) 

47 

48 for vdi_ref, vdi_rec in vdi_recs.items(): 

49 vdi_uuid = vdi_rec["uuid"] 

50 sm_config = vdi_rec["sm_config"] 

51 if sm_config.get(host_key): 

52 util.SMlog("Clearing attached status for VDI %s" % vdi_uuid) 

53 session.xenapi.VDI.remove_from_sm_config(vdi_ref, host_key) 

54 if is_sr_master and sm_config.get("paused"): 

55 util.SMlog("Clearing paused status for VDI %s" % vdi_uuid) 

56 session.xenapi.VDI.remove_from_sm_config(vdi_ref, "paused") 

57 

58 sr_lock.release() 

59 gc_lock.release() 

60 

61 

62def reset_vdi(session, vdi_uuid, force, term_output=True, writable=True): 

63 vdi_ref = session.xenapi.VDI.get_by_uuid(vdi_uuid) 

64 vdi_rec = session.xenapi.VDI.get_record(vdi_ref) 

65 sm_config = vdi_rec["sm_config"] 

66 host_ref = None 

67 clean = True 

68 for key, val in sm_config.items(): 

69 if key.startswith("host_"): 

70 host_ref = key[len("host_"):] 

71 host_uuid = None 

72 host_invalid = False 

73 host_str = host_ref 

74 try: 

75 host_rec = session.xenapi.host.get_record(host_ref) 

76 host_uuid = host_rec["uuid"] 

77 host_str = "%s (%s)" % (host_uuid, host_rec["name_label"]) 

78 except XenAPI.Failure as e: 

79 msg = "Invalid host: %s (%s)" % (host_ref, e) 

80 util.SMlog(msg) 

81 if term_output: 

82 print(msg) 

83 host_invalid = True 

84 

85 if host_invalid: 

86 session.xenapi.VDI.remove_from_sm_config(vdi_ref, key) 

87 msg = "Invalid host: Force-cleared %s for %s on host %s" % \ 

88 (val, vdi_uuid, host_str) 

89 util.SMlog(msg) 

90 if term_output: 

91 print(msg) 

92 continue 

93 

94 if force: 

95 session.xenapi.VDI.remove_from_sm_config(vdi_ref, key) 

96 msg = "Force-cleared %s for %s on host %s" % \ 

97 (val, vdi_uuid, host_str) 

98 util.SMlog(msg) 

99 if term_output: 

100 print(msg) 

101 continue 

102 

103 ret = session.xenapi.host.call_plugin( 

104 host_ref, "on-slave", "is_open", 

105 {"vdiUuid": vdi_uuid, "srRef": vdi_rec["SR"]}) 

106 if ret != "False": 

107 util.SMlog("VDI %s is still open on host %s, not resetting" % \ 

108 (vdi_uuid, host_str)) 

109 if term_output: 

110 print("ERROR: VDI %s is still open on host %s" % \ 

111 (vdi_uuid, host_str)) 

112 if writable: 

113 return False 

114 else: 

115 clean = False 

116 else: 

117 session.xenapi.VDI.remove_from_sm_config(vdi_ref, key) 

118 msg = "Cleared %s for %s on host %s" % \ 

119 (val, vdi_uuid, host_str) 

120 util.SMlog(msg) 

121 if term_output: 

122 print(msg) 

123 

124 if not host_ref: 

125 msg = "VDI %s is not marked as attached anywhere, nothing to do" \ 

126 % vdi_uuid 

127 util.SMlog(msg) 

128 if term_output: 

129 print(msg) 

130 return clean 

131 

132 

133def usage(): 

134 print("Usage:") 

135 print("all <HOST UUID> <SR UUID> [--master]") 

136 print("single <VDI UUID> [--force]") 

137 print() 

138 print("*WARNING!* calling with 'all' on an attached SR, or using " + \ 

139 "--force may cause DATA CORRUPTION if the VDI is still " + \ 

140 "attached somewhere. Always manually double-check that " + \ 

141 "the VDI is not in use before running this script.") 

142 sys.exit(1) 

143 

144if __name__ == '__main__': 144 ↛ 145line 144 didn't jump to line 145, because the condition on line 144 was never true

145 import sys 

146 import atexit 

147 

148 if len(sys.argv) not in [3, 4, 5]: 

149 usage() 

150 

151 session = XenAPI.xapi_local() 

152 session.xenapi.login_with_password('root', '', '', 'SM') 

153 atexit.register(session.xenapi.session.logout) 

154 

155 mode = sys.argv[1] 

156 if mode == "all": 

157 if len(sys.argv) not in [4, 5]: 

158 usage() 

159 host_uuid = sys.argv[2] 

160 sr_uuid = sys.argv[3] 

161 is_master = False 

162 if len(sys.argv) == 5: 

163 if sys.argv[4] == "--master": 

164 is_master = True 

165 else: 

166 usage() 

167 reset_sr(session, host_uuid, sr_uuid, is_master) 

168 elif mode == "single": 

169 vdi_uuid = sys.argv[2] 

170 force = False 

171 if len(sys.argv) == 4 and sys.argv[3] == "--force": 

172 force = True 

173 reset_vdi(session, vdi_uuid, force) 

174 elif len(sys.argv) in [3, 4]: 

175 # backwards compatibility: the arguments for the "all" case used to be 

176 # just host_uuid, sr_uuid, [is_master] (i.e., no "all" string, since it 

177 # was the only mode available). To avoid having to change XAPI, accept 

178 # the old format here as well. 

179 host_uuid = sys.argv[1] 

180 sr_uuid = sys.argv[2] 

181 is_master = False 

182 if len(sys.argv) == 4: 

183 if sys.argv[3] == "--master": 

184 is_master = True 

185 else: 

186 usage() 

187 reset_sr(session, host_uuid, sr_uuid, is_master) 

188 else: 

189 usage()