qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

nbd: Split nbd.c

We have NBD server code and client code, all mixed in a file. Now split
them into separate files under nbd/, and update MAINTAINERS.

filter_nbd for iotest 083 is updated to keep the log filtered out.

Signed-off-by: Fam Zheng <famz@redhat.com>
Message-Id: <1452760863-25350-3-git-send-email-famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

authored by

Fam Zheng and committed by
Paolo Bonzini
798bfe00 ee7d7aab

+547 -453
+3 -2
MAINTAINERS
··· 1116 1116 Network Block Device (NBD) 1117 1117 M: Paolo Bonzini <pbonzini@redhat.com> 1118 1118 S: Odd Fixes 1119 - F: block/nbd.c 1120 - F: nbd.* 1119 + F: block/nbd* 1120 + F: nbd/ 1121 + F: include/block/nbd* 1121 1122 F: qemu-nbd.c 1122 1123 T: git git://github.com/bonzini/qemu.git nbd-next 1123 1124
+2 -1
Makefile.objs
··· 8 8 # block-obj-y is code used by both qemu system emulation and qemu-img 9 9 10 10 block-obj-y = async.o thread-pool.o 11 - block-obj-y += nbd.o block.o blockjob.o 11 + block-obj-y += nbd/ 12 + block-obj-y += block.o blockjob.o 12 13 block-obj-y += main-loop.o iohandler.o qemu-timer.o 13 14 block-obj-$(CONFIG_POSIX) += aio-posix.o 14 15 block-obj-$(CONFIG_WIN32) += aio-win32.o
+2 -449
nbd.c nbd/server.c
··· 1 1 /* 2 2 * Copyright (C) 2005 Anthony Liguori <anthony@codemonkey.ws> 3 3 * 4 - * Network Block Device 4 + * Network Block Device Server Side 5 5 * 6 6 * This program is free software; you can redistribute it and/or modify 7 7 * it under the terms of the GNU General Public License as published by ··· 16 16 * along with this program; if not, see <http://www.gnu.org/licenses/>. 17 17 */ 18 18 19 - #include "block/nbd.h" 20 - #include "sysemu/block-backend.h" 21 - 22 - #include "qemu/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 - /* NBD errors are based on errno numbers, so there is a 1:1 mapping, 90 - * but only a limited set of errno values is specified in the protocol. 91 - * Everything else is squashed to EINVAL. 92 - */ 93 - #define NBD_SUCCESS 0 94 - #define NBD_EPERM 1 95 - #define NBD_EIO 5 96 - #define NBD_ENOMEM 12 97 - #define NBD_EINVAL 22 98 - #define NBD_ENOSPC 28 19 + #include "nbd-internal.h" 99 20 100 21 static int system_errno_to_nbd_errno(int err) 101 22 { ··· 120 41 } 121 42 } 122 43 123 - static int nbd_errno_to_system_errno(int err) 124 - { 125 - switch (err) { 126 - case NBD_SUCCESS: 127 - return 0; 128 - case NBD_EPERM: 129 - return EPERM; 130 - case NBD_EIO: 131 - return EIO; 132 - case NBD_ENOMEM: 133 - return ENOMEM; 134 - case NBD_ENOSPC: 135 - return ENOSPC; 136 - case NBD_EINVAL: 137 - default: 138 - return EINVAL; 139 - } 140 - } 141 - 142 44 /* Definitions for opaque data types */ 143 45 144 46 typedef struct NBDRequest NBDRequest; ··· 191 93 static void nbd_unset_handlers(NBDClient *client); 192 94 static void nbd_update_can_read(NBDClient *client); 193 95 194 - ssize_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read) 195 - { 196 - size_t offset = 0; 197 - int err; 198 - 199 - if (qemu_in_coroutine()) { 200 - if (do_read) { 201 - return qemu_co_recv(fd, buffer, size); 202 - } else { 203 - return qemu_co_send(fd, buffer, size); 204 - } 205 - } 206 - 207 - while (offset < size) { 208 - ssize_t len; 209 - 210 - if (do_read) { 211 - len = qemu_recv(fd, buffer + offset, size - offset, 0); 212 - } else { 213 - len = send(fd, buffer + offset, size - offset, 0); 214 - } 215 - 216 - if (len < 0) { 217 - err = socket_error(); 218 - 219 - /* recoverable error */ 220 - if (err == EINTR || (offset > 0 && (err == EAGAIN || err == EWOULDBLOCK))) { 221 - continue; 222 - } 223 - 224 - /* unrecoverable error */ 225 - return -err; 226 - } 227 - 228 - /* eof */ 229 - if (len == 0) { 230 - break; 231 - } 232 - 233 - offset += len; 234 - } 235 - 236 - return offset; 237 - } 238 - 239 - static ssize_t read_sync(int fd, void *buffer, size_t size) 240 - { 241 - /* Sockets are kept in blocking mode in the negotiation phase. After 242 - * that, a non-readable socket simply means that another thread stole 243 - * our request/reply. Synchronization is done with recv_coroutine, so 244 - * that this is coroutine-safe. 245 - */ 246 - return nbd_wr_sync(fd, buffer, size, true); 247 - } 248 - 249 96 static ssize_t drop_sync(int fd, size_t size) 250 97 { 251 98 ssize_t ret, dropped = size; ··· 264 111 265 112 g_free(buffer); 266 113 return dropped; 267 - } 268 - 269 - static ssize_t write_sync(int fd, void *buffer, size_t size) 270 - { 271 - int ret; 272 - do { 273 - /* For writes, we do expect the socket to be writable. */ 274 - ret = nbd_wr_sync(fd, buffer, size, false); 275 - } while (ret == -EAGAIN); 276 - return ret; 277 114 } 278 115 279 116 /* Basic flow for negotiation ··· 579 416 return rc; 580 417 } 581 418 582 - int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags, 583 - off_t *size, Error **errp) 584 - { 585 - char buf[256]; 586 - uint64_t magic, s; 587 - uint16_t tmp; 588 - int rc; 589 - 590 - TRACE("Receiving negotiation."); 591 - 592 - rc = -EINVAL; 593 - 594 - if (read_sync(csock, buf, 8) != 8) { 595 - error_setg(errp, "Failed to read data"); 596 - goto fail; 597 - } 598 - 599 - buf[8] = '\0'; 600 - if (strlen(buf) == 0) { 601 - error_setg(errp, "Server connection closed unexpectedly"); 602 - goto fail; 603 - } 604 - 605 - TRACE("Magic is %c%c%c%c%c%c%c%c", 606 - qemu_isprint(buf[0]) ? buf[0] : '.', 607 - qemu_isprint(buf[1]) ? buf[1] : '.', 608 - qemu_isprint(buf[2]) ? buf[2] : '.', 609 - qemu_isprint(buf[3]) ? buf[3] : '.', 610 - qemu_isprint(buf[4]) ? buf[4] : '.', 611 - qemu_isprint(buf[5]) ? buf[5] : '.', 612 - qemu_isprint(buf[6]) ? buf[6] : '.', 613 - qemu_isprint(buf[7]) ? buf[7] : '.'); 614 - 615 - if (memcmp(buf, "NBDMAGIC", 8) != 0) { 616 - error_setg(errp, "Invalid magic received"); 617 - goto fail; 618 - } 619 - 620 - if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) { 621 - error_setg(errp, "Failed to read magic"); 622 - goto fail; 623 - } 624 - magic = be64_to_cpu(magic); 625 - TRACE("Magic is 0x%" PRIx64, magic); 626 - 627 - if (name) { 628 - uint32_t reserved = 0; 629 - uint32_t opt; 630 - uint32_t namesize; 631 - 632 - TRACE("Checking magic (opts_magic)"); 633 - if (magic != NBD_OPTS_MAGIC) { 634 - if (magic == NBD_CLIENT_MAGIC) { 635 - error_setg(errp, "Server does not support export names"); 636 - } else { 637 - error_setg(errp, "Bad magic received"); 638 - } 639 - goto fail; 640 - } 641 - if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) { 642 - error_setg(errp, "Failed to read server flags"); 643 - goto fail; 644 - } 645 - *flags = be16_to_cpu(tmp) << 16; 646 - /* reserved for future use */ 647 - if (write_sync(csock, &reserved, sizeof(reserved)) != 648 - sizeof(reserved)) { 649 - error_setg(errp, "Failed to read reserved field"); 650 - goto fail; 651 - } 652 - /* write the export name */ 653 - magic = cpu_to_be64(magic); 654 - if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) { 655 - error_setg(errp, "Failed to send export name magic"); 656 - goto fail; 657 - } 658 - opt = cpu_to_be32(NBD_OPT_EXPORT_NAME); 659 - if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) { 660 - error_setg(errp, "Failed to send export name option number"); 661 - goto fail; 662 - } 663 - namesize = cpu_to_be32(strlen(name)); 664 - if (write_sync(csock, &namesize, sizeof(namesize)) != 665 - sizeof(namesize)) { 666 - error_setg(errp, "Failed to send export name length"); 667 - goto fail; 668 - } 669 - if (write_sync(csock, (char*)name, strlen(name)) != strlen(name)) { 670 - error_setg(errp, "Failed to send export name"); 671 - goto fail; 672 - } 673 - } else { 674 - TRACE("Checking magic (cli_magic)"); 675 - 676 - if (magic != NBD_CLIENT_MAGIC) { 677 - if (magic == NBD_OPTS_MAGIC) { 678 - error_setg(errp, "Server requires an export name"); 679 - } else { 680 - error_setg(errp, "Bad magic received"); 681 - } 682 - goto fail; 683 - } 684 - } 685 - 686 - if (read_sync(csock, &s, sizeof(s)) != sizeof(s)) { 687 - error_setg(errp, "Failed to read export length"); 688 - goto fail; 689 - } 690 - *size = be64_to_cpu(s); 691 - TRACE("Size is %" PRIu64, *size); 692 - 693 - if (!name) { 694 - if (read_sync(csock, flags, sizeof(*flags)) != sizeof(*flags)) { 695 - error_setg(errp, "Failed to read export flags"); 696 - goto fail; 697 - } 698 - *flags = be32_to_cpup(flags); 699 - } else { 700 - if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) { 701 - error_setg(errp, "Failed to read export flags"); 702 - goto fail; 703 - } 704 - *flags |= be16_to_cpu(tmp); 705 - } 706 - if (read_sync(csock, &buf, 124) != 124) { 707 - error_setg(errp, "Failed to read reserved block"); 708 - goto fail; 709 - } 710 - rc = 0; 711 - 712 - fail: 713 - return rc; 714 - } 715 - 716 419 #ifdef __linux__ 717 - int nbd_init(int fd, int csock, uint32_t flags, off_t size) 718 - { 719 - TRACE("Setting NBD socket"); 720 - 721 - if (ioctl(fd, NBD_SET_SOCK, csock) < 0) { 722 - int serrno = errno; 723 - LOG("Failed to set NBD socket"); 724 - return -serrno; 725 - } 726 - 727 - TRACE("Setting block size to %lu", (unsigned long)BDRV_SECTOR_SIZE); 728 - 729 - if (ioctl(fd, NBD_SET_BLKSIZE, (size_t)BDRV_SECTOR_SIZE) < 0) { 730 - int serrno = errno; 731 - LOG("Failed setting NBD block size"); 732 - return -serrno; 733 - } 734 - 735 - TRACE("Setting size to %zd block(s)", (size_t)(size / BDRV_SECTOR_SIZE)); 736 - 737 - if (ioctl(fd, NBD_SET_SIZE_BLOCKS, (size_t)(size / BDRV_SECTOR_SIZE)) < 0) { 738 - int serrno = errno; 739 - LOG("Failed setting size (in blocks)"); 740 - return -serrno; 741 - } 742 - 743 - if (ioctl(fd, NBD_SET_FLAGS, flags) < 0) { 744 - if (errno == ENOTTY) { 745 - int read_only = (flags & NBD_FLAG_READ_ONLY) != 0; 746 - TRACE("Setting readonly attribute"); 747 - 748 - if (ioctl(fd, BLKROSET, (unsigned long) &read_only) < 0) { 749 - int serrno = errno; 750 - LOG("Failed setting read-only attribute"); 751 - return -serrno; 752 - } 753 - } else { 754 - int serrno = errno; 755 - LOG("Failed setting flags"); 756 - return -serrno; 757 - } 758 - } 759 - 760 - TRACE("Negotiation ended"); 761 - 762 - return 0; 763 - } 764 420 765 421 int nbd_disconnect(int fd) 766 422 { ··· 770 426 return 0; 771 427 } 772 428 773 - int nbd_client(int fd) 774 - { 775 - int ret; 776 - int serrno; 777 - 778 - TRACE("Doing NBD loop"); 779 - 780 - ret = ioctl(fd, NBD_DO_IT); 781 - if (ret < 0 && errno == EPIPE) { 782 - /* NBD_DO_IT normally returns EPIPE when someone has disconnected 783 - * the socket via NBD_DISCONNECT. We do not want to return 1 in 784 - * that case. 785 - */ 786 - ret = 0; 787 - } 788 - serrno = errno; 789 - 790 - TRACE("NBD loop returned %d: %s", ret, strerror(serrno)); 791 - 792 - TRACE("Clearing NBD queue"); 793 - ioctl(fd, NBD_CLEAR_QUE); 794 - 795 - TRACE("Clearing NBD socket"); 796 - ioctl(fd, NBD_CLEAR_SOCK); 797 - 798 - errno = serrno; 799 - return ret; 800 - } 801 429 #else 802 - int nbd_init(int fd, int csock, uint32_t flags, off_t size) 803 - { 804 - return -ENOTSUP; 805 - } 806 430 807 431 int nbd_disconnect(int fd) 808 432 { 809 433 return -ENOTSUP; 810 434 } 811 - 812 - int nbd_client(int fd) 813 - { 814 - return -ENOTSUP; 815 - } 816 435 #endif 817 436 818 - ssize_t nbd_send_request(int csock, struct nbd_request *request) 819 - { 820 - uint8_t buf[NBD_REQUEST_SIZE]; 821 - ssize_t ret; 822 - 823 - cpu_to_be32w((uint32_t*)buf, NBD_REQUEST_MAGIC); 824 - cpu_to_be32w((uint32_t*)(buf + 4), request->type); 825 - cpu_to_be64w((uint64_t*)(buf + 8), request->handle); 826 - cpu_to_be64w((uint64_t*)(buf + 16), request->from); 827 - cpu_to_be32w((uint32_t*)(buf + 24), request->len); 828 - 829 - TRACE("Sending request to client: " 830 - "{ .from = %" PRIu64", .len = %u, .handle = %" PRIu64", .type=%i}", 831 - request->from, request->len, request->handle, request->type); 832 - 833 - ret = write_sync(csock, buf, sizeof(buf)); 834 - if (ret < 0) { 835 - return ret; 836 - } 837 - 838 - if (ret != sizeof(buf)) { 839 - LOG("writing to socket failed"); 840 - return -EINVAL; 841 - } 842 - return 0; 843 - } 844 - 845 437 static ssize_t nbd_receive_request(int csock, struct nbd_request *request) 846 438 { 847 439 uint8_t buf[NBD_REQUEST_SIZE]; ··· 877 469 magic, request->type, request->from, request->len); 878 470 879 471 if (magic != NBD_REQUEST_MAGIC) { 880 - LOG("invalid magic (got 0x%x)", magic); 881 - return -EINVAL; 882 - } 883 - return 0; 884 - } 885 - 886 - ssize_t nbd_receive_reply(int csock, struct nbd_reply *reply) 887 - { 888 - uint8_t buf[NBD_REPLY_SIZE]; 889 - uint32_t magic; 890 - ssize_t ret; 891 - 892 - ret = read_sync(csock, buf, sizeof(buf)); 893 - if (ret < 0) { 894 - return ret; 895 - } 896 - 897 - if (ret != sizeof(buf)) { 898 - LOG("read failed"); 899 - return -EINVAL; 900 - } 901 - 902 - /* Reply 903 - [ 0 .. 3] magic (NBD_REPLY_MAGIC) 904 - [ 4 .. 7] error (0 == no error) 905 - [ 7 .. 15] handle 906 - */ 907 - 908 - magic = be32_to_cpup((uint32_t*)buf); 909 - reply->error = be32_to_cpup((uint32_t*)(buf + 4)); 910 - reply->handle = be64_to_cpup((uint64_t*)(buf + 8)); 911 - 912 - reply->error = nbd_errno_to_system_errno(reply->error); 913 - 914 - TRACE("Got reply: " 915 - "{ magic = 0x%x, .error = %d, handle = %" PRIu64" }", 916 - magic, reply->error, reply->handle); 917 - 918 - if (magic != NBD_REPLY_MAGIC) { 919 472 LOG("invalid magic (got 0x%x)", magic); 920 473 return -EINVAL; 921 474 }
+1
nbd/Makefile.objs
··· 1 + block-obj-y += server.o client.o common.o
+361
nbd/client.c
··· 1 + /* 2 + * Copyright (C) 2005 Anthony Liguori <anthony@codemonkey.ws> 3 + * 4 + * Network Block Device Client Side 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 "nbd-internal.h" 20 + 21 + static int nbd_errno_to_system_errno(int err) 22 + { 23 + switch (err) { 24 + case NBD_SUCCESS: 25 + return 0; 26 + case NBD_EPERM: 27 + return EPERM; 28 + case NBD_EIO: 29 + return EIO; 30 + case NBD_ENOMEM: 31 + return ENOMEM; 32 + case NBD_ENOSPC: 33 + return ENOSPC; 34 + case NBD_EINVAL: 35 + default: 36 + return EINVAL; 37 + } 38 + } 39 + 40 + /* Definitions for opaque data types */ 41 + 42 + static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports); 43 + 44 + /* That's all folks */ 45 + 46 + /* Basic flow for negotiation 47 + 48 + Server Client 49 + Negotiate 50 + 51 + or 52 + 53 + Server Client 54 + Negotiate #1 55 + Option 56 + Negotiate #2 57 + 58 + ---- 59 + 60 + followed by 61 + 62 + Server Client 63 + Request 64 + Response 65 + Request 66 + Response 67 + ... 68 + ... 69 + Request (type == 2) 70 + 71 + */ 72 + 73 + int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags, 74 + off_t *size, Error **errp) 75 + { 76 + char buf[256]; 77 + uint64_t magic, s; 78 + uint16_t tmp; 79 + int rc; 80 + 81 + TRACE("Receiving negotiation."); 82 + 83 + rc = -EINVAL; 84 + 85 + if (read_sync(csock, buf, 8) != 8) { 86 + error_setg(errp, "Failed to read data"); 87 + goto fail; 88 + } 89 + 90 + buf[8] = '\0'; 91 + if (strlen(buf) == 0) { 92 + error_setg(errp, "Server connection closed unexpectedly"); 93 + goto fail; 94 + } 95 + 96 + TRACE("Magic is %c%c%c%c%c%c%c%c", 97 + qemu_isprint(buf[0]) ? buf[0] : '.', 98 + qemu_isprint(buf[1]) ? buf[1] : '.', 99 + qemu_isprint(buf[2]) ? buf[2] : '.', 100 + qemu_isprint(buf[3]) ? buf[3] : '.', 101 + qemu_isprint(buf[4]) ? buf[4] : '.', 102 + qemu_isprint(buf[5]) ? buf[5] : '.', 103 + qemu_isprint(buf[6]) ? buf[6] : '.', 104 + qemu_isprint(buf[7]) ? buf[7] : '.'); 105 + 106 + if (memcmp(buf, "NBDMAGIC", 8) != 0) { 107 + error_setg(errp, "Invalid magic received"); 108 + goto fail; 109 + } 110 + 111 + if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) { 112 + error_setg(errp, "Failed to read magic"); 113 + goto fail; 114 + } 115 + magic = be64_to_cpu(magic); 116 + TRACE("Magic is 0x%" PRIx64, magic); 117 + 118 + if (name) { 119 + uint32_t reserved = 0; 120 + uint32_t opt; 121 + uint32_t namesize; 122 + 123 + TRACE("Checking magic (opts_magic)"); 124 + if (magic != NBD_OPTS_MAGIC) { 125 + if (magic == NBD_CLIENT_MAGIC) { 126 + error_setg(errp, "Server does not support export names"); 127 + } else { 128 + error_setg(errp, "Bad magic received"); 129 + } 130 + goto fail; 131 + } 132 + if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) { 133 + error_setg(errp, "Failed to read server flags"); 134 + goto fail; 135 + } 136 + *flags = be16_to_cpu(tmp) << 16; 137 + /* reserved for future use */ 138 + if (write_sync(csock, &reserved, sizeof(reserved)) != 139 + sizeof(reserved)) { 140 + error_setg(errp, "Failed to read reserved field"); 141 + goto fail; 142 + } 143 + /* write the export name */ 144 + magic = cpu_to_be64(magic); 145 + if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) { 146 + error_setg(errp, "Failed to send export name magic"); 147 + goto fail; 148 + } 149 + opt = cpu_to_be32(NBD_OPT_EXPORT_NAME); 150 + if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) { 151 + error_setg(errp, "Failed to send export name option number"); 152 + goto fail; 153 + } 154 + namesize = cpu_to_be32(strlen(name)); 155 + if (write_sync(csock, &namesize, sizeof(namesize)) != 156 + sizeof(namesize)) { 157 + error_setg(errp, "Failed to send export name length"); 158 + goto fail; 159 + } 160 + if (write_sync(csock, (char*)name, strlen(name)) != strlen(name)) { 161 + error_setg(errp, "Failed to send export name"); 162 + goto fail; 163 + } 164 + } else { 165 + TRACE("Checking magic (cli_magic)"); 166 + 167 + if (magic != NBD_CLIENT_MAGIC) { 168 + if (magic == NBD_OPTS_MAGIC) { 169 + error_setg(errp, "Server requires an export name"); 170 + } else { 171 + error_setg(errp, "Bad magic received"); 172 + } 173 + goto fail; 174 + } 175 + } 176 + 177 + if (read_sync(csock, &s, sizeof(s)) != sizeof(s)) { 178 + error_setg(errp, "Failed to read export length"); 179 + goto fail; 180 + } 181 + *size = be64_to_cpu(s); 182 + TRACE("Size is %" PRIu64, *size); 183 + 184 + if (!name) { 185 + if (read_sync(csock, flags, sizeof(*flags)) != sizeof(*flags)) { 186 + error_setg(errp, "Failed to read export flags"); 187 + goto fail; 188 + } 189 + *flags = be32_to_cpup(flags); 190 + } else { 191 + if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) { 192 + error_setg(errp, "Failed to read export flags"); 193 + goto fail; 194 + } 195 + *flags |= be16_to_cpu(tmp); 196 + } 197 + if (read_sync(csock, &buf, 124) != 124) { 198 + error_setg(errp, "Failed to read reserved block"); 199 + goto fail; 200 + } 201 + rc = 0; 202 + 203 + fail: 204 + return rc; 205 + } 206 + 207 + #ifdef __linux__ 208 + int nbd_init(int fd, int csock, uint32_t flags, off_t size) 209 + { 210 + TRACE("Setting NBD socket"); 211 + 212 + if (ioctl(fd, NBD_SET_SOCK, csock) < 0) { 213 + int serrno = errno; 214 + LOG("Failed to set NBD socket"); 215 + return -serrno; 216 + } 217 + 218 + TRACE("Setting block size to %lu", (unsigned long)BDRV_SECTOR_SIZE); 219 + 220 + if (ioctl(fd, NBD_SET_BLKSIZE, (size_t)BDRV_SECTOR_SIZE) < 0) { 221 + int serrno = errno; 222 + LOG("Failed setting NBD block size"); 223 + return -serrno; 224 + } 225 + 226 + TRACE("Setting size to %zd block(s)", (size_t)(size / BDRV_SECTOR_SIZE)); 227 + 228 + if (ioctl(fd, NBD_SET_SIZE_BLOCKS, (size_t)(size / BDRV_SECTOR_SIZE)) < 0) { 229 + int serrno = errno; 230 + LOG("Failed setting size (in blocks)"); 231 + return -serrno; 232 + } 233 + 234 + if (ioctl(fd, NBD_SET_FLAGS, flags) < 0) { 235 + if (errno == ENOTTY) { 236 + int read_only = (flags & NBD_FLAG_READ_ONLY) != 0; 237 + TRACE("Setting readonly attribute"); 238 + 239 + if (ioctl(fd, BLKROSET, (unsigned long) &read_only) < 0) { 240 + int serrno = errno; 241 + LOG("Failed setting read-only attribute"); 242 + return -serrno; 243 + } 244 + } else { 245 + int serrno = errno; 246 + LOG("Failed setting flags"); 247 + return -serrno; 248 + } 249 + } 250 + 251 + TRACE("Negotiation ended"); 252 + 253 + return 0; 254 + } 255 + 256 + int nbd_client(int fd) 257 + { 258 + int ret; 259 + int serrno; 260 + 261 + TRACE("Doing NBD loop"); 262 + 263 + ret = ioctl(fd, NBD_DO_IT); 264 + if (ret < 0 && errno == EPIPE) { 265 + /* NBD_DO_IT normally returns EPIPE when someone has disconnected 266 + * the socket via NBD_DISCONNECT. We do not want to return 1 in 267 + * that case. 268 + */ 269 + ret = 0; 270 + } 271 + serrno = errno; 272 + 273 + TRACE("NBD loop returned %d: %s", ret, strerror(serrno)); 274 + 275 + TRACE("Clearing NBD queue"); 276 + ioctl(fd, NBD_CLEAR_QUE); 277 + 278 + TRACE("Clearing NBD socket"); 279 + ioctl(fd, NBD_CLEAR_SOCK); 280 + 281 + errno = serrno; 282 + return ret; 283 + } 284 + #else 285 + int nbd_init(int fd, int csock, uint32_t flags, off_t size) 286 + { 287 + return -ENOTSUP; 288 + } 289 + 290 + int nbd_client(int fd) 291 + { 292 + return -ENOTSUP; 293 + } 294 + #endif 295 + 296 + ssize_t nbd_send_request(int csock, struct nbd_request *request) 297 + { 298 + uint8_t buf[NBD_REQUEST_SIZE]; 299 + ssize_t ret; 300 + 301 + cpu_to_be32w((uint32_t*)buf, NBD_REQUEST_MAGIC); 302 + cpu_to_be32w((uint32_t*)(buf + 4), request->type); 303 + cpu_to_be64w((uint64_t*)(buf + 8), request->handle); 304 + cpu_to_be64w((uint64_t*)(buf + 16), request->from); 305 + cpu_to_be32w((uint32_t*)(buf + 24), request->len); 306 + 307 + TRACE("Sending request to client: " 308 + "{ .from = %" PRIu64", .len = %u, .handle = %" PRIu64", .type=%i}", 309 + request->from, request->len, request->handle, request->type); 310 + 311 + ret = write_sync(csock, buf, sizeof(buf)); 312 + if (ret < 0) { 313 + return ret; 314 + } 315 + 316 + if (ret != sizeof(buf)) { 317 + LOG("writing to socket failed"); 318 + return -EINVAL; 319 + } 320 + return 0; 321 + } 322 + 323 + ssize_t nbd_receive_reply(int csock, struct nbd_reply *reply) 324 + { 325 + uint8_t buf[NBD_REPLY_SIZE]; 326 + uint32_t magic; 327 + ssize_t ret; 328 + 329 + ret = read_sync(csock, buf, sizeof(buf)); 330 + if (ret < 0) { 331 + return ret; 332 + } 333 + 334 + if (ret != sizeof(buf)) { 335 + LOG("read failed"); 336 + return -EINVAL; 337 + } 338 + 339 + /* Reply 340 + [ 0 .. 3] magic (NBD_REPLY_MAGIC) 341 + [ 4 .. 7] error (0 == no error) 342 + [ 7 .. 15] handle 343 + */ 344 + 345 + magic = be32_to_cpup((uint32_t*)buf); 346 + reply->error = be32_to_cpup((uint32_t*)(buf + 4)); 347 + reply->handle = be64_to_cpup((uint64_t*)(buf + 8)); 348 + 349 + reply->error = nbd_errno_to_system_errno(reply->error); 350 + 351 + TRACE("Got reply: " 352 + "{ magic = 0x%x, .error = %d, handle = %" PRIu64" }", 353 + magic, reply->error, reply->handle); 354 + 355 + if (magic != NBD_REPLY_MAGIC) { 356 + LOG("invalid magic (got 0x%x)", magic); 357 + return -EINVAL; 358 + } 359 + return 0; 360 + } 361 +
+64
nbd/common.c
··· 1 + /* 2 + * Copyright (C) 2005 Anthony Liguori <anthony@codemonkey.ws> 3 + * 4 + * Network Block Device Common Code 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 "nbd-internal.h" 20 + 21 + ssize_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read) 22 + { 23 + size_t offset = 0; 24 + int err; 25 + 26 + if (qemu_in_coroutine()) { 27 + if (do_read) { 28 + return qemu_co_recv(fd, buffer, size); 29 + } else { 30 + return qemu_co_send(fd, buffer, size); 31 + } 32 + } 33 + 34 + while (offset < size) { 35 + ssize_t len; 36 + 37 + if (do_read) { 38 + len = qemu_recv(fd, buffer + offset, size - offset, 0); 39 + } else { 40 + len = send(fd, buffer + offset, size - offset, 0); 41 + } 42 + 43 + if (len < 0) { 44 + err = socket_error(); 45 + 46 + /* recoverable error */ 47 + if (err == EINTR || (offset > 0 && (err == EAGAIN || err == EWOULDBLOCK))) { 48 + continue; 49 + } 50 + 51 + /* unrecoverable error */ 52 + return -err; 53 + } 54 + 55 + /* eof */ 56 + if (len == 0) { 57 + break; 58 + } 59 + 60 + offset += len; 61 + } 62 + 63 + return offset; 64 + }
+113
nbd/nbd-internal.h
··· 1 + /* 2 + * NBD Internal Declarations 3 + * 4 + * Copyright (C) 2016 Red Hat, Inc. 5 + * 6 + * This work is licensed under the terms of the GNU GPL, version 2 or later. 7 + * See the COPYING file in the top-level directory. 8 + */ 9 + 10 + #ifndef NBD_INTERNAL_H 11 + #define NBD_INTERNAL_H 12 + #include "block/nbd.h" 13 + #include "sysemu/block-backend.h" 14 + 15 + #include "qemu/coroutine.h" 16 + 17 + #include <errno.h> 18 + #include <string.h> 19 + #ifndef _WIN32 20 + #include <sys/ioctl.h> 21 + #endif 22 + #if defined(__sun__) || defined(__HAIKU__) 23 + #include <sys/ioccom.h> 24 + #endif 25 + #include <ctype.h> 26 + #include <inttypes.h> 27 + 28 + #ifdef __linux__ 29 + #include <linux/fs.h> 30 + #endif 31 + 32 + #include "qemu/sockets.h" 33 + #include "qemu/queue.h" 34 + #include "qemu/main-loop.h" 35 + 36 + /* #define DEBUG_NBD */ 37 + 38 + #ifdef DEBUG_NBD 39 + #define TRACE(msg, ...) do { \ 40 + LOG(msg, ## __VA_ARGS__); \ 41 + } while(0) 42 + #else 43 + #define TRACE(msg, ...) \ 44 + do { } while (0) 45 + #endif 46 + 47 + #define LOG(msg, ...) do { \ 48 + fprintf(stderr, "%s:%s():L%d: " msg "\n", \ 49 + __FILE__, __FUNCTION__, __LINE__, ## __VA_ARGS__); \ 50 + } while(0) 51 + 52 + /* This is all part of the "official" NBD API. 53 + * 54 + * The most up-to-date documentation is available at: 55 + * https://github.com/yoe/nbd/blob/master/doc/proto.txt 56 + */ 57 + 58 + #define NBD_REQUEST_SIZE (4 + 4 + 8 + 8 + 4) 59 + #define NBD_REPLY_SIZE (4 + 4 + 8) 60 + #define NBD_REQUEST_MAGIC 0x25609513 61 + #define NBD_REPLY_MAGIC 0x67446698 62 + #define NBD_OPTS_MAGIC 0x49484156454F5054LL 63 + #define NBD_CLIENT_MAGIC 0x0000420281861253LL 64 + #define NBD_REP_MAGIC 0x3e889045565a9LL 65 + 66 + #define NBD_SET_SOCK _IO(0xab, 0) 67 + #define NBD_SET_BLKSIZE _IO(0xab, 1) 68 + #define NBD_SET_SIZE _IO(0xab, 2) 69 + #define NBD_DO_IT _IO(0xab, 3) 70 + #define NBD_CLEAR_SOCK _IO(0xab, 4) 71 + #define NBD_CLEAR_QUE _IO(0xab, 5) 72 + #define NBD_PRINT_DEBUG _IO(0xab, 6) 73 + #define NBD_SET_SIZE_BLOCKS _IO(0xab, 7) 74 + #define NBD_DISCONNECT _IO(0xab, 8) 75 + #define NBD_SET_TIMEOUT _IO(0xab, 9) 76 + #define NBD_SET_FLAGS _IO(0xab, 10) 77 + 78 + #define NBD_OPT_EXPORT_NAME (1) 79 + #define NBD_OPT_ABORT (2) 80 + #define NBD_OPT_LIST (3) 81 + 82 + /* NBD errors are based on errno numbers, so there is a 1:1 mapping, 83 + * but only a limited set of errno values is specified in the protocol. 84 + * Everything else is squashed to EINVAL. 85 + */ 86 + #define NBD_SUCCESS 0 87 + #define NBD_EPERM 1 88 + #define NBD_EIO 5 89 + #define NBD_ENOMEM 12 90 + #define NBD_EINVAL 22 91 + #define NBD_ENOSPC 28 92 + 93 + static inline ssize_t read_sync(int fd, void *buffer, size_t size) 94 + { 95 + /* Sockets are kept in blocking mode in the negotiation phase. After 96 + * that, a non-readable socket simply means that another thread stole 97 + * our request/reply. Synchronization is done with recv_coroutine, so 98 + * that this is coroutine-safe. 99 + */ 100 + return nbd_wr_sync(fd, buffer, size, true); 101 + } 102 + 103 + static inline ssize_t write_sync(int fd, void *buffer, size_t size) 104 + { 105 + int ret; 106 + do { 107 + /* For writes, we do expect the socket to be writable. */ 108 + ret = nbd_wr_sync(fd, buffer, size, false); 109 + } while (ret == -EAGAIN); 110 + return ret; 111 + } 112 + 113 + #endif
+1 -1
tests/qemu-iotests/083
··· 55 55 # callbacks sometimes, making them unreliable. 56 56 # 57 57 # Filter out the TCP port number since this changes between runs. 58 - sed -e 's#^.*nbd\.c:.*##g' \ 58 + sed -e 's#^.*nbd/.*\.c:.*##g' \ 59 59 -e 's#nbd:127\.0\.0\.1:[^:]*:#nbd:127\.0\.0\.1:PORT:#g' \ 60 60 -e 's#\(exportname=foo\|PORT\): Failed to .*$#\1#' 61 61 }