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