1798bfe00SFam Zheng /* 2798bfe00SFam Zheng * NBD Internal Declarations 3798bfe00SFam Zheng * 4798bfe00SFam Zheng * Copyright (C) 2016 Red Hat, Inc. 5798bfe00SFam Zheng * 6798bfe00SFam Zheng * This work is licensed under the terms of the GNU GPL, version 2 or later. 7798bfe00SFam Zheng * See the COPYING file in the top-level directory. 8798bfe00SFam Zheng */ 9798bfe00SFam Zheng 10798bfe00SFam Zheng #ifndef NBD_INTERNAL_H 11798bfe00SFam Zheng #define NBD_INTERNAL_H 12798bfe00SFam Zheng #include "block/nbd.h" 13798bfe00SFam Zheng #include "sysemu/block-backend.h" 14f95910feSDaniel P. Berrange #include "io/channel-tls.h" 15798bfe00SFam Zheng 16798bfe00SFam Zheng #include "qemu/coroutine.h" 171c778ef7SDaniel P. Berrange #include "qemu/iov.h" 18798bfe00SFam Zheng 19798bfe00SFam Zheng #ifndef _WIN32 20798bfe00SFam Zheng #include <sys/ioctl.h> 21798bfe00SFam Zheng #endif 22798bfe00SFam Zheng #if defined(__sun__) || defined(__HAIKU__) 23798bfe00SFam Zheng #include <sys/ioccom.h> 24798bfe00SFam Zheng #endif 25798bfe00SFam Zheng 26798bfe00SFam Zheng #ifdef __linux__ 27798bfe00SFam Zheng #include <linux/fs.h> 28798bfe00SFam Zheng #endif 29798bfe00SFam Zheng 3058369e22SPaolo Bonzini #include "qemu/bswap.h" 31798bfe00SFam Zheng #include "qemu/queue.h" 32798bfe00SFam Zheng #include "qemu/main-loop.h" 33798bfe00SFam Zheng 34798bfe00SFam Zheng /* #define DEBUG_NBD */ 35798bfe00SFam Zheng 36798bfe00SFam Zheng #ifdef DEBUG_NBD 378c659712SEric Blake #define DEBUG_NBD_PRINT 1 38798bfe00SFam Zheng #else 398c659712SEric Blake #define DEBUG_NBD_PRINT 0 40798bfe00SFam Zheng #endif 41798bfe00SFam Zheng 428c659712SEric Blake #define TRACE(msg, ...) do { \ 438c659712SEric Blake if (DEBUG_NBD_PRINT) { \ 448c659712SEric Blake LOG(msg, ## __VA_ARGS__); \ 458c659712SEric Blake } \ 468c659712SEric Blake } while (0) 478c659712SEric Blake 48798bfe00SFam Zheng #define LOG(msg, ...) do { \ 49798bfe00SFam Zheng fprintf(stderr, "%s:%s():L%d: " msg "\n", \ 50798bfe00SFam Zheng __FILE__, __FUNCTION__, __LINE__, ## __VA_ARGS__); \ 51798bfe00SFam Zheng } while (0) 52798bfe00SFam Zheng 53798bfe00SFam Zheng /* This is all part of the "official" NBD API. 54798bfe00SFam Zheng * 55798bfe00SFam Zheng * The most up-to-date documentation is available at: 56b626b51aSEric Blake * https://github.com/yoe/nbd/blob/master/doc/proto.md 57798bfe00SFam Zheng */ 58798bfe00SFam Zheng 59b626b51aSEric Blake #define NBD_REQUEST_SIZE (4 + 2 + 2 + 8 + 8 + 4) 60798bfe00SFam Zheng #define NBD_REPLY_SIZE (4 + 4 + 8) 61798bfe00SFam Zheng #define NBD_REQUEST_MAGIC 0x25609513 62798bfe00SFam Zheng #define NBD_REPLY_MAGIC 0x67446698 63798bfe00SFam Zheng #define NBD_OPTS_MAGIC 0x49484156454F5054LL 64798bfe00SFam Zheng #define NBD_CLIENT_MAGIC 0x0000420281861253LL 65c8a3a1b6SEric Blake #define NBD_REP_MAGIC 0x0003e889045565a9LL 66798bfe00SFam Zheng 67798bfe00SFam Zheng #define NBD_SET_SOCK _IO(0xab, 0) 68798bfe00SFam Zheng #define NBD_SET_BLKSIZE _IO(0xab, 1) 69798bfe00SFam Zheng #define NBD_SET_SIZE _IO(0xab, 2) 70798bfe00SFam Zheng #define NBD_DO_IT _IO(0xab, 3) 71798bfe00SFam Zheng #define NBD_CLEAR_SOCK _IO(0xab, 4) 72798bfe00SFam Zheng #define NBD_CLEAR_QUE _IO(0xab, 5) 73798bfe00SFam Zheng #define NBD_PRINT_DEBUG _IO(0xab, 6) 74798bfe00SFam Zheng #define NBD_SET_SIZE_BLOCKS _IO(0xab, 7) 75798bfe00SFam Zheng #define NBD_DISCONNECT _IO(0xab, 8) 76798bfe00SFam Zheng #define NBD_SET_TIMEOUT _IO(0xab, 9) 77798bfe00SFam Zheng #define NBD_SET_FLAGS _IO(0xab, 10) 78798bfe00SFam Zheng 79798bfe00SFam Zheng #define NBD_OPT_EXPORT_NAME (1) 80798bfe00SFam Zheng #define NBD_OPT_ABORT (2) 81798bfe00SFam Zheng #define NBD_OPT_LIST (3) 82f95910feSDaniel P. Berrange #define NBD_OPT_PEEK_EXPORT (4) 83f95910feSDaniel P. Berrange #define NBD_OPT_STARTTLS (5) 84798bfe00SFam Zheng 85798bfe00SFam Zheng /* NBD errors are based on errno numbers, so there is a 1:1 mapping, 86798bfe00SFam Zheng * but only a limited set of errno values is specified in the protocol. 87798bfe00SFam Zheng * Everything else is squashed to EINVAL. 88798bfe00SFam Zheng */ 89798bfe00SFam Zheng #define NBD_SUCCESS 0 90798bfe00SFam Zheng #define NBD_EPERM 1 91798bfe00SFam Zheng #define NBD_EIO 5 92798bfe00SFam Zheng #define NBD_ENOMEM 12 93798bfe00SFam Zheng #define NBD_EINVAL 22 94798bfe00SFam Zheng #define NBD_ENOSPC 28 95b6f5d3b5SEric Blake #define NBD_ESHUTDOWN 108 96798bfe00SFam Zheng 97*d1fdf257SVladimir Sementsov-Ogievskiy /* nbd_read_eof 98f5d406feSVladimir Sementsov-Ogievskiy * Tries to read @size bytes from @ioc. Returns number of bytes actually read. 99f5d406feSVladimir Sementsov-Ogievskiy * May return a value >= 0 and < size only on EOF, i.e. when iteratively called 100*d1fdf257SVladimir Sementsov-Ogievskiy * qio_channel_readv() returns 0. So, there is no need to call nbd_read_eof 101f5d406feSVladimir Sementsov-Ogievskiy * iteratively. 102f5d406feSVladimir Sementsov-Ogievskiy */ 103*d1fdf257SVladimir Sementsov-Ogievskiy static inline ssize_t nbd_read_eof(QIOChannel *ioc, void *buffer, size_t size, 104e44ed99dSVladimir Sementsov-Ogievskiy Error **errp) 105798bfe00SFam Zheng { 1061c778ef7SDaniel P. Berrange struct iovec iov = { .iov_base = buffer, .iov_len = size }; 107798bfe00SFam Zheng /* Sockets are kept in blocking mode in the negotiation phase. After 108798bfe00SFam Zheng * that, a non-readable socket simply means that another thread stole 109798bfe00SFam Zheng * our request/reply. Synchronization is done with recv_coroutine, so 110798bfe00SFam Zheng * that this is coroutine-safe. 111798bfe00SFam Zheng */ 112*d1fdf257SVladimir Sementsov-Ogievskiy return nbd_rwv(ioc, &iov, 1, size, true, errp); 113798bfe00SFam Zheng } 114798bfe00SFam Zheng 115*d1fdf257SVladimir Sementsov-Ogievskiy /* nbd_read 116f5d406feSVladimir Sementsov-Ogievskiy * Reads @size bytes from @ioc. Returns 0 on success. 117f5d406feSVladimir Sementsov-Ogievskiy */ 118*d1fdf257SVladimir Sementsov-Ogievskiy static inline int nbd_read(QIOChannel *ioc, void *buffer, size_t size, 119e44ed99dSVladimir Sementsov-Ogievskiy Error **errp) 120f5d406feSVladimir Sementsov-Ogievskiy { 121*d1fdf257SVladimir Sementsov-Ogievskiy ssize_t ret = nbd_read_eof(ioc, buffer, size, errp); 122f5d406feSVladimir Sementsov-Ogievskiy 123f5d406feSVladimir Sementsov-Ogievskiy if (ret >= 0 && ret != size) { 124f5d406feSVladimir Sementsov-Ogievskiy ret = -EINVAL; 125e44ed99dSVladimir Sementsov-Ogievskiy error_setg(errp, "End of file"); 126f5d406feSVladimir Sementsov-Ogievskiy } 127f5d406feSVladimir Sementsov-Ogievskiy 128f5d406feSVladimir Sementsov-Ogievskiy return ret < 0 ? ret : 0; 129f5d406feSVladimir Sementsov-Ogievskiy } 130f5d406feSVladimir Sementsov-Ogievskiy 131*d1fdf257SVladimir Sementsov-Ogievskiy /* nbd_write 132f5d406feSVladimir Sementsov-Ogievskiy * Writes @size bytes to @ioc. Returns 0 on success. 133f5d406feSVladimir Sementsov-Ogievskiy */ 134*d1fdf257SVladimir Sementsov-Ogievskiy static inline int nbd_write(QIOChannel *ioc, const void *buffer, size_t size, 135e44ed99dSVladimir Sementsov-Ogievskiy Error **errp) 136798bfe00SFam Zheng { 137b1a75b33SEric Blake struct iovec iov = { .iov_base = (void *) buffer, .iov_len = size }; 1381c778ef7SDaniel P. Berrange 139*d1fdf257SVladimir Sementsov-Ogievskiy ssize_t ret = nbd_rwv(ioc, &iov, 1, size, false, errp); 140f5d406feSVladimir Sementsov-Ogievskiy 141f5d406feSVladimir Sementsov-Ogievskiy assert(ret < 0 || ret == size); 142f5d406feSVladimir Sementsov-Ogievskiy 143f5d406feSVladimir Sementsov-Ogievskiy return ret < 0 ? ret : 0; 144798bfe00SFam Zheng } 145798bfe00SFam Zheng 146f95910feSDaniel P. Berrange struct NBDTLSHandshakeData { 147f95910feSDaniel P. Berrange GMainLoop *loop; 148f95910feSDaniel P. Berrange bool complete; 149f95910feSDaniel P. Berrange Error *error; 150f95910feSDaniel P. Berrange }; 151f95910feSDaniel P. Berrange 152f95910feSDaniel P. Berrange 15360e705c5SDaniel P. Berrange void nbd_tls_handshake(QIOTask *task, 154f95910feSDaniel P. Berrange void *opaque); 155f95910feSDaniel P. Berrange 156798bfe00SFam Zheng #endif 157