diff --git a/.cvsignore b/.cvsignore index 220baba..55e6af8 100644 --- a/.cvsignore +++ b/.cvsignore @@ -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 diff --git a/libvirt-0.7.1-audio-config.patch b/libvirt-0.7.1-audio-config.patch deleted file mode 100644 index b921845..0000000 --- a/libvirt-0.7.1-audio-config.patch +++ /dev/null @@ -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 */ diff --git a/libvirt-0.7.1-backing-perms.patch b/libvirt-0.7.1-backing-perms.patch deleted file mode 100644 index 9cc3318..0000000 --- a/libvirt-0.7.1-backing-perms.patch +++ /dev/null @@ -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; - } diff --git a/libvirt-0.7.1-caps-option.patch b/libvirt-0.7.1-caps-option.patch deleted file mode 100644 index 354f017..0000000 --- a/libvirt-0.7.1-caps-option.patch +++ /dev/null @@ -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); diff --git a/libvirt-0.7.1-fix-cgroup-crash.patch b/libvirt-0.7.1-fix-cgroup-crash.patch deleted file mode 100644 index d74de81..0000000 --- a/libvirt-0.7.1-fix-cgroup-crash.patch +++ /dev/null @@ -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); - } diff --git a/libvirt-0.7.1-fix-selinux-save.patch b/libvirt-0.7.1-fix-selinux-save.patch deleted file mode 100644 index 09cf804..0000000 --- a/libvirt-0.7.1-fix-selinux-save.patch +++ /dev/null @@ -1,267 +0,0 @@ -commit bc0010b3d149df00406b82c37eb59874d8525af4 -Author: Daniel P. Berrange -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, - }; diff --git a/libvirt-0.7.1-fix-usb-busaddr.patch b/libvirt-0.7.1-fix-usb-busaddr.patch deleted file mode 100644 index 41c12f1..0000000 --- a/libvirt-0.7.1-fix-usb-busaddr.patch +++ /dev/null @@ -1,22 +0,0 @@ -commit 823a684f8d0495bd5e7b413e1a81fd5a600abef7 -Author: Daniel P. Berrange -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); diff --git a/libvirt-0.7.1-fix-usb-parsing.patch b/libvirt-0.7.1-fix-usb-parsing.patch deleted file mode 100644 index 5efc109..0000000 --- a/libvirt-0.7.1-fix-usb-parsing.patch +++ /dev/null @@ -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) { diff --git a/libvirt-0.7.1-fix-usb-product.patch b/libvirt-0.7.1-fix-usb-product.patch deleted file mode 100644 index f82917e..0000000 --- a/libvirt-0.7.1-fix-usb-product.patch +++ /dev/null @@ -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); - } - - diff --git a/libvirt-0.7.1-gcrypt-thread-init.patch b/libvirt-0.7.1-gcrypt-thread-init.patch deleted file mode 100644 index f4be2e2..0000000 --- a/libvirt-0.7.1-gcrypt-thread-init.patch +++ /dev/null @@ -1,686 +0,0 @@ -commit 33a198c1f6a4a1bc7f34d50a31032e03bec10fee -Author: Daniel P. Berrange -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 - #endif - #include -+#include - - #include - #include -@@ -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 -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, diff --git a/libvirt-0.7.1-lxc-uri-crash.patch b/libvirt-0.7.1-lxc-uri-crash.patch deleted file mode 100644 index 0a72d98..0000000 --- a/libvirt-0.7.1-lxc-uri-crash.patch +++ /dev/null @@ -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); diff --git a/libvirt-0.7.1-man-page-list.patch b/libvirt-0.7.1-man-page-list.patch deleted file mode 100644 index a7ce030..0000000 --- a/libvirt-0.7.1-man-page-list.patch +++ /dev/null @@ -1,65 +0,0 @@ -commit e5f31f461f63bbad211e84b810d6ba43a705f9dd -Author: Justin Clift -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 - The XML also show the NUMA topology information if available. - --=item B -+=item B 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 - --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 -+ -+The domain is not running. Usually this indicates the domain has been -+shut down completely, or has not been started. -+ - =item B - - The domain has crashed, which is always a violent ending. Usually diff --git a/libvirt-0.7.1-migrate-errreport.patch b/libvirt-0.7.1-migrate-errreport.patch deleted file mode 100644 index 081edd1..0000000 --- a/libvirt-0.7.1-migrate-errreport.patch +++ /dev/null @@ -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 diff --git a/libvirt-0.7.1-network-collision.patch b/libvirt-0.7.1-network-collision.patch deleted file mode 100644 index abc81e8..0000000 --- a/libvirt-0.7.1-network-collision.patch +++ /dev/null @@ -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 - #include - #include -+#include -+#include - - #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'"), diff --git a/libvirt-0.7.1-qemu-uri-crash.patch b/libvirt-0.7.1-qemu-uri-crash.patch deleted file mode 100644 index 20bc52d..0000000 --- a/libvirt-0.7.1-qemu-uri-crash.patch +++ /dev/null @@ -1,29 +0,0 @@ -commit c11a82b62aefc21e070c527f59a1f9c57a7b4f36 -Author: Richard Jones -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")) { diff --git a/libvirt-0.7.1-sanitize-pool.patch b/libvirt-0.7.1-sanitize-pool.patch deleted file mode 100644 index 37b95eb..0000000 --- a/libvirt-0.7.1-sanitize-pool.patch +++ /dev/null @@ -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, diff --git a/libvirt-0.8.2-01-extract-backing-store-format.patch b/libvirt-0.8.2-01-extract-backing-store-format.patch new file mode 100644 index 0000000..569cf0a --- /dev/null +++ b/libvirt-0.8.2-01-extract-backing-store-format.patch @@ -0,0 +1,356 @@ +From 953440bd12608a20007ee5da5ab69fbbe910bd28 Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +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 + + 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 + diff --git a/libvirt-0.8.2-02-remove-type-field.patch b/libvirt-0.8.2-02-remove-type-field.patch new file mode 100644 index 0000000..74672f5 --- /dev/null +++ b/libvirt-0.8.2-02-remove-type-field.patch @@ -0,0 +1,159 @@ +From cab428b1d4d432965cee6f5afb67265557706715 Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +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 + diff --git a/libvirt-0.8.2-03-refactor-metadata-extract.patch b/libvirt-0.8.2-03-refactor-metadata-extract.patch new file mode 100644 index 0000000..d868825 --- /dev/null +++ b/libvirt-0.8.2-03-refactor-metadata-extract.patch @@ -0,0 +1,585 @@ +From 57482ca0be29e9e92e242c9acb577e0b770c01d1 Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +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 + diff --git a/libvirt-0.8.2-04-require-storage-format.patch b/libvirt-0.8.2-04-require-storage-format.patch new file mode 100644 index 0000000..deb4c37 --- /dev/null +++ b/libvirt-0.8.2-04-require-storage-format.patch @@ -0,0 +1,285 @@ +From 726a63a437efd96510ce316bf30d16f213d4db27 Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +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 + diff --git a/libvirt-0.8.2-05-disk-path-iterator.patch b/libvirt-0.8.2-05-disk-path-iterator.patch new file mode 100644 index 0000000..4f74940 --- /dev/null +++ b/libvirt-0.8.2-05-disk-path-iterator.patch @@ -0,0 +1,170 @@ +From ac5067f1e2e98181ee0e9230f756697f50d853eb Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +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 + diff --git a/libvirt-0.8.2-06-use-disk-iterator.patch b/libvirt-0.8.2-06-use-disk-iterator.patch new file mode 100644 index 0000000..028710e --- /dev/null +++ b/libvirt-0.8.2-06-use-disk-iterator.patch @@ -0,0 +1,506 @@ +From 54c1bb731d2b19a46a594cf9682c022f1e1114d2 Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +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 + diff --git a/libvirt-0.8.2-07-secdriver-params.patch b/libvirt-0.8.2-07-secdriver-params.patch new file mode 100644 index 0000000..08adca0 --- /dev/null +++ b/libvirt-0.8.2-07-secdriver-params.patch @@ -0,0 +1,1152 @@ +From bbf8c57b06ec1b63ae814114867eaceebb7dc166 Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +Date: Tue, 15 Jun 2010 17:44:19 +0100 +Subject: [PATCH 07/11] Pass security driver object into all security driver callbacks + +The implementation of security driver callbacks often needs +to access the security driver object. Currently only a handful +of callbacks include the driver object as a parameter. Later +patches require this is many more places. + +* src/qemu/qemu_driver.c: Pass in the security driver object + to all callbacks +* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_stacked.c, + src/security/security_apparmor.c, src/security/security_driver.h, + src/security/security_selinux.c: Add a virSecurityDriverPtr + param to all security callbacks +--- + src/qemu/qemu_driver.c | 88 ++++++++++++++++++++----------- + src/qemu/qemu_security_dac.c | 44 +++++++++++----- + src/qemu/qemu_security_stacked.c | 107 +++++++++++++++++++++++++------------- + src/security/security_apparmor.c | 57 +++++++++++++------- + src/security/security_driver.h | 40 ++++++++++---- + src/security/security_selinux.c | 56 +++++++++++++------ + 6 files changed, 260 insertions(+), 132 deletions(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 99aeffa..616547c 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -1278,7 +1278,8 @@ qemuReconnectDomain(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaq + + if (driver->securityDriver && + driver->securityDriver->domainReserveSecurityLabel && +- driver->securityDriver->domainReserveSecurityLabel(obj) < 0) ++ driver->securityDriver->domainReserveSecurityLabel(driver->securityDriver, ++ obj) < 0) + goto error; + + if (obj->def->id >= driver->nextvmid) +@@ -3401,13 +3402,15 @@ static int qemudStartVMDaemon(virConnectPtr conn, + DEBUG0("Generating domain security label (if required)"); + if (driver->securityDriver && + driver->securityDriver->domainGenSecurityLabel && +- driver->securityDriver->domainGenSecurityLabel(vm) < 0) ++ driver->securityDriver->domainGenSecurityLabel(driver->securityDriver, ++ vm) < 0) + goto cleanup; + + DEBUG0("Generating setting domain security labels (if required)"); + if (driver->securityDriver && + driver->securityDriver->domainSetSecurityAllLabel && +- driver->securityDriver->domainSetSecurityAllLabel(vm, stdin_path) < 0) { ++ driver->securityDriver->domainSetSecurityAllLabel(driver->securityDriver, ++ vm, stdin_path) < 0) { + if (stdin_path && virStorageFileIsSharedFS(stdin_path) != 1) + goto cleanup; + } +@@ -3766,10 +3769,12 @@ static void qemudShutdownVMDaemon(struct qemud_driver *driver, + /* Reset Security Labels */ + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityAllLabel) +- driver->securityDriver->domainRestoreSecurityAllLabel(vm, migrated); ++ driver->securityDriver->domainRestoreSecurityAllLabel(driver->securityDriver, ++ vm, migrated); + if (driver->securityDriver && + driver->securityDriver->domainReleaseSecurityLabel) +- driver->securityDriver->domainReleaseSecurityLabel(vm); ++ driver->securityDriver->domainReleaseSecurityLabel(driver->securityDriver, ++ vm); + + /* Clear out dynamically assigned labels */ + if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) { +@@ -5171,7 +5176,8 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path, + if ((!bypassSecurityDriver) && + driver->securityDriver && + driver->securityDriver->domainSetSavedStateLabel && +- driver->securityDriver->domainSetSavedStateLabel(vm, path) == -1) ++ driver->securityDriver->domainSetSavedStateLabel(driver->securityDriver, ++ vm, path) == -1) + goto endjob; + + if (header.compressed == QEMUD_SAVE_FORMAT_RAW) { +@@ -5206,7 +5212,8 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path, + if ((!bypassSecurityDriver) && + driver->securityDriver && + driver->securityDriver->domainRestoreSavedStateLabel && +- driver->securityDriver->domainRestoreSavedStateLabel(vm, path) == -1) ++ driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver, ++ vm, path) == -1) + VIR_WARN("failed to restore save state label on %s", path); + + if (cgroup != NULL) { +@@ -5253,7 +5260,8 @@ endjob: + if ((!bypassSecurityDriver) && + driver->securityDriver && + driver->securityDriver->domainRestoreSavedStateLabel && +- driver->securityDriver->domainRestoreSavedStateLabel(vm, path) == -1) ++ driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver, ++ vm, path) == -1) + VIR_WARN("failed to restore save state label on %s", path); + } + +@@ -5488,7 +5496,8 @@ static int qemudDomainCoreDump(virDomainPtr dom, + + if (driver->securityDriver && + driver->securityDriver->domainSetSavedStateLabel && +- driver->securityDriver->domainSetSavedStateLabel(vm, path) == -1) ++ driver->securityDriver->domainSetSavedStateLabel(driver->securityDriver, ++ vm, path) == -1) + goto endjob; + + /* Migrate will always stop the VM, so the resume condition is +@@ -5531,7 +5540,8 @@ static int qemudDomainCoreDump(virDomainPtr dom, + + if (driver->securityDriver && + driver->securityDriver->domainRestoreSavedStateLabel && +- driver->securityDriver->domainRestoreSavedStateLabel(vm, path) == -1) ++ driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver, ++ vm, path) == -1) + goto endjob; + + endjob: +@@ -5914,12 +5924,13 @@ static int qemudDomainGetSecurityLabel(virDomainPtr dom, virSecurityLabelPtr sec + * QEMU monitor hasn't seen SIGHUP/ERR on poll(). + */ + if (virDomainObjIsActive(vm)) { +- if (driver->securityDriver && driver->securityDriver->domainGetSecurityProcessLabel) { +- if (driver->securityDriver->domainGetSecurityProcessLabel(vm, seclabel) == -1) { +- qemuReportError(VIR_ERR_INTERNAL_ERROR, +- "%s", _("Failed to get security label")); +- goto cleanup; +- } ++ if (driver->securityDriver && ++ driver->securityDriver->domainGetSecurityProcessLabel && ++ driver->securityDriver->domainGetSecurityProcessLabel(driver->securityDriver, ++ vm, seclabel) < 0) { ++ qemuReportError(VIR_ERR_INTERNAL_ERROR, ++ "%s", _("Failed to get security label")); ++ goto cleanup; + } + } + +@@ -6325,7 +6336,8 @@ qemudDomainSaveImageStartVM(virConnectPtr conn, + out: + if (driver->securityDriver && + driver->securityDriver->domainRestoreSavedStateLabel && +- driver->securityDriver->domainRestoreSavedStateLabel(vm, path) == -1) ++ driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver, ++ vm, path) == -1) + VIR_WARN("failed to restore save state label on %s", path); + + return ret; +@@ -7039,7 +7051,8 @@ static int qemudDomainChangeEjectableMedia(struct qemud_driver *driver, + + if (driver->securityDriver && + driver->securityDriver->domainSetSecurityImageLabel && +- driver->securityDriver->domainSetSecurityImageLabel(vm, disk) < 0) ++ driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver, ++ vm, disk) < 0) + return -1; + + if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, qemuCmdFlags))) +@@ -7068,7 +7081,8 @@ static int qemudDomainChangeEjectableMedia(struct qemud_driver *driver, + + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityImageLabel && +- driver->securityDriver->domainRestoreSecurityImageLabel(vm, origdisk) < 0) ++ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, ++ vm, origdisk) < 0) + VIR_WARN("Unable to restore security label on ejected image %s", origdisk->src); + + VIR_FREE(origdisk->src); +@@ -7086,7 +7100,8 @@ error: + VIR_FREE(driveAlias); + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityImageLabel && +- driver->securityDriver->domainRestoreSecurityImageLabel(vm, disk) < 0) ++ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, ++ vm, disk) < 0) + VIR_WARN("Unable to restore security label on new media %s", disk->src); + return -1; + } +@@ -7113,7 +7128,8 @@ static int qemudDomainAttachPciDiskDevice(struct qemud_driver *driver, + + if (driver->securityDriver && + driver->securityDriver->domainSetSecurityImageLabel && +- driver->securityDriver->domainSetSecurityImageLabel(vm, disk) < 0) ++ driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver, ++ vm, disk) < 0) + return -1; + + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { +@@ -7180,7 +7196,8 @@ error: + + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityImageLabel && +- driver->securityDriver->domainRestoreSecurityImageLabel(vm, disk) < 0) ++ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, ++ vm, disk) < 0) + VIR_WARN("Unable to restore security label on %s", disk->src); + + return -1; +@@ -7322,7 +7339,8 @@ static int qemudDomainAttachSCSIDisk(struct qemud_driver *driver, + + if (driver->securityDriver && + driver->securityDriver->domainSetSecurityImageLabel && +- driver->securityDriver->domainSetSecurityImageLabel(vm, disk) < 0) ++ driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver, ++ vm, disk) < 0) + return -1; + + /* We should have an address already, so make sure */ +@@ -7408,7 +7426,8 @@ error: + + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityImageLabel && +- driver->securityDriver->domainRestoreSecurityImageLabel(vm, disk) < 0) ++ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, ++ vm, disk) < 0) + VIR_WARN("Unable to restore security label on %s", disk->src); + + return -1; +@@ -7435,7 +7454,8 @@ static int qemudDomainAttachUsbMassstorageDevice(struct qemud_driver *driver, + + if (driver->securityDriver && + driver->securityDriver->domainSetSecurityImageLabel && +- driver->securityDriver->domainSetSecurityImageLabel(vm, disk) < 0) ++ driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver, ++ vm, disk) < 0) + return -1; + + if (!disk->src) { +@@ -7491,7 +7511,8 @@ error: + + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityImageLabel && +- driver->securityDriver->domainRestoreSecurityImageLabel(vm, disk) < 0) ++ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, ++ vm, disk) < 0) + VIR_WARN("Unable to restore security label on %s", disk->src); + + return -1; +@@ -7928,7 +7949,8 @@ static int qemudDomainAttachHostDevice(struct qemud_driver *driver, + + if (driver->securityDriver && + driver->securityDriver->domainSetSecurityHostdevLabel && +- driver->securityDriver->domainSetSecurityHostdevLabel(vm, hostdev) < 0) ++ driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver, ++ vm, hostdev) < 0) + return -1; + + switch (hostdev->source.subsys.type) { +@@ -7956,7 +7978,8 @@ static int qemudDomainAttachHostDevice(struct qemud_driver *driver, + error: + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityHostdevLabel && +- driver->securityDriver->domainRestoreSecurityHostdevLabel(vm, hostdev) < 0) ++ driver->securityDriver->domainRestoreSecurityHostdevLabel(driver->securityDriver, ++ vm, hostdev) < 0) + VIR_WARN0("Unable to restore host device labelling on hotplug fail"); + + return -1; +@@ -8401,7 +8424,8 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver, + + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityImageLabel && +- driver->securityDriver->domainRestoreSecurityImageLabel(vm, dev->data.disk) < 0) ++ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, ++ vm, dev->data.disk) < 0) + VIR_WARN("Unable to restore security label on %s", dev->data.disk->src); + + if (cgroup != NULL) { +@@ -8464,7 +8488,8 @@ static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver, + + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityImageLabel && +- driver->securityDriver->domainRestoreSecurityImageLabel(vm, dev->data.disk) < 0) ++ driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver, ++ vm, dev->data.disk) < 0) + VIR_WARN("Unable to restore security label on %s", dev->data.disk->src); + + if (cgroup != NULL) { +@@ -8889,7 +8914,8 @@ static int qemudDomainDetachHostDevice(struct qemud_driver *driver, + + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityHostdevLabel && +- driver->securityDriver->domainRestoreSecurityHostdevLabel(vm, dev->data.hostdev) < 0) ++ driver->securityDriver->domainRestoreSecurityHostdevLabel(driver->securityDriver, ++ vm, dev->data.hostdev) < 0) + VIR_WARN0("Failed to restore host device labelling"); + + return ret; +diff --git a/src/qemu/qemu_security_dac.c b/src/qemu/qemu_security_dac.c +index 770010d..0bbcf69 100644 +--- a/src/qemu/qemu_security_dac.c ++++ b/src/qemu/qemu_security_dac.c +@@ -108,7 +108,8 @@ qemuSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED, + + + static int +-qemuSecurityDACSetSecurityImageLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED, ++qemuSecurityDACSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm ATTRIBUTE_UNUSED, + virDomainDiskDefPtr disk) + + { +@@ -124,7 +125,8 @@ qemuSecurityDACSetSecurityImageLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED, + + + static int +-qemuSecurityDACRestoreSecurityImageLabelInt(virDomainObjPtr vm ATTRIBUTE_UNUSED, ++qemuSecurityDACRestoreSecurityImageLabelInt(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm ATTRIBUTE_UNUSED, + virDomainDiskDefPtr disk, + int migrated) + { +@@ -166,10 +168,11 @@ qemuSecurityDACRestoreSecurityImageLabelInt(virDomainObjPtr vm ATTRIBUTE_UNUSED, + + + static int +-qemuSecurityDACRestoreSecurityImageLabel(virDomainObjPtr vm, ++qemuSecurityDACRestoreSecurityImageLabel(virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + virDomainDiskDefPtr disk) + { +- return qemuSecurityDACRestoreSecurityImageLabelInt(vm, disk, 0); ++ return qemuSecurityDACRestoreSecurityImageLabelInt(drv, vm, disk, 0); + } + + +@@ -192,7 +195,8 @@ qemuSecurityDACSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED, + + + static int +-qemuSecurityDACSetSecurityHostdevLabel(virDomainObjPtr vm, ++qemuSecurityDACSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainHostdevDefPtr dev) + + { +@@ -261,7 +265,8 @@ qemuSecurityDACRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED, + + + static int +-qemuSecurityDACRestoreSecurityHostdevLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED, ++qemuSecurityDACRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm ATTRIBUTE_UNUSED, + virDomainHostdevDefPtr dev) + + { +@@ -407,7 +412,8 @@ qemuSecurityDACRestoreChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED, + + + static int +-qemuSecurityDACRestoreSecurityAllLabel(virDomainObjPtr vm, ++qemuSecurityDACRestoreSecurityAllLabel(virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + int migrated) + { + int i; +@@ -420,12 +426,14 @@ qemuSecurityDACRestoreSecurityAllLabel(virDomainObjPtr vm, + vm->def->name, migrated); + + for (i = 0 ; i < vm->def->nhostdevs ; i++) { +- if (qemuSecurityDACRestoreSecurityHostdevLabel(vm, ++ if (qemuSecurityDACRestoreSecurityHostdevLabel(drv, ++ vm, + vm->def->hostdevs[i]) < 0) + rc = -1; + } + for (i = 0 ; i < vm->def->ndisks ; i++) { +- if (qemuSecurityDACRestoreSecurityImageLabelInt(vm, ++ if (qemuSecurityDACRestoreSecurityImageLabelInt(drv, ++ vm, + vm->def->disks[i], + migrated) < 0) + rc = -1; +@@ -461,7 +469,9 @@ qemuSecurityDACSetChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED, + + + static int +-qemuSecurityDACSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_path ATTRIBUTE_UNUSED) ++qemuSecurityDACSetSecurityAllLabel(virSecurityDriverPtr drv, ++ virDomainObjPtr vm, ++ const char *stdin_path ATTRIBUTE_UNUSED) + { + int i; + +@@ -472,11 +482,15 @@ qemuSecurityDACSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_path AT + /* XXX fixme - we need to recursively label the entriy tree :-( */ + if (vm->def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_DIR) + continue; +- if (qemuSecurityDACSetSecurityImageLabel(vm, vm->def->disks[i]) < 0) ++ if (qemuSecurityDACSetSecurityImageLabel(drv, ++ vm, ++ vm->def->disks[i]) < 0) + return -1; + } + for (i = 0 ; i < vm->def->nhostdevs ; i++) { +- if (qemuSecurityDACSetSecurityHostdevLabel(vm, vm->def->hostdevs[i]) < 0) ++ if (qemuSecurityDACSetSecurityHostdevLabel(drv, ++ vm, ++ vm->def->hostdevs[i]) < 0) + return -1; + } + +@@ -503,7 +517,8 @@ qemuSecurityDACSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_path AT + + + static int +-qemuSecurityDACSetSavedStateLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED, ++qemuSecurityDACSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm ATTRIBUTE_UNUSED, + const char *savefile) + { + if (!driver->privileged) +@@ -514,7 +529,8 @@ qemuSecurityDACSetSavedStateLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED, + + + static int +-qemuSecurityDACRestoreSavedStateLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED, ++qemuSecurityDACRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm ATTRIBUTE_UNUSED, + const char *savefile) + { + if (!driver->privileged) +diff --git a/src/qemu/qemu_security_stacked.c b/src/qemu/qemu_security_stacked.c +index df76135..432d095 100644 +--- a/src/qemu/qemu_security_stacked.c ++++ b/src/qemu/qemu_security_stacked.c +@@ -57,18 +57,21 @@ qemuSecurityStackedVerify(virDomainDefPtr def) + + + static int +-qemuSecurityStackedGenLabel(virDomainObjPtr vm) ++qemuSecurityStackedGenLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainGenSecurityLabel && +- driver->securitySecondaryDriver->domainGenSecurityLabel(vm) < 0) ++ driver->securitySecondaryDriver->domainGenSecurityLabel(driver->securitySecondaryDriver, ++ vm) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainGenSecurityLabel && +- driver->securityPrimaryDriver->domainGenSecurityLabel(vm) < 0) ++ driver->securityPrimaryDriver->domainGenSecurityLabel(driver->securityPrimaryDriver, ++ vm) < 0) + rc = -1; + + return rc; +@@ -76,18 +79,21 @@ qemuSecurityStackedGenLabel(virDomainObjPtr vm) + + + static int +-qemuSecurityStackedReleaseLabel(virDomainObjPtr vm) ++qemuSecurityStackedReleaseLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainReleaseSecurityLabel && +- driver->securitySecondaryDriver->domainReleaseSecurityLabel(vm) < 0) ++ driver->securitySecondaryDriver->domainReleaseSecurityLabel(driver->securitySecondaryDriver, ++ vm) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainReleaseSecurityLabel && +- driver->securityPrimaryDriver->domainReleaseSecurityLabel(vm) < 0) ++ driver->securityPrimaryDriver->domainReleaseSecurityLabel(driver->securityPrimaryDriver, ++ vm) < 0) + rc = -1; + + return rc; +@@ -95,18 +101,21 @@ qemuSecurityStackedReleaseLabel(virDomainObjPtr vm) + + + static int +-qemuSecurityStackedReserveLabel(virDomainObjPtr vm) ++qemuSecurityStackedReserveLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainReserveSecurityLabel && +- driver->securitySecondaryDriver->domainReserveSecurityLabel(vm) < 0) ++ driver->securitySecondaryDriver->domainReserveSecurityLabel(driver->securitySecondaryDriver, ++ vm) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainReserveSecurityLabel && +- driver->securityPrimaryDriver->domainReserveSecurityLabel(vm) < 0) ++ driver->securityPrimaryDriver->domainReserveSecurityLabel(driver->securityPrimaryDriver, ++ vm) < 0) + rc = -1; + + return rc; +@@ -114,19 +123,22 @@ qemuSecurityStackedReserveLabel(virDomainObjPtr vm) + + + static int +-qemuSecurityStackedSetSecurityImageLabel(virDomainObjPtr vm, ++qemuSecurityStackedSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainDiskDefPtr disk) + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainSetSecurityImageLabel && +- driver->securitySecondaryDriver->domainSetSecurityImageLabel(vm, disk) < 0) ++ driver->securitySecondaryDriver->domainSetSecurityImageLabel(driver->securitySecondaryDriver, ++ vm, disk) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainSetSecurityImageLabel && +- driver->securityPrimaryDriver->domainSetSecurityImageLabel(vm, disk) < 0) ++ driver->securityPrimaryDriver->domainSetSecurityImageLabel(driver->securityPrimaryDriver, ++ vm, disk) < 0) + rc = -1; + + return rc; +@@ -134,19 +146,22 @@ qemuSecurityStackedSetSecurityImageLabel(virDomainObjPtr vm, + + + static int +-qemuSecurityStackedRestoreSecurityImageLabel(virDomainObjPtr vm, ++qemuSecurityStackedRestoreSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainDiskDefPtr disk) + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainRestoreSecurityImageLabel && +- driver->securitySecondaryDriver->domainRestoreSecurityImageLabel(vm, disk) < 0) ++ driver->securitySecondaryDriver->domainRestoreSecurityImageLabel(driver->securitySecondaryDriver, ++ vm, disk) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainRestoreSecurityImageLabel && +- driver->securityPrimaryDriver->domainRestoreSecurityImageLabel(vm, disk) < 0) ++ driver->securityPrimaryDriver->domainRestoreSecurityImageLabel(driver->securityPrimaryDriver, ++ vm, disk) < 0) + rc = -1; + + return rc; +@@ -154,7 +169,8 @@ qemuSecurityStackedRestoreSecurityImageLabel(virDomainObjPtr vm, + + + static int +-qemuSecurityStackedSetSecurityHostdevLabel(virDomainObjPtr vm, ++qemuSecurityStackedSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainHostdevDefPtr dev) + + { +@@ -162,12 +178,14 @@ qemuSecurityStackedSetSecurityHostdevLabel(virDomainObjPtr vm, + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainSetSecurityHostdevLabel && +- driver->securitySecondaryDriver->domainSetSecurityHostdevLabel(vm, dev) < 0) ++ driver->securitySecondaryDriver->domainSetSecurityHostdevLabel(driver->securitySecondaryDriver, ++ vm, dev) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainSetSecurityHostdevLabel && +- driver->securityPrimaryDriver->domainSetSecurityHostdevLabel(vm, dev) < 0) ++ driver->securityPrimaryDriver->domainSetSecurityHostdevLabel(driver->securityPrimaryDriver, ++ vm, dev) < 0) + rc = -1; + + return rc; +@@ -175,20 +193,22 @@ qemuSecurityStackedSetSecurityHostdevLabel(virDomainObjPtr vm, + + + static int +-qemuSecurityStackedRestoreSecurityHostdevLabel(virDomainObjPtr vm, ++qemuSecurityStackedRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainHostdevDefPtr dev) +- + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel && +- driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel(vm, dev) < 0) ++ driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel(driver->securitySecondaryDriver, ++ vm, dev) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel && +- driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel(vm, dev) < 0) ++ driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel(driver->securityPrimaryDriver, ++ vm, dev) < 0) + rc = -1; + + return rc; +@@ -196,18 +216,22 @@ qemuSecurityStackedRestoreSecurityHostdevLabel(virDomainObjPtr vm, + + + static int +-qemuSecurityStackedSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_path) ++qemuSecurityStackedSetSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, ++ const char *stdin_path) + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainSetSecurityAllLabel && +- driver->securitySecondaryDriver->domainSetSecurityAllLabel(vm, stdin_path) < 0) ++ driver->securitySecondaryDriver->domainSetSecurityAllLabel(driver->securitySecondaryDriver, ++ vm, stdin_path) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainSetSecurityAllLabel && +- driver->securityPrimaryDriver->domainSetSecurityAllLabel(vm, stdin_path) < 0) ++ driver->securityPrimaryDriver->domainSetSecurityAllLabel(driver->securityPrimaryDriver, ++ vm, stdin_path) < 0) + rc = -1; + + return rc; +@@ -215,19 +239,22 @@ qemuSecurityStackedSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_pat + + + static int +-qemuSecurityStackedRestoreSecurityAllLabel(virDomainObjPtr vm, ++qemuSecurityStackedRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + int migrated) + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainRestoreSecurityAllLabel && +- driver->securitySecondaryDriver->domainRestoreSecurityAllLabel(vm, migrated) < 0) ++ driver->securitySecondaryDriver->domainRestoreSecurityAllLabel(driver->securitySecondaryDriver, ++ vm, migrated) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainRestoreSecurityAllLabel && +- driver->securityPrimaryDriver->domainRestoreSecurityAllLabel(vm, migrated) < 0) ++ driver->securityPrimaryDriver->domainRestoreSecurityAllLabel(driver->securityPrimaryDriver, ++ vm, migrated) < 0) + rc = -1; + + return rc; +@@ -235,19 +262,22 @@ qemuSecurityStackedRestoreSecurityAllLabel(virDomainObjPtr vm, + + + static int +-qemuSecurityStackedSetSavedStateLabel(virDomainObjPtr vm, ++qemuSecurityStackedSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + const char *savefile) + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainSetSavedStateLabel && +- driver->securitySecondaryDriver->domainSetSavedStateLabel(vm, savefile) < 0) ++ driver->securitySecondaryDriver->domainSetSavedStateLabel(driver->securitySecondaryDriver, ++ vm, savefile) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainSetSavedStateLabel && +- driver->securityPrimaryDriver->domainSetSavedStateLabel(vm, savefile) < 0) ++ driver->securityPrimaryDriver->domainSetSavedStateLabel(driver->securityPrimaryDriver, ++ vm, savefile) < 0) + rc = -1; + + return rc; +@@ -255,19 +285,22 @@ qemuSecurityStackedSetSavedStateLabel(virDomainObjPtr vm, + + + static int +-qemuSecurityStackedRestoreSavedStateLabel(virDomainObjPtr vm, ++qemuSecurityStackedRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + const char *savefile) + { + int rc = 0; + + if (driver->securitySecondaryDriver && + driver->securitySecondaryDriver->domainRestoreSavedStateLabel && +- driver->securitySecondaryDriver->domainRestoreSavedStateLabel(vm, savefile) < 0) ++ driver->securitySecondaryDriver->domainRestoreSavedStateLabel(driver->securitySecondaryDriver, ++ vm, savefile) < 0) + rc = -1; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainRestoreSavedStateLabel && +- driver->securityPrimaryDriver->domainRestoreSavedStateLabel(vm, savefile) < 0) ++ driver->securityPrimaryDriver->domainRestoreSavedStateLabel(driver->securityPrimaryDriver, ++ vm, savefile) < 0) + rc = -1; + + return rc; +@@ -296,14 +329,16 @@ qemuSecurityStackedSetProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, + } + + static int +-qemuSecurityStackedGetProcessLabel(virDomainObjPtr vm, ++qemuSecurityStackedGetProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virSecurityLabelPtr seclabel) + { + int rc = 0; + + if (driver->securityPrimaryDriver && + driver->securityPrimaryDriver->domainGetSecurityProcessLabel && +- driver->securityPrimaryDriver->domainGetSecurityProcessLabel(vm, ++ driver->securityPrimaryDriver->domainGetSecurityProcessLabel(driver->securityPrimaryDriver, ++ vm, + seclabel) < 0) + rc = -1; + +diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c +index e883f69..cb5c739 100644 +--- a/src/security/security_apparmor.c ++++ b/src/security/security_apparmor.c +@@ -148,7 +148,8 @@ profile_status_file(const char *str) + * load (add) a profile. Will create one if necessary + */ + static int +-load_profile(const char *profile, virDomainObjPtr vm, ++load_profile(virSecurityDriverPtr drv, ++ const char *profile, virDomainObjPtr vm, + const char *fn) + { + int rc = -1, status, ret; +@@ -281,7 +282,8 @@ cleanup: + * NULL. + */ + static int +-reload_profile(virDomainObjPtr vm, const char *fn) ++reload_profile(virSecurityDriverPtr drv, ++ virDomainObjPtr vm, const char *fn) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; + int rc = -1; +@@ -295,7 +297,7 @@ reload_profile(virDomainObjPtr vm, const char *fn) + + /* Update the profile only if it is loaded */ + if (profile_loaded(secdef->imagelabel) >= 0) { +- if (load_profile(secdef->imagelabel, vm, fn) < 0) { ++ if (load_profile(drv, secdef->imagelabel, vm, fn) < 0) { + virSecurityReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot update AppArmor profile " + "\'%s\'"), +@@ -357,7 +359,8 @@ AppArmorSecurityDriverOpen(virSecurityDriverPtr drv) + * called on shutdown. + */ + static int +-AppArmorGenSecurityLabel(virDomainObjPtr vm) ++AppArmorGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + int rc = -1; + char *profile_name = NULL; +@@ -411,14 +414,15 @@ AppArmorGenSecurityLabel(virDomainObjPtr vm) + } + + static int +-AppArmorSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_path) ++AppArmorSetSecurityAllLabel(virSecurityDriverPtr drv, ++ virDomainObjPtr vm, const char *stdin_path) + { + if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC) + return 0; + + /* if the profile is not already loaded, then load one */ + if (profile_loaded(vm->def->seclabel.label) < 0) { +- if (load_profile(vm->def->seclabel.label, vm, stdin_path) < 0) { ++ if (load_profile(drv, vm->def->seclabel.label, vm, stdin_path) < 0) { + virSecurityReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot generate AppArmor profile " + "\'%s\'"), vm->def->seclabel.label); +@@ -433,7 +437,9 @@ AppArmorSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_path) + * running. + */ + static int +-AppArmorGetSecurityProcessLabel(virDomainObjPtr vm, virSecurityLabelPtr sec) ++AppArmorGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, ++ virSecurityLabelPtr sec) + { + int rc = -1; + char *profile_name = NULL; +@@ -465,7 +471,8 @@ AppArmorGetSecurityProcessLabel(virDomainObjPtr vm, virSecurityLabelPtr sec) + * more details. Currently called via qemudShutdownVMDaemon. + */ + static int +-AppArmorReleaseSecurityLabel(virDomainObjPtr vm) ++AppArmorReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; + +@@ -478,7 +485,8 @@ AppArmorReleaseSecurityLabel(virDomainObjPtr vm) + + + static int +-AppArmorRestoreSecurityAllLabel(virDomainObjPtr vm, ++AppArmorRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + int migrated ATTRIBUTE_UNUSED) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; +@@ -533,15 +541,17 @@ AppArmorSetSecurityProcessLabel(virSecurityDriverPtr drv, virDomainObjPtr vm) + + /* Called when hotplugging */ + static int +-AppArmorRestoreSecurityImageLabel(virDomainObjPtr vm, ++AppArmorRestoreSecurityImageLabel(virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + virDomainDiskDefPtr disk ATTRIBUTE_UNUSED) + { +- return reload_profile(vm, NULL); ++ return reload_profile(drv, vm, NULL); + } + + /* Called when hotplugging */ + static int +-AppArmorSetSecurityImageLabel(virDomainObjPtr vm, virDomainDiskDefPtr disk) ++AppArmorSetSecurityImageLabel(virSecurityDriverPtr drv, ++ virDomainObjPtr vm, virDomainDiskDefPtr disk) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; + int rc = -1; +@@ -566,7 +576,7 @@ AppArmorSetSecurityImageLabel(virDomainObjPtr vm, virDomainDiskDefPtr disk) + + /* update the profile only if it is loaded */ + if (profile_loaded(secdef->imagelabel) >= 0) { +- if (load_profile(secdef->imagelabel, vm, disk->src) < 0) { ++ if (load_profile(drv, secdef->imagelabel, vm, disk->src) < 0) { + virSecurityReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot update AppArmor profile " + "\'%s\'"), +@@ -600,14 +610,16 @@ AppArmorSecurityVerify(virDomainDefPtr def) + } + + static int +-AppArmorReserveSecurityLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED) ++AppArmorReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm ATTRIBUTE_UNUSED) + { + /* NOOP. Nothing to reserve with AppArmor */ + return 0; + } + + static int +-AppArmorSetSecurityHostdevLabel(virDomainObjPtr vm, ++AppArmorSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED) + + { +@@ -621,7 +633,8 @@ AppArmorSetSecurityHostdevLabel(virDomainObjPtr vm, + } + + static int +-AppArmorRestoreSecurityHostdevLabel(virDomainObjPtr vm, ++AppArmorRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED) + + { +@@ -634,18 +647,20 @@ AppArmorRestoreSecurityHostdevLabel(virDomainObjPtr vm, + } + + static int +-AppArmorSetSavedStateLabel(virDomainObjPtr vm, +- const char *savefile) ++AppArmorSetSavedStateLabel(virSecurityDriverPtr drv, ++ virDomainObjPtr vm, ++ const char *savefile) + { +- return reload_profile(vm, savefile); ++ return reload_profile(drv, vm, savefile); + } + + + static int +-AppArmorRestoreSavedStateLabel(virDomainObjPtr vm, ++AppArmorRestoreSavedStateLabel(virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + const char *savefile ATTRIBUTE_UNUSED) + { +- return reload_profile(vm, NULL); ++ return reload_profile(drv, vm, NULL); + } + + virSecurityDriver virAppArmorSecurityDriver = { +diff --git a/src/security/security_driver.h b/src/security/security_driver.h +index 99260a4..61c9eb0 100644 +--- a/src/security/security_driver.h ++++ b/src/security/security_driver.h +@@ -28,32 +28,48 @@ typedef enum { + + typedef struct _virSecurityDriver virSecurityDriver; + typedef virSecurityDriver *virSecurityDriverPtr; ++ ++typedef struct _virSecurityDriverState virSecurityDriverState; ++typedef virSecurityDriverState *virSecurityDriverStatePtr; ++ + typedef virSecurityDriverStatus (*virSecurityDriverProbe) (void); + typedef int (*virSecurityDriverOpen) (virSecurityDriverPtr drv); +-typedef int (*virSecurityDomainRestoreImageLabel) (virDomainObjPtr vm, ++typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + virDomainDiskDefPtr disk); + typedef int (*virSecurityDomainSetSocketLabel) (virSecurityDriverPtr drv, + virDomainObjPtr vm); + typedef int (*virSecurityDomainClearSocketLabel)(virSecurityDriverPtr drv, + virDomainObjPtr vm); +-typedef int (*virSecurityDomainSetImageLabel) (virDomainObjPtr vm, ++typedef int (*virSecurityDomainSetImageLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + virDomainDiskDefPtr disk); +-typedef int (*virSecurityDomainRestoreHostdevLabel) (virDomainObjPtr vm, ++typedef int (*virSecurityDomainRestoreHostdevLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + virDomainHostdevDefPtr dev); +-typedef int (*virSecurityDomainSetHostdevLabel) (virDomainObjPtr vm, ++typedef int (*virSecurityDomainSetHostdevLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + virDomainHostdevDefPtr dev); +-typedef int (*virSecurityDomainSetSavedStateLabel) (virDomainObjPtr vm, ++typedef int (*virSecurityDomainSetSavedStateLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + const char *savefile); +-typedef int (*virSecurityDomainRestoreSavedStateLabel) (virDomainObjPtr vm, ++typedef int (*virSecurityDomainRestoreSavedStateLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + const char *savefile); +-typedef int (*virSecurityDomainGenLabel) (virDomainObjPtr sec); +-typedef int (*virSecurityDomainReserveLabel) (virDomainObjPtr sec); +-typedef int (*virSecurityDomainReleaseLabel) (virDomainObjPtr sec); +-typedef int (*virSecurityDomainSetAllLabel) (virDomainObjPtr sec, ++typedef int (*virSecurityDomainGenLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr sec); ++typedef int (*virSecurityDomainReserveLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr sec); ++typedef int (*virSecurityDomainReleaseLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr sec); ++typedef int (*virSecurityDomainSetAllLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr sec, + const char *stdin_path); +-typedef int (*virSecurityDomainRestoreAllLabel) (virDomainObjPtr vm, ++typedef int (*virSecurityDomainRestoreAllLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + int migrated); +-typedef int (*virSecurityDomainGetProcessLabel) (virDomainObjPtr vm, ++typedef int (*virSecurityDomainGetProcessLabel) (virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + virSecurityLabelPtr sec); + typedef int (*virSecurityDomainSetProcessLabel) (virSecurityDriverPtr drv, + virDomainObjPtr vm); +diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c +index d191118..cc3812b 100644 +--- a/src/security/security_selinux.c ++++ b/src/security/security_selinux.c +@@ -156,7 +156,8 @@ SELinuxInitialize(void) + } + + static int +-SELinuxGenSecurityLabel(virDomainObjPtr vm) ++SELinuxGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + int rc = -1; + char mcs[1024]; +@@ -220,7 +221,8 @@ done: + } + + static int +-SELinuxReserveSecurityLabel(virDomainObjPtr vm) ++SELinuxReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + security_context_t pctx; + context_t ctx = NULL; +@@ -275,7 +277,8 @@ SELinuxSecurityDriverOpen(virSecurityDriverPtr drv) + } + + static int +-SELinuxGetSecurityProcessLabel(virDomainObjPtr vm, ++SELinuxGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virSecurityLabelPtr sec) + { + security_context_t ctx; +@@ -387,7 +390,8 @@ err: + } + + static int +-SELinuxRestoreSecurityImageLabelInt(virDomainObjPtr vm, ++SELinuxRestoreSecurityImageLabelInt(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainDiskDefPtr disk, + int migrated) + { +@@ -431,10 +435,11 @@ SELinuxRestoreSecurityImageLabelInt(virDomainObjPtr vm, + + + static int +-SELinuxRestoreSecurityImageLabel(virDomainObjPtr vm, ++SELinuxRestoreSecurityImageLabel(virSecurityDriverPtr drv, ++ virDomainObjPtr vm, + virDomainDiskDefPtr disk) + { +- return SELinuxRestoreSecurityImageLabelInt(vm, disk, 0); ++ return SELinuxRestoreSecurityImageLabelInt(drv, vm, disk, 0); + } + + +@@ -462,7 +467,8 @@ SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk, + } + + static int +-SELinuxSetSecurityImageLabel(virDomainObjPtr vm, ++SELinuxSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainDiskDefPtr disk) + + { +@@ -500,7 +506,8 @@ SELinuxSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED, + } + + static int +-SELinuxSetSecurityHostdevLabel(virDomainObjPtr vm, ++SELinuxSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainHostdevDefPtr dev) + + { +@@ -568,7 +575,8 @@ SELinuxRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED, + } + + static int +-SELinuxRestoreSecurityHostdevLabel(virDomainObjPtr vm, ++SELinuxRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + virDomainHostdevDefPtr dev) + + { +@@ -715,7 +723,8 @@ SELinuxRestoreSecurityChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED, + + + static int +-SELinuxRestoreSecurityAllLabel(virDomainObjPtr vm, ++SELinuxRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + int migrated ATTRIBUTE_UNUSED) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; +@@ -728,11 +737,14 @@ SELinuxRestoreSecurityAllLabel(virDomainObjPtr vm, + return 0; + + for (i = 0 ; i < vm->def->nhostdevs ; i++) { +- if (SELinuxRestoreSecurityHostdevLabel(vm, vm->def->hostdevs[i]) < 0) ++ if (SELinuxRestoreSecurityHostdevLabel(drv, ++ vm, ++ vm->def->hostdevs[i]) < 0) + rc = -1; + } + for (i = 0 ; i < vm->def->ndisks ; i++) { +- if (SELinuxRestoreSecurityImageLabelInt(vm, ++ if (SELinuxRestoreSecurityImageLabelInt(drv, ++ vm, + vm->def->disks[i], + migrated) < 0) + rc = -1; +@@ -756,7 +768,8 @@ SELinuxRestoreSecurityAllLabel(virDomainObjPtr vm, + } + + static int +-SELinuxReleaseSecurityLabel(virDomainObjPtr vm) ++SELinuxReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; + +@@ -779,7 +792,8 @@ SELinuxReleaseSecurityLabel(virDomainObjPtr vm) + + + static int +-SELinuxSetSavedStateLabel(virDomainObjPtr vm, ++SELinuxSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + const char *savefile) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; +@@ -792,7 +806,8 @@ SELinuxSetSavedStateLabel(virDomainObjPtr vm, + + + static int +-SELinuxRestoreSavedStateLabel(virDomainObjPtr vm, ++SELinuxRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED, ++ virDomainObjPtr vm, + const char *savefile) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; +@@ -963,7 +978,9 @@ SELinuxSetSecurityChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED, + + + static int +-SELinuxSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_path) ++SELinuxSetSecurityAllLabel(virSecurityDriverPtr drv, ++ virDomainObjPtr vm, ++ const char *stdin_path) + { + const virSecurityLabelDefPtr secdef = &vm->def->seclabel; + int i; +@@ -978,11 +995,14 @@ SELinuxSetSecurityAllLabel(virDomainObjPtr vm, const char *stdin_path) + vm->def->disks[i]->src, vm->def->disks[i]->dst); + continue; + } +- if (SELinuxSetSecurityImageLabel(vm, vm->def->disks[i]) < 0) ++ if (SELinuxSetSecurityImageLabel(drv, ++ vm, vm->def->disks[i]) < 0) + return -1; + } + for (i = 0 ; i < vm->def->nhostdevs ; i++) { +- if (SELinuxSetSecurityHostdevLabel(vm, vm->def->hostdevs[i]) < 0) ++ if (SELinuxSetSecurityHostdevLabel(drv, ++ vm, ++ vm->def->hostdevs[i]) < 0) + return -1; + } + +-- +1.7.1.1 + diff --git a/libvirt-0.8.2-08-disable-disk-probing.patch b/libvirt-0.8.2-08-disable-disk-probing.patch new file mode 100644 index 0000000..5952ad5 --- /dev/null +++ b/libvirt-0.8.2-08-disable-disk-probing.patch @@ -0,0 +1,468 @@ +From dac2b936e77f6c76c11f162e4b175492e4803acb Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +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 elements to include ++# 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 + diff --git a/libvirt-0.8.2-09-set-default-driver.patch b/libvirt-0.8.2-09-set-default-driver.patch new file mode 100644 index 0000000..93c4ca5 --- /dev/null +++ b/libvirt-0.8.2-09-set-default-driver.patch @@ -0,0 +1,94 @@ +From 3534cd47a57ee9cf7041472511444784f14d6939 Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +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 + diff --git a/libvirt-0.8.2-10-qemu-img-format-handling.patch b/libvirt-0.8.2-10-qemu-img-format-handling.patch new file mode 100644 index 0000000..813bf16 --- /dev/null +++ b/libvirt-0.8.2-10-qemu-img-format-handling.patch @@ -0,0 +1,291 @@ +From 2ba8625d6d148fa489586efabdfaf2ef20903762 Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +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 + diff --git a/libvirt-0.8.2-11-storage-vol-backing.patch b/libvirt-0.8.2-11-storage-vol-backing.patch new file mode 100644 index 0000000..7ffcc57 --- /dev/null +++ b/libvirt-0.8.2-11-storage-vol-backing.patch @@ -0,0 +1,165 @@ +From d33f44c2e74de28c89b64cdc2c0a6564662e075c Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +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 + diff --git a/libvirt-0.8.2-apply-iptables-sport-mapping.patch b/libvirt-0.8.2-apply-iptables-sport-mapping.patch new file mode 100644 index 0000000..d929a34 --- /dev/null +++ b/libvirt-0.8.2-apply-iptables-sport-mapping.patch @@ -0,0 +1,265 @@ +From 112a309bc7839e95c558b535143f855ce89cca8c Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +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 + diff --git a/libvirt-change-logrotate-config-to-weekly.patch b/libvirt-change-logrotate-config-to-weekly.patch deleted file mode 100644 index 4e80077..0000000 --- a/libvirt-change-logrotate-config-to-weekly.patch +++ /dev/null @@ -1,34 +0,0 @@ -From bcd4180124afa20580d720912e2179b3a2f9295a Mon Sep 17 00:00:00 2001 -From: Daniel Veillard -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 - diff --git a/libvirt-disable-audio-backend.patch b/libvirt-disable-audio-backend.patch deleted file mode 100644 index 329a98f..0000000 --- a/libvirt-disable-audio-backend.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 4721ceb9b85daabe53804627473b06ced821c695 Mon Sep 17 00:00:00 2001 -From: Daniel P. Berrange -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 - diff --git a/libvirt-double-free-on-virsh-error.patch b/libvirt-double-free-on-virsh-error.patch deleted file mode 100644 index e8e2e57..0000000 --- a/libvirt-double-free-on-virsh-error.patch +++ /dev/null @@ -1,1901 +0,0 @@ -From 4eca48753dfa5f584fb22d133145a24f9146d389 Mon Sep 17 00:00:00 2001 -From: Jim Fehlig -Date: Tue, 29 Sep 2009 13:42:42 +0200 -Subject: [PATCH] Avoid double free in errors in virsh - -* tools/virsh.c: it was possible to get vshDeinit to call itself back - via vshError, remove the doexit parameter of vshError to avoid the - possibility and make sure to exit directly after in those case. - -(cherry picked from commit 1caa19cb0667233e9775d9d860c4766151542d23) - -Fedora-patch: libvirt-double-free-on-virsh-error.patch ---- - src/virsh.c | 515 ++++++++++++++++++++++++++++------------------------------- - 1 files changed, 246 insertions(+), 269 deletions(-) - -diff --git a/src/virsh.c b/src/virsh.c -index 4825f1c..3482389 100644 ---- a/src/virsh.c -+++ b/src/virsh.c -@@ -202,8 +202,8 @@ typedef struct __vshControl { - - static const vshCmdDef commands[]; - --static void vshError(vshControl *ctl, int doexit, const char *format, ...) -- ATTRIBUTE_FMT_PRINTF(3, 4); -+static void vshError(vshControl *ctl, const char *format, ...) -+ ATTRIBUTE_FMT_PRINTF(2, 3); - static int vshInit(vshControl *ctl); - static int vshDeinit(vshControl *ctl); - static void vshUsage(void); -@@ -351,11 +351,11 @@ virshReportError(vshControl *ctl) - return; - - if (last_error->code == VIR_ERR_OK) { -- vshError(ctl, FALSE, "%s", _("unknown error")); -+ vshError(ctl, "%s", _("unknown error")); - goto out; - } - -- vshError(ctl, FALSE, "%s", last_error->message); -+ vshError(ctl, "%s", last_error->message); - - out: - virFreeError(last_error); -@@ -433,11 +433,9 @@ cmdAutostart(vshControl *ctl, const vshCmd *cmd) - - if (virDomainSetAutostart(dom, autostart) < 0) { - if (autostart) -- vshError(ctl, FALSE, _("Failed to mark domain %s as autostarted"), -- name); -+ vshError(ctl, _("Failed to mark domain %s as autostarted"), name); - else -- vshError(ctl, FALSE, _("Failed to unmark domain %s as autostarted"), -- name); -+ vshError(ctl, _("Failed to unmark domain %s as autostarted"), name); - virDomainFree(dom); - return FALSE; - } -@@ -474,8 +472,7 @@ cmdConnect(vshControl *ctl, const vshCmd *cmd) - - if (ctl->conn) { - if (virConnectClose(ctl->conn) != 0) { -- vshError(ctl, FALSE, "%s", -- _("Failed to disconnect from the hypervisor")); -+ vshError(ctl, "%s", _("Failed to disconnect from the hypervisor")); - return FALSE; - } - ctl->conn = NULL; -@@ -494,7 +491,7 @@ cmdConnect(vshControl *ctl, const vshCmd *cmd) - ctl->readonly ? VIR_CONNECT_RO : 0); - - if (!ctl->conn) -- vshError(ctl, FALSE, "%s", _("Failed to connect to the hypervisor")); -+ vshError(ctl, "%s", _("Failed to connect to the hypervisor")); - - return ctl->conn ? TRUE : FALSE; - } -@@ -528,17 +525,17 @@ cmdRunConsole(vshControl *ctl, virDomainPtr dom) - char *thisHost = NULL; - - if (!(thisHost = virGetHostname())) { -- vshError(ctl, FALSE, "%s", _("Failed to get local hostname")); -+ vshError(ctl, "%s", _("Failed to get local hostname")); - goto cleanup; - } - - if (!(thatHost = virConnectGetHostname(ctl->conn))) { -- vshError(ctl, FALSE, "%s", _("Failed to get connection hostname")); -+ vshError(ctl, "%s", _("Failed to get connection hostname")); - goto cleanup; - } - - if (STRNEQ(thisHost, thatHost)) { -- vshError(ctl, FALSE, "%s", _("Cannot connect to a remote console device")); -+ vshError(ctl, "%s", _("Cannot connect to a remote console device")); - goto cleanup; - } - -@@ -632,14 +629,14 @@ cmdList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - if (active) { - maxid = virConnectNumOfDomains(ctl->conn); - if (maxid < 0) { -- vshError(ctl, FALSE, "%s", _("Failed to list active domains")); -+ vshError(ctl, "%s", _("Failed to list active domains")); - return FALSE; - } - if (maxid) { - ids = vshMalloc(ctl, sizeof(int) * maxid); - - if ((maxid = virConnectListDomains(ctl->conn, &ids[0], maxid)) < 0) { -- vshError(ctl, FALSE, "%s", _("Failed to list active domains")); -+ vshError(ctl, "%s", _("Failed to list active domains")); - free(ids); - return FALSE; - } -@@ -650,7 +647,7 @@ cmdList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - if (inactive) { - maxname = virConnectNumOfDefinedDomains(ctl->conn); - if (maxname < 0) { -- vshError(ctl, FALSE, "%s", _("Failed to list inactive domains")); -+ vshError(ctl, "%s", _("Failed to list inactive domains")); - free(ids); - return FALSE; - } -@@ -658,7 +655,7 @@ cmdList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - names = vshMalloc(ctl, sizeof(char *) * maxname); - - if ((maxname = virConnectListDefinedDomains(ctl->conn, names, maxname)) < 0) { -- vshError(ctl, FALSE, "%s", _("Failed to list inactive domains")); -+ vshError(ctl, "%s", _("Failed to list inactive domains")); - free(ids); - free(names); - return FALSE; -@@ -786,8 +783,7 @@ cmdDomblkstat (vshControl *ctl, const vshCmd *cmd) - } - - if (virDomainBlockStats (dom, device, &stats, sizeof stats) == -1) { -- vshError (ctl, FALSE, _("Failed to get block stats %s %s"), -- name, device); -+ vshError(ctl, _("Failed to get block stats %s %s"), name, device); - virDomainFree(dom); - return FALSE; - } -@@ -844,8 +840,7 @@ cmdDomIfstat (vshControl *ctl, const vshCmd *cmd) - } - - if (virDomainInterfaceStats (dom, device, &stats, sizeof stats) == -1) { -- vshError (ctl, FALSE, _("Failed to get interface stats %s %s"), -- name, device); -+ vshError(ctl, _("Failed to get interface stats %s %s"), name, device); - virDomainFree(dom); - return FALSE; - } -@@ -908,7 +903,7 @@ cmdSuspend(vshControl *ctl, const vshCmd *cmd) - if (virDomainSuspend(dom) == 0) { - vshPrint(ctl, _("Domain %s suspended\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to suspend domain %s"), name); -+ vshError(ctl, _("Failed to suspend domain %s"), name); - ret = FALSE; - } - -@@ -967,7 +962,7 @@ cmdCreate(vshControl *ctl, const vshCmd *cmd) - #endif - virDomainFree(dom); - } else { -- vshError(ctl, FALSE, _("Failed to create domain from %s"), from); -+ vshError(ctl, _("Failed to create domain from %s"), from); - ret = FALSE; - } - return ret; -@@ -1014,7 +1009,7 @@ cmdDefine(vshControl *ctl, const vshCmd *cmd) - virDomainGetName(dom), from); - virDomainFree(dom); - } else { -- vshError(ctl, FALSE, _("Failed to define domain from %s"), from); -+ vshError(ctl, _("Failed to define domain from %s"), from); - ret = FALSE; - } - return ret; -@@ -1052,9 +1047,11 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd) - - if (name && virStrToLong_i(name, NULL, 10, &id) == 0 - && id >= 0 && (dom = virDomainLookupByID(ctl->conn, id))) { -- vshError(ctl, FALSE, _("a running domain like %s cannot be undefined;\n" -- "to undefine, first shutdown then undefine" -- " using its name or UUID"), name); -+ vshError(ctl, -+ _("a running domain like %s cannot be undefined;\n" -+ "to undefine, first shutdown then undefine" -+ " using its name or UUID"), -+ name); - virDomainFree(dom); - return FALSE; - } -@@ -1065,7 +1062,7 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd) - if (virDomainUndefine(dom) == 0) { - vshPrint(ctl, _("Domain %s has been undefined\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to undefine domain %s"), name); -+ vshError(ctl, _("Failed to undefine domain %s"), name); - ret = FALSE; - } - -@@ -1107,7 +1104,7 @@ cmdStart(vshControl *ctl, const vshCmd *cmd) - return FALSE; - - if (virDomainGetID(dom) != (unsigned int)-1) { -- vshError(ctl, FALSE, "%s", _("Domain is already active")); -+ vshError(ctl, "%s", _("Domain is already active")); - virDomainFree(dom); - return FALSE; - } -@@ -1120,8 +1117,7 @@ cmdStart(vshControl *ctl, const vshCmd *cmd) - cmdRunConsole(ctl, dom); - #endif - } else { -- vshError(ctl, FALSE, _("Failed to start domain %s"), -- virDomainGetName(dom)); -+ vshError(ctl, _("Failed to start domain %s"), virDomainGetName(dom)); - ret = FALSE; - } - virDomainFree(dom); -@@ -1163,7 +1159,7 @@ cmdSave(vshControl *ctl, const vshCmd *cmd) - if (virDomainSave(dom, to) == 0) { - vshPrint(ctl, _("Domain %s saved to %s\n"), name, to); - } else { -- vshError(ctl, FALSE, _("Failed to save domain %s to %s"), name, to); -+ vshError(ctl, _("Failed to save domain %s to %s"), name, to); - ret = FALSE; - } - -@@ -1202,7 +1198,7 @@ cmdSchedInfoUpdate(vshControl *ctl, const vshCmd *cmd, - int val; - val = vshCommandOptInt(cmd, "weight", &found); - if (!found) { -- vshError(ctl, FALSE, "%s", _("Invalid value of weight")); -+ vshError(ctl, "%s", _("Invalid value of weight")); - return -1; - } else { - param->value.ui = val; -@@ -1217,7 +1213,7 @@ cmdSchedInfoUpdate(vshControl *ctl, const vshCmd *cmd, - int val; - val = vshCommandOptInt(cmd, "cap", &found); - if (!found) { -- vshError(ctl, FALSE, "%s", _("Invalid value of cap")); -+ vshError(ctl, "%s", _("Invalid value of cap")); - return -1; - } else { - param->value.ui = val; -@@ -1229,7 +1225,7 @@ cmdSchedInfoUpdate(vshControl *ctl, const vshCmd *cmd, - char *val = strchr(data, '='); - int match = 0; - if (!val) { -- vshError(ctl, FALSE, "%s", _("Invalid syntax for --set, expecting name=value")); -+ vshError(ctl, "%s", _("Invalid syntax for --set, expecting name=value")); - return -1; - } - *val = '\0'; -@@ -1243,35 +1239,35 @@ cmdSchedInfoUpdate(vshControl *ctl, const vshCmd *cmd, - switch (param->type) { - case VIR_DOMAIN_SCHED_FIELD_INT: - if (virStrToLong_i(val, NULL, 10, ¶m->value.i) < 0) { -- vshError(ctl, FALSE, "%s", -+ vshError(ctl, "%s", - _("Invalid value for parameter, expecting an int")); - return -1; - } - break; - case VIR_DOMAIN_SCHED_FIELD_UINT: - if (virStrToLong_ui(val, NULL, 10, ¶m->value.ui) < 0) { -- vshError(ctl, FALSE, "%s", -+ vshError(ctl, "%s", - _("Invalid value for parameter, expecting an unsigned int")); - return -1; - } - break; - case VIR_DOMAIN_SCHED_FIELD_LLONG: - if (virStrToLong_ll(val, NULL, 10, ¶m->value.l) < 0) { -- vshError(ctl, FALSE, "%s", -+ vshError(ctl, "%s", - _("Invalid value for parameter, expecting an long long")); - return -1; - } - break; - case VIR_DOMAIN_SCHED_FIELD_ULLONG: - if (virStrToLong_ull(val, NULL, 10, ¶m->value.ul) < 0) { -- vshError(ctl, FALSE, "%s", -+ vshError(ctl, "%s", - _("Invalid value for parameter, expecting an unsigned long long")); - return -1; - } - break; - case VIR_DOMAIN_SCHED_FIELD_DOUBLE: - if (virStrToDouble(val, NULL, ¶m->value.d) < 0) { -- vshError(ctl, FALSE, "%s", _("Invalid value for parameter, expecting a double")); -+ vshError(ctl, "%s", _("Invalid value for parameter, expecting a double")); - return -1; - } - break; -@@ -1408,7 +1404,7 @@ cmdRestore(vshControl *ctl, const vshCmd *cmd) - if (virDomainRestore(ctl->conn, from) == 0) { - vshPrint(ctl, _("Domain restored from %s\n"), from); - } else { -- vshError(ctl, FALSE, _("Failed to restore domain from %s"), from); -+ vshError(ctl, _("Failed to restore domain from %s"), from); - ret = FALSE; - } - return ret; -@@ -1449,8 +1445,7 @@ cmdDump(vshControl *ctl, const vshCmd *cmd) - if (virDomainCoreDump(dom, to, 0) == 0) { - vshPrint(ctl, _("Domain %s dumped to %s\n"), name, to); - } else { -- vshError(ctl, FALSE, _("Failed to core dump domain %s to %s"), -- name, to); -+ vshError(ctl, _("Failed to core dump domain %s to %s"), name, to); - ret = FALSE; - } - -@@ -1488,7 +1483,7 @@ cmdResume(vshControl *ctl, const vshCmd *cmd) - if (virDomainResume(dom) == 0) { - vshPrint(ctl, _("Domain %s resumed\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to resume domain %s"), name); -+ vshError(ctl, _("Failed to resume domain %s"), name); - ret = FALSE; - } - -@@ -1526,7 +1521,7 @@ cmdShutdown(vshControl *ctl, const vshCmd *cmd) - if (virDomainShutdown(dom) == 0) { - vshPrint(ctl, _("Domain %s is being shutdown\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to shutdown domain %s"), name); -+ vshError(ctl, _("Failed to shutdown domain %s"), name); - ret = FALSE; - } - -@@ -1564,7 +1559,7 @@ cmdReboot(vshControl *ctl, const vshCmd *cmd) - if (virDomainReboot(dom, 0) == 0) { - vshPrint(ctl, _("Domain %s is being rebooted\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to reboot domain %s"), name); -+ vshError(ctl, _("Failed to reboot domain %s"), name); - ret = FALSE; - } - -@@ -1602,7 +1597,7 @@ cmdDestroy(vshControl *ctl, const vshCmd *cmd) - if (virDomainDestroy(dom) == 0) { - vshPrint(ctl, _("Domain %s destroyed\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to destroy domain %s"), name); -+ vshError(ctl, _("Failed to destroy domain %s"), name); - ret = FALSE; - } - -@@ -1835,8 +1830,8 @@ cmdVcpuinfo(vshControl *ctl, const vshCmd *cmd) - } - } else { - if (info.state == VIR_DOMAIN_SHUTOFF) { -- vshError(ctl, FALSE, "%s", -- _("Domain shut off, virtual CPUs not present.")); -+ vshError(ctl, "%s", -+ _("Domain shut off, virtual CPUs not present.")); - } - ret = FALSE; - } -@@ -1886,14 +1881,13 @@ cmdVcpupin(vshControl *ctl, const vshCmd *cmd) - - vcpu = vshCommandOptInt(cmd, "vcpu", &vcpufound); - if (!vcpufound) { -- vshError(ctl, FALSE, "%s", -- _("vcpupin: Invalid or missing vCPU number.")); -+ vshError(ctl, "%s", _("vcpupin: Invalid or missing vCPU number.")); - virDomainFree(dom); - return FALSE; - } - - if (!(cpulist = vshCommandOptString(cmd, "cpulist", NULL))) { -- vshError(ctl, FALSE, "%s", _("vcpupin: Missing cpulist")); -+ vshError(ctl, "%s", _("vcpupin: Missing cpulist")); - virDomainFree(dom); - return FALSE; - } -@@ -1904,14 +1898,13 @@ cmdVcpupin(vshControl *ctl, const vshCmd *cmd) - } - - if (virDomainGetInfo(dom, &info) != 0) { -- vshError(ctl, FALSE, "%s", -- _("vcpupin: failed to get domain informations.")); -+ vshError(ctl, "%s", _("vcpupin: failed to get domain informations.")); - virDomainFree(dom); - return FALSE; - } - - if (vcpu >= info.nrVirtCpu) { -- vshError(ctl, FALSE, "%s", _("vcpupin: Invalid vCPU number.")); -+ vshError(ctl, "%s", _("vcpupin: Invalid vCPU number.")); - virDomainFree(dom); - return FALSE; - } -@@ -1920,7 +1913,7 @@ cmdVcpupin(vshControl *ctl, const vshCmd *cmd) - * numbers and give an intelligent error message if not. - */ - if (cpulist[0] == '\0') { -- vshError(ctl, FALSE, "%s", _("cpulist: Invalid format. Empty string.")); -+ vshError(ctl, "%s", _("cpulist: Invalid format. Empty string.")); - virDomainFree (dom); - return FALSE; - } -@@ -1930,7 +1923,9 @@ cmdVcpupin(vshControl *ctl, const vshCmd *cmd) - switch (state) { - case expect_num: - if (!c_isdigit (cpulist[i])) { -- vshError( ctl, FALSE, _("cpulist: %s: Invalid format. Expecting digit at position %d (near '%c')."), cpulist, i, cpulist[i]); -+ vshError(ctl, _("cpulist: %s: Invalid format. Expecting " -+ "digit at position %d (near '%c')."), -+ cpulist, i, cpulist[i]); - virDomainFree (dom); - return FALSE; - } -@@ -1940,14 +1935,18 @@ cmdVcpupin(vshControl *ctl, const vshCmd *cmd) - if (cpulist[i] == ',') - state = expect_num; - else if (!c_isdigit (cpulist[i])) { -- vshError(ctl, FALSE, _("cpulist: %s: Invalid format. Expecting digit or comma at position %d (near '%c')."), cpulist, i, cpulist[i]); -+ vshError(ctl, _("cpulist: %s: Invalid format. Expecting " -+ "digit or comma at position %d (near '%c')."), -+ cpulist, i, cpulist[i]); - virDomainFree (dom); - return FALSE; - } - } - } - if (state == expect_num) { -- vshError(ctl, FALSE, _("cpulist: %s: Invalid format. Trailing comma at position %d."), cpulist, i); -+ vshError(ctl, _("cpulist: %s: Invalid format. Trailing comma " -+ "at position %d."), -+ cpulist, i); - virDomainFree (dom); - return FALSE; - } -@@ -1961,7 +1960,7 @@ cmdVcpupin(vshControl *ctl, const vshCmd *cmd) - if (cpu < VIR_NODEINFO_MAXCPUS(nodeinfo)) { - VIR_USE_CPU(cpumap, cpu); - } else { -- vshError(ctl, FALSE, _("Physical CPU %d doesn't exist."), cpu); -+ vshError(ctl, _("Physical CPU %d doesn't exist."), cpu); - free(cpumap); - virDomainFree(dom); - return FALSE; -@@ -2011,7 +2010,7 @@ cmdSetvcpus(vshControl *ctl, const vshCmd *cmd) - - count = vshCommandOptInt(cmd, "count", &count); - if (count <= 0) { -- vshError(ctl, FALSE, "%s", _("Invalid number of virtual CPUs.")); -+ vshError(ctl, "%s", _("Invalid number of virtual CPUs.")); - virDomainFree(dom); - return FALSE; - } -@@ -2023,7 +2022,7 @@ cmdSetvcpus(vshControl *ctl, const vshCmd *cmd) - } - - if (count > maxcpu) { -- vshError(ctl, FALSE, "%s", _("Too many virtual CPUs.")); -+ vshError(ctl, "%s", _("Too many virtual CPUs.")); - virDomainFree(dom); - return FALSE; - } -@@ -2068,19 +2067,19 @@ cmdSetmem(vshControl *ctl, const vshCmd *cmd) - kilobytes = vshCommandOptInt(cmd, "kilobytes", &kilobytes); - if (kilobytes <= 0) { - virDomainFree(dom); -- vshError(ctl, FALSE, _("Invalid value of %d for memory size"), kilobytes); -+ vshError(ctl, _("Invalid value of %d for memory size"), kilobytes); - return FALSE; - } - - if (virDomainGetInfo(dom, &info) != 0) { - virDomainFree(dom); -- vshError(ctl, FALSE, "%s", _("Unable to verify MaxMemorySize")); -+ vshError(ctl, "%s", _("Unable to verify MaxMemorySize")); - return FALSE; - } - - if (kilobytes > info.maxMem) { - virDomainFree(dom); -- vshError(ctl, FALSE, _("Invalid value of %d for memory size"), kilobytes); -+ vshError(ctl, _("Invalid value of %d for memory size"), kilobytes); - return FALSE; - } - -@@ -2124,26 +2123,26 @@ cmdSetmaxmem(vshControl *ctl, const vshCmd *cmd) - kilobytes = vshCommandOptInt(cmd, "kilobytes", &kilobytes); - if (kilobytes <= 0) { - virDomainFree(dom); -- vshError(ctl, FALSE, _("Invalid value of %d for memory size"), kilobytes); -+ vshError(ctl, _("Invalid value of %d for memory size"), kilobytes); - return FALSE; - } - - if (virDomainGetInfo(dom, &info) != 0) { - virDomainFree(dom); -- vshError(ctl, FALSE, "%s", _("Unable to verify current MemorySize")); -+ vshError(ctl, "%s", _("Unable to verify current MemorySize")); - return FALSE; - } - - if (kilobytes < info.memory) { - if (virDomainSetMemory(dom, kilobytes) != 0) { - virDomainFree(dom); -- vshError(ctl, FALSE, "%s", _("Unable to shrink current MemorySize")); -+ vshError(ctl, "%s", _("Unable to shrink current MemorySize")); - return FALSE; - } - } - - if (virDomainSetMaxMemory(dom, kilobytes) != 0) { -- vshError(ctl, FALSE, "%s", _("Unable to change MaxMemorySize")); -+ vshError(ctl, "%s", _("Unable to change MaxMemorySize")); - ret = FALSE; - } - -@@ -2169,7 +2168,7 @@ cmdNodeinfo(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - return FALSE; - - if (virNodeGetInfo(ctl->conn, &info) < 0) { -- vshError(ctl, FALSE, "%s", _("failed to get node information")); -+ vshError(ctl, "%s", _("failed to get node information")); - return FALSE; - } - vshPrint(ctl, "%-20s %s\n", _("CPU model:"), info.model); -@@ -2202,7 +2201,7 @@ cmdCapabilities (vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - return FALSE; - - if ((caps = virConnectGetCapabilities (ctl->conn)) == NULL) { -- vshError(ctl, FALSE, "%s", _("failed to get capabilities")); -+ vshError(ctl, "%s", _("failed to get capabilities")); - return FALSE; - } - vshPrint (ctl, "%s\n", caps); -@@ -2446,7 +2445,7 @@ cmdDomuuid(vshControl *ctl, const vshCmd *cmd) - if (virDomainGetUUIDString(dom, uuid) != -1) - vshPrint(ctl, "%s\n", uuid); - else -- vshError(ctl, FALSE, "%s", _("failed to get domain UUID")); -+ vshError(ctl, "%s", _("failed to get domain UUID")); - - virDomainFree(dom); - return TRUE; -@@ -2489,7 +2488,7 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd) - - desturi = vshCommandOptString (cmd, "desturi", &found); - if (!found) { -- vshError (ctl, FALSE, "%s", _("migrate: Missing desturi")); -+ vshError(ctl, "%s", _("migrate: Missing desturi")); - goto done; - } - -@@ -2550,11 +2549,9 @@ cmdNetworkAutostart(vshControl *ctl, const vshCmd *cmd) - - if (virNetworkSetAutostart(network, autostart) < 0) { - if (autostart) -- vshError(ctl, FALSE, _("failed to mark network %s as autostarted"), -- name); -+ vshError(ctl, _("failed to mark network %s as autostarted"), name); - else -- vshError(ctl, FALSE,_("failed to unmark network %s as autostarted"), -- name); -+ vshError(ctl, _("failed to unmark network %s as autostarted"), name); - virNetworkFree(network); - return FALSE; - } -@@ -2609,7 +2606,7 @@ cmdNetworkCreate(vshControl *ctl, const vshCmd *cmd) - virNetworkGetName(network), from); - virNetworkFree(network); - } else { -- vshError(ctl, FALSE, _("Failed to create network from %s"), from); -+ vshError(ctl, _("Failed to create network from %s"), from); - ret = FALSE; - } - return ret; -@@ -2657,7 +2654,7 @@ cmdNetworkDefine(vshControl *ctl, const vshCmd *cmd) - virNetworkGetName(network), from); - virNetworkFree(network); - } else { -- vshError(ctl, FALSE, _("Failed to define network from %s"), from); -+ vshError(ctl, _("Failed to define network from %s"), from); - ret = FALSE; - } - return ret; -@@ -2694,7 +2691,7 @@ cmdNetworkDestroy(vshControl *ctl, const vshCmd *cmd) - if (virNetworkDestroy(network) == 0) { - vshPrint(ctl, _("Network %s destroyed\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to destroy network %s"), name); -+ vshError(ctl, _("Failed to destroy network %s"), name); - ret = FALSE; - } - -@@ -2811,8 +2808,8 @@ cmdInterfaceEdit (vshControl *ctl, const vshCmd *cmd) - goto cleanup; - - if (STRNEQ (doc, doc_reread)) { -- vshError (ctl, FALSE, "%s", -- _("ERROR: the XML configuration was changed by another user")); -+ vshError(ctl, "%s", -+ _("ERROR: the XML configuration was changed by another user")); - goto cleanup; - } - -@@ -2874,7 +2871,7 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - if (active) { - maxactive = virConnectNumOfNetworks(ctl->conn); - if (maxactive < 0) { -- vshError(ctl, FALSE, "%s", _("Failed to list active networks")); -+ vshError(ctl, "%s", _("Failed to list active networks")); - return FALSE; - } - if (maxactive) { -@@ -2882,7 +2879,7 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - - if ((maxactive = virConnectListNetworks(ctl->conn, activeNames, - maxactive)) < 0) { -- vshError(ctl, FALSE, "%s", _("Failed to list active networks")); -+ vshError(ctl, "%s", _("Failed to list active networks")); - free(activeNames); - return FALSE; - } -@@ -2893,7 +2890,7 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - if (inactive) { - maxinactive = virConnectNumOfDefinedNetworks(ctl->conn); - if (maxinactive < 0) { -- vshError(ctl, FALSE, "%s", _("Failed to list inactive networks")); -+ vshError(ctl, "%s", _("Failed to list inactive networks")); - free(activeNames); - return FALSE; - } -@@ -2903,8 +2900,7 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - if ((maxinactive = - virConnectListDefinedNetworks(ctl->conn, inactiveNames, - maxinactive)) < 0) { -- vshError(ctl, FALSE, "%s", -- _("Failed to list inactive networks")); -+ vshError(ctl, "%s", _("Failed to list inactive networks")); - free(activeNames); - free(inactiveNames); - return FALSE; -@@ -3032,7 +3028,7 @@ cmdNetworkStart(vshControl *ctl, const vshCmd *cmd) - vshPrint(ctl, _("Network %s started\n"), - virNetworkGetName(network)); - } else { -- vshError(ctl, FALSE, _("Failed to start network %s"), -+ vshError(ctl, _("Failed to start network %s"), - virNetworkGetName(network)); - ret = FALSE; - } -@@ -3071,7 +3067,7 @@ cmdNetworkUndefine(vshControl *ctl, const vshCmd *cmd) - if (virNetworkUndefine(network) == 0) { - vshPrint(ctl, _("Network %s has been undefined\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to undefine network %s"), name); -+ vshError(ctl, _("Failed to undefine network %s"), name); - ret = FALSE; - } - -@@ -3110,7 +3106,7 @@ cmdNetworkUuid(vshControl *ctl, const vshCmd *cmd) - if (virNetworkGetUUIDString(network, uuid) != -1) - vshPrint(ctl, "%s\n", uuid); - else -- vshError(ctl, FALSE, "%s", _("failed to get network UUID")); -+ vshError(ctl, "%s", _("failed to get network UUID")); - - virNetworkFree(network); - return TRUE; -@@ -3148,7 +3144,7 @@ cmdInterfaceList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - if (active) { - maxactive = virConnectNumOfInterfaces(ctl->conn); - if (maxactive < 0) { -- vshError(ctl, FALSE, "%s", _("Failed to list active interfaces")); -+ vshError(ctl, "%s", _("Failed to list active interfaces")); - return FALSE; - } - if (maxactive) { -@@ -3156,8 +3152,7 @@ cmdInterfaceList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - - if ((maxactive = virConnectListInterfaces(ctl->conn, activeNames, - maxactive)) < 0) { -- vshError(ctl, FALSE, "%s", -- _("Failed to list active interfaces")); -+ vshError(ctl, "%s", _("Failed to list active interfaces")); - free(activeNames); - return FALSE; - } -@@ -3168,8 +3163,7 @@ cmdInterfaceList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - if (inactive) { - maxinactive = virConnectNumOfDefinedInterfaces(ctl->conn); - if (maxinactive < 0) { -- vshError(ctl, FALSE, "%s", -- _("Failed to list inactive interfaces")); -+ vshError(ctl, "%s", _("Failed to list inactive interfaces")); - free(activeNames); - return FALSE; - } -@@ -3179,8 +3173,7 @@ cmdInterfaceList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - if ((maxinactive = - virConnectListDefinedInterfaces(ctl->conn, inactiveNames, - maxinactive)) < 0) { -- vshError(ctl, FALSE, "%s", -- _("Failed to list inactive interfaces")); -+ vshError(ctl, "%s", _("Failed to list inactive interfaces")); - free(activeNames); - free(inactiveNames); - return FALSE; -@@ -3373,7 +3366,7 @@ cmdInterfaceDefine(vshControl *ctl, const vshCmd *cmd) - virInterfaceGetName(iface), from); - virInterfaceFree (iface); - } else { -- vshError(ctl, FALSE, _("Failed to define interface from %s"), from); -+ vshError(ctl, _("Failed to define interface from %s"), from); - ret = FALSE; - } - return ret; -@@ -3409,7 +3402,7 @@ cmdInterfaceUndefine(vshControl *ctl, const vshCmd *cmd) - if (virInterfaceUndefine(iface) == 0) { - vshPrint(ctl, _("Interface %s undefined\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to undefine interface %s"), name); -+ vshError(ctl, _("Failed to undefine interface %s"), name); - ret = FALSE; - } - -@@ -3447,7 +3440,7 @@ cmdInterfaceStart(vshControl *ctl, const vshCmd *cmd) - if (virInterfaceCreate(iface, 0) == 0) { - vshPrint(ctl, _("Interface %s started\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to start interface %s"), name); -+ vshError(ctl, _("Failed to start interface %s"), name); - ret = FALSE; - } - -@@ -3485,7 +3478,7 @@ cmdInterfaceDestroy(vshControl *ctl, const vshCmd *cmd) - if (virInterfaceDestroy(iface, 0) == 0) { - vshPrint(ctl, _("Interface %s destroyed\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to destroy interface %s"), name); -+ vshError(ctl, _("Failed to destroy interface %s"), name); - ret = FALSE; - } - -@@ -3527,11 +3520,9 @@ cmdPoolAutostart(vshControl *ctl, const vshCmd *cmd) - - if (virStoragePoolSetAutostart(pool, autostart) < 0) { - if (autostart) -- vshError(ctl, FALSE, _("failed to mark pool %s as autostarted"), -- name); -+ vshError(ctl, _("failed to mark pool %s as autostarted"), name); - else -- vshError(ctl, FALSE,_("failed to unmark pool %s as autostarted"), -- name); -+ vshError(ctl, _("failed to unmark pool %s as autostarted"), name); - virStoragePoolFree(pool); - return FALSE; - } -@@ -3587,7 +3578,7 @@ cmdPoolCreate(vshControl *ctl, const vshCmd *cmd) - virStoragePoolGetName(pool), from); - virStoragePoolFree(pool); - } else { -- vshError(ctl, FALSE, _("Failed to create pool from %s"), from); -+ vshError(ctl, _("Failed to create pool from %s"), from); - ret = FALSE; - } - return ret; -@@ -3641,7 +3632,7 @@ cmdNodeDeviceCreate(vshControl *ctl, const vshCmd *cmd) - virNodeDeviceGetName(dev), from); - virNodeDeviceFree(dev); - } else { -- vshError(ctl, FALSE, _("Failed to create node device from %s"), from); -+ vshError(ctl, _("Failed to create node device from %s"), from); - ret = FALSE; - } - -@@ -3687,7 +3678,7 @@ cmdNodeDeviceDestroy(vshControl *ctl, const vshCmd *cmd) - if (virNodeDeviceDestroy(dev) == 0) { - vshPrint(ctl, _("Destroyed node device '%s'\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to destroy node device '%s'"), name); -+ vshError(ctl, _("Failed to destroy node device '%s'"), name); - ret = FALSE; - } - -@@ -3800,7 +3791,7 @@ cmdPoolCreateAs(vshControl *ctl, const vshCmd *cmd) - vshPrint(ctl, _("Pool %s created\n"), name); - virStoragePoolFree(pool); - } else { -- vshError(ctl, FALSE, _("Failed to create pool %s"), name); -+ vshError(ctl, _("Failed to create pool %s"), name); - return FALSE; - } - } -@@ -3849,7 +3840,7 @@ cmdPoolDefine(vshControl *ctl, const vshCmd *cmd) - virStoragePoolGetName(pool), from); - virStoragePoolFree(pool); - } else { -- vshError(ctl, FALSE, _("Failed to define pool from %s"), from); -+ vshError(ctl, _("Failed to define pool from %s"), from); - ret = FALSE; - } - return ret; -@@ -3889,7 +3880,7 @@ cmdPoolDefineAs(vshControl *ctl, const vshCmd *cmd) - vshPrint(ctl, _("Pool %s defined\n"), name); - virStoragePoolFree(pool); - } else { -- vshError(ctl, FALSE, _("Failed to define pool %s"), name); -+ vshError(ctl, _("Failed to define pool %s"), name); - return FALSE; - } - } -@@ -3927,7 +3918,7 @@ cmdPoolBuild(vshControl *ctl, const vshCmd *cmd) - if (virStoragePoolBuild(pool, 0) == 0) { - vshPrint(ctl, _("Pool %s built\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to build pool %s"), name); -+ vshError(ctl, _("Failed to build pool %s"), name); - ret = FALSE; - virStoragePoolFree(pool); - } -@@ -3966,7 +3957,7 @@ cmdPoolDestroy(vshControl *ctl, const vshCmd *cmd) - if (virStoragePoolDestroy(pool) == 0) { - vshPrint(ctl, _("Pool %s destroyed\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to destroy pool %s"), name); -+ vshError(ctl, _("Failed to destroy pool %s"), name); - ret = FALSE; - } - -@@ -4005,7 +3996,7 @@ cmdPoolDelete(vshControl *ctl, const vshCmd *cmd) - if (virStoragePoolDelete(pool, 0) == 0) { - vshPrint(ctl, _("Pool %s deleted\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to delete pool %s"), name); -+ vshError(ctl, _("Failed to delete pool %s"), name); - ret = FALSE; - } - -@@ -4044,7 +4035,7 @@ cmdPoolRefresh(vshControl *ctl, const vshCmd *cmd) - if (virStoragePoolRefresh(pool, 0) == 0) { - vshPrint(ctl, _("Pool %s refreshed\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to refresh pool %s"), name); -+ vshError(ctl, _("Failed to refresh pool %s"), name); - ret = FALSE; - } - virStoragePoolFree(pool); -@@ -4124,7 +4115,7 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - if (active) { - maxactive = virConnectNumOfStoragePools(ctl->conn); - if (maxactive < 0) { -- vshError(ctl, FALSE, "%s", _("Failed to list active pools")); -+ vshError(ctl, "%s", _("Failed to list active pools")); - return FALSE; - } - if (maxactive) { -@@ -4132,7 +4123,7 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - - if ((maxactive = virConnectListStoragePools(ctl->conn, activeNames, - maxactive)) < 0) { -- vshError(ctl, FALSE, "%s", _("Failed to list active pools")); -+ vshError(ctl, "%s", _("Failed to list active pools")); - free(activeNames); - return FALSE; - } -@@ -4143,7 +4134,7 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - if (inactive) { - maxinactive = virConnectNumOfDefinedStoragePools(ctl->conn); - if (maxinactive < 0) { -- vshError(ctl, FALSE, "%s", _("Failed to list inactive pools")); -+ vshError(ctl, "%s", _("Failed to list inactive pools")); - free(activeNames); - return FALSE; - } -@@ -4151,7 +4142,7 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - inactiveNames = vshMalloc(ctl, sizeof(char *) * maxinactive); - - if ((maxinactive = virConnectListDefinedStoragePools(ctl->conn, inactiveNames, maxinactive)) < 0) { -- vshError(ctl, FALSE, "%s", _("Failed to list inactive pools")); -+ vshError(ctl, "%s", _("Failed to list inactive pools")); - free(activeNames); - free(inactiveNames); - return FALSE; -@@ -4273,10 +4264,10 @@ cmdPoolDiscoverSourcesAs(vshControl * ctl, const vshCmd * cmd ATTRIBUTE_UNUSED) - if (ret < 0) { - switch (errno) { - case ENOMEM: -- vshError(ctl, FALSE, "%s", _("Out of memory")); -+ vshError(ctl, "%s", _("Out of memory")); - break; - default: -- vshError(ctl, FALSE, _("virAsprintf failed (errno %d)"), errno); -+ vshError(ctl, _("virAsprintf failed (errno %d)"), errno); - } - return FALSE; - } -@@ -4285,7 +4276,7 @@ cmdPoolDiscoverSourcesAs(vshControl * ctl, const vshCmd * cmd ATTRIBUTE_UNUSED) - srcList = virConnectFindStoragePoolSources(ctl->conn, type, srcSpec, 0); - free(srcSpec); - if (srcList == NULL) { -- vshError(ctl, FALSE, _("Failed to find any %s pool sources"), type); -+ vshError(ctl, _("Failed to find any %s pool sources"), type); - return FALSE; - } - vshPrint(ctl, "%s", srcList); -@@ -4336,7 +4327,7 @@ cmdPoolDiscoverSources(vshControl * ctl, const vshCmd * cmd ATTRIBUTE_UNUSED) - srcList = virConnectFindStoragePoolSources(ctl->conn, type, srcSpec, 0); - free(srcSpec); - if (srcList == NULL) { -- vshError(ctl, FALSE, _("Failed to find any %s pool sources"), type); -+ vshError(ctl, _("Failed to find any %s pool sources"), type); - return FALSE; - } - vshPrint(ctl, "%s", srcList); -@@ -4503,8 +4494,7 @@ cmdPoolStart(vshControl *ctl, const vshCmd *cmd) - vshPrint(ctl, _("Pool %s started\n"), - virStoragePoolGetName(pool)); - } else { -- vshError(ctl, FALSE, _("Failed to start pool %s"), -- virStoragePoolGetName(pool)); -+ vshError(ctl, _("Failed to start pool %s"), virStoragePoolGetName(pool)); - ret = FALSE; - } - -@@ -4585,12 +4575,12 @@ cmdVolCreateAs(vshControl *ctl, const vshCmd *cmd) - if (!found) - goto cleanup; - if (cmdVolSize(capacityStr, &capacity) < 0) -- vshError(ctl, FALSE, _("Malformed size %s"), capacityStr); -+ vshError(ctl, _("Malformed size %s"), capacityStr); - - allocationStr = vshCommandOptString(cmd, "allocation", &found); - if (allocationStr && - cmdVolSize(allocationStr, &allocation) < 0) -- vshError(ctl, FALSE, _("Malformed size %s"), allocationStr); -+ vshError(ctl, _("Malformed size %s"), allocationStr); - - format = vshCommandOptString(cmd, "format", &found); - -@@ -4623,7 +4613,7 @@ cmdVolCreateAs(vshControl *ctl, const vshCmd *cmd) - virStorageVolFree(vol); - return TRUE; - } else { -- vshError(ctl, FALSE, _("Failed to create vol %s"), name); -+ vshError(ctl, _("Failed to create vol %s"), name); - return FALSE; - } - -@@ -4664,7 +4654,7 @@ cmdPoolUndefine(vshControl *ctl, const vshCmd *cmd) - if (virStoragePoolUndefine(pool) == 0) { - vshPrint(ctl, _("Pool %s has been undefined\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to undefine pool %s"), name); -+ vshError(ctl, _("Failed to undefine pool %s"), name); - ret = FALSE; - } - -@@ -4703,7 +4693,7 @@ cmdPoolUuid(vshControl *ctl, const vshCmd *cmd) - if (virStoragePoolGetUUIDString(pool, uuid) != -1) - vshPrint(ctl, "%s\n", uuid); - else -- vshError(ctl, FALSE, "%s", _("failed to get pool UUID")); -+ vshError(ctl, "%s", _("failed to get pool UUID")); - - virStoragePoolFree(pool); - return TRUE; -@@ -4762,7 +4752,7 @@ cmdVolCreate(vshControl *ctl, const vshCmd *cmd) - virStorageVolGetName(vol), from); - virStorageVolFree(vol); - } else { -- vshError(ctl, FALSE, _("Failed to create vol from %s"), from); -+ vshError(ctl, _("Failed to create vol from %s"), from); - ret = FALSE; - } - return ret; -@@ -4819,7 +4809,7 @@ cmdVolCreateFrom(vshControl *ctl, const vshCmd *cmd) - vshPrint(ctl, _("Vol %s created from input vol %s\n"), - virStorageVolGetName(newvol), virStorageVolGetName(inputvol)); - } else { -- vshError(ctl, FALSE, _("Failed to create vol from %s"), from); -+ vshError(ctl, _("Failed to create vol from %s"), from); - goto cleanup; - } - -@@ -4901,7 +4891,7 @@ cmdVolClone(vshControl *ctl, const vshCmd *cmd) - - origpool = virStoragePoolLookupByVolume(origvol); - if (!origpool) { -- vshError(ctl, FALSE, "%s", _("failed to get parent pool")); -+ vshError(ctl, "%s", _("failed to get parent pool")); - goto cleanup; - } - -@@ -4925,7 +4915,7 @@ cmdVolClone(vshControl *ctl, const vshCmd *cmd) - vshPrint(ctl, _("Vol %s cloned from %s\n"), - virStorageVolGetName(newvol), virStorageVolGetName(origvol)); - } else { -- vshError(ctl, FALSE, _("Failed to clone vol from %s"), -+ vshError(ctl, _("Failed to clone vol from %s"), - virStorageVolGetName(origvol)); - goto cleanup; - } -@@ -4976,7 +4966,7 @@ cmdVolDelete(vshControl *ctl, const vshCmd *cmd) - if (virStorageVolDelete(vol, 0) == 0) { - vshPrint(ctl, _("Vol %s deleted\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to delete vol %s"), name); -+ vshError(ctl, _("Failed to delete vol %s"), name); - ret = FALSE; - } - -@@ -5107,7 +5097,7 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - maxactive = virStoragePoolNumOfVolumes(pool); - if (maxactive < 0) { - virStoragePoolFree(pool); -- vshError(ctl, FALSE, "%s", _("Failed to list active vols")); -+ vshError(ctl, "%s", _("Failed to list active vols")); - return FALSE; - } - if (maxactive) { -@@ -5115,7 +5105,7 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - - if ((maxactive = virStoragePoolListVolumes(pool, activeNames, - maxactive)) < 0) { -- vshError(ctl, FALSE, "%s", _("Failed to list active vols")); -+ vshError(ctl, "%s", _("Failed to list active vols")); - free(activeNames); - virStoragePoolFree(pool); - return FALSE; -@@ -5288,12 +5278,11 @@ cmdSecretDefine(vshControl *ctl, const vshCmd *cmd) - free (buffer); - - if (res == NULL) { -- vshError(ctl, FALSE, _("Failed to set attributes from %s"), from); -+ vshError(ctl, _("Failed to set attributes from %s"), from); - return FALSE; - } - if (virSecretGetUUIDString(res, &(uuid[0])) < 0) { -- vshError(ctl, FALSE, "%s", -- _("Failed to get UUID of created secret")); -+ vshError(ctl, "%s", _("Failed to get UUID of created secret")); - virSecretFree(res); - return FALSE; - } -@@ -5377,11 +5366,11 @@ cmdSecretSetValue(vshControl *ctl, const vshCmd *cmd) - goto cleanup; - - if (!base64_decode_alloc(base64, strlen(base64), &value, &value_size)) { -- vshError(ctl, FALSE, _("Invalid base64 data")); -+ vshError(ctl, _("Invalid base64 data")); - goto cleanup; - } - if (value == NULL) { -- vshError(ctl, FALSE, "%s", _("Failed to allocate memory")); -+ vshError(ctl, "%s", _("Failed to allocate memory")); - return FALSE; - } - -@@ -5390,7 +5379,7 @@ cmdSecretSetValue(vshControl *ctl, const vshCmd *cmd) - free (value); - - if (res != 0) { -- vshError(ctl, FALSE, "%s", _("Failed to set secret value")); -+ vshError(ctl, "%s", _("Failed to set secret value")); - goto cleanup; - } - vshPrint(ctl, "%s", _("Secret value set\n")); -@@ -5440,7 +5429,7 @@ cmdSecretGetValue(vshControl *ctl, const vshCmd *cmd) - free(value); - - if (base64 == NULL) { -- vshError(ctl, FALSE, "%s", _("Failed to allocate memory")); -+ vshError(ctl, "%s", _("Failed to allocate memory")); - goto cleanup; - } - printf("%s", base64); -@@ -5482,7 +5471,7 @@ cmdSecretUndefine(vshControl *ctl, const vshCmd *cmd) - return FALSE; - - if (virSecretUndefine(secret) < 0) { -- vshError(ctl, FALSE, _("Failed to delete secret %s"), uuid); -+ vshError(ctl, _("Failed to delete secret %s"), uuid); - goto cleanup; - } - vshPrint(ctl, _("Secret %s deleted\n"), uuid); -@@ -5513,14 +5502,14 @@ cmdSecretList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - - maxuuids = virConnectNumOfSecrets(ctl->conn); - if (maxuuids < 0) { -- vshError(ctl, FALSE, "%s", _("Failed to list secrets")); -+ vshError(ctl, "%s", _("Failed to list secrets")); - return FALSE; - } - uuids = vshMalloc(ctl, sizeof(*uuids) * maxuuids); - - maxuuids = virConnectListSecrets(ctl->conn, uuids, maxuuids); - if (maxuuids < 0) { -- vshError(ctl, FALSE, "%s", _("Failed to list secrets")); -+ vshError(ctl, "%s", _("Failed to list secrets")); - free(uuids); - return FALSE; - } -@@ -5589,7 +5578,7 @@ cmdVersion(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - - hvType = virConnectGetType(ctl->conn); - if (hvType == NULL) { -- vshError(ctl, FALSE, "%s", _("failed to get hypervisor type")); -+ vshError(ctl, "%s", _("failed to get hypervisor type")); - return FALSE; - } - -@@ -5603,7 +5592,7 @@ cmdVersion(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - - ret = virGetVersion(&libVersion, hvType, &apiVersion); - if (ret < 0) { -- vshError(ctl, FALSE, "%s", _("failed to get the library version")); -+ vshError(ctl, "%s", _("failed to get the library version")); - return FALSE; - } - major = libVersion / 1000000; -@@ -5622,7 +5611,7 @@ cmdVersion(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - - ret = virConnectGetVersion(ctl->conn, &hvVersion); - if (ret < 0) { -- vshError(ctl, FALSE, "%s", _("failed to get the hypervisor version")); -+ vshError(ctl, "%s", _("failed to get the hypervisor version")); - return FALSE; - } - if (hvVersion == 0) { -@@ -5752,7 +5741,7 @@ cmdNodeListDevices (vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - - num_devices = virNodeNumOfDevices(ctl->conn, cap, 0); - if (num_devices < 0) { -- vshError(ctl, FALSE, "%s", _("Failed to count node devices")); -+ vshError(ctl, "%s", _("Failed to count node devices")); - return FALSE; - } else if (num_devices == 0) { - return TRUE; -@@ -5762,7 +5751,7 @@ cmdNodeListDevices (vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - num_devices = - virNodeListDevices(ctl->conn, cap, devices, num_devices, 0); - if (num_devices < 0) { -- vshError(ctl, FALSE, "%s", _("Failed to list node devices")); -+ vshError(ctl, "%s", _("Failed to list node devices")); - free(devices); - return FALSE; - } -@@ -5835,7 +5824,7 @@ cmdNodeDeviceDumpXML (vshControl *ctl, const vshCmd *cmd) - if (!(name = vshCommandOptString(cmd, "device", NULL))) - return FALSE; - if (!(device = virNodeDeviceLookupByName(ctl->conn, name))) { -- vshError(ctl, FALSE, "%s '%s'", _("Could not find matching device"), name); -+ vshError(ctl, "%s '%s'", _("Could not find matching device"), name); - return FALSE; - } - -@@ -5878,14 +5867,14 @@ cmdNodeDeviceDettach (vshControl *ctl, const vshCmd *cmd) - if (!(name = vshCommandOptString(cmd, "device", NULL))) - return FALSE; - if (!(device = virNodeDeviceLookupByName(ctl->conn, name))) { -- vshError(ctl, FALSE, "%s '%s'", _("Could not find matching device"), name); -+ vshError(ctl, "%s '%s'", _("Could not find matching device"), name); - return FALSE; - } - - if (virNodeDeviceDettach(device) == 0) { - vshPrint(ctl, _("Device %s dettached\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to dettach device %s"), name); -+ vshError(ctl, _("Failed to dettach device %s"), name); - ret = FALSE; - } - virNodeDeviceFree(device); -@@ -5919,14 +5908,14 @@ cmdNodeDeviceReAttach (vshControl *ctl, const vshCmd *cmd) - if (!(name = vshCommandOptString(cmd, "device", NULL))) - return FALSE; - if (!(device = virNodeDeviceLookupByName(ctl->conn, name))) { -- vshError(ctl, FALSE, "%s '%s'", _("Could not find matching device"), name); -+ vshError(ctl, "%s '%s'", _("Could not find matching device"), name); - return FALSE; - } - - if (virNodeDeviceReAttach(device) == 0) { - vshPrint(ctl, _("Device %s re-attached\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to re-attach device %s"), name); -+ vshError(ctl, _("Failed to re-attach device %s"), name); - ret = FALSE; - } - virNodeDeviceFree(device); -@@ -5960,14 +5949,14 @@ cmdNodeDeviceReset (vshControl *ctl, const vshCmd *cmd) - if (!(name = vshCommandOptString(cmd, "device", NULL))) - return FALSE; - if (!(device = virNodeDeviceLookupByName(ctl->conn, name))) { -- vshError(ctl, FALSE, "%s '%s'", _("Could not find matching device"), name); -+ vshError(ctl, "%s '%s'", _("Could not find matching device"), name); - return FALSE; - } - - if (virNodeDeviceReset(device) == 0) { - vshPrint(ctl, _("Device %s reset\n"), name); - } else { -- vshError(ctl, FALSE, _("Failed to reset device %s"), name); -+ vshError(ctl, _("Failed to reset device %s"), name); - ret = FALSE; - } - virNodeDeviceFree(device); -@@ -5993,7 +5982,7 @@ cmdHostname (vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - - hostname = virConnectGetHostname (ctl->conn); - if (hostname == NULL) { -- vshError(ctl, FALSE, "%s", _("failed to get hostname")); -+ vshError(ctl, "%s", _("failed to get hostname")); - return FALSE; - } - -@@ -6022,7 +6011,7 @@ cmdURI (vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - - uri = virConnectGetURI (ctl->conn); - if (uri == NULL) { -- vshError(ctl, FALSE, "%s", _("failed to get URI")); -+ vshError(ctl, "%s", _("failed to get URI")); - return FALSE; - } - -@@ -6200,7 +6189,7 @@ cmdAttachDevice(vshControl *ctl, const vshCmd *cmd) - - from = vshCommandOptString(cmd, "file", &found); - if (!found) { -- vshError(ctl, FALSE, "%s", _("attach-device: Missing option")); -+ vshError(ctl, "%s", _("attach-device: Missing option")); - virDomainFree(dom); - return FALSE; - } -@@ -6214,7 +6203,7 @@ cmdAttachDevice(vshControl *ctl, const vshCmd *cmd) - free (buffer); - - if (ret < 0) { -- vshError(ctl, FALSE, _("Failed to attach device from %s"), from); -+ vshError(ctl, _("Failed to attach device from %s"), from); - virDomainFree(dom); - return FALSE; - } else { -@@ -6258,7 +6247,7 @@ cmdDetachDevice(vshControl *ctl, const vshCmd *cmd) - - from = vshCommandOptString(cmd, "file", &found); - if (!found) { -- vshError(ctl, FALSE, "%s", _("detach-device: Missing option")); -+ vshError(ctl, "%s", _("detach-device: Missing option")); - virDomainFree(dom); - return FALSE; - } -@@ -6272,7 +6261,7 @@ cmdDetachDevice(vshControl *ctl, const vshCmd *cmd) - free (buffer); - - if (ret < 0) { -- vshError(ctl, FALSE, _("Failed to detach device from %s"), from); -+ vshError(ctl, _("Failed to detach device from %s"), from); - virDomainFree(dom); - return FALSE; - } else { -@@ -6331,7 +6320,7 @@ cmdAttachInterface(vshControl *ctl, const vshCmd *cmd) - } else if (STREQ(type, "bridge")) { - typ = 2; - } else { -- vshError(ctl, FALSE, _("No support %s in command 'attach-interface'"), type); -+ vshError(ctl, _("No support %s in command 'attach-interface'"), type); - goto cleanup; - } - -@@ -6450,12 +6439,12 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd) - XML_PARSE_NOWARNING); - free(doc); - if (!xml) { -- vshError(ctl, FALSE, "%s", _("Failed to get interface information")); -+ vshError(ctl, "%s", _("Failed to get interface information")); - goto cleanup; - } - ctxt = xmlXPathNewContext(xml); - if (!ctxt) { -- vshError(ctl, FALSE, "%s", _("Failed to get interface information")); -+ vshError(ctl, "%s", _("Failed to get interface information")); - goto cleanup; - } - -@@ -6463,7 +6452,7 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd) - obj = xmlXPathEval(BAD_CAST buf, ctxt); - if ((obj == NULL) || (obj->type != XPATH_NODESET) || - (obj->nodesetval == NULL) || (obj->nodesetval->nodeNr == 0)) { -- vshError(ctl, FALSE, _("No found interface whose type is %s"), type); -+ vshError(ctl, _("No found interface whose type is %s"), type); - goto cleanup; - } - -@@ -6485,18 +6474,18 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd) - cur = cur->next; - } - } -- vshError(ctl, FALSE, _("No found interface whose MAC address is %s"), mac); -+ vshError(ctl, _("No found interface whose MAC address is %s"), mac); - goto cleanup; - - hit: - xml_buf = xmlBufferCreate(); - if (!xml_buf) { -- vshError(ctl, FALSE, "%s", _("Failed to allocate memory")); -+ vshError(ctl, "%s", _("Failed to allocate memory")); - goto cleanup; - } - - if(xmlNodeDump(xml_buf, xml, obj->nodesetval->nodeTab[i], 0, 0) < 0){ -- vshError(ctl, FALSE, "%s", _("Failed to create XML")); -+ vshError(ctl, "%s", _("Failed to create XML")); - goto cleanup; - } - -@@ -6569,14 +6558,14 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd) - if (STREQ(driver, "file") || STREQ(driver, "tap")) { - isFile = 1; - } else if (STRNEQ(driver, "phy")) { -- vshError(ctl, FALSE, _("No support %s in command 'attach-disk'"), driver); -+ vshError(ctl, _("No support %s in command 'attach-disk'"), driver); - goto cleanup; - } - } - - if (mode) { - if (STRNEQ(mode, "readonly") && STRNEQ(mode, "shareable")) { -- vshError(ctl, FALSE, _("No support %s in command 'attach-disk'"), mode); -+ vshError(ctl, _("No support %s in command 'attach-disk'"), mode); - goto cleanup; - } - } -@@ -6723,19 +6712,19 @@ cmdDetachDisk(vshControl *ctl, const vshCmd *cmd) - XML_PARSE_NOWARNING); - free(doc); - if (!xml) { -- vshError(ctl, FALSE, "%s", _("Failed to get disk information")); -+ vshError(ctl, "%s", _("Failed to get disk information")); - goto cleanup; - } - ctxt = xmlXPathNewContext(xml); - if (!ctxt) { -- vshError(ctl, FALSE, "%s", _("Failed to get disk information")); -+ vshError(ctl, "%s", _("Failed to get disk information")); - goto cleanup; - } - - obj = xmlXPathEval(BAD_CAST "/domain/devices/disk", ctxt); - if ((obj == NULL) || (obj->type != XPATH_NODESET) || - (obj->nodesetval == NULL) || (obj->nodesetval->nodeNr == 0)) { -- vshError(ctl, FALSE, "%s", _("Failed to get disk information")); -+ vshError(ctl, "%s", _("Failed to get disk information")); - goto cleanup; - } - -@@ -6754,18 +6743,18 @@ cmdDetachDisk(vshControl *ctl, const vshCmd *cmd) - cur = cur->next; - } - } -- vshError(ctl, FALSE, _("No found disk whose target is %s"), target); -+ vshError(ctl, _("No found disk whose target is %s"), target); - goto cleanup; - - hit: - xml_buf = xmlBufferCreate(); - if (!xml_buf) { -- vshError(ctl, FALSE, "%s", _("Failed to allocate memory")); -+ vshError(ctl, "%s", _("Failed to allocate memory")); - goto cleanup; - } - - if(xmlNodeDump(xml_buf, xml, obj->nodesetval->nodeTab[i], 0, 0) < 0){ -- vshError(ctl, FALSE, "%s", _("Failed to create XML")); -+ vshError(ctl, "%s", _("Failed to create XML")); - goto cleanup; - } - -@@ -6799,9 +6788,8 @@ editWriteToTempFile (vshControl *ctl, const char *doc) - - ret = malloc (PATH_MAX); - if (!ret) { -- vshError(ctl, FALSE, -- _("malloc: failed to allocate temporary file name: %s"), -- strerror (errno)); -+ vshError(ctl, _("malloc: failed to allocate temporary file name: %s"), -+ strerror(errno)); - return NULL; - } - -@@ -6810,25 +6798,22 @@ editWriteToTempFile (vshControl *ctl, const char *doc) - snprintf (ret, PATH_MAX, "%s/virshXXXXXX", tmpdir); - fd = mkstemp (ret); - if (fd == -1) { -- vshError(ctl, FALSE, -- _("mkstemp: failed to create temporary file: %s"), -- strerror (errno)); -+ vshError(ctl, _("mkstemp: failed to create temporary file: %s"), -+ strerror(errno)); - return NULL; - } - - if (safewrite (fd, doc, strlen (doc)) == -1) { -- vshError(ctl, FALSE, -- _("write: %s: failed to write to temporary file: %s"), -- ret, strerror (errno)); -+ vshError(ctl, _("write: %s: failed to write to temporary file: %s"), -+ ret, strerror(errno)); - close (fd); - unlink (ret); - free (ret); - return NULL; - } - if (close (fd) == -1) { -- vshError(ctl, FALSE, -- _("close: %s: failed to write or close temporary file: %s"), -- ret, strerror (errno)); -+ vshError(ctl, _("close: %s: failed to write or close temporary file: %s"), -+ ret, strerror(errno)); - unlink (ret); - free (ret); - return NULL; -@@ -6856,35 +6841,37 @@ editFile (vshControl *ctl, const char *filename) - * it does, refuse to run. - */ - if (strspn (editor, ACCEPTED_CHARS) != strlen (editor)) { -- vshError(ctl, FALSE, -- _("%s: $EDITOR environment variable contains shell meta or other unacceptable characters"), -+ vshError(ctl, -+ _("%s: $EDITOR environment variable contains shell meta or " -+ "other unacceptable characters"), - editor); - return -1; - } - /* Same for the filename. */ - if (strspn (filename, ACCEPTED_CHARS) != strlen (filename)) { -- vshError(ctl, FALSE, -- _("%s: temporary filename contains shell meta or other unacceptable characters (is $TMPDIR wrong?)"), -+ vshError(ctl, -+ _("%s: temporary filename contains shell meta or other " -+ "unacceptable characters (is $TMPDIR wrong?)"), - filename); - return -1; - } - - if (virAsprintf(&command, "%s %s", editor, filename) == -1) { -- vshError(ctl, FALSE, -+ vshError(ctl, - _("virAsprintf: could not create editing command: %s"), -- strerror (errno)); -+ strerror(errno)); - return -1; - } - - command_ret = system (command); - if (command_ret == -1) { -- vshError(ctl, FALSE, -- _("%s: edit command failed: %s"), command, strerror (errno)); -+ vshError(ctl, -+ _("%s: edit command failed: %s"), command, strerror(errno)); - free (command); - return -1; - } - if (command_ret != WEXITSTATUS (0)) { -- vshError(ctl, FALSE, -+ vshError(ctl, - _("%s: command exited with non-zero status"), command); - free (command); - return -1; -@@ -6899,9 +6886,9 @@ editReadBackFile (vshControl *ctl, const char *filename) - char *ret; - - if (virFileReadAll (filename, VIRSH_MAX_XML_FILE, &ret) == -1) { -- vshError(ctl, FALSE, -+ vshError(ctl, - _("%s: failed to read temporary file: %s"), -- filename, strerror (errno)); -+ filename, strerror(errno)); - return NULL; - } - return ret; -@@ -6930,8 +6917,7 @@ cmdCd(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - int found; - - if (!ctl->imode) { -- vshError(ctl, FALSE, "%s", -- _("cd: command valid only in interactive mode")); -+ vshError(ctl, "%s", _("cd: command valid only in interactive mode")); - return -1; - } - -@@ -6944,7 +6930,7 @@ cmdCd(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - dir = "/"; - - if (chdir (dir) == -1) { -- vshError(ctl, FALSE, _("cd: %s: %s"), strerror (errno), dir); -+ vshError(ctl, _("cd: %s: %s"), strerror(errno), dir); - return -1; - } - -@@ -6982,7 +6968,8 @@ cmdPwd(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) - } - - if (err) -- vshError(ctl, FALSE, _("pwd: cannot get current directory: %s"), strerror (errno)); -+ vshError(ctl, _("pwd: cannot get current directory: %s"), -+ strerror(errno)); - else - vshPrint (ctl, _("%s\n"), cwd); - -@@ -7062,8 +7049,8 @@ cmdEdit (vshControl *ctl, const vshCmd *cmd) - goto cleanup; - - if (STRNEQ (doc, doc_reread)) { -- vshError (ctl, FALSE, -- "%s", _("ERROR: the XML configuration was changed by another user")); -+ vshError(ctl, -+ "%s", _("ERROR: the XML configuration was changed by another user")); - goto cleanup; - } - -@@ -7348,7 +7335,7 @@ vshCommandCheckOpts(vshControl *ctl, const vshCmd *cmd) - o = o->next; - } - if (!ok) { -- vshError(ctl, FALSE, -+ vshError(ctl, - d->type == VSH_OT_DATA ? - _("command '%s' requires <%s> option") : - _("command '%s' requires --%s option"), -@@ -7378,7 +7365,7 @@ vshCmddefHelp(vshControl *ctl, const char *cmdname) - const vshCmdDef *def = vshCmddefSearch(cmdname); - - if (!def) { -- vshError(ctl, FALSE, _("command '%s' doesn't exist"), cmdname); -+ vshError(ctl, _("command '%s' doesn't exist"), cmdname); - return FALSE; - } else { - const char *desc = N_(vshCmddefGetInfo(def, "desc")); -@@ -7577,8 +7564,7 @@ cmd_has_option (vshControl *ctl, const vshCmd *cmd, const char *optname) - } - - if (!found) -- vshError(ctl, FALSE, -- _("internal error: virsh %s: no %s VSH_OT_DATA option"), -+ vshError(ctl, _("internal error: virsh %s: no %s VSH_OT_DATA option"), - cmd->def->name, optname); - return found; - } -@@ -7595,7 +7581,7 @@ vshCommandOptDomainBy(vshControl *ctl, const vshCmd *cmd, - return NULL; - - if (!(n = vshCommandOptString(cmd, optname, NULL))) { -- vshError(ctl, FALSE, "%s", _("undefined domain name or id")); -+ vshError(ctl, "%s", _("undefined domain name or id")); - return NULL; - } - -@@ -7627,7 +7613,7 @@ vshCommandOptDomainBy(vshControl *ctl, const vshCmd *cmd, - } - - if (!dom) -- vshError(ctl, FALSE, _("failed to get domain '%s'"), n); -+ vshError(ctl, _("failed to get domain '%s'"), n); - - return dom; - } -@@ -7643,7 +7629,7 @@ vshCommandOptNetworkBy(vshControl *ctl, const vshCmd *cmd, - return NULL; - - if (!(n = vshCommandOptString(cmd, optname, NULL))) { -- vshError(ctl, FALSE, "%s", _("undefined network name")); -+ vshError(ctl, "%s", _("undefined network name")); - return NULL; - } - -@@ -7667,7 +7653,7 @@ vshCommandOptNetworkBy(vshControl *ctl, const vshCmd *cmd, - } - - if (!network) -- vshError(ctl, FALSE, _("failed to get network '%s'"), n); -+ vshError(ctl, _("failed to get network '%s'"), n); - - return network; - } -@@ -7683,7 +7669,7 @@ vshCommandOptInterfaceBy(vshControl *ctl, const vshCmd *cmd, - return NULL; - - if (!(n = vshCommandOptString(cmd, optname, NULL))) { -- vshError(ctl, FALSE, "%s", _("undefined interface identifier")); -+ vshError(ctl, "%s", _("undefined interface identifier")); - return NULL; - } - -@@ -7707,7 +7693,7 @@ vshCommandOptInterfaceBy(vshControl *ctl, const vshCmd *cmd, - } - - if (!iface) -- vshError(ctl, FALSE, _("failed to get interface '%s'"), n); -+ vshError(ctl, _("failed to get interface '%s'"), n); - - return iface; - } -@@ -7720,7 +7706,7 @@ vshCommandOptPoolBy(vshControl *ctl, const vshCmd *cmd, const char *optname, - char *n; - - if (!(n = vshCommandOptString(cmd, optname, NULL))) { -- vshError(ctl, FALSE, "%s", _("undefined pool name")); -+ vshError(ctl, "%s", _("undefined pool name")); - return NULL; - } - -@@ -7744,7 +7730,7 @@ vshCommandOptPoolBy(vshControl *ctl, const vshCmd *cmd, const char *optname, - } - - if (!pool) -- vshError(ctl, FALSE, _("failed to get pool '%s'"), n); -+ vshError(ctl, _("failed to get pool '%s'"), n); - - return pool; - } -@@ -7761,12 +7747,12 @@ vshCommandOptVolBy(vshControl *ctl, const vshCmd *cmd, - int found; - - if (!(n = vshCommandOptString(cmd, optname, NULL))) { -- vshError(ctl, FALSE, "%s", _("undefined vol name")); -+ vshError(ctl, "%s", _("undefined vol name")); - return NULL; - } - - if (!(p = vshCommandOptString(cmd, pooloptname, &found)) && found) { -- vshError(ctl, FALSE, "%s", _("undefined pool name")); -+ vshError(ctl, "%s", _("undefined pool name")); - return NULL; - } - -@@ -7797,7 +7783,7 @@ vshCommandOptVolBy(vshControl *ctl, const vshCmd *cmd, - } - - if (!vol) -- vshError(ctl, FALSE, _("failed to get vol '%s'"), n); -+ vshError(ctl, _("failed to get vol '%s'"), n); - - if (pool) - virStoragePoolFree(pool); -@@ -7817,7 +7803,7 @@ vshCommandOptSecret(vshControl *ctl, const vshCmd *cmd, char **name) - - n = vshCommandOptString(cmd, optname, NULL); - if (n == NULL) { -- vshError(ctl, FALSE, "%s", _("undefined secret UUID")); -+ vshError(ctl, "%s", _("undefined secret UUID")); - return NULL; - } - -@@ -7829,7 +7815,7 @@ vshCommandOptSecret(vshControl *ctl, const vshCmd *cmd, char **name) - secret = virSecretLookupByUUIDString(ctl->conn, n); - - if (secret == NULL) -- vshError(ctl, FALSE, _("failed to get secret '%s'"), n); -+ vshError(ctl, _("failed to get secret '%s'"), n); - - return secret; - } -@@ -7934,7 +7920,7 @@ vshCommandGetToken(vshControl *ctl, char *str, char **end, char **res) - sz++; - } - if (quote) { -- vshError(ctl, FALSE, "%s", _("missing \"")); -+ vshError(ctl, "%s", _("missing \"")); - return VSH_TK_ERROR; - } - if (tkstr == NULL || *tkstr == '\0' || p == NULL) -@@ -7994,19 +7980,19 @@ vshCommandParse(vshControl *ctl, char *cmdstr) - if (cmd == NULL) { - /* first token must be command name */ - if (tk != VSH_TK_DATA) { -- vshError(ctl, FALSE, -+ vshError(ctl, - _("unexpected token (command name): '%s'"), - tkdata); - goto syntaxError; - } - if (!(cmd = vshCmddefSearch(tkdata))) { -- vshError(ctl, FALSE, _("unknown command: '%s'"), tkdata); -+ vshError(ctl, _("unknown command: '%s'"), tkdata); - goto syntaxError; /* ... or ignore this command only? */ - } - free(tkdata); - } else if (tk == VSH_TK_OPTION) { - if (!(opt = vshCmddefGetOption(cmd, tkdata))) { -- vshError(ctl, FALSE, -+ vshError(ctl, - _("command '%s' doesn't support option --%s"), - cmd->name, tkdata); - goto syntaxError; -@@ -8021,7 +8007,7 @@ vshCommandParse(vshControl *ctl, char *cmdstr) - if (tk == VSH_TK_ERROR) - goto syntaxError; - if (tk != VSH_TK_DATA) { -- vshError(ctl, FALSE, -+ vshError(ctl, - _("expected syntax: --%s <%s>"), - opt->name, - opt->type == -@@ -8031,7 +8017,7 @@ vshCommandParse(vshControl *ctl, char *cmdstr) - } - } else if (tk == VSH_TK_DATA) { - if (!(opt = vshCmddefGetData(cmd, data_ct++))) { -- vshError(ctl, FALSE, _("unexpected data '%s'"), tkdata); -+ vshError(ctl, _("unexpected data '%s'"), tkdata); - goto syntaxError; - } - } -@@ -8143,7 +8129,7 @@ vshConnectionUsability(vshControl *ctl, virConnectPtr conn, int showerror) - */ - if (!conn) { - if (showerror) -- vshError(ctl, FALSE, "%s", _("no valid connection")); -+ vshError(ctl, "%s", _("no valid connection")); - return FALSE; - } - return TRUE; -@@ -8181,7 +8167,7 @@ vshPrintExtra(vshControl *ctl, const char *format, ...) - - - static void --vshError(vshControl *ctl, int doexit, const char *format, ...) -+vshError(vshControl *ctl, const char *format, ...) - { - va_list ap; - -@@ -8189,22 +8175,13 @@ vshError(vshControl *ctl, int doexit, const char *format, ...) - vshOutputLogFile(ctl, VSH_ERR_ERROR, format, ap); - va_end(ap); - -- if (doexit) -- fprintf(stderr, _("%s: error: "), progname); -- else -- fputs(_("error: "), stderr); -+ fputs(_("error: "), stderr); - - va_start(ap, format); - vfprintf(stderr, format, ap); - va_end(ap); - - fputc('\n', stderr); -- -- if (doexit) { -- if (ctl) -- vshDeinit(ctl); -- exit(EXIT_FAILURE); -- } - } - - static void * -@@ -8214,9 +8191,9 @@ _vshMalloc(vshControl *ctl, size_t size, const char *filename, int line) - - if ((x = malloc(size))) - return x; -- vshError(ctl, TRUE, _("%s: %d: failed to allocate %d bytes"), -+ vshError(ctl, _("%s: %d: failed to allocate %d bytes"), - filename, line, (int) size); -- return NULL; -+ exit(EXIT_FAILURE); - } - - static void * -@@ -8226,9 +8203,9 @@ _vshCalloc(vshControl *ctl, size_t nmemb, size_t size, const char *filename, int - - if ((x = calloc(nmemb, size))) - return x; -- vshError(ctl, TRUE, _("%s: %d: failed to allocate %d bytes"), -+ vshError(ctl, _("%s: %d: failed to allocate %d bytes"), - filename, line, (int) (size*nmemb)); -- return NULL; -+ exit(EXIT_FAILURE); - } - - static void * -@@ -8239,9 +8216,9 @@ _vshRealloc(vshControl *ctl, void *ptr, size_t size, const char *filename, int l - if ((x = realloc(ptr, size))) - return x; - free(ptr); -- vshError(ctl, TRUE, _("%s: %d: failed to allocate %d bytes"), -+ vshError(ctl, _("%s: %d: failed to allocate %d bytes"), - filename, line, (int) size); -- return NULL; -+ exit(EXIT_FAILURE); - } - - static char * -@@ -8253,9 +8230,9 @@ _vshStrdup(vshControl *ctl, const char *s, const char *filename, int line) - return(NULL); - if ((x = strdup(s))) - return x; -- vshError(ctl, TRUE, _("%s: %d: failed to allocate %lu bytes"), -+ vshError(ctl, _("%s: %d: failed to allocate %lu bytes"), - filename, line, (unsigned long)strlen(s)); -- return NULL; -+ exit(EXIT_FAILURE); - } - - /* -@@ -8283,7 +8260,7 @@ vshInit(vshControl *ctl) - */ - if (!ctl->conn) { - virshReportError(ctl); -- vshError(ctl, FALSE, "%s", _("failed to connect to the hypervisor")); -+ vshError(ctl, "%s", _("failed to connect to the hypervisor")); - return FALSE; - } - -@@ -8314,20 +8291,22 @@ vshOpenLogFile(vshControl *ctl) - case ENOENT: - break; - default: -- vshError(ctl, TRUE, "%s", -+ vshError(ctl, "%s", - _("failed to get the log file information")); -- break; -+ exit(EXIT_FAILURE); - } - } else { - if (!S_ISREG(st.st_mode)) { -- vshError(ctl, TRUE, "%s", _("the log path is not a file")); -+ vshError(ctl, "%s", _("the log path is not a file")); -+ exit(EXIT_FAILURE); - } - } - - /* log file open */ - if ((ctl->log_fd = open(ctl->logfile, LOGFILE_FLAGS, FILE_MODE)) < 0) { -- vshError(ctl, TRUE, "%s", -+ vshError(ctl, "%s", - _("failed to open the log file. check the log file path")); -+ exit(EXIT_FAILURE); - } - } - -@@ -8395,7 +8374,7 @@ vshOutputLogFile(vshControl *ctl, int log_level, const char *msg_format, va_list - /* write log */ - if (safewrite(ctl->log_fd, msg_buf, strlen(msg_buf)) < 0) { - vshCloseLogFile(ctl); -- vshError(ctl, FALSE, "%s", _("failed to write the log file")); -+ vshError(ctl, "%s", _("failed to write the log file")); - } - } - -@@ -8410,7 +8389,7 @@ vshCloseLogFile(vshControl *ctl) - /* log file close */ - if (ctl->log_fd >= 0) { - if (close(ctl->log_fd) < 0) -- vshError(ctl, FALSE, _("%s: failed to write log file: %s"), -+ vshError(ctl, _("%s: failed to write log file: %s"), - ctl->logfile ? ctl->logfile : "?", strerror (errno)); - ctl->log_fd = -1; - } -@@ -8588,9 +8567,7 @@ vshDeinit(vshControl *ctl) - free(ctl->name); - if (ctl->conn) { - if (virConnectClose(ctl->conn) != 0) { -- ctl->conn = NULL; /* prevent recursive call from vshError() */ -- vshError(ctl, TRUE, "%s", -- _("failed to disconnect from the hypervisor")); -+ vshError(ctl, "%s", _("failed to disconnect from the hypervisor")); - } - } - virResetLastError(); -@@ -8715,16 +8692,16 @@ vshParseArgv(vshControl *ctl, int argc, char **argv) - ctl->logfile = vshStrdup(ctl, optarg); - break; - default: -- vshError(ctl, TRUE, -- _("unsupported option '-%c'. See --help."), arg); -- break; -+ vshError(ctl, _("unsupported option '-%c'. See --help."), arg); -+ exit(EXIT_FAILURE); - } - } - - if (help) { -- if (end < argc) -- vshError(ctl, TRUE, -- _("extra argument '%s'. See --help."), argv[end]); -+ if (end < argc) { -+ vshError(ctl, _("extra argument '%s'. See --help."), argv[end]); -+ exit(EXIT_FAILURE); -+ } - - /* list all command */ - vshUsage(); --- -1.6.2.5 - diff --git a/libvirt-fix-crash-on-device-hotplug-parse-error.patch b/libvirt-fix-crash-on-device-hotplug-parse-error.patch deleted file mode 100644 index 54a4c60..0000000 --- a/libvirt-fix-crash-on-device-hotplug-parse-error.patch +++ /dev/null @@ -1,31 +0,0 @@ -From a5fa9f63fcffbf70465386672f24edac439866b9 Mon Sep 17 00:00:00 2001 -From: Daniel P. Berrange -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 - diff --git a/libvirt-fix-crash-on-missing-iface-target-dev.patch b/libvirt-fix-crash-on-missing-iface-target-dev.patch deleted file mode 100644 index 14a34fb..0000000 --- a/libvirt-fix-crash-on-missing-iface-target-dev.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 7bc1491deba6338e514504d1b68fe097e7f2bf19 Mon Sep 17 00:00:00 2001 -From: Daniel Veillard -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 - diff --git a/libvirt-fix-device-detach-typo1.patch b/libvirt-fix-device-detach-typo1.patch deleted file mode 100644 index 81315ac..0000000 --- a/libvirt-fix-device-detach-typo1.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 58c38896a67c170063401d8091bae7dca8842923 Mon Sep 17 00:00:00 2001 -From: Jiri Denemark -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 -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 - diff --git a/libvirt-fix-device-detach-typo2.patch b/libvirt-fix-device-detach-typo2.patch deleted file mode 100644 index 0d17d6b..0000000 --- a/libvirt-fix-device-detach-typo2.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 81e967c716ce8c085be8baad9169f7772452d187 Mon Sep 17 00:00:00 2001 -From: Mark McLoughlin -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 - diff --git a/libvirt-fix-device-detach-typo3.patch b/libvirt-fix-device-detach-typo3.patch deleted file mode 100644 index 4a69e80..0000000 --- a/libvirt-fix-device-detach-typo3.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 3a64779ec5a89d38d64e07bca2b11b19e1882d7a Mon Sep 17 00:00:00 2001 -From: Charles Duffy -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 - diff --git a/libvirt-fix-drv-supports-feature-bogus-error.patch b/libvirt-fix-drv-supports-feature-bogus-error.patch deleted file mode 100644 index de0fcac..0000000 --- a/libvirt-fix-drv-supports-feature-bogus-error.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 7692e1e19487c28454b1e5f6488d5574c70883f2 Mon Sep 17 00:00:00 2001 -From: Chris Lalancette -Date: Mon, 21 Sep 2009 14:53:31 +0200 -Subject: [PATCH] Don't do virSetConnError when virDrvSupportsFeature is successful. - -Signed-off-by: Chris Lalancette -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 - diff --git a/libvirt-fix-libvirtd-leak-in-error-reply.patch b/libvirt-fix-libvirtd-leak-in-error-reply.patch deleted file mode 100644 index 057ff65..0000000 --- a/libvirt-fix-libvirtd-leak-in-error-reply.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 71de8d92f20a9a9ee76d4d5df77ff477f1b7d441 Mon Sep 17 00:00:00 2001 -From: Matthias Bolte -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 - diff --git a/libvirt-fix-net-hotunplug-double-free.patch b/libvirt-fix-net-hotunplug-double-free.patch deleted file mode 100644 index 5a8ebbc..0000000 --- a/libvirt-fix-net-hotunplug-double-free.patch +++ /dev/null @@ -1,46 +0,0 @@ -From ba585ed6cff624c6c0f1f9801382fd6846466ee0 Mon Sep 17 00:00:00 2001 -From: Mark McLoughlin -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 - diff --git a/libvirt-fix-pci-hostdev-hotunplug-leak.patch b/libvirt-fix-pci-hostdev-hotunplug-leak.patch deleted file mode 100644 index f71e823..0000000 --- a/libvirt-fix-pci-hostdev-hotunplug-leak.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 17831d20051f8de8f1f7d661e8a23f4fe67c2153 Mon Sep 17 00:00:00 2001 -From: Mark McLoughlin -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 - diff --git a/libvirt-fix-qemu-raw-format-save.patch b/libvirt-fix-qemu-raw-format-save.patch deleted file mode 100644 index d390f0e..0000000 --- a/libvirt-fix-qemu-raw-format-save.patch +++ /dev/null @@ -1,53 +0,0 @@ -From f1be5a4714e194a84840343e0937fe62463a18dc Mon Sep 17 00:00:00 2001 -From: Charles Duffy -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 - diff --git a/libvirt-fix-qemu-restore-from-raw1.patch b/libvirt-fix-qemu-restore-from-raw1.patch deleted file mode 100644 index a4f224d..0000000 --- a/libvirt-fix-qemu-restore-from-raw1.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0b846a30468a6b4586407f020ccde7bb51afaf98 Mon Sep 17 00:00:00 2001 -From: Daniel P. Berrange -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 - diff --git a/libvirt-fix-qemu-restore-from-raw2.patch b/libvirt-fix-qemu-restore-from-raw2.patch deleted file mode 100644 index 5ad8a59..0000000 --- a/libvirt-fix-qemu-restore-from-raw2.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 57d7cc602d14c6b50e2826e427a5de124e479f95 Mon Sep 17 00:00:00 2001 -From: Daniel P. Berrange -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 - diff --git a/libvirt-fix-usb-device-passthrough.patch b/libvirt-fix-usb-device-passthrough.patch deleted file mode 100644 index a28bbd9..0000000 --- a/libvirt-fix-usb-device-passthrough.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 6b12148864cf6a1d22a2cf4e0e9c48e9946331cb Mon Sep 17 00:00:00 2001 -From: Mark McLoughlin -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 - diff --git a/libvirt-fix-xen-driver-refcounting.patch b/libvirt-fix-xen-driver-refcounting.patch deleted file mode 100644 index 33ee1eb..0000000 --- a/libvirt-fix-xen-driver-refcounting.patch +++ /dev/null @@ -1,103 +0,0 @@ -From cab81502320d97dac4c5c12e7496f30896709c49 Mon Sep 17 00:00:00 2001 -From: Matthias Bolte -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 - -(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 - diff --git a/libvirt-logrotate-avoid-compressing-small-logs.patch b/libvirt-logrotate-avoid-compressing-small-logs.patch deleted file mode 100644 index b74519d..0000000 --- a/libvirt-logrotate-avoid-compressing-small-logs.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 918724aa76982224437384d712c182c332fa5ef9 Mon Sep 17 00:00:00 2001 -From: Dan Kenigsberg -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 - diff --git a/libvirt-logrotate-create-lxc-uml-dirs.patch b/libvirt-logrotate-create-lxc-uml-dirs.patch deleted file mode 100644 index ec004a7..0000000 --- a/libvirt-logrotate-create-lxc-uml-dirs.patch +++ /dev/null @@ -1,54 +0,0 @@ -From b7e3ac4f23befe67518b57e34691c301820a436c Mon Sep 17 00:00:00 2001 -From: Mark McLoughlin -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 - diff --git a/libvirt-network-delay-attribute-formatting.patch b/libvirt-network-delay-attribute-formatting.patch deleted file mode 100644 index 34319bc..0000000 --- a/libvirt-network-delay-attribute-formatting.patch +++ /dev/null @@ -1,32 +0,0 @@ -From ba3bc9b22a21b8e9e110166c98be70e2ad6469cb Mon Sep 17 00:00:00 2001 -From: Cole Robinson -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) - 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 - diff --git a/libvirt-qemu-machine-type-fixes1.patch b/libvirt-qemu-machine-type-fixes1.patch deleted file mode 100644 index 127d246..0000000 --- a/libvirt-qemu-machine-type-fixes1.patch +++ /dev/null @@ -1,177 +0,0 @@ -From d7722ed1cb04aa8a7b9fbf880882841867b69ab0 Mon Sep 17 00:00:00 2001 -From: Mark McLoughlin -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. - - - hvm - - 64 - /usr/bin/qemu-system-x86_64 - pc-0.11 - pc - pc-0.10 - isapc - - - - /usr/bin/kvm - pc - isapc - - - - -and start a guest with: - - - ... - - hvm - ... - - - -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 @@ -- -+ - QEMUGuest1 - c7a5fdbd-edaf-9455-926a-d65c16db1809 - 219200 - 219200 - 1 - -- hvm -+ hvm - - - --- -1.6.2.5 - diff --git a/libvirt-qemu-machine-type-fixes2.patch b/libvirt-qemu-machine-type-fixes2.patch deleted file mode 100644 index fa4faeb..0000000 --- a/libvirt-qemu-machine-type-fixes2.patch +++ /dev/null @@ -1,42 +0,0 @@ -From bb64cc4cbe5d3c69057f63be2c1acaca72038e5a Mon Sep 17 00:00:00 2001 -From: Mark McLoughlin -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 - diff --git a/libvirt-storage-iscsi-auth-xml-formatting.patch b/libvirt-storage-iscsi-auth-xml-formatting.patch deleted file mode 100644 index d45935f..0000000 --- a/libvirt-storage-iscsi-auth-xml-formatting.patch +++ /dev/null @@ -1,30 +0,0 @@ -From a44bce591a8d746a4a00c8609cb0111c76271cab Mon Sep 17 00:00:00 2001 -From: Cole Robinson -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," \n", -+ virBufferVSprintf(buf," \n", - src->auth.chap.login, - src->auth.chap.passwd); - virBufferAddLit(buf," \n"); --- -1.6.2.5 - diff --git a/libvirt-svirt-relabel-qcow2-backing-files.patch b/libvirt-svirt-relabel-qcow2-backing-files.patch deleted file mode 100644 index db5839c..0000000 --- a/libvirt-svirt-relabel-qcow2-backing-files.patch +++ /dev/null @@ -1,1402 +0,0 @@ -From 5bb2da190bc6d5a36952315dd48a00709f88c3c2 Mon Sep 17 00:00:00 2001 -From: Mark McLoughlin -Date: Fri, 25 Sep 2009 14:20:13 +0100 -Subject: [PATCH] Re-label image file backing stores - -Use virStorageFileGetMetadata() to find any backing stores for images -and re-label them - -Without this, qemu cannot access qcow2 backing files, see: - - https://bugzilla.redhat.com/497131 - -* src/security/security_selinux.c: re-label backing store files in - SELinuxSetSecurityImageLabel() - -(cherry picked from commit fe627697a3830cd2db0efcc201d8caa9e171263d) - -Includes the following commits: - - util.h needs libvirt.h for virConnectPtr - - Seems standard to include internal.h in order to pull in libvirt.h - - * src/util/util.h: include internal.h - - (cherry picked from commit 25e2857c219e7fb91412746f7919931552c4e07a) - - Move file format enum to libvirt_util - - Rename virStorageVolFormatFileSystem to virStorageFileFormat and - move to src/util/storage_file.[ch] - - * src/Makefile.am: add src/util/storage_file.[ch] - - * src/conf/storage_conf.[ch]: move enum from here ... - - * src/util/storage_file.[ch]: .. to here - - * src/libvirt_private.syms: update To/FromString exports - - * src/storage/storage_backend.c, src/storage/storage_backend_fs.c, - src/vbox/vbox_tmpl.c: update for above changes - - (cherry picked from commit 00fd3ff49bb1e4578756a32a812fdbf5ee335d8c) - - Split virStorageGetMetadataFromFD() from virStorageBackendProbeTarget() - - Prepare the code probing a file's format and associated metadata for - moving into libvirt_util. - - * src/storage/storage_backend_fs.c: re-factor the format and metadata - probing code in preparation for moving it - - (cherry picked from commit f5fc670638d94776a4eba55f5affa69f69ba1ae2) - - Introduce virStorageFileMetadata structure - - Introduce a metadata structure and make virStorageGetMetadataFromFD() - fill it in. - - * src/util/storage_file.h: add virStorageFileMetadata - - * src/backend/storage_backend_fs.c: virStorageGetMetadataFromFD() now - fills in the virStorageFileMetadata structure - - (cherry picked from commit 5fede0a90be565e1c44b7c8236cb8910fd06b52f) - - Move virStorageGetMetadataFromFD() to libvirt_util - - Finally, we get to the point of all this. - - Move virStorageGetMetadataFromFD() to virStorageFileGetMetadataFromFD() - and move to src/util/storage_file.[ch] - - There's no functional changes in this patch, just code movement - - * src/storage/storage_backend_fs.c: move code from here ... - - * src/util/storage_file.[ch]: ... to here - - * src/libvirt_private.syms: export virStorageFileGetMetadataFromFD() - - (cherry picked from commit a010fb58d6bce026852d611e32302da7687639e5) - - Add virStorageFileGetMetadata() helper - - * src/util/storage_file.c: add virStorageFileGetMetadata() so that - the caller does not need to open the file - - (cherry picked from commit 295fd6e8330c7416e2d97634364f2890133c28fa) - -Fedora-patch: libvirt-svirt-relabel-qcow2-backing-files.patch ---- - src/Makefile.am | 1 + - src/libvirt_private.syms | 7 +- - src/security_selinux.c | 28 +++ - src/storage_backend.c | 17 +- - src/storage_backend_fs.c | 418 +++++---------------------------------------- - src/storage_conf.c | 25 +-- - src/storage_conf.h | 17 -- - src/storage_file.c | 424 ++++++++++++++++++++++++++++++++++++++++++++++ - src/storage_file.h | 62 +++++++ - src/util.h | 1 + - src/vbox/vbox_tmpl.c | 15 +- - 11 files changed, 591 insertions(+), 424 deletions(-) - create mode 100644 src/storage_file.c - create mode 100644 src/storage_file.h - -diff --git a/src/Makefile.am b/src/Makefile.am -index 463252e..3d279f2 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -54,6 +54,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 \ -diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms -index 867678f..500c209 100644 ---- a/src/libvirt_private.syms -+++ b/src/libvirt_private.syms -@@ -359,8 +359,6 @@ virStorageVolDefParseNode; - virStoragePoolFormatDiskTypeToString; - virStoragePoolFormatFileSystemTypeToString; - virStoragePoolFormatFileSystemNetTypeToString; --virStorageVolFormatFileSystemTypeToString; --virStorageVolFormatFileSystemTypeFromString; - virStoragePoolTypeFromString; - virStoragePartedFsTypeTypeToString; - virStoragePoolObjLock; -@@ -373,6 +371,11 @@ virStorageEncryptionParseNode; - virStorageEncryptionFormat; - virStorageGenerateQcowPassphrase; - -+# storage_file.h -+virStorageFileFormatTypeToString; -+virStorageFileFormatTypeFromString; -+virStorageFileGetMetadata; -+virStorageFileGetMetadataFromFD; - - # threads.h - virMutexInit; -diff --git a/src/security_selinux.c b/src/security_selinux.c -index b4dc153..600fc75 100644 ---- a/src/security_selinux.c -+++ b/src/security_selinux.c -@@ -27,6 +27,7 @@ - #include "logging.h" - #include "pci.h" - #include "hostusb.h" -+#include "storage_file.h" - - #define VIR_FROM_THIS VIR_FROM_SECURITY - -@@ -403,10 +404,37 @@ SELinuxSetSecurityImageLabel(virConnectPtr conn, - - { - const virSecurityLabelDefPtr secdef = &vm->def->seclabel; -+ const char *path; - - if (!disk->src) - return 0; - -+ path = disk->src; -+ do { -+ virStorageFileMetadata meta; -+ int ret; -+ -+ memset(&meta, 0, sizeof(meta)); -+ -+ ret = virStorageFileGetMetadata(conn, path, &meta); -+ -+ if (path != disk->src) -+ VIR_FREE(path); -+ path = NULL; -+ -+ if (ret < 0) -+ return -1; -+ -+ if (meta.backingStore != NULL && -+ SELinuxSetFilecon(conn, meta.backingStore, -+ default_content_context) < 0) { -+ VIR_FREE(meta.backingStore); -+ return -1; -+ } -+ -+ path = meta.backingStore; -+ } while (path != NULL); -+ - if (disk->shared) { - return SELinuxSetFilecon(conn, disk->src, default_image_context); - } else if (disk->readonly) { -diff --git a/src/storage_backend.c b/src/storage_backend.c -index 800d4ea..1b65c5d 100644 ---- a/src/storage_backend.c -+++ b/src/storage_backend.c -@@ -51,6 +51,7 @@ - #include "internal.h" - #include "secret_conf.h" - #include "uuid.h" -+#include "storage_file.h" - #include "storage_backend.h" - #include "logging.h" - -@@ -462,16 +463,16 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, - char *create_tool; - short use_kvmimg; - -- const char *type = virStorageVolFormatFileSystemTypeToString(vol->target.format); -+ const char *type = virStorageFileFormatTypeToString(vol->target.format); - const char *backingType = vol->backingStore.path ? -- virStorageVolFormatFileSystemTypeToString(vol->backingStore.format) : NULL; -+ virStorageFileFormatTypeToString(vol->backingStore.format) : NULL; - - const char *inputBackingPath = (inputvol ? inputvol->backingStore.path - : NULL); - const char *inputPath = inputvol ? inputvol->target.path : NULL; - /* Treat input block devices as 'raw' format */ - const char *inputType = inputPath ? -- virStorageVolFormatFileSystemTypeToString(inputvol->type == VIR_STORAGE_VOL_BLOCK ? VIR_STORAGE_VOL_FILE_RAW : inputvol->target.format) : -+ virStorageFileFormatTypeToString(inputvol->type == VIR_STORAGE_VOL_BLOCK ? VIR_STORAGE_FILE_RAW : inputvol->target.format) : - NULL; - - const char **imgargv; -@@ -552,8 +553,8 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, - if (vol->target.encryption != NULL) { - virStorageEncryptionPtr enc; - -- if (vol->target.format != VIR_STORAGE_VOL_FILE_QCOW && -- vol->target.format != VIR_STORAGE_VOL_FILE_QCOW2) { -+ if (vol->target.format != VIR_STORAGE_FILE_QCOW && -+ vol->target.format != VIR_STORAGE_FILE_QCOW2) { - virStorageReportError(conn, VIR_ERR_NO_SUPPORT, - _("qcow volume encryption unsupported with " - "volume format %s"), type); -@@ -644,7 +645,7 @@ virStorageBackendCreateQcowCreate(virConnectPtr conn, - return -1; - } - -- if (vol->target.format != VIR_STORAGE_VOL_FILE_QCOW2) { -+ if (vol->target.format != VIR_STORAGE_FILE_QCOW2) { - virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, - _("unsupported storage vol type %d"), - vol->target.format); -@@ -735,9 +736,9 @@ virStorageBackendGetBuildVolFromFunction(virConnectPtr conn, - * tool for converting - */ - if ((vol->type == VIR_STORAGE_VOL_FILE && -- vol->target.format != VIR_STORAGE_VOL_FILE_RAW) || -+ vol->target.format != VIR_STORAGE_FILE_RAW) || - (inputvol->type == VIR_STORAGE_VOL_FILE && -- inputvol->target.format != VIR_STORAGE_VOL_FILE_RAW)) { -+ inputvol->target.format != VIR_STORAGE_FILE_RAW)) { - - if ((tool_type = virStorageBackendFindFSImageTool(NULL)) < 0) { - virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, -diff --git a/src/storage_backend_fs.c b/src/storage_backend_fs.c -index 01cb171..6816da8 100644 ---- a/src/storage_backend_fs.c -+++ b/src/storage_backend_fs.c -@@ -41,259 +41,24 @@ - #include "virterror_internal.h" - #include "storage_backend_fs.h" - #include "storage_conf.h" -+#include "storage_file.h" - #include "util.h" - #include "memory.h" - #include "xml.h" - --enum lv_endian { -- LV_LITTLE_ENDIAN = 1, /* 1234 */ -- LV_BIG_ENDIAN /* 4321 */ --}; -- --enum { -- BACKING_STORE_OK, -- BACKING_STORE_INVALID, -- BACKING_STORE_ERROR, --}; -- --static int cowGetBackingStore(virConnectPtr, char **, -- const unsigned char *, size_t); --static int qcowXGetBackingStore(virConnectPtr, char **, -- const unsigned char *, size_t); --static int vmdk4GetBackingStore(virConnectPtr, char **, -- const unsigned char *, size_t); -- --/* 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 */ -- enum lv_endian endian; /* Endianness of file format */ -- int versionOffset; /* Byte offset from start of file -- * where we find version number, -- * -1 to skip version test */ -- int versionNumber; /* Version number to validate */ -- int sizeOffset; /* Byte offset from start of file -- * where we find capacity info, -- * -1 to use st_size as capacity */ -- int sizeBytes; /* Number of bytes for size field */ -- int sizeMultiplier; /* A scaling factor if size is not in bytes */ -- /* Store a COW base image path (possibly relative), -- * or NULL if there is no COW base image, to RES; -- * return BACKING_STORE_* */ -- int qcowCryptOffset; /* Byte offset from start of file -- * where to find encryption mode, -- * -1 if encryption is not used */ -- int (*getBackingStore)(virConnectPtr conn, char **res, -- const unsigned char *buf, size_t buf_size); --}; --struct FileTypeInfo const fileTypeInfo[] = { -- /* Bochs */ -- /* XXX Untested -- { VIR_STORAGE_VOL_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_VOL_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_VOL_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_VOL_FILE_ISO, NULL, ".iso", -- 0, -1, 0, -- -1, 0, 0, -1, NULL }, -- /* Parallels */ -- /* XXX Untested -- { VIR_STORAGE_VOL_FILE_PARALLELS, "WithoutFreeSpace", NULL, -- LV_LITTLE_ENDIAN, 16, 2, -- 16+4+4+4+4, 4, 512, -1, NULL }, -- */ -- /* QCow */ -- { VIR_STORAGE_VOL_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 }, -- /* QCow 2 */ -- { VIR_STORAGE_VOL_FILE_QCOW2, "QFI", NULL, -- LV_BIG_ENDIAN, 4, 2, -- 4+4+8+4+4, 8, 1, 4+4+8+4+4+8, qcowXGetBackingStore }, -- /* VMDK 3 */ -- /* XXX Untested -- { VIR_STORAGE_VOL_FILE_VMDK, "COWD", NULL, -- LV_LITTLE_ENDIAN, 4, 1, -- 4+4+4, 4, 512, -1, NULL }, -- */ -- /* VMDK 4 */ -- { VIR_STORAGE_VOL_FILE_VMDK, "KDMV", NULL, -- LV_LITTLE_ENDIAN, 4, 1, -- 4+4+4, 8, 512, -1, vmdk4GetBackingStore }, -- /* Connectix / VirtualPC */ -- /* XXX Untested -- { VIR_STORAGE_VOL_FILE_VPC, "conectix", NULL, -- LV_BIG_ENDIAN, -1, 0, -- -1, 0, 0, -1, NULL}, -- */ --}; -- - #define VIR_FROM_THIS VIR_FROM_STORAGE - - static int --cowGetBackingStore(virConnectPtr conn, -- char **res, -- const unsigned char *buf, -- size_t buf_size) --{ --#define COW_FILENAME_MAXLEN 1024 -- *res = NULL; -- if (buf_size < 4+4+ COW_FILENAME_MAXLEN) -- return BACKING_STORE_INVALID; -- if (buf[4+4] == '\0') /* cow_header_v2.backing_file[0] */ -- return BACKING_STORE_OK; -- -- *res = strndup ((const char*)buf + 4+4, COW_FILENAME_MAXLEN); -- if (*res == NULL) { -- virReportOOMError(conn); -- return BACKING_STORE_ERROR; -- } -- return BACKING_STORE_OK; --} -- --static int --qcowXGetBackingStore(virConnectPtr conn, -- char **res, -- const unsigned char *buf, -- size_t buf_size) --{ -- unsigned long long offset; -- unsigned long size; -- -- *res = NULL; -- if (buf_size < 4+4+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 */ -- 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 */ -- if (size == 0) -- return BACKING_STORE_OK; -- if (offset + size > buf_size || offset + size < offset) -- return BACKING_STORE_INVALID; -- if (size + 1 == 0) -- return BACKING_STORE_INVALID; -- if (VIR_ALLOC_N(*res, size + 1) < 0) { -- virReportOOMError(conn); -- return BACKING_STORE_ERROR; -- } -- memcpy(*res, buf + offset, size); -- (*res)[size] = '\0'; -- return BACKING_STORE_OK; --} -- -- --static int --vmdk4GetBackingStore(virConnectPtr conn, -- char **res, -- const unsigned char *buf, -- size_t buf_size) --{ -- static const char prefix[] = "parentFileNameHint=\""; -- -- char desc[20*512 + 1], *start, *end; -- size_t len; -- -- *res = NULL; -- -- if (buf_size <= 0x200) -- return BACKING_STORE_INVALID; -- len = buf_size - 0x200; -- if (len > sizeof(desc) - 1) -- len = sizeof(desc) - 1; -- memcpy(desc, buf + 0x200, len); -- desc[len] = '\0'; -- start = strstr(desc, prefix); -- if (start == NULL) -- return BACKING_STORE_OK; -- start += strlen(prefix); -- end = strchr(start, '"'); -- if (end == NULL) -- return BACKING_STORE_INVALID; -- if (end == start) -- return BACKING_STORE_OK; -- *end = '\0'; -- *res = strdup(start); -- if (*res == NULL) { -- virReportOOMError(conn); -- return BACKING_STORE_ERROR; -- } -- return BACKING_STORE_OK; --} -- --/** -- * Return an absolute path corresponding to PATH, which is absolute or relative -- * to the directory containing BASE_FILE, or NULL on error -- */ --static char *absolutePathFromBaseFile(const char *base_file, const char *path) -+virStorageBackendProbeTarget(virConnectPtr conn, -+ virStorageVolTargetPtr target, -+ char **backingStore, -+ unsigned long long *allocation, -+ unsigned long long *capacity, -+ virStorageEncryptionPtr *encryption) - { -- size_t base_size, path_size; -- char *res, *p; -- -- if (*path == '/') -- return strdup(path); -- -- base_size = strlen(base_file) + 1; -- path_size = strlen(path) + 1; -- if (VIR_ALLOC_N(res, base_size - 1 + path_size) < 0) -- return NULL; -- memcpy(res, base_file, base_size); -- p = strrchr(res, '/'); -- if (p != NULL) -- p++; -- else -- p = res; -- memcpy(p, path, path_size); -- if (VIR_REALLOC_N(res, (p + path_size) - res) < 0) { -- /* Ignore failure */ -- } -- return res; --} -- -- -- --/** -- * Probe the header of a file to determine what type of disk image -- * it is, and info about its capacity if available. -- */ --static int virStorageBackendProbeTarget(virConnectPtr conn, -- virStorageVolTargetPtr target, -- char **backingStore, -- unsigned long long *allocation, -- unsigned long long *capacity, -- virStorageEncryptionPtr *encryption) { -- int fd; -- unsigned char head[20*512]; /* vmdk4GetBackingStore needs this much. */ -- int len, i, ret; -+ int fd, ret; -+ virStorageFileMetadata meta; - -- if (backingStore) -- *backingStore = NULL; - if (encryption) - *encryption = NULL; - -@@ -311,148 +76,51 @@ static int virStorageBackendProbeTarget(virConnectPtr conn, - return ret; /* Take care to propagate ret, it is not always -1 */ - } - -- if ((len = read(fd, head, sizeof(head))) < 0) { -- virReportSystemError(conn, errno, -- _("cannot read header '%s'"), -- target->path); -+ memset(&meta, 0, sizeof(meta)); -+ -+ if (virStorageFileGetMetadataFromFD(conn, target->path, fd, &meta) < 0) { - close(fd); - return -1; - } - - close(fd); - -- /* First check file magic */ -- for (i = 0 ; i < ARRAY_CARDINALITY(fileTypeInfo) ; i++) { -- int mlen; -- bool encrypted_qcow = false; -- -- 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; -- } -- -- /* Optionally extract capacity from file */ -- if (fileTypeInfo[i].sizeOffset != -1 && capacity) { -- if (fileTypeInfo[i].endian == LV_LITTLE_ENDIAN) { -- *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 { -- *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 (*capacity > (ULLONG_MAX / fileTypeInfo[i].sizeMultiplier)) -- continue; -- *capacity *= fileTypeInfo[i].sizeMultiplier; -- } -- -- if (fileTypeInfo[i].qcowCryptOffset != -1) { -- int crypt_format; -+ target->format = meta.format; - -- crypt_format = (head[fileTypeInfo[i].qcowCryptOffset] << 24) | -- (head[fileTypeInfo[i].qcowCryptOffset+1] << 16) | -- (head[fileTypeInfo[i].qcowCryptOffset+2] << 8) | -- head[fileTypeInfo[i].qcowCryptOffset+3]; -- encrypted_qcow = crypt_format != 0; -- } -- -- /* Validation passed, we know the file format now */ -- target->format = fileTypeInfo[i].type; -- if (fileTypeInfo[i].getBackingStore != NULL && backingStore) { -- char *base; -+ if (backingStore) { -+ *backingStore = meta.backingStore; -+ meta.backingStore = NULL; -+ } - -- switch (fileTypeInfo[i].getBackingStore(conn, &base, head, len)) { -- case BACKING_STORE_OK: -- break; -+ VIR_FREE(meta.backingStore); - -- case BACKING_STORE_INVALID: -- continue; -+ if (capacity && meta.capacity) -+ *capacity = meta.capacity; - -- case BACKING_STORE_ERROR: -- return -1; -- } -- if (base != NULL) { -- *backingStore -- = absolutePathFromBaseFile(target->path, base); -- VIR_FREE(base); -- if (*backingStore == NULL) { -- virReportOOMError(conn); -- return -1; -- } -- } -+ if (encryption != NULL && meta.encrypted) { -+ if (VIR_ALLOC(*encryption) < 0) { -+ virReportOOMError(conn); -+ if (backingStore) -+ VIR_FREE(*backingStore); -+ return -1; - } -- if (encryption != NULL && encrypted_qcow) { -- virStorageEncryptionPtr enc; - -- if (VIR_ALLOC(enc) < 0) { -- virReportOOMError(conn); -- if (backingStore) -- VIR_FREE(*backingStore); -- return -1; -- } -- enc->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW; -- *encryption = enc; -- /* XXX ideally we'd fill in secret UUID here -- * but we cannot guarentee 'conn' is non-NULL -- * at this point in time :-( So we only fill -- * in secrets when someone first queries a vol -- */ -+ switch (target->format) { -+ case VIR_STORAGE_FILE_QCOW: -+ case VIR_STORAGE_FILE_QCOW2: -+ (*encryption)->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW; -+ break; -+ default: -+ break; - } -- return 0; -- } -- -- /* No magic, so check file extension */ -- for (i = 0 ; i < ARRAY_CARDINALITY(fileTypeInfo) ; i++) { -- if (fileTypeInfo[i].extension == NULL) -- continue; -- -- if (!virFileHasSuffix(target->path, fileTypeInfo[i].extension)) -- continue; - -- target->format = fileTypeInfo[i].type; -- return 0; -+ /* XXX ideally we'd fill in secret UUID here -+ * but we cannot guarentee 'conn' is non-NULL -+ * at this point in time :-( So we only fill -+ * in secrets when someone first queries a vol -+ */ - } - -- /* All fails, so call it a raw file */ -- target->format = VIR_STORAGE_VOL_FILE_RAW; - return 0; - } - -@@ -891,7 +559,7 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn, - goto no_memory; - - vol->type = VIR_STORAGE_VOL_FILE; -- vol->target.format = VIR_STORAGE_VOL_FILE_RAW; /* Real value is filled in during probe */ -+ vol->target.format = VIR_STORAGE_FILE_RAW; /* Real value is filled in during probe */ - if (virAsprintf(&vol->target.path, "%s/%s", - pool->def->target.path, - vol->name) == -1) -@@ -918,7 +586,7 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn, - } - - if (backingStore != NULL) { -- if (vol->target.format == VIR_STORAGE_VOL_FILE_QCOW2 && -+ if (vol->target.format == VIR_STORAGE_FILE_QCOW2 && - STRPREFIX("fmt:", backingStore)) { - char *fmtstr = backingStore + 4; - char *path = strchr(fmtstr, ':'); -@@ -927,7 +595,7 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn, - } else { - *path = '\0'; - if ((vol->backingStore.format = -- virStorageVolFormatFileSystemTypeFromString(fmtstr)) < 0) { -+ virStorageFileFormatTypeFromString(fmtstr)) < 0) { - VIR_FREE(backingStore); - } else { - memmove(backingStore, path, strlen(path) + 1); -@@ -1121,9 +789,9 @@ _virStorageBackendFileSystemVolBuild(virConnectPtr conn, - inputvol); - if (!create_func) - return -1; -- } else if (vol->target.format == VIR_STORAGE_VOL_FILE_RAW) { -+ } else if (vol->target.format == VIR_STORAGE_FILE_RAW) { - create_func = virStorageBackendCreateRaw; -- } else if (vol->target.format == VIR_STORAGE_VOL_FILE_DIR) { -+ } else if (vol->target.format == VIR_STORAGE_FILE_DIR) { - create_func = createFileDir; - } else if ((tool_type = virStorageBackendFindFSImageTool(NULL)) != -1) { - create_func = virStorageBackendFSImageToolTypeToFunc(conn, tool_type); -diff --git a/src/storage_conf.c b/src/storage_conf.c -index cb063cc..788de15 100644 ---- a/src/storage_conf.c -+++ b/src/storage_conf.c -@@ -36,6 +36,7 @@ - #include "virterror_internal.h" - #include "datatypes.h" - #include "storage_conf.h" -+#include "storage_file.h" - - #include "xml.h" - #include "uuid.h" -@@ -82,12 +83,6 @@ VIR_ENUM_IMPL(virStorageVolFormatDisk, - "linux-lvm", "linux-raid", - "extended") - --VIR_ENUM_IMPL(virStorageVolFormatFileSystem, -- VIR_STORAGE_VOL_FILE_LAST, -- "raw", "dir", "bochs", -- "cloop", "cow", "dmg", "iso", -- "qcow", "qcow2", "vmdk", "vpc") -- - VIR_ENUM_IMPL(virStoragePartedFsType, - VIR_STORAGE_PARTED_FS_TYPE_LAST, - "ext2", "ext2", "fat16", -@@ -150,9 +145,9 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { - }, - { .poolType = VIR_STORAGE_POOL_DIR, - .volOptions = { -- .defaultFormat = VIR_STORAGE_VOL_FILE_RAW, -- .formatFromString = virStorageVolFormatFileSystemTypeFromString, -- .formatToString = virStorageVolFormatFileSystemTypeToString, -+ .defaultFormat = VIR_STORAGE_FILE_RAW, -+ .formatFromString = virStorageFileFormatTypeFromString, -+ .formatToString = virStorageFileFormatTypeToString, - }, - }, - { .poolType = VIR_STORAGE_POOL_FS, -@@ -162,9 +157,9 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { - .formatToString = virStoragePoolFormatFileSystemTypeToString, - }, - .volOptions = { -- .defaultFormat = VIR_STORAGE_VOL_FILE_RAW, -- .formatFromString = virStorageVolFormatFileSystemTypeFromString, -- .formatToString = virStorageVolFormatFileSystemTypeToString, -+ .defaultFormat = VIR_STORAGE_FILE_RAW, -+ .formatFromString = virStorageFileFormatTypeFromString, -+ .formatToString = virStorageFileFormatTypeToString, - }, - }, - { .poolType = VIR_STORAGE_POOL_NETFS, -@@ -176,9 +171,9 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { - .formatToString = virStoragePoolFormatFileSystemNetTypeToString, - }, - .volOptions = { -- .defaultFormat = VIR_STORAGE_VOL_FILE_RAW, -- .formatFromString = virStorageVolFormatFileSystemTypeFromString, -- .formatToString = virStorageVolFormatFileSystemTypeToString, -+ .defaultFormat = VIR_STORAGE_FILE_RAW, -+ .formatFromString = virStorageFileFormatTypeFromString, -+ .formatToString = virStorageFileFormatTypeToString, - }, - }, - { .poolType = VIR_STORAGE_POOL_ISCSI, -diff --git a/src/storage_conf.h b/src/storage_conf.h -index 421d305..9fedb12 100644 ---- a/src/storage_conf.h -+++ b/src/storage_conf.h -@@ -429,23 +429,6 @@ enum virStoragePoolFormatLogical { - }; - VIR_ENUM_DECL(virStoragePoolFormatLogical) - -- --enum virStorageVolFormatFileSystem { -- VIR_STORAGE_VOL_FILE_RAW = 0, -- VIR_STORAGE_VOL_FILE_DIR, -- VIR_STORAGE_VOL_FILE_BOCHS, -- VIR_STORAGE_VOL_FILE_CLOOP, -- VIR_STORAGE_VOL_FILE_COW, -- VIR_STORAGE_VOL_FILE_DMG, -- VIR_STORAGE_VOL_FILE_ISO, -- VIR_STORAGE_VOL_FILE_QCOW, -- VIR_STORAGE_VOL_FILE_QCOW2, -- VIR_STORAGE_VOL_FILE_VMDK, -- VIR_STORAGE_VOL_FILE_VPC, -- VIR_STORAGE_VOL_FILE_LAST, --}; --VIR_ENUM_DECL(virStorageVolFormatFileSystem) -- - /* - * XXX these are basically partition types. - * -diff --git a/src/storage_file.c b/src/storage_file.c -new file mode 100644 -index 0000000..44057d2 ---- /dev/null -+++ b/src/storage_file.c -@@ -0,0 +1,424 @@ -+/* -+ * storage_file.c: file utility functions for FS storage backend -+ * -+ * Copyright (C) 2007-2009 Red Hat, Inc. -+ * Copyright (C) 2007-2008 Daniel P. Berrange -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ * Author: Daniel P. Berrange -+ */ -+ -+#include -+#include "storage_file.h" -+ -+#include -+#include -+#include "memory.h" -+#include "virterror_internal.h" -+ -+#define VIR_FROM_THIS VIR_FROM_STORAGE -+ -+VIR_ENUM_IMPL(virStorageFileFormat, -+ VIR_STORAGE_FILE_LAST, -+ "raw", "dir", "bochs", -+ "cloop", "cow", "dmg", "iso", -+ "qcow", "qcow2", "vmdk", "vpc") -+ -+enum lv_endian { -+ LV_LITTLE_ENDIAN = 1, /* 1234 */ -+ LV_BIG_ENDIAN /* 4321 */ -+}; -+ -+enum { -+ BACKING_STORE_OK, -+ BACKING_STORE_INVALID, -+ BACKING_STORE_ERROR, -+}; -+ -+/* 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 */ -+ enum lv_endian endian; /* Endianness of file format */ -+ int versionOffset; /* Byte offset from start of file -+ * where we find version number, -+ * -1 to skip version test */ -+ int versionNumber; /* Version number to validate */ -+ int sizeOffset; /* Byte offset from start of file -+ * where we find capacity info, -+ * -1 to use st_size as capacity */ -+ int sizeBytes; /* Number of bytes for size field */ -+ int sizeMultiplier; /* A scaling factor if size is not in bytes */ -+ /* Store a COW base image path (possibly relative), -+ * or NULL if there is no COW base image, to RES; -+ * return BACKING_STORE_* */ -+ int qcowCryptOffset; /* Byte offset from start of file -+ * where to find encryption mode, -+ * -1 if encryption is not used */ -+ int (*getBackingStore)(virConnectPtr conn, char **res, -+ const unsigned char *buf, size_t buf_size); -+}; -+ -+static int cowGetBackingStore(virConnectPtr, char **, -+ const unsigned char *, size_t); -+static int qcowXGetBackingStore(virConnectPtr, char **, -+ const unsigned char *, size_t); -+static int vmdk4GetBackingStore(virConnectPtr, char **, -+ const unsigned char *, size_t); -+ -+ -+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, -+ 4+4+8+4+4, 8, 1, 4+4+8+4+4+8+1+1+2, qcowXGetBackingStore }, -+ /* 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 }, -+ /* 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 */ -+ /* XXX Untested -+ { VIR_STORAGE_FILE_VPC, "conectix", NULL, -+ LV_BIG_ENDIAN, -1, 0, -+ -1, 0, 0, -1, NULL}, -+ */ -+}; -+ -+static int -+cowGetBackingStore(virConnectPtr conn, -+ char **res, -+ const unsigned char *buf, -+ size_t buf_size) -+{ -+#define COW_FILENAME_MAXLEN 1024 -+ *res = NULL; -+ if (buf_size < 4+4+ COW_FILENAME_MAXLEN) -+ return BACKING_STORE_INVALID; -+ if (buf[4+4] == '\0') /* cow_header_v2.backing_file[0] */ -+ return BACKING_STORE_OK; -+ -+ *res = strndup ((const char*)buf + 4+4, COW_FILENAME_MAXLEN); -+ if (*res == NULL) { -+ virReportOOMError(conn); -+ return BACKING_STORE_ERROR; -+ } -+ return BACKING_STORE_OK; -+} -+ -+static int -+qcowXGetBackingStore(virConnectPtr conn, -+ char **res, -+ const unsigned char *buf, -+ size_t buf_size) -+{ -+ unsigned long long offset; -+ unsigned long size; -+ -+ *res = NULL; -+ if (buf_size < 4+4+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 */ -+ 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 */ -+ if (size == 0) -+ return BACKING_STORE_OK; -+ if (offset + size > buf_size || offset + size < offset) -+ return BACKING_STORE_INVALID; -+ if (size + 1 == 0) -+ return BACKING_STORE_INVALID; -+ if (VIR_ALLOC_N(*res, size + 1) < 0) { -+ virReportOOMError(conn); -+ return BACKING_STORE_ERROR; -+ } -+ memcpy(*res, buf + offset, size); -+ (*res)[size] = '\0'; -+ return BACKING_STORE_OK; -+} -+ -+ -+static int -+vmdk4GetBackingStore(virConnectPtr conn, -+ char **res, -+ const unsigned char *buf, -+ size_t buf_size) -+{ -+ static const char prefix[] = "parentFileNameHint=\""; -+ -+ char desc[20*512 + 1], *start, *end; -+ size_t len; -+ -+ *res = NULL; -+ -+ if (buf_size <= 0x200) -+ return BACKING_STORE_INVALID; -+ len = buf_size - 0x200; -+ if (len > sizeof(desc) - 1) -+ len = sizeof(desc) - 1; -+ memcpy(desc, buf + 0x200, len); -+ desc[len] = '\0'; -+ start = strstr(desc, prefix); -+ if (start == NULL) -+ return BACKING_STORE_OK; -+ start += strlen(prefix); -+ end = strchr(start, '"'); -+ if (end == NULL) -+ return BACKING_STORE_INVALID; -+ if (end == start) -+ return BACKING_STORE_OK; -+ *end = '\0'; -+ *res = strdup(start); -+ if (*res == NULL) { -+ virReportOOMError(conn); -+ return BACKING_STORE_ERROR; -+ } -+ return BACKING_STORE_OK; -+} -+ -+/** -+ * Return an absolute path corresponding to PATH, which is absolute or relative -+ * to the directory containing BASE_FILE, or NULL on error -+ */ -+static char * -+absolutePathFromBaseFile(const char *base_file, const char *path) -+{ -+ size_t base_size, path_size; -+ char *res, *p; -+ -+ if (*path == '/') -+ return strdup(path); -+ -+ base_size = strlen(base_file) + 1; -+ path_size = strlen(path) + 1; -+ if (VIR_ALLOC_N(res, base_size - 1 + path_size) < 0) -+ return NULL; -+ memcpy(res, base_file, base_size); -+ p = strrchr(res, '/'); -+ if (p != NULL) -+ p++; -+ else -+ p = res; -+ memcpy(p, path, path_size); -+ if (VIR_REALLOC_N(res, (p + path_size) - res) < 0) { -+ /* Ignore failure */ -+ } -+ 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(virConnectPtr conn, -+ const char *path, -+ int fd, -+ virStorageFileMetadata *meta) -+{ -+ unsigned char head[20*512]; /* vmdk4GetBackingStore needs this much. */ -+ int len, i; -+ -+ /* If all else fails, call it a raw file */ -+ meta->format = VIR_STORAGE_FILE_RAW; -+ -+ if ((len = read(fd, head, sizeof(head))) < 0) { -+ virReportSystemError(conn, errno, _("cannot read header '%s'"), path); -+ return -1; -+ } -+ -+ /* 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; -+ } -+ -+ /* 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; -+ -+ 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; -+ } -+ -+ /* Validation passed, we know the file format now */ -+ meta->format = fileTypeInfo[i].type; -+ if (fileTypeInfo[i].getBackingStore != NULL) { -+ char *base; -+ -+ switch (fileTypeInfo[i].getBackingStore(conn, &base, head, len)) { -+ case BACKING_STORE_OK: -+ break; -+ -+ case BACKING_STORE_INVALID: -+ continue; -+ -+ case BACKING_STORE_ERROR: -+ return -1; -+ } -+ if (base != NULL) { -+ meta->backingStore = absolutePathFromBaseFile(path, base); -+ VIR_FREE(base); -+ if (meta->backingStore == NULL) { -+ virReportOOMError(conn); -+ return -1; -+ } -+ } -+ } -+ return 0; -+ } -+ -+ /* No magic, so check file extension */ -+ for (i = 0 ; i < ARRAY_CARDINALITY(fileTypeInfo) ; i++) { -+ if (fileTypeInfo[i].extension == NULL) -+ continue; -+ -+ if (!virFileHasSuffix(path, fileTypeInfo[i].extension)) -+ continue; -+ -+ meta->format = fileTypeInfo[i].type; -+ return 0; -+ } -+ -+ return 0; -+} -+ -+int -+virStorageFileGetMetadata(virConnectPtr conn, -+ const char *path, -+ virStorageFileMetadata *meta) -+{ -+ int fd, ret; -+ -+ if ((fd = open(path, O_RDONLY)) < 0) { -+ virReportSystemError(conn, errno, _("cannot open file '%s'"), path); -+ return -1; -+ } -+ -+ ret = virStorageFileGetMetadataFromFD(conn, path, fd, meta); -+ -+ close(fd); -+ -+ return ret; -+} -diff --git a/src/storage_file.h b/src/storage_file.h -new file mode 100644 -index 0000000..b0abcaf ---- /dev/null -+++ b/src/storage_file.h -@@ -0,0 +1,62 @@ -+/* -+ * storage_file.c: file utility functions for FS storage backend -+ * -+ * Copyright (C) 2007-2009 Red Hat, Inc. -+ * Copyright (C) 2007-2008 Daniel P. Berrange -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ * Author: Daniel P. Berrange -+ */ -+ -+#ifndef __VIR_STORAGE_FILE_H__ -+#define __VIR_STORAGE_FILE_H__ -+ -+#include "util.h" -+#include -+ -+enum virStorageFileFormat { -+ VIR_STORAGE_FILE_RAW = 0, -+ VIR_STORAGE_FILE_DIR, -+ VIR_STORAGE_FILE_BOCHS, -+ VIR_STORAGE_FILE_CLOOP, -+ VIR_STORAGE_FILE_COW, -+ VIR_STORAGE_FILE_DMG, -+ VIR_STORAGE_FILE_ISO, -+ VIR_STORAGE_FILE_QCOW, -+ VIR_STORAGE_FILE_QCOW2, -+ VIR_STORAGE_FILE_VMDK, -+ VIR_STORAGE_FILE_VPC, -+ VIR_STORAGE_FILE_LAST, -+}; -+ -+VIR_ENUM_DECL(virStorageFileFormat); -+ -+typedef struct _virStorageFileMetadata { -+ int format; -+ char *backingStore; -+ unsigned long long capacity; -+ bool encrypted; -+} virStorageFileMetadata; -+ -+int virStorageFileGetMetadata(virConnectPtr conn, -+ const char *path, -+ virStorageFileMetadata *meta); -+int virStorageFileGetMetadataFromFD(virConnectPtr conn, -+ const char *path, -+ int fd, -+ virStorageFileMetadata *meta); -+ -+#endif /* __VIR_STORAGE_FILE_H__ */ -diff --git a/src/util.h b/src/util.h -index f9715ab..75afecc 100644 ---- a/src/util.h -+++ b/src/util.h -@@ -26,6 +26,7 @@ - #define __VIR_UTIL_H__ - - #include "verify.h" -+#include "internal.h" - #include - #include - -diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c -index 7270710..783a216 100644 ---- a/src/vbox/vbox_tmpl.c -+++ b/src/vbox/vbox_tmpl.c -@@ -45,6 +45,7 @@ - #include "virterror_internal.h" - #include "domain_event.h" - #include "storage_conf.h" -+#include "storage_file.h" - #include "uuid.h" - #include "event.h" - #include "memory.h" -@@ -5980,14 +5981,14 @@ static virStorageVolPtr vboxStorageVolCreateXML(virStoragePoolPtr pool, - - /* TODO: for now only the vmdk, vpc and vdi type harddisk - * variants can be created, also since there is no vdi -- * type in enum virStorageVolFormatFileSystem {} the default -+ * type in enum virStorageFileFormat {} the default - * will be to create vdi if nothing is specified in - * def->target.format - */ - -- if (def->target.format == VIR_STORAGE_VOL_FILE_VMDK) { -+ if (def->target.format == VIR_STORAGE_FILE_VMDK) { - data->pFuncs->pfnUtf8ToUtf16("VMDK", &hddFormatUtf16); -- } else if (def->target.format == VIR_STORAGE_VOL_FILE_VPC) { -+ } else if (def->target.format == VIR_STORAGE_FILE_VPC) { - data->pFuncs->pfnUtf8ToUtf16("VHD", &hddFormatUtf16); - } else { - data->pFuncs->pfnUtf8ToUtf16("VDI", &hddFormatUtf16); -@@ -6302,13 +6303,13 @@ static char *vboxStorageVolGetXMLDesc(virStorageVolPtr vol, unsigned int flags A - DEBUG("Storage Volume Format: %s", hddFormatUtf8); - - if (STRCASEEQ("vmdk", hddFormatUtf8)) -- def.target.format = VIR_STORAGE_VOL_FILE_VMDK; -+ def.target.format = VIR_STORAGE_FILE_VMDK; - else if (STRCASEEQ("vhd", hddFormatUtf8)) -- def.target.format = VIR_STORAGE_VOL_FILE_VPC; -+ def.target.format = VIR_STORAGE_FILE_VPC; - else -- def.target.format = VIR_STORAGE_VOL_FILE_RAW; -+ def.target.format = VIR_STORAGE_FILE_RAW; - -- /* TODO: need to add vdi to enum virStorageVolFormatFileSystem {} -+ /* TODO: need to add vdi to enum virStorageFileFormat {} - * and then add it here - */ - --- -1.6.2.5 - diff --git a/libvirt.spec b/libvirt.spec index 1f174cd..38a1caa 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -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,,\n $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 - 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 - 0.7.1-18.fc12 - Actually apply all previous patches diff --git a/sources b/sources index 1e94be1..e8d4bbd 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -f1cd360a5da38b847e166c6482141940 libvirt-0.7.1.tar.gz +14164638fe0e7f65e425acc85dabc517 libvirt-0.8.2.tar.gz