1 | The following changes since commit 6cb4f6db4f4367faa33da85b15f75bbbd2bed2a6: | 1 | The following changes since commit 741e1a618b126e664f7b723e6fe1b7ace511caf7: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'remotes/cleber/tags/python-next-pull-request' into staging (2019-03-07 16:16:02 +0000) | 3 | Merge remote-tracking branch 'remotes/stefanberger/tags/pull-tpm-2018-09-07-1' into staging (2018-09-24 18:12:54 +0100) |
4 | 4 | ||
5 | are available in the Git repository at: | 5 | are available in the Git repository at: |
6 | 6 | ||
7 | git://github.com/stefanha/qemu.git tags/block-pull-request | 7 | git://github.com/codyprime/qemu-kvm-jtc.git tags/block-pull-request |
8 | 8 | ||
9 | for you to fetch changes up to 6ca206204fa773c8626d59caf2a5676d6cc35f52: | 9 | for you to fetch changes up to 637fa44ab80c6b317adf1d117494325a95daad60: |
10 | 10 | ||
11 | iothread: document about why we need explicit aio_poll() (2019-03-08 10:20:57 +0000) | 11 | curl: Make sslverify=off disable host as well as peer verification. (2018-09-24 23:46:05 -0400) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Pull request | 14 | RBD and Curl patches |
15 | |||
16 | ---------------------------------------------------------------- | 15 | ---------------------------------------------------------------- |
17 | 16 | ||
18 | Anastasiia Rusakova (1): | 17 | Jeff Cody (4): |
19 | hw/block/virtio-blk: Clean req->dev repetitions | 18 | block/rbd: pull out qemu_rbd_convert_options |
19 | block/rbd: Attempt to parse legacy filenames | ||
20 | block/rbd: add iotest for rbd legacy keyvalue filename parsing | ||
21 | block/rbd: add deprecation documentation for filename keyvalue pairs | ||
20 | 22 | ||
21 | Peter Xu (5): | 23 | Richard W.M. Jones (1): |
22 | iothread: replace init_done_cond with a semaphore | 24 | curl: Make sslverify=off disable host as well as peer verification. |
23 | iothread: create the gcontext unconditionally | ||
24 | iothread: create main loop unconditionally | ||
25 | iothread: push gcontext earlier in the thread_fn | ||
26 | iothread: document about why we need explicit aio_poll() | ||
27 | 25 | ||
28 | Stefan Hajnoczi (1): | 26 | block/curl.c | 2 + |
29 | MAINTAINERS: add missing support status fields | 27 | block/rbd.c | 90 ++++++++++++++++++++++++++++++++------ |
30 | 28 | qemu-deprecated.texi | 15 +++++++ | |
31 | MAINTAINERS | 3 ++ | 29 | tests/qemu-iotests/231 | 62 ++++++++++++++++++++++++++ |
32 | include/sysemu/iothread.h | 5 +-- | 30 | tests/qemu-iotests/231.out | 9 ++++ |
33 | hw/block/virtio-blk.c | 16 ++++--- | 31 | tests/qemu-iotests/group | 1 + |
34 | iothread.c | 90 +++++++++++++++++++-------------------- | 32 | 6 files changed, 165 insertions(+), 14 deletions(-) |
35 | 4 files changed, 57 insertions(+), 57 deletions(-) | 33 | create mode 100755 tests/qemu-iotests/231 |
34 | create mode 100644 tests/qemu-iotests/231.out | ||
36 | 35 | ||
37 | -- | 36 | -- |
38 | 2.20.1 | 37 | 2.17.1 |
39 | 38 | ||
40 | 39 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | This patch adds the "S:" line for areas of the codebase that currently | ||
2 | lack a support status field. | ||
3 | 1 | ||
4 | Note that there are a few more areas that are more abstract and do not | ||
5 | correspond to a specific set of files. They have not been modified. | ||
6 | |||
7 | Cc: Alex Bennée <alex.bennee@linaro.org> | ||
8 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
9 | Reviewed-by: Thomas Huth <thuth@redhat.com> | ||
10 | Reviewed-by: Alex Bennée <alex.bennee@linaro.org> | ||
11 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | ||
12 | Message-id: 20190301163518.20702-1-stefanha@redhat.com | ||
13 | Message-Id: <20190301163518.20702-1-stefanha@redhat.com> | ||
14 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
15 | --- | ||
16 | MAINTAINERS | 3 +++ | ||
17 | 1 file changed, 3 insertions(+) | ||
18 | |||
19 | diff --git a/MAINTAINERS b/MAINTAINERS | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/MAINTAINERS | ||
22 | +++ b/MAINTAINERS | ||
23 | @@ -XXX,XX +XXX,XX @@ F: include/hw/tricore/ | ||
24 | |||
25 | Multiarch Linux User Tests | ||
26 | M: Alex Bennée <alex.bennee@linaro.org> | ||
27 | +S: Maintained | ||
28 | F: tests/tcg/multiarch/ | ||
29 | |||
30 | Guest CPU Cores (KVM): | ||
31 | @@ -XXX,XX +XXX,XX @@ F: qemu.sasl | ||
32 | Coroutines | ||
33 | M: Stefan Hajnoczi <stefanha@redhat.com> | ||
34 | M: Kevin Wolf <kwolf@redhat.com> | ||
35 | +S: Maintained | ||
36 | F: util/*coroutine* | ||
37 | F: include/qemu/coroutine* | ||
38 | F: tests/test-coroutine.c | ||
39 | @@ -XXX,XX +XXX,XX @@ F: .gitlab-ci.yml | ||
40 | Guest Test Compilation Support | ||
41 | M: Alex Bennée <alex.bennee@linaro.org> | ||
42 | R: Philippe Mathieu-Daudé <f4bug@amsat.org> | ||
43 | +S: Maintained | ||
44 | F: tests/tcg/Makefile | ||
45 | F: tests/tcg/Makefile.include | ||
46 | L: qemu-devel@nongnu.org | ||
47 | -- | ||
48 | 2.20.1 | ||
49 | |||
50 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Anastasiia Rusakova <arusakova917@gmail.com> | ||
2 | 1 | ||
3 | Some functions sometimes uses req->dev even though a local variable | ||
4 | VirtIOBlock* s = req->dev has already been defined. | ||
5 | Updated places to use s everywhere in the file. | ||
6 | |||
7 | Signed-off-by: Anastasiia Rusakova <arusakova917@gmail.com> | ||
8 | Message-id: 20190307161925.4158-1-rusakova.nastasia@icloud.com | ||
9 | Message-Id: <20190307161925.4158-1-rusakova.nastasia@icloud.com> | ||
10 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
11 | --- | ||
12 | hw/block/virtio-blk.c | 16 +++++++++------- | ||
13 | 1 file changed, 9 insertions(+), 7 deletions(-) | ||
14 | |||
15 | diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/hw/block/virtio-blk.c | ||
18 | +++ b/hw/block/virtio-blk.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static void virtio_blk_rw_complete(void *opaque, int ret) | ||
20 | } | ||
21 | |||
22 | if (ret) { | ||
23 | - int p = virtio_ldl_p(VIRTIO_DEVICE(req->dev), &req->out.type); | ||
24 | + int p = virtio_ldl_p(VIRTIO_DEVICE(s), &req->out.type); | ||
25 | bool is_read = !(p & VIRTIO_BLK_T_OUT); | ||
26 | /* Note that memory may be dirtied on read failure. If the | ||
27 | * virtio request is not completed here, as is the case for | ||
28 | @@ -XXX,XX +XXX,XX @@ static void virtio_blk_rw_complete(void *opaque, int ret) | ||
29 | } | ||
30 | |||
31 | virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); | ||
32 | - block_acct_done(blk_get_stats(req->dev->blk), &req->acct); | ||
33 | + block_acct_done(blk_get_stats(s->blk), &req->acct); | ||
34 | virtio_blk_free_request(req); | ||
35 | } | ||
36 | aio_context_release(blk_get_aio_context(s->conf.conf.blk)); | ||
37 | @@ -XXX,XX +XXX,XX @@ static int virtio_blk_handle_scsi_req(VirtIOBlockReq *req) | ||
38 | { | ||
39 | int status = VIRTIO_BLK_S_OK; | ||
40 | struct virtio_scsi_inhdr *scsi = NULL; | ||
41 | - VirtIODevice *vdev = VIRTIO_DEVICE(req->dev); | ||
42 | - VirtQueueElement *elem = &req->elem; | ||
43 | VirtIOBlock *blk = req->dev; | ||
44 | + VirtIODevice *vdev = VIRTIO_DEVICE(blk); | ||
45 | + VirtQueueElement *elem = &req->elem; | ||
46 | |||
47 | #ifdef __linux__ | ||
48 | int i; | ||
49 | @@ -XXX,XX +XXX,XX @@ static void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb) | ||
50 | |||
51 | static void virtio_blk_handle_flush(VirtIOBlockReq *req, MultiReqBuffer *mrb) | ||
52 | { | ||
53 | - block_acct_start(blk_get_stats(req->dev->blk), &req->acct, 0, | ||
54 | + VirtIOBlock *s = req->dev; | ||
55 | + | ||
56 | + block_acct_start(blk_get_stats(s->blk), &req->acct, 0, | ||
57 | BLOCK_ACCT_FLUSH); | ||
58 | |||
59 | /* | ||
60 | * Make sure all outstanding writes are posted to the backing device. | ||
61 | */ | ||
62 | if (mrb->is_write && mrb->num_reqs > 0) { | ||
63 | - virtio_blk_submit_multireq(req->dev->blk, mrb); | ||
64 | + virtio_blk_submit_multireq(s->blk, mrb); | ||
65 | } | ||
66 | - blk_aio_flush(req->dev->blk, virtio_blk_flush_complete, req); | ||
67 | + blk_aio_flush(s->blk, virtio_blk_flush_complete, req); | ||
68 | } | ||
69 | |||
70 | static bool virtio_blk_sect_range_ok(VirtIOBlock *dev, | ||
71 | -- | ||
72 | 2.20.1 | ||
73 | |||
74 | diff view generated by jsdifflib |
1 | From: Peter Xu <peterx@redhat.com> | 1 | Code movement to pull the conversion from Qdict to BlockdevOptionsRbd |
---|---|---|---|
2 | into a helper function. | ||
2 | 3 | ||
3 | In existing code we create the gcontext dynamically at the first | 4 | Reviewed-by: Eric Blake <eblake@redhat.com> |
4 | access of the gcontext from caller. That can bring some complexity | 5 | Reviewed-by: John Snow <jsnow@redhat.com> |
5 | and potential races during using iothread. Since the context itself | 6 | Signed-off-by: Jeff Cody <jcody@redhat.com> |
6 | is not that big a resource, and we won't have millions of iothread, | 7 | Message-id: 5b49a980f2cde6610ab1df41bb0277d00b5db893.1536704901.git.jcody@redhat.com |
7 | let's simply create the gcontext unconditionally. | 8 | Signed-off-by: Jeff Cody <jcody@redhat.com> |
9 | --- | ||
10 | block/rbd.c | 36 ++++++++++++++++++++++++------------ | ||
11 | 1 file changed, 24 insertions(+), 12 deletions(-) | ||
8 | 12 | ||
9 | This will also be a preparation work further to move the thread | 13 | diff --git a/block/rbd.c b/block/rbd.c |
10 | context push operation earlier than before (now it's only pushed right | ||
11 | before we want to start running the gmainloop). | ||
12 | |||
13 | Removing the g_once since it's not necessary, while introducing a new | ||
14 | run_gcontext boolean to show whether we want to run the gcontext. | ||
15 | |||
16 | Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> | ||
17 | Signed-off-by: Peter Xu <peterx@redhat.com> | ||
18 | Message-id: 20190306115532.23025-3-peterx@redhat.com | ||
19 | Message-Id: <20190306115532.23025-3-peterx@redhat.com> | ||
20 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
21 | --- | ||
22 | include/sysemu/iothread.h | 2 +- | ||
23 | iothread.c | 43 +++++++++++++++++++-------------------- | ||
24 | 2 files changed, 22 insertions(+), 23 deletions(-) | ||
25 | |||
26 | diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h | ||
27 | index XXXXXXX..XXXXXXX 100644 | 14 | index XXXXXXX..XXXXXXX 100644 |
28 | --- a/include/sysemu/iothread.h | 15 | --- a/block/rbd.c |
29 | +++ b/include/sysemu/iothread.h | 16 | +++ b/block/rbd.c |
30 | @@ -XXX,XX +XXX,XX @@ typedef struct { | 17 | @@ -XXX,XX +XXX,XX @@ failed_opts: |
31 | 18 | return r; | |
32 | QemuThread thread; | ||
33 | AioContext *ctx; | ||
34 | + bool run_gcontext; /* whether we should run gcontext */ | ||
35 | GMainContext *worker_context; | ||
36 | GMainLoop *main_loop; | ||
37 | - GOnce once; | ||
38 | QemuSemaphore init_done_sem; /* is thread init done? */ | ||
39 | bool stopping; /* has iothread_stop() been called? */ | ||
40 | bool running; /* should iothread_run() continue? */ | ||
41 | diff --git a/iothread.c b/iothread.c | ||
42 | index XXXXXXX..XXXXXXX 100644 | ||
43 | --- a/iothread.c | ||
44 | +++ b/iothread.c | ||
45 | @@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque) | ||
46 | * We must check the running state again in case it was | ||
47 | * changed in previous aio_poll() | ||
48 | */ | ||
49 | - if (iothread->running && atomic_read(&iothread->worker_context)) { | ||
50 | + if (iothread->running && atomic_read(&iothread->run_gcontext)) { | ||
51 | GMainLoop *loop; | ||
52 | |||
53 | g_main_context_push_thread_default(iothread->worker_context); | ||
54 | @@ -XXX,XX +XXX,XX @@ static void iothread_instance_init(Object *obj) | ||
55 | iothread->poll_max_ns = IOTHREAD_POLL_MAX_NS_DEFAULT; | ||
56 | iothread->thread_id = -1; | ||
57 | qemu_sem_init(&iothread->init_done_sem, 0); | ||
58 | + /* By default, we don't run gcontext */ | ||
59 | + atomic_set(&iothread->run_gcontext, 0); | ||
60 | } | 19 | } |
61 | 20 | ||
62 | static void iothread_instance_finalize(Object *obj) | 21 | +static int qemu_rbd_convert_options(QDict *options, BlockdevOptionsRbd **opts, |
63 | @@ -XXX,XX +XXX,XX @@ static void iothread_instance_finalize(Object *obj) | 22 | + Error **errp) |
64 | qemu_sem_destroy(&iothread->init_done_sem); | ||
65 | } | ||
66 | |||
67 | +static void iothread_init_gcontext(IOThread *iothread) | ||
68 | +{ | 23 | +{ |
69 | + GSource *source; | 24 | + Visitor *v; |
25 | + Error *local_err = NULL; | ||
70 | + | 26 | + |
71 | + iothread->worker_context = g_main_context_new(); | 27 | + /* Convert the remaining options into a QAPI object */ |
72 | + source = aio_get_g_source(iothread_get_aio_context(iothread)); | 28 | + v = qobject_input_visitor_new_flat_confused(options, errp); |
73 | + g_source_attach(source, iothread->worker_context); | 29 | + if (!v) { |
74 | + g_source_unref(source); | 30 | + return -EINVAL; |
31 | + } | ||
32 | + | ||
33 | + visit_type_BlockdevOptionsRbd(v, NULL, opts, &local_err); | ||
34 | + visit_free(v); | ||
35 | + | ||
36 | + if (local_err) { | ||
37 | + error_propagate(errp, local_err); | ||
38 | + return -EINVAL; | ||
39 | + } | ||
40 | + | ||
41 | + return 0; | ||
75 | +} | 42 | +} |
76 | + | 43 | + |
77 | static void iothread_complete(UserCreatable *obj, Error **errp) | 44 | static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, |
45 | Error **errp) | ||
78 | { | 46 | { |
79 | Error *local_error = NULL; | 47 | BDRVRBDState *s = bs->opaque; |
80 | @@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp) | 48 | BlockdevOptionsRbd *opts = NULL; |
81 | return; | 49 | - Visitor *v; |
50 | const QDictEntry *e; | ||
51 | Error *local_err = NULL; | ||
52 | char *keypairs, *secretid; | ||
53 | @@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, | ||
54 | qdict_del(options, "password-secret"); | ||
82 | } | 55 | } |
83 | 56 | ||
84 | + /* | 57 | - /* Convert the remaining options into a QAPI object */ |
85 | + * Init one GMainContext for the iothread unconditionally, even if | 58 | - v = qobject_input_visitor_new_flat_confused(options, errp); |
86 | + * it's not used | 59 | - if (!v) { |
87 | + */ | 60 | - r = -EINVAL; |
88 | + iothread_init_gcontext(iothread); | 61 | - goto out; |
89 | + | 62 | - } |
90 | aio_context_set_poll_params(iothread->ctx, | 63 | - |
91 | iothread->poll_max_ns, | 64 | - visit_type_BlockdevOptionsRbd(v, NULL, &opts, &local_err); |
92 | iothread->poll_grow, | 65 | - visit_free(v); |
93 | @@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp) | 66 | - |
94 | return; | 67 | + r = qemu_rbd_convert_options(options, &opts, &local_err); |
68 | if (local_err) { | ||
69 | error_propagate(errp, local_err); | ||
70 | - r = -EINVAL; | ||
71 | goto out; | ||
95 | } | 72 | } |
96 | 73 | ||
97 | - iothread->once = (GOnce) G_ONCE_INIT; | ||
98 | - | ||
99 | /* This assumes we are called from a thread with useful CPU affinity for us | ||
100 | * to inherit. | ||
101 | */ | ||
102 | @@ -XXX,XX +XXX,XX @@ IOThreadInfoList *qmp_query_iothreads(Error **errp) | ||
103 | return head; | ||
104 | } | ||
105 | |||
106 | -static gpointer iothread_g_main_context_init(gpointer opaque) | ||
107 | -{ | ||
108 | - AioContext *ctx; | ||
109 | - IOThread *iothread = opaque; | ||
110 | - GSource *source; | ||
111 | - | ||
112 | - iothread->worker_context = g_main_context_new(); | ||
113 | - | ||
114 | - ctx = iothread_get_aio_context(iothread); | ||
115 | - source = aio_get_g_source(ctx); | ||
116 | - g_source_attach(source, iothread->worker_context); | ||
117 | - g_source_unref(source); | ||
118 | - | ||
119 | - aio_notify(iothread->ctx); | ||
120 | - return NULL; | ||
121 | -} | ||
122 | - | ||
123 | GMainContext *iothread_get_g_main_context(IOThread *iothread) | ||
124 | { | ||
125 | - g_once(&iothread->once, iothread_g_main_context_init, iothread); | ||
126 | - | ||
127 | + atomic_set(&iothread->run_gcontext, 1); | ||
128 | + aio_notify(iothread->ctx); | ||
129 | return iothread->worker_context; | ||
130 | } | ||
131 | |||
132 | -- | 74 | -- |
133 | 2.20.1 | 75 | 2.17.1 |
134 | 76 | ||
135 | 77 | diff view generated by jsdifflib |
1 | From: Peter Xu <peterx@redhat.com> | 1 | When we converted rbd to get rid of the older key/value-centric |
---|---|---|---|
2 | encoding format, we broke compatibility with image files with backing | ||
3 | file strings encoded in the old format. | ||
2 | 4 | ||
3 | We were pushing the context until right before running the gmainloop. | 5 | This leaves a bit of an ugly conundrum, and a hacky solution. |
4 | Now since we have everything unconditionally, we can move this | ||
5 | earlier. | ||
6 | 6 | ||
7 | One benefit is that now it's done even before init_done_sem, so as | 7 | If the initial attempt to parse the "proper" options fails, it assumes |
8 | long as the iothread user calls iothread_create() and completes, we | 8 | that we may have an older key/value encoded filename. Fall back to |
9 | know that the thread stack is ready. | 9 | attempting to parse the filename, and extract the required options from |
10 | it. If that fails, pass along the original error message. | ||
10 | 11 | ||
11 | Signed-off-by: Peter Xu <peterx@redhat.com> | 12 | We do not support mixed modern usage alongside legacy keyvalue pair |
12 | Message-id: 20190306115532.23025-5-peterx@redhat.com | 13 | usage. |
13 | Message-Id: <20190306115532.23025-5-peterx@redhat.com> | ||
14 | 14 | ||
15 | [Tweaked comment wording as discussed with Peter Xu. | 15 | A deprecation warning has been added, although care should be taken |
16 | --Stefan] | 16 | when actually deprecating since the impact is not limited to |
17 | commandline or qapi usage, but also opening existing images. | ||
17 | 18 | ||
18 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | 19 | Reviewed-by: Eric Blake <eblake@redhat.com> |
20 | Signed-off-by: Jeff Cody <jcody@redhat.com> | ||
21 | Message-id: 15b332e5432ad069441f7275a46080f465d789a0.1536704901.git.jcody@redhat.com | ||
22 | Signed-off-by: Jeff Cody <jcody@redhat.com> | ||
19 | --- | 23 | --- |
20 | iothread.c | 9 ++++++--- | 24 | block/rbd.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++-- |
21 | 1 file changed, 6 insertions(+), 3 deletions(-) | 25 | 1 file changed, 52 insertions(+), 2 deletions(-) |
22 | 26 | ||
23 | diff --git a/iothread.c b/iothread.c | 27 | diff --git a/block/rbd.c b/block/rbd.c |
24 | index XXXXXXX..XXXXXXX 100644 | 28 | index XXXXXXX..XXXXXXX 100644 |
25 | --- a/iothread.c | 29 | --- a/block/rbd.c |
26 | +++ b/iothread.c | 30 | +++ b/block/rbd.c |
27 | @@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque) | 31 | @@ -XXX,XX +XXX,XX @@ static int qemu_rbd_convert_options(QDict *options, BlockdevOptionsRbd **opts, |
28 | IOThread *iothread = opaque; | 32 | return 0; |
29 | 33 | } | |
30 | rcu_register_thread(); | 34 | |
31 | - | 35 | +static int qemu_rbd_attempt_legacy_options(QDict *options, |
32 | + /* | 36 | + BlockdevOptionsRbd **opts, |
33 | + * g_main_context_push_thread_default() must be called before anything | 37 | + char **keypairs) |
34 | + * in this new thread uses glib. | 38 | +{ |
35 | + */ | 39 | + char *filename; |
36 | + g_main_context_push_thread_default(iothread->worker_context); | 40 | + int r; |
37 | my_iothread = iothread; | 41 | + |
38 | iothread->thread_id = qemu_get_thread_id(); | 42 | + filename = g_strdup(qdict_get_try_str(options, "filename")); |
39 | qemu_sem_post(&iothread->init_done_sem); | 43 | + if (!filename) { |
40 | @@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque) | 44 | + return -EINVAL; |
41 | * changed in previous aio_poll() | 45 | + } |
42 | */ | 46 | + qdict_del(options, "filename"); |
43 | if (iothread->running && atomic_read(&iothread->run_gcontext)) { | 47 | + |
44 | - g_main_context_push_thread_default(iothread->worker_context); | 48 | + qemu_rbd_parse_filename(filename, options, NULL); |
45 | g_main_loop_run(iothread->main_loop); | 49 | + |
46 | - g_main_context_pop_thread_default(iothread->worker_context); | 50 | + /* keypairs freed by caller */ |
47 | } | 51 | + *keypairs = g_strdup(qdict_get_try_str(options, "=keyvalue-pairs")); |
52 | + if (*keypairs) { | ||
53 | + qdict_del(options, "=keyvalue-pairs"); | ||
54 | + } | ||
55 | + | ||
56 | + r = qemu_rbd_convert_options(options, opts, NULL); | ||
57 | + | ||
58 | + g_free(filename); | ||
59 | + return r; | ||
60 | +} | ||
61 | + | ||
62 | static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, | ||
63 | Error **errp) | ||
64 | { | ||
65 | @@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, | ||
66 | |||
67 | r = qemu_rbd_convert_options(options, &opts, &local_err); | ||
68 | if (local_err) { | ||
69 | - error_propagate(errp, local_err); | ||
70 | - goto out; | ||
71 | + /* If keypairs are present, that means some options are present in | ||
72 | + * the modern option format. Don't attempt to parse legacy option | ||
73 | + * formats, as we won't support mixed usage. */ | ||
74 | + if (keypairs) { | ||
75 | + error_propagate(errp, local_err); | ||
76 | + goto out; | ||
77 | + } | ||
78 | + | ||
79 | + /* If the initial attempt to convert and process the options failed, | ||
80 | + * we may be attempting to open an image file that has the rbd options | ||
81 | + * specified in the older format consisting of all key/value pairs | ||
82 | + * encoded in the filename. Go ahead and attempt to parse the | ||
83 | + * filename, and see if we can pull out the required options. */ | ||
84 | + r = qemu_rbd_attempt_legacy_options(options, &opts, &keypairs); | ||
85 | + if (r < 0) { | ||
86 | + /* Propagate the original error, not the legacy parsing fallback | ||
87 | + * error, as the latter was just a best-effort attempt. */ | ||
88 | + error_propagate(errp, local_err); | ||
89 | + goto out; | ||
90 | + } | ||
91 | + /* Take care whenever deciding to actually deprecate; once this ability | ||
92 | + * is removed, we will not be able to open any images with legacy-styled | ||
93 | + * backing image strings. */ | ||
94 | + error_report("RBD options encoded in the filename as keyvalue pairs " | ||
95 | + "is deprecated"); | ||
48 | } | 96 | } |
49 | 97 | ||
50 | + g_main_context_pop_thread_default(iothread->worker_context); | 98 | /* Remove the processed options from the QDict (the visitor processes |
51 | rcu_unregister_thread(); | ||
52 | return NULL; | ||
53 | } | ||
54 | -- | 99 | -- |
55 | 2.20.1 | 100 | 2.17.1 |
56 | 101 | ||
57 | 102 | diff view generated by jsdifflib |
1 | From: Peter Xu <peterx@redhat.com> | 1 | This is a small test that will check for the ability to parse |
---|---|---|---|
2 | both legacy and modern options for rbd. | ||
2 | 3 | ||
3 | After consulting Paolo I know why we'd better keep the explicit | 4 | The way the test is set up is for failure to occur, but without |
4 | aio_poll() in iothread_run(). Document it directly into the code so | 5 | having to wait to timeout on a non-existent rbd server. The error |
5 | that future readers will know the answer from day one. | 6 | messages in the success path show that the arguments were parsed. |
6 | 7 | ||
7 | Signed-off-by: Peter Xu <peterx@redhat.com> | 8 | The failure behavior prior to the patch series that has this test, is |
8 | Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> | 9 | qemu-img complaining about mandatory options (e.g. 'pool') not being |
9 | Message-id: 20190306115532.23025-6-peterx@redhat.com | 10 | provided. |
10 | Message-Id: <20190306115532.23025-6-peterx@redhat.com> | 11 | |
11 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | 12 | Reviewed-by: Eric Blake <eblake@redhat.com> |
13 | Signed-off-by: Jeff Cody <jcody@redhat.com> | ||
14 | Message-id: f830580e339b974a83ed4870d11adcdc17f49a47.1536704901.git.jcody@redhat.com | ||
15 | Signed-off-by: Jeff Cody <jcody@redhat.com> | ||
12 | --- | 16 | --- |
13 | iothread.c | 9 +++++++++ | 17 | tests/qemu-iotests/231 | 62 ++++++++++++++++++++++++++++++++++++++ |
14 | 1 file changed, 9 insertions(+) | 18 | tests/qemu-iotests/231.out | 9 ++++++ |
19 | tests/qemu-iotests/group | 1 + | ||
20 | 3 files changed, 72 insertions(+) | ||
21 | create mode 100755 tests/qemu-iotests/231 | ||
22 | create mode 100644 tests/qemu-iotests/231.out | ||
15 | 23 | ||
16 | diff --git a/iothread.c b/iothread.c | 24 | diff --git a/tests/qemu-iotests/231 b/tests/qemu-iotests/231 |
25 | new file mode 100755 | ||
26 | index XXXXXXX..XXXXXXX | ||
27 | --- /dev/null | ||
28 | +++ b/tests/qemu-iotests/231 | ||
29 | @@ -XXX,XX +XXX,XX @@ | ||
30 | +#!/bin/bash | ||
31 | +# | ||
32 | +# Test legacy and modern option parsing for rbd/ceph. This will not | ||
33 | +# actually connect to a ceph server, but rather looks for the appropriate | ||
34 | +# error message that indicates we parsed the options correctly. | ||
35 | +# | ||
36 | +# Copyright (C) 2018 Red Hat, Inc. | ||
37 | +# | ||
38 | +# This program is free software; you can redistribute it and/or modify | ||
39 | +# it under the terms of the GNU General Public License as published by | ||
40 | +# the Free Software Foundation; either version 2 of the License, or | ||
41 | +# (at your option) any later version. | ||
42 | +# | ||
43 | +# This program is distributed in the hope that it will be useful, | ||
44 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
45 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
46 | +# GNU General Public License for more details. | ||
47 | +# | ||
48 | +# You should have received a copy of the GNU General Public License | ||
49 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
50 | +# | ||
51 | + | ||
52 | +# creator | ||
53 | +owner=jcody@redhat.com | ||
54 | + | ||
55 | +seq=`basename $0` | ||
56 | +echo "QA output created by $seq" | ||
57 | + | ||
58 | +here=`pwd` | ||
59 | +status=1 # failure is the default! | ||
60 | + | ||
61 | +_cleanup() | ||
62 | +{ | ||
63 | + rm "${BOGUS_CONF}" | ||
64 | +} | ||
65 | +trap "_cleanup; exit \$status" 0 1 2 3 15 | ||
66 | + | ||
67 | +# get standard environment, filters and checks | ||
68 | +. ./common.rc | ||
69 | +. ./common.filter | ||
70 | + | ||
71 | +_supported_fmt generic | ||
72 | +_supported_proto rbd | ||
73 | +_supported_os Linux | ||
74 | + | ||
75 | +BOGUS_CONF=${TEST_DIR}/ceph-$$.conf | ||
76 | +touch "${BOGUS_CONF}" | ||
77 | + | ||
78 | +_filter_conf() | ||
79 | +{ | ||
80 | + sed -e "s#$BOGUS_CONF#BOGUS_CONF#g" | ||
81 | +} | ||
82 | + | ||
83 | +# We expect this to fail, with no monitor ip provided and a null conf file. Just want it | ||
84 | +# to fail in the right way. | ||
85 | +$QEMU_IMG info "json:{'file.driver':'rbd','file.filename':'rbd:rbd/bogus:conf=${BOGUS_CONF}'}" 2>&1 | _filter_conf | ||
86 | +$QEMU_IMG info "json:{'file.driver':'rbd','file.pool':'rbd','file.image':'bogus','file.conf':'${BOGUS_CONF}'}" 2>&1 | _filter_conf | ||
87 | + | ||
88 | +# success, all done | ||
89 | +echo "*** done" | ||
90 | +rm -f $seq.full | ||
91 | +status=0 | ||
92 | diff --git a/tests/qemu-iotests/231.out b/tests/qemu-iotests/231.out | ||
93 | new file mode 100644 | ||
94 | index XXXXXXX..XXXXXXX | ||
95 | --- /dev/null | ||
96 | +++ b/tests/qemu-iotests/231.out | ||
97 | @@ -XXX,XX +XXX,XX @@ | ||
98 | +QA output created by 231 | ||
99 | +qemu-img: RBD options encoded in the filename as keyvalue pairs is deprecated. Future versions may cease to parse these options in the future. | ||
100 | +unable to get monitor info from DNS SRV with service name: ceph-mon | ||
101 | +no monitors specified to connect to. | ||
102 | +qemu-img: Could not open 'json:{'file.driver':'rbd','file.filename':'rbd:rbd/bogus:conf=BOGUS_CONF'}': error connecting: No such file or directory | ||
103 | +unable to get monitor info from DNS SRV with service name: ceph-mon | ||
104 | +no monitors specified to connect to. | ||
105 | +qemu-img: Could not open 'json:{'file.driver':'rbd','file.pool':'rbd','file.image':'bogus','file.conf':'BOGUS_CONF'}': error connecting: No such file or directory | ||
106 | +*** done | ||
107 | diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group | ||
17 | index XXXXXXX..XXXXXXX 100644 | 108 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/iothread.c | 109 | --- a/tests/qemu-iotests/group |
19 | +++ b/iothread.c | 110 | +++ b/tests/qemu-iotests/group |
20 | @@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque) | 111 | @@ -XXX,XX +XXX,XX @@ |
21 | qemu_sem_post(&iothread->init_done_sem); | 112 | 226 auto quick |
22 | 113 | 227 auto quick | |
23 | while (iothread->running) { | 114 | 229 auto quick |
24 | + /* | 115 | +231 auto quick |
25 | + * Note: from functional-wise the g_main_loop_run() below can | ||
26 | + * already cover the aio_poll() events, but we can't run the | ||
27 | + * main loop unconditionally because explicit aio_poll() here | ||
28 | + * is faster than g_main_loop_run() when we do not need the | ||
29 | + * gcontext at all (e.g., pure block layer iothreads). In | ||
30 | + * other words, when we want to run the gcontext with the | ||
31 | + * iothread we need to pay some performance for functionality. | ||
32 | + */ | ||
33 | aio_poll(iothread->ctx, true); | ||
34 | |||
35 | /* | ||
36 | -- | 116 | -- |
37 | 2.20.1 | 117 | 2.17.1 |
38 | 118 | ||
39 | 119 | diff view generated by jsdifflib |
1 | From: Peter Xu <peterx@redhat.com> | 1 | Signed-off-by: Jeff Cody <jcody@redhat.com> |
---|---|---|---|
2 | Message-id: 647f5b5ab7efd8bf567a504c832b1d2d6f719b23.1536704901.git.jcody@redhat.com | ||
3 | Signed-off-by: Jeff Cody <jcody@redhat.com> | ||
4 | --- | ||
5 | qemu-deprecated.texi | 15 +++++++++++++++ | ||
6 | 1 file changed, 15 insertions(+) | ||
2 | 7 | ||
3 | Since we've have the gcontext always there, create the main loop | 8 | diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi |
4 | altogether. The iothread_run() is even cleaner. | ||
5 | |||
6 | Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> | ||
7 | Signed-off-by: Peter Xu <peterx@redhat.com> | ||
8 | Message-id: 20190306115532.23025-4-peterx@redhat.com | ||
9 | Message-Id: <20190306115532.23025-4-peterx@redhat.com> | ||
10 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
11 | --- | ||
12 | iothread.c | 12 +++--------- | ||
13 | 1 file changed, 3 insertions(+), 9 deletions(-) | ||
14 | |||
15 | diff --git a/iothread.c b/iothread.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/iothread.c | 10 | --- a/qemu-deprecated.texi |
18 | +++ b/iothread.c | 11 | +++ b/qemu-deprecated.texi |
19 | @@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque) | 12 | @@ -XXX,XX +XXX,XX @@ used instead. |
20 | * changed in previous aio_poll() | 13 | In order to prevent QEMU from automatically opening an image's backing |
21 | */ | 14 | chain, use ``"backing": null'' instead. |
22 | if (iothread->running && atomic_read(&iothread->run_gcontext)) { | 15 | |
23 | - GMainLoop *loop; | 16 | +@subsubsection rbd keyvalue pair encoded filenames: "" (since 3.1.0) |
24 | - | 17 | + |
25 | g_main_context_push_thread_default(iothread->worker_context); | 18 | +Options for ``rbd'' should be specified according to its runtime options, |
26 | - iothread->main_loop = | 19 | +like other block drivers. Legacy parsing of keyvalue pair encoded |
27 | - g_main_loop_new(iothread->worker_context, TRUE); | 20 | +filenames is useful to open images with the old format for backing files; |
28 | - loop = iothread->main_loop; | 21 | +These image files should be updated to use the current format. |
29 | - | 22 | + |
30 | g_main_loop_run(iothread->main_loop); | 23 | +Example of legacy encoding: |
31 | - iothread->main_loop = NULL; | 24 | + |
32 | - g_main_loop_unref(loop); | 25 | +@code{json:@{"file.driver":"rbd", "file.filename":"rbd:rbd/name"@}} |
33 | - | 26 | + |
34 | g_main_context_pop_thread_default(iothread->worker_context); | 27 | +The above, converted to the current supported format: |
35 | } | 28 | + |
36 | } | 29 | +@code{json:@{"file.driver":"rbd", "file.pool":"rbd", "file.image":"name"@}} |
37 | @@ -XXX,XX +XXX,XX @@ static void iothread_instance_finalize(Object *obj) | 30 | + |
38 | if (iothread->worker_context) { | 31 | @subsection vio-spapr-device device options |
39 | g_main_context_unref(iothread->worker_context); | 32 | |
40 | iothread->worker_context = NULL; | 33 | @subsubsection "irq": "" (since 3.0.0) |
41 | + g_main_loop_unref(iothread->main_loop); | ||
42 | + iothread->main_loop = NULL; | ||
43 | } | ||
44 | qemu_sem_destroy(&iothread->init_done_sem); | ||
45 | } | ||
46 | @@ -XXX,XX +XXX,XX @@ static void iothread_init_gcontext(IOThread *iothread) | ||
47 | source = aio_get_g_source(iothread_get_aio_context(iothread)); | ||
48 | g_source_attach(source, iothread->worker_context); | ||
49 | g_source_unref(source); | ||
50 | + iothread->main_loop = g_main_loop_new(iothread->worker_context, TRUE); | ||
51 | } | ||
52 | |||
53 | static void iothread_complete(UserCreatable *obj, Error **errp) | ||
54 | -- | 34 | -- |
55 | 2.20.1 | 35 | 2.17.1 |
56 | 36 | ||
57 | 37 | diff view generated by jsdifflib |
1 | From: Peter Xu <peterx@redhat.com> | 1 | From: "Richard W.M. Jones" <rjones@redhat.com> |
---|---|---|---|
2 | 2 | ||
3 | Only sending an init-done message using lock+cond seems an overkill to | 3 | The sslverify setting is supposed to turn off all TLS certificate |
4 | me. Replacing it with a simpler semaphore. | 4 | checks in libcurl. However because of the way we use it, it only |
5 | turns off peer certificate authenticity checks | ||
6 | (CURLOPT_SSL_VERIFYPEER). This patch makes it also turn off the check | ||
7 | that the server name in the certificate is the same as the server | ||
8 | you're connecting to (CURLOPT_SSL_VERIFYHOST). | ||
5 | 9 | ||
6 | Meanwhile, init the semaphore unconditionally, then we can destroy it | 10 | We can use Google's server at 8.8.8.8 which happens to have a bad TLS |
7 | unconditionally too in finalize which seems cleaner. | 11 | certificate to demonstrate this: |
8 | 12 | ||
9 | Signed-off-by: Peter Xu <peterx@redhat.com> | 13 | $ ./qemu-img create -q -f qcow2 -b 'json: { "file.sslverify": "off", "file.driver": "https", "file.url": "https://8.8.8.8/foo" }' /var/tmp/file.qcow2 |
10 | Message-id: 20190306115532.23025-2-peterx@redhat.com | 14 | qemu-img: /var/tmp/file.qcow2: CURL: Error opening file: SSL: no alternative certificate subject name matches target host name '8.8.8.8' |
11 | Message-Id: <20190306115532.23025-2-peterx@redhat.com> | 15 | Could not open backing image to determine size. |
12 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | 16 | |
17 | With this patch applied, qemu-img connects to the server regardless of | ||
18 | the bad certificate: | ||
19 | |||
20 | $ ./qemu-img create -q -f qcow2 -b 'json: { "file.sslverify": "off", "file.driver": "https", "file.url": "https://8.8.8.8/foo" }' /var/tmp/file.qcow2 | ||
21 | qemu-img: /var/tmp/file.qcow2: CURL: Error opening file: The requested URL returned error: 404 Not Found | ||
22 | |||
23 | (The 404 error is expected because 8.8.8.8 is not actually serving a | ||
24 | file called "/foo".) | ||
25 | |||
26 | Of course the default (without sslverify=off) remains to always check | ||
27 | the certificate: | ||
28 | |||
29 | $ ./qemu-img create -q -f qcow2 -b 'json: { "file.driver": "https", "file.url": "https://8.8.8.8/foo" }' /var/tmp/file.qcow2 | ||
30 | qemu-img: /var/tmp/file.qcow2: CURL: Error opening file: SSL: no alternative certificate subject name matches target host name '8.8.8.8' | ||
31 | Could not open backing image to determine size. | ||
32 | |||
33 | Further information about the two settings is available here: | ||
34 | |||
35 | https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html | ||
36 | https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html | ||
37 | |||
38 | Signed-off-by: Richard W.M. Jones <rjones@redhat.com> | ||
39 | Message-id: 20180914095622.19698-1-rjones@redhat.com | ||
40 | Signed-off-by: Jeff Cody <jcody@redhat.com> | ||
13 | --- | 41 | --- |
14 | include/sysemu/iothread.h | 3 +-- | 42 | block/curl.c | 2 ++ |
15 | iothread.c | 17 ++++------------- | 43 | 1 file changed, 2 insertions(+) |
16 | 2 files changed, 5 insertions(+), 15 deletions(-) | ||
17 | 44 | ||
18 | diff --git a/include/sysemu/iothread.h b/include/sysemu/iothread.h | 45 | diff --git a/block/curl.c b/block/curl.c |
19 | index XXXXXXX..XXXXXXX 100644 | 46 | index XXXXXXX..XXXXXXX 100644 |
20 | --- a/include/sysemu/iothread.h | 47 | --- a/block/curl.c |
21 | +++ b/include/sysemu/iothread.h | 48 | +++ b/block/curl.c |
22 | @@ -XXX,XX +XXX,XX @@ typedef struct { | 49 | @@ -XXX,XX +XXX,XX @@ static int curl_init_state(BDRVCURLState *s, CURLState *state) |
23 | GMainContext *worker_context; | 50 | curl_easy_setopt(state->curl, CURLOPT_URL, s->url); |
24 | GMainLoop *main_loop; | 51 | curl_easy_setopt(state->curl, CURLOPT_SSL_VERIFYPEER, |
25 | GOnce once; | 52 | (long) s->sslverify); |
26 | - QemuMutex init_done_lock; | 53 | + curl_easy_setopt(state->curl, CURLOPT_SSL_VERIFYHOST, |
27 | - QemuCond init_done_cond; /* is thread initialization done? */ | 54 | + s->sslverify ? 2L : 0L); |
28 | + QemuSemaphore init_done_sem; /* is thread init done? */ | 55 | if (s->cookie) { |
29 | bool stopping; /* has iothread_stop() been called? */ | 56 | curl_easy_setopt(state->curl, CURLOPT_COOKIE, s->cookie); |
30 | bool running; /* should iothread_run() continue? */ | 57 | } |
31 | int thread_id; | ||
32 | diff --git a/iothread.c b/iothread.c | ||
33 | index XXXXXXX..XXXXXXX 100644 | ||
34 | --- a/iothread.c | ||
35 | +++ b/iothread.c | ||
36 | @@ -XXX,XX +XXX,XX @@ static void *iothread_run(void *opaque) | ||
37 | rcu_register_thread(); | ||
38 | |||
39 | my_iothread = iothread; | ||
40 | - qemu_mutex_lock(&iothread->init_done_lock); | ||
41 | iothread->thread_id = qemu_get_thread_id(); | ||
42 | - qemu_cond_signal(&iothread->init_done_cond); | ||
43 | - qemu_mutex_unlock(&iothread->init_done_lock); | ||
44 | + qemu_sem_post(&iothread->init_done_sem); | ||
45 | |||
46 | while (iothread->running) { | ||
47 | aio_poll(iothread->ctx, true); | ||
48 | @@ -XXX,XX +XXX,XX @@ static void iothread_instance_init(Object *obj) | ||
49 | |||
50 | iothread->poll_max_ns = IOTHREAD_POLL_MAX_NS_DEFAULT; | ||
51 | iothread->thread_id = -1; | ||
52 | + qemu_sem_init(&iothread->init_done_sem, 0); | ||
53 | } | ||
54 | |||
55 | static void iothread_instance_finalize(Object *obj) | ||
56 | @@ -XXX,XX +XXX,XX @@ static void iothread_instance_finalize(Object *obj) | ||
57 | |||
58 | iothread_stop(iothread); | ||
59 | |||
60 | - if (iothread->thread_id != -1) { | ||
61 | - qemu_cond_destroy(&iothread->init_done_cond); | ||
62 | - qemu_mutex_destroy(&iothread->init_done_lock); | ||
63 | - } | ||
64 | /* | ||
65 | * Before glib2 2.33.10, there is a glib2 bug that GSource context | ||
66 | * pointer may not be cleared even if the context has already been | ||
67 | @@ -XXX,XX +XXX,XX @@ static void iothread_instance_finalize(Object *obj) | ||
68 | g_main_context_unref(iothread->worker_context); | ||
69 | iothread->worker_context = NULL; | ||
70 | } | ||
71 | + qemu_sem_destroy(&iothread->init_done_sem); | ||
72 | } | ||
73 | |||
74 | static void iothread_complete(UserCreatable *obj, Error **errp) | ||
75 | @@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp) | ||
76 | return; | ||
77 | } | ||
78 | |||
79 | - qemu_mutex_init(&iothread->init_done_lock); | ||
80 | - qemu_cond_init(&iothread->init_done_cond); | ||
81 | iothread->once = (GOnce) G_ONCE_INIT; | ||
82 | |||
83 | /* This assumes we are called from a thread with useful CPU affinity for us | ||
84 | @@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp) | ||
85 | g_free(name); | ||
86 | |||
87 | /* Wait for initialization to complete */ | ||
88 | - qemu_mutex_lock(&iothread->init_done_lock); | ||
89 | while (iothread->thread_id == -1) { | ||
90 | - qemu_cond_wait(&iothread->init_done_cond, | ||
91 | - &iothread->init_done_lock); | ||
92 | + qemu_sem_wait(&iothread->init_done_sem); | ||
93 | } | ||
94 | - qemu_mutex_unlock(&iothread->init_done_lock); | ||
95 | } | ||
96 | |||
97 | typedef struct { | ||
98 | -- | 58 | -- |
99 | 2.20.1 | 59 | 2.17.1 |
100 | 60 | ||
101 | 61 | diff view generated by jsdifflib |