diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2011-09-19 14:33:23 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2011-12-22 11:53:59 +0100 |
commit | 1743b515860ef645b285908ee367c5e343e0020c (patch) | |
tree | e3e4b075df3892869bce293affd2d6dbb5dca40b /nbd.c | |
parent | a61c67828dea7c64edaf226cadb45b4ffcc1d411 (diff) |
qemu-nbd: move client handling to nbd.c
This patch sets up the fd handler in nbd.c instead of qemu-nbd.c. It
introduces NBDClient, which wraps the arguments to nbd_trip in a single
structure, so that we can add a notifier to it. This way, qemu-nbd can
know about disconnections.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'nbd.c')
-rw-r--r-- | nbd.c | 62 |
1 files changed, 59 insertions, 3 deletions
@@ -600,6 +600,37 @@ struct NBDExport { QSIMPLEQ_HEAD(, NBDRequest) requests; }; +struct NBDClient { + int refcount; + void (*close)(NBDClient *client); + + NBDExport *exp; + int sock; +}; + +static void nbd_client_get(NBDClient *client) +{ + client->refcount++; +} + +static void nbd_client_put(NBDClient *client) +{ + if (--client->refcount == 0) { + g_free(client); + } +} + +static void nbd_client_close(NBDClient *client) +{ + qemu_set_fd_handler2(client->sock, NULL, NULL, NULL, NULL); + close(client->sock); + client->sock = -1; + if (client->close) { + client->close(client); + } + nbd_client_put(client); +} + static NBDRequest *nbd_request_get(NBDExport *exp) { NBDRequest *req; @@ -712,9 +743,11 @@ out: return rc; } -int nbd_trip(NBDExport *exp, int csock) +static int nbd_trip(NBDClient *client) { + NBDExport *exp = client->exp; NBDRequest *req = nbd_request_get(exp); + int csock = client->sock; struct nbd_request request; struct nbd_reply reply; int rc = -1; @@ -836,7 +869,30 @@ out: return rc; } -int nbd_negotiate(NBDExport *exp, int csock) +static void nbd_read(void *opaque) +{ + NBDClient *client = opaque; + + nbd_client_get(client); + if (nbd_trip(client) != 0) { + nbd_client_close(client); + } + + nbd_client_put(client); +} + +NBDClient *nbd_client_new(NBDExport *exp, int csock, + void (*close)(NBDClient *)) { - return nbd_send_negotiate(csock, exp->size, exp->nbdflags); + NBDClient *client; + if (nbd_send_negotiate(csock, exp->size, exp->nbdflags) == -1) { + return NULL; + } + client = g_malloc0(sizeof(NBDClient)); + client->refcount = 1; + client->exp = exp; + client->sock = csock; + client->close = close; + qemu_set_fd_handler2(csock, NULL, nbd_read, NULL, client); + return client; } |