Coverage for sm/core/util.py : 43%
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"""Fake util module"""
4import os
5import subprocess
6import time
7import re
8import glob
9import syslog
10import signal
11import socket
13from . import f_exceptions
15SCSI_ID_BIN = '/usr/lib/udev/scsi_id'
16ISCSI_REFDIR = '/var/run/sr-ref'
18NO_LOGGING_STAMPFILE = '/etc/xensource/no_sm_log'
19LOGGING = not os.path.exists(NO_LOGGING_STAMPFILE)
20_SM_SYSLOG_FACILITY = syslog.LOG_LOCAL2
21LOG_EMERG = syslog.LOG_EMERG
22LOG_ALERT = syslog.LOG_ALERT
23LOG_CRIT = syslog.LOG_CRIT
24LOG_ERR = syslog.LOG_ERR
25LOG_WARNING = syslog.LOG_WARNING
26LOG_NOTICE = syslog.LOG_NOTICE
27LOG_INFO = syslog.LOG_INFO
28LOG_DEBUG = syslog.LOG_DEBUG
31def doexec(args, inputtext=None):
32 """Execute a subprocess, then return its return code, stdout and stderr"""
34 proc = subprocess.Popen(args, stdin=subprocess.PIPE,
35 stdout=subprocess.PIPE,
36 stderr=subprocess.PIPE,
37 close_fds=True)
38 inputtext = inputtext.encode('utf-8') if inputtext else inputtext
39 (stdout, stderr) = proc.communicate(inputtext)
40 stdout = stdout.decode('utf-8')
41 stderr = stderr.decode('utf-8')
42 ret = proc.returncode
43 return (ret, stdout, stderr)
45def wait_for_path(path, timeout):
46 for _ in range(timeout):
47 if len(glob.glob(path)):
48 return True
49 time.sleep(1)
50 return False
52def wait_for_nopath(path,timeout):
53 for i in range(0,timeout):
54 if not os.path.exists(path):
55 return True
56 time.sleep(1)
57 return False
60def scsi_id_sanitise(str_):
61 """scsi_id_sanitise"""
62 text = re.sub("^\s+", "", str_) # pylint: disable=W1401
63 return re.sub("\s+", "_", text) # pylint: disable=W1401
66def is_string(value):
67 """trivial"""
68 return isinstance(value, str)
71def pread(cmdlist, scramble=None, expect_rc=0):
72 """ported from SM util"""
73 cmdlist_for_exec = []
74 cmdlist_for_log = []
75 for item in cmdlist:
76 if is_string(item):
77 cmdlist_for_exec.append(item)
78 if scramble:
79 if item.find(scramble) != -1:
80 cmdlist_for_log.append("<filtered out>")
81 else:
82 cmdlist_for_log.append(item)
83 else:
84 cmdlist_for_log.append(item)
85 else:
86 cmdlist_for_exec.append(item[0])
87 cmdlist_for_log.append(item[1])
89 (ret, stdout, stderr) = doexec(cmdlist_for_exec)
90 if ret != expect_rc:
91 if stderr == '':
92 stderr = stdout
93 raise f_exceptions.XenError("Command", stderr.strip())
94 return stdout
97def pread2(cmdlist):
98 """Ditto"""
99 return pread(cmdlist)
102def get_scsi_id(path):
103 """Get the SCSI id of a block device
105 Input:
106 path -- (str) path to block device; can be symlink
108 Return:
109 scsi_id -- (str) the device's SCSI id
111 Raise:
112 f_exceptions.XenError
113 """
115 if not path.startswith('/dev/'): 115 ↛ 116line 115 didn't jump to line 116, because the condition on line 115 was never true
116 path = '/dev/' + path.lstrip('/')
118 stdout = pread2([SCSI_ID_BIN, '-g', '--device', path])
120 scsi_id = scsi_id_sanitise(stdout.rstrip())
121 if scsi_id.endswith('0000000000000000'): 121 ↛ 122line 121 didn't jump to line 122, because the condition on line 121 was never true
122 SMlog(f'SCSI Id for path {path} ends in all 0s')
124 return scsi_id
127def match_uuid(s):
128 regex = re.compile("^[0-9a-f]{8}-(([0-9a-f]{4})-){3}[0-9a-f]{12}")
129 return regex.search(s, 0)
132class TimeoutException(Exception):
133 pass
136def timeout_call(timeoutseconds, function, *arguments):
137 def handler(signum, frame):
138 raise TimeoutException()
139 signal.signal(signal.SIGALRM, handler)
140 signal.alarm(timeoutseconds)
141 try:
142 function(*arguments)
143 finally:
144 # Cancel the alarm signal so that it isn't fired later on
145 signal.alarm(0)
148def _incr_iscsiSR_refcount(targetIQN, uuid):
149 if not os.path.exists(ISCSI_REFDIR):
150 os.mkdir(ISCSI_REFDIR)
151 filename = os.path.join(ISCSI_REFDIR, targetIQN)
152 try:
153 f = open(filename, 'a+')
154 except:
155 raise f_exceptions.XenError('LVMRefCount',
156 message='file %s' % filename)
158 f.seek(0)
159 found = False
160 refcount = 0
161 for line in filter(match_uuid, f.readlines()):
162 refcount += 1
163 if line.find(uuid) != -1:
164 found = True
165 if not found:
166 f.write("%s\n" % uuid)
167 refcount += 1
168 f.close()
169 return refcount
172def _decr_iscsiSR_refcount(targetIQN, uuid):
173 filename = os.path.join(ISCSI_REFDIR, targetIQN)
174 if not os.path.exists(filename):
175 return 0
176 try:
177 f = open(filename, 'a+')
178 except:
179 raise f_exceptions.XenError('LVMRefCount',
180 message='file %s' % filename)
181 f.seek(0)
182 output = []
183 refcount = 0
184 for line in filter(match_uuid, f.readlines()):
185 if line.find(uuid) == -1:
186 output.append(line[:-1])
187 refcount += 1
188 if not refcount:
189 os.unlink(filename)
190 return refcount
192 # Re-open file and truncate
193 f.close()
194 f = open(filename, 'w')
195 for i in range(0,refcount):
196 f.write("%s\n" % output[i])
197 f.close()
198 return refcount
200def _logToSyslog(ident, facility, priority, message):
201 syslog.openlog(ident, 0, facility)
202 syslog.syslog(priority, "[%d] %s" % (os.getpid(), message))
203 syslog.closelog()
206def SMlog(message, ident="SM", priority=LOG_INFO):
207 if LOGGING: 207 ↛ exitline 207 didn't return from function 'SMlog', because the condition on line 207 was never false
208 for message_line in str(message).split('\n'):
209 _logToSyslog(ident, _SM_SYSLOG_FACILITY, priority, message_line)
212def retry(f, maxretry=20, period=3):
213 retries = 0
214 while True:
215 try:
216 return f()
217 except Exception as e:
218 SMlog("Got exception: %s. Retry number: %s" % (str(e),retries))
220 retries += 1
221 if retries >= maxretry:
222 break
224 time.sleep(period)
226 return f()
228def testHost(hostname, port):
229 """
230 Modified from _testHost in sm.util
231 """
232 SMlog("testHost: Testing host/port: %s,%d" % (hostname,port))
233 try:
234 sockinfo = socket.getaddrinfo(hostname, int(port))[0]
235 except:
236 SMlog('Exception occured getting IP for %s' % hostname)
237 return False
239 timeout = 10
241 sock = socket.socket(sockinfo[0], socket.SOCK_STREAM)
242 # Only allow the connect to block for up to timeout seconds
243 sock.settimeout(timeout)
244 try:
245 sock.connect(sockinfo[4])
246 # Fix for MS storage server bug
247 sock.send(b'\n')
248 sock.close()
249 return True
250 except socket.error as reason:
251 SMlog("testHost: Connect failed after %d seconds (%s) - %s" \
252 % (timeout, hostname, reason))
253 return False