qemu/nbd/client.c
<<
>>
Prefs
   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 "qapi/error.h"
  21#include "nbd-internal.h"
  22
  23static int nbd_errno_to_system_errno(int err)
  24{
  25    switch (err) {
  26    case NBD_SUCCESS:
  27        return 0;
  28    case NBD_EPERM:
  29        return EPERM;
  30    case NBD_EIO:
  31        return EIO;
  32    case NBD_ENOMEM:
  33        return ENOMEM;
  34    case NBD_ENOSPC:
  35        return ENOSPC;
  36    case NBD_EINVAL:
  37    default:
  38        return EINVAL;
  39    }
  40}
  41
  42/* Definitions for opaque data types */
  43
  44static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
  45
  46/* That's all folks */
  47
  48/* Basic flow for negotiation
  49
  50   Server         Client
  51   Negotiate
  52
  53   or
  54
  55   Server         Client
  56   Negotiate #1
  57                  Option
  58   Negotiate #2
  59
  60   ----
  61
  62   followed by
  63
  64   Server         Client
  65                  Request
  66   Response
  67                  Request
  68   Response
  69                  ...
  70   ...
  71                  Request (type == 2)
  72
  73*/
  74
  75
  76/* If type represents success, return 1 without further action.
  77 * If type represents an error reply, consume the rest of the packet on ioc.
  78 * Then return 0 for unsupported (so the client can fall back to
  79 * other approaches), or -1 with errp set for other errors.
  80 */
  81static int nbd_handle_reply_err(QIOChannel *ioc, uint32_t opt, uint32_t type,
  82                                Error **errp)
  83{
  84    uint32_t len;
  85    char *msg = NULL;
  86    int result = -1;
  87
  88    if (!(type & (1 << 31))) {
  89        return 1;
  90    }
  91
  92    if (read_sync(ioc, &len, sizeof(len)) != sizeof(len)) {
  93        error_setg(errp, "failed to read option length");
  94        return -1;
  95    }
  96    len = be32_to_cpu(len);
  97    if (len) {
  98        if (len > NBD_MAX_BUFFER_SIZE) {
  99            error_setg(errp, "server's error message is too long");
 100            goto cleanup;
 101        }
 102        msg = g_malloc(len + 1);
 103        if (read_sync(ioc, msg, len) != len) {
 104            error_setg(errp, "failed to read option error message");
 105            goto cleanup;
 106        }
 107        msg[len] = '\0';
 108    }
 109
 110    switch (type) {
 111    case NBD_REP_ERR_UNSUP:
 112        TRACE("server doesn't understand request %" PRIx32
 113              ", attempting fallback", opt);
 114        result = 0;
 115        goto cleanup;
 116
 117    case NBD_REP_ERR_POLICY:
 118        error_setg(errp, "Denied by server for option %" PRIx32, opt);
 119        break;
 120
 121    case NBD_REP_ERR_INVALID:
 122        error_setg(errp, "Invalid data length for option %" PRIx32, opt);
 123        break;
 124
 125    case NBD_REP_ERR_TLS_REQD:
 126        error_setg(errp, "TLS negotiation required before option %" PRIx32,
 127                   opt);
 128        break;
 129
 130    default:
 131        error_setg(errp, "Unknown error code when asking for option %" PRIx32,
 132                   opt);
 133        break;
 134    }
 135
 136    if (msg) {
 137        error_append_hint(errp, "%s\n", msg);
 138    }
 139
 140 cleanup:
 141    g_free(msg);
 142    return result;
 143}
 144
 145static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp)
 146{
 147    uint64_t magic;
 148    uint32_t opt;
 149    uint32_t type;
 150    uint32_t len;
 151    uint32_t namelen;
 152    int error;
 153
 154    *name = NULL;
 155    if (read_sync(ioc, &magic, sizeof(magic)) != sizeof(magic)) {
 156        error_setg(errp, "failed to read list option magic");
 157        return -1;
 158    }
 159    magic = be64_to_cpu(magic);
 160    if (magic != NBD_REP_MAGIC) {
 161        error_setg(errp, "Unexpected option list magic");
 162        return -1;
 163    }
 164    if (read_sync(ioc, &opt, sizeof(opt)) != sizeof(opt)) {
 165        error_setg(errp, "failed to read list option");
 166        return -1;
 167    }
 168    opt = be32_to_cpu(opt);
 169    if (opt != NBD_OPT_LIST) {
 170        error_setg(errp, "Unexpected option type %" PRIx32 " expected %x",
 171                   opt, NBD_OPT_LIST);
 172        return -1;
 173    }
 174
 175    if (read_sync(ioc, &type, sizeof(type)) != sizeof(type)) {
 176        error_setg(errp, "failed to read list option type");
 177        return -1;
 178    }
 179    type = be32_to_cpu(type);
 180    error = nbd_handle_reply_err(ioc, opt, type, errp);
 181    if (error <= 0) {
 182        return error;
 183    }
 184
 185    if (read_sync(ioc, &len, sizeof(len)) != sizeof(len)) {
 186        error_setg(errp, "failed to read option length");
 187        return -1;
 188    }
 189    len = be32_to_cpu(len);
 190
 191    if (type == NBD_REP_ACK) {
 192        if (len != 0) {
 193            error_setg(errp, "length too long for option end");
 194            return -1;
 195        }
 196    } else if (type == NBD_REP_SERVER) {
 197        if (len < sizeof(namelen) || len > NBD_MAX_BUFFER_SIZE) {
 198            error_setg(errp, "incorrect option length");
 199            return -1;
 200        }
 201        if (read_sync(ioc, &namelen, sizeof(namelen)) != sizeof(namelen)) {
 202            error_setg(errp, "failed to read option name length");
 203            return -1;
 204        }
 205        namelen = be32_to_cpu(namelen);
 206        len -= sizeof(namelen);
 207        if (len < namelen) {
 208            error_setg(errp, "incorrect option name length");
 209            return -1;
 210        }
 211        if (namelen > 255) {
 212            error_setg(errp, "export name length too long %" PRIu32, namelen);
 213            return -1;
 214        }
 215
 216        *name = g_new0(char, namelen + 1);
 217        if (read_sync(ioc, *name, namelen) != namelen) {
 218            error_setg(errp, "failed to read export name");
 219            g_free(*name);
 220            *name = NULL;
 221            return -1;
 222        }
 223        (*name)[namelen] = '\0';
 224        len -= namelen;
 225        if (len) {
 226            char *buf = g_malloc(len + 1);
 227            if (read_sync(ioc, buf, len) != len) {
 228                error_setg(errp, "failed to read export description");
 229                g_free(*name);
 230                g_free(buf);
 231                *name = NULL;
 232                return -1;
 233            }
 234            buf[len] = '\0';
 235            TRACE("Ignoring export description: %s", buf);
 236            g_free(buf);
 237        }
 238    } else {
 239        error_setg(errp, "Unexpected reply type %" PRIx32 " expected %x",
 240                   type, NBD_REP_SERVER);
 241        return -1;
 242    }
 243    return 1;
 244}
 245
 246
 247static int nbd_receive_query_exports(QIOChannel *ioc,
 248                                     const char *wantname,
 249                                     Error **errp)
 250{
 251    uint64_t magic = cpu_to_be64(NBD_OPTS_MAGIC);
 252    uint32_t opt = cpu_to_be32(NBD_OPT_LIST);
 253    uint32_t length = 0;
 254    bool foundExport = false;
 255
 256    TRACE("Querying export list");
 257    if (write_sync(ioc, &magic, sizeof(magic)) != sizeof(magic)) {
 258        error_setg(errp, "Failed to send list option magic");
 259        return -1;
 260    }
 261
 262    if (write_sync(ioc, &opt, sizeof(opt)) != sizeof(opt)) {
 263        error_setg(errp, "Failed to send list option number");
 264        return -1;
 265    }
 266
 267    if (write_sync(ioc, &length, sizeof(length)) != sizeof(length)) {
 268        error_setg(errp, "Failed to send list option length");
 269        return -1;
 270    }
 271
 272    TRACE("Reading available export names");
 273    while (1) {
 274        char *name = NULL;
 275        int ret = nbd_receive_list(ioc, &name, errp);
 276
 277        if (ret < 0) {
 278            g_free(name);
 279            name = NULL;
 280            return -1;
 281        }
 282        if (ret == 0) {
 283            /* Server doesn't support export listing, so
 284             * we will just assume an export with our
 285             * wanted name exists */
 286            foundExport = true;
 287            break;
 288        }
 289        if (name == NULL) {
 290            TRACE("End of export name list");
 291            break;
 292        }
 293        if (g_str_equal(name, wantname)) {
 294            foundExport = true;
 295            TRACE("Found desired export name '%s'", name);
 296        } else {
 297            TRACE("Ignored export name '%s'", name);
 298        }
 299        g_free(name);
 300    }
 301
 302    if (!foundExport) {
 303        error_setg(errp, "No export with name '%s' available", wantname);
 304        return -1;
 305    }
 306
 307    return 0;
 308}
 309
 310static QIOChannel *nbd_receive_starttls(QIOChannel *ioc,
 311                                        QCryptoTLSCreds *tlscreds,
 312                                        const char *hostname, Error **errp)
 313{
 314    uint64_t magic = cpu_to_be64(NBD_OPTS_MAGIC);
 315    uint32_t opt = cpu_to_be32(NBD_OPT_STARTTLS);
 316    uint32_t length = 0;
 317    uint32_t type;
 318    QIOChannelTLS *tioc;
 319    struct NBDTLSHandshakeData data = { 0 };
 320
 321    TRACE("Requesting TLS from server");
 322    if (write_sync(ioc, &magic, sizeof(magic)) != sizeof(magic)) {
 323        error_setg(errp, "Failed to send option magic");
 324        return NULL;
 325    }
 326
 327    if (write_sync(ioc, &opt, sizeof(opt)) != sizeof(opt)) {
 328        error_setg(errp, "Failed to send option number");
 329        return NULL;
 330    }
 331
 332    if (write_sync(ioc, &length, sizeof(length)) != sizeof(length)) {
 333        error_setg(errp, "Failed to send option length");
 334        return NULL;
 335    }
 336
 337    TRACE("Getting TLS reply from server1");
 338    if (read_sync(ioc, &magic, sizeof(magic)) != sizeof(magic)) {
 339        error_setg(errp, "failed to read option magic");
 340        return NULL;
 341    }
 342    magic = be64_to_cpu(magic);
 343    if (magic != NBD_REP_MAGIC) {
 344        error_setg(errp, "Unexpected option magic");
 345        return NULL;
 346    }
 347    TRACE("Getting TLS reply from server2");
 348    if (read_sync(ioc, &opt, sizeof(opt)) != sizeof(opt)) {
 349        error_setg(errp, "failed to read option");
 350        return NULL;
 351    }
 352    opt = be32_to_cpu(opt);
 353    if (opt != NBD_OPT_STARTTLS) {
 354        error_setg(errp, "Unexpected option type %" PRIx32 " expected %x",
 355                   opt, NBD_OPT_STARTTLS);
 356        return NULL;
 357    }
 358
 359    TRACE("Getting TLS reply from server");
 360    if (read_sync(ioc, &type, sizeof(type)) != sizeof(type)) {
 361        error_setg(errp, "failed to read option type");
 362        return NULL;
 363    }
 364    type = be32_to_cpu(type);
 365    if (type != NBD_REP_ACK) {
 366        error_setg(errp, "Server rejected request to start TLS %" PRIx32,
 367                   type);
 368        return NULL;
 369    }
 370
 371    TRACE("Getting TLS reply from server");
 372    if (read_sync(ioc, &length, sizeof(length)) != sizeof(length)) {
 373        error_setg(errp, "failed to read option length");
 374        return NULL;
 375    }
 376    length = be32_to_cpu(length);
 377    if (length != 0) {
 378        error_setg(errp, "Start TLS response was not zero %" PRIu32,
 379                   length);
 380        return NULL;
 381    }
 382
 383    TRACE("TLS request approved, setting up TLS");
 384    tioc = qio_channel_tls_new_client(ioc, tlscreds, hostname, errp);
 385    if (!tioc) {
 386        return NULL;
 387    }
 388    data.loop = g_main_loop_new(g_main_context_default(), FALSE);
 389    TRACE("Starting TLS handshake");
 390    qio_channel_tls_handshake(tioc,
 391                              nbd_tls_handshake,
 392                              &data,
 393                              NULL);
 394
 395    if (!data.complete) {
 396        g_main_loop_run(data.loop);
 397    }
 398    g_main_loop_unref(data.loop);
 399    if (data.error) {
 400        error_propagate(errp, data.error);
 401        object_unref(OBJECT(tioc));
 402        return NULL;
 403    }
 404
 405    return QIO_CHANNEL(tioc);
 406}
 407
 408
 409int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags,
 410                          QCryptoTLSCreds *tlscreds, const char *hostname,
 411                          QIOChannel **outioc,
 412                          off_t *size, Error **errp)
 413{
 414    char buf[256];
 415    uint64_t magic, s;
 416    int rc;
 417
 418    TRACE("Receiving negotiation tlscreds=%p hostname=%s.",
 419          tlscreds, hostname ? hostname : "<null>");
 420
 421    rc = -EINVAL;
 422
 423    if (outioc) {
 424        *outioc = NULL;
 425    }
 426    if (tlscreds && !outioc) {
 427        error_setg(errp, "Output I/O channel required for TLS");
 428        goto fail;
 429    }
 430
 431    if (read_sync(ioc, buf, 8) != 8) {
 432        error_setg(errp, "Failed to read data");
 433        goto fail;
 434    }
 435
 436    buf[8] = '\0';
 437    if (strlen(buf) == 0) {
 438        error_setg(errp, "Server connection closed unexpectedly");
 439        goto fail;
 440    }
 441
 442    TRACE("Magic is %c%c%c%c%c%c%c%c",
 443          qemu_isprint(buf[0]) ? buf[0] : '.',
 444          qemu_isprint(buf[1]) ? buf[1] : '.',
 445          qemu_isprint(buf[2]) ? buf[2] : '.',
 446          qemu_isprint(buf[3]) ? buf[3] : '.',
 447          qemu_isprint(buf[4]) ? buf[4] : '.',
 448          qemu_isprint(buf[5]) ? buf[5] : '.',
 449          qemu_isprint(buf[6]) ? buf[6] : '.',
 450          qemu_isprint(buf[7]) ? buf[7] : '.');
 451
 452    if (memcmp(buf, "NBDMAGIC", 8) != 0) {
 453        error_setg(errp, "Invalid magic received");
 454        goto fail;
 455    }
 456
 457    if (read_sync(ioc, &magic, sizeof(magic)) != sizeof(magic)) {
 458        error_setg(errp, "Failed to read magic");
 459        goto fail;
 460    }
 461    magic = be64_to_cpu(magic);
 462    TRACE("Magic is 0x%" PRIx64, magic);
 463
 464    if (magic == NBD_OPTS_MAGIC) {
 465        uint32_t clientflags = 0;
 466        uint32_t opt;
 467        uint32_t namesize;
 468        uint16_t globalflags;
 469        bool fixedNewStyle = false;
 470
 471        if (read_sync(ioc, &globalflags, sizeof(globalflags)) !=
 472            sizeof(globalflags)) {
 473            error_setg(errp, "Failed to read server flags");
 474            goto fail;
 475        }
 476        globalflags = be16_to_cpu(globalflags);
 477        TRACE("Global flags are %" PRIx32, globalflags);
 478        if (globalflags & NBD_FLAG_FIXED_NEWSTYLE) {
 479            fixedNewStyle = true;
 480            TRACE("Server supports fixed new style");
 481            clientflags |= NBD_FLAG_C_FIXED_NEWSTYLE;
 482        }
 483        /* client requested flags */
 484        clientflags = cpu_to_be32(clientflags);
 485        if (write_sync(ioc, &clientflags, sizeof(clientflags)) !=
 486            sizeof(clientflags)) {
 487            error_setg(errp, "Failed to send clientflags field");
 488            goto fail;
 489        }
 490        if (tlscreds) {
 491            if (fixedNewStyle) {
 492                *outioc = nbd_receive_starttls(ioc, tlscreds, hostname, errp);
 493                if (!*outioc) {
 494                    goto fail;
 495                }
 496                ioc = *outioc;
 497            } else {
 498                error_setg(errp, "Server does not support STARTTLS");
 499                goto fail;
 500            }
 501        }
 502        if (!name) {
 503            TRACE("Using default NBD export name \"\"");
 504            name = "";
 505        }
 506        if (fixedNewStyle) {
 507            /* Check our desired export is present in the
 508             * server export list. Since NBD_OPT_EXPORT_NAME
 509             * cannot return an error message, running this
 510             * query gives us good error reporting if the
 511             * server required TLS
 512             */
 513            if (nbd_receive_query_exports(ioc, name, errp) < 0) {
 514                goto fail;
 515            }
 516        }
 517        /* write the export name */
 518        magic = cpu_to_be64(magic);
 519        if (write_sync(ioc, &magic, sizeof(magic)) != sizeof(magic)) {
 520            error_setg(errp, "Failed to send export name magic");
 521            goto fail;
 522        }
 523        opt = cpu_to_be32(NBD_OPT_EXPORT_NAME);
 524        if (write_sync(ioc, &opt, sizeof(opt)) != sizeof(opt)) {
 525            error_setg(errp, "Failed to send export name option number");
 526            goto fail;
 527        }
 528        namesize = cpu_to_be32(strlen(name));
 529        if (write_sync(ioc, &namesize, sizeof(namesize)) !=
 530            sizeof(namesize)) {
 531            error_setg(errp, "Failed to send export name length");
 532            goto fail;
 533        }
 534        if (write_sync(ioc, (char *)name, strlen(name)) != strlen(name)) {
 535            error_setg(errp, "Failed to send export name");
 536            goto fail;
 537        }
 538
 539        if (read_sync(ioc, &s, sizeof(s)) != sizeof(s)) {
 540            error_setg(errp, "Failed to read export length");
 541            goto fail;
 542        }
 543        *size = be64_to_cpu(s);
 544
 545        if (read_sync(ioc, flags, sizeof(*flags)) != sizeof(*flags)) {
 546            error_setg(errp, "Failed to read export flags");
 547            goto fail;
 548        }
 549        be16_to_cpus(flags);
 550    } else if (magic == NBD_CLIENT_MAGIC) {
 551        uint32_t oldflags;
 552
 553        if (name) {
 554            error_setg(errp, "Server does not support export names");
 555            goto fail;
 556        }
 557        if (tlscreds) {
 558            error_setg(errp, "Server does not support STARTTLS");
 559            goto fail;
 560        }
 561
 562        if (read_sync(ioc, &s, sizeof(s)) != sizeof(s)) {
 563            error_setg(errp, "Failed to read export length");
 564            goto fail;
 565        }
 566        *size = be64_to_cpu(s);
 567        TRACE("Size is %" PRIu64, *size);
 568
 569        if (read_sync(ioc, &oldflags, sizeof(oldflags)) != sizeof(oldflags)) {
 570            error_setg(errp, "Failed to read export flags");
 571            goto fail;
 572        }
 573        be32_to_cpus(&oldflags);
 574        if (oldflags & ~0xffff) {
 575            error_setg(errp, "Unexpected export flags %0x" PRIx32, oldflags);
 576            goto fail;
 577        }
 578        *flags = oldflags;
 579    } else {
 580        error_setg(errp, "Bad magic received");
 581        goto fail;
 582    }
 583
 584    TRACE("Size is %" PRIu64 ", export flags %" PRIx16, *size, *flags);
 585    if (read_sync(ioc, &buf, 124) != 124) {
 586        error_setg(errp, "Failed to read reserved block");
 587        goto fail;
 588    }
 589    rc = 0;
 590
 591fail:
 592    return rc;
 593}
 594
 595#ifdef __linux__
 596int nbd_init(int fd, QIOChannelSocket *sioc, uint16_t flags, off_t size)
 597{
 598    TRACE("Setting NBD socket");
 599
 600    if (ioctl(fd, NBD_SET_SOCK, sioc->fd) < 0) {
 601        int serrno = errno;
 602        LOG("Failed to set NBD socket");
 603        return -serrno;
 604    }
 605
 606    TRACE("Setting block size to %lu", (unsigned long)BDRV_SECTOR_SIZE);
 607
 608    if (ioctl(fd, NBD_SET_BLKSIZE, (size_t)BDRV_SECTOR_SIZE) < 0) {
 609        int serrno = errno;
 610        LOG("Failed setting NBD block size");
 611        return -serrno;
 612    }
 613
 614    TRACE("Setting size to %zd block(s)", (size_t)(size / BDRV_SECTOR_SIZE));
 615
 616    if (ioctl(fd, NBD_SET_SIZE_BLOCKS, (size_t)(size / BDRV_SECTOR_SIZE)) < 0) {
 617        int serrno = errno;
 618        LOG("Failed setting size (in blocks)");
 619        return -serrno;
 620    }
 621
 622    if (ioctl(fd, NBD_SET_FLAGS, flags) < 0) {
 623        if (errno == ENOTTY) {
 624            int read_only = (flags & NBD_FLAG_READ_ONLY) != 0;
 625            TRACE("Setting readonly attribute");
 626
 627            if (ioctl(fd, BLKROSET, (unsigned long) &read_only) < 0) {
 628                int serrno = errno;
 629                LOG("Failed setting read-only attribute");
 630                return -serrno;
 631            }
 632        } else {
 633            int serrno = errno;
 634            LOG("Failed setting flags");
 635            return -serrno;
 636        }
 637    }
 638
 639    TRACE("Negotiation ended");
 640
 641    return 0;
 642}
 643
 644int nbd_client(int fd)
 645{
 646    int ret;
 647    int serrno;
 648
 649    TRACE("Doing NBD loop");
 650
 651    ret = ioctl(fd, NBD_DO_IT);
 652    if (ret < 0 && errno == EPIPE) {
 653        /* NBD_DO_IT normally returns EPIPE when someone has disconnected
 654         * the socket via NBD_DISCONNECT.  We do not want to return 1 in
 655         * that case.
 656         */
 657        ret = 0;
 658    }
 659    serrno = errno;
 660
 661    TRACE("NBD loop returned %d: %s", ret, strerror(serrno));
 662
 663    TRACE("Clearing NBD queue");
 664    ioctl(fd, NBD_CLEAR_QUE);
 665
 666    TRACE("Clearing NBD socket");
 667    ioctl(fd, NBD_CLEAR_SOCK);
 668
 669    errno = serrno;
 670    return ret;
 671}
 672#else
 673int nbd_init(int fd, QIOChannelSocket *ioc, uint16_t flags, off_t size)
 674{
 675    return -ENOTSUP;
 676}
 677
 678int nbd_client(int fd)
 679{
 680    return -ENOTSUP;
 681}
 682#endif
 683
 684ssize_t nbd_send_request(QIOChannel *ioc, struct nbd_request *request)
 685{
 686    uint8_t buf[NBD_REQUEST_SIZE];
 687    ssize_t ret;
 688
 689    TRACE("Sending request to server: "
 690          "{ .from = %" PRIu64", .len = %" PRIu32 ", .handle = %" PRIu64
 691          ", .type=%" PRIu16 " }",
 692          request->from, request->len, request->handle, request->type);
 693
 694    cpu_to_be32w((uint32_t*)buf, NBD_REQUEST_MAGIC);
 695    cpu_to_be32w((uint32_t*)(buf + 4), request->type);
 696    cpu_to_be64w((uint64_t*)(buf + 8), request->handle);
 697    cpu_to_be64w((uint64_t*)(buf + 16), request->from);
 698    cpu_to_be32w((uint32_t*)(buf + 24), request->len);
 699
 700    ret = write_sync(ioc, buf, sizeof(buf));
 701    if (ret < 0) {
 702        return ret;
 703    }
 704
 705    if (ret != sizeof(buf)) {
 706        LOG("writing to socket failed");
 707        return -EINVAL;
 708    }
 709    return 0;
 710}
 711
 712ssize_t nbd_receive_reply(QIOChannel *ioc, struct nbd_reply *reply)
 713{
 714    uint8_t buf[NBD_REPLY_SIZE];
 715    uint32_t magic;
 716    ssize_t ret;
 717
 718    ret = read_sync(ioc, buf, sizeof(buf));
 719    if (ret < 0) {
 720        return ret;
 721    }
 722
 723    if (ret != sizeof(buf)) {
 724        LOG("read failed");
 725        return -EINVAL;
 726    }
 727
 728    /* Reply
 729       [ 0 ..  3]    magic   (NBD_REPLY_MAGIC)
 730       [ 4 ..  7]    error   (0 == no error)
 731       [ 7 .. 15]    handle
 732     */
 733
 734    magic = ldl_be_p(buf);
 735    reply->error  = ldl_be_p(buf + 4);
 736    reply->handle = ldq_be_p(buf + 8);
 737
 738    reply->error = nbd_errno_to_system_errno(reply->error);
 739
 740    TRACE("Got reply: { magic = 0x%" PRIx32 ", .error = % " PRId32
 741          ", handle = %" PRIu64" }",
 742          magic, reply->error, reply->handle);
 743
 744    if (magic != NBD_REPLY_MAGIC) {
 745        LOG("invalid magic (got 0x%" PRIx32 ")", magic);
 746        return -EINVAL;
 747    }
 748    return 0;
 749}
 750
 751