community/libvirt to 7.0.0-2

This commit is contained in:
Kevin Mihelich 2021-01-25 18:34:46 +00:00
parent bab51489e4
commit 5a73dfaffd
3 changed files with 51 additions and 504 deletions

View file

@ -1,478 +0,0 @@
diff --git a/po/POTFILES.in b/po/POTFILES.in
index af52054aa4..eb1ffd1dbd 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -240,6 +240,7 @@
@SRCDIR@/src/util/vircrypto.c
@SRCDIR@/src/util/virdaemon.c
@SRCDIR@/src/util/virdbus.c
+@SRCDIR@/src/util/virdevmapper.c
@SRCDIR@/src/util/virdnsmasq.c
@SRCDIR@/src/util/virerror.c
@SRCDIR@/src/util/virerror.h
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 914bf640ca..e88da02341 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -87,7 +87,7 @@ qemuSetupImagePathCgroup(virDomainObjPtr vm,
}
if (virDevMapperGetTargets(path, &targetPaths) < 0 &&
- errno != ENOSYS && errno != EBADF) {
+ errno != ENOSYS) {
virReportSystemError(errno,
_("Unable to get devmapper targets for %s"),
path);
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index c5b8d91f9a..088d711ae3 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -10338,7 +10338,7 @@ qemuDomainSetupDisk(virQEMUDriverConfigPtr cfg G_GNUC_UNUSED,
return -1;
if (virDevMapperGetTargets(next->path, &targetPaths) < 0 &&
- errno != ENOSYS && errno != EBADF) {
+ errno != ENOSYS) {
virReportSystemError(errno,
_("Unable to get devmapper targets for %s"),
next->path);
@@ -11402,7 +11402,7 @@ qemuDomainNamespaceSetupDisk(virDomainObjPtr vm,
tmpPath = g_strdup(next->path);
if (virDevMapperGetTargets(next->path, &targetPaths) < 0 &&
- errno != ENOSYS && errno != EBADF) {
+ errno != ENOSYS) {
virReportSystemError(errno,
_("Unable to get devmapper targets for %s"),
next->path);
diff --git a/src/util/virdevmapper.c b/src/util/virdevmapper.c
index 40a82285f9..a471504176 100644
--- a/src/util/virdevmapper.c
+++ b/src/util/virdevmapper.c
@@ -20,38 +20,67 @@
#include <config.h>
+#include "virdevmapper.h"
+#include "internal.h"
+
#ifdef __linux__
# include <sys/sysmacros.h>
-#endif
+# include <linux/dm-ioctl.h>
+# include <sys/ioctl.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
-#ifdef WITH_DEVMAPPER
-# include <libdevmapper.h>
-#endif
+# include "virthread.h"
+# include "viralloc.h"
+# include "virstring.h"
+# include "virfile.h"
+
+# define VIR_FROM_THIS VIR_FROM_STORAGE
+
+# define PROC_DEVICES "/proc/devices"
+# define DM_NAME "device-mapper"
+# define DEV_DM_DIR "/dev/" DM_DIR
+# define CONTROL_PATH DEV_DM_DIR "/" DM_CONTROL_NODE
+# define BUF_SIZE (16 * 1024)
+
+G_STATIC_ASSERT(BUF_SIZE > sizeof(struct dm_ioctl));
+
+static unsigned int virDMMajor;
-#include "virdevmapper.h"
-#include "internal.h"
-#include "virthread.h"
-#include "viralloc.h"
-#include "virstring.h"
-
-#ifdef WITH_DEVMAPPER
-static void
-virDevMapperDummyLogger(int level G_GNUC_UNUSED,
- const char *file G_GNUC_UNUSED,
- int line G_GNUC_UNUSED,
- int dm_errno G_GNUC_UNUSED,
- const char *fmt G_GNUC_UNUSED,
- ...)
-{
- return;
-}
static int
virDevMapperOnceInit(void)
{
- /* Ideally, we would not need this. But libdevmapper prints
- * error messages to stderr by default. Sad but true. */
- dm_log_with_errno_init(virDevMapperDummyLogger);
+ g_autofree char *buf = NULL;
+ VIR_AUTOSTRINGLIST lines = NULL;
+ size_t i;
+
+ if (virFileReadAll(PROC_DEVICES, BUF_SIZE, &buf) < 0)
+ return -1;
+
+ lines = virStringSplit(buf, "\n", 0);
+ if (!lines)
+ return -1;
+
+ for (i = 0; lines[i]; i++) {
+ g_autofree char *dev = NULL;
+ unsigned int maj;
+
+ if (sscanf(lines[i], "%u %ms\n", &maj, &dev) == 2 &&
+ STREQ(dev, DM_NAME)) {
+ virDMMajor = maj;
+ break;
+ }
+ }
+
+ if (!lines[i]) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unable to find major for %s"),
+ DM_NAME);
+ return -1;
+ }
+
return 0;
}
@@ -59,104 +88,190 @@ virDevMapperOnceInit(void)
VIR_ONCE_GLOBAL_INIT(virDevMapper);
+static void *
+virDMIoctl(int controlFD, int cmd, struct dm_ioctl *dm, char **buf)
+{
+ size_t bufsize = BUF_SIZE;
+
+ reread:
+ *buf = g_new0(char, bufsize);
+
+ dm->version[0] = DM_VERSION_MAJOR;
+ dm->version[1] = 0;
+ dm->version[2] = 0;
+ dm->data_size = bufsize;
+ dm->data_start = sizeof(struct dm_ioctl);
+
+ memcpy(*buf, dm, sizeof(struct dm_ioctl));
+
+ if (ioctl(controlFD, cmd, *buf) < 0) {
+ VIR_FREE(*buf);
+ return NULL;
+ }
+
+ memcpy(dm, *buf, sizeof(struct dm_ioctl));
+
+ if (dm->flags & DM_BUFFER_FULL_FLAG) {
+ bufsize += BUF_SIZE;
+ VIR_FREE(*buf);
+ goto reread;
+ }
+
+ return *buf + dm->data_start;
+}
+
+
static int
-virDevMapperGetTargetsImpl(const char *path,
+virDMOpen(void)
+{
+ VIR_AUTOCLOSE controlFD = -1;
+ struct dm_ioctl dm;
+ g_autofree char *tmp = NULL;
+ int ret;
+
+ memset(&dm, 0, sizeof(dm));
+
+ if ((controlFD = open(CONTROL_PATH, O_RDWR)) < 0)
+ return -1;
+
+ if (!virDMIoctl(controlFD, DM_VERSION, &dm, &tmp)) {
+ virReportSystemError(errno, "%s",
+ _("Unable to get device-mapper version"));
+ return -1;
+ }
+
+ if (dm.version[0] != DM_VERSION_MAJOR) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+ _("Unsupported device-mapper version. Expected %d got %d"),
+ DM_VERSION_MAJOR, dm.version[0]);
+ return -1;
+ }
+
+ ret = controlFD;
+ controlFD = -1;
+ return ret;
+}
+
+
+static char *
+virDMSanitizepath(const char *path)
+{
+ g_autofree char *dmDirPath = NULL;
+ struct dirent *ent = NULL;
+ struct stat sb[2];
+ DIR *dh = NULL;
+ const char *p;
+ char *ret = NULL;
+ int rc;
+
+ /* If a path is NOT provided then assume it's DM name */
+ p = strrchr(path, '/');
+
+ if (!p)
+ return g_strdup(path);
+ else
+ p++;
+
+ /* It's a path. Check if the last component is DM name */
+ if (stat(path, &sb[0]) < 0) {
+ virReportError(errno,
+ _("Unable to stat %p"),
+ path);
+ return NULL;
+ }
+
+ dmDirPath = g_strdup_printf(DEV_DM_DIR "/%s", p);
+
+ if (stat(dmDirPath, &sb[1]) == 0 &&
+ sb[0].st_rdev == sb[1].st_rdev) {
+ return g_strdup(p);
+ }
+
+ /* The last component of @path wasn't DM name. Let's check if
+ * there's a device under /dev/mapper/ with the same rdev. */
+ if (virDirOpen(&dh, DEV_DM_DIR) < 0)
+ return NULL;
+
+ while ((rc = virDirRead(dh, &ent, DEV_DM_DIR)) > 0) {
+ g_autofree char *tmp = g_strdup_printf(DEV_DM_DIR "/%s", ent->d_name);
+
+ if (stat(tmp, &sb[1]) == 0 &&
+ sb[0].st_rdev == sb[0].st_rdev) {
+ ret = g_steal_pointer(&tmp);
+ break;
+ }
+ }
+
+ virDirClose(&dh);
+ return ret;
+}
+
+
+static int
+virDevMapperGetTargetsImpl(int controlFD,
+ const char *path,
char ***devPaths_ret,
unsigned int ttl)
{
- struct dm_task *dmt = NULL;
- struct dm_deps *deps;
- struct dm_info info;
- char **devPaths = NULL;
- char **recursiveDevPaths = NULL;
+ g_autofree char *sanitizedPath = NULL;
+ g_autofree char *buf = NULL;
+ struct dm_ioctl dm;
+ struct dm_target_deps *deps = NULL;
+ VIR_AUTOSTRINGLIST devPaths = NULL;
size_t i;
- int ret = -1;
+ memset(&dm, 0, sizeof(dm));
*devPaths_ret = NULL;
- if (virDevMapperInitialize() < 0)
- return ret;
-
if (ttl == 0) {
errno = ELOOP;
- return ret;
+ return -1;
}
if (!virIsDevMapperDevice(path))
return 0;
- if (!(dmt = dm_task_create(DM_DEVICE_DEPS))) {
- if (errno == ENOENT || errno == ENODEV) {
- /* It's okay. Kernel is probably built without
- * devmapper support. */
- ret = 0;
- }
- return ret;
- }
-
- if (!dm_task_set_name(dmt, path)) {
- if (errno == ENOENT) {
- /* It's okay, @path is not managed by devmapper =>
- * not a devmapper device. */
- ret = 0;
- }
- goto cleanup;
- }
-
- dm_task_no_open_count(dmt);
+ if (!(sanitizedPath = virDMSanitizepath(path)))
+ return 0;
- if (!dm_task_run(dmt)) {
- if (errno == ENXIO) {
- /* If @path = "/dev/mapper/control" ENXIO is returned. */
- ret = 0;
- }
- goto cleanup;
+ if (virStrncpy(dm.name, sanitizedPath, -1, DM_TABLE_DEPS) < 0) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("Resolved device mapper name too long"));
+ return -1;
}
- if (!dm_task_get_info(dmt, &info))
- goto cleanup;
+ deps = virDMIoctl(controlFD, DM_TABLE_DEPS, &dm, &buf);
+ if (!deps) {
+ if (errno == ENXIO)
+ return 0;
- if (!info.exists) {
- ret = 0;
- goto cleanup;
+ virReportSystemError(errno,
+ _("Unable to query dependencies for %s"),
+ path);
+ return -1;
}
- if (!(deps = dm_task_get_deps(dmt)))
- goto cleanup;
-
if (VIR_ALLOC_N_QUIET(devPaths, deps->count + 1) < 0)
- goto cleanup;
+ return -1;
for (i = 0; i < deps->count; i++) {
devPaths[i] = g_strdup_printf("/dev/block/%u:%u",
- major(deps->device[i]),
- minor(deps->device[i]));
+ major(deps->dev[i]),
+ minor(deps->dev[i]));
}
- recursiveDevPaths = NULL;
for (i = 0; i < deps->count; i++) {
- char **tmpPaths;
+ VIR_AUTOSTRINGLIST tmpPaths = NULL;
- if (virDevMapperGetTargetsImpl(devPaths[i], &tmpPaths, ttl - 1) < 0)
- goto cleanup;
+ if (virDevMapperGetTargetsImpl(controlFD, devPaths[i], &tmpPaths, ttl - 1) < 0)
+ return -1;
- if (tmpPaths &&
- virStringListMerge(&recursiveDevPaths, &tmpPaths) < 0) {
- virStringListFree(tmpPaths);
- goto cleanup;
- }
+ if (virStringListMerge(&devPaths, &tmpPaths) < 0)
+ return -1;
}
- if (virStringListMerge(&devPaths, &recursiveDevPaths) < 0)
- goto cleanup;
-
*devPaths_ret = g_steal_pointer(&devPaths);
- ret = 0;
- cleanup:
- virStringListFree(recursiveDevPaths);
- virStringListFree(devPaths);
- dm_task_destroy(dmt);
- return ret;
+ return 0;
}
@@ -175,9 +290,6 @@ virDevMapperGetTargetsImpl(const char *path,
* If @path consists of yet another devmapper targets these are
* consulted recursively.
*
- * If we don't have permissions to talk to kernel, -1 is returned
- * and errno is set to EBADF.
- *
* Returns 0 on success,
* -1 otherwise (with errno set, no libvirt error is
* reported)
@@ -186,46 +298,53 @@ int
virDevMapperGetTargets(const char *path,
char ***devPaths)
{
+ VIR_AUTOCLOSE controlFD = -1;
const unsigned int ttl = 32;
/* Arbitrary limit on recursion level. A devmapper target can
* consist of devices or yet another targets. If that's the
* case, we have to stop recursion somewhere. */
- return virDevMapperGetTargetsImpl(path, devPaths, ttl);
-}
+ if (virDevMapperInitialize() < 0)
+ return -1;
-#else /* ! WITH_DEVMAPPER */
+ if ((controlFD = virDMOpen()) < 0)
+ return -1;
-int
-virDevMapperGetTargets(const char *path G_GNUC_UNUSED,
- char ***devPaths G_GNUC_UNUSED)
-{
- errno = ENOSYS;
- return -1;
+ return virDevMapperGetTargetsImpl(controlFD, path, devPaths, ttl);
}
-#endif /* ! WITH_DEVMAPPER */
-#if WITH_DEVMAPPER
bool
virIsDevMapperDevice(const char *dev_name)
{
struct stat buf;
+ if (virDevMapperInitialize() < 0)
+ return false;
+
if (!stat(dev_name, &buf) &&
S_ISBLK(buf.st_mode) &&
- dm_is_dm_major(major(buf.st_rdev)))
- return true;
+ major(buf.st_rdev) == virDMMajor)
+ return true;
return false;
}
-#else /* ! WITH_DEVMAPPER */
+#else /* !defined(__linux__) */
+
+int
+virDevMapperGetTargets(const char *path G_GNUC_UNUSED,
+ char ***devPaths G_GNUC_UNUSED)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
bool
virIsDevMapperDevice(const char *dev_name G_GNUC_UNUSED)
{
return false;
}
-#endif /* ! WITH_DEVMAPPER */
+#endif /* ! defined(__linux__) */

View file

@ -9,15 +9,15 @@
pkgname=(libvirt libvirt-storage-gluster libvirt-storage-iscsi-direct)
epoch=1
pkgver=6.5.0
pkgrel=3
pkgver=7.0.0
pkgrel=2
pkgdesc="API for controlling virtualization engines (openvz,kvm,qemu,virtualbox,xen,etc)"
arch=('x86_64')
url="https://libvirt.org/"
license=('LGPL' 'GPL3') #libvirt_parthelper links to libparted which is GPL3 only
install=libvirt.install
depends=('libpciaccess' 'yajl' 'fuse2' 'gnutls' 'parted' 'libssh' 'libxml2' 'numactl' 'polkit')
makedepends=('libxslt' 'python-docutils' 'lvm2' 'open-iscsi' 'libiscsi' 'glusterfs'
makedepends=('meson' 'libxslt' 'python-docutils' 'lvm2' 'open-iscsi' 'libiscsi' 'glusterfs'
'bash-completion' 'rpcsvc-proto' 'dnsmasq' 'iproute2')
checkdepends=('ebtables')
optdepends=('libvirt-storage-gluster: Gluster storage backend'
@ -51,8 +51,12 @@ backup=(
'etc/libvirt/lxc.conf'
'etc/libvirt/nwfilter/allow-arp.xml'
'etc/libvirt/nwfilter/allow-dhcp-server.xml'
'etc/libvirt/nwfilter/allow-dhcpv6-server.xml'
'etc/libvirt/nwfilter/allow-dhcp.xml'
'etc/libvirt/nwfilter/allow-dhcpv6.xml'
'etc/libvirt/nwfilter/allow-incoming-ipv4.xml'
'etc/libvirt/nwfilter/allow-incoming-ipv6.xml'
'etc/libvirt/nwfilter/allow-ipv6.xml'
'etc/libvirt/nwfilter/allow-ipv4.xml'
'etc/libvirt/nwfilter/clean-traffic-gateway.xml'
'etc/libvirt/nwfilter/clean-traffic.xml'
@ -60,9 +64,11 @@ backup=(
'etc/libvirt/nwfilter/no-arp-mac-spoofing.xml'
'etc/libvirt/nwfilter/no-arp-spoofing.xml'
'etc/libvirt/nwfilter/no-ip-multicast.xml'
'etc/libvirt/nwfilter/no-ipv6-multicast.xml'
'etc/libvirt/nwfilter/no-ip-spoofing.xml'
'etc/libvirt/nwfilter/no-mac-broadcast.xml'
'etc/libvirt/nwfilter/no-ipv6-spoofing.xml'
'etc/libvirt/nwfilter/no-mac-spoofing.xml'
'etc/libvirt/nwfilter/no-mac-broadcast.xml'
'etc/libvirt/nwfilter/no-other-l2-traffic.xml'
'etc/libvirt/nwfilter/no-other-rarp-traffic.xml'
'etc/libvirt/nwfilter/qemu-announce-self-rarp.xml'
@ -89,18 +95,15 @@ backup=(
'etc/sasl2/libvirt.conf'
)
source=("https://libvirt.org/sources/$pkgname-$pkgver.tar.xz"{,.asc}
"CVE-2020-14339.patch")
sha256sums=('4915d9eab299ed79288d7598b717c587156708c05f701fe55a72293f32eb3182'
"find_programs.ini")
sha256sums=('ca3833844d08c22867f1d1a46edc36bda7d6fe1a4f267e7d77100b79fc9ddd89'
'SKIP'
'af90e325ae5f6f3f946695a8900ef2ea8cd579da61c608d69c4c550a8bc1b9db')
validpgpkeys=('C74415BA7C9C7F78F02E1DC34606B8A5DE95BC1F') # Daniel Veillard <veillard@redhat.com>
'735ac805fbf06021418f82297845babf481d5681bd939a6994fbdf36fe1661e4')
validpgpkeys=('453B65310595562855471199CA68BE8010084C9C') # Jiří Denemark <jdenemar@redhat.com>
prepare() {
mkdir build
cd "$pkgname-$pkgver"
patch -Np1 -i "${srcdir}/CVE-2020-14339.patch"
sed -i 's|/sysconfig/|/conf.d/|g' \
src/remote/libvirtd.service.in \
tools/{libvirt-guests.service,libvirt-guests.sh,virt-pki-validate}.in \
@ -114,27 +117,44 @@ prepare() {
}
build() {
cd build
ZFS=/usr/bin/zfs ZPOOL=/usr/bin/zpool \
"../$pkgname-$pkgver/configure" \
--prefix=/usr \
"--libexec=/usr/lib/$pkgname" \
--sbindir=/usr/bin \
--with-runstatedir=/run \
--with-qemu-group=kvm
sed -i -e 's/ -shared / -Wl,-O1,--as-needed\0/g' libtool
make
cd "$pkgname-$pkgver"
arch-meson build \
--libexecdir=lib/libvirt \
--native-file "$srcdir"/find_programs.ini \
-Drunstatedir=/run \
-Dqemu_group=kvm \
-Dnetcf=disabled \
-Dopenwsman=disabled \
-Dapparmor=disabled \
-Dselinux=disabled \
-Dwireshark_dissector=disabled \
-Ddriver_bhyve=disabled \
-Ddriver_hyperv=disabled \
-Ddriver_libxl=disabled \
-Ddriver_vz=disabled \
-Dsecdriver_apparmor=disabled \
-Dsecdriver_selinux=disabled \
-Dstorage_sheepdog=disabled \
-Dstorage_vstorage=disabled \
-Ddtrace=disabled \
-Dnumad=disabled \
-Dstorage_zfs=enabled \
-Dstorage_rbd=disabled
ninja -C build
}
check() {
cd build
make check
cd "$pkgname-$pkgver"
ninja -C build test
}
package_libvirt() {
provides=("libvirt=$pkgver" 'libvirt.so' 'libvirt-admin.so' 'libvirt-lxc.so' 'libvirt-qemu.so')
cd build
make DESTDIR="$pkgdir" install
cd "$pkgname-$pkgver"
DESTDIR="$pkgdir" ninja -C build install
mv "$pkgdir"/etc/{sysconfig,conf.d}
mkdir "$pkgdir"/usr/lib/{sysusers,tmpfiles}.d
@ -158,7 +178,7 @@ package_libvirt() {
rm -f "$pkgdir/etc/libvirt/qemu/networks/autostart/default.xml"
# move split modules
mv "$pkgdir"/usr/lib/libvirt/storage-backend/libvirt_storage_backend_gluster.so "$pkgdir/../"
mv "$pkgdir"/usr/lib/libvirt/storage-backend/libvirt_storage_backend_{rbd,gluster}.so "$pkgdir/../"
mv "$pkgdir/usr/lib/libvirt/storage-backend/libvirt_storage_backend_iscsi-direct.so" "$pkgdir/../"
mv "$pkgdir/usr/lib/libvirt/storage-file/libvirt_storage_file_gluster.so" "$pkgdir/../"
}

View file

@ -0,0 +1,5 @@
[binaries]
# these don't exist in the official repos, but if users get them some other
# way then this is the expected path for them
zfs = '/usr/bin/zfs'
zpool = '/usr/bin/zpool'