Coverage for drivers/LUNperVDI.py : 19%

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/python3
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# LUNperVDI: Generic Raw LUN handler, used by HBASR and ISCSISR
19#
21import os
22import VDI
23import util
24import scsiutil
25import xs_errors
27MAX_TIMEOUT = 15
30class RAWVDI(VDI.VDI):
31 def load(self, vdi_uuid):
32 if not self.sr.attached: 32 ↛ 33line 32 didn't jump to line 33, because the condition on line 32 was never true
33 raise xs_errors.XenError('SRUnavailable')
35 self.uuid = vdi_uuid
36 self.location = vdi_uuid
37 self.managed = False
38 try:
39 vdi_ref = self.sr.session.xenapi.VDI.get_by_uuid(vdi_uuid)
40 self.managed = self.sr.session.xenapi.VDI.get_managed(vdi_ref)
41 self.sm_config = self.sr.session.xenapi.VDI.get_sm_config(vdi_ref)
42 self.path = self.sr.mpathmodule.path(self.sm_config['SCSIid'])
43 except:
44 pass
45 if self.sr.cmd == "vdi_introduce": 45 ↛ 46line 45 didn't jump to line 46, because the condition on line 45 was never true
46 self.managed = True
48 def _query(self, path, id):
49 self.uuid = scsiutil.gen_uuid_from_string(scsiutil.getuniqueserial(path))
50 self.location = self.uuid
51 self.vendor = scsiutil.getmanufacturer(path)
52 self.serial = scsiutil.getserial(path)
53 self.LUNid = id
54 self.size = scsiutil.getsize(path)
55 self.SCSIid = scsiutil.getSCSIid(path)
56 self.path = path
57 sm_config = util.default(self, "sm_config", lambda: {})
58 sm_config['LUNid'] = str(self.LUNid)
59 sm_config['SCSIid'] = self.SCSIid
60 sm_config['backend-kind'] = 'vbd'
61 self.sm_config = sm_config
63 def introduce(self, sr_uuid, vdi_uuid):
64 self.sm_config = self.sr.srcmd.params['vdi_sm_config']
65 vdi_path = self.sr._getLUNbySMconfig(self.sm_config)
66 self._query(vdi_path, self.sm_config['LUNid'])
67 vdi_uuid = self.uuid
68 self.sr.vdis[vdi_uuid] = self
70 try:
71 util._getVDI(self.sr, vdi_uuid)
72 self.sr.vdis[vdi_uuid]._db_update()
73 # For reasons I don't understand, VDI._db_update() doesn't set the
74 # managed flag, so we do that ourselves here.
75 vdi_ref = self.sr.session.xenapi.VDI.get_by_uuid(vdi_uuid)
76 self.sr.session.xenapi.VDI.set_managed(vdi_ref, self.managed)
77 except:
78 self.sr.vdis[vdi_uuid]._db_introduce()
79 return super(RAWVDI, self).get_params()
81 def create(self, sr_uuid, vdi_uuid, size):
82 VDIs = util._getVDIs(self.sr)
83 self.sr._loadvdis()
84 smallest = 0
85 for vdi in VDIs:
86 if not vdi['managed'] \
87 and int(vdi['virtual_size']) >= int(size) \
88 and vdi['uuid'] in self.sr.vdis:
89 if not smallest:
90 smallest = int(vdi['virtual_size'])
91 v = vdi
92 elif int(vdi['virtual_size']) < smallest:
93 smallest = int(vdi['virtual_size'])
94 v = vdi
95 if smallest > 0:
96 self.managed = True
97 self.sr.session.xenapi.VDI.set_managed(v['vdi_ref'], self.managed)
98 return super(RAWVDI, self.sr.vdis[v['uuid']]).get_params()
99 raise xs_errors.XenError('SRNoSpace')
101 def delete(self, sr_uuid, vdi_uuid):
102 try:
103 vdi = util._getVDI(self.sr, vdi_uuid)
104 if not vdi['managed']:
105 return
106 sm_config = vdi['sm_config']
107 self.sr.session.xenapi.VDI.set_managed(vdi['vdi_ref'], False)
108 except:
109 pass
111 def attach(self, sr_uuid, vdi_uuid):
112 self.sr._loadvdis()
113 if vdi_uuid not in self.sr.vdis:
114 raise xs_errors.XenError('VDIUnavailable')
115 if not util.pathexists(self.path):
116 self.sr.refresh()
117 if 'SCSIid' in self.sm_config:
118 if self.sr.mpath == 'true':
119 self.sr.mpathmodule.refresh(self.sm_config['SCSIid'], 0)
120 devs = os.listdir("/dev/disk/by-scsid/%s" % self.sm_config['SCSIid'])
121 for dev in devs:
122 realdev = os.path.realpath("/dev/disk/by-scsid/%s/%s" % (self.sm_config['SCSIid'], dev))
123 util.set_scheduler(realdev.split("/")[-1])
124 if not util.wait_for_path(self.path, MAX_TIMEOUT):
125 util.SMlog("Unable to detect LUN attached to host [%s]" % self.sr.path)
126 raise xs_errors.XenError('VDIUnavailable')
127 return super(RAWVDI, self).attach(sr_uuid, vdi_uuid)
129 def detach(self, sr_uuid, vdi_uuid):
130 self.sr._loadvdis()
131 if 'SCSIid' in self.sm_config:
132 self.sr.mpathmodule.reset(self.sm_config['SCSIid'], True) # explicitly unmap
133 if vdi_uuid not in self.sr.vdis:
134 raise xs_errors.XenError('VDIUnavailable')
136 def _set_managed(self, vdi_uuid, managed):
137 try:
138 vdi = util._getVDI(self.sr, vdi_uuid)
139 self.sr.session.xenapi.VDI.set_managed(vdi['vdi_ref'], managed)
140 except:
141 raise xs_errors.XenError('VDIUnavailable')