summaryrefslogtreecommitdiff
path: root/block
AgeCommit message (Collapse)Author
2014-04-30block: Use error_abort in bdrv_image_info_specific_dump()Max Reitz
Currently, bdrv_image_info_specific_dump() uses an error variable for visit_type_ImageInfoSpecific, but ignores the result. As this function is used here with an output visitor to transform the ImageInfoSpecific object to a generic QDict, an error should actually be impossible. It is however better to assert that this is indeed the case. This is done by this patch using error_abort instead of an unused local Error variable. Signed-off-by: Max Reitz <mreitz@redhat.com> Reported-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-04-30block: Unlink temporary files in raw-posix/win32Kevin Wolf
Instead of having unlink() calls in the generic block layer, where we aren't even guarateed to have a file name, move them to those block drivers that are actually used and that always have a filename. Gets us rid of some #ifdefs as well. The patch also converts bs->is_temporary to a new BDRV_O_TEMPORARY open flag so that it is inherited in the protocol layer and the raw-posix and raw-win32 drivers can unlink the file. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com>
2014-04-29qcow2: Fix discardMax Reitz
discard_single_l2() should not implement its own version of qcow2_get_cluster_type(), but rather rely on this already existing function. By doing so, it will work for compressed clusters as well (which it did not so far). Also, rename "old_offset" to "old_l2_entry", as both are quite different (and the value is indeed of the latter kind). Signed-off-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-04-29mirror: Check for bdrv_get_info resultFam Zheng
bdrv_get_info could fail. Add check before using the returned value. Signed-off-by: Fam Zheng <famz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-04-29mirror: Fix resource leak when bdrv_getlength failsFam Zheng
The direct return will skip releasing of all the resouces at immediate_exit, don't miss that. Signed-off-by: Fam Zheng <famz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-04-28mirror: Use DIV_ROUND_UPFam Zheng
Although bdrv_getlength() was just called above this, and checked for error, it is better to just use the value we already get, and use DIV_ROUND_UP. Signed-off-by: Fam Zheng <famz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-04-28Merge remote-tracking branch 'remotes/qmp-unstable/queue/qmp' into stagingPeter Maydell
* remotes/qmp-unstable/queue/qmp: monitor: fix qmp_getfd() fd leak in error case HMP: support specifying dump format for dump-guest-memory HMP: fix doc of dump-guest-memory qmp: object-add: Validate class before creating object monitor: Add device_add and device_del completion. monitor: Add command_completion callback to mon_cmd_t. monitor: Fix drive_del id argument type completion. error: Remove some unused headers qerror.h: Replace QERR_NOT_SUPPORTED with QERR_UNSUPPORTED qerror.h: Remove QERR defines that are only used once qerror.h: Remove unused error classes error: Print error_report() to stderr if using qmp monitor: Remove unused monitor_print_filename error: Privatize error_print_loc vnc: Remove default_mon usage slirp: Remove default_mon usage Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-04-25iscsi: Don't use error_is_set() to suppress additional errorsMarkus Armbruster
Using error_is_set(errp) that way can sweep programming errors under the carpet when we get called incorrectly with an error set. Commit 24d3bd6 added a broken error path to iscsi_do_inquiry(): it first calls error_setg(), then jumps to the preexisting error label, where error_setg() gets called again, triggering an assertion failure. Commit cbee81f fixed this by guarding the second error_setg() with an error_is_set(). Replace this fix by a simpler and safer one: jump right behind the second error_setg(). Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-25nbd: Use return values instead of error_is_set(errp)Markus Armbruster
Using error_is_set(errp) to check whether a function call failed is fragile: it breaks when errp is null. Check perfectly suitable return values instead when possible. errp can't be null there now, but this is more robust and more obviously correct Signed-off-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-25Use error_is_set() only when necessary (again)Markus Armbruster
error_is_set(&var) is the same as var != NULL, but it takes whole-program analysis to figure that out. Unnecessarily hard for optimizers, static checkers, and human readers. Commit 84d18f0 dumbed it down to obvious, but a few more have crept in since, and documentation was overlooked. Dumb these down, too. Signed-off-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-25qerror.h: Remove QERR defines that are only used onceCole Robinson
Just hardcode them in the callers Cc: Luiz Capitulino <lcapitulino@redhat.com> Cc: Markus Armbruster <armbru@redhat.com> Signed-off-by: Cole Robinson <crobinso@redhat.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-04-23block/cloop: use PRIu32 format specifier for uint32_tStefan Hajnoczi
PRIu32 is the format string specifier for uint32_t, let's use it. Variables ->block_size, ->n_blocks, and i are all uint32_t. Suggested-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-04-22vmdk: Fix "%x" to PRIx32 in format strings for cidFam Zheng
Signed-off-by: Fam Zheng <famz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-04-22block: Add errp to bdrv_new()Kevin Wolf
This patch adds an errp parameter to bdrv_new() and updates all its callers. The next patches will make use of this in order to check for duplicate IDs. Most of the callers know that their ID is fine, so they can simply assert that there is no error. Behaviour doesn't change with this patch yet as bdrv_new() doesn't actually assign errors to errp. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2014-04-22convert fprintf() calls to error_setg() in block/qed.c:bdrv_qed_create()Aakriti Gupta
This patch converts fprintf() calls to error_setg() in block/qed.c:bdrv_qed_create() (error_setg() is part of error reporting API in include/qapi/error.h) Signed-off-by: Aakriti Gupta <aakritty@gmail.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-04-22curl: Replaced old error handling with error reporting API.Maria Kustova
Signed-off-by: Maria Kustova <maria.k@catit.be> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-04-22block: Handle error of bdrv_getlength in bdrv_create_dirty_bitmapFam Zheng
bdrv_getlength could fail, check the return value before using it. Return NULL and set errno if it fails. Callers are updated to handle the error case. Signed-off-by: Fam Zheng <famz@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-04-22vmdk: Fix %d and %lld to PRI* in format stringsFam Zheng
Signed-off-by: Fam Zheng <famz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-04-11iscsi: Remember to set ret for iscsi_open in error caseFam Zheng
Signed-off-by: Fam Zheng <famz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-04-11bochs: Fix catalog size checkKevin Wolf
The old check was off by a factor of 512 and didn't consider cases where we don't get an exact division. This could lead to an out-of-bounds array access in seek_to_sector(). Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2014-04-11bochs: Fix memory leak in bochs_open() error pathKevin Wolf
Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2014-04-04qcow2: Put cache reference in error caseKevin Wolf
When qcow2_get_cluster_offset() sees a zero cluster in a version 2 image, it (rightfully) returns an error. But in doing so it shouldn't leak an L2 table cache reference. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com>
2014-04-04qcow2: Flush metadata during read-only reopenKevin Wolf
If lazy refcounts are enabled for a backing file, committing to this backing file may leave it in a dirty state even if the commit succeeds. The reason is that the bdrv_flush() call in bdrv_commit() doesn't flush refcount updates with lazy refcounts enabled, and qcow2_reopen_prepare() doesn't take care to flush metadata. In order to fix this, this patch also fixes qcow2_mark_clean(), which contains another ineffective bdrv_flush() call beause lazy refcounts are disabled only afterwards. All existing callers of qcow2_mark_clean() either don't modify refcounts or already flush manually, so that this fixes only a latent, but not yet actually triggerable bug. Another instance of the same problem is live snapshots. Again, a real corruption is prevented by an explicit flush for non-read-only images in external_snapshot_prepare(), but images using lazy refcounts stay dirty. Cc: qemu-stable@nongnu.org Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-04iscsi: Don't set error if already set in iscsi_do_inquiryFam Zheng
This eliminates the possible assertion failure in error_setg(). Signed-off-by: Fam Zheng <famz@redhat.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2014-04-03Merge remote-tracking branch 'remotes/bonzini/scsi-next' into stagingPeter Maydell
* remotes/bonzini/scsi-next: iscsi: always query max WRITE SAME length iscsi: ignore flushes on scsi-generic devices iscsi: recognize "invalid field" ASCQ from WRITE SAME command scsi-bus: remove bogus assertion Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-04-03iscsi: always query max WRITE SAME lengthPaolo Bonzini
Max WRITE SAME length is also used when the UNMAP bit is zero, so it should be queried even if LBPWS=0. Same for the optimal transfer length. However, the write_zeroes_alignment only matters for UNMAP=1 so we still restrict it to LBPWS=1. Reviewed-by: Peter Lieven <pl@kamp.de> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-04-03iscsi: ignore flushes on scsi-generic devicesPaolo Bonzini
Non-block SCSI devices do not support flushing, but we may still send them requests via bdrv_flush_all. Just ignore them. Reviewed-by: Peter Lieven <pl@kamp.de> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-04-03iscsi: recognize "invalid field" ASCQ from WRITE SAME commandPaolo Bonzini
Some targets may return "invalid field" as the ASCQ from WRITE SAME if they support the command only without the UNMAP field. Recognize that, and return ENOTSUP just like for "invalid operation code". Reviewed-by: Peter Lieven <pl@kamp.de> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-04-01qcow2: link all L2 meta updates in preallocate()Stefan Hajnoczi
preallocate() only links the first QCowL2Meta's data clusters into the L2 table and ignores any chained QCowL2Metas in the linked list. Chains of QCowL2Meta structs are built up when contiguous clusters span L2 tables. Each QCowL2Meta describes one L2 table update. This is a rare case in preallocate() but can happen. This patch fixes preallocate() by iterating over the whole list of QCowL2Metas. Compare with the qcow2_co_writev() function's implementation, which is similar but also also handles request dependencies. preallocate() only performs one allocation at a time so there can be no dependencies. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01parallels: Sanity check for s->tracks (CVE-2014-0142)Kevin Wolf
This avoids a possible division by zero. Convert s->tracks to unsigned as well because it feels better than surviving just because the results of calculations with s->tracks are converted to unsigned anyway. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01parallels: Fix catalog size integer overflow (CVE-2014-0143)Kevin Wolf
The first test case would cause a huge memory allocation, leading to a qemu abort; the second one to a too small malloc() for the catalog (smaller than s->catalog_size), which causes a read-only out-of-bounds array access and on big endian hosts an endianess conversion for an undefined memory area. The sample image used here is not an original Parallels image. It was created using an hexeditor on the basis of the struct that qemu uses. Good enough for trying to crash the driver, but not for ensuring compatibility. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01qcow2: Limit snapshot table sizeKevin Wolf
Even with a limit of 64k snapshots, each snapshot could have a filename and an ID with up to 64k, which would still lead to pretty large allocations, which could potentially lead to qemu aborting. Limit the total size of the snapshot table to an average of 1k per entry when the limit of 64k snapshots is fully used. This should be plenty for any reasonable user. This also fixes potential integer overflows of s->snapshot_size. Suggested-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01qcow2: Check maximum L1 size in qcow2_snapshot_load_tmp() (CVE-2014-0143)Kevin Wolf
This avoids an unbounded allocation. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01qcow2: Fix L1 allocation size in qcow2_snapshot_load_tmp() (CVE-2014-0145)Kevin Wolf
For the L1 table to loaded for an internal snapshot, the code allocated only enough memory to hold the currently active L1 table. If the snapshot's L1 table is actually larger than the current one, this leads to a buffer overflow. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01qcow2: Fix NULL dereference in qcow2_open() error path (CVE-2014-0146)Kevin Wolf
The qcow2 code assumes that s->snapshots is non-NULL if s->nb_snapshots != 0. By having the initialisation of both fields separated in qcow2_open(), any error occuring in between would cause the error path to dereference NULL in qcow2_free_snapshots() if the image had any snapshots. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01qcow2: Fix copy_sectors() with VM stateKevin Wolf
bs->total_sectors is not the highest possible sector number that could be involved in a copy on write operation: VM state is after the end of the virtual disk. This resulted in wrong values for the number of sectors to be copied (n). The code that checks for the end of the image isn't required any more because the code hasn't been calling the block layer's bdrv_read() for a long time; instead, it directly calls qcow2_readv(), which doesn't error out on VM state sector numbers. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01dmg: prevent chunk buffer overflow (CVE-2014-0145)Stefan Hajnoczi
Both compressed and uncompressed I/O is buffered. dmg_open() calculates the maximum buffer size needed from the metadata in the image file. There is currently a buffer overflow since ->lengths[] is accounted against the maximum compressed buffer size but actually uses the uncompressed buffer: switch (s->types[chunk]) { case 1: /* copy */ ret = bdrv_pread(bs->file, s->offsets[chunk], s->uncompressed_chunk, s->lengths[chunk]); We must account against the maximum uncompressed buffer size for type=1 chunks. This patch fixes the maximum buffer size calculation to take into account the chunk type. It is critical that we update the correct maximum since there are two buffers ->compressed_chunk and ->uncompressed_chunk. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01dmg: use uint64_t consistently for sectors and lengthsStefan Hajnoczi
The DMG metadata is stored as uint64_t, so use the same type for sector_num. int was a particularly poor choice since it is only 32-bit and would truncate large values. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01dmg: sanitize chunk length and sectorcount (CVE-2014-0145)Stefan Hajnoczi
Chunk length and sectorcount are used for decompression buffers as well as the bdrv_pread() count argument. Ensure that they have reasonable values so neither memory allocation nor conversion from uint64_t to int will cause problems. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01dmg: use appropriate types when reading chunksStefan Hajnoczi
Use the right types instead of signed int: size_t new_size; This is a byte count for g_realloc() that is calculated from uint32_t and size_t values. uint32_t chunk_count; Use the same type as s->n_chunks, which is used together with chunk_count. This patch is a cleanup and does not fix bugs. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01dmg: drop broken bdrv_pread() loopStefan Hajnoczi
It is not necessary to check errno for EINTR and the block layer does not produce short reads. Therefore we can drop the loop that attempts to read a compressed chunk. The loop is buggy because it incorrectly adds the transferred bytes twice: do { ret = bdrv_pread(...); i += ret; } while (ret >= 0 && ret + i < s->lengths[chunk]); Luckily we can drop the loop completely and perform a single bdrv_pread(). Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01dmg: prevent out-of-bounds array access on terminatorStefan Hajnoczi
When a terminator is reached the base for offsets and sectors is stored. The following records that are processed will use this base value. If the first record we encounter is a terminator, then calculating the base values would result in out-of-bounds array accesses. Don't do that. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01dmg: coding style and indentation cleanupStefan Hajnoczi
Clean up the mix of tabs and spaces, as well as the coding style violations in block/dmg.c. There are no semantic changes since this patch simply reformats the code. This patch is necessary before we can make meaningful changes to this file, due to the inconsistent formatting and confusing indentation. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01qcow2: Fix new L1 table size check (CVE-2014-0143)Kevin Wolf
The size in bytes is assigned to an int later, so check that instead of the number of entries. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01qcow2: Protect against some integer overflows in bdrv_checkKevin Wolf
Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01qcow2: Fix types in qcow2_alloc_clusters and alloc_clusters_norefKevin Wolf
In order to avoid integer overflows. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01qcow2: Check new refcount table size on growthKevin Wolf
If the size becomes larger than what qcow2_open() would accept, fail the growing operation. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01qcow2: Avoid integer overflow in get_refcount (CVE-2014-0143)Kevin Wolf
This ensures that the checks catch all invalid cluster indexes instead of returning the refcount of a wrong cluster. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01qcow2: Don't rely on free_cluster_index in alloc_refcount_block() ↵Kevin Wolf
(CVE-2014-0147) free_cluster_index is only correct if update_refcount() was called from an allocation function, and even there it's brittle because it's used to protect unfinished allocations which still have a refcount of 0 - if it moves in the wrong place, the unfinished allocation can be corrupted. So not using it any more seems to be a good idea. Instead, use the first requested cluster to do the calculations. Return -EAGAIN if unfinished allocations could become invalid and let the caller restart its search for some free clusters. The context of creating a snapsnot is one situation where update_refcount() is called outside of a cluster allocation. For this case, the change fixes a buffer overflow if a cluster is referenced in an L2 table that cannot be represented by an existing refcount block. (new_table[refcount_table_index] was out of bounds) [Bump the qemu-iotests 026 refblock_alloc.write leak count from 10 to 11. --Stefan] Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-04-01qcow2: Fix backing file name length checkKevin Wolf
len could become negative and would pass the check then. Nothing bad happened because bdrv_pread() happens to return an error for negative length values, but make variables for sizes unsigned anyway. This patch also changes the behaviour to error out on invalid lengths instead of silently truncating it to 1023. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>