diff --git a/.cvsignore b/.cvsignore index 220baba..a2440df 100644 --- a/.cvsignore +++ b/.cvsignore @@ -11,3 +11,4 @@ libvirt-0.6.4.tar.gz libvirt-0.6.5.tar.gz libvirt-0.7.0.tar.gz libvirt-0.7.1.tar.gz +libvirt-0.7.2.tar.gz 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-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-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-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 548fd05..bc1f4c6 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -150,47 +150,11 @@ Summary: Library providing a simple API virtualization Name: libvirt -Version: 0.7.1 -Release: 12%{?dist}%{?extra_release} +Version: 0.7.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 - BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root URL: http://libvirt.org/ BuildRequires: python-devel @@ -350,9 +314,6 @@ BuildRequires: netcf-devel # 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 @@ -406,26 +367,7 @@ 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 -%patch10 -p1 -%patch11 -p1 -%patch12 -p1 -%patch13 -p1 -%patch14 -p1 -%patch15 -p1 - %build -# Needed for libvirt-logrotate-create-lxc-uml-dirs.patch -automake - %if ! %{with_xen} %define _without_xen --without-xen %endif @@ -567,10 +509,10 @@ 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 +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 @@ -597,6 +539,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 @@ -608,6 +555,9 @@ rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/libvirt-%{version} %if ! %{with_qemu} rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/qemu.conf %endif +%if ! %{with_lxc} +rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/lxc.conf +%endif %if %{with_libvirtd} chmod 0644 $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/libvirtd @@ -688,6 +638,9 @@ fi %if %{with_qemu} %config(noreplace) %{_sysconfdir}/libvirt/qemu.conf %endif +%if %{with_lxc} +%config(noreplace) %{_sysconfdir}/libvirt/lxc.conf +%endif %dir %{_datadir}/libvirt/ @@ -729,6 +682,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 @@ -762,8 +720,10 @@ 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/ @@ -797,9 +757,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 @@ -810,11 +773,18 @@ 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 +* Wed Oct 14 2009 Daniel Veillard - 0.7.2-1 +- Upstream release of 0.7.2 +- Allow to define ESX domains +- Allows suspend and resulme of LXC domains +- API for data streams +- many bug fixes + * Tue Oct 13 2009 Mark McLoughlin - 0.7.1-12 - Fix restore of qemu guest using raw save format (#523158) diff --git a/sources b/sources index 1e94be1..de98120 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -f1cd360a5da38b847e166c6482141940 libvirt-0.7.1.tar.gz +133aead8c46c0601b6b37e024c6aa86a libvirt-0.7.2.tar.gz