xref: /openbmc/qemu/nbd/common.c (revision 6350b2a0)
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 "qemu/osdep.h"
20 #include "qapi/error.h"
21 #include "trace.h"
22 #include "nbd-internal.h"
23 
24 /* Discard length bytes from channel.  Return -errno on failure and 0 on
25  * success */
26 int nbd_drop(QIOChannel *ioc, size_t size, Error **errp)
27 {
28     ssize_t ret = 0;
29     char small[1024];
30     char *buffer;
31 
32     buffer = sizeof(small) >= size ? small : g_malloc(MIN(65536, size));
33     while (size > 0) {
34         ssize_t count = MIN(65536, size);
35         ret = nbd_read(ioc, buffer, MIN(65536, size), errp);
36 
37         if (ret < 0) {
38             goto cleanup;
39         }
40         size -= count;
41     }
42 
43  cleanup:
44     if (buffer != small) {
45         g_free(buffer);
46     }
47     return ret;
48 }
49 
50 
51 void nbd_tls_handshake(QIOTask *task,
52                        void *opaque)
53 {
54     struct NBDTLSHandshakeData *data = opaque;
55 
56     qio_task_propagate_error(task, &data->error);
57     data->complete = true;
58     g_main_loop_quit(data->loop);
59 }
60 
61 
62 const char *nbd_opt_lookup(uint32_t opt)
63 {
64     switch (opt) {
65     case NBD_OPT_EXPORT_NAME:
66         return "export name";
67     case NBD_OPT_ABORT:
68         return "abort";
69     case NBD_OPT_LIST:
70         return "list";
71     case NBD_OPT_STARTTLS:
72         return "starttls";
73     case NBD_OPT_INFO:
74         return "info";
75     case NBD_OPT_GO:
76         return "go";
77     case NBD_OPT_STRUCTURED_REPLY:
78         return "structured reply";
79     default:
80         return "<unknown>";
81     }
82 }
83 
84 
85 const char *nbd_rep_lookup(uint32_t rep)
86 {
87     switch (rep) {
88     case NBD_REP_ACK:
89         return "ack";
90     case NBD_REP_SERVER:
91         return "server";
92     case NBD_REP_INFO:
93         return "info";
94     case NBD_REP_ERR_UNSUP:
95         return "unsupported";
96     case NBD_REP_ERR_POLICY:
97         return "denied by policy";
98     case NBD_REP_ERR_INVALID:
99         return "invalid";
100     case NBD_REP_ERR_PLATFORM:
101         return "platform lacks support";
102     case NBD_REP_ERR_TLS_REQD:
103         return "TLS required";
104     case NBD_REP_ERR_UNKNOWN:
105         return "export unknown";
106     case NBD_REP_ERR_SHUTDOWN:
107         return "server shutting down";
108     case NBD_REP_ERR_BLOCK_SIZE_REQD:
109         return "block size required";
110     default:
111         return "<unknown>";
112     }
113 }
114 
115 
116 const char *nbd_info_lookup(uint16_t info)
117 {
118     switch (info) {
119     case NBD_INFO_EXPORT:
120         return "export";
121     case NBD_INFO_NAME:
122         return "name";
123     case NBD_INFO_DESCRIPTION:
124         return "description";
125     case NBD_INFO_BLOCK_SIZE:
126         return "block size";
127     default:
128         return "<unknown>";
129     }
130 }
131 
132 
133 const char *nbd_cmd_lookup(uint16_t cmd)
134 {
135     switch (cmd) {
136     case NBD_CMD_READ:
137         return "read";
138     case NBD_CMD_WRITE:
139         return "write";
140     case NBD_CMD_DISC:
141         return "disconnect";
142     case NBD_CMD_FLUSH:
143         return "flush";
144     case NBD_CMD_TRIM:
145         return "trim";
146     case NBD_CMD_WRITE_ZEROES:
147         return "write zeroes";
148     default:
149         return "<unknown>";
150     }
151 }
152 
153 
154 const char *nbd_reply_type_lookup(uint16_t type)
155 {
156     switch (type) {
157     case NBD_REPLY_TYPE_NONE:
158         return "none";
159     case NBD_REPLY_TYPE_OFFSET_DATA:
160         return "data";
161     case NBD_REPLY_TYPE_OFFSET_HOLE:
162         return "hole";
163     case NBD_REPLY_TYPE_ERROR:
164         return "generic error";
165     case NBD_REPLY_TYPE_ERROR_OFFSET:
166         return "error at offset";
167     default:
168         if (type & (1 << 15)) {
169             return "<unknown error>";
170         }
171         return "<unknown>";
172     }
173 }
174 
175 
176 const char *nbd_err_lookup(int err)
177 {
178     switch (err) {
179     case NBD_SUCCESS:
180         return "success";
181     case NBD_EPERM:
182         return "EPERM";
183     case NBD_EIO:
184         return "EIO";
185     case NBD_ENOMEM:
186         return "ENOMEM";
187     case NBD_EINVAL:
188         return "EINVAL";
189     case NBD_ENOSPC:
190         return "ENOSPC";
191     case NBD_EOVERFLOW:
192         return "EOVERFLOW";
193     case NBD_ESHUTDOWN:
194         return "ESHUTDOWN";
195     default:
196         return "<unknown>";
197     }
198 }
199 
200 
201 int nbd_errno_to_system_errno(int err)
202 {
203     int ret;
204     switch (err) {
205     case NBD_SUCCESS:
206         ret = 0;
207         break;
208     case NBD_EPERM:
209         ret = EPERM;
210         break;
211     case NBD_EIO:
212         ret = EIO;
213         break;
214     case NBD_ENOMEM:
215         ret = ENOMEM;
216         break;
217     case NBD_ENOSPC:
218         ret = ENOSPC;
219         break;
220     case NBD_EOVERFLOW:
221         ret = EOVERFLOW;
222         break;
223     case NBD_ESHUTDOWN:
224         ret = ESHUTDOWN;
225         break;
226     default:
227         trace_nbd_unknown_error(err);
228         /* fallthrough */
229     case NBD_EINVAL:
230         ret = EINVAL;
231         break;
232     }
233     return ret;
234 }
235