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