Sync from SUSE:ALP:Source:Standard:1.0 libvirt revision c02dcd1e6fa7036f5670200c5d659158
This commit is contained in:
commit
ef81382f28
23
.gitattributes
vendored
Normal file
23
.gitattributes
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
## Default LFS
|
||||
*.7z filter=lfs diff=lfs merge=lfs -text
|
||||
*.bsp filter=lfs diff=lfs merge=lfs -text
|
||||
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
||||
*.gem filter=lfs diff=lfs merge=lfs -text
|
||||
*.gz filter=lfs diff=lfs merge=lfs -text
|
||||
*.jar filter=lfs diff=lfs merge=lfs -text
|
||||
*.lz filter=lfs diff=lfs merge=lfs -text
|
||||
*.lzma filter=lfs diff=lfs merge=lfs -text
|
||||
*.obscpio filter=lfs diff=lfs merge=lfs -text
|
||||
*.oxt filter=lfs diff=lfs merge=lfs -text
|
||||
*.pdf filter=lfs diff=lfs merge=lfs -text
|
||||
*.png filter=lfs diff=lfs merge=lfs -text
|
||||
*.rpm filter=lfs diff=lfs merge=lfs -text
|
||||
*.tbz filter=lfs diff=lfs merge=lfs -text
|
||||
*.tbz2 filter=lfs diff=lfs merge=lfs -text
|
||||
*.tgz filter=lfs diff=lfs merge=lfs -text
|
||||
*.ttf filter=lfs diff=lfs merge=lfs -text
|
||||
*.txz filter=lfs diff=lfs merge=lfs -text
|
||||
*.whl filter=lfs diff=lfs merge=lfs -text
|
||||
*.xz filter=lfs diff=lfs merge=lfs -text
|
||||
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||
*.zst filter=lfs diff=lfs merge=lfs -text
|
12
README.packaging.txt
Normal file
12
README.packaging.txt
Normal file
@ -0,0 +1,12 @@
|
||||
This package is maintained in git at
|
||||
https://github.com/openSUSE/libvirt
|
||||
|
||||
Please submit a pull request for any changes. The spec file is also maintained
|
||||
in git.
|
||||
|
||||
To build a package from git, edit the _service to reference the desired branch
|
||||
and call
|
||||
|
||||
osc service localrun
|
||||
|
||||
The package can then be build as usual with your prefered osc build options.
|
19
_service
Normal file
19
_service
Normal file
@ -0,0 +1,19 @@
|
||||
<services>
|
||||
<service name="tar_scm" mode="manual">
|
||||
<param name="scm">git</param>
|
||||
<param name="url">https://github.com/openSUSE/libvirt.git</param>
|
||||
<param name="revision">factory</param>
|
||||
<param name="extract">libvirt.spec</param>
|
||||
<param name="extract">README.packaging.txt</param>
|
||||
<param name="extract">libvirt-supportconfig</param>
|
||||
<param name="versionformat">@PARENT_TAG@</param>
|
||||
<param name="versionrewrite-pattern">[v]?([^-+a-z]+)(.*)</param>
|
||||
<param name="versionrewrite-replacement">\1</param>
|
||||
<param name="changesgenerate">disable</param>
|
||||
</service>
|
||||
<service name="set_version" mode="manual"/>
|
||||
<service name="recompress" mode="manual">
|
||||
<param name="file">*.tar</param>
|
||||
<param name="compression">xz</param>
|
||||
</service>
|
||||
</services>
|
4
baselibs.conf
Normal file
4
baselibs.conf
Normal file
@ -0,0 +1,4 @@
|
||||
libvirt-client
|
||||
requires -libvirt-<targettype>
|
||||
libvirt-devel
|
||||
requires -libvirt-<targettype>
|
BIN
libvirt-10.0.0.tar.xz
(Stored with Git LFS)
Normal file
BIN
libvirt-10.0.0.tar.xz
(Stored with Git LFS)
Normal file
Binary file not shown.
3
libvirt-rpmlintrc
Normal file
3
libvirt-rpmlintrc
Normal file
@ -0,0 +1,3 @@
|
||||
addFilter("shlib-policy-name-error")
|
||||
addFilter("missing-dependency-to-logrotate for logrotate script /etc/logrotate.d/libvirtd.(qemu|lxc|uml|libxl)")
|
||||
addFilter("incoherent-logrotate-file")
|
95
libvirt-supportconfig
Normal file
95
libvirt-supportconfig
Normal file
@ -0,0 +1,95 @@
|
||||
#!/bin/bash
|
||||
#############################################################
|
||||
# Name: Supportconfig Plugin for libvirt
|
||||
# Description: Gathers important troubleshooting information
|
||||
# about libvirt
|
||||
#############################################################
|
||||
|
||||
RCFILE="/usr/lib/supportconfig/resources/supportconfig.rc"
|
||||
OF="output-libvirt.txt"
|
||||
|
||||
# conf files for all daemons reside in /etc/libvirt/. VM conf files
|
||||
# and log files reside in hypervisor-specific locations.
|
||||
DAEMON_CONF_FILES="$(find -L /etc/libvirt/*.conf -type f 2>/dev/null | sort)"
|
||||
PERSISTENT_VM_CONF_FILES=""
|
||||
ACTIVE_VM_CONF_FILES=""
|
||||
DAEMON_LOG_FILES=""
|
||||
|
||||
if [ -s $RCFILE ]; then
|
||||
if ! source $RCFILE; then
|
||||
log_write $OF "ERROR: Initializing resource file: $RCFILE"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
rpm_installed() {
|
||||
thisrpm="$1"
|
||||
|
||||
if rpm -q "$thisrpm" >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
if rpm_installed libvirt-daemon-driver-libxl; then
|
||||
test -d /etc/libvirt/libxl && PERSISTENT_VM_CONF_FILES="$PERSISTENT_VM_CONF_FILES $(find -L /etc/libvirt/libxl/ -type f | sort)"
|
||||
test -d /run/libvirt/libxl && ACTIVE_VM_CONF_FILES="$ACTIVE_VM_CONF_FILES $(find -L /run/libvirt/libxl/ -type f | sort)"
|
||||
test -d /var/log/libvirt/libxl && DAEMON_LOG_FILES="$DAEMON_LOG_FILES $(find -L /var/log/libvirt/libxl/ -type f | sort)"
|
||||
fi
|
||||
|
||||
if rpm_installed libvirt-daemon-driver-qemu; then
|
||||
test -d /etc/libvirt/qemu && PERSISTENT_VM_CONF_FILES="$PERSISTENT_VM_CONF_FILES $(find -L /etc/libvirt/qemu/ -type f | sort)"
|
||||
test -d /run/libvirt/qemu && ACTIVE_VM_CONF_FILES="$ACTIVE_VM_CONF_FILES $(find -L /run/libvirt/qemu/ -type f | sort)"
|
||||
test -d /var/log/libvirt/qemu && DAEMON_LOG_FILES="$DAEMON_LOG_FILES $(find -L /var/log/libvirt/qemu/ -type f | sort)"
|
||||
fi
|
||||
|
||||
if rpm_installed libvirt-daemon; then
|
||||
DAEMON_LOG_FILES="$DAEMON_LOG_FILES $(find -L /var/log/libvirt/*.log -type f 2>/dev/null | sort)"
|
||||
fi
|
||||
|
||||
if rpm_installed libvirt-client && virsh capabilities > /dev/null 2>&1; then
|
||||
|
||||
log_cmd $OF "virsh version"
|
||||
log_cmd $OF "virsh capabilities"
|
||||
log_cmd $OF "virsh domcapabilities"
|
||||
log_cmd $OF "virsh nodeinfo"
|
||||
log_cmd $OF "virsh nodedev-list"
|
||||
# print all known domains on default URI
|
||||
log_cmd $OF "virsh list --all"
|
||||
# dump configuration info of active domains on default URI
|
||||
for DOM in $(virsh list --name)
|
||||
do
|
||||
log_cmd $OF "virsh dumpxml $DOM"
|
||||
log_cmd $OF "virsh vcpuinfo $DOM"
|
||||
log_cmd $OF "virsh dominfo $DOM"
|
||||
log_cmd $OF "virsh domjobinfo $DOM"
|
||||
log_cmd $OF "virsh dommemstat $DOM"
|
||||
log_cmd $OF "virsh snapshot-list $DOM"
|
||||
done
|
||||
# dump configuration info of inactive domains on default URI
|
||||
for DOM in $(virsh list --name --inactive)
|
||||
do
|
||||
log_cmd $OF "virsh dumpxml $DOM"
|
||||
log_cmd $OF "virsh snapshot-list $DOM"
|
||||
done
|
||||
# dump active networks, interfaces and storage pools
|
||||
log_cmd $OF "virsh net-list"
|
||||
log_cmd $OF "virsh iface-list"
|
||||
log_cmd $OF "virsh pool-list"
|
||||
fi
|
||||
|
||||
# dump libvirtd-related conf files
|
||||
conf_files $OF "$DAEMON_CONF_FILES"
|
||||
|
||||
# dump persistent VM-related conf files
|
||||
conf_files $OF "$PERSISTENT_VM_CONF_FILES"
|
||||
|
||||
# dump active VM-related conf files
|
||||
conf_files $OF "$ACTIVE_VM_CONF_FILES"
|
||||
|
||||
# dump hook conf files
|
||||
test -d /etc/libvirt/hooks && FILES="$(find -L /etc/libvirt/hooks/ -type f | sort)"
|
||||
conf_files $OF "$FILES"
|
||||
|
||||
# dump all log files
|
||||
log_files $OF 0 "$DAEMON_LOG_FILES"
|
6321
libvirt.changes
Normal file
6321
libvirt.changes
Normal file
File diff suppressed because it is too large
Load Diff
1919
libvirt.spec
Normal file
1919
libvirt.spec
Normal file
File diff suppressed because it is too large
Load Diff
6
libvirtd-relocation-server.xml
Normal file
6
libvirtd-relocation-server.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<service>
|
||||
<short>libvirtd Migration Server</short>
|
||||
<description>Enables TCP ports for libvirtd native migration</description>
|
||||
<port protocol="tcp" port="49152-49215"/>
|
||||
</service>
|
331
suse-qemu-domain-hook.py
Normal file
331
suse-qemu-domain-hook.py
Normal file
@ -0,0 +1,331 @@
|
||||
#!/usr/bin/python3
|
||||
# libvirt hook script for QEMU/KVM domains. See the libvirt hooks
|
||||
# documenation for more details
|
||||
#
|
||||
# https://www.libvirt.org/hooks.html
|
||||
#
|
||||
# Currently this hook looks for domains with <metadata> containing
|
||||
# configuration for dmmd <disk> devices. All <metadata> sub-elements
|
||||
# must have a matching <disk> under <devices>. Those without a matching
|
||||
# <disk> will be ignored.
|
||||
#
|
||||
# The dmmd device syntax is similar to Xen's block-dmmd. E.g.
|
||||
# md;/dev/md0(/etc/mdadm/mdadm.conf);lvm;/dev/vg/lv
|
||||
#
|
||||
# Device pairs (type;dev) are processed in order. The last device
|
||||
# should match a <source dev=> attribute of a <disk>. The following
|
||||
# configuration illustrates a domain with two dmmd devices
|
||||
#
|
||||
# <domain>
|
||||
# ...
|
||||
# <metadata>
|
||||
# <hook:dmmd xmlns:hook='https://libvirt.org/schemas/domain/hooks/1.0'>
|
||||
# <disk>md;/dev/md0(/etc/mdadm.conf);lvm;/dev/vg1/lv1</disk>
|
||||
# <disk>md;/dev/md1(/etc/mdadm.conf);lvm;/dev/vg1/lv2</disk>
|
||||
# </hook:dmmd>
|
||||
# </metadata>
|
||||
# <devices>
|
||||
# ...
|
||||
# <disk type='block' device='disk'>
|
||||
# <driver name='qemu' type='raw'/>
|
||||
# <source dev='/dev/vg1/lv1'/>
|
||||
# <target dev='vdb' bus='virtio'/>
|
||||
# </disk>
|
||||
# <disk type='block' device='disk'>
|
||||
# <driver name='qemu' type='raw'/>
|
||||
# <source dev='/dev/vg1/lv2'/>
|
||||
# <target dev='vdc' bus='virtio'/>
|
||||
# </disk>
|
||||
# </devices>
|
||||
# </domain>
|
||||
#
|
||||
#
|
||||
# md devices can optionally:
|
||||
# specify a config file through:
|
||||
# md;/dev/md100(/var/opt/config/mdadm.conf)
|
||||
# use an array name (mdadm -N option):
|
||||
# md;My-MD-name;lvm;/dev/vg1/lv1
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import subprocess
|
||||
from lxml import etree
|
||||
from subprocess import check_output
|
||||
from subprocess import CalledProcessError
|
||||
|
||||
COMMAND_TIMEOUT = 60
|
||||
MDADM_BIN = "/sbin/mdadm"
|
||||
PVSCAN_BIN = "/sbin/pvscan"
|
||||
LVCHANGE_BIN = "/sbin/lvchange"
|
||||
HOOK_NAMESPACE = "https://libvirt.org/schemas/domain/hooks/1.0"
|
||||
HOOK_NS_TAG = "{%s}" % HOOK_NAMESPACE
|
||||
|
||||
DEBUG = False
|
||||
|
||||
def write_debug(msg):
|
||||
if DEBUG:
|
||||
with open("/var/log/libvirt/qemu/suse-qemu-hook-output.log", "a") as f:
|
||||
f.write(msg + "\n")
|
||||
|
||||
|
||||
def run_cmd(cmd):
|
||||
cmd_output = ""
|
||||
rc = 0
|
||||
|
||||
msg = ""
|
||||
for m in cmd:
|
||||
msg += m + " "
|
||||
write_debug("run_cmd executing: " + msg)
|
||||
|
||||
try:
|
||||
cmd_output = check_output(cmd, stderr=subprocess.STDOUT)
|
||||
except CalledProcessError as err:
|
||||
write_debug("run_cmd: caught CalledProcessError with output: " + err.output)
|
||||
rc = err.returncode
|
||||
|
||||
if rc != 0:
|
||||
write_debug("run_cmd failed: " + msg)
|
||||
|
||||
return [rc, cmd_output]
|
||||
|
||||
|
||||
def prepare_md(dev):
|
||||
conf = []
|
||||
mdadmopts = []
|
||||
devpath = ""
|
||||
startcfg = dev.find("(")
|
||||
|
||||
# check if MD config specifies a conf file for mdadm
|
||||
if startcfg != -1:
|
||||
endcfg = dev.find(")")
|
||||
conf = ["-c"]
|
||||
conf.append(dev[startcfg + 1:endcfg])
|
||||
dev = dev[:startcfg]
|
||||
|
||||
# check if MD config contains a device or array name
|
||||
if not dev.startswith("/"):
|
||||
mdadmopts = ["-s"]
|
||||
mdadmopts.append("-N")
|
||||
devpath = "/dev/md/" + dev
|
||||
else:
|
||||
devpath = dev
|
||||
|
||||
# check if MD device is already active
|
||||
cmd = [MDADM_BIN, "-Q"]
|
||||
cmd.append(devpath)
|
||||
write_debug("prepare_md: calling mdadm -Q for device " + devpath)
|
||||
ret, cmd_output = run_cmd(cmd)
|
||||
if ret == 0:
|
||||
write_debug("prepare_md: mdadm -Q succeeded for device " + devpath + ". Already activated")
|
||||
return 0
|
||||
|
||||
cmd = [MDADM_BIN, "-A"]
|
||||
cmd.extend(mdadmopts)
|
||||
cmd.extend(conf)
|
||||
cmd.append(devpath)
|
||||
|
||||
write_debug("prepare_md: calling mdadm -A for device " + devpath)
|
||||
ret, cmd_output = run_cmd(cmd)
|
||||
|
||||
if ret != 0:
|
||||
write_debug("prepare_md: mdadm -A failed for device " + devpath)
|
||||
else:
|
||||
write_debug("prepare_md: mdadm -A succeeded for device " + devpath)
|
||||
return ret
|
||||
|
||||
|
||||
def release_md(dev):
|
||||
conf = []
|
||||
devpath = ""
|
||||
startcfg = dev.find("(")
|
||||
|
||||
if startcfg != -1:
|
||||
endcfg = dev.find(")")
|
||||
conf = ["-c"]
|
||||
conf.append(dev[startcfg + 1:endcfg])
|
||||
dev = dev[:startcfg]
|
||||
|
||||
# check if MD config contains a device or array name. For
|
||||
# querying and deactivating a device name is required
|
||||
if not dev.startswith("/"):
|
||||
devpath = "/dev/md/" + dev
|
||||
else:
|
||||
devpath = dev
|
||||
|
||||
# check if device exists
|
||||
cmd = [MDADM_BIN, "-Q"]
|
||||
cmd.extend(conf)
|
||||
cmd.append(devpath)
|
||||
|
||||
write_debug("release_md: calling mdadm -Q for device " + devpath)
|
||||
ret, cmd_output = run_cmd(cmd)
|
||||
if ret != 0:
|
||||
write_debug("release_md: mdadm -Q failed for device " + devpath + ". Already deactivated")
|
||||
return 0
|
||||
|
||||
cmd = [MDADM_BIN, "-S"]
|
||||
cmd.extend(conf)
|
||||
cmd.append(devpath)
|
||||
write_debug("release_md: calling mdadm -S for device " + devpath)
|
||||
ret, cmd_output = run_cmd(cmd)
|
||||
if ret == 0:
|
||||
write_debug("release_md: mdadm -S succeeded for device " + devpath)
|
||||
else:
|
||||
write_debug("release_md: mdadm -S failed for device " + devpath)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def prepare_lvm(dev):
|
||||
cmd = [LVCHANGE_BIN]
|
||||
cmd.append("-aey")
|
||||
cmd.append(dev)
|
||||
|
||||
endtime = time.time() + COMMAND_TIMEOUT;
|
||||
while time.time() < endtime:
|
||||
# When using MD devices for LVM PV, it is best to rescan for PV and VG
|
||||
run_cmd([PVSCAN_BIN])
|
||||
ret, cmd_output = run_cmd(cmd)
|
||||
if ret == 0 and os.path.exists(dev):
|
||||
write_debug("prepare_lvm: lvchange -aey succeeded on device " + dev)
|
||||
return 0
|
||||
else:
|
||||
write_debug("prepare_lvm: lvchange -aey failed on device " + dev)
|
||||
time.sleep(0.1)
|
||||
|
||||
write_debug("prepare_lvm: lvchange -aey never succeeded for device " + dev)
|
||||
return 1
|
||||
|
||||
|
||||
def release_lvm(dev):
|
||||
# Nothing to do if the device doesn't exist or is already deactivated
|
||||
if not os.path.exists(dev):
|
||||
write_debug("release_lvm: dev " + dev + " does not exist. Nothing to do!")
|
||||
return 0
|
||||
|
||||
cmd = [LVCHANGE_BIN]
|
||||
cmd.append("-aen")
|
||||
cmd.append(dev)
|
||||
|
||||
endtime = time.time() + COMMAND_TIMEOUT;
|
||||
while time.time() < endtime:
|
||||
ret, cmd_output = run_cmd(cmd)
|
||||
if ret == 0:
|
||||
write_debug("release_lvm: lvchange -aen succeeded for device " + dev)
|
||||
return 0
|
||||
else:
|
||||
write_debug("release_lvm: lvchange -aen failed for device " + dev + ". Trying again...")
|
||||
|
||||
time.sleep(0.1)
|
||||
|
||||
write_debug("release_lvm: lvchange -aen never succeeded for device " + dev)
|
||||
return 1
|
||||
|
||||
|
||||
def prepare_config(params):
|
||||
write_debug("prepare_config: called with params " + params)
|
||||
conf = params.split(";")
|
||||
i = 0
|
||||
|
||||
while i < len(conf):
|
||||
t = conf[i]
|
||||
d = conf[i+1]
|
||||
write_debug("prepare_config: got t = " + t + " and d = " + d)
|
||||
if t == "md":
|
||||
if prepare_md(d):
|
||||
write_debug("prepare_config: failed to prepare MD device " + d)
|
||||
return 1
|
||||
if t == "lvm":
|
||||
if prepare_lvm(d):
|
||||
write_debug("prepare_config: failed to prepare LVM device " + d)
|
||||
return 1
|
||||
i += 2
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def release_config(params):
|
||||
write_debug("release_config: called with params " + params)
|
||||
conf = params.split(";")
|
||||
i = len(conf) - 1
|
||||
ret = 0
|
||||
|
||||
# work backwards through the list when releasing, cleaning
|
||||
# up LVM first, then MD
|
||||
while i >= 0:
|
||||
t = conf[i-1]
|
||||
d = conf[i]
|
||||
write_debug("release_config: got t = " + t + " and d = " + d)
|
||||
if t == "md":
|
||||
if release_md(d):
|
||||
write_debug("release_config: failed to release MD device " + d)
|
||||
ret = 1
|
||||
if t == "lvm":
|
||||
if release_lvm(d):
|
||||
write_debug("release_config: failed to release LVM device " + d)
|
||||
ret = 1
|
||||
i -= 2
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
sys.exit(1)
|
||||
|
||||
exit_code = 0
|
||||
disk_devs = []
|
||||
phase = sys.argv[2]
|
||||
vmxml = sys.stdin.read()
|
||||
|
||||
tree = etree.fromstring(vmxml.encode("utf-8", "ignore"))
|
||||
devs = tree.xpath("/domain/devices/disk")
|
||||
dmmd_configs = tree.xpath("/domain/metadata/hook:dmmd/disk", namespaces={'hook': HOOK_NAMESPACE})
|
||||
|
||||
if len(dmmd_configs) == 0:
|
||||
write_debug("No dmmd configurations found in <metadata>")
|
||||
sys.exit(0)
|
||||
|
||||
write_debug("got phase: " + phase)
|
||||
|
||||
# build a list of <disk type='block'> source device names to check against
|
||||
# dmmd configurations
|
||||
for d in devs:
|
||||
val = d.get("type")
|
||||
if val is None or val != "block":
|
||||
continue
|
||||
|
||||
for child in d:
|
||||
if child.tag == "source":
|
||||
disk_devs.append(child.get("dev"))
|
||||
|
||||
# For each dmmd configuration in <metadata>, check there is a corresponding
|
||||
# disk
|
||||
for config in dmmd_configs:
|
||||
# check that a disk exists for this config. <disk> devices may have
|
||||
# been added or removed without a corresponding update to <metadata>
|
||||
index = config.text.rfind(";")
|
||||
if index == -1:
|
||||
continue
|
||||
|
||||
disk = config.text[index + 1:]
|
||||
# remove config file specfied with '(/path/to/conf)'
|
||||
if disk.endswith(")"):
|
||||
index = disk.rfind("(")
|
||||
if index == -1:
|
||||
continue
|
||||
disk = disk[:index]
|
||||
|
||||
if disk not in disk_devs:
|
||||
write_debug("Ignoring config '" + config.text + "' with no matching <disk> device")
|
||||
continue
|
||||
|
||||
# TODO: check that migration can be handled by the 'prepare' phase on
|
||||
# destination and 'release' phase on source
|
||||
if phase == "prepare":
|
||||
exit_code = prepare_config(config.text)
|
||||
|
||||
if phase == "release":
|
||||
exit_code = release_config(config.text)
|
||||
|
||||
sys.exit(exit_code)
|
Loading…
Reference in New Issue
Block a user