1
The following changes since commit 5704c36d25ee84e7129722cb0db53df9faefe943:
1
The following changes since commit 4f59102571fce49af180cfc6d4cdd2b5df7bdb14:
2
2
3
Merge remote-tracking branch 'remotes/kraxel/tags/fixes-31-20181112-pull-request' into staging (2018-11-12 15:55:40 +0000)
3
Merge remote-tracking branch 'remotes/amarkovic/tags/mips-queue-oct-01-2019' into staging (2019-10-01 16:21:42 +0100)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
8
8
9
for you to fetch changes up to 1a42e5d8298d1b0f90d2254e7d559391dd3a45ca:
9
for you to fetch changes up to 7e693a0500455edab21754573c32b7146138cffd:
10
10
11
Merge remote-tracking branch 'mreitz/tags/pull-block-2018-11-12' into queue-block (2018-11-12 17:57:32 +0100)
11
iotests: Remove Python 2 compatibility code (2019-10-04 11:59:16 +0200)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches:
15
15
16
- file-posix: Don't waste a file descriptor for locking, don't lock the
16
- Fix internal snapshots with typical -blockdev setups
17
same bit multiple times
17
- iotests: Require Python 3.6 or later
18
- nvme: Fix double free and memory leak
19
- Misc error handling fixes
20
- Added NULL checks found by static analysis
21
- Allow more block drivers to not be included in the qemu build
22
18
23
----------------------------------------------------------------
19
----------------------------------------------------------------
24
Fam Zheng (4):
20
Kevin Wolf (4):
25
file-posix: Use error API properly
21
block/snapshot: Restrict set of snapshot nodes
26
file-posix: Skip effectiveless OFD lock operations
22
iotests: Test internal snapshots with -blockdev
27
file-posix: Drop s->lock_fd
23
iotests: Require Python 3.6 or later
28
tests: Add unit tests for image locking
24
iotests: Remove Python 2 compatibility code
29
25
30
Jeff Cody (1):
26
block/snapshot.c | 26 ++++--
31
block: Make more block drivers compile-time configurable
27
tests/qemu-iotests/044 | 3 -
28
tests/qemu-iotests/163 | 3 -
29
tests/qemu-iotests/267 | 168 ++++++++++++++++++++++++++++++++++++
30
tests/qemu-iotests/267.out | 182 +++++++++++++++++++++++++++++++++++++++
31
tests/qemu-iotests/check | 13 ++-
32
tests/qemu-iotests/common.filter | 11 ++-
33
tests/qemu-iotests/group | 1 +
34
tests/qemu-iotests/iotests.py | 13 +--
35
9 files changed, 392 insertions(+), 28 deletions(-)
36
create mode 100755 tests/qemu-iotests/267
37
create mode 100644 tests/qemu-iotests/267.out
32
38
33
Kevin Wolf (1):
34
Merge remote-tracking branch 'mreitz/tags/pull-block-2018-11-12' into queue-block
35
36
Li Qiang (2):
37
nvme: don't unref ctrl_mem when device unrealized
38
nvme: free cmbuf in nvme_exit
39
40
Liam Merwick (5):
41
job: Fix off-by-one assert checks for JobSTT and JobVerbTable
42
block: Null pointer dereference in blk_root_get_parent_desc()
43
qemu-img: assert block_job_get() does not return NULL in img_commit()
44
block: Fix potential Null pointer dereferences in vvfat.c
45
qcow2: Read outside array bounds in qcow2_pre_write_overlap_check()
46
47
Peter Maydell (1):
48
blockdev: Consistently use snapshot_node_name in external_snapshot_prepare()
49
50
zhenwei pi (1):
51
blockdev: handle error on block latency histogram set error
52
53
configure | 91 ++++++++++++++++++++++++++
54
block/block-backend.c | 3 +-
55
block/file-posix.c | 122 ++++++++++++++++++++---------------
56
block/qcow2-refcount.c | 18 +++---
57
block/vvfat.c | 46 ++++++++-----
58
blockdev.c | 21 ++++--
59
hw/block/nvme.c | 6 +-
60
job.c | 4 +-
61
qemu-img.c | 1 +
62
tests/test-image-locking.c | 157 +++++++++++++++++++++++++++++++++++++++++++++
63
block/Makefile.objs | 22 +++++--
64
tests/Makefile.include | 2 +
65
12 files changed, 400 insertions(+), 93 deletions(-)
66
create mode 100644 tests/test-image-locking.c
67
diff view generated by jsdifflib
Deleted patch
1
From: Fam Zheng <famz@redhat.com>
2
1
3
Use error_report for situations that affect user operation (i.e. we're
4
actually returning error), and warn_report/warn_report_err when some
5
less critical error happened but the user operation can still carry on.
6
7
For raw_normalize_devicepath, add Error parameter to propagate to
8
its callers.
9
10
Suggested-by: Markus Armbruster <armbru@redhat.com>
11
Signed-off-by: Fam Zheng <famz@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
block/file-posix.c | 39 ++++++++++++++++-----------------------
15
1 file changed, 16 insertions(+), 23 deletions(-)
16
17
diff --git a/block/file-posix.c b/block/file-posix.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/file-posix.c
20
+++ b/block/file-posix.c
21
@@ -XXX,XX +XXX,XX @@ static int cdrom_reopen(BlockDriverState *bs);
22
#endif
23
24
#if defined(__NetBSD__)
25
-static int raw_normalize_devicepath(const char **filename)
26
+static int raw_normalize_devicepath(const char **filename, Error **errp)
27
{
28
static char namebuf[PATH_MAX];
29
const char *dp, *fname;
30
@@ -XXX,XX +XXX,XX @@ static int raw_normalize_devicepath(const char **filename)
31
fname = *filename;
32
dp = strrchr(fname, '/');
33
if (lstat(fname, &sb) < 0) {
34
- fprintf(stderr, "%s: stat failed: %s\n",
35
- fname, strerror(errno));
36
+ error_setg_errno(errp, errno, "%s: stat failed", fname);
37
return -errno;
38
}
39
40
@@ -XXX,XX +XXX,XX @@ static int raw_normalize_devicepath(const char **filename)
41
snprintf(namebuf, PATH_MAX, "%.*s/r%s",
42
(int)(dp - fname), fname, dp + 1);
43
}
44
- fprintf(stderr, "%s is a block device", fname);
45
*filename = namebuf;
46
- fprintf(stderr, ", using %s\n", *filename);
47
+ warn_report("%s is a block device, using %s", fname, *filename);
48
49
return 0;
50
}
51
#else
52
-static int raw_normalize_devicepath(const char **filename)
53
+static int raw_normalize_devicepath(const char **filename, Error **errp)
54
{
55
return 0;
56
}
57
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
58
59
filename = qemu_opt_get(opts, "filename");
60
61
- ret = raw_normalize_devicepath(&filename);
62
+ ret = raw_normalize_devicepath(&filename, errp);
63
if (ret != 0) {
64
- error_setg_errno(errp, -ret, "Could not normalize device path");
65
goto fail;
66
}
67
68
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
69
case ON_OFF_AUTO_ON:
70
s->use_lock = true;
71
if (!qemu_has_ofd_lock()) {
72
- fprintf(stderr,
73
- "File lock requested but OFD locking syscall is "
74
- "unavailable, falling back to POSIX file locks.\n"
75
- "Due to the implementation, locks can be lost "
76
- "unexpectedly.\n");
77
+ warn_report("File lock requested but OFD locking syscall is "
78
+ "unavailable, falling back to POSIX file locks");
79
+ error_printf("Due to the implementation, locks can be lost "
80
+ "unexpectedly.\n");
81
}
82
break;
83
case ON_OFF_AUTO_OFF:
84
@@ -XXX,XX +XXX,XX @@ static int raw_handle_perm_lock(BlockDriverState *bs,
85
/* Theoretically the above call only unlocks bytes and it cannot
86
* fail. Something weird happened, report it.
87
*/
88
- error_report_err(local_err);
89
+ warn_report_err(local_err);
90
}
91
break;
92
case RAW_PL_COMMIT:
93
@@ -XXX,XX +XXX,XX @@ static int raw_handle_perm_lock(BlockDriverState *bs,
94
/* Theoretically the above call only unlocks bytes and it cannot
95
* fail. Something weird happened, report it.
96
*/
97
- error_report_err(local_err);
98
+ warn_report_err(local_err);
99
}
100
break;
101
}
102
@@ -XXX,XX +XXX,XX @@ static int raw_reopen_prepare(BDRVReopenState *state,
103
/* If we cannot use fcntl, or fcntl failed, fall back to qemu_open() */
104
if (rs->fd == -1) {
105
const char *normalized_filename = state->bs->filename;
106
- ret = raw_normalize_devicepath(&normalized_filename);
107
- if (ret < 0) {
108
- error_setg_errno(errp, -ret, "Could not normalize device path");
109
- } else {
110
+ ret = raw_normalize_devicepath(&normalized_filename, errp);
111
+ if (ret >= 0) {
112
assert(!(rs->open_flags & O_CREAT));
113
rs->fd = qemu_open(normalized_filename, rs->open_flags);
114
if (rs->fd == -1) {
115
@@ -XXX,XX +XXX,XX @@ static int aio_worker(void *arg)
116
ret = handle_aiocb_truncate(aiocb);
117
break;
118
default:
119
- fprintf(stderr, "invalid aio request (0x%x)\n", aiocb->aio_type);
120
+ error_report("invalid aio request (0x%x)", aiocb->aio_type);
121
ret = -EINVAL;
122
break;
123
}
124
@@ -XXX,XX +XXX,XX @@ out_unlock:
125
* not mean the whole creation operation has failed. So
126
* report it the user for their convenience, but do not report
127
* it to the caller. */
128
- error_report_err(local_err);
129
+ warn_report_err(local_err);
130
}
131
132
out_close:
133
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn hdev_co_create_opts(const char *filename, QemuOpts *opts
134
135
(void)has_prefix;
136
137
- ret = raw_normalize_devicepath(&filename);
138
+ ret = raw_normalize_devicepath(&filename, errp);
139
if (ret < 0) {
140
- error_setg_errno(errp, -ret, "Could not normalize device path");
141
return ret;
142
}
143
144
--
145
2.19.1
146
147
diff view generated by jsdifflib
1
From: Liam Merwick <Liam.Merwick@oracle.com>
1
Nodes involved in internal snapshots were those that were returned by
2
bdrv_next(), inserted and not read-only. bdrv_next() in turn returns all
3
nodes that are either the root node of a BlockBackend or monitor-owned
4
nodes.
2
5
3
The calls to find_mapping_for_cluster() may return NULL but it
6
With the typical -drive use, this worked well enough. However, in the
4
isn't always checked for before dereferencing the value returned.
7
typical -blockdev case, the user defines one node per option, making all
5
Additionally, add some asserts to cover cases where NULL can't
8
nodes monitor-owned nodes. This includes protocol nodes etc. which often
6
be returned but which might not be obvious at first glance.
9
are not snapshottable, so "savevm" only returns an error.
7
10
8
Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com>
11
Change the conditions so that internal snapshot still include all nodes
9
Message-id: 1541453919-25973-5-git-send-email-Liam.Merwick@oracle.com
12
that have a BlockBackend attached (we definitely want to snapshot
10
[mreitz: Dropped superfluous check of "mapping" following an assertion
13
anything attached to a guest device and probably also the built-in NBD
11
that it is not NULL, and fixed some indentation]
14
server; snapshotting block job BlockBackends is more of an accident, but
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
a preexisting one), but other monitor-owned nodes are only included if
16
they have no parents.
17
18
This makes internal snapshots usable again with typical -blockdev
19
configurations.
20
21
Cc: qemu-stable@nongnu.org
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
Reviewed-by: Eric Blake <eblake@redhat.com>
24
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
25
Tested-by: Peter Krempa <pkrempa@redhat.com>
13
---
26
---
14
block/vvfat.c | 46 ++++++++++++++++++++++++++++++----------------
27
block/snapshot.c | 26 +++++++++++++++++++-------
15
1 file changed, 30 insertions(+), 16 deletions(-)
28
1 file changed, 19 insertions(+), 7 deletions(-)
16
29
17
diff --git a/block/vvfat.c b/block/vvfat.c
30
diff --git a/block/snapshot.c b/block/snapshot.c
18
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
19
--- a/block/vvfat.c
32
--- a/block/snapshot.c
20
+++ b/block/vvfat.c
33
+++ b/block/snapshot.c
21
@@ -XXX,XX +XXX,XX @@ static inline void array_free(array_t* array)
34
@@ -XXX,XX +XXX,XX @@
22
/* does not automatically grow */
35
#include "qapi/qmp/qerror.h"
23
static inline void* array_get(array_t* array,unsigned int index) {
36
#include "qapi/qmp/qstring.h"
24
assert(index < array->next);
37
#include "qemu/option.h"
25
+ assert(array->pointer);
38
+#include "sysemu/block-backend.h"
26
return array->pointer + index * array->item_size;
39
40
QemuOptsList internal_snapshot_opts = {
41
.name = "snapshot",
42
@@ -XXX,XX +XXX,XX @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
43
return ret;
27
}
44
}
28
45
29
-static inline int array_ensure_allocated(array_t* array, int index)
46
+static bool bdrv_all_snapshots_includes_bs(BlockDriverState *bs)
30
+static inline void array_ensure_allocated(array_t *array, int index)
47
+{
31
{
48
+ if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
32
if((index + 1) * array->item_size > array->size) {
49
+ return false;
33
int new_size = (index + 32) * array->item_size;
34
array->pointer = g_realloc(array->pointer, new_size);
35
- if (!array->pointer)
36
- return -1;
37
+ assert(array->pointer);
38
memset(array->pointer + array->size, 0, new_size - array->size);
39
array->size = new_size;
40
array->next = index + 1;
41
}
42
-
43
- return 0;
44
}
45
46
static inline void* array_get_next(array_t* array) {
47
unsigned int next = array->next;
48
49
- if (array_ensure_allocated(array, next) < 0)
50
- return NULL;
51
-
52
+ array_ensure_allocated(array, next);
53
array->next = next + 1;
54
return array_get(array, next);
55
}
56
@@ -XXX,XX +XXX,XX @@ static int commit_direntries(BDRVVVFATState* s,
57
direntry_t* direntry = array_get(&(s->directory), dir_index);
58
uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry);
59
mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
60
-
61
int factor = 0x10 * s->sectors_per_cluster;
62
int old_cluster_count, new_cluster_count;
63
- int current_dir_index = mapping->info.dir.first_dir_index;
64
- int first_dir_index = current_dir_index;
65
+ int current_dir_index;
66
+ int first_dir_index;
67
int ret, i;
68
uint32_t c;
69
70
-DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapping->path, parent_mapping_index));
71
-
72
assert(direntry);
73
assert(mapping);
74
assert(mapping->begin == first_cluster);
75
@@ -XXX,XX +XXX,XX @@ DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapp
76
assert(mapping->mode & MODE_DIRECTORY);
77
assert(dir_index == 0 || is_directory(direntry));
78
79
+ DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n",
80
+ mapping->path, parent_mapping_index));
81
+
82
+ current_dir_index = mapping->info.dir.first_dir_index;
83
+ first_dir_index = current_dir_index;
84
mapping->info.dir.parent_mapping_index = parent_mapping_index;
85
86
if (first_cluster == 0) {
87
@@ -XXX,XX +XXX,XX @@ DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapp
88
direntry = array_get(&(s->directory), first_dir_index + i);
89
if (is_directory(direntry) && !is_dot(direntry)) {
90
mapping = find_mapping_for_cluster(s, first_cluster);
91
+ if (mapping == NULL) {
92
+ return -1;
93
+ }
94
assert(mapping->mode & MODE_DIRECTORY);
95
ret = commit_direntries(s, first_dir_index + i,
96
array_index(&(s->mapping), mapping));
97
@@ -XXX,XX +XXX,XX @@ static int commit_one_file(BDRVVVFATState* s,
98
assert(offset < size);
99
assert((offset % s->cluster_size) == 0);
100
101
+ if (mapping == NULL) {
102
+ return -1;
103
+ }
50
+ }
104
+
51
+
105
for (i = s->cluster_size; i < offset; i += s->cluster_size)
52
+ /* Include all nodes that are either in use by a BlockBackend, or that
106
c = modified_fat_get(s, c);
53
+ * aren't attached to any node, but owned by the monitor. */
107
54
+ return bdrv_has_blk(bs) || QLIST_EMPTY(&bs->parents);
108
@@ -XXX,XX +XXX,XX @@ static int handle_renames_and_mkdirs(BDRVVVFATState* s)
55
+}
109
if (commit->action == ACTION_RENAME) {
56
110
mapping_t* mapping = find_mapping_for_cluster(s,
57
/* Group operations. All block drivers are involved.
111
commit->param.rename.cluster);
58
* These functions will properly handle dataplane (take aio_context_acquire
112
- char* old_path = mapping->path;
59
@@ -XXX,XX +XXX,XX @@ bool bdrv_all_can_snapshot(BlockDriverState **first_bad_bs)
113
+ char *old_path;
60
AioContext *ctx = bdrv_get_aio_context(bs);
114
61
115
+ if (mapping == NULL) {
62
aio_context_acquire(ctx);
116
+ return -1;
63
- if (bdrv_is_inserted(bs) && !bdrv_is_read_only(bs)) {
117
+ }
64
+ if (bdrv_all_snapshots_includes_bs(bs)) {
118
+ old_path = mapping->path;
65
ok = bdrv_can_snapshot(bs);
119
assert(commit->path);
66
}
120
mapping->path = commit->path;
67
aio_context_release(ctx);
121
if (rename(old_path, mapping->path))
68
@@ -XXX,XX +XXX,XX @@ int bdrv_all_delete_snapshot(const char *name, BlockDriverState **first_bad_bs,
122
@@ -XXX,XX +XXX,XX @@ static int handle_renames_and_mkdirs(BDRVVVFATState* s)
69
AioContext *ctx = bdrv_get_aio_context(bs);
123
direntry_t* d = direntry + i;
70
124
71
aio_context_acquire(ctx);
125
if (is_file(d) || (is_directory(d) && !is_dot(d))) {
72
- if (bdrv_can_snapshot(bs) &&
126
+ int l;
73
- bdrv_snapshot_find(bs, snapshot, name) >= 0) {
127
+ char *new_path;
74
+ if (bdrv_all_snapshots_includes_bs(bs) &&
128
mapping_t* m = find_mapping_for_cluster(s,
75
+ bdrv_snapshot_find(bs, snapshot, name) >= 0)
129
begin_of_direntry(d));
76
+ {
130
- int l = strlen(m->path);
77
ret = bdrv_snapshot_delete(bs, snapshot->id_str,
131
- char* new_path = g_malloc(l + diff + 1);
78
snapshot->name, err);
132
+ if (m == NULL) {
79
}
133
+ return -1;
80
@@ -XXX,XX +XXX,XX @@ int bdrv_all_goto_snapshot(const char *name, BlockDriverState **first_bad_bs,
134
+ }
81
AioContext *ctx = bdrv_get_aio_context(bs);
135
+ l = strlen(m->path);
82
136
+ new_path = g_malloc(l + diff + 1);
83
aio_context_acquire(ctx);
137
84
- if (bdrv_can_snapshot(bs)) {
138
assert(!strncmp(m->path, mapping->path, l2));
85
+ if (bdrv_all_snapshots_includes_bs(bs)) {
139
86
ret = bdrv_snapshot_goto(bs, name, errp);
87
}
88
aio_context_release(ctx);
89
@@ -XXX,XX +XXX,XX @@ int bdrv_all_find_snapshot(const char *name, BlockDriverState **first_bad_bs)
90
AioContext *ctx = bdrv_get_aio_context(bs);
91
92
aio_context_acquire(ctx);
93
- if (bdrv_can_snapshot(bs)) {
94
+ if (bdrv_all_snapshots_includes_bs(bs)) {
95
err = bdrv_snapshot_find(bs, &sn, name);
96
}
97
aio_context_release(ctx);
98
@@ -XXX,XX +XXX,XX @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
99
if (bs == vm_state_bs) {
100
sn->vm_state_size = vm_state_size;
101
err = bdrv_snapshot_create(bs, sn);
102
- } else if (bdrv_can_snapshot(bs)) {
103
+ } else if (bdrv_all_snapshots_includes_bs(bs)) {
104
sn->vm_state_size = 0;
105
err = bdrv_snapshot_create(bs, sn);
106
}
107
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_all_find_vmstate_bs(void)
108
bool found;
109
110
aio_context_acquire(ctx);
111
- found = bdrv_can_snapshot(bs);
112
+ found = bdrv_all_snapshots_includes_bs(bs) && bdrv_can_snapshot(bs);
113
aio_context_release(ctx);
114
115
if (found) {
140
--
116
--
141
2.19.1
117
2.20.1
142
118
143
119
diff view generated by jsdifflib
1
From: Fam Zheng <famz@redhat.com>
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
3
Tested-by: Peter Krempa <pkrempa@redhat.com>
4
---
5
tests/qemu-iotests/267 | 168 ++++++++++++++++++++++++++++
6
tests/qemu-iotests/267.out | 182 +++++++++++++++++++++++++++++++
7
tests/qemu-iotests/common.filter | 11 +-
8
tests/qemu-iotests/group | 1 +
9
4 files changed, 358 insertions(+), 4 deletions(-)
10
create mode 100755 tests/qemu-iotests/267
11
create mode 100644 tests/qemu-iotests/267.out
2
12
3
Signed-off-by: Fam Zheng <famz@redhat.com>
13
diff --git a/tests/qemu-iotests/267 b/tests/qemu-iotests/267
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
new file mode 100755
5
---
15
index XXXXXXX..XXXXXXX
6
tests/test-image-locking.c | 157 +++++++++++++++++++++++++++++++++++++
16
--- /dev/null
7
tests/Makefile.include | 2 +
17
+++ b/tests/qemu-iotests/267
8
2 files changed, 159 insertions(+)
18
@@ -XXX,XX +XXX,XX @@
9
create mode 100644 tests/test-image-locking.c
19
+#!/usr/bin/env bash
10
20
+#
11
diff --git a/tests/test-image-locking.c b/tests/test-image-locking.c
21
+# Test which nodes are involved in internal snapshots
22
+#
23
+# Copyright (C) 2019 Red Hat, Inc.
24
+#
25
+# This program is free software; you can redistribute it and/or modify
26
+# it under the terms of the GNU General Public License as published by
27
+# the Free Software Foundation; either version 2 of the License, or
28
+# (at your option) any later version.
29
+#
30
+# This program is distributed in the hope that it will be useful,
31
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
32
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33
+# GNU General Public License for more details.
34
+#
35
+# You should have received a copy of the GNU General Public License
36
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
37
+#
38
+
39
+# creator
40
+owner=kwolf@redhat.com
41
+
42
+seq=`basename $0`
43
+echo "QA output created by $seq"
44
+
45
+status=1    # failure is the default!
46
+
47
+_cleanup()
48
+{
49
+ _cleanup_test_img
50
+ rm -f "$TEST_DIR/nbd"
51
+}
52
+trap "_cleanup; exit \$status" 0 1 2 3 15
53
+
54
+# get standard environment, filters and checks
55
+. ./common.rc
56
+. ./common.filter
57
+
58
+_supported_fmt qcow2
59
+_supported_proto file
60
+_supported_os Linux
61
+
62
+# Internal snapshots are (currently) impossible with refcount_bits=1
63
+_unsupported_imgopts 'refcount_bits=1[^0-9]'
64
+
65
+do_run_qemu()
66
+{
67
+ echo Testing: "$@"
68
+ (
69
+ if ! test -t 0; then
70
+ while read cmd; do
71
+ echo $cmd
72
+ done
73
+ fi
74
+ echo quit
75
+ ) | $QEMU -nographic -monitor stdio -nodefaults "$@"
76
+ echo
77
+}
78
+
79
+run_qemu()
80
+{
81
+ do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_hmp |
82
+ _filter_generated_node_ids | _filter_imgfmt | _filter_vmstate_size
83
+}
84
+
85
+size=128M
86
+
87
+run_test()
88
+{
89
+ _make_test_img $size
90
+ printf "savevm snap0\ninfo snapshots\nloadvm snap0\n" | run_qemu "$@" | _filter_date
91
+}
92
+
93
+
94
+echo
95
+echo "=== No block devices at all ==="
96
+echo
97
+
98
+run_test
99
+
100
+echo
101
+echo "=== -drive if=none ==="
102
+echo
103
+
104
+run_test -drive driver=file,file="$TEST_IMG",if=none
105
+run_test -drive driver=$IMGFMT,file="$TEST_IMG",if=none
106
+run_test -drive driver=$IMGFMT,file="$TEST_IMG",if=none -device virtio-blk,drive=none0
107
+
108
+echo
109
+echo "=== -drive if=virtio ==="
110
+echo
111
+
112
+run_test -drive driver=file,file="$TEST_IMG",if=virtio
113
+run_test -drive driver=$IMGFMT,file="$TEST_IMG",if=virtio
114
+
115
+echo
116
+echo "=== Simple -blockdev ==="
117
+echo
118
+
119
+run_test -blockdev driver=file,filename="$TEST_IMG",node-name=file
120
+run_test -blockdev driver=file,filename="$TEST_IMG",node-name=file \
121
+ -blockdev driver=$IMGFMT,file=file,node-name=fmt
122
+run_test -blockdev driver=file,filename="$TEST_IMG",node-name=file \
123
+ -blockdev driver=raw,file=file,node-name=raw \
124
+ -blockdev driver=$IMGFMT,file=raw,node-name=fmt
125
+
126
+echo
127
+echo "=== -blockdev with a filter on top ==="
128
+echo
129
+
130
+run_test -blockdev driver=file,filename="$TEST_IMG",node-name=file \
131
+ -blockdev driver=$IMGFMT,file=file,node-name=fmt \
132
+ -blockdev driver=copy-on-read,file=fmt,node-name=filter
133
+
134
+echo
135
+echo "=== -blockdev with a backing file ==="
136
+echo
137
+
138
+TEST_IMG="$TEST_IMG.base" _make_test_img $size
139
+
140
+IMGOPTS="backing_file=$TEST_IMG.base" \
141
+run_test -blockdev driver=file,filename="$TEST_IMG.base",node-name=backing-file \
142
+ -blockdev driver=file,filename="$TEST_IMG",node-name=file \
143
+ -blockdev driver=$IMGFMT,file=file,backing=backing-file,node-name=fmt
144
+
145
+IMGOPTS="backing_file=$TEST_IMG.base" \
146
+run_test -blockdev driver=file,filename="$TEST_IMG.base",node-name=backing-file \
147
+ -blockdev driver=$IMGFMT,file=backing-file,node-name=backing-fmt \
148
+ -blockdev driver=file,filename="$TEST_IMG",node-name=file \
149
+ -blockdev driver=$IMGFMT,file=file,backing=backing-fmt,node-name=fmt
150
+
151
+# A snapshot should be present on the overlay, but not the backing file
152
+echo Internal snapshots on overlay:
153
+$QEMU_IMG snapshot -l "$TEST_IMG" | _filter_date | _filter_vmstate_size
154
+
155
+echo Internal snapshots on backing file:
156
+$QEMU_IMG snapshot -l "$TEST_IMG.base" | _filter_date | _filter_vmstate_size
157
+
158
+echo
159
+echo "=== -blockdev with NBD server on the backing file ==="
160
+echo
161
+
162
+IMGOPTS="backing_file=$TEST_IMG.base" _make_test_img $size
163
+cat <<EOF |
164
+nbd_server_start unix:$TEST_DIR/nbd
165
+nbd_server_add -w backing-fmt
166
+savevm snap0
167
+info snapshots
168
+loadvm snap0
169
+EOF
170
+run_qemu -blockdev driver=file,filename="$TEST_IMG.base",node-name=backing-file \
171
+ -blockdev driver=$IMGFMT,file=backing-file,node-name=backing-fmt \
172
+ -blockdev driver=file,filename="$TEST_IMG",node-name=file \
173
+ -blockdev driver=$IMGFMT,file=file,backing=backing-fmt,node-name=fmt |
174
+ _filter_date
175
+
176
+# This time, a snapshot should be created on both files
177
+echo Internal snapshots on overlay:
178
+$QEMU_IMG snapshot -l "$TEST_IMG" | _filter_date | _filter_vmstate_size
179
+
180
+echo Internal snapshots on backing file:
181
+$QEMU_IMG snapshot -l "$TEST_IMG.base" | _filter_date | _filter_vmstate_size
182
+
183
+# success, all done
184
+echo "*** done"
185
+rm -f $seq.full
186
+status=0
187
diff --git a/tests/qemu-iotests/267.out b/tests/qemu-iotests/267.out
12
new file mode 100644
188
new file mode 100644
13
index XXXXXXX..XXXXXXX
189
index XXXXXXX..XXXXXXX
14
--- /dev/null
190
--- /dev/null
15
+++ b/tests/test-image-locking.c
191
+++ b/tests/qemu-iotests/267.out
16
@@ -XXX,XX +XXX,XX @@
192
@@ -XXX,XX +XXX,XX @@
17
+/*
193
+QA output created by 267
18
+ * Image locking tests
194
+
19
+ *
195
+=== No block devices at all ===
20
+ * Copyright (c) 2018 Red Hat Inc.
196
+
21
+ *
197
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
22
+ * Author: Fam Zheng <famz@redhat.com>
198
+Testing:
23
+ *
199
+QEMU X.Y.Z monitor - type 'help' for more information
24
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
200
+(qemu) savevm snap0
25
+ * of this software and associated documentation files (the "Software"), to deal
201
+Error: No block device can accept snapshots
26
+ * in the Software without restriction, including without limitation the rights
202
+(qemu) info snapshots
27
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
203
+No available block device supports snapshots
28
+ * copies of the Software, and to permit persons to whom the Software is
204
+(qemu) loadvm snap0
29
+ * furnished to do so, subject to the following conditions:
205
+Error: No block device supports snapshots
30
+ *
206
+(qemu) quit
31
+ * The above copyright notice and this permission notice shall be included in
207
+
32
+ * all copies or substantial portions of the Software.
208
+
33
+ *
209
+=== -drive if=none ===
34
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
210
+
35
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
211
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
36
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
212
+Testing: -drive driver=file,file=TEST_DIR/t.IMGFMT,if=none
37
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
213
+QEMU X.Y.Z monitor - type 'help' for more information
38
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
214
+(qemu) savevm snap0
39
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
215
+Error: Device 'none0' is writable but does not support snapshots
40
+ * THE SOFTWARE.
216
+(qemu) info snapshots
41
+ */
217
+No available block device supports snapshots
42
+
218
+(qemu) loadvm snap0
43
+#include "qemu/osdep.h"
219
+Error: Device 'none0' is writable but does not support snapshots
44
+#include "block/block.h"
220
+(qemu) quit
45
+#include "sysemu/block-backend.h"
221
+
46
+#include "qapi/error.h"
222
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
47
+#include "qapi/qmp/qdict.h"
223
+Testing: -drive driver=IMGFMT,file=TEST_DIR/t.IMGFMT,if=none
48
+
224
+QEMU X.Y.Z monitor - type 'help' for more information
49
+static BlockBackend *open_image(const char *path,
225
+(qemu) savevm snap0
50
+ uint64_t perm, uint64_t shared_perm,
226
+(qemu) info snapshots
51
+ Error **errp)
227
+List of snapshots present on all disks:
228
+ID TAG VM SIZE DATE VM CLOCK
229
+-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
230
+(qemu) loadvm snap0
231
+(qemu) quit
232
+
233
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
234
+Testing: -drive driver=IMGFMT,file=TEST_DIR/t.IMGFMT,if=none -device virtio-blk,drive=none0
235
+QEMU X.Y.Z monitor - type 'help' for more information
236
+(qemu) savevm snap0
237
+(qemu) info snapshots
238
+List of snapshots present on all disks:
239
+ID TAG VM SIZE DATE VM CLOCK
240
+-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
241
+(qemu) loadvm snap0
242
+(qemu) quit
243
+
244
+
245
+=== -drive if=virtio ===
246
+
247
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
248
+Testing: -drive driver=file,file=TEST_DIR/t.IMGFMT,if=virtio
249
+QEMU X.Y.Z monitor - type 'help' for more information
250
+(qemu) savevm snap0
251
+Error: Device 'virtio0' is writable but does not support snapshots
252
+(qemu) info snapshots
253
+No available block device supports snapshots
254
+(qemu) loadvm snap0
255
+Error: Device 'virtio0' is writable but does not support snapshots
256
+(qemu) quit
257
+
258
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
259
+Testing: -drive driver=IMGFMT,file=TEST_DIR/t.IMGFMT,if=virtio
260
+QEMU X.Y.Z monitor - type 'help' for more information
261
+(qemu) savevm snap0
262
+(qemu) info snapshots
263
+List of snapshots present on all disks:
264
+ID TAG VM SIZE DATE VM CLOCK
265
+-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
266
+(qemu) loadvm snap0
267
+(qemu) quit
268
+
269
+
270
+=== Simple -blockdev ===
271
+
272
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
273
+Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=file
274
+QEMU X.Y.Z monitor - type 'help' for more information
275
+(qemu) savevm snap0
276
+Error: Device '' is writable but does not support snapshots
277
+(qemu) info snapshots
278
+No available block device supports snapshots
279
+(qemu) loadvm snap0
280
+Error: Device '' is writable but does not support snapshots
281
+(qemu) quit
282
+
283
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
284
+Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=file -blockdev driver=IMGFMT,file=file,node-name=fmt
285
+QEMU X.Y.Z monitor - type 'help' for more information
286
+(qemu) savevm snap0
287
+(qemu) info snapshots
288
+List of snapshots present on all disks:
289
+ID TAG VM SIZE DATE VM CLOCK
290
+-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
291
+(qemu) loadvm snap0
292
+(qemu) quit
293
+
294
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
295
+Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=file -blockdev driver=raw,file=file,node-name=raw -blockdev driver=IMGFMT,file=raw,node-name=fmt
296
+QEMU X.Y.Z monitor - type 'help' for more information
297
+(qemu) savevm snap0
298
+(qemu) info snapshots
299
+List of snapshots present on all disks:
300
+ID TAG VM SIZE DATE VM CLOCK
301
+-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
302
+(qemu) loadvm snap0
303
+(qemu) quit
304
+
305
+
306
+=== -blockdev with a filter on top ===
307
+
308
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
309
+Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=file -blockdev driver=IMGFMT,file=file,node-name=fmt -blockdev driver=copy-on-read,file=fmt,node-name=filter
310
+QEMU X.Y.Z monitor - type 'help' for more information
311
+(qemu) savevm snap0
312
+(qemu) info snapshots
313
+List of snapshots present on all disks:
314
+ID TAG VM SIZE DATE VM CLOCK
315
+-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
316
+(qemu) loadvm snap0
317
+(qemu) quit
318
+
319
+
320
+=== -blockdev with a backing file ===
321
+
322
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
323
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
324
+Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT.base,node-name=backing-file -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=file -blockdev driver=IMGFMT,file=file,backing=backing-file,node-name=fmt
325
+QEMU X.Y.Z monitor - type 'help' for more information
326
+(qemu) savevm snap0
327
+(qemu) info snapshots
328
+List of snapshots present on all disks:
329
+ID TAG VM SIZE DATE VM CLOCK
330
+-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
331
+(qemu) loadvm snap0
332
+(qemu) quit
333
+
334
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
335
+Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT.base,node-name=backing-file -blockdev driver=IMGFMT,file=backing-file,node-name=backing-fmt -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=file -blockdev driver=IMGFMT,file=file,backing=backing-fmt,node-name=fmt
336
+QEMU X.Y.Z monitor - type 'help' for more information
337
+(qemu) savevm snap0
338
+(qemu) info snapshots
339
+List of snapshots present on all disks:
340
+ID TAG VM SIZE DATE VM CLOCK
341
+-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
342
+(qemu) loadvm snap0
343
+(qemu) quit
344
+
345
+Internal snapshots on overlay:
346
+Snapshot list:
347
+ID TAG VM SIZE DATE VM CLOCK
348
+1 snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
349
+Internal snapshots on backing file:
350
+
351
+=== -blockdev with NBD server on the backing file ===
352
+
353
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
354
+Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT.base,node-name=backing-file -blockdev driver=IMGFMT,file=backing-file,node-name=backing-fmt -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=file -blockdev driver=IMGFMT,file=file,backing=backing-fmt,node-name=fmt
355
+QEMU X.Y.Z monitor - type 'help' for more information
356
+(qemu) nbd_server_start unix:TEST_DIR/nbd
357
+(qemu) nbd_server_add -w backing-fmt
358
+(qemu) savevm snap0
359
+(qemu) info snapshots
360
+List of snapshots present on all disks:
361
+ID TAG VM SIZE DATE VM CLOCK
362
+-- snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
363
+(qemu) loadvm snap0
364
+(qemu) quit
365
+
366
+Internal snapshots on overlay:
367
+Snapshot list:
368
+ID TAG VM SIZE DATE VM CLOCK
369
+1 snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
370
+Internal snapshots on backing file:
371
+Snapshot list:
372
+ID TAG VM SIZE DATE VM CLOCK
373
+1 snap0 SIZE yyyy-mm-dd hh:mm:ss 00:00:00.000
374
+*** done
375
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
376
index XXXXXXX..XXXXXXX 100644
377
--- a/tests/qemu-iotests/common.filter
378
+++ b/tests/qemu-iotests/common.filter
379
@@ -XXX,XX +XXX,XX @@
380
# standard filters
381
#
382
383
-# ctime(3) dates
384
-#
385
_filter_date()
386
{
387
- $SED \
388
- -e 's/[A-Z][a-z][a-z] [A-z][a-z][a-z] *[0-9][0-9]* [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9][0-9][0-9][0-9]$/DATE/'
389
+ $SED -re 's/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/yyyy-mm-dd hh:mm:ss/'
390
+}
391
+
392
+_filter_vmstate_size()
52
+{
393
+{
53
+ Error *local_err = NULL;
394
+ $SED -r -e 's/[0-9. ]{5} [KMGT]iB/ SIZE/' \
54
+ BlockBackend *blk;
395
+ -e 's/[0-9. ]{5} B/ SIZE/'
55
+ QDict *options = qdict_new();
396
}
56
+
397
57
+ qdict_put_str(options, "driver", "raw");
398
_filter_generated_node_ids()
58
+ blk = blk_new_open(path, NULL, options, BDRV_O_RDWR, &local_err);
399
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
59
+ if (blk) {
60
+ g_assert_null(local_err);
61
+ if (blk_set_perm(blk, perm, shared_perm, errp)) {
62
+ blk_unref(blk);
63
+ blk = NULL;
64
+ }
65
+ } else {
66
+ error_propagate(errp, local_err);
67
+ }
68
+ return blk;
69
+}
70
+
71
+static void check_locked_bytes(int fd, uint64_t perm_locks,
72
+ uint64_t shared_perm_locks)
73
+{
74
+ int i;
75
+
76
+ if (!perm_locks && !shared_perm_locks) {
77
+ g_assert(!qemu_lock_fd_test(fd, 0, 0, true));
78
+ return;
79
+ }
80
+ for (i = 0; (1ULL << i) <= BLK_PERM_ALL; i++) {
81
+ uint64_t bit = (1ULL << i);
82
+ bool perm_expected = !!(bit & perm_locks);
83
+ bool shared_perm_expected = !!(bit & shared_perm_locks);
84
+ g_assert_cmpint(perm_expected, ==,
85
+ !!qemu_lock_fd_test(fd, 100 + i, 1, true));
86
+ g_assert_cmpint(shared_perm_expected, ==,
87
+ !!qemu_lock_fd_test(fd, 200 + i, 1, true));
88
+ }
89
+}
90
+
91
+static void test_image_locking_basic(void)
92
+{
93
+ BlockBackend *blk1, *blk2, *blk3;
94
+ char img_path[] = "/tmp/qtest.XXXXXX";
95
+ uint64_t perm, shared_perm;
96
+
97
+ int fd = mkstemp(img_path);
98
+ assert(fd >= 0);
99
+
100
+ perm = BLK_PERM_WRITE | BLK_PERM_CONSISTENT_READ;
101
+ shared_perm = BLK_PERM_ALL;
102
+ blk1 = open_image(img_path, perm, shared_perm, &error_abort);
103
+ g_assert(blk1);
104
+
105
+ check_locked_bytes(fd, perm, ~shared_perm);
106
+
107
+ /* compatible perm between blk1 and blk2 */
108
+ blk2 = open_image(img_path, perm | BLK_PERM_RESIZE, shared_perm, NULL);
109
+ g_assert(blk2);
110
+ check_locked_bytes(fd, perm | BLK_PERM_RESIZE, ~shared_perm);
111
+
112
+ /* incompatible perm with already open blk1 and blk2 */
113
+ blk3 = open_image(img_path, perm, BLK_PERM_WRITE_UNCHANGED, NULL);
114
+ g_assert_null(blk3);
115
+
116
+ blk_unref(blk2);
117
+
118
+ /* Check that extra bytes in blk2 are correctly unlocked */
119
+ check_locked_bytes(fd, perm, ~shared_perm);
120
+
121
+ blk_unref(blk1);
122
+
123
+ /* Image is unused, no lock there */
124
+ check_locked_bytes(fd, 0, 0);
125
+ blk3 = open_image(img_path, perm, BLK_PERM_WRITE_UNCHANGED, &error_abort);
126
+ g_assert(blk3);
127
+ blk_unref(blk3);
128
+ close(fd);
129
+ unlink(img_path);
130
+}
131
+
132
+static void test_set_perm_abort(void)
133
+{
134
+ BlockBackend *blk1, *blk2;
135
+ char img_path[] = "/tmp/qtest.XXXXXX";
136
+ uint64_t perm, shared_perm;
137
+ int r;
138
+ int fd = mkstemp(img_path);
139
+ assert(fd >= 0);
140
+
141
+ perm = BLK_PERM_WRITE | BLK_PERM_CONSISTENT_READ;
142
+ shared_perm = BLK_PERM_ALL;
143
+ blk1 = open_image(img_path, perm, shared_perm, &error_abort);
144
+ g_assert(blk1);
145
+
146
+ blk2 = open_image(img_path, perm, shared_perm, &error_abort);
147
+ g_assert(blk2);
148
+
149
+ check_locked_bytes(fd, perm, ~shared_perm);
150
+
151
+ /* A failed blk_set_perm mustn't change perm status (locked bytes) */
152
+ r = blk_set_perm(blk2, perm | BLK_PERM_RESIZE, BLK_PERM_WRITE_UNCHANGED,
153
+ NULL);
154
+ g_assert_cmpint(r, !=, 0);
155
+ check_locked_bytes(fd, perm, ~shared_perm);
156
+ blk_unref(blk1);
157
+ blk_unref(blk2);
158
+}
159
+
160
+int main(int argc, char **argv)
161
+{
162
+ bdrv_init();
163
+ qemu_init_main_loop(&error_abort);
164
+
165
+ g_test_init(&argc, &argv, NULL);
166
+
167
+ if (qemu_has_ofd_lock()) {
168
+ g_test_add_func("/image-locking/basic", test_image_locking_basic);
169
+ g_test_add_func("/image-locking/set-perm-abort", test_set_perm_abort);
170
+ }
171
+
172
+ return g_test_run();
173
+}
174
diff --git a/tests/Makefile.include b/tests/Makefile.include
175
index XXXXXXX..XXXXXXX 100644
400
index XXXXXXX..XXXXXXX 100644
176
--- a/tests/Makefile.include
401
--- a/tests/qemu-iotests/group
177
+++ b/tests/Makefile.include
402
+++ b/tests/qemu-iotests/group
178
@@ -XXX,XX +XXX,XX @@ check-unit-y += tests/test-bdrv-drain$(EXESUF)
403
@@ -XXX,XX +XXX,XX @@
179
check-unit-y += tests/test-blockjob$(EXESUF)
404
263 rw quick
180
check-unit-y += tests/test-blockjob-txn$(EXESUF)
405
265 rw auto quick
181
check-unit-y += tests/test-block-backend$(EXESUF)
406
266 rw quick
182
+check-unit-y += tests/test-image-locking$(EXESUF)
407
+267 rw auto quick snapshot
183
check-unit-y += tests/test-x86-cpuid$(EXESUF)
184
# all code tested by test-x86-cpuid is inside topology.h
185
ifeq ($(CONFIG_SOFTMMU),y)
186
@@ -XXX,XX +XXX,XX @@ tests/test-bdrv-drain$(EXESUF): tests/test-bdrv-drain.o $(test-block-obj-y) $(te
187
tests/test-blockjob$(EXESUF): tests/test-blockjob.o $(test-block-obj-y) $(test-util-obj-y)
188
tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y)
189
tests/test-block-backend$(EXESUF): tests/test-block-backend.o $(test-block-obj-y) $(test-util-obj-y)
190
+tests/test-image-locking$(EXESUF): tests/test-image-locking.o $(test-block-obj-y) $(test-util-obj-y)
191
tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y)
192
tests/test-iov$(EXESUF): tests/test-iov.o $(test-util-obj-y)
193
tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o $(test-util-obj-y) $(test-crypto-obj-y)
194
--
408
--
195
2.19.1
409
2.20.1
196
410
197
411
diff view generated by jsdifflib
1
From: Jeff Cody <jcody@redhat.com>
1
Running iotests is not required to build QEMU, so we can have stricter
2
version requirements for Python here and can make use of new features
3
and drop compatibility code earlier.
2
4
3
This adds configure options to control the following block drivers:
5
This makes qemu-iotests skip all Python tests if a Python version before
6
3.6 is used for the build.
4
7
5
* Bochs
8
Suggested-by: Eduardo Habkost <ehabkost@redhat.com>
6
* Cloop
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
* Dmg
10
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
8
* Qcow (V1)
11
Reviewed-by: Thomas Huth <thuth@redhat.com>
9
* Vdi
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
* Vvfat
13
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
* qed
14
---
12
* parallels
15
tests/qemu-iotests/check | 13 ++++++++++++-
13
* sheepdog
16
1 file changed, 12 insertions(+), 1 deletion(-)
14
17
15
Each of these defaults to being enabled.
18
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
16
17
Signed-off-by: Jeff Cody <jcody@redhat.com>
18
Signed-off-by: Markus Armbruster <armbru@redhat.com>
19
Message-id: 20181107063644.2254-1-armbru@redhat.com
20
Signed-off-by: Max Reitz <mreitz@redhat.com>
21
---
22
configure | 91 +++++++++++++++++++++++++++++++++++++++++++++
23
block/Makefile.objs | 22 ++++++++---
24
2 files changed, 107 insertions(+), 6 deletions(-)
25
26
diff --git a/configure b/configure
27
index XXXXXXX..XXXXXXX 100755
19
index XXXXXXX..XXXXXXX 100755
28
--- a/configure
20
--- a/tests/qemu-iotests/check
29
+++ b/configure
21
+++ b/tests/qemu-iotests/check
30
@@ -XXX,XX +XXX,XX @@ tcmalloc="no"
22
@@ -XXX,XX +XXX,XX @@ then
31
jemalloc="no"
23
export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper"
32
replication="yes"
33
vxhs=""
34
+bochs="yes"
35
+cloop="yes"
36
+dmg="yes"
37
+qcow1="yes"
38
+vdi="yes"
39
+vvfat="yes"
40
+qed="yes"
41
+parallels="yes"
42
+sheepdog="yes"
43
libxml2=""
44
docker="no"
45
debug_mutex="no"
46
@@ -XXX,XX +XXX,XX @@ for opt do
47
;;
48
--enable-vxhs) vxhs="yes"
49
;;
50
+ --disable-bochs) bochs="no"
51
+ ;;
52
+ --enable-bochs) bochs="yes"
53
+ ;;
54
+ --disable-cloop) cloop="no"
55
+ ;;
56
+ --enable-cloop) cloop="yes"
57
+ ;;
58
+ --disable-dmg) dmg="no"
59
+ ;;
60
+ --enable-dmg) dmg="yes"
61
+ ;;
62
+ --disable-qcow1) qcow1="no"
63
+ ;;
64
+ --enable-qcow1) qcow1="yes"
65
+ ;;
66
+ --disable-vdi) vdi="no"
67
+ ;;
68
+ --enable-vdi) vdi="yes"
69
+ ;;
70
+ --disable-vvfat) vvfat="no"
71
+ ;;
72
+ --enable-vvfat) vvfat="yes"
73
+ ;;
74
+ --disable-qed) qed="no"
75
+ ;;
76
+ --enable-qed) qed="yes"
77
+ ;;
78
+ --disable-parallels) parallels="no"
79
+ ;;
80
+ --enable-parallels) parallels="yes"
81
+ ;;
82
+ --disable-sheepdog) sheepdog="no"
83
+ ;;
84
+ --enable-sheepdog) sheepdog="yes"
85
+ ;;
86
--disable-vhost-user) vhost_user="no"
87
;;
88
--enable-vhost-user)
89
@@ -XXX,XX +XXX,XX @@ disabled with --disable-FEATURE, default is enabled if available:
90
qom-cast-debug cast debugging support
91
tools build qemu-io, qemu-nbd and qemu-image tools
92
vxhs Veritas HyperScale vDisk backend support
93
+ bochs bochs image format support
94
+ cloop cloop image format support
95
+ dmg dmg image format support
96
+ qcow1 qcow v1 image format support
97
+ vdi vdi image format support
98
+ vvfat vvfat image format support
99
+ qed qed image format support
100
+ parallels parallels image format support
101
+ sheepdog sheepdog block driver support
102
crypto-afalg Linux AF_ALG crypto backend driver
103
vhost-user vhost-user support
104
capstone capstone disassembler support
105
@@ -XXX,XX +XXX,XX @@ echo "jemalloc support $jemalloc"
106
echo "avx2 optimization $avx2_opt"
107
echo "replication support $replication"
108
echo "VxHS block device $vxhs"
109
+echo "bochs support $bochs"
110
+echo "cloop support $cloop"
111
+echo "dmg support $dmg"
112
+echo "qcow v1 support $qcow1"
113
+echo "vdi support $vdi"
114
+echo "vvfat support $vvfat"
115
+echo "qed support $qed"
116
+echo "parallels support $parallels"
117
+echo "sheepdog support $sheepdog"
118
echo "capstone $capstone"
119
echo "docker $docker"
120
echo "libpmem support $libpmem"
121
@@ -XXX,XX +XXX,XX @@ if test "$libpmem" = "yes" ; then
122
echo "CONFIG_LIBPMEM=y" >> $config_host_mak
123
fi
24
fi
124
25
125
+if test "$bochs" = "yes" ; then
26
+python_usable=false
126
+ echo "CONFIG_BOCHS=y" >> $config_host_mak
27
+if $PYTHON -c 'import sys; sys.exit(0 if sys.version_info >= (3,6) else 1)'
127
+fi
28
+then
128
+if test "$cloop" = "yes" ; then
29
+ python_usable=true
129
+ echo "CONFIG_CLOOP=y" >> $config_host_mak
130
+fi
131
+if test "$dmg" = "yes" ; then
132
+ echo "CONFIG_DMG=y" >> $config_host_mak
133
+fi
134
+if test "$qcow1" = "yes" ; then
135
+ echo "CONFIG_QCOW1=y" >> $config_host_mak
136
+fi
137
+if test "$vdi" = "yes" ; then
138
+ echo "CONFIG_VDI=y" >> $config_host_mak
139
+fi
140
+if test "$vvfat" = "yes" ; then
141
+ echo "CONFIG_VVFAT=y" >> $config_host_mak
142
+fi
143
+if test "$qed" = "yes" ; then
144
+ echo "CONFIG_QED=y" >> $config_host_mak
145
+fi
146
+if test "$parallels" = "yes" ; then
147
+ echo "CONFIG_PARALLELS=y" >> $config_host_mak
148
+fi
149
+if test "$sheepdog" = "yes" ; then
150
+ echo "CONFIG_SHEEPDOG=y" >> $config_host_mak
151
+fi
30
+fi
152
+
31
+
153
if test "$tcg_interpreter" = "yes"; then
32
default_machine=$($QEMU_PROG -machine help | sed -n '/(default)/ s/ .*//p')
154
QEMU_INCLUDES="-iquote \$(SRC_PATH)/tcg/tci $QEMU_INCLUDES"
33
default_alias_machine=$($QEMU_PROG -machine help | \
155
elif test "$ARCH" = "sparc64" ; then
34
sed -n "/(alias of $default_machine)/ { s/ .*//p; q; }")
156
diff --git a/block/Makefile.objs b/block/Makefile.objs
35
@@ -XXX,XX +XXX,XX @@ do
157
index XXXXXXX..XXXXXXX 100644
36
start=$(_wallclock)
158
--- a/block/Makefile.objs
37
159
+++ b/block/Makefile.objs
38
if [ "$(head -n 1 "$source_iotests/$seq")" == "#!/usr/bin/env python" ]; then
160
@@ -XXX,XX +XXX,XX @@
39
- run_command="$PYTHON $seq"
161
-block-obj-y += raw-format.o qcow.o vdi.o vmdk.o cloop.o bochs.o vpc.o vvfat.o dmg.o
40
+ if $python_usable; then
162
+block-obj-y += raw-format.o vmdk.o vpc.o
41
+ run_command="$PYTHON $seq"
163
+block-obj-$(CONFIG_QCOW1) += qcow.o
42
+ else
164
+block-obj-$(CONFIG_VDI) += vdi.o
43
+ run_command="false"
165
+block-obj-$(CONFIG_CLOOP) += cloop.o
44
+ echo "Unsupported Python version" > $seq.notrun
166
+block-obj-$(CONFIG_BOCHS) += bochs.o
45
+ fi
167
+block-obj-$(CONFIG_VVFAT) += vvfat.o
46
else
168
+block-obj-$(CONFIG_DMG) += dmg.o
47
run_command="./$seq"
169
+
48
fi
170
block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o qcow2-bitmap.o
171
-block-obj-y += qed.o qed-l2-cache.o qed-table.o qed-cluster.o
172
-block-obj-y += qed-check.o
173
+block-obj-$(CONFIG_QED) += qed.o qed-l2-cache.o qed-table.o qed-cluster.o
174
+block-obj-$(CONFIG_QED) += qed-check.o
175
block-obj-y += vhdx.o vhdx-endian.o vhdx-log.o
176
block-obj-y += quorum.o
177
-block-obj-y += parallels.o blkdebug.o blkverify.o blkreplay.o
178
+block-obj-y += blkdebug.o blkverify.o blkreplay.o
179
+block-obj-$(CONFIG_PARALLELS) += parallels.o
180
block-obj-y += blklogwrites.o
181
block-obj-y += block-backend.o snapshot.o qapi.o
182
block-obj-$(CONFIG_WIN32) += file-win32.o win32-aio.o
183
@@ -XXX,XX +XXX,XX @@ block-obj-y += null.o mirror.o commit.o io.o create.o
184
block-obj-y += throttle-groups.o
185
block-obj-$(CONFIG_LINUX) += nvme.o
186
187
-block-obj-y += nbd.o nbd-client.o sheepdog.o
188
+block-obj-y += nbd.o nbd-client.o
189
+block-obj-$(CONFIG_SHEEPDOG) += sheepdog.o
190
block-obj-$(CONFIG_LIBISCSI) += iscsi.o
191
block-obj-$(if $(CONFIG_LIBISCSI),y,n) += iscsi-opts.o
192
block-obj-$(CONFIG_LIBNFS) += nfs.o
193
@@ -XXX,XX +XXX,XX @@ gluster.o-libs := $(GLUSTERFS_LIBS)
194
vxhs.o-libs := $(VXHS_LIBS)
195
ssh.o-cflags := $(LIBSSH2_CFLAGS)
196
ssh.o-libs := $(LIBSSH2_LIBS)
197
-block-obj-$(if $(CONFIG_BZIP2),m,n) += dmg-bz2.o
198
+block-obj-dmg-bz2-$(CONFIG_BZIP2) += dmg-bz2.o
199
+block-obj-$(if $(CONFIG_DMG),m,n) += $(block-obj-dmg-bz2-y)
200
dmg-bz2.o-libs := $(BZIP2_LIBS)
201
qcow.o-libs := -lz
202
linux-aio.o-libs := -laio
203
--
49
--
204
2.19.1
50
2.20.1
205
51
206
52
diff view generated by jsdifflib
1
From: zhenwei pi <pizhenwei@bytedance.com>
1
Some scripts check the Python version number and have two code paths to
2
accomodate both Python 2 and 3. Remove the code specific to Python 2 and
3
assert the minimum version of 3.6 instead (check skips Python tests in
4
this case, so the assertion would only ever trigger if a Python script
5
is executed manually).
2
6
3
Function block_latency_histogram_set may return error, but qapi ignore this.
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
This can be reproduced easily by qmp command:
8
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
5
virsh qemu-monitor-command INSTANCE '{"execute":"x-block-latency-histogram-set",
9
Reviewed-by: Thomas Huth <thuth@redhat.com>
6
"arguments":{"device":"drive-virtio-disk1","boundaries":[10,200,40]}}'
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
In fact this command does not work, but we still get success result.
11
Reviewed-by: John Snow <jsnow@redhat.com>
12
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
13
---
14
tests/qemu-iotests/044 | 3 ---
15
tests/qemu-iotests/163 | 3 ---
16
tests/qemu-iotests/iotests.py | 13 +++----------
17
3 files changed, 3 insertions(+), 16 deletions(-)
8
18
9
qmp_x_block_latency_histogram_set is a batch setting API, report error ASAP.
19
diff --git a/tests/qemu-iotests/044 b/tests/qemu-iotests/044
10
20
index XXXXXXX..XXXXXXX 100755
11
Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
21
--- a/tests/qemu-iotests/044
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
+++ b/tests/qemu-iotests/044
13
---
23
@@ -XXX,XX +XXX,XX @@ import struct
14
blockdev.c | 19 ++++++++++++++++---
24
import subprocess
15
1 file changed, 16 insertions(+), 3 deletions(-)
25
import sys
16
26
17
diff --git a/blockdev.c b/blockdev.c
27
-if sys.version_info.major == 2:
28
- range = xrange
29
-
30
test_img = os.path.join(iotests.test_dir, 'test.img')
31
32
class TestRefcountTableGrowth(iotests.QMPTestCase):
33
diff --git a/tests/qemu-iotests/163 b/tests/qemu-iotests/163
34
index XXXXXXX..XXXXXXX 100755
35
--- a/tests/qemu-iotests/163
36
+++ b/tests/qemu-iotests/163
37
@@ -XXX,XX +XXX,XX @@
38
import os, random, iotests, struct, qcow2, sys
39
from iotests import qemu_img, qemu_io, image_size
40
41
-if sys.version_info.major == 2:
42
- range = xrange
43
-
44
test_img = os.path.join(iotests.test_dir, 'test.img')
45
check_img = os.path.join(iotests.test_dir, 'check.img')
46
47
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
18
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
19
--- a/blockdev.c
49
--- a/tests/qemu-iotests/iotests.py
20
+++ b/blockdev.c
50
+++ b/tests/qemu-iotests/iotests.py
21
@@ -XXX,XX +XXX,XX @@ void qmp_x_block_latency_histogram_set(
51
@@ -XXX,XX +XXX,XX @@ from collections import OrderedDict
22
{
52
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
23
BlockBackend *blk = blk_by_name(device);
53
from qemu import qtest
24
BlockAcctStats *stats;
54
25
+ int ret;
55
+assert sys.version_info >= (3,6)
26
56
27
if (!blk) {
57
# This will not work if arguments contain spaces but is necessary if we
28
error_setg(errp, "Device '%s' not found", device);
58
# want to support the override options that ./check supports.
29
@@ -XXX,XX +XXX,XX @@ void qmp_x_block_latency_histogram_set(
59
@@ -XXX,XX +XXX,XX @@ def image_size(img):
30
}
60
return json.loads(r)['virtual-size']
31
61
32
if (has_boundaries || has_boundaries_read) {
62
def is_str(val):
33
- block_latency_histogram_set(
63
- if sys.version_info.major >= 3:
34
+ ret = block_latency_histogram_set(
64
- return isinstance(val, str)
35
stats, BLOCK_ACCT_READ,
65
- else:
36
has_boundaries_read ? boundaries_read : boundaries);
66
- return isinstance(val, str) or isinstance(val, unicode)
37
+ if (ret) {
67
+ return isinstance(val, str)
38
+ error_setg(errp, "Device '%s' set read boundaries fail", device);
68
39
+ return;
69
test_dir_re = re.compile(r"%s" % test_dir)
40
+ }
70
def filter_test_dir(msg):
41
}
71
@@ -XXX,XX +XXX,XX @@ def execute_test(test_function=None,
42
72
else:
43
if (has_boundaries || has_boundaries_write) {
73
# We need to filter out the time taken from the output so that
44
- block_latency_histogram_set(
74
# qemu-iotest can reliably diff the results against master output.
45
+ ret = block_latency_histogram_set(
75
- if sys.version_info.major >= 3:
46
stats, BLOCK_ACCT_WRITE,
76
- output = io.StringIO()
47
has_boundaries_write ? boundaries_write : boundaries);
77
- else:
48
+ if (ret) {
78
- # io.StringIO is for unicode strings, which is not what
49
+ error_setg(errp, "Device '%s' set write boundaries fail", device);
79
- # 2.x's test runner emits.
50
+ return;
80
- output = io.BytesIO()
51
+ }
81
+ output = io.StringIO()
52
}
82
53
83
logging.basicConfig(level=(logging.DEBUG if debug else logging.WARN))
54
if (has_boundaries || has_boundaries_flush) {
55
- block_latency_histogram_set(
56
+ ret = block_latency_histogram_set(
57
stats, BLOCK_ACCT_FLUSH,
58
has_boundaries_flush ? boundaries_flush : boundaries);
59
+ if (ret) {
60
+ error_setg(errp, "Device '%s' set flush boundaries fail", device);
61
+ return;
62
+ }
63
}
64
}
65
84
66
--
85
--
67
2.19.1
86
2.20.1
68
87
69
88
diff view generated by jsdifflib
Deleted patch
1
From: Peter Maydell <peter.maydell@linaro.org>
2
1
3
In the function external_snapshot_prepare() we have a
4
BlockdevSnapshotSync struct, which has the usual combination
5
of has_snapshot_node_name and snapshot_node_name fields for an
6
optional field. We set up a local variable
7
const char *snapshot_node_name =
8
s->has_snapshot_node_name ? s->snapshot_node_name : NULL;
9
10
and then mostly use "if (!snapshot_node_name)" for checking
11
whether we have a snapshot node name. The exception is that in
12
one place we check s->has_snapshot_node_name instead. This
13
confuses Coverity (CID 1396473), which thinks it might be
14
possible to get here with s->has_snapshot_node_name true but
15
snapshot_node_name NULL, and warns that the call to
16
qdict_put_str() will segfault in that case.
17
18
Make the code consistent and unconfuse Coverity by using
19
the same check for this conditional that we do in the rest
20
of the surrounding code.
21
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Alberto Garcia <berto@igalia.com>
24
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
25
---
26
blockdev.c | 2 +-
27
1 file changed, 1 insertion(+), 1 deletion(-)
28
29
diff --git a/blockdev.c b/blockdev.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/blockdev.c
32
+++ b/blockdev.c
33
@@ -XXX,XX +XXX,XX @@ static void external_snapshot_prepare(BlkActionState *common,
34
}
35
36
options = qdict_new();
37
- if (s->has_snapshot_node_name) {
38
+ if (snapshot_node_name) {
39
qdict_put_str(options, "node-name", snapshot_node_name);
40
}
41
qdict_put_str(options, "driver", format);
42
--
43
2.19.1
44
45
diff view generated by jsdifflib
Deleted patch
1
From: Li Qiang <liq3ea@gmail.com>
2
1
3
Currently, when hotplug/unhotplug nvme device, it will cause an
4
assert in object.c. Following is the backtrack:
5
6
ERROR:qom/object.c:981:object_unref: assertion failed: (obj->ref > 0)
7
8
Thread 2 "qemu-system-x86" received signal SIGABRT, Aborted.
9
[Switching to Thread 0x7fffcbd32700 (LWP 18844)]
10
0x00007fffdb9e4fff in raise () from /lib/x86_64-linux-gnu/libc.so.6
11
(gdb) bt
12
/lib/x86_64-linux-gnu/libglib-2.0.so.0
13
/lib/x86_64-linux-gnu/libglib-2.0.so.0
14
qom/object.c:981
15
/home/liqiang02/qemu-upstream/qemu/memory.c:1732
16
/home/liqiang02/qemu-upstream/qemu/memory.c:285
17
util/qemu-thread-posix.c:504
18
/lib/x86_64-linux-gnu/libpthread.so.0
19
20
This is caused by memory_region_unref in nvme_exit.
21
22
Remove it to make the PCIdevice refcount correct.
23
24
Signed-off-by: Li Qiang <liq3ea@gmail.com>
25
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
26
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
27
---
28
hw/block/nvme.c | 3 ---
29
1 file changed, 3 deletions(-)
30
31
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/block/nvme.c
34
+++ b/hw/block/nvme.c
35
@@ -XXX,XX +XXX,XX @@ static void nvme_exit(PCIDevice *pci_dev)
36
g_free(n->namespaces);
37
g_free(n->cq);
38
g_free(n->sq);
39
- if (n->cmbsz) {
40
- memory_region_unref(&n->ctrl_mem);
41
- }
42
43
msix_uninit_exclusive_bar(pci_dev);
44
}
45
--
46
2.19.1
47
48
diff view generated by jsdifflib
Deleted patch
1
From: Li Qiang <liq3ea@gmail.com>
2
1
3
This avoid a memory leak in unhotplug nvme device.
4
5
Signed-off-by: Li Qiang <liq3ea@gmail.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
hw/block/nvme.c | 3 +++
10
1 file changed, 3 insertions(+)
11
12
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/block/nvme.c
15
+++ b/hw/block/nvme.c
16
@@ -XXX,XX +XXX,XX @@ static void nvme_exit(PCIDevice *pci_dev)
17
g_free(n->cq);
18
g_free(n->sq);
19
20
+ if (n->cmb_size_mb) {
21
+ g_free(n->cmbuf);
22
+ }
23
msix_uninit_exclusive_bar(pci_dev);
24
}
25
26
--
27
2.19.1
28
29
diff view generated by jsdifflib
Deleted patch
1
From: Fam Zheng <famz@redhat.com>
2
1
3
If we know we've already locked the bytes, don't do it again; similarly
4
don't unlock a byte if we haven't locked it. This doesn't change the
5
behavior, but fixes a corner case explained below.
6
7
Libvirt had an error handling bug that an image can get its (ownership,
8
file mode, SELinux) permissions changed (RHBZ 1584982) by mistake behind
9
QEMU. Specifically, an image in use by Libvirt VM has:
10
11
$ ls -lhZ b.img
12
-rw-r--r--. qemu qemu system_u:object_r:svirt_image_t:s0:c600,c690 b.img
13
14
Trying to attach it a second time won't work because of image locking.
15
And after the error, it becomes:
16
17
$ ls -lhZ b.img
18
-rw-r--r--. root root system_u:object_r:virt_image_t:s0 b.img
19
20
Then, we won't be able to do OFD lock operations with the existing fd.
21
In other words, the code such as in blk_detach_dev:
22
23
blk_set_perm(blk, 0, BLK_PERM_ALL, &error_abort);
24
25
can abort() QEMU, out of environmental changes.
26
27
This patch is an easy fix to this and the change is regardlessly
28
reasonable, so do it.
29
30
Signed-off-by: Fam Zheng <famz@redhat.com>
31
Reviewed-by: Max Reitz <mreitz@redhat.com>
32
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
33
---
34
block/file-posix.c | 54 +++++++++++++++++++++++++++++++++++++---------
35
1 file changed, 44 insertions(+), 10 deletions(-)
36
37
diff --git a/block/file-posix.c b/block/file-posix.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/block/file-posix.c
40
+++ b/block/file-posix.c
41
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVRawState {
42
uint64_t perm;
43
uint64_t shared_perm;
44
45
+ /* The perms bits whose corresponding bytes are already locked in
46
+ * s->lock_fd. */
47
+ uint64_t locked_perm;
48
+ uint64_t locked_shared_perm;
49
+
50
#ifdef CONFIG_XFS
51
bool is_xfs:1;
52
#endif
53
@@ -XXX,XX +XXX,XX @@ typedef enum {
54
* file; if @unlock == true, also unlock the unneeded bytes.
55
* @shared_perm_lock_bits is the mask of all permissions that are NOT shared.
56
*/
57
-static int raw_apply_lock_bytes(int fd,
58
+static int raw_apply_lock_bytes(BDRVRawState *s, int fd,
59
uint64_t perm_lock_bits,
60
uint64_t shared_perm_lock_bits,
61
bool unlock, Error **errp)
62
{
63
int ret;
64
int i;
65
+ uint64_t locked_perm, locked_shared_perm;
66
+
67
+ if (s) {
68
+ locked_perm = s->locked_perm;
69
+ locked_shared_perm = s->locked_shared_perm;
70
+ } else {
71
+ /*
72
+ * We don't have the previous bits, just lock/unlock for each of the
73
+ * requested bits.
74
+ */
75
+ if (unlock) {
76
+ locked_perm = BLK_PERM_ALL;
77
+ locked_shared_perm = BLK_PERM_ALL;
78
+ } else {
79
+ locked_perm = 0;
80
+ locked_shared_perm = 0;
81
+ }
82
+ }
83
84
PERM_FOREACH(i) {
85
int off = RAW_LOCK_PERM_BASE + i;
86
- if (perm_lock_bits & (1ULL << i)) {
87
+ uint64_t bit = (1ULL << i);
88
+ if ((perm_lock_bits & bit) && !(locked_perm & bit)) {
89
ret = qemu_lock_fd(fd, off, 1, false);
90
if (ret) {
91
error_setg(errp, "Failed to lock byte %d", off);
92
return ret;
93
+ } else if (s) {
94
+ s->locked_perm |= bit;
95
}
96
- } else if (unlock) {
97
+ } else if (unlock && (locked_perm & bit) && !(perm_lock_bits & bit)) {
98
ret = qemu_unlock_fd(fd, off, 1);
99
if (ret) {
100
error_setg(errp, "Failed to unlock byte %d", off);
101
return ret;
102
+ } else if (s) {
103
+ s->locked_perm &= ~bit;
104
}
105
}
106
}
107
PERM_FOREACH(i) {
108
int off = RAW_LOCK_SHARED_BASE + i;
109
- if (shared_perm_lock_bits & (1ULL << i)) {
110
+ uint64_t bit = (1ULL << i);
111
+ if ((shared_perm_lock_bits & bit) && !(locked_shared_perm & bit)) {
112
ret = qemu_lock_fd(fd, off, 1, false);
113
if (ret) {
114
error_setg(errp, "Failed to lock byte %d", off);
115
return ret;
116
+ } else if (s) {
117
+ s->locked_shared_perm |= bit;
118
}
119
- } else if (unlock) {
120
+ } else if (unlock && (locked_shared_perm & bit) &&
121
+ !(shared_perm_lock_bits & bit)) {
122
ret = qemu_unlock_fd(fd, off, 1);
123
if (ret) {
124
error_setg(errp, "Failed to unlock byte %d", off);
125
return ret;
126
+ } else if (s) {
127
+ s->locked_shared_perm &= ~bit;
128
}
129
}
130
}
131
@@ -XXX,XX +XXX,XX @@ static int raw_handle_perm_lock(BlockDriverState *bs,
132
133
switch (op) {
134
case RAW_PL_PREPARE:
135
- ret = raw_apply_lock_bytes(s->lock_fd, s->perm | new_perm,
136
+ ret = raw_apply_lock_bytes(s, s->lock_fd, s->perm | new_perm,
137
~s->shared_perm | ~new_shared,
138
false, errp);
139
if (!ret) {
140
@@ -XXX,XX +XXX,XX @@ static int raw_handle_perm_lock(BlockDriverState *bs,
141
op = RAW_PL_ABORT;
142
/* fall through to unlock bytes. */
143
case RAW_PL_ABORT:
144
- raw_apply_lock_bytes(s->lock_fd, s->perm, ~s->shared_perm,
145
+ raw_apply_lock_bytes(s, s->lock_fd, s->perm, ~s->shared_perm,
146
true, &local_err);
147
if (local_err) {
148
/* Theoretically the above call only unlocks bytes and it cannot
149
@@ -XXX,XX +XXX,XX @@ static int raw_handle_perm_lock(BlockDriverState *bs,
150
}
151
break;
152
case RAW_PL_COMMIT:
153
- raw_apply_lock_bytes(s->lock_fd, new_perm, ~new_shared,
154
+ raw_apply_lock_bytes(s, s->lock_fd, new_perm, ~new_shared,
155
true, &local_err);
156
if (local_err) {
157
/* Theoretically the above call only unlocks bytes and it cannot
158
@@ -XXX,XX +XXX,XX @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
159
shared = BLK_PERM_ALL & ~BLK_PERM_RESIZE;
160
161
/* Step one: Take locks */
162
- result = raw_apply_lock_bytes(fd, perm, ~shared, false, errp);
163
+ result = raw_apply_lock_bytes(NULL, fd, perm, ~shared, false, errp);
164
if (result < 0) {
165
goto out_close;
166
}
167
@@ -XXX,XX +XXX,XX @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
168
}
169
170
out_unlock:
171
- raw_apply_lock_bytes(fd, 0, 0, true, &local_err);
172
+ raw_apply_lock_bytes(NULL, fd, 0, 0, true, &local_err);
173
if (local_err) {
174
/* The above call should not fail, and if it does, that does
175
* not mean the whole creation operation has failed. So
176
--
177
2.19.1
178
179
diff view generated by jsdifflib
Deleted patch
1
From: Fam Zheng <famz@redhat.com>
2
1
3
The lock_fd field is not strictly necessary because transferring locked
4
bytes from old fd to the new one shouldn't fail anyway. This spares the
5
user one fd per image.
6
7
Signed-off-by: Fam Zheng <famz@redhat.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
block/file-posix.c | 37 +++++++++++++------------------------
12
1 file changed, 13 insertions(+), 24 deletions(-)
13
14
diff --git a/block/file-posix.c b/block/file-posix.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/file-posix.c
17
+++ b/block/file-posix.c
18
@@ -XXX,XX +XXX,XX @@ do { \
19
20
typedef struct BDRVRawState {
21
int fd;
22
- int lock_fd;
23
bool use_lock;
24
int type;
25
int open_flags;
26
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVRawState {
27
uint64_t shared_perm;
28
29
/* The perms bits whose corresponding bytes are already locked in
30
- * s->lock_fd. */
31
+ * s->fd. */
32
uint64_t locked_perm;
33
uint64_t locked_shared_perm;
34
35
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
36
}
37
s->fd = fd;
38
39
- s->lock_fd = -1;
40
- if (s->use_lock) {
41
- fd = qemu_open(filename, s->open_flags);
42
- if (fd < 0) {
43
- ret = -errno;
44
- error_setg_errno(errp, errno, "Could not open '%s' for locking",
45
- filename);
46
- qemu_close(s->fd);
47
- goto fail;
48
- }
49
- s->lock_fd = fd;
50
- }
51
s->perm = 0;
52
s->shared_perm = BLK_PERM_ALL;
53
54
@@ -XXX,XX +XXX,XX @@ static int raw_handle_perm_lock(BlockDriverState *bs,
55
return 0;
56
}
57
58
- assert(s->lock_fd > 0);
59
-
60
switch (op) {
61
case RAW_PL_PREPARE:
62
- ret = raw_apply_lock_bytes(s, s->lock_fd, s->perm | new_perm,
63
+ ret = raw_apply_lock_bytes(s, s->fd, s->perm | new_perm,
64
~s->shared_perm | ~new_shared,
65
false, errp);
66
if (!ret) {
67
- ret = raw_check_lock_bytes(s->lock_fd, new_perm, new_shared, errp);
68
+ ret = raw_check_lock_bytes(s->fd, new_perm, new_shared, errp);
69
if (!ret) {
70
return 0;
71
}
72
@@ -XXX,XX +XXX,XX @@ static int raw_handle_perm_lock(BlockDriverState *bs,
73
op = RAW_PL_ABORT;
74
/* fall through to unlock bytes. */
75
case RAW_PL_ABORT:
76
- raw_apply_lock_bytes(s, s->lock_fd, s->perm, ~s->shared_perm,
77
+ raw_apply_lock_bytes(s, s->fd, s->perm, ~s->shared_perm,
78
true, &local_err);
79
if (local_err) {
80
/* Theoretically the above call only unlocks bytes and it cannot
81
@@ -XXX,XX +XXX,XX @@ static int raw_handle_perm_lock(BlockDriverState *bs,
82
}
83
break;
84
case RAW_PL_COMMIT:
85
- raw_apply_lock_bytes(s, s->lock_fd, new_perm, ~new_shared,
86
+ raw_apply_lock_bytes(s, s->fd, new_perm, ~new_shared,
87
true, &local_err);
88
if (local_err) {
89
/* Theoretically the above call only unlocks bytes and it cannot
90
@@ -XXX,XX +XXX,XX @@ static void raw_reopen_commit(BDRVReopenState *state)
91
{
92
BDRVRawReopenState *rs = state->opaque;
93
BDRVRawState *s = state->bs->opaque;
94
+ Error *local_err = NULL;
95
96
s->check_cache_dropped = rs->check_cache_dropped;
97
s->open_flags = rs->open_flags;
98
99
+ /* Copy locks to the new fd before closing the old one. */
100
+ raw_apply_lock_bytes(NULL, rs->fd, s->locked_perm,
101
+ ~s->locked_shared_perm, false, &local_err);
102
+ if (local_err) {
103
+ /* shouldn't fail in a sane host, but report it just in case. */
104
+ error_report_err(local_err);
105
+ }
106
qemu_close(s->fd);
107
s->fd = rs->fd;
108
109
@@ -XXX,XX +XXX,XX @@ static void raw_close(BlockDriverState *bs)
110
qemu_close(s->fd);
111
s->fd = -1;
112
}
113
- if (s->lock_fd >= 0) {
114
- qemu_close(s->lock_fd);
115
- s->lock_fd = -1;
116
- }
117
}
118
119
/**
120
--
121
2.19.1
122
123
diff view generated by jsdifflib
Deleted patch
1
From: Liam Merwick <Liam.Merwick@oracle.com>
2
1
3
In the assert checking the array dereference of JobVerbTable[verb]
4
in job_apply_verb() the check of the index, verb, allows an overrun
5
because an index equal to the array size is permitted.
6
7
Similarly, in the assert check of JobSTT[s0][s1] with index s1
8
in job_state_transition(), an off-by-one overrun is not flagged
9
either.
10
11
This is not a run-time issue as there are no callers actually
12
passing in the max value.
13
14
Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com>
15
Reviewed-by: Darren Kenny <Darren.Kenny@oracle.com>
16
Reviewed-by: Mark Kanda <Mark.Kanda@oracle.com>
17
Reviewed-by: Eric Blake <eblake@redhat.com>
18
Reviewed-by: John Snow <jsnow@redhat.com>
19
Message-id: 1541453919-25973-2-git-send-email-Liam.Merwick@oracle.com
20
Signed-off-by: Max Reitz <mreitz@redhat.com>
21
---
22
job.c | 4 ++--
23
1 file changed, 2 insertions(+), 2 deletions(-)
24
25
diff --git a/job.c b/job.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/job.c
28
+++ b/job.c
29
@@ -XXX,XX +XXX,XX @@ bool job_is_internal(Job *job)
30
static void job_state_transition(Job *job, JobStatus s1)
31
{
32
JobStatus s0 = job->status;
33
- assert(s1 >= 0 && s1 <= JOB_STATUS__MAX);
34
+ assert(s1 >= 0 && s1 < JOB_STATUS__MAX);
35
trace_job_state_transition(job, job->ret,
36
JobSTT[s0][s1] ? "allowed" : "disallowed",
37
JobStatus_str(s0), JobStatus_str(s1));
38
@@ -XXX,XX +XXX,XX @@ static void job_state_transition(Job *job, JobStatus s1)
39
int job_apply_verb(Job *job, JobVerb verb, Error **errp)
40
{
41
JobStatus s0 = job->status;
42
- assert(verb >= 0 && verb <= JOB_VERB__MAX);
43
+ assert(verb >= 0 && verb < JOB_VERB__MAX);
44
trace_job_apply_verb(job, JobStatus_str(s0), JobVerb_str(verb),
45
JobVerbTable[verb][s0] ? "allowed" : "prohibited");
46
if (JobVerbTable[verb][s0]) {
47
--
48
2.19.1
49
50
diff view generated by jsdifflib
Deleted patch
1
From: Liam Merwick <Liam.Merwick@oracle.com>
2
1
3
The dev_id returned by the call to blk_get_attached_dev_id() in
4
blk_root_get_parent_desc() can be NULL (an internal call to
5
object_get_canonical_path may have returned NULL).
6
7
Instead of just checking this case before before dereferencing,
8
adjust blk_get_attached_dev_id() to return the empty string if no
9
object path can be found (similar to the case when blk->dev is NULL
10
and an empty string is returned).
11
12
Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com>
13
Message-id: 1541453919-25973-3-git-send-email-Liam.Merwick@oracle.com
14
Reviewed-by: Max Reitz <mreitz@redhat.com>
15
Signed-off-by: Max Reitz <mreitz@redhat.com>
16
---
17
block/block-backend.c | 3 ++-
18
1 file changed, 2 insertions(+), 1 deletion(-)
19
20
diff --git a/block/block-backend.c b/block/block-backend.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/block/block-backend.c
23
+++ b/block/block-backend.c
24
@@ -XXX,XX +XXX,XX @@ char *blk_get_attached_dev_id(BlockBackend *blk)
25
} else if (dev->id) {
26
return g_strdup(dev->id);
27
}
28
- return object_get_canonical_path(OBJECT(dev));
29
+
30
+ return object_get_canonical_path(OBJECT(dev)) ?: g_strdup("");
31
}
32
33
/*
34
--
35
2.19.1
36
37
diff view generated by jsdifflib
Deleted patch
1
From: Liam Merwick <Liam.Merwick@oracle.com>
2
1
3
Although the function block_job_get() can return NULL, it would be a
4
serious bug if it did so (because the job yields before executing anything
5
(if it started successfully); but otherwise, commit_active_start() would
6
have returned an error). However, as a precaution, before dereferencing
7
the 'job' pointer in img_commit() assert it is not NULL.
8
9
Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com>
10
Reviewed-by: Max Reitz <mreitz@redhat.com>
11
Message-id: 1541453919-25973-4-git-send-email-Liam.Merwick@oracle.com
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
---
14
qemu-img.c | 1 +
15
1 file changed, 1 insertion(+)
16
17
diff --git a/qemu-img.c b/qemu-img.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/qemu-img.c
20
+++ b/qemu-img.c
21
@@ -XXX,XX +XXX,XX @@ static int img_commit(int argc, char **argv)
22
}
23
24
job = block_job_get("commit");
25
+ assert(job);
26
run_block_job(job, &local_err);
27
if (local_err) {
28
goto unref_backing;
29
--
30
2.19.1
31
32
diff view generated by jsdifflib
Deleted patch
1
From: Liam Merwick <Liam.Merwick@oracle.com>
2
1
3
The commit for 0e4e4318eaa5 increments QCOW2_OL_MAX_BITNR but does not
4
add an array entry for QCOW2_OL_BITMAP_DIRECTORY_BITNR to metadata_ol_names[].
5
As a result, an array dereference of metadata_ol_names[8] in
6
qcow2_pre_write_overlap_check() could result in a read outside of the array bounds.
7
8
Fixes: 0e4e4318eaa5 ('qcow2: add overlap check for bitmap directory')
9
10
Cc: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com>
12
Reviewed-by: Eric Blake <eblake@redhat.com>
13
Reviewed-by: Max Reitz <mreitz@redhat.com>
14
Message-id: 1541453919-25973-6-git-send-email-Liam.Merwick@oracle.com
15
Signed-off-by: Max Reitz <mreitz@redhat.com>
16
---
17
block/qcow2-refcount.c | 18 ++++++++++--------
18
1 file changed, 10 insertions(+), 8 deletions(-)
19
20
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/block/qcow2-refcount.c
23
+++ b/block/qcow2-refcount.c
24
@@ -XXX,XX +XXX,XX @@ int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
25
}
26
27
static const char *metadata_ol_names[] = {
28
- [QCOW2_OL_MAIN_HEADER_BITNR] = "qcow2_header",
29
- [QCOW2_OL_ACTIVE_L1_BITNR] = "active L1 table",
30
- [QCOW2_OL_ACTIVE_L2_BITNR] = "active L2 table",
31
- [QCOW2_OL_REFCOUNT_TABLE_BITNR] = "refcount table",
32
- [QCOW2_OL_REFCOUNT_BLOCK_BITNR] = "refcount block",
33
- [QCOW2_OL_SNAPSHOT_TABLE_BITNR] = "snapshot table",
34
- [QCOW2_OL_INACTIVE_L1_BITNR] = "inactive L1 table",
35
- [QCOW2_OL_INACTIVE_L2_BITNR] = "inactive L2 table",
36
+ [QCOW2_OL_MAIN_HEADER_BITNR] = "qcow2_header",
37
+ [QCOW2_OL_ACTIVE_L1_BITNR] = "active L1 table",
38
+ [QCOW2_OL_ACTIVE_L2_BITNR] = "active L2 table",
39
+ [QCOW2_OL_REFCOUNT_TABLE_BITNR] = "refcount table",
40
+ [QCOW2_OL_REFCOUNT_BLOCK_BITNR] = "refcount block",
41
+ [QCOW2_OL_SNAPSHOT_TABLE_BITNR] = "snapshot table",
42
+ [QCOW2_OL_INACTIVE_L1_BITNR] = "inactive L1 table",
43
+ [QCOW2_OL_INACTIVE_L2_BITNR] = "inactive L2 table",
44
+ [QCOW2_OL_BITMAP_DIRECTORY_BITNR] = "bitmap directory",
45
};
46
+QEMU_BUILD_BUG_ON(QCOW2_OL_MAX_BITNR != ARRAY_SIZE(metadata_ol_names));
47
48
/*
49
* First performs a check for metadata overlaps (through
50
--
51
2.19.1
52
53
diff view generated by jsdifflib