1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-11 12:46:49 +00:00

fix(instances): a VM's destruction checks its files on every host first

Destroying a VM with its disk files forced it off first and then
worked out which files to delete, so a check that failed left the VM
stopped, and only this host's VMs and volumes were checked: a file on
shared storage that a VM on another host uses was deleted.

The files are now worked out before the VM is stopped: the disks it
runs with and those of its next start, as before with their snapshot
files and seed. A file a VM or volume of another of the panel's hosts
uses at the same path (shared storage is mounted at one path on every
host, as migration needs) is kept like one used here; another record
of the VM's own host is skipped, as there the VM itself uses them. A
host that cannot be read stops the destruction with its name, before
anything is stopped or deleted.
This commit is contained in:
catborise 2026-10-31 01:08:42 +03:00
parent 6dc2e5851b
commit 54a1943e26
8 changed files with 125 additions and 12 deletions

View file

@ -1691,18 +1691,25 @@ class wvmInstance(wvmConnect):
are this VM's: their backing files do not count."""
return self.paths_in_use(self.instance.UUIDString(), own)
def split_disk_paths_by_use(self):
def split_disk_paths_by_use(self, elsewhere=None):
"""This VM's disk paths, split into (only this VM, also used by another
domain). With external snapshots, the files below a disk that the
snapshots were taken on, and their memory files, are the VM's too, and
so is its cloud-init seed, in a CD-ROM drive or ejected."""
domain). Its disks are those it runs with and those of its next start.
With external snapshots, the files below a disk that the snapshots
were taken on, and their memory files, are the VM's too, and so is its
cloud-init seed, in a CD-ROM drive or ejected. elsewhere(own): the
paths of these that other hosts use."""
self.refresh_instance_pools()
own = [disk["path"] for disk in self.get_disk_devices() if disk["path"]]
own = []
for disk in self.get_disk_devices() + self.get_disk_devices(config=True):
if disk["path"] and disk["path"] not in own:
own.append(disk["path"])
own += self._snapshot_chain_files(own)
seed = self._seed_path()
if seed:
own.append(seed)
used_elsewhere = self.paths_used_by_other_domains(own)
if elsewhere:
used_elsewhere |= elsewhere(own)
# a kept file keeps the files below it
for path in [path for path in own if path in used_elsewhere]:
while (path := self.backing_path(path)) and path not in used_elsewhere: