All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrange" <berrange@redhat.com>
To: qemu-devel@nongnu.org
Cc: Paolo Bonzini <pbonzini@redhat.com>, qemu-block@nongnu.org
Subject: [Qemu-devel] [PATCH v3 01/13] nbd: convert block client to use I/O channels for connection setup
Date: Tue, 19 Jan 2016 13:09:11 +0000	[thread overview]
Message-ID: <1453208963-16834-2-git-send-email-berrange@redhat.com> (raw)
In-Reply-To: <1453208963-16834-1-git-send-email-berrange@redhat.com>

This converts the NBD block driver client to use the QIOChannelSocket
class for initial connection setup. The NbdClientSession struct has
two pointers, one to the master QIOChannelSocket providing the raw
data channel, and one to a QIOChannel which is the current channel
used for I/O. Initially the two point to the same object, but when
TLS support is added, they will point to different objects.

In this initial conversion though, all I/O is still actually done
using the raw POSIX sockets APIs.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 Makefile           |  6 +++---
 block/nbd-client.c | 59 ++++++++++++++++++++++++++++--------------------------
 block/nbd-client.h |  8 ++++++--
 block/nbd.c        | 39 ++++++++++++++++++------------------
 tests/Makefile     |  2 +-
 5 files changed, 61 insertions(+), 53 deletions(-)

diff --git a/Makefile b/Makefile
index d0de2d4..b7b0f24 100644
--- a/Makefile
+++ b/Makefile
@@ -234,9 +234,9 @@ util/module.o-cflags = -D'CONFIG_BLOCK_MODULES=$(block-modules)'
 
 qemu-img.o: qemu-img-cmds.h
 
-qemu-img$(EXESUF): qemu-img.o $(block-obj-y) $(crypto-obj-y) $(qom-obj-y) libqemuutil.a libqemustub.a
-qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) $(crypto-obj-y) $(qom-obj-y) libqemuutil.a libqemustub.a
-qemu-io$(EXESUF): qemu-io.o $(block-obj-y) $(crypto-obj-y) $(qom-obj-y) libqemuutil.a libqemustub.a
+qemu-img$(EXESUF): qemu-img.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) libqemuutil.a libqemustub.a
+qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) libqemuutil.a libqemustub.a
+qemu-io$(EXESUF): qemu-io.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) libqemuutil.a libqemustub.a
 
 qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
 
diff --git a/block/nbd-client.c b/block/nbd-client.c
index b7fd17a..bf5b0a3 100644
--- a/block/nbd-client.c
+++ b/block/nbd-client.c
@@ -27,7 +27,6 @@
  */
 
 #include "nbd-client.h"
-#include "qemu/sockets.h"
 
 #define HANDLE_TO_INDEX(bs, handle) ((handle) ^ ((uint64_t)(intptr_t)bs))
 #define INDEX_TO_HANDLE(bs, index)  ((index)  ^ ((uint64_t)(intptr_t)bs))
@@ -48,12 +47,16 @@ static void nbd_teardown_connection(BlockDriverState *bs)
     NbdClientSession *client = nbd_get_client_session(bs);
 
     /* finish any pending coroutines */
-    shutdown(client->sock, 2);
+    qio_channel_shutdown(client->ioc,
+                         QIO_CHANNEL_SHUTDOWN_BOTH,
+                         NULL);
     nbd_recv_coroutines_enter_all(client);
 
     nbd_client_detach_aio_context(bs);
-    closesocket(client->sock);
-    client->sock = -1;
+    object_unref(OBJECT(client->sioc));
+    client->sioc = NULL;
+    object_unref(OBJECT(client->ioc));
+    client->ioc = NULL;
 }
 
 static void nbd_reply_ready(void *opaque)
@@ -68,7 +71,7 @@ static void nbd_reply_ready(void *opaque)
          * that another thread has done the same thing in parallel, so
          * the socket is not readable anymore.
          */
-        ret = nbd_receive_reply(s->sock, &s->reply);
+        ret = nbd_receive_reply(s->sioc->fd, &s->reply);
         if (ret == -EAGAIN) {
             return;
         }
@@ -124,27 +127,23 @@ static int nbd_co_send_request(BlockDriverState *bs,
     s->send_coroutine = qemu_coroutine_self();
     aio_context = bdrv_get_aio_context(bs);
 
-    aio_set_fd_handler(aio_context, s->sock, false,
+    aio_set_fd_handler(aio_context, s->sioc->fd, false,
                        nbd_reply_ready, nbd_restart_write, bs);
     if (qiov) {
-        if (!s->is_unix) {
-            socket_set_cork(s->sock, 1);
-        }
-        rc = nbd_send_request(s->sock, request);
+        qio_channel_set_cork(s->ioc, true);
+        rc = nbd_send_request(s->sioc->fd, request);
         if (rc >= 0) {
-            ret = qemu_co_sendv(s->sock, qiov->iov, qiov->niov,
+            ret = qemu_co_sendv(s->sioc->fd, qiov->iov, qiov->niov,
                                 offset, request->len);
             if (ret != request->len) {
                 rc = -EIO;
             }
         }
-        if (!s->is_unix) {
-            socket_set_cork(s->sock, 0);
-        }
+        qio_channel_set_cork(s->ioc, false);
     } else {
-        rc = nbd_send_request(s->sock, request);
+        rc = nbd_send_request(s->sioc->fd, request);
     }
-    aio_set_fd_handler(aio_context, s->sock, false,
+    aio_set_fd_handler(aio_context, s->sioc->fd, false,
                        nbd_reply_ready, NULL, bs);
     s->send_coroutine = NULL;
     qemu_co_mutex_unlock(&s->send_mutex);
@@ -165,7 +164,7 @@ static void nbd_co_receive_reply(NbdClientSession *s,
         reply->error = EIO;
     } else {
         if (qiov && reply->error == 0) {
-            ret = qemu_co_recvv(s->sock, qiov->iov, qiov->niov,
+            ret = qemu_co_recvv(s->sioc->fd, qiov->iov, qiov->niov,
                                 offset, request->len);
             if (ret != request->len) {
                 reply->error = EIO;
@@ -349,14 +348,14 @@ int nbd_client_co_discard(BlockDriverState *bs, int64_t sector_num,
 void nbd_client_detach_aio_context(BlockDriverState *bs)
 {
     aio_set_fd_handler(bdrv_get_aio_context(bs),
-                       nbd_get_client_session(bs)->sock,
+                       nbd_get_client_session(bs)->sioc->fd,
                        false, NULL, NULL, NULL);
 }
 
 void nbd_client_attach_aio_context(BlockDriverState *bs,
                                    AioContext *new_context)
 {
-    aio_set_fd_handler(new_context, nbd_get_client_session(bs)->sock,
+    aio_set_fd_handler(new_context, nbd_get_client_session(bs)->sioc->fd,
                        false, nbd_reply_ready, NULL, bs);
 }
 
@@ -369,39 +368,43 @@ void nbd_client_close(BlockDriverState *bs)
         .len = 0
     };
 
-    if (client->sock == -1) {
+    if (client->ioc == NULL) {
         return;
     }
 
-    nbd_send_request(client->sock, &request);
+    nbd_send_request(client->sioc->fd, &request);
 
     nbd_teardown_connection(bs);
 }
 
-int nbd_client_init(BlockDriverState *bs, int sock, const char *export,
-                    Error **errp)
+int nbd_client_init(BlockDriverState *bs, QIOChannelSocket *sioc,
+                    const char *export, Error **errp)
 {
     NbdClientSession *client = nbd_get_client_session(bs);
     int ret;
 
     /* NBD handshake */
     logout("session init %s\n", export);
-    qemu_set_block(sock);
-    ret = nbd_receive_negotiate(sock, export,
+    qio_channel_set_blocking(QIO_CHANNEL(sioc), true, NULL);
+
+    ret = nbd_receive_negotiate(sioc->fd, export,
                                 &client->nbdflags, &client->size, errp);
     if (ret < 0) {
         logout("Failed to negotiate with the NBD server\n");
-        closesocket(sock);
         return ret;
     }
 
     qemu_co_mutex_init(&client->send_mutex);
     qemu_co_mutex_init(&client->free_sema);
-    client->sock = sock;
+    client->sioc = sioc;
+    object_ref(OBJECT(client->sioc));
+    client->ioc = QIO_CHANNEL(sioc);
+    object_ref(OBJECT(client->ioc));
 
     /* Now that we're connected, set the socket to be non-blocking and
      * kick the reply mechanism.  */
-    qemu_set_nonblock(sock);
+    qio_channel_set_blocking(QIO_CHANNEL(sioc), false, NULL);
+
     nbd_client_attach_aio_context(bs, bdrv_get_aio_context(bs));
 
     logout("Established connection with NBD server\n");
diff --git a/block/nbd-client.h b/block/nbd-client.h
index e841340..e8b3283 100644
--- a/block/nbd-client.h
+++ b/block/nbd-client.h
@@ -4,6 +4,7 @@
 #include "qemu-common.h"
 #include "block/nbd.h"
 #include "block/block_int.h"
+#include "io/channel-socket.h"
 
 /* #define DEBUG_NBD */
 
@@ -17,7 +18,8 @@
 #define MAX_NBD_REQUESTS    16
 
 typedef struct NbdClientSession {
-    int sock;
+    QIOChannelSocket *sioc; /* The master data channel */
+    QIOChannel *ioc; /* The current I/O channel which may differ (eg TLS) */
     uint32_t nbdflags;
     off_t size;
 
@@ -34,7 +36,9 @@ typedef struct NbdClientSession {
 
 NbdClientSession *nbd_get_client_session(BlockDriverState *bs);
 
-int nbd_client_init(BlockDriverState *bs, int sock, const char *export_name,
+int nbd_client_init(BlockDriverState *bs,
+                    QIOChannelSocket *sock,
+                    const char *export_name,
                     Error **errp);
 void nbd_client_close(BlockDriverState *bs);
 
diff --git a/block/nbd.c b/block/nbd.c
index 416f42b..072fc5f 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -30,7 +30,6 @@
 #include "qemu/uri.h"
 #include "block/block_int.h"
 #include "qemu/module.h"
-#include "qemu/sockets.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qjson.h"
 #include "qapi/qmp/qint.h"
@@ -239,25 +238,25 @@ NbdClientSession *nbd_get_client_session(BlockDriverState *bs)
     return &s->client;
 }
 
-static int nbd_establish_connection(BlockDriverState *bs,
-                                    SocketAddress *saddr,
-                                    Error **errp)
+static QIOChannelSocket *nbd_establish_connection(SocketAddress *saddr,
+                                                  Error **errp)
 {
-    BDRVNBDState *s = bs->opaque;
-    int sock;
+    QIOChannelSocket *sioc;
+    Error *local_err = NULL;
 
-    sock = socket_connect(saddr, errp, NULL, NULL);
+    sioc = qio_channel_socket_new();
 
-    if (sock < 0) {
-        logout("Failed to establish connection to NBD server\n");
-        return -EIO;
+    qio_channel_socket_connect_sync(sioc,
+                                    saddr,
+                                    &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return NULL;
     }
 
-    if (!s->client.is_unix) {
-        socket_set_nodelay(sock);
-    }
+    qio_channel_set_delay(QIO_CHANNEL(sioc), false);
 
-    return sock;
+    return sioc;
 }
 
 static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
@@ -265,7 +264,8 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
 {
     BDRVNBDState *s = bs->opaque;
     char *export = NULL;
-    int result, sock;
+    int result;
+    QIOChannelSocket *sioc;
     SocketAddress *saddr;
 
     /* Pop the config into our state object. Exit if invalid. */
@@ -277,15 +277,16 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
     /* establish TCP connection, return error if it fails
      * TODO: Configurable retry-until-timeout behaviour.
      */
-    sock = nbd_establish_connection(bs, saddr, errp);
+    sioc = nbd_establish_connection(saddr, errp);
     qapi_free_SocketAddress(saddr);
-    if (sock < 0) {
+    if (!sioc) {
         g_free(export);
-        return sock;
+        return -ECONNREFUSED;
     }
 
     /* NBD handshake */
-    result = nbd_client_init(bs, sock, export, errp);
+    result = nbd_client_init(bs, sioc, export, errp);
+    object_unref(OBJECT(sioc));
     g_free(export);
     return result;
 }
diff --git a/tests/Makefile b/tests/Makefile
index b7352f1..4c2958e 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -390,8 +390,8 @@ test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o \
 	tests/test-qapi-event.o tests/test-qmp-introspect.o \
 	$(test-qom-obj-y)
 test-crypto-obj-y = $(crypto-obj-y) $(test-qom-obj-y)
-test-block-obj-y = $(block-obj-y) $(test-crypto-obj-y)
 test-io-obj-y = $(io-obj-y) $(test-crypto-obj-y)
+test-block-obj-y = $(block-obj-y) $(test-io-obj-y)
 
 tests/check-qint$(EXESUF): tests/check-qint.o $(test-util-obj-y)
 tests/check-qstring$(EXESUF): tests/check-qstring.o $(test-util-obj-y)
-- 
2.5.0

  reply	other threads:[~2016-01-19 13:09 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-19 13:09 [Qemu-devel] [PATCH v3 00/13] Implement TLS support to QEMU NBD server & client Daniel P. Berrange
2016-01-19 13:09 ` Daniel P. Berrange [this message]
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 02/13] nbd: convert qemu-nbd server to use I/O channels for connection setup Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 03/13] nbd: convert blockdev NBD " Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 04/13] nbd: convert to using I/O channels for actual socket I/O Daniel P. Berrange
2016-01-19 16:08   ` Paolo Bonzini
2016-01-19 16:52     ` Daniel P. Berrange
2016-01-19 18:00       ` Paolo Bonzini
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 05/13] nbd: invert client logic for negotiating protocol version Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 06/13] nbd: make server compliant with fixed newstyle spec Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 07/13] nbd: make client request fixed new style if advertized Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 08/13] nbd: allow setting of an export name for qemu-nbd server Daniel P. Berrange
2016-01-19 16:12   ` Paolo Bonzini
2016-01-19 16:48     ` Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 09/13] nbd: pick first exported volume if no export name is requested Daniel P. Berrange
2016-01-19 16:14   ` Paolo Bonzini
2016-01-19 16:44     ` Daniel P. Berrange
2016-01-21 10:30       ` Paolo Bonzini
2016-01-21 14:26         ` Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 10/13] nbd: implement TLS support in the protocol negotiation Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 11/13] nbd: enable use of TLS with NBD block driver Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 12/13] nbd: enable use of TLS with qemu-nbd server Daniel P. Berrange
2016-01-19 13:09 ` [Qemu-devel] [PATCH v3 13/13] nbd: enable use of TLS with nbd-server-start command Daniel P. Berrange

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1453208963-16834-2-git-send-email-berrange@redhat.com \
    --to=berrange@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.