[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-stable] [PATCH 56/67] block/curl: Remember all sockets
From: |
Michael Roth |
Subject: |
[Qemu-stable] [PATCH 56/67] block/curl: Remember all sockets |
Date: |
Wed, 14 Dec 2016 18:44:50 -0600 |
From: Max Reitz <address@hidden>
For some connection types (like FTP, generally), more than one socket
may be used (in FTP's case: control vs. data stream). As of commit
838ef602498b8d1985a231a06f5e328e2946a81d ("curl: Eliminate unnecessary
use of curl_multi_socket_all"), we have to remember all of the sockets
used by libcurl, but in fact we only did that for a single one. Since
one libcurl connection may use multiple sockets, however, we have to
remember them all.
Cc: address@hidden
Signed-off-by: Max Reitz <address@hidden>
Message-id: address@hidden
Signed-off-by: Jeff Cody <address@hidden>
(cherry picked from commit ff5ca1664af85b24a4180d595ea6873fd3deac57)
Signed-off-by: Michael Roth <address@hidden>
---
block/curl.c | 47 +++++++++++++++++++++++++++++++++++++++++------
1 file changed, 41 insertions(+), 6 deletions(-)
diff --git a/block/curl.c b/block/curl.c
index f47f4e6..600d032 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -105,12 +105,17 @@ typedef struct CURLAIOCB {
size_t end;
} CURLAIOCB;
+typedef struct CURLSocket {
+ int fd;
+ QLIST_ENTRY(CURLSocket) next;
+} CURLSocket;
+
typedef struct CURLState
{
struct BDRVCURLState *s;
CURLAIOCB *acb[CURL_NUM_ACB];
CURL *curl;
- curl_socket_t sock_fd;
+ QLIST_HEAD(, CURLSocket) sockets;
char *orig_buf;
size_t buf_start;
size_t buf_off;
@@ -164,10 +169,27 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int
action,
{
BDRVCURLState *s;
CURLState *state = NULL;
+ CURLSocket *socket;
+
curl_easy_getinfo(curl, CURLINFO_PRIVATE, (char **)&state);
- state->sock_fd = fd;
s = state->s;
+ QLIST_FOREACH(socket, &state->sockets, next) {
+ if (socket->fd == fd) {
+ if (action == CURL_POLL_REMOVE) {
+ QLIST_REMOVE(socket, next);
+ g_free(socket);
+ }
+ break;
+ }
+ }
+ if (!socket) {
+ socket = g_new0(CURLSocket, 1);
+ socket->fd = fd;
+ QLIST_INSERT_HEAD(&state->sockets, socket, next);
+ }
+ socket = NULL;
+
DPRINTF("CURL (AIO): Sock action %d on fd %d\n", action, (int)fd);
switch (action) {
case CURL_POLL_IN:
@@ -355,6 +377,7 @@ static void curl_multi_check_completion(BDRVCURLState *s)
static void curl_multi_do(void *arg)
{
CURLState *s = (CURLState *)arg;
+ CURLSocket *socket, *next_socket;
int running;
int r;
@@ -362,10 +385,13 @@ static void curl_multi_do(void *arg)
return;
}
- do {
- r = curl_multi_socket_action(s->s->multi, s->sock_fd, 0, &running);
- } while(r == CURLM_CALL_MULTI_PERFORM);
-
+ /* Need to use _SAFE because curl_multi_socket_action() may trigger
+ * curl_sock_cb() which might modify this list */
+ QLIST_FOREACH_SAFE(socket, &s->sockets, next, next_socket) {
+ do {
+ r = curl_multi_socket_action(s->s->multi, socket->fd, 0, &running);
+ } while (r == CURLM_CALL_MULTI_PERFORM);
+ }
}
static void curl_multi_read(void *arg)
@@ -469,6 +495,7 @@ static CURLState *curl_init_state(BlockDriverState *bs,
BDRVCURLState *s)
#endif
}
+ QLIST_INIT(&state->sockets);
state->s = s;
return state;
@@ -478,6 +505,14 @@ static void curl_clean_state(CURLState *s)
{
if (s->s->multi)
curl_multi_remove_handle(s->s->multi, s->curl);
+
+ while (!QLIST_EMPTY(&s->sockets)) {
+ CURLSocket *socket = QLIST_FIRST(&s->sockets);
+
+ QLIST_REMOVE(socket, next);
+ g_free(socket);
+ }
+
s->in_use = 0;
}
--
1.9.1
- [Qemu-stable] [PATCH 47/67] block: Don't mark node clean after failed flush, (continued)
- [Qemu-stable] [PATCH 47/67] block: Don't mark node clean after failed flush, Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 50/67] qcow2: Inform block layer about discard boundaries, Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 46/67] virtio-net: mark VIRTIO_NET_F_GSO as legacy, Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 51/67] block: Let write zeroes fallback work even with small max_transfer, Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 48/67] vhost: adapt vhost_verify_ring_mappings() to virtio 1 ring layout, Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 04/67] ppc: Check the availability of transactional memory, Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 53/67] block: Pass unaligned discard requests to drivers, Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 54/67] block/curl: Use BDRV_SECTOR_SIZE, Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 55/67] block/curl: Fix return value from curl_read_cb, Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 49/67] slirp: Fix access to freed memory, Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 56/67] block/curl: Remember all sockets,
Michael Roth <=
- [Qemu-stable] [PATCH 58/67] vhost: drop legacy vring layout bits, Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 60/67] pci-assign: sync MSI/MSI-X cap and table with PCIDevice, Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 52/67] block: Return -ENOTSUP rather than assert on unaligned discards, Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 63/67] vhost-user-test: Use libqos instead of pxe-virtio.rom, Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 57/67] block/curl: Do not wait for data beyond EOF, Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 61/67] rules.mak: Use -r instead of -Wl, -r to fix building when PIE is default, Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 66/67] msmouse: Fix segfault caused by free the chr before chardev cleanup., Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 05/67] virtio: zero vq->inuse in virtio_reset(), Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 59/67] ivshmem: Fix 64 bit memory bar configuration, Michael Roth, 2016/12/14
- [Qemu-stable] [PATCH 62/67] intel_iommu: fix incorrect device invalidate, Michael Roth, 2016/12/14