2 * Copyright (C) 2005 Anthony Liguori <anthony@codemonkey.ws>
4 * Network Block Device Server Side
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; under version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
20 #include "nbd-internal.h"
22 static int system_errno_to_nbd_errno(int err
)
45 /* Definitions for opaque data types */
47 typedef struct NBDRequest NBDRequest
;
50 QSIMPLEQ_ENTRY(NBDRequest
) entry
;
57 void (*close
)(NBDExport
*exp
);
64 QTAILQ_HEAD(, NBDClient
) clients
;
65 QTAILQ_ENTRY(NBDExport
) next
;
69 Notifier eject_notifier
;
72 static QTAILQ_HEAD(, NBDExport
) exports
= QTAILQ_HEAD_INITIALIZER(exports
);
76 void (*close
)(NBDClient
*client
);
81 Coroutine
*recv_coroutine
;
84 Coroutine
*send_coroutine
;
88 QTAILQ_ENTRY(NBDClient
) next
;
93 /* That's all folks */
95 static void nbd_set_handlers(NBDClient
*client
);
96 static void nbd_unset_handlers(NBDClient
*client
);
97 static void nbd_update_can_read(NBDClient
*client
);
99 static void nbd_negotiate_continue(void *opaque
)
101 qemu_coroutine_enter(opaque
, NULL
);
104 static ssize_t
nbd_negotiate_read(int fd
, void *buffer
, size_t size
)
108 assert(qemu_in_coroutine());
109 /* Negotiation are always in main loop. */
110 qemu_set_fd_handler(fd
, nbd_negotiate_continue
, NULL
,
111 qemu_coroutine_self());
112 ret
= read_sync(fd
, buffer
, size
);
113 qemu_set_fd_handler(fd
, NULL
, NULL
, NULL
);
118 static ssize_t
nbd_negotiate_write(int fd
, void *buffer
, size_t size
)
122 assert(qemu_in_coroutine());
123 /* Negotiation are always in main loop. */
124 qemu_set_fd_handler(fd
, NULL
, nbd_negotiate_continue
,
125 qemu_coroutine_self());
126 ret
= write_sync(fd
, buffer
, size
);
127 qemu_set_fd_handler(fd
, NULL
, NULL
, NULL
);
131 static ssize_t
nbd_negotiate_drop_sync(int fd
, size_t size
)
133 ssize_t ret
, dropped
= size
;
134 uint8_t *buffer
= g_malloc(MIN(65536, size
));
137 ret
= nbd_negotiate_read(fd
, buffer
, MIN(65536, size
));
151 /* Basic flow for negotiation
178 static int nbd_negotiate_send_rep(int csock
, uint32_t type
, uint32_t opt
)
183 magic
= cpu_to_be64(NBD_REP_MAGIC
);
184 if (nbd_negotiate_write(csock
, &magic
, sizeof(magic
)) != sizeof(magic
)) {
185 LOG("write failed (rep magic)");
188 opt
= cpu_to_be32(opt
);
189 if (nbd_negotiate_write(csock
, &opt
, sizeof(opt
)) != sizeof(opt
)) {
190 LOG("write failed (rep opt)");
193 type
= cpu_to_be32(type
);
194 if (nbd_negotiate_write(csock
, &type
, sizeof(type
)) != sizeof(type
)) {
195 LOG("write failed (rep type)");
198 len
= cpu_to_be32(0);
199 if (nbd_negotiate_write(csock
, &len
, sizeof(len
)) != sizeof(len
)) {
200 LOG("write failed (rep data length)");
206 static int nbd_negotiate_send_rep_list(int csock
, NBDExport
*exp
)
208 uint64_t magic
, name_len
;
209 uint32_t opt
, type
, len
;
211 name_len
= strlen(exp
->name
);
212 magic
= cpu_to_be64(NBD_REP_MAGIC
);
213 if (nbd_negotiate_write(csock
, &magic
, sizeof(magic
)) != sizeof(magic
)) {
214 LOG("write failed (magic)");
217 opt
= cpu_to_be32(NBD_OPT_LIST
);
218 if (nbd_negotiate_write(csock
, &opt
, sizeof(opt
)) != sizeof(opt
)) {
219 LOG("write failed (opt)");
222 type
= cpu_to_be32(NBD_REP_SERVER
);
223 if (nbd_negotiate_write(csock
, &type
, sizeof(type
)) != sizeof(type
)) {
224 LOG("write failed (reply type)");
227 len
= cpu_to_be32(name_len
+ sizeof(len
));
228 if (nbd_negotiate_write(csock
, &len
, sizeof(len
)) != sizeof(len
)) {
229 LOG("write failed (length)");
232 len
= cpu_to_be32(name_len
);
233 if (nbd_negotiate_write(csock
, &len
, sizeof(len
)) != sizeof(len
)) {
234 LOG("write failed (length)");
237 if (nbd_negotiate_write(csock
, exp
->name
, name_len
) != name_len
) {
238 LOG("write failed (buffer)");
244 static int nbd_negotiate_handle_list(NBDClient
*client
, uint32_t length
)
249 csock
= client
->sock
;
251 if (nbd_negotiate_drop_sync(csock
, length
) != length
) {
254 return nbd_negotiate_send_rep(csock
, NBD_REP_ERR_INVALID
, NBD_OPT_LIST
);
257 /* For each export, send a NBD_REP_SERVER reply. */
258 QTAILQ_FOREACH(exp
, &exports
, next
) {
259 if (nbd_negotiate_send_rep_list(csock
, exp
)) {
263 /* Finish with a NBD_REP_ACK. */
264 return nbd_negotiate_send_rep(csock
, NBD_REP_ACK
, NBD_OPT_LIST
);
267 static int nbd_negotiate_handle_export_name(NBDClient
*client
, uint32_t length
)
269 int rc
= -EINVAL
, csock
= client
->sock
;
273 [20 .. xx] export name (length bytes)
275 TRACE("Checking length");
277 LOG("Bad length received");
280 if (nbd_negotiate_read(csock
, name
, length
) != length
) {
286 client
->exp
= nbd_export_find(name
);
288 LOG("export not found");
292 QTAILQ_INSERT_TAIL(&client
->exp
->clients
, client
, next
);
293 nbd_export_get(client
->exp
);
299 static int nbd_negotiate_options(NBDClient
*client
)
301 int csock
= client
->sock
;
305 [ 0 .. 3] client flags
307 [ 0 .. 7] NBD_OPTS_MAGIC
308 [ 8 .. 11] NBD option
309 [12 .. 15] Data length
312 [ 0 .. 7] NBD_OPTS_MAGIC
313 [ 8 .. 11] Second NBD option
314 [12 .. 15] Data length
318 if (nbd_negotiate_read(csock
, &flags
, sizeof(flags
)) != sizeof(flags
)) {
322 TRACE("Checking client flags");
323 be32_to_cpus(&flags
);
324 if (flags
!= 0 && flags
!= NBD_FLAG_C_FIXED_NEWSTYLE
) {
325 LOG("Bad client flags received");
331 uint32_t tmp
, length
;
334 if (nbd_negotiate_read(csock
, &magic
, sizeof(magic
)) != sizeof(magic
)) {
338 TRACE("Checking opts magic");
339 if (magic
!= be64_to_cpu(NBD_OPTS_MAGIC
)) {
340 LOG("Bad magic received");
344 if (nbd_negotiate_read(csock
, &tmp
, sizeof(tmp
)) != sizeof(tmp
)) {
349 if (nbd_negotiate_read(csock
, &length
,
350 sizeof(length
)) != sizeof(length
)) {
354 length
= be32_to_cpu(length
);
356 TRACE("Checking option");
357 switch (be32_to_cpu(tmp
)) {
359 ret
= nbd_negotiate_handle_list(client
, length
);
368 case NBD_OPT_EXPORT_NAME
:
369 return nbd_negotiate_handle_export_name(client
, length
);
372 tmp
= be32_to_cpu(tmp
);
373 LOG("Unsupported option 0x%x", tmp
);
374 nbd_negotiate_send_rep(client
->sock
, NBD_REP_ERR_UNSUP
, tmp
);
385 static coroutine_fn
int nbd_negotiate(NBDClientNewData
*data
)
387 NBDClient
*client
= data
->client
;
388 int csock
= client
->sock
;
389 char buf
[8 + 8 + 8 + 128];
391 const int myflags
= (NBD_FLAG_HAS_FLAGS
| NBD_FLAG_SEND_TRIM
|
392 NBD_FLAG_SEND_FLUSH
| NBD_FLAG_SEND_FUA
);
394 /* Negotiation header without options:
395 [ 0 .. 7] passwd ("NBDMAGIC")
396 [ 8 .. 15] magic (NBD_CLIENT_MAGIC)
398 [24 .. 25] server flags (0)
399 [26 .. 27] export flags
400 [28 .. 151] reserved (0)
402 Negotiation header with options, part 1:
403 [ 0 .. 7] passwd ("NBDMAGIC")
404 [ 8 .. 15] magic (NBD_OPTS_MAGIC)
405 [16 .. 17] server flags (0)
407 part 2 (after options are sent):
409 [26 .. 27] export flags
410 [28 .. 151] reserved (0)
415 TRACE("Beginning negotiation.");
416 memset(buf
, 0, sizeof(buf
));
417 memcpy(buf
, "NBDMAGIC", 8);
419 assert ((client
->exp
->nbdflags
& ~65535) == 0);
420 cpu_to_be64w((uint64_t*)(buf
+ 8), NBD_CLIENT_MAGIC
);
421 cpu_to_be64w((uint64_t*)(buf
+ 16), client
->exp
->size
);
422 cpu_to_be16w((uint16_t*)(buf
+ 26), client
->exp
->nbdflags
| myflags
);
424 cpu_to_be64w((uint64_t*)(buf
+ 8), NBD_OPTS_MAGIC
);
425 cpu_to_be16w((uint16_t *)(buf
+ 16), NBD_FLAG_FIXED_NEWSTYLE
);
429 if (nbd_negotiate_write(csock
, buf
, sizeof(buf
)) != sizeof(buf
)) {
434 if (nbd_negotiate_write(csock
, buf
, 18) != 18) {
438 rc
= nbd_negotiate_options(client
);
440 LOG("option negotiation failed");
444 assert ((client
->exp
->nbdflags
& ~65535) == 0);
445 cpu_to_be64w((uint64_t*)(buf
+ 18), client
->exp
->size
);
446 cpu_to_be16w((uint16_t*)(buf
+ 26), client
->exp
->nbdflags
| myflags
);
447 if (nbd_negotiate_write(csock
, buf
+ 18,
448 sizeof(buf
) - 18) != sizeof(buf
) - 18) {
454 TRACE("Negotiation succeeded.");
462 int nbd_disconnect(int fd
)
464 ioctl(fd
, NBD_CLEAR_QUE
);
465 ioctl(fd
, NBD_DISCONNECT
);
466 ioctl(fd
, NBD_CLEAR_SOCK
);
472 int nbd_disconnect(int fd
)
478 static ssize_t
nbd_receive_request(int csock
, struct nbd_request
*request
)
480 uint8_t buf
[NBD_REQUEST_SIZE
];
484 ret
= read_sync(csock
, buf
, sizeof(buf
));
489 if (ret
!= sizeof(buf
)) {
495 [ 0 .. 3] magic (NBD_REQUEST_MAGIC)
496 [ 4 .. 7] type (0 == READ, 1 == WRITE)
502 magic
= be32_to_cpup((uint32_t*)buf
);
503 request
->type
= be32_to_cpup((uint32_t*)(buf
+ 4));
504 request
->handle
= be64_to_cpup((uint64_t*)(buf
+ 8));
505 request
->from
= be64_to_cpup((uint64_t*)(buf
+ 16));
506 request
->len
= be32_to_cpup((uint32_t*)(buf
+ 24));
508 TRACE("Got request: "
509 "{ magic = 0x%x, .type = %d, from = %" PRIu64
" , len = %u }",
510 magic
, request
->type
, request
->from
, request
->len
);
512 if (magic
!= NBD_REQUEST_MAGIC
) {
513 LOG("invalid magic (got 0x%x)", magic
);
519 static ssize_t
nbd_send_reply(int csock
, struct nbd_reply
*reply
)
521 uint8_t buf
[NBD_REPLY_SIZE
];
524 reply
->error
= system_errno_to_nbd_errno(reply
->error
);
527 [ 0 .. 3] magic (NBD_REPLY_MAGIC)
528 [ 4 .. 7] error (0 == no error)
531 cpu_to_be32w((uint32_t*)buf
, NBD_REPLY_MAGIC
);
532 cpu_to_be32w((uint32_t*)(buf
+ 4), reply
->error
);
533 cpu_to_be64w((uint64_t*)(buf
+ 8), reply
->handle
);
535 TRACE("Sending response to client");
537 ret
= write_sync(csock
, buf
, sizeof(buf
));
542 if (ret
!= sizeof(buf
)) {
543 LOG("writing to socket failed");
549 #define MAX_NBD_REQUESTS 16
551 void nbd_client_get(NBDClient
*client
)
556 void nbd_client_put(NBDClient
*client
)
558 if (--client
->refcount
== 0) {
559 /* The last reference should be dropped by client->close,
560 * which is called by client_close.
562 assert(client
->closing
);
564 nbd_unset_handlers(client
);
568 QTAILQ_REMOVE(&client
->exp
->clients
, client
, next
);
569 nbd_export_put(client
->exp
);
575 static void client_close(NBDClient
*client
)
577 if (client
->closing
) {
581 client
->closing
= true;
583 /* Force requests to finish. They will drop their own references,
584 * then we'll close the socket and free the NBDClient.
586 shutdown(client
->sock
, 2);
588 /* Also tell the client, so that they release their reference. */
590 client
->close(client
);
594 static NBDRequest
*nbd_request_get(NBDClient
*client
)
598 assert(client
->nb_requests
<= MAX_NBD_REQUESTS
- 1);
599 client
->nb_requests
++;
600 nbd_update_can_read(client
);
602 req
= g_new0(NBDRequest
, 1);
603 nbd_client_get(client
);
604 req
->client
= client
;
608 static void nbd_request_put(NBDRequest
*req
)
610 NBDClient
*client
= req
->client
;
613 qemu_vfree(req
->data
);
617 client
->nb_requests
--;
618 nbd_update_can_read(client
);
619 nbd_client_put(client
);
622 static void blk_aio_attached(AioContext
*ctx
, void *opaque
)
624 NBDExport
*exp
= opaque
;
627 TRACE("Export %s: Attaching clients to AIO context %p\n", exp
->name
, ctx
);
631 QTAILQ_FOREACH(client
, &exp
->clients
, next
) {
632 nbd_set_handlers(client
);
636 static void blk_aio_detach(void *opaque
)
638 NBDExport
*exp
= opaque
;
641 TRACE("Export %s: Detaching clients from AIO context %p\n", exp
->name
, exp
->ctx
);
643 QTAILQ_FOREACH(client
, &exp
->clients
, next
) {
644 nbd_unset_handlers(client
);
650 static void nbd_eject_notifier(Notifier
*n
, void *data
)
652 NBDExport
*exp
= container_of(n
, NBDExport
, eject_notifier
);
653 nbd_export_close(exp
);
656 NBDExport
*nbd_export_new(BlockBackend
*blk
, off_t dev_offset
, off_t size
,
657 uint32_t nbdflags
, void (*close
)(NBDExport
*),
660 NBDExport
*exp
= g_malloc0(sizeof(NBDExport
));
662 QTAILQ_INIT(&exp
->clients
);
664 exp
->dev_offset
= dev_offset
;
665 exp
->nbdflags
= nbdflags
;
666 exp
->size
= size
< 0 ? blk_getlength(blk
) : size
;
668 error_setg_errno(errp
, -exp
->size
,
669 "Failed to determine the NBD export's length");
672 exp
->size
-= exp
->size
% BDRV_SECTOR_SIZE
;
675 exp
->ctx
= blk_get_aio_context(blk
);
677 blk_add_aio_context_notifier(blk
, blk_aio_attached
, blk_aio_detach
, exp
);
679 exp
->eject_notifier
.notify
= nbd_eject_notifier
;
680 blk_add_remove_bs_notifier(blk
, &exp
->eject_notifier
);
683 * NBD exports are used for non-shared storage migration. Make sure
684 * that BDRV_O_INACTIVE is cleared and the image is ready for write
685 * access since the export could be available before migration handover.
687 aio_context_acquire(exp
->ctx
);
688 blk_invalidate_cache(blk
, NULL
);
689 aio_context_release(exp
->ctx
);
697 NBDExport
*nbd_export_find(const char *name
)
700 QTAILQ_FOREACH(exp
, &exports
, next
) {
701 if (strcmp(name
, exp
->name
) == 0) {
709 void nbd_export_set_name(NBDExport
*exp
, const char *name
)
711 if (exp
->name
== name
) {
716 if (exp
->name
!= NULL
) {
719 QTAILQ_REMOVE(&exports
, exp
, next
);
724 exp
->name
= g_strdup(name
);
725 QTAILQ_INSERT_TAIL(&exports
, exp
, next
);
730 void nbd_export_close(NBDExport
*exp
)
732 NBDClient
*client
, *next
;
735 QTAILQ_FOREACH_SAFE(client
, &exp
->clients
, next
, next
) {
736 client_close(client
);
738 nbd_export_set_name(exp
, NULL
);
742 void nbd_export_get(NBDExport
*exp
)
744 assert(exp
->refcount
> 0);
748 void nbd_export_put(NBDExport
*exp
)
750 assert(exp
->refcount
> 0);
751 if (exp
->refcount
== 1) {
752 nbd_export_close(exp
);
755 if (--exp
->refcount
== 0) {
756 assert(exp
->name
== NULL
);
763 notifier_remove(&exp
->eject_notifier
);
764 blk_remove_aio_context_notifier(exp
->blk
, blk_aio_attached
,
765 blk_aio_detach
, exp
);
774 BlockBackend
*nbd_export_get_blockdev(NBDExport
*exp
)
779 void nbd_export_close_all(void)
781 NBDExport
*exp
, *next
;
783 QTAILQ_FOREACH_SAFE(exp
, &exports
, next
, next
) {
784 nbd_export_close(exp
);
788 static ssize_t
nbd_co_send_reply(NBDRequest
*req
, struct nbd_reply
*reply
,
791 NBDClient
*client
= req
->client
;
792 int csock
= client
->sock
;
795 qemu_co_mutex_lock(&client
->send_lock
);
796 client
->send_coroutine
= qemu_coroutine_self();
797 nbd_set_handlers(client
);
800 rc
= nbd_send_reply(csock
, reply
);
802 socket_set_cork(csock
, 1);
803 rc
= nbd_send_reply(csock
, reply
);
805 ret
= qemu_co_send(csock
, req
->data
, len
);
810 socket_set_cork(csock
, 0);
813 client
->send_coroutine
= NULL
;
814 nbd_set_handlers(client
);
815 qemu_co_mutex_unlock(&client
->send_lock
);
819 static ssize_t
nbd_co_receive_request(NBDRequest
*req
, struct nbd_request
*request
)
821 NBDClient
*client
= req
->client
;
822 int csock
= client
->sock
;
826 client
->recv_coroutine
= qemu_coroutine_self();
827 nbd_update_can_read(client
);
829 rc
= nbd_receive_request(csock
, request
);
837 if ((request
->from
+ request
->len
) < request
->from
) {
838 LOG("integer overflow detected! "
839 "you're probably being attacked");
844 TRACE("Decoding type");
846 command
= request
->type
& NBD_CMD_MASK_COMMAND
;
847 if (command
== NBD_CMD_READ
|| command
== NBD_CMD_WRITE
) {
848 if (request
->len
> NBD_MAX_BUFFER_SIZE
) {
849 LOG("len (%u) is larger than max len (%u)",
850 request
->len
, NBD_MAX_BUFFER_SIZE
);
855 req
->data
= blk_try_blockalign(client
->exp
->blk
, request
->len
);
856 if (req
->data
== NULL
) {
861 if (command
== NBD_CMD_WRITE
) {
862 TRACE("Reading %u byte(s)", request
->len
);
864 if (qemu_co_recv(csock
, req
->data
, request
->len
) != request
->len
) {
865 LOG("reading from socket failed");
873 client
->recv_coroutine
= NULL
;
874 nbd_update_can_read(client
);
879 static void nbd_trip(void *opaque
)
881 NBDClient
*client
= opaque
;
882 NBDExport
*exp
= client
->exp
;
884 struct nbd_request request
;
885 struct nbd_reply reply
;
889 TRACE("Reading request.");
890 if (client
->closing
) {
894 req
= nbd_request_get(client
);
895 ret
= nbd_co_receive_request(req
, &request
);
896 if (ret
== -EAGAIN
) {
903 reply
.handle
= request
.handle
;
910 command
= request
.type
& NBD_CMD_MASK_COMMAND
;
911 if (command
!= NBD_CMD_DISC
&& (request
.from
+ request
.len
) > exp
->size
) {
912 LOG("From: %" PRIu64
", Len: %u, Size: %" PRIu64
913 ", Offset: %" PRIu64
"\n",
914 request
.from
, request
.len
,
915 (uint64_t)exp
->size
, (uint64_t)exp
->dev_offset
);
916 LOG("requested operation past EOF--bad client?");
917 goto invalid_request
;
920 if (client
->closing
) {
922 * The client may be closed when we are blocked in
923 * nbd_co_receive_request()
930 TRACE("Request type is READ");
932 if (request
.type
& NBD_CMD_FLAG_FUA
) {
933 ret
= blk_co_flush(exp
->blk
);
941 ret
= blk_read(exp
->blk
,
942 (request
.from
+ exp
->dev_offset
) / BDRV_SECTOR_SIZE
,
943 req
->data
, request
.len
/ BDRV_SECTOR_SIZE
);
945 LOG("reading from file failed");
950 TRACE("Read %u byte(s)", request
.len
);
951 if (nbd_co_send_reply(req
, &reply
, request
.len
) < 0)
955 TRACE("Request type is WRITE");
957 if (exp
->nbdflags
& NBD_FLAG_READ_ONLY
) {
958 TRACE("Server is read-only, return error");
963 TRACE("Writing to device");
965 ret
= blk_write(exp
->blk
,
966 (request
.from
+ exp
->dev_offset
) / BDRV_SECTOR_SIZE
,
967 req
->data
, request
.len
/ BDRV_SECTOR_SIZE
);
969 LOG("writing to file failed");
974 if (request
.type
& NBD_CMD_FLAG_FUA
) {
975 ret
= blk_co_flush(exp
->blk
);
983 if (nbd_co_send_reply(req
, &reply
, 0) < 0) {
988 TRACE("Request type is DISCONNECT");
992 TRACE("Request type is FLUSH");
994 ret
= blk_co_flush(exp
->blk
);
999 if (nbd_co_send_reply(req
, &reply
, 0) < 0) {
1004 TRACE("Request type is TRIM");
1005 ret
= blk_co_discard(exp
->blk
, (request
.from
+ exp
->dev_offset
)
1007 request
.len
/ BDRV_SECTOR_SIZE
);
1009 LOG("discard failed");
1012 if (nbd_co_send_reply(req
, &reply
, 0) < 0) {
1017 LOG("invalid request type (%u) received", request
.type
);
1019 reply
.error
= EINVAL
;
1021 if (nbd_co_send_reply(req
, &reply
, 0) < 0) {
1027 TRACE("Request/Reply complete");
1030 nbd_request_put(req
);
1034 nbd_request_put(req
);
1035 client_close(client
);
1038 static void nbd_read(void *opaque
)
1040 NBDClient
*client
= opaque
;
1042 if (client
->recv_coroutine
) {
1043 qemu_coroutine_enter(client
->recv_coroutine
, NULL
);
1045 qemu_coroutine_enter(qemu_coroutine_create(nbd_trip
), client
);
1049 static void nbd_restart_write(void *opaque
)
1051 NBDClient
*client
= opaque
;
1053 qemu_coroutine_enter(client
->send_coroutine
, NULL
);
1056 static void nbd_set_handlers(NBDClient
*client
)
1058 if (client
->exp
&& client
->exp
->ctx
) {
1059 aio_set_fd_handler(client
->exp
->ctx
, client
->sock
,
1061 client
->can_read
? nbd_read
: NULL
,
1062 client
->send_coroutine
? nbd_restart_write
: NULL
,
1067 static void nbd_unset_handlers(NBDClient
*client
)
1069 if (client
->exp
&& client
->exp
->ctx
) {
1070 aio_set_fd_handler(client
->exp
->ctx
, client
->sock
,
1071 true, NULL
, NULL
, NULL
);
1075 static void nbd_update_can_read(NBDClient
*client
)
1077 bool can_read
= client
->recv_coroutine
||
1078 client
->nb_requests
< MAX_NBD_REQUESTS
;
1080 if (can_read
!= client
->can_read
) {
1081 client
->can_read
= can_read
;
1082 nbd_set_handlers(client
);
1084 /* There is no need to invoke aio_notify(), since aio_set_fd_handler()
1085 * in nbd_set_handlers() will have taken care of that */
1089 static coroutine_fn
void nbd_co_client_start(void *opaque
)
1091 NBDClientNewData
*data
= opaque
;
1092 NBDClient
*client
= data
->client
;
1093 NBDExport
*exp
= client
->exp
;
1096 nbd_export_get(exp
);
1098 if (nbd_negotiate(data
)) {
1099 client_close(client
);
1102 qemu_co_mutex_init(&client
->send_lock
);
1103 nbd_set_handlers(client
);
1106 QTAILQ_INSERT_TAIL(&exp
->clients
, client
, next
);
1112 void nbd_client_new(NBDExport
*exp
, int csock
, void (*close_fn
)(NBDClient
*))
1115 NBDClientNewData
*data
= g_new(NBDClientNewData
, 1);
1117 client
= g_malloc0(sizeof(NBDClient
));
1118 client
->refcount
= 1;
1120 client
->sock
= csock
;
1121 client
->can_read
= true;
1122 client
->close
= close_fn
;
1124 data
->client
= client
;
1125 data
->co
= qemu_coroutine_create(nbd_co_client_start
);
1126 qemu_coroutine_enter(data
->co
, data
);