xref: /openbmc/qemu/nbd/nbd-internal.h (revision d1fdf257)
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