1 | The following changes since commit 9964e96dc9999cf7f7c936ee854a795415d19b60: | 1 | The following changes since commit 4907644841e3200aea6475c0f72d3d987e9f3d93: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'jasowang/tags/net-pull-request' into staging (2017-05-23 15:01:31 +0100) | 3 | Merge tag 'mem-2023-09-19' of https://github.com/davidhildenbrand/qemu into staging (2023-09-19 13:22:19 -0400) |
4 | 4 | ||
5 | are available in the git repository at: | 5 | are available in the Git repository at: |
6 | 6 | ||
7 | https://repo.or.cz/qemu/kevin.git tags/for-upstream | ||
7 | 8 | ||
8 | git://repo.or.cz/qemu/kevin.git tags/for-upstream | 9 | for you to fetch changes up to c428b392590df6364a025d5841e3e8a589ebfd4a: |
9 | 10 | ||
10 | for you to fetch changes up to 42a48128417b3bfade93d1a4721348cc480e9e50: | 11 | block: mark aio_poll as non-coroutine (2023-09-20 17:46:16 +0200) |
11 | |||
12 | Merge remote-tracking branch 'mreitz/tags/pull-block-2017-05-29-v3' into queue-block (2017-05-29 16:34:27 +0200) | ||
13 | 12 | ||
14 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
15 | |||
16 | Block layer patches | 14 | Block layer patches |
17 | 15 | ||
16 | - Graph locking part 4 (node management) | ||
17 | - qemu-img map: report compressed data blocks | ||
18 | - block-backend: process I/O in the current AioContext | ||
19 | |||
18 | ---------------------------------------------------------------- | 20 | ---------------------------------------------------------------- |
19 | Alberto Garcia (2): | 21 | Andrey Drobyshev via (2): |
20 | stream: fix crash in stream_start() when block_job_create() fails | 22 | block: add BDRV_BLOCK_COMPRESSED flag for bdrv_block_status() |
21 | qcow2: remove extra local_error variable | 23 | qemu-img: map: report compressed data blocks |
22 | 24 | ||
23 | Daniel P. Berrange (4): | 25 | Kevin Wolf (21): |
24 | qemu-img: add support for --object with 'dd' command | 26 | block: Remove unused BlockReopenQueueEntry.perms_checked |
25 | qemu-img: fix --image-opts usage with dd command | 27 | preallocate: Factor out preallocate_truncate_to_real_size() |
26 | qemu-img: introduce --target-image-opts for 'convert' command | 28 | preallocate: Don't poll during permission updates |
27 | qemu-img: copy *key-secret opts when opening newly created files | 29 | block: Take AioContext lock for bdrv_append() more consistently |
30 | block: Introduce bdrv_schedule_unref() | ||
31 | block-coroutine-wrapper: Add no_co_wrapper_bdrv_wrlock functions | ||
32 | block-coroutine-wrapper: Allow arbitrary parameter names | ||
33 | block: Mark bdrv_replace_child_noperm() GRAPH_WRLOCK | ||
34 | block: Mark bdrv_replace_child_tran() GRAPH_WRLOCK | ||
35 | block: Mark bdrv_attach_child_common() GRAPH_WRLOCK | ||
36 | block: Call transaction callbacks with lock held | ||
37 | block: Mark bdrv_attach_child() GRAPH_WRLOCK | ||
38 | block: Mark bdrv_parent_perms_conflict() and callers GRAPH_RDLOCK | ||
39 | block: Mark bdrv_get_cumulative_perm() and callers GRAPH_RDLOCK | ||
40 | block: Mark bdrv_child_perm() GRAPH_RDLOCK | ||
41 | block: Mark bdrv_parent_cb_change_media() GRAPH_RDLOCK | ||
42 | block: Take graph rdlock in bdrv_drop_intermediate() | ||
43 | block: Take graph rdlock in bdrv_change_aio_context() | ||
44 | block: Mark bdrv_root_unref_child() GRAPH_WRLOCK | ||
45 | block: Mark bdrv_unref_child() GRAPH_WRLOCK | ||
46 | block: Mark bdrv_add/del_child() and caller GRAPH_WRLOCK | ||
28 | 47 | ||
29 | Eric Blake (1): | 48 | Paolo Bonzini (1): |
30 | block: Tweak error message related to qemu-img amend | 49 | block: mark aio_poll as non-coroutine |
31 | 50 | ||
32 | Fam Zheng (3): | 51 | Stefan Hajnoczi (4): |
33 | iotests: 147: Don't test inet6 if not available | 52 | block: remove AIOCBInfo->get_aio_context() |
34 | qemu-img: Fix documentation of convert | 53 | test-bdrv-drain: avoid race with BH in IOThread drain test |
35 | qemu-img: Fix leakage of options on error | 54 | block-backend: process I/O in the current AioContext |
55 | block-backend: process zoned requests in the current AioContext | ||
36 | 56 | ||
37 | Kevin Wolf (3): | 57 | qapi/block-core.json | 6 +- |
38 | qemu-iotests: Test streaming with missing job ID | 58 | include/block/aio.h | 3 +- |
39 | mirror: Drop permissions on s->target on completion | 59 | include/block/block-common.h | 7 + |
40 | Merge remote-tracking branch 'mreitz/tags/pull-block-2017-05-29-v3' into queue-block | 60 | include/block/block-global-state.h | 32 +- |
41 | 61 | include/block/block-io.h | 1 - | |
42 | Max Reitz (2): | 62 | include/block/block_int-common.h | 34 +- |
43 | block: Fix backing paths for filenames with colons | 63 | include/block/block_int-global-state.h | 14 +- |
44 | block/file-*: *_parse_filename() and colons | 64 | include/sysemu/block-backend-global-state.h | 4 +- |
45 | 65 | block.c | 348 +++++++--- | |
46 | Stephen Bates (1): | 66 | block/blklogwrites.c | 4 + |
47 | nvme: Add support for Controller Memory Buffers | 67 | block/blkverify.c | 2 + |
48 | 68 | block/block-backend.c | 64 +- | |
49 | block.c | 50 +++++++++++++-- | 69 | block/copy-before-write.c | 10 +- |
50 | block/file-posix.c | 17 +----- | 70 | block/crypto.c | 6 +- |
51 | block/file-win32.c | 12 +--- | 71 | block/graph-lock.c | 26 +- |
52 | block/mirror.c | 7 ++- | 72 | block/io.c | 23 +- |
53 | block/qcow2-cluster.c | 3 +- | 73 | block/mirror.c | 8 + |
54 | block/qcow2.c | 5 +- | 74 | block/preallocate.c | 133 ++-- |
55 | block/stream.c | 2 +- | 75 | block/qcow.c | 5 +- |
56 | hw/block/nvme.c | 75 +++++++++++++++++++++-- | 76 | block/qcow2.c | 7 +- |
57 | hw/block/nvme.h | 73 ++++++++++++++++++++++ | 77 | block/quorum.c | 23 +- |
58 | include/block/block_int.h | 3 + | 78 | block/replication.c | 9 + |
59 | qemu-img-cmds.hx | 4 +- | 79 | block/snapshot.c | 2 + |
60 | qemu-img.c | 148 +++++++++++++++++++++++++++++++++++---------- | 80 | block/stream.c | 20 +- |
61 | qemu-img.texi | 12 +++- | 81 | block/vmdk.c | 15 + |
62 | tests/qemu-iotests/030 | 4 ++ | 82 | blockdev.c | 23 +- |
63 | tests/qemu-iotests/030.out | 4 +- | 83 | blockjob.c | 2 + |
64 | tests/qemu-iotests/060.out | 2 +- | 84 | hw/nvme/ctrl.c | 7 - |
65 | tests/qemu-iotests/147 | 7 +++ | 85 | qemu-img.c | 8 +- |
66 | 17 files changed, 351 insertions(+), 77 deletions(-) | 86 | softmmu/dma-helpers.c | 8 - |
67 | 87 | tests/unit/test-bdrv-drain.c | 31 +- | |
88 | tests/unit/test-bdrv-graph-mod.c | 20 + | ||
89 | tests/unit/test-block-iothread.c | 3 + | ||
90 | util/thread-pool.c | 8 - | ||
91 | scripts/block-coroutine-wrapper.py | 18 +- | ||
92 | tests/qemu-iotests/051.pc.out | 6 +- | ||
93 | tests/qemu-iotests/122.out | 84 +-- | ||
94 | tests/qemu-iotests/146.out | 780 +++++++++++------------ | ||
95 | tests/qemu-iotests/154.out | 194 +++--- | ||
96 | tests/qemu-iotests/179.out | 178 +++--- | ||
97 | tests/qemu-iotests/209.out | 4 +- | ||
98 | tests/qemu-iotests/221.out | 16 +- | ||
99 | tests/qemu-iotests/223.out | 60 +- | ||
100 | tests/qemu-iotests/241.out | 10 +- | ||
101 | tests/qemu-iotests/244.out | 24 +- | ||
102 | tests/qemu-iotests/252.out | 10 +- | ||
103 | tests/qemu-iotests/253.out | 20 +- | ||
104 | tests/qemu-iotests/274.out | 48 +- | ||
105 | tests/qemu-iotests/tests/nbd-qemu-allocation.out | 16 +- | ||
106 | tests/qemu-iotests/tests/qemu-img-bitmaps.out | 24 +- | ||
107 | 50 files changed, 1375 insertions(+), 1033 deletions(-) | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Alberto Garcia <berto@igalia.com> | ||
2 | 1 | ||
3 | The code that tries to reopen a BlockDriverState in stream_start() | ||
4 | when the creation of a new block job fails crashes because it attempts | ||
5 | to dereference a pointer that is known to be NULL. | ||
6 | |||
7 | This is a regression introduced in a170a91fd3eab6155da39e740381867e, | ||
8 | likely because the code was copied from stream_complete(). | ||
9 | |||
10 | Cc: qemu-stable@nongnu.org | ||
11 | Reported-by: Kashyap Chamarthy <kchamart@redhat.com> | ||
12 | Signed-off-by: Alberto Garcia <berto@igalia.com> | ||
13 | Tested-by: Kashyap Chamarthy <kchamart@redhat.com> | ||
14 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
15 | --- | ||
16 | block/stream.c | 2 +- | ||
17 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
18 | |||
19 | diff --git a/block/stream.c b/block/stream.c | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/block/stream.c | ||
22 | +++ b/block/stream.c | ||
23 | @@ -XXX,XX +XXX,XX @@ void stream_start(const char *job_id, BlockDriverState *bs, | ||
24 | |||
25 | fail: | ||
26 | if (orig_bs_flags != bdrv_get_flags(bs)) { | ||
27 | - bdrv_reopen(bs, s->bs_flags, NULL); | ||
28 | + bdrv_reopen(bs, orig_bs_flags, NULL); | ||
29 | } | ||
30 | } | ||
31 | -- | ||
32 | 1.8.3.1 | ||
33 | |||
34 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This adds a small test for the image streaming error path for failing | ||
2 | block_job_create(), which would have found the null pointer dereference | ||
3 | in commit a170a91f. | ||
4 | 1 | ||
5 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
6 | Reviewed-by: Alberto Garcia <berto@igalia.com> | ||
7 | Reviewed-by: Kashyap Chamarthy <kchamart@redhat.com> | ||
8 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
9 | Reviewed-by: Jeff Cody <jcody@redhat.com> | ||
10 | --- | ||
11 | tests/qemu-iotests/030 | 4 ++++ | ||
12 | tests/qemu-iotests/030.out | 4 ++-- | ||
13 | 2 files changed, 6 insertions(+), 2 deletions(-) | ||
14 | |||
15 | diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030 | ||
16 | index XXXXXXX..XXXXXXX 100755 | ||
17 | --- a/tests/qemu-iotests/030 | ||
18 | +++ b/tests/qemu-iotests/030 | ||
19 | @@ -XXX,XX +XXX,XX @@ class TestSingleDrive(iotests.QMPTestCase): | ||
20 | result = self.vm.qmp('block-stream', device='nonexistent') | ||
21 | self.assert_qmp(result, 'error/class', 'GenericError') | ||
22 | |||
23 | + def test_job_id_missing(self): | ||
24 | + result = self.vm.qmp('block-stream', device='mid') | ||
25 | + self.assert_qmp(result, 'error/class', 'GenericError') | ||
26 | + | ||
27 | |||
28 | class TestParallelOps(iotests.QMPTestCase): | ||
29 | num_ops = 4 # Number of parallel block-stream operations | ||
30 | diff --git a/tests/qemu-iotests/030.out b/tests/qemu-iotests/030.out | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/tests/qemu-iotests/030.out | ||
33 | +++ b/tests/qemu-iotests/030.out | ||
34 | @@ -XXX,XX +XXX,XX @@ | ||
35 | -...................... | ||
36 | +....................... | ||
37 | ---------------------------------------------------------------------- | ||
38 | -Ran 22 tests | ||
39 | +Ran 23 tests | ||
40 | |||
41 | OK | ||
42 | -- | ||
43 | 1.8.3.1 | ||
44 | |||
45 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Fam Zheng <famz@redhat.com> | ||
2 | 1 | ||
3 | This is the case in our docker tests, as we use --net=none there. Skip | ||
4 | this method. | ||
5 | |||
6 | Signed-off-by: Fam Zheng <famz@redhat.com> | ||
7 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
8 | --- | ||
9 | tests/qemu-iotests/147 | 7 +++++++ | ||
10 | 1 file changed, 7 insertions(+) | ||
11 | |||
12 | diff --git a/tests/qemu-iotests/147 b/tests/qemu-iotests/147 | ||
13 | index XXXXXXX..XXXXXXX 100755 | ||
14 | --- a/tests/qemu-iotests/147 | ||
15 | +++ b/tests/qemu-iotests/147 | ||
16 | @@ -XXX,XX +XXX,XX @@ class BuiltinNBD(NBDBlockdevAddBase): | ||
17 | self._server_down() | ||
18 | |||
19 | def test_inet6(self): | ||
20 | + try: | ||
21 | + socket.getaddrinfo("::0", "0", socket.AF_INET6, | ||
22 | + socket.SOCK_STREAM, socket.IPPROTO_TCP, | ||
23 | + socket.AI_ADDRCONFIG | socket.AI_CANONNAME) | ||
24 | + except socket.gaierror: | ||
25 | + # IPv6 not available, skip | ||
26 | + return | ||
27 | address = { 'type': 'inet', | ||
28 | 'data': { | ||
29 | 'host': '::1', | ||
30 | -- | ||
31 | 1.8.3.1 | ||
32 | |||
33 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Stephen Bates <sbates@raithlin.com> | ||
2 | 1 | ||
3 | Implement NVMe Controller Memory Buffers (CMBs) which were added in | ||
4 | version 1.2 of the NVMe Specification. This patch adds an optional | ||
5 | argument (cmb_size_mb) which indicates the size of the CMB (in | ||
6 | MB). Currently only the Submission Queue Support (SQS) is enabled | ||
7 | which aligns with the current Linux driver for NVMe. | ||
8 | |||
9 | Signed-off-by: Stephen Bates <sbates@raithlin.com> | ||
10 | Acked-by: Keith Busch <keith.busch@intel.com> | ||
11 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
12 | --- | ||
13 | hw/block/nvme.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- | ||
14 | hw/block/nvme.h | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
15 | 2 files changed, 144 insertions(+), 4 deletions(-) | ||
16 | |||
17 | diff --git a/hw/block/nvme.c b/hw/block/nvme.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/hw/block/nvme.c | ||
20 | +++ b/hw/block/nvme.c | ||
21 | @@ -XXX,XX +XXX,XX @@ | ||
22 | */ | ||
23 | |||
24 | /** | ||
25 | - * Reference Specs: http://www.nvmexpress.org, 1.1, 1.0e | ||
26 | + * Reference Specs: http://www.nvmexpress.org, 1.2, 1.1, 1.0e | ||
27 | * | ||
28 | * http://www.nvmexpress.org/resources/ | ||
29 | */ | ||
30 | @@ -XXX,XX +XXX,XX @@ | ||
31 | /** | ||
32 | * Usage: add options: | ||
33 | * -drive file=<file>,if=none,id=<drive_id> | ||
34 | - * -device nvme,drive=<drive_id>,serial=<serial>,id=<id[optional]> | ||
35 | + * -device nvme,drive=<drive_id>,serial=<serial>,id=<id[optional]>, \ | ||
36 | + * cmb_size_mb=<cmb_size_mb[optional]> | ||
37 | + * | ||
38 | + * Note cmb_size_mb denotes size of CMB in MB. CMB is assumed to be at | ||
39 | + * offset 0 in BAR2 and supports SQS only for now. | ||
40 | */ | ||
41 | |||
42 | #include "qemu/osdep.h" | ||
43 | @@ -XXX,XX +XXX,XX @@ | ||
44 | |||
45 | static void nvme_process_sq(void *opaque); | ||
46 | |||
47 | +static void nvme_addr_read(NvmeCtrl *n, hwaddr addr, void *buf, int size) | ||
48 | +{ | ||
49 | + if (n->cmbsz && addr >= n->ctrl_mem.addr && | ||
50 | + addr < (n->ctrl_mem.addr + int128_get64(n->ctrl_mem.size))) { | ||
51 | + memcpy(buf, (void *)&n->cmbuf[addr - n->ctrl_mem.addr], size); | ||
52 | + } else { | ||
53 | + pci_dma_read(&n->parent_obj, addr, buf, size); | ||
54 | + } | ||
55 | +} | ||
56 | + | ||
57 | static int nvme_check_sqid(NvmeCtrl *n, uint16_t sqid) | ||
58 | { | ||
59 | return sqid < n->num_queues && n->sq[sqid] != NULL ? 0 : -1; | ||
60 | @@ -XXX,XX +XXX,XX @@ static void nvme_process_sq(void *opaque) | ||
61 | |||
62 | while (!(nvme_sq_empty(sq) || QTAILQ_EMPTY(&sq->req_list))) { | ||
63 | addr = sq->dma_addr + sq->head * n->sqe_size; | ||
64 | - pci_dma_read(&n->parent_obj, addr, (void *)&cmd, sizeof(cmd)); | ||
65 | + nvme_addr_read(n, addr, (void *)&cmd, sizeof(cmd)); | ||
66 | nvme_inc_sq_head(sq); | ||
67 | |||
68 | req = QTAILQ_FIRST(&sq->req_list); | ||
69 | @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps nvme_mmio_ops = { | ||
70 | }, | ||
71 | }; | ||
72 | |||
73 | +static void nvme_cmb_write(void *opaque, hwaddr addr, uint64_t data, | ||
74 | + unsigned size) | ||
75 | +{ | ||
76 | + NvmeCtrl *n = (NvmeCtrl *)opaque; | ||
77 | + memcpy(&n->cmbuf[addr], &data, size); | ||
78 | +} | ||
79 | + | ||
80 | +static uint64_t nvme_cmb_read(void *opaque, hwaddr addr, unsigned size) | ||
81 | +{ | ||
82 | + uint64_t val; | ||
83 | + NvmeCtrl *n = (NvmeCtrl *)opaque; | ||
84 | + | ||
85 | + memcpy(&val, &n->cmbuf[addr], size); | ||
86 | + return val; | ||
87 | +} | ||
88 | + | ||
89 | +static const MemoryRegionOps nvme_cmb_ops = { | ||
90 | + .read = nvme_cmb_read, | ||
91 | + .write = nvme_cmb_write, | ||
92 | + .endianness = DEVICE_LITTLE_ENDIAN, | ||
93 | + .impl = { | ||
94 | + .min_access_size = 2, | ||
95 | + .max_access_size = 8, | ||
96 | + }, | ||
97 | +}; | ||
98 | + | ||
99 | static int nvme_init(PCIDevice *pci_dev) | ||
100 | { | ||
101 | NvmeCtrl *n = NVME(pci_dev); | ||
102 | @@ -XXX,XX +XXX,XX @@ static int nvme_init(PCIDevice *pci_dev) | ||
103 | NVME_CAP_SET_CSS(n->bar.cap, 1); | ||
104 | NVME_CAP_SET_MPSMAX(n->bar.cap, 4); | ||
105 | |||
106 | - n->bar.vs = 0x00010100; | ||
107 | + n->bar.vs = 0x00010200; | ||
108 | n->bar.intmc = n->bar.intms = 0; | ||
109 | |||
110 | + if (n->cmb_size_mb) { | ||
111 | + | ||
112 | + NVME_CMBLOC_SET_BIR(n->bar.cmbloc, 2); | ||
113 | + NVME_CMBLOC_SET_OFST(n->bar.cmbloc, 0); | ||
114 | + | ||
115 | + NVME_CMBSZ_SET_SQS(n->bar.cmbsz, 1); | ||
116 | + NVME_CMBSZ_SET_CQS(n->bar.cmbsz, 0); | ||
117 | + NVME_CMBSZ_SET_LISTS(n->bar.cmbsz, 0); | ||
118 | + NVME_CMBSZ_SET_RDS(n->bar.cmbsz, 0); | ||
119 | + NVME_CMBSZ_SET_WDS(n->bar.cmbsz, 0); | ||
120 | + NVME_CMBSZ_SET_SZU(n->bar.cmbsz, 2); /* MBs */ | ||
121 | + NVME_CMBSZ_SET_SZ(n->bar.cmbsz, n->cmb_size_mb); | ||
122 | + | ||
123 | + n->cmbuf = g_malloc0(NVME_CMBSZ_GETSIZE(n->bar.cmbsz)); | ||
124 | + memory_region_init_io(&n->ctrl_mem, OBJECT(n), &nvme_cmb_ops, n, | ||
125 | + "nvme-cmb", NVME_CMBSZ_GETSIZE(n->bar.cmbsz)); | ||
126 | + pci_register_bar(&n->parent_obj, NVME_CMBLOC_BIR(n->bar.cmbloc), | ||
127 | + PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64 | | ||
128 | + PCI_BASE_ADDRESS_MEM_PREFETCH, &n->ctrl_mem); | ||
129 | + | ||
130 | + } | ||
131 | + | ||
132 | for (i = 0; i < n->num_namespaces; i++) { | ||
133 | NvmeNamespace *ns = &n->namespaces[i]; | ||
134 | NvmeIdNs *id_ns = &ns->id_ns; | ||
135 | @@ -XXX,XX +XXX,XX @@ static void nvme_exit(PCIDevice *pci_dev) | ||
136 | g_free(n->namespaces); | ||
137 | g_free(n->cq); | ||
138 | g_free(n->sq); | ||
139 | + if (n->cmbsz) { | ||
140 | + memory_region_unref(&n->ctrl_mem); | ||
141 | + } | ||
142 | + | ||
143 | msix_uninit_exclusive_bar(pci_dev); | ||
144 | } | ||
145 | |||
146 | static Property nvme_props[] = { | ||
147 | DEFINE_BLOCK_PROPERTIES(NvmeCtrl, conf), | ||
148 | DEFINE_PROP_STRING("serial", NvmeCtrl, serial), | ||
149 | + DEFINE_PROP_UINT32("cmb_size_mb", NvmeCtrl, cmb_size_mb, 0), | ||
150 | DEFINE_PROP_END_OF_LIST(), | ||
151 | }; | ||
152 | |||
153 | diff --git a/hw/block/nvme.h b/hw/block/nvme.h | ||
154 | index XXXXXXX..XXXXXXX 100644 | ||
155 | --- a/hw/block/nvme.h | ||
156 | +++ b/hw/block/nvme.h | ||
157 | @@ -XXX,XX +XXX,XX @@ typedef struct NvmeBar { | ||
158 | uint32_t aqa; | ||
159 | uint64_t asq; | ||
160 | uint64_t acq; | ||
161 | + uint32_t cmbloc; | ||
162 | + uint32_t cmbsz; | ||
163 | } NvmeBar; | ||
164 | |||
165 | enum NvmeCapShift { | ||
166 | @@ -XXX,XX +XXX,XX @@ enum NvmeAqaMask { | ||
167 | #define NVME_AQA_ASQS(aqa) ((aqa >> AQA_ASQS_SHIFT) & AQA_ASQS_MASK) | ||
168 | #define NVME_AQA_ACQS(aqa) ((aqa >> AQA_ACQS_SHIFT) & AQA_ACQS_MASK) | ||
169 | |||
170 | +enum NvmeCmblocShift { | ||
171 | + CMBLOC_BIR_SHIFT = 0, | ||
172 | + CMBLOC_OFST_SHIFT = 12, | ||
173 | +}; | ||
174 | + | ||
175 | +enum NvmeCmblocMask { | ||
176 | + CMBLOC_BIR_MASK = 0x7, | ||
177 | + CMBLOC_OFST_MASK = 0xfffff, | ||
178 | +}; | ||
179 | + | ||
180 | +#define NVME_CMBLOC_BIR(cmbloc) ((cmbloc >> CMBLOC_BIR_SHIFT) & \ | ||
181 | + CMBLOC_BIR_MASK) | ||
182 | +#define NVME_CMBLOC_OFST(cmbloc)((cmbloc >> CMBLOC_OFST_SHIFT) & \ | ||
183 | + CMBLOC_OFST_MASK) | ||
184 | + | ||
185 | +#define NVME_CMBLOC_SET_BIR(cmbloc, val) \ | ||
186 | + (cmbloc |= (uint64_t)(val & CMBLOC_BIR_MASK) << CMBLOC_BIR_SHIFT) | ||
187 | +#define NVME_CMBLOC_SET_OFST(cmbloc, val) \ | ||
188 | + (cmbloc |= (uint64_t)(val & CMBLOC_OFST_MASK) << CMBLOC_OFST_SHIFT) | ||
189 | + | ||
190 | +enum NvmeCmbszShift { | ||
191 | + CMBSZ_SQS_SHIFT = 0, | ||
192 | + CMBSZ_CQS_SHIFT = 1, | ||
193 | + CMBSZ_LISTS_SHIFT = 2, | ||
194 | + CMBSZ_RDS_SHIFT = 3, | ||
195 | + CMBSZ_WDS_SHIFT = 4, | ||
196 | + CMBSZ_SZU_SHIFT = 8, | ||
197 | + CMBSZ_SZ_SHIFT = 12, | ||
198 | +}; | ||
199 | + | ||
200 | +enum NvmeCmbszMask { | ||
201 | + CMBSZ_SQS_MASK = 0x1, | ||
202 | + CMBSZ_CQS_MASK = 0x1, | ||
203 | + CMBSZ_LISTS_MASK = 0x1, | ||
204 | + CMBSZ_RDS_MASK = 0x1, | ||
205 | + CMBSZ_WDS_MASK = 0x1, | ||
206 | + CMBSZ_SZU_MASK = 0xf, | ||
207 | + CMBSZ_SZ_MASK = 0xfffff, | ||
208 | +}; | ||
209 | + | ||
210 | +#define NVME_CMBSZ_SQS(cmbsz) ((cmbsz >> CMBSZ_SQS_SHIFT) & CMBSZ_SQS_MASK) | ||
211 | +#define NVME_CMBSZ_CQS(cmbsz) ((cmbsz >> CMBSZ_CQS_SHIFT) & CMBSZ_CQS_MASK) | ||
212 | +#define NVME_CMBSZ_LISTS(cmbsz)((cmbsz >> CMBSZ_LISTS_SHIFT) & CMBSZ_LISTS_MASK) | ||
213 | +#define NVME_CMBSZ_RDS(cmbsz) ((cmbsz >> CMBSZ_RDS_SHIFT) & CMBSZ_RDS_MASK) | ||
214 | +#define NVME_CMBSZ_WDS(cmbsz) ((cmbsz >> CMBSZ_WDS_SHIFT) & CMBSZ_WDS_MASK) | ||
215 | +#define NVME_CMBSZ_SZU(cmbsz) ((cmbsz >> CMBSZ_SZU_SHIFT) & CMBSZ_SZU_MASK) | ||
216 | +#define NVME_CMBSZ_SZ(cmbsz) ((cmbsz >> CMBSZ_SZ_SHIFT) & CMBSZ_SZ_MASK) | ||
217 | + | ||
218 | +#define NVME_CMBSZ_SET_SQS(cmbsz, val) \ | ||
219 | + (cmbsz |= (uint64_t)(val & CMBSZ_SQS_MASK) << CMBSZ_SQS_SHIFT) | ||
220 | +#define NVME_CMBSZ_SET_CQS(cmbsz, val) \ | ||
221 | + (cmbsz |= (uint64_t)(val & CMBSZ_CQS_MASK) << CMBSZ_CQS_SHIFT) | ||
222 | +#define NVME_CMBSZ_SET_LISTS(cmbsz, val) \ | ||
223 | + (cmbsz |= (uint64_t)(val & CMBSZ_LISTS_MASK) << CMBSZ_LISTS_SHIFT) | ||
224 | +#define NVME_CMBSZ_SET_RDS(cmbsz, val) \ | ||
225 | + (cmbsz |= (uint64_t)(val & CMBSZ_RDS_MASK) << CMBSZ_RDS_SHIFT) | ||
226 | +#define NVME_CMBSZ_SET_WDS(cmbsz, val) \ | ||
227 | + (cmbsz |= (uint64_t)(val & CMBSZ_WDS_MASK) << CMBSZ_WDS_SHIFT) | ||
228 | +#define NVME_CMBSZ_SET_SZU(cmbsz, val) \ | ||
229 | + (cmbsz |= (uint64_t)(val & CMBSZ_SZU_MASK) << CMBSZ_SZU_SHIFT) | ||
230 | +#define NVME_CMBSZ_SET_SZ(cmbsz, val) \ | ||
231 | + (cmbsz |= (uint64_t)(val & CMBSZ_SZ_MASK) << CMBSZ_SZ_SHIFT) | ||
232 | + | ||
233 | +#define NVME_CMBSZ_GETSIZE(cmbsz) \ | ||
234 | + (NVME_CMBSZ_SZ(cmbsz) * (1 << (12 + 4 * NVME_CMBSZ_SZU(cmbsz)))) | ||
235 | + | ||
236 | typedef struct NvmeCmd { | ||
237 | uint8_t opcode; | ||
238 | uint8_t fuse; | ||
239 | @@ -XXX,XX +XXX,XX @@ typedef struct NvmeNamespace { | ||
240 | typedef struct NvmeCtrl { | ||
241 | PCIDevice parent_obj; | ||
242 | MemoryRegion iomem; | ||
243 | + MemoryRegion ctrl_mem; | ||
244 | NvmeBar bar; | ||
245 | BlockConf conf; | ||
246 | |||
247 | @@ -XXX,XX +XXX,XX @@ typedef struct NvmeCtrl { | ||
248 | uint32_t num_queues; | ||
249 | uint32_t max_q_ents; | ||
250 | uint64_t ns_size; | ||
251 | + uint32_t cmb_size_mb; | ||
252 | + uint32_t cmbsz; | ||
253 | + uint32_t cmbloc; | ||
254 | + uint8_t *cmbuf; | ||
255 | |||
256 | char *serial; | ||
257 | NvmeNamespace *namespaces; | ||
258 | -- | ||
259 | 1.8.3.1 | ||
260 | |||
261 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This fixes an assertion failure that was triggered by qemu-iotests 129 | ||
2 | on some CI host, while the same test case didn't seem to fail on other | ||
3 | hosts. | ||
4 | 1 | ||
5 | Essentially the problem is that the blk_unref(s->target) in | ||
6 | mirror_exit() doesn't necessarily mean that the BlockBackend goes away | ||
7 | immediately. It is possible that the job completion was triggered nested | ||
8 | in mirror_drain(), which looks like this: | ||
9 | |||
10 | BlockBackend *target = s->target; | ||
11 | blk_ref(target); | ||
12 | blk_drain(target); | ||
13 | blk_unref(target); | ||
14 | |||
15 | In this case, the write permissions for s->target are retained until | ||
16 | after blk_drain(), which makes removing mirror_top_bs fail for the | ||
17 | active commit case (can't have a writable backing file in the chain | ||
18 | without the filter driver). | ||
19 | |||
20 | Explicitly dropping the permissions first means that the additional | ||
21 | reference doesn't hurt and the job can complete successfully even if | ||
22 | called from the nested blk_drain(). | ||
23 | |||
24 | Cc: qemu-stable@nongnu.org | ||
25 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | ||
26 | Acked-by: Paolo Bonzini <pbonzini@redhat.com> | ||
27 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
28 | --- | ||
29 | block/mirror.c | 7 ++++++- | ||
30 | 1 file changed, 6 insertions(+), 1 deletion(-) | ||
31 | |||
32 | diff --git a/block/mirror.c b/block/mirror.c | ||
33 | index XXXXXXX..XXXXXXX 100644 | ||
34 | --- a/block/mirror.c | ||
35 | +++ b/block/mirror.c | ||
36 | @@ -XXX,XX +XXX,XX @@ static void mirror_exit(BlockJob *job, void *opaque) | ||
37 | |||
38 | /* Remove target parent that still uses BLK_PERM_WRITE/RESIZE before | ||
39 | * inserting target_bs at s->to_replace, where we might not be able to get | ||
40 | - * these permissions. */ | ||
41 | + * these permissions. | ||
42 | + * | ||
43 | + * Note that blk_unref() alone doesn't necessarily drop permissions because | ||
44 | + * we might be running nested inside mirror_drain(), which takes an extra | ||
45 | + * reference, so use an explicit blk_set_perm() first. */ | ||
46 | + blk_set_perm(s->target, 0, BLK_PERM_ALL, &error_abort); | ||
47 | blk_unref(s->target); | ||
48 | s->target = NULL; | ||
49 | |||
50 | -- | ||
51 | 1.8.3.1 | ||
52 | |||
53 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Alberto Garcia <berto@igalia.com> | ||
2 | 1 | ||
3 | Commit d7086422b1c1e75e320519cfe26176db6ec97a37 added a local_err | ||
4 | variable global to the qcow2_amend_options() function, so there's no | ||
5 | need to have this other one. | ||
6 | |||
7 | Signed-off-by: Alberto Garcia <berto@igalia.com> | ||
8 | Message-id: 20170511150337.21470-1-berto@igalia.com | ||
9 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
10 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
11 | --- | ||
12 | block/qcow2.c | 5 ++--- | ||
13 | 1 file changed, 2 insertions(+), 3 deletions(-) | ||
14 | |||
15 | diff --git a/block/qcow2.c b/block/qcow2.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/block/qcow2.c | ||
18 | +++ b/block/qcow2.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, | ||
20 | |||
21 | if (s->refcount_bits != refcount_bits) { | ||
22 | int refcount_order = ctz32(refcount_bits); | ||
23 | - Error *local_error = NULL; | ||
24 | |||
25 | if (new_version < 3 && refcount_bits != 16) { | ||
26 | error_report("Different refcount widths than 16 bits require " | ||
27 | @@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, | ||
28 | helper_cb_info.current_operation = QCOW2_CHANGING_REFCOUNT_ORDER; | ||
29 | ret = qcow2_change_refcount_order(bs, refcount_order, | ||
30 | &qcow2_amend_helper_cb, | ||
31 | - &helper_cb_info, &local_error); | ||
32 | + &helper_cb_info, &local_err); | ||
33 | if (ret < 0) { | ||
34 | - error_report_err(local_error); | ||
35 | + error_report_err(local_err); | ||
36 | return ret; | ||
37 | } | ||
38 | } | ||
39 | -- | ||
40 | 1.8.3.1 | ||
41 | |||
42 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Fam Zheng <famz@redhat.com> | ||
2 | 1 | ||
3 | It got lost in commit a8d16f9ca "qemu-img: Update documentation for -U". | ||
4 | |||
5 | Reported-by: Max Reitz <mreitz@redhat.com> | ||
6 | Signed-off-by: Fam Zheng <famz@redhat.com> | ||
7 | Message-id: 20170515103551.31313-1-famz@redhat.com | ||
8 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
9 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
10 | --- | ||
11 | qemu-img-cmds.hx | 4 ++-- | ||
12 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
13 | |||
14 | diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx | ||
15 | index XXXXXXX..XXXXXXX 100644 | ||
16 | --- a/qemu-img-cmds.hx | ||
17 | +++ b/qemu-img-cmds.hx | ||
18 | @@ -XXX,XX +XXX,XX @@ STEXI | ||
19 | ETEXI | ||
20 | |||
21 | DEF("convert", img_convert, | ||
22 | - "convert [--object objectdef] [--image-opts] [-U] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-o options] [-s snapshot_id_or_name] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename [filename2 [...]] output_filename") | ||
23 | + "convert [--object objectdef] [--image-opts] [-U] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-s snapshot_id_or_name] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename [filename2 [...]] output_filename") | ||
24 | STEXI | ||
25 | -@item convert [--object @var{objectdef}] [--image-opts] [-U] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename} | ||
26 | +@item convert [--object @var{objectdef}] [--image-opts] [-U] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename} | ||
27 | ETEXI | ||
28 | |||
29 | DEF("dd", img_dd, | ||
30 | -- | ||
31 | 1.8.3.1 | ||
32 | |||
33 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | The qemu-img dd command added --image-opts support, but missed | ||
4 | the corresponding --object support. This prevented passing | ||
5 | secrets (eg auth passwords) needed by certain disk images. | ||
6 | |||
7 | Reviewed-by: Fam Zheng <famz@redhat.com> | ||
8 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
9 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
10 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
11 | Message-id: 20170515164712.6643-2-berrange@redhat.com | ||
12 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
13 | --- | ||
14 | qemu-img.c | 18 ++++++++++++++++++ | ||
15 | 1 file changed, 18 insertions(+) | ||
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_dd(int argc, char **argv) | ||
22 | }; | ||
23 | const struct option long_options[] = { | ||
24 | { "help", no_argument, 0, 'h'}, | ||
25 | + { "object", required_argument, 0, OPTION_OBJECT}, | ||
26 | { "image-opts", no_argument, 0, OPTION_IMAGE_OPTS}, | ||
27 | { "force-share", no_argument, 0, 'U'}, | ||
28 | { 0, 0, 0, 0 } | ||
29 | @@ -XXX,XX +XXX,XX @@ static int img_dd(int argc, char **argv) | ||
30 | case 'U': | ||
31 | force_share = true; | ||
32 | break; | ||
33 | + case OPTION_OBJECT: { | ||
34 | + QemuOpts *opts; | ||
35 | + opts = qemu_opts_parse_noisily(&qemu_object_opts, | ||
36 | + optarg, true); | ||
37 | + if (!opts) { | ||
38 | + ret = -1; | ||
39 | + goto out; | ||
40 | + } | ||
41 | + } break; | ||
42 | case OPTION_IMAGE_OPTS: | ||
43 | image_opts = true; | ||
44 | break; | ||
45 | @@ -XXX,XX +XXX,XX @@ static int img_dd(int argc, char **argv) | ||
46 | ret = -1; | ||
47 | goto out; | ||
48 | } | ||
49 | + | ||
50 | + if (qemu_opts_foreach(&qemu_object_opts, | ||
51 | + user_creatable_add_opts_foreach, | ||
52 | + NULL, NULL)) { | ||
53 | + ret = -1; | ||
54 | + goto out; | ||
55 | + } | ||
56 | + | ||
57 | blk1 = img_open(image_opts, in.filename, fmt, 0, false, false, | ||
58 | force_share); | ||
59 | |||
60 | -- | ||
61 | 1.8.3.1 | ||
62 | |||
63 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | The --image-opts flag can only be used to affect the parsing | ||
4 | of the source image. The target image has to be specified in | ||
5 | the traditional style regardless, since it needs to be passed | ||
6 | to the bdrv_create() API which does not support the new style | ||
7 | opts. | ||
8 | |||
9 | Reviewed-by: Fam Zheng <famz@redhat.com> | ||
10 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
11 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
12 | Message-id: 20170515164712.6643-3-berrange@redhat.com | ||
13 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
14 | --- | ||
15 | qemu-img.c | 9 +++++++-- | ||
16 | 1 file changed, 7 insertions(+), 2 deletions(-) | ||
17 | |||
18 | diff --git a/qemu-img.c b/qemu-img.c | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/qemu-img.c | ||
21 | +++ b/qemu-img.c | ||
22 | @@ -XXX,XX +XXX,XX @@ static int img_dd(int argc, char **argv) | ||
23 | goto out; | ||
24 | } | ||
25 | |||
26 | - blk2 = img_open(image_opts, out.filename, out_fmt, BDRV_O_RDWR, | ||
27 | - false, false, false); | ||
28 | + /* TODO, we can't honour --image-opts for the target, | ||
29 | + * since it needs to be given in a format compatible | ||
30 | + * with the bdrv_create() call above which does not | ||
31 | + * support image-opts style. | ||
32 | + */ | ||
33 | + blk2 = img_open_file(out.filename, out_fmt, BDRV_O_RDWR, | ||
34 | + false, false, false); | ||
35 | |||
36 | if (!blk2) { | ||
37 | ret = -1; | ||
38 | -- | ||
39 | 1.8.3.1 | ||
40 | |||
41 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | The '--image-opts' flag indicates whether the source filename | ||
4 | includes options. The target filename has to remain in the | ||
5 | plain filename format though, since it needs to be passed to | ||
6 | bdrv_create(). When using --skip-create though, it would be | ||
7 | possible to use image-opts syntax. This adds --target-image-opts | ||
8 | to indicate that the target filename includes options. Currently | ||
9 | this mandates use of the --skip-create flag too. | ||
10 | |||
11 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
12 | Message-id: 20170515164712.6643-4-berrange@redhat.com | ||
13 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
14 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
15 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
16 | --- | ||
17 | qemu-img-cmds.hx | 4 +-- | ||
18 | qemu-img.c | 84 ++++++++++++++++++++++++++++++++++++++------------------ | ||
19 | qemu-img.texi | 12 ++++++-- | ||
20 | 3 files changed, 69 insertions(+), 31 deletions(-) | ||
21 | |||
22 | diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx | ||
23 | index XXXXXXX..XXXXXXX 100644 | ||
24 | --- a/qemu-img-cmds.hx | ||
25 | +++ b/qemu-img-cmds.hx | ||
26 | @@ -XXX,XX +XXX,XX @@ STEXI | ||
27 | ETEXI | ||
28 | |||
29 | DEF("convert", img_convert, | ||
30 | - "convert [--object objectdef] [--image-opts] [-U] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-s snapshot_id_or_name] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename [filename2 [...]] output_filename") | ||
31 | + "convert [--object objectdef] [--image-opts] [--target-image-opts] [-U] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-s snapshot_id_or_name] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename [filename2 [...]] output_filename") | ||
32 | STEXI | ||
33 | -@item convert [--object @var{objectdef}] [--image-opts] [-U] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename} | ||
34 | +@item convert [--object @var{objectdef}] [--image-opts] [--target-image-opts] [-U] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename} | ||
35 | ETEXI | ||
36 | |||
37 | DEF("dd", img_dd, | ||
38 | diff --git a/qemu-img.c b/qemu-img.c | ||
39 | index XXXXXXX..XXXXXXX 100644 | ||
40 | --- a/qemu-img.c | ||
41 | +++ b/qemu-img.c | ||
42 | @@ -XXX,XX +XXX,XX @@ enum { | ||
43 | OPTION_PATTERN = 260, | ||
44 | OPTION_FLUSH_INTERVAL = 261, | ||
45 | OPTION_NO_DRAIN = 262, | ||
46 | + OPTION_TARGET_IMAGE_OPTS = 263, | ||
47 | }; | ||
48 | |||
49 | typedef enum OutputFormat { | ||
50 | @@ -XXX,XX +XXX,XX @@ static int convert_do_copy(ImgConvertState *s) | ||
51 | static int img_convert(int argc, char **argv) | ||
52 | { | ||
53 | int c, bs_i, flags, src_flags = 0; | ||
54 | - const char *fmt = NULL, *out_fmt = "raw", *cache = "unsafe", | ||
55 | + const char *fmt = NULL, *out_fmt = NULL, *cache = "unsafe", | ||
56 | *src_cache = BDRV_DEFAULT_CACHE, *out_baseimg = NULL, | ||
57 | *out_filename, *out_baseimg_param, *snapshot_name = NULL; | ||
58 | - BlockDriver *drv, *proto_drv; | ||
59 | + BlockDriver *drv = NULL, *proto_drv = NULL; | ||
60 | BlockDriverInfo bdi; | ||
61 | BlockDriverState *out_bs; | ||
62 | QemuOpts *opts = NULL, *sn_opts = NULL; | ||
63 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
64 | char *options = NULL; | ||
65 | Error *local_err = NULL; | ||
66 | bool writethrough, src_writethrough, quiet = false, image_opts = false, | ||
67 | - skip_create = false, progress = false; | ||
68 | + skip_create = false, progress = false, tgt_image_opts = false; | ||
69 | int64_t ret = -EINVAL; | ||
70 | bool force_share = false; | ||
71 | |||
72 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
73 | {"object", required_argument, 0, OPTION_OBJECT}, | ||
74 | {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS}, | ||
75 | {"force-share", no_argument, 0, 'U'}, | ||
76 | + {"target-image-opts", no_argument, 0, OPTION_TARGET_IMAGE_OPTS}, | ||
77 | {0, 0, 0, 0} | ||
78 | }; | ||
79 | c = getopt_long(argc, argv, ":hf:O:B:ce6o:s:l:S:pt:T:qnm:WU", | ||
80 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
81 | case OPTION_IMAGE_OPTS: | ||
82 | image_opts = true; | ||
83 | break; | ||
84 | + case OPTION_TARGET_IMAGE_OPTS: | ||
85 | + tgt_image_opts = true; | ||
86 | + break; | ||
87 | } | ||
88 | } | ||
89 | |||
90 | + if (!out_fmt && !tgt_image_opts) { | ||
91 | + out_fmt = "raw"; | ||
92 | + } | ||
93 | + | ||
94 | if (qemu_opts_foreach(&qemu_object_opts, | ||
95 | user_creatable_add_opts_foreach, | ||
96 | NULL, NULL)) { | ||
97 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
98 | goto fail_getopt; | ||
99 | } | ||
100 | |||
101 | + if (tgt_image_opts && !skip_create) { | ||
102 | + error_report("--target-image-opts requires use of -n flag"); | ||
103 | + goto fail_getopt; | ||
104 | + } | ||
105 | + | ||
106 | s.src_num = argc - optind - 1; | ||
107 | out_filename = s.src_num >= 1 ? argv[argc - 1] : NULL; | ||
108 | |||
109 | if (options && has_help_option(options)) { | ||
110 | - ret = print_block_option_help(out_filename, out_fmt); | ||
111 | - goto fail_getopt; | ||
112 | + if (out_fmt) { | ||
113 | + ret = print_block_option_help(out_filename, out_fmt); | ||
114 | + goto fail_getopt; | ||
115 | + } else { | ||
116 | + error_report("Option help requires a format be specified"); | ||
117 | + goto fail_getopt; | ||
118 | + } | ||
119 | } | ||
120 | |||
121 | if (s.src_num < 1) { | ||
122 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
123 | goto out; | ||
124 | } | ||
125 | |||
126 | - /* Find driver and parse its options */ | ||
127 | - drv = bdrv_find_format(out_fmt); | ||
128 | - if (!drv) { | ||
129 | - error_report("Unknown file format '%s'", out_fmt); | ||
130 | - ret = -1; | ||
131 | - goto out; | ||
132 | - } | ||
133 | + if (!skip_create) { | ||
134 | + /* Find driver and parse its options */ | ||
135 | + drv = bdrv_find_format(out_fmt); | ||
136 | + if (!drv) { | ||
137 | + error_report("Unknown file format '%s'", out_fmt); | ||
138 | + ret = -1; | ||
139 | + goto out; | ||
140 | + } | ||
141 | |||
142 | - proto_drv = bdrv_find_protocol(out_filename, true, &local_err); | ||
143 | - if (!proto_drv) { | ||
144 | - error_report_err(local_err); | ||
145 | - ret = -1; | ||
146 | - goto out; | ||
147 | - } | ||
148 | + proto_drv = bdrv_find_protocol(out_filename, true, &local_err); | ||
149 | + if (!proto_drv) { | ||
150 | + error_report_err(local_err); | ||
151 | + ret = -1; | ||
152 | + goto out; | ||
153 | + } | ||
154 | |||
155 | - if (!skip_create) { | ||
156 | if (!drv->create_opts) { | ||
157 | error_report("Format driver '%s' does not support image creation", | ||
158 | drv->format_name); | ||
159 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
160 | const char *preallocation = | ||
161 | qemu_opt_get(opts, BLOCK_OPT_PREALLOC); | ||
162 | |||
163 | - if (!drv->bdrv_co_pwritev_compressed) { | ||
164 | + if (drv && !drv->bdrv_co_pwritev_compressed) { | ||
165 | error_report("Compression not supported for this file format"); | ||
166 | ret = -1; | ||
167 | goto out; | ||
168 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
169 | goto out; | ||
170 | } | ||
171 | |||
172 | - /* XXX we should allow --image-opts to trigger use of | ||
173 | - * img_open() here, but then we have trouble with | ||
174 | - * the bdrv_create() call which takes different params. | ||
175 | - * Not critical right now, so fix can wait... | ||
176 | - */ | ||
177 | - s.target = img_open_file(out_filename, out_fmt, flags, writethrough, quiet, | ||
178 | - false); | ||
179 | + if (skip_create) { | ||
180 | + s.target = img_open(tgt_image_opts, out_filename, out_fmt, | ||
181 | + flags, writethrough, quiet, false); | ||
182 | + } else { | ||
183 | + /* TODO ultimately we should allow --target-image-opts | ||
184 | + * to be used even when -n is not given. | ||
185 | + * That has to wait for bdrv_create to be improved | ||
186 | + * to allow filenames in option syntax | ||
187 | + */ | ||
188 | + s.target = img_open_file(out_filename, out_fmt, flags, | ||
189 | + writethrough, quiet, false); | ||
190 | + } | ||
191 | if (!s.target) { | ||
192 | ret = -1; | ||
193 | goto out; | ||
194 | } | ||
195 | out_bs = blk_bs(s.target); | ||
196 | |||
197 | + if (s.compressed && !out_bs->drv->bdrv_co_pwritev_compressed) { | ||
198 | + error_report("Compression not supported for this file format"); | ||
199 | + ret = -1; | ||
200 | + goto out; | ||
201 | + } | ||
202 | + | ||
203 | /* increase bufsectors from the default 4096 (2M) if opt_transfer | ||
204 | * or discard_alignment of the out_bs is greater. Limit to 32768 (16MB) | ||
205 | * as maximum. */ | ||
206 | diff --git a/qemu-img.texi b/qemu-img.texi | ||
207 | index XXXXXXX..XXXXXXX 100644 | ||
208 | --- a/qemu-img.texi | ||
209 | +++ b/qemu-img.texi | ||
210 | @@ -XXX,XX +XXX,XX @@ keys. | ||
211 | |||
212 | @item --image-opts | ||
213 | |||
214 | -Indicates that the @var{filename} parameter is to be interpreted as a | ||
215 | +Indicates that the source @var{filename} parameter is to be interpreted as a | ||
216 | full option string, not a plain filename. This parameter is mutually | ||
217 | -exclusive with the @var{-f} and @var{-F} parameters. | ||
218 | +exclusive with the @var{-f} parameter. | ||
219 | + | ||
220 | +@item --target-image-opts | ||
221 | + | ||
222 | +Indicates that the @var{output_filename} parameter(s) are to be interpreted as | ||
223 | +a full option string, not a plain filename. This parameter is mutually | ||
224 | +exclusive with the @var{-O} parameters. It is currently required to also use | ||
225 | +the @var{-n} parameter to skip image creation. This restriction may be relaxed | ||
226 | +in a future release. | ||
227 | |||
228 | @item fmt | ||
229 | is the disk image format. It is guessed automatically in most cases. See below | ||
230 | -- | ||
231 | 1.8.3.1 | ||
232 | |||
233 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: "Daniel P. Berrange" <berrange@redhat.com> | ||
2 | 1 | ||
3 | The qemu-img dd/convert commands will create an image file and | ||
4 | then try to open it. Historically it has been possible to open | ||
5 | new files without passing any options. With encrypted files | ||
6 | though, the *key-secret options are mandatory, so we need to | ||
7 | provide those options when opening the newly created file. | ||
8 | |||
9 | Signed-off-by: Daniel P. Berrange <berrange@redhat.com> | ||
10 | Message-id: 20170515164712.6643-5-berrange@redhat.com | ||
11 | Reviewed-by: Max Reitz <mreitz@redhat.com> | ||
12 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
13 | --- | ||
14 | qemu-img.c | 42 +++++++++++++++++++++++++++++++++++++----- | ||
15 | 1 file changed, 37 insertions(+), 5 deletions(-) | ||
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 BlockBackend *img_open_opts(const char *optstr, | ||
22 | } | ||
23 | |||
24 | static BlockBackend *img_open_file(const char *filename, | ||
25 | + QDict *options, | ||
26 | const char *fmt, int flags, | ||
27 | bool writethrough, bool quiet, | ||
28 | bool force_share) | ||
29 | { | ||
30 | BlockBackend *blk; | ||
31 | Error *local_err = NULL; | ||
32 | - QDict *options = qdict_new(); | ||
33 | |||
34 | + if (!options) { | ||
35 | + options = qdict_new(); | ||
36 | + } | ||
37 | if (fmt) { | ||
38 | qdict_put_str(options, "driver", fmt); | ||
39 | } | ||
40 | @@ -XXX,XX +XXX,XX @@ static BlockBackend *img_open_file(const char *filename, | ||
41 | } | ||
42 | |||
43 | |||
44 | +static int img_add_key_secrets(void *opaque, | ||
45 | + const char *name, const char *value, | ||
46 | + Error **errp) | ||
47 | +{ | ||
48 | + QDict *options = opaque; | ||
49 | + | ||
50 | + if (g_str_has_suffix(name, "key-secret")) { | ||
51 | + qdict_put(options, name, qstring_from_str(value)); | ||
52 | + } | ||
53 | + | ||
54 | + return 0; | ||
55 | +} | ||
56 | + | ||
57 | +static BlockBackend *img_open_new_file(const char *filename, | ||
58 | + QemuOpts *create_opts, | ||
59 | + const char *fmt, int flags, | ||
60 | + bool writethrough, bool quiet, | ||
61 | + bool force_share) | ||
62 | +{ | ||
63 | + QDict *options = NULL; | ||
64 | + | ||
65 | + options = qdict_new(); | ||
66 | + qemu_opt_foreach(create_opts, img_add_key_secrets, options, &error_abort); | ||
67 | + | ||
68 | + return img_open_file(filename, options, fmt, flags, writethrough, quiet, | ||
69 | + force_share); | ||
70 | +} | ||
71 | + | ||
72 | + | ||
73 | static BlockBackend *img_open(bool image_opts, | ||
74 | const char *filename, | ||
75 | const char *fmt, int flags, bool writethrough, | ||
76 | @@ -XXX,XX +XXX,XX @@ static BlockBackend *img_open(bool image_opts, | ||
77 | blk = img_open_opts(filename, opts, flags, writethrough, quiet, | ||
78 | force_share); | ||
79 | } else { | ||
80 | - blk = img_open_file(filename, fmt, flags, writethrough, quiet, | ||
81 | + blk = img_open_file(filename, NULL, fmt, flags, writethrough, quiet, | ||
82 | force_share); | ||
83 | } | ||
84 | return blk; | ||
85 | @@ -XXX,XX +XXX,XX @@ static int img_convert(int argc, char **argv) | ||
86 | * That has to wait for bdrv_create to be improved | ||
87 | * to allow filenames in option syntax | ||
88 | */ | ||
89 | - s.target = img_open_file(out_filename, out_fmt, flags, | ||
90 | - writethrough, quiet, false); | ||
91 | + s.target = img_open_new_file(out_filename, opts, out_fmt, | ||
92 | + flags, writethrough, quiet, false); | ||
93 | } | ||
94 | if (!s.target) { | ||
95 | ret = -1; | ||
96 | @@ -XXX,XX +XXX,XX @@ static int img_dd(int argc, char **argv) | ||
97 | * with the bdrv_create() call above which does not | ||
98 | * support image-opts style. | ||
99 | */ | ||
100 | - blk2 = img_open_file(out.filename, out_fmt, BDRV_O_RDWR, | ||
101 | + blk2 = img_open_file(out.filename, NULL, out_fmt, BDRV_O_RDWR, | ||
102 | false, false, false); | ||
103 | |||
104 | if (!blk2) { | ||
105 | -- | ||
106 | 1.8.3.1 | ||
107 | |||
108 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Fam Zheng <famz@redhat.com> | ||
2 | 1 | ||
3 | Reported by Coverity. | ||
4 | |||
5 | Signed-off-by: Fam Zheng <famz@redhat.com> | ||
6 | Message-id: 20170515141014.25793-1-famz@redhat.com | ||
7 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
8 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
9 | --- | ||
10 | qemu-img.c | 1 + | ||
11 | 1 file changed, 1 insertion(+) | ||
12 | |||
13 | diff --git a/qemu-img.c b/qemu-img.c | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/qemu-img.c | ||
16 | +++ b/qemu-img.c | ||
17 | @@ -XXX,XX +XXX,XX @@ static BlockBackend *img_open_opts(const char *optstr, | ||
18 | if (qdict_haskey(options, BDRV_OPT_FORCE_SHARE) | ||
19 | && !qdict_get_bool(options, BDRV_OPT_FORCE_SHARE)) { | ||
20 | error_report("--force-share/-U conflicts with image options"); | ||
21 | + QDECREF(options); | ||
22 | return NULL; | ||
23 | } | ||
24 | qdict_put(options, BDRV_OPT_FORCE_SHARE, qbool_from_bool(true)); | ||
25 | -- | ||
26 | 1.8.3.1 | ||
27 | |||
28 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Eric Blake <eblake@redhat.com> | ||
2 | 1 | ||
3 | When converting a 1.1 image down to 0.10, qemu-iotests 060 forces | ||
4 | a contrived failure where allocating a cluster used to replace a | ||
5 | zero cluster reads unaligned data. Since it is a zero cluster | ||
6 | rather than a data cluster being converted, changing the error | ||
7 | message to match our earlier change in 'qcow2: Make distinction | ||
8 | between zero cluster types obvious' is worthwhile. | ||
9 | |||
10 | Suggested-by: Max Reitz <mreitz@redhat.com> | ||
11 | Signed-off-by: Eric Blake <eblake@redhat.com> | ||
12 | Message-id: 20170508171302.17805-1-eblake@redhat.com | ||
13 | [mreitz: Commit message fixes] | ||
14 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
15 | --- | ||
16 | block/qcow2-cluster.c | 3 ++- | ||
17 | tests/qemu-iotests/060.out | 2 +- | ||
18 | 2 files changed, 3 insertions(+), 2 deletions(-) | ||
19 | |||
20 | diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/block/qcow2-cluster.c | ||
23 | +++ b/block/qcow2-cluster.c | ||
24 | @@ -XXX,XX +XXX,XX @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table, | ||
25 | } | ||
26 | |||
27 | if (offset_into_cluster(s, offset)) { | ||
28 | - qcow2_signal_corruption(bs, true, -1, -1, "Data cluster offset " | ||
29 | + qcow2_signal_corruption(bs, true, -1, -1, | ||
30 | + "Cluster allocation offset " | ||
31 | "%#" PRIx64 " unaligned (L2 offset: %#" | ||
32 | PRIx64 ", L2 index: %#x)", offset, | ||
33 | l2_offset, j); | ||
34 | diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out | ||
35 | index XXXXXXX..XXXXXXX 100644 | ||
36 | --- a/tests/qemu-iotests/060.out | ||
37 | +++ b/tests/qemu-iotests/060.out | ||
38 | @@ -XXX,XX +XXX,XX @@ read failed: Input/output error | ||
39 | Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 | ||
40 | wrote 65536/65536 bytes at offset 0 | ||
41 | 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) | ||
42 | -qcow2: Marking image as corrupt: Data cluster offset 0x52a00 unaligned (L2 offset: 0x40000, L2 index: 0); further corruption events will be suppressed | ||
43 | +qcow2: Marking image as corrupt: Cluster allocation offset 0x52a00 unaligned (L2 offset: 0x40000, L2 index: 0); further corruption events will be suppressed | ||
44 | qemu-img: Error while amending options: Input/output error | ||
45 | |||
46 | === Testing unaligned reftable entry === | ||
47 | -- | ||
48 | 1.8.3.1 | ||
49 | |||
50 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Max Reitz <mreitz@redhat.com> | ||
2 | 1 | ||
3 | path_combine() naturally tries to preserve a protocol prefix. However, | ||
4 | it recognizes such a prefix by scanning for the first colon; which is | ||
5 | different from what path_has_protocol() does: There only is a protocol | ||
6 | prefix if there is a colon before the first slash. | ||
7 | |||
8 | A protocol prefix that is not recognized by path_has_protocol() is none, | ||
9 | and should thus not be taken as one. | ||
10 | |||
11 | Case in point, before this patch: | ||
12 | $ ./qemu-img create -f qcow2 -b backing.qcow2 ./top:image.qcow2 | ||
13 | qemu-img: ./top:image.qcow2: Could not open './top:backing.qcow2': | ||
14 | No such file or directory | ||
15 | |||
16 | Afterwards: | ||
17 | $ ./qemu-img create -f qcow2 -b backing.qcow2 ./top:image.qcow2 | ||
18 | qemu-img: ./top:image.qcow2: Could not open './backing.qcow2': | ||
19 | No such file or directory | ||
20 | |||
21 | Reported-by: yangyang <yangyang@redhat.com> | ||
22 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
23 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
24 | Message-id: 20170522195217.12991-2-mreitz@redhat.com | ||
25 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
26 | --- | ||
27 | block.c | 15 ++++++++++----- | ||
28 | 1 file changed, 10 insertions(+), 5 deletions(-) | ||
29 | |||
30 | diff --git a/block.c b/block.c | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/block.c | ||
33 | +++ b/block.c | ||
34 | @@ -XXX,XX +XXX,XX @@ void path_combine(char *dest, int dest_size, | ||
35 | if (path_is_absolute(filename)) { | ||
36 | pstrcpy(dest, dest_size, filename); | ||
37 | } else { | ||
38 | - p = strchr(base_path, ':'); | ||
39 | - if (p) | ||
40 | - p++; | ||
41 | - else | ||
42 | - p = base_path; | ||
43 | + const char *protocol_stripped = NULL; | ||
44 | + | ||
45 | + if (path_has_protocol(base_path)) { | ||
46 | + protocol_stripped = strchr(base_path, ':'); | ||
47 | + if (protocol_stripped) { | ||
48 | + protocol_stripped++; | ||
49 | + } | ||
50 | + } | ||
51 | + p = protocol_stripped ?: base_path; | ||
52 | + | ||
53 | p1 = strrchr(base_path, '/'); | ||
54 | #ifdef _WIN32 | ||
55 | { | ||
56 | -- | ||
57 | 1.8.3.1 | ||
58 | |||
59 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Max Reitz <mreitz@redhat.com> | ||
2 | 1 | ||
3 | The file drivers' *_parse_filename() implementations just strip the | ||
4 | optional protocol prefix off the filename. However, for e.g. | ||
5 | "file:foo:bar", this would lead to "foo:bar" being stored as the BDS's | ||
6 | filename which looks like it should be managed using the "foo" protocol. | ||
7 | This is especially troublesome if you then try to resolve a backing | ||
8 | filename based on "foo:bar". | ||
9 | |||
10 | This issue can only occur if the stripped part is a relative filename | ||
11 | ("file:/foo:bar" will be shortened to "/foo:bar" and having a slash | ||
12 | before the first colon means that "/foo" is not recognized as a protocol | ||
13 | part). Therefore, we can easily fix it by prepending "./" to such | ||
14 | filenames. | ||
15 | |||
16 | Before this patch: | ||
17 | $ ./qemu-img create -f qcow2 backing.qcow2 64M | ||
18 | Formatting 'backing.qcow2', fmt=qcow2 size=67108864 encryption=off | ||
19 | cluster_size=65536 lazy_refcounts=off refcount_bits=16 | ||
20 | $ ./qemu-img create -f qcow2 -b backing.qcow2 file:top:image.qcow2 | ||
21 | Formatting 'file:top:image.qcow2', fmt=qcow2 size=67108864 | ||
22 | backing_file=backing.qcow2 encryption=off cluster_size=65536 | ||
23 | lazy_refcounts=off refcount_bits=16 | ||
24 | $ ./qemu-io file:top:image.qcow2 | ||
25 | can't open device file:top:image.qcow2: Could not open backing file: | ||
26 | Unknown protocol 'top' | ||
27 | |||
28 | After this patch: | ||
29 | $ ./qemu-io file:top:image.qcow2 | ||
30 | [no error] | ||
31 | |||
32 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
33 | Message-id: 20170522195217.12991-3-mreitz@redhat.com | ||
34 | Reviewed-by: Eric Blake <eblake@redhat.com> | ||
35 | Signed-off-by: Max Reitz <mreitz@redhat.com> | ||
36 | --- | ||
37 | block.c | 35 +++++++++++++++++++++++++++++++++++ | ||
38 | block/file-posix.c | 17 +++-------------- | ||
39 | block/file-win32.c | 12 ++---------- | ||
40 | include/block/block_int.h | 3 +++ | ||
41 | 4 files changed, 43 insertions(+), 24 deletions(-) | ||
42 | |||
43 | diff --git a/block.c b/block.c | ||
44 | index XXXXXXX..XXXXXXX 100644 | ||
45 | --- a/block.c | ||
46 | +++ b/block.c | ||
47 | @@ -XXX,XX +XXX,XX @@ void path_combine(char *dest, int dest_size, | ||
48 | } | ||
49 | } | ||
50 | |||
51 | +/* | ||
52 | + * Helper function for bdrv_parse_filename() implementations to remove optional | ||
53 | + * protocol prefixes (especially "file:") from a filename and for putting the | ||
54 | + * stripped filename into the options QDict if there is such a prefix. | ||
55 | + */ | ||
56 | +void bdrv_parse_filename_strip_prefix(const char *filename, const char *prefix, | ||
57 | + QDict *options) | ||
58 | +{ | ||
59 | + if (strstart(filename, prefix, &filename)) { | ||
60 | + /* Stripping the explicit protocol prefix may result in a protocol | ||
61 | + * prefix being (wrongly) detected (if the filename contains a colon) */ | ||
62 | + if (path_has_protocol(filename)) { | ||
63 | + QString *fat_filename; | ||
64 | + | ||
65 | + /* This means there is some colon before the first slash; therefore, | ||
66 | + * this cannot be an absolute path */ | ||
67 | + assert(!path_is_absolute(filename)); | ||
68 | + | ||
69 | + /* And we can thus fix the protocol detection issue by prefixing it | ||
70 | + * by "./" */ | ||
71 | + fat_filename = qstring_from_str("./"); | ||
72 | + qstring_append(fat_filename, filename); | ||
73 | + | ||
74 | + assert(!path_has_protocol(qstring_get_str(fat_filename))); | ||
75 | + | ||
76 | + qdict_put(options, "filename", fat_filename); | ||
77 | + } else { | ||
78 | + /* If no protocol prefix was detected, we can use the shortened | ||
79 | + * filename as-is */ | ||
80 | + qdict_put_str(options, "filename", filename); | ||
81 | + } | ||
82 | + } | ||
83 | +} | ||
84 | + | ||
85 | + | ||
86 | /* Returns whether the image file is opened as read-only. Note that this can | ||
87 | * return false and writing to the image file is still not possible because the | ||
88 | * image is inactivated. */ | ||
89 | diff --git a/block/file-posix.c b/block/file-posix.c | ||
90 | index XXXXXXX..XXXXXXX 100644 | ||
91 | --- a/block/file-posix.c | ||
92 | +++ b/block/file-posix.c | ||
93 | @@ -XXX,XX +XXX,XX @@ static void raw_parse_flags(int bdrv_flags, int *open_flags) | ||
94 | static void raw_parse_filename(const char *filename, QDict *options, | ||
95 | Error **errp) | ||
96 | { | ||
97 | - /* The filename does not have to be prefixed by the protocol name, since | ||
98 | - * "file" is the default protocol; therefore, the return value of this | ||
99 | - * function call can be ignored. */ | ||
100 | - strstart(filename, "file:", &filename); | ||
101 | - | ||
102 | - qdict_put_str(options, "filename", filename); | ||
103 | + bdrv_parse_filename_strip_prefix(filename, "file:", options); | ||
104 | } | ||
105 | |||
106 | static QemuOptsList raw_runtime_opts = { | ||
107 | @@ -XXX,XX +XXX,XX @@ static int check_hdev_writable(BDRVRawState *s) | ||
108 | static void hdev_parse_filename(const char *filename, QDict *options, | ||
109 | Error **errp) | ||
110 | { | ||
111 | - /* The prefix is optional, just as for "file". */ | ||
112 | - strstart(filename, "host_device:", &filename); | ||
113 | - | ||
114 | - qdict_put_str(options, "filename", filename); | ||
115 | + bdrv_parse_filename_strip_prefix(filename, "host_device:", options); | ||
116 | } | ||
117 | |||
118 | static bool hdev_is_sg(BlockDriverState *bs) | ||
119 | @@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_host_device = { | ||
120 | static void cdrom_parse_filename(const char *filename, QDict *options, | ||
121 | Error **errp) | ||
122 | { | ||
123 | - /* The prefix is optional, just as for "file". */ | ||
124 | - strstart(filename, "host_cdrom:", &filename); | ||
125 | - | ||
126 | - qdict_put_str(options, "filename", filename); | ||
127 | + bdrv_parse_filename_strip_prefix(filename, "host_cdrom:", options); | ||
128 | } | ||
129 | #endif | ||
130 | |||
131 | diff --git a/block/file-win32.c b/block/file-win32.c | ||
132 | index XXXXXXX..XXXXXXX 100644 | ||
133 | --- a/block/file-win32.c | ||
134 | +++ b/block/file-win32.c | ||
135 | @@ -XXX,XX +XXX,XX @@ static void raw_parse_flags(int flags, bool use_aio, int *access_flags, | ||
136 | static void raw_parse_filename(const char *filename, QDict *options, | ||
137 | Error **errp) | ||
138 | { | ||
139 | - /* The filename does not have to be prefixed by the protocol name, since | ||
140 | - * "file" is the default protocol; therefore, the return value of this | ||
141 | - * function call can be ignored. */ | ||
142 | - strstart(filename, "file:", &filename); | ||
143 | - | ||
144 | - qdict_put_str(options, "filename", filename); | ||
145 | + bdrv_parse_filename_strip_prefix(filename, "file:", options); | ||
146 | } | ||
147 | |||
148 | static QemuOptsList raw_runtime_opts = { | ||
149 | @@ -XXX,XX +XXX,XX @@ static int hdev_probe_device(const char *filename) | ||
150 | static void hdev_parse_filename(const char *filename, QDict *options, | ||
151 | Error **errp) | ||
152 | { | ||
153 | - /* The prefix is optional, just as for "file". */ | ||
154 | - strstart(filename, "host_device:", &filename); | ||
155 | - | ||
156 | - qdict_put_str(options, "filename", filename); | ||
157 | + bdrv_parse_filename_strip_prefix(filename, "host_device:", options); | ||
158 | } | ||
159 | |||
160 | static int hdev_open(BlockDriverState *bs, QDict *options, int flags, | ||
161 | diff --git a/include/block/block_int.h b/include/block/block_int.h | ||
162 | index XXXXXXX..XXXXXXX 100644 | ||
163 | --- a/include/block/block_int.h | ||
164 | +++ b/include/block/block_int.h | ||
165 | @@ -XXX,XX +XXX,XX @@ int get_tmp_filename(char *filename, int size); | ||
166 | BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size, | ||
167 | const char *filename); | ||
168 | |||
169 | +void bdrv_parse_filename_strip_prefix(const char *filename, const char *prefix, | ||
170 | + QDict *options); | ||
171 | + | ||
172 | |||
173 | /** | ||
174 | * bdrv_add_before_write_notifier: | ||
175 | -- | ||
176 | 1.8.3.1 | ||
177 | |||
178 | diff view generated by jsdifflib |