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 

22from . import util 

23from . import f_exceptions 

24 

25DEVMAPPERPATH = "/dev/mapper" 

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

27MP_INUSEDIR = "/dev/disk/mpInuse" 

28 

29def activate_MPdev(sid, dst): 

30 try: 

31 os.mkdir(MP_INUSEDIR) 

32 except OSError as exc: 

33 if exc.errno == errno.EEXIST: 

34 pass 

35 else: 

36 raise 

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

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

39 util.pread2(cmd) 

40 

41def deactivate_MPdev(sid): 

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

43 if os.path.exists(path): 

44 os.unlink(path) 

45 

46def reset(sid): 

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

48 _resetDMP(sid) 

49 

50def _resetDMP(sid): 

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

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

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

54 deactivate_MPdev(sid) 

55 

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

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

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

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

60 util.retry(lambda: util.pread2(['/usr/sbin/multipath', '-f', sid]), 

61 maxretry = 3, period = 4) 

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

63 period = 4) 

64 

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

66 

67 if not util.wait_for_nopath(path, 10): 

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

69 else: 

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

71 

72def refresh(sid): 

73 # Refresh the multipath status 

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

75 if len(sid): 

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

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

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

79 format(path)) 

80 _refresh_DMP(sid) 

81 else: 

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

83 

84 

85def _is_valid_multipath_device(sid): 

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

87 real_path = util.get_real_path(by_id_path) 

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

89 if ret < 0: 

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

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

92 return False 

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

94 real_path]) 

95 if ret == 1: 

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

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

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

99 # device. 

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

101 if not stdout+stderr: 

102 # Attempt to cleanup wwids file before raising 

103 try: 

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

105 '-w', sid]) 

106 except OSError: 

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

108 raise f_exceptions.XenError('MultipathGenericFailure', 

109 '"multipath -c" failed without any' 

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

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

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

113 .format(sid, stdout, stderr)) 

114 return False 

115 return True 

116 

117 

118def _refresh_DMP(sid): 

119 if not _is_valid_multipath_device(sid): 

120 return 

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

122 period = 4) 

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

124 util.wait_for_path(path, 10) 

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

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

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

128 util.wait_for_path(lvm_path, 10) 

129 activate_MPdev(sid, path)