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/python 

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"""Copy of mpath_dmp.py in SM with unneeded code removed""" 

19 

20import os 

21import errno 

22 

23from fairlock import Fairlock 

24 

25from . import util 

26from . import f_exceptions 

27 

28DEVMAPPERPATH = "/dev/mapper" 

29DEVBYIDPATH = "/dev/disk/by-id" 

30MP_INUSEDIR = "/dev/disk/mpInuse" 

31 

32def activate_MPdev(sid, dst): 

33 try: 

34 os.mkdir(MP_INUSEDIR) 

35 except OSError as exc: 

36 if exc.errno == errno.EEXIST: 

37 pass 

38 else: 

39 raise 

40 path = os.path.join(MP_INUSEDIR, sid) 

41 cmd = ['ln', '-sf', dst, path] 

42 util.pread2(cmd) 

43 

44def deactivate_MPdev(sid): 

45 path = os.path.join(MP_INUSEDIR, sid) 

46 if os.path.exists(path): 46 ↛ 47line 46 didn't jump to line 47, because the condition on line 46 was never true

47 os.unlink(path) 

48 

49def reset(sid): 

50 util.SMlog("Resetting LUN %s" % sid) 

51 _resetDMP(sid) 

52 

53def _resetDMP(sid): 

54# If mpath has been turned on since the sr/vdi was attached, we 

55# might be trying to unmap it before the daemon has been started 

56# This is unnecessary (and will fail) so just return. 

57 deactivate_MPdev(sid) 

58 

59# If the multipath daemon is running, but we were initially plugged 

60# with multipathing set to no, there may be no map for us in the multipath 

61# tables. In that case, list_paths will return [], but remove_map might 

62# throw an exception. Catch it and ignore it. 

63 with Fairlock("devicemapper"): 

64 util.retry(lambda: util.pread2(['/usr/sbin/multipath', '-f', sid]), 64 ↛ exitline 64 didn't run the lambda on line 64

65 maxretry = 3, period = 4) 

66 util.retry(lambda: util.pread2(['/usr/sbin/multipath', '-W']), maxretry = 3, 66 ↛ exitline 66 didn't run the lambda on line 66

67 period = 4) 

68 

69 path = "/dev/mapper/%s" % sid 

70 

71 if not util.wait_for_nopath(path, 10): 71 ↛ 72line 71 didn't jump to line 72, because the condition on line 71 was never true

72 util.SMlog("MPATH: WARNING - path did not disappear [%s]" % path) 

73 else: 

74 util.SMlog("MPATH: path disappeared [%s]" % path) 

75 

76def refresh(sid): 

77 # Refresh the multipath status 

78 util.SMlog("Refreshing LUN %s" % sid) 

79 if len(sid): 

80 path = DEVBYIDPATH + "/scsi-" + sid 

81 if not os.path.exists(path): 

82 raise f_exceptions.XenError("mpath_dmp", "{} not found". 

83 format(path)) 

84 _refresh_DMP(sid) 

85 else: 

86 raise f_exceptions.XenError('mpath_dmp', 'MPath not written yet') 

87 

88 

89def _is_valid_multipath_device(sid): 

90 by_id_path = "/dev/disk/by-id/scsi-"+sid 

91 real_path = util.get_real_path(by_id_path) 

92 with Fairlock("devicemapper"): 

93 (ret, stdout, stderr) = util.doexec(['/usr/sbin/multipath', '-a', sid]) 

94 

95 if ret < 0: 

96 util.SMlog("Failed to add {}: wwid could be explicitly blacklisted\n" 

97 " Continue with multipath disabled for this SR".format(sid)) 

98 return False 

99 

100 with Fairlock("devicemapper"): 

101 (ret, stdout, stderr) = util.doexec(['/usr/sbin/multipath', '-c', 

102 real_path]) 

103 

104 if ret == 1: 

105 # This is very fragile but it is not a good sign to fail without 

106 # any output. At least until multipath 0.4.9, for example, multipath -c 

107 # fails without any log if it is able to retrieve the wwid of the 

108 # device. 

109 # In this case it is better to fail immediately. 

110 if not stdout+stderr: 

111 # Attempt to cleanup wwids file before raising 

112 try: 

113 with Fairlock("devicemapper"): 

114 (ret, stdout, stderr) = util.doexec(['/usr/sbin/multipath', 

115 '-w', sid]) 

116 except OSError: 

117 util.SMlog("Error removing {} from wwids file".format(sid)) 

118 raise f_exceptions.XenError('MultipathGenericFailure', 

119 '"multipath -c" failed without any' 

120 ' output on {}'.format(real_path)) 

121 util.SMlog("When dealing with {} returned with:\n" 

122 " {}{} Continue with multipath disabled for this SR" 

123 .format(sid, stdout, stderr)) 

124 return False 

125 return True 

126 

127 

128def _refresh_DMP(sid): 

129 if not _is_valid_multipath_device(sid): 129 ↛ 130line 129 didn't jump to line 130, because the condition on line 129 was never true

130 return 

131 

132 with Fairlock("devicemapper"): 

133 util.retry(lambda: util.pread2(['/usr/sbin/multipath', '-r', sid]), maxretry = 3, 

134 period = 4) 

135 

136 path = os.path.join(DEVMAPPERPATH, sid) 

137 util.wait_for_path(path, 10) 

138 if not os.path.exists(path): 

139 raise f_exceptions.XenError('DMP', 'failed to activate mapper path') 

140 lvm_path = "/dev/disk/by-scsid/"+sid+"/mapper" 

141 util.wait_for_path(lvm_path, 10) 

142 activate_MPdev(sid, path)