Block layer patches

-----BEGIN PGP SIGNATURE-----
 
 iQIcBAABAgAGBQJZylugAAoJEH8JsnLIjy/Wp1QP/jtwre8WwtlX3SZ82cyiwonc
 fODcokF6iEsX7vs9vMr8lkbwF4mjxaU2Xf/knC98J/6rCxM8DRP/MW4BZttTxDI9
 ++U926cIHHzjtSDalcjfTKnJD7PikHbLXz3SJ+u9hPnIeGs56hybCU6iHrrIcOTs
 YSMtD3eUQ8B8JaoegKgNyqkhvfhEdHlWFCq9/T2YEWwYMzGt1jvSTRqe3vr8vIu3
 v7QKvh35gm965yaUTGpv7Ej7TOBTWOaYBo9D1TBKNEZOFTBjqyldciyBoDhCF2P9
 +4EsNTkZ7u20Rko41dzsZPzhjG10gm/lNZNj3Cul9ta4kQ0hGeOjEujd9L9ANTGl
 gwnPPHKwgax5O+ctCPmrU7yHG+XIQD3gckC69qQeRXnPYQ4Jeo/LqhwjU+FcZfHs
 97Lz6CHQHgtBP9JJwBMtUp77HJ58KPnnWIxGkb9u2vm4CpvRFkMrx5ekmj//9klX
 5niRiqkNdrkEUnu/FIXOXxSmwnlhedAGQNq7ALSoW95El1QCy8Mm0eKEvmHyvZzd
 z2gSufLX6ynOaG4x5oY5eezKm6F4Hxwt+w8Svj9PHXIrmrEIop11LG5MVsDGDjyh
 XKiLddEIVKTYGwffX0CGTLYA34m2uHPkVVrMOIEvni3G6byXkb10+4pBpuTu/O/h
 wQPFraquH1I2B5YETsMa
 =7Bt2
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging

Block layer patches

# gpg: Signature made Tue 26 Sep 2017 14:52:32 BST
# gpg:                using RSA key 0x7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream: (24 commits)
  block/qcow2-bitmap: fix use of uninitialized pointer
  qemu-iotests: add shrinking image test
  qcow2: add shrink image support
  qcow2: add qcow2_cache_discard
  qemu-img: add --shrink flag for resize
  iotests: fix 181: enable postcopy-ram capability on target
  qemu-iotests: Test change-backing-file command
  block: Fix permissions after bdrv_reopen()
  block: reopen: Queue children after their parents
  block: Base permissions on rw state after reopen
  block: Add reopen queue to bdrv_check_perm()
  block: Add reopen_queue to bdrv_child_perm()
  qemu-io: Drop write permissions before read-only reopen
  block: Clean up some bad code in the vvfat driver
  block/throttle-groups.c: allocate RestartData on the heap
  throttle: Assert that bkt->max is valid in throttle_compute_wait()
  iotests: Print full path of bad output if mismatch
  iotests: use virtio aliases for 067
  iotests: use -ccw on s390x for 051
  iotests: use -ccw on s390x for 040, 139, and 182
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2017-09-27 16:48:39 +01:00
commit cfe4cade05
45 changed files with 1710 additions and 897 deletions

View File

@ -209,6 +209,7 @@ ifdef BUILD_DOCS
DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1 qemu-nbd.8 qemu-ga.8
DOCS+=docs/interop/qemu-qmp-ref.html docs/interop/qemu-qmp-ref.txt docs/interop/qemu-qmp-ref.7
DOCS+=docs/interop/qemu-ga-ref.html docs/interop/qemu-ga-ref.txt docs/interop/qemu-ga-ref.7
DOCS+=docs/qemu-block-drivers.7
ifdef CONFIG_VIRTFS
DOCS+=fsdev/virtfs-proxy-helper.1
endif
@ -532,6 +533,7 @@ distclean: clean
rm -f docs/interop/qemu-qmp-ref.txt docs/interop/qemu-ga-ref.txt
rm -f docs/interop/qemu-qmp-ref.pdf docs/interop/qemu-ga-ref.pdf
rm -f docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html
rm -f docs/qemu-block-drivers.7
for d in $(TARGET_DIRS); do \
rm -rf $$d || exit 1 ; \
done
@ -576,6 +578,7 @@ ifdef CONFIG_POSIX
$(INSTALL_DATA) qemu.1 "$(DESTDIR)$(mandir)/man1"
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man7"
$(INSTALL_DATA) docs/interop/qemu-qmp-ref.7 "$(DESTDIR)$(mandir)/man7"
$(INSTALL_DATA) docs/qemu-block-drivers.7 "$(DESTDIR)$(mandir)/man7"
ifneq ($(TOOLS),)
$(INSTALL_DATA) qemu-img.1 "$(DESTDIR)$(mandir)/man1"
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man8"
@ -721,6 +724,7 @@ qemu-img.1: qemu-img.texi qemu-option-trace.texi qemu-img-cmds.texi
fsdev/virtfs-proxy-helper.1: fsdev/virtfs-proxy-helper.texi
qemu-nbd.8: qemu-nbd.texi qemu-option-trace.texi
qemu-ga.8: qemu-ga.texi
docs/qemu-block-drivers.7: docs/qemu-block-drivers.texi
html: qemu-doc.html docs/interop/qemu-qmp-ref.html docs/interop/qemu-ga-ref.html
info: qemu-doc.info docs/interop/qemu-qmp-ref.info docs/interop/qemu-ga-ref.info
@ -730,7 +734,7 @@ txt: qemu-doc.txt docs/interop/qemu-qmp-ref.txt docs/interop/qemu-ga-ref.txt
qemu-doc.html qemu-doc.info qemu-doc.pdf qemu-doc.txt: \
qemu-img.texi qemu-nbd.texi qemu-options.texi qemu-option-trace.texi \
qemu-monitor.texi qemu-img-cmds.texi qemu-ga.texi \
qemu-monitor-info.texi
qemu-monitor-info.texi docs/qemu-block-drivers.texi
docs/interop/qemu-ga-ref.dvi docs/interop/qemu-ga-ref.html \
docs/interop/qemu-ga-ref.info docs/interop/qemu-ga-ref.pdf \

191
block.c
View File

@ -239,12 +239,6 @@ bool bdrv_is_read_only(BlockDriverState *bs)
return bs->read_only;
}
/* Returns whether the image file can be written to right now */
bool bdrv_is_writable(BlockDriverState *bs)
{
return !bdrv_is_read_only(bs) && !(bs->open_flags & BDRV_O_INACTIVE);
}
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
bool ignore_allow_rdw, Error **errp)
{
@ -1531,22 +1525,59 @@ static int bdrv_fill_options(QDict **options, const char *filename,
return 0;
}
static int bdrv_child_check_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q,
uint64_t perm, uint64_t shared,
GSList *ignore_children, Error **errp);
static void bdrv_child_abort_perm_update(BdrvChild *c);
static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared);
typedef struct BlockReopenQueueEntry {
bool prepared;
BDRVReopenState state;
QSIMPLEQ_ENTRY(BlockReopenQueueEntry) entry;
} BlockReopenQueueEntry;
/*
* Return the flags that @bs will have after the reopens in @q have
* successfully completed. If @q is NULL (or @bs is not contained in @q),
* return the current flags.
*/
static int bdrv_reopen_get_flags(BlockReopenQueue *q, BlockDriverState *bs)
{
BlockReopenQueueEntry *entry;
if (q != NULL) {
QSIMPLEQ_FOREACH(entry, q, entry) {
if (entry->state.bs == bs) {
return entry->state.flags;
}
}
}
return bs->open_flags;
}
/* Returns whether the image file can be written to after the reopen queue @q
* has been successfully applied, or right now if @q is NULL. */
static bool bdrv_is_writable(BlockDriverState *bs, BlockReopenQueue *q)
{
int flags = bdrv_reopen_get_flags(q, bs);
return (flags & (BDRV_O_RDWR | BDRV_O_INACTIVE)) == BDRV_O_RDWR;
}
static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
BdrvChild *c,
const BdrvChildRole *role,
BdrvChild *c, const BdrvChildRole *role,
BlockReopenQueue *reopen_queue,
uint64_t parent_perm, uint64_t parent_shared,
uint64_t *nperm, uint64_t *nshared)
{
if (bs->drv && bs->drv->bdrv_child_perm) {
bs->drv->bdrv_child_perm(bs, c, role,
bs->drv->bdrv_child_perm(bs, c, role, reopen_queue,
parent_perm, parent_shared,
nperm, nshared);
}
/* TODO Take force_share from reopen_queue */
if (child_bs && child_bs->force_share) {
*nshared = BLK_PERM_ALL;
}
@ -1561,7 +1592,8 @@ static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
* A call to this function must always be followed by a call to bdrv_set_perm()
* or bdrv_abort_perm_update().
*/
static int bdrv_check_perm(BlockDriverState *bs, uint64_t cumulative_perms,
static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
uint64_t cumulative_perms,
uint64_t cumulative_shared_perms,
GSList *ignore_children, Error **errp)
{
@ -1571,7 +1603,7 @@ static int bdrv_check_perm(BlockDriverState *bs, uint64_t cumulative_perms,
/* Write permissions never work with read-only images */
if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&
!bdrv_is_writable(bs))
!bdrv_is_writable(bs, q))
{
error_setg(errp, "Block node is read-only");
return -EPERM;
@ -1596,11 +1628,11 @@ static int bdrv_check_perm(BlockDriverState *bs, uint64_t cumulative_perms,
/* Check all children */
QLIST_FOREACH(c, &bs->children, next) {
uint64_t cur_perm, cur_shared;
bdrv_child_perm(bs, c->bs, c, c->role,
bdrv_child_perm(bs, c->bs, c, c->role, q,
cumulative_perms, cumulative_shared_perms,
&cur_perm, &cur_shared);
ret = bdrv_child_check_perm(c, cur_perm, cur_shared, ignore_children,
errp);
ret = bdrv_child_check_perm(c, q, cur_perm, cur_shared,
ignore_children, errp);
if (ret < 0) {
return ret;
}
@ -1658,7 +1690,7 @@ static void bdrv_set_perm(BlockDriverState *bs, uint64_t cumulative_perms,
/* Update all children */
QLIST_FOREACH(c, &bs->children, next) {
uint64_t cur_perm, cur_shared;
bdrv_child_perm(bs, c->bs, c, c->role,
bdrv_child_perm(bs, c->bs, c, c->role, NULL,
cumulative_perms, cumulative_shared_perms,
&cur_perm, &cur_shared);
bdrv_child_set_perm(c, cur_perm, cur_shared);
@ -1726,7 +1758,8 @@ char *bdrv_perm_names(uint64_t perm)
*
* Needs to be followed by a call to either bdrv_set_perm() or
* bdrv_abort_perm_update(). */
static int bdrv_check_update_perm(BlockDriverState *bs, uint64_t new_used_perm,
static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *q,
uint64_t new_used_perm,
uint64_t new_shared_perm,
GSList *ignore_children, Error **errp)
{
@ -1768,19 +1801,20 @@ static int bdrv_check_update_perm(BlockDriverState *bs, uint64_t new_used_perm,
cumulative_shared_perms &= c->shared_perm;
}
return bdrv_check_perm(bs, cumulative_perms, cumulative_shared_perms,
return bdrv_check_perm(bs, q, cumulative_perms, cumulative_shared_perms,
ignore_children, errp);
}
/* Needs to be followed by a call to either bdrv_child_set_perm() or
* bdrv_child_abort_perm_update(). */
static int bdrv_child_check_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q,
uint64_t perm, uint64_t shared,
GSList *ignore_children, Error **errp)
{
int ret;
ignore_children = g_slist_prepend(g_slist_copy(ignore_children), c);
ret = bdrv_check_update_perm(c->bs, perm, shared, ignore_children, errp);
ret = bdrv_check_update_perm(c->bs, q, perm, shared, ignore_children, errp);
g_slist_free(ignore_children);
return ret;
@ -1808,7 +1842,7 @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
{
int ret;
ret = bdrv_child_check_perm(c, perm, shared, NULL, errp);
ret = bdrv_child_check_perm(c, NULL, perm, shared, NULL, errp);
if (ret < 0) {
bdrv_child_abort_perm_update(c);
return ret;
@ -1827,6 +1861,7 @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
const BdrvChildRole *role,
BlockReopenQueue *reopen_queue,
uint64_t perm, uint64_t shared,
uint64_t *nperm, uint64_t *nshared)
{
@ -1844,6 +1879,7 @@ void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
const BdrvChildRole *role,
BlockReopenQueue *reopen_queue,
uint64_t perm, uint64_t shared,
uint64_t *nperm, uint64_t *nshared)
{
@ -1853,10 +1889,11 @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
if (!backing) {
/* Apart from the modifications below, the same permissions are
* forwarded and left alone as for filters */
bdrv_filter_default_perms(bs, c, role, perm, shared, &perm, &shared);
bdrv_filter_default_perms(bs, c, role, reopen_queue, perm, shared,
&perm, &shared);
/* Format drivers may touch metadata even if the guest doesn't write */
if (bdrv_is_writable(bs)) {
if (bdrv_is_writable(bs, reopen_queue)) {
perm |= BLK_PERM_WRITE | BLK_PERM_RESIZE;
}
@ -1945,7 +1982,7 @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
* because we're just taking a parent away, so we're loosening
* restrictions. */
bdrv_get_cumulative_perm(old_bs, &perm, &shared_perm);
bdrv_check_perm(old_bs, perm, shared_perm, NULL, &error_abort);
bdrv_check_perm(old_bs, NULL, perm, shared_perm, NULL, &error_abort);
bdrv_set_perm(old_bs, perm, shared_perm);
}
@ -1964,7 +2001,7 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
BdrvChild *child;
int ret;
ret = bdrv_check_update_perm(child_bs, perm, shared_perm, NULL, errp);
ret = bdrv_check_update_perm(child_bs, NULL, perm, shared_perm, NULL, errp);
if (ret < 0) {
bdrv_abort_perm_update(child_bs);
return NULL;
@ -1999,7 +2036,7 @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
assert(parent_bs->drv);
assert(bdrv_get_aio_context(parent_bs) == bdrv_get_aio_context(child_bs));
bdrv_child_perm(parent_bs, child_bs, NULL, child_role,
bdrv_child_perm(parent_bs, child_bs, NULL, child_role, NULL,
perm, shared_perm, &perm, &shared_perm);
child = bdrv_root_attach_child(child_bs, child_name, child_role,
@ -2633,12 +2670,6 @@ BlockDriverState *bdrv_open(const char *filename, const char *reference,
NULL, errp);
}
typedef struct BlockReopenQueueEntry {
bool prepared;
BDRVReopenState state;
QSIMPLEQ_ENTRY(BlockReopenQueueEntry) entry;
} BlockReopenQueueEntry;
/*
* Adds a BlockDriverState to a simple queue for an atomic, transactional
* reopen of multiple devices.
@ -2737,6 +2768,23 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
flags |= BDRV_O_ALLOW_RDWR;
}
if (!bs_entry) {
bs_entry = g_new0(BlockReopenQueueEntry, 1);
QSIMPLEQ_INSERT_TAIL(bs_queue, bs_entry, entry);
} else {
QDECREF(bs_entry->state.options);
QDECREF(bs_entry->state.explicit_options);
}
bs_entry->state.bs = bs;
bs_entry->state.options = options;
bs_entry->state.explicit_options = explicit_options;
bs_entry->state.flags = flags;
/* This needs to be overwritten in bdrv_reopen_prepare() */
bs_entry->state.perm = UINT64_MAX;
bs_entry->state.shared_perm = 0;
QLIST_FOREACH(child, &bs->children, next) {
QDict *new_child_options;
char *child_key_dot;
@ -2756,19 +2804,6 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
child->role, options, flags);
}
if (!bs_entry) {
bs_entry = g_new0(BlockReopenQueueEntry, 1);
QSIMPLEQ_INSERT_TAIL(bs_queue, bs_entry, entry);
} else {
QDECREF(bs_entry->state.options);
QDECREF(bs_entry->state.explicit_options);
}
bs_entry->state.bs = bs;
bs_entry->state.options = options;
bs_entry->state.explicit_options = explicit_options;
bs_entry->state.flags = flags;
return bs_queue;
}
@ -2856,6 +2891,52 @@ int bdrv_reopen(BlockDriverState *bs, int bdrv_flags, Error **errp)
return ret;
}
static BlockReopenQueueEntry *find_parent_in_reopen_queue(BlockReopenQueue *q,
BdrvChild *c)
{
BlockReopenQueueEntry *entry;
QSIMPLEQ_FOREACH(entry, q, entry) {
BlockDriverState *bs = entry->state.bs;
BdrvChild *child;
QLIST_FOREACH(child, &bs->children, next) {
if (child == c) {
return entry;
}
}
}
return NULL;
}
static void bdrv_reopen_perm(BlockReopenQueue *q, BlockDriverState *bs,
uint64_t *perm, uint64_t *shared)
{
BdrvChild *c;
BlockReopenQueueEntry *parent;
uint64_t cumulative_perms = 0;
uint64_t cumulative_shared_perms = BLK_PERM_ALL;
QLIST_FOREACH(c, &bs->parents, next_parent) {
parent = find_parent_in_reopen_queue(q, c);
if (!parent) {
cumulative_perms |= c->perm;
cumulative_shared_perms &= c->shared_perm;
} else {
uint64_t nperm, nshared;
bdrv_child_perm(parent->state.bs, bs, c, c->role, q,
parent->state.perm, parent->state.shared_perm,
&nperm, &nshared);
cumulative_perms |= nperm;
cumulative_shared_perms &= nshared;
}
}
*perm = cumulative_perms;
*shared = cumulative_shared_perms;
}
/*
* Prepares a BlockDriverState for reopen. All changes are staged in the
@ -2921,6 +3002,9 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
goto error;
}
/* Calculate required permissions after reopening */
bdrv_reopen_perm(queue, reopen_state->bs,
&reopen_state->perm, &reopen_state->shared_perm);
ret = bdrv_flush(reopen_state->bs);
if (ret) {
@ -2976,6 +3060,12 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
} while ((entry = qdict_next(reopen_state->options, entry)));
}
ret = bdrv_check_perm(reopen_state->bs, queue, reopen_state->perm,
reopen_state->shared_perm, NULL, errp);
if (ret < 0) {
goto error;
}
ret = 0;
error:
@ -3016,6 +3106,9 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state)
bdrv_refresh_limits(bs, NULL);
bdrv_set_perm(reopen_state->bs, reopen_state->perm,
reopen_state->shared_perm);
new_can_write =
!bdrv_is_read_only(bs) && !(bdrv_get_flags(bs) & BDRV_O_INACTIVE);
if (!old_can_write && new_can_write && drv->bdrv_reopen_bitmaps_rw) {
@ -3049,6 +3142,8 @@ void bdrv_reopen_abort(BDRVReopenState *reopen_state)
}
QDECREF(reopen_state->explicit_options);
bdrv_abort_perm_update(reopen_state->bs);
}
@ -3179,7 +3274,7 @@ void bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
/* Check whether the required permissions can be granted on @to, ignoring
* all BdrvChild in @list so that they can't block themselves. */
ret = bdrv_check_update_perm(to, perm, shared, list, errp);
ret = bdrv_check_update_perm(to, NULL, perm, shared, list, errp);
if (ret < 0) {
bdrv_abort_perm_update(to);
goto out;
@ -4049,7 +4144,7 @@ void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp)
/* Update permissions, they may differ for inactive nodes */
bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
ret = bdrv_check_perm(bs, perm, shared_perm, NULL, &local_err);
ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, &local_err);
if (ret < 0) {
bs->open_flags |= BDRV_O_INACTIVE;
error_propagate(errp, local_err);
@ -4116,7 +4211,7 @@ static int bdrv_inactivate_recurse(BlockDriverState *bs,
/* Update permissions, they may differ for inactive nodes */
bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
bdrv_check_perm(bs, perm, shared_perm, NULL, &error_abort);
bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, &error_abort);
bdrv_set_perm(bs, perm, shared_perm);
}

View File

@ -257,6 +257,7 @@ static void bdrv_commit_top_close(BlockDriverState *bs)
static void bdrv_commit_top_child_perm(BlockDriverState *bs, BdrvChild *c,
const BdrvChildRole *role,
BlockReopenQueue *reopen_queue,
uint64_t perm, uint64_t shared,
uint64_t *nperm, uint64_t *nshared)
{

View File

@ -2730,6 +2730,16 @@ static int hdev_create(const char *filename, QemuOpts *opts,
ret = -ENOSPC;
}
if (!ret && total_size) {
uint8_t buf[BDRV_SECTOR_SIZE] = { 0 };
int64_t zero_size = MIN(BDRV_SECTOR_SIZE, total_size);
if (lseek(fd, 0, SEEK_SET) == -1) {
ret = -errno;
} else {
ret = qemu_write_full(fd, buf, zero_size);
ret = ret == zero_size ? 0 : -errno;
}
}
qemu_close(fd);
return ret;
}

View File

@ -1084,6 +1084,7 @@ static void bdrv_mirror_top_close(BlockDriverState *bs)
static void bdrv_mirror_top_child_perm(BlockDriverState *bs, BdrvChild *c,
const BdrvChildRole *role,
BlockReopenQueue *reopen_queue,
uint64_t perm, uint64_t shared,
uint64_t *nperm, uint64_t *nshared)
{

View File

@ -602,7 +602,7 @@ static Qcow2BitmapList *bitmap_list_load(BlockDriverState *bs, uint64_t offset,
goto fail;
}
bm = g_new(Qcow2Bitmap, 1);
bm = g_new0(Qcow2Bitmap, 1);
bm->table.offset = e->bitmap_table_offset;
bm->table.size = e->bitmap_table_size;
bm->flags = e->flags;

View File

@ -411,3 +411,29 @@ void qcow2_cache_entry_mark_dirty(BlockDriverState *bs, Qcow2Cache *c,
assert(c->entries[i].offset != 0);
c->entries[i].dirty = true;
}
void *qcow2_cache_is_table_offset(BlockDriverState *bs, Qcow2Cache *c,
uint64_t offset)
{
int i;
for (i = 0; i < c->size; i++) {
if (c->entries[i].offset == offset) {
return qcow2_cache_get_table_addr(bs, c, i);
}
}
return NULL;
}
void qcow2_cache_discard(BlockDriverState *bs, Qcow2Cache *c, void *table)
{
int i = qcow2_cache_get_table_idx(bs, c, table);
assert(c->entries[i].ref == 0);
c->entries[i].offset = 0;
c->entries[i].lru_counter = 0;
c->entries[i].dirty = false;
qcow2_cache_table_release(bs, c, i, 1);
}

View File

@ -32,6 +32,56 @@
#include "qemu/bswap.h"
#include "trace.h"
int qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t exact_size)
{
BDRVQcow2State *s = bs->opaque;
int new_l1_size, i, ret;
if (exact_size >= s->l1_size) {
return 0;
}
new_l1_size = exact_size;
#ifdef DEBUG_ALLOC2
fprintf(stderr, "shrink l1_table from %d to %d\n", s->l1_size, new_l1_size);
#endif
BLKDBG_EVENT(bs->file, BLKDBG_L1_SHRINK_WRITE_TABLE);
ret = bdrv_pwrite_zeroes(bs->file, s->l1_table_offset +
new_l1_size * sizeof(uint64_t),
(s->l1_size - new_l1_size) * sizeof(uint64_t), 0);
if (ret < 0) {
goto fail;
}
ret = bdrv_flush(bs->file->bs);
if (ret < 0) {
goto fail;
}
BLKDBG_EVENT(bs->file, BLKDBG_L1_SHRINK_FREE_L2_CLUSTERS);
for (i = s->l1_size - 1; i > new_l1_size - 1; i--) {
if ((s->l1_table[i] & L1E_OFFSET_MASK) == 0) {
continue;
}
qcow2_free_clusters(bs, s->l1_table[i] & L1E_OFFSET_MASK,
s->cluster_size, QCOW2_DISCARD_ALWAYS);
s->l1_table[i] = 0;
}
return 0;
fail:
/*
* If the write in the l1_table failed the image may contain a partially
* overwritten l1_table. In this case it would be better to clear the
* l1_table in memory to avoid possible image corruption.
*/
memset(s->l1_table + new_l1_size, 0,
(s->l1_size - new_l1_size) * sizeof(uint64_t));
return ret;
}
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
bool exact_size)
{

View File

@ -29,6 +29,7 @@
#include "block/qcow2.h"
#include "qemu/range.h"
#include "qemu/bswap.h"
#include "qemu/cutils.h"
static int64_t alloc_clusters_noref(BlockDriverState *bs, uint64_t size);
static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
@ -861,8 +862,24 @@ static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
}
s->set_refcount(refcount_block, block_index, refcount);
if (refcount == 0 && s->discard_passthrough[type]) {
update_refcount_discard(bs, cluster_offset, s->cluster_size);
if (refcount == 0) {
void *table;
table = qcow2_cache_is_table_offset(bs, s->refcount_block_cache,
offset);
if (table != NULL) {
qcow2_cache_put(bs, s->refcount_block_cache, &refcount_block);
qcow2_cache_discard(bs, s->refcount_block_cache, table);
}
table = qcow2_cache_is_table_offset(bs, s->l2_table_cache, offset);
if (table != NULL) {
qcow2_cache_discard(bs, s->l2_table_cache, table);
}
if (s->discard_passthrough[type]) {
update_refcount_discard(bs, cluster_offset, s->cluster_size);
}
}
}
@ -3045,3 +3062,122 @@ done:
qemu_vfree(new_refblock);
return ret;
}
static int qcow2_discard_refcount_block(BlockDriverState *bs,
uint64_t discard_block_offs)
{
BDRVQcow2State *s = bs->opaque;
uint64_t refblock_offs = get_refblock_offset(s, discard_block_offs);
uint64_t cluster_index = discard_block_offs >> s->cluster_bits;
uint32_t block_index = cluster_index & (s->refcount_block_size - 1);
void *refblock;
int ret;
assert(discard_block_offs != 0);
ret = qcow2_cache_get(bs, s->refcount_block_cache, refblock_offs,
&refblock);
if (ret < 0) {
return ret;
}
if (s->get_refcount(refblock, block_index) != 1) {
qcow2_signal_corruption(bs, true, -1, -1, "Invalid refcount:"
" refblock offset %#" PRIx64
", reftable index %u"
", block offset %#" PRIx64
", refcount %#" PRIx64,
refblock_offs,
offset_to_reftable_index(s, discard_block_offs),
discard_block_offs,
s->get_refcount(refblock, block_index));
qcow2_cache_put(bs, s->refcount_block_cache, &refblock);
return -EINVAL;
}
s->set_refcount(refblock, block_index, 0);
qcow2_cache_entry_mark_dirty(bs, s->refcount_block_cache, refblock);
qcow2_cache_put(bs, s->refcount_block_cache, &refblock);
if (cluster_index < s->free_cluster_index) {
s->free_cluster_index = cluster_index;
}
refblock = qcow2_cache_is_table_offset(bs, s->refcount_block_cache,
discard_block_offs);
if (refblock) {
/* discard refblock from the cache if refblock is cached */
qcow2_cache_discard(bs, s->refcount_block_cache, refblock);
}
update_refcount_discard(bs, discard_block_offs, s->cluster_size);
return 0;
}
int qcow2_shrink_reftable(BlockDriverState *bs)
{
BDRVQcow2State *s = bs->opaque;
uint64_t *reftable_tmp =
g_malloc(s->refcount_table_size * sizeof(uint64_t));
int i, ret;
for (i = 0; i < s->refcount_table_size; i++) {
int64_t refblock_offs = s->refcount_table[i] & REFT_OFFSET_MASK;
void *refblock;
bool unused_block;
if (refblock_offs == 0) {
reftable_tmp[i] = 0;
continue;
}
ret = qcow2_cache_get(bs, s->refcount_block_cache, refblock_offs,
&refblock);
if (ret < 0) {
goto out;
}
/* the refblock has own reference */
if (i == offset_to_reftable_index(s, refblock_offs)) {
uint64_t block_index = (refblock_offs >> s->cluster_bits) &
(s->refcount_block_size - 1);
uint64_t refcount = s->get_refcount(refblock, block_index);
s->set_refcount(refblock, block_index, 0);
unused_block = buffer_is_zero(refblock, s->cluster_size);
s->set_refcount(refblock, block_index, refcount);
} else {
unused_block = buffer_is_zero(refblock, s->cluster_size);
}
qcow2_cache_put(bs, s->refcount_block_cache, &refblock);
reftable_tmp[i] = unused_block ? 0 : cpu_to_be64(s->refcount_table[i]);
}
ret = bdrv_pwrite_sync(bs->file, s->refcount_table_offset, reftable_tmp,
s->refcount_table_size * sizeof(uint64_t));
/*
* If the write in the reftable failed the image may contain a partially
* overwritten reftable. In this case it would be better to clear the
* reftable in memory to avoid possible image corruption.
*/
for (i = 0; i < s->refcount_table_size; i++) {
if (s->refcount_table[i] && !reftable_tmp[i]) {
if (ret == 0) {
ret = qcow2_discard_refcount_block(bs, s->refcount_table[i] &
REFT_OFFSET_MASK);
}
s->refcount_table[i] = 0;
}
}
if (!s->cache_discards) {
qcow2_process_discards(bs, ret);
}
out:
g_free(reftable_tmp);
return ret;
}

View File

@ -3104,18 +3104,43 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset,
}
old_length = bs->total_sectors * 512;
/* shrinking is currently not supported */
if (offset < old_length) {
error_setg(errp, "qcow2 doesn't support shrinking images yet");
return -ENOTSUP;
}
new_l1_size = size_to_l1(s, offset);
ret = qcow2_grow_l1_table(bs, new_l1_size, true);
if (ret < 0) {
error_setg_errno(errp, -ret, "Failed to grow the L1 table");
return ret;
if (offset < old_length) {
if (prealloc != PREALLOC_MODE_OFF) {
error_setg(errp,
"Preallocation can't be used for shrinking an image");
return -EINVAL;
}
ret = qcow2_cluster_discard(bs, ROUND_UP(offset, s->cluster_size),
old_length - ROUND_UP(offset,
s->cluster_size),
QCOW2_DISCARD_ALWAYS, true);
if (ret < 0) {
error_setg_errno(errp, -ret, "Failed to discard cropped clusters");
return ret;
}
ret = qcow2_shrink_l1_table(bs, new_l1_size);
if (ret < 0) {
error_setg_errno(errp, -ret,
"Failed to reduce the number of L2 tables");
return ret;
}
ret = qcow2_shrink_reftable(bs);
if (ret < 0) {
error_setg_errno(errp, -ret,
"Failed to discard unused refblocks");
return ret;
}
} else {
ret = qcow2_grow_l1_table(bs, new_l1_size, true);
if (ret < 0) {
error_setg_errno(errp, -ret, "Failed to grow the L1 table");
return ret;
}
}
switch (prealloc) {

View File

@ -521,6 +521,18 @@ static inline uint64_t refcount_diff(uint64_t r1, uint64_t r2)
return r1 > r2 ? r1 - r2 : r2 - r1;
}
static inline
uint32_t offset_to_reftable_index(BDRVQcow2State *s, uint64_t offset)
{
return offset >> (s->refcount_block_bits + s->cluster_bits);
}
static inline uint64_t get_refblock_offset(BDRVQcow2State *s, uint64_t offset)
{
uint32_t index = offset_to_reftable_index(s, offset);
return s->refcount_table[index] & REFT_OFFSET_MASK;
}
/* qcow2.c functions */
int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
int64_t sector_num, int nb_sectors);
@ -584,10 +596,12 @@ int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
BlockDriverAmendStatusCB *status_cb,
void *cb_opaque, Error **errp);
int qcow2_shrink_reftable(BlockDriverState *bs);
/* qcow2-cluster.c functions */
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
bool exact_size);
int qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size);
int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index);
int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
@ -649,6 +663,9 @@ int qcow2_cache_get(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
int qcow2_cache_get_empty(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
void **table);
void qcow2_cache_put(BlockDriverState *bs, Qcow2Cache *c, void **table);
void *qcow2_cache_is_table_offset(BlockDriverState *bs, Qcow2Cache *c,
uint64_t offset);
void qcow2_cache_discard(BlockDriverState *bs, Qcow2Cache *c, void *table);
/* qcow2-bitmap.c functions */
int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,

View File

@ -157,6 +157,7 @@ static void replication_close(BlockDriverState *bs)
static void replication_child_perm(BlockDriverState *bs, BdrvChild *c,
const BdrvChildRole *role,
BlockReopenQueue *reopen_queue,
uint64_t perm, uint64_t shared,
uint64_t *nperm, uint64_t *nshared)
{

View File

@ -403,17 +403,19 @@ static void coroutine_fn throttle_group_restart_queue_entry(void *opaque)
schedule_next_request(tgm, is_write);
qemu_mutex_unlock(&tg->lock);
}
g_free(data);
}
static void throttle_group_restart_queue(ThrottleGroupMember *tgm, bool is_write)
{
Coroutine *co;
RestartData rd = {
.tgm = tgm,
.is_write = is_write
};
RestartData *rd = g_new0(RestartData, 1);
co = qemu_coroutine_create(throttle_group_restart_queue_entry, &rd);
rd->tgm = tgm;
rd->is_write = is_write;
co = qemu_coroutine_create(throttle_group_restart_queue_entry, rd);
aio_co_enter(tgm->aio_context, co);
}

View File

@ -57,15 +57,6 @@
static void checkpoint(void);
#ifdef __MINGW32__
void nonono(const char* file, int line, const char* msg) {
fprintf(stderr, "Nonono! %s:%d %s\n", file, line, msg);
exit(-5);
}
#undef assert
#define assert(a) do {if (!(a)) nonono(__FILE__, __LINE__, #a);}while(0)
#endif
#else
#define DLOG(a)
@ -3211,6 +3202,7 @@ err:
static void vvfat_child_perm(BlockDriverState *bs, BdrvChild *c,
const BdrvChildRole *role,
BlockReopenQueue *reopen_queue,
uint64_t perm, uint64_t shared,
uint64_t *nperm, uint64_t *nshared)
{
@ -3270,24 +3262,11 @@ static void bdrv_vvfat_init(void)
block_init(bdrv_vvfat_init);
#ifdef DEBUG
static void checkpoint(void) {
static void checkpoint(void)
{
assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2);
check1(vvv);
check2(vvv);
assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY));
#if 0
if (((direntry_t*)vvv->directory.pointer)[1].attributes != 0xf)
fprintf(stderr, "Nonono!\n");
mapping_t* mapping;
direntry_t* direntry;
assert(vvv->mapping.size >= vvv->mapping.item_size * vvv->mapping.next);
assert(vvv->directory.size >= vvv->directory.item_size * vvv->directory.next);
if (vvv->mapping.next<47)
return;
assert((mapping = array_get(&(vvv->mapping), 47)));
assert(mapping->dir_index < vvv->directory.next);
direntry = array_get(&(vvv->directory), mapping->dir_index);
assert(!memcmp(direntry->name, "USB H ", 11) || direntry->name[0]==0);
#endif
}
#endif

View File

@ -0,0 +1,804 @@
@c man begin SYNOPSIS
QEMU block driver reference manual
@c man end
@c man begin DESCRIPTION
@node disk_images_formats
@subsection Disk image file formats
QEMU supports many image file formats that can be used with VMs as well as with
any of the tools (like @code{qemu-img}). This includes the preferred formats
raw and qcow2 as well as formats that are supported for compatibility with
older QEMU versions or other hypervisors.
Depending on the image format, different options can be passed to
@code{qemu-img create} and @code{qemu-img convert} using the @code{-o} option.
This section describes each format and the options that are supported for it.
@table @option
@item raw
Raw disk image format. This format has the advantage of
being simple and easily exportable to all other emulators. If your
file system supports @emph{holes} (for example in ext2 or ext3 on
Linux or NTFS on Windows), then only the written sectors will reserve
space. Use @code{qemu-img info} to know the real size used by the
image or @code{ls -ls} on Unix/Linux.
Supported options:
@table @code
@item preallocation
Preallocation mode (allowed values: @code{off}, @code{falloc}, @code{full}).
@code{falloc} mode preallocates space for image by calling posix_fallocate().
@code{full} mode preallocates space for image by writing zeros to underlying
storage.
@end table
@item qcow2
QEMU image format, the most versatile format. Use it to have smaller
images (useful if your filesystem does not supports holes, for example
on Windows), zlib based compression and support of multiple VM
snapshots.
Supported options:
@table @code
@item compat
Determines the qcow2 version to use. @code{compat=0.10} uses the
traditional image format that can be read by any QEMU since 0.10.
@code{compat=1.1} enables image format extensions that only QEMU 1.1 and
newer understand (this is the default). Amongst others, this includes
zero clusters, which allow efficient copy-on-read for sparse images.
@item backing_file
File name of a base image (see @option{create} subcommand)
@item backing_fmt
Image format of the base image
@item encryption
This option is deprecated and equivalent to @code{encrypt.format=aes}
@item encrypt.format
If this is set to @code{luks}, it requests that the qcow2 payload (not
qcow2 header) be encrypted using the LUKS format. The passphrase to
use to unlock the LUKS key slot is given by the @code{encrypt.key-secret}
parameter. LUKS encryption parameters can be tuned with the other
@code{encrypt.*} parameters.
If this is set to @code{aes}, the image is encrypted with 128-bit AES-CBC.
The encryption key is given by the @code{encrypt.key-secret} parameter.
This encryption format is considered to be flawed by modern cryptography
standards, suffering from a number of design problems:
@itemize @minus
@item The AES-CBC cipher is used with predictable initialization vectors based
on the sector number. This makes it vulnerable to chosen plaintext attacks
which can reveal the existence of encrypted data.
@item The user passphrase is directly used as the encryption key. A poorly
chosen or short passphrase will compromise the security of the encryption.
@item In the event of the passphrase being compromised there is no way to
change the passphrase to protect data in any qcow images. The files must
be cloned, using a different encryption passphrase in the new file. The
original file must then be securely erased using a program like shred,
though even this is ineffective with many modern storage technologies.
@end itemize
The use of this is no longer supported in system emulators. Support only
remains in the command line utilities, for the purposes of data liberation
and interoperability with old versions of QEMU. The @code{luks} format
should be used instead.
@item encrypt.key-secret
Provides the ID of a @code{secret} object that contains the passphrase
(@code{encrypt.format=luks}) or encryption key (@code{encrypt.format=aes}).
@item encrypt.cipher-alg
Name of the cipher algorithm and key length. Currently defaults
to @code{aes-256}. Only used when @code{encrypt.format=luks}.
@item encrypt.cipher-mode
Name of the encryption mode to use. Currently defaults to @code{xts}.
Only used when @code{encrypt.format=luks}.
@item encrypt.ivgen-alg
Name of the initialization vector generator algorithm. Currently defaults
to @code{plain64}. Only used when @code{encrypt.format=luks}.
@item encrypt.ivgen-hash-alg
Name of the hash algorithm to use with the initialization vector generator
(if required). Defaults to @code{sha256}. Only used when @code{encrypt.format=luks}.
@item encrypt.hash-alg
Name of the hash algorithm to use for PBKDF algorithm
Defaults to @code{sha256}. Only used when @code{encrypt.format=luks}.
@item encrypt.iter-time
Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
Defaults to @code{2000}. Only used when @code{encrypt.format=luks}.
@item cluster_size
Changes the qcow2 cluster size (must be between 512 and 2M). Smaller cluster
sizes can improve the image file size whereas larger cluster sizes generally
provide better performance.
@item preallocation
Preallocation mode (allowed values: @code{off}, @code{metadata}, @code{falloc},
@code{full}). An image with preallocated metadata is initially larger but can
improve performance when the image needs to grow. @code{falloc} and @code{full}
preallocations are like the same options of @code{raw} format, but sets up
metadata also.
@item lazy_refcounts
If this option is set to @code{on}, reference count updates are postponed with
the goal of avoiding metadata I/O and improving performance. This is
particularly interesting with @option{cache=writethrough} which doesn't batch
metadata updates. The tradeoff is that after a host crash, the reference count
tables must be rebuilt, i.e. on the next open an (automatic) @code{qemu-img
check -r all} is required, which may take some time.
This option can only be enabled if @code{compat=1.1} is specified.
@item nocow
If this option is set to @code{on}, it will turn off COW of the file. It's only
valid on btrfs, no effect on other file systems.
Btrfs has low performance when hosting a VM image file, even more when the guest
on the VM also using btrfs as file system. Turning off COW is a way to mitigate
this bad performance. Generally there are two ways to turn off COW on btrfs:
a) Disable it by mounting with nodatacow, then all newly created files will be
NOCOW. b) For an empty file, add the NOCOW file attribute. That's what this option
does.
Note: this option is only valid to new or empty files. If there is an existing
file which is COW and has data blocks already, it couldn't be changed to NOCOW
by setting @code{nocow=on}. One can issue @code{lsattr filename} to check if
the NOCOW flag is set or not (Capital 'C' is NOCOW flag).
@end table
@item qed
Old QEMU image format with support for backing files and compact image files
(when your filesystem or transport medium does not support holes).
When converting QED images to qcow2, you might want to consider using the
@code{lazy_refcounts=on} option to get a more QED-like behaviour.
Supported options:
@table @code
@item backing_file
File name of a base image (see @option{create} subcommand).
@item backing_fmt
Image file format of backing file (optional). Useful if the format cannot be
autodetected because it has no header, like some vhd/vpc files.
@item cluster_size
Changes the cluster size (must be power-of-2 between 4K and 64K). Smaller
cluster sizes can improve the image file size whereas larger cluster sizes
generally provide better performance.
@item table_size
Changes the number of clusters per L1/L2 table (must be power-of-2 between 1
and 16). There is normally no need to change this value but this option can be
used for performance benchmarking.
@end table
@item qcow
Old QEMU image format with support for backing files, compact image files,
encryption and compression.
Supported options:
@table @code
@item backing_file
File name of a base image (see @option{create} subcommand)
@item encryption
This option is deprecated and equivalent to @code{encrypt.format=aes}
@item encrypt.format
If this is set to @code{aes}, the image is encrypted with 128-bit AES-CBC.
The encryption key is given by the @code{encrypt.key-secret} parameter.
This encryption format is considered to be flawed by modern cryptography
standards, suffering from a number of design problems enumerated previously
against the @code{qcow2} image format.
The use of this is no longer supported in system emulators. Support only
remains in the command line utilities, for the purposes of data liberation
and interoperability with old versions of QEMU.
Users requiring native encryption should use the @code{qcow2} format
instead with @code{encrypt.format=luks}.
@item encrypt.key-secret
Provides the ID of a @code{secret} object that contains the encryption
key (@code{encrypt.format=aes}).
@end table
@item luks
LUKS v1 encryption format, compatible with Linux dm-crypt/cryptsetup
Supported options:
@table @code
@item key-secret
Provides the ID of a @code{secret} object that contains the passphrase.
@item cipher-alg
Name of the cipher algorithm and key length. Currently defaults
to @code{aes-256}.
@item cipher-mode
Name of the encryption mode to use. Currently defaults to @code{xts}.
@item ivgen-alg
Name of the initialization vector generator algorithm. Currently defaults
to @code{plain64}.
@item ivgen-hash-alg
Name of the hash algorithm to use with the initialization vector generator
(if required). Defaults to @code{sha256}.
@item hash-alg
Name of the hash algorithm to use for PBKDF algorithm
Defaults to @code{sha256}.
@item iter-time
Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
Defaults to @code{2000}.
@end table
@item vdi
VirtualBox 1.1 compatible image format.
Supported options:
@table @code
@item static
If this option is set to @code{on}, the image is created with metadata
preallocation.
@end table
@item vmdk
VMware 3 and 4 compatible image format.
Supported options:
@table @code
@item backing_file
File name of a base image (see @option{create} subcommand).
@item compat6
Create a VMDK version 6 image (instead of version 4)
@item hwversion
Specify vmdk virtual hardware version. Compat6 flag cannot be enabled
if hwversion is specified.
@item subformat
Specifies which VMDK subformat to use. Valid options are
@code{monolithicSparse} (default),
@code{monolithicFlat},
@code{twoGbMaxExtentSparse},
@code{twoGbMaxExtentFlat} and
@code{streamOptimized}.
@end table
@item vpc
VirtualPC compatible image format (VHD).
Supported options:
@table @code
@item subformat
Specifies which VHD subformat to use. Valid options are
@code{dynamic} (default) and @code{fixed}.
@end table
@item VHDX
Hyper-V compatible image format (VHDX).
Supported options:
@table @code
@item subformat
Specifies which VHDX subformat to use. Valid options are
@code{dynamic} (default) and @code{fixed}.
@item block_state_zero
Force use of payload blocks of type 'ZERO'. Can be set to @code{on} (default)
or @code{off}. When set to @code{off}, new blocks will be created as
@code{PAYLOAD_BLOCK_NOT_PRESENT}, which means parsers are free to return
arbitrary data for those blocks. Do not set to @code{off} when using
@code{qemu-img convert} with @code{subformat=dynamic}.
@item block_size
Block size; min 1 MB, max 256 MB. 0 means auto-calculate based on image size.
@item log_size
Log size; min 1 MB.
@end table
@end table
@subsubsection Read-only formats
More disk image file formats are supported in a read-only mode.
@table @option
@item bochs
Bochs images of @code{growing} type.
@item cloop
Linux Compressed Loop image, useful only to reuse directly compressed
CD-ROM images present for example in the Knoppix CD-ROMs.
@item dmg
Apple disk image.
@item parallels
Parallels disk image format.
@end table
@node host_drives
@subsection Using host drives
In addition to disk image files, QEMU can directly access host
devices. We describe here the usage for QEMU version >= 0.8.3.
@subsubsection Linux
On Linux, you can directly use the host device filename instead of a
disk image filename provided you have enough privileges to access
it. For example, use @file{/dev/cdrom} to access to the CDROM.
@table @code
@item CD
You can specify a CDROM device even if no CDROM is loaded. QEMU has
specific code to detect CDROM insertion or removal. CDROM ejection by
the guest OS is supported. Currently only data CDs are supported.
@item Floppy
You can specify a floppy device even if no floppy is loaded. Floppy
removal is currently not detected accurately (if you change floppy
without doing floppy access while the floppy is not loaded, the guest
OS will think that the same floppy is loaded).
Use of the host's floppy device is deprecated, and support for it will
be removed in a future release.
@item Hard disks
Hard disks can be used. Normally you must specify the whole disk
(@file{/dev/hdb} instead of @file{/dev/hdb1}) so that the guest OS can
see it as a partitioned disk. WARNING: unless you know what you do, it
is better to only make READ-ONLY accesses to the hard disk otherwise
you may corrupt your host data (use the @option{-snapshot} command
line option or modify the device permissions accordingly).
@end table
@subsubsection Windows
@table @code
@item CD
The preferred syntax is the drive letter (e.g. @file{d:}). The
alternate syntax @file{\\.\d:} is supported. @file{/dev/cdrom} is
supported as an alias to the first CDROM drive.
Currently there is no specific code to handle removable media, so it
is better to use the @code{change} or @code{eject} monitor commands to
change or eject media.
@item Hard disks
Hard disks can be used with the syntax: @file{\\.\PhysicalDrive@var{N}}
where @var{N} is the drive number (0 is the first hard disk).
WARNING: unless you know what you do, it is better to only make
READ-ONLY accesses to the hard disk otherwise you may corrupt your
host data (use the @option{-snapshot} command line so that the
modifications are written in a temporary file).
@end table
@subsubsection Mac OS X
@file{/dev/cdrom} is an alias to the first CDROM.
Currently there is no specific code to handle removable media, so it
is better to use the @code{change} or @code{eject} monitor commands to
change or eject media.
@node disk_images_fat_images
@subsection Virtual FAT disk images
QEMU can automatically create a virtual FAT disk image from a
directory tree. In order to use it, just type:
@example
qemu-system-i386 linux.img -hdb fat:/my_directory
@end example
Then you access access to all the files in the @file{/my_directory}
directory without having to copy them in a disk image or to export
them via SAMBA or NFS. The default access is @emph{read-only}.
Floppies can be emulated with the @code{:floppy:} option:
@example
qemu-system-i386 linux.img -fda fat:floppy:/my_directory
@end example
A read/write support is available for testing (beta stage) with the
@code{:rw:} option:
@example
qemu-system-i386 linux.img -fda fat:floppy:rw:/my_directory
@end example
What you should @emph{never} do:
@itemize
@item use non-ASCII filenames ;
@item use "-snapshot" together with ":rw:" ;
@item expect it to work when loadvm'ing ;
@item write to the FAT directory on the host system while accessing it with the guest system.
@end itemize
@node disk_images_nbd
@subsection NBD access
QEMU can access directly to block device exported using the Network Block Device
protocol.
@example
qemu-system-i386 linux.img -hdb nbd://my_nbd_server.mydomain.org:1024/
@end example
If the NBD server is located on the same host, you can use an unix socket instead
of an inet socket:
@example
qemu-system-i386 linux.img -hdb nbd+unix://?socket=/tmp/my_socket
@end example
In this case, the block device must be exported using qemu-nbd:
@example
qemu-nbd --socket=/tmp/my_socket my_disk.qcow2
@end example
The use of qemu-nbd allows sharing of a disk between several guests:
@example
qemu-nbd --socket=/tmp/my_socket --share=2 my_disk.qcow2
@end example
@noindent
and then you can use it with two guests:
@example
qemu-system-i386 linux1.img -hdb nbd+unix://?socket=/tmp/my_socket
qemu-system-i386 linux2.img -hdb nbd+unix://?socket=/tmp/my_socket
@end example
If the nbd-server uses named exports (supported since NBD 2.9.18, or with QEMU's
own embedded NBD server), you must specify an export name in the URI:
@example
qemu-system-i386 -cdrom nbd://localhost/debian-500-ppc-netinst
qemu-system-i386 -cdrom nbd://localhost/openSUSE-11.1-ppc-netinst
@end example
The URI syntax for NBD is supported since QEMU 1.3. An alternative syntax is
also available. Here are some example of the older syntax:
@example
qemu-system-i386 linux.img -hdb nbd:my_nbd_server.mydomain.org:1024
qemu-system-i386 linux2.img -hdb nbd:unix:/tmp/my_socket
qemu-system-i386 -cdrom nbd:localhost:10809:exportname=debian-500-ppc-netinst
@end example
@node disk_images_sheepdog
@subsection Sheepdog disk images
Sheepdog is a distributed storage system for QEMU. It provides highly
available block level storage volumes that can be attached to
QEMU-based virtual machines.
You can create a Sheepdog disk image with the command:
@example
qemu-img create sheepdog:///@var{image} @var{size}
@end example
where @var{image} is the Sheepdog image name and @var{size} is its
size.
To import the existing @var{filename} to Sheepdog, you can use a
convert command.
@example
qemu-img convert @var{filename} sheepdog:///@var{image}
@end example
You can boot from the Sheepdog disk image with the command:
@example
qemu-system-i386 sheepdog:///@var{image}
@end example
You can also create a snapshot of the Sheepdog image like qcow2.
@example
qemu-img snapshot -c @var{tag} sheepdog:///@var{image}
@end example
where @var{tag} is a tag name of the newly created snapshot.
To boot from the Sheepdog snapshot, specify the tag name of the
snapshot.
@example
qemu-system-i386 sheepdog:///@var{image}#@var{tag}
@end example
You can create a cloned image from the existing snapshot.
@example
qemu-img create -b sheepdog:///@var{base}#@var{tag} sheepdog:///@var{image}
@end example
where @var{base} is a image name of the source snapshot and @var{tag}
is its tag name.
You can use an unix socket instead of an inet socket:
@example
qemu-system-i386 sheepdog+unix:///@var{image}?socket=@var{path}
@end example
If the Sheepdog daemon doesn't run on the local host, you need to
specify one of the Sheepdog servers to connect to.
@example
qemu-img create sheepdog://@var{hostname}:@var{port}/@var{image} @var{size}
qemu-system-i386 sheepdog://@var{hostname}:@var{port}/@var{image}
@end example
@node disk_images_iscsi
@subsection iSCSI LUNs
iSCSI is a popular protocol used to access SCSI devices across a computer
network.
There are two different ways iSCSI devices can be used by QEMU.
The first method is to mount the iSCSI LUN on the host, and make it appear as
any other ordinary SCSI device on the host and then to access this device as a
/dev/sd device from QEMU. How to do this differs between host OSes.
The second method involves using the iSCSI initiator that is built into
QEMU. This provides a mechanism that works the same way regardless of which
host OS you are running QEMU on. This section will describe this second method
of using iSCSI together with QEMU.
In QEMU, iSCSI devices are described using special iSCSI URLs
@example
URL syntax:
iscsi://[<username>[%<password>]@@]<host>[:<port>]/<target-iqn-name>/<lun>
@end example
Username and password are optional and only used if your target is set up
using CHAP authentication for access control.
Alternatively the username and password can also be set via environment
variables to have these not show up in the process list
@example
export LIBISCSI_CHAP_USERNAME=<username>
export LIBISCSI_CHAP_PASSWORD=<password>
iscsi://<host>/<target-iqn-name>/<lun>
@end example
Various session related parameters can be set via special options, either
in a configuration file provided via '-readconfig' or directly on the
command line.
If the initiator-name is not specified qemu will use a default name
of 'iqn.2008-11.org.linux-kvm[:<uuid>'] where <uuid> is the UUID of the
virtual machine. If the UUID is not specified qemu will use
'iqn.2008-11.org.linux-kvm[:<name>'] where <name> is the name of the
virtual machine.
@example
Setting a specific initiator name to use when logging in to the target
-iscsi initiator-name=iqn.qemu.test:my-initiator
@end example
@example
Controlling which type of header digest to negotiate with the target
-iscsi header-digest=CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
@end example
These can also be set via a configuration file
@example
[iscsi]
user = "CHAP username"
password = "CHAP password"
initiator-name = "iqn.qemu.test:my-initiator"
# header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
header-digest = "CRC32C"
@end example
Setting the target name allows different options for different targets
@example
[iscsi "iqn.target.name"]
user = "CHAP username"
password = "CHAP password"
initiator-name = "iqn.qemu.test:my-initiator"
# header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
header-digest = "CRC32C"
@end example
Howto use a configuration file to set iSCSI configuration options:
@example
cat >iscsi.conf <<EOF
[iscsi]
user = "me"
password = "my password"
initiator-name = "iqn.qemu.test:my-initiator"
header-digest = "CRC32C"
EOF
qemu-system-i386 -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \
-readconfig iscsi.conf
@end example
Howto set up a simple iSCSI target on loopback and accessing it via QEMU:
@example
This example shows how to set up an iSCSI target with one CDROM and one DISK
using the Linux STGT software target. This target is available on Red Hat based
systems as the package 'scsi-target-utils'.
tgtd --iscsi portal=127.0.0.1:3260
tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.qemu.test
tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 1 \
-b /IMAGES/disk.img --device-type=disk
tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 2 \
-b /IMAGES/cd.iso --device-type=cd
tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL
qemu-system-i386 -iscsi initiator-name=iqn.qemu.test:my-initiator \
-boot d -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \
-cdrom iscsi://127.0.0.1/iqn.qemu.test/2
@end example
@node disk_images_gluster
@subsection GlusterFS disk images
GlusterFS is a user space distributed file system.
You can boot from the GlusterFS disk image with the command:
@example
URI:
qemu-system-x86_64 -drive file=gluster[+@var{type}]://[@var{host}[:@var{port}]]/@var{volume}/@var{path}
[?socket=...][,file.debug=9][,file.logfile=...]
JSON:
qemu-system-x86_64 'json:@{"driver":"qcow2",
"file":@{"driver":"gluster",
"volume":"testvol","path":"a.img","debug":9,"logfile":"...",
"server":[@{"type":"tcp","host":"...","port":"..."@},
@{"type":"unix","socket":"..."@}]@}@}'
@end example
@var{gluster} is the protocol.
@var{type} specifies the transport type used to connect to gluster
management daemon (glusterd). Valid transport types are
tcp and unix. In the URI form, if a transport type isn't specified,
then tcp type is assumed.
@var{host} specifies the server where the volume file specification for
the given volume resides. This can be either a hostname or an ipv4 address.
If transport type is unix, then @var{host} field should not be specified.
Instead @var{socket} field needs to be populated with the path to unix domain
socket.
@var{port} is the port number on which glusterd is listening. This is optional
and if not specified, it defaults to port 24007. If the transport type is unix,
then @var{port} should not be specified.
@var{volume} is the name of the gluster volume which contains the disk image.
@var{path} is the path to the actual disk image that resides on gluster volume.
@var{debug} is the logging level of the gluster protocol driver. Debug levels
are 0-9, with 9 being the most verbose, and 0 representing no debugging output.
The default level is 4. The current logging levels defined in the gluster source
are 0 - None, 1 - Emergency, 2 - Alert, 3 - Critical, 4 - Error, 5 - Warning,
6 - Notice, 7 - Info, 8 - Debug, 9 - Trace
@var{logfile} is a commandline option to mention log file path which helps in
logging to the specified file and also help in persisting the gfapi logs. The
default is stderr.
You can create a GlusterFS disk image with the command:
@example
qemu-img create gluster://@var{host}/@var{volume}/@var{path} @var{size}
@end example
Examples
@example
qemu-system-x86_64 -drive file=gluster://1.2.3.4/testvol/a.img
qemu-system-x86_64 -drive file=gluster+tcp://1.2.3.4/testvol/a.img
qemu-system-x86_64 -drive file=gluster+tcp://1.2.3.4:24007/testvol/dir/a.img
qemu-system-x86_64 -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]/testvol/dir/a.img
qemu-system-x86_64 -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]:24007/testvol/dir/a.img
qemu-system-x86_64 -drive file=gluster+tcp://server.domain.com:24007/testvol/dir/a.img
qemu-system-x86_64 -drive file=gluster+unix:///testvol/dir/a.img?socket=/tmp/glusterd.socket
qemu-system-x86_64 -drive file=gluster+rdma://1.2.3.4:24007/testvol/a.img
qemu-system-x86_64 -drive file=gluster://1.2.3.4/testvol/a.img,file.debug=9,file.logfile=/var/log/qemu-gluster.log
qemu-system-x86_64 'json:@{"driver":"qcow2",
"file":@{"driver":"gluster",
"volume":"testvol","path":"a.img",
"debug":9,"logfile":"/var/log/qemu-gluster.log",
"server":[@{"type":"tcp","host":"1.2.3.4","port":24007@},
@{"type":"unix","socket":"/var/run/glusterd.socket"@}]@}@}'
qemu-system-x86_64 -drive driver=qcow2,file.driver=gluster,file.volume=testvol,file.path=/path/a.img,
file.debug=9,file.logfile=/var/log/qemu-gluster.log,
file.server.0.type=tcp,file.server.0.host=1.2.3.4,file.server.0.port=24007,
file.server.1.type=unix,file.server.1.socket=/var/run/glusterd.socket
@end example
@node disk_images_ssh
@subsection Secure Shell (ssh) disk images
You can access disk images located on a remote ssh server
by using the ssh protocol:
@example
qemu-system-x86_64 -drive file=ssh://[@var{user}@@]@var{server}[:@var{port}]/@var{path}[?host_key_check=@var{host_key_check}]
@end example
Alternative syntax using properties:
@example
qemu-system-x86_64 -drive file.driver=ssh[,file.user=@var{user}],file.host=@var{server}[,file.port=@var{port}],file.path=@var{path}[,file.host_key_check=@var{host_key_check}]
@end example
@var{ssh} is the protocol.
@var{user} is the remote user. If not specified, then the local
username is tried.
@var{server} specifies the remote ssh server. Any ssh server can be
used, but it must implement the sftp-server protocol. Most Unix/Linux
systems should work without requiring any extra configuration.
@var{port} is the port number on which sshd is listening. By default
the standard ssh port (22) is used.
@var{path} is the path to the disk image.
The optional @var{host_key_check} parameter controls how the remote
host's key is checked. The default is @code{yes} which means to use
the local @file{.ssh/known_hosts} file. Setting this to @code{no}
turns off known-hosts checking. Or you can check that the host key
matches a specific fingerprint:
@code{host_key_check=md5:78:45:8e:14:57:4f:d5:45:83:0a:0e:f3:49:82:c9:c8}
(@code{sha1:} can also be used as a prefix, but note that OpenSSH
tools only use MD5 to print fingerprints).
Currently authentication must be done using ssh-agent. Other
authentication methods may be supported in future.
Note: Many ssh servers do not support an @code{fsync}-style operation.
The ssh driver cannot guarantee that disk flush requests are
obeyed, and this causes a risk of disk corruption if the remote
server or network goes down during writes. The driver will
print a warning when @code{fsync} is not supported:
warning: ssh server @code{ssh.example.com:22} does not support fsync
With sufficiently new versions of libssh2 and OpenSSH, @code{fsync} is
supported.
@c man end
@ignore
@setfilename qemu-block-drivers
@settitle QEMU block drivers reference
@c man begin SEEALSO
The HTML documentation of QEMU for more precise information and Linux
user mode emulator invocation.
@c man end
@c man begin AUTHOR
Fabrice Bellard and the QEMU Project developers
@c man end
@end ignore

View File

@ -166,6 +166,7 @@ typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;
typedef struct BDRVReopenState {
BlockDriverState *bs;
int flags;
uint64_t perm, shared_perm;
QDict *options;
QDict *explicit_options;
void *opaque;
@ -435,7 +436,6 @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
int64_t offset, int64_t bytes, int64_t *pnum);
bool bdrv_is_read_only(BlockDriverState *bs);
bool bdrv_is_writable(BlockDriverState *bs);
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
bool ignore_allow_rdw, Error **errp);
int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);

View File

@ -411,9 +411,14 @@ struct BlockDriver {
*
* If @c is NULL, return the permissions for attaching a new child for the
* given @role.
*
* If @reopen_queue is non-NULL, don't return the currently needed
* permissions, but those that will be needed after applying the
* @reopen_queue.
*/
void (*bdrv_child_perm)(BlockDriverState *bs, BdrvChild *c,
const BdrvChildRole *role,
BlockReopenQueue *reopen_queue,
uint64_t parent_perm, uint64_t parent_shared,
uint64_t *nperm, uint64_t *nshared);
@ -983,6 +988,7 @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
* all children */
void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
const BdrvChildRole *role,
BlockReopenQueue *reopen_queue,
uint64_t perm, uint64_t shared,
uint64_t *nperm, uint64_t *nshared);
@ -992,6 +998,7 @@ void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
* CONSISTENT_READ and doesn't share WRITE. */
void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
const BdrvChildRole *role,
BlockReopenQueue *reopen_queue,
uint64_t perm, uint64_t shared,
uint64_t *nperm, uint64_t *nshared);

View File

@ -2533,6 +2533,11 @@
#
# Trigger events supported by blkdebug.
#
# @l1_shrink_write_table: write zeros to the l1 table to shrink image.
# (since 2.11)
#
# @l1_shrink_free_l2_clusters: discard the l2 tables. (since 2.11)
#
# Since: 2.9
##
{ 'enum': 'BlkdebugEvent', 'prefix': 'BLKDBG',
@ -2549,7 +2554,8 @@
'cluster_alloc_bytes', 'cluster_free', 'flush_to_os',
'flush_to_disk', 'pwritev_rmw_head', 'pwritev_rmw_after_head',
'pwritev_rmw_tail', 'pwritev_rmw_after_tail', 'pwritev',
'pwritev_zero', 'pwritev_done', 'empty_image_prepare' ] }
'pwritev_zero', 'pwritev_done', 'empty_image_prepare',
'l1_shrink_write_table', 'l1_shrink_free_l2_clusters' ] }
##
# @BlkdebugInjectErrorOptions:

View File

@ -490,786 +490,7 @@ state is not saved or restored properly (in particular USB).
@include qemu-nbd.texi
@node disk_images_formats
@subsection Disk image file formats
QEMU supports many image file formats that can be used with VMs as well as with
any of the tools (like @code{qemu-img}). This includes the preferred formats
raw and qcow2 as well as formats that are supported for compatibility with
older QEMU versions or other hypervisors.
Depending on the image format, different options can be passed to
@code{qemu-img create} and @code{qemu-img convert} using the @code{-o} option.
This section describes each format and the options that are supported for it.
@table @option
@item raw
Raw disk image format. This format has the advantage of
being simple and easily exportable to all other emulators. If your
file system supports @emph{holes} (for example in ext2 or ext3 on
Linux or NTFS on Windows), then only the written sectors will reserve
space. Use @code{qemu-img info} to know the real size used by the
image or @code{ls -ls} on Unix/Linux.
Supported options:
@table @code
@item preallocation
Preallocation mode (allowed values: @code{off}, @code{falloc}, @code{full}).
@code{falloc} mode preallocates space for image by calling posix_fallocate().
@code{full} mode preallocates space for image by writing zeros to underlying
storage.
@end table
@item qcow2
QEMU image format, the most versatile format. Use it to have smaller
images (useful if your filesystem does not supports holes, for example
on Windows), zlib based compression and support of multiple VM
snapshots.
Supported options:
@table @code
@item compat
Determines the qcow2 version to use. @code{compat=0.10} uses the
traditional image format that can be read by any QEMU since 0.10.
@code{compat=1.1} enables image format extensions that only QEMU 1.1 and
newer understand (this is the default). Amongst others, this includes
zero clusters, which allow efficient copy-on-read for sparse images.
@item backing_file
File name of a base image (see @option{create} subcommand)
@item backing_fmt
Image format of the base image
@item encryption
This option is deprecated and equivalent to @code{encrypt.format=aes}
@item encrypt.format
If this is set to @code{luks}, it requests that the qcow2 payload (not
qcow2 header) be encrypted using the LUKS format. The passphrase to
use to unlock the LUKS key slot is given by the @code{encrypt.key-secret}
parameter. LUKS encryption parameters can be tuned with the other
@code{encrypt.*} parameters.
If this is set to @code{aes}, the image is encrypted with 128-bit AES-CBC.
The encryption key is given by the @code{encrypt.key-secret} parameter.
This encryption format is considered to be flawed by modern cryptography
standards, suffering from a number of design problems:
@itemize @minus
@item The AES-CBC cipher is used with predictable initialization vectors based
on the sector number. This makes it vulnerable to chosen plaintext attacks
which can reveal the existence of encrypted data.
@item The user passphrase is directly used as the encryption key. A poorly
chosen or short passphrase will compromise the security of the encryption.
@item In the event of the passphrase being compromised there is no way to
change the passphrase to protect data in any qcow images. The files must
be cloned, using a different encryption passphrase in the new file. The
original file must then be securely erased using a program like shred,
though even this is ineffective with many modern storage technologies.
@end itemize
The use of this is no longer supported in system emulators. Support only
remains in the command line utilities, for the purposes of data liberation
and interoperability with old versions of QEMU. The @code{luks} format
should be used instead.
@item encrypt.key-secret
Provides the ID of a @code{secret} object that contains the passphrase
(@code{encrypt.format=luks}) or encryption key (@code{encrypt.format=aes}).
@item encrypt.cipher-alg
Name of the cipher algorithm and key length. Currently defaults
to @code{aes-256}. Only used when @code{encrypt.format=luks}.
@item encrypt.cipher-mode
Name of the encryption mode to use. Currently defaults to @code{xts}.
Only used when @code{encrypt.format=luks}.
@item encrypt.ivgen-alg
Name of the initialization vector generator algorithm. Currently defaults
to @code{plain64}. Only used when @code{encrypt.format=luks}.
@item encrypt.ivgen-hash-alg
Name of the hash algorithm to use with the initialization vector generator
(if required). Defaults to @code{sha256}. Only used when @code{encrypt.format=luks}.
@item encrypt.hash-alg
Name of the hash algorithm to use for PBKDF algorithm
Defaults to @code{sha256}. Only used when @code{encrypt.format=luks}.
@item encrypt.iter-time
Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
Defaults to @code{2000}. Only used when @code{encrypt.format=luks}.
@item cluster_size
Changes the qcow2 cluster size (must be between 512 and 2M). Smaller cluster
sizes can improve the image file size whereas larger cluster sizes generally
provide better performance.
@item preallocation
Preallocation mode (allowed values: @code{off}, @code{metadata}, @code{falloc},
@code{full}). An image with preallocated metadata is initially larger but can
improve performance when the image needs to grow. @code{falloc} and @code{full}
preallocations are like the same options of @code{raw} format, but sets up
metadata also.
@item lazy_refcounts
If this option is set to @code{on}, reference count updates are postponed with
the goal of avoiding metadata I/O and improving performance. This is
particularly interesting with @option{cache=writethrough} which doesn't batch
metadata updates. The tradeoff is that after a host crash, the reference count
tables must be rebuilt, i.e. on the next open an (automatic) @code{qemu-img
check -r all} is required, which may take some time.
This option can only be enabled if @code{compat=1.1} is specified.
@item nocow
If this option is set to @code{on}, it will turn off COW of the file. It's only
valid on btrfs, no effect on other file systems.
Btrfs has low performance when hosting a VM image file, even more when the guest
on the VM also using btrfs as file system. Turning off COW is a way to mitigate
this bad performance. Generally there are two ways to turn off COW on btrfs:
a) Disable it by mounting with nodatacow, then all newly created files will be
NOCOW. b) For an empty file, add the NOCOW file attribute. That's what this option
does.
Note: this option is only valid to new or empty files. If there is an existing
file which is COW and has data blocks already, it couldn't be changed to NOCOW
by setting @code{nocow=on}. One can issue @code{lsattr filename} to check if
the NOCOW flag is set or not (Capital 'C' is NOCOW flag).
@end table
@item qed
Old QEMU image format with support for backing files and compact image files
(when your filesystem or transport medium does not support holes).
When converting QED images to qcow2, you might want to consider using the
@code{lazy_refcounts=on} option to get a more QED-like behaviour.
Supported options:
@table @code
@item backing_file
File name of a base image (see @option{create} subcommand).
@item backing_fmt
Image file format of backing file (optional). Useful if the format cannot be
autodetected because it has no header, like some vhd/vpc files.
@item cluster_size
Changes the cluster size (must be power-of-2 between 4K and 64K). Smaller
cluster sizes can improve the image file size whereas larger cluster sizes
generally provide better performance.
@item table_size
Changes the number of clusters per L1/L2 table (must be power-of-2 between 1
and 16). There is normally no need to change this value but this option can be
used for performance benchmarking.
@end table
@item qcow
Old QEMU image format with support for backing files, compact image files,
encryption and compression.
Supported options:
@table @code
@item backing_file
File name of a base image (see @option{create} subcommand)
@item encryption
This option is deprecated and equivalent to @code{encrypt.format=aes}
@item encrypt.format
If this is set to @code{aes}, the image is encrypted with 128-bit AES-CBC.
The encryption key is given by the @code{encrypt.key-secret} parameter.
This encryption format is considered to be flawed by modern cryptography
standards, suffering from a number of design problems enumerated previously
against the @code{qcow2} image format.
The use of this is no longer supported in system emulators. Support only
remains in the command line utilities, for the purposes of data liberation
and interoperability with old versions of QEMU.
Users requiring native encryption should use the @code{qcow2} format
instead with @code{encrypt.format=luks}.
@item encrypt.key-secret
Provides the ID of a @code{secret} object that contains the encryption
key (@code{encrypt.format=aes}).
@end table
@item luks
LUKS v1 encryption format, compatible with Linux dm-crypt/cryptsetup
Supported options:
@table @code
@item key-secret
Provides the ID of a @code{secret} object that contains the passphrase.
@item cipher-alg
Name of the cipher algorithm and key length. Currently defaults
to @code{aes-256}.
@item cipher-mode
Name of the encryption mode to use. Currently defaults to @code{xts}.
@item ivgen-alg
Name of the initialization vector generator algorithm. Currently defaults
to @code{plain64}.
@item ivgen-hash-alg
Name of the hash algorithm to use with the initialization vector generator
(if required). Defaults to @code{sha256}.
@item hash-alg
Name of the hash algorithm to use for PBKDF algorithm
Defaults to @code{sha256}.
@item iter-time
Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
Defaults to @code{2000}.
@end table
@item vdi
VirtualBox 1.1 compatible image format.
Supported options:
@table @code
@item static
If this option is set to @code{on}, the image is created with metadata
preallocation.
@end table
@item vmdk
VMware 3 and 4 compatible image format.
Supported options:
@table @code
@item backing_file
File name of a base image (see @option{create} subcommand).
@item compat6
Create a VMDK version 6 image (instead of version 4)
@item hwversion
Specify vmdk virtual hardware version. Compat6 flag cannot be enabled
if hwversion is specified.
@item subformat
Specifies which VMDK subformat to use. Valid options are
@code{monolithicSparse} (default),
@code{monolithicFlat},
@code{twoGbMaxExtentSparse},
@code{twoGbMaxExtentFlat} and
@code{streamOptimized}.
@end table
@item vpc
VirtualPC compatible image format (VHD).
Supported options:
@table @code
@item subformat
Specifies which VHD subformat to use. Valid options are
@code{dynamic} (default) and @code{fixed}.
@end table
@item VHDX
Hyper-V compatible image format (VHDX).
Supported options:
@table @code
@item subformat
Specifies which VHDX subformat to use. Valid options are
@code{dynamic} (default) and @code{fixed}.
@item block_state_zero
Force use of payload blocks of type 'ZERO'. Can be set to @code{on} (default)
or @code{off}. When set to @code{off}, new blocks will be created as
@code{PAYLOAD_BLOCK_NOT_PRESENT}, which means parsers are free to return
arbitrary data for those blocks. Do not set to @code{off} when using
@code{qemu-img convert} with @code{subformat=dynamic}.
@item block_size
Block size; min 1 MB, max 256 MB. 0 means auto-calculate based on image size.
@item log_size
Log size; min 1 MB.
@end table
@end table
@subsubsection Read-only formats
More disk image file formats are supported in a read-only mode.
@table @option
@item bochs
Bochs images of @code{growing} type.
@item cloop
Linux Compressed Loop image, useful only to reuse directly compressed
CD-ROM images present for example in the Knoppix CD-ROMs.
@item dmg
Apple disk image.
@item parallels
Parallels disk image format.
@end table
@node host_drives
@subsection Using host drives
In addition to disk image files, QEMU can directly access host
devices. We describe here the usage for QEMU version >= 0.8.3.
@subsubsection Linux
On Linux, you can directly use the host device filename instead of a
disk image filename provided you have enough privileges to access
it. For example, use @file{/dev/cdrom} to access to the CDROM.
@table @code
@item CD
You can specify a CDROM device even if no CDROM is loaded. QEMU has
specific code to detect CDROM insertion or removal. CDROM ejection by
the guest OS is supported. Currently only data CDs are supported.
@item Floppy
You can specify a floppy device even if no floppy is loaded. Floppy
removal is currently not detected accurately (if you change floppy
without doing floppy access while the floppy is not loaded, the guest
OS will think that the same floppy is loaded).
Use of the host's floppy device is deprecated, and support for it will
be removed in a future release.
@item Hard disks
Hard disks can be used. Normally you must specify the whole disk
(@file{/dev/hdb} instead of @file{/dev/hdb1}) so that the guest OS can
see it as a partitioned disk. WARNING: unless you know what you do, it
is better to only make READ-ONLY accesses to the hard disk otherwise
you may corrupt your host data (use the @option{-snapshot} command
line option or modify the device permissions accordingly).
@end table
@subsubsection Windows
@table @code
@item CD
The preferred syntax is the drive letter (e.g. @file{d:}). The
alternate syntax @file{\\.\d:} is supported. @file{/dev/cdrom} is
supported as an alias to the first CDROM drive.
Currently there is no specific code to handle removable media, so it
is better to use the @code{change} or @code{eject} monitor commands to
change or eject media.
@item Hard disks
Hard disks can be used with the syntax: @file{\\.\PhysicalDrive@var{N}}
where @var{N} is the drive number (0 is the first hard disk).
WARNING: unless you know what you do, it is better to only make
READ-ONLY accesses to the hard disk otherwise you may corrupt your
host data (use the @option{-snapshot} command line so that the
modifications are written in a temporary file).
@end table
@subsubsection Mac OS X
@file{/dev/cdrom} is an alias to the first CDROM.
Currently there is no specific code to handle removable media, so it
is better to use the @code{change} or @code{eject} monitor commands to
change or eject media.
@node disk_images_fat_images
@subsection Virtual FAT disk images
QEMU can automatically create a virtual FAT disk image from a
directory tree. In order to use it, just type:
@example
qemu-system-i386 linux.img -hdb fat:/my_directory
@end example
Then you access access to all the files in the @file{/my_directory}
directory without having to copy them in a disk image or to export
them via SAMBA or NFS. The default access is @emph{read-only}.
Floppies can be emulated with the @code{:floppy:} option:
@example
qemu-system-i386 linux.img -fda fat:floppy:/my_directory
@end example
A read/write support is available for testing (beta stage) with the
@code{:rw:} option:
@example
qemu-system-i386 linux.img -fda fat:floppy:rw:/my_directory
@end example
What you should @emph{never} do:
@itemize
@item use non-ASCII filenames ;
@item use "-snapshot" together with ":rw:" ;
@item expect it to work when loadvm'ing ;
@item write to the FAT directory on the host system while accessing it with the guest system.
@end itemize
@node disk_images_nbd
@subsection NBD access
QEMU can access directly to block device exported using the Network Block Device
protocol.
@example
qemu-system-i386 linux.img -hdb nbd://my_nbd_server.mydomain.org:1024/
@end example
If the NBD server is located on the same host, you can use an unix socket instead
of an inet socket:
@example
qemu-system-i386 linux.img -hdb nbd+unix://?socket=/tmp/my_socket
@end example
In this case, the block device must be exported using qemu-nbd:
@example
qemu-nbd --socket=/tmp/my_socket my_disk.qcow2
@end example
The use of qemu-nbd allows sharing of a disk between several guests:
@example
qemu-nbd --socket=/tmp/my_socket --share=2 my_disk.qcow2
@end example
@noindent
and then you can use it with two guests:
@example
qemu-system-i386 linux1.img -hdb nbd+unix://?socket=/tmp/my_socket
qemu-system-i386 linux2.img -hdb nbd+unix://?socket=/tmp/my_socket
@end example
If the nbd-server uses named exports (supported since NBD 2.9.18, or with QEMU's
own embedded NBD server), you must specify an export name in the URI:
@example
qemu-system-i386 -cdrom nbd://localhost/debian-500-ppc-netinst
qemu-system-i386 -cdrom nbd://localhost/openSUSE-11.1-ppc-netinst
@end example
The URI syntax for NBD is supported since QEMU 1.3. An alternative syntax is
also available. Here are some example of the older syntax:
@example
qemu-system-i386 linux.img -hdb nbd:my_nbd_server.mydomain.org:1024
qemu-system-i386 linux2.img -hdb nbd:unix:/tmp/my_socket
qemu-system-i386 -cdrom nbd:localhost:10809:exportname=debian-500-ppc-netinst
@end example
@node disk_images_sheepdog
@subsection Sheepdog disk images
Sheepdog is a distributed storage system for QEMU. It provides highly
available block level storage volumes that can be attached to
QEMU-based virtual machines.
You can create a Sheepdog disk image with the command:
@example
qemu-img create sheepdog:///@var{image} @var{size}
@end example
where @var{image} is the Sheepdog image name and @var{size} is its
size.
To import the existing @var{filename} to Sheepdog, you can use a
convert command.
@example
qemu-img convert @var{filename} sheepdog:///@var{image}
@end example
You can boot from the Sheepdog disk image with the command:
@example
qemu-system-i386 sheepdog:///@var{image}
@end example
You can also create a snapshot of the Sheepdog image like qcow2.
@example
qemu-img snapshot -c @var{tag} sheepdog:///@var{image}
@end example
where @var{tag} is a tag name of the newly created snapshot.
To boot from the Sheepdog snapshot, specify the tag name of the
snapshot.
@example
qemu-system-i386 sheepdog:///@var{image}#@var{tag}
@end example
You can create a cloned image from the existing snapshot.
@example
qemu-img create -b sheepdog:///@var{base}#@var{tag} sheepdog:///@var{image}
@end example
where @var{base} is a image name of the source snapshot and @var{tag}
is its tag name.
You can use an unix socket instead of an inet socket:
@example
qemu-system-i386 sheepdog+unix:///@var{image}?socket=@var{path}
@end example
If the Sheepdog daemon doesn't run on the local host, you need to
specify one of the Sheepdog servers to connect to.
@example
qemu-img create sheepdog://@var{hostname}:@var{port}/@var{image} @var{size}
qemu-system-i386 sheepdog://@var{hostname}:@var{port}/@var{image}
@end example
@node disk_images_iscsi
@subsection iSCSI LUNs
iSCSI is a popular protocol used to access SCSI devices across a computer
network.
There are two different ways iSCSI devices can be used by QEMU.
The first method is to mount the iSCSI LUN on the host, and make it appear as
any other ordinary SCSI device on the host and then to access this device as a
/dev/sd device from QEMU. How to do this differs between host OSes.
The second method involves using the iSCSI initiator that is built into
QEMU. This provides a mechanism that works the same way regardless of which
host OS you are running QEMU on. This section will describe this second method
of using iSCSI together with QEMU.
In QEMU, iSCSI devices are described using special iSCSI URLs
@example
URL syntax:
iscsi://[<username>[%<password>]@@]<host>[:<port>]/<target-iqn-name>/<lun>
@end example
Username and password are optional and only used if your target is set up
using CHAP authentication for access control.
Alternatively the username and password can also be set via environment
variables to have these not show up in the process list
@example
export LIBISCSI_CHAP_USERNAME=<username>
export LIBISCSI_CHAP_PASSWORD=<password>
iscsi://<host>/<target-iqn-name>/<lun>
@end example
Various session related parameters can be set via special options, either
in a configuration file provided via '-readconfig' or directly on the
command line.
If the initiator-name is not specified qemu will use a default name
of 'iqn.2008-11.org.linux-kvm[:<uuid>'] where <uuid> is the UUID of the
virtual machine. If the UUID is not specified qemu will use
'iqn.2008-11.org.linux-kvm[:<name>'] where <name> is the name of the
virtual machine.
@example
Setting a specific initiator name to use when logging in to the target
-iscsi initiator-name=iqn.qemu.test:my-initiator
@end example
@example
Controlling which type of header digest to negotiate with the target
-iscsi header-digest=CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
@end example
These can also be set via a configuration file
@example
[iscsi]
user = "CHAP username"
password = "CHAP password"
initiator-name = "iqn.qemu.test:my-initiator"
# header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
header-digest = "CRC32C"
@end example
Setting the target name allows different options for different targets
@example
[iscsi "iqn.target.name"]
user = "CHAP username"
password = "CHAP password"
initiator-name = "iqn.qemu.test:my-initiator"
# header digest is one of CRC32C|CRC32C-NONE|NONE-CRC32C|NONE
header-digest = "CRC32C"
@end example
Howto use a configuration file to set iSCSI configuration options:
@example
cat >iscsi.conf <<EOF
[iscsi]
user = "me"
password = "my password"
initiator-name = "iqn.qemu.test:my-initiator"
header-digest = "CRC32C"
EOF
qemu-system-i386 -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \
-readconfig iscsi.conf
@end example
Howto set up a simple iSCSI target on loopback and accessing it via QEMU:
@example
This example shows how to set up an iSCSI target with one CDROM and one DISK
using the Linux STGT software target. This target is available on Red Hat based
systems as the package 'scsi-target-utils'.
tgtd --iscsi portal=127.0.0.1:3260
tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.qemu.test
tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 1 \
-b /IMAGES/disk.img --device-type=disk
tgtadm --lld iscsi --mode logicalunit --op new --tid 1 --lun 2 \
-b /IMAGES/cd.iso --device-type=cd
tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL
qemu-system-i386 -iscsi initiator-name=iqn.qemu.test:my-initiator \
-boot d -drive file=iscsi://127.0.0.1/iqn.qemu.test/1 \
-cdrom iscsi://127.0.0.1/iqn.qemu.test/2
@end example
@node disk_images_gluster
@subsection GlusterFS disk images
GlusterFS is a user space distributed file system.
You can boot from the GlusterFS disk image with the command:
@example
URI:
qemu-system-x86_64 -drive file=gluster[+@var{type}]://[@var{host}[:@var{port}]]/@var{volume}/@var{path}
[?socket=...][,file.debug=9][,file.logfile=...]
JSON:
qemu-system-x86_64 'json:@{"driver":"qcow2",
"file":@{"driver":"gluster",
"volume":"testvol","path":"a.img","debug":9,"logfile":"...",
"server":[@{"type":"tcp","host":"...","port":"..."@},
@{"type":"unix","socket":"..."@}]@}@}'
@end example
@var{gluster} is the protocol.
@var{type} specifies the transport type used to connect to gluster
management daemon (glusterd). Valid transport types are
tcp and unix. In the URI form, if a transport type isn't specified,
then tcp type is assumed.
@var{host} specifies the server where the volume file specification for
the given volume resides. This can be either a hostname or an ipv4 address.
If transport type is unix, then @var{host} field should not be specified.
Instead @var{socket} field needs to be populated with the path to unix domain
socket.
@var{port} is the port number on which glusterd is listening. This is optional
and if not specified, it defaults to port 24007. If the transport type is unix,
then @var{port} should not be specified.
@var{volume} is the name of the gluster volume which contains the disk image.
@var{path} is the path to the actual disk image that resides on gluster volume.
@var{debug} is the logging level of the gluster protocol driver. Debug levels
are 0-9, with 9 being the most verbose, and 0 representing no debugging output.
The default level is 4. The current logging levels defined in the gluster source
are 0 - None, 1 - Emergency, 2 - Alert, 3 - Critical, 4 - Error, 5 - Warning,
6 - Notice, 7 - Info, 8 - Debug, 9 - Trace
@var{logfile} is a commandline option to mention log file path which helps in
logging to the specified file and also help in persisting the gfapi logs. The
default is stderr.
You can create a GlusterFS disk image with the command:
@example
qemu-img create gluster://@var{host}/@var{volume}/@var{path} @var{size}
@end example
Examples
@example
qemu-system-x86_64 -drive file=gluster://1.2.3.4/testvol/a.img
qemu-system-x86_64 -drive file=gluster+tcp://1.2.3.4/testvol/a.img
qemu-system-x86_64 -drive file=gluster+tcp://1.2.3.4:24007/testvol/dir/a.img
qemu-system-x86_64 -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]/testvol/dir/a.img
qemu-system-x86_64 -drive file=gluster+tcp://[1:2:3:4:5:6:7:8]:24007/testvol/dir/a.img
qemu-system-x86_64 -drive file=gluster+tcp://server.domain.com:24007/testvol/dir/a.img
qemu-system-x86_64 -drive file=gluster+unix:///testvol/dir/a.img?socket=/tmp/glusterd.socket
qemu-system-x86_64 -drive file=gluster+rdma://1.2.3.4:24007/testvol/a.img
qemu-system-x86_64 -drive file=gluster://1.2.3.4/testvol/a.img,file.debug=9,file.logfile=/var/log/qemu-gluster.log
qemu-system-x86_64 'json:@{"driver":"qcow2",
"file":@{"driver":"gluster",
"volume":"testvol","path":"a.img",
"debug":9,"logfile":"/var/log/qemu-gluster.log",
"server":[@{"type":"tcp","host":"1.2.3.4","port":24007@},
@{"type":"unix","socket":"/var/run/glusterd.socket"@}]@}@}'
qemu-system-x86_64 -drive driver=qcow2,file.driver=gluster,file.volume=testvol,file.path=/path/a.img,
file.debug=9,file.logfile=/var/log/qemu-gluster.log,
file.server.0.type=tcp,file.server.0.host=1.2.3.4,file.server.0.port=24007,
file.server.1.type=unix,file.server.1.socket=/var/run/glusterd.socket
@end example
@node disk_images_ssh
@subsection Secure Shell (ssh) disk images
You can access disk images located on a remote ssh server
by using the ssh protocol:
@example
qemu-system-x86_64 -drive file=ssh://[@var{user}@@]@var{server}[:@var{port}]/@var{path}[?host_key_check=@var{host_key_check}]
@end example
Alternative syntax using properties:
@example
qemu-system-x86_64 -drive file.driver=ssh[,file.user=@var{user}],file.host=@var{server}[,file.port=@var{port}],file.path=@var{path}[,file.host_key_check=@var{host_key_check}]
@end example
@var{ssh} is the protocol.
@var{user} is the remote user. If not specified, then the local
username is tried.
@var{server} specifies the remote ssh server. Any ssh server can be
used, but it must implement the sftp-server protocol. Most Unix/Linux
systems should work without requiring any extra configuration.
@var{port} is the port number on which sshd is listening. By default
the standard ssh port (22) is used.
@var{path} is the path to the disk image.
The optional @var{host_key_check} parameter controls how the remote
host's key is checked. The default is @code{yes} which means to use
the local @file{.ssh/known_hosts} file. Setting this to @code{no}
turns off known-hosts checking. Or you can check that the host key
matches a specific fingerprint:
@code{host_key_check=md5:78:45:8e:14:57:4f:d5:45:83:0a:0e:f3:49:82:c9:c8}
(@code{sha1:} can also be used as a prefix, but note that OpenSSH
tools only use MD5 to print fingerprints).
Currently authentication must be done using ssh-agent. Other
authentication methods may be supported in future.
Note: Many ssh servers do not support an @code{fsync}-style operation.
The ssh driver cannot guarantee that disk flush requests are
obeyed, and this causes a risk of disk corruption if the remote
server or network goes down during writes. The driver will
print a warning when @code{fsync} is not supported:
warning: ssh server @code{ssh.example.com:22} does not support fsync
With sufficiently new versions of libssh2 and OpenSSH, @code{fsync} is
supported.
@include docs/qemu-block-drivers.texi
@node pcsys_network
@section Network emulation

View File

@ -89,9 +89,9 @@ STEXI
ETEXI
DEF("resize", img_resize,
"resize [--object objectdef] [--image-opts] [-q] filename [+ | -]size")
"resize [--object objectdef] [--image-opts] [-q] [--shrink] filename [+ | -]size")
STEXI
@item resize [--object @var{objectdef}] [--image-opts] [-q] @var{filename} [+ | -]@var{size}
@item resize [--object @var{objectdef}] [--image-opts] [-q] [--shrink] @var{filename} [+ | -]@var{size}
ETEXI
STEXI

View File

@ -64,6 +64,7 @@ enum {
OPTION_TARGET_IMAGE_OPTS = 263,
OPTION_SIZE = 264,
OPTION_PREALLOCATION = 265,
OPTION_SHRINK = 266,
};
typedef enum OutputFormat {
@ -3436,6 +3437,7 @@ static int img_resize(int argc, char **argv)
},
};
bool image_opts = false;
bool shrink = false;
/* Remove size from argv manually so that negative numbers are not treated
* as options by getopt. */
@ -3454,6 +3456,7 @@ static int img_resize(int argc, char **argv)
{"object", required_argument, 0, OPTION_OBJECT},
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
{"preallocation", required_argument, 0, OPTION_PREALLOCATION},
{"shrink", no_argument, 0, OPTION_SHRINK},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, ":f:hq",
@ -3496,6 +3499,9 @@ static int img_resize(int argc, char **argv)
return 1;
}
break;
case OPTION_SHRINK:
shrink = true;
break;
}
}
if (optind != argc - 1) {
@ -3569,6 +3575,23 @@ static int img_resize(int argc, char **argv)
goto out;
}
if (total_size < current_size && !shrink) {
warn_report("Shrinking an image will delete all data beyond the "
"shrunken image's end. Before performing such an "
"operation, make sure there is no important data there.");
if (g_strcmp0(bdrv_get_format_name(blk_bs(blk)), "raw") != 0) {
error_report(
"Use the --shrink option to perform a shrink operation.");
ret = -1;
goto out;
} else {
warn_report("Using the --shrink option will suppress this message. "
"Note that future versions of qemu-img may refuse to "
"shrink images without this option.");
}
}
ret = blk_truncate(blk, total_size, prealloc, &err);
if (!ret) {
qprintf(quiet, "Image resized.\n");

View File

@ -244,6 +244,9 @@ only the differences from @var{backing_file}. No size needs to be specified in
this case. @var{backing_file} will never be modified unless you use the
@code{commit} monitor command (or qemu-img commit).
If a relative path name is given, the backing file is looked up relative to
the directory containing @var{filename}.
Note that a given backing file will be opened to check that it is valid. Use
the @code{-u} option to enable unsafe backing file mode, which means that the
image will be created even if the associated backing file cannot be opened. A
@ -343,6 +346,9 @@ created as a copy on write image of the specified base image; the
@var{backing_file} should have the same content as the input's base image,
however the path, image format, etc may differ.
If a relative path name is given, the backing file is looked up relative to
the directory containing @var{output_filename}.
If the @code{-n} option is specified, the target volume creation will be
skipped. This is useful for formats such as @code{rbd} if the target
volume has already been created with site specific options that cannot
@ -490,6 +496,9 @@ The backing file is changed to @var{backing_file} and (if the image format of
string), then the image is rebased onto no backing file (i.e. it will exist
independently of any backing file).
If a relative path name is given, the backing file is looked up relative to
the directory containing @var{filename}.
@var{cache} specifies the cache mode to be used for @var{filename}, whereas
@var{src_cache} specifies the cache mode for reading backing files.
@ -536,7 +545,7 @@ qemu-img rebase -b base.img diff.qcow2
At this point, @code{modified.img} can be discarded, since
@code{base.img + diff.qcow2} contains the same information.
@item resize [--preallocation=@var{prealloc}] @var{filename} [+ | -]@var{size}
@item resize [--shrink] [--preallocation=@var{prealloc}] @var{filename} [+ | -]@var{size}
Change the disk image as if it had been created with @var{size}.
@ -544,6 +553,10 @@ Before using this command to shrink a disk image, you MUST use file system and
partitioning tools inside the VM to reduce allocated file systems and partition
sizes accordingly. Failure to do so will result in data loss!
When shrinking images, the @code{--shrink} option must be given. This informs
qemu-img that the user acknowledges all loss of data beyond the truncated
image's end.
After using this command to grow a disk image, you must use file system and
partitioning tools inside the VM to actually begin using the new space on the
device.

View File

@ -2010,6 +2010,18 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
return 0;
}
if (!(flags & BDRV_O_RDWR)) {
uint64_t orig_perm, orig_shared_perm;
bdrv_drain(bs);
blk_get_perm(blk, &orig_perm, &orig_shared_perm);
blk_set_perm(blk,
orig_perm & ~(BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED),
orig_shared_perm,
&error_abort);
}
qopts = qemu_opts_find(&reopen_opts, NULL);
opts = qopts ? qemu_opts_to_qdict(qopts, NULL) : NULL;
qemu_opts_reset(&reopen_opts);

View File

@ -82,7 +82,11 @@ class TestSingleDrive(ImageCommitTestCase):
qemu_io('-f', 'raw', '-c', 'write -P 0xab 0 524288', backing_img)
qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', mid_img)
self.vm = iotests.VM().add_drive(test_img, "node-name=top,backing.node-name=mid,backing.backing.node-name=base", interface="none")
self.vm.add_device("virtio-scsi-pci")
if iotests.qemu_default_machine == 's390-ccw-virtio':
self.vm.add_device("virtio-scsi-ccw")
else:
self.vm.add_device("virtio-scsi-pci")
self.vm.add_device("scsi-hd,id=scsi0,drive=drive0")
self.vm.launch()

View File

@ -103,7 +103,17 @@ echo
echo === Device without drive ===
echo
run_qemu -device virtio-scsi-pci -device scsi-hd
case "$QEMU_DEFAULT_MACHINE" in
s390-ccw-virtio)
virtio_scsi=virtio-scsi-ccw
;;
*)
virtio_scsi=virtio-scsi-pci
;;
esac
run_qemu -device $virtio_scsi -device scsi-hd |
sed -e "s/$virtio_scsi/VIRTIO_SCSI/"
echo
echo === Overriding backing file ===

View File

@ -49,7 +49,7 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,driver=qcow2,format=qcow2: Cannot specif
=== Device without drive ===
Testing: -device virtio-scsi-pci -device scsi-hd
Testing: -device VIRTIO_SCSI -device scsi-hd
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -device scsi-hd: drive property not set

View File

@ -49,7 +49,7 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,driver=qcow2,format=qcow2: Cannot specif
=== Device without drive ===
Testing: -device virtio-scsi-pci -device scsi-hd
Testing: -device VIRTIO_SCSI -device scsi-hd
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -device scsi-hd: drive property not set

View File

@ -141,7 +141,7 @@ echo
echo === Empty drive with -device and device_del ===
echo
run_qemu -device virtio-scsi-pci -device scsi-cd,id=cd0 <<EOF
run_qemu -device virtio-scsi -device scsi-cd,id=cd0 <<EOF
{ "execute": "qmp_capabilities" }
{ "execute": "query-block" }
{ "execute": "device_del", "arguments": { "id": "cd0" } }

View File

@ -419,7 +419,7 @@ Testing:
=== Empty drive with -device and device_del ===
Testing: -device virtio-scsi-pci -device scsi-cd,id=cd0
Testing: -device virtio-scsi -device scsi-cd,id=cd0
{
QMP_VERSION
}

View File

@ -54,7 +54,7 @@ _make_test_img $IMG_SIZE
$QEMU_IO -c 'write 0 64k' "$TEST_IMG" | _filter_qemu_io
# Remove data cluster from image (first cluster: image header, second: reftable,
# third: refblock, fourth: L1 table, fifth: L2 table)
$QEMU_IMG resize -f raw "$TEST_IMG" $((5 * 64 * 1024))
$QEMU_IMG resize -f raw --shrink "$TEST_IMG" $((5 * 64 * 1024))
$QEMU_IO -c map "$TEST_IMG"
$QEMU_IMG map "$TEST_IMG"
@ -69,7 +69,7 @@ $QEMU_IO -c 'write 0 64k' "$TEST_IMG" | _filter_qemu_io
qemu_comm_method=monitor _launch_qemu -drive if=none,file="$TEST_IMG",id=drv0
$QEMU_IMG resize -f raw "$TEST_IMG" $((5 * 64 * 1024))
$QEMU_IMG resize -f raw --shrink "$TEST_IMG" $((5 * 64 * 1024))
_send_qemu_cmd $QEMU_HANDLE 'qemu-io drv0 map' 'allocated' \
| sed -e 's/^(qemu).*qemu-io drv0 map...$/(qemu) qemu-io drv0 map/'

View File

@ -83,7 +83,7 @@ echo '=== Testing image shrinking ==='
for growth_mode in falloc full off; do
echo
echo "--- growth_mode=$growth_mode ---"
$QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" -${GROWTH_SIZE}K
$QEMU_IMG resize -f "$IMGFMT" --shrink --preallocation=$growth_mode "$TEST_IMG" -${GROWTH_SIZE}K
done
# success, all done

View File

@ -25,13 +25,21 @@ import time
base_img = os.path.join(iotests.test_dir, 'base.img')
new_img = os.path.join(iotests.test_dir, 'new.img')
if iotests.qemu_default_machine == 's390-ccw-virtio':
default_virtio_blk = 'virtio-blk-ccw'
else:
default_virtio_blk = 'virtio-blk-pci'
class TestBlockdevDel(iotests.QMPTestCase):
def setUp(self):
iotests.qemu_img('create', '-f', iotests.imgfmt, base_img, '1M')
self.vm = iotests.VM()
self.vm.add_device("virtio-scsi-pci,id=virtio-scsi")
if iotests.qemu_default_machine == 's390-ccw-virtio':
self.vm.add_device("virtio-scsi-ccw,id=virtio-scsi")
else:
self.vm.add_device("virtio-scsi-pci,id=virtio-scsi")
self.vm.launch()
def tearDown(self):
@ -87,7 +95,7 @@ class TestBlockdevDel(iotests.QMPTestCase):
self.checkBlockDriverState(node, expect_error)
# Add a device model
def addDeviceModel(self, device, backend, driver = 'virtio-blk-pci'):
def addDeviceModel(self, device, backend, driver = default_virtio_blk):
result = self.vm.qmp('device_add', id = device,
driver = driver, drive = backend)
self.assert_qmp(result, 'return', {})

170
tests/qemu-iotests/163 Normal file
View File

@ -0,0 +1,170 @@
#!/usr/bin/env python
#
# Tests for shrinking images
#
# Copyright (c) 2016-2017 Parallels International GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import os, random, iotests, struct, qcow2
from iotests import qemu_img, qemu_io, image_size
test_img = os.path.join(iotests.test_dir, 'test.img')
check_img = os.path.join(iotests.test_dir, 'check.img')
def size_to_int(str):
suff = ['B', 'K', 'M', 'G', 'T']
return int(str[:-1]) * 1024**suff.index(str[-1:])
class ShrinkBaseClass(iotests.QMPTestCase):
image_len = '128M'
shrink_size = '10M'
chunk_size = '16M'
refcount_bits = '16'
def __qcow2_check(self, filename):
entry_bits = 3
entry_size = 1 << entry_bits
l1_mask = 0x00fffffffffffe00
div_roundup = lambda n, d: (n + d - 1) / d
def split_by_n(data, n):
for x in xrange(0, len(data), n):
yield struct.unpack('>Q', data[x:x + n])[0] & l1_mask
def check_l1_table(h, l1_data):
l1_list = list(split_by_n(l1_data, entry_size))
real_l1_size = div_roundup(h.size,
1 << (h.cluster_bits*2 - entry_size))
used, unused = l1_list[:real_l1_size], l1_list[real_l1_size:]
self.assertTrue(len(used) != 0, "Verifying l1 table content")
self.assertFalse(any(unused), "Verifying l1 table content")
def check_reftable(fd, h, reftable):
for offset in split_by_n(reftable, entry_size):
if offset != 0:
fd.seek(offset)
cluster = fd.read(1 << h.cluster_bits)
self.assertTrue(any(cluster), "Verifying reftable content")
with open(filename, "rb") as fd:
h = qcow2.QcowHeader(fd)
fd.seek(h.l1_table_offset)
l1_table = fd.read(h.l1_size << entry_bits)
fd.seek(h.refcount_table_offset)
reftable = fd.read(h.refcount_table_clusters << h.cluster_bits)
check_l1_table(h, l1_table)
check_reftable(fd, h, reftable)
def __raw_check(self, filename):
pass
image_check = {
'qcow2' : __qcow2_check,
'raw' : __raw_check
}
def setUp(self):
if iotests.imgfmt == 'raw':
qemu_img('create', '-f', iotests.imgfmt, test_img, self.image_len)
qemu_img('create', '-f', iotests.imgfmt, check_img,
self.shrink_size)
else:
qemu_img('create', '-f', iotests.imgfmt,
'-o', 'cluster_size=' + self.cluster_size +
',refcount_bits=' + self.refcount_bits,
test_img, self.image_len)
qemu_img('create', '-f', iotests.imgfmt,
'-o', 'cluster_size=%s'% self.cluster_size,
check_img, self.shrink_size)
qemu_io('-c', 'write -P 0xff 0 ' + self.shrink_size, check_img)
def tearDown(self):
os.remove(test_img)
os.remove(check_img)
def image_verify(self):
self.assertEqual(image_size(test_img), image_size(check_img),
"Verifying image size")
self.image_check[iotests.imgfmt](self, test_img)
if iotests.imgfmt == 'raw':
return
self.assertEqual(qemu_img('check', test_img), 0,
"Verifying image corruption")
def test_empty_image(self):
qemu_img('resize', '-f', iotests.imgfmt, '--shrink', test_img,
self.shrink_size)
self.assertEqual(
qemu_io('-c', 'read -P 0x00 %s'%self.shrink_size, test_img),
qemu_io('-c', 'read -P 0x00 %s'%self.shrink_size, check_img),
"Verifying image content")
self.image_verify()
def test_sequential_write(self):
for offs in range(0, size_to_int(self.image_len),
size_to_int(self.chunk_size)):
qemu_io('-c', 'write -P 0xff %d %s' % (offs, self.chunk_size),
test_img)
qemu_img('resize', '-f', iotests.imgfmt, '--shrink', test_img,
self.shrink_size)
self.assertEqual(qemu_img("compare", test_img, check_img), 0,
"Verifying image content")
self.image_verify()
def test_random_write(self):
offs_list = range(0, size_to_int(self.image_len),
size_to_int(self.chunk_size))
random.shuffle(offs_list)
for offs in offs_list:
qemu_io('-c', 'write -P 0xff %d %s' % (offs, self.chunk_size),
test_img)
qemu_img('resize', '-f', iotests.imgfmt, '--shrink', test_img,
self.shrink_size)
self.assertEqual(qemu_img("compare", test_img, check_img), 0,
"Verifying image content")
self.image_verify()
class TestShrink512(ShrinkBaseClass):
image_len = '3M'
shrink_size = '1M'
chunk_size = '256K'
cluster_size = '512'
refcount_bits = '64'
class TestShrink64K(ShrinkBaseClass):
cluster_size = '64K'
class TestShrink1M(ShrinkBaseClass):
cluster_size = '1M'
refcount_bits = '1'
ShrinkBaseClass = None
if __name__ == '__main__':
iotests.main(supported_fmts=['raw', 'qcow2'])

View File

@ -0,0 +1,5 @@
.........
----------------------------------------------------------------------
Ran 9 tests
OK

View File

@ -56,7 +56,7 @@ function do_run_qemu()
done
fi
echo quit
) | $QEMU -nographic -monitor stdio -serial none "$@"
) | $QEMU -machine accel=qtest -nographic -monitor stdio -serial none "$@"
echo
}

View File

@ -93,7 +93,9 @@ echo
# Slow down migration so much that it definitely won't finish before we can
# switch to postcopy
# Enable postcopy-ram capability both on source and destination
silent=yes
_send_qemu_cmd $dest 'migrate_set_capability postcopy-ram on' "(qemu)"
_send_qemu_cmd $src 'migrate_set_speed 4k' "(qemu)"
_send_qemu_cmd $src 'migrate_set_capability postcopy-ram on' "(qemu)"
_send_qemu_cmd $src "migrate -d unix:${MIG_SOCKET}" "(qemu)"

View File

@ -20,7 +20,6 @@ read 65536/65536 bytes at offset 0
=== Do some I/O on the destination ===
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) qemu-io disk "read -P 0x55 0 64k"
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)

View File

@ -45,17 +45,26 @@ _supported_os Linux
size=32M
case "$QEMU_DEFAULT_MACHINE" in
s390-ccw-virtio)
virtioblk=virtio-blk-ccw
;;
*)
virtioblk=virtio-blk-pci
;;
esac
_make_test_img $size
echo "Starting QEMU"
_launch_qemu -drive file=$TEST_IMG,if=none,id=drive0,file.locking=on \
-device virtio-blk-pci,drive=drive0
-device $virtioblk,drive=drive0
echo
echo "Starting a second QEMU using the same image should fail"
echo 'quit' | $QEMU -monitor stdio \
-drive file=$TEST_IMG,if=none,id=drive0,file.locking=on \
-device virtio-blk-pci,drive=drive0 2>&1 | _filter_testdir 2>&1 |
-device $virtioblk,drive=drive0 2>&1 | _filter_testdir 2>&1 |
_filter_qemu |
sed -e '/falling back to POSIX file/d' \
-e '/locks can be lost unexpectedly/d'

View File

@ -56,15 +56,15 @@ function do_run_qemu()
done
fi
echo quit
) | $QEMU -S -nodefaults -display none -device virtio-scsi-pci -monitor stdio "$@" 2>&1
) | $QEMU -S -display none -device virtio-scsi-pci -monitor stdio "$@" 2>&1
echo
}
function check_info_block()
{
echo "info block" |
QEMU_OPTIONS="" do_run_qemu "$@" | _filter_win32 | _filter_hmp |
_filter_qemu | _filter_generated_node_ids
do_run_qemu "$@" | _filter_win32 | _filter_hmp | _filter_qemu |
_filter_generated_node_ids
}

View File

@ -12,7 +12,7 @@ Start from read-write
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
write failed: Operation not permitted
Block node is read-only
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
*** done

92
tests/qemu-iotests/195 Executable file
View File

@ -0,0 +1,92 @@
#!/bin/bash
#
# Test change-backing-file command
#
# Copyright (C) 2017 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# creator
owner=kwolf@redhat.com
seq=`basename $0`
echo "QA output created by $seq"
here=`pwd`
status=1 # failure is the default!
_cleanup()
{
_cleanup_test_img
rm -f "$TEST_IMG.mid"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
# get standard environment, filters and checks
. ./common.rc
. ./common.filter
_supported_fmt qcow2
_supported_proto file
_supported_os Linux
function do_run_qemu()
{
echo Testing: "$@" | _filter_imgfmt
$QEMU -nographic -qmp-pretty stdio -serial none "$@"
echo
}
function run_qemu()
{
do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_qmp \
| _filter_qemu_io | _filter_generated_node_ids
}
size=64M
TEST_IMG="$TEST_IMG.base" _make_test_img $size
TEST_IMG="$TEST_IMG.mid" _make_test_img -b "$TEST_IMG.base"
_make_test_img -b "$TEST_IMG.mid"
echo
echo "Change backing file of mid (opened read-only)"
echo
run_qemu -drive if=none,file="$TEST_IMG",backing.node-name=mid <<EOF
{"execute":"qmp_capabilities"}
{"execute":"change-backing-file", "arguments":{"device":"none0","image-node-name":"mid","backing-file":"/dev/null"}}
{"execute":"quit"}
EOF
TEST_IMG="$TEST_IMG.mid" _img_info
echo
echo "Change backing file of top (opened writable)"
echo
TEST_IMG="$TEST_IMG.mid" _make_test_img -b "$TEST_IMG.base"
run_qemu -drive if=none,file="$TEST_IMG",node-name=top <<EOF
{"execute":"qmp_capabilities"}
{"execute":"change-backing-file", "arguments":{"device":"none0","image-node-name":"top","backing-file":"/dev/null"}}
{"execute":"quit"}
EOF
_img_info
# success, all done
echo "*** done"
rm -f $seq.full
status=0

View File

@ -0,0 +1,78 @@
QA output created by 195
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
Formatting 'TEST_DIR/t.IMGFMT.mid', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.mid
Change backing file of mid (opened read-only)
Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,backing.node-name=mid
{
QMP_VERSION
}
{
"return": {
}
}
{
"return": {
}
}
{
"return": {
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "SHUTDOWN",
"data": {
"guest": false
}
}
image: TEST_DIR/t.IMGFMT.mid
file format: IMGFMT
virtual size: 64M (67108864 bytes)
cluster_size: 65536
backing file: /dev/null
backing file format: IMGFMT
Change backing file of top (opened writable)
Formatting 'TEST_DIR/t.IMGFMT.mid', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
Testing: -drive if=none,file=TEST_DIR/t.IMGFMT,node-name=top
{
QMP_VERSION
}
{
"return": {
}
}
{
"return": {
}
}
{
"return": {
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "SHUTDOWN",
"data": {
"guest": false
}
}
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 64M (67108864 bytes)
cluster_size: 65536
backing file: /dev/null
backing file format: IMGFMT
*** done

View File

@ -353,7 +353,7 @@ do
else
echo " - output mismatch (see $seq.out.bad)"
mv $tmp.out $seq.out.bad
$diff -w "$reference" $seq.out.bad
$diff -w "$reference" $(realpath $seq.out.bad)
err=true
fi
fi

View File

@ -166,6 +166,7 @@
159 rw auto quick
160 rw auto quick
162 auto quick
163 rw auto quick
165 rw auto quick
170 rw auto quick
171 rw auto quick
@ -189,3 +190,4 @@
190 rw auto quick
192 rw auto quick
194 rw auto migration quick
195 rw auto quick

View File

@ -124,6 +124,7 @@ int64_t throttle_compute_wait(LeakyBucket *bkt)
/* If the main bucket is not full yet we still have to check the
* burst bucket in order to enforce the burst limit */
if (bkt->burst_length > 1) {
assert(bkt->max > 0); /* see throttle_is_valid() */
extra = bkt->burst_level - burst_bucket_size;
if (extra > 0) {
return throttle_do_compute_wait(bkt->max, extra);