1798bfe00SFam Zheng /*
2798bfe00SFam Zheng * Copyright (C) 2005 Anthony Liguori <anthony@codemonkey.ws>
3798bfe00SFam Zheng *
4798bfe00SFam Zheng * Network Block Device Common Code
5798bfe00SFam Zheng *
6798bfe00SFam Zheng * This program is free software; you can redistribute it and/or modify
7798bfe00SFam Zheng * it under the terms of the GNU General Public License as published by
8798bfe00SFam Zheng * the Free Software Foundation; under version 2 of the License.
9798bfe00SFam Zheng *
10798bfe00SFam Zheng * This program is distributed in the hope that it will be useful,
11798bfe00SFam Zheng * but WITHOUT ANY WARRANTY; without even the implied warranty of
12798bfe00SFam Zheng * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13798bfe00SFam Zheng * GNU General Public License for more details.
14798bfe00SFam Zheng *
15798bfe00SFam Zheng * You should have received a copy of the GNU General Public License
16798bfe00SFam Zheng * along with this program; if not, see <http://www.gnu.org/licenses/>.
17798bfe00SFam Zheng */
18798bfe00SFam Zheng
19d38ea87aSPeter Maydell #include "qemu/osdep.h"
20dd689440SEric Blake #include "trace.h"
21798bfe00SFam Zheng #include "nbd-internal.h"
22798bfe00SFam Zheng
2344298024SVladimir Sementsov-Ogievskiy /* Discard length bytes from channel. Return -errno on failure and 0 on
2444298024SVladimir Sementsov-Ogievskiy * success */
nbd_drop(QIOChannel * ioc,size_t size,Error ** errp)2544298024SVladimir Sementsov-Ogievskiy int nbd_drop(QIOChannel *ioc, size_t size, Error **errp)
2644298024SVladimir Sementsov-Ogievskiy {
2744298024SVladimir Sementsov-Ogievskiy ssize_t ret = 0;
2844298024SVladimir Sementsov-Ogievskiy char small[1024];
2944298024SVladimir Sementsov-Ogievskiy char *buffer;
3044298024SVladimir Sementsov-Ogievskiy
3144298024SVladimir Sementsov-Ogievskiy buffer = sizeof(small) >= size ? small : g_malloc(MIN(65536, size));
3244298024SVladimir Sementsov-Ogievskiy while (size > 0) {
3344298024SVladimir Sementsov-Ogievskiy ssize_t count = MIN(65536, size);
34e6798f06SVladimir Sementsov-Ogievskiy ret = nbd_read(ioc, buffer, MIN(65536, size), NULL, errp);
3544298024SVladimir Sementsov-Ogievskiy
3644298024SVladimir Sementsov-Ogievskiy if (ret < 0) {
3744298024SVladimir Sementsov-Ogievskiy goto cleanup;
3844298024SVladimir Sementsov-Ogievskiy }
3944298024SVladimir Sementsov-Ogievskiy size -= count;
4044298024SVladimir Sementsov-Ogievskiy }
4144298024SVladimir Sementsov-Ogievskiy
4244298024SVladimir Sementsov-Ogievskiy cleanup:
4344298024SVladimir Sementsov-Ogievskiy if (buffer != small) {
4444298024SVladimir Sementsov-Ogievskiy g_free(buffer);
4544298024SVladimir Sementsov-Ogievskiy }
4644298024SVladimir Sementsov-Ogievskiy return ret;
4744298024SVladimir Sementsov-Ogievskiy }
4844298024SVladimir Sementsov-Ogievskiy
49f95910feSDaniel P. Berrange
nbd_opt_lookup(uint32_t opt)503736cc5bSEric Blake const char *nbd_opt_lookup(uint32_t opt)
513736cc5bSEric Blake {
523736cc5bSEric Blake switch (opt) {
533736cc5bSEric Blake case NBD_OPT_EXPORT_NAME:
543736cc5bSEric Blake return "export name";
553736cc5bSEric Blake case NBD_OPT_ABORT:
563736cc5bSEric Blake return "abort";
573736cc5bSEric Blake case NBD_OPT_LIST:
583736cc5bSEric Blake return "list";
593736cc5bSEric Blake case NBD_OPT_STARTTLS:
603736cc5bSEric Blake return "starttls";
613736cc5bSEric Blake case NBD_OPT_INFO:
623736cc5bSEric Blake return "info";
633736cc5bSEric Blake case NBD_OPT_GO:
643736cc5bSEric Blake return "go";
653736cc5bSEric Blake case NBD_OPT_STRUCTURED_REPLY:
663736cc5bSEric Blake return "structured reply";
6725c14678SVladimir Sementsov-Ogievskiy case NBD_OPT_LIST_META_CONTEXT:
6825c14678SVladimir Sementsov-Ogievskiy return "list meta context";
6925c14678SVladimir Sementsov-Ogievskiy case NBD_OPT_SET_META_CONTEXT:
7025c14678SVladimir Sementsov-Ogievskiy return "set meta context";
71*d95ffb6fSEric Blake case NBD_OPT_EXTENDED_HEADERS:
72*d95ffb6fSEric Blake return "extended headers";
733736cc5bSEric Blake default:
743736cc5bSEric Blake return "<unknown>";
753736cc5bSEric Blake }
763736cc5bSEric Blake }
773736cc5bSEric Blake
783736cc5bSEric Blake
nbd_rep_lookup(uint32_t rep)793736cc5bSEric Blake const char *nbd_rep_lookup(uint32_t rep)
803736cc5bSEric Blake {
813736cc5bSEric Blake switch (rep) {
823736cc5bSEric Blake case NBD_REP_ACK:
833736cc5bSEric Blake return "ack";
843736cc5bSEric Blake case NBD_REP_SERVER:
853736cc5bSEric Blake return "server";
863736cc5bSEric Blake case NBD_REP_INFO:
873736cc5bSEric Blake return "info";
8825c14678SVladimir Sementsov-Ogievskiy case NBD_REP_META_CONTEXT:
8925c14678SVladimir Sementsov-Ogievskiy return "meta context";
903736cc5bSEric Blake case NBD_REP_ERR_UNSUP:
913736cc5bSEric Blake return "unsupported";
923736cc5bSEric Blake case NBD_REP_ERR_POLICY:
933736cc5bSEric Blake return "denied by policy";
943736cc5bSEric Blake case NBD_REP_ERR_INVALID:
953736cc5bSEric Blake return "invalid";
963736cc5bSEric Blake case NBD_REP_ERR_PLATFORM:
973736cc5bSEric Blake return "platform lacks support";
983736cc5bSEric Blake case NBD_REP_ERR_TLS_REQD:
993736cc5bSEric Blake return "TLS required";
1003736cc5bSEric Blake case NBD_REP_ERR_UNKNOWN:
1013736cc5bSEric Blake return "export unknown";
1023736cc5bSEric Blake case NBD_REP_ERR_SHUTDOWN:
1033736cc5bSEric Blake return "server shutting down";
1043736cc5bSEric Blake case NBD_REP_ERR_BLOCK_SIZE_REQD:
1053736cc5bSEric Blake return "block size required";
106*d95ffb6fSEric Blake case NBD_REP_ERR_TOO_BIG:
107*d95ffb6fSEric Blake return "option payload too big";
108*d95ffb6fSEric Blake case NBD_REP_ERR_EXT_HEADER_REQD:
109*d95ffb6fSEric Blake return "extended headers required";
1103736cc5bSEric Blake default:
1113736cc5bSEric Blake return "<unknown>";
1123736cc5bSEric Blake }
1133736cc5bSEric Blake }
1143736cc5bSEric Blake
1153736cc5bSEric Blake
nbd_info_lookup(uint16_t info)1163736cc5bSEric Blake const char *nbd_info_lookup(uint16_t info)
1173736cc5bSEric Blake {
1183736cc5bSEric Blake switch (info) {
1193736cc5bSEric Blake case NBD_INFO_EXPORT:
1203736cc5bSEric Blake return "export";
1213736cc5bSEric Blake case NBD_INFO_NAME:
1223736cc5bSEric Blake return "name";
1233736cc5bSEric Blake case NBD_INFO_DESCRIPTION:
1243736cc5bSEric Blake return "description";
1253736cc5bSEric Blake case NBD_INFO_BLOCK_SIZE:
1263736cc5bSEric Blake return "block size";
1273736cc5bSEric Blake default:
1283736cc5bSEric Blake return "<unknown>";
1293736cc5bSEric Blake }
1303736cc5bSEric Blake }
1313736cc5bSEric Blake
1323736cc5bSEric Blake
nbd_cmd_lookup(uint16_t cmd)1333736cc5bSEric Blake const char *nbd_cmd_lookup(uint16_t cmd)
1343736cc5bSEric Blake {
1353736cc5bSEric Blake switch (cmd) {
1363736cc5bSEric Blake case NBD_CMD_READ:
1373736cc5bSEric Blake return "read";
1383736cc5bSEric Blake case NBD_CMD_WRITE:
1393736cc5bSEric Blake return "write";
1403736cc5bSEric Blake case NBD_CMD_DISC:
141dad3946eSEric Blake return "disconnect";
1423736cc5bSEric Blake case NBD_CMD_FLUSH:
1433736cc5bSEric Blake return "flush";
1443736cc5bSEric Blake case NBD_CMD_TRIM:
1453736cc5bSEric Blake return "trim";
146bc37b06aSVladimir Sementsov-Ogievskiy case NBD_CMD_CACHE:
147bc37b06aSVladimir Sementsov-Ogievskiy return "cache";
1483736cc5bSEric Blake case NBD_CMD_WRITE_ZEROES:
1493736cc5bSEric Blake return "write zeroes";
15025c14678SVladimir Sementsov-Ogievskiy case NBD_CMD_BLOCK_STATUS:
15125c14678SVladimir Sementsov-Ogievskiy return "block status";
1523736cc5bSEric Blake default:
1533736cc5bSEric Blake return "<unknown>";
1543736cc5bSEric Blake }
1553736cc5bSEric Blake }
156e7a78d0eSEric Blake
157e7a78d0eSEric Blake
nbd_reply_type_lookup(uint16_t type)158bae245d1SEric Blake const char *nbd_reply_type_lookup(uint16_t type)
159bae245d1SEric Blake {
160bae245d1SEric Blake switch (type) {
161bae245d1SEric Blake case NBD_REPLY_TYPE_NONE:
162bae245d1SEric Blake return "none";
163bae245d1SEric Blake case NBD_REPLY_TYPE_OFFSET_DATA:
164bae245d1SEric Blake return "data";
165bae245d1SEric Blake case NBD_REPLY_TYPE_OFFSET_HOLE:
166bae245d1SEric Blake return "hole";
16725c14678SVladimir Sementsov-Ogievskiy case NBD_REPLY_TYPE_BLOCK_STATUS:
168*d95ffb6fSEric Blake return "block status (32-bit)";
169*d95ffb6fSEric Blake case NBD_REPLY_TYPE_BLOCK_STATUS_EXT:
170*d95ffb6fSEric Blake return "block status (64-bit)";
171bae245d1SEric Blake case NBD_REPLY_TYPE_ERROR:
172bae245d1SEric Blake return "generic error";
173bae245d1SEric Blake case NBD_REPLY_TYPE_ERROR_OFFSET:
174bae245d1SEric Blake return "error at offset";
175bae245d1SEric Blake default:
176bae245d1SEric Blake if (type & (1 << 15)) {
177bae245d1SEric Blake return "<unknown error>";
178bae245d1SEric Blake }
179bae245d1SEric Blake return "<unknown>";
180bae245d1SEric Blake }
181bae245d1SEric Blake }
182bae245d1SEric Blake
183bae245d1SEric Blake
nbd_err_lookup(int err)184e7a78d0eSEric Blake const char *nbd_err_lookup(int err)
185e7a78d0eSEric Blake {
186e7a78d0eSEric Blake switch (err) {
187e7a78d0eSEric Blake case NBD_SUCCESS:
188e7a78d0eSEric Blake return "success";
189e7a78d0eSEric Blake case NBD_EPERM:
190e7a78d0eSEric Blake return "EPERM";
191e7a78d0eSEric Blake case NBD_EIO:
192e7a78d0eSEric Blake return "EIO";
193e7a78d0eSEric Blake case NBD_ENOMEM:
194e7a78d0eSEric Blake return "ENOMEM";
195e7a78d0eSEric Blake case NBD_EINVAL:
196e7a78d0eSEric Blake return "EINVAL";
197e7a78d0eSEric Blake case NBD_ENOSPC:
198e7a78d0eSEric Blake return "ENOSPC";
199bae245d1SEric Blake case NBD_EOVERFLOW:
200bae245d1SEric Blake return "EOVERFLOW";
2010a479545SEric Blake case NBD_ENOTSUP:
2020a479545SEric Blake return "ENOTSUP";
203e7a78d0eSEric Blake case NBD_ESHUTDOWN:
204e7a78d0eSEric Blake return "ESHUTDOWN";
205e7a78d0eSEric Blake default:
206e7a78d0eSEric Blake return "<unknown>";
207e7a78d0eSEric Blake }
208e7a78d0eSEric Blake }
209dd689440SEric Blake
210dd689440SEric Blake
nbd_errno_to_system_errno(int err)211dd689440SEric Blake int nbd_errno_to_system_errno(int err)
212dd689440SEric Blake {
213dd689440SEric Blake int ret;
214dd689440SEric Blake switch (err) {
215dd689440SEric Blake case NBD_SUCCESS:
216dd689440SEric Blake ret = 0;
217dd689440SEric Blake break;
218dd689440SEric Blake case NBD_EPERM:
219dd689440SEric Blake ret = EPERM;
220dd689440SEric Blake break;
221dd689440SEric Blake case NBD_EIO:
222dd689440SEric Blake ret = EIO;
223dd689440SEric Blake break;
224dd689440SEric Blake case NBD_ENOMEM:
225dd689440SEric Blake ret = ENOMEM;
226dd689440SEric Blake break;
227dd689440SEric Blake case NBD_ENOSPC:
228dd689440SEric Blake ret = ENOSPC;
229dd689440SEric Blake break;
230bae245d1SEric Blake case NBD_EOVERFLOW:
231bae245d1SEric Blake ret = EOVERFLOW;
232bae245d1SEric Blake break;
2330a479545SEric Blake case NBD_ENOTSUP:
2340a479545SEric Blake ret = ENOTSUP;
2350a479545SEric Blake break;
236dd689440SEric Blake case NBD_ESHUTDOWN:
237dd689440SEric Blake ret = ESHUTDOWN;
238dd689440SEric Blake break;
239dd689440SEric Blake default:
240dd689440SEric Blake trace_nbd_unknown_error(err);
241dd689440SEric Blake /* fallthrough */
242dd689440SEric Blake case NBD_EINVAL:
243dd689440SEric Blake ret = EINVAL;
244dd689440SEric Blake break;
245dd689440SEric Blake }
246dd689440SEric Blake return ret;
247dd689440SEric Blake }
248bfe04d0aSEric Blake
249bfe04d0aSEric Blake
nbd_mode_lookup(NBDMode mode)250bfe04d0aSEric Blake const char *nbd_mode_lookup(NBDMode mode)
251bfe04d0aSEric Blake {
252bfe04d0aSEric Blake switch (mode) {
253bfe04d0aSEric Blake case NBD_MODE_OLDSTYLE:
254bfe04d0aSEric Blake return "oldstyle";
255bfe04d0aSEric Blake case NBD_MODE_EXPORT_NAME:
256bfe04d0aSEric Blake return "export name only";
257bfe04d0aSEric Blake case NBD_MODE_SIMPLE:
258bfe04d0aSEric Blake return "simple headers";
259bfe04d0aSEric Blake case NBD_MODE_STRUCTURED:
260bfe04d0aSEric Blake return "structured replies";
261*d95ffb6fSEric Blake case NBD_MODE_EXTENDED:
262*d95ffb6fSEric Blake return "extended headers";
263bfe04d0aSEric Blake default:
264bfe04d0aSEric Blake return "<unknown>";
265bfe04d0aSEric Blake }
266bfe04d0aSEric Blake }
267