1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "qemu/osdep.h"
21#include "qapi/error.h"
22#include "trace.h"
23#include "nbd-internal.h"
24
25#define NBD_META_ID_BASE_ALLOCATION 0
26#define NBD_META_ID_DIRTY_BITMAP 1
27
28
29
30
31
32#define NBD_MAX_BITMAP_EXTENTS (0x100000 / 8)
33
34static int system_errno_to_nbd_errno(int err)
35{
36 switch (err) {
37 case 0:
38 return NBD_SUCCESS;
39 case EPERM:
40 case EROFS:
41 return NBD_EPERM;
42 case EIO:
43 return NBD_EIO;
44 case ENOMEM:
45 return NBD_ENOMEM;
46#ifdef EDQUOT
47 case EDQUOT:
48#endif
49 case EFBIG:
50 case ENOSPC:
51 return NBD_ENOSPC;
52 case EOVERFLOW:
53 return NBD_EOVERFLOW;
54 case ESHUTDOWN:
55 return NBD_ESHUTDOWN;
56 case EINVAL:
57 default:
58 return NBD_EINVAL;
59 }
60}
61
62
63
64typedef struct NBDRequestData NBDRequestData;
65
66struct NBDRequestData {
67 QSIMPLEQ_ENTRY(NBDRequestData) entry;
68 NBDClient *client;
69 uint8_t *data;
70 bool complete;
71};
72
73struct NBDExport {
74 int refcount;
75 void (*close)(NBDExport *exp);
76
77 BlockBackend *blk;
78 char *name;
79 char *description;
80 uint64_t dev_offset;
81 uint64_t size;
82 uint16_t nbdflags;
83 QTAILQ_HEAD(, NBDClient) clients;
84 QTAILQ_ENTRY(NBDExport) next;
85
86 AioContext *ctx;
87
88 BlockBackend *eject_notifier_blk;
89 Notifier eject_notifier;
90
91 BdrvDirtyBitmap *export_bitmap;
92 char *export_bitmap_context;
93};
94
95static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
96
97
98
99
100typedef struct NBDExportMetaContexts {
101 NBDExport *exp;
102 bool valid;
103
104 bool base_allocation;
105 bool bitmap;
106} NBDExportMetaContexts;
107
108struct NBDClient {
109 int refcount;
110 void (*close_fn)(NBDClient *client, bool negotiated);
111
112 NBDExport *exp;
113 QCryptoTLSCreds *tlscreds;
114 char *tlsauthz;
115 QIOChannelSocket *sioc;
116 QIOChannel *ioc;
117
118 Coroutine *recv_coroutine;
119
120 CoMutex send_lock;
121 Coroutine *send_coroutine;
122
123 QTAILQ_ENTRY(NBDClient) next;
124 int nb_requests;
125 bool closing;
126
127 uint32_t check_align;
128
129 bool structured_reply;
130 NBDExportMetaContexts export_meta;
131
132 uint32_t opt;
133 uint32_t optlen;
134
135};
136
137static void nbd_client_receive_next_request(NBDClient *client);
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166static inline void set_be_option_rep(NBDOptionReply *rep, uint32_t option,
167 uint32_t type, uint32_t length)
168{
169 stq_be_p(&rep->magic, NBD_REP_MAGIC);
170 stl_be_p(&rep->option, option);
171 stl_be_p(&rep->type, type);
172 stl_be_p(&rep->length, length);
173}
174
175
176
177static int nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type,
178 uint32_t len, Error **errp)
179{
180 NBDOptionReply rep;
181
182 trace_nbd_negotiate_send_rep_len(client->opt, nbd_opt_lookup(client->opt),
183 type, nbd_rep_lookup(type), len);
184
185 assert(len < NBD_MAX_BUFFER_SIZE);
186
187 set_be_option_rep(&rep, client->opt, type, len);
188 return nbd_write(client->ioc, &rep, sizeof(rep), errp);
189}
190
191
192
193static int nbd_negotiate_send_rep(NBDClient *client, uint32_t type,
194 Error **errp)
195{
196 return nbd_negotiate_send_rep_len(client, type, 0, errp);
197}
198
199
200
201static int GCC_FMT_ATTR(4, 0)
202nbd_negotiate_send_rep_verr(NBDClient *client, uint32_t type,
203 Error **errp, const char *fmt, va_list va)
204{
205 char *msg;
206 int ret;
207 size_t len;
208
209 msg = g_strdup_vprintf(fmt, va);
210 len = strlen(msg);
211 assert(len < 4096);
212 trace_nbd_negotiate_send_rep_err(msg);
213 ret = nbd_negotiate_send_rep_len(client, type, len, errp);
214 if (ret < 0) {
215 goto out;
216 }
217 if (nbd_write(client->ioc, msg, len, errp) < 0) {
218 error_prepend(errp, "write failed (error message): ");
219 ret = -EIO;
220 } else {
221 ret = 0;
222 }
223
224out:
225 g_free(msg);
226 return ret;
227}
228
229
230
231static int GCC_FMT_ATTR(4, 5)
232nbd_negotiate_send_rep_err(NBDClient *client, uint32_t type,
233 Error **errp, const char *fmt, ...)
234{
235 va_list va;
236 int ret;
237
238 va_start(va, fmt);
239 ret = nbd_negotiate_send_rep_verr(client, type, errp, fmt, va);
240 va_end(va);
241 return ret;
242}
243
244
245
246
247static int GCC_FMT_ATTR(4, 0)
248nbd_opt_vdrop(NBDClient *client, uint32_t type, Error **errp,
249 const char *fmt, va_list va)
250{
251 int ret = nbd_drop(client->ioc, client->optlen, errp);
252
253 client->optlen = 0;
254 if (!ret) {
255 ret = nbd_negotiate_send_rep_verr(client, type, errp, fmt, va);
256 }
257 return ret;
258}
259
260static int GCC_FMT_ATTR(4, 5)
261nbd_opt_drop(NBDClient *client, uint32_t type, Error **errp,
262 const char *fmt, ...)
263{
264 int ret;
265 va_list va;
266
267 va_start(va, fmt);
268 ret = nbd_opt_vdrop(client, type, errp, fmt, va);
269 va_end(va);
270
271 return ret;
272}
273
274static int GCC_FMT_ATTR(3, 4)
275nbd_opt_invalid(NBDClient *client, Error **errp, const char *fmt, ...)
276{
277 int ret;
278 va_list va;
279
280 va_start(va, fmt);
281 ret = nbd_opt_vdrop(client, NBD_REP_ERR_INVALID, errp, fmt, va);
282 va_end(va);
283
284 return ret;
285}
286
287
288
289
290static int nbd_opt_read(NBDClient *client, void *buffer, size_t size,
291 Error **errp)
292{
293 if (size > client->optlen) {
294 return nbd_opt_invalid(client, errp,
295 "Inconsistent lengths in option %s",
296 nbd_opt_lookup(client->opt));
297 }
298 client->optlen -= size;
299 return qio_channel_read_all(client->ioc, buffer, size, errp) < 0 ? -EIO : 1;
300}
301
302
303
304
305static int nbd_opt_skip(NBDClient *client, size_t size, Error **errp)
306{
307 if (size > client->optlen) {
308 return nbd_opt_invalid(client, errp,
309 "Inconsistent lengths in option %s",
310 nbd_opt_lookup(client->opt));
311 }
312 client->optlen -= size;
313 return nbd_drop(client->ioc, size, errp) < 0 ? -EIO : 1;
314}
315
316
317
318
319
320
321
322
323
324
325
326
327
328static int nbd_opt_read_name(NBDClient *client, char *name, uint32_t *length,
329 Error **errp)
330{
331 int ret;
332 uint32_t len;
333
334 ret = nbd_opt_read(client, &len, sizeof(len), errp);
335 if (ret <= 0) {
336 return ret;
337 }
338 len = cpu_to_be32(len);
339
340 if (len > NBD_MAX_NAME_SIZE) {
341 return nbd_opt_invalid(client, errp,
342 "Invalid name length: %" PRIu32, len);
343 }
344
345 ret = nbd_opt_read(client, name, len, errp);
346 if (ret <= 0) {
347 return ret;
348 }
349 name[len] = '\0';
350
351 if (length) {
352 *length = len;
353 }
354
355 return 1;
356}
357
358
359
360static int nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp,
361 Error **errp)
362{
363 size_t name_len, desc_len;
364 uint32_t len;
365 const char *name = exp->name ? exp->name : "";
366 const char *desc = exp->description ? exp->description : "";
367 QIOChannel *ioc = client->ioc;
368 int ret;
369
370 trace_nbd_negotiate_send_rep_list(name, desc);
371 name_len = strlen(name);
372 desc_len = strlen(desc);
373 len = name_len + desc_len + sizeof(len);
374 ret = nbd_negotiate_send_rep_len(client, NBD_REP_SERVER, len, errp);
375 if (ret < 0) {
376 return ret;
377 }
378
379 len = cpu_to_be32(name_len);
380 if (nbd_write(ioc, &len, sizeof(len), errp) < 0) {
381 error_prepend(errp, "write failed (name length): ");
382 return -EINVAL;
383 }
384
385 if (nbd_write(ioc, name, name_len, errp) < 0) {
386 error_prepend(errp, "write failed (name buffer): ");
387 return -EINVAL;
388 }
389
390 if (nbd_write(ioc, desc, desc_len, errp) < 0) {
391 error_prepend(errp, "write failed (description buffer): ");
392 return -EINVAL;
393 }
394
395 return 0;
396}
397
398
399
400static int nbd_negotiate_handle_list(NBDClient *client, Error **errp)
401{
402 NBDExport *exp;
403 assert(client->opt == NBD_OPT_LIST);
404
405
406 QTAILQ_FOREACH(exp, &exports, next) {
407 if (nbd_negotiate_send_rep_list(client, exp, errp)) {
408 return -EINVAL;
409 }
410 }
411
412 return nbd_negotiate_send_rep(client, NBD_REP_ACK, errp);
413}
414
415static void nbd_check_meta_export(NBDClient *client)
416{
417 client->export_meta.valid &= client->exp == client->export_meta.exp;
418}
419
420
421
422static int nbd_negotiate_handle_export_name(NBDClient *client,
423 uint16_t myflags, bool no_zeroes,
424 Error **errp)
425{
426 char name[NBD_MAX_NAME_SIZE + 1];
427 char buf[NBD_REPLY_EXPORT_NAME_SIZE] = "";
428 size_t len;
429 int ret;
430
431
432
433
434
435
436
437
438 trace_nbd_negotiate_handle_export_name();
439 if (client->optlen >= sizeof(name)) {
440 error_setg(errp, "Bad length received");
441 return -EINVAL;
442 }
443 if (nbd_read(client->ioc, name, client->optlen, "export name", errp) < 0) {
444 return -EIO;
445 }
446 name[client->optlen] = '\0';
447 client->optlen = 0;
448
449 trace_nbd_negotiate_handle_export_name_request(name);
450
451 client->exp = nbd_export_find(name);
452 if (!client->exp) {
453 error_setg(errp, "export not found");
454 return -EINVAL;
455 }
456
457 trace_nbd_negotiate_new_style_size_flags(client->exp->size,
458 client->exp->nbdflags | myflags);
459 stq_be_p(buf, client->exp->size);
460 stw_be_p(buf + 8, client->exp->nbdflags | myflags);
461 len = no_zeroes ? 10 : sizeof(buf);
462 ret = nbd_write(client->ioc, buf, len, errp);
463 if (ret < 0) {
464 error_prepend(errp, "write failed: ");
465 return ret;
466 }
467
468 QTAILQ_INSERT_TAIL(&client->exp->clients, client, next);
469 nbd_export_get(client->exp);
470 nbd_check_meta_export(client);
471
472 return 0;
473}
474
475
476
477
478static int nbd_negotiate_send_info(NBDClient *client,
479 uint16_t info, uint32_t length, void *buf,
480 Error **errp)
481{
482 int rc;
483
484 trace_nbd_negotiate_send_info(info, nbd_info_lookup(info), length);
485 rc = nbd_negotiate_send_rep_len(client, NBD_REP_INFO,
486 sizeof(info) + length, errp);
487 if (rc < 0) {
488 return rc;
489 }
490 info = cpu_to_be16(info);
491 if (nbd_write(client->ioc, &info, sizeof(info), errp) < 0) {
492 return -EIO;
493 }
494 if (nbd_write(client->ioc, buf, length, errp) < 0) {
495 return -EIO;
496 }
497 return 0;
498}
499
500
501
502
503
504
505
506
507static int nbd_reject_length(NBDClient *client, bool fatal, Error **errp)
508{
509 int ret;
510
511 assert(client->optlen);
512 ret = nbd_opt_invalid(client, errp, "option '%s' has unexpected length",
513 nbd_opt_lookup(client->opt));
514 if (fatal && !ret) {
515 error_setg(errp, "option '%s' has unexpected length",
516 nbd_opt_lookup(client->opt));
517 return -EINVAL;
518 }
519 return ret;
520}
521
522
523
524
525static int nbd_negotiate_handle_info(NBDClient *client, uint16_t myflags,
526 Error **errp)
527{
528 int rc;
529 char name[NBD_MAX_NAME_SIZE + 1];
530 NBDExport *exp;
531 uint16_t requests;
532 uint16_t request;
533 uint32_t namelen;
534 bool sendname = false;
535 bool blocksize = false;
536 uint32_t sizes[3];
537 char buf[sizeof(uint64_t) + sizeof(uint16_t)];
538 uint32_t check_align = 0;
539
540
541
542
543
544
545
546 rc = nbd_opt_read_name(client, name, &namelen, errp);
547 if (rc <= 0) {
548 return rc;
549 }
550 trace_nbd_negotiate_handle_export_name_request(name);
551
552 rc = nbd_opt_read(client, &requests, sizeof(requests), errp);
553 if (rc <= 0) {
554 return rc;
555 }
556 requests = be16_to_cpu(requests);
557 trace_nbd_negotiate_handle_info_requests(requests);
558 while (requests--) {
559 rc = nbd_opt_read(client, &request, sizeof(request), errp);
560 if (rc <= 0) {
561 return rc;
562 }
563 request = be16_to_cpu(request);
564 trace_nbd_negotiate_handle_info_request(request,
565 nbd_info_lookup(request));
566
567
568
569 switch (request) {
570 case NBD_INFO_NAME:
571 sendname = true;
572 break;
573 case NBD_INFO_BLOCK_SIZE:
574 blocksize = true;
575 break;
576 }
577 }
578 if (client->optlen) {
579 return nbd_reject_length(client, false, errp);
580 }
581
582 exp = nbd_export_find(name);
583 if (!exp) {
584 return nbd_negotiate_send_rep_err(client, NBD_REP_ERR_UNKNOWN,
585 errp, "export '%s' not present",
586 name);
587 }
588
589
590 if (sendname) {
591 rc = nbd_negotiate_send_info(client, NBD_INFO_NAME, namelen, name,
592 errp);
593 if (rc < 0) {
594 return rc;
595 }
596 }
597
598
599
600 if (exp->description) {
601 size_t len = strlen(exp->description);
602
603 rc = nbd_negotiate_send_info(client, NBD_INFO_DESCRIPTION,
604 len, exp->description, errp);
605 if (rc < 0) {
606 return rc;
607 }
608 }
609
610
611
612
613
614 if (client->opt == NBD_OPT_INFO || blocksize) {
615 check_align = sizes[0] = blk_get_request_alignment(exp->blk);
616 } else {
617 sizes[0] = 1;
618 }
619 assert(sizes[0] <= NBD_MAX_BUFFER_SIZE);
620
621
622 sizes[1] = MAX(4096, sizes[0]);
623
624 sizes[2] = MIN(blk_get_max_transfer(exp->blk), NBD_MAX_BUFFER_SIZE);
625 trace_nbd_negotiate_handle_info_block_size(sizes[0], sizes[1], sizes[2]);
626 sizes[0] = cpu_to_be32(sizes[0]);
627 sizes[1] = cpu_to_be32(sizes[1]);
628 sizes[2] = cpu_to_be32(sizes[2]);
629 rc = nbd_negotiate_send_info(client, NBD_INFO_BLOCK_SIZE,
630 sizeof(sizes), sizes, errp);
631 if (rc < 0) {
632 return rc;
633 }
634
635
636 trace_nbd_negotiate_new_style_size_flags(exp->size,
637 exp->nbdflags | myflags);
638 stq_be_p(buf, exp->size);
639 stw_be_p(buf + 8, exp->nbdflags | myflags);
640 rc = nbd_negotiate_send_info(client, NBD_INFO_EXPORT,
641 sizeof(buf), buf, errp);
642 if (rc < 0) {
643 return rc;
644 }
645
646
647
648
649
650
651
652 if (client->opt == NBD_OPT_INFO && !blocksize &&
653 blk_get_request_alignment(exp->blk) > 1) {
654 return nbd_negotiate_send_rep_err(client,
655 NBD_REP_ERR_BLOCK_SIZE_REQD,
656 errp,
657 "request NBD_INFO_BLOCK_SIZE to "
658 "use this export");
659 }
660
661
662 rc = nbd_negotiate_send_rep(client, NBD_REP_ACK, errp);
663 if (rc < 0) {
664 return rc;
665 }
666
667 if (client->opt == NBD_OPT_GO) {
668 client->exp = exp;
669 client->check_align = check_align;
670 QTAILQ_INSERT_TAIL(&client->exp->clients, client, next);
671 nbd_export_get(client->exp);
672 nbd_check_meta_export(client);
673 rc = 1;
674 }
675 return rc;
676}
677
678
679
680
681static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
682 Error **errp)
683{
684 QIOChannel *ioc;
685 QIOChannelTLS *tioc;
686 struct NBDTLSHandshakeData data = { 0 };
687
688 assert(client->opt == NBD_OPT_STARTTLS);
689
690 trace_nbd_negotiate_handle_starttls();
691 ioc = client->ioc;
692
693 if (nbd_negotiate_send_rep(client, NBD_REP_ACK, errp) < 0) {
694 return NULL;
695 }
696
697 tioc = qio_channel_tls_new_server(ioc,
698 client->tlscreds,
699 client->tlsauthz,
700 errp);
701 if (!tioc) {
702 return NULL;
703 }
704
705 qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-server-tls");
706 trace_nbd_negotiate_handle_starttls_handshake();
707 data.loop = g_main_loop_new(g_main_context_default(), FALSE);
708 qio_channel_tls_handshake(tioc,
709 nbd_tls_handshake,
710 &data,
711 NULL,
712 NULL);
713
714 if (!data.complete) {
715 g_main_loop_run(data.loop);
716 }
717 g_main_loop_unref(data.loop);
718 if (data.error) {
719 object_unref(OBJECT(tioc));
720 error_propagate(errp, data.error);
721 return NULL;
722 }
723
724 return QIO_CHANNEL(tioc);
725}
726
727
728
729
730
731
732
733static int nbd_negotiate_send_meta_context(NBDClient *client,
734 const char *context,
735 uint32_t context_id,
736 Error **errp)
737{
738 NBDOptionReplyMetaContext opt;
739 struct iovec iov[] = {
740 {.iov_base = &opt, .iov_len = sizeof(opt)},
741 {.iov_base = (void *)context, .iov_len = strlen(context)}
742 };
743
744 if (client->opt == NBD_OPT_LIST_META_CONTEXT) {
745 context_id = 0;
746 }
747
748 trace_nbd_negotiate_meta_query_reply(context, context_id);
749 set_be_option_rep(&opt.h, client->opt, NBD_REP_META_CONTEXT,
750 sizeof(opt) - sizeof(opt.h) + iov[1].iov_len);
751 stl_be_p(&opt.context_id, context_id);
752
753 return qio_channel_writev_all(client->ioc, iov, 2, errp) < 0 ? -EIO : 0;
754}
755
756
757
758
759
760
761
762
763
764
765static int nbd_meta_pattern(NBDClient *client, const char *pattern, bool *match,
766 Error **errp)
767{
768 int ret;
769 char *query;
770 size_t len = strlen(pattern);
771
772 assert(len);
773
774 query = g_malloc(len);
775 ret = nbd_opt_read(client, query, len, errp);
776 if (ret <= 0) {
777 g_free(query);
778 return ret;
779 }
780
781 if (strncmp(query, pattern, len) == 0) {
782 trace_nbd_negotiate_meta_query_parse(pattern);
783 *match = true;
784 } else {
785 trace_nbd_negotiate_meta_query_skip("pattern not matched");
786 }
787 g_free(query);
788
789 return 1;
790}
791
792
793
794
795
796
797
798
799
800
801
802static int nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern,
803 uint32_t len, bool *match, Error **errp)
804{
805 if (len == 0) {
806 if (client->opt == NBD_OPT_LIST_META_CONTEXT) {
807 *match = true;
808 }
809 trace_nbd_negotiate_meta_query_parse("empty");
810 return 1;
811 }
812
813 if (len != strlen(pattern)) {
814 trace_nbd_negotiate_meta_query_skip("different lengths");
815 return nbd_opt_skip(client, len, errp);
816 }
817
818 return nbd_meta_pattern(client, pattern, match, errp);
819}
820
821
822
823
824
825
826
827
828
829
830static int nbd_meta_base_query(NBDClient *client, NBDExportMetaContexts *meta,
831 uint32_t len, Error **errp)
832{
833 return nbd_meta_empty_or_pattern(client, "allocation", len,
834 &meta->base_allocation, errp);
835}
836
837
838
839
840
841
842
843
844
845static int nbd_meta_qemu_query(NBDClient *client, NBDExportMetaContexts *meta,
846 uint32_t len, Error **errp)
847{
848 bool dirty_bitmap = false;
849 size_t dirty_bitmap_len = strlen("dirty-bitmap:");
850 int ret;
851
852 if (!meta->exp->export_bitmap) {
853 trace_nbd_negotiate_meta_query_skip("no dirty-bitmap exported");
854 return nbd_opt_skip(client, len, errp);
855 }
856
857 if (len == 0) {
858 if (client->opt == NBD_OPT_LIST_META_CONTEXT) {
859 meta->bitmap = true;
860 }
861 trace_nbd_negotiate_meta_query_parse("empty");
862 return 1;
863 }
864
865 if (len < dirty_bitmap_len) {
866 trace_nbd_negotiate_meta_query_skip("not dirty-bitmap:");
867 return nbd_opt_skip(client, len, errp);
868 }
869
870 len -= dirty_bitmap_len;
871 ret = nbd_meta_pattern(client, "dirty-bitmap:", &dirty_bitmap, errp);
872 if (ret <= 0) {
873 return ret;
874 }
875 if (!dirty_bitmap) {
876 trace_nbd_negotiate_meta_query_skip("not dirty-bitmap:");
877 return nbd_opt_skip(client, len, errp);
878 }
879
880 trace_nbd_negotiate_meta_query_parse("dirty-bitmap:");
881
882 return nbd_meta_empty_or_pattern(
883 client, meta->exp->export_bitmap_context +
884 strlen("qemu:dirty_bitmap:"), len, &meta->bitmap, errp);
885}
886
887
888
889
890
891
892
893
894
895
896
897
898
899static int nbd_negotiate_meta_query(NBDClient *client,
900 NBDExportMetaContexts *meta, Error **errp)
901{
902
903
904
905
906
907 int ret;
908 size_t ns_len = 5;
909 char ns[5];
910 uint32_t len;
911
912 ret = nbd_opt_read(client, &len, sizeof(len), errp);
913 if (ret <= 0) {
914 return ret;
915 }
916 len = cpu_to_be32(len);
917
918 if (len < ns_len) {
919 trace_nbd_negotiate_meta_query_skip("length too short");
920 return nbd_opt_skip(client, len, errp);
921 }
922
923 len -= ns_len;
924 ret = nbd_opt_read(client, ns, ns_len, errp);
925 if (ret <= 0) {
926 return ret;
927 }
928
929 if (!strncmp(ns, "base:", ns_len)) {
930 trace_nbd_negotiate_meta_query_parse("base:");
931 return nbd_meta_base_query(client, meta, len, errp);
932 } else if (!strncmp(ns, "qemu:", ns_len)) {
933 trace_nbd_negotiate_meta_query_parse("qemu:");
934 return nbd_meta_qemu_query(client, meta, len, errp);
935 }
936
937 trace_nbd_negotiate_meta_query_skip("unknown namespace");
938 return nbd_opt_skip(client, len, errp);
939}
940
941
942
943
944
945static int nbd_negotiate_meta_queries(NBDClient *client,
946 NBDExportMetaContexts *meta, Error **errp)
947{
948 int ret;
949 char export_name[NBD_MAX_NAME_SIZE + 1];
950 NBDExportMetaContexts local_meta;
951 uint32_t nb_queries;
952 int i;
953
954 if (!client->structured_reply) {
955 return nbd_opt_invalid(client, errp,
956 "request option '%s' when structured reply "
957 "is not negotiated",
958 nbd_opt_lookup(client->opt));
959 }
960
961 if (client->opt == NBD_OPT_LIST_META_CONTEXT) {
962
963 meta = &local_meta;
964 }
965
966 memset(meta, 0, sizeof(*meta));
967
968 ret = nbd_opt_read_name(client, export_name, NULL, errp);
969 if (ret <= 0) {
970 return ret;
971 }
972
973 meta->exp = nbd_export_find(export_name);
974 if (meta->exp == NULL) {
975 return nbd_opt_drop(client, NBD_REP_ERR_UNKNOWN, errp,
976 "export '%s' not present", export_name);
977 }
978
979 ret = nbd_opt_read(client, &nb_queries, sizeof(nb_queries), errp);
980 if (ret <= 0) {
981 return ret;
982 }
983 nb_queries = cpu_to_be32(nb_queries);
984 trace_nbd_negotiate_meta_context(nbd_opt_lookup(client->opt),
985 export_name, nb_queries);
986
987 if (client->opt == NBD_OPT_LIST_META_CONTEXT && !nb_queries) {
988
989 meta->base_allocation = true;
990 meta->bitmap = !!meta->exp->export_bitmap;
991 } else {
992 for (i = 0; i < nb_queries; ++i) {
993 ret = nbd_negotiate_meta_query(client, meta, errp);
994 if (ret <= 0) {
995 return ret;
996 }
997 }
998 }
999
1000 if (meta->base_allocation) {
1001 ret = nbd_negotiate_send_meta_context(client, "base:allocation",
1002 NBD_META_ID_BASE_ALLOCATION,
1003 errp);
1004 if (ret < 0) {
1005 return ret;
1006 }
1007 }
1008
1009 if (meta->bitmap) {
1010 ret = nbd_negotiate_send_meta_context(client,
1011 meta->exp->export_bitmap_context,
1012 NBD_META_ID_DIRTY_BITMAP,
1013 errp);
1014 if (ret < 0) {
1015 return ret;
1016 }
1017 }
1018
1019 ret = nbd_negotiate_send_rep(client, NBD_REP_ACK, errp);
1020 if (ret == 0) {
1021 meta->valid = true;
1022 }
1023
1024 return ret;
1025}
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036static int nbd_negotiate_options(NBDClient *client, uint16_t myflags,
1037 Error **errp)
1038{
1039 uint32_t flags;
1040 bool fixedNewstyle = false;
1041 bool no_zeroes = false;
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058 if (nbd_read32(client->ioc, &flags, "flags", errp) < 0) {
1059 return -EIO;
1060 }
1061 trace_nbd_negotiate_options_flags(flags);
1062 if (flags & NBD_FLAG_C_FIXED_NEWSTYLE) {
1063 fixedNewstyle = true;
1064 flags &= ~NBD_FLAG_C_FIXED_NEWSTYLE;
1065 }
1066 if (flags & NBD_FLAG_C_NO_ZEROES) {
1067 no_zeroes = true;
1068 flags &= ~NBD_FLAG_C_NO_ZEROES;
1069 }
1070 if (flags != 0) {
1071 error_setg(errp, "Unknown client flags 0x%" PRIx32 " received", flags);
1072 return -EINVAL;
1073 }
1074
1075 while (1) {
1076 int ret;
1077 uint32_t option, length;
1078 uint64_t magic;
1079
1080 if (nbd_read64(client->ioc, &magic, "opts magic", errp) < 0) {
1081 return -EINVAL;
1082 }
1083 trace_nbd_negotiate_options_check_magic(magic);
1084 if (magic != NBD_OPTS_MAGIC) {
1085 error_setg(errp, "Bad magic received");
1086 return -EINVAL;
1087 }
1088
1089 if (nbd_read32(client->ioc, &option, "option", errp) < 0) {
1090 return -EINVAL;
1091 }
1092 client->opt = option;
1093
1094 if (nbd_read32(client->ioc, &length, "option length", errp) < 0) {
1095 return -EINVAL;
1096 }
1097 assert(!client->optlen);
1098 client->optlen = length;
1099
1100 if (length > NBD_MAX_BUFFER_SIZE) {
1101 error_setg(errp, "len (%" PRIu32" ) is larger than max len (%u)",
1102 length, NBD_MAX_BUFFER_SIZE);
1103 return -EINVAL;
1104 }
1105
1106 trace_nbd_negotiate_options_check_option(option,
1107 nbd_opt_lookup(option));
1108 if (client->tlscreds &&
1109 client->ioc == (QIOChannel *)client->sioc) {
1110 QIOChannel *tioc;
1111 if (!fixedNewstyle) {
1112 error_setg(errp, "Unsupported option 0x%" PRIx32, option);
1113 return -EINVAL;
1114 }
1115 switch (option) {
1116 case NBD_OPT_STARTTLS:
1117 if (length) {
1118
1119
1120 return nbd_reject_length(client, true, errp);
1121 }
1122 tioc = nbd_negotiate_handle_starttls(client, errp);
1123 if (!tioc) {
1124 return -EIO;
1125 }
1126 ret = 0;
1127 object_unref(OBJECT(client->ioc));
1128 client->ioc = QIO_CHANNEL(tioc);
1129 break;
1130
1131 case NBD_OPT_EXPORT_NAME:
1132
1133 error_setg(errp, "Option 0x%x not permitted before TLS",
1134 option);
1135 return -EINVAL;
1136
1137 default:
1138
1139
1140
1141
1142
1143
1144 ret = nbd_opt_drop(client, NBD_REP_ERR_TLS_REQD,
1145 option == NBD_OPT_ABORT ? NULL : errp,
1146 "Option 0x%" PRIx32
1147 " not permitted before TLS", option);
1148 if (option == NBD_OPT_ABORT) {
1149 return 1;
1150 }
1151 break;
1152 }
1153 } else if (fixedNewstyle) {
1154 switch (option) {
1155 case NBD_OPT_LIST:
1156 if (length) {
1157 ret = nbd_reject_length(client, false, errp);
1158 } else {
1159 ret = nbd_negotiate_handle_list(client, errp);
1160 }
1161 break;
1162
1163 case NBD_OPT_ABORT:
1164
1165
1166
1167 nbd_negotiate_send_rep(client, NBD_REP_ACK, NULL);
1168 return 1;
1169
1170 case NBD_OPT_EXPORT_NAME:
1171 return nbd_negotiate_handle_export_name(client,
1172 myflags, no_zeroes,
1173 errp);
1174
1175 case NBD_OPT_INFO:
1176 case NBD_OPT_GO:
1177 ret = nbd_negotiate_handle_info(client, myflags, errp);
1178 if (ret == 1) {
1179 assert(option == NBD_OPT_GO);
1180 return 0;
1181 }
1182 break;
1183
1184 case NBD_OPT_STARTTLS:
1185 if (length) {
1186 ret = nbd_reject_length(client, false, errp);
1187 } else if (client->tlscreds) {
1188 ret = nbd_negotiate_send_rep_err(client,
1189 NBD_REP_ERR_INVALID, errp,
1190 "TLS already enabled");
1191 } else {
1192 ret = nbd_negotiate_send_rep_err(client,
1193 NBD_REP_ERR_POLICY, errp,
1194 "TLS not configured");
1195 }
1196 break;
1197
1198 case NBD_OPT_STRUCTURED_REPLY:
1199 if (length) {
1200 ret = nbd_reject_length(client, false, errp);
1201 } else if (client->structured_reply) {
1202 ret = nbd_negotiate_send_rep_err(
1203 client, NBD_REP_ERR_INVALID, errp,
1204 "structured reply already negotiated");
1205 } else {
1206 ret = nbd_negotiate_send_rep(client, NBD_REP_ACK, errp);
1207 client->structured_reply = true;
1208 myflags |= NBD_FLAG_SEND_DF;
1209 }
1210 break;
1211
1212 case NBD_OPT_LIST_META_CONTEXT:
1213 case NBD_OPT_SET_META_CONTEXT:
1214 ret = nbd_negotiate_meta_queries(client, &client->export_meta,
1215 errp);
1216 break;
1217
1218 default:
1219 ret = nbd_opt_drop(client, NBD_REP_ERR_UNSUP, errp,
1220 "Unsupported option %" PRIu32 " (%s)",
1221 option, nbd_opt_lookup(option));
1222 break;
1223 }
1224 } else {
1225
1226
1227
1228
1229 switch (option) {
1230 case NBD_OPT_EXPORT_NAME:
1231 return nbd_negotiate_handle_export_name(client,
1232 myflags, no_zeroes,
1233 errp);
1234
1235 default:
1236 error_setg(errp, "Unsupported option %" PRIu32 " (%s)",
1237 option, nbd_opt_lookup(option));
1238 return -EINVAL;
1239 }
1240 }
1241 if (ret < 0) {
1242 return ret;
1243 }
1244 }
1245}
1246
1247
1248
1249
1250
1251
1252
1253
1254static coroutine_fn int nbd_negotiate(NBDClient *client, Error **errp)
1255{
1256 char buf[NBD_OLDSTYLE_NEGOTIATE_SIZE] = "";
1257 int ret;
1258 const uint16_t myflags = (NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
1259 NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA |
1260 NBD_FLAG_SEND_WRITE_ZEROES | NBD_FLAG_SEND_CACHE);
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276 qio_channel_set_blocking(client->ioc, false, NULL);
1277
1278 trace_nbd_negotiate_begin();
1279 memcpy(buf, "NBDMAGIC", 8);
1280
1281 stq_be_p(buf + 8, NBD_OPTS_MAGIC);
1282 stw_be_p(buf + 16, NBD_FLAG_FIXED_NEWSTYLE | NBD_FLAG_NO_ZEROES);
1283
1284 if (nbd_write(client->ioc, buf, 18, errp) < 0) {
1285 error_prepend(errp, "write failed: ");
1286 return -EINVAL;
1287 }
1288 ret = nbd_negotiate_options(client, myflags, errp);
1289 if (ret != 0) {
1290 if (ret < 0) {
1291 error_prepend(errp, "option negotiation failed: ");
1292 }
1293 return ret;
1294 }
1295
1296 assert(!client->optlen);
1297 trace_nbd_negotiate_success();
1298
1299 return 0;
1300}
1301
1302static int nbd_receive_request(QIOChannel *ioc, NBDRequest *request,
1303 Error **errp)
1304{
1305 uint8_t buf[NBD_REQUEST_SIZE];
1306 uint32_t magic;
1307 int ret;
1308
1309 ret = nbd_read(ioc, buf, sizeof(buf), "request", errp);
1310 if (ret < 0) {
1311 return ret;
1312 }
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323 magic = ldl_be_p(buf);
1324 request->flags = lduw_be_p(buf + 4);
1325 request->type = lduw_be_p(buf + 6);
1326 request->handle = ldq_be_p(buf + 8);
1327 request->from = ldq_be_p(buf + 16);
1328 request->len = ldl_be_p(buf + 24);
1329
1330 trace_nbd_receive_request(magic, request->flags, request->type,
1331 request->from, request->len);
1332
1333 if (magic != NBD_REQUEST_MAGIC) {
1334 error_setg(errp, "invalid magic (got 0x%" PRIx32 ")", magic);
1335 return -EINVAL;
1336 }
1337 return 0;
1338}
1339
1340#define MAX_NBD_REQUESTS 16
1341
1342void nbd_client_get(NBDClient *client)
1343{
1344 client->refcount++;
1345}
1346
1347void nbd_client_put(NBDClient *client)
1348{
1349 if (--client->refcount == 0) {
1350
1351
1352
1353 assert(client->closing);
1354
1355 qio_channel_detach_aio_context(client->ioc);
1356 object_unref(OBJECT(client->sioc));
1357 object_unref(OBJECT(client->ioc));
1358 if (client->tlscreds) {
1359 object_unref(OBJECT(client->tlscreds));
1360 }
1361 g_free(client->tlsauthz);
1362 if (client->exp) {
1363 QTAILQ_REMOVE(&client->exp->clients, client, next);
1364 nbd_export_put(client->exp);
1365 }
1366 g_free(client);
1367 }
1368}
1369
1370static void client_close(NBDClient *client, bool negotiated)
1371{
1372 if (client->closing) {
1373 return;
1374 }
1375
1376 client->closing = true;
1377
1378
1379
1380
1381 qio_channel_shutdown(client->ioc, QIO_CHANNEL_SHUTDOWN_BOTH,
1382 NULL);
1383
1384
1385 if (client->close_fn) {
1386 client->close_fn(client, negotiated);
1387 }
1388}
1389
1390static NBDRequestData *nbd_request_get(NBDClient *client)
1391{
1392 NBDRequestData *req;
1393
1394 assert(client->nb_requests <= MAX_NBD_REQUESTS - 1);
1395 client->nb_requests++;
1396
1397 req = g_new0(NBDRequestData, 1);
1398 nbd_client_get(client);
1399 req->client = client;
1400 return req;
1401}
1402
1403static void nbd_request_put(NBDRequestData *req)
1404{
1405 NBDClient *client = req->client;
1406
1407 if (req->data) {
1408 qemu_vfree(req->data);
1409 }
1410 g_free(req);
1411
1412 client->nb_requests--;
1413 nbd_client_receive_next_request(client);
1414
1415 nbd_client_put(client);
1416}
1417
1418static void blk_aio_attached(AioContext *ctx, void *opaque)
1419{
1420 NBDExport *exp = opaque;
1421 NBDClient *client;
1422
1423 trace_nbd_blk_aio_attached(exp->name, ctx);
1424
1425 exp->ctx = ctx;
1426
1427 QTAILQ_FOREACH(client, &exp->clients, next) {
1428 qio_channel_attach_aio_context(client->ioc, ctx);
1429 if (client->recv_coroutine) {
1430 aio_co_schedule(ctx, client->recv_coroutine);
1431 }
1432 if (client->send_coroutine) {
1433 aio_co_schedule(ctx, client->send_coroutine);
1434 }
1435 }
1436}
1437
1438static void blk_aio_detach(void *opaque)
1439{
1440 NBDExport *exp = opaque;
1441 NBDClient *client;
1442
1443 trace_nbd_blk_aio_detach(exp->name, exp->ctx);
1444
1445 QTAILQ_FOREACH(client, &exp->clients, next) {
1446 qio_channel_detach_aio_context(client->ioc);
1447 }
1448
1449 exp->ctx = NULL;
1450}
1451
1452static void nbd_eject_notifier(Notifier *n, void *data)
1453{
1454 NBDExport *exp = container_of(n, NBDExport, eject_notifier);
1455 nbd_export_close(exp);
1456}
1457
1458NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset,
1459 uint64_t size, const char *name, const char *desc,
1460 const char *bitmap, uint16_t nbdflags,
1461 void (*close)(NBDExport *), bool writethrough,
1462 BlockBackend *on_eject_blk, Error **errp)
1463{
1464 AioContext *ctx;
1465 BlockBackend *blk;
1466 NBDExport *exp = g_new0(NBDExport, 1);
1467 uint64_t perm;
1468 int ret;
1469
1470
1471
1472
1473
1474
1475 assert(name);
1476 ctx = bdrv_get_aio_context(bs);
1477 aio_context_acquire(ctx);
1478 bdrv_invalidate_cache(bs, NULL);
1479 aio_context_release(ctx);
1480
1481
1482
1483 perm = BLK_PERM_CONSISTENT_READ;
1484 if ((nbdflags & NBD_FLAG_READ_ONLY) == 0) {
1485 perm |= BLK_PERM_WRITE;
1486 }
1487 blk = blk_new(perm, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED |
1488 BLK_PERM_WRITE | BLK_PERM_GRAPH_MOD);
1489 ret = blk_insert_bs(blk, bs, errp);
1490 if (ret < 0) {
1491 goto fail;
1492 }
1493 blk_set_enable_write_cache(blk, !writethrough);
1494
1495 exp->refcount = 1;
1496 QTAILQ_INIT(&exp->clients);
1497 exp->blk = blk;
1498 assert(dev_offset <= INT64_MAX);
1499 exp->dev_offset = dev_offset;
1500 exp->name = g_strdup(name);
1501 exp->description = g_strdup(desc);
1502 exp->nbdflags = nbdflags;
1503 assert(size <= INT64_MAX - dev_offset);
1504 exp->size = QEMU_ALIGN_DOWN(size, BDRV_SECTOR_SIZE);
1505
1506 if (bitmap) {
1507 BdrvDirtyBitmap *bm = NULL;
1508
1509 while (true) {
1510 bm = bdrv_find_dirty_bitmap(bs, bitmap);
1511 if (bm != NULL || bs->backing == NULL) {
1512 break;
1513 }
1514
1515 bs = bs->backing->bs;
1516 }
1517
1518 if (bm == NULL) {
1519 error_setg(errp, "Bitmap '%s' is not found", bitmap);
1520 goto fail;
1521 }
1522
1523 if (bdrv_dirty_bitmap_check(bm, BDRV_BITMAP_ALLOW_RO, errp)) {
1524 goto fail;
1525 }
1526
1527 if ((nbdflags & NBD_FLAG_READ_ONLY) && bdrv_is_writable(bs) &&
1528 bdrv_dirty_bitmap_enabled(bm)) {
1529 error_setg(errp,
1530 "Enabled bitmap '%s' incompatible with readonly export",
1531 bitmap);
1532 goto fail;
1533 }
1534
1535 bdrv_dirty_bitmap_set_busy(bm, true);
1536 exp->export_bitmap = bm;
1537 exp->export_bitmap_context = g_strdup_printf("qemu:dirty-bitmap:%s",
1538 bitmap);
1539 }
1540
1541 exp->close = close;
1542 exp->ctx = blk_get_aio_context(blk);
1543 blk_add_aio_context_notifier(blk, blk_aio_attached, blk_aio_detach, exp);
1544
1545 if (on_eject_blk) {
1546 blk_ref(on_eject_blk);
1547 exp->eject_notifier_blk = on_eject_blk;
1548 exp->eject_notifier.notify = nbd_eject_notifier;
1549 blk_add_remove_bs_notifier(on_eject_blk, &exp->eject_notifier);
1550 }
1551 QTAILQ_INSERT_TAIL(&exports, exp, next);
1552 nbd_export_get(exp);
1553 return exp;
1554
1555fail:
1556 blk_unref(blk);
1557 g_free(exp->name);
1558 g_free(exp->description);
1559 g_free(exp);
1560 return NULL;
1561}
1562
1563NBDExport *nbd_export_find(const char *name)
1564{
1565 NBDExport *exp;
1566 QTAILQ_FOREACH(exp, &exports, next) {
1567 if (strcmp(name, exp->name) == 0) {
1568 return exp;
1569 }
1570 }
1571
1572 return NULL;
1573}
1574
1575void nbd_export_close(NBDExport *exp)
1576{
1577 NBDClient *client, *next;
1578
1579 nbd_export_get(exp);
1580
1581
1582
1583
1584
1585
1586
1587 QTAILQ_FOREACH_SAFE(client, &exp->clients, next, next) {
1588 client_close(client, true);
1589 }
1590 if (exp->name) {
1591 nbd_export_put(exp);
1592 g_free(exp->name);
1593 exp->name = NULL;
1594 QTAILQ_REMOVE(&exports, exp, next);
1595 }
1596 g_free(exp->description);
1597 exp->description = NULL;
1598 nbd_export_put(exp);
1599}
1600
1601void nbd_export_remove(NBDExport *exp, NbdServerRemoveMode mode, Error **errp)
1602{
1603 if (mode == NBD_SERVER_REMOVE_MODE_HARD || QTAILQ_EMPTY(&exp->clients)) {
1604 nbd_export_close(exp);
1605 return;
1606 }
1607
1608 assert(mode == NBD_SERVER_REMOVE_MODE_SAFE);
1609
1610 error_setg(errp, "export '%s' still in use", exp->name);
1611 error_append_hint(errp, "Use mode='hard' to force client disconnect\n");
1612}
1613
1614void nbd_export_get(NBDExport *exp)
1615{
1616 assert(exp->refcount > 0);
1617 exp->refcount++;
1618}
1619
1620void nbd_export_put(NBDExport *exp)
1621{
1622 assert(exp->refcount > 0);
1623 if (exp->refcount == 1) {
1624 nbd_export_close(exp);
1625 }
1626
1627
1628
1629
1630
1631
1632 assert(exp->refcount > 0);
1633 if (--exp->refcount == 0) {
1634 assert(exp->name == NULL);
1635 assert(exp->description == NULL);
1636
1637 if (exp->close) {
1638 exp->close(exp);
1639 }
1640
1641 if (exp->blk) {
1642 if (exp->eject_notifier_blk) {
1643 notifier_remove(&exp->eject_notifier);
1644 blk_unref(exp->eject_notifier_blk);
1645 }
1646 blk_remove_aio_context_notifier(exp->blk, blk_aio_attached,
1647 blk_aio_detach, exp);
1648 blk_unref(exp->blk);
1649 exp->blk = NULL;
1650 }
1651
1652 if (exp->export_bitmap) {
1653 bdrv_dirty_bitmap_set_busy(exp->export_bitmap, false);
1654 g_free(exp->export_bitmap_context);
1655 }
1656
1657 g_free(exp);
1658 }
1659}
1660
1661BlockBackend *nbd_export_get_blockdev(NBDExport *exp)
1662{
1663 return exp->blk;
1664}
1665
1666void nbd_export_close_all(void)
1667{
1668 NBDExport *exp, *next;
1669
1670 QTAILQ_FOREACH_SAFE(exp, &exports, next, next) {
1671 nbd_export_close(exp);
1672 }
1673}
1674
1675static int coroutine_fn nbd_co_send_iov(NBDClient *client, struct iovec *iov,
1676 unsigned niov, Error **errp)
1677{
1678 int ret;
1679
1680 g_assert(qemu_in_coroutine());
1681 qemu_co_mutex_lock(&client->send_lock);
1682 client->send_coroutine = qemu_coroutine_self();
1683
1684 ret = qio_channel_writev_all(client->ioc, iov, niov, errp) < 0 ? -EIO : 0;
1685
1686 client->send_coroutine = NULL;
1687 qemu_co_mutex_unlock(&client->send_lock);
1688
1689 return ret;
1690}
1691
1692static inline void set_be_simple_reply(NBDSimpleReply *reply, uint64_t error,
1693 uint64_t handle)
1694{
1695 stl_be_p(&reply->magic, NBD_SIMPLE_REPLY_MAGIC);
1696 stl_be_p(&reply->error, error);
1697 stq_be_p(&reply->handle, handle);
1698}
1699
1700static int nbd_co_send_simple_reply(NBDClient *client,
1701 uint64_t handle,
1702 uint32_t error,
1703 void *data,
1704 size_t len,
1705 Error **errp)
1706{
1707 NBDSimpleReply reply;
1708 int nbd_err = system_errno_to_nbd_errno(error);
1709 struct iovec iov[] = {
1710 {.iov_base = &reply, .iov_len = sizeof(reply)},
1711 {.iov_base = data, .iov_len = len}
1712 };
1713
1714 trace_nbd_co_send_simple_reply(handle, nbd_err, nbd_err_lookup(nbd_err),
1715 len);
1716 set_be_simple_reply(&reply, nbd_err, handle);
1717
1718 return nbd_co_send_iov(client, iov, len ? 2 : 1, errp);
1719}
1720
1721static inline void set_be_chunk(NBDStructuredReplyChunk *chunk, uint16_t flags,
1722 uint16_t type, uint64_t handle, uint32_t length)
1723{
1724 stl_be_p(&chunk->magic, NBD_STRUCTURED_REPLY_MAGIC);
1725 stw_be_p(&chunk->flags, flags);
1726 stw_be_p(&chunk->type, type);
1727 stq_be_p(&chunk->handle, handle);
1728 stl_be_p(&chunk->length, length);
1729}
1730
1731static int coroutine_fn nbd_co_send_structured_done(NBDClient *client,
1732 uint64_t handle,
1733 Error **errp)
1734{
1735 NBDStructuredReplyChunk chunk;
1736 struct iovec iov[] = {
1737 {.iov_base = &chunk, .iov_len = sizeof(chunk)},
1738 };
1739
1740 trace_nbd_co_send_structured_done(handle);
1741 set_be_chunk(&chunk, NBD_REPLY_FLAG_DONE, NBD_REPLY_TYPE_NONE, handle, 0);
1742
1743 return nbd_co_send_iov(client, iov, 1, errp);
1744}
1745
1746static int coroutine_fn nbd_co_send_structured_read(NBDClient *client,
1747 uint64_t handle,
1748 uint64_t offset,
1749 void *data,
1750 size_t size,
1751 bool final,
1752 Error **errp)
1753{
1754 NBDStructuredReadData chunk;
1755 struct iovec iov[] = {
1756 {.iov_base = &chunk, .iov_len = sizeof(chunk)},
1757 {.iov_base = data, .iov_len = size}
1758 };
1759
1760 assert(size);
1761 trace_nbd_co_send_structured_read(handle, offset, data, size);
1762 set_be_chunk(&chunk.h, final ? NBD_REPLY_FLAG_DONE : 0,
1763 NBD_REPLY_TYPE_OFFSET_DATA, handle,
1764 sizeof(chunk) - sizeof(chunk.h) + size);
1765 stq_be_p(&chunk.offset, offset);
1766
1767 return nbd_co_send_iov(client, iov, 2, errp);
1768}
1769
1770static int coroutine_fn nbd_co_send_structured_error(NBDClient *client,
1771 uint64_t handle,
1772 uint32_t error,
1773 const char *msg,
1774 Error **errp)
1775{
1776 NBDStructuredError chunk;
1777 int nbd_err = system_errno_to_nbd_errno(error);
1778 struct iovec iov[] = {
1779 {.iov_base = &chunk, .iov_len = sizeof(chunk)},
1780 {.iov_base = (char *)msg, .iov_len = msg ? strlen(msg) : 0},
1781 };
1782
1783 assert(nbd_err);
1784 trace_nbd_co_send_structured_error(handle, nbd_err,
1785 nbd_err_lookup(nbd_err), msg ? msg : "");
1786 set_be_chunk(&chunk.h, NBD_REPLY_FLAG_DONE, NBD_REPLY_TYPE_ERROR, handle,
1787 sizeof(chunk) - sizeof(chunk.h) + iov[1].iov_len);
1788 stl_be_p(&chunk.error, nbd_err);
1789 stw_be_p(&chunk.message_length, iov[1].iov_len);
1790
1791 return nbd_co_send_iov(client, iov, 1 + !!iov[1].iov_len, errp);
1792}
1793
1794
1795
1796
1797
1798static int coroutine_fn nbd_co_send_sparse_read(NBDClient *client,
1799 uint64_t handle,
1800 uint64_t offset,
1801 uint8_t *data,
1802 size_t size,
1803 Error **errp)
1804{
1805 int ret = 0;
1806 NBDExport *exp = client->exp;
1807 size_t progress = 0;
1808
1809 while (progress < size) {
1810 int64_t pnum;
1811 int status = bdrv_block_status_above(blk_bs(exp->blk), NULL,
1812 offset + progress,
1813 size - progress, &pnum, NULL,
1814 NULL);
1815 bool final;
1816
1817 if (status < 0) {
1818 char *msg = g_strdup_printf("unable to check for holes: %s",
1819 strerror(-status));
1820
1821 ret = nbd_co_send_structured_error(client, handle, -status, msg,
1822 errp);
1823 g_free(msg);
1824 return ret;
1825 }
1826 assert(pnum && pnum <= size - progress);
1827 final = progress + pnum == size;
1828 if (status & BDRV_BLOCK_ZERO) {
1829 NBDStructuredReadHole chunk;
1830 struct iovec iov[] = {
1831 {.iov_base = &chunk, .iov_len = sizeof(chunk)},
1832 };
1833
1834 trace_nbd_co_send_structured_read_hole(handle, offset + progress,
1835 pnum);
1836 set_be_chunk(&chunk.h, final ? NBD_REPLY_FLAG_DONE : 0,
1837 NBD_REPLY_TYPE_OFFSET_HOLE,
1838 handle, sizeof(chunk) - sizeof(chunk.h));
1839 stq_be_p(&chunk.offset, offset + progress);
1840 stl_be_p(&chunk.length, pnum);
1841 ret = nbd_co_send_iov(client, iov, 1, errp);
1842 } else {
1843 ret = blk_pread(exp->blk, offset + progress + exp->dev_offset,
1844 data + progress, pnum);
1845 if (ret < 0) {
1846 error_setg_errno(errp, -ret, "reading from file failed");
1847 break;
1848 }
1849 ret = nbd_co_send_structured_read(client, handle, offset + progress,
1850 data + progress, pnum, final,
1851 errp);
1852 }
1853
1854 if (ret < 0) {
1855 break;
1856 }
1857 progress += pnum;
1858 }
1859 return ret;
1860}
1861
1862
1863
1864
1865
1866
1867
1868
1869static int blockstatus_to_extents(BlockDriverState *bs, uint64_t offset,
1870 uint64_t *bytes, NBDExtent *extents,
1871 unsigned int *nb_extents)
1872{
1873 uint64_t remaining_bytes = *bytes;
1874 NBDExtent *extent = extents, *extents_end = extents + *nb_extents;
1875 bool first_extent = true;
1876
1877 assert(*nb_extents);
1878 while (remaining_bytes) {
1879 uint32_t flags;
1880 int64_t num;
1881 int ret = bdrv_block_status_above(bs, NULL, offset, remaining_bytes,
1882 &num, NULL, NULL);
1883
1884 if (ret < 0) {
1885 return ret;
1886 }
1887
1888 flags = (ret & BDRV_BLOCK_ALLOCATED ? 0 : NBD_STATE_HOLE) |
1889 (ret & BDRV_BLOCK_ZERO ? NBD_STATE_ZERO : 0);
1890
1891 if (first_extent) {
1892 extent->flags = flags;
1893 extent->length = num;
1894 first_extent = false;
1895 } else if (flags == extent->flags) {
1896
1897 extent->length += num;
1898 } else {
1899 if (extent + 1 == extents_end) {
1900 break;
1901 }
1902
1903
1904 extent++;
1905 extent->flags = flags;
1906 extent->length = num;
1907 }
1908 offset += num;
1909 remaining_bytes -= num;
1910 }
1911
1912 extents_end = extent + 1;
1913
1914 for (extent = extents; extent < extents_end; extent++) {
1915 extent->flags = cpu_to_be32(extent->flags);
1916 extent->length = cpu_to_be32(extent->length);
1917 }
1918
1919 *bytes -= remaining_bytes;
1920 *nb_extents = extents_end - extents;
1921
1922 return 0;
1923}
1924
1925
1926
1927
1928
1929
1930
1931
1932static int nbd_co_send_extents(NBDClient *client, uint64_t handle,
1933 NBDExtent *extents, unsigned int nb_extents,
1934 uint64_t length, bool last,
1935 uint32_t context_id, Error **errp)
1936{
1937 NBDStructuredMeta chunk;
1938
1939 struct iovec iov[] = {
1940 {.iov_base = &chunk, .iov_len = sizeof(chunk)},
1941 {.iov_base = extents, .iov_len = nb_extents * sizeof(extents[0])}
1942 };
1943
1944 trace_nbd_co_send_extents(handle, nb_extents, context_id, length, last);
1945 set_be_chunk(&chunk.h, last ? NBD_REPLY_FLAG_DONE : 0,
1946 NBD_REPLY_TYPE_BLOCK_STATUS,
1947 handle, sizeof(chunk) - sizeof(chunk.h) + iov[1].iov_len);
1948 stl_be_p(&chunk.context_id, context_id);
1949
1950 return nbd_co_send_iov(client, iov, 2, errp);
1951}
1952
1953
1954static int nbd_co_send_block_status(NBDClient *client, uint64_t handle,
1955 BlockDriverState *bs, uint64_t offset,
1956 uint32_t length, bool dont_fragment,
1957 bool last, uint32_t context_id,
1958 Error **errp)
1959{
1960 int ret;
1961 unsigned int nb_extents = dont_fragment ? 1 : NBD_MAX_BITMAP_EXTENTS;
1962 NBDExtent *extents = g_new(NBDExtent, nb_extents);
1963 uint64_t final_length = length;
1964
1965 ret = blockstatus_to_extents(bs, offset, &final_length, extents,
1966 &nb_extents);
1967 if (ret < 0) {
1968 g_free(extents);
1969 return nbd_co_send_structured_error(
1970 client, handle, -ret, "can't get block status", errp);
1971 }
1972
1973 ret = nbd_co_send_extents(client, handle, extents, nb_extents,
1974 final_length, last, context_id, errp);
1975
1976 g_free(extents);
1977
1978 return ret;
1979}
1980
1981
1982
1983
1984
1985
1986
1987static unsigned int bitmap_to_extents(BdrvDirtyBitmap *bitmap, uint64_t offset,
1988 uint64_t *length, NBDExtent *extents,
1989 unsigned int nb_extents,
1990 bool dont_fragment)
1991{
1992 uint64_t begin = offset, end = offset;
1993 uint64_t overall_end = offset + *length;
1994 unsigned int i = 0;
1995 BdrvDirtyBitmapIter *it;
1996 bool dirty;
1997
1998 bdrv_dirty_bitmap_lock(bitmap);
1999
2000 it = bdrv_dirty_iter_new(bitmap);
2001 dirty = bdrv_get_dirty_locked(NULL, bitmap, offset);
2002
2003 assert(begin < overall_end && nb_extents);
2004 while (begin < overall_end && i < nb_extents) {
2005 bool next_dirty = !dirty;
2006
2007 if (dirty) {
2008 end = bdrv_dirty_bitmap_next_zero(bitmap, begin, UINT64_MAX);
2009 } else {
2010 bdrv_set_dirty_iter(it, begin);
2011 end = bdrv_dirty_iter_next(it);
2012 }
2013 if (end == -1 || end - begin > UINT32_MAX) {
2014
2015 end = MIN(bdrv_dirty_bitmap_size(bitmap),
2016 begin + UINT32_MAX + 1 -
2017 bdrv_dirty_bitmap_granularity(bitmap));
2018 next_dirty = dirty;
2019 }
2020 if (dont_fragment && end > overall_end) {
2021 end = overall_end;
2022 }
2023
2024 extents[i].length = cpu_to_be32(end - begin);
2025 extents[i].flags = cpu_to_be32(dirty ? NBD_STATE_DIRTY : 0);
2026 i++;
2027 begin = end;
2028 dirty = next_dirty;
2029 }
2030
2031 bdrv_dirty_iter_free(it);
2032
2033 bdrv_dirty_bitmap_unlock(bitmap);
2034
2035 assert(offset < end);
2036 *length = end - offset;
2037 return i;
2038}
2039
2040static int nbd_co_send_bitmap(NBDClient *client, uint64_t handle,
2041 BdrvDirtyBitmap *bitmap, uint64_t offset,
2042 uint32_t length, bool dont_fragment, bool last,
2043 uint32_t context_id, Error **errp)
2044{
2045 int ret;
2046 unsigned int nb_extents = dont_fragment ? 1 : NBD_MAX_BITMAP_EXTENTS;
2047 NBDExtent *extents = g_new(NBDExtent, nb_extents);
2048 uint64_t final_length = length;
2049
2050 nb_extents = bitmap_to_extents(bitmap, offset, &final_length, extents,
2051 nb_extents, dont_fragment);
2052
2053 ret = nbd_co_send_extents(client, handle, extents, nb_extents,
2054 final_length, last, context_id, errp);
2055
2056 g_free(extents);
2057
2058 return ret;
2059}
2060
2061
2062
2063
2064
2065
2066
2067static int nbd_co_receive_request(NBDRequestData *req, NBDRequest *request,
2068 Error **errp)
2069{
2070 NBDClient *client = req->client;
2071 int valid_flags;
2072
2073 g_assert(qemu_in_coroutine());
2074 assert(client->recv_coroutine == qemu_coroutine_self());
2075 if (nbd_receive_request(client->ioc, request, errp) < 0) {
2076 return -EIO;
2077 }
2078
2079 trace_nbd_co_receive_request_decode_type(request->handle, request->type,
2080 nbd_cmd_lookup(request->type));
2081
2082 if (request->type != NBD_CMD_WRITE) {
2083
2084 req->complete = true;
2085 }
2086
2087 if (request->type == NBD_CMD_DISC) {
2088
2089
2090 return -EIO;
2091 }
2092
2093 if (request->type == NBD_CMD_READ || request->type == NBD_CMD_WRITE ||
2094 request->type == NBD_CMD_CACHE)
2095 {
2096 if (request->len > NBD_MAX_BUFFER_SIZE) {
2097 error_setg(errp, "len (%" PRIu32" ) is larger than max len (%u)",
2098 request->len, NBD_MAX_BUFFER_SIZE);
2099 return -EINVAL;
2100 }
2101
2102 req->data = blk_try_blockalign(client->exp->blk, request->len);
2103 if (req->data == NULL) {
2104 error_setg(errp, "No memory");
2105 return -ENOMEM;
2106 }
2107 }
2108 if (request->type == NBD_CMD_WRITE) {
2109 if (nbd_read(client->ioc, req->data, request->len, "CMD_WRITE data",
2110 errp) < 0)
2111 {
2112 return -EIO;
2113 }
2114 req->complete = true;
2115
2116 trace_nbd_co_receive_request_payload_received(request->handle,
2117 request->len);
2118 }
2119
2120
2121 if (client->exp->nbdflags & NBD_FLAG_READ_ONLY &&
2122 (request->type == NBD_CMD_WRITE ||
2123 request->type == NBD_CMD_WRITE_ZEROES ||
2124 request->type == NBD_CMD_TRIM)) {
2125 error_setg(errp, "Export is read-only");
2126 return -EROFS;
2127 }
2128 if (request->from > client->exp->size ||
2129 request->len > client->exp->size - request->from) {
2130 error_setg(errp, "operation past EOF; From: %" PRIu64 ", Len: %" PRIu32
2131 ", Size: %" PRIu64, request->from, request->len,
2132 client->exp->size);
2133 return (request->type == NBD_CMD_WRITE ||
2134 request->type == NBD_CMD_WRITE_ZEROES) ? -ENOSPC : -EINVAL;
2135 }
2136 if (client->check_align && !QEMU_IS_ALIGNED(request->from | request->len,
2137 client->check_align)) {
2138
2139
2140
2141
2142 trace_nbd_co_receive_align_compliance(nbd_cmd_lookup(request->type),
2143 request->from,
2144 request->len,
2145 client->check_align);
2146 }
2147 valid_flags = NBD_CMD_FLAG_FUA;
2148 if (request->type == NBD_CMD_READ && client->structured_reply) {
2149 valid_flags |= NBD_CMD_FLAG_DF;
2150 } else if (request->type == NBD_CMD_WRITE_ZEROES) {
2151 valid_flags |= NBD_CMD_FLAG_NO_HOLE;
2152 } else if (request->type == NBD_CMD_BLOCK_STATUS) {
2153 valid_flags |= NBD_CMD_FLAG_REQ_ONE;
2154 }
2155 if (request->flags & ~valid_flags) {
2156 error_setg(errp, "unsupported flags for command %s (got 0x%x)",
2157 nbd_cmd_lookup(request->type), request->flags);
2158 return -EINVAL;
2159 }
2160
2161 return 0;
2162}
2163
2164
2165
2166
2167
2168static coroutine_fn int nbd_send_generic_reply(NBDClient *client,
2169 uint64_t handle,
2170 int ret,
2171 const char *error_msg,
2172 Error **errp)
2173{
2174 if (client->structured_reply && ret < 0) {
2175 return nbd_co_send_structured_error(client, handle, -ret, error_msg,
2176 errp);
2177 } else {
2178 return nbd_co_send_simple_reply(client, handle, ret < 0 ? -ret : 0,
2179 NULL, 0, errp);
2180 }
2181}
2182
2183
2184
2185
2186static coroutine_fn int nbd_do_cmd_read(NBDClient *client, NBDRequest *request,
2187 uint8_t *data, Error **errp)
2188{
2189 int ret;
2190 NBDExport *exp = client->exp;
2191
2192 assert(request->type == NBD_CMD_READ || request->type == NBD_CMD_CACHE);
2193
2194
2195 if (request->flags & NBD_CMD_FLAG_FUA) {
2196 ret = blk_co_flush(exp->blk);
2197 if (ret < 0) {
2198 return nbd_send_generic_reply(client, request->handle, ret,
2199 "flush failed", errp);
2200 }
2201 }
2202
2203 if (client->structured_reply && !(request->flags & NBD_CMD_FLAG_DF) &&
2204 request->len && request->type != NBD_CMD_CACHE)
2205 {
2206 return nbd_co_send_sparse_read(client, request->handle, request->from,
2207 data, request->len, errp);
2208 }
2209
2210 ret = blk_pread(exp->blk, request->from + exp->dev_offset, data,
2211 request->len);
2212 if (ret < 0 || request->type == NBD_CMD_CACHE) {
2213 return nbd_send_generic_reply(client, request->handle, ret,
2214 "reading from file failed", errp);
2215 }
2216
2217 if (client->structured_reply) {
2218 if (request->len) {
2219 return nbd_co_send_structured_read(client, request->handle,
2220 request->from, data,
2221 request->len, true, errp);
2222 } else {
2223 return nbd_co_send_structured_done(client, request->handle, errp);
2224 }
2225 } else {
2226 return nbd_co_send_simple_reply(client, request->handle, 0,
2227 data, request->len, errp);
2228 }
2229}
2230
2231
2232
2233
2234static coroutine_fn int nbd_handle_request(NBDClient *client,
2235 NBDRequest *request,
2236 uint8_t *data, Error **errp)
2237{
2238 int ret;
2239 int flags;
2240 NBDExport *exp = client->exp;
2241 char *msg;
2242
2243 switch (request->type) {
2244 case NBD_CMD_READ:
2245 case NBD_CMD_CACHE:
2246 return nbd_do_cmd_read(client, request, data, errp);
2247
2248 case NBD_CMD_WRITE:
2249 flags = 0;
2250 if (request->flags & NBD_CMD_FLAG_FUA) {
2251 flags |= BDRV_REQ_FUA;
2252 }
2253 ret = blk_pwrite(exp->blk, request->from + exp->dev_offset,
2254 data, request->len, flags);
2255 return nbd_send_generic_reply(client, request->handle, ret,
2256 "writing to file failed", errp);
2257
2258 case NBD_CMD_WRITE_ZEROES:
2259 flags = 0;
2260 if (request->flags & NBD_CMD_FLAG_FUA) {
2261 flags |= BDRV_REQ_FUA;
2262 }
2263 if (!(request->flags & NBD_CMD_FLAG_NO_HOLE)) {
2264 flags |= BDRV_REQ_MAY_UNMAP;
2265 }
2266 ret = blk_pwrite_zeroes(exp->blk, request->from + exp->dev_offset,
2267 request->len, flags);
2268 return nbd_send_generic_reply(client, request->handle, ret,
2269 "writing to file failed", errp);
2270
2271 case NBD_CMD_DISC:
2272
2273 abort();
2274
2275 case NBD_CMD_FLUSH:
2276 ret = blk_co_flush(exp->blk);
2277 return nbd_send_generic_reply(client, request->handle, ret,
2278 "flush failed", errp);
2279
2280 case NBD_CMD_TRIM:
2281 ret = blk_co_pdiscard(exp->blk, request->from + exp->dev_offset,
2282 request->len);
2283 if (ret == 0 && request->flags & NBD_CMD_FLAG_FUA) {
2284 ret = blk_co_flush(exp->blk);
2285 }
2286 return nbd_send_generic_reply(client, request->handle, ret,
2287 "discard failed", errp);
2288
2289 case NBD_CMD_BLOCK_STATUS:
2290 if (!request->len) {
2291 return nbd_send_generic_reply(client, request->handle, -EINVAL,
2292 "need non-zero length", errp);
2293 }
2294 if (client->export_meta.valid &&
2295 (client->export_meta.base_allocation ||
2296 client->export_meta.bitmap))
2297 {
2298 bool dont_fragment = request->flags & NBD_CMD_FLAG_REQ_ONE;
2299
2300 if (client->export_meta.base_allocation) {
2301 ret = nbd_co_send_block_status(client, request->handle,
2302 blk_bs(exp->blk), request->from,
2303 request->len, dont_fragment,
2304 !client->export_meta.bitmap,
2305 NBD_META_ID_BASE_ALLOCATION,
2306 errp);
2307 if (ret < 0) {
2308 return ret;
2309 }
2310 }
2311
2312 if (client->export_meta.bitmap) {
2313 ret = nbd_co_send_bitmap(client, request->handle,
2314 client->exp->export_bitmap,
2315 request->from, request->len,
2316 dont_fragment,
2317 true, NBD_META_ID_DIRTY_BITMAP, errp);
2318 if (ret < 0) {
2319 return ret;
2320 }
2321 }
2322
2323 return ret;
2324 } else {
2325 return nbd_send_generic_reply(client, request->handle, -EINVAL,
2326 "CMD_BLOCK_STATUS not negotiated",
2327 errp);
2328 }
2329
2330 default:
2331 msg = g_strdup_printf("invalid request type (%" PRIu32 ") received",
2332 request->type);
2333 ret = nbd_send_generic_reply(client, request->handle, -EINVAL, msg,
2334 errp);
2335 g_free(msg);
2336 return ret;
2337 }
2338}
2339
2340
2341static coroutine_fn void nbd_trip(void *opaque)
2342{
2343 NBDClient *client = opaque;
2344 NBDRequestData *req;
2345 NBDRequest request = { 0 };
2346 int ret;
2347 Error *local_err = NULL;
2348
2349 trace_nbd_trip();
2350 if (client->closing) {
2351 nbd_client_put(client);
2352 return;
2353 }
2354
2355 req = nbd_request_get(client);
2356 ret = nbd_co_receive_request(req, &request, &local_err);
2357 client->recv_coroutine = NULL;
2358
2359 if (client->closing) {
2360
2361
2362
2363
2364 goto done;
2365 }
2366
2367 nbd_client_receive_next_request(client);
2368 if (ret == -EIO) {
2369 goto disconnect;
2370 }
2371
2372 if (ret < 0) {
2373
2374
2375 Error *export_err = local_err;
2376
2377 local_err = NULL;
2378 ret = nbd_send_generic_reply(client, request.handle, -EINVAL,
2379 error_get_pretty(export_err), &local_err);
2380 error_free(export_err);
2381 } else {
2382 ret = nbd_handle_request(client, &request, req->data, &local_err);
2383 }
2384 if (ret < 0) {
2385 error_prepend(&local_err, "Failed to send reply: ");
2386 goto disconnect;
2387 }
2388
2389
2390
2391
2392 if (!req->complete) {
2393 error_setg(&local_err, "Request handling failed in intermediate state");
2394 goto disconnect;
2395 }
2396
2397done:
2398 nbd_request_put(req);
2399 nbd_client_put(client);
2400 return;
2401
2402disconnect:
2403 if (local_err) {
2404 error_reportf_err(local_err, "Disconnect client, due to: ");
2405 }
2406 nbd_request_put(req);
2407 client_close(client, true);
2408 nbd_client_put(client);
2409}
2410
2411static void nbd_client_receive_next_request(NBDClient *client)
2412{
2413 if (!client->recv_coroutine && client->nb_requests < MAX_NBD_REQUESTS) {
2414 nbd_client_get(client);
2415 client->recv_coroutine = qemu_coroutine_create(nbd_trip, client);
2416 aio_co_schedule(client->exp->ctx, client->recv_coroutine);
2417 }
2418}
2419
2420static coroutine_fn void nbd_co_client_start(void *opaque)
2421{
2422 NBDClient *client = opaque;
2423 Error *local_err = NULL;
2424
2425 qemu_co_mutex_init(&client->send_lock);
2426
2427 if (nbd_negotiate(client, &local_err)) {
2428 if (local_err) {
2429 error_report_err(local_err);
2430 }
2431 client_close(client, false);
2432 return;
2433 }
2434
2435 nbd_client_receive_next_request(client);
2436}
2437
2438
2439
2440
2441
2442
2443void nbd_client_new(QIOChannelSocket *sioc,
2444 QCryptoTLSCreds *tlscreds,
2445 const char *tlsauthz,
2446 void (*close_fn)(NBDClient *, bool))
2447{
2448 NBDClient *client;
2449 Coroutine *co;
2450
2451 client = g_new0(NBDClient, 1);
2452 client->refcount = 1;
2453 client->tlscreds = tlscreds;
2454 if (tlscreds) {
2455 object_ref(OBJECT(client->tlscreds));
2456 }
2457 client->tlsauthz = g_strdup(tlsauthz);
2458 client->sioc = sioc;
2459 object_ref(OBJECT(client->sioc));
2460 client->ioc = QIO_CHANNEL(sioc);
2461 object_ref(OBJECT(client->ioc));
2462 client->close_fn = close_fn;
2463
2464 co = qemu_coroutine_create(nbd_co_client_start, client);
2465 qemu_coroutine_enter(co);
2466}
2467