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 cpu_to_be32s(&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 cpu_to_be16s(&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 be16_to_cpus(&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 be16_to_cpus(&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 cpu_to_be32s(&sizes[0]);
622 cpu_to_be32s(&sizes[1]);
623 cpu_to_be32s(&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 cpu_to_be32s(&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 cpu_to_be32s(&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 } else {
982 for (i = 0; i < nb_queries; ++i) {
983 ret = nbd_negotiate_meta_query(client, meta, errp);
984 if (ret <= 0) {
985 return ret;
986 }
987 }
988 }
989
990 if (meta->base_allocation) {
991 ret = nbd_negotiate_send_meta_context(client, "base:allocation",
992 NBD_META_ID_BASE_ALLOCATION,
993 errp);
994 if (ret < 0) {
995 return ret;
996 }
997 }
998
999 if (meta->bitmap) {
1000 ret = nbd_negotiate_send_meta_context(client,
1001 meta->exp->export_bitmap_context,
1002 NBD_META_ID_DIRTY_BITMAP,
1003 errp);
1004 if (ret < 0) {
1005 return ret;
1006 }
1007 }
1008
1009 ret = nbd_negotiate_send_rep(client, NBD_REP_ACK, errp);
1010 if (ret == 0) {
1011 meta->valid = true;
1012 }
1013
1014 return ret;
1015}
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026static int nbd_negotiate_options(NBDClient *client, uint16_t myflags,
1027 Error **errp)
1028{
1029 uint32_t flags;
1030 bool fixedNewstyle = false;
1031 bool no_zeroes = false;
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048 if (nbd_read(client->ioc, &flags, sizeof(flags), errp) < 0) {
1049 error_prepend(errp, "read failed: ");
1050 return -EIO;
1051 }
1052 be32_to_cpus(&flags);
1053 trace_nbd_negotiate_options_flags(flags);
1054 if (flags & NBD_FLAG_C_FIXED_NEWSTYLE) {
1055 fixedNewstyle = true;
1056 flags &= ~NBD_FLAG_C_FIXED_NEWSTYLE;
1057 }
1058 if (flags & NBD_FLAG_C_NO_ZEROES) {
1059 no_zeroes = true;
1060 flags &= ~NBD_FLAG_C_NO_ZEROES;
1061 }
1062 if (flags != 0) {
1063 error_setg(errp, "Unknown client flags 0x%" PRIx32 " received", flags);
1064 return -EINVAL;
1065 }
1066
1067 while (1) {
1068 int ret;
1069 uint32_t option, length;
1070 uint64_t magic;
1071
1072 if (nbd_read(client->ioc, &magic, sizeof(magic), errp) < 0) {
1073 error_prepend(errp, "read failed: ");
1074 return -EINVAL;
1075 }
1076 magic = be64_to_cpu(magic);
1077 trace_nbd_negotiate_options_check_magic(magic);
1078 if (magic != NBD_OPTS_MAGIC) {
1079 error_setg(errp, "Bad magic received");
1080 return -EINVAL;
1081 }
1082
1083 if (nbd_read(client->ioc, &option,
1084 sizeof(option), errp) < 0) {
1085 error_prepend(errp, "read failed: ");
1086 return -EINVAL;
1087 }
1088 option = be32_to_cpu(option);
1089 client->opt = option;
1090
1091 if (nbd_read(client->ioc, &length, sizeof(length), errp) < 0) {
1092 error_prepend(errp, "read failed: ");
1093 return -EINVAL;
1094 }
1095 length = be32_to_cpu(length);
1096 assert(!client->optlen);
1097 client->optlen = length;
1098
1099 if (length > NBD_MAX_BUFFER_SIZE) {
1100 error_setg(errp, "len (%" PRIu32" ) is larger than max len (%u)",
1101 length, NBD_MAX_BUFFER_SIZE);
1102 return -EINVAL;
1103 }
1104
1105 trace_nbd_negotiate_options_check_option(option,
1106 nbd_opt_lookup(option));
1107 if (client->tlscreds &&
1108 client->ioc == (QIOChannel *)client->sioc) {
1109 QIOChannel *tioc;
1110 if (!fixedNewstyle) {
1111 error_setg(errp, "Unsupported option 0x%" PRIx32, option);
1112 return -EINVAL;
1113 }
1114 switch (option) {
1115 case NBD_OPT_STARTTLS:
1116 if (length) {
1117
1118
1119 return nbd_reject_length(client, true, errp);
1120 }
1121 tioc = nbd_negotiate_handle_starttls(client, errp);
1122 if (!tioc) {
1123 return -EIO;
1124 }
1125 ret = 0;
1126 object_unref(OBJECT(client->ioc));
1127 client->ioc = QIO_CHANNEL(tioc);
1128 break;
1129
1130 case NBD_OPT_EXPORT_NAME:
1131
1132 error_setg(errp, "Option 0x%x not permitted before TLS",
1133 option);
1134 return -EINVAL;
1135
1136 default:
1137 ret = nbd_opt_drop(client, NBD_REP_ERR_TLS_REQD, errp,
1138 "Option 0x%" PRIx32
1139 "not permitted before TLS", option);
1140
1141
1142
1143 if (option == NBD_OPT_ABORT) {
1144 return 1;
1145 }
1146 break;
1147 }
1148 } else if (fixedNewstyle) {
1149 switch (option) {
1150 case NBD_OPT_LIST:
1151 if (length) {
1152 ret = nbd_reject_length(client, false, errp);
1153 } else {
1154 ret = nbd_negotiate_handle_list(client, errp);
1155 }
1156 break;
1157
1158 case NBD_OPT_ABORT:
1159
1160
1161
1162 nbd_negotiate_send_rep(client, NBD_REP_ACK, NULL);
1163 return 1;
1164
1165 case NBD_OPT_EXPORT_NAME:
1166 return nbd_negotiate_handle_export_name(client,
1167 myflags, no_zeroes,
1168 errp);
1169
1170 case NBD_OPT_INFO:
1171 case NBD_OPT_GO:
1172 ret = nbd_negotiate_handle_info(client, myflags, errp);
1173 if (ret == 1) {
1174 assert(option == NBD_OPT_GO);
1175 return 0;
1176 }
1177 break;
1178
1179 case NBD_OPT_STARTTLS:
1180 if (length) {
1181 ret = nbd_reject_length(client, false, errp);
1182 } else if (client->tlscreds) {
1183 ret = nbd_negotiate_send_rep_err(client,
1184 NBD_REP_ERR_INVALID, errp,
1185 "TLS already enabled");
1186 } else {
1187 ret = nbd_negotiate_send_rep_err(client,
1188 NBD_REP_ERR_POLICY, errp,
1189 "TLS not configured");
1190 }
1191 break;
1192
1193 case NBD_OPT_STRUCTURED_REPLY:
1194 if (length) {
1195 ret = nbd_reject_length(client, false, errp);
1196 } else if (client->structured_reply) {
1197 ret = nbd_negotiate_send_rep_err(
1198 client, NBD_REP_ERR_INVALID, errp,
1199 "structured reply already negotiated");
1200 } else {
1201 ret = nbd_negotiate_send_rep(client, NBD_REP_ACK, errp);
1202 client->structured_reply = true;
1203 myflags |= NBD_FLAG_SEND_DF;
1204 }
1205 break;
1206
1207 case NBD_OPT_LIST_META_CONTEXT:
1208 case NBD_OPT_SET_META_CONTEXT:
1209 ret = nbd_negotiate_meta_queries(client, &client->export_meta,
1210 errp);
1211 break;
1212
1213 default:
1214 ret = nbd_opt_drop(client, NBD_REP_ERR_UNSUP, errp,
1215 "Unsupported option %" PRIu32 " (%s)",
1216 option, nbd_opt_lookup(option));
1217 break;
1218 }
1219 } else {
1220
1221
1222
1223
1224 switch (option) {
1225 case NBD_OPT_EXPORT_NAME:
1226 return nbd_negotiate_handle_export_name(client,
1227 myflags, no_zeroes,
1228 errp);
1229
1230 default:
1231 error_setg(errp, "Unsupported option %" PRIu32 " (%s)",
1232 option, nbd_opt_lookup(option));
1233 return -EINVAL;
1234 }
1235 }
1236 if (ret < 0) {
1237 return ret;
1238 }
1239 }
1240}
1241
1242
1243
1244
1245
1246
1247
1248
1249static coroutine_fn int nbd_negotiate(NBDClient *client, Error **errp)
1250{
1251 char buf[NBD_OLDSTYLE_NEGOTIATE_SIZE] = "";
1252 int ret;
1253 const uint16_t myflags = (NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
1254 NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA |
1255 NBD_FLAG_SEND_WRITE_ZEROES | NBD_FLAG_SEND_CACHE);
1256 bool oldStyle;
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272 qio_channel_set_blocking(client->ioc, false, NULL);
1273
1274 trace_nbd_negotiate_begin();
1275 memcpy(buf, "NBDMAGIC", 8);
1276
1277 oldStyle = client->exp != NULL && !client->tlscreds;
1278 if (oldStyle) {
1279 trace_nbd_negotiate_old_style(client->exp->size,
1280 client->exp->nbdflags | myflags);
1281 stq_be_p(buf + 8, NBD_CLIENT_MAGIC);
1282 stq_be_p(buf + 16, client->exp->size);
1283 stl_be_p(buf + 24, client->exp->nbdflags | myflags);
1284
1285 if (nbd_write(client->ioc, buf, sizeof(buf), errp) < 0) {
1286 error_prepend(errp, "write failed: ");
1287 return -EINVAL;
1288 }
1289 } else {
1290 stq_be_p(buf + 8, NBD_OPTS_MAGIC);
1291 stw_be_p(buf + 16, NBD_FLAG_FIXED_NEWSTYLE | NBD_FLAG_NO_ZEROES);
1292
1293 if (nbd_write(client->ioc, buf, 18, errp) < 0) {
1294 error_prepend(errp, "write failed: ");
1295 return -EINVAL;
1296 }
1297 ret = nbd_negotiate_options(client, myflags, errp);
1298 if (ret != 0) {
1299 if (ret < 0) {
1300 error_prepend(errp, "option negotiation failed: ");
1301 }
1302 return ret;
1303 }
1304 }
1305
1306 assert(!client->optlen);
1307 trace_nbd_negotiate_success();
1308
1309 return 0;
1310}
1311
1312static int nbd_receive_request(QIOChannel *ioc, NBDRequest *request,
1313 Error **errp)
1314{
1315 uint8_t buf[NBD_REQUEST_SIZE];
1316 uint32_t magic;
1317 int ret;
1318
1319 ret = nbd_read(ioc, buf, sizeof(buf), errp);
1320 if (ret < 0) {
1321 return ret;
1322 }
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333 magic = ldl_be_p(buf);
1334 request->flags = lduw_be_p(buf + 4);
1335 request->type = lduw_be_p(buf + 6);
1336 request->handle = ldq_be_p(buf + 8);
1337 request->from = ldq_be_p(buf + 16);
1338 request->len = ldl_be_p(buf + 24);
1339
1340 trace_nbd_receive_request(magic, request->flags, request->type,
1341 request->from, request->len);
1342
1343 if (magic != NBD_REQUEST_MAGIC) {
1344 error_setg(errp, "invalid magic (got 0x%" PRIx32 ")", magic);
1345 return -EINVAL;
1346 }
1347 return 0;
1348}
1349
1350#define MAX_NBD_REQUESTS 16
1351
1352void nbd_client_get(NBDClient *client)
1353{
1354 client->refcount++;
1355}
1356
1357void nbd_client_put(NBDClient *client)
1358{
1359 if (--client->refcount == 0) {
1360
1361
1362
1363 assert(client->closing);
1364
1365 qio_channel_detach_aio_context(client->ioc);
1366 object_unref(OBJECT(client->sioc));
1367 object_unref(OBJECT(client->ioc));
1368 if (client->tlscreds) {
1369 object_unref(OBJECT(client->tlscreds));
1370 }
1371 g_free(client->tlsaclname);
1372 if (client->exp) {
1373 QTAILQ_REMOVE(&client->exp->clients, client, next);
1374 nbd_export_put(client->exp);
1375 }
1376 g_free(client);
1377 }
1378}
1379
1380static void client_close(NBDClient *client, bool negotiated)
1381{
1382 if (client->closing) {
1383 return;
1384 }
1385
1386 client->closing = true;
1387
1388
1389
1390
1391 qio_channel_shutdown(client->ioc, QIO_CHANNEL_SHUTDOWN_BOTH,
1392 NULL);
1393
1394
1395 if (client->close_fn) {
1396 client->close_fn(client, negotiated);
1397 }
1398}
1399
1400static NBDRequestData *nbd_request_get(NBDClient *client)
1401{
1402 NBDRequestData *req;
1403
1404 assert(client->nb_requests <= MAX_NBD_REQUESTS - 1);
1405 client->nb_requests++;
1406
1407 req = g_new0(NBDRequestData, 1);
1408 nbd_client_get(client);
1409 req->client = client;
1410 return req;
1411}
1412
1413static void nbd_request_put(NBDRequestData *req)
1414{
1415 NBDClient *client = req->client;
1416
1417 if (req->data) {
1418 qemu_vfree(req->data);
1419 }
1420 g_free(req);
1421
1422 client->nb_requests--;
1423 nbd_client_receive_next_request(client);
1424
1425 nbd_client_put(client);
1426}
1427
1428static void blk_aio_attached(AioContext *ctx, void *opaque)
1429{
1430 NBDExport *exp = opaque;
1431 NBDClient *client;
1432
1433 trace_nbd_blk_aio_attached(exp->name, ctx);
1434
1435 exp->ctx = ctx;
1436
1437 QTAILQ_FOREACH(client, &exp->clients, next) {
1438 qio_channel_attach_aio_context(client->ioc, ctx);
1439 if (client->recv_coroutine) {
1440 aio_co_schedule(ctx, client->recv_coroutine);
1441 }
1442 if (client->send_coroutine) {
1443 aio_co_schedule(ctx, client->send_coroutine);
1444 }
1445 }
1446}
1447
1448static void blk_aio_detach(void *opaque)
1449{
1450 NBDExport *exp = opaque;
1451 NBDClient *client;
1452
1453 trace_nbd_blk_aio_detach(exp->name, exp->ctx);
1454
1455 QTAILQ_FOREACH(client, &exp->clients, next) {
1456 qio_channel_detach_aio_context(client->ioc);
1457 }
1458
1459 exp->ctx = NULL;
1460}
1461
1462static void nbd_eject_notifier(Notifier *n, void *data)
1463{
1464 NBDExport *exp = container_of(n, NBDExport, eject_notifier);
1465 nbd_export_close(exp);
1466}
1467
1468NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size,
1469 uint16_t nbdflags, void (*close)(NBDExport *),
1470 bool writethrough, BlockBackend *on_eject_blk,
1471 Error **errp)
1472{
1473 AioContext *ctx;
1474 BlockBackend *blk;
1475 NBDExport *exp = g_new0(NBDExport, 1);
1476 uint64_t perm;
1477 int ret;
1478
1479
1480
1481
1482
1483
1484 ctx = bdrv_get_aio_context(bs);
1485 aio_context_acquire(ctx);
1486 bdrv_invalidate_cache(bs, NULL);
1487 aio_context_release(ctx);
1488
1489
1490
1491 perm = BLK_PERM_CONSISTENT_READ;
1492 if ((nbdflags & NBD_FLAG_READ_ONLY) == 0) {
1493 perm |= BLK_PERM_WRITE;
1494 }
1495 blk = blk_new(perm, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED |
1496 BLK_PERM_WRITE | BLK_PERM_GRAPH_MOD);
1497 ret = blk_insert_bs(blk, bs, errp);
1498 if (ret < 0) {
1499 goto fail;
1500 }
1501 blk_set_enable_write_cache(blk, !writethrough);
1502
1503 exp->refcount = 1;
1504 QTAILQ_INIT(&exp->clients);
1505 exp->blk = blk;
1506 exp->dev_offset = dev_offset;
1507 exp->nbdflags = nbdflags;
1508 exp->size = size < 0 ? blk_getlength(blk) : size;
1509 if (exp->size < 0) {
1510 error_setg_errno(errp, -exp->size,
1511 "Failed to determine the NBD export's length");
1512 goto fail;
1513 }
1514 exp->size -= exp->size % BDRV_SECTOR_SIZE;
1515
1516 exp->close = close;
1517 exp->ctx = blk_get_aio_context(blk);
1518 blk_add_aio_context_notifier(blk, blk_aio_attached, blk_aio_detach, exp);
1519
1520 if (on_eject_blk) {
1521 blk_ref(on_eject_blk);
1522 exp->eject_notifier_blk = on_eject_blk;
1523 exp->eject_notifier.notify = nbd_eject_notifier;
1524 blk_add_remove_bs_notifier(on_eject_blk, &exp->eject_notifier);
1525 }
1526 return exp;
1527
1528fail:
1529 blk_unref(blk);
1530 g_free(exp);
1531 return NULL;
1532}
1533
1534NBDExport *nbd_export_find(const char *name)
1535{
1536 NBDExport *exp;
1537 QTAILQ_FOREACH(exp, &exports, next) {
1538 if (strcmp(name, exp->name) == 0) {
1539 return exp;
1540 }
1541 }
1542
1543 return NULL;
1544}
1545
1546void nbd_export_set_name(NBDExport *exp, const char *name)
1547{
1548 if (exp->name == name) {
1549 return;
1550 }
1551
1552 nbd_export_get(exp);
1553 if (exp->name != NULL) {
1554 g_free(exp->name);
1555 exp->name = NULL;
1556 QTAILQ_REMOVE(&exports, exp, next);
1557 nbd_export_put(exp);
1558 }
1559 if (name != NULL) {
1560 nbd_export_get(exp);
1561 exp->name = g_strdup(name);
1562 QTAILQ_INSERT_TAIL(&exports, exp, next);
1563 }
1564 nbd_export_put(exp);
1565}
1566
1567void nbd_export_set_description(NBDExport *exp, const char *description)
1568{
1569 g_free(exp->description);
1570 exp->description = g_strdup(description);
1571}
1572
1573void nbd_export_close(NBDExport *exp)
1574{
1575 NBDClient *client, *next;
1576
1577 nbd_export_get(exp);
1578 QTAILQ_FOREACH_SAFE(client, &exp->clients, next, next) {
1579 client_close(client, true);
1580 }
1581 nbd_export_set_name(exp, NULL);
1582 nbd_export_set_description(exp, NULL);
1583 nbd_export_put(exp);
1584}
1585
1586void nbd_export_remove(NBDExport *exp, NbdServerRemoveMode mode, Error **errp)
1587{
1588 if (mode == NBD_SERVER_REMOVE_MODE_HARD || QTAILQ_EMPTY(&exp->clients)) {
1589 nbd_export_close(exp);
1590 return;
1591 }
1592
1593 assert(mode == NBD_SERVER_REMOVE_MODE_SAFE);
1594
1595 error_setg(errp, "export '%s' still in use", exp->name);
1596 error_append_hint(errp, "Use mode='hard' to force client disconnect\n");
1597}
1598
1599void nbd_export_get(NBDExport *exp)
1600{
1601 assert(exp->refcount > 0);
1602 exp->refcount++;
1603}
1604
1605void nbd_export_put(NBDExport *exp)
1606{
1607 assert(exp->refcount > 0);
1608 if (exp->refcount == 1) {
1609 nbd_export_close(exp);
1610 }
1611
1612
1613
1614
1615
1616
1617 assert(exp->refcount > 0);
1618 if (--exp->refcount == 0) {
1619 assert(exp->name == NULL);
1620 assert(exp->description == NULL);
1621
1622 if (exp->close) {
1623 exp->close(exp);
1624 }
1625
1626 if (exp->blk) {
1627 if (exp->eject_notifier_blk) {
1628 notifier_remove(&exp->eject_notifier);
1629 blk_unref(exp->eject_notifier_blk);
1630 }
1631 blk_remove_aio_context_notifier(exp->blk, blk_aio_attached,
1632 blk_aio_detach, exp);
1633 blk_unref(exp->blk);
1634 exp->blk = NULL;
1635 }
1636
1637 if (exp->export_bitmap) {
1638 bdrv_dirty_bitmap_set_qmp_locked(exp->export_bitmap, false);
1639 g_free(exp->export_bitmap_context);
1640 }
1641
1642 g_free(exp);
1643 }
1644}
1645
1646BlockBackend *nbd_export_get_blockdev(NBDExport *exp)
1647{
1648 return exp->blk;
1649}
1650
1651void nbd_export_close_all(void)
1652{
1653 NBDExport *exp, *next;
1654
1655 QTAILQ_FOREACH_SAFE(exp, &exports, next, next) {
1656 nbd_export_close(exp);
1657 }
1658}
1659
1660static int coroutine_fn nbd_co_send_iov(NBDClient *client, struct iovec *iov,
1661 unsigned niov, Error **errp)
1662{
1663 int ret;
1664
1665 g_assert(qemu_in_coroutine());
1666 qemu_co_mutex_lock(&client->send_lock);
1667 client->send_coroutine = qemu_coroutine_self();
1668
1669 ret = qio_channel_writev_all(client->ioc, iov, niov, errp) < 0 ? -EIO : 0;
1670
1671 client->send_coroutine = NULL;
1672 qemu_co_mutex_unlock(&client->send_lock);
1673
1674 return ret;
1675}
1676
1677static inline void set_be_simple_reply(NBDSimpleReply *reply, uint64_t error,
1678 uint64_t handle)
1679{
1680 stl_be_p(&reply->magic, NBD_SIMPLE_REPLY_MAGIC);
1681 stl_be_p(&reply->error, error);
1682 stq_be_p(&reply->handle, handle);
1683}
1684
1685static int nbd_co_send_simple_reply(NBDClient *client,
1686 uint64_t handle,
1687 uint32_t error,
1688 void *data,
1689 size_t len,
1690 Error **errp)
1691{
1692 NBDSimpleReply reply;
1693 int nbd_err = system_errno_to_nbd_errno(error);
1694 struct iovec iov[] = {
1695 {.iov_base = &reply, .iov_len = sizeof(reply)},
1696 {.iov_base = data, .iov_len = len}
1697 };
1698
1699 trace_nbd_co_send_simple_reply(handle, nbd_err, nbd_err_lookup(nbd_err),
1700 len);
1701 set_be_simple_reply(&reply, nbd_err, handle);
1702
1703 return nbd_co_send_iov(client, iov, len ? 2 : 1, errp);
1704}
1705
1706static inline void set_be_chunk(NBDStructuredReplyChunk *chunk, uint16_t flags,
1707 uint16_t type, uint64_t handle, uint32_t length)
1708{
1709 stl_be_p(&chunk->magic, NBD_STRUCTURED_REPLY_MAGIC);
1710 stw_be_p(&chunk->flags, flags);
1711 stw_be_p(&chunk->type, type);
1712 stq_be_p(&chunk->handle, handle);
1713 stl_be_p(&chunk->length, length);
1714}
1715
1716static int coroutine_fn nbd_co_send_structured_done(NBDClient *client,
1717 uint64_t handle,
1718 Error **errp)
1719{
1720 NBDStructuredReplyChunk chunk;
1721 struct iovec iov[] = {
1722 {.iov_base = &chunk, .iov_len = sizeof(chunk)},
1723 };
1724
1725 trace_nbd_co_send_structured_done(handle);
1726 set_be_chunk(&chunk, NBD_REPLY_FLAG_DONE, NBD_REPLY_TYPE_NONE, handle, 0);
1727
1728 return nbd_co_send_iov(client, iov, 1, errp);
1729}
1730
1731static int coroutine_fn nbd_co_send_structured_read(NBDClient *client,
1732 uint64_t handle,
1733 uint64_t offset,
1734 void *data,
1735 size_t size,
1736 bool final,
1737 Error **errp)
1738{
1739 NBDStructuredReadData chunk;
1740 struct iovec iov[] = {
1741 {.iov_base = &chunk, .iov_len = sizeof(chunk)},
1742 {.iov_base = data, .iov_len = size}
1743 };
1744
1745 assert(size);
1746 trace_nbd_co_send_structured_read(handle, offset, data, size);
1747 set_be_chunk(&chunk.h, final ? NBD_REPLY_FLAG_DONE : 0,
1748 NBD_REPLY_TYPE_OFFSET_DATA, handle,
1749 sizeof(chunk) - sizeof(chunk.h) + size);
1750 stq_be_p(&chunk.offset, offset);
1751
1752 return nbd_co_send_iov(client, iov, 2, errp);
1753}
1754
1755static int coroutine_fn nbd_co_send_structured_error(NBDClient *client,
1756 uint64_t handle,
1757 uint32_t error,
1758 const char *msg,
1759 Error **errp)
1760{
1761 NBDStructuredError chunk;
1762 int nbd_err = system_errno_to_nbd_errno(error);
1763 struct iovec iov[] = {
1764 {.iov_base = &chunk, .iov_len = sizeof(chunk)},
1765 {.iov_base = (char *)msg, .iov_len = msg ? strlen(msg) : 0},
1766 };
1767
1768 assert(nbd_err);
1769 trace_nbd_co_send_structured_error(handle, nbd_err,
1770 nbd_err_lookup(nbd_err), msg ? msg : "");
1771 set_be_chunk(&chunk.h, NBD_REPLY_FLAG_DONE, NBD_REPLY_TYPE_ERROR, handle,
1772 sizeof(chunk) - sizeof(chunk.h) + iov[1].iov_len);
1773 stl_be_p(&chunk.error, nbd_err);
1774 stw_be_p(&chunk.message_length, iov[1].iov_len);
1775
1776 return nbd_co_send_iov(client, iov, 1 + !!iov[1].iov_len, errp);
1777}
1778
1779
1780
1781
1782
1783static int coroutine_fn nbd_co_send_sparse_read(NBDClient *client,
1784 uint64_t handle,
1785 uint64_t offset,
1786 uint8_t *data,
1787 size_t size,
1788 Error **errp)
1789{
1790 int ret = 0;
1791 NBDExport *exp = client->exp;
1792 size_t progress = 0;
1793
1794 while (progress < size) {
1795 int64_t pnum;
1796 int status = bdrv_block_status_above(blk_bs(exp->blk), NULL,
1797 offset + progress,
1798 size - progress, &pnum, NULL,
1799 NULL);
1800 bool final;
1801
1802 if (status < 0) {
1803 char *msg = g_strdup_printf("unable to check for holes: %s",
1804 strerror(-status));
1805
1806 ret = nbd_co_send_structured_error(client, handle, -status, msg,
1807 errp);
1808 g_free(msg);
1809 return ret;
1810 }
1811 assert(pnum && pnum <= size - progress);
1812 final = progress + pnum == size;
1813 if (status & BDRV_BLOCK_ZERO) {
1814 NBDStructuredReadHole chunk;
1815 struct iovec iov[] = {
1816 {.iov_base = &chunk, .iov_len = sizeof(chunk)},
1817 };
1818
1819 trace_nbd_co_send_structured_read_hole(handle, offset + progress,
1820 pnum);
1821 set_be_chunk(&chunk.h, final ? NBD_REPLY_FLAG_DONE : 0,
1822 NBD_REPLY_TYPE_OFFSET_HOLE,
1823 handle, sizeof(chunk) - sizeof(chunk.h));
1824 stq_be_p(&chunk.offset, offset + progress);
1825 stl_be_p(&chunk.length, pnum);
1826 ret = nbd_co_send_iov(client, iov, 1, errp);
1827 } else {
1828 ret = blk_pread(exp->blk, offset + progress + exp->dev_offset,
1829 data + progress, pnum);
1830 if (ret < 0) {
1831 error_setg_errno(errp, -ret, "reading from file failed");
1832 break;
1833 }
1834 ret = nbd_co_send_structured_read(client, handle, offset + progress,
1835 data + progress, pnum, final,
1836 errp);
1837 }
1838
1839 if (ret < 0) {
1840 break;
1841 }
1842 progress += pnum;
1843 }
1844 return ret;
1845}
1846
1847static int blockstatus_to_extent_be(BlockDriverState *bs, uint64_t offset,
1848 uint64_t bytes, NBDExtent *extent)
1849{
1850 uint64_t remaining_bytes = bytes;
1851
1852 while (remaining_bytes) {
1853 uint32_t flags;
1854 int64_t num;
1855 int ret = bdrv_block_status_above(bs, NULL, offset, remaining_bytes,
1856 &num, NULL, NULL);
1857 if (ret < 0) {
1858 return ret;
1859 }
1860
1861 flags = (ret & BDRV_BLOCK_ALLOCATED ? 0 : NBD_STATE_HOLE) |
1862 (ret & BDRV_BLOCK_ZERO ? NBD_STATE_ZERO : 0);
1863
1864 if (remaining_bytes == bytes) {
1865 extent->flags = flags;
1866 }
1867
1868 if (flags != extent->flags) {
1869 break;
1870 }
1871
1872 offset += num;
1873 remaining_bytes -= num;
1874 }
1875
1876 cpu_to_be32s(&extent->flags);
1877 extent->length = cpu_to_be32(bytes - remaining_bytes);
1878
1879 return 0;
1880}
1881
1882
1883
1884
1885
1886
1887
1888
1889static int nbd_co_send_extents(NBDClient *client, uint64_t handle,
1890 NBDExtent *extents, unsigned int nb_extents,
1891 uint64_t length, bool last,
1892 uint32_t context_id, Error **errp)
1893{
1894 NBDStructuredMeta chunk;
1895
1896 struct iovec iov[] = {
1897 {.iov_base = &chunk, .iov_len = sizeof(chunk)},
1898 {.iov_base = extents, .iov_len = nb_extents * sizeof(extents[0])}
1899 };
1900
1901 trace_nbd_co_send_extents(handle, nb_extents, context_id, length, last);
1902 set_be_chunk(&chunk.h, last ? NBD_REPLY_FLAG_DONE : 0,
1903 NBD_REPLY_TYPE_BLOCK_STATUS,
1904 handle, sizeof(chunk) - sizeof(chunk.h) + iov[1].iov_len);
1905 stl_be_p(&chunk.context_id, context_id);
1906
1907 return nbd_co_send_iov(client, iov, 2, errp);
1908}
1909
1910
1911static int nbd_co_send_block_status(NBDClient *client, uint64_t handle,
1912 BlockDriverState *bs, uint64_t offset,
1913 uint32_t length, bool last,
1914 uint32_t context_id, Error **errp)
1915{
1916 int ret;
1917 NBDExtent extent;
1918
1919 ret = blockstatus_to_extent_be(bs, offset, length, &extent);
1920 if (ret < 0) {
1921 return nbd_co_send_structured_error(
1922 client, handle, -ret, "can't get block status", errp);
1923 }
1924
1925 return nbd_co_send_extents(client, handle, &extent, 1,
1926 be32_to_cpu(extent.length), last,
1927 context_id, errp);
1928}
1929
1930
1931
1932
1933
1934
1935
1936static unsigned int bitmap_to_extents(BdrvDirtyBitmap *bitmap, uint64_t offset,
1937 uint64_t *length, NBDExtent *extents,
1938 unsigned int nb_extents,
1939 bool dont_fragment)
1940{
1941 uint64_t begin = offset, end = offset;
1942 uint64_t overall_end = offset + *length;
1943 unsigned int i = 0;
1944 BdrvDirtyBitmapIter *it;
1945 bool dirty;
1946
1947 bdrv_dirty_bitmap_lock(bitmap);
1948
1949 it = bdrv_dirty_iter_new(bitmap);
1950 dirty = bdrv_get_dirty_locked(NULL, bitmap, offset);
1951
1952 assert(begin < overall_end && nb_extents);
1953 while (begin < overall_end && i < nb_extents) {
1954 if (dirty) {
1955 end = bdrv_dirty_bitmap_next_zero(bitmap, begin);
1956 } else {
1957 bdrv_set_dirty_iter(it, begin);
1958 end = bdrv_dirty_iter_next(it);
1959 }
1960 if (end == -1 || end - begin > UINT32_MAX) {
1961
1962 end = MIN(bdrv_dirty_bitmap_size(bitmap),
1963 begin + UINT32_MAX + 1 -
1964 bdrv_dirty_bitmap_granularity(bitmap));
1965 }
1966 if (dont_fragment && end > overall_end) {
1967 end = overall_end;
1968 }
1969
1970 extents[i].length = cpu_to_be32(end - begin);
1971 extents[i].flags = cpu_to_be32(dirty ? NBD_STATE_DIRTY : 0);
1972 i++;
1973 begin = end;
1974 dirty = !dirty;
1975 }
1976
1977 bdrv_dirty_iter_free(it);
1978
1979 bdrv_dirty_bitmap_unlock(bitmap);
1980
1981 assert(offset < end);
1982 *length = end - offset;
1983 return i;
1984}
1985
1986static int nbd_co_send_bitmap(NBDClient *client, uint64_t handle,
1987 BdrvDirtyBitmap *bitmap, uint64_t offset,
1988 uint32_t length, bool dont_fragment, bool last,
1989 uint32_t context_id, Error **errp)
1990{
1991 int ret;
1992 unsigned int nb_extents = dont_fragment ? 1 : NBD_MAX_BITMAP_EXTENTS;
1993 NBDExtent *extents = g_new(NBDExtent, nb_extents);
1994 uint64_t final_length = length;
1995
1996 nb_extents = bitmap_to_extents(bitmap, offset, &final_length, extents,
1997 nb_extents, dont_fragment);
1998
1999 ret = nbd_co_send_extents(client, handle, extents, nb_extents,
2000 final_length, last, context_id, errp);
2001
2002 g_free(extents);
2003
2004 return ret;
2005}
2006
2007
2008
2009
2010
2011
2012
2013static int nbd_co_receive_request(NBDRequestData *req, NBDRequest *request,
2014 Error **errp)
2015{
2016 NBDClient *client = req->client;
2017 int valid_flags;
2018
2019 g_assert(qemu_in_coroutine());
2020 assert(client->recv_coroutine == qemu_coroutine_self());
2021 if (nbd_receive_request(client->ioc, request, errp) < 0) {
2022 return -EIO;
2023 }
2024
2025 trace_nbd_co_receive_request_decode_type(request->handle, request->type,
2026 nbd_cmd_lookup(request->type));
2027
2028 if (request->type != NBD_CMD_WRITE) {
2029
2030 req->complete = true;
2031 }
2032
2033 if (request->type == NBD_CMD_DISC) {
2034
2035
2036 return -EIO;
2037 }
2038
2039 if (request->type == NBD_CMD_READ || request->type == NBD_CMD_WRITE ||
2040 request->type == NBD_CMD_CACHE)
2041 {
2042 if (request->len > NBD_MAX_BUFFER_SIZE) {
2043 error_setg(errp, "len (%" PRIu32" ) is larger than max len (%u)",
2044 request->len, NBD_MAX_BUFFER_SIZE);
2045 return -EINVAL;
2046 }
2047
2048 req->data = blk_try_blockalign(client->exp->blk, request->len);
2049 if (req->data == NULL) {
2050 error_setg(errp, "No memory");
2051 return -ENOMEM;
2052 }
2053 }
2054 if (request->type == NBD_CMD_WRITE) {
2055 if (nbd_read(client->ioc, req->data, request->len, errp) < 0) {
2056 error_prepend(errp, "reading from socket failed: ");
2057 return -EIO;
2058 }
2059 req->complete = true;
2060
2061 trace_nbd_co_receive_request_payload_received(request->handle,
2062 request->len);
2063 }
2064
2065
2066 if (client->exp->nbdflags & NBD_FLAG_READ_ONLY &&
2067 (request->type == NBD_CMD_WRITE ||
2068 request->type == NBD_CMD_WRITE_ZEROES ||
2069 request->type == NBD_CMD_TRIM)) {
2070 error_setg(errp, "Export is read-only");
2071 return -EROFS;
2072 }
2073 if (request->from > client->exp->size ||
2074 request->from + request->len > client->exp->size) {
2075 error_setg(errp, "operation past EOF; From: %" PRIu64 ", Len: %" PRIu32
2076 ", Size: %" PRIu64, request->from, request->len,
2077 (uint64_t)client->exp->size);
2078 return (request->type == NBD_CMD_WRITE ||
2079 request->type == NBD_CMD_WRITE_ZEROES) ? -ENOSPC : -EINVAL;
2080 }
2081 valid_flags = NBD_CMD_FLAG_FUA;
2082 if (request->type == NBD_CMD_READ && client->structured_reply) {
2083 valid_flags |= NBD_CMD_FLAG_DF;
2084 } else if (request->type == NBD_CMD_WRITE_ZEROES) {
2085 valid_flags |= NBD_CMD_FLAG_NO_HOLE;
2086 } else if (request->type == NBD_CMD_BLOCK_STATUS) {
2087 valid_flags |= NBD_CMD_FLAG_REQ_ONE;
2088 }
2089 if (request->flags & ~valid_flags) {
2090 error_setg(errp, "unsupported flags for command %s (got 0x%x)",
2091 nbd_cmd_lookup(request->type), request->flags);
2092 return -EINVAL;
2093 }
2094
2095 return 0;
2096}
2097
2098
2099
2100
2101
2102static coroutine_fn int nbd_send_generic_reply(NBDClient *client,
2103 uint64_t handle,
2104 int ret,
2105 const char *error_msg,
2106 Error **errp)
2107{
2108 if (client->structured_reply && ret < 0) {
2109 return nbd_co_send_structured_error(client, handle, -ret, error_msg,
2110 errp);
2111 } else {
2112 return nbd_co_send_simple_reply(client, handle, ret < 0 ? -ret : 0,
2113 NULL, 0, errp);
2114 }
2115}
2116
2117
2118
2119
2120static coroutine_fn int nbd_do_cmd_read(NBDClient *client, NBDRequest *request,
2121 uint8_t *data, Error **errp)
2122{
2123 int ret;
2124 NBDExport *exp = client->exp;
2125
2126 assert(request->type == NBD_CMD_READ || request->type == NBD_CMD_CACHE);
2127
2128
2129 if (request->flags & NBD_CMD_FLAG_FUA) {
2130 ret = blk_co_flush(exp->blk);
2131 if (ret < 0) {
2132 return nbd_send_generic_reply(client, request->handle, ret,
2133 "flush failed", errp);
2134 }
2135 }
2136
2137 if (client->structured_reply && !(request->flags & NBD_CMD_FLAG_DF) &&
2138 request->len) {
2139 return nbd_co_send_sparse_read(client, request->handle, request->from,
2140 data, request->len, errp);
2141 }
2142
2143 ret = blk_pread(exp->blk, request->from + exp->dev_offset, data,
2144 request->len);
2145 if (ret < 0 || request->type == NBD_CMD_CACHE) {
2146 return nbd_send_generic_reply(client, request->handle, ret,
2147 "reading from file failed", errp);
2148 }
2149
2150 if (client->structured_reply) {
2151 if (request->len) {
2152 return nbd_co_send_structured_read(client, request->handle,
2153 request->from, data,
2154 request->len, true, errp);
2155 } else {
2156 return nbd_co_send_structured_done(client, request->handle, errp);
2157 }
2158 } else {
2159 return nbd_co_send_simple_reply(client, request->handle, 0,
2160 data, request->len, errp);
2161 }
2162}
2163
2164
2165
2166
2167static coroutine_fn int nbd_handle_request(NBDClient *client,
2168 NBDRequest *request,
2169 uint8_t *data, Error **errp)
2170{
2171 int ret;
2172 int flags;
2173 NBDExport *exp = client->exp;
2174 char *msg;
2175
2176 switch (request->type) {
2177 case NBD_CMD_READ:
2178 case NBD_CMD_CACHE:
2179 return nbd_do_cmd_read(client, request, data, errp);
2180
2181 case NBD_CMD_WRITE:
2182 flags = 0;
2183 if (request->flags & NBD_CMD_FLAG_FUA) {
2184 flags |= BDRV_REQ_FUA;
2185 }
2186 ret = blk_pwrite(exp->blk, request->from + exp->dev_offset,
2187 data, request->len, flags);
2188 return nbd_send_generic_reply(client, request->handle, ret,
2189 "writing to file failed", errp);
2190
2191 case NBD_CMD_WRITE_ZEROES:
2192 flags = 0;
2193 if (request->flags & NBD_CMD_FLAG_FUA) {
2194 flags |= BDRV_REQ_FUA;
2195 }
2196 if (!(request->flags & NBD_CMD_FLAG_NO_HOLE)) {
2197 flags |= BDRV_REQ_MAY_UNMAP;
2198 }
2199 ret = blk_pwrite_zeroes(exp->blk, request->from + exp->dev_offset,
2200 request->len, flags);
2201 return nbd_send_generic_reply(client, request->handle, ret,
2202 "writing to file failed", errp);
2203
2204 case NBD_CMD_DISC:
2205
2206 abort();
2207
2208 case NBD_CMD_FLUSH:
2209 ret = blk_co_flush(exp->blk);
2210 return nbd_send_generic_reply(client, request->handle, ret,
2211 "flush failed", errp);
2212
2213 case NBD_CMD_TRIM:
2214 ret = blk_co_pdiscard(exp->blk, request->from + exp->dev_offset,
2215 request->len);
2216 if (ret == 0 && request->flags & NBD_CMD_FLAG_FUA) {
2217 ret = blk_co_flush(exp->blk);
2218 }
2219 return nbd_send_generic_reply(client, request->handle, ret,
2220 "discard failed", errp);
2221
2222 case NBD_CMD_BLOCK_STATUS:
2223 if (!request->len) {
2224 return nbd_send_generic_reply(client, request->handle, -EINVAL,
2225 "need non-zero length", errp);
2226 }
2227 if (client->export_meta.valid &&
2228 (client->export_meta.base_allocation ||
2229 client->export_meta.bitmap))
2230 {
2231 if (client->export_meta.base_allocation) {
2232 ret = nbd_co_send_block_status(client, request->handle,
2233 blk_bs(exp->blk), request->from,
2234 request->len,
2235 !client->export_meta.bitmap,
2236 NBD_META_ID_BASE_ALLOCATION,
2237 errp);
2238 if (ret < 0) {
2239 return ret;
2240 }
2241 }
2242
2243 if (client->export_meta.bitmap) {
2244 ret = nbd_co_send_bitmap(client, request->handle,
2245 client->exp->export_bitmap,
2246 request->from, request->len,
2247 request->flags & NBD_CMD_FLAG_REQ_ONE,
2248 true, NBD_META_ID_DIRTY_BITMAP, errp);
2249 if (ret < 0) {
2250 return ret;
2251 }
2252 }
2253
2254 return ret;
2255 } else {
2256 return nbd_send_generic_reply(client, request->handle, -EINVAL,
2257 "CMD_BLOCK_STATUS not negotiated",
2258 errp);
2259 }
2260
2261 default:
2262 msg = g_strdup_printf("invalid request type (%" PRIu32 ") received",
2263 request->type);
2264 ret = nbd_send_generic_reply(client, request->handle, -EINVAL, msg,
2265 errp);
2266 g_free(msg);
2267 return ret;
2268 }
2269}
2270
2271
2272static coroutine_fn void nbd_trip(void *opaque)
2273{
2274 NBDClient *client = opaque;
2275 NBDRequestData *req;
2276 NBDRequest request = { 0 };
2277 int ret;
2278 Error *local_err = NULL;
2279
2280 trace_nbd_trip();
2281 if (client->closing) {
2282 nbd_client_put(client);
2283 return;
2284 }
2285
2286 req = nbd_request_get(client);
2287 ret = nbd_co_receive_request(req, &request, &local_err);
2288 client->recv_coroutine = NULL;
2289
2290 if (client->closing) {
2291
2292
2293
2294
2295 goto done;
2296 }
2297
2298 nbd_client_receive_next_request(client);
2299 if (ret == -EIO) {
2300 goto disconnect;
2301 }
2302
2303 if (ret < 0) {
2304
2305
2306 Error *export_err = local_err;
2307
2308 local_err = NULL;
2309 ret = nbd_send_generic_reply(client, request.handle, -EINVAL,
2310 error_get_pretty(export_err), &local_err);
2311 error_free(export_err);
2312 } else {
2313 ret = nbd_handle_request(client, &request, req->data, &local_err);
2314 }
2315 if (ret < 0) {
2316 error_prepend(&local_err, "Failed to send reply: ");
2317 goto disconnect;
2318 }
2319
2320
2321
2322
2323 if (!req->complete) {
2324 error_setg(&local_err, "Request handling failed in intermediate state");
2325 goto disconnect;
2326 }
2327
2328done:
2329 nbd_request_put(req);
2330 nbd_client_put(client);
2331 return;
2332
2333disconnect:
2334 if (local_err) {
2335 error_reportf_err(local_err, "Disconnect client, due to: ");
2336 }
2337 nbd_request_put(req);
2338 client_close(client, true);
2339 nbd_client_put(client);
2340}
2341
2342static void nbd_client_receive_next_request(NBDClient *client)
2343{
2344 if (!client->recv_coroutine && client->nb_requests < MAX_NBD_REQUESTS) {
2345 nbd_client_get(client);
2346 client->recv_coroutine = qemu_coroutine_create(nbd_trip, client);
2347 aio_co_schedule(client->exp->ctx, client->recv_coroutine);
2348 }
2349}
2350
2351static coroutine_fn void nbd_co_client_start(void *opaque)
2352{
2353 NBDClient *client = opaque;
2354 NBDExport *exp = client->exp;
2355 Error *local_err = NULL;
2356
2357 if (exp) {
2358 nbd_export_get(exp);
2359 QTAILQ_INSERT_TAIL(&exp->clients, client, next);
2360 }
2361 qemu_co_mutex_init(&client->send_lock);
2362
2363 if (nbd_negotiate(client, &local_err)) {
2364 if (local_err) {
2365 error_report_err(local_err);
2366 }
2367 client_close(client, false);
2368 return;
2369 }
2370
2371 nbd_client_receive_next_request(client);
2372}
2373
2374
2375
2376
2377
2378
2379
2380void nbd_client_new(NBDExport *exp,
2381 QIOChannelSocket *sioc,
2382 QCryptoTLSCreds *tlscreds,
2383 const char *tlsaclname,
2384 void (*close_fn)(NBDClient *, bool))
2385{
2386 NBDClient *client;
2387 Coroutine *co;
2388
2389 client = g_new0(NBDClient, 1);
2390 client->refcount = 1;
2391 client->exp = exp;
2392 client->tlscreds = tlscreds;
2393 if (tlscreds) {
2394 object_ref(OBJECT(client->tlscreds));
2395 }
2396 client->tlsaclname = g_strdup(tlsaclname);
2397 client->sioc = sioc;
2398 object_ref(OBJECT(client->sioc));
2399 client->ioc = QIO_CHANNEL(sioc);
2400 object_ref(OBJECT(client->ioc));
2401 client->close_fn = close_fn;
2402
2403 co = qemu_coroutine_create(nbd_co_client_start, client);
2404 qemu_coroutine_enter(co);
2405}
2406
2407void nbd_export_bitmap(NBDExport *exp, const char *bitmap,
2408 const char *bitmap_export_name, Error **errp)
2409{
2410 BdrvDirtyBitmap *bm = NULL;
2411 BlockDriverState *bs = blk_bs(exp->blk);
2412
2413 if (exp->export_bitmap) {
2414 error_setg(errp, "Export bitmap is already set");
2415 return;
2416 }
2417
2418 while (true) {
2419 bm = bdrv_find_dirty_bitmap(bs, bitmap);
2420 if (bm != NULL || bs->backing == NULL) {
2421 break;
2422 }
2423
2424 bs = bs->backing->bs;
2425 }
2426
2427 if (bm == NULL) {
2428 error_setg(errp, "Bitmap '%s' is not found", bitmap);
2429 return;
2430 }
2431
2432 if (bdrv_dirty_bitmap_enabled(bm)) {
2433 error_setg(errp, "Bitmap '%s' is enabled", bitmap);
2434 return;
2435 }
2436
2437 if (bdrv_dirty_bitmap_qmp_locked(bm)) {
2438 error_setg(errp, "Bitmap '%s' is locked", bitmap);
2439 return;
2440 }
2441
2442 bdrv_dirty_bitmap_set_qmp_locked(bm, true);
2443 exp->export_bitmap = bm;
2444 exp->export_bitmap_context =
2445 g_strdup_printf("qemu:dirty-bitmap:%s", bitmap_export_name);
2446}
2447