[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 04/15] nbd: convert qemu-nbd server to use I/O chann
From: |
Daniel P. Berrange |
Subject: |
[Qemu-devel] [PATCH 04/15] nbd: convert qemu-nbd server to use I/O channels for connection setup |
Date: |
Fri, 27 Nov 2015 12:20:42 +0000 |
This converts the qemu-nbd server to use the QIOChannelSocket
class for initial listener socket setup and accepting of client
connections. Actual I/O is still being performed against the
socket file descriptor using the POSIX socket APIs.
In this initial conversion though, all I/O is still actually done
using the raw POSIX sockets APIs.
Signed-off-by: Daniel P. Berrange <address@hidden>
---
qemu-nbd.c | 91 ++++++++++++++++++++++++++++++++++----------------------------
1 file changed, 50 insertions(+), 41 deletions(-)
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 41f4285..28ab54f 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -21,7 +21,6 @@
#include "block/block_int.h"
#include "block/nbd.h"
#include "qemu/main-loop.h"
-#include "qemu/sockets.h"
#include "qemu/error-report.h"
#include "qemu/config-file.h"
#include "block/snapshot.h"
@@ -29,16 +28,13 @@
#include "qapi/qmp/qstring.h"
#include "qapi/opts-visitor.h"
#include "qom/object_interfaces.h"
+#include "io/channel-socket.h"
#include <stdarg.h>
#include <stdio.h>
#include <getopt.h>
#include <err.h>
#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
#include <signal.h>
#include <libgen.h>
#include <pthread.h>
@@ -58,7 +54,8 @@ static int persistent = 0;
static enum { RUNNING, TERMINATE, TERMINATING, TERMINATED } state;
static int shared = 1;
static int nb_fds;
-static int server_fd;
+static QIOChannelSocket *server_ioc;
+static int server_watch = -1;
static void usage(const char *name)
{
@@ -241,19 +238,21 @@ static void *nbd_client_thread(void *arg)
char *device = arg;
off_t size;
uint32_t nbdflags;
- int fd, sock;
+ QIOChannelSocket *sioc;
+ int fd;
int ret;
pthread_t show_parts_thread;
Error *local_error = NULL;
-
- sock = socket_connect(saddr, &local_error, NULL, NULL);
- if (sock < 0) {
+ sioc = qio_channel_socket_new();
+ if (qio_channel_socket_connect_sync(sioc,
+ saddr,
+ &local_error) < 0) {
error_report_err(local_error);
goto out;
}
- ret = nbd_receive_negotiate(sock, NULL, &nbdflags,
+ ret = nbd_receive_negotiate(sioc->fd, NULL, &nbdflags,
&size, &local_error);
if (ret < 0) {
if (local_error) {
@@ -270,7 +269,7 @@ static void *nbd_client_thread(void *arg)
goto out_socket;
}
- ret = nbd_init(fd, sock, nbdflags, size);
+ ret = nbd_init(fd, sioc->fd, nbdflags, size);
if (ret < 0) {
goto out_fd;
}
@@ -291,13 +290,14 @@ static void *nbd_client_thread(void *arg)
goto out_fd;
}
close(fd);
+ object_unref(OBJECT(sioc));
kill(getpid(), SIGTERM);
return (void *) EXIT_SUCCESS;
out_fd:
close(fd);
out_socket:
- closesocket(sock);
+ object_unref(OBJECT(sioc));
out:
kill(getpid(), SIGTERM);
return (void *) EXIT_FAILURE;
@@ -314,7 +314,7 @@ static void nbd_export_closed(NBDExport *exp)
state = TERMINATED;
}
-static void nbd_update_server_fd_handler(int fd);
+static void nbd_update_server_watch(void);
static void nbd_client_closed(NBDClient *client)
{
@@ -322,41 +322,51 @@ static void nbd_client_closed(NBDClient *client)
if (nb_fds == 0 && !persistent && state == RUNNING) {
state = TERMINATE;
}
- nbd_update_server_fd_handler(server_fd);
+ nbd_update_server_watch();
nbd_client_put(client);
}
-static void nbd_accept(void *opaque)
+static gboolean nbd_accept(QIOChannel *ioc, GIOCondition cond, gpointer opaque)
{
- struct sockaddr_in addr;
- socklen_t addr_len = sizeof(addr);
+ QIOChannelSocket *cioc;
+ int fd;
- int fd = accept(server_fd, (struct sockaddr *)&addr, &addr_len);
- if (fd < 0) {
- perror("accept");
- return;
+ cioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc),
+ NULL);
+ if (!cioc) {
+ return TRUE;
}
if (state >= TERMINATE) {
- close(fd);
- return;
+ object_unref(OBJECT(cioc));
+ return TRUE;
}
- if (nbd_client_new(exp, fd, nbd_client_closed)) {
+ fd = dup(cioc->fd);
+ if (fd >= 0 &&
+ nbd_client_new(exp, fd, nbd_client_closed)) {
nb_fds++;
- nbd_update_server_fd_handler(server_fd);
- } else {
- shutdown(fd, 2);
- close(fd);
+ nbd_update_server_watch();
}
+ object_unref(OBJECT(cioc));
+
+ return TRUE;
}
-static void nbd_update_server_fd_handler(int fd)
+static void nbd_update_server_watch(void)
{
if (nbd_can_accept()) {
- qemu_set_fd_handler(fd, nbd_accept, NULL, (void *)(uintptr_t)fd);
+ if (server_watch == -1) {
+ server_watch = qio_channel_add_watch(QIO_CHANNEL(server_ioc),
+ G_IO_IN,
+ nbd_accept,
+ NULL, NULL);
+ }
} else {
- qemu_set_fd_handler(fd, NULL, NULL, NULL);
+ if (server_watch != -1) {
+ g_source_remove(server_watch);
+ server_watch = -1;
+ }
}
}
@@ -494,7 +504,6 @@ int main(int argc, char **argv)
int flags = BDRV_O_RDWR;
int partition = -1;
int ret = 0;
- int fd;
bool seen_cache = false;
bool seen_discard = false;
bool seen_aio = false;
@@ -676,13 +685,13 @@ int main(int argc, char **argv)
}
if (disconnect) {
- fd = open(argv[optind], O_RDWR);
- if (fd < 0) {
+ int nbdfd = open(argv[optind], O_RDWR);
+ if (nbdfd < 0) {
err(EXIT_FAILURE, "Cannot open %s", argv[optind]);
}
- nbd_disconnect(fd);
+ nbd_disconnect(nbdfd);
- close(fd);
+ close(nbdfd);
printf("%s disconnected\n", argv[optind]);
@@ -807,8 +816,9 @@ int main(int argc, char **argv)
errx(EXIT_FAILURE, "%s", error_get_pretty(local_err));
}
- fd = socket_listen(saddr, &local_err);
- if (fd < 0) {
+ server_ioc = qio_channel_socket_new();
+ if (qio_channel_socket_listen_sync(server_ioc, saddr, &local_err) < 0) {
+ object_unref(OBJECT(server_ioc));
error_report_err(local_err);
return 1;
}
@@ -826,8 +836,7 @@ int main(int argc, char **argv)
memset(&client_thread, 0, sizeof(client_thread));
}
- server_fd = fd;
- nbd_update_server_fd_handler(fd);
+ nbd_update_server_watch();
/* now when the initialization is (almost) complete, chdir("/")
* to free any busy filesystems */
--
2.5.0
- [Qemu-devel] [PATCH 00/15] Implement TLS support to QEMU NBD server & client, Daniel P. Berrange, 2015/11/27
- [Qemu-devel] [PATCH 01/15] qom: add user_creatable_add & user_creatable_del methods, Daniel P. Berrange, 2015/11/27
- [Qemu-devel] [PATCH 04/15] nbd: convert qemu-nbd server to use I/O channels for connection setup,
Daniel P. Berrange <=
- [Qemu-devel] [PATCH 03/15] nbd: convert block client to use I/O channels for connection setup, Daniel P. Berrange, 2015/11/27
- [Qemu-devel] [PATCH 05/15] nbd: convert blockdev NBD server to use I/O channels for connection setup, Daniel P. Berrange, 2015/11/27
- [Qemu-devel] [PATCH 07/15] nbd: invert client logic for negotiating protocol version, Daniel P. Berrange, 2015/11/27
- [Qemu-devel] [PATCH 09/15] nbd: make client request fixed new style if advertized, Daniel P. Berrange, 2015/11/27
- [Qemu-devel] [PATCH 02/15] qemu-nbd: add support for --object command line arg, Daniel P. Berrange, 2015/11/27
- [Qemu-devel] [PATCH 08/15] nbd: make server compliant with fixed newstyle spec, Daniel P. Berrange, 2015/11/27
- [Qemu-devel] [PATCH 06/15] nbd: convert to using I/O channels for actual socket I/O, Daniel P. Berrange, 2015/11/27
- [Qemu-devel] [PATCH 10/15] nbd: allow setting of an export name for qemu-nbd server, Daniel P. Berrange, 2015/11/27
- [Qemu-devel] [PATCH 14/15] nbd: enable use of TLS with qemu-nbd server, Daniel P. Berrange, 2015/11/27
- [Qemu-devel] [PATCH 12/15] nbd: implement TLS support in the protocol negotiation, Daniel P. Berrange, 2015/11/27