kvm: Conditionally apply workaround for KVM slot handling bug
[qemu] / 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, write to the Free Software
17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
18  */
19
20 #include "nbd.h"
21
22 #include <errno.h>
23 #include <string.h>
24 #ifndef _WIN32
25 #include <sys/ioctl.h>
26 #endif
27 #ifdef __sun__
28 #include <sys/ioccom.h>
29 #endif
30 #include <ctype.h>
31 #include <inttypes.h>
32
33 #include "qemu_socket.h"
34
35 //#define DEBUG_NBD
36
37 #ifdef DEBUG_NBD
38 #define TRACE(msg, ...) do { \
39     LOG(msg, ## __VA_ARGS__); \
40 } while(0)
41 #else
42 #define TRACE(msg, ...) \
43     do { } while (0)
44 #endif
45
46 #define LOG(msg, ...) do { \
47     fprintf(stderr, "%s:%s():L%d: " msg "\n", \
48             __FILE__, __FUNCTION__, __LINE__, ## __VA_ARGS__); \
49 } while(0)
50
51 /* This is all part of the "official" NBD API */
52
53 #define NBD_REQUEST_MAGIC       0x25609513
54 #define NBD_REPLY_MAGIC         0x67446698
55
56 #define NBD_SET_SOCK            _IO(0xab, 0)
57 #define NBD_SET_BLKSIZE         _IO(0xab, 1)
58 #define NBD_SET_SIZE            _IO(0xab, 2)
59 #define NBD_DO_IT               _IO(0xab, 3)
60 #define NBD_CLEAR_SOCK          _IO(0xab, 4)
61 #define NBD_CLEAR_QUE           _IO(0xab, 5)
62 #define NBD_PRINT_DEBUG         _IO(0xab, 6)
63 #define NBD_SET_SIZE_BLOCKS     _IO(0xab, 7)
64 #define NBD_DISCONNECT          _IO(0xab, 8)
65
66 /* That's all folks */
67
68 #define read_sync(fd, buffer, size) nbd_wr_sync(fd, buffer, size, true)
69 #define write_sync(fd, buffer, size) nbd_wr_sync(fd, buffer, size, false)
70
71 size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read)
72 {
73     size_t offset = 0;
74
75     while (offset < size) {
76         ssize_t len;
77
78         if (do_read) {
79             len = recv(fd, buffer + offset, size - offset, 0);
80         } else {
81             len = send(fd, buffer + offset, size - offset, 0);
82         }
83
84         if (len == -1)
85             errno = socket_error();
86
87         /* recoverable error */
88         if (len == -1 && (errno == EAGAIN || errno == EINTR)) {
89             continue;
90         }
91
92         /* eof */
93         if (len == 0) {
94             break;
95         }
96
97         /* unrecoverable error */
98         if (len == -1) {
99             return 0;
100         }
101
102         offset += len;
103     }
104
105     return offset;
106 }
107
108 int tcp_socket_outgoing(const char *address, uint16_t port)
109 {
110     int s;
111     struct in_addr in;
112     struct sockaddr_in addr;
113
114     s = socket(PF_INET, SOCK_STREAM, 0);
115     if (s == -1) {
116         return -1;
117     }
118
119     if (inet_aton(address, &in) == 0) {
120         struct hostent *ent;
121
122         ent = gethostbyname(address);
123         if (ent == NULL) {
124             goto error;
125         }
126
127         memcpy(&in, ent->h_addr, sizeof(in));
128     }
129
130     addr.sin_family = AF_INET;
131     addr.sin_port = htons(port);
132     memcpy(&addr.sin_addr.s_addr, &in, sizeof(in));
133
134     if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
135         goto error;
136     }
137
138     return s;
139 error:
140     closesocket(s);
141     return -1;
142 }
143
144 int tcp_socket_incoming(const char *address, uint16_t port)
145 {
146     int s;
147     struct in_addr in;
148     struct sockaddr_in addr;
149     int opt;
150
151     s = socket(PF_INET, SOCK_STREAM, 0);
152     if (s == -1) {
153         return -1;
154     }
155
156     if (inet_aton(address, &in) == 0) {
157         struct hostent *ent;
158
159         ent = gethostbyname(address);
160         if (ent == NULL) {
161             goto error;
162         }
163
164         memcpy(&in, ent->h_addr, sizeof(in));
165     }
166
167     addr.sin_family = AF_INET;
168     addr.sin_port = htons(port);
169     memcpy(&addr.sin_addr.s_addr, &in, sizeof(in));
170
171     opt = 1;
172     if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
173                    (const void *) &opt, sizeof(opt)) == -1) {
174         goto error;
175     }
176
177     if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
178         goto error;
179     }
180
181     if (listen(s, 128) == -1) {
182         goto error;
183     }
184
185     return s;
186 error:
187     closesocket(s);
188     return -1;
189 }
190
191 #ifndef _WIN32
192 int unix_socket_incoming(const char *path)
193 {
194     int s;
195     struct sockaddr_un addr;
196
197     s = socket(PF_UNIX, SOCK_STREAM, 0);
198     if (s == -1) {
199         return -1;
200     }
201
202     memset(&addr, 0, sizeof(addr));
203     addr.sun_family = AF_UNIX;
204     pstrcpy(addr.sun_path, sizeof(addr.sun_path), path);
205
206     if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
207         goto error;
208     }
209
210     if (listen(s, 128) == -1) {
211         goto error;
212     }
213
214     return s;
215 error:
216     closesocket(s);
217     return -1;
218 }
219
220 int unix_socket_outgoing(const char *path)
221 {
222     int s;
223     struct sockaddr_un addr;
224
225     s = socket(PF_UNIX, SOCK_STREAM, 0);
226     if (s == -1) {
227         return -1;
228     }
229
230     memset(&addr, 0, sizeof(addr));
231     addr.sun_family = AF_UNIX;
232     pstrcpy(addr.sun_path, sizeof(addr.sun_path), path);
233
234     if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
235         goto error;
236     }
237
238     return s;
239 error:
240     closesocket(s);
241     return -1;
242 }
243 #else
244 int unix_socket_incoming(const char *path)
245 {
246     errno = ENOTSUP;
247     return -1;
248 }
249
250 int unix_socket_outgoing(const char *path)
251 {
252     errno = ENOTSUP;
253     return -1;
254 }
255 #endif
256
257
258 /* Basic flow
259
260    Server         Client
261
262    Negotiate
263                   Request
264    Response
265                   Request
266    Response
267                   ...
268    ...
269                   Request (type == 2)
270 */
271
272 int nbd_negotiate(int csock, off_t size)
273 {
274         char buf[8 + 8 + 8 + 128];
275
276         /* Negotiate
277            [ 0 ..   7]   passwd   ("NBDMAGIC")
278            [ 8 ..  15]   magic    (0x00420281861253)
279            [16 ..  23]   size
280            [24 .. 151]   reserved (0)
281          */
282
283         TRACE("Beginning negotiation.");
284         memcpy(buf, "NBDMAGIC", 8);
285         cpu_to_be64w((uint64_t*)(buf + 8), 0x00420281861253LL);
286         cpu_to_be64w((uint64_t*)(buf + 16), size);
287         memset(buf + 24, 0, 128);
288
289         if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
290                 LOG("write failed");
291                 errno = EINVAL;
292                 return -1;
293         }
294
295         TRACE("Negotation succeeded.");
296
297         return 0;
298 }
299
300 int nbd_receive_negotiate(int csock, off_t *size, size_t *blocksize)
301 {
302         char buf[8 + 8 + 8 + 128];
303         uint64_t magic;
304
305         TRACE("Receiving negotation.");
306
307         if (read_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
308                 LOG("read failed");
309                 errno = EINVAL;
310                 return -1;
311         }
312
313         magic = be64_to_cpup((uint64_t*)(buf + 8));
314         *size = be64_to_cpup((uint64_t*)(buf + 16));
315         *blocksize = 1024;
316
317         TRACE("Magic is %c%c%c%c%c%c%c%c",
318               qemu_isprint(buf[0]) ? buf[0] : '.',
319               qemu_isprint(buf[1]) ? buf[1] : '.',
320               qemu_isprint(buf[2]) ? buf[2] : '.',
321               qemu_isprint(buf[3]) ? buf[3] : '.',
322               qemu_isprint(buf[4]) ? buf[4] : '.',
323               qemu_isprint(buf[5]) ? buf[5] : '.',
324               qemu_isprint(buf[6]) ? buf[6] : '.',
325               qemu_isprint(buf[7]) ? buf[7] : '.');
326         TRACE("Magic is 0x%" PRIx64, magic);
327         TRACE("Size is %" PRIu64, *size);
328
329         if (memcmp(buf, "NBDMAGIC", 8) != 0) {
330                 LOG("Invalid magic received");
331                 errno = EINVAL;
332                 return -1;
333         }
334
335         TRACE("Checking magic");
336
337         if (magic != 0x00420281861253LL) {
338                 LOG("Bad magic received");
339                 errno = EINVAL;
340                 return -1;
341         }
342         return 0;
343 }
344
345 #ifndef _WIN32
346 int nbd_init(int fd, int csock, off_t size, size_t blocksize)
347 {
348         TRACE("Setting block size to %lu", (unsigned long)blocksize);
349
350         if (ioctl(fd, NBD_SET_BLKSIZE, blocksize) == -1) {
351                 int serrno = errno;
352                 LOG("Failed setting NBD block size");
353                 errno = serrno;
354                 return -1;
355         }
356
357         TRACE("Setting size to %llu block(s)",
358               (unsigned long long)(size / blocksize));
359
360         if (ioctl(fd, NBD_SET_SIZE_BLOCKS, size / blocksize) == -1) {
361                 int serrno = errno;
362                 LOG("Failed setting size (in blocks)");
363                 errno = serrno;
364                 return -1;
365         }
366
367         TRACE("Clearing NBD socket");
368
369         if (ioctl(fd, NBD_CLEAR_SOCK) == -1) {
370                 int serrno = errno;
371                 LOG("Failed clearing NBD socket");
372                 errno = serrno;
373                 return -1;
374         }
375
376         TRACE("Setting NBD socket");
377
378         if (ioctl(fd, NBD_SET_SOCK, csock) == -1) {
379                 int serrno = errno;
380                 LOG("Failed to set NBD socket");
381                 errno = serrno;
382                 return -1;
383         }
384
385         TRACE("Negotiation ended");
386
387         return 0;
388 }
389
390 int nbd_disconnect(int fd)
391 {
392         ioctl(fd, NBD_CLEAR_QUE);
393         ioctl(fd, NBD_DISCONNECT);
394         ioctl(fd, NBD_CLEAR_SOCK);
395         return 0;
396 }
397
398 int nbd_client(int fd, int csock)
399 {
400         int ret;
401         int serrno;
402
403         TRACE("Doing NBD loop");
404
405         ret = ioctl(fd, NBD_DO_IT);
406         serrno = errno;
407
408         TRACE("NBD loop returned %d: %s", ret, strerror(serrno));
409
410         TRACE("Clearing NBD queue");
411         ioctl(fd, NBD_CLEAR_QUE);
412
413         TRACE("Clearing NBD socket");
414         ioctl(fd, NBD_CLEAR_SOCK);
415
416         errno = serrno;
417         return ret;
418 }
419 #else
420 int nbd_init(int fd, int csock, off_t size, size_t blocksize)
421 {
422     errno = ENOTSUP;
423     return -1;
424 }
425
426 int nbd_disconnect(int fd)
427 {
428     errno = ENOTSUP;
429     return -1;
430 }
431
432 int nbd_client(int fd, int csock)
433 {
434     errno = ENOTSUP;
435     return -1;
436 }
437 #endif
438
439 int nbd_send_request(int csock, struct nbd_request *request)
440 {
441         uint8_t buf[4 + 4 + 8 + 8 + 4];
442
443         cpu_to_be32w((uint32_t*)buf, NBD_REQUEST_MAGIC);
444         cpu_to_be32w((uint32_t*)(buf + 4), request->type);
445         cpu_to_be64w((uint64_t*)(buf + 8), request->handle);
446         cpu_to_be64w((uint64_t*)(buf + 16), request->from);
447         cpu_to_be32w((uint32_t*)(buf + 24), request->len);
448
449         TRACE("Sending request to client");
450
451         if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
452                 LOG("writing to socket failed");
453                 errno = EINVAL;
454                 return -1;
455         }
456         return 0;
457 }
458
459
460 static int nbd_receive_request(int csock, struct nbd_request *request)
461 {
462         uint8_t buf[4 + 4 + 8 + 8 + 4];
463         uint32_t magic;
464
465         if (read_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
466                 LOG("read failed");
467                 errno = EINVAL;
468                 return -1;
469         }
470
471         /* Request
472            [ 0 ..  3]   magic   (NBD_REQUEST_MAGIC)
473            [ 4 ..  7]   type    (0 == READ, 1 == WRITE)
474            [ 8 .. 15]   handle
475            [16 .. 23]   from
476            [24 .. 27]   len
477          */
478
479         magic = be32_to_cpup((uint32_t*)buf);
480         request->type  = be32_to_cpup((uint32_t*)(buf + 4));
481         request->handle = be64_to_cpup((uint64_t*)(buf + 8));
482         request->from  = be64_to_cpup((uint64_t*)(buf + 16));
483         request->len   = be32_to_cpup((uint32_t*)(buf + 24));
484
485         TRACE("Got request: "
486               "{ magic = 0x%x, .type = %d, from = %" PRIu64" , len = %u }",
487               magic, request->type, request->from, request->len);
488
489         if (magic != NBD_REQUEST_MAGIC) {
490                 LOG("invalid magic (got 0x%x)", magic);
491                 errno = EINVAL;
492                 return -1;
493         }
494         return 0;
495 }
496
497 int nbd_receive_reply(int csock, struct nbd_reply *reply)
498 {
499         uint8_t buf[4 + 4 + 8];
500         uint32_t magic;
501
502         memset(buf, 0xAA, sizeof(buf));
503
504         if (read_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
505                 LOG("read failed");
506                 errno = EINVAL;
507                 return -1;
508         }
509
510         /* Reply
511            [ 0 ..  3]    magic   (NBD_REPLY_MAGIC)
512            [ 4 ..  7]    error   (0 == no error)
513            [ 7 .. 15]    handle
514          */
515
516         magic = be32_to_cpup((uint32_t*)buf);
517         reply->error  = be32_to_cpup((uint32_t*)(buf + 4));
518         reply->handle = be64_to_cpup((uint64_t*)(buf + 8));
519
520         TRACE("Got reply: "
521               "{ magic = 0x%x, .error = %d, handle = %" PRIu64" }",
522               magic, reply->error, reply->handle);
523
524         if (magic != NBD_REPLY_MAGIC) {
525                 LOG("invalid magic (got 0x%x)", magic);
526                 errno = EINVAL;
527                 return -1;
528         }
529         return 0;
530 }
531
532 static int nbd_send_reply(int csock, struct nbd_reply *reply)
533 {
534         uint8_t buf[4 + 4 + 8];
535
536         /* Reply
537            [ 0 ..  3]    magic   (NBD_REPLY_MAGIC)
538            [ 4 ..  7]    error   (0 == no error)
539            [ 7 .. 15]    handle
540          */
541         cpu_to_be32w((uint32_t*)buf, NBD_REPLY_MAGIC);
542         cpu_to_be32w((uint32_t*)(buf + 4), reply->error);
543         cpu_to_be64w((uint64_t*)(buf + 8), reply->handle);
544
545         TRACE("Sending response to client");
546
547         if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
548                 LOG("writing to socket failed");
549                 errno = EINVAL;
550                 return -1;
551         }
552         return 0;
553 }
554
555 int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
556              off_t *offset, bool readonly, uint8_t *data, int data_size)
557 {
558         struct nbd_request request;
559         struct nbd_reply reply;
560
561         TRACE("Reading request.");
562
563         if (nbd_receive_request(csock, &request) == -1)
564                 return -1;
565
566         if (request.len > data_size) {
567                 LOG("len (%u) is larger than max len (%u)",
568                     request.len, data_size);
569                 errno = EINVAL;
570                 return -1;
571         }
572
573         if ((request.from + request.len) < request.from) {
574                 LOG("integer overflow detected! "
575                     "you're probably being attacked");
576                 errno = EINVAL;
577                 return -1;
578         }
579
580         if ((request.from + request.len) > size) {
581                 LOG("From: %" PRIu64 ", Len: %u, Size: %" PRIu64
582                     ", Offset: %" PRIu64 "\n",
583                     request.from, request.len, (uint64_t)size, dev_offset);
584                 LOG("requested operation past EOF--bad client?");
585                 errno = EINVAL;
586                 return -1;
587         }
588
589         TRACE("Decoding type");
590
591         reply.handle = request.handle;
592         reply.error = 0;
593
594         switch (request.type) {
595         case NBD_CMD_READ:
596                 TRACE("Request type is READ");
597
598                 if (bdrv_read(bs, (request.from + dev_offset) / 512, data,
599                               request.len / 512) == -1) {
600                         LOG("reading from file failed");
601                         errno = EINVAL;
602                         return -1;
603                 }
604                 *offset += request.len;
605
606                 TRACE("Read %u byte(s)", request.len);
607
608                 if (nbd_send_reply(csock, &reply) == -1)
609                         return -1;
610
611                 TRACE("Sending data to client");
612
613                 if (write_sync(csock, data, request.len) != request.len) {
614                         LOG("writing to socket failed");
615                         errno = EINVAL;
616                         return -1;
617                 }
618                 break;
619         case NBD_CMD_WRITE:
620                 TRACE("Request type is WRITE");
621
622                 TRACE("Reading %u byte(s)", request.len);
623
624                 if (read_sync(csock, data, request.len) != request.len) {
625                         LOG("reading from socket failed");
626                         errno = EINVAL;
627                         return -1;
628                 }
629
630                 if (readonly) {
631                         TRACE("Server is read-only, return error");
632                         reply.error = 1;
633                 } else {
634                         TRACE("Writing to device");
635
636                         if (bdrv_write(bs, (request.from + dev_offset) / 512,
637                                        data, request.len / 512) == -1) {
638                                 LOG("writing to file failed");
639                                 errno = EINVAL;
640                                 return -1;
641                         }
642
643                         *offset += request.len;
644                 }
645
646                 if (nbd_send_reply(csock, &reply) == -1)
647                         return -1;
648                 break;
649         case NBD_CMD_DISC:
650                 TRACE("Request type is DISCONNECT");
651                 errno = 0;
652                 return 1;
653         default:
654                 LOG("invalid request type (%u) received", request.type);
655                 errno = EINVAL;
656                 return -1;
657         }
658
659         TRACE("Request/Reply complete");
660
661         return 0;
662 }