Skip to content

Commit 6d7e147

Browse files
committed
in progress
Signed-off-by: Ronan Abhamon <ronan.abhamon@vates.tech>
1 parent d7cd0b1 commit 6d7e147

File tree

8 files changed

+82
-23
lines changed

8 files changed

+82
-23
lines changed

drivers/LinstorSR.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1838,7 +1838,7 @@ def attach(self, sr_uuid, vdi_uuid) -> str:
18381838
return self._attach_using_http_nbd()
18391839

18401840
# Ensure we have a path...
1841-
self.sr._vhdutil.create_chain_paths(self.uuid, readonly=not writable)
1841+
self.sr._vhdutil.create_chain_paths(self.uuid, not writable, cleanup.LinstorSR.abort_from_openers)
18421842

18431843
self.attached = True
18441844
return VDI.VDI.attach(self, self.sr.uuid, self.uuid)
@@ -2375,7 +2375,7 @@ def _snapshot(self, snap_type, cbtlog=None, cbt_consistency=None):
23752375
raise xs_errors.XenError('SnapshotChainTooLong')
23762376

23772377
# Ensure we have a valid path if we don't have a local diskful.
2378-
self.sr._vhdutil.create_chain_paths(self.uuid, readonly=True)
2378+
self.sr._vhdutil.create_chain_paths(self.uuid, True, cleanup.LinstorSR.abort_from_openers)
23792379

23802380
volume_path = self.path
23812381
if not util.pathexists(volume_path):

drivers/VDI.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,7 @@ def __init__(self, sr, uuid):
123123

124124
@staticmethod
125125
def from_uuid(session, vdi_uuid):
126-
127-
_VDI = session.xenapi.VDI
128-
vdi_ref = _VDI.get_by_uuid(vdi_uuid)
129-
sr_ref = _VDI.get_SR(vdi_ref)
130-
131-
_SR = session.xenapi.SR
132-
sr_uuid = _SR.get_uuid(sr_ref)
133-
126+
sr_uuid = util.get_sr_from_vdi_uuid(session, vdi)
134127
sr = SR.SR.from_uuid(session, sr_uuid)
135128

136129
sr.srcmd.params['vdi_ref'] = vdi_ref

drivers/blktap2.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,8 @@ def unpause(cls, pid, minor, _type=None, _file=None, mirror=None,
424424
args += ["-a", str(params)]
425425
if cbtlog:
426426
args.extend(["-c", cbtlog])
427+
428+
# TODO: Handle issue.
427429
cls._pread(args)
428430

429431
@classmethod
@@ -844,11 +846,16 @@ def launch_on_tap(cls, blktap, path, _type, options):
844846
err = (
845847
'status' in e.info and e.info['status']
846848
) or None
847-
if err in (errno.EIO, errno.EROFS, errno.EAGAIN):
849+
if err in (errno.EIO, errno.EROFS, errno.EMEDIUMTYPE, errno.EAGAIN):
848850
if retry_open < 5:
849851
retry_open += 1
850852
time.sleep(1)
851853
continue
854+
855+
import cleanup
856+
cleanup.LinstorSR.abort_from_openers()
857+
858+
# TODO: create chain
852859
if LINSTOR_AVAILABLE and err == errno.EROFS:
853860
log_drbd_openers(path)
854861
raise

drivers/cleanup.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3656,9 +3656,9 @@ def _finishInterruptedCoalesceLeaf(self, childUuid, parentUuid):
36563656

36573657
def _checkSlaves(self, vdi):
36583658
try:
3659-
all_openers = self._linstor.get_volume_openers(vdi.uuid)
3660-
for openers in all_openers.values():
3661-
for opener in openers.values():
3659+
openers = self._linstor.get_volume_openers(vdi.uuid)
3660+
for host_openers in openers.values():
3661+
for opener in host_openers.values():
36623662
if opener['process-name'] != 'tapdisk':
36633663
raise util.SMException(
36643664
'VDI {} is in use: {}'.format(vdi.uuid, all_openers)
@@ -3667,6 +3667,34 @@ def _checkSlaves(self, vdi):
36673667
if e.code != LinstorVolumeManagerError.ERR_VOLUME_NOT_EXISTS:
36683668
raise
36693669

3670+
@staticmethod
3671+
def abort_from_openers(vdi_uuid, openers) -> None:
3672+
from linstorvhdutil import MANAGER_PLUGIN
3673+
3674+
node_name = None
3675+
3676+
for host_openers in openers.values():
3677+
for hostname, opener in host_openers.values():
3678+
if opener['process-name'] != 'vhd-util' or 'coalesce' not in opener['cmdline']:
3679+
continue
3680+
3681+
if not node_name:
3682+
import socket
3683+
node_name = socket.gethostname()
3684+
3685+
if node_name == hostname:
3686+
continue
3687+
3688+
session = self.xapi.getSession()
3689+
try:
3690+
sr_uuid = util.get_sr_from_vdi_uuid(session, vdi_uuid)
3691+
ret = session.xenapi.host.call_plugin(
3692+
util.get_master_ref(session), self.MANAGER_PLUGIN, command, args
3693+
)
3694+
finally:
3695+
self.session.xenapi.session.logout()
3696+
3697+
36703698

36713699
################################################################################
36723700
#

drivers/linstorvhdutil.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ def __init__(self, session, linstor):
169169
self._session = session
170170
self._linstor = linstor
171171

172-
def create_chain_paths(self, vdi_uuid, readonly=False):
172+
def create_chain_paths(self, vdi_uuid, readonly=False, cb_openers=None):
173173
# OPTIMIZE: Add a limit_to_first_allocated_block param to limit vhdutil calls.
174174
# Useful for the snapshot code algorithm.
175175

@@ -192,9 +192,10 @@ def check_volume_usable():
192192
time.sleep(2)
193193
continue
194194
if e.errno == errno.EROFS or e.errno == errno.EMEDIUMTYPE:
195-
util.SMlog('Volume not attachable because used. Openers: {}'.format(
196-
self._linstor.get_volume_openers(vdi_uuid)
197-
))
195+
openers = self._linstor.get_volume_openers(vdi_uuid)
196+
util.SMlog(f'Volume not attachable because RO. Openers: {openers}')
197+
if cb_openers:
198+
cb_openers(vdi_uuid, openers)
198199
raise
199200
break
200201
util.retry(check_volume_usable, 15, 2)
@@ -554,7 +555,7 @@ def _call_method(self, local_method, remote_method, device_path, use_parent, *ar
554555
# B.3. Call!
555556
def remote_call():
556557
try:
557-
all_openers = self._linstor.get_volume_openers(openers_uuid)
558+
openers = self._linstor.get_volume_openers(openers_uuid)
558559
except Exception as e:
559560
raise xs_errors.XenError(
560561
'VDIUnavailable',
@@ -563,8 +564,8 @@ def remote_call():
563564
)
564565

565566
no_host_found = True
566-
for hostname, openers in all_openers.items():
567-
if not openers:
567+
for hostname, host_openers in all_openers.items():
568+
if not host_openers:
568569
continue
569570

570571
host_ref = self._find_host_ref_from_hostname(hosts, hostname)

drivers/linstorvolumemanager.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,16 @@ def get_local_volume_openers(resource_name, volume):
7171
process_name = groups[0]
7272
pid = groups[1]
7373
open_duration_ms = groups[2]
74+
75+
try:
76+
cmdline = util.get_process_cmdline()
77+
except Exception:
78+
cmdline = []
79+
7480
result[pid] = {
7581
'process-name': process_name,
76-
'open-duration': open_duration_ms
82+
'open-duration': open_duration_ms,
83+
'cmdline': cmdline
7784
}
7885

7986
return json.dumps(result)

drivers/tapdisk-pause

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,11 @@ class Tapdisk:
168168
group_name,
169169
logger=util.SMlog
170170
)
171-
device_path = LinstorVhdUtil(session, linstor).create_chain_paths(self.vdi_uuid)
171+
172+
import cleanup
173+
device_path = LinstorVhdUtil(session, linstor).create_chain_paths(
174+
self.vdi_uuid, False, cleanup.LinstorSR.abort_from_openers
175+
)
172176

173177
if realpath != device_path:
174178
util.SMlog(

drivers/util.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
# Miscellaneous utility functions
1717
#
1818

19+
from sm_typing import List
20+
1921
import os
2022
import re
2123
import sys
@@ -1210,6 +1212,12 @@ def _getVDIs(srobj):
12101212
return VDIs
12111213

12121214

1215+
def get_sr_from_vdi_uuid(session, vdi_uuid):
1216+
vdi_ref = session.xenapi.VDI.get_by_uuid(vdi_uuid)
1217+
sr_ref = session.xenapi.VDI.get_SR(vdi_ref)
1218+
return session.xenapi.get_uuid(sr_ref)
1219+
1220+
12131221
def _getVDI(srobj, vdi_uuid):
12141222
vdi = srobj.session.xenapi.VDI.get_by_uuid(vdi_uuid)
12151223
ref = srobj.session.xenapi.VDI.get_record(vdi)
@@ -1484,6 +1492,17 @@ def pid_is_alive(pid):
14841492
return False
14851493

14861494

1495+
def get_process_cmdline(pid: int) -> List[str]:
1496+
try:
1497+
with open(os.path.join('/proc', str(pid), 'cmdline'), 'rb') as f:
1498+
line = f.read().split(b'\0')
1499+
return [arg.decode() for arg in line]
1500+
except IOError as e:
1501+
if e.errno == errno.ENOENT:
1502+
raise
1503+
return []
1504+
1505+
14871506
# Looks at /proc and figures either
14881507
# If a process is still running (default), returns open file names
14891508
# If any running process has open handles to the given file (process = False)

0 commit comments

Comments
 (0)