Coverage for sm/core/mpath_dmp.py : 0%

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
18"""Copy of mpath_dmp.py in SM with unneeded code removed"""
20import os
21import errno
22from . import util
23from . import f_exceptions
25DEVMAPPERPATH = "/dev/mapper"
26DEVBYIDPATH = "/dev/disk/by-id"
27MP_INUSEDIR = "/dev/disk/mpInuse"
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)
41def deactivate_MPdev(sid):
42 path = os.path.join(MP_INUSEDIR, sid)
43 if os.path.exists(path):
44 os.unlink(path)
46def reset(sid):
47 util.SMlog("Resetting LUN %s" % sid)
48 _resetDMP(sid)
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)
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)
65 path = "/dev/mapper/%s" % sid
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)
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')
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
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)