|
18 | 18 | # Script to coalesce and garbage collect VHD-based SR's in the background |
19 | 19 | # |
20 | 20 |
|
21 | | -from sm_typing import Optional, override |
| 21 | +from sm_typing import Dict, Optional, override |
22 | 22 |
|
23 | 23 | import os |
24 | 24 | import os.path |
|
56 | 56 | from linstorjournaler import LinstorJournaler |
57 | 57 | from linstorvhdutil import LinstorVhdUtil |
58 | 58 | from linstorvolumemanager import get_controller_uri |
59 | | - from linstorvolumemanager import LinstorVolumeManager |
60 | | - from linstorvolumemanager import LinstorVolumeManagerError |
| 59 | + from linstorvolumemanager import LinstorVolumeManager, LinstorVolumeManagerError, LinstorVolumeOpeners |
61 | 60 | from linstorvolumemanager import PERSISTENT_PREFIX as LINSTOR_PERSISTENT_PREFIX |
62 | 61 |
|
63 | 62 | LINSTOR_AVAILABLE = True |
@@ -3656,17 +3655,57 @@ def _finishInterruptedCoalesceLeaf(self, childUuid, parentUuid): |
3656 | 3655 |
|
3657 | 3656 | def _checkSlaves(self, vdi): |
3658 | 3657 | try: |
3659 | | - all_openers = self._linstor.get_volume_openers(vdi.uuid) |
3660 | | - for openers in all_openers.values(): |
3661 | | - for opener in openers.values(): |
| 3658 | + openers = self._linstor.get_volume_openers(vdi.uuid) |
| 3659 | + for host_openers in openers.values(): |
| 3660 | + for opener in host_openers.values(): |
3662 | 3661 | if opener['process-name'] != 'tapdisk': |
3663 | 3662 | raise util.SMException( |
3664 | | - 'VDI {} is in use: {}'.format(vdi.uuid, all_openers) |
| 3663 | + 'VDI {} is in use: {}'.format(vdi.uuid, openers) |
3665 | 3664 | ) |
3666 | 3665 | except LinstorVolumeManagerError as e: |
3667 | 3666 | if e.code != LinstorVolumeManagerError.ERR_VOLUME_NOT_EXISTS: |
3668 | 3667 | raise |
3669 | 3668 |
|
| 3669 | + @classmethod |
| 3670 | + def abort_gc_from_openers_vdi(cls, vdi_uuid: str, openers: "LinstorVolumeOpeners") -> bool: |
| 3671 | + return cls._abort_gc_from_openers(vdi_uuid, True, openers) |
| 3672 | + |
| 3673 | + @classmethod |
| 3674 | + def abort_gc_from_openers_sr(cls, sr_uuid: str, openers: "LinstorVolumeOpeners") -> bool: |
| 3675 | + return cls._abort_gc_from_openers(sr_uuid, False, openers) |
| 3676 | + |
| 3677 | + @staticmethod |
| 3678 | + def _abort_gc_from_openers(uuid: str, is_vdi_uuid: bool, openers: "LinstorVolumeOpeners") -> bool: |
| 3679 | + from linstorvhdutil import MANAGER_PLUGIN |
| 3680 | + |
| 3681 | + node_name = None |
| 3682 | + |
| 3683 | + for host_openers in openers.values(): |
| 3684 | + for hostname, opener in host_openers.items(): |
| 3685 | + # Not the most accurate check but it works... |
| 3686 | + # `vhd-util` is probably prefixed with a "+" which is ignored here. |
| 3687 | + if not opener["process-name"].endswith("vhd-util") or "coalesce" not in opener["cmdline"]: |
| 3688 | + continue |
| 3689 | + |
| 3690 | + if not node_name: |
| 3691 | + import socket |
| 3692 | + node_name = socket.gethostname() |
| 3693 | + |
| 3694 | + if node_name == hostname: |
| 3695 | + continue |
| 3696 | + |
| 3697 | + session = XAPI.getSession() |
| 3698 | + try: |
| 3699 | + sr_uuid = util.get_sr_from_vdi_uuid(session, uuid) if is_vdi_uuid else uuid |
| 3700 | + util.SMlog(f"LINSTOR volume is coalescing on `{sr_uuid}`. We're going to interrupt the GC...") |
| 3701 | + return util.strtobool(session.xenapi.host.call_plugin( |
| 3702 | + util.get_master_ref(session), MANAGER_PLUGIN, "abortGc", {"srUuid": sr_uuid} |
| 3703 | + )) |
| 3704 | + finally: |
| 3705 | + session.xenapi.session.logout() |
| 3706 | + return False |
| 3707 | + |
| 3708 | + |
3670 | 3709 |
|
3671 | 3710 | ################################################################################ |
3672 | 3711 | # |
|
0 commit comments