1 /* 2 * Copyright (C) 2005 Anthony Liguori <anthony@codemonkey.ws> 3 * 4 * Network Block Device Client Side 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 "nbd-internal.h" 21 22 static int nbd_errno_to_system_errno(int err) 23 { 24 switch (err) { 25 case NBD_SUCCESS: 26 return 0; 27 case NBD_EPERM: 28 return EPERM; 29 case NBD_EIO: 30 return EIO; 31 case NBD_ENOMEM: 32 return ENOMEM; 33 case NBD_ENOSPC: 34 return ENOSPC; 35 case NBD_EINVAL: 36 default: 37 return EINVAL; 38 } 39 } 40 41 /* Definitions for opaque data types */ 42 43 static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports); 44 45 /* That's all folks */ 46 47 /* Basic flow for negotiation 48 49 Server Client 50 Negotiate 51 52 or 53 54 Server Client 55 Negotiate #1 56 Option 57 Negotiate #2 58 59 ---- 60 61 followed by 62 63 Server Client 64 Request 65 Response 66 Request 67 Response 68 ... 69 ... 70 Request (type == 2) 71 72 */ 73 74 int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags, 75 off_t *size, Error **errp) 76 { 77 char buf[256]; 78 uint64_t magic, s; 79 uint16_t tmp; 80 int rc; 81 82 TRACE("Receiving negotiation."); 83 84 rc = -EINVAL; 85 86 if (read_sync(csock, buf, 8) != 8) { 87 error_setg(errp, "Failed to read data"); 88 goto fail; 89 } 90 91 buf[8] = '\0'; 92 if (strlen(buf) == 0) { 93 error_setg(errp, "Server connection closed unexpectedly"); 94 goto fail; 95 } 96 97 TRACE("Magic is %c%c%c%c%c%c%c%c", 98 qemu_isprint(buf[0]) ? buf[0] : '.', 99 qemu_isprint(buf[1]) ? buf[1] : '.', 100 qemu_isprint(buf[2]) ? buf[2] : '.', 101 qemu_isprint(buf[3]) ? buf[3] : '.', 102 qemu_isprint(buf[4]) ? buf[4] : '.', 103 qemu_isprint(buf[5]) ? buf[5] : '.', 104 qemu_isprint(buf[6]) ? buf[6] : '.', 105 qemu_isprint(buf[7]) ? buf[7] : '.'); 106 107 if (memcmp(buf, "NBDMAGIC", 8) != 0) { 108 error_setg(errp, "Invalid magic received"); 109 goto fail; 110 } 111 112 if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) { 113 error_setg(errp, "Failed to read magic"); 114 goto fail; 115 } 116 magic = be64_to_cpu(magic); 117 TRACE("Magic is 0x%" PRIx64, magic); 118 119 if (name) { 120 uint32_t reserved = 0; 121 uint32_t opt; 122 uint32_t namesize; 123 124 TRACE("Checking magic (opts_magic)"); 125 if (magic != NBD_OPTS_MAGIC) { 126 if (magic == NBD_CLIENT_MAGIC) { 127 error_setg(errp, "Server does not support export names"); 128 } else { 129 error_setg(errp, "Bad magic received"); 130 } 131 goto fail; 132 } 133 if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) { 134 error_setg(errp, "Failed to read server flags"); 135 goto fail; 136 } 137 *flags = be16_to_cpu(tmp) << 16; 138 /* reserved for future use */ 139 if (write_sync(csock, &reserved, sizeof(reserved)) != 140 sizeof(reserved)) { 141 error_setg(errp, "Failed to read reserved field"); 142 goto fail; 143 } 144 /* write the export name */ 145 magic = cpu_to_be64(magic); 146 if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) { 147 error_setg(errp, "Failed to send export name magic"); 148 goto fail; 149 } 150 opt = cpu_to_be32(NBD_OPT_EXPORT_NAME); 151 if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) { 152 error_setg(errp, "Failed to send export name option number"); 153 goto fail; 154 } 155 namesize = cpu_to_be32(strlen(name)); 156 if (write_sync(csock, &namesize, sizeof(namesize)) != 157 sizeof(namesize)) { 158 error_setg(errp, "Failed to send export name length"); 159 goto fail; 160 } 161 if (write_sync(csock, (char*)name, strlen(name)) != strlen(name)) { 162 error_setg(errp, "Failed to send export name"); 163 goto fail; 164 } 165 } else { 166 TRACE("Checking magic (cli_magic)"); 167 168 if (magic != NBD_CLIENT_MAGIC) { 169 if (magic == NBD_OPTS_MAGIC) { 170 error_setg(errp, "Server requires an export name"); 171 } else { 172 error_setg(errp, "Bad magic received"); 173 } 174 goto fail; 175 } 176 } 177 178 if (read_sync(csock, &s, sizeof(s)) != sizeof(s)) { 179 error_setg(errp, "Failed to read export length"); 180 goto fail; 181 } 182 *size = be64_to_cpu(s); 183 TRACE("Size is %" PRIu64, *size); 184 185 if (!name) { 186 if (read_sync(csock, flags, sizeof(*flags)) != sizeof(*flags)) { 187 error_setg(errp, "Failed to read export flags"); 188 goto fail; 189 } 190 *flags = be32_to_cpup(flags); 191 } else { 192 if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) { 193 error_setg(errp, "Failed to read export flags"); 194 goto fail; 195 } 196 *flags |= be16_to_cpu(tmp); 197 } 198 if (read_sync(csock, &buf, 124) != 124) { 199 error_setg(errp, "Failed to read reserved block"); 200 goto fail; 201 } 202 rc = 0; 203 204 fail: 205 return rc; 206 } 207 208 #ifdef __linux__ 209 int nbd_init(int fd, int csock, uint32_t flags, off_t size) 210 { 211 TRACE("Setting NBD socket"); 212 213 if (ioctl(fd, NBD_SET_SOCK, csock) < 0) { 214 int serrno = errno; 215 LOG("Failed to set NBD socket"); 216 return -serrno; 217 } 218 219 TRACE("Setting block size to %lu", (unsigned long)BDRV_SECTOR_SIZE); 220 221 if (ioctl(fd, NBD_SET_BLKSIZE, (size_t)BDRV_SECTOR_SIZE) < 0) { 222 int serrno = errno; 223 LOG("Failed setting NBD block size"); 224 return -serrno; 225 } 226 227 TRACE("Setting size to %zd block(s)", (size_t)(size / BDRV_SECTOR_SIZE)); 228 229 if (ioctl(fd, NBD_SET_SIZE_BLOCKS, (size_t)(size / BDRV_SECTOR_SIZE)) < 0) { 230 int serrno = errno; 231 LOG("Failed setting size (in blocks)"); 232 return -serrno; 233 } 234 235 if (ioctl(fd, NBD_SET_FLAGS, flags) < 0) { 236 if (errno == ENOTTY) { 237 int read_only = (flags & NBD_FLAG_READ_ONLY) != 0; 238 TRACE("Setting readonly attribute"); 239 240 if (ioctl(fd, BLKROSET, (unsigned long) &read_only) < 0) { 241 int serrno = errno; 242 LOG("Failed setting read-only attribute"); 243 return -serrno; 244 } 245 } else { 246 int serrno = errno; 247 LOG("Failed setting flags"); 248 return -serrno; 249 } 250 } 251 252 TRACE("Negotiation ended"); 253 254 return 0; 255 } 256 257 int nbd_client(int fd) 258 { 259 int ret; 260 int serrno; 261 262 TRACE("Doing NBD loop"); 263 264 ret = ioctl(fd, NBD_DO_IT); 265 if (ret < 0 && errno == EPIPE) { 266 /* NBD_DO_IT normally returns EPIPE when someone has disconnected 267 * the socket via NBD_DISCONNECT. We do not want to return 1 in 268 * that case. 269 */ 270 ret = 0; 271 } 272 serrno = errno; 273 274 TRACE("NBD loop returned %d: %s", ret, strerror(serrno)); 275 276 TRACE("Clearing NBD queue"); 277 ioctl(fd, NBD_CLEAR_QUE); 278 279 TRACE("Clearing NBD socket"); 280 ioctl(fd, NBD_CLEAR_SOCK); 281 282 errno = serrno; 283 return ret; 284 } 285 #else 286 int nbd_init(int fd, int csock, uint32_t flags, off_t size) 287 { 288 return -ENOTSUP; 289 } 290 291 int nbd_client(int fd) 292 { 293 return -ENOTSUP; 294 } 295 #endif 296 297 ssize_t nbd_send_request(int csock, struct nbd_request *request) 298 { 299 uint8_t buf[NBD_REQUEST_SIZE]; 300 ssize_t ret; 301 302 cpu_to_be32w((uint32_t*)buf, NBD_REQUEST_MAGIC); 303 cpu_to_be32w((uint32_t*)(buf + 4), request->type); 304 cpu_to_be64w((uint64_t*)(buf + 8), request->handle); 305 cpu_to_be64w((uint64_t*)(buf + 16), request->from); 306 cpu_to_be32w((uint32_t*)(buf + 24), request->len); 307 308 TRACE("Sending request to client: " 309 "{ .from = %" PRIu64", .len = %u, .handle = %" PRIu64", .type=%i}", 310 request->from, request->len, request->handle, request->type); 311 312 ret = write_sync(csock, buf, sizeof(buf)); 313 if (ret < 0) { 314 return ret; 315 } 316 317 if (ret != sizeof(buf)) { 318 LOG("writing to socket failed"); 319 return -EINVAL; 320 } 321 return 0; 322 } 323 324 ssize_t nbd_receive_reply(int csock, struct nbd_reply *reply) 325 { 326 uint8_t buf[NBD_REPLY_SIZE]; 327 uint32_t magic; 328 ssize_t ret; 329 330 ret = read_sync(csock, buf, sizeof(buf)); 331 if (ret < 0) { 332 return ret; 333 } 334 335 if (ret != sizeof(buf)) { 336 LOG("read failed"); 337 return -EINVAL; 338 } 339 340 /* Reply 341 [ 0 .. 3] magic (NBD_REPLY_MAGIC) 342 [ 4 .. 7] error (0 == no error) 343 [ 7 .. 15] handle 344 */ 345 346 magic = be32_to_cpup((uint32_t*)buf); 347 reply->error = be32_to_cpup((uint32_t*)(buf + 4)); 348 reply->handle = be64_to_cpup((uint64_t*)(buf + 8)); 349 350 reply->error = nbd_errno_to_system_errno(reply->error); 351 352 TRACE("Got reply: " 353 "{ magic = 0x%x, .error = %d, handle = %" PRIu64" }", 354 magic, reply->error, reply->handle); 355 356 if (magic != NBD_REPLY_MAGIC) { 357 LOG("invalid magic (got 0x%x)", magic); 358 return -EINVAL; 359 } 360 return 0; 361 } 362 363