Update to 0.8.2 release. Fix CVE-2010-2237, CVE-2010-2238, CVE-2010-2239, CVE-2010-2242

This commit is contained in:
Daniel P. Berrange 2010-07-12 14:13:51 +00:00
parent 96c8a1c6b6
commit 14695477a0
54 changed files with 4697 additions and 7233 deletions

View File

@ -3,11 +3,3 @@
i686
x86_64
libvirt-*.tar.gz
libvirt-0.6.0.tar.gz
libvirt-0.6.1.tar.gz
libvirt-0.6.2.tar.gz
libvirt-0.6.3.tar.gz
libvirt-0.6.4.tar.gz
libvirt-0.6.5.tar.gz
libvirt-0.7.0.tar.gz
libvirt-0.7.1.tar.gz

View File

@ -1,122 +0,0 @@
diff -rup libvirt-0.7.1/qemud/libvirtd.init.in audio/qemud/libvirtd.init.in
--- libvirt-0.7.1/qemud/libvirtd.init.in 2009-07-22 09:37:32.000000000 -0400
+++ audio/qemud/libvirtd.init.in 2010-05-26 12:05:50.584822000 -0400
@@ -47,6 +47,9 @@ KRB5_KTNAME=/etc/libvirt/krb5.tab
test -f @sysconfdir@/sysconfig/libvirtd && . @sysconfdir@/sysconfig/libvirtd
+export QEMU_AUDIO_DRV
+export SDL_AUDIODRIVER
+
LIBVIRTD_CONFIG_ARGS=
if [ -n "$LIBVIRTD_CONFIG" ]
then
diff -rup libvirt-0.7.1/qemud/libvirtd_qemu.aug audio/qemud/libvirtd_qemu.aug
--- libvirt-0.7.1/qemud/libvirtd_qemu.aug 2009-09-08 10:16:02.000000000 -0400
+++ audio/qemud/libvirtd_qemu.aug 2010-05-26 12:07:24.169216000 -0400
@@ -36,6 +36,7 @@ module Libvirtd_qemu =
| str_array_entry "cgroup_device_acl"
| str_entry "save_image_format"
| str_entry "hugetlbfs_mount"
+ | bool_entry "vnc_allow_host_audio"
(* Each enty in the config is one of the following three ... *)
let entry = vnc_entry
diff -rup libvirt-0.7.1/qemud/libvirtd.sysconf audio/qemud/libvirtd.sysconf
--- libvirt-0.7.1/qemud/libvirtd.sysconf 2010-05-26 12:04:08.379130000 -0400
+++ audio/qemud/libvirtd.sysconf 2010-05-26 12:10:28.263486000 -0400
@@ -11,7 +11,8 @@
# Override the QEMU/SDL default audio driver probing when
# starting virtual machines using SDL graphics
#
-# NB these have no effect for VMs using VNC
+# NB these have no effect for VMs using VNC, unless vnc_allow_host_audio
+# is enabled in /etc/libvirt/qemu.conf
#QEMU_AUDIO_DRV=sdl
#
#SDL_AUDIODRIVER=pulse
diff -rup libvirt-0.7.1/qemud/test_libvirtd_qemu.aug audio/qemud/test_libvirtd_qemu.aug
--- libvirt-0.7.1/qemud/test_libvirtd_qemu.aug 2009-09-08 10:16:02.000000000 -0400
+++ audio/qemud/test_libvirtd_qemu.aug 2010-05-26 12:11:19.540907000 -0400
@@ -92,6 +92,8 @@ cgroup_device_acl = [ \"/dev/null\", \"/
save_image_format = \"gzip\"
+vnc_allow_host_audio = 1
+
hugetlbfs_mount = \"/dev/hugepages\"
"
@@ -195,4 +197,6 @@ hugetlbfs_mount = \"/dev/hugepages\"
{ "#empty" }
{ "save_image_format" = "gzip" }
{ "#empty" }
-{ "hugetlbfs_mount" = "/dev/hugepages" }
\ No newline at end of file
+{ "hugetlbfs_mount" = "/dev/hugepages" }
+{ "#empty" }
+{ "vnc_allow_host_audio" = "1" }
diff -rup libvirt-0.7.1/src/qemu.conf audio/src/qemu.conf
--- libvirt-0.7.1/src/qemu.conf 2009-09-10 05:15:56.000000000 -0400
+++ audio/src/qemu.conf 2010-05-26 12:08:12.419811000 -0400
@@ -152,3 +152,13 @@
# in a location of $MOUNTPOINT/libvirt/qemu
# hugetlbfs_mount = "/dev/hugepages"
+#
+
+# QEMU implements an extension for providing audio over a VNC connection,
+# though if your VNC client does not support it, your only chance for getting
+# sound output is through regular audio backends. By default, libvirt will
+# disable all QEMU sound backends if using VNC, since they can cause
+# permissions issues. Enabling this option will make libvirtd honor the
+# QEMU_AUDIO_DRV environment variable when using VNC.
+#
+# vnc_allow_host_audio = 0
diff -rup libvirt-0.7.1/src/qemu_conf.c audio/src/qemu_conf.c
--- libvirt-0.7.1/src/qemu_conf.c 2010-05-26 12:04:08.578062000 -0400
+++ audio/src/qemu_conf.c 2010-05-26 12:09:31.174206000 -0400
@@ -318,6 +318,10 @@ int qemudLoadDriverConfig(struct qemud_d
}
}
+ p = virConfGetValue (conf, "vnc_allow_host_audio");
+ CHECK_TYPE ("vnc_allow_host_audio", VIR_CONF_LONG);
+ if (p) driver->vncAllowHostAudio = p->l;
+
virConfFree (conf);
return 0;
}
@@ -2113,12 +2117,15 @@ int qemudBuildCommandLine(virConnectPtr
ADD_ARG_LIT(def->graphics[0]->data.vnc.keymap);
}
- /* QEMU implements a VNC extension for providing audio, so we
- * set the audio backend to none, to prevent it opening the
- * host OS audio devices since that causes security issues
- * and is non-sensical when using VNC.
+ /* Unless user requested it, set the audio backend to none, to
+ * prevent it opening the host OS audio devices, since that causes
+ * security issues and might not work when using VNC.
*/
- ADD_ENV_LIT("QEMU_AUDIO_DRV=none");
+ if (driver->vncAllowHostAudio) {
+ ADD_ENV_COPY("QEMU_AUDIO_DRV");
+ } else {
+ ADD_ENV_LIT("QEMU_AUDIO_DRV=none");
+ }
} else if ((def->ngraphics == 1) &&
def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
char *xauth = NULL;
diff -rup libvirt-0.7.1/src/qemu_conf.h audio/src/qemu_conf.h
--- libvirt-0.7.1/src/qemu_conf.h 2009-09-10 09:45:00.000000000 -0400
+++ audio/src/qemu_conf.h 2010-05-26 12:10:07.196992000 -0400
@@ -110,6 +110,8 @@ struct qemud_driver {
char *hugetlbfs_mount;
char *hugepage_path;
+ unsigned int vncAllowHostAudio : 1;
+
virCapsPtr caps;
/* An array of callbacks */

View File

@ -1,99 +0,0 @@
--- libvirt-0.7.1/src/qemu_driver.c 2010-06-17 11:30:54.501983000 -0400
+++ new/src/qemu_driver.c 2010-06-17 11:20:13.032900000 -0400
@@ -69,7 +69,7 @@
#include "hostusb.h"
#include "security.h"
#include "cgroup.h"
-
+#include "storage_file.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -1895,6 +1895,7 @@ static int qemuDomainSetDeviceOwnership(
{
uid_t uid;
gid_t gid;
+ const char *path;
if (!driver->privileged)
return 0;
@@ -1912,6 +1913,35 @@ static int qemuDomainSetDeviceOwnership(
(def->data.disk->readonly || def->data.disk->shared))
return 0;
+ if (!def->data.disk->src)
+ return 0;
+
+ path = def->data.disk->src;
+ do {
+ virStorageFileMetadata meta;
+ int ret;
+
+ memset(&meta, 0, sizeof(meta));
+
+ ret = virStorageFileGetMetadata(conn, path, &meta);
+
+ if (path != def->data.disk->src)
+ VIR_FREE(path);
+ path = NULL;
+
+ if (ret < 0)
+ return -1;
+
+ if (meta.backingStore != NULL &&
+ qemuDomainSetFileOwnership(conn,
+ meta.backingStore, uid, gid) < 0) {
+ VIR_FREE(meta.backingStore);
+ return -1;
+ }
+
+ path = meta.backingStore;
+ } while (path != NULL);
+
return qemuDomainSetFileOwnership(conn, def->data.disk->src, uid, gid);
case VIR_DOMAIN_DEVICE_HOSTDEV:
@@ -1929,6 +1959,7 @@ static int qemuDomainSetAllDeviceOwnersh
int i;
uid_t uid;
gid_t gid;
+ const char *path;
if (!driver->privileged)
return 0;
@@ -1949,6 +1980,35 @@ static int qemuDomainSetAllDeviceOwnersh
(def->disks[i]->readonly || def->disks[i]->shared))
continue;
+ if (!def->disks[i]->src)
+ continue;
+
+ path = def->disks[i]->src;
+ do {
+ virStorageFileMetadata meta;
+ int ret;
+
+ memset(&meta, 0, sizeof(meta));
+
+ ret = virStorageFileGetMetadata(conn, path, &meta);
+
+ if (path != def->disks[i]->src)
+ VIR_FREE(path);
+ path = NULL;
+
+ if (ret < 0)
+ return -1;
+
+ if (meta.backingStore != NULL &&
+ qemuDomainSetFileOwnership(conn,
+ meta.backingStore, uid, gid) < 0) {
+ VIR_FREE(meta.backingStore);
+ return -1;
+ }
+
+ path = meta.backingStore;
+ } while (path != NULL);
+
if (qemuDomainSetFileOwnership(conn, def->disks[i]->src, uid, gid) < 0)
return -1;
}

View File

@ -1,82 +0,0 @@
diff -rup libvirt-0.7.1/src/qemu.conf new/src/qemu.conf
--- libvirt-0.7.1/src/qemu.conf 2010-06-03 15:01:14.288848000 -0400
+++ new/src/qemu.conf 2010-06-03 15:04:05.062031000 -0400
@@ -162,3 +162,12 @@
# QEMU_AUDIO_DRV environment variable when using VNC.
#
# vnc_allow_host_audio = 0
+
+# If clear_emulator_capabilities is enabled, libvirt will drop all
+# privileged capabilities of the QEmu/KVM emulator. This is enabled by
+# default.
+#
+# Warning: Disabling this option means that a compromised guest can
+# exploit the privileges and possibly do damage to the host.
+#
+# clear_emulator_capabilities = 1
diff -rup libvirt-0.7.1/src/qemu_conf.c new/src/qemu_conf.c
--- libvirt-0.7.1/src/qemu_conf.c 2010-06-03 15:01:14.302852000 -0400
+++ new/src/qemu_conf.c 2010-06-03 15:05:09.755183000 -0400
@@ -98,7 +98,9 @@ int qemudLoadDriverConfig(struct qemud_d
char *group;
int i;
- /* Setup 2 critical defaults */
+ /* Setup critical defaults */
+ driver->clearEmulatorCapabilities = 1;
+
if (!(driver->vncListen = strdup("127.0.0.1"))) {
virReportOOMError(NULL);
return -1;
@@ -322,6 +324,10 @@ int qemudLoadDriverConfig(struct qemud_d
CHECK_TYPE ("vnc_allow_host_audio", VIR_CONF_LONG);
if (p) driver->vncAllowHostAudio = p->l;
+ p = virConfGetValue (conf, "clear_emulator_capabilities");
+ CHECK_TYPE ("clear_emulator_capabilities", VIR_CONF_LONG);
+ if (p) driver->clearEmulatorCapabilities = p->l;
+
virConfFree (conf);
return 0;
}
diff -rup libvirt-0.7.1/src/qemu_conf.h new/src/qemu_conf.h
--- libvirt-0.7.1/src/qemu_conf.h 2010-06-03 15:01:14.306860000 -0400
+++ new/src/qemu_conf.h 2010-06-03 15:05:27.968796000 -0400
@@ -111,6 +111,7 @@ struct qemud_driver {
char *hugepage_path;
unsigned int vncAllowHostAudio : 1;
+ unsigned int clearEmulatorCapabilities : 1;
virCapsPtr caps;
diff -rup libvirt-0.7.1/src/qemu_driver.c new/src/qemu_driver.c
--- libvirt-0.7.1/src/qemu_driver.c 2010-06-03 15:01:14.413848000 -0400
+++ new/src/qemu_driver.c 2010-06-03 15:06:08.186798000 -0400
@@ -2063,7 +2063,7 @@ static int qemudStartVMDaemon(virConnect
int stdin_fd) {
const char **argv = NULL, **tmp;
const char **progenv = NULL;
- int i, ret;
+ int i, ret, runflags;
struct stat sb;
int *tapfds = NULL;
int ntapfds = 0;
@@ -2205,9 +2205,16 @@ static int qemudStartVMDaemon(virConnect
for (i = 0 ; i < ntapfds ; i++)
FD_SET(tapfds[i], &keepfd);
+ VIR_DEBUG("Clear emulator capabilities: %d",
+ driver->clearEmulatorCapabilities);
+ runflags = VIR_EXEC_NONBLOCK;
+ if (driver->clearEmulatorCapabilities) {
+ runflags |= VIR_EXEC_CLEAR_CAPS;
+ }
+
ret = virExecDaemonize(conn, argv, progenv, &keepfd, &child,
stdin_fd, &logfile, &logfile,
- VIR_EXEC_NONBLOCK | VIR_EXEC_CLEAR_CAPS,
+ runflags,
qemudSecurityHook, &hookData,
pidfile);
VIR_FREE(pidfile);

View File

@ -1,12 +0,0 @@
diff -rup libvirt-0.7.1/src/qemu_driver.c new/src/qemu_driver.c
--- libvirt-0.7.1/src/qemu_driver.c 2010-06-03 13:51:14.398483000 -0400
+++ new/src/qemu_driver.c 2010-06-03 13:56:05.667092000 -0400
@@ -5988,7 +5988,7 @@ static int qemudDomainAttachDevice(virDo
virDomainDiskDeviceTypeToString(dev->data.disk->device));
/* Fallthrough */
}
- if (ret != 0) {
+ if (ret != 0 && cgroup) {
virCgroupDenyDevicePath(cgroup,
dev->data.disk->src);
}

View File

@ -1,267 +0,0 @@
commit bc0010b3d149df00406b82c37eb59874d8525af4
Author: Daniel P. Berrange <berrange@redhat.com>
Date: Wed Nov 11 12:07:00 2009 +0000
Fix save and restore with non-privileged guests and SELinux
When running qemu:///system instance, libvirtd runs as root,
but QEMU may optionally be configured to run non-root. When
then saving a guest to a state file, the file is initially
created as root, and thus QEMU cannot write to it. It is also
missing labelling required to allow access via SELinux.
* src/qemu_driver.c: Set ownership on save image before
running migrate command in virDomainSave impl. Call out to
security driver to set save image labelling
* src/security.h: Add driver APIs for setting
and restoring saved state file labelling
* src/security_selinux.c: Implement saved state file
labelling for SELinux
diff --git a/src/security.h b/src/security.h
index fde2978..5514962 100644
--- a/src/security.h
+++ b/src/security.h
@@ -42,6 +42,11 @@ typedef int (*virSecurityDomainRestoreHostdevLabel) (virConnectPtr conn,
typedef int (*virSecurityDomainSetHostdevLabel) (virConnectPtr conn,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev);
+typedef int (*virSecurityDomainSetSavedStateLabel) (virConnectPtr conn,
+ virDomainObjPtr vm,
+ const char *savefile);
+typedef int (*virSecurityDomainRestoreSavedStateLabel) (virConnectPtr conn,
+ const char *savefile);
typedef int (*virSecurityDomainGenLabel) (virConnectPtr conn,
virDomainObjPtr sec);
typedef int (*virSecurityDomainReserveLabel) (virConnectPtr conn,
@@ -71,6 +76,8 @@ struct _virSecurityDriver {
virSecurityDomainRestoreLabel domainRestoreSecurityLabel;
virSecurityDomainRestoreHostdevLabel domainRestoreSecurityHostdevLabel;
virSecurityDomainSetHostdevLabel domainSetSecurityHostdevLabel;
+ virSecurityDomainSetSavedStateLabel domainSetSavedStateLabel;
+ virSecurityDomainRestoreSavedStateLabel domainRestoreSavedStateLabel;
/*
* This is internally managed driver state and should only be accessed
diff --git a/src/security_selinux.c b/src/security_selinux.c
index 0e31077..bd838e6 100644
--- a/src/security_selinux.c
+++ b/src/security_selinux.c
@@ -523,6 +523,7 @@ done:
return ret;
}
+
static int
SELinuxRestoreSecurityPCILabel(virConnectPtr conn,
pciDevice *dev ATTRIBUTE_UNUSED,
@@ -623,6 +624,26 @@ SELinuxRestoreSecurityLabel(virConnectPtr conn,
return rc;
}
+
+static int
+SELinuxSetSavedStateLabel(virConnectPtr conn,
+ virDomainObjPtr vm,
+ const char *savefile)
+{
+ const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+
+ return SELinuxSetFilecon(conn, savefile, secdef->imagelabel);
+}
+
+
+static int
+SELinuxRestoreSavedStateLabel(virConnectPtr conn,
+ const char *savefile)
+{
+ return SELinuxRestoreSecurityFileLabel(conn, savefile);
+}
+
+
static int
SELinuxSecurityVerify(virConnectPtr conn, virDomainDefPtr def)
{
@@ -692,4 +713,6 @@ virSecurityDriver virSELinuxSecurityDriver = {
.domainSetSecurityLabel = SELinuxSetSecurityLabel,
.domainSetSecurityHostdevLabel = SELinuxSetSecurityHostdevLabel,
.domainRestoreSecurityHostdevLabel = SELinuxRestoreSecurityHostdevLabel,
+ .domainSetSavedStateLabel = SELinuxSetSavedStateLabel,
+ .domainRestoreSavedStateLabel = SELinuxRestoreSavedStateLabel,
};
diff -rup libvirt-0.7.1/src/qemu_driver.c new/src/qemu_driver.c
--- libvirt-0.7.1/src/qemu_driver.c 2010-05-17 16:28:38.243890000 -0400
+++ new/src/qemu_driver.c 2010-05-17 16:36:28.035091000 -0400
@@ -3907,6 +3907,20 @@ static int qemudDomainSave(virDomainPtr
}
fd = -1;
+ if (driver->privileged &&
+ chown(path, driver->user, driver->group) < 0) {
+ virReportSystemError(NULL, errno,
+ _("unable to set ownership of '%s' to user %d:%d"),
+ path, driver->user, driver->group);
+ goto cleanup;
+ }
+
+ if (driver->securityDriver &&
+ driver->securityDriver->domainSetSavedStateLabel &&
+ driver->securityDriver->domainSetSavedStateLabel(dom->conn, vm, path) == -1)
+ goto cleanup;
+
+
/* Migrate to file */
safe_path = qemudEscapeShellArg(path);
if (!safe_path) {
@@ -3956,6 +3970,20 @@ static int qemudDomainSave(virDomainPtr
goto cleanup;
}
+ if (driver->privileged &&
+ chown(path, 0, 0) < 0) {
+ virReportSystemError(NULL, errno,
+ _("unable to set ownership of '%s' to user %d:%d"),
+ path, 0, 0);
+ goto cleanup;
+ }
+
+ if (driver->securityDriver &&
+ driver->securityDriver->domainRestoreSavedStateLabel &&
+ driver->securityDriver->domainRestoreSavedStateLabel(dom->conn, path) == -1)
+ VIR_WARN("failed to restore save state label on %s", path);
+
+
/* Shut it down */
qemudShutdownVMDaemon(dom->conn, driver, vm);
event = virDomainEventNewFromObj(vm,
diff -rup libvirt-0.7.1/src/qemu_driver.c new/src/qemu_driver.c
--- libvirt-0.7.1/src/qemu_driver.c 2010-05-17 17:55:34.000000000 -0400
+++ new/src/qemu_driver.c 2010-05-18 11:45:29.903145000 -0400
@@ -4028,7 +4028,7 @@ static int qemudDomainSave(virDomainPtr
if (driver->securityDriver &&
driver->securityDriver->domainRestoreSavedStateLabel &&
- driver->securityDriver->domainRestoreSavedStateLabel(dom->conn, path) == -1)
+ driver->securityDriver->domainRestoreSavedStateLabel(dom->conn, vm, path) == -1)
VIR_WARN("failed to restore save state label on %s", path);
@@ -4616,6 +4616,11 @@ static int qemudDomainRestore(virConnect
}
def = NULL;
+ if (driver->securityDriver &&
+ driver->securityDriver->domainSetSavedStateLabelRO &&
+ driver->securityDriver->domainSetSavedStateLabelRO(conn, vm, path) == -1)
+ goto cleanup;
+
if (header.version == 2) {
const char *intermediate_argv[3] = { NULL, "-dc", NULL };
const char *prog = qemudSaveCompressionTypeToString(header.compressed);
@@ -4651,11 +4656,6 @@ static int qemudDomainRestore(virConnect
close(fd);
fd = -1;
if (ret < 0) {
- if (!vm->persistent) {
- virDomainRemoveInactive(&driver->domains,
- vm);
- vm = NULL;
- }
goto cleanup;
}
@@ -4677,6 +4677,19 @@ static int qemudDomainRestore(virConnect
ret = 0;
cleanup:
+ if (ret < 0) {
+ if (!vm->persistent) {
+ virDomainRemoveInactive(&driver->domains,
+ vm);
+ vm = NULL;
+ }
+ }
+
+ if (driver->securityDriver &&
+ driver->securityDriver->domainRestoreSavedStateLabel &&
+ driver->securityDriver->domainRestoreSavedStateLabel(conn, vm, path) == -1)
+ VIR_WARN("Unable to restore labelling on %s", path);
+
virDomainDefFree(def);
VIR_FREE(xml);
if (fd != -1)
diff -rup libvirt-0.7.1/src/security.h new/src/security.h
--- libvirt-0.7.1/src/security.h 2010-05-17 17:55:34.000000000 -0400
+++ new/src/security.h 2010-05-18 11:41:27.703746000 -0400
@@ -44,7 +44,11 @@ typedef int (*virSecurityDomainSetHostde
typedef int (*virSecurityDomainSetSavedStateLabel) (virConnectPtr conn,
virDomainObjPtr vm,
const char *savefile);
+typedef int (*virSecurityDomainSetSavedStateLabelRO) (virConnectPtr conn,
+ virDomainObjPtr vm,
+ const char *savefile);
typedef int (*virSecurityDomainRestoreSavedStateLabel) (virConnectPtr conn,
+ virDomainObjPtr vm,
const char *savefile);
typedef int (*virSecurityDomainGenLabel) (virConnectPtr conn,
virDomainObjPtr sec);
@@ -76,6 +80,7 @@ struct _virSecurityDriver {
virSecurityDomainRestoreHostdevLabel domainRestoreSecurityHostdevLabel;
virSecurityDomainSetHostdevLabel domainSetSecurityHostdevLabel;
virSecurityDomainSetSavedStateLabel domainSetSavedStateLabel;
+ virSecurityDomainSetSavedStateLabelRO domainSetSavedStateLabelRO;
virSecurityDomainRestoreSavedStateLabel domainRestoreSavedStateLabel;
/*
diff -rup libvirt-0.7.1/src/security_selinux.c new/src/security_selinux.c
--- libvirt-0.7.1/src/security_selinux.c 2010-05-17 17:55:34.000000000 -0400
+++ new/src/security_selinux.c 2010-05-18 11:49:24.542106000 -0400
@@ -364,12 +364,20 @@ SELinuxRestoreSecurityFileLabel(virConne
goto err;
}
- if (stat(newpath, &buf) != 0)
+ if (stat(newpath, &buf) != 0) {
+ virReportSystemError(conn, err,
+ _("cannot stat %s"), newpath);
goto err;
+ }
- if (matchpathcon(newpath, buf.st_mode, &fcon) == 0) {
- rc = SELinuxSetFilecon(conn, newpath, fcon);
+ if (matchpathcon(newpath, buf.st_mode, &fcon) != 0) {
+ virReportSystemError(conn, err,
+ _("failed to determine default context for %s"), newpath);
+ goto err;
}
+
+ rc = SELinuxSetFilecon(conn, newpath, fcon);
+
err:
VIR_FREE(fcon);
VIR_FREE(newpath);
@@ -632,7 +640,17 @@ SELinuxSetSavedStateLabel(virConnectPtr
static int
+SELinuxSetSavedStateLabelRO(virConnectPtr conn,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ const char *savefile)
+{
+ return SELinuxSetFilecon(conn, savefile, default_content_context);
+}
+
+
+static int
SELinuxRestoreSavedStateLabel(virConnectPtr conn,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
const char *savefile)
{
return SELinuxRestoreSecurityFileLabel(conn, savefile);
@@ -709,5 +727,6 @@ virSecurityDriver virSELinuxSecurityDriv
.domainSetSecurityHostdevLabel = SELinuxSetSecurityHostdevLabel,
.domainRestoreSecurityHostdevLabel = SELinuxRestoreSecurityHostdevLabel,
.domainSetSavedStateLabel = SELinuxSetSavedStateLabel,
+ .domainSetSavedStateLabelRO = SELinuxSetSavedStateLabelRO,
.domainRestoreSavedStateLabel = SELinuxRestoreSavedStateLabel,
};

View File

@ -1,22 +0,0 @@
commit 823a684f8d0495bd5e7b413e1a81fd5a600abef7
Author: Daniel P. Berrange <berrange@redhat.com>
Date: Thu Feb 11 14:39:13 2010 +0000
Fix USB device path formatting mixup
* src/util/hostusb.c: The device path for a USB device wants the
bus/device IDs in decimal not octal
diff --git a/src/util/hostusb.c b/src/util/hostusb.c
index 3cce66b..bf96539 100644
--- a/src/hostusb.c
+++ b/src/hostusb.c
@@ -184,7 +184,7 @@ usbGetDevice(unsigned bus,
snprintf(dev->name, sizeof(dev->name), "%.3o:%.3o",
dev->bus, dev->dev);
snprintf(dev->path, sizeof(dev->path),
- USB_DEVFS "%03o/%03o", dev->bus, dev->dev);
+ USB_DEVFS "%03d/%03d", dev->bus, dev->dev);
/* XXX fixme. this should be product/vendor */
snprintf(dev->id, sizeof(dev->id), "%d %d", dev->bus, dev->dev);

View File

@ -1,13 +0,0 @@
Only in new: qemu_driver.c
diff -rup libvirt-0.7.1/src/hostusb.c new/src/hostusb.c
--- libvirt-0.7.1/src/hostusb.c 2010-06-03 13:51:14.392459000 -0400
+++ new/src/hostusb.c 2010-06-03 14:49:11.763379000 -0400
@@ -123,7 +123,7 @@ static int usbFindBusByVendor(virConnect
char *tmpstr = de->d_name;
unsigned found_bus, found_addr;
- if (STREQ(de->d_name, "usb"))
+ if (STRPREFIX(de->d_name, "usb"))
tmpstr += 3;
if (virStrToLong_ui(tmpstr, &ignore, 10, &found_bus) < 0) {

View File

@ -1,496 +0,0 @@
diff -rup libvirt-0.7.1/src/hostusb.c new/src/hostusb.c
--- libvirt-0.7.1/src/hostusb.c 2010-05-17 16:53:48.740748000 -0400
+++ new/src/hostusb.c 2010-05-17 16:57:19.294731000 -0400
@@ -37,9 +37,10 @@
#include "util.h"
#include "virterror_internal.h"
+#define USB_SYSFS "/sys/bus/usb"
#define USB_DEVFS "/dev/bus/usb/"
-#define USB_ID_LEN 10 /* "XXXX XXXX" */
-#define USB_ADDR_LEN 8 /* "XXX:XXX" */
+#define USB_ID_LEN 10 /* "1234 5678" */
+#define USB_ADDR_LEN 8 /* "123:456" */
struct _usbDevice {
unsigned bus;
@@ -57,6 +58,101 @@ struct _usbDevice {
virReportErrorHelper(conn, VIR_FROM_NONE, code, __FILE__, \
__FUNCTION__, __LINE__, fmt)
+static int usbSysReadFile(virConnectPtr conn,
+ const char *f_name, const char *d_name,
+ int base, unsigned *value)
+{
+ int ret = -1, tmp;
+ char *buf = NULL;
+ char *filename = NULL;
+ char *ignore = NULL;
+
+ tmp = virAsprintf(&filename, USB_SYSFS "/devices/%s/%s", d_name, f_name);
+ if (tmp < 0) {
+ virReportOOMError(conn);
+ goto error;
+ }
+
+ if (virFileReadAll(filename, 1024, &buf) < 0)
+ goto error;
+
+ if (virStrToLong_ui(buf, &ignore, base, value) < 0) {
+ usbReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("Could not parse usb file %s"), filename);
+ goto error;
+ }
+
+ ret = 0;
+error:
+ VIR_FREE(filename);
+ VIR_FREE(buf);
+ return ret;
+}
+
+static int usbFindBusByVendor(virConnectPtr conn,
+ unsigned vendor, unsigned product,
+ unsigned *bus, unsigned *devno)
+{
+ DIR *dir = NULL;
+ int ret = -1, found = 0;
+ char *ignore = NULL;
+ struct dirent *de;
+
+ dir = opendir(USB_SYSFS "/devices");
+ if (!dir) {
+ virReportSystemError(conn, errno,
+ _("Could not open directory %s"),
+ USB_SYSFS "/devices");
+ goto error;
+ }
+
+ while ((de = readdir(dir))) {
+ unsigned found_prod, found_vend;
+ if (de->d_name[0] == '.' || strchr(de->d_name, ':'))
+ continue;
+
+ if (usbSysReadFile(conn, "idVendor", de->d_name,
+ 16, &found_vend) < 0)
+ goto error;
+ if (usbSysReadFile(conn, "idProduct", de->d_name,
+ 16, &found_prod) < 0)
+ goto error;
+
+ if (found_prod == product && found_vend == vendor) {
+ /* Lookup bus.addr info */
+ char *tmpstr = de->d_name;
+ unsigned found_bus, found_addr;
+
+ if (STREQ(de->d_name, "usb"))
+ tmpstr += 3;
+
+ if (virStrToLong_ui(tmpstr, &ignore, 10, &found_bus) < 0) {
+ usbReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("Failed to parse dir name '%s'"),
+ de->d_name);
+ goto error;
+ }
+
+ if (usbSysReadFile(conn, "devnum", de->d_name,
+ 10, &found_addr) < 0)
+ goto error;
+
+ *bus = found_bus;
+ *devno = found_addr;
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found)
+ usbReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("Did not find USB device %x:%x"), vendor, product);
+ else
+ ret = 0;
+
+error:
+ return ret;
+}
usbDevice *
usbGetDevice(virConnectPtr conn,
@@ -86,6 +182,21 @@ usbGetDevice(virConnectPtr conn,
return dev;
}
+
+usbDevice *
+usbFindDevice(unsigned vendor,
+ unsigned product)
+{
+ unsigned bus = 0, devno = 0;
+
+ if (usbFindBusByVendor(vendor, product, &bus, &devno) < 0) {
+ return NULL;
+ }
+
+ return usbGetDevice(bus, devno);
+}
+
+
void
usbFreeDevice(virConnectPtr conn ATTRIBUTE_UNUSED, usbDevice *dev)
{
@@ -93,6 +204,18 @@ usbFreeDevice(virConnectPtr conn ATTRIBU
VIR_FREE(dev);
}
+unsigned usbDeviceGetBus(usbDevice *dev)
+{
+ return dev->bus;
+}
+
+
+unsigned usbDeviceGetDevno(usbDevice *dev)
+{
+ return dev->dev;
+}
+
+
int usbDeviceFileIterate(virConnectPtr conn,
usbDevice *dev,
diff -rup libvirt-0.7.1/src/hostusb.h new/src/hostusb.h
--- libvirt-0.7.1/src/hostusb.h 2009-09-10 09:45:00.000000000 -0400
+++ new/src/hostusb.h 2010-05-17 16:58:06.553924000 -0400
@@ -27,11 +27,16 @@
typedef struct _usbDevice usbDevice;
-usbDevice *usbGetDevice (virConnectPtr conn,
- unsigned bus,
- unsigned devno);
-void usbFreeDevice (virConnectPtr conn,
- usbDevice *dev);
+usbDevice *usbGetDevice(virConnectPtr conn,
+ unsigned bus,
+ unsigned devno);
+usbDevice *usbFindDevice(virConnectPtr conn,
+ unsigned vendor,
+ unsigned product);
+void usbFreeDevice (virConnectPtr conn, usbDevice *dev);
+
+unsigned usbDeviceGetBus(usbDevice *dev);
+unsigned usbDeviceGetDevno(usbDevice *dev);
/*
* Callback that will be invoked once for each file
diff -rup libvirt-0.7.1/src/libvirt_private.syms new/src/libvirt_private.syms
--- libvirt-0.7.1/src/libvirt_private.syms 2010-05-17 16:53:48.401831000 -0400
+++ new/src/libvirt_private.syms 2010-05-17 16:55:03.001748000 -0400
@@ -441,7 +441,10 @@ virFileMatchesNameSuffix;
# usb.h
usbGetDevice;
+usbFindDevice;
usbFreeDevice;
+usbDeviceGetBus;
+usbDeviceGetDevno;
usbDeviceFileIterate;
# uuid.h
diff -rup libvirt-0.7.1/src/qemu_driver.c new/src/qemu_driver.c
--- libvirt-0.7.1/src/qemu_driver.c 2010-05-17 16:53:48.785743000 -0400
+++ new/src/qemu_driver.c 2010-05-17 17:06:40.575145000 -0400
@@ -1493,16 +1493,13 @@ qemuUpdateActivePciHostdevs(struct qemud
}
static int
-qemuPrepareHostDevices(virConnectPtr conn,
- struct qemud_driver *driver,
- virDomainDefPtr def)
+qemuPrepareHostPCIDevices(virConnectPtr conn,
+ struct qemud_driver *driver,
+ virDomainDefPtr def)
{
pciDeviceList *pcidevs;
int i;
- if (!def->nhostdevs)
- return 0;
-
if (!(pcidevs = qemuGetPciHostDeviceList(conn, def)))
return -1;
@@ -1792,14 +1789,11 @@ static int qemuDomainSetHostdevUSBOwners
struct qemuFileOwner owner = { uid, gid };
int ret = -1;
- /* XXX what todo for USB devs assigned based on product/vendor ? Doom :-( */
- if (!def->source.subsys.u.usb.bus ||
- !def->source.subsys.u.usb.device)
- return 0;
-
usbDevice *dev = usbGetDevice(conn,
def->source.subsys.u.usb.bus,
- def->source.subsys.u.usb.device);
+ def->source.subsys.u.usb.device,
+ def->source.subsys.u.usb.vendor,
+ def->source.subsys.u.usb.product);
if (!dev)
goto cleanup;
@@ -2065,13 +2059,17 @@ static int qemudStartVMDaemon(virConnect
return -1;
}
+ DEBUG0("Preparing host devices");
+ if (qemuPrepareHostDevices(conn, driver, vm->def) < 0)
+ goto cleanup;
+
/* If you are using a SecurityDriver with dynamic labelling,
then generate a security label for isolation */
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
driver->securityDriver &&
driver->securityDriver->domainGenSecurityLabel &&
driver->securityDriver->domainGenSecurityLabel(conn, vm) < 0)
- return -1;
+ return cleanup;
/* Ensure no historical cgroup for this VM is lieing around bogus settings */
qemuRemoveCgroup(conn, driver, vm);
@@ -2119,9 +2117,6 @@ static int qemudStartVMDaemon(virConnect
if (qemuSetupCgroup(conn, driver, vm) < 0)
goto cleanup;
- if (qemuPrepareHostDevices(conn, driver, vm->def) < 0)
- goto cleanup;
-
if (VIR_ALLOC(vm->monitor_chr) < 0) {
virReportOOMError(conn);
goto cleanup;
@@ -2348,6 +2343,56 @@ retry:
}
+
+static int
+qemuPrepareHostUSBDevices(struct qemud_driver *driver ATTRIBUTE_UNUSED,
+ virDomainDefPtr def)
+{
+ int i;
+ for (i = 0 ; i < def->nhostdevs ; i++) {
+ virDomainHostdevDefPtr hostdev = def->hostdevs[i];
+
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ continue;
+ if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
+ continue;
+
+ /* Resolve a vendor/product to bus/device */
+ if (hostdev->source.subsys.u.usb.vendor) {
+ usbDevice *usb
+ = usbFindDevice(hostdev->source.subsys.u.usb.vendor,
+ hostdev->source.subsys.u.usb.product);
+
+ if (!usb)
+ return -1;
+
+ hostdev->source.subsys.u.usb.bus = usbDeviceGetBus(usb);
+ hostdev->source.subsys.u.usb.device = usbDeviceGetDevno(usb);
+
+ usbFreeDevice(usb);
+ }
+ }
+
+ return 0;
+}
+
+static int
+qemuPrepareHostDevices(struct qemud_driver *driver,
+ virDomainDefPtr def)
+{
+ if (!def->nhostdevs)
+ return 0;
+
+ if (qemuPrepareHostPCIDevices(driver, def) < 0)
+ return -1;
+
+ if (qemuPrepareHostUSBDevices(driver, def) < 0)
+ return -1;
+
+ return 0;
+}
+
+
static void
qemudDispatchVMEvent(int watch, int fd, int events, void *opaque) {
struct qemud_driver *driver = opaque;
@@ -6294,6 +6339,23 @@ static int qemudDomainDetachHostDevice(v
return -1;
}
+ /* Resolve USB product/vendor to bus/device */
+ if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB &&
+ hostdev->source.subsys.u.usb.vendor) {
+ usbDevice *usb
+ = usbFindDevice(hostdev->source.subsys.u.usb.vendor,
+ hostdev->source.subsys.u.usb.product);
+
+ if (!usb)
+ return -1;
+
+ hostdev->source.subsys.u.usb.bus = usbDeviceGetBus(usb);
+ hostdev->source.subsys.u.usb.device = usbDeviceGetDevno(usb);
+
+ usbFreeDevice(usb);
+ }
+
+
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel(conn, vm, dev->data.hostdev) < 0)
VIR_WARN0("Failed to restore device labelling");
diff -rup libvirt-0.7.1/src/security_selinux.c new/src/security_selinux.c
--- libvirt-0.7.1/src/security_selinux.c 2010-05-17 16:53:48.775745000 -0400
+++ new/src/security_selinux.c 2010-05-17 16:58:47.442604000 -0400
@@ -482,20 +482,15 @@ SELinuxSetSecurityHostdevLabel(virConnec
switch (dev->source.subsys.type) {
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
- if (dev->source.subsys.u.usb.bus && dev->source.subsys.u.usb.device) {
- usbDevice *usb = usbGetDevice(conn,
- dev->source.subsys.u.usb.bus,
- dev->source.subsys.u.usb.device);
-
- if (!usb)
- goto done;
-
- ret = usbDeviceFileIterate(conn, usb, SELinuxSetSecurityUSBLabel, vm);
- usbFreeDevice(conn, usb);
- } else {
- /* XXX deal with product/vendor better */
- ret = 0;
- }
+ usbDevice *usb = usbGetDevice(conn,
+ dev->source.subsys.u.usb.bus,
+ dev->source.subsys.u.usb.device);
+
+ if (!usb)
+ goto done;
+
+ ret = usbDeviceFileIterate(conn, usb, SELinuxSetSecurityUSBLabel, vm);
+ usbFreeDevice(conn, usb);
break;
}
diff -rup libvirt-0.7.1/src/hostusb.c new/src/hostusb.c
--- libvirt-0.7.1/src/hostusb.c 2010-05-17 17:09:02.573638000 -0400
+++ new/src/hostusb.c 2010-05-17 17:29:49.133509000 -0400
@@ -184,16 +184,17 @@ usbGetDevice(virConnectPtr conn,
usbDevice *
-usbFindDevice(unsigned vendor,
+usbFindDevice(virConnectPtr conn,
+ unsigned vendor,
unsigned product)
{
unsigned bus = 0, devno = 0;
- if (usbFindBusByVendor(vendor, product, &bus, &devno) < 0) {
+ if (usbFindBusByVendor(conn, vendor, product, &bus, &devno) < 0) {
return NULL;
}
- return usbGetDevice(bus, devno);
+ return usbGetDevice(conn, bus, devno);
}
diff -rup libvirt-0.7.1/src/qemu_driver.c new/src/qemu_driver.c
--- libvirt-0.7.1/src/qemu_driver.c 2010-05-17 17:09:02.602638000 -0400
+++ new/src/qemu_driver.c 2010-05-17 17:36:10.066214000 -0400
@@ -1791,9 +1791,7 @@ static int qemuDomainSetHostdevUSBOwners
usbDevice *dev = usbGetDevice(conn,
def->source.subsys.u.usb.bus,
- def->source.subsys.u.usb.device,
- def->source.subsys.u.usb.vendor,
- def->source.subsys.u.usb.product);
+ def->source.subsys.u.usb.device);
if (!dev)
goto cleanup;
@@ -2026,6 +2024,10 @@ qemuPrepareMonitorChr(virConnectPtr conn
return 0;
}
+static int
+qemuPrepareHostDevices(struct qemud_driver *driver,
+ virDomainDefPtr def);
+
static int qemudStartVMDaemon(virConnectPtr conn,
struct qemud_driver *driver,
virDomainObjPtr vm,
@@ -2060,7 +2062,7 @@ static int qemudStartVMDaemon(virConnect
}
DEBUG0("Preparing host devices");
- if (qemuPrepareHostDevices(conn, driver, vm->def) < 0)
+ if (qemuPrepareHostDevices(driver, vm->def) < 0)
goto cleanup;
/* If you are using a SecurityDriver with dynamic labelling,
@@ -2069,7 +2071,7 @@ static int qemudStartVMDaemon(virConnect
driver->securityDriver &&
driver->securityDriver->domainGenSecurityLabel &&
driver->securityDriver->domainGenSecurityLabel(conn, vm) < 0)
- return cleanup;
+ goto cleanup;
/* Ensure no historical cgroup for this VM is lieing around bogus settings */
qemuRemoveCgroup(conn, driver, vm);
@@ -2360,7 +2362,8 @@ qemuPrepareHostUSBDevices(struct qemud_d
/* Resolve a vendor/product to bus/device */
if (hostdev->source.subsys.u.usb.vendor) {
usbDevice *usb
- = usbFindDevice(hostdev->source.subsys.u.usb.vendor,
+ = usbFindDevice(NULL,
+ hostdev->source.subsys.u.usb.vendor,
hostdev->source.subsys.u.usb.product);
if (!usb)
@@ -2369,7 +2372,7 @@ qemuPrepareHostUSBDevices(struct qemud_d
hostdev->source.subsys.u.usb.bus = usbDeviceGetBus(usb);
hostdev->source.subsys.u.usb.device = usbDeviceGetDevno(usb);
- usbFreeDevice(usb);
+ usbFreeDevice(NULL, usb);
}
}
@@ -2383,7 +2386,7 @@ qemuPrepareHostDevices(struct qemud_driv
if (!def->nhostdevs)
return 0;
- if (qemuPrepareHostPCIDevices(driver, def) < 0)
+ if (qemuPrepareHostPCIDevices(NULL, driver, def) < 0)
return -1;
if (qemuPrepareHostUSBDevices(driver, def) < 0)
@@ -6343,7 +6346,8 @@ static int qemudDomainDetachHostDevice(v
if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB &&
hostdev->source.subsys.u.usb.vendor) {
usbDevice *usb
- = usbFindDevice(hostdev->source.subsys.u.usb.vendor,
+ = usbFindDevice(NULL,
+ hostdev->source.subsys.u.usb.vendor,
hostdev->source.subsys.u.usb.product);
if (!usb)
@@ -6352,7 +6356,7 @@ static int qemudDomainDetachHostDevice(v
hostdev->source.subsys.u.usb.bus = usbDeviceGetBus(usb);
hostdev->source.subsys.u.usb.device = usbDeviceGetDevno(usb);
- usbFreeDevice(usb);
+ usbFreeDevice(NULL, usb);
}

View File

@ -1,686 +0,0 @@
commit 33a198c1f6a4a1bc7f34d50a31032e03bec10fee
Author: Daniel P. Berrange <berrange@redhat.com>
Date: Fri Jul 17 20:20:08 2009 +0100
Initialize gcrypt threading
GNUTLS uses gcrypt for its crypto functions. gcrypt requires
that the app/library initializes threading before using it.
We don't want to force apps using libvirt to know about
gcrypt, so we make virInitialize init threading on their
behalf. This location also ensures libvirtd has initialized
it correctly. This initialization is required even if libvirt
itself were only using one thread, since another non-libvirt
library (eg GTK-VNC) could also be using gcrypt from another
thread
* src/libvirt.c: Register thread functions for gcrypt
* configure.in: Add -lgcrypt to linker flags
diff --git a/src/libvirt.c b/src/libvirt.c
index 103b331..cad33c2 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -22,6 +22,7 @@
#include <sys/wait.h>
#endif
#include <time.h>
+#include <gcrypt.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>
@@ -251,6 +252,55 @@ winsock_init (void)
}
#endif
+static int virTLSMutexInit (void **priv)
+{ \
+ virMutexPtr lock = NULL;
+
+ if (VIR_ALLOC(lock) < 0)
+ return ENOMEM;
+
+ if (virMutexInit(lock) < 0) {
+ VIR_FREE(lock);
+ return errno;
+ }
+
+ *priv = lock;
+ return 0;
+}
+
+static int virTLSMutexDestroy(void **priv)
+{
+ virMutexPtr lock = *priv;
+ virMutexDestroy(lock);
+ VIR_FREE(lock);
+ return 0;
+}
+
+static int virTLSMutexLock(void **priv)
+{
+ virMutexPtr lock = *priv;
+ virMutexLock(lock);
+ return 0;
+}
+
+static int virTLSMutexUnlock(void **priv)
+{
+ virMutexPtr lock = *priv;
+ virMutexUnlock(lock);
+ return 0;
+}
+
+static struct gcry_thread_cbs virTLSThreadImpl = {
+ (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8)),
+ NULL,
+ virTLSMutexInit,
+ virTLSMutexDestroy,
+ virTLSMutexLock,
+ virTLSMutexUnlock,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+
/**
* virInitialize:
*
@@ -273,6 +323,9 @@ virInitialize(void)
virRandomInitialize(time(NULL) ^ getpid()))
return -1;
+ gcry_control(GCRYCTL_SET_THREAD_CBS, &virTLSThreadImpl);
+ gcry_check_version(NULL);
+
virLogSetFromEnv();
DEBUG0("register drivers");
commit 1c5c63338c90f6e82731f6871901dc72732033ef
Author: Matthias Bolte <matthias.bolte@googlemail.com>
Date: Fri Dec 18 12:02:07 2009 +0100
Fix compilation with gcrypt < 1.4.2
Commit 33a198c1f6a4a1bc7f34d50a31032e03bec10fee increased the gcrypt
version requirement to 1.4.2 because the GCRY_THREAD_OPTION_VERSION
define was added in this version.
The configure script doesn't check for the gcrypt version. To support
gcrypt versions < 1.4.2 change the virTLSThreadImpl initialization
to use GCRY_THREAD_OPTION_VERSION only if it's defined.
diff --git a/src/libvirt.c b/src/libvirt.c
index 5167bc2..16c851f 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -291,7 +291,12 @@ static int virTLSMutexUnlock(void **priv)
}
static struct gcry_thread_cbs virTLSThreadImpl = {
+ /* GCRY_THREAD_OPTION_VERSION was added in gcrypt 1.4.2 */
+#ifdef GCRY_THREAD_OPTION_VERSION
(GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8)),
+#else
+ GCRY_THREAD_OPTION_PTHREAD,
+#endif
NULL,
virTLSMutexInit,
virTLSMutexDestroy,
diff -rup libvirt-0.7.1/aclocal.m4 gcrypt-new/aclocal.m4
--- libvirt-0.7.1/aclocal.m4 2009-09-15 08:35:04.000000000 -0400
+++ gcrypt-new/aclocal.m4 2010-05-17 17:52:13.765215000 -0400
@@ -1,4 +1,4 @@
-# generated automatically by aclocal 1.11 -*- Autoconf -*-
+# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
@@ -190,7 +190,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.11'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.11], [],
+m4_if([$1], [1.11.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -206,7 +206,7 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11])dnl
+[AM_AUTOMAKE_VERSION([1.11.1])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
diff -rup libvirt-0.7.1/configure gcrypt-new/configure
--- libvirt-0.7.1/configure 2009-09-15 08:35:09.000000000 -0400
+++ gcrypt-new/configure 2010-05-17 17:52:18.706838000 -0400
@@ -43324,7 +43324,7 @@ fi
$as_echo "$as_me: error: You must install the GnuTLS library in order to compile and run libvirt" >&2;}
{ (exit 1); exit 1; }; }
- GNUTLS_LIBS=$LIBS
+ GNUTLS_LIBS="$LIBS -lgcrypt"
LIBS="$old_libs"
fi
diff -rup libvirt-0.7.1/docs/devhelp/Makefile.in gcrypt-new/docs/devhelp/Makefile.in
--- libvirt-0.7.1/docs/devhelp/Makefile.in 2009-09-15 08:35:13.000000000 -0400
+++ gcrypt-new/docs/devhelp/Makefile.in 2010-05-17 17:52:23.305455000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
diff -rup libvirt-0.7.1/docs/examples/Makefile.in gcrypt-new/docs/examples/Makefile.in
--- libvirt-0.7.1/docs/examples/Makefile.in 2009-09-15 08:35:14.000000000 -0400
+++ gcrypt-new/docs/examples/Makefile.in 2010-05-17 17:52:23.492454000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -999,7 +999,7 @@ clean-libtool:
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
- @failcom='exit 1'; \
+ @fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
@@ -1024,7 +1024,7 @@ $(RECURSIVE_TARGETS):
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
- @failcom='exit 1'; \
+ @fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
diff -rup libvirt-0.7.1/docs/examples/python/Makefile.in gcrypt-new/docs/examples/python/Makefile.in
--- libvirt-0.7.1/docs/examples/python/Makefile.in 2009-09-15 08:35:14.000000000 -0400
+++ gcrypt-new/docs/examples/python/Makefile.in 2010-05-17 17:52:23.650454000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
diff -rup libvirt-0.7.1/docs/Makefile.in gcrypt-new/docs/Makefile.in
--- libvirt-0.7.1/docs/Makefile.in 2009-09-15 08:35:13.000000000 -0400
+++ gcrypt-new/docs/Makefile.in 2010-05-17 17:52:23.143456000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -966,7 +966,7 @@ clean-libtool:
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
- @failcom='exit 1'; \
+ @fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
@@ -991,7 +991,7 @@ $(RECURSIVE_TARGETS):
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
- @failcom='exit 1'; \
+ @fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
diff -rup libvirt-0.7.1/docs/schemas/Makefile.in gcrypt-new/docs/schemas/Makefile.in
--- libvirt-0.7.1/docs/schemas/Makefile.in 2009-09-15 08:35:14.000000000 -0400
+++ gcrypt-new/docs/schemas/Makefile.in 2010-05-17 17:52:23.807456000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
diff -rup libvirt-0.7.1/examples/domain-events/events-c/Makefile.in gcrypt-new/examples/domain-events/events-c/Makefile.in
--- libvirt-0.7.1/examples/domain-events/events-c/Makefile.in 2009-09-15 08:35:14.000000000 -0400
+++ gcrypt-new/examples/domain-events/events-c/Makefile.in 2010-05-17 17:52:23.983380000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
diff -rup libvirt-0.7.1/examples/hellolibvirt/Makefile.in gcrypt-new/examples/hellolibvirt/Makefile.in
--- libvirt-0.7.1/examples/hellolibvirt/Makefile.in 2009-09-15 08:35:14.000000000 -0400
+++ gcrypt-new/examples/hellolibvirt/Makefile.in 2010-05-17 17:52:24.166378000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
diff -rup libvirt-0.7.1/gnulib/lib/Makefile.in gcrypt-new/gnulib/lib/Makefile.in
--- libvirt-0.7.1/gnulib/lib/Makefile.in 2009-09-15 08:35:14.000000000 -0400
+++ gcrypt-new/gnulib/lib/Makefile.in 2010-05-17 17:52:24.409381000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -1128,7 +1128,7 @@ clean-libtool:
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
- @failcom='exit 1'; \
+ @fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
@@ -1153,7 +1153,7 @@ $(RECURSIVE_TARGETS):
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
- @failcom='exit 1'; \
+ @fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
diff -rup libvirt-0.7.1/gnulib/tests/Makefile.in gcrypt-new/gnulib/tests/Makefile.in
--- libvirt-0.7.1/gnulib/tests/Makefile.in 2009-09-15 08:35:15.000000000 -0400
+++ gcrypt-new/gnulib/tests/Makefile.in 2010-05-17 17:52:24.719382000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -1501,7 +1501,7 @@ clean-libtool:
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
- @failcom='exit 1'; \
+ @fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
@@ -1526,7 +1526,7 @@ $(RECURSIVE_TARGETS):
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
- @failcom='exit 1'; \
+ @fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
diff -rup libvirt-0.7.1/include/libvirt/Makefile.in gcrypt-new/include/libvirt/Makefile.in
--- libvirt-0.7.1/include/libvirt/Makefile.in 2009-09-15 08:35:15.000000000 -0400
+++ gcrypt-new/include/libvirt/Makefile.in 2010-05-17 17:52:25.069302000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
diff -rup libvirt-0.7.1/include/Makefile.in gcrypt-new/include/Makefile.in
--- libvirt-0.7.1/include/Makefile.in 2009-09-15 08:35:15.000000000 -0400
+++ gcrypt-new/include/Makefile.in 2010-05-17 17:52:24.902313000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -896,7 +896,7 @@ clean-libtool:
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
- @failcom='exit 1'; \
+ @fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
@@ -921,7 +921,7 @@ $(RECURSIVE_TARGETS):
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
- @failcom='exit 1'; \
+ @fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
diff -rup libvirt-0.7.1/Makefile.in gcrypt-new/Makefile.in
--- libvirt-0.7.1/Makefile.in 2009-09-15 08:35:18.000000000 -0400
+++ gcrypt-new/Makefile.in 2010-05-17 17:52:28.423082000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -1060,7 +1060,7 @@ uninstall-pkgconfigDATA:
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
- @failcom='exit 1'; \
+ @fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
@@ -1085,7 +1085,7 @@ $(RECURSIVE_TARGETS):
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
- @failcom='exit 1'; \
+ @fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
@@ -1265,7 +1265,8 @@ distdir: $(DISTFILES)
top_distdir="$(top_distdir)" distdir="$(distdir)" \
dist-hook
-test -n "$(am__skip_mode_fix)" \
- || find "$(distdir)" -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+ || find "$(distdir)" -type d ! -perm -755 \
+ -exec chmod u+rwx,go+rx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
@@ -1309,17 +1310,17 @@ dist dist-all: distdir
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
- GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
- bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lzma*) \
- unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
+ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
*.tar.xz*) \
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
- GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
diff -rup libvirt-0.7.1/proxy/Makefile.in gcrypt-new/proxy/Makefile.in
--- libvirt-0.7.1/proxy/Makefile.in 2009-09-15 08:35:15.000000000 -0400
+++ gcrypt-new/proxy/Makefile.in 2010-05-17 17:52:25.334306000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
diff -rup libvirt-0.7.1/python/Makefile.in gcrypt-new/python/Makefile.in
--- libvirt-0.7.1/python/Makefile.in 2009-09-15 08:35:16.000000000 -0400
+++ gcrypt-new/python/Makefile.in 2010-05-17 17:52:25.538302000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -1090,7 +1090,7 @@ clean-libtool:
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
- @failcom='exit 1'; \
+ @fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
@@ -1115,7 +1115,7 @@ $(RECURSIVE_TARGETS):
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
- @failcom='exit 1'; \
+ @fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
diff -rup libvirt-0.7.1/python/tests/Makefile.in gcrypt-new/python/tests/Makefile.in
--- libvirt-0.7.1/python/tests/Makefile.in 2009-09-15 08:35:16.000000000 -0400
+++ gcrypt-new/python/tests/Makefile.in 2010-05-17 17:52:25.702304000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
diff -rup libvirt-0.7.1/qemud/Makefile.in gcrypt-new/qemud/Makefile.in
--- libvirt-0.7.1/qemud/Makefile.in 2009-09-15 08:35:16.000000000 -0400
+++ gcrypt-new/qemud/Makefile.in 2010-05-17 17:52:25.997229000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -1522,7 +1522,7 @@ remote_protocol.c: remote_protocol.h
@WITH_LIBVIRTD_TRUE@ test -e $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart/default.xml || \
@WITH_LIBVIRTD_TRUE@ ln -s ../default.xml \
@WITH_LIBVIRTD_TRUE@ $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart/default.xml
-@WITH_LIBVIRTD_TRUE@ mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/qemu
+@WITH_LIBVIRTD_TRUE@ mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt
@WITH_LIBVIRTD_TRUE@ mkdir -p $(DESTDIR)$(localstatedir)/run/libvirt
@WITH_LIBVIRTD_TRUE@ mkdir -p $(DESTDIR)$(localstatedir)/lib/libvirt
@@ -1530,7 +1530,7 @@ remote_protocol.c: remote_protocol.h
@WITH_LIBVIRTD_TRUE@ rm -f $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart/default.xml
@WITH_LIBVIRTD_TRUE@ rm -f $(DESTDIR)$(sysconfdir)/$(default_xml_dest)
@WITH_LIBVIRTD_TRUE@ rmdir $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart || :
-@WITH_LIBVIRTD_TRUE@ rmdir $(DESTDIR)$(localstatedir)/log/libvirt/qemu || :
+@WITH_LIBVIRTD_TRUE@ rmdir $(DESTDIR)$(localstatedir)/log/libvirt || :
@WITH_LIBVIRTD_TRUE@ rmdir $(DESTDIR)$(localstatedir)/run/libvirt || :
@WITH_LIBVIRTD_TRUE@ rmdir $(DESTDIR)$(localstatedir)/lib/libvirt || :
@@ -1577,6 +1577,8 @@ remote_protocol.c: remote_protocol.h
@WITH_LIBVIRTD_TRUE@install-logrotate: libvirtd.logrotate
@WITH_LIBVIRTD_TRUE@ mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/qemu/
+@WITH_LIBVIRTD_TRUE@ mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/lxc/
+@WITH_LIBVIRTD_TRUE@ mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/uml/
@WITH_LIBVIRTD_TRUE@ mkdir -p $(DESTDIR)$(sysconfdir)/logrotate.d/
@WITH_LIBVIRTD_TRUE@ $(INSTALL_DATA) $< $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd
diff -rup libvirt-0.7.1/src/Makefile.in gcrypt-new/src/Makefile.in
--- libvirt-0.7.1/src/Makefile.in 2009-09-15 08:35:17.000000000 -0400
+++ gcrypt-new/src/Makefile.in 2010-05-17 17:52:26.929151000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -598,9 +598,9 @@ am__objects_45 = libvirt_util_la-bridge.
libvirt_util_la-pci.lo libvirt_util_la-hostusb.lo \
libvirt_util_la-qparams.lo \
libvirt_util_la-storage_encryption_conf.lo \
- libvirt_util_la-threads.lo libvirt_util_la-uuid.lo \
- libvirt_util_la-util.lo libvirt_util_la-virterror.lo \
- libvirt_util_la-xml.lo
+ libvirt_util_la-storage_file.lo libvirt_util_la-threads.lo \
+ libvirt_util_la-uuid.lo libvirt_util_la-util.lo \
+ libvirt_util_la-virterror.lo libvirt_util_la-xml.lo
am_libvirt_util_la_OBJECTS = $(am__objects_45)
libvirt_util_la_OBJECTS = $(am_libvirt_util_la_OBJECTS)
libvirt_util_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
@@ -617,11 +617,11 @@ am__libvirt_lxc_SOURCES_DIST = lxc_conf.
event.h hash.c hash.h iptables.c iptables.h logging.c \
logging.h memory.c memory.h pci.c pci.h hostusb.c hostusb.h \
qparams.c qparams.h storage_encryption_conf.h \
- storage_encryption_conf.c threads.c threads.h \
- threads-pthread.h threads-win32.h uuid.c uuid.h util.c util.h \
- virterror.c virterror_internal.h xml.c xml.h capabilities.c \
- capabilities.h domain_conf.c domain_conf.h nodeinfo.h \
- nodeinfo.c
+ storage_encryption_conf.c storage_file.c storage_file.h \
+ threads.c threads.h threads-pthread.h threads-win32.h uuid.c \
+ uuid.h util.c util.h virterror.c virterror_internal.h xml.c \
+ xml.h capabilities.c capabilities.h domain_conf.c \
+ domain_conf.h nodeinfo.h nodeinfo.c
am__objects_46 = libvirt_lxc-lxc_conf.$(OBJEXT) \
libvirt_lxc-lxc_container.$(OBJEXT) \
libvirt_lxc-lxc_controller.$(OBJEXT) \
@@ -633,6 +633,7 @@ am__objects_47 = libvirt_lxc-bridge.$(OB
libvirt_lxc-memory.$(OBJEXT) libvirt_lxc-pci.$(OBJEXT) \
libvirt_lxc-hostusb.$(OBJEXT) libvirt_lxc-qparams.$(OBJEXT) \
libvirt_lxc-storage_encryption_conf.$(OBJEXT) \
+ libvirt_lxc-storage_file.$(OBJEXT) \
libvirt_lxc-threads.$(OBJEXT) libvirt_lxc-uuid.$(OBJEXT) \
libvirt_lxc-util.$(OBJEXT) libvirt_lxc-virterror.$(OBJEXT) \
libvirt_lxc-xml.$(OBJEXT)
@@ -1485,6 +1486,7 @@ UTIL_SOURCES = \
hostusb.c hostusb.h \
qparams.c qparams.h \
storage_encryption_conf.h storage_encryption_conf.c \
+ storage_file.c storage_file.h \
threads.c threads.h \
threads-pthread.h \
threads-win32.h \
@@ -2151,6 +2153,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvirt_lxc-pci.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvirt_lxc-qparams.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvirt_lxc-storage_encryption_conf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvirt_lxc-storage_file.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvirt_lxc-threads.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvirt_lxc-util.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvirt_lxc-uuid.Po@am__quote@
@@ -2170,6 +2173,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvirt_util_la-pci.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvirt_util_la-qparams.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvirt_util_la-storage_encryption_conf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvirt_util_la-storage_file.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvirt_util_la-threads.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvirt_util_la-util.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvirt_util_la-uuid.Plo@am__quote@
@@ -2753,6 +2757,14 @@ libvirt_util_la-storage_encryption_conf.
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvirt_util_la_CFLAGS) $(CFLAGS) -c -o libvirt_util_la-storage_encryption_conf.lo `test -f 'storage_encryption_conf.c' || echo '$(srcdir)/'`storage_encryption_conf.c
+libvirt_util_la-storage_file.lo: storage_file.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvirt_util_la_CFLAGS) $(CFLAGS) -MT libvirt_util_la-storage_file.lo -MD -MP -MF $(DEPDIR)/libvirt_util_la-storage_file.Tpo -c -o libvirt_util_la-storage_file.lo `test -f 'storage_file.c' || echo '$(srcdir)/'`storage_file.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libvirt_util_la-storage_file.Tpo $(DEPDIR)/libvirt_util_la-storage_file.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='storage_file.c' object='libvirt_util_la-storage_file.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvirt_util_la_CFLAGS) $(CFLAGS) -c -o libvirt_util_la-storage_file.lo `test -f 'storage_file.c' || echo '$(srcdir)/'`storage_file.c
+
libvirt_util_la-threads.lo: threads.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvirt_util_la_CFLAGS) $(CFLAGS) -MT libvirt_util_la-threads.lo -MD -MP -MF $(DEPDIR)/libvirt_util_la-threads.Tpo -c -o libvirt_util_la-threads.lo `test -f 'threads.c' || echo '$(srcdir)/'`threads.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libvirt_util_la-threads.Tpo $(DEPDIR)/libvirt_util_la-threads.Plo
@@ -3065,6 +3077,22 @@ libvirt_lxc-storage_encryption_conf.obj:
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvirt_lxc_CFLAGS) $(CFLAGS) -c -o libvirt_lxc-storage_encryption_conf.obj `if test -f 'storage_encryption_conf.c'; then $(CYGPATH_W) 'storage_encryption_conf.c'; else $(CYGPATH_W) '$(srcdir)/storage_encryption_conf.c'; fi`
+libvirt_lxc-storage_file.o: storage_file.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvirt_lxc_CFLAGS) $(CFLAGS) -MT libvirt_lxc-storage_file.o -MD -MP -MF $(DEPDIR)/libvirt_lxc-storage_file.Tpo -c -o libvirt_lxc-storage_file.o `test -f 'storage_file.c' || echo '$(srcdir)/'`storage_file.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libvirt_lxc-storage_file.Tpo $(DEPDIR)/libvirt_lxc-storage_file.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='storage_file.c' object='libvirt_lxc-storage_file.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvirt_lxc_CFLAGS) $(CFLAGS) -c -o libvirt_lxc-storage_file.o `test -f 'storage_file.c' || echo '$(srcdir)/'`storage_file.c
+
+libvirt_lxc-storage_file.obj: storage_file.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvirt_lxc_CFLAGS) $(CFLAGS) -MT libvirt_lxc-storage_file.obj -MD -MP -MF $(DEPDIR)/libvirt_lxc-storage_file.Tpo -c -o libvirt_lxc-storage_file.obj `if test -f 'storage_file.c'; then $(CYGPATH_W) 'storage_file.c'; else $(CYGPATH_W) '$(srcdir)/storage_file.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libvirt_lxc-storage_file.Tpo $(DEPDIR)/libvirt_lxc-storage_file.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='storage_file.c' object='libvirt_lxc-storage_file.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvirt_lxc_CFLAGS) $(CFLAGS) -c -o libvirt_lxc-storage_file.obj `if test -f 'storage_file.c'; then $(CYGPATH_W) 'storage_file.c'; else $(CYGPATH_W) '$(srcdir)/storage_file.c'; fi`
+
libvirt_lxc-threads.o: threads.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvirt_lxc_CFLAGS) $(CFLAGS) -MT libvirt_lxc-threads.o -MD -MP -MF $(DEPDIR)/libvirt_lxc-threads.Tpo -c -o libvirt_lxc-threads.o `test -f 'threads.c' || echo '$(srcdir)/'`threads.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libvirt_lxc-threads.Tpo $(DEPDIR)/libvirt_lxc-threads.Po
diff -rup libvirt-0.7.1/tests/confdata/Makefile.in gcrypt-new/tests/confdata/Makefile.in
--- libvirt-0.7.1/tests/confdata/Makefile.in 2009-09-15 08:35:17.000000000 -0400
+++ gcrypt-new/tests/confdata/Makefile.in 2010-05-17 17:52:27.383154000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
diff -rup libvirt-0.7.1/tests/Makefile.in gcrypt-new/tests/Makefile.in
--- libvirt-0.7.1/tests/Makefile.in 2009-09-15 08:35:17.000000000 -0400
+++ gcrypt-new/tests/Makefile.in 2010-05-17 17:52:27.223153000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -1401,7 +1401,7 @@ clean-libtool:
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
- @failcom='exit 1'; \
+ @fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
@@ -1426,7 +1426,7 @@ $(RECURSIVE_TARGETS):
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
- @failcom='exit 1'; \
+ @fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
diff -rup libvirt-0.7.1/tests/sexpr2xmldata/Makefile.in gcrypt-new/tests/sexpr2xmldata/Makefile.in
--- libvirt-0.7.1/tests/sexpr2xmldata/Makefile.in 2009-09-15 08:35:17.000000000 -0400
+++ gcrypt-new/tests/sexpr2xmldata/Makefile.in 2010-05-17 17:52:27.543159000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
diff -rup libvirt-0.7.1/tests/xencapsdata/Makefile.in gcrypt-new/tests/xencapsdata/Makefile.in
--- libvirt-0.7.1/tests/xencapsdata/Makefile.in 2009-09-15 08:35:18.000000000 -0400
+++ gcrypt-new/tests/xencapsdata/Makefile.in 2010-05-17 17:52:27.704150000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
diff -rup libvirt-0.7.1/tests/xmconfigdata/Makefile.in gcrypt-new/tests/xmconfigdata/Makefile.in
--- libvirt-0.7.1/tests/xmconfigdata/Makefile.in 2009-09-15 08:35:18.000000000 -0400
+++ gcrypt-new/tests/xmconfigdata/Makefile.in 2010-05-17 17:52:27.872118000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
diff -rup libvirt-0.7.1/tests/xml2sexprdata/Makefile.in gcrypt-new/tests/xml2sexprdata/Makefile.in
--- libvirt-0.7.1/tests/xml2sexprdata/Makefile.in 2009-09-15 08:35:18.000000000 -0400
+++ gcrypt-new/tests/xml2sexprdata/Makefile.in 2010-05-17 17:52:28.046074000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
diff -rup libvirt-0.7.1/tools/Makefile.in gcrypt-new/tools/Makefile.in
--- libvirt-0.7.1/tools/Makefile.in 2009-09-15 08:35:18.000000000 -0400
+++ gcrypt-new/tools/Makefile.in 2010-05-17 17:52:28.213075000 -0400
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,

View File

@ -1,13 +0,0 @@
diff -rup libvirt-0.7.1/src/lxc_driver.c new/src/lxc_driver.c
--- libvirt-0.7.1/src/lxc_driver.c 2009-09-10 09:45:00.000000000 -0400
+++ new/src/lxc_driver.c 2010-06-03 15:03:11.524069000 -0400
@@ -96,7 +96,8 @@ static virDrvOpenStatus lxcOpen(virConne
return VIR_DRV_OPEN_DECLINED;
/* If path isn't '/' then they typoed, tell them correct path */
- if (STRNEQ(conn->uri->path, "/")) {
+ if (conn->uri->path != NULL &&
+ STRNEQ(conn->uri->path, "/")) {
lxcError(conn, NULL, VIR_ERR_INTERNAL_ERROR,
_("unexpected LXC URI path '%s', try lxc:///"),
conn->uri->path);

View File

@ -1,65 +0,0 @@
commit e5f31f461f63bbad211e84b810d6ba43a705f9dd
Author: Justin Clift <justin@salasaga.org>
Date: Sun May 30 13:28:42 2010 +1000
Trivial virsh.pod additions --all for "list" command and similar
This is just a trivial patch to virsh.pod (from git master). It adds the
following pieces to the virsh man page:
+ Shows the --inactive and --all optional parameters for the list
command.
Closes Bugzilla #575512, reported by Renich Bon Ciric
https://bugzilla.redhat.com/show_bug.cgi?id=575512
+ Corrects the existing description of the list command, to now say
that only running domains are listed if no domains are specified.
The man page up until this point has said all domains are listed if
no domains are specified, which is incorrect.
+ Adds the "shut off" state to the list of states for the list
command.
+ Adds a missing =back around line 755, that pod2man was complaining
was missing.
diff --git a/tools/virsh.pod b/tools/virsh.pod
index cf7585d..495bb46 100644
--- a/docs/virsh.pod
+++ b/docs/virsh.pod
@@ -156,10 +156,10 @@ description see:
L<http://libvirt.org/formatcaps.html>
The XML also show the NUMA topology information if available.
-=item B<list>
+=item B<list> optional I<--inactive> I<--all>
Prints information about one or more domains. If no domains are
-specified it prints out information about all domains.
+specified it prints out information about running domains.
An example format for the list is as follows:
@@ -177,7 +177,7 @@ State is the run state (see below).
B<STATES>
-The State field lists 6 states for a domain, and which ones the
+The State field lists 7 states for a domain, and which ones the
current domain is in.
=over 4
@@ -205,6 +205,11 @@ The domain is in the process of shutting down, i.e. the guest operating system
has been notified and should be in the process of stopping its operations
gracefully.
+=item B<shut off>
+
+The domain is not running. Usually this indicates the domain has been
+shut down completely, or has not been started.
+
=item B<crashed>
The domain has crashed, which is always a violent ending. Usually

View File

@ -1,401 +0,0 @@
diff -rup libvirt-0.7.1/src/libvirt.c new/src/libvirt.c
--- libvirt-0.7.1/src/libvirt.c 2010-06-03 15:30:32.615164000 -0400
+++ new/src/libvirt.c 2010-06-03 15:33:22.863409000 -0400
@@ -3054,6 +3054,7 @@ virDomainMigrateVersion2 (virDomainPtr d
char *cookie = NULL;
char *dom_xml = NULL;
int cookielen = 0, ret;
+ virErrorPtr orig_err = NULL;
/* Prepare the migration.
*
@@ -3102,6 +3103,10 @@ virDomainMigrateVersion2 (virDomainPtr d
ret = domain->conn->driver->domainMigratePerform
(domain, cookie, cookielen, uri, flags, dname, bandwidth);
+ /* Perform failed. Make sure Finish doesn't overwrite the error */
+ if (ret < 0)
+ orig_err = virSaveLastError();
+
/* In version 2 of the migration protocol, we pass the
* status code from the sender to the destination host,
* so it can do any cleanup if the migration failed.
@@ -3111,6 +3116,10 @@ virDomainMigrateVersion2 (virDomainPtr d
(dconn, dname, cookie, cookielen, uri, flags, ret);
done:
+ if (orig_err) {
+ virSetError(orig_err);
+ virFreeError(orig_err);
+ }
VIR_FREE (uri_out);
VIR_FREE (cookie);
return ddomain;
@@ -3222,7 +3231,7 @@ virDomainMigrate (virDomainPtr domain,
error:
/* Copy to connection error object for back compatability */
- virSetConnError(domain->conn);
+ virDispatchError(domain->conn);
return NULL;
}
@@ -3269,8 +3278,7 @@ virDomainMigratePrepare (virConnectPtr d
virLibConnError (dconn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
- /* Copy to connection error object for back compatability */
- virSetConnError(dconn);
+ virDispatchError(dconn);
return -1;
}
@@ -3318,8 +3326,7 @@ virDomainMigratePerform (virDomainPtr do
virLibDomainError (domain, VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
- /* Copy to connection error object for back compatability */
- virSetConnError(domain->conn);
+ virDispatchError(domain->conn);
return -1;
}
@@ -3364,8 +3371,7 @@ virDomainMigrateFinish (virConnectPtr dc
virLibConnError (dconn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
- /* Copy to connection error object for back compatability */
- virSetConnError(dconn);
+ virDispatchError(dconn);
return NULL;
}
@@ -3416,8 +3422,7 @@ virDomainMigratePrepare2 (virConnectPtr
virLibConnError (dconn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
- /* Copy to connection error object for back compatability */
- virSetConnError(dconn);
+ virDispatchError(dconn);
return -1;
}
@@ -3464,8 +3469,7 @@ virDomainMigrateFinish2 (virConnectPtr d
virLibConnError (dconn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
- /* Copy to connection error object for back compatability */
- virSetConnError(dconn);
+ virDispatchError(dconn);
return NULL;
}
diff -rup libvirt-0.7.1/src/libvirt_private.syms new/src/libvirt_private.syms
--- libvirt-0.7.1/src/libvirt_private.syms 2010-06-03 15:30:33.051186000 -0400
+++ new/src/libvirt_private.syms 2010-06-03 15:33:22.869400000 -0400
@@ -461,6 +461,7 @@ virRaiseErrorFull;
virReportSystemErrorFull;
virReportOOMErrorFull;
virStrerror;
+virSetError;
# xml.h
diff -rup libvirt-0.7.1/src/qemu_driver.c new/src/qemu_driver.c
--- libvirt-0.7.1/src/qemu_driver.c 2010-06-03 15:30:33.111159000 -0400
+++ new/src/qemu_driver.c 2010-06-03 15:35:22.809404000 -0400
@@ -2297,12 +2297,17 @@ static void qemudShutdownVMDaemon(virCon
virDomainObjPtr vm) {
int ret;
int retries = 0;
+ virErrorPtr orig_err;
if (!virDomainIsActive(vm))
return;
VIR_DEBUG(_("Shutting down VM '%s'\n"), vm->def->name);
+ /* This method is routinely used in clean up paths. Disable error
+ * reporting so we don't squash a legit error. */
+ orig_err = virSaveLastError();
+
if (virKillProcess(vm->pid, 0) == 0 &&
virKillProcess(vm->pid, SIGTERM) < 0)
virReportSystemError(conn, errno,
@@ -2377,6 +2382,11 @@ retry:
vm->def->id = -1;
vm->newDef = NULL;
}
+
+ if (orig_err) {
+ virSetError(orig_err);
+ virFreeError(orig_err);
+ }
}
@@ -7497,6 +7507,10 @@ qemudDomainMigrateFinish2 (virConnectPtr
virDomainObjPtr vm;
virDomainPtr dom = NULL;
virDomainEventPtr event = NULL;
+ virErrorPtr orig_err;
+
+ /* Migration failed. Save the current error so nothing squashes it */
+ orig_err = virSaveLastError();
qemuDriverLock(driver);
vm = virDomainFindByName(&driver->domains, dname);
@@ -7540,6 +7554,10 @@ qemudDomainMigrateFinish2 (virConnectPtr
}
cleanup:
+ if (orig_err) {
+ virSetError(orig_err);
+ virFreeError(orig_err);
+ }
if (vm)
virDomainObjUnlock(vm);
if (event)
diff -rup libvirt-0.7.1/src/util.c new/src/util.c
--- libvirt-0.7.1/src/util.c 2010-06-03 15:30:33.064159000 -0400
+++ new/src/util.c 2010-06-03 15:33:22.881417000 -0400
@@ -1764,31 +1764,82 @@ int virDiskNameToIndex(const char *name)
#define AI_CANONIDN 0
#endif
-char *virGetHostname(void)
+/* Who knew getting a hostname could be so delicate. In Linux (and Unices
+ * in general), many things depend on "hostname" returning a value that will
+ * resolve one way or another. In the modern world where networks frequently
+ * come and go this is often being hard-coded to resolve to "localhost". If
+ * it *doesn't* resolve to localhost, then we would prefer to have the FQDN.
+ * That leads us to 3 possibilities:
+ *
+ * 1) gethostname() returns an FQDN (not localhost) - we return the string
+ * as-is, it's all of the information we want
+ * 2) gethostname() returns "localhost" - we return localhost; doing further
+ * work to try to resolve it is pointless
+ * 3) gethostname() returns a shortened hostname - in this case, we want to
+ * try to resolve this to a fully-qualified name. Therefore we pass it
+ * to getaddrinfo(). There are two possible responses:
+ * a) getaddrinfo() resolves to a FQDN - return the FQDN
+ * b) getaddrinfo() resolves to localhost - in this case, the data we got
+ * from gethostname() is actually more useful than what we got from
+ * getaddrinfo(). Return the value from gethostname() and hope for
+ * the best.
+ */
+char *virGetHostname()
{
int r;
char hostname[HOST_NAME_MAX+1], *result;
struct addrinfo hints, *info;
r = gethostname (hostname, sizeof(hostname));
- if (r == -1)
+ if (r == -1) {
+ virReportSystemError(NULL, errno,
+ "%s", _("failed to determine host name"));
return NULL;
+ }
NUL_TERMINATE(hostname);
+ if (STRPREFIX(hostname, "localhost") || strchr(hostname, '.')) {
+ /* in this case, gethostname returned localhost (meaning we can't
+ * do any further canonicalization), or it returned an FQDN (and
+ * we don't need to do any further canonicalization). Return the
+ * string as-is; it's up to callers to check whether "localhost"
+ * is allowed.
+ */
+ result = strdup(hostname);
+ goto check_and_return;
+ }
+
+ /* otherwise, it's a shortened, non-localhost, hostname. Attempt to
+ * canonicalize the hostname by running it through getaddrinfo
+ */
+
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME|AI_CANONIDN;
hints.ai_family = AF_UNSPEC;
r = getaddrinfo(hostname, NULL, &hints, &info);
- if (r != 0)
- return NULL;
- if (info->ai_canonname == NULL) {
- freeaddrinfo(info);
+ if (r != 0) {
+ ReportError(NULL, VIR_ERR_INTERNAL_ERROR,
+ _("getaddrinfo failed for '%s': %s"),
+ hostname, gai_strerror(r));
return NULL;
}
- /* Caller frees this string. */
- result = strdup (info->ai_canonname);
+ if (info->ai_canonname == NULL ||
+ STRPREFIX(info->ai_canonname, "localhost"))
+ /* in this case, we tried to canonicalize and we ended up back with
+ * localhost. Ignore the canonicalized name and just return the
+ * original hostname
+ */
+ result = strdup(hostname);
+ else
+ /* Caller frees this string. */
+ result = strdup (info->ai_canonname);
+
freeaddrinfo(info);
+
+check_and_return:
+ if (result == NULL)
+ virReportOOMError(NULL);
return result;
}
diff -rup libvirt-0.7.1/src/virterror.c new/src/virterror.c
--- libvirt-0.7.1/src/virterror.c 2009-09-14 06:12:53.000000000 -0400
+++ new/src/virterror.c 2010-06-03 15:33:22.886409000 -0400
@@ -287,6 +287,28 @@ virGetLastError(void)
}
/**
+ * virSetError:
+ *
+ * Set the current error from a previously saved error object
+ *
+ * Can be used to re-set an old error, which may have been squashed by
+ * other functions (like cleanup routines).
+ *
+ * Returns 0 on success, 1 on failure
+ */
+int
+virSetError(virErrorPtr newerr)
+{
+ virErrorPtr err;
+ err = virGetLastError();
+ if (!err)
+ return -1;
+
+ virResetError(err);
+ return virCopyError(newerr, err);
+}
+
+/**
* virCopyLastError:
* @to: target to receive the copy
*
@@ -596,6 +618,52 @@ virSetConnError(virConnectPtr conn)
}
}
+/**
+ * virDispatchError:
+ * @conn: pointer to the hypervisor connection
+ *
+ * Internal helper to do final stage of error
+ * reporting in public APIs.
+ *
+ * - Copy the global error to per-connection error if needed
+ * - Set a generic error message if none is already set
+ * - Invoke the error callback functions
+ */
+void
+virDispatchError(virConnectPtr conn)
+{
+ virErrorPtr err = virLastErrorObject();
+ virErrorFunc handler = virErrorHandler;
+ void *userData = virUserData;
+
+ /* Should never happen, but doesn't hurt to check */
+ if (!err)
+ return;
+
+ /* Set a generic error message if none is already set */
+ if (err->code == VIR_ERR_OK)
+ virErrorGenericFailure(err);
+
+ /* Copy the global error to per-connection error if needed */
+ if (conn) {
+ virMutexLock(&conn->lock);
+ virCopyError(err, &conn->err);
+
+ if (conn->handler != NULL) {
+ handler = conn->handler;
+ userData = conn->userData;
+ }
+ virMutexUnlock(&conn->lock);
+ }
+
+ /* Invoke the error callback functions */
+ if (handler != NULL) {
+ (handler)(userData, err);
+ } else {
+ virDefaultErrorFunc(err);
+ }
+}
+
/**
@@ -634,8 +702,6 @@ virRaiseErrorFull(virConnectPtr conn,
const char *fmt, ...)
{
virErrorPtr to;
- void *userData = virUserData;
- virErrorFunc handler = virErrorHandler;
char *str;
/*
@@ -653,18 +719,6 @@ virRaiseErrorFull(virConnectPtr conn,
return;
/*
- * try to find the best place to save and report the error
- */
- if (conn != NULL) {
- virMutexLock(&conn->lock);
- if (conn->handler != NULL) {
- handler = conn->handler;
- userData = conn->userData;
- }
- virMutexUnlock(&conn->lock);
- }
-
- /*
* formats the message
*/
if (fmt == NULL) {
@@ -683,7 +737,6 @@ virRaiseErrorFull(virConnectPtr conn,
/*
* Save the information about the error
*/
- virResetError(to);
/*
* Delibrately not setting conn, dom & net fields since
* they're utterly unsafe
@@ -701,14 +754,7 @@ virRaiseErrorFull(virConnectPtr conn,
to->int1 = int1;
to->int2 = int2;
- /*
- * now, report it
- */
- if (handler != NULL) {
- handler(userData, to);
- } else {
- virDefaultErrorFunc(to);
- }
+ virDispatchError(conn);
}
/**
diff -rup libvirt-0.7.1/src/virterror_internal.h new/src/virterror_internal.h
--- libvirt-0.7.1/src/virterror_internal.h 2009-07-23 12:33:02.000000000 -0400
+++ new/src/virterror_internal.h 2010-06-03 15:33:22.890402000 -0400
@@ -89,6 +89,8 @@ void virReportOOMErrorFull(virConnectPtr
void virSetGlobalError(void);
void virSetConnError(virConnectPtr conn);
+int virSetError(virErrorPtr newerr);
+void virDispatchError(virConnectPtr conn);
const char *virStrerror(int theerrno, char *errBuf, size_t errBufLen);
#endif

View File

@ -1,126 +0,0 @@
diff -rup libvirt-0.7.1/src/network_driver.c new/src/network_driver.c
--- libvirt-0.7.1/src/network_driver.c 2009-09-15 03:49:04.000000000 -0400
+++ new/src/network_driver.c 2010-06-15 13:33:01.900912000 -0400
@@ -43,6 +43,8 @@
#include <stdio.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#include "virterror_internal.h"
#include "datatypes.h"
@@ -843,6 +845,102 @@ cleanup:
return ret;
}
+#define PROC_NET_ROUTE "/proc/net/route"
+
+static int networkCheckRouteCollision(virNetworkObjPtr network)
+{
+ int ret = -1, len;
+ char *cur, *buf = NULL;
+ enum {MAX_ROUTE_SIZE = 1024*64};
+ struct in_addr inaddress, innetmask;
+ unsigned int net_dest;
+
+ if (!network->def->ipAddress || !network->def->netmask)
+ return 0;
+
+ if (inet_pton(AF_INET, network->def->ipAddress, &inaddress) <= 0) {
+ networkReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse IP address '%s'"),
+ network->def->ipAddress);
+ goto error;
+ }
+ if (inet_pton(AF_INET, network->def->netmask, &innetmask) <= 0) {
+ networkReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse netmask '%s'"),
+ network->def->netmask);
+ goto error;
+ }
+
+ net_dest = (inaddress.s_addr & innetmask.s_addr);
+
+ /* Read whole routing table into memory */
+ if ((len = virFileReadAll(PROC_NET_ROUTE, MAX_ROUTE_SIZE, &buf)) < 0)
+ goto error;
+
+ /* Dropping the last character shouldn't hurt */
+ if (len > 0)
+ buf[len-1] = '\0';
+
+ VIR_DEBUG("%s output:\n%s", PROC_NET_ROUTE, buf);
+
+ if (!STRPREFIX (buf, "Iface"))
+ goto out;
+
+ /* First line is just headings, skip it */
+ cur = strchr(buf, '\n');
+ if (cur)
+ cur++;
+
+ while (cur) {
+ char iface[17], dest[128], mask[128];
+ unsigned int addr_val, mask_val;
+ int num;
+
+ /* NUL-terminate the line, so sscanf doesn't go beyond a newline. */
+ char *nl = strchr(cur, '\n');
+ if (nl) {
+ *nl++ = '\0';
+ }
+
+ num = sscanf(cur, "%16s %127s %*s %*s %*s %*s %*s %127s",
+ iface, dest, mask);
+ cur = nl;
+
+ if (num != 3) {
+ VIR_DEBUG("Failed to parse %s", PROC_NET_ROUTE);
+ continue;
+ }
+
+ if (virStrToLong_ui(dest, NULL, 16, &addr_val) < 0) {
+ VIR_DEBUG("Failed to convert network address %s to uint", dest);
+ continue;
+ }
+
+ if (virStrToLong_ui(mask, NULL, 16, &mask_val) < 0) {
+ VIR_DEBUG("Failed to convert network mask %s to uint", mask);
+ continue;
+ }
+
+ addr_val &= mask_val;
+
+ if ((net_dest == addr_val) &&
+ (innetmask.s_addr == mask_val)) {
+ networkReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Network %s/%s is already in use by "
+ "interface %s"),
+ network->def->ipAddress,
+ network->def->netmask, iface);
+ goto error;
+ }
+ }
+
+out:
+ ret = 0;
+error:
+ VIR_FREE(buf);
+ return ret;
+}
+
static int networkStartNetworkDaemon(virConnectPtr conn,
struct network_driver *driver,
virNetworkObjPtr network) {
@@ -854,6 +952,10 @@ static int networkStartNetworkDaemon(vir
return -1;
}
+ /* Check to see if network collides with an existing route */
+ if (networkCheckRouteCollision(network) < 0)
+ return -1;
+
if ((err = brAddBridge(driver->brctl, network->def->bridge))) {
virReportSystemError(conn, err,
_("cannot create bridge '%s'"),

View File

@ -1,29 +0,0 @@
commit c11a82b62aefc21e070c527f59a1f9c57a7b4f36
Author: Richard Jones <rjones@redhat.com>
Date: Thu Dec 10 16:39:07 2009 +0000
qemu driver: Fix segfault in libvirt/libvirtd when uri->path is NULL.
See also:
https://bugzilla.redhat.com/show_bug.cgi?id=545400#c1
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2fb059d..e9cc8c3 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -2651,6 +2651,15 @@ static virDrvOpenStatus qemudOpen(virConnectPtr conn,
return VIR_DRV_OPEN_ERROR;
}
+ if (conn->uri->path == NULL) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("no QEMU URI path given, try %s"),
+ qemu_driver->privileged
+ ? "qemu:///system"
+ : "qemu:///session");
+ return VIR_DRV_OPEN_ERROR;
+ }
+
if (qemu_driver->privileged) {
if (STRNEQ (conn->uri->path, "/system") &&
STRNEQ (conn->uri->path, "/session")) {

View File

@ -1,143 +0,0 @@
diff -rup libvirt-0.7.1/src/libvirt_private.syms paths/src/libvirt_private.syms
--- libvirt-0.7.1/src/libvirt_private.syms 2010-05-26 12:48:49.276277000 -0400
+++ paths/src/libvirt_private.syms 2010-05-26 13:00:47.501023000 -0400
@@ -417,6 +417,7 @@ virParseMacAddr;
virFileDeletePid;
virFindFileInPath;
virFileExists;
+virFileSanitizePath;
virFileHasSuffix;
virFileLinkPointsTo;
virFileMakePath;
diff -rup libvirt-0.7.1/src/storage_conf.c paths/src/storage_conf.c
--- libvirt-0.7.1/src/storage_conf.c 2010-05-26 12:48:48.885306000 -0400
+++ paths/src/storage_conf.c 2010-05-26 13:00:17.027330000 -0400
@@ -463,6 +463,7 @@ virStoragePoolDefParseXML(virConnectPtr
char *type = NULL;
char *uuid = NULL;
char *authType = NULL;
+ char *tmppath;
if (VIR_ALLOC(ret) < 0) {
virReportOOMError(conn);
@@ -610,11 +611,15 @@ virStoragePoolDefParseXML(virConnectPtr
goto cleanup;
}
- if ((ret->target.path = virXPathString(conn, "string(./target/path)", ctxt)) == NULL) {
+ if ((tmppath = virXPathString(conn, "string(./target/path)", ctxt)) == NULL) {
virStorageReportError(conn, VIR_ERR_XML_ERROR,
"%s", _("missing storage pool target path"));
goto cleanup;
}
+ ret->target.path = virFileSanitizePath(tmppath);
+ VIR_FREE(tmppath);
+ if (!ret->target.path)
+ goto cleanup;
if (virStorageDefParsePerms(conn, ctxt, &ret->target.perms,
"./target/permissions", 0700) < 0)
diff -rup libvirt-0.7.1/src/storage_driver.c paths/src/storage_driver.c
--- libvirt-0.7.1/src/storage_driver.c 2009-09-10 09:45:00.000000000 -0400
+++ paths/src/storage_driver.c 2010-05-26 12:59:14.815537000 -0400
@@ -1152,6 +1152,11 @@ storageVolumeLookupByPath(virConnectPtr
virStorageDriverStatePtr driver = conn->storagePrivateData;
unsigned int i;
virStorageVolPtr ret = NULL;
+ char *cleanpath;
+
+ cleanpath = virFileSanitizePath(path);
+ if (!cleanpath)
+ return NULL;
storageDriverLock(driver);
for (i = 0 ; i < driver->pools.count && !ret ; i++) {
@@ -1162,7 +1167,7 @@ storageVolumeLookupByPath(virConnectPtr
stable_path = virStorageBackendStablePath(conn,
driver->pools.objs[i],
- path);
+ cleanpath);
/*
* virStorageBackendStablePath already does
* virStorageReportError if it fails; we just need to keep
@@ -1191,6 +1196,7 @@ storageVolumeLookupByPath(virConnectPtr
"%s", _("no storage vol with matching path"));
cleanup:
+ VIR_FREE(cleanpath);
storageDriverUnlock(driver);
return ret;
}
diff -rup libvirt-0.7.1/src/util.c paths/src/util.c
--- libvirt-0.7.1/src/util.c 2010-05-26 12:48:48.840341000 -0400
+++ paths/src/util.c 2010-05-26 12:58:02.088721000 -0400
@@ -1126,6 +1126,55 @@ int virFileExists(const char *path)
return(0);
}
+/* Remove spurious / characters from a path. The result must be freed */
+char *
+virFileSanitizePath(const char *path)
+{
+ const char *cur = path;
+ char *cleanpath;
+ int idx = 0;
+
+ cleanpath = strdup(path);
+ if (!cleanpath) {
+ virReportOOMError(NULL);
+ return NULL;
+ }
+
+ /* Need to sanitize:
+ * // -> //
+ * /// -> /
+ * /../foo -> /../foo
+ * /foo///bar/ -> /foo/bar
+ */
+
+ /* Starting with // is valid posix, but ///foo == /foo */
+ if (cur[0] == '/' && cur[1] == '/' && cur[2] != '/') {
+ idx = 2;
+ cur += 2;
+ }
+
+ /* Sanitize path in place */
+ while (*cur != '\0') {
+ if (*cur != '/') {
+ cleanpath[idx++] = *cur++;
+ continue;
+ }
+
+ /* Skip all extra / */
+ while (*++cur == '/')
+ continue;
+
+ /* Don't add a trailing / */
+ if (idx != 0 && *cur == '\0')
+ break;
+
+ cleanpath[idx++] = '/';
+ }
+ cleanpath[idx] = '\0';
+
+ return cleanpath;
+}
+
int virFileMakePath(const char *path)
{
struct stat st;
diff -rup libvirt-0.7.1/src/util.h paths/src/util.h
--- libvirt-0.7.1/src/util.h 2010-05-26 12:48:48.749342000 -0400
+++ paths/src/util.h 2010-05-26 12:56:57.494264000 -0400
@@ -107,6 +107,9 @@ char *virFindFileInPath(const char *file
int virFileExists(const char *path);
+char *virFileSanitizePath(const char *path);
+
+
int virFileMakePath(const char *path);
int virFileBuildPath(const char *dir,

View File

@ -0,0 +1,356 @@
From 953440bd12608a20007ee5da5ab69fbbe910bd28 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 14 Jun 2010 15:53:59 +0100
Subject: [PATCH 01/11] Extract the backing store format as well as name, if available
When QEMU opens a backing store for a QCow2 file, it will
normally auto-probe for the format of the backing store,
rather than assuming it has the same format as the referencing
file. There is a QCow2 extension that allows an explicit format
for the backing store to be embedded in the referencing file.
This closes the auto-probing security hole in QEMU.
This backing store format can be useful for libvirt users
of virStorageFileGetMetadata, so extract this data and report
it.
QEMU does not require disk image backing store files to be in
the same format the file linkee. It will auto-probe the disk
format for the backing store when opening it. If the backing
store was intended to be a raw file this could be a security
hole, because a guest may have written data into its disk that
then makes the backing store look like a qcow2 file. If it can
trick QEMU into thinking the raw file is a qcow2 file, it can
access arbitrary files on the host by adding further backing
store links.
To address this, callers of virStorageFileGetMeta need to be
told of the backing store format. If no format is declared,
they can make a decision whether to allow format probing or
not.
---
src/util/storage_file.c | 206 +++++++++++++++++++++++++++++++++++++++++------
src/util/storage_file.h | 2 +
2 files changed, 183 insertions(+), 25 deletions(-)
diff --git a/src/util/storage_file.c b/src/util/storage_file.c
index 0adea40..80f743e 100644
--- a/src/util/storage_file.c
+++ b/src/util/storage_file.c
@@ -78,12 +78,33 @@ struct FileTypeInfo {
int qcowCryptOffset; /* Byte offset from start of file
* where to find encryption mode,
* -1 if encryption is not used */
- int (*getBackingStore)(char **res, const unsigned char *buf, size_t buf_size);
+ int (*getBackingStore)(char **res, int *format,
+ const unsigned char *buf, size_t buf_size);
};
-static int cowGetBackingStore(char **, const unsigned char *, size_t);
-static int qcowXGetBackingStore(char **, const unsigned char *, size_t);
-static int vmdk4GetBackingStore(char **, const unsigned char *, size_t);
+static int cowGetBackingStore(char **, int *,
+ const unsigned char *, size_t);
+static int qcow1GetBackingStore(char **, int *,
+ const unsigned char *, size_t);
+static int qcow2GetBackingStore(char **, int *,
+ const unsigned char *, size_t);
+static int vmdk4GetBackingStore(char **, int *,
+ const unsigned char *, size_t);
+
+#define QCOWX_HDR_VERSION (4)
+#define QCOWX_HDR_BACKING_FILE_OFFSET (QCOWX_HDR_VERSION+4)
+#define QCOWX_HDR_BACKING_FILE_SIZE (QCOWX_HDR_BACKING_FILE_OFFSET+8)
+#define QCOWX_HDR_IMAGE_SIZE (QCOWX_HDR_BACKING_FILE_SIZE+4+4)
+
+#define QCOW1_HDR_CRYPT (QCOWX_HDR_IMAGE_SIZE+8+1+1)
+#define QCOW2_HDR_CRYPT (QCOWX_HDR_IMAGE_SIZE+8)
+
+#define QCOW1_HDR_TOTAL_SIZE (QCOW1_HDR_CRYPT+4+8)
+#define QCOW2_HDR_TOTAL_SIZE (QCOW2_HDR_CRYPT+4+4+8+8+4+4+8)
+
+#define QCOW2_HDR_EXTENSION_END 0
+#define QCOW2_HDR_EXTENSION_BACKING_FORMAT 0xE2792ACA
+
static struct FileTypeInfo const fileTypeInfo[] = {
@@ -119,11 +140,11 @@ static struct FileTypeInfo const fileTypeInfo[] = {
/* QCow */
{ VIR_STORAGE_FILE_QCOW, "QFI", NULL,
LV_BIG_ENDIAN, 4, 1,
- 4+4+8+4+4, 8, 1, 4+4+8+4+4+8+1+1+2, qcowXGetBackingStore },
+ QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW1_HDR_CRYPT, qcow1GetBackingStore },
/* QCow 2 */
{ VIR_STORAGE_FILE_QCOW2, "QFI", NULL,
LV_BIG_ENDIAN, 4, 2,
- 4+4+8+4+4, 8, 1, 4+4+8+4+4+8, qcowXGetBackingStore },
+ QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW2_HDR_CRYPT, qcow2GetBackingStore },
/* VMDK 3 */
/* XXX Untested
{ VIR_STORAGE_FILE_VMDK, "COWD", NULL,
@@ -142,11 +163,14 @@ static struct FileTypeInfo const fileTypeInfo[] = {
static int
cowGetBackingStore(char **res,
+ int *format,
const unsigned char *buf,
size_t buf_size)
{
#define COW_FILENAME_MAXLEN 1024
*res = NULL;
+ *format = VIR_STORAGE_FILE_AUTO;
+
if (buf_size < 4+4+ COW_FILENAME_MAXLEN)
return BACKING_STORE_INVALID;
if (buf[4+4] == '\0') /* cow_header_v2.backing_file[0] */
@@ -160,31 +184,98 @@ cowGetBackingStore(char **res,
return BACKING_STORE_OK;
}
+
+static int
+qcow2GetBackingStoreFormat(int *format,
+ const unsigned char *buf,
+ size_t buf_size,
+ size_t extension_start,
+ size_t extension_end)
+{
+ size_t offset = extension_start;
+
+ /*
+ * The extensions take format of
+ *
+ * int32: magic
+ * int32: length
+ * byte[length]: payload
+ *
+ * Unknown extensions can be ignored by skipping
+ * over "length" bytes in the data stream.
+ */
+ while (offset < (buf_size-8) &&
+ offset < (extension_end-8)) {
+ unsigned int magic =
+ (buf[offset] << 24) +
+ (buf[offset+1] << 16) +
+ (buf[offset+2] << 8) +
+ (buf[offset+3]);
+ unsigned int len =
+ (buf[offset+4] << 24) +
+ (buf[offset+5] << 16) +
+ (buf[offset+6] << 8) +
+ (buf[offset+7]);
+
+ offset += 8;
+
+ if ((offset + len) < offset)
+ break;
+
+ if ((offset + len) > buf_size)
+ break;
+
+ switch (magic) {
+ case QCOW2_HDR_EXTENSION_END:
+ goto done;
+
+ case QCOW2_HDR_EXTENSION_BACKING_FORMAT:
+ if (buf[offset+len] != '\0')
+ break;
+ *format = virStorageFileFormatTypeFromString(
+ ((const char *)buf)+offset);
+ break;
+ }
+
+ offset += len;
+ }
+
+done:
+
+ return 0;
+}
+
+
static int
qcowXGetBackingStore(char **res,
+ int *format,
const unsigned char *buf,
- size_t buf_size)
+ size_t buf_size,
+ bool isQCow2)
{
unsigned long long offset;
unsigned long size;
*res = NULL;
- if (buf_size < 4+4+8+4)
+ if (format)
+ *format = VIR_STORAGE_FILE_AUTO;
+
+ if (buf_size < QCOWX_HDR_BACKING_FILE_OFFSET+8+4)
return BACKING_STORE_INVALID;
- offset = (((unsigned long long)buf[4+4] << 56)
- | ((unsigned long long)buf[4+4+1] << 48)
- | ((unsigned long long)buf[4+4+2] << 40)
- | ((unsigned long long)buf[4+4+3] << 32)
- | ((unsigned long long)buf[4+4+4] << 24)
- | ((unsigned long long)buf[4+4+5] << 16)
- | ((unsigned long long)buf[4+4+6] << 8)
- | buf[4+4+7]); /* QCowHeader.backing_file_offset */
+ offset = (((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET] << 56)
+ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+1] << 48)
+ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+2] << 40)
+ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+3] << 32)
+ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+4] << 24)
+ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+5] << 16)
+ | ((unsigned long long)buf[QCOWX_HDR_BACKING_FILE_OFFSET+6] << 8)
+ | buf[QCOWX_HDR_BACKING_FILE_OFFSET+7]); /* QCowHeader.backing_file_offset */
if (offset > buf_size)
return BACKING_STORE_INVALID;
- size = ((buf[4+4+8] << 24)
- | (buf[4+4+8+1] << 16)
- | (buf[4+4+8+2] << 8)
- | buf[4+4+8+3]); /* QCowHeader.backing_file_size */
+ size = ((buf[QCOWX_HDR_BACKING_FILE_SIZE] << 24)
+ | (buf[QCOWX_HDR_BACKING_FILE_SIZE+1] << 16)
+ | (buf[QCOWX_HDR_BACKING_FILE_SIZE+2] << 8)
+ | buf[QCOWX_HDR_BACKING_FILE_SIZE+3]); /* QCowHeader.backing_file_size */
if (size == 0)
return BACKING_STORE_OK;
if (offset + size > buf_size || offset + size < offset)
@@ -197,12 +288,63 @@ qcowXGetBackingStore(char **res,
}
memcpy(*res, buf + offset, size);
(*res)[size] = '\0';
+
+ /*
+ * Traditionally QCow2 files had a layout of
+ *
+ * [header]
+ * [backingStoreName]
+ *
+ * Although the backingStoreName typically followed
+ * the header immediately, this was not required by
+ * the format. By specifying a higher byte offset for
+ * the backing file offset in the header, it was
+ * possible to leave space between the header and
+ * start of backingStore.
+ *
+ * This hack is now used to store extensions to the
+ * qcow2 format:
+ *
+ * [header]
+ * [extensions]
+ * [backingStoreName]
+ *
+ * Thus the file region to search for extensions is
+ * between the end of the header (QCOW2_HDR_TOTAL_SIZE)
+ * and the start of the backingStoreName (offset)
+ */
+ if (isQCow2)
+ qcow2GetBackingStoreFormat(format, buf, buf_size, QCOW2_HDR_TOTAL_SIZE, offset);
+
return BACKING_STORE_OK;
}
static int
+qcow1GetBackingStore(char **res,
+ int *format,
+ const unsigned char *buf,
+ size_t buf_size)
+{
+ /* QCow1 doesn't have the extensions capability
+ * used to store backing format */
+ *format = VIR_STORAGE_FILE_AUTO;
+ return qcowXGetBackingStore(res, NULL, buf, buf_size, false);
+}
+
+static int
+qcow2GetBackingStore(char **res,
+ int *format,
+ const unsigned char *buf,
+ size_t buf_size)
+{
+ return qcowXGetBackingStore(res, format, buf, buf_size, true);
+}
+
+
+static int
vmdk4GetBackingStore(char **res,
+ int *format,
const unsigned char *buf,
size_t buf_size)
{
@@ -212,6 +354,14 @@ vmdk4GetBackingStore(char **res,
size_t len;
*res = NULL;
+ /*
+ * Technically this should have been VMDK, since
+ * VMDK spec / VMWare impl only support VMDK backed
+ * by VMDK. QEMU isn't following this though and
+ * does probing on VMDK backing files, hence we set
+ * AUTO
+ */
+ *format = VIR_STORAGE_FILE_AUTO;
if (buf_size <= 0x200)
return BACKING_STORE_INVALID;
@@ -358,9 +508,12 @@ virStorageFileGetMetadataFromFD(const char *path,
/* Validation passed, we know the file format now */
meta->format = fileTypeInfo[i].type;
if (fileTypeInfo[i].getBackingStore != NULL) {
- char *base;
+ char *backing;
+ int backingFormat;
- switch (fileTypeInfo[i].getBackingStore(&base, head, len)) {
+ switch (fileTypeInfo[i].getBackingStore(&backing,
+ &backingFormat,
+ head, len)) {
case BACKING_STORE_OK:
break;
@@ -370,13 +523,16 @@ virStorageFileGetMetadataFromFD(const char *path,
case BACKING_STORE_ERROR:
return -1;
}
- if (base != NULL) {
- meta->backingStore = absolutePathFromBaseFile(path, base);
- VIR_FREE(base);
+ if (backing != NULL) {
+ meta->backingStore = absolutePathFromBaseFile(path, backing);
+ VIR_FREE(backing);
if (meta->backingStore == NULL) {
virReportOOMError();
return -1;
}
+ meta->backingStoreFormat = backingFormat;
+ } else {
+ meta->backingStoreFormat = VIR_STORAGE_FILE_AUTO;
}
}
return 0;
diff --git a/src/util/storage_file.h b/src/util/storage_file.h
index 58533ee..6328ba7 100644
--- a/src/util/storage_file.h
+++ b/src/util/storage_file.h
@@ -28,6 +28,7 @@
# include <stdbool.h>
enum virStorageFileFormat {
+ VIR_STORAGE_FILE_AUTO = -1,
VIR_STORAGE_FILE_RAW = 0,
VIR_STORAGE_FILE_DIR,
VIR_STORAGE_FILE_BOCHS,
@@ -47,6 +48,7 @@ VIR_ENUM_DECL(virStorageFileFormat);
typedef struct _virStorageFileMetadata {
int format;
char *backingStore;
+ int backingStoreFormat;
unsigned long long capacity;
bool encrypted;
} virStorageFileMetadata;
--
1.7.1.1

View File

@ -0,0 +1,159 @@
From cab428b1d4d432965cee6f5afb67265557706715 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 14 Jun 2010 16:39:32 +0100
Subject: [PATCH 02/11] Remove 'type' field from FileTypeInfo struct
Instead of including a field in FileTypeInfo struct for the
disk format, rely on the array index matching the format.
Use verify() to assert the correct number of elements in the
array.
* src/util/storage_file.c: remove type field from FileTypeInfo
---
src/util/storage_file.c | 108 +++++++++++++++++++++++-----------------------
1 files changed, 54 insertions(+), 54 deletions(-)
diff --git a/src/util/storage_file.c b/src/util/storage_file.c
index 80f743e..df0e3a1 100644
--- a/src/util/storage_file.c
+++ b/src/util/storage_file.c
@@ -58,7 +58,6 @@ enum {
/* Either 'magic' or 'extension' *must* be provided */
struct FileTypeInfo {
- int type; /* One of the constants above */
const char *magic; /* Optional string of file magic
* to check at head of file */
const char *extension; /* Optional file extension to check */
@@ -108,58 +107,59 @@ static int vmdk4GetBackingStore(char **, int *,
static struct FileTypeInfo const fileTypeInfo[] = {
- /* Bochs */
- /* XXX Untested
- { VIR_STORAGE_FILE_BOCHS, "Bochs Virtual HD Image", NULL,
- LV_LITTLE_ENDIAN, 64, 0x20000,
- 32+16+16+4+4+4+4+4, 8, 1, -1, NULL },*/
- /* CLoop */
- /* XXX Untested
- { VIR_STORAGE_VOL_CLOOP, "#!/bin/sh\n#V2.0 Format\nmodprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n", NULL,
- LV_LITTLE_ENDIAN, -1, 0,
- -1, 0, 0, -1, NULL }, */
- /* Cow */
- { VIR_STORAGE_FILE_COW, "OOOM", NULL,
- LV_BIG_ENDIAN, 4, 2,
- 4+4+1024+4, 8, 1, -1, cowGetBackingStore },
- /* DMG */
- /* XXX QEMU says there's no magic for dmg, but we should check... */
- { VIR_STORAGE_FILE_DMG, NULL, ".dmg",
- 0, -1, 0,
- -1, 0, 0, -1, NULL },
- /* XXX there's probably some magic for iso we can validate too... */
- { VIR_STORAGE_FILE_ISO, NULL, ".iso",
- 0, -1, 0,
- -1, 0, 0, -1, NULL },
- /* Parallels */
- /* XXX Untested
- { VIR_STORAGE_FILE_PARALLELS, "WithoutFreeSpace", NULL,
- LV_LITTLE_ENDIAN, 16, 2,
- 16+4+4+4+4, 4, 512, -1, NULL },
- */
- /* QCow */
- { VIR_STORAGE_FILE_QCOW, "QFI", NULL,
- LV_BIG_ENDIAN, 4, 1,
- QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW1_HDR_CRYPT, qcow1GetBackingStore },
- /* QCow 2 */
- { VIR_STORAGE_FILE_QCOW2, "QFI", NULL,
- LV_BIG_ENDIAN, 4, 2,
- QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW2_HDR_CRYPT, qcow2GetBackingStore },
- /* VMDK 3 */
- /* XXX Untested
- { VIR_STORAGE_FILE_VMDK, "COWD", NULL,
- LV_LITTLE_ENDIAN, 4, 1,
- 4+4+4, 4, 512, -1, NULL },
- */
- /* VMDK 4 */
- { VIR_STORAGE_FILE_VMDK, "KDMV", NULL,
- LV_LITTLE_ENDIAN, 4, 1,
- 4+4+4, 8, 512, -1, vmdk4GetBackingStore },
- /* Connectix / VirtualPC */
- { VIR_STORAGE_FILE_VPC, "conectix", NULL,
- LV_BIG_ENDIAN, 12, 0x10000,
- 8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, -1, NULL},
+ [VIR_STORAGE_FILE_RAW] = { NULL, NULL, LV_LITTLE_ENDIAN, -1, 0, 0, 0, 0, 0, NULL },
+ [VIR_STORAGE_FILE_DIR] = { NULL, NULL, LV_LITTLE_ENDIAN, -1, 0, 0, 0, 0, 0, NULL },
+ [VIR_STORAGE_FILE_BOCHS] = {
+ /*"Bochs Virtual HD Image", */ /* Untested */ NULL,
+ NULL,
+ LV_LITTLE_ENDIAN, 64, 0x20000,
+ 32+16+16+4+4+4+4+4, 8, 1, -1, NULL
+ },
+ [VIR_STORAGE_FILE_CLOOP] = {
+ /*"#!/bin/sh\n#V2.0 Format\nmodprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n", */ /* Untested */ NULL,
+ NULL,
+ LV_LITTLE_ENDIAN, -1, 0,
+ -1, 0, 0, -1, NULL
+ },
+ [VIR_STORAGE_FILE_COW] = {
+ "OOOM", NULL,
+ LV_BIG_ENDIAN, 4, 2,
+ 4+4+1024+4, 8, 1, -1, cowGetBackingStore
+ },
+ [VIR_STORAGE_FILE_DMG] = {
+ NULL, /* XXX QEMU says there's no magic for dmg, but we should check... */
+ ".dmg",
+ 0, -1, 0,
+ -1, 0, 0, -1, NULL
+ },
+ [VIR_STORAGE_FILE_ISO] = {
+ NULL, /* XXX there's probably some magic for iso we can validate too... */
+ ".iso",
+ 0, -1, 0,
+ -1, 0, 0, -1, NULL
+ },
+ [VIR_STORAGE_FILE_QCOW] = {
+ "QFI", NULL,
+ LV_BIG_ENDIAN, 4, 1,
+ QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW1_HDR_CRYPT, qcow1GetBackingStore,
+ },
+ [VIR_STORAGE_FILE_QCOW2] = {
+ "QFI", NULL,
+ LV_BIG_ENDIAN, 4, 2,
+ QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW2_HDR_CRYPT, qcow2GetBackingStore,
+ },
+ [VIR_STORAGE_FILE_VMDK] = {
+ "KDMV", NULL,
+ LV_LITTLE_ENDIAN, 4, 1,
+ 4+4+4, 8, 512, -1, vmdk4GetBackingStore
+ },
+ [VIR_STORAGE_FILE_VPC] = {
+ "conectix", NULL,
+ LV_BIG_ENDIAN, 12, 0x10000,
+ 8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, -1, NULL
+ },
};
+verify(ARRAY_CARDINALITY(fileTypeInfo) == VIR_STORAGE_FILE_LAST);
static int
cowGetBackingStore(char **res,
@@ -506,7 +506,7 @@ virStorageFileGetMetadataFromFD(const char *path,
}
/* Validation passed, we know the file format now */
- meta->format = fileTypeInfo[i].type;
+ meta->format = i;
if (fileTypeInfo[i].getBackingStore != NULL) {
char *backing;
int backingFormat;
@@ -546,7 +546,7 @@ virStorageFileGetMetadataFromFD(const char *path,
if (!virFileHasSuffix(path, fileTypeInfo[i].extension))
continue;
- meta->format = fileTypeInfo[i].type;
+ meta->format = i;
return 0;
}
--
1.7.1.1

View File

@ -0,0 +1,585 @@
From 57482ca0be29e9e92e242c9acb577e0b770c01d1 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Tue, 15 Jun 2010 14:58:10 +0100
Subject: [PATCH 03/11] Refactor virStorageFileGetMetadataFromFD to separate functionality
The virStorageFileGetMetadataFromFD did two jobs in one. First
it probed for storage type, then it extracted metadata for the
type. It is desirable to be able to separate these jobs, allowing
probing without querying metadata, and querying metadata without
probing.
To prepare for this, split out probing code into a new pair of
methods
virStorageFileProbeFormatFromFD
virStorageFileProbeFormat
* src/util/storage_file.c, src/util/storage_file.h,
src/libvirt_private.syms: Introduce virStorageFileProbeFormat
and virStorageFileProbeFormatFromFD
---
src/libvirt_private.syms | 2 +
src/util/storage_file.c | 460 +++++++++++++++++++++++++++++++++-------------
src/util/storage_file.h | 4 +
3 files changed, 335 insertions(+), 131 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 778ceb1..4607f49 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -628,6 +628,8 @@ virStorageGenerateQcowPassphrase;
# storage_file.h
virStorageFileFormatTypeToString;
virStorageFileFormatTypeFromString;
+virStorageFileProbeFormat;
+virStorageFileProbeFormatFromFD;
virStorageFileGetMetadata;
virStorageFileGetMetadataFromFD;
virStorageFileIsSharedFS;
diff --git a/src/util/storage_file.c b/src/util/storage_file.c
index df0e3a1..221268b 100644
--- a/src/util/storage_file.c
+++ b/src/util/storage_file.c
@@ -104,6 +104,9 @@ static int vmdk4GetBackingStore(char **, int *,
#define QCOW2_HDR_EXTENSION_END 0
#define QCOW2_HDR_EXTENSION_BACKING_FORMAT 0xE2792ACA
+/* VMDK needs at least this to find backing store,
+ * other formats are less */
+#define STORAGE_MAX_HEAD (20*512)
static struct FileTypeInfo const fileTypeInfo[] = {
@@ -349,9 +352,14 @@ vmdk4GetBackingStore(char **res,
size_t buf_size)
{
static const char prefix[] = "parentFileNameHint=\"";
-
- char desc[20*512 + 1], *start, *end;
+ char *desc, *start, *end;
size_t len;
+ int ret = BACKING_STORE_ERROR;
+
+ if (VIR_ALLOC_N(desc, STORAGE_MAX_HEAD + 1) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
*res = NULL;
/*
@@ -363,29 +371,42 @@ vmdk4GetBackingStore(char **res,
*/
*format = VIR_STORAGE_FILE_AUTO;
- if (buf_size <= 0x200)
- return BACKING_STORE_INVALID;
+ if (buf_size <= 0x200) {
+ ret = BACKING_STORE_INVALID;
+ goto cleanup;
+ }
len = buf_size - 0x200;
- if (len > sizeof(desc) - 1)
- len = sizeof(desc) - 1;
+ if (len > STORAGE_MAX_HEAD)
+ len = STORAGE_MAX_HEAD;
memcpy(desc, buf + 0x200, len);
desc[len] = '\0';
start = strstr(desc, prefix);
- if (start == NULL)
- return BACKING_STORE_OK;
+ if (start == NULL) {
+ ret = BACKING_STORE_OK;
+ goto cleanup;
+ }
start += strlen(prefix);
end = strchr(start, '"');
- if (end == NULL)
- return BACKING_STORE_INVALID;
- if (end == start)
- return BACKING_STORE_OK;
+ if (end == NULL) {
+ ret = BACKING_STORE_INVALID;
+ goto cleanup;
+ }
+ if (end == start) {
+ ret = BACKING_STORE_OK;
+ goto cleanup;
+ }
*end = '\0';
*res = strdup(start);
if (*res == NULL) {
virReportOOMError();
- return BACKING_STORE_ERROR;
+ goto cleanup;
}
- return BACKING_STORE_OK;
+
+ ret = BACKING_STORE_OK;
+
+cleanup:
+ VIR_FREE(desc);
+ return ret;
}
/**
@@ -411,148 +432,325 @@ absolutePathFromBaseFile(const char *base_file, const char *path)
return res;
}
-/**
- * Probe the header of a file to determine what type of disk image
- * it is, and info about its capacity if available.
- */
-int
-virStorageFileGetMetadataFromFD(const char *path,
- int fd,
- virStorageFileMetadata *meta)
+
+static bool
+virStorageFileMatchesMagic(int format,
+ unsigned char *buf,
+ size_t buflen)
{
- unsigned char head[20*512]; /* vmdk4GetBackingStore needs this much. */
- int len, i;
+ int mlen;
- memset(meta, 0, sizeof (*meta));
+ if (fileTypeInfo[format].magic == NULL)
+ return false;
- /* If all else fails, call it a raw file */
- meta->format = VIR_STORAGE_FILE_RAW;
+ /* Validate magic data */
+ mlen = strlen(fileTypeInfo[format].magic);
+ if (mlen > buflen)
+ return false;
- if ((len = read(fd, head, sizeof(head))) < 0) {
- virReportSystemError(errno, _("cannot read header '%s'"), path);
- return -1;
+ if (memcmp(buf, fileTypeInfo[format].magic, mlen) != 0)
+ return false;
+
+ return true;
+}
+
+
+static bool
+virStorageFileMatchesExtension(int format,
+ const char *path)
+{
+ if (fileTypeInfo[format].extension == NULL)
+ return false;
+
+ if (virFileHasSuffix(path, fileTypeInfo[format].extension))
+ return true;
+
+ return false;
+}
+
+
+static bool
+virStorageFileMatchesVersion(int format,
+ unsigned char *buf,
+ size_t buflen)
+{
+ int version;
+
+ /* Validate version number info */
+ if (fileTypeInfo[format].versionOffset == -1)
+ return false;
+
+ if ((fileTypeInfo[format].versionOffset + 4) > buflen)
+ return false;
+
+ if (fileTypeInfo[format].endian == LV_LITTLE_ENDIAN) {
+ version =
+ (buf[fileTypeInfo[format].versionOffset+3] << 24) |
+ (buf[fileTypeInfo[format].versionOffset+2] << 16) |
+ (buf[fileTypeInfo[format].versionOffset+1] << 8) |
+ (buf[fileTypeInfo[format].versionOffset]);
+ } else {
+ version =
+ (buf[fileTypeInfo[format].versionOffset] << 24) |
+ (buf[fileTypeInfo[format].versionOffset+1] << 16) |
+ (buf[fileTypeInfo[format].versionOffset+2] << 8) |
+ (buf[fileTypeInfo[format].versionOffset+3]);
}
+ if (version != fileTypeInfo[format].versionNumber)
+ return false;
- /* First check file magic */
- for (i = 0 ; i < ARRAY_CARDINALITY(fileTypeInfo) ; i++) {
- int mlen;
-
- if (fileTypeInfo[i].magic == NULL)
- continue;
-
- /* Validate magic data */
- mlen = strlen(fileTypeInfo[i].magic);
- if (mlen > len)
- continue;
- if (memcmp(head, fileTypeInfo[i].magic, mlen) != 0)
- continue;
-
- /* Validate version number info */
- if (fileTypeInfo[i].versionNumber != -1) {
- int version;
-
- if (fileTypeInfo[i].endian == LV_LITTLE_ENDIAN) {
- version = (head[fileTypeInfo[i].versionOffset+3] << 24) |
- (head[fileTypeInfo[i].versionOffset+2] << 16) |
- (head[fileTypeInfo[i].versionOffset+1] << 8) |
- head[fileTypeInfo[i].versionOffset];
- } else {
- version = (head[fileTypeInfo[i].versionOffset] << 24) |
- (head[fileTypeInfo[i].versionOffset+1] << 16) |
- (head[fileTypeInfo[i].versionOffset+2] << 8) |
- head[fileTypeInfo[i].versionOffset+3];
- }
- if (version != fileTypeInfo[i].versionNumber)
- continue;
- }
+ return true;
+}
- /* Optionally extract capacity from file */
- if (fileTypeInfo[i].sizeOffset != -1) {
- if (fileTypeInfo[i].endian == LV_LITTLE_ENDIAN) {
- meta->capacity =
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+7] << 56) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+6] << 48) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+5] << 40) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+4] << 32) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+3] << 24) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+2] << 16) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+1] << 8) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset]);
- } else {
- meta->capacity =
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset] << 56) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+1] << 48) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+2] << 40) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+3] << 32) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+4] << 24) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+5] << 16) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+6] << 8) |
- ((unsigned long long)head[fileTypeInfo[i].sizeOffset+7]);
- }
- /* Avoid unlikely, but theoretically possible overflow */
- if (meta->capacity > (ULLONG_MAX / fileTypeInfo[i].sizeMultiplier))
- continue;
- meta->capacity *= fileTypeInfo[i].sizeMultiplier;
- }
- if (fileTypeInfo[i].qcowCryptOffset != -1) {
- int crypt_format;
+static int
+virStorageFileGetMetadataFromBuf(int format,
+ const char *path,
+ unsigned char *buf,
+ size_t buflen,
+ virStorageFileMetadata *meta)
+{
+ /* XXX we should consider moving virStorageBackendUpdateVolInfo
+ * code into this method, for non-magic files
+ */
+ if (!fileTypeInfo[format].magic) {
+ return 0;
+ }
- crypt_format = (head[fileTypeInfo[i].qcowCryptOffset] << 24) |
- (head[fileTypeInfo[i].qcowCryptOffset+1] << 16) |
- (head[fileTypeInfo[i].qcowCryptOffset+2] << 8) |
- head[fileTypeInfo[i].qcowCryptOffset+3];
- meta->encrypted = crypt_format != 0;
+ /* Optionally extract capacity from file */
+ if (fileTypeInfo[format].sizeOffset != -1) {
+ if ((fileTypeInfo[format].sizeOffset + 8) > buflen)
+ return 1;
+
+ if (fileTypeInfo[format].endian == LV_LITTLE_ENDIAN) {
+ meta->capacity =
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+7] << 56) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+6] << 48) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+5] << 40) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+4] << 32) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+3] << 24) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+2] << 16) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+1] << 8) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset]);
+ } else {
+ meta->capacity =
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset] << 56) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+1] << 48) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+2] << 40) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+3] << 32) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+4] << 24) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+5] << 16) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+6] << 8) |
+ ((unsigned long long)buf[fileTypeInfo[format].sizeOffset+7]);
}
+ /* Avoid unlikely, but theoretically possible overflow */
+ if (meta->capacity > (ULLONG_MAX / fileTypeInfo[format].sizeMultiplier))
+ return 1;
+ meta->capacity *= fileTypeInfo[format].sizeMultiplier;
+ }
- /* Validation passed, we know the file format now */
- meta->format = i;
- if (fileTypeInfo[i].getBackingStore != NULL) {
- char *backing;
- int backingFormat;
+ if (fileTypeInfo[format].qcowCryptOffset != -1) {
+ int crypt_format;
- switch (fileTypeInfo[i].getBackingStore(&backing,
- &backingFormat,
- head, len)) {
- case BACKING_STORE_OK:
- break;
+ crypt_format =
+ (buf[fileTypeInfo[format].qcowCryptOffset] << 24) |
+ (buf[fileTypeInfo[format].qcowCryptOffset+1] << 16) |
+ (buf[fileTypeInfo[format].qcowCryptOffset+2] << 8) |
+ (buf[fileTypeInfo[format].qcowCryptOffset+3]);
+ meta->encrypted = crypt_format != 0;
+ }
- case BACKING_STORE_INVALID:
- continue;
+ if (fileTypeInfo[format].getBackingStore != NULL) {
+ char *backing;
+ int backingFormat;
+ int ret = fileTypeInfo[format].getBackingStore(&backing,
+ &backingFormat,
+ buf, buflen);
+ if (ret == BACKING_STORE_INVALID)
+ return 1;
+
+ if (ret == BACKING_STORE_ERROR)
+ return -1;
- case BACKING_STORE_ERROR:
+ if (backing != NULL) {
+ meta->backingStore = absolutePathFromBaseFile(path, backing);
+ VIR_FREE(backing);
+ if (meta->backingStore == NULL) {
+ virReportOOMError();
return -1;
}
- if (backing != NULL) {
- meta->backingStore = absolutePathFromBaseFile(path, backing);
- VIR_FREE(backing);
- if (meta->backingStore == NULL) {
- virReportOOMError();
- return -1;
- }
- meta->backingStoreFormat = backingFormat;
- } else {
- meta->backingStoreFormat = VIR_STORAGE_FILE_AUTO;
- }
+ meta->backingStoreFormat = backingFormat;
+ } else {
+ meta->backingStore = NULL;
+ meta->backingStoreFormat = VIR_STORAGE_FILE_AUTO;
+ }
+ }
+
+ return 0;
+}
+
+
+static int
+virStorageFileProbeFormatFromBuf(const char *path,
+ unsigned char *buf,
+ size_t buflen)
+{
+ int format = VIR_STORAGE_FILE_RAW;
+ int i;
+
+ /* First check file magic */
+ for (i = 0 ; i < VIR_STORAGE_FILE_LAST ; i++) {
+ if (virStorageFileMatchesMagic(i, buf, buflen) &&
+ virStorageFileMatchesVersion(i, buf, buflen)) {
+ format = i;
+ goto cleanup;
}
- return 0;
}
/* No magic, so check file extension */
- for (i = 0 ; i < ARRAY_CARDINALITY(fileTypeInfo) ; i++) {
- if (fileTypeInfo[i].extension == NULL)
- continue;
+ for (i = 0 ; i < VIR_STORAGE_FILE_LAST ; i++) {
+ if (virStorageFileMatchesExtension(i, path)) {
+ format = i;
+ goto cleanup;
+ }
+ }
- if (!virFileHasSuffix(path, fileTypeInfo[i].extension))
- continue;
+cleanup:
+ return format;
+}
- meta->format = i;
- return 0;
+
+/**
+ * virStorageFileProbeFormatFromFD:
+ *
+ * Probe for the format of 'fd' (which is an open file descriptor
+ * pointing to 'path'), returning the detected disk format.
+ *
+ * Callers are advised never to trust the returned 'format'
+ * unless it is listed as VIR_STORAGE_FILE_RAW, since a
+ * malicious guest can turn a file into any other non-raw
+ * format at will.
+ *
+ * Best option: Don't use this function
+ */
+int
+virStorageFileProbeFormatFromFD(const char *path, int fd)
+{
+ unsigned char *head;
+ ssize_t len = STORAGE_MAX_HEAD;
+ int ret = -1;
+
+ if (VIR_ALLOC_N(head, len) < 0) {
+ virReportOOMError();
+ return -1;
}
- return 0;
+ if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
+ virReportSystemError(errno, _("cannot set to start of '%s'"), path);
+ goto cleanup;
+ }
+
+ if ((len = read(fd, head, len)) < 0) {
+ virReportSystemError(errno, _("cannot read header '%s'"), path);
+ goto cleanup;
+ }
+
+ ret = virStorageFileProbeFormatFromBuf(path, head, len);
+
+cleanup:
+ VIR_FREE(head);
+ return ret;
+}
+
+
+/**
+ * virStorageFileProbeFormat:
+ *
+ * Probe for the format of 'path', returning the detected
+ * disk format.
+ *
+ * Callers are advised never to trust the returned 'format'
+ * unless it is listed as VIR_STORAGE_FILE_RAW, since a
+ * malicious guest can turn a raw file into any other non-raw
+ * format at will.
+ *
+ * Best option: Don't use this function
+ */
+int
+virStorageFileProbeFormat(const char *path)
+{
+ int fd, ret;
+
+ if ((fd = open(path, O_RDONLY)) < 0) {
+ virReportSystemError(errno, _("cannot open file '%s'"), path);
+ return -1;
+ }
+
+ ret = virStorageFileProbeFormatFromFD(path, fd);
+
+ close(fd);
+
+ return ret;
}
+/**
+ * virStorageFileGetMetadataFromFD:
+ *
+ * Probe for the format of 'fd' (which is an open file descriptor
+ * for the file 'path'), filling 'meta' with the detected
+ * format and other associated metadata.
+ *
+ * Callers are advised never to trust the returned 'meta->format'
+ * unless it is listed as VIR_STORAGE_FILE_RAW, since a
+ * malicious guest can turn a raw file into any other non-raw
+ * format at will.
+ */
+int
+virStorageFileGetMetadataFromFD(const char *path,
+ int fd,
+ virStorageFileMetadata *meta)
+{
+ unsigned char *head;
+ ssize_t len = STORAGE_MAX_HEAD;
+ int ret = -1;
+
+ if (VIR_ALLOC_N(head, len) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ memset(meta, 0, sizeof (*meta));
+
+ if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
+ virReportSystemError(errno, _("cannot set to start of '%s'"), path);
+ goto cleanup;
+ }
+
+ if ((len = read(fd, head, len)) < 0) {
+ virReportSystemError(errno, _("cannot read header '%s'"), path);
+ goto cleanup;
+ }
+
+ meta->format = virStorageFileProbeFormatFromBuf(path, head, len);
+
+ ret = virStorageFileGetMetadataFromBuf(meta->format, path, head, len, meta);
+
+cleanup:
+ VIR_FREE(head);
+ return ret;
+}
+
+/**
+ * virStorageFileGetMetadata:
+ *
+ * Probe for the format of 'path', filling 'meta' with the detected
+ * format and other associated metadata.
+ *
+ * Callers are advised never to trust the returned 'meta->format'
+ * unless it is listed as VIR_STORAGE_FILE_RAW, since a
+ * malicious guest can turn a raw file into any other non-raw
+ * format at will.
+ */
int
virStorageFileGetMetadata(const char *path,
virStorageFileMetadata *meta)
diff --git a/src/util/storage_file.h b/src/util/storage_file.h
index 6328ba7..3420d44 100644
--- a/src/util/storage_file.h
+++ b/src/util/storage_file.h
@@ -57,6 +57,10 @@ typedef struct _virStorageFileMetadata {
# define DEV_BSIZE 512
# endif
+int virStorageFileProbeFormat(const char *path);
+int virStorageFileProbeFormatFromFD(const char *path,
+ int fd);
+
int virStorageFileGetMetadata(const char *path,
virStorageFileMetadata *meta);
int virStorageFileGetMetadataFromFD(const char *path,
--
1.7.1.1

View File

@ -0,0 +1,285 @@
From 726a63a437efd96510ce316bf30d16f213d4db27 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Tue, 15 Jun 2010 16:15:51 +0100
Subject: [PATCH 04/11] Require format to be passed into virStorageFileGetMetadata
Require the disk image to be passed into virStorageFileGetMetadata.
If this is set to VIR_STORAGE_FILE_AUTO, then the format will be
resolved using probing. This makes it easier to control when
probing will be used
* src/qemu/qemu_driver.c, src/qemu/qemu_security_dac.c,
src/security/security_selinux.c, src/security/virt-aa-helper.c:
Set VIR_STORAGE_FILE_AUTO when calling virStorageFileGetMetadata.
* src/storage/storage_backend_fs.c: Probe for disk format before
calling virStorageFileGetMetadata.
* src/util/storage_file.h, src/util/storage_file.c: Remove format
from virStorageFileMeta struct & require it to be passed into
method.
---
src/qemu/qemu_driver.c | 27 +++++++++++++++++---
src/qemu/qemu_security_dac.c | 4 ++-
src/security/security_selinux.c | 4 ++-
src/security/virt-aa-helper.c | 4 ++-
src/storage/storage_backend_fs.c | 11 ++++++--
src/util/storage_file.c | 50 +++++++++++++++++++++++++------------
src/util/storage_file.h | 3 +-
7 files changed, 76 insertions(+), 27 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 487bfa3..97f2990 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3069,7 +3069,9 @@ static int qemuSetupDiskCgroup(virCgroupPtr cgroup,
}
}
- rc = virStorageFileGetMetadata(path, &meta);
+ rc = virStorageFileGetMetadata(path,
+ VIR_STORAGE_FILE_AUTO,
+ &meta);
if (rc < 0)
VIR_WARN("Unable to lookup parent image for %s", path);
@@ -3119,7 +3121,9 @@ static int qemuTeardownDiskCgroup(virCgroupPtr cgroup,
}
}
- rc = virStorageFileGetMetadata(path, &meta);
+ rc = virStorageFileGetMetadata(path,
+ VIR_STORAGE_FILE_AUTO,
+ &meta);
if (rc < 0)
VIR_WARN("Unable to lookup parent image for %s", path);
@@ -9614,6 +9618,7 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
virDomainDiskDefPtr disk = NULL;
struct stat sb;
int i;
+ int format;
virCheckFlags(0, -1);
@@ -9658,7 +9663,21 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
}
/* Probe for magic formats */
- if (virStorageFileGetMetadataFromFD(path, fd, &meta) < 0)
+ if (disk->driverType) {
+ if ((format = virStorageFileFormatTypeFromString(disk->driverType)) < 0) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unknown disk format %s for %s"),
+ disk->driverType, disk->src);
+ goto cleanup;
+ }
+ } else {
+ if ((format = virStorageFileProbeFormat(disk->src)) < 0)
+ goto cleanup;
+ }
+
+ if (virStorageFileGetMetadataFromFD(path, fd,
+ format,
+ &meta) < 0)
goto cleanup;
/* Get info for normal formats */
@@ -9706,7 +9725,7 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
highest allocated extent from QEMU */
if (virDomainObjIsActive(vm) &&
disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK &&
- meta.format != VIR_STORAGE_FILE_RAW &&
+ format != VIR_STORAGE_FILE_RAW &&
S_ISBLK(sb.st_mode)) {
qemuDomainObjPrivatePtr priv = vm->privateData;
if (qemuDomainObjBeginJob(vm) < 0)
diff --git a/src/qemu/qemu_security_dac.c b/src/qemu/qemu_security_dac.c
index 95015b0..acfe48e 100644
--- a/src/qemu/qemu_security_dac.c
+++ b/src/qemu/qemu_security_dac.c
@@ -115,7 +115,9 @@ qemuSecurityDACSetSecurityImageLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED,
virStorageFileMetadata meta;
int ret;
- ret = virStorageFileGetMetadata(path, &meta);
+ ret = virStorageFileGetMetadata(path,
+ VIR_STORAGE_FILE_AUTO,
+ &meta);
if (path != disk->src)
VIR_FREE(path);
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index e5eef19..5c0f002 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -457,7 +457,9 @@ SELinuxSetSecurityImageLabel(virDomainObjPtr vm,
virStorageFileMetadata meta;
int ret;
- ret = virStorageFileGetMetadata(path, &meta);
+ ret = virStorageFileGetMetadata(path,
+ VIR_STORAGE_FILE_AUTO,
+ &meta);
if (path != disk->src)
VIR_FREE(path);
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index c66f107..2c045e6 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -830,7 +830,9 @@ get_files(vahControl * ctl)
do {
virStorageFileMetadata meta;
- ret = virStorageFileGetMetadata(path, &meta);
+ ret = virStorageFileGetMetadata(path,
+ VIR_STORAGE_FILE_AUTO,
+ &meta);
if (path != ctl->def->disks[i]->src)
VIR_FREE(path);
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index f0cd770..d3ac0fe 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -75,14 +75,19 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
memset(&meta, 0, sizeof(meta));
- if (virStorageFileGetMetadataFromFD(target->path, fd, &meta) < 0) {
+ if ((target->format = virStorageFileProbeFormatFromFD(target->path, fd)) < 0) {
close(fd);
return -1;
}
- close(fd);
+ if (virStorageFileGetMetadataFromFD(target->path, fd,
+ target->format,
+ &meta) < 0) {
+ close(fd);
+ return -1;
+ }
- target->format = meta.format;
+ close(fd);
if (backingStore) {
*backingStore = meta.backingStore;
diff --git a/src/util/storage_file.c b/src/util/storage_file.c
index 221268b..9712d92 100644
--- a/src/util/storage_file.c
+++ b/src/util/storage_file.c
@@ -696,18 +696,23 @@ virStorageFileProbeFormat(const char *path)
/**
* virStorageFileGetMetadataFromFD:
*
- * Probe for the format of 'fd' (which is an open file descriptor
- * for the file 'path'), filling 'meta' with the detected
- * format and other associated metadata.
+ * Extract metadata about the storage volume with the specified
+ * image format. If image format is VIR_STORAGE_FILE_AUTO, it
+ * will probe to automatically identify the format.
*
- * Callers are advised never to trust the returned 'meta->format'
- * unless it is listed as VIR_STORAGE_FILE_RAW, since a
- * malicious guest can turn a raw file into any other non-raw
- * format at will.
+ * Callers are advised never to use VIR_STORAGE_FILE_AUTO as a
+ * format, since a malicious guest can turn a raw file into any
+ * other non-raw format at will.
+ *
+ * If the returned meta.backingStoreFormat is VIR_STORAGE_FILE_AUTO
+ * it indicates the image didn't specify an explicit format for its
+ * backing store. Callers are advised against probing for the
+ * backing store format in this case.
*/
int
virStorageFileGetMetadataFromFD(const char *path,
int fd,
+ int format,
virStorageFileMetadata *meta)
{
unsigned char *head;
@@ -731,9 +736,16 @@ virStorageFileGetMetadataFromFD(const char *path,
goto cleanup;
}
- meta->format = virStorageFileProbeFormatFromBuf(path, head, len);
+ if (format == VIR_STORAGE_FILE_AUTO)
+ format = virStorageFileProbeFormatFromBuf(path, head, len);
+
+ if (format < 0 ||
+ format >= VIR_STORAGE_FILE_LAST) {
+ virReportSystemError(EINVAL, _("unknown storage file format %d"), format);
+ return -1;
+ }
- ret = virStorageFileGetMetadataFromBuf(meta->format, path, head, len, meta);
+ ret = virStorageFileGetMetadataFromBuf(format, path, head, len, meta);
cleanup:
VIR_FREE(head);
@@ -743,16 +755,22 @@ cleanup:
/**
* virStorageFileGetMetadata:
*
- * Probe for the format of 'path', filling 'meta' with the detected
- * format and other associated metadata.
+ * Extract metadata about the storage volume with the specified
+ * image format. If image format is VIR_STORAGE_FILE_AUTO, it
+ * will probe to automatically identify the format.
*
- * Callers are advised never to trust the returned 'meta->format'
- * unless it is listed as VIR_STORAGE_FILE_RAW, since a
- * malicious guest can turn a raw file into any other non-raw
- * format at will.
+ * Callers are advised never to use VIR_STORAGE_FILE_AUTO as a
+ * format, since a malicious guest can turn a raw file into any
+ * other non-raw format at will.
+ *
+ * If the returned meta.backingStoreFormat is VIR_STORAGE_FILE_AUTO
+ * it indicates the image didn't specify an explicit format for its
+ * backing store. Callers are advised against probing for the
+ * backing store format in this case.
*/
int
virStorageFileGetMetadata(const char *path,
+ int format,
virStorageFileMetadata *meta)
{
int fd, ret;
@@ -762,7 +780,7 @@ virStorageFileGetMetadata(const char *path,
return -1;
}
- ret = virStorageFileGetMetadataFromFD(path, fd, meta);
+ ret = virStorageFileGetMetadataFromFD(path, fd, format, meta);
close(fd);
diff --git a/src/util/storage_file.h b/src/util/storage_file.h
index 3420d44..6853182 100644
--- a/src/util/storage_file.h
+++ b/src/util/storage_file.h
@@ -46,7 +46,6 @@ enum virStorageFileFormat {
VIR_ENUM_DECL(virStorageFileFormat);
typedef struct _virStorageFileMetadata {
- int format;
char *backingStore;
int backingStoreFormat;
unsigned long long capacity;
@@ -62,9 +61,11 @@ int virStorageFileProbeFormatFromFD(const char *path,
int fd);
int virStorageFileGetMetadata(const char *path,
+ int format,
virStorageFileMetadata *meta);
int virStorageFileGetMetadataFromFD(const char *path,
int fd,
+ int format,
virStorageFileMetadata *meta);
int virStorageFileIsSharedFS(const char *path);
--
1.7.1.1

View File

@ -0,0 +1,170 @@
From ac5067f1e2e98181ee0e9230f756697f50d853eb Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 14 Jun 2010 18:09:15 +0100
Subject: [PATCH 05/11] Add an API for iterating over disk paths
There is duplicated code which iterates over disk backing stores
performing some action. Provide a convenient helper for doing
this to eliminate duplication & risk of mistakes with disk format
probing
* src/conf/domain_conf.c, src/conf/domain_conf.h,
src/libvirt_private.syms: Add virDomainDiskDefForeachPath()
---
src/conf/domain_conf.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 11 +++++
src/libvirt_private.syms | 1 +
3 files changed, 111 insertions(+), 0 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 378c06e..b20ca97 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -45,6 +45,7 @@
#include "macvtap.h"
#include "nwfilter_conf.h"
#include "ignore-value.h"
+#include "storage_file.h"
#define VIR_FROM_THIS VIR_FROM_DOMAIN
@@ -7273,4 +7274,102 @@ done:
}
+int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
+ bool allowProbing,
+ bool ignoreOpenFailure,
+ virDomainDiskDefPathIterator iter,
+ void *opaque)
+{
+ virHashTablePtr paths;
+ int format;
+ int ret = -1;
+ size_t depth = 0;
+ char *nextpath = NULL;
+
+ if (!disk->src)
+ return 0;
+
+ if (disk->driverType) {
+ const char *formatStr = disk->driverType;
+ if (STREQ(formatStr, "aio"))
+ formatStr = "raw"; /* Xen compat */
+
+ if ((format = virStorageFileFormatTypeFromString(formatStr)) < 0) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unknown disk format '%s' for %s"),
+ disk->driverType, disk->src);
+ return -1;
+ }
+ } else {
+ if (allowProbing) {
+ format = VIR_STORAGE_FILE_AUTO;
+ } else {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("no disk format for %s and probing is disabled"),
+ disk->src);
+ return -1;
+ }
+ }
+
+ paths = virHashCreate(5);
+
+ do {
+ virStorageFileMetadata meta;
+ const char *path = nextpath ? nextpath : disk->src;
+ int fd;
+
+ if (iter(disk, path, depth, opaque) < 0)
+ goto cleanup;
+
+ if (virHashLookup(paths, path)) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("backing store for %s is self-referential"),
+ disk->src);
+ goto cleanup;
+ }
+
+ if ((fd = open(path, O_RDONLY)) < 0) {
+ if (ignoreOpenFailure) {
+ char ebuf[1024];
+ VIR_WARN("Ignoring open failure on %s: %s", path,
+ virStrerror(errno, ebuf, sizeof(ebuf)));
+ break;
+ } else {
+ virReportSystemError(errno,
+ _("unable to open disk path %s"),
+ path);
+ goto cleanup;
+ }
+ }
+
+ if (virStorageFileGetMetadataFromFD(path, fd, format, &meta) < 0) {
+ close(fd);
+ goto cleanup;
+ }
+ close(fd);
+
+ if (virHashAddEntry(paths, path, (void*)0x1) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ depth++;
+ nextpath = meta.backingStore;
+
+ format = meta.backingStoreFormat;
+
+ if (format == VIR_STORAGE_FILE_AUTO &&
+ !allowProbing)
+ format = VIR_STORAGE_FILE_RAW; /* Stops further recursion */
+ } while (nextpath);
+
+ ret = 0;
+
+cleanup:
+ virHashFree(paths, NULL);
+ VIR_FREE(nextpath);
+
+ return ret;
+}
+
#endif /* ! PROXY */
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 01da17e..d46869e 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1079,6 +1079,17 @@ int virDomainChrDefForeach(virDomainDefPtr def,
void *opaque);
+typedef int (*virDomainDiskDefPathIterator)(virDomainDiskDefPtr disk,
+ const char *path,
+ size_t depth,
+ void *opaque);
+
+int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
+ bool allowProbing,
+ bool ignoreOpenFailure,
+ virDomainDiskDefPathIterator iter,
+ void *opaque);
+
VIR_ENUM_DECL(virDomainVirt)
VIR_ENUM_DECL(virDomainBoot)
VIR_ENUM_DECL(virDomainFeature)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4607f49..b5f3695 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -225,6 +225,7 @@ virDomainSnapshotDefFormat;
virDomainSnapshotAssignDef;
virDomainObjAssignDef;
virDomainChrDefForeach;
+virDomainDiskDefForeachPath;
# domain_event.h
--
1.7.1.1

View File

@ -0,0 +1,506 @@
From 54c1bb731d2b19a46a594cf9682c022f1e1114d2 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Tue, 15 Jun 2010 16:40:47 +0100
Subject: [PATCH 06/11] Convert all disk backing store loops to shared helper API
Update the QEMU cgroups code, QEMU DAC security driver, SELinux
and AppArmour security drivers over to use the shared helper API
virDomainDiskDefForeachPath().
* src/qemu/qemu_driver.c, src/qemu/qemu_security_dac.c,
src/security/security_selinux.c, src/security/virt-aa-helper.c:
Convert over to use virDomainDiskDefForeachPath()
---
src/qemu/qemu_driver.c | 161 ++++++++++++++++----------------------
src/qemu/qemu_security_dac.c | 47 ++++--------
src/security/security_selinux.c | 67 +++++++----------
src/security/virt-aa-helper.c | 71 ++++++++----------
4 files changed, 142 insertions(+), 204 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 97f2990..99aeffa 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3040,107 +3040,82 @@ static const char *const defaultDeviceACL[] = {
#define DEVICE_PTY_MAJOR 136
#define DEVICE_SND_MAJOR 116
-static int qemuSetupDiskCgroup(virCgroupPtr cgroup,
- virDomainObjPtr vm,
- virDomainDiskDefPtr disk)
-{
- char *path = disk->src;
- int ret = -1;
- while (path != NULL) {
- virStorageFileMetadata meta;
- int rc;
+static int qemuSetupDiskPathAllow(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
+ const char *path,
+ size_t depth ATTRIBUTE_UNUSED,
+ void *opaque)
+{
+ virCgroupPtr cgroup = opaque;
+ int rc;
- VIR_DEBUG("Process path '%s' for disk", path);
- rc = virCgroupAllowDevicePath(cgroup, path);
- if (rc != 0) {
- /* Get this for non-block devices */
- if (rc == -EINVAL) {
- VIR_DEBUG("Ignoring EINVAL for %s", path);
- } else if (rc == -EACCES) { /* Get this for root squash NFS */
- VIR_DEBUG("Ignoring EACCES for %s", path);
- } else {
- virReportSystemError(-rc,
- _("Unable to allow device %s for %s"),
- path, vm->def->name);
- if (path != disk->src)
- VIR_FREE(path);
- goto cleanup;
- }
+ VIR_DEBUG("Process path %s for disk", path);
+ /* XXX RO vs RW */
+ rc = virCgroupAllowDevicePath(cgroup, path);
+ if (rc != 0) {
+ /* Get this for non-block devices */
+ if (rc == -EINVAL) {
+ VIR_DEBUG("Ignoring EINVAL for %s", path);
+ } else if (rc == -EACCES) { /* Get this for root squash NFS */
+ VIR_DEBUG("Ignoring EACCES for %s", path);
+ } else {
+ virReportSystemError(-rc,
+ _("Unable to allow access for disk path %s"),
+ path);
+ return -1;
}
-
- rc = virStorageFileGetMetadata(path,
- VIR_STORAGE_FILE_AUTO,
- &meta);
- if (rc < 0)
- VIR_WARN("Unable to lookup parent image for %s", path);
-
- if (path != disk->src)
- VIR_FREE(path);
- path = NULL;
-
- if (rc < 0)
- break; /* Treating as non fatal */
-
- path = meta.backingStore;
}
+ return 0;
+}
- ret = 0;
-cleanup:
- return ret;
+static int qemuSetupDiskCgroup(virCgroupPtr cgroup,
+ virDomainDiskDefPtr disk)
+{
+ return virDomainDiskDefForeachPath(disk,
+ true,
+ true,
+ qemuSetupDiskPathAllow,
+ cgroup);
}
-static int qemuTeardownDiskCgroup(virCgroupPtr cgroup,
- virDomainObjPtr vm,
- virDomainDiskDefPtr disk)
+static int qemuTeardownDiskPathDeny(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
+ const char *path,
+ size_t depth ATTRIBUTE_UNUSED,
+ void *opaque)
{
- char *path = disk->src;
- int ret = -1;
-
- while (path != NULL) {
- virStorageFileMetadata meta;
- int rc;
+ virCgroupPtr cgroup = opaque;
+ int rc;
- VIR_DEBUG("Process path '%s' for disk", path);
- rc = virCgroupDenyDevicePath(cgroup, path);
- if (rc != 0) {
- /* Get this for non-block devices */
- if (rc == -EINVAL) {
- VIR_DEBUG("Ignoring EINVAL for %s", path);
- } else if (rc == -EACCES) { /* Get this for root squash NFS */
- VIR_DEBUG("Ignoring EACCES for %s", path);
- } else {
- virReportSystemError(-rc,
- _("Unable to deny device %s for %s"),
- path, vm->def->name);
- if (path != disk->src)
- VIR_FREE(path);
- goto cleanup;
- }
+ VIR_DEBUG("Process path %s for disk", path);
+ /* XXX RO vs RW */
+ rc = virCgroupDenyDevicePath(cgroup, path);
+ if (rc != 0) {
+ /* Get this for non-block devices */
+ if (rc == -EINVAL) {
+ VIR_DEBUG("Ignoring EINVAL for %s", path);
+ } else if (rc == -EACCES) { /* Get this for root squash NFS */
+ VIR_DEBUG("Ignoring EACCES for %s", path);
+ } else {
+ virReportSystemError(-rc,
+ _("Unable to allow access for disk path %s"),
+ path);
+ return -1;
}
-
- rc = virStorageFileGetMetadata(path,
- VIR_STORAGE_FILE_AUTO,
- &meta);
- if (rc < 0)
- VIR_WARN("Unable to lookup parent image for %s", path);
-
- if (path != disk->src)
- VIR_FREE(path);
- path = NULL;
-
- if (rc < 0)
- break; /* Treating as non fatal */
-
- path = meta.backingStore;
}
+ return 0;
+}
- ret = 0;
-cleanup:
- return ret;
+static int qemuTeardownDiskCgroup(virCgroupPtr cgroup,
+ virDomainDiskDefPtr disk)
+{
+ return virDomainDiskDefForeachPath(disk,
+ true,
+ true,
+ qemuTeardownDiskPathDeny,
+ cgroup);
}
@@ -3204,7 +3179,7 @@ static int qemuSetupCgroup(struct qemud_driver *driver,
}
for (i = 0; i < vm->def->ndisks ; i++) {
- if (qemuSetupDiskCgroup(cgroup, vm, vm->def->disks[i]) < 0)
+ if (qemuSetupDiskCgroup(cgroup, vm->def->disks[i]) < 0)
goto cleanup;
}
@@ -8035,7 +8010,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
vm->def->name);
goto endjob;
}
- if (qemuSetupDiskCgroup(cgroup, vm, dev->data.disk) < 0)
+ if (qemuSetupDiskCgroup(cgroup, dev->data.disk) < 0)
goto endjob;
}
@@ -8080,7 +8055,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
/* Fallthrough */
}
if (ret != 0 && cgroup) {
- if (qemuTeardownDiskCgroup(cgroup, vm, dev->data.disk) < 0)
+ if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
VIR_WARN("Failed to teardown cgroup for disk path %s",
NULLSTR(dev->data.disk->src));
}
@@ -8280,7 +8255,7 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
vm->def->name);
goto endjob;
}
- if (qemuSetupDiskCgroup(cgroup, vm, dev->data.disk) < 0)
+ if (qemuSetupDiskCgroup(cgroup, dev->data.disk) < 0)
goto endjob;
}
@@ -8303,7 +8278,7 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
}
if (ret != 0 && cgroup) {
- if (qemuTeardownDiskCgroup(cgroup, vm, dev->data.disk) < 0)
+ if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
VIR_WARN("Failed to teardown cgroup for disk path %s",
NULLSTR(dev->data.disk->src));
}
@@ -8430,7 +8405,7 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
if (cgroup != NULL) {
- if (qemuTeardownDiskCgroup(cgroup, vm, dev->data.disk) < 0)
+ if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
VIR_WARN("Failed to teardown cgroup for disk path %s",
NULLSTR(dev->data.disk->src));
}
@@ -8493,7 +8468,7 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
if (cgroup != NULL) {
- if (qemuTeardownDiskCgroup(cgroup, vm, dev->data.disk) < 0)
+ if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
VIR_WARN("Failed to teardown cgroup for disk path %s",
NULLSTR(dev->data.disk->src));
}
diff --git a/src/qemu/qemu_security_dac.c b/src/qemu/qemu_security_dac.c
index acfe48e..770010d 100644
--- a/src/qemu/qemu_security_dac.c
+++ b/src/qemu/qemu_security_dac.c
@@ -98,45 +98,28 @@ err:
static int
+qemuSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
+ const char *path,
+ size_t depth ATTRIBUTE_UNUSED,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ return qemuSecurityDACSetOwnership(path, driver->user, driver->group);
+}
+
+
+static int
qemuSecurityDACSetSecurityImageLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED,
virDomainDiskDefPtr disk)
{
- const char *path;
-
if (!driver->privileged || !driver->dynamicOwnership)
return 0;
- if (!disk->src)
- return 0;
-
- path = disk->src;
- do {
- virStorageFileMetadata meta;
- int ret;
-
- ret = virStorageFileGetMetadata(path,
- VIR_STORAGE_FILE_AUTO,
- &meta);
-
- if (path != disk->src)
- VIR_FREE(path);
- path = NULL;
-
- if (ret < 0)
- return -1;
-
- if (meta.backingStore != NULL &&
- qemuSecurityDACSetOwnership(meta.backingStore,
- driver->user, driver->group) < 0) {
- VIR_FREE(meta.backingStore);
- return -1;
- }
-
- path = meta.backingStore;
- } while (path != NULL);
-
- return qemuSecurityDACSetOwnership(disk->src, driver->user, driver->group);
+ return virDomainDiskDefForeachPath(disk,
+ true,
+ false,
+ qemuSecurityDACSetSecurityFileLabel,
+ NULL);
}
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 5c0f002..d191118 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -439,54 +439,43 @@ SELinuxRestoreSecurityImageLabel(virDomainObjPtr vm,
static int
+SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
+ const char *path,
+ size_t depth,
+ void *opaque)
+{
+ const virSecurityLabelDefPtr secdef = opaque;
+
+ if (depth == 0) {
+ if (disk->shared) {
+ return SELinuxSetFilecon(path, default_image_context);
+ } else if (disk->readonly) {
+ return SELinuxSetFilecon(path, default_content_context);
+ } else if (secdef->imagelabel) {
+ return SELinuxSetFilecon(path, secdef->imagelabel);
+ } else {
+ return 0;
+ }
+ } else {
+ return SELinuxSetFilecon(path, default_content_context);
+ }
+}
+
+static int
SELinuxSetSecurityImageLabel(virDomainObjPtr vm,
virDomainDiskDefPtr disk)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
- const char *path;
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
return 0;
- if (!disk->src)
- return 0;
-
- path = disk->src;
- do {
- virStorageFileMetadata meta;
- int ret;
-
- ret = virStorageFileGetMetadata(path,
- VIR_STORAGE_FILE_AUTO,
- &meta);
-
- if (path != disk->src)
- VIR_FREE(path);
- path = NULL;
-
- if (ret < 0)
- break;
-
- if (meta.backingStore != NULL &&
- SELinuxSetFilecon(meta.backingStore,
- default_content_context) < 0) {
- VIR_FREE(meta.backingStore);
- return -1;
- }
-
- path = meta.backingStore;
- } while (path != NULL);
-
- if (disk->shared) {
- return SELinuxSetFilecon(disk->src, default_image_context);
- } else if (disk->readonly) {
- return SELinuxSetFilecon(disk->src, default_content_context);
- } else if (secdef->imagelabel) {
- return SELinuxSetFilecon(disk->src, secdef->imagelabel);
- }
-
- return 0;
+ return virDomainDiskDefForeachPath(disk,
+ true,
+ false,
+ SELinuxSetSecurityFileLabel,
+ secdef);
}
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 2c045e6..9ed0cd3 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -36,7 +36,6 @@
#include "uuid.h"
#include "hostusb.h"
#include "pci.h"
-#include "storage_file.h"
static char *progname;
@@ -801,6 +800,28 @@ file_iterate_pci_cb(pciDevice *dev ATTRIBUTE_UNUSED,
}
static int
+add_file_path(virDomainDiskDefPtr disk,
+ const char *path,
+ size_t depth,
+ void *opaque)
+{
+ virBufferPtr buf = opaque;
+ int ret;
+
+ if (depth == 0) {
+ if (disk->readonly)
+ ret = vah_add_file(buf, path, "r");
+ else
+ ret = vah_add_file(buf, path, "rw");
+ } else {
+ ret = vah_add_file(buf, path, "r");
+ }
+
+ return ret;
+}
+
+
+static int
get_files(vahControl * ctl)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
@@ -821,45 +842,15 @@ get_files(vahControl * ctl)
goto clean;
}
- for (i = 0; i < ctl->def->ndisks; i++)
- if (ctl->def->disks[i] && ctl->def->disks[i]->src) {
- int ret;
- const char *path;
-
- path = ctl->def->disks[i]->src;
- do {
- virStorageFileMetadata meta;
-
- ret = virStorageFileGetMetadata(path,
- VIR_STORAGE_FILE_AUTO,
- &meta);
-
- if (path != ctl->def->disks[i]->src)
- VIR_FREE(path);
- path = NULL;
-
- if (ret < 0) {
- vah_warning("could not open path, skipping");
- continue;
- }
-
- if (meta.backingStore != NULL &&
- (ret = vah_add_file(&buf, meta.backingStore, "rw")) != 0) {
- VIR_FREE(meta.backingStore);
- goto clean;
- }
-
- path = meta.backingStore;
- } while (path != NULL);
-
- if (ctl->def->disks[i]->readonly)
- ret = vah_add_file(&buf, ctl->def->disks[i]->src, "r");
- else
- ret = vah_add_file(&buf, ctl->def->disks[i]->src, "rw");
-
- if (ret != 0)
- goto clean;
- }
+ for (i = 0; i < ctl->def->ndisks; i++) {
+ int ret = virDomainDiskDefForeachPath(ctl->def->disks[i],
+ true,
+ false,
+ add_file_path,
+ &buf);
+ if (ret != 0)
+ goto clean;
+ }
for (i = 0; i < ctl->def->nserials; i++)
if (ctl->def->serials[i] && ctl->def->serials[i]->data.file.path)
--
1.7.1.1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,468 @@
From dac2b936e77f6c76c11f162e4b175492e4803acb Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Tue, 15 Jun 2010 17:58:58 +0100
Subject: [PATCH 08/11] Disable all disk probing in QEMU driver & add config option to re-enable
Disk format probing is now disabled by default. A new config
option in /etc/qemu/qemu.conf will re-enable it for existing
deployments where this causes trouble
---
src/qemu/libvirtd_qemu.aug | 1 +
src/qemu/qemu.conf | 12 ++++++++++++
src/qemu/qemu_conf.c | 4 ++++
src/qemu/qemu_conf.h | 1 +
src/qemu/qemu_driver.c | 36 +++++++++++++++++++++++-------------
src/qemu/qemu_security_dac.c | 2 +-
src/qemu/test_libvirtd_qemu.aug | 4 ++++
src/security/security_apparmor.c | 12 ++++++++----
src/security/security_driver.c | 16 ++++++++++++++--
src/security/security_driver.h | 10 ++++++++--
src/security/security_selinux.c | 9 ++++++---
src/security/virt-aa-helper.c | 10 +++++++++-
tests/seclabeltest.c | 2 +-
13 files changed, 92 insertions(+), 27 deletions(-)
diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug
index 7c9f271..47d0525 100644
--- a/src/qemu/libvirtd_qemu.aug
+++ b/src/qemu/libvirtd_qemu.aug
@@ -40,6 +40,7 @@ module Libvirtd_qemu =
| bool_entry "relaxed_acs_check"
| bool_entry "vnc_allow_host_audio"
| bool_entry "clear_emulator_capabilities"
+ | bool_entry "allow_disk_format_probing"
(* Each enty in the config is one of the following three ... *)
let entry = vnc_entry
diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index 93934f3..dc8eb83 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -187,3 +187,15 @@
# exploit the privileges and possibly do damage to the host.
#
# clear_emulator_capabilities = 1
+
+
+
+# If allow_disk_format_probing is enabled, libvirt will probe disk
+# images to attempt to identify their format, when not otherwise
+# specified in the XML. This is disabled by default.
+#
+# WARNING: Enabling probing is a security hole in almost all
+# deployments. It is strongly recommended that users update their
+# guest XML <disk> elements to include <driver type='XXXX'/>
+# elements instead of enabling this option.
+# allow_disk_format_probing = 1
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 988220b..3ba48bf 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -365,6 +365,10 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
CHECK_TYPE ("clear_emulator_capabilities", VIR_CONF_LONG);
if (p) driver->clearEmulatorCapabilities = p->l;
+ p = virConfGetValue (conf, "allow_disk_format_probing");
+ CHECK_TYPE ("allow_disk_format_probing", VIR_CONF_LONG);
+ if (p) driver->allowDiskFormatProbing = p->l;
+
virConfFree (conf);
return 0;
}
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index ab5f158..30e9f20 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -141,6 +141,7 @@ struct qemud_driver {
unsigned int relaxedACS : 1;
unsigned int vncAllowHostAudio : 1;
unsigned int clearEmulatorCapabilities : 1;
+ unsigned int allowDiskFormatProbing : 1;
virCapsPtr caps;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 616547c..3c479c5 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1322,7 +1322,8 @@ qemudSecurityInit(struct qemud_driver *qemud_drv)
qemuSecurityDACSetDriver(qemud_drv);
ret = virSecurityDriverStartup(&security_drv,
- qemud_drv->securityDriverName);
+ qemud_drv->securityDriverName,
+ qemud_drv->allowDiskFormatProbing);
if (ret == -1) {
VIR_ERROR0(_("Failed to start security driver"));
return -1;
@@ -3070,11 +3071,12 @@ static int qemuSetupDiskPathAllow(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
}
-static int qemuSetupDiskCgroup(virCgroupPtr cgroup,
+static int qemuSetupDiskCgroup(struct qemud_driver *driver,
+ virCgroupPtr cgroup,
virDomainDiskDefPtr disk)
{
return virDomainDiskDefForeachPath(disk,
- true,
+ driver->allowDiskFormatProbing,
true,
qemuSetupDiskPathAllow,
cgroup);
@@ -3109,11 +3111,12 @@ static int qemuTeardownDiskPathDeny(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
}
-static int qemuTeardownDiskCgroup(virCgroupPtr cgroup,
+static int qemuTeardownDiskCgroup(struct qemud_driver *driver,
+ virCgroupPtr cgroup,
virDomainDiskDefPtr disk)
{
return virDomainDiskDefForeachPath(disk,
- true,
+ driver->allowDiskFormatProbing,
true,
qemuTeardownDiskPathDeny,
cgroup);
@@ -3180,7 +3183,7 @@ static int qemuSetupCgroup(struct qemud_driver *driver,
}
for (i = 0; i < vm->def->ndisks ; i++) {
- if (qemuSetupDiskCgroup(cgroup, vm->def->disks[i]) < 0)
+ if (qemuSetupDiskCgroup(driver, cgroup, vm->def->disks[i]) < 0)
goto cleanup;
}
@@ -8033,7 +8036,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
vm->def->name);
goto endjob;
}
- if (qemuSetupDiskCgroup(cgroup, dev->data.disk) < 0)
+ if (qemuSetupDiskCgroup(driver, cgroup, dev->data.disk) < 0)
goto endjob;
}
@@ -8078,7 +8081,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
/* Fallthrough */
}
if (ret != 0 && cgroup) {
- if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
+ if (qemuTeardownDiskCgroup(driver, cgroup, dev->data.disk) < 0)
VIR_WARN("Failed to teardown cgroup for disk path %s",
NULLSTR(dev->data.disk->src));
}
@@ -8278,7 +8281,7 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
vm->def->name);
goto endjob;
}
- if (qemuSetupDiskCgroup(cgroup, dev->data.disk) < 0)
+ if (qemuSetupDiskCgroup(driver, cgroup, dev->data.disk) < 0)
goto endjob;
}
@@ -8301,7 +8304,7 @@ static int qemuDomainUpdateDeviceFlags(virDomainPtr dom,
}
if (ret != 0 && cgroup) {
- if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
+ if (qemuTeardownDiskCgroup(driver, cgroup, dev->data.disk) < 0)
VIR_WARN("Failed to teardown cgroup for disk path %s",
NULLSTR(dev->data.disk->src));
}
@@ -8429,7 +8432,7 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver,
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
if (cgroup != NULL) {
- if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
+ if (qemuTeardownDiskCgroup(driver, cgroup, dev->data.disk) < 0)
VIR_WARN("Failed to teardown cgroup for disk path %s",
NULLSTR(dev->data.disk->src));
}
@@ -8493,7 +8496,7 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
if (cgroup != NULL) {
- if (qemuTeardownDiskCgroup(cgroup, dev->data.disk) < 0)
+ if (qemuTeardownDiskCgroup(driver, cgroup, dev->data.disk) < 0)
VIR_WARN("Failed to teardown cgroup for disk path %s",
NULLSTR(dev->data.disk->src));
}
@@ -9672,8 +9675,15 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
goto cleanup;
}
} else {
- if ((format = virStorageFileProbeFormat(disk->src)) < 0)
+ if (driver->allowDiskFormatProbing) {
+ if ((format = virStorageFileProbeFormat(disk->src)) < 0)
+ goto cleanup;
+ } else {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("no disk format for %s and probing is disabled"),
+ disk->src);
goto cleanup;
+ }
}
if (virStorageFileGetMetadataFromFD(path, fd,
diff --git a/src/qemu/qemu_security_dac.c b/src/qemu/qemu_security_dac.c
index 0bbcf69..55dc0c6 100644
--- a/src/qemu/qemu_security_dac.c
+++ b/src/qemu/qemu_security_dac.c
@@ -117,7 +117,7 @@ qemuSecurityDACSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
return 0;
return virDomainDiskDefForeachPath(disk,
- true,
+ driver->allowDiskFormatProbing,
false,
qemuSecurityDACSetSecurityFileLabel,
NULL);
diff --git a/src/qemu/test_libvirtd_qemu.aug b/src/qemu/test_libvirtd_qemu.aug
index 3326cc5..f0c4a0d 100644
--- a/src/qemu/test_libvirtd_qemu.aug
+++ b/src/qemu/test_libvirtd_qemu.aug
@@ -101,6 +101,8 @@ relaxed_acs_check = 1
vnc_allow_host_audio = 1
clear_emulator_capabilities = 0
+
+allow_disk_format_probing = 1
"
test Libvirtd_qemu.lns get conf =
@@ -212,3 +214,5 @@ clear_emulator_capabilities = 0
{ "vnc_allow_host_audio" = "1" }
{ "#empty" }
{ "clear_emulator_capabilities" = "0" }
+{ "#empty" }
+{ "allow_disk_format_probing" = "1" }
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index cb5c739..c5f9829 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -157,6 +157,8 @@ load_profile(virSecurityDriverPtr drv,
char *xml = NULL;
int pipefd[2];
pid_t child;
+ const char *probe = virSecurityDriverGetAllowDiskFormatProbing(drv)
+ ? "1" : "0";
if (pipe(pipefd) < -1) {
virReportSystemError(errno, "%s", _("unable to create pipe"));
@@ -172,19 +174,19 @@ load_profile(virSecurityDriverPtr drv,
if (create) {
const char *const argv[] = {
- VIRT_AA_HELPER, "-c", "-u", profile, NULL
+ VIRT_AA_HELPER, "-p", probe, "-c", "-u", profile, NULL
};
ret = virExec(argv, NULL, NULL, &child,
pipefd[0], NULL, NULL, VIR_EXEC_NONE);
} else if (fn) {
const char *const argv[] = {
- VIRT_AA_HELPER, "-r", "-u", profile, "-f", fn, NULL
+ VIRT_AA_HELPER, "-p", probe, "-r", "-u", profile, "-f", fn, NULL
};
ret = virExec(argv, NULL, NULL, &child,
pipefd[0], NULL, NULL, VIR_EXEC_NONE);
} else {
const char *const argv[] = {
- VIRT_AA_HELPER, "-r", "-u", profile, NULL
+ VIRT_AA_HELPER, "-p", probe, "-r", "-u", profile, NULL
};
ret = virExec(argv, NULL, NULL, &child,
pipefd[0], NULL, NULL, VIR_EXEC_NONE);
@@ -347,9 +349,11 @@ AppArmorSecurityDriverProbe(void)
* currently not used.
*/
static int
-AppArmorSecurityDriverOpen(virSecurityDriverPtr drv)
+AppArmorSecurityDriverOpen(virSecurityDriverPtr drv,
+ bool allowDiskFormatProbing)
{
virSecurityDriverSetDOI(drv, SECURITY_APPARMOR_VOID_DOI);
+ virSecurityDriverSetAllowDiskFormatProbing(drv, allowDiskFormatProbing);
return 0;
}
diff --git a/src/security/security_driver.c b/src/security/security_driver.c
index aac9f78..9e32fa4 100644
--- a/src/security/security_driver.c
+++ b/src/security/security_driver.c
@@ -56,7 +56,8 @@ virSecurityDriverVerify(virDomainDefPtr def)
int
virSecurityDriverStartup(virSecurityDriverPtr *drv,
- const char *name)
+ const char *name,
+ bool allowDiskFormatProbing)
{
unsigned int i;
@@ -72,7 +73,7 @@ virSecurityDriverStartup(virSecurityDriverPtr *drv,
switch (tmp->probe()) {
case SECURITY_DRIVER_ENABLE:
virSecurityDriverInit(tmp);
- if (tmp->open(tmp) == -1) {
+ if (tmp->open(tmp, allowDiskFormatProbing) == -1) {
return -1;
} else {
*drv = tmp;
@@ -125,3 +126,14 @@ virSecurityDriverGetModel(virSecurityDriverPtr drv)
{
return drv->name;
}
+
+void virSecurityDriverSetAllowDiskFormatProbing(virSecurityDriverPtr drv,
+ bool allowDiskFormatProbing)
+{
+ drv->_private.allowDiskFormatProbing = allowDiskFormatProbing;
+}
+
+bool virSecurityDriverGetAllowDiskFormatProbing(virSecurityDriverPtr drv)
+{
+ return drv->_private.allowDiskFormatProbing;
+}
diff --git a/src/security/security_driver.h b/src/security/security_driver.h
index 61c9eb0..d768f32 100644
--- a/src/security/security_driver.h
+++ b/src/security/security_driver.h
@@ -33,7 +33,8 @@ typedef struct _virSecurityDriverState virSecurityDriverState;
typedef virSecurityDriverState *virSecurityDriverStatePtr;
typedef virSecurityDriverStatus (*virSecurityDriverProbe) (void);
-typedef int (*virSecurityDriverOpen) (virSecurityDriverPtr drv);
+typedef int (*virSecurityDriverOpen) (virSecurityDriverPtr drv,
+ bool allowDiskFormatProbing);
typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityDriverPtr drv,
virDomainObjPtr vm,
virDomainDiskDefPtr disk);
@@ -102,12 +103,14 @@ struct _virSecurityDriver {
*/
struct {
char doi[VIR_SECURITY_DOI_BUFLEN];
+ bool allowDiskFormatProbing;
} _private;
};
/* Global methods */
int virSecurityDriverStartup(virSecurityDriverPtr *drv,
- const char *name);
+ const char *name,
+ bool allowDiskFormatProbing);
int
virSecurityDriverVerify(virDomainDefPtr def);
@@ -120,7 +123,10 @@ virSecurityDriverVerify(virDomainDefPtr def);
void virSecurityDriverInit(virSecurityDriverPtr drv);
int virSecurityDriverSetDOI(virSecurityDriverPtr drv,
const char *doi);
+void virSecurityDriverSetAllowDiskFormatProbing(virSecurityDriverPtr drv,
+ bool allowDiskFormatProbing);
const char *virSecurityDriverGetDOI(virSecurityDriverPtr drv);
const char *virSecurityDriverGetModel(virSecurityDriverPtr drv);
+bool virSecurityDriverGetAllowDiskFormatProbing(virSecurityDriverPtr drv);
#endif /* __VIR_SECURITY_H__ */
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index cc3812b..a9dd836 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -266,13 +266,15 @@ SELinuxSecurityDriverProbe(void)
}
static int
-SELinuxSecurityDriverOpen(virSecurityDriverPtr drv)
+SELinuxSecurityDriverOpen(virSecurityDriverPtr drv,
+ bool allowDiskFormatProbing)
{
/*
* Where will the DOI come from? SELinux configuration, or qemu
* configuration? For the moment, we'll just set it to "0".
*/
virSecurityDriverSetDOI(drv, SECURITY_SELINUX_VOID_DOI);
+ virSecurityDriverSetAllowDiskFormatProbing(drv, allowDiskFormatProbing);
return SELinuxInitialize();
}
@@ -467,18 +469,19 @@ SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
}
static int
-SELinuxSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxSetSecurityImageLabel(virSecurityDriverPtr drv,
virDomainObjPtr vm,
virDomainDiskDefPtr disk)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+ bool allowDiskFormatProbing = virSecurityDriverGetAllowDiskFormatProbing(drv);
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
return 0;
return virDomainDiskDefForeachPath(disk,
- true,
+ allowDiskFormatProbing,
false,
SELinuxSetSecurityFileLabel,
secdef);
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 9ed0cd3..521545d 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -40,6 +40,7 @@
static char *progname;
typedef struct {
+ bool allowDiskFormatProbing;
char uuid[PROFILE_NAME_SIZE]; /* UUID of vm */
bool dryrun; /* dry run */
char cmd; /* 'c' create
@@ -844,7 +845,7 @@ get_files(vahControl * ctl)
for (i = 0; i < ctl->def->ndisks; i++) {
int ret = virDomainDiskDefForeachPath(ctl->def->disks[i],
- true,
+ ctl->allowDiskFormatProbing,
false,
add_file_path,
&buf);
@@ -943,6 +944,7 @@ vahParseArgv(vahControl * ctl, int argc, char **argv)
{
int arg, idx = 0;
struct option opt[] = {
+ {"probing", 1, 0, 'p' },
{"add", 0, 0, 'a'},
{"create", 0, 0, 'c'},
{"dryrun", 0, 0, 'd'},
@@ -991,6 +993,12 @@ vahParseArgv(vahControl * ctl, int argc, char **argv)
PROFILE_NAME_SIZE) == NULL)
vah_error(ctl, 1, "error copying UUID");
break;
+ case 'p':
+ if (STREQ(optarg, "1"))
+ ctl->allowDiskFormatProbing = true;
+ else
+ ctl->allowDiskFormatProbing = false;
+ break;
default:
vah_error(ctl, 1, "unsupported option");
break;
diff --git a/tests/seclabeltest.c b/tests/seclabeltest.c
index 26d1f86..ef3f026 100644
--- a/tests/seclabeltest.c
+++ b/tests/seclabeltest.c
@@ -15,7 +15,7 @@ main (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
const char *doi, *model;
virSecurityDriverPtr security_drv;
- ret = virSecurityDriverStartup (&security_drv, "selinux");
+ ret = virSecurityDriverStartup (&security_drv, "selinux", false);
if (ret == -1)
{
fprintf (stderr, "Failed to start security driver");
--
1.7.1.1

View File

@ -0,0 +1,94 @@
From 3534cd47a57ee9cf7041472511444784f14d6939 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 14 Jun 2010 16:08:55 +0100
Subject: [PATCH 09/11] Add ability to set a default driver name/type when parsing disks
Record a default driver name/type in capabilities struct. Use this
when parsing disks if value is not set in XML config.
* src/conf/capabilities.h: Record default driver name/type for disks
* src/conf/domain_conf.c: Fallback to default driver name/type
when parsing disks
* src/qemu/qemu_driver.c: Set default driver name/type to raw
---
src/conf/capabilities.h | 2 ++
src/conf/domain_conf.c | 16 +++++++++++++++-
src/qemu/qemu_driver.c | 8 ++++++++
3 files changed, 25 insertions(+), 1 deletions(-)
diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h
index 9290c82..f676eb8 100644
--- a/src/conf/capabilities.h
+++ b/src/conf/capabilities.h
@@ -123,6 +123,8 @@ struct _virCaps {
virCapsGuestPtr *guests;
unsigned char macPrefix[VIR_MAC_PREFIX_BUFLEN];
unsigned int emulatorRequired : 1;
+ const char *defaultDiskDriverName;
+ const char *defaultDiskDriverType;
void *(*privateDataAllocFunc)(void);
void (*privateDataFreeFunc)(void *);
int (*privateDataXMLFormat)(virBufferPtr, void *);
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b20ca97..f3b8cfa 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1639,6 +1639,16 @@ virDomainDiskDefParseXML(virCapsPtr caps,
def->serial = serial;
serial = NULL;
+ if (!def->driverType &&
+ caps->defaultDiskDriverType &&
+ !(def->driverType = strdup(caps->defaultDiskDriverType)))
+ goto no_memory;
+
+ if (!def->driverName &&
+ caps->defaultDiskDriverName &&
+ !(def->driverName = strdup(caps->defaultDiskDriverName)))
+ goto no_memory;
+
if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE
&& virDomainDiskDefAssignAddress(caps, def) < 0)
goto error;
@@ -1659,6 +1669,9 @@ cleanup:
return def;
+no_memory:
+ virReportOOMError();
+
error:
virDomainDiskDefFree(def);
def = NULL;
@@ -4275,7 +4288,8 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
if (n && VIR_ALLOC_N(def->disks, n) < 0)
goto no_memory;
for (i = 0 ; i < n ; i++) {
- virDomainDiskDefPtr disk = virDomainDiskDefParseXML(caps, nodes[i],
+ virDomainDiskDefPtr disk = virDomainDiskDefParseXML(caps,
+ nodes[i],
flags);
if (!disk)
goto error;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 3c479c5..14b790e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1357,6 +1357,14 @@ qemuCreateCapabilities(virCapsPtr oldcaps,
return NULL;
}
+ if (driver->allowDiskFormatProbing) {
+ caps->defaultDiskDriverName = NULL;
+ caps->defaultDiskDriverType = NULL;
+ } else {
+ caps->defaultDiskDriverName = "qemu";
+ caps->defaultDiskDriverType = "raw";
+ }
+
/* Domain XML parser hooks */
caps->privateDataAllocFunc = qemuDomainObjPrivateAlloc;
caps->privateDataFreeFunc = qemuDomainObjPrivateFree;
--
1.7.1.1

View File

@ -0,0 +1,291 @@
From 2ba8625d6d148fa489586efabdfaf2ef20903762 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Wed, 16 Jun 2010 14:14:05 +0100
Subject: [PATCH 10/11] Rewrite qemu-img backing store format handling
When creating qcow2 files with a backing store, it is important
to set an explicit format to prevent QEMU probing. The storage
backend was only doing this if it found a 'kvm-img' binary. This
is wrong because plenty of kvm-img binaries don't support an
explicit format, and plenty of 'qemu-img' binaries do support
a format. The result was that most qcow2 files were not getting
a backing store format.
This patch runs 'qemu-img -h' to check for the two support
argument formats
'-o backing_format=raw'
'-F raw'
and use whichever option it finds
* src/storage/storage_backend.c: Query binary to determine
how to set the backing store format
---
src/storage/storage_backend.c | 214 +++++++++++++++++++++++++++++------------
1 files changed, 152 insertions(+), 62 deletions(-)
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index aba8937..c185693 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -561,6 +561,69 @@ static int virStorageBackendCreateExecCommand(virStoragePoolObjPtr pool,
return 0;
}
+enum {
+ QEMU_IMG_BACKING_FORMAT_NONE = 0,
+ QEMU_IMG_BACKING_FORMAT_FLAG,
+ QEMU_IMG_BACKING_FORMAT_OPTIONS,
+};
+
+static int virStorageBackendQEMUImgBackingFormat(const char *qemuimg)
+{
+ const char *const qemuarg[] = { qemuimg, "-h", NULL };
+ const char *const qemuenv[] = { "LC_ALL=C", NULL };
+ pid_t child = 0;
+ int status;
+ int newstdout = -1;
+ char *help = NULL;
+ enum { MAX_HELP_OUTPUT_SIZE = 1024*8 };
+ int len;
+ char *start;
+ char *end;
+ char *tmp;
+ int ret = -1;
+
+ if (virExec(qemuarg, qemuenv, NULL,
+ &child, -1, &newstdout, NULL, VIR_EXEC_CLEAR_CAPS) < 0)
+ goto cleanup;
+
+ if ((len = virFileReadLimFD(newstdout, MAX_HELP_OUTPUT_SIZE, &help)) < 0) {
+ virReportSystemError(errno,
+ _("Unable to read '%s -h' output"),
+ qemuimg);
+ goto cleanup;
+ }
+
+ start = strstr(help, " create ");
+ end = strstr(start, "\n");
+ if ((tmp = strstr(start, "-F fmt")) && tmp < end)
+ ret = QEMU_IMG_BACKING_FORMAT_FLAG;
+ else if ((tmp = strstr(start, "[-o options]")) && tmp < end)
+ ret = QEMU_IMG_BACKING_FORMAT_OPTIONS;
+ else
+ ret = QEMU_IMG_BACKING_FORMAT_NONE;
+
+cleanup:
+ VIR_FREE(help);
+ close(newstdout);
+rewait:
+ if (child) {
+ if (waitpid(child, &status, 0) != child) {
+ if (errno == EINTR)
+ goto rewait;
+
+ VIR_ERROR(_("Unexpected exit status from qemu %d pid %lu"),
+ WEXITSTATUS(status), (unsigned long)child);
+ }
+ if (WEXITSTATUS(status) != 0) {
+ VIR_WARN("Unexpected exit status '%d', qemu probably failed",
+ WEXITSTATUS(status));
+ }
+ }
+
+ return ret;
+}
+
+
static int
virStorageBackendCreateQemuImg(virConnectPtr conn,
virStoragePoolObjPtr pool,
@@ -568,10 +631,9 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
virStorageVolDefPtr inputvol,
unsigned int flags ATTRIBUTE_UNUSED)
{
- int ret;
+ int ret = -1;
char size[100];
char *create_tool;
- short use_kvmimg;
const char *type = virStorageFileFormatTypeToString(vol->target.format);
const char *backingType = vol->backingStore.path ?
@@ -582,41 +644,10 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
const char *inputPath = inputvol ? inputvol->target.path : NULL;
/* Treat input block devices as 'raw' format */
const char *inputType = inputPath ?
- virStorageFileFormatTypeToString(inputvol->type == VIR_STORAGE_VOL_BLOCK ? VIR_STORAGE_FILE_RAW : inputvol->target.format) :
- NULL;
-
- const char **imgargv;
- /* The extra NULL field is for indicating encryption (-e). */
- const char *imgargvnormal[] = {
- NULL, "create",
- "-f", type,
- vol->target.path,
- size,
- NULL,
- NULL
- };
- /* Extra NULL fields are for including "backingType" when using
- * kvm-img (-F backingType), and for indicating encryption (-e).
- */
- const char *imgargvbacking[] = {
- NULL, "create",
- "-f", type,
- "-b", vol->backingStore.path,
- vol->target.path,
- size,
- NULL,
- NULL,
- NULL,
- NULL
- };
- const char *convargv[] = {
- NULL, "convert",
- "-f", inputType,
- "-O", type,
- inputPath,
- vol->target.path,
- NULL,
- };
+ virStorageFileFormatTypeToString(inputvol->type == VIR_STORAGE_VOL_BLOCK ?
+ VIR_STORAGE_FILE_RAW :
+ inputvol->target.format) :
+ NULL;
if (type == NULL) {
virStorageReportError(VIR_ERR_INTERNAL_ERROR,
@@ -690,44 +721,103 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
}
}
- if ((create_tool = virFindFileInPath("kvm-img")) != NULL)
- use_kvmimg = 1;
- else if ((create_tool = virFindFileInPath("qemu-img")) != NULL)
- use_kvmimg = 0;
- else {
+ /* Size in KB */
+ snprintf(size, sizeof(size), "%lluK", vol->capacity/1024);
+
+ /* KVM is usually ahead of qemu on features, so try that first */
+ create_tool = virFindFileInPath("kvm-img");
+ if (!create_tool)
+ create_tool = virFindFileInPath("qemu-img");
+
+ if (!create_tool) {
virStorageReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("unable to find kvm-img or qemu-img"));
return -1;
}
if (inputvol) {
- convargv[0] = create_tool;
- imgargv = convargv;
+ const char *imgargv[] = {
+ create_tool,
+ "convert",
+ "-f", inputType,
+ "-O", type,
+ inputPath,
+ vol->target.path,
+ NULL,
+ };
+
+ ret = virStorageBackendCreateExecCommand(pool, vol, imgargv);
} else if (vol->backingStore.path) {
- imgargvbacking[0] = create_tool;
- if (use_kvmimg) {
- imgargvbacking[6] = "-F";
- imgargvbacking[7] = backingType;
- imgargvbacking[8] = vol->target.path;
- imgargvbacking[9] = size;
+ const char *imgargv[] = {
+ create_tool,
+ "create",
+ "-f", type,
+ "-b", vol->backingStore.path,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+ int imgformat = virStorageBackendQEMUImgBackingFormat(create_tool);
+ char *optflag = NULL;
+ if (imgformat < 0)
+ goto cleanup;
+
+ switch (imgformat) {
+ case QEMU_IMG_BACKING_FORMAT_FLAG:
+ imgargv[6] = "-F";
+ imgargv[7] = backingType;
+ imgargv[8] = vol->target.path;
+ imgargv[9] = size;
+ if (vol->target.encryption != NULL)
+ imgargv[10] = "-e";
+ break;
+
+ case QEMU_IMG_BACKING_FORMAT_OPTIONS:
+ if (virAsprintf(&optflag, "backing_fmt=%s", backingType) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ imgargv[6] = "-o";
+ imgargv[7] = optflag;
+ imgargv[8] = vol->target.path;
+ imgargv[9] = size;
if (vol->target.encryption != NULL)
- imgargvbacking[10] = "-e";
- } else if (vol->target.encryption != NULL)
- imgargvbacking[8] = "-e";
- imgargv = imgargvbacking;
+ imgargv[10] = "-e";
+ break;
+
+ default:
+ VIR_INFO("Unable to set backing store format for %s with %s",
+ vol->target.path, create_tool);
+ imgargv[6] = vol->target.path;
+ imgargv[7] = size;
+ if (vol->target.encryption != NULL)
+ imgargv[8] = "-e";
+ }
+
+ ret = virStorageBackendCreateExecCommand(pool, vol, imgargv);
+ VIR_FREE(optflag);
} else {
- imgargvnormal[0] = create_tool;
- imgargv = imgargvnormal;
+ /* The extra NULL field is for indicating encryption (-e). */
+ const char *imgargv[] = {
+ create_tool,
+ "create",
+ "-f", type,
+ vol->target.path,
+ size,
+ NULL,
+ NULL
+ };
if (vol->target.encryption != NULL)
imgargv[6] = "-e";
- }
+ ret = virStorageBackendCreateExecCommand(pool, vol, imgargv);
+ }
- /* Size in KB */
- snprintf(size, sizeof(size), "%lluK", vol->capacity/1024);
-
- ret = virStorageBackendCreateExecCommand(pool, vol, imgargv);
- VIR_FREE(imgargv[0]);
+ cleanup:
+ VIR_FREE(create_tool);
return ret;
}
--
1.7.1.1

View File

@ -0,0 +1,165 @@
From d33f44c2e74de28c89b64cdc2c0a6564662e075c Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Fri, 9 Jul 2010 11:28:40 +0100
Subject: [PATCH 11/11] Use the extract backing store format in storage volume lookup
The storage volume lookup code was probing for the backing store
format, instead of using the format extracted from the file
itself. This meant it could report in accurate information. If
a format is included in the file, then use that in preference,
with probing as a fallback.
* src/storage/storage_backend_fs.c: Use extracted backing store
format
---
src/storage/storage_backend_fs.c | 80 +++++++++++++++++---------------------
1 files changed, 36 insertions(+), 44 deletions(-)
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index d3ac0fe..ffb0071 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -51,6 +51,7 @@
static int
virStorageBackendProbeTarget(virStorageVolTargetPtr target,
char **backingStore,
+ int *backingStoreFormat,
unsigned long long *allocation,
unsigned long long *capacity,
virStorageEncryptionPtr *encryption)
@@ -58,6 +59,10 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
int fd, ret;
virStorageFileMetadata meta;
+ if (backingStore)
+ *backingStore = NULL;
+ if (backingStoreFormat)
+ *backingStoreFormat = VIR_STORAGE_FILE_AUTO;
if (encryption)
*encryption = NULL;
@@ -89,22 +94,30 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
close(fd);
- if (backingStore) {
- *backingStore = meta.backingStore;
- meta.backingStore = NULL;
+ if (meta.backingStore) {
+ if (backingStore) {
+ *backingStore = meta.backingStore;
+ meta.backingStore = NULL;
+ if (meta.backingStoreFormat == VIR_STORAGE_FILE_AUTO) {
+ if ((*backingStoreFormat = virStorageFileProbeFormat(*backingStore)) < 0) {
+ close(fd);
+ goto cleanup;
+ }
+ } else {
+ *backingStoreFormat = meta.backingStoreFormat;
+ }
+ } else {
+ VIR_FREE(meta.backingStore);
+ }
}
- VIR_FREE(meta.backingStore);
-
if (capacity && meta.capacity)
*capacity = meta.capacity;
if (encryption != NULL && meta.encrypted) {
if (VIR_ALLOC(*encryption) < 0) {
virReportOOMError();
- if (backingStore)
- VIR_FREE(*backingStore);
- return -1;
+ goto cleanup;
}
switch (target->format) {
@@ -124,6 +137,11 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
}
return 0;
+
+cleanup:
+ if (backingStore)
+ VIR_FREE(*backingStore);
+ return -1;
}
#if WITH_STORAGE_FS
@@ -585,6 +603,7 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED,
while ((ent = readdir(dir)) != NULL) {
int ret;
char *backingStore;
+ int backingStoreFormat;
if (VIR_ALLOC(vol) < 0)
goto no_memory;
@@ -604,6 +623,7 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED,
if ((ret = virStorageBackendProbeTarget(&vol->target,
&backingStore,
+ &backingStoreFormat,
&vol->allocation,
&vol->capacity,
&vol->target.encryption)) < 0) {
@@ -619,46 +639,18 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED,
}
if (backingStore != NULL) {
- if (vol->target.format == VIR_STORAGE_FILE_QCOW2 &&
- STRPREFIX("fmt:", backingStore)) {
- char *fmtstr = backingStore + 4;
- char *path = strchr(fmtstr, ':');
- if (!path) {
- VIR_FREE(backingStore);
- } else {
- *path = '\0';
- if ((vol->backingStore.format =
- virStorageFileFormatTypeFromString(fmtstr)) < 0) {
- VIR_FREE(backingStore);
- } else {
- memmove(backingStore, path, strlen(path) + 1);
- vol->backingStore.path = backingStore;
-
- if (virStorageBackendUpdateVolTargetInfo(&vol->backingStore,
- NULL,
- NULL) < 0)
- VIR_FREE(vol->backingStore);
- }
- }
- } else {
- vol->backingStore.path = backingStore;
-
- if ((ret = virStorageBackendProbeTarget(&vol->backingStore,
- NULL, NULL, NULL,
- NULL)) < 0) {
- if (ret == -1)
- goto cleanup;
- else {
- /* Silently ignore non-regular files,
- * eg '.' '..', 'lost+found' */
- VIR_FREE(vol->backingStore);
- }
- }
+ vol->backingStore.path = backingStore;
+ vol->backingStore.format = backingStoreFormat;
+
+ if (virStorageBackendUpdateVolTargetInfo(&vol->backingStore,
+ NULL,
+ NULL) < 0) {
+ VIR_FREE(vol->backingStore.path);
+ goto cleanup;
}
}
-
if (VIR_REALLOC_N(pool->volumes.objs,
pool->volumes.count+1) < 0)
goto no_memory;
--
1.7.1.1

View File

@ -0,0 +1,265 @@
From 112a309bc7839e95c558b535143f855ce89cca8c Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Thu, 10 Jun 2010 12:50:38 -0400
Subject: [PATCH] CVE-2010-2242 Apply a source port mapping to virtual network masquerading
IPtables will seek to preserve the source port unchanged when
doing masquerading, if possible. NFS has a pseudo-security
option where it checks for the source port <= 1023 before
allowing a mount request. If an admin has used this to make the
host OS trusted for mounts, the default iptables behaviour will
potentially allow NAT'd guests access too. This needs to be
stopped.
With this change, the iptables -t nat -L -n -v rules for the
default network will be
Chain POSTROUTING (policy ACCEPT 95 packets, 9163 bytes)
pkts bytes target prot opt in out source destination
14 840 MASQUERADE tcp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
75 5752 MASQUERADE udp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
0 0 MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24
* src/network/bridge_driver.c: Add masquerade rules for TCP
and UDP protocols
* src/util/iptables.c, src/util/iptables.c: Add source port
mappings for TCP & UDP protocols when masquerading.
---
src/network/bridge_driver.c | 73 ++++++++++++++++++++++++++++++++++++++++--
src/util/iptables.c | 70 +++++++++++++++++++++++++++++------------
src/util/iptables.h | 6 ++-
3 files changed, 122 insertions(+), 27 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 72255c1..80ed57a 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -638,18 +638,74 @@ networkAddMasqueradingIptablesRules(struct network_driver *driver,
goto masqerr2;
}
- /* enable masquerading */
+ /*
+ * Enable masquerading.
+ *
+ * We need to end up with 3 rules in the table in this order
+ *
+ * 1. protocol=tcp with sport mapping restricton
+ * 2. protocol=udp with sport mapping restricton
+ * 3. generic any protocol
+ *
+ * The sport mappings are required, because default IPtables
+ * MASQUERADE is maintain port number unchanged where possible.
+ *
+ * NFS can be configured to only "trust" port numbers < 1023.
+ *
+ * Guests using NAT thus need to be prevented from having port
+ * numbers < 1023, otherwise they can bypass the NFS "security"
+ * check on the source port number.
+ *
+ * Since we use '--insert' to add rules to the header of the
+ * chain, we actually need to add them in the reverse of the
+ * order just mentioned !
+ */
+
+ /* First the generic masquerade rule for other protocols */
if ((err = iptablesAddForwardMasquerade(driver->iptables,
network->def->network,
- network->def->forwardDev))) {
+ network->def->forwardDev,
+ NULL))) {
virReportSystemError(err,
_("failed to add iptables rule to enable masquerading to '%s'"),
network->def->forwardDev ? network->def->forwardDev : NULL);
goto masqerr3;
}
+ /* UDP with a source port restriction */
+ if ((err = iptablesAddForwardMasquerade(driver->iptables,
+ network->def->network,
+ network->def->forwardDev,
+ "udp"))) {
+ virReportSystemError(err,
+ _("failed to add iptables rule to enable UDP masquerading to '%s'"),
+ network->def->forwardDev ? network->def->forwardDev : NULL);
+ goto masqerr4;
+ }
+
+ /* TCP with a source port restriction */
+ if ((err = iptablesAddForwardMasquerade(driver->iptables,
+ network->def->network,
+ network->def->forwardDev,
+ "tcp"))) {
+ virReportSystemError(err,
+ _("failed to add iptables rule to enable TCP masquerading to '%s'"),
+ network->def->forwardDev ? network->def->forwardDev : NULL);
+ goto masqerr5;
+ }
+
return 1;
+ masqerr5:
+ iptablesRemoveForwardMasquerade(driver->iptables,
+ network->def->network,
+ network->def->forwardDev,
+ "udp");
+ masqerr4:
+ iptablesRemoveForwardMasquerade(driver->iptables,
+ network->def->network,
+ network->def->forwardDev,
+ NULL);
masqerr3:
iptablesRemoveForwardAllowRelatedIn(driver->iptables,
network->def->network,
@@ -814,8 +870,17 @@ networkRemoveIptablesRules(struct network_driver *driver,
if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE) {
if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT) {
iptablesRemoveForwardMasquerade(driver->iptables,
- network->def->network,
- network->def->forwardDev);
+ network->def->network,
+ network->def->forwardDev,
+ "tcp");
+ iptablesRemoveForwardMasquerade(driver->iptables,
+ network->def->network,
+ network->def->forwardDev,
+ "udp");
+ iptablesRemoveForwardMasquerade(driver->iptables,
+ network->def->network,
+ network->def->forwardDev,
+ NULL);
iptablesRemoveForwardAllowRelatedIn(driver->iptables,
network->def->network,
network->def->bridge,
diff --git a/src/util/iptables.c b/src/util/iptables.c
index d06b857..f63e8c6 100644
--- a/src/util/iptables.c
+++ b/src/util/iptables.c
@@ -692,25 +692,49 @@ iptablesRemoveForwardRejectIn(iptablesContext *ctx,
*/
static int
iptablesForwardMasquerade(iptablesContext *ctx,
- const char *network,
- const char *physdev,
- int action)
+ const char *network,
+ const char *physdev,
+ const char *protocol,
+ int action)
{
- if (physdev && physdev[0]) {
- return iptablesAddRemoveRule(ctx->nat_postrouting,
- action,
- "--source", network,
- "!", "--destination", network,
- "--out-interface", physdev,
- "--jump", "MASQUERADE",
- NULL);
+ if (protocol && protocol[0]) {
+ if (physdev && physdev[0]) {
+ return iptablesAddRemoveRule(ctx->nat_postrouting,
+ action,
+ "--source", network,
+ "-p", protocol,
+ "!", "--destination", network,
+ "--out-interface", physdev,
+ "--jump", "MASQUERADE",
+ "--to-ports", "1024-65535",
+ NULL);
+ } else {
+ return iptablesAddRemoveRule(ctx->nat_postrouting,
+ action,
+ "--source", network,
+ "-p", protocol,
+ "!", "--destination", network,
+ "--jump", "MASQUERADE",
+ "--to-ports", "1024-65535",
+ NULL);
+ }
} else {
- return iptablesAddRemoveRule(ctx->nat_postrouting,
- action,
- "--source", network,
- "!", "--destination", network,
- "--jump", "MASQUERADE",
- NULL);
+ if (physdev && physdev[0]) {
+ return iptablesAddRemoveRule(ctx->nat_postrouting,
+ action,
+ "--source", network,
+ "!", "--destination", network,
+ "--out-interface", physdev,
+ "--jump", "MASQUERADE",
+ NULL);
+ } else {
+ return iptablesAddRemoveRule(ctx->nat_postrouting,
+ action,
+ "--source", network,
+ "!", "--destination", network,
+ "--jump", "MASQUERADE",
+ NULL);
+ }
}
}
@@ -719,6 +743,7 @@ iptablesForwardMasquerade(iptablesContext *ctx,
* @ctx: pointer to the IP table context
* @network: the source network name
* @physdev: the physical input device or NULL
+ * @protocol: the network protocol or NULL
*
* Add rules to the IP table context to allow masquerading
* network @network on @physdev. This allow the bridge to
@@ -729,9 +754,10 @@ iptablesForwardMasquerade(iptablesContext *ctx,
int
iptablesAddForwardMasquerade(iptablesContext *ctx,
const char *network,
- const char *physdev)
+ const char *physdev,
+ const char *protocol)
{
- return iptablesForwardMasquerade(ctx, network, physdev, ADD);
+ return iptablesForwardMasquerade(ctx, network, physdev, protocol, ADD);
}
/**
@@ -739,6 +765,7 @@ iptablesAddForwardMasquerade(iptablesContext *ctx,
* @ctx: pointer to the IP table context
* @network: the source network name
* @physdev: the physical input device or NULL
+ * @protocol: the network protocol or NULL
*
* Remove rules from the IP table context to stop masquerading
* network @network on @physdev. This stops the bridge from
@@ -749,7 +776,8 @@ iptablesAddForwardMasquerade(iptablesContext *ctx,
int
iptablesRemoveForwardMasquerade(iptablesContext *ctx,
const char *network,
- const char *physdev)
+ const char *physdev,
+ const char *protocol)
{
- return iptablesForwardMasquerade(ctx, network, physdev, REMOVE);
+ return iptablesForwardMasquerade(ctx, network, physdev, protocol, REMOVE);
}
diff --git a/src/util/iptables.h b/src/util/iptables.h
index 7d55a6d..b47d854 100644
--- a/src/util/iptables.h
+++ b/src/util/iptables.h
@@ -85,9 +85,11 @@ int iptablesRemoveForwardRejectIn (iptablesContext *ctx,
int iptablesAddForwardMasquerade (iptablesContext *ctx,
const char *network,
- const char *physdev);
+ const char *physdev,
+ const char *protocol);
int iptablesRemoveForwardMasquerade (iptablesContext *ctx,
const char *network,
- const char *physdev);
+ const char *physdev,
+ const char *protocol);
#endif /* __QEMUD_IPTABLES_H__ */
--
1.6.6.1

View File

@ -1,34 +0,0 @@
From bcd4180124afa20580d720912e2179b3a2f9295a Mon Sep 17 00:00:00 2001
From: Daniel Veillard <veillard@redhat.com>
Date: Mon, 5 Oct 2009 17:03:14 +0200
Subject: [PATCH] 526769 change logrotate config default to weekly
* daemon/libvirtd.logrotate.in: change to weekly rotation of logs,
keep a month worth of data and also extend to cover LXC and UML
domain logs
(cherry picked from commit 529325bbdd050af89bda5a5c1a01b5553c49a57e)
Fedora-patch: libvirt-change-logrotate-config-to-weekly.patch
---
qemud/libvirtd.logrotate.in | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/qemud/libvirtd.logrotate.in b/qemud/libvirtd.logrotate.in
index 9b42630..093651c 100644
--- a/qemud/libvirtd.logrotate.in
+++ b/qemud/libvirtd.logrotate.in
@@ -1,7 +1,7 @@
-@localstatedir@/log/libvirt/qemu/*.log {
- daily
+@localstatedir@/log/libvirt/qemu/*.log @localstatedir@/log/libvirt/uml/*.log @localstatedir@/log/libvirt/lxc/*.log {
+ weekly
missingok
- rotate 7
+ rotate 4
compress
delaycompress
copytruncate
--
1.6.2.5

View File

@ -1,77 +0,0 @@
From 4721ceb9b85daabe53804627473b06ced821c695 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 14 Sep 2009 11:23:20 +0100
Subject: [PATCH] Allow control over QEMU audio backend
When using VNC for graphics + keyboard + mouse, we shouldn't
then use the host OS for audio. Audio should go back over
VNC.
When using SDL for graphics, we should use the host OS for
audio since that's where the display is. We need to allow
certain QEMU env variables to be passed through to guest
too to allow choice of QEMU audio backend.
* qemud/libvirtd.sysconf: Mention QEMU/SDL audio env vars
* src/qemu_conf.c: Passthrough QEMU/SDL audio env for SDL display,
disable host audio for VNC display
(cherry picked from commit b08e6d38ae7a0ed70300d7d82107f83fddb60f44)
Fedora-patch: libvirt-disable-audio-backend.patch
---
qemud/libvirtd.sysconf | 8 ++++++++
src/qemu_conf.c | 14 ++++++++++++++
2 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/qemud/libvirtd.sysconf b/qemud/libvirtd.sysconf
index fe4596a..28080a0 100644
--- a/qemud/libvirtd.sysconf
+++ b/qemud/libvirtd.sysconf
@@ -7,3 +7,11 @@
# Override Kerberos service keytab for SASL/GSSAPI
#KRB5_KTNAME=/etc/libvirt/krb5.tab
+
+# Override the QEMU/SDL default audio driver probing when
+# starting virtual machines using SDL graphics
+#
+# NB these have no effect for VMs using VNC
+#QEMU_AUDIO_DRV=sdl
+#
+#SDL_AUDIODRIVER=pulse
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index f92bcef..0dd0624 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -2109,6 +2109,13 @@ int qemudBuildCommandLine(virConnectPtr conn,
ADD_ARG_LIT("-k");
ADD_ARG_LIT(def->graphics[0]->data.vnc.keymap);
}
+
+ /* QEMU implements a VNC extension for providing audio, so we
+ * set the audio backend to none, to prevent it opening the
+ * host OS audio devices since that causes security issues
+ * and is non-sensical when using VNC.
+ */
+ ADD_ENV_LIT("QEMU_AUDIO_DRV=none");
} else if ((def->ngraphics == 1) &&
def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
char *xauth = NULL;
@@ -2131,6 +2138,13 @@ int qemudBuildCommandLine(virConnectPtr conn,
ADD_ENV(display);
if (def->graphics[0]->data.sdl.fullscreen)
ADD_ARG_LIT("-full-screen");
+
+ /* If using SDL for video, then we should just let it
+ * use QEMU's host audio drivers, possibly SDL too
+ * User can set these two before starting libvirtd
+ */
+ ADD_ENV_COPY("QEMU_AUDIO_DRV");
+ ADD_ENV_COPY("SDL_AUDIODRIVER");
}
if (def->nvideos) {
--
1.6.2.5

File diff suppressed because it is too large Load Diff

View File

@ -1,31 +0,0 @@
From a5fa9f63fcffbf70465386672f24edac439866b9 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Thu, 24 Sep 2009 15:42:25 +0100
Subject: [PATCH] Fix crash in device hotplug cleanup code
* src/qemu/qemu_driver.c: Fix crash in scenario where XML
parsing of hotplugged device failed & thus 'dev' is NULL
(cherry picked from commit 879cd8cc2ba00f795913f296556e05f25afa7877)
Fedora-patch: libvirt-fix-crash-on-device-hotplug-parse-error.patch
---
src/qemu_driver.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 0ce403c..c956258 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -5912,7 +5912,7 @@ cleanup:
if (cgroup)
virCgroupFree(&cgroup);
- if (ret < 0) {
+ if (ret < 0 && dev != NULL) {
if (qemuDomainSetDeviceOwnership(dom->conn, driver, dev, 1) < 0)
VIR_WARN0("Fail to restore disk device ownership");
virDomainDeviceDefFree(dev);
--
1.6.2.5

View File

@ -1,33 +0,0 @@
From 7bc1491deba6338e514504d1b68fe097e7f2bf19 Mon Sep 17 00:00:00 2001
From: Daniel Veillard <veillard@redhat.com>
Date: Thu, 1 Oct 2009 11:54:38 +0200
Subject: [PATCH] Avoid a libvirtd crash on broken input 523418
* src/conf/domain_conf.c: a simple typo in an XML domain file could lead
to a crash, because we called STRPREFIX() on the looked up value without
checking it was non-null.
(cherry picked from commit 79d233b5ca62f86ab22d271d1f08ec20060eee88)
Fedora-patch: libvirt-fix-crash-on-missing-iface-target-dev.patch
---
src/domain_conf.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/src/domain_conf.c b/src/domain_conf.c
index c424c67..476cdd7 100644
--- a/src/domain_conf.c
+++ b/src/domain_conf.c
@@ -1031,7 +1031,8 @@ virDomainNetDefParseXML(virConnectPtr conn,
} else if ((ifname == NULL) &&
xmlStrEqual(cur->name, BAD_CAST "target")) {
ifname = virXMLPropString(cur, "dev");
- if (STRPREFIX((const char*)ifname, "vnet")) {
+ if ((ifname != NULL) &&
+ (STRPREFIX((const char*)ifname, "vnet"))) {
/* An auto-generated target name, blank it out */
VIR_FREE(ifname);
}
--
1.6.2.5

View File

@ -1,29 +0,0 @@
From 58c38896a67c170063401d8091bae7dca8842923 Mon Sep 17 00:00:00 2001
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 23 Sep 2009 18:46:23 +0200
Subject: [PATCH] Fix a typo in virDiskHasValidPciAddr()
(cherry-picked from commit 3620e3cdcfe56cc4475b5ef1a0a893757240b795)
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Fedora-patch: libvirt-fix-device-detach-typo1.patch
---
src/domain_conf.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/domain_conf.h b/src/domain_conf.h
index 09368d9..d494e54 100644
--- a/src/domain_conf.h
+++ b/src/domain_conf.h
@@ -125,7 +125,7 @@ struct _virDomainDiskDef {
static inline int
virDiskHasValidPciAddr(virDomainDiskDefPtr def)
{
- return def->pci_addr.domain || def->pci_addr.domain || def->pci_addr.slot;
+ return def->pci_addr.domain || def->pci_addr.bus || def->pci_addr.slot;
}
--
1.6.2.5

View File

@ -1,30 +0,0 @@
From 81e967c716ce8c085be8baad9169f7772452d187 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Thu, 24 Sep 2009 08:55:55 +0100
Subject: [PATCH] Fix a typo in virNetHasValidPciAddr() too
* src/domain_conf.h: check domain/bus/slot, not domain/domain/slot
(cherry-picked from commit 6bfffce91635bb08de601747e94ed1182c0f47eb)
Fedora-patch: libvirt-fix-device-detach-typo2.patch
---
src/domain_conf.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/domain_conf.h b/src/domain_conf.h
index d494e54..7c918a7 100644
--- a/src/domain_conf.h
+++ b/src/domain_conf.h
@@ -207,7 +207,7 @@ struct _virDomainNetDef {
static inline int
virNetHasValidPciAddr(virDomainNetDefPtr def)
{
- return def->pci_addr.domain || def->pci_addr.domain || def->pci_addr.slot;
+ return def->pci_addr.domain || def->pci_addr.bus || def->pci_addr.slot;
}
enum virDomainChrSrcType {
--
1.6.2.5

View File

@ -1,30 +0,0 @@
From 3a64779ec5a89d38d64e07bca2b11b19e1882d7a Mon Sep 17 00:00:00 2001
From: Charles Duffy <charles@dyfis.net>
Date: Thu, 24 Sep 2009 09:00:24 +0100
Subject: [PATCH] Fix unitialized variable in qemudDomainDetachHostPciDevice()
* src/qemu_driver.c: initialize detach var
(cherry-picked from commit 580ad29288751234bee47ac9f6c04dac1dc529ea)
Fedora-patch: libvirt-fix-device-detach-typo3.patch
---
src/qemu_driver.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 7c7b985..550a59c 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -6126,7 +6126,7 @@ static int qemudDomainDetachHostPciDevice(virConnectPtr conn,
virDomainObjPtr vm,
virDomainDeviceDefPtr dev)
{
- virDomainHostdevDefPtr detach;
+ virDomainHostdevDefPtr detach = NULL;
char *cmd, *reply;
int i, ret;
pciDevice *pci;
--
1.6.2.5

View File

@ -1,32 +0,0 @@
From 7692e1e19487c28454b1e5f6488d5574c70883f2 Mon Sep 17 00:00:00 2001
From: Chris Lalancette <clalance@redhat.com>
Date: Mon, 21 Sep 2009 14:53:31 +0200
Subject: [PATCH] Don't do virSetConnError when virDrvSupportsFeature is successful.
Signed-off-by: Chris Lalancette <clalance@redhat.com>
Fedora-patch: libvirt-fix-drv-supports-feature-bogus-error.patch
---
src/libvirt.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index 4a11688..fa59dc7 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -1349,8 +1349,11 @@ virDrvSupportsFeature (virConnectPtr conn, int feature)
}
ret = VIR_DRV_SUPPORTS_FEATURE (conn->driver, conn, feature);
- /* Copy to connection error object for back compatability */
- virSetConnError(conn);
+
+ if (ret < 0)
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+
return ret;
}
--
1.6.2.5

View File

@ -1,79 +0,0 @@
From 71de8d92f20a9a9ee76d4d5df77ff477f1b7d441 Mon Sep 17 00:00:00 2001
From: Matthias Bolte <matthias.bolte@googlemail.com>
Date: Wed, 30 Sep 2009 02:17:27 +0200
Subject: [PATCH] Fix memory leaks in libvirtd's message processing
Commit 47cab734995fa9521b1df05d37e9978eedd8d3a2 changed the way how
qemud_client_message objects were reused. Before this commit
remoteDispatchClientRequest() reused the received message for normal responses
and to report non-fatal errors. If a fatal error occurred qemudWorker() frees
the message. After this commit non-fatal errors are reported by
remoteSerializeReplyError() using a new qemud_client_message object and the
original message leaks.
To fix this leak the original message has to be freed if
remoteSerializeReplyError() succeeds. If remoteSerializeReplyError()
fails the original message is freed in qemudWorker().
* daemon/dispatch.c: free qemud_client_message objects that will not be reused
and would leak otherwise, also free the allocated qemud_client_message object
in remoteSerializeError() if an error occurs
(cherry-picked from commit c6f1459eb998619ab21a92d9bb87341f26978181)
Fedora-patch: libvirt-fix-libvirtd-leak-in-error-reply.patch
---
qemud/dispatch.c | 15 +++++++++++++--
1 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/qemud/dispatch.c b/qemud/dispatch.c
index a60f2f4..ddb3215 100644
--- a/qemud/dispatch.c
+++ b/qemud/dispatch.c
@@ -191,6 +191,7 @@ remoteSerializeError(struct qemud_client *client,
xdr_error:
xdr_destroy(&xdr);
+ VIR_FREE(msg);
fatal_error:
xdr_free((xdrproc_t)xdr_remote_error, (char *)rerr);
return -1;
@@ -336,6 +337,7 @@ remoteDispatchClientRequest (struct qemud_server *server,
struct qemud_client *client,
struct qemud_client_message *msg)
{
+ int ret;
remote_error rerr;
memset(&rerr, 0, sizeof rerr);
@@ -364,7 +366,12 @@ remoteDispatchClientRequest (struct qemud_server *server,
}
error:
- return remoteSerializeReplyError(client, &rerr, &msg->hdr);
+ ret = remoteSerializeReplyError(client, &rerr, &msg->hdr);
+
+ if (ret >= 0)
+ VIR_FREE(msg);
+
+ return ret;
}
@@ -521,8 +528,12 @@ remoteDispatchClientCall (struct qemud_server *server,
rpc_error:
/* Semi-bad stuff happened, we can still try to send back
* an RPC error message to client */
- return remoteSerializeReplyError(client, &rerr, &msg->hdr);
+ rv = remoteSerializeReplyError(client, &rerr, &msg->hdr);
+
+ if (rv >= 0)
+ VIR_FREE(msg);
+ return rv;
xdr_error:
/* Seriously bad stuff happened, so we'll kill off this client
--
1.6.2.5

View File

@ -1,46 +0,0 @@
From ba585ed6cff624c6c0f1f9801382fd6846466ee0 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Thu, 17 Sep 2009 15:31:08 +0100
Subject: [PATCH] Fix net/disk hot-unplug segfault
When we hot-unplug the last device, we're currently double-freeing
the device definition.
Reported by Michal Nowak here:
https://bugzilla.redhat.com/523953
* src/qemu_driver.c: fix double free
(cherry-picked from commit 8881ae1bf8783006777429403cc543c33187175d)
Fedora-patch: libvirt-fix-net-hotunplug-double-free.patch
---
src/qemu_driver.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index a65334f..de31581 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -5998,7 +5998,7 @@ try_command:
/* ignore, harmless */
}
} else {
- VIR_FREE(vm->def->disks[0]);
+ VIR_FREE(vm->def->disks);
vm->def->ndisks = 0;
}
virDomainDiskDefFree(detach);
@@ -6100,7 +6100,7 @@ qemudDomainDetachNetDevice(virConnectPtr conn,
/* ignore, harmless */
}
} else {
- VIR_FREE(vm->def->nets[0]);
+ VIR_FREE(vm->def->nets);
vm->def->nnets = 0;
}
virDomainNetDefFree(detach);
--
1.6.2.5

View File

@ -1,50 +0,0 @@
From 17831d20051f8de8f1f7d661e8a23f4fe67c2153 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Thu, 17 Sep 2009 15:32:45 +0100
Subject: [PATCH] Fix leak in PCI hostdev hot-unplug
* src/qemu_driver.c: sync the hostdev hot-unplug code with the disk/net
code.
(cherry-picked from commit a70da51ff76ed860bfc0cdee2e1d556da997c557)
Fedora-patch: libvirt-fix-pci-hostdev-hotunplug-leak.patch
---
src/qemu_driver.c | 20 +++++++++++++-------
1 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index de31581..2ddcdc0 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -6206,14 +6206,20 @@ static int qemudDomainDetachHostPciDevice(virConnectPtr conn,
pciFreeDevice(conn, pci);
}
- if (i != --vm->def->nhostdevs)
- memmove(&vm->def->hostdevs[i],
- &vm->def->hostdevs[i+1],
- sizeof(*vm->def->hostdevs) * (vm->def->nhostdevs-i));
- if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs) < 0) {
- virReportOOMError(conn);
- ret = -1;
+ if (vm->def->nhostdevs > 1) {
+ memmove(vm->def->hostdevs + i,
+ vm->def->hostdevs + i + 1,
+ sizeof(*vm->def->hostdevs) *
+ (vm->def->nhostdevs - (i + 1)));
+ vm->def->nhostdevs--;
+ if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs) < 0) {
+ /* ignore, harmless */
+ }
+ } else {
+ VIR_FREE(vm->def->hostdevs);
+ vm->def->nhostdevs = 0;
}
+ virDomainHostdevDefFree(detach);
return ret;
}
--
1.6.2.5

View File

@ -1,53 +0,0 @@
From f1be5a4714e194a84840343e0937fe62463a18dc Mon Sep 17 00:00:00 2001
From: Charles Duffy <Charles_Duffy@dell.com>
Date: Fri, 18 Sep 2009 11:32:35 -0500
Subject: [PATCH] Prevent attempt to call cat -c during virDomainSave to raw
Fedora-patch: libvirt-fix-qemu-raw-format-save.patch
---
src/qemu_driver.c | 28 ++++++++++++++++++----------
1 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 2ddcdc0..7c7b985 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -3905,17 +3905,25 @@ static int qemudDomainSave(virDomainPtr dom,
goto cleanup;
}
- const char *prog = qemudSaveCompressionTypeToString(header.compressed);
- if (prog == NULL) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
- _("Invalid compress format %d"), header.compressed);
- goto cleanup;
- }
+ {
+ const char *prog = qemudSaveCompressionTypeToString(header.compressed);
+ const char *args;
- if (STREQ (prog, "raw"))
- prog = "cat";
- internalret = virAsprintf(&command, "migrate \"exec:"
- "%s -c >> '%s' 2>/dev/null\"", prog, safe_path);
+ if (prog == NULL) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Invalid compress format %d"), header.compressed);
+ goto cleanup;
+ }
+
+ if (STREQ (prog, "raw")) {
+ prog = "cat";
+ args = "";
+ } else {
+ args = "-c";
+ }
+ internalret = virAsprintf(&command, "migrate \"exec:"
+ "%s %s >> '%s' 2>/dev/null\"", prog, args, safe_path);
+ }
if (internalret < 0) {
virReportOOMError(dom->conn);
--
1.6.2.5

View File

@ -1,38 +0,0 @@
From 0b846a30468a6b4586407f020ccde7bb51afaf98 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 12 Oct 2009 20:03:50 +0100
Subject: [PATCH] Fix QEMU restore from file in raw format
The logic for running the decompression programs was broken in
commit f238709304f9f6c57204cdd943e542cbae38fa5f, so that for
non-raw formats the decompression program was never run, and
for raw formats, it tried to exec an argv[] with initial NULL
in the program name.
* src/qemu/qemu_driver.c: Fix logic in runing decompression program
(cherry picked from commit 74b379cbd5ba9f472a3a2d5710e497966b1a3a37)
Fedora-patch: libvirt-fix-qemu-restore-from-raw1.patch
---
src/qemu_driver.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 550a59c..0ce403c 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -4541,9 +4541,8 @@ static int qemudDomainRestore(virConnectPtr conn,
goto cleanup;
}
- if (header.compressed != QEMUD_SAVE_FORMAT_RAW)
+ if (header.compressed != QEMUD_SAVE_FORMAT_RAW) {
intermediate_argv[0] = prog;
- else {
intermediatefd = fd;
fd = -1;
if (virExec(conn, intermediate_argv, NULL, NULL,
--
1.6.2.5

View File

@ -1,120 +0,0 @@
From 57d7cc602d14c6b50e2826e427a5de124e479f95 Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berrange@redhat.com>
Date: Mon, 12 Oct 2009 20:32:33 +0100
Subject: [PATCH] Fix virFileReadLimFD/virFileReadAll to handle EINTR
The fread_file_lim() function uses fread() but never handles
EINTR results, causing unexpected failures when reading QEMU
help arg info. It was unneccessarily using FILE * instead
of plain UNIX file handles, which prevented use of saferead()
* src/util/util.c: Switch fread_file_lim over to use saferead
instead of fread, remove FILE * use, and rename
(cherry picked from commit 11a36d956cb8a5e439e535bff3e0cfce50a64bca)
Fedora-patch: libvirt-fix-qemu-restore-from-raw2.patch
---
src/util.c | 45 ++++++++++++---------------------------------
1 files changed, 12 insertions(+), 33 deletions(-)
diff --git a/src/util.c b/src/util.c
index 1878e33..7bc3a66 100644
--- a/src/util.c
+++ b/src/util.c
@@ -887,7 +887,7 @@ virExec(virConnectPtr conn,
number of bytes. If the length of the input is <= max_len, and
upon error while reading that data, it works just like fread_file. */
static char *
-fread_file_lim (FILE *stream, size_t max_len, size_t *length)
+saferead_lim (int fd, size_t max_len, size_t *length)
{
char *buf = NULL;
size_t alloc = 0;
@@ -895,8 +895,8 @@ fread_file_lim (FILE *stream, size_t max_len, size_t *length)
int save_errno;
for (;;) {
- size_t count;
- size_t requested;
+ int count;
+ int requested;
if (size + BUFSIZ + 1 > alloc) {
alloc += alloc / 2;
@@ -912,12 +912,12 @@ fread_file_lim (FILE *stream, size_t max_len, size_t *length)
/* Ensure that (size + requested <= max_len); */
requested = MIN (size < max_len ? max_len - size : 0,
alloc - size - 1);
- count = fread (buf + size, 1, requested, stream);
+ count = saferead (fd, buf + size, requested);
size += count;
if (count != requested || requested == 0) {
save_errno = errno;
- if (ferror (stream))
+ if (count < 0)
break;
buf[size] = '\0';
*length = size;
@@ -930,12 +930,12 @@ fread_file_lim (FILE *stream, size_t max_len, size_t *length)
return NULL;
}
-/* A wrapper around fread_file_lim that maps a failure due to
+/* A wrapper around saferead_lim that maps a failure due to
exceeding the maximum size limitation to EOVERFLOW. */
-static int virFileReadLimFP(FILE *fp, int maxlen, char **buf)
+int virFileReadLimFD(int fd, int maxlen, char **buf)
{
size_t len;
- char *s = fread_file_lim (fp, maxlen+1, &len);
+ char *s = saferead_lim (fd, maxlen+1, &len);
if (s == NULL)
return -1;
if (len > maxlen || (int)len != len) {
@@ -949,37 +949,16 @@ static int virFileReadLimFP(FILE *fp, int maxlen, char **buf)
return len;
}
-/* Like virFileReadLimFP, but use a file descriptor rather than a FILE*. */
-int virFileReadLimFD(int fd_arg, int maxlen, char **buf)
-{
- int fd = dup (fd_arg);
- if (fd >= 0) {
- FILE *fp = fdopen (fd, "r");
- if (fp) {
- int len = virFileReadLimFP (fp, maxlen, buf);
- int saved_errno = errno;
- fclose (fp);
- errno = saved_errno;
- return len;
- } else {
- int saved_errno = errno;
- close (fd);
- errno = saved_errno;
- }
- }
- return -1;
-}
-
int virFileReadAll(const char *path, int maxlen, char **buf)
{
- FILE *fh = fopen(path, "r");
- if (fh == NULL) {
+ int fd = open(path, O_RDONLY);
+ if (fd < 0) {
virReportSystemError(NULL, errno, _("Failed to open file '%s'"), path);
return -1;
}
- int len = virFileReadLimFP (fh, maxlen, buf);
- fclose(fh);
+ int len = virFileReadLimFD(fd, maxlen, buf);
+ close(fd);
if (len < 0) {
virReportSystemError(NULL, errno, _("Failed to read file '%s'"), path);
return -1;
--
1.6.2.5

View File

@ -1,41 +0,0 @@
From 6b12148864cf6a1d22a2cf4e0e9c48e9946331cb Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Wed, 30 Sep 2009 18:37:03 +0100
Subject: [PATCH] Fix USB device re-labelling
A simple misplaced break out of a switch results in:
libvir: error : Failed to open file '/sys/bus/pci/devices/0000:00:54c./vendor': No such file or directory
libvir: error : Failed to open file '/sys/bus/pci/devices/0000:00:54c./device': No such file or directory
libvir: error : this function is not supported by the hypervisor: Failed to read product/vendor ID for 0000:00:54c.
when trying to passthrough a USB host device to qemu.
* src/security_selinux.c: fix a switch/break thinko
Fedora-patch: libvirt-fix-usb-device-passthrough.patch
---
src/security_selinux.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/src/security_selinux.c b/src/security_selinux.c
index bc295b1..b4dc153 100644
--- a/src/security_selinux.c
+++ b/src/security_selinux.c
@@ -464,12 +464,11 @@ SELinuxSetSecurityHostdevLabel(virConnectPtr conn,
ret = usbDeviceFileIterate(conn, usb, SELinuxSetSecurityUSBLabel, vm);
usbFreeDevice(conn, usb);
-
- break;
} else {
/* XXX deal with product/vendor better */
ret = 0;
}
+ break;
}
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
--
1.6.2.5

View File

@ -1,103 +0,0 @@
From cab81502320d97dac4c5c12e7496f30896709c49 Mon Sep 17 00:00:00 2001
From: Matthias Bolte <matthias.bolte@googlemail.com>
Date: Tue, 22 Sep 2009 15:12:48 +0200
Subject: [PATCH] Fix xen driver refcounting.
The commit cb51aa48a777ddae6997faa9f28350cb62655ffd "Fix up connection
reference counting." changed the driver closing and virConnectPtr
unref-logic in virConnectClose().
Before this commit virConnectClose() closed all drivers of the given
virConnectPtr and virUnrefConnect()'ed it afterwards. After this
commit the driver-closing is done in virUnrefConnect() if and only if
the ref-count of the virConnectPtr dropped to zero.
This change in execution order leads to a virConnectPtr leak, at least
for connections to Xen.
The relevant call sequences:
virConnectOpen() -> xenUnifiedOpen() ...
... xenInotifyOpen() -> virConnectRef(conn)
... xenStoreOpen() -> xenStoreAddWatch() -> conn->refs++
virConnectClose() -> xenUnifiedClose() ...
... xenInotifyClose() -> virUnrefConnect(conn)
... xenStoreClose() -> xenStoreRemoveWatch() -> virUnrefConnect(conn)
Before the commit this additional virConnectRef/virUnrefConnect calls
where no problem, because virConnectClose() closed the drivers
explicitly and the additional refs added by the Xen subdrivers were
removed properly. After the commit this additional refs result in a
virConnectPtr leak (including a leak of the hypercall file handle;
that's how I noticed this problem), because now the drivers are only
close if and only if the ref-count drops to zero, but this cannot
happen anymore, because the additional refs from the Xen subdrivers
would only be removed if the drivers get closed, but that doesn't
happen because the ref-count cannot drop to zero.
The fix for this problem is simple: remove the
virConnectRef/virUnrefConnect calls from the Xen subdrivers (see
attached patch). Maybe someone could explain why the Xen Inotify and
Xen Store driver do this extra ref-counting, but none of the other Xen
subdrivers. It seems unnecessary to me and can be removed without
problems.
Signed-off-by: Chris Lalancette <clalance@redhat.com>
(cherry picked from commit 6ed7374c5a6c6a2b1b1801d7d041dc7f09748592)
Fedora-patch: libvirt-fix-xen-driver-refcounting.patch
---
src/xen_inotify.c | 2 --
src/xs_internal.c | 3 ---
2 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/src/xen_inotify.c b/src/xen_inotify.c
index e312b9e..ecaefaf 100644
--- a/src/xen_inotify.c
+++ b/src/xen_inotify.c
@@ -463,7 +463,6 @@ xenInotifyOpen(virConnectPtr conn ATTRIBUTE_UNUSED,
DEBUG0("Failed to add inotify handle, disabling events");
}
- virConnectRef(conn);
return 0;
}
@@ -486,7 +485,6 @@ xenInotifyClose(virConnectPtr conn)
if (priv->inotifyWatch != -1)
virEventRemoveHandle(priv->inotifyWatch);
close(priv->inotifyFD);
- virUnrefConnect(conn);
return 0;
}
diff --git a/src/xs_internal.c b/src/xs_internal.c
index 1f54b1f..a18dcad 100644
--- a/src/xs_internal.c
+++ b/src/xs_internal.c
@@ -1139,8 +1139,6 @@ int xenStoreAddWatch(virConnectPtr conn,
list->watches[n] = watch;
list->count++;
- conn->refs++;
-
return xs_watch(priv->xshandle, watch->path, watch->token);
}
@@ -1190,7 +1188,6 @@ int xenStoreRemoveWatch(virConnectPtr conn,
; /* Failure to reduce memory allocation isn't fatal */
}
list->count--;
- virUnrefConnect(conn);
return 0;
}
}
--
1.6.2.5

View File

@ -1,31 +0,0 @@
From 918724aa76982224437384d712c182c332fa5ef9 Mon Sep 17 00:00:00 2001
From: Dan Kenigsberg <danken@redhat.com>
Date: Wed, 21 Oct 2009 13:56:04 +0200
Subject: [PATCH] Do not log rotate very small logs
Without this, after few weeks without use, each defined domain grows a
tail of empty gzipped logs, instead of keeping just the last log of
interest.
* daemon/libvirtd.logrotate.in: only rotate when the log is over 100 KBytes
(cherry picked from commit b03fe2d0aefb57a096a102bf23375f0a167ca189)
Fedora-patch: libvirt-logrotate-avoid-compressing-small-logs.patch
---
qemud/libvirtd.logrotate.in | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/qemud/libvirtd.logrotate.in b/qemud/libvirtd.logrotate.in
index 093651c..0c51fd3 100644
--- a/qemud/libvirtd.logrotate.in
+++ b/qemud/libvirtd.logrotate.in
@@ -5,4 +5,5 @@
compress
delaycompress
copytruncate
+ minsize 100k
}
--
1.6.2.5

View File

@ -1,54 +0,0 @@
From b7e3ac4f23befe67518b57e34691c301820a436c Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Tue, 6 Oct 2009 12:33:17 +0100
Subject: [PATCH] Create /var/log/libvirt/{lxc,uml} dirs
Otherwise logrotate barfs:
error: error accessing /var/log/libvirt/uml: No such file or directory
error: libvirtd:1 glob failed for /var/log/libvirt/uml/*.log
error: found error in /var/log/libvirt/qemu/*.log /var/log/libvirt/uml/*.log /var/log/libvirt/lxc/*.log , skipping
* qemud/Makefile.am: always create /var/log/libvirt/{lxc,uml} when
installing the logrotate conf; not ideal, but easier than making
the logrotate conf depend on which drivers are enabled
Fedora-patch: libvirt-logrotate-create-lxc-uml-dirs.patch
---
qemud/Makefile.am | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/qemud/Makefile.am b/qemud/Makefile.am
index 3d143da..a7f4bdf 100644
--- a/qemud/Makefile.am
+++ b/qemud/Makefile.am
@@ -176,7 +176,7 @@ install-data-local: install-init install-data-sasl install-data-polkit \
test -e $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart/default.xml || \
ln -s ../default.xml \
$(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart/default.xml
- mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/qemu
+ mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt
mkdir -p $(DESTDIR)$(localstatedir)/run/libvirt
mkdir -p $(DESTDIR)$(localstatedir)/lib/libvirt
@@ -184,7 +184,7 @@ uninstall-local:: uninstall-init uninstall-data-sasl install-data-polkit
rm -f $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart/default.xml
rm -f $(DESTDIR)$(sysconfdir)/$(default_xml_dest)
rmdir $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart || :
- rmdir $(DESTDIR)$(localstatedir)/log/libvirt/qemu || :
+ rmdir $(DESTDIR)$(localstatedir)/log/libvirt || :
rmdir $(DESTDIR)$(localstatedir)/run/libvirt || :
rmdir $(DESTDIR)$(localstatedir)/lib/libvirt || :
@@ -240,6 +240,8 @@ libvirtd.logrotate: libvirtd.logrotate.in
install-logrotate: libvirtd.logrotate
mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/qemu/
+ mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/lxc/
+ mkdir -p $(DESTDIR)$(localstatedir)/log/libvirt/uml/
mkdir -p $(DESTDIR)$(sysconfdir)/logrotate.d/
$(INSTALL_DATA) $< $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd
--
1.6.2.5

View File

@ -1,32 +0,0 @@
From ba3bc9b22a21b8e9e110166c98be70e2ad6469cb Mon Sep 17 00:00:00 2001
From: Cole Robinson <crobinso@redhat.com>
Date: Tue, 13 Oct 2009 11:31:27 -0400
Subject: [PATCH] network: Fix printing XML 'delay' attribute
When specifying bridge delay via network XML define, we were looking for
the 'delay' attribute, but would dump the value as 'forwardDelay'. Have
the output match the expected input (and schema).
(cherry picked from commit 3b13aa3db37bf5a692bccfa015a01999043e797b)
Fedora-patch: libvirt-network-delay-attribute-formatting.patch
---
src/network_conf.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/network_conf.c b/src/network_conf.c
index 3764bb4..f75c457 100644
--- a/src/network_conf.c
+++ b/src/network_conf.c
@@ -587,7 +587,7 @@ char *virNetworkDefFormat(virConnectPtr conn,
virBufferAddLit(&buf, " <bridge");
if (def->bridge)
virBufferEscapeString(&buf, " name='%s'", def->bridge);
- virBufferVSprintf(&buf, " stp='%s' forwardDelay='%ld' />\n",
+ virBufferVSprintf(&buf, " stp='%s' delay='%ld' />\n",
def->stp ? "on" : "off",
def->delay);
--
1.6.2.5

View File

@ -1,177 +0,0 @@
From d7722ed1cb04aa8a7b9fbf880882841867b69ab0 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Mon, 12 Oct 2009 10:52:13 +0100
Subject: [PATCH] Take domain type into account when looking up default machine
If one has e.g.
<guest>
<os_type>hvm</os_type>
<arch name='x86_64'>
<wordsize>64</wordsize>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<machine>pc-0.11</machine>
<machine canonical='pc-0.11'>pc</machine>
<machine>pc-0.10</machine>
<machine>isapc</machine>
<domain type='qemu'>
</domain>
<domain type='kvm'>
<emulator>/usr/bin/kvm</emulator>
<machine>pc</machine>
<machine>isapc</machine>
</domain>
</arch>
</guest>
and start a guest with:
<domain type='kvm'>
...
<os>
<type arch='x86_64'>hvm</type>
...
</os>
</domain>
then the default machine type should be 'pc' and not 'pc-0.11'
Issue was reported by Anton Protopopov.
* src/capabilities.[ch]: pass the domain type to
virCapabilitiesDefaultGuestArch() and use it to look up the default
machine type from a specific guest domain if needed.
* src/conf/domain_conf.c, src/xen/xm_internal.c: update
* tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml: update
the domain type to 'kvm' and remove the machine type to check
that the default gets looked up correctly
(cherry picked from commit 73c901a8075c09203545fc81164c1e5f11c67c89)
Fedora-patch: libvirt-qemu-machine-type-fixes1.patch
---
src/capabilities.c | 31 ++++++++++++++++---
src/capabilities.h | 3 +-
src/domain_conf.c | 3 +-
src/xm_internal.c | 3 +-
.../qemuxml2argv-machine-aliases2.xml | 4 +-
5 files changed, 34 insertions(+), 10 deletions(-)
diff --git a/src/capabilities.c b/src/capabilities.c
index 38fe7fc..6ebddf5 100644
--- a/src/capabilities.c
+++ b/src/capabilities.c
@@ -549,22 +549,43 @@ virCapabilitiesDefaultGuestArch(virCapsPtr caps,
* @caps: capabilities to query
* @ostype: OS type to search for
* @arch: architecture to search for
+ * @domain: domain type to search for
*
* Returns the first machine variant associated with
- * the requested operating system type and architecture
+ * the requested operating system type, architecture
+ * and domain type
*/
extern const char *
virCapabilitiesDefaultGuestMachine(virCapsPtr caps,
const char *ostype,
- const char *arch)
+ const char *arch,
+ const char *domain)
{
int i;
+
for (i = 0 ; i < caps->nguests ; i++) {
- if (STREQ(caps->guests[i]->ostype, ostype) &&
- STREQ(caps->guests[i]->arch.name, arch) &&
- caps->guests[i]->arch.defaultInfo.nmachines)
+ virCapsGuestPtr guest = caps->guests[i];
+ int j;
+
+ if (!STREQ(guest->ostype, ostype) || !STREQ(guest->arch.name, arch))
+ continue;
+
+ for (j = 0; j < guest->arch.ndomains; j++) {
+ virCapsGuestDomainPtr dom= guest->arch.domains[j];
+
+ if (!STREQ(dom->type, domain))
+ continue;
+
+ if (!dom->info.nmachines)
+ break;
+
+ return dom->info.machines[0]->name;
+ }
+
+ if (guest->arch.defaultInfo.nmachines)
return caps->guests[i]->arch.defaultInfo.machines[0]->name;
}
+
return NULL;
}
diff --git a/src/capabilities.h b/src/capabilities.h
index b958d95..2f24605 100644
--- a/src/capabilities.h
+++ b/src/capabilities.h
@@ -207,7 +207,8 @@ virCapabilitiesDefaultGuestArch(virCapsPtr caps,
extern const char *
virCapabilitiesDefaultGuestMachine(virCapsPtr caps,
const char *ostype,
- const char *arch);
+ const char *arch,
+ const char *domain);
extern const char *
virCapabilitiesDefaultGuestEmulator(virCapsPtr caps,
const char *ostype,
diff --git a/src/domain_conf.c b/src/domain_conf.c
index 5ae0775..c424c67 100644
--- a/src/domain_conf.c
+++ b/src/domain_conf.c
@@ -2664,7 +2664,8 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
if (!def->os.machine) {
const char *defaultMachine = virCapabilitiesDefaultGuestMachine(caps,
def->os.type,
- def->os.arch);
+ def->os.arch,
+ virDomainVirtTypeToString(def->virtType));
if (defaultMachine != NULL) {
if (!(def->os.machine = strdup(defaultMachine))) {
virReportOOMError(conn);
diff --git a/src/xm_internal.c b/src/xm_internal.c
index de3aca9..6d351d4 100644
--- a/src/xm_internal.c
+++ b/src/xm_internal.c
@@ -720,7 +720,8 @@ xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
defaultMachine = virCapabilitiesDefaultGuestMachine(priv->caps,
def->os.type,
- def->os.arch);
+ def->os.arch,
+ virDomainVirtTypeToString(def->virtType));
if (defaultMachine != NULL) {
if (!(def->os.machine = strdup(defaultMachine)))
goto no_memory;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml
index 6f62243..a2c6254 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml
@@ -1,11 +1,11 @@
-<domain type='qemu'>
+<domain type='kvm'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory>219200</memory>
<currentMemory>219200</currentMemory>
<vcpu>1</vcpu>
<os>
- <type arch='x86_64' machine='pc'>hvm</type>
+ <type arch='x86_64'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
--
1.6.2.5

View File

@ -1,42 +0,0 @@
From bb64cc4cbe5d3c69057f63be2c1acaca72038e5a Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc@redhat.com>
Date: Thu, 15 Oct 2009 12:09:17 +0100
Subject: [PATCH] Don't copy old machines from a domain which has none
If the the qemu and kvm binaries are the same, we don't include machine
types in the kvm domain info.
However, the code which refreshes the machine types info from the
previous capabilities structure first looks at the kvm domain's info,
finds it matches and then copies the empty machine types list over
for the top-level qemu domain.
That doesn't make sense, we shouldn't copy an empty machin types list.
* src/qemu/qemu_conf.c: qemudGetOldMachinesFromInfo(): don't copy an
empty machine types list.
(cherry picked from commit 2210f8a3a8e2774ca4fb8b42e21899e5b85ca913)
Fedora-patch: libvirt-qemu-machine-type-fixes2.patch
---
src/qemu_conf.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index 0dd0624..34a7fe1 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -505,6 +505,9 @@ qemudGetOldMachinesFromInfo(virCapsGuestDomainInfoPtr info,
virCapsGuestMachinePtr *list;
int i;
+ if (!info->nmachines)
+ return 0;
+
if (!info->emulator || !STREQ(emulator, info->emulator))
return 0;
--
1.6.2.5

View File

@ -1,30 +0,0 @@
From a44bce591a8d746a4a00c8609cb0111c76271cab Mon Sep 17 00:00:00 2001
From: Cole Robinson <crobinso@redhat.com>
Date: Thu, 8 Oct 2009 18:05:36 -0400
Subject: [PATCH] storage: Fix generating iscsi 'auth' xml
We were missing a closing tag, so the XML wasn't proper.
(cherry picked from commit 826cbac4591fd5929b497299a90d3a65226b2825)
Fedora-patch: libvirt-storage-iscsi-auth-xml-formatting.patch
---
src/storage_conf.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/storage_conf.c b/src/storage_conf.c
index 788de15..1633aac 100644
--- a/src/storage_conf.c
+++ b/src/storage_conf.c
@@ -799,7 +799,7 @@ virStoragePoolSourceFormat(virConnectPtr conn,
if (src->authType == VIR_STORAGE_POOL_AUTH_CHAP)
- virBufferVSprintf(buf," <auth type='chap' login='%s' passwd='%s'>\n",
+ virBufferVSprintf(buf," <auth type='chap' login='%s' passwd='%s'/>\n",
src->auth.chap.login,
src->auth.chap.passwd);
virBufferAddLit(buf," </source>\n");
--
1.6.2.5

File diff suppressed because it is too large Load Diff

View File

@ -53,12 +53,17 @@
%define with_storage_mpath 0%{!?_without_storage_mpath:%{server_drivers}}
%define with_numactl 0%{!?_without_numactl:%{server_drivers}}
%define with_selinux 0%{!?_without_selinux:%{server_drivers}}
%define with_hal 0%{!?_without_hal:%{server_drivers}}
# A few optional bits off by default, we enable later
%define with_polkit 0%{!?_without_polkit:0}
%define with_capng 0%{!?_without_capng:0}
%define with_netcf 0%{!?_without_netcf:0}
%define with_udev 0%{!?_without_udev:0}
%define with_hal 0%{!?_without_hal:0}
%define with_yajl 0%{!?_without_yajl:0}
%define with_nwfilter 0%{!?_without_nwfilter:0}
%define with_libpcap 0%{!?_without_libpcap:0}
%define with_macvtap 0%{!?_without_macvtap:0}
# Non-server/HV driver defaults which are always enabled
%define with_python 0%{!?_without_python:1}
@ -72,6 +77,10 @@
%define with_xen 0
%endif
# Numactl is not available on s390[x]
%ifarch s390 s390x
%define with_numactl 0
%endif
# RHEL doesn't ship OpenVZ, VBox, UML, OpenNebula, PowerHypervisor or ESX
%if 0%{?rhel}
@ -129,6 +138,29 @@
%define with_netcf 0%{!?_without_netcf:%{server_drivers}}
%endif
# udev is used to manage host devices in Fedora 12 / RHEL-6 or newer
%if 0%{?fedora} >= 12 || 0%{?rhel} >= 6
%define with_udev 0%{!?_without_udev:%{server_drivers}}
%else
%define with_hal 0%{!?_without_hal:%{server_drivers}}
%endif
# Enable yajl library for JSON mode with QEMU
%if 0%{?fedora} >= 13 || 0%{?rhel} >= 6
%define with_yajl 0%{!?_without_yajl:%{server_drivers}}
%endif
# Enable libpcap library
%if %{with_qemu}
%define with_nwfilter 0%{!?_without_nwfilter:%{server_drivers}}
%define with_libpcap 0%{!?_without_libpcap:%{server_drivers}}
%define with_macvtap 0%{!?_without_macvtap:%{server_drivers}}
%endif
%if %{with_macvtap}
%define with_libnl 1
%endif
# Force QEMU to run as non-root
%if 0%{?fedora} >= 12 || 0%{?rhel} >= 6
%define qemu_user qemu
@ -150,106 +182,31 @@
Summary: Library providing a simple API virtualization
Name: libvirt
Version: 0.7.1
Release: 18%{?dist}%{?extra_release}
Version: 0.8.2
Release: 1%{?dist}%{?extra_release}
License: LGPLv2+
Group: Development/Libraries
Source: http://libvirt.org/sources/libvirt-%{version}.tar.gz
# A couple of hot-unplug memory handling fixes (#523953)
Patch01: libvirt-fix-net-hotunplug-double-free.patch
Patch02: libvirt-fix-pci-hostdev-hotunplug-leak.patch
# Don't set a bogus error in virDrvSupportsFeature()
Patch03: libvirt-fix-drv-supports-feature-bogus-error.patch
# Fix raw save format
Patch04: libvirt-fix-qemu-raw-format-save.patch
# Fix USB device passthrough (#422683)
Patch05: libvirt-fix-usb-device-passthrough.patch
# Disable sound backend (#524499, #508317)
Patch06: libvirt-disable-audio-backend.patch
# Re-label qcow2 backing files (#497131)
Patch07: libvirt-svirt-relabel-qcow2-backing-files.patch
# Change logrotate config to weekly (#526769)
Patch08: libvirt-change-logrotate-config-to-weekly.patch
Patch09: libvirt-logrotate-create-lxc-uml-dirs.patch
# Add several PCI hot-unplug typo fixes from upstream
Patch10: libvirt-fix-device-detach-typo1.patch
Patch11: libvirt-fix-device-detach-typo2.patch
Patch12: libvirt-fix-device-detach-typo3.patch
# Fix libvirtd memory leak during error reply sending (#528162)
Patch13: libvirt-fix-libvirtd-leak-in-error-reply.patch
# Fix restore of qemu guest using raw save format (#523158)
Patch14: libvirt-fix-qemu-restore-from-raw1.patch
Patch15: libvirt-fix-qemu-restore-from-raw2.patch
# Misc fixes to qemu machine types handling
Patch16: libvirt-qemu-machine-type-fixes1.patch
Patch17: libvirt-qemu-machine-type-fixes2.patch
# A couple of XML formatting fixes
Patch18: libvirt-storage-iscsi-auth-xml-formatting.patch
Patch19: libvirt-network-delay-attribute-formatting.patch
# Fix xen driver recounting (#531429)
Patch20: libvirt-fix-xen-driver-refcounting.patch
# Fix crash on virsh error (#531429)
Patch21: libvirt-double-free-on-virsh-error.patch
# Fix segfault where XML parsing fails in qemu disk hotplug
Patch22: libvirt-fix-crash-on-device-hotplug-parse-error.patch
# Fix segfault where interface target device name is ommitted (#523418)
Patch23: libvirt-fix-crash-on-missing-iface-target-dev.patch
# Avoid compressing small log files (#531030)
Patch24: libvirt-logrotate-avoid-compressing-small-logs.patch
# Fix crash with invalid QEmu URI (bz 566070)
Patch25: %{name}-%{version}-qemu-uri-crash.patch
# Fix VNC TLS crash (bz 544305)
Patch26: %{name}-%{version}-gcrypt-thread-init.patch
# Fix USB devices with high bus/addr values (bz 542639)
Patch27: %{name}-%{version}-fix-usb-busaddr.patch
# Fix save/restore with non-root guests (bz 534143, bz 532654)
Patch28: %{name}-%{version}-fix-selinux-save.patch
# Fix USB devices attached via virt-manager (bz 537227)
Patch29: %{name}-%{version}-fix-usb-product.patch
# Fix attach-device crash on cgroup cleanup (bz 556791)
Patch30: %{name}-%{version}-fix-cgroup-crash.patch
# Fix crash on bad LXC URI (bz 554191)
Patch31: %{name}-%{version}-lxc-uri-crash.patch
# Add qemu.conf options for audio workaround
Patch32: %{name}-%{version}-audio-config.patch
# Fix permissions of storage backing stores (bz 579067)
Patch33: %{name}-%{version}-backing-perms.patch
# Fix parsing certain USB sysfs files (bz 598272)
Patch34: %{name}-%{version}-fix-usb-parsing.patch
# Improve migration error reporting (bz 499750)
Patch35: %{name}-%{version}-migrate-errreport.patch
# Sanitize pool target paths (bz 494005)
Patch36: %{name}-%{version}-sanitize-pool.patch
# Add qemu.conf for clear emulator capabilities
Patch37: %{name}-%{version}-caps-option.patch
# Prevent libvirtd inside a VM from breaking network access (bz 235961)
Patch38: %{name}-%{version}-network-collision.patch
# Mention --all in 'virsh list' docs (bz 575512)
Patch39: %{name}-%{version}-man-page-list.patch
# Patches 1-> 11 CVE-2010-2237, 2238, 2239
Patch1: libvirt-0.8.2-01-extract-backing-store-format.patch
Patch2: libvirt-0.8.2-02-remove-type-field.patch
Patch3: libvirt-0.8.2-03-refactor-metadata-extract.patch
Patch4: libvirt-0.8.2-04-require-storage-format.patch
Patch5: libvirt-0.8.2-05-disk-path-iterator.patch
Patch6: libvirt-0.8.2-06-use-disk-iterator.patch
Patch7: libvirt-0.8.2-07-secdriver-params.patch
Patch8: libvirt-0.8.2-08-disable-disk-probing.patch
Patch9: libvirt-0.8.2-09-set-default-driver.patch
Patch10: libvirt-0.8.2-10-qemu-img-format-handling.patch
Patch11: libvirt-0.8.2-11-storage-vol-backing.patch
# CVE-2010-2242
Patch12: libvirt-0.8.2-apply-iptables-sport-mapping.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
URL: http://libvirt.org/
BuildRequires: python-devel
# The client side, i.e. shared libs and virsh are in a subpackage
Requires: libvirt-client = %{version}-%{release}
Requires: %{name}-client = %{version}-%{release}
# Used by many of the drivers, so turn it on whenever the
# daemon is present
@ -260,10 +217,18 @@ Requires: bridge-utils
Requires: dnsmasq
Requires: iptables
%endif
%if %{with_nwfilter}
Requires: ebtables
Requires: iptables
Requires: iptables-ipv6
%endif
# needed for device enumeration
%if %{with_hal}
Requires: hal
%endif
%if %{with_udev}
Requires: udev >= 145
%endif
%if %{with_polkit}
%if 0%{?fedora} >= 12 || 0%{?rhel} >=6
Requires: polkit >= 0.93
@ -327,6 +292,19 @@ BuildRequires: gnutls-devel
%if %{with_hal}
BuildRequires: hal-devel
%endif
%if %{with_udev}
BuildRequires: libudev-devel >= 145
BuildRequires: libpciaccess-devel >= 0.10.9
%endif
%if %{with_yajl}
BuildRequires: yajl-devel
%endif
%if %{with_libpcap}
BuildRequires: libpcap-devel
%endif
%if %{with_libnl}
BuildRequires: libnl-devel
%endif
%if %{with_avahi}
BuildRequires: avahi-devel
%endif
@ -397,15 +375,15 @@ BuildRequires: libcap-ng-devel >= 0.5.0
BuildRequires: libssh2-devel
%endif
%if %{with_netcf}
BuildRequires: netcf-devel
BuildRequires: netcf-devel >= 0.1.4
%endif
%if %{with_esx}
BuildRequires: libcurl-devel
%endif
# Fedora build root suckage
BuildRequires: gawk
# Needed for libvirt-logrotate-create-lxc-uml-dirs.patch
BuildRequires: automake
%description
Libvirt is a C toolkit to interact with the virtualization capabilities
of recent versions of Linux (and other OSes). The main package includes
@ -433,7 +411,7 @@ virtualization capabilities of recent versions of Linux (and other OSes).
%package devel
Summary: Libraries, includes, etc. to compile with the libvirt library
Group: Development/Libraries
Requires: libvirt-client = %{version}-%{release}
Requires: %{name}-client = %{version}-%{release}
Requires: pkgconfig
%if %{with_xen}
Requires: xen-devel
@ -447,7 +425,7 @@ the virtualization capabilities of recent versions of Linux (and other OSes).
%package python
Summary: Python bindings for the libvirt library
Group: Development/Libraries
Requires: libvirt-client = %{version}-%{release}
Requires: %{name}-client = %{version}-%{release}
%description python
The libvirt-python package contains a module that permits applications
@ -458,51 +436,20 @@ of recent versions of Linux (and other OSes).
%prep
%setup -q
%patch01 -p1
%patch02 -p1
%patch03 -p1
%patch04 -p1
%patch05 -p1
%patch06 -p1
%patch07 -p1
%patch08 -p1
%patch09 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch29 -p1
%patch30 -p1
%patch31 -p1
%patch32 -p1
%patch33 -p1
%patch34 -p1
%patch35 -p1
%patch36 -p1
%patch37 -p1
%patch38 -p1
%patch39 -p1
%build
# Needed for libvirt-logrotate-create-lxc-uml-dirs.patch
automake
%if ! %{with_xen}
%define _without_xen --without-xen
%endif
@ -607,6 +554,22 @@ automake
%define _without_hal --without-hal
%endif
%if ! %{with_udev}
%define _without_udev --without-udev
%endif
%if ! %{with_yajl}
%define _without_yajl --without-yajl
%endif
%if ! %{with_libpcap}
%define _without_libpcap --without-libpcap
%endif
%if ! %{with_macvtap}
%define _without_macvtap --without-macvtap
%endif
%configure %{?_without_xen} \
%{?_without_qemu} \
%{?_without_openvz} \
@ -633,6 +596,10 @@ automake
%{?_without_netcf} \
%{?_without_selinux} \
%{?_without_hal} \
%{?_without_udev} \
%{?_without_yajl} \
%{?_without_libpcap} \
%{?_without_macvtap} \
--with-qemu-user=%{qemu_user} \
--with-qemu-group=%{qemu_group} \
--with-init-script=redhat \
@ -644,16 +611,17 @@ gzip -9 ChangeLog
rm -fr %{buildroot}
%makeinstall
(cd docs/examples ; make clean ; rm -rf .deps Makefile Makefile.in)
(cd docs/examples/python ; rm -rf .deps Makefile Makefile.in)
(cd examples/hellolibvirt ; make clean ; rm -rf .deps .libs Makefile Makefile.in)
(cd examples/domain-events/events-c ; make clean ;rm -rf .deps .libs Makefile Makefile.in)
for i in domain-events/events-c dominfo domsuspend hellolibvirt python xml/nwfilter
do
(cd examples/$i ; make clean ; rm -rf .deps .libs Makefile Makefile.in)
done
rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
rm -f $RPM_BUILD_ROOT%{_libdir}/*.a
rm -f $RPM_BUILD_ROOT%{_libdir}/python*/site-packages/*.la
rm -f $RPM_BUILD_ROOT%{_libdir}/python*/site-packages/*.a
%if %{with_network}
install -d -m 0755 $RPM_BUILD_ROOT%{_datadir}/lib/libvirt/dnsmasq/
# We don't want to install /etc/libvirt/qemu/networks in the main %files list
# because if the admin wants to delete the default network completely, we don't
# want to end up re-incarnating it on every RPM upgrade.
@ -674,6 +642,11 @@ rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug
%endif
%find_lang %{name}
%if ! %{with_lxc}
rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/libvirtd_lxc.aug
rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/tests/test_libvirtd_lxc.aug
%endif
%if ! %{with_python}
rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/libvirt-python-%{version}
%endif
@ -682,8 +655,20 @@ rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/libvirt-python-%{version}
rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/libvirt-%{version}
%endif
%if ! %{with_libvirtd}
rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/nwfilter
%endif
%if ! %{with_qemu}
rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/qemu.conf
rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/libvirtd.qemu
%endif
%if ! %{with_lxc}
rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/lxc.conf
rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/libvirtd.lxc
%endif
%if ! %{with_uml}
rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/libvirtd.uml
%endif
%if %{with_libvirtd}
@ -693,6 +678,17 @@ chmod 0644 $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/libvirtd
%clean
rm -fr %{buildroot}
%check
cd tests
# These 3 tests don't current work in a mock build root
for i in nodeinfotest daemon-conf seclabeltest
do
rm -f $i
printf "#!/bin/sh\nexit 0\n" > $i
chmod +x $i
done
make check
%pre
%if 0%{?fedora} >= 12 || 0%{?rhel} >= 6
# Normally 'setup' adds this in /etc/passwd, but this is
@ -713,7 +709,7 @@ getent passwd qemu >/dev/null || \
# or on the first upgrade from a non-network aware libvirt only.
# We check this by looking to see if the daemon is already installed
/sbin/chkconfig --list libvirtd 1>/dev/null 2>&1
if [ $? != 0 -a ! -f %{_sysconfdir}/libvirt/qemu/networks/default.xml ]
if test $? != 0 && test ! -f %{_sysconfdir}/libvirt/qemu/networks/default.xml
then
UUID=`/usr/bin/uuidgen`
sed -e "s,</name>,</name>\n <uuid>$UUID</uuid>," \
@ -737,7 +733,22 @@ if [ $1 = 0 ]; then
fi
%endif
%post client -p /sbin/ldconfig
%preun client
if [ $1 = 0 ]; then
/sbin/chkconfig --del libvirt-guests
rm -f /var/lib/libvirt/libvirt-guests
fi
%post client
/sbin/ldconfig
/sbin/chkconfig --add libvirt-guests
if [ $1 -ge 1 ]; then
# this doesn't do anything but allowing for libvirt-guests to be
# stopped on the first shutdown
/sbin/service libvirt-guests start > /dev/null 2>&1 || true
fi
%postun client -p /sbin/ldconfig
@ -754,16 +765,26 @@ fi
%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/networks/autostart
%endif
%dir %attr(0700, root, root) %{_sysconfdir}/libvirt/nwfilter/
%{_sysconfdir}/libvirt/nwfilter/*.xml
%{_sysconfdir}/rc.d/init.d/libvirtd
%config(noreplace) %{_sysconfdir}/sysconfig/libvirtd
%config(noreplace) %{_sysconfdir}/libvirt/libvirtd.conf
%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd
%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/qemu/
%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/lxc/
%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/uml/
%if %{with_qemu}
%config(noreplace) %{_sysconfdir}/libvirt/qemu.conf
%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd.qemu
%endif
%if %{with_lxc}
%config(noreplace) %{_sysconfdir}/libvirt/lxc.conf
%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd.lxc
%endif
%if %{with_uml}
%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd.uml
%endif
%dir %{_datadir}/libvirt/
@ -796,9 +817,7 @@ fi
%if %{with_network}
%dir %{_localstatedir}/run/libvirt/network/
%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/network/
%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/iptables/
%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/iptables/filter/
%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/iptables/nat/
%dir %attr(0755, root, root) %{_localstatedir}/lib/libvirt/dnsmasq/
%endif
%if %{with_qemu}
@ -806,6 +825,11 @@ fi
%{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug
%endif
%if %{with_lxc}
%{_datadir}/augeas/lenses/libvirtd_lxc.aug
%{_datadir}/augeas/lenses/tests/test_libvirtd_lxc.aug
%endif
%{_datadir}/augeas/lenses/libvirtd.aug
%{_datadir}/augeas/lenses/tests/test_libvirtd.aug
@ -839,14 +863,17 @@ fi
%{_mandir}/man1/virsh.1*
%{_mandir}/man1/virt-xml-validate.1*
%{_mandir}/man1/virt-pki-validate.1*
%{_bindir}/virsh
%{_bindir}/virt-xml-validate
%{_bindir}/virt-pki-validate
%{_libdir}/lib*.so.*
%dir %{_datadir}/libvirt/
%dir %{_datadir}/libvirt/schemas/
%{_datadir}/libvirt/schemas/domain.rng
%{_datadir}/libvirt/schemas/domainsnapshot.rng
%{_datadir}/libvirt/schemas/network.rng
%{_datadir}/libvirt/schemas/storagepool.rng
%{_datadir}/libvirt/schemas/storagevol.rng
@ -855,6 +882,13 @@ fi
%{_datadir}/libvirt/schemas/interface.rng
%{_datadir}/libvirt/schemas/secret.rng
%{_datadir}/libvirt/schemas/storageencryption.rng
%{_datadir}/libvirt/schemas/nwfilter.rng
%{_datadir}/libvirt/cpu_map.xml
%{_sysconfdir}/rc.d/init.d/libvirt-guests
%config(noreplace) %{_sysconfdir}/sysconfig/libvirt-guests
%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt
%if %{with_sasl}
%config(noreplace) %{_sysconfdir}/sasl2/libvirt.conf
@ -874,9 +908,12 @@ fi
%doc %{_datadir}/gtk-doc/html/libvirt/*.css
%doc docs/*.html docs/html docs/*.gif
%doc docs/examples
%doc docs/libvirt-api.xml
%doc examples
%doc examples/hellolibvirt
%doc examples/domain-events/events-c
%doc examples/dominfo
%doc examples/domsuspend
%doc examples/xml
%if %{with_python}
%files python
@ -887,11 +924,21 @@ fi
%{_libdir}/python*/site-packages/libvirtmod*
%doc python/tests/*.py
%doc python/TODO
%doc python/libvirtclass.txt
%doc docs/examples/python
%doc examples/python
%doc examples/domain-events/events-python
%endif
%changelog
* Mon Jul 12 2010 Daniel P. Berrange <berrange@redhat.com> - 0.8.2-1
- Update to 0.8.2 release
- CVE-2010-2237 ignoring defined main disk format when looking up disk backing stores
- CVE-2010-2238 ignoring defined disk backing store format when recursing into disk
image backing stores
- CVE-2010-2239 not setting user defined backing store format when creating new image
- CVE-2010-2242 libvirt: improperly mapped source privileged ports may allow for
obtaining privileged resources on the host
* Thu Jun 17 2010 Cole Robinson <crobinso@redhat.com> - 0.7.1-18.fc12
- Actually apply all previous patches

View File

@ -1 +1 @@
f1cd360a5da38b847e166c6482141940 libvirt-0.7.1.tar.gz
14164638fe0e7f65e425acc85dabc517 libvirt-0.8.2.tar.gz