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