]> rtime.felk.cvut.cz Git - lisovros/qemu_apohw.git/blob - nbd.c
Support for Humusoft MF624 data acquisition card.
[lisovros/qemu_apohw.git] / nbd.c
1 /*
2  *  Copyright (C) 2005  Anthony Liguori <anthony@codemonkey.ws>
3  *
4  *  Network Block Device
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; under version 2 of the License.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include "block/nbd.h"
20 #include "block/block.h"
21
22 #include "block/coroutine.h"
23
24 #include <errno.h>
25 #include <string.h>
26 #ifndef _WIN32
27 #include <sys/ioctl.h>
28 #endif
29 #if defined(__sun__) || defined(__HAIKU__)
30 #include <sys/ioccom.h>
31 #endif
32 #include <ctype.h>
33 #include <inttypes.h>
34
35 #ifdef __linux__
36 #include <linux/fs.h>
37 #endif
38
39 #include "qemu/sockets.h"
40 #include "qemu/queue.h"
41 #include "qemu/main-loop.h"
42
43 //#define DEBUG_NBD
44
45 #ifdef DEBUG_NBD
46 #define TRACE(msg, ...) do { \
47     LOG(msg, ## __VA_ARGS__); \
48 } while(0)
49 #else
50 #define TRACE(msg, ...) \
51     do { } while (0)
52 #endif
53
54 #define LOG(msg, ...) do { \
55     fprintf(stderr, "%s:%s():L%d: " msg "\n", \
56             __FILE__, __FUNCTION__, __LINE__, ## __VA_ARGS__); \
57 } while(0)
58
59 /* This is all part of the "official" NBD API.
60  *
61  * The most up-to-date documentation is available at:
62  * https://github.com/yoe/nbd/blob/master/doc/proto.txt
63  */
64
65 #define NBD_REQUEST_SIZE        (4 + 4 + 8 + 8 + 4)
66 #define NBD_REPLY_SIZE          (4 + 4 + 8)
67 #define NBD_REQUEST_MAGIC       0x25609513
68 #define NBD_REPLY_MAGIC         0x67446698
69 #define NBD_OPTS_MAGIC          0x49484156454F5054LL
70 #define NBD_CLIENT_MAGIC        0x0000420281861253LL
71 #define NBD_REP_MAGIC           0x3e889045565a9LL
72
73 #define NBD_SET_SOCK            _IO(0xab, 0)
74 #define NBD_SET_BLKSIZE         _IO(0xab, 1)
75 #define NBD_SET_SIZE            _IO(0xab, 2)
76 #define NBD_DO_IT               _IO(0xab, 3)
77 #define NBD_CLEAR_SOCK          _IO(0xab, 4)
78 #define NBD_CLEAR_QUE           _IO(0xab, 5)
79 #define NBD_PRINT_DEBUG         _IO(0xab, 6)
80 #define NBD_SET_SIZE_BLOCKS     _IO(0xab, 7)
81 #define NBD_DISCONNECT          _IO(0xab, 8)
82 #define NBD_SET_TIMEOUT         _IO(0xab, 9)
83 #define NBD_SET_FLAGS           _IO(0xab, 10)
84
85 #define NBD_OPT_EXPORT_NAME     (1)
86 #define NBD_OPT_ABORT           (2)
87 #define NBD_OPT_LIST            (3)
88
89 /* Definitions for opaque data types */
90
91 typedef struct NBDRequest NBDRequest;
92
93 struct NBDRequest {
94     QSIMPLEQ_ENTRY(NBDRequest) entry;
95     NBDClient *client;
96     uint8_t *data;
97 };
98
99 struct NBDExport {
100     int refcount;
101     void (*close)(NBDExport *exp);
102
103     BlockDriverState *bs;
104     char *name;
105     off_t dev_offset;
106     off_t size;
107     uint32_t nbdflags;
108     QTAILQ_HEAD(, NBDClient) clients;
109     QTAILQ_ENTRY(NBDExport) next;
110 };
111
112 static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
113
114 struct NBDClient {
115     int refcount;
116     void (*close)(NBDClient *client);
117
118     NBDExport *exp;
119     int sock;
120
121     Coroutine *recv_coroutine;
122
123     CoMutex send_lock;
124     Coroutine *send_coroutine;
125
126     QTAILQ_ENTRY(NBDClient) next;
127     int nb_requests;
128     bool closing;
129 };
130
131 /* That's all folks */
132
133 ssize_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read)
134 {
135     size_t offset = 0;
136     int err;
137
138     if (qemu_in_coroutine()) {
139         if (do_read) {
140             return qemu_co_recv(fd, buffer, size);
141         } else {
142             return qemu_co_send(fd, buffer, size);
143         }
144     }
145
146     while (offset < size) {
147         ssize_t len;
148
149         if (do_read) {
150             len = qemu_recv(fd, buffer + offset, size - offset, 0);
151         } else {
152             len = send(fd, buffer + offset, size - offset, 0);
153         }
154
155         if (len < 0) {
156             err = socket_error();
157
158             /* recoverable error */
159             if (err == EINTR || (offset > 0 && err == EAGAIN)) {
160                 continue;
161             }
162
163             /* unrecoverable error */
164             return -err;
165         }
166
167         /* eof */
168         if (len == 0) {
169             break;
170         }
171
172         offset += len;
173     }
174
175     return offset;
176 }
177
178 static ssize_t read_sync(int fd, void *buffer, size_t size)
179 {
180     /* Sockets are kept in blocking mode in the negotiation phase.  After
181      * that, a non-readable socket simply means that another thread stole
182      * our request/reply.  Synchronization is done with recv_coroutine, so
183      * that this is coroutine-safe.
184      */
185     return nbd_wr_sync(fd, buffer, size, true);
186 }
187
188 static ssize_t write_sync(int fd, void *buffer, size_t size)
189 {
190     int ret;
191     do {
192         /* For writes, we do expect the socket to be writable.  */
193         ret = nbd_wr_sync(fd, buffer, size, false);
194     } while (ret == -EAGAIN);
195     return ret;
196 }
197
198 /* Basic flow for negotiation
199
200    Server         Client
201    Negotiate
202
203    or
204
205    Server         Client
206    Negotiate #1
207                   Option
208    Negotiate #2
209
210    ----
211
212    followed by
213
214    Server         Client
215                   Request
216    Response
217                   Request
218    Response
219                   ...
220    ...
221                   Request (type == 2)
222
223 */
224
225 static int nbd_send_rep(int csock, uint32_t type, uint32_t opt)
226 {
227     uint64_t magic;
228     uint32_t len;
229
230     magic = cpu_to_be64(NBD_REP_MAGIC);
231     if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
232         LOG("write failed (rep magic)");
233         return -EINVAL;
234     }
235     opt = cpu_to_be32(opt);
236     if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) {
237         LOG("write failed (rep opt)");
238         return -EINVAL;
239     }
240     type = cpu_to_be32(type);
241     if (write_sync(csock, &type, sizeof(type)) != sizeof(type)) {
242         LOG("write failed (rep type)");
243         return -EINVAL;
244     }
245     len = cpu_to_be32(0);
246     if (write_sync(csock, &len, sizeof(len)) != sizeof(len)) {
247         LOG("write failed (rep data length)");
248         return -EINVAL;
249     }
250     return 0;
251 }
252
253 static int nbd_send_rep_list(int csock, NBDExport *exp)
254 {
255     uint64_t magic, name_len;
256     uint32_t opt, type, len;
257
258     name_len = strlen(exp->name);
259     magic = cpu_to_be64(NBD_REP_MAGIC);
260     if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
261         LOG("write failed (magic)");
262         return -EINVAL;
263      }
264     opt = cpu_to_be32(NBD_OPT_LIST);
265     if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) {
266         LOG("write failed (opt)");
267         return -EINVAL;
268     }
269     type = cpu_to_be32(NBD_REP_SERVER);
270     if (write_sync(csock, &type, sizeof(type)) != sizeof(type)) {
271         LOG("write failed (reply type)");
272         return -EINVAL;
273     }
274     len = cpu_to_be32(name_len + sizeof(len));
275     if (write_sync(csock, &len, sizeof(len)) != sizeof(len)) {
276         LOG("write failed (length)");
277         return -EINVAL;
278     }
279     len = cpu_to_be32(name_len);
280     if (write_sync(csock, &len, sizeof(len)) != sizeof(len)) {
281         LOG("write failed (length)");
282         return -EINVAL;
283     }
284     if (write_sync(csock, exp->name, name_len) != name_len) {
285         LOG("write failed (buffer)");
286         return -EINVAL;
287     }
288     return 0;
289 }
290
291 static int nbd_handle_list(NBDClient *client, uint32_t length)
292 {
293     int csock;
294     NBDExport *exp;
295
296     csock = client->sock;
297     if (length) {
298         return nbd_send_rep(csock, NBD_REP_ERR_INVALID, NBD_OPT_LIST);
299     }
300
301     /* For each export, send a NBD_REP_SERVER reply. */
302     QTAILQ_FOREACH(exp, &exports, next) {
303         if (nbd_send_rep_list(csock, exp)) {
304             return -EINVAL;
305         }
306     }
307     /* Finish with a NBD_REP_ACK. */
308     return nbd_send_rep(csock, NBD_REP_ACK, NBD_OPT_LIST);
309 }
310
311 static int nbd_handle_export_name(NBDClient *client, uint32_t length)
312 {
313     int rc = -EINVAL, csock = client->sock;
314     char name[256];
315
316     /* Client sends:
317         [20 ..  xx]   export name (length bytes)
318      */
319     TRACE("Checking length");
320     if (length > 255) {
321         LOG("Bad length received");
322         goto fail;
323     }
324     if (read_sync(csock, name, length) != length) {
325         LOG("read failed");
326         goto fail;
327     }
328     name[length] = '\0';
329
330     client->exp = nbd_export_find(name);
331     if (!client->exp) {
332         LOG("export not found");
333         goto fail;
334     }
335
336     QTAILQ_INSERT_TAIL(&client->exp->clients, client, next);
337     nbd_export_get(client->exp);
338     rc = 0;
339 fail:
340     return rc;
341 }
342
343 static int nbd_receive_options(NBDClient *client)
344 {
345     while (1) {
346         int csock = client->sock;
347         uint32_t tmp, length;
348         uint64_t magic;
349
350         /* Client sends:
351             [ 0 ..   3]   client flags
352             [ 4 ..  11]   NBD_OPTS_MAGIC
353             [12 ..  15]   NBD option
354             [16 ..  19]   length
355             ...           Rest of request
356         */
357
358         if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
359             LOG("read failed");
360             return -EINVAL;
361         }
362         TRACE("Checking client flags");
363         tmp = be32_to_cpu(tmp);
364         if (tmp != 0 && tmp != NBD_FLAG_C_FIXED_NEWSTYLE) {
365             LOG("Bad client flags received");
366             return -EINVAL;
367         }
368
369         if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
370             LOG("read failed");
371             return -EINVAL;
372         }
373         TRACE("Checking opts magic");
374         if (magic != be64_to_cpu(NBD_OPTS_MAGIC)) {
375             LOG("Bad magic received");
376             return -EINVAL;
377         }
378
379         if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
380             LOG("read failed");
381             return -EINVAL;
382         }
383
384         if (read_sync(csock, &length, sizeof(length)) != sizeof(length)) {
385             LOG("read failed");
386             return -EINVAL;
387         }
388         length = be32_to_cpu(length);
389
390         TRACE("Checking option");
391         switch (be32_to_cpu(tmp)) {
392         case NBD_OPT_LIST:
393             if (nbd_handle_list(client, length) < 0) {
394                 return 1;
395             }
396             break;
397
398         case NBD_OPT_ABORT:
399             return -EINVAL;
400
401         case NBD_OPT_EXPORT_NAME:
402             return nbd_handle_export_name(client, length);
403
404         default:
405             tmp = be32_to_cpu(tmp);
406             LOG("Unsupported option 0x%x", tmp);
407             nbd_send_rep(client->sock, NBD_REP_ERR_UNSUP, tmp);
408             return -EINVAL;
409         }
410     }
411 }
412
413 static int nbd_send_negotiate(NBDClient *client)
414 {
415     int csock = client->sock;
416     char buf[8 + 8 + 8 + 128];
417     int rc;
418     const int myflags = (NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
419                          NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA);
420
421     /* Negotiation header without options:
422         [ 0 ..   7]   passwd       ("NBDMAGIC")
423         [ 8 ..  15]   magic        (NBD_CLIENT_MAGIC)
424         [16 ..  23]   size
425         [24 ..  25]   server flags (0)
426         [26 ..  27]   export flags
427         [28 .. 151]   reserved     (0)
428
429        Negotiation header with options, part 1:
430         [ 0 ..   7]   passwd       ("NBDMAGIC")
431         [ 8 ..  15]   magic        (NBD_OPTS_MAGIC)
432         [16 ..  17]   server flags (0)
433
434        part 2 (after options are sent):
435         [18 ..  25]   size
436         [26 ..  27]   export flags
437         [28 .. 151]   reserved     (0)
438      */
439
440     qemu_set_block(csock);
441     rc = -EINVAL;
442
443     TRACE("Beginning negotiation.");
444     memset(buf, 0, sizeof(buf));
445     memcpy(buf, "NBDMAGIC", 8);
446     if (client->exp) {
447         assert ((client->exp->nbdflags & ~65535) == 0);
448         cpu_to_be64w((uint64_t*)(buf + 8), NBD_CLIENT_MAGIC);
449         cpu_to_be64w((uint64_t*)(buf + 16), client->exp->size);
450         cpu_to_be16w((uint16_t*)(buf + 26), client->exp->nbdflags | myflags);
451     } else {
452         cpu_to_be64w((uint64_t*)(buf + 8), NBD_OPTS_MAGIC);
453         cpu_to_be16w((uint16_t *)(buf + 16), NBD_FLAG_FIXED_NEWSTYLE);
454     }
455
456     if (client->exp) {
457         if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
458             LOG("write failed");
459             goto fail;
460         }
461     } else {
462         if (write_sync(csock, buf, 18) != 18) {
463             LOG("write failed");
464             goto fail;
465         }
466         rc = nbd_receive_options(client);
467         if (rc != 0) {
468             LOG("option negotiation failed");
469             goto fail;
470         }
471
472         assert ((client->exp->nbdflags & ~65535) == 0);
473         cpu_to_be64w((uint64_t*)(buf + 18), client->exp->size);
474         cpu_to_be16w((uint16_t*)(buf + 26), client->exp->nbdflags | myflags);
475         if (write_sync(csock, buf + 18, sizeof(buf) - 18) != sizeof(buf) - 18) {
476             LOG("write failed");
477             goto fail;
478         }
479     }
480
481     TRACE("Negotiation succeeded.");
482     rc = 0;
483 fail:
484     qemu_set_nonblock(csock);
485     return rc;
486 }
487
488 int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags,
489                           off_t *size, size_t *blocksize)
490 {
491     char buf[256];
492     uint64_t magic, s;
493     uint16_t tmp;
494     int rc;
495
496     TRACE("Receiving negotiation.");
497
498     rc = -EINVAL;
499
500     if (read_sync(csock, buf, 8) != 8) {
501         LOG("read failed");
502         goto fail;
503     }
504
505     buf[8] = '\0';
506     if (strlen(buf) == 0) {
507         LOG("server connection closed");
508         goto fail;
509     }
510
511     TRACE("Magic is %c%c%c%c%c%c%c%c",
512           qemu_isprint(buf[0]) ? buf[0] : '.',
513           qemu_isprint(buf[1]) ? buf[1] : '.',
514           qemu_isprint(buf[2]) ? buf[2] : '.',
515           qemu_isprint(buf[3]) ? buf[3] : '.',
516           qemu_isprint(buf[4]) ? buf[4] : '.',
517           qemu_isprint(buf[5]) ? buf[5] : '.',
518           qemu_isprint(buf[6]) ? buf[6] : '.',
519           qemu_isprint(buf[7]) ? buf[7] : '.');
520
521     if (memcmp(buf, "NBDMAGIC", 8) != 0) {
522         LOG("Invalid magic received");
523         goto fail;
524     }
525
526     if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
527         LOG("read failed");
528         goto fail;
529     }
530     magic = be64_to_cpu(magic);
531     TRACE("Magic is 0x%" PRIx64, magic);
532
533     if (name) {
534         uint32_t reserved = 0;
535         uint32_t opt;
536         uint32_t namesize;
537
538         TRACE("Checking magic (opts_magic)");
539         if (magic != NBD_OPTS_MAGIC) {
540             LOG("Bad magic received");
541             goto fail;
542         }
543         if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
544             LOG("flags read failed");
545             goto fail;
546         }
547         *flags = be16_to_cpu(tmp) << 16;
548         /* reserved for future use */
549         if (write_sync(csock, &reserved, sizeof(reserved)) !=
550             sizeof(reserved)) {
551             LOG("write failed (reserved)");
552             goto fail;
553         }
554         /* write the export name */
555         magic = cpu_to_be64(magic);
556         if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
557             LOG("write failed (magic)");
558             goto fail;
559         }
560         opt = cpu_to_be32(NBD_OPT_EXPORT_NAME);
561         if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) {
562             LOG("write failed (opt)");
563             goto fail;
564         }
565         namesize = cpu_to_be32(strlen(name));
566         if (write_sync(csock, &namesize, sizeof(namesize)) !=
567             sizeof(namesize)) {
568             LOG("write failed (namesize)");
569             goto fail;
570         }
571         if (write_sync(csock, (char*)name, strlen(name)) != strlen(name)) {
572             LOG("write failed (name)");
573             goto fail;
574         }
575     } else {
576         TRACE("Checking magic (cli_magic)");
577
578         if (magic != NBD_CLIENT_MAGIC) {
579             LOG("Bad magic received");
580             goto fail;
581         }
582     }
583
584     if (read_sync(csock, &s, sizeof(s)) != sizeof(s)) {
585         LOG("read failed");
586         goto fail;
587     }
588     *size = be64_to_cpu(s);
589     *blocksize = 1024;
590     TRACE("Size is %" PRIu64, *size);
591
592     if (!name) {
593         if (read_sync(csock, flags, sizeof(*flags)) != sizeof(*flags)) {
594             LOG("read failed (flags)");
595             goto fail;
596         }
597         *flags = be32_to_cpup(flags);
598     } else {
599         if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
600             LOG("read failed (tmp)");
601             goto fail;
602         }
603         *flags |= be32_to_cpu(tmp);
604     }
605     if (read_sync(csock, &buf, 124) != 124) {
606         LOG("read failed (buf)");
607         goto fail;
608     }
609     rc = 0;
610
611 fail:
612     return rc;
613 }
614
615 #ifdef __linux__
616 int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize)
617 {
618     TRACE("Setting NBD socket");
619
620     if (ioctl(fd, NBD_SET_SOCK, csock) < 0) {
621         int serrno = errno;
622         LOG("Failed to set NBD socket");
623         return -serrno;
624     }
625
626     TRACE("Setting block size to %lu", (unsigned long)blocksize);
627
628     if (ioctl(fd, NBD_SET_BLKSIZE, blocksize) < 0) {
629         int serrno = errno;
630         LOG("Failed setting NBD block size");
631         return -serrno;
632     }
633
634         TRACE("Setting size to %zd block(s)", (size_t)(size / blocksize));
635
636     if (ioctl(fd, NBD_SET_SIZE_BLOCKS, size / blocksize) < 0) {
637         int serrno = errno;
638         LOG("Failed setting size (in blocks)");
639         return -serrno;
640     }
641
642     if (ioctl(fd, NBD_SET_FLAGS, flags) < 0) {
643         if (errno == ENOTTY) {
644             int read_only = (flags & NBD_FLAG_READ_ONLY) != 0;
645             TRACE("Setting readonly attribute");
646
647             if (ioctl(fd, BLKROSET, (unsigned long) &read_only) < 0) {
648                 int serrno = errno;
649                 LOG("Failed setting read-only attribute");
650                 return -serrno;
651             }
652         } else {
653             int serrno = errno;
654             LOG("Failed setting flags");
655             return -serrno;
656         }
657     }
658
659     TRACE("Negotiation ended");
660
661     return 0;
662 }
663
664 int nbd_disconnect(int fd)
665 {
666     ioctl(fd, NBD_CLEAR_QUE);
667     ioctl(fd, NBD_DISCONNECT);
668     ioctl(fd, NBD_CLEAR_SOCK);
669     return 0;
670 }
671
672 int nbd_client(int fd)
673 {
674     int ret;
675     int serrno;
676
677     TRACE("Doing NBD loop");
678
679     ret = ioctl(fd, NBD_DO_IT);
680     if (ret < 0 && errno == EPIPE) {
681         /* NBD_DO_IT normally returns EPIPE when someone has disconnected
682          * the socket via NBD_DISCONNECT.  We do not want to return 1 in
683          * that case.
684          */
685         ret = 0;
686     }
687     serrno = errno;
688
689     TRACE("NBD loop returned %d: %s", ret, strerror(serrno));
690
691     TRACE("Clearing NBD queue");
692     ioctl(fd, NBD_CLEAR_QUE);
693
694     TRACE("Clearing NBD socket");
695     ioctl(fd, NBD_CLEAR_SOCK);
696
697     errno = serrno;
698     return ret;
699 }
700 #else
701 int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize)
702 {
703     return -ENOTSUP;
704 }
705
706 int nbd_disconnect(int fd)
707 {
708     return -ENOTSUP;
709 }
710
711 int nbd_client(int fd)
712 {
713     return -ENOTSUP;
714 }
715 #endif
716
717 ssize_t nbd_send_request(int csock, struct nbd_request *request)
718 {
719     uint8_t buf[NBD_REQUEST_SIZE];
720     ssize_t ret;
721
722     cpu_to_be32w((uint32_t*)buf, NBD_REQUEST_MAGIC);
723     cpu_to_be32w((uint32_t*)(buf + 4), request->type);
724     cpu_to_be64w((uint64_t*)(buf + 8), request->handle);
725     cpu_to_be64w((uint64_t*)(buf + 16), request->from);
726     cpu_to_be32w((uint32_t*)(buf + 24), request->len);
727
728     TRACE("Sending request to client: "
729           "{ .from = %" PRIu64", .len = %u, .handle = %" PRIu64", .type=%i}",
730           request->from, request->len, request->handle, request->type);
731
732     ret = write_sync(csock, buf, sizeof(buf));
733     if (ret < 0) {
734         return ret;
735     }
736
737     if (ret != sizeof(buf)) {
738         LOG("writing to socket failed");
739         return -EINVAL;
740     }
741     return 0;
742 }
743
744 static ssize_t nbd_receive_request(int csock, struct nbd_request *request)
745 {
746     uint8_t buf[NBD_REQUEST_SIZE];
747     uint32_t magic;
748     ssize_t ret;
749
750     ret = read_sync(csock, buf, sizeof(buf));
751     if (ret < 0) {
752         return ret;
753     }
754
755     if (ret != sizeof(buf)) {
756         LOG("read failed");
757         return -EINVAL;
758     }
759
760     /* Request
761        [ 0 ..  3]   magic   (NBD_REQUEST_MAGIC)
762        [ 4 ..  7]   type    (0 == READ, 1 == WRITE)
763        [ 8 .. 15]   handle
764        [16 .. 23]   from
765        [24 .. 27]   len
766      */
767
768     magic = be32_to_cpup((uint32_t*)buf);
769     request->type  = be32_to_cpup((uint32_t*)(buf + 4));
770     request->handle = be64_to_cpup((uint64_t*)(buf + 8));
771     request->from  = be64_to_cpup((uint64_t*)(buf + 16));
772     request->len   = be32_to_cpup((uint32_t*)(buf + 24));
773
774     TRACE("Got request: "
775           "{ magic = 0x%x, .type = %d, from = %" PRIu64" , len = %u }",
776           magic, request->type, request->from, request->len);
777
778     if (magic != NBD_REQUEST_MAGIC) {
779         LOG("invalid magic (got 0x%x)", magic);
780         return -EINVAL;
781     }
782     return 0;
783 }
784
785 ssize_t nbd_receive_reply(int csock, struct nbd_reply *reply)
786 {
787     uint8_t buf[NBD_REPLY_SIZE];
788     uint32_t magic;
789     ssize_t ret;
790
791     ret = read_sync(csock, buf, sizeof(buf));
792     if (ret < 0) {
793         return ret;
794     }
795
796     if (ret != sizeof(buf)) {
797         LOG("read failed");
798         return -EINVAL;
799     }
800
801     /* Reply
802        [ 0 ..  3]    magic   (NBD_REPLY_MAGIC)
803        [ 4 ..  7]    error   (0 == no error)
804        [ 7 .. 15]    handle
805      */
806
807     magic = be32_to_cpup((uint32_t*)buf);
808     reply->error  = be32_to_cpup((uint32_t*)(buf + 4));
809     reply->handle = be64_to_cpup((uint64_t*)(buf + 8));
810
811     TRACE("Got reply: "
812           "{ magic = 0x%x, .error = %d, handle = %" PRIu64" }",
813           magic, reply->error, reply->handle);
814
815     if (magic != NBD_REPLY_MAGIC) {
816         LOG("invalid magic (got 0x%x)", magic);
817         return -EINVAL;
818     }
819     return 0;
820 }
821
822 static ssize_t nbd_send_reply(int csock, struct nbd_reply *reply)
823 {
824     uint8_t buf[NBD_REPLY_SIZE];
825     ssize_t ret;
826
827     /* Reply
828        [ 0 ..  3]    magic   (NBD_REPLY_MAGIC)
829        [ 4 ..  7]    error   (0 == no error)
830        [ 7 .. 15]    handle
831      */
832     cpu_to_be32w((uint32_t*)buf, NBD_REPLY_MAGIC);
833     cpu_to_be32w((uint32_t*)(buf + 4), reply->error);
834     cpu_to_be64w((uint64_t*)(buf + 8), reply->handle);
835
836     TRACE("Sending response to client");
837
838     ret = write_sync(csock, buf, sizeof(buf));
839     if (ret < 0) {
840         return ret;
841     }
842
843     if (ret != sizeof(buf)) {
844         LOG("writing to socket failed");
845         return -EINVAL;
846     }
847     return 0;
848 }
849
850 #define MAX_NBD_REQUESTS 16
851
852 void nbd_client_get(NBDClient *client)
853 {
854     client->refcount++;
855 }
856
857 void nbd_client_put(NBDClient *client)
858 {
859     if (--client->refcount == 0) {
860         /* The last reference should be dropped by client->close,
861          * which is called by nbd_client_close.
862          */
863         assert(client->closing);
864
865         qemu_set_fd_handler2(client->sock, NULL, NULL, NULL, NULL);
866         close(client->sock);
867         client->sock = -1;
868         if (client->exp) {
869             QTAILQ_REMOVE(&client->exp->clients, client, next);
870             nbd_export_put(client->exp);
871         }
872         g_free(client);
873     }
874 }
875
876 void nbd_client_close(NBDClient *client)
877 {
878     if (client->closing) {
879         return;
880     }
881
882     client->closing = true;
883
884     /* Force requests to finish.  They will drop their own references,
885      * then we'll close the socket and free the NBDClient.
886      */
887     shutdown(client->sock, 2);
888
889     /* Also tell the client, so that they release their reference.  */
890     if (client->close) {
891         client->close(client);
892     }
893 }
894
895 static NBDRequest *nbd_request_get(NBDClient *client)
896 {
897     NBDRequest *req;
898
899     assert(client->nb_requests <= MAX_NBD_REQUESTS - 1);
900     client->nb_requests++;
901
902     req = g_slice_new0(NBDRequest);
903     nbd_client_get(client);
904     req->client = client;
905     return req;
906 }
907
908 static void nbd_request_put(NBDRequest *req)
909 {
910     NBDClient *client = req->client;
911
912     if (req->data) {
913         qemu_vfree(req->data);
914     }
915     g_slice_free(NBDRequest, req);
916
917     if (client->nb_requests-- == MAX_NBD_REQUESTS) {
918         qemu_notify_event();
919     }
920     nbd_client_put(client);
921 }
922
923 NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
924                           off_t size, uint32_t nbdflags,
925                           void (*close)(NBDExport *))
926 {
927     NBDExport *exp = g_malloc0(sizeof(NBDExport));
928     exp->refcount = 1;
929     QTAILQ_INIT(&exp->clients);
930     exp->bs = bs;
931     exp->dev_offset = dev_offset;
932     exp->nbdflags = nbdflags;
933     exp->size = size == -1 ? bdrv_getlength(bs) : size;
934     exp->close = close;
935     bdrv_ref(bs);
936     return exp;
937 }
938
939 NBDExport *nbd_export_find(const char *name)
940 {
941     NBDExport *exp;
942     QTAILQ_FOREACH(exp, &exports, next) {
943         if (strcmp(name, exp->name) == 0) {
944             return exp;
945         }
946     }
947
948     return NULL;
949 }
950
951 void nbd_export_set_name(NBDExport *exp, const char *name)
952 {
953     if (exp->name == name) {
954         return;
955     }
956
957     nbd_export_get(exp);
958     if (exp->name != NULL) {
959         g_free(exp->name);
960         exp->name = NULL;
961         QTAILQ_REMOVE(&exports, exp, next);
962         nbd_export_put(exp);
963     }
964     if (name != NULL) {
965         nbd_export_get(exp);
966         exp->name = g_strdup(name);
967         QTAILQ_INSERT_TAIL(&exports, exp, next);
968     }
969     nbd_export_put(exp);
970 }
971
972 void nbd_export_close(NBDExport *exp)
973 {
974     NBDClient *client, *next;
975
976     nbd_export_get(exp);
977     QTAILQ_FOREACH_SAFE(client, &exp->clients, next, next) {
978         nbd_client_close(client);
979     }
980     nbd_export_set_name(exp, NULL);
981     nbd_export_put(exp);
982     if (exp->bs) {
983         bdrv_unref(exp->bs);
984         exp->bs = NULL;
985     }
986 }
987
988 void nbd_export_get(NBDExport *exp)
989 {
990     assert(exp->refcount > 0);
991     exp->refcount++;
992 }
993
994 void nbd_export_put(NBDExport *exp)
995 {
996     assert(exp->refcount > 0);
997     if (exp->refcount == 1) {
998         nbd_export_close(exp);
999     }
1000
1001     if (--exp->refcount == 0) {
1002         assert(exp->name == NULL);
1003
1004         if (exp->close) {
1005             exp->close(exp);
1006         }
1007
1008         g_free(exp);
1009     }
1010 }
1011
1012 BlockDriverState *nbd_export_get_blockdev(NBDExport *exp)
1013 {
1014     return exp->bs;
1015 }
1016
1017 void nbd_export_close_all(void)
1018 {
1019     NBDExport *exp, *next;
1020
1021     QTAILQ_FOREACH_SAFE(exp, &exports, next, next) {
1022         nbd_export_close(exp);
1023     }
1024 }
1025
1026 static int nbd_can_read(void *opaque);
1027 static void nbd_read(void *opaque);
1028 static void nbd_restart_write(void *opaque);
1029
1030 static ssize_t nbd_co_send_reply(NBDRequest *req, struct nbd_reply *reply,
1031                                  int len)
1032 {
1033     NBDClient *client = req->client;
1034     int csock = client->sock;
1035     ssize_t rc, ret;
1036
1037     qemu_co_mutex_lock(&client->send_lock);
1038     qemu_set_fd_handler2(csock, nbd_can_read, nbd_read,
1039                          nbd_restart_write, client);
1040     client->send_coroutine = qemu_coroutine_self();
1041
1042     if (!len) {
1043         rc = nbd_send_reply(csock, reply);
1044     } else {
1045         socket_set_cork(csock, 1);
1046         rc = nbd_send_reply(csock, reply);
1047         if (rc >= 0) {
1048             ret = qemu_co_send(csock, req->data, len);
1049             if (ret != len) {
1050                 rc = -EIO;
1051             }
1052         }
1053         socket_set_cork(csock, 0);
1054     }
1055
1056     client->send_coroutine = NULL;
1057     qemu_set_fd_handler2(csock, nbd_can_read, nbd_read, NULL, client);
1058     qemu_co_mutex_unlock(&client->send_lock);
1059     return rc;
1060 }
1061
1062 static ssize_t nbd_co_receive_request(NBDRequest *req, struct nbd_request *request)
1063 {
1064     NBDClient *client = req->client;
1065     int csock = client->sock;
1066     uint32_t command;
1067     ssize_t rc;
1068
1069     client->recv_coroutine = qemu_coroutine_self();
1070     rc = nbd_receive_request(csock, request);
1071     if (rc < 0) {
1072         if (rc != -EAGAIN) {
1073             rc = -EIO;
1074         }
1075         goto out;
1076     }
1077
1078     if (request->len > NBD_MAX_BUFFER_SIZE) {
1079         LOG("len (%u) is larger than max len (%u)",
1080             request->len, NBD_MAX_BUFFER_SIZE);
1081         rc = -EINVAL;
1082         goto out;
1083     }
1084
1085     if ((request->from + request->len) < request->from) {
1086         LOG("integer overflow detected! "
1087             "you're probably being attacked");
1088         rc = -EINVAL;
1089         goto out;
1090     }
1091
1092     TRACE("Decoding type");
1093
1094     command = request->type & NBD_CMD_MASK_COMMAND;
1095     if (command == NBD_CMD_READ || command == NBD_CMD_WRITE) {
1096         req->data = qemu_blockalign(client->exp->bs, request->len);
1097     }
1098     if (command == NBD_CMD_WRITE) {
1099         TRACE("Reading %u byte(s)", request->len);
1100
1101         if (qemu_co_recv(csock, req->data, request->len) != request->len) {
1102             LOG("reading from socket failed");
1103             rc = -EIO;
1104             goto out;
1105         }
1106     }
1107     rc = 0;
1108
1109 out:
1110     client->recv_coroutine = NULL;
1111     return rc;
1112 }
1113
1114 static void nbd_trip(void *opaque)
1115 {
1116     NBDClient *client = opaque;
1117     NBDExport *exp = client->exp;
1118     NBDRequest *req;
1119     struct nbd_request request;
1120     struct nbd_reply reply;
1121     ssize_t ret;
1122     uint32_t command;
1123
1124     TRACE("Reading request.");
1125     if (client->closing) {
1126         return;
1127     }
1128
1129     req = nbd_request_get(client);
1130     ret = nbd_co_receive_request(req, &request);
1131     if (ret == -EAGAIN) {
1132         goto done;
1133     }
1134     if (ret == -EIO) {
1135         goto out;
1136     }
1137
1138     reply.handle = request.handle;
1139     reply.error = 0;
1140
1141     if (ret < 0) {
1142         reply.error = -ret;
1143         goto error_reply;
1144     }
1145     command = request.type & NBD_CMD_MASK_COMMAND;
1146     if (command != NBD_CMD_DISC && (request.from + request.len) > exp->size) {
1147             LOG("From: %" PRIu64 ", Len: %u, Size: %" PRIu64
1148             ", Offset: %" PRIu64 "\n",
1149                     request.from, request.len,
1150                     (uint64_t)exp->size, (uint64_t)exp->dev_offset);
1151         LOG("requested operation past EOF--bad client?");
1152         goto invalid_request;
1153     }
1154
1155     switch (command) {
1156     case NBD_CMD_READ:
1157         TRACE("Request type is READ");
1158
1159         if (request.type & NBD_CMD_FLAG_FUA) {
1160             ret = bdrv_co_flush(exp->bs);
1161             if (ret < 0) {
1162                 LOG("flush failed");
1163                 reply.error = -ret;
1164                 goto error_reply;
1165             }
1166         }
1167
1168         ret = bdrv_read(exp->bs, (request.from + exp->dev_offset) / 512,
1169                         req->data, request.len / 512);
1170         if (ret < 0) {
1171             LOG("reading from file failed");
1172             reply.error = -ret;
1173             goto error_reply;
1174         }
1175
1176         TRACE("Read %u byte(s)", request.len);
1177         if (nbd_co_send_reply(req, &reply, request.len) < 0)
1178             goto out;
1179         break;
1180     case NBD_CMD_WRITE:
1181         TRACE("Request type is WRITE");
1182
1183         if (exp->nbdflags & NBD_FLAG_READ_ONLY) {
1184             TRACE("Server is read-only, return error");
1185             reply.error = EROFS;
1186             goto error_reply;
1187         }
1188
1189         TRACE("Writing to device");
1190
1191         ret = bdrv_write(exp->bs, (request.from + exp->dev_offset) / 512,
1192                          req->data, request.len / 512);
1193         if (ret < 0) {
1194             LOG("writing to file failed");
1195             reply.error = -ret;
1196             goto error_reply;
1197         }
1198
1199         if (request.type & NBD_CMD_FLAG_FUA) {
1200             ret = bdrv_co_flush(exp->bs);
1201             if (ret < 0) {
1202                 LOG("flush failed");
1203                 reply.error = -ret;
1204                 goto error_reply;
1205             }
1206         }
1207
1208         if (nbd_co_send_reply(req, &reply, 0) < 0) {
1209             goto out;
1210         }
1211         break;
1212     case NBD_CMD_DISC:
1213         TRACE("Request type is DISCONNECT");
1214         errno = 0;
1215         goto out;
1216     case NBD_CMD_FLUSH:
1217         TRACE("Request type is FLUSH");
1218
1219         ret = bdrv_co_flush(exp->bs);
1220         if (ret < 0) {
1221             LOG("flush failed");
1222             reply.error = -ret;
1223         }
1224         if (nbd_co_send_reply(req, &reply, 0) < 0) {
1225             goto out;
1226         }
1227         break;
1228     case NBD_CMD_TRIM:
1229         TRACE("Request type is TRIM");
1230         ret = bdrv_co_discard(exp->bs, (request.from + exp->dev_offset) / 512,
1231                               request.len / 512);
1232         if (ret < 0) {
1233             LOG("discard failed");
1234             reply.error = -ret;
1235         }
1236         if (nbd_co_send_reply(req, &reply, 0) < 0) {
1237             goto out;
1238         }
1239         break;
1240     default:
1241         LOG("invalid request type (%u) received", request.type);
1242     invalid_request:
1243         reply.error = -EINVAL;
1244     error_reply:
1245         if (nbd_co_send_reply(req, &reply, 0) < 0) {
1246             goto out;
1247         }
1248         break;
1249     }
1250
1251     TRACE("Request/Reply complete");
1252
1253 done:
1254     nbd_request_put(req);
1255     return;
1256
1257 out:
1258     nbd_request_put(req);
1259     nbd_client_close(client);
1260 }
1261
1262 static int nbd_can_read(void *opaque)
1263 {
1264     NBDClient *client = opaque;
1265
1266     return client->recv_coroutine || client->nb_requests < MAX_NBD_REQUESTS;
1267 }
1268
1269 static void nbd_read(void *opaque)
1270 {
1271     NBDClient *client = opaque;
1272
1273     if (client->recv_coroutine) {
1274         qemu_coroutine_enter(client->recv_coroutine, NULL);
1275     } else {
1276         qemu_coroutine_enter(qemu_coroutine_create(nbd_trip), client);
1277     }
1278 }
1279
1280 static void nbd_restart_write(void *opaque)
1281 {
1282     NBDClient *client = opaque;
1283
1284     qemu_coroutine_enter(client->send_coroutine, NULL);
1285 }
1286
1287 NBDClient *nbd_client_new(NBDExport *exp, int csock,
1288                           void (*close)(NBDClient *))
1289 {
1290     NBDClient *client;
1291     client = g_malloc0(sizeof(NBDClient));
1292     client->refcount = 1;
1293     client->exp = exp;
1294     client->sock = csock;
1295     if (nbd_send_negotiate(client)) {
1296         g_free(client);
1297         return NULL;
1298     }
1299     client->close = close;
1300     qemu_co_mutex_init(&client->send_lock);
1301     qemu_set_fd_handler2(csock, nbd_can_read, nbd_read, NULL, client);
1302
1303     if (exp) {
1304         QTAILQ_INSERT_TAIL(&exp->clients, client, next);
1305         nbd_export_get(exp);
1306     }
1307     return client;
1308 }