forked from xapi-project/xen-api
-
Notifications
You must be signed in to change notification settings - Fork 0
/
multipathrt-helper
146 lines (112 loc) · 4.12 KB
/
multipathrt-helper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/env python
# Multipath test support plugin
import subprocess, sys, socket, struct, time, syslog
import os
import re
import signal
from threading import Timer
import XenAPI, inventory
import XenAPIPlugin
dmsetup = "/sbin/dmsetup"
iptables = "/sbin/iptables"
dd = "/bin/dd"
scli = "/usr/local/bin/scli"
list_domains = "@OPTDIR@/bin/list_domains"
xs = "@OPTDIR@/debug/xs"
def doexec(args, inputtext=None):
"""Execute a subprocess, then return its return code, stdout and stderr"""
proc = subprocess.Popen(args,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,close_fds=True)
(stdout,stderr) = proc.communicate(inputtext)
rc = proc.returncode
return (rc,stdout,stderr)
def get_devmapper_status(session, args):
(rc,stdout,stderr) = doexec([dmsetup, "status", "--target", "multipath"])
return stdout
def modify_paths(session, args):
if args['remove'] == 'true':
remove = '-A'
else:
remove = '-D'
num_paths = int(args['num_paths'])
# Get the IP addresses of the paths to remove
rcs = []
for i in range(num_paths):
ip = args['ip%d' % i]
(rc,stdout,stderr) = doexec([iptables, remove, "OUTPUT", "-d", ip, "-j", "DROP"])
rcs.append(str(rc))
# Return the iptables exit codes
return ','.join(rcs)
def time_data_transfer(session, args):
dev = "/dev/%s" % args['device']
# Time the dd
start_time = time.time()
(rc,stdout,stderr) = doexec([dd, "if=/dev/zero", "of=%s" % dev, "bs=1K", "count=1024"])
finish_time = time.time()
return str(finish_time - start_time)
def get_hba_status(session, args):
(rc,stdout,stderr) = doexec([scli, "-t"])
# Extract the WWPNs and online/offline status
wwpn = None
wwpns = []
lines = stdout.splitlines()
for line in lines:
if line.find('HBA Instance') == 0:
fields = line.split(' ')
wwpn = fields[7]
if line.find('Status') == 0:
fields = re.split('\s+', line)
status = fields[2]
wwpns.append("%s:%s" % (wwpn, status))
return ','.join(wwpns)
def check_xenstore_key_exists(key):
# See if there's a value in XenStore against the given key
(rc,stdout,stderr) = doexec([xs, "read", key])
if rc == 0:
return True
else:
return False
def get_domid_for_vm(vm_uuid):
(rc,stdout,stderr) = doexec([list_domains])
lines = stdout.split("\n")
lines.pop() # remove last element (blank line)
lines.pop(0) # remove first element (column headers)
for line in lines:
cols = line.split(" | ")
if cols[1] == vm_uuid:
return cols[0].strip() # remove start and end whitespace
return None
def wait_for_iscsi_vm_boot(session, args):
vm_uuid = args['vm_uuid']
delay = float(args['delay'])
# Find the domain ID for the VM with the given UUID
domid = get_domid_for_vm(vm_uuid)
if domid == None:
return 'ERROR: could not find domain with uuid %s' % vm_uuid
# Now wait for the key to appear in XenStore
key = "/local/domain/%s/data/updated" % domid
finished = False
if check_xenstore_key_exists(key):
finished = True
proc = subprocess.Popen([xs,'watch',key],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,close_fds=True)
def kill():
os.kill(proc.pid, signal.SIGKILL)
# Kill the watch if it takes too long
timer = Timer(delay, kill)
timer.start()
while not finished:
# Wait for the watch to fire
line = proc.stdout.readline()
if line == '':
# Then EOF was reached
return 'ERROR: waiting for xenstore key %s timed out after %.1f secs' % (key,delay)
if check_xenstore_key_exists(key):
kill()
timer.cancel()
finished = True
return 'OK'
if __name__ == "__main__":
XenAPIPlugin.dispatch({"get_devmapper_status": get_devmapper_status,
"modify_paths": modify_paths,
"time_data_transfer": time_data_transfer,
"get_hba_status": get_hba_status,
"wait_for_iscsi_vm_boot": wait_for_iscsi_vm_boot})