server.c 50.9 KB
Newer Older
1
/*
2
 *  Copyright (C) 2016-2017 Red Hat, Inc.
B
bellard 已提交
3 4
 *  Copyright (C) 2005  Anthony Liguori <anthony@codemonkey.ws>
 *
F
Fam Zheng 已提交
5
 *  Network Block Device Server Side
B
bellard 已提交
6 7 8 9 10 11 12 13 14 15 16
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; under version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18
 */
B
bellard 已提交
19

P
Peter Maydell 已提交
20
#include "qemu/osdep.h"
21
#include "qapi/error.h"
22
#include "trace.h"
F
Fam Zheng 已提交
23
#include "nbd-internal.h"
24 25 26 27 28 29 30

static int system_errno_to_nbd_errno(int err)
{
    switch (err) {
    case 0:
        return NBD_SUCCESS;
    case EPERM:
31
    case EROFS:
32 33 34 35 36 37 38 39 40 41 42
        return NBD_EPERM;
    case EIO:
        return NBD_EIO;
    case ENOMEM:
        return NBD_ENOMEM;
#ifdef EDQUOT
    case EDQUOT:
#endif
    case EFBIG:
    case ENOSPC:
        return NBD_ENOSPC;
43 44
    case EOVERFLOW:
        return NBD_EOVERFLOW;
45 46
    case ESHUTDOWN:
        return NBD_ESHUTDOWN;
47 48 49 50 51 52
    case EINVAL:
    default:
        return NBD_EINVAL;
    }
}

53 54
/* Definitions for opaque data types */

55
typedef struct NBDRequestData NBDRequestData;
56

57 58
struct NBDRequestData {
    QSIMPLEQ_ENTRY(NBDRequestData) entry;
59 60
    NBDClient *client;
    uint8_t *data;
61
    bool complete;
62 63 64
};

struct NBDExport {
65
    int refcount;
66 67
    void (*close)(NBDExport *exp);

M
Max Reitz 已提交
68
    BlockBackend *blk;
P
Paolo Bonzini 已提交
69
    char *name;
70
    char *description;
71 72
    off_t dev_offset;
    off_t size;
E
Eric Blake 已提交
73
    uint16_t nbdflags;
74
    QTAILQ_HEAD(, NBDClient) clients;
P
Paolo Bonzini 已提交
75
    QTAILQ_ENTRY(NBDExport) next;
M
Max Reitz 已提交
76 77

    AioContext *ctx;
78

79
    BlockBackend *eject_notifier_blk;
80
    Notifier eject_notifier;
81 82
};

P
Paolo Bonzini 已提交
83 84
static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);

85 86
struct NBDClient {
    int refcount;
87
    void (*close_fn)(NBDClient *client, bool negotiated);
88 89

    NBDExport *exp;
90 91
    QCryptoTLSCreds *tlscreds;
    char *tlsaclname;
92 93
    QIOChannelSocket *sioc; /* The underlying data channel */
    QIOChannel *ioc; /* The current I/O channel which may differ (eg TLS) */
94 95 96 97 98 99

    Coroutine *recv_coroutine;

    CoMutex send_lock;
    Coroutine *send_coroutine;

100
    QTAILQ_ENTRY(NBDClient) next;
101
    int nb_requests;
102
    bool closing;
103 104

    bool structured_reply;
105 106
};

B
bellard 已提交
107 108
/* That's all folks */

109
static void nbd_client_receive_next_request(NBDClient *client);
M
Max Reitz 已提交
110

111
/* Basic flow for negotiation
B
bellard 已提交
112 113 114

   Server         Client
   Negotiate
115 116 117 118 119 120 121 122 123 124 125 126 127

   or

   Server         Client
   Negotiate #1
                  Option
   Negotiate #2

   ----

   followed by

   Server         Client
B
bellard 已提交
128 129 130 131 132 133 134
                  Request
   Response
                  Request
   Response
                  ...
   ...
                  Request (type == 2)
135

B
bellard 已提交
136 137
*/

138 139 140
/* Send a reply header, including length, but no payload.
 * Return -errno on error, 0 on success. */
static int nbd_negotiate_send_rep_len(QIOChannel *ioc, uint32_t type,
141
                                      uint32_t opt, uint32_t len, Error **errp)
142 143 144
{
    uint64_t magic;

145 146
    trace_nbd_negotiate_send_rep_len(opt, nbd_opt_lookup(opt),
                                     type, nbd_rep_lookup(type), len);
147

E
Eric Blake 已提交
148
    assert(len < NBD_MAX_BUFFER_SIZE);
149
    magic = cpu_to_be64(NBD_REP_MAGIC);
150 151
    if (nbd_write(ioc, &magic, sizeof(magic), errp) < 0) {
        error_prepend(errp, "write failed (rep magic): ");
152
        return -EINVAL;
153
    }
154

155
    opt = cpu_to_be32(opt);
156 157
    if (nbd_write(ioc, &opt, sizeof(opt), errp) < 0) {
        error_prepend(errp, "write failed (rep opt): ");
158
        return -EINVAL;
159
    }
160

161
    type = cpu_to_be32(type);
162 163
    if (nbd_write(ioc, &type, sizeof(type), errp) < 0) {
        error_prepend(errp, "write failed (rep type): ");
164
        return -EINVAL;
165
    }
166

167
    len = cpu_to_be32(len);
168 169
    if (nbd_write(ioc, &len, sizeof(len), errp) < 0) {
        error_prepend(errp, "write failed (rep data length): ");
170
        return -EINVAL;
171
    }
172 173
    return 0;
}
174

175 176
/* Send a reply header with default 0 length.
 * Return -errno on error, 0 on success. */
177 178
static int nbd_negotiate_send_rep(QIOChannel *ioc, uint32_t type, uint32_t opt,
                                  Error **errp)
179
{
180
    return nbd_negotiate_send_rep_len(ioc, type, opt, 0, errp);
181 182
}

183 184
/* Send an error reply.
 * Return -errno on error, 0 on success. */
185
static int GCC_FMT_ATTR(5, 6)
186
nbd_negotiate_send_rep_err(QIOChannel *ioc, uint32_t type,
187
                           uint32_t opt, Error **errp, const char *fmt, ...)
188 189 190 191 192 193 194 195 196 197 198
{
    va_list va;
    char *msg;
    int ret;
    size_t len;

    va_start(va, fmt);
    msg = g_strdup_vprintf(fmt, va);
    va_end(va);
    len = strlen(msg);
    assert(len < 4096);
199
    trace_nbd_negotiate_send_rep_err(msg);
200
    ret = nbd_negotiate_send_rep_len(ioc, type, opt, len, errp);
201 202 203
    if (ret < 0) {
        goto out;
    }
204 205
    if (nbd_write(ioc, msg, len, errp) < 0) {
        error_prepend(errp, "write failed (error message): ");
206 207 208 209
        ret = -EIO;
    } else {
        ret = 0;
    }
210

211 212 213 214 215
out:
    g_free(msg);
    return ret;
}

216 217
/* Send a single NBD_REP_SERVER reply to NBD_OPT_LIST, including payload.
 * Return -errno on error, 0 on success. */
218 219
static int nbd_negotiate_send_rep_list(QIOChannel *ioc, NBDExport *exp,
                                       Error **errp)
220
{
221
    size_t name_len, desc_len;
222
    uint32_t len;
223 224
    const char *name = exp->name ? exp->name : "";
    const char *desc = exp->description ? exp->description : "";
225
    int ret;
226

227
    trace_nbd_negotiate_send_rep_list(name, desc);
228 229
    name_len = strlen(name);
    desc_len = strlen(desc);
230
    len = name_len + desc_len + sizeof(len);
231 232
    ret = nbd_negotiate_send_rep_len(ioc, NBD_REP_SERVER, NBD_OPT_LIST, len,
                                     errp);
233 234
    if (ret < 0) {
        return ret;
235
    }
236

237
    len = cpu_to_be32(name_len);
238 239
    if (nbd_write(ioc, &len, sizeof(len), errp) < 0) {
        error_prepend(errp, "write failed (name length): ");
240 241
        return -EINVAL;
    }
242 243 244

    if (nbd_write(ioc, name, name_len, errp) < 0) {
        error_prepend(errp, "write failed (name buffer): ");
245 246
        return -EINVAL;
    }
247 248 249

    if (nbd_write(ioc, desc, desc_len, errp) < 0) {
        error_prepend(errp, "write failed (description buffer): ");
250 251
        return -EINVAL;
    }
252

253 254 255
    return 0;
}

256 257
/* Process the NBD_OPT_LIST command, with a potential series of replies.
 * Return -errno on error, 0 on success. */
258
static int nbd_negotiate_handle_list(NBDClient *client, Error **errp)
259 260 261 262 263
{
    NBDExport *exp;

    /* For each export, send a NBD_REP_SERVER reply. */
    QTAILQ_FOREACH(exp, &exports, next) {
264
        if (nbd_negotiate_send_rep_list(client->ioc, exp, errp)) {
265 266 267 268
            return -EINVAL;
        }
    }
    /* Finish with a NBD_REP_ACK. */
269
    return nbd_negotiate_send_rep(client->ioc, NBD_REP_ACK, NBD_OPT_LIST, errp);
270 271
}

E
Eric Blake 已提交
272 273
/* Send a reply to NBD_OPT_EXPORT_NAME.
 * Return -errno on error, 0 on success. */
274
static int nbd_negotiate_handle_export_name(NBDClient *client, uint32_t length,
275
                                            uint16_t myflags, bool no_zeroes,
276
                                            Error **errp)
277
{
278
    char name[NBD_MAX_NAME_SIZE + 1];
279
    char buf[NBD_REPLY_EXPORT_NAME_SIZE] = "";
280 281
    size_t len;
    int ret;
282

283 284
    /* Client sends:
        [20 ..  xx]   export name (length bytes)
285 286 287 288
       Server replies:
        [ 0 ..   7]   size
        [ 8 ..   9]   export flags
        [10 .. 133]   reserved     (0) [unless no_zeroes]
289
     */
290
    trace_nbd_negotiate_handle_export_name();
291
    if (length >= sizeof(name)) {
292
        error_setg(errp, "Bad length received");
293
        return -EINVAL;
294
    }
295 296
    if (nbd_read(client->ioc, name, length, errp) < 0) {
        error_prepend(errp, "read failed: ");
297
        return -EINVAL;
298 299 300
    }
    name[length] = '\0';

301
    trace_nbd_negotiate_handle_export_name_request(name);
302

303 304
    client->exp = nbd_export_find(name);
    if (!client->exp) {
305
        error_setg(errp, "export not found");
306
        return -EINVAL;
307 308
    }

309 310 311 312 313 314 315 316 317 318 319
    trace_nbd_negotiate_new_style_size_flags(client->exp->size,
                                             client->exp->nbdflags | myflags);
    stq_be_p(buf, client->exp->size);
    stw_be_p(buf + 8, client->exp->nbdflags | myflags);
    len = no_zeroes ? 10 : sizeof(buf);
    ret = nbd_write(client->ioc, buf, len, errp);
    if (ret < 0) {
        error_prepend(errp, "write failed: ");
        return ret;
    }

320 321
    QTAILQ_INSERT_TAIL(&client->exp->clients, client, next);
    nbd_export_get(client->exp);
322 323

    return 0;
324 325
}

E
Eric Blake 已提交
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
/* Send a single NBD_REP_INFO, with a buffer @buf of @length bytes.
 * The buffer does NOT include the info type prefix.
 * Return -errno on error, 0 if ready to send more. */
static int nbd_negotiate_send_info(NBDClient *client, uint32_t opt,
                                   uint16_t info, uint32_t length, void *buf,
                                   Error **errp)
{
    int rc;

    trace_nbd_negotiate_send_info(info, nbd_info_lookup(info), length);
    rc = nbd_negotiate_send_rep_len(client->ioc, NBD_REP_INFO, opt,
                                    sizeof(info) + length, errp);
    if (rc < 0) {
        return rc;
    }
    cpu_to_be16s(&info);
    if (nbd_write(client->ioc, &info, sizeof(info), errp) < 0) {
        return -EIO;
    }
    if (nbd_write(client->ioc, buf, length, errp) < 0) {
        return -EIO;
    }
    return 0;
}

/* Handle NBD_OPT_INFO and NBD_OPT_GO.
 * Return -errno on error, 0 if ready for next option, and 1 to move
 * into transmission phase.  */
static int nbd_negotiate_handle_info(NBDClient *client, uint32_t length,
                                     uint32_t opt, uint16_t myflags,
                                     Error **errp)
{
    int rc;
    char name[NBD_MAX_NAME_SIZE + 1];
    NBDExport *exp;
    uint16_t requests;
    uint16_t request;
    uint32_t namelen;
    bool sendname = false;
365 366
    bool blocksize = false;
    uint32_t sizes[3];
E
Eric Blake 已提交
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
    char buf[sizeof(uint64_t) + sizeof(uint16_t)];
    const char *msg;

    /* Client sends:
        4 bytes: L, name length (can be 0)
        L bytes: export name
        2 bytes: N, number of requests (can be 0)
        N * 2 bytes: N requests
    */
    if (length < sizeof(namelen) + sizeof(requests)) {
        msg = "overall request too short";
        goto invalid;
    }
    if (nbd_read(client->ioc, &namelen, sizeof(namelen), errp) < 0) {
        return -EIO;
    }
    be32_to_cpus(&namelen);
    length -= sizeof(namelen);
    if (namelen > length - sizeof(requests) || (length - namelen) % 2) {
        msg = "name length is incorrect";
        goto invalid;
    }
389 390 391 392
    if (namelen >= sizeof(name)) {
        msg = "name too long for qemu";
        goto invalid;
    }
E
Eric Blake 已提交
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417
    if (nbd_read(client->ioc, name, namelen, errp) < 0) {
        return -EIO;
    }
    name[namelen] = '\0';
    length -= namelen;
    trace_nbd_negotiate_handle_export_name_request(name);

    if (nbd_read(client->ioc, &requests, sizeof(requests), errp) < 0) {
        return -EIO;
    }
    be16_to_cpus(&requests);
    length -= sizeof(requests);
    trace_nbd_negotiate_handle_info_requests(requests);
    if (requests != length / sizeof(request)) {
        msg = "incorrect number of  requests for overall length";
        goto invalid;
    }
    while (requests--) {
        if (nbd_read(client->ioc, &request, sizeof(request), errp) < 0) {
            return -EIO;
        }
        be16_to_cpus(&request);
        length -= sizeof(request);
        trace_nbd_negotiate_handle_info_request(request,
                                                nbd_info_lookup(request));
418 419 420 421 422
        /* We care about NBD_INFO_NAME and NBD_INFO_BLOCK_SIZE;
         * everything else is either a request we don't know or
         * something we send regardless of request */
        switch (request) {
        case NBD_INFO_NAME:
E
Eric Blake 已提交
423
            sendname = true;
424 425 426 427
            break;
        case NBD_INFO_BLOCK_SIZE:
            blocksize = true;
            break;
E
Eric Blake 已提交
428 429
        }
    }
430
    assert(length == 0);
E
Eric Blake 已提交
431 432 433 434 435 436 437 438 439 440

    exp = nbd_export_find(name);
    if (!exp) {
        return nbd_negotiate_send_rep_err(client->ioc, NBD_REP_ERR_UNKNOWN,
                                          opt, errp, "export '%s' not present",
                                          name);
    }

    /* Don't bother sending NBD_INFO_NAME unless client requested it */
    if (sendname) {
441
        rc = nbd_negotiate_send_info(client, opt, NBD_INFO_NAME, namelen, name,
E
Eric Blake 已提交
442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459
                                     errp);
        if (rc < 0) {
            return rc;
        }
    }

    /* Send NBD_INFO_DESCRIPTION only if available, regardless of
     * client request */
    if (exp->description) {
        size_t len = strlen(exp->description);

        rc = nbd_negotiate_send_info(client, opt, NBD_INFO_DESCRIPTION,
                                     len, exp->description, errp);
        if (rc < 0) {
            return rc;
        }
    }

460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480
    /* Send NBD_INFO_BLOCK_SIZE always, but tweak the minimum size
     * according to whether the client requested it, and according to
     * whether this is OPT_INFO or OPT_GO. */
    /* minimum - 1 for back-compat, or 512 if client is new enough.
     * TODO: consult blk_bs(blk)->bl.request_alignment? */
    sizes[0] = (opt == NBD_OPT_INFO || blocksize) ? BDRV_SECTOR_SIZE : 1;
    /* preferred - Hard-code to 4096 for now.
     * TODO: is blk_bs(blk)->bl.opt_transfer appropriate? */
    sizes[1] = 4096;
    /* maximum - At most 32M, but smaller as appropriate. */
    sizes[2] = MIN(blk_get_max_transfer(exp->blk), NBD_MAX_BUFFER_SIZE);
    trace_nbd_negotiate_handle_info_block_size(sizes[0], sizes[1], sizes[2]);
    cpu_to_be32s(&sizes[0]);
    cpu_to_be32s(&sizes[1]);
    cpu_to_be32s(&sizes[2]);
    rc = nbd_negotiate_send_info(client, opt, NBD_INFO_BLOCK_SIZE,
                                 sizeof(sizes), sizes, errp);
    if (rc < 0) {
        return rc;
    }

E
Eric Blake 已提交
481 482 483 484 485 486 487 488 489 490 491
    /* Send NBD_INFO_EXPORT always */
    trace_nbd_negotiate_new_style_size_flags(exp->size,
                                             exp->nbdflags | myflags);
    stq_be_p(buf, exp->size);
    stw_be_p(buf + 8, exp->nbdflags | myflags);
    rc = nbd_negotiate_send_info(client, opt, NBD_INFO_EXPORT,
                                 sizeof(buf), buf, errp);
    if (rc < 0) {
        return rc;
    }

492 493 494 495 496 497 498 499 500 501 502 503
    /* If the client is just asking for NBD_OPT_INFO, but forgot to
     * request block sizes, return an error.
     * TODO: consult blk_bs(blk)->request_align, and only error if it
     * is not 1? */
    if (opt == NBD_OPT_INFO && !blocksize) {
        return nbd_negotiate_send_rep_err(client->ioc,
                                          NBD_REP_ERR_BLOCK_SIZE_REQD, opt,
                                          errp,
                                          "request NBD_INFO_BLOCK_SIZE to "
                                          "use this export");
    }

E
Eric Blake 已提交
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526
    /* Final reply */
    rc = nbd_negotiate_send_rep(client->ioc, NBD_REP_ACK, opt, errp);
    if (rc < 0) {
        return rc;
    }

    if (opt == NBD_OPT_GO) {
        client->exp = exp;
        QTAILQ_INSERT_TAIL(&client->exp->clients, client, next);
        nbd_export_get(client->exp);
        rc = 1;
    }
    return rc;

 invalid:
    if (nbd_drop(client->ioc, length, errp) < 0) {
        return -EIO;
    }
    return nbd_negotiate_send_rep_err(client->ioc, NBD_REP_ERR_INVALID, opt,
                                      errp, "%s", msg);
}


527 528
/* Handle NBD_OPT_STARTTLS. Return NULL to drop connection, or else the
 * new channel for all further (now-encrypted) communication. */
529
static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
530
                                                 Error **errp)
531 532 533 534 535
{
    QIOChannel *ioc;
    QIOChannelTLS *tioc;
    struct NBDTLSHandshakeData data = { 0 };

536
    trace_nbd_negotiate_handle_starttls();
537 538
    ioc = client->ioc;

539
    if (nbd_negotiate_send_rep(client->ioc, NBD_REP_ACK,
540
                               NBD_OPT_STARTTLS, errp) < 0) {
541 542
        return NULL;
    }
543 544 545 546

    tioc = qio_channel_tls_new_server(ioc,
                                      client->tlscreds,
                                      client->tlsaclname,
547
                                      errp);
548 549 550 551
    if (!tioc) {
        return NULL;
    }

552
    qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-server-tls");
553
    trace_nbd_negotiate_handle_starttls_handshake();
554 555 556 557 558 559 560 561 562 563 564 565
    data.loop = g_main_loop_new(g_main_context_default(), FALSE);
    qio_channel_tls_handshake(tioc,
                              nbd_tls_handshake,
                              &data,
                              NULL);

    if (!data.complete) {
        g_main_loop_run(data.loop);
    }
    g_main_loop_unref(data.loop);
    if (data.error) {
        object_unref(OBJECT(tioc));
566
        error_propagate(errp, data.error);
567 568 569 570 571 572
        return NULL;
    }

    return QIO_CHANNEL(tioc);
}

573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600
/* nbd_reject_length: Handle any unexpected payload.
 * @fatal requests that we quit talking to the client, even if we are able
 * to successfully send an error to the guest.
 * Return:
 * -errno  transmission error occurred or @fatal was requested, errp is set
 * 0       error message successfully sent to client, errp is not set
 */
static int nbd_reject_length(NBDClient *client, uint32_t length,
                             uint32_t option, bool fatal, Error **errp)
{
    int ret;

    assert(length);
    if (nbd_drop(client->ioc, length, errp) < 0) {
        return -EIO;
    }
    ret = nbd_negotiate_send_rep_err(client->ioc, NBD_REP_ERR_INVALID,
                                     option, errp,
                                     "option '%s' should have zero length",
                                     nbd_opt_lookup(option));
    if (fatal && !ret) {
        error_setg(errp, "option '%s' should have zero length",
                   nbd_opt_lookup(option));
        return -EINVAL;
    }
    return ret;
}

601
/* nbd_negotiate_options
E
Eric Blake 已提交
602 603
 * Process all NBD_OPT_* client option commands, during fixed newstyle
 * negotiation.
604
 * Return:
605 606 607 608
 * -errno  on error, errp is set
 * 0       on successful negotiation, errp is not set
 * 1       if client sent NBD_OPT_ABORT, i.e. on valid disconnect,
 *         errp is not set
609
 */
610 611
static int nbd_negotiate_options(NBDClient *client, uint16_t myflags,
                                 Error **errp)
612
{
M
Max Reitz 已提交
613
    uint32_t flags;
614
    bool fixedNewstyle = false;
615
    bool no_zeroes = false;
M
Max Reitz 已提交
616 617 618 619

    /* Client sends:
        [ 0 ..   3]   client flags

E
Eric Blake 已提交
620
       Then we loop until NBD_OPT_EXPORT_NAME or NBD_OPT_GO:
M
Max Reitz 已提交
621 622 623 624 625 626 627 628 629 630 631
        [ 0 ..   7]   NBD_OPTS_MAGIC
        [ 8 ..  11]   NBD option
        [12 ..  15]   Data length
        ...           Rest of request

        [ 0 ..   7]   NBD_OPTS_MAGIC
        [ 8 ..  11]   Second NBD option
        [12 ..  15]   Data length
        ...           Rest of request
    */

632 633
    if (nbd_read(client->ioc, &flags, sizeof(flags), errp) < 0) {
        error_prepend(errp, "read failed: ");
M
Max Reitz 已提交
634 635 636
        return -EIO;
    }
    be32_to_cpus(&flags);
637
    trace_nbd_negotiate_options_flags(flags);
638 639 640 641
    if (flags & NBD_FLAG_C_FIXED_NEWSTYLE) {
        fixedNewstyle = true;
        flags &= ~NBD_FLAG_C_FIXED_NEWSTYLE;
    }
E
Eric Blake 已提交
642
    if (flags & NBD_FLAG_C_NO_ZEROES) {
643
        no_zeroes = true;
E
Eric Blake 已提交
644 645
        flags &= ~NBD_FLAG_C_NO_ZEROES;
    }
646
    if (flags != 0) {
647
        error_setg(errp, "Unknown client flags 0x%" PRIx32 " received", flags);
648
        return -EINVAL;
M
Max Reitz 已提交
649 650
    }

651
    while (1) {
M
Max Reitz 已提交
652
        int ret;
653
        uint32_t option, length;
654 655
        uint64_t magic;

656 657
        if (nbd_read(client->ioc, &magic, sizeof(magic), errp) < 0) {
            error_prepend(errp, "read failed: ");
658 659
            return -EINVAL;
        }
660 661 662
        magic = be64_to_cpu(magic);
        trace_nbd_negotiate_options_check_magic(magic);
        if (magic != NBD_OPTS_MAGIC) {
663
            error_setg(errp, "Bad magic received");
664 665 666
            return -EINVAL;
        }

667 668
        if (nbd_read(client->ioc, &option,
                     sizeof(option), errp) < 0) {
669
            error_prepend(errp, "read failed: ");
670 671
            return -EINVAL;
        }
672
        option = be32_to_cpu(option);
673

674 675
        if (nbd_read(client->ioc, &length, sizeof(length), errp) < 0) {
            error_prepend(errp, "read failed: ");
676 677 678 679
            return -EINVAL;
        }
        length = be32_to_cpu(length);

680 681 682 683 684 685
        if (length > NBD_MAX_BUFFER_SIZE) {
            error_setg(errp, "len (%" PRIu32" ) is larger than max len (%u)",
                       length, NBD_MAX_BUFFER_SIZE);
            return -EINVAL;
        }

686 687
        trace_nbd_negotiate_options_check_option(option,
                                                 nbd_opt_lookup(option));
688 689 690 691
        if (client->tlscreds &&
            client->ioc == (QIOChannel *)client->sioc) {
            QIOChannel *tioc;
            if (!fixedNewstyle) {
692
                error_setg(errp, "Unsupported option 0x%" PRIx32, option);
693 694
                return -EINVAL;
            }
695
            switch (option) {
696
            case NBD_OPT_STARTTLS:
697 698 699 700 701 702 703
                if (length) {
                    /* Unconditionally drop the connection if the client
                     * can't start a TLS negotiation correctly */
                    return nbd_reject_length(client, length, option, true,
                                             errp);
                }
                tioc = nbd_negotiate_handle_starttls(client, errp);
704 705 706
                if (!tioc) {
                    return -EIO;
                }
707
                ret = 0;
708 709 710 711
                object_unref(OBJECT(client->ioc));
                client->ioc = QIO_CHANNEL(tioc);
                break;

712 713
            case NBD_OPT_EXPORT_NAME:
                /* No way to return an error to client, so drop connection */
714
                error_setg(errp, "Option 0x%x not permitted before TLS",
715
                           option);
716 717
                return -EINVAL;

718
            default:
719
                if (nbd_drop(client->ioc, length, errp) < 0) {
720 721
                    return -EIO;
                }
722 723
                ret = nbd_negotiate_send_rep_err(client->ioc,
                                                 NBD_REP_ERR_TLS_REQD,
724
                                                 option, errp,
725 726
                                                 "Option 0x%" PRIx32
                                                 "not permitted before TLS",
727
                                                 option);
728 729 730
                /* Let the client keep trying, unless they asked to
                 * quit. In this mode, we've already sent an error, so
                 * we can't ack the abort.  */
731
                if (option == NBD_OPT_ABORT) {
732
                    return 1;
733
                }
734
                break;
735 736
            }
        } else if (fixedNewstyle) {
737
            switch (option) {
738
            case NBD_OPT_LIST:
739 740 741 742 743 744
                if (length) {
                    ret = nbd_reject_length(client, length, option, false,
                                            errp);
                } else {
                    ret = nbd_negotiate_handle_list(client, errp);
                }
745 746 747
                break;

            case NBD_OPT_ABORT:
748 749 750
                /* NBD spec says we must try to reply before
                 * disconnecting, but that we must also tolerate
                 * guests that don't wait for our reply. */
751
                nbd_negotiate_send_rep(client->ioc, NBD_REP_ACK, option, NULL);
752
                return 1;
753 754

            case NBD_OPT_EXPORT_NAME:
755 756 757
                return nbd_negotiate_handle_export_name(client, length,
                                                        myflags, no_zeroes,
                                                        errp);
758

E
Eric Blake 已提交
759 760 761 762 763 764 765 766 767 768
            case NBD_OPT_INFO:
            case NBD_OPT_GO:
                ret = nbd_negotiate_handle_info(client, length, option,
                                                myflags, errp);
                if (ret == 1) {
                    assert(option == NBD_OPT_GO);
                    return 0;
                }
                break;

769
            case NBD_OPT_STARTTLS:
770 771 772 773
                if (length) {
                    ret = nbd_reject_length(client, length, option, false,
                                            errp);
                } else if (client->tlscreds) {
774 775
                    ret = nbd_negotiate_send_rep_err(client->ioc,
                                                     NBD_REP_ERR_INVALID,
776
                                                     option, errp,
777
                                                     "TLS already enabled");
778
                } else {
779 780
                    ret = nbd_negotiate_send_rep_err(client->ioc,
                                                     NBD_REP_ERR_POLICY,
781
                                                     option, errp,
782
                                                     "TLS not configured");
783
                }
784
                break;
785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801

            case NBD_OPT_STRUCTURED_REPLY:
                if (length) {
                    ret = nbd_reject_length(client, length, option, false,
                                            errp);
                } else if (client->structured_reply) {
                    ret = nbd_negotiate_send_rep_err(
                        client->ioc, NBD_REP_ERR_INVALID, option, errp,
                        "structured reply already negotiated");
                } else {
                    ret = nbd_negotiate_send_rep(client->ioc, NBD_REP_ACK,
                                                 option, errp);
                    client->structured_reply = true;
                    myflags |= NBD_FLAG_SEND_DF;
                }
                break;

802
            default:
803
                if (nbd_drop(client->ioc, length, errp) < 0) {
804 805
                    return -EIO;
                }
806 807
                ret = nbd_negotiate_send_rep_err(client->ioc,
                                                 NBD_REP_ERR_UNSUP,
808
                                                 option, errp,
809
                                                 "Unsupported option 0x%"
810 811
                                                 PRIx32 " (%s)", option,
                                                 nbd_opt_lookup(option));
812
                break;
813 814 815 816 817 818
            }
        } else {
            /*
             * If broken new-style we should drop the connection
             * for anything except NBD_OPT_EXPORT_NAME
             */
819
            switch (option) {
820
            case NBD_OPT_EXPORT_NAME:
821 822 823
                return nbd_negotiate_handle_export_name(client, length,
                                                        myflags, no_zeroes,
                                                        errp);
824 825

            default:
826 827
                error_setg(errp, "Unsupported option 0x%" PRIx32 " (%s)",
                           option, nbd_opt_lookup(option));
828
                return -EINVAL;
829
            }
830
        }
831 832 833
        if (ret < 0) {
            return ret;
        }
834 835 836
    }
}

837 838
/* nbd_negotiate
 * Return:
839 840 841 842
 * -errno  on error, errp is set
 * 0       on successful negotiation, errp is not set
 * 1       if client sent NBD_OPT_ABORT, i.e. on valid disconnect,
 *         errp is not set
843
 */
844
static coroutine_fn int nbd_negotiate(NBDClient *client, Error **errp)
B
bellard 已提交
845
{
846
    char buf[NBD_OLDSTYLE_NEGOTIATE_SIZE] = "";
847
    int ret;
E
Eric Blake 已提交
848
    const uint16_t myflags = (NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
849 850
                              NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA |
                              NBD_FLAG_SEND_WRITE_ZEROES);
851
    bool oldStyle;
N
Nick Thomas 已提交
852

853
    /* Old style negotiation header, no room for options
854 855
        [ 0 ..   7]   passwd       ("NBDMAGIC")
        [ 8 ..  15]   magic        (NBD_CLIENT_MAGIC)
N
Nick Thomas 已提交
856
        [16 ..  23]   size
857
        [24 ..  27]   export flags (zero-extended)
858 859
        [28 .. 151]   reserved     (0)

860
       New style negotiation header, client can send options
861 862 863
        [ 0 ..   7]   passwd       ("NBDMAGIC")
        [ 8 ..  15]   magic        (NBD_OPTS_MAGIC)
        [16 ..  17]   server flags (0)
E
Eric Blake 已提交
864
        ....options sent, ending in NBD_OPT_EXPORT_NAME or NBD_OPT_GO....
N
Nick Thomas 已提交
865 866
     */

867
    qio_channel_set_blocking(client->ioc, false, NULL);
868

869
    trace_nbd_negotiate_begin();
N
Nick Thomas 已提交
870
    memcpy(buf, "NBDMAGIC", 8);
871 872 873

    oldStyle = client->exp != NULL && !client->tlscreds;
    if (oldStyle) {
874 875
        trace_nbd_negotiate_old_style(client->exp->size,
                                      client->exp->nbdflags | myflags);
J
John Snow 已提交
876 877
        stq_be_p(buf + 8, NBD_CLIENT_MAGIC);
        stq_be_p(buf + 16, client->exp->size);
878
        stl_be_p(buf + 24, client->exp->nbdflags | myflags);
N
Nick Thomas 已提交
879

880 881
        if (nbd_write(client->ioc, buf, sizeof(buf), errp) < 0) {
            error_prepend(errp, "write failed: ");
882
            return -EINVAL;
883 884
        }
    } else {
885 886 887
        stq_be_p(buf + 8, NBD_OPTS_MAGIC);
        stw_be_p(buf + 16, NBD_FLAG_FIXED_NEWSTYLE | NBD_FLAG_NO_ZEROES);

888 889
        if (nbd_write(client->ioc, buf, 18, errp) < 0) {
            error_prepend(errp, "write failed: ");
890
            return -EINVAL;
891
        }
892
        ret = nbd_negotiate_options(client, myflags, errp);
893
        if (ret != 0) {
894 895 896
            if (ret < 0) {
                error_prepend(errp, "option negotiation failed: ");
            }
897
            return ret;
898
        }
N
Nick Thomas 已提交
899 900
    }

901
    trace_nbd_negotiate_success();
902 903

    return 0;
B
bellard 已提交
904 905
}

906 907
static int nbd_receive_request(QIOChannel *ioc, NBDRequest *request,
                               Error **errp)
908
{
P
Paolo Bonzini 已提交
909
    uint8_t buf[NBD_REQUEST_SIZE];
N
Nick Thomas 已提交
910
    uint32_t magic;
911
    int ret;
N
Nick Thomas 已提交
912

913
    ret = nbd_read(ioc, buf, sizeof(buf), errp);
914 915 916 917
    if (ret < 0) {
        return ret;
    }

N
Nick Thomas 已提交
918 919
    /* Request
       [ 0 ..  3]   magic   (NBD_REQUEST_MAGIC)
920 921
       [ 4 ..  5]   flags   (NBD_CMD_FLAG_FUA, ...)
       [ 6 ..  7]   type    (NBD_CMD_READ, ...)
N
Nick Thomas 已提交
922 923 924 925 926
       [ 8 .. 15]   handle
       [16 .. 23]   from
       [24 .. 27]   len
     */

927
    magic = ldl_be_p(buf);
928 929
    request->flags  = lduw_be_p(buf + 4);
    request->type   = lduw_be_p(buf + 6);
930 931 932
    request->handle = ldq_be_p(buf + 8);
    request->from   = ldq_be_p(buf + 16);
    request->len    = ldl_be_p(buf + 24);
N
Nick Thomas 已提交
933

934 935
    trace_nbd_receive_request(magic, request->flags, request->type,
                              request->from, request->len);
N
Nick Thomas 已提交
936 937

    if (magic != NBD_REQUEST_MAGIC) {
938
        error_setg(errp, "invalid magic (got 0x%" PRIx32 ")", magic);
939
        return -EINVAL;
N
Nick Thomas 已提交
940 941
    }
    return 0;
942 943
}

P
Paolo Bonzini 已提交
944 945
#define MAX_NBD_REQUESTS 16

946
void nbd_client_get(NBDClient *client)
947 948 949 950
{
    client->refcount++;
}

951
void nbd_client_put(NBDClient *client)
952 953
{
    if (--client->refcount == 0) {
954
        /* The last reference should be dropped by client->close,
M
Max Reitz 已提交
955
         * which is called by client_close.
956 957 958
         */
        assert(client->closing);

959
        qio_channel_detach_aio_context(client->ioc);
960 961
        object_unref(OBJECT(client->sioc));
        object_unref(OBJECT(client->ioc));
962 963 964 965
        if (client->tlscreds) {
            object_unref(OBJECT(client->tlscreds));
        }
        g_free(client->tlsaclname);
966 967 968 969
        if (client->exp) {
            QTAILQ_REMOVE(&client->exp->clients, client, next);
            nbd_export_put(client->exp);
        }
970 971 972 973
        g_free(client);
    }
}

974
static void client_close(NBDClient *client, bool negotiated)
975
{
976 977 978 979 980 981 982 983 984
    if (client->closing) {
        return;
    }

    client->closing = true;

    /* Force requests to finish.  They will drop their own references,
     * then we'll close the socket and free the NBDClient.
     */
985 986
    qio_channel_shutdown(client->ioc, QIO_CHANNEL_SHUTDOWN_BOTH,
                         NULL);
987 988

    /* Also tell the client, so that they release their reference.  */
989 990
    if (client->close_fn) {
        client->close_fn(client, negotiated);
991 992 993
    }
}

994
static NBDRequestData *nbd_request_get(NBDClient *client)
P
Paolo Bonzini 已提交
995
{
996
    NBDRequestData *req;
997

P
Paolo Bonzini 已提交
998 999 1000
    assert(client->nb_requests <= MAX_NBD_REQUESTS - 1);
    client->nb_requests++;

1001
    req = g_new0(NBDRequestData, 1);
1002 1003
    nbd_client_get(client);
    req->client = client;
P
Paolo Bonzini 已提交
1004 1005 1006
    return req;
}

1007
static void nbd_request_put(NBDRequestData *req)
P
Paolo Bonzini 已提交
1008
{
1009
    NBDClient *client = req->client;
1010

1011 1012 1013
    if (req->data) {
        qemu_vfree(req->data);
    }
1014
    g_free(req);
1015

M
Max Reitz 已提交
1016
    client->nb_requests--;
1017 1018
    nbd_client_receive_next_request(client);

1019
    nbd_client_put(client);
P
Paolo Bonzini 已提交
1020 1021
}

M
Max Reitz 已提交
1022
static void blk_aio_attached(AioContext *ctx, void *opaque)
M
Max Reitz 已提交
1023 1024 1025 1026
{
    NBDExport *exp = opaque;
    NBDClient *client;

1027
    trace_nbd_blk_aio_attached(exp->name, ctx);
M
Max Reitz 已提交
1028 1029 1030 1031

    exp->ctx = ctx;

    QTAILQ_FOREACH(client, &exp->clients, next) {
1032 1033 1034 1035 1036 1037 1038
        qio_channel_attach_aio_context(client->ioc, ctx);
        if (client->recv_coroutine) {
            aio_co_schedule(ctx, client->recv_coroutine);
        }
        if (client->send_coroutine) {
            aio_co_schedule(ctx, client->send_coroutine);
        }
M
Max Reitz 已提交
1039 1040 1041
    }
}

M
Max Reitz 已提交
1042
static void blk_aio_detach(void *opaque)
M
Max Reitz 已提交
1043 1044 1045 1046
{
    NBDExport *exp = opaque;
    NBDClient *client;

1047
    trace_nbd_blk_aio_detach(exp->name, exp->ctx);
M
Max Reitz 已提交
1048 1049

    QTAILQ_FOREACH(client, &exp->clients, next) {
1050
        qio_channel_detach_aio_context(client->ioc);
M
Max Reitz 已提交
1051 1052 1053 1054 1055
    }

    exp->ctx = NULL;
}

1056 1057 1058 1059 1060 1061
static void nbd_eject_notifier(Notifier *n, void *data)
{
    NBDExport *exp = container_of(n, NBDExport, eject_notifier);
    nbd_export_close(exp);
}

1062
NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size,
E
Eric Blake 已提交
1063
                          uint16_t nbdflags, void (*close)(NBDExport *),
1064
                          bool writethrough, BlockBackend *on_eject_blk,
M
Max Reitz 已提交
1065
                          Error **errp)
P
Paolo Bonzini 已提交
1066
{
1067
    AioContext *ctx;
1068
    BlockBackend *blk;
1069
    NBDExport *exp = g_new0(NBDExport, 1);
1070
    uint64_t perm;
1071
    int ret;
1072

1073 1074 1075 1076 1077 1078 1079 1080 1081 1082
    /*
     * NBD exports are used for non-shared storage migration.  Make sure
     * that BDRV_O_INACTIVE is cleared and the image is ready for write
     * access since the export could be available before migration handover.
     */
    ctx = bdrv_get_aio_context(bs);
    aio_context_acquire(ctx);
    bdrv_invalidate_cache(bs, NULL);
    aio_context_release(ctx);

1083 1084 1085 1086 1087 1088 1089 1090
    /* Don't allow resize while the NBD server is running, otherwise we don't
     * care what happens with the node. */
    perm = BLK_PERM_CONSISTENT_READ;
    if ((nbdflags & NBD_FLAG_READ_ONLY) == 0) {
        perm |= BLK_PERM_WRITE;
    }
    blk = blk_new(perm, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED |
                        BLK_PERM_WRITE | BLK_PERM_GRAPH_MOD);
1091 1092 1093 1094
    ret = blk_insert_bs(blk, bs, errp);
    if (ret < 0) {
        goto fail;
    }
1095 1096
    blk_set_enable_write_cache(blk, !writethrough);

1097
    exp->refcount = 1;
1098
    QTAILQ_INIT(&exp->clients);
M
Max Reitz 已提交
1099
    exp->blk = blk;
P
Paolo Bonzini 已提交
1100 1101
    exp->dev_offset = dev_offset;
    exp->nbdflags = nbdflags;
M
Max Reitz 已提交
1102 1103 1104 1105 1106 1107 1108 1109
    exp->size = size < 0 ? blk_getlength(blk) : size;
    if (exp->size < 0) {
        error_setg_errno(errp, -exp->size,
                         "Failed to determine the NBD export's length");
        goto fail;
    }
    exp->size -= exp->size % BDRV_SECTOR_SIZE;

1110
    exp->close = close;
M
Max Reitz 已提交
1111 1112
    exp->ctx = blk_get_aio_context(blk);
    blk_add_aio_context_notifier(blk, blk_aio_attached, blk_aio_detach, exp);
1113

1114 1115 1116 1117 1118 1119
    if (on_eject_blk) {
        blk_ref(on_eject_blk);
        exp->eject_notifier_blk = on_eject_blk;
        exp->eject_notifier.notify = nbd_eject_notifier;
        blk_add_remove_bs_notifier(on_eject_blk, &exp->eject_notifier);
    }
P
Paolo Bonzini 已提交
1120
    return exp;
M
Max Reitz 已提交
1121 1122

fail:
1123
    blk_unref(blk);
M
Max Reitz 已提交
1124 1125
    g_free(exp);
    return NULL;
P
Paolo Bonzini 已提交
1126 1127
}

P
Paolo Bonzini 已提交
1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160
NBDExport *nbd_export_find(const char *name)
{
    NBDExport *exp;
    QTAILQ_FOREACH(exp, &exports, next) {
        if (strcmp(name, exp->name) == 0) {
            return exp;
        }
    }

    return NULL;
}

void nbd_export_set_name(NBDExport *exp, const char *name)
{
    if (exp->name == name) {
        return;
    }

    nbd_export_get(exp);
    if (exp->name != NULL) {
        g_free(exp->name);
        exp->name = NULL;
        QTAILQ_REMOVE(&exports, exp, next);
        nbd_export_put(exp);
    }
    if (name != NULL) {
        nbd_export_get(exp);
        exp->name = g_strdup(name);
        QTAILQ_INSERT_TAIL(&exports, exp, next);
    }
    nbd_export_put(exp);
}

1161 1162 1163 1164 1165 1166
void nbd_export_set_description(NBDExport *exp, const char *description)
{
    g_free(exp->description);
    exp->description = g_strdup(description);
}

P
Paolo Bonzini 已提交
1167 1168
void nbd_export_close(NBDExport *exp)
{
1169
    NBDClient *client, *next;
1170

1171 1172
    nbd_export_get(exp);
    QTAILQ_FOREACH_SAFE(client, &exp->clients, next, next) {
1173
        client_close(client, true);
1174
    }
P
Paolo Bonzini 已提交
1175
    nbd_export_set_name(exp, NULL);
1176
    nbd_export_set_description(exp, NULL);
1177
    nbd_export_put(exp);
1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190
}

void nbd_export_get(NBDExport *exp)
{
    assert(exp->refcount > 0);
    exp->refcount++;
}

void nbd_export_put(NBDExport *exp)
{
    assert(exp->refcount > 0);
    if (exp->refcount == 1) {
        nbd_export_close(exp);
P
Paolo Bonzini 已提交
1191 1192
    }

1193
    if (--exp->refcount == 0) {
P
Paolo Bonzini 已提交
1194
        assert(exp->name == NULL);
1195
        assert(exp->description == NULL);
P
Paolo Bonzini 已提交
1196

1197 1198 1199 1200
        if (exp->close) {
            exp->close(exp);
        }

1201
        if (exp->blk) {
1202 1203 1204 1205
            if (exp->eject_notifier_blk) {
                notifier_remove(&exp->eject_notifier);
                blk_unref(exp->eject_notifier_blk);
            }
1206 1207 1208 1209 1210 1211
            blk_remove_aio_context_notifier(exp->blk, blk_aio_attached,
                                            blk_aio_detach, exp);
            blk_unref(exp->blk);
            exp->blk = NULL;
        }

1212 1213
        g_free(exp);
    }
P
Paolo Bonzini 已提交
1214 1215
}

1216
BlockBackend *nbd_export_get_blockdev(NBDExport *exp)
P
Paolo Bonzini 已提交
1217
{
M
Max Reitz 已提交
1218
    return exp->blk;
P
Paolo Bonzini 已提交
1219 1220
}

P
Paolo Bonzini 已提交
1221 1222 1223 1224 1225 1226 1227 1228 1229
void nbd_export_close_all(void)
{
    NBDExport *exp, *next;

    QTAILQ_FOREACH_SAFE(exp, &exports, next, next) {
        nbd_export_close(exp);
    }
}

1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246
static int coroutine_fn nbd_co_send_iov(NBDClient *client, struct iovec *iov,
                                        unsigned niov, Error **errp)
{
    int ret;

    g_assert(qemu_in_coroutine());
    qemu_co_mutex_lock(&client->send_lock);
    client->send_coroutine = qemu_coroutine_self();

    ret = qio_channel_writev_all(client->ioc, iov, niov, errp) < 0 ? -EIO : 0;

    client->send_coroutine = NULL;
    qemu_co_mutex_unlock(&client->send_lock);

    return ret;
}

1247 1248 1249 1250 1251 1252 1253 1254
static inline void set_be_simple_reply(NBDSimpleReply *reply, uint64_t error,
                                       uint64_t handle)
{
    stl_be_p(&reply->magic, NBD_SIMPLE_REPLY_MAGIC);
    stl_be_p(&reply->error, error);
    stq_be_p(&reply->handle, handle);
}

1255
static int nbd_co_send_simple_reply(NBDClient *client,
1256 1257
                                    uint64_t handle,
                                    uint32_t error,
1258 1259 1260
                                    void *data,
                                    size_t len,
                                    Error **errp)
1261
{
1262
    NBDSimpleReply reply;
1263
    int nbd_err = system_errno_to_nbd_errno(error);
1264 1265 1266 1267
    struct iovec iov[] = {
        {.iov_base = &reply, .iov_len = sizeof(reply)},
        {.iov_base = data, .iov_len = len}
    };
1268

1269 1270
    trace_nbd_co_send_simple_reply(handle, nbd_err, nbd_err_lookup(nbd_err),
                                   len);
1271
    set_be_simple_reply(&reply, nbd_err, handle);
P
Paolo Bonzini 已提交
1272

1273
    return nbd_co_send_iov(client, iov, len ? 2 : 1, errp);
1274 1275
}

1276 1277 1278 1279 1280 1281 1282 1283 1284 1285
static inline void set_be_chunk(NBDStructuredReplyChunk *chunk, uint16_t flags,
                                uint16_t type, uint64_t handle, uint32_t length)
{
    stl_be_p(&chunk->magic, NBD_STRUCTURED_REPLY_MAGIC);
    stw_be_p(&chunk->flags, flags);
    stw_be_p(&chunk->type, type);
    stq_be_p(&chunk->handle, handle);
    stl_be_p(&chunk->length, length);
}

1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300
static int coroutine_fn nbd_co_send_structured_done(NBDClient *client,
                                                    uint64_t handle,
                                                    Error **errp)
{
    NBDStructuredReplyChunk chunk;
    struct iovec iov[] = {
        {.iov_base = &chunk, .iov_len = sizeof(chunk)},
    };

    trace_nbd_co_send_structured_done(handle);
    set_be_chunk(&chunk, NBD_REPLY_FLAG_DONE, NBD_REPLY_TYPE_NONE, handle, 0);

    return nbd_co_send_iov(client, iov, 1, errp);
}

1301 1302 1303 1304 1305 1306 1307
static int coroutine_fn nbd_co_send_structured_read(NBDClient *client,
                                                    uint64_t handle,
                                                    uint64_t offset,
                                                    void *data,
                                                    size_t size,
                                                    Error **errp)
{
1308
    NBDStructuredReadData chunk;
1309 1310 1311 1312 1313
    struct iovec iov[] = {
        {.iov_base = &chunk, .iov_len = sizeof(chunk)},
        {.iov_base = data, .iov_len = size}
    };

1314
    assert(size);
1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325
    trace_nbd_co_send_structured_read(handle, offset, data, size);
    set_be_chunk(&chunk.h, NBD_REPLY_FLAG_DONE, NBD_REPLY_TYPE_OFFSET_DATA,
                 handle, sizeof(chunk) - sizeof(chunk.h) + size);
    stq_be_p(&chunk.offset, offset);

    return nbd_co_send_iov(client, iov, 2, errp);
}

static int coroutine_fn nbd_co_send_structured_error(NBDClient *client,
                                                     uint64_t handle,
                                                     uint32_t error,
1326
                                                     const char *msg,
1327 1328 1329 1330 1331 1332
                                                     Error **errp)
{
    NBDStructuredError chunk;
    int nbd_err = system_errno_to_nbd_errno(error);
    struct iovec iov[] = {
        {.iov_base = &chunk, .iov_len = sizeof(chunk)},
1333
        {.iov_base = (char *)msg, .iov_len = msg ? strlen(msg) : 0},
1334 1335 1336 1337
    };

    assert(nbd_err);
    trace_nbd_co_send_structured_error(handle, nbd_err,
1338
                                       nbd_err_lookup(nbd_err), msg ? msg : "");
1339
    set_be_chunk(&chunk.h, NBD_REPLY_FLAG_DONE, NBD_REPLY_TYPE_ERROR, handle,
1340
                 sizeof(chunk) - sizeof(chunk.h) + iov[1].iov_len);
1341
    stl_be_p(&chunk.error, nbd_err);
1342
    stw_be_p(&chunk.message_length, iov[1].iov_len);
1343

1344
    return nbd_co_send_iov(client, iov, 1 + !!iov[1].iov_len, errp);
1345 1346
}

1347 1348 1349 1350 1351 1352
/* nbd_co_receive_request
 * Collect a client request. Return 0 if request looks valid, -EIO to drop
 * connection right away, and any other negative value to report an error to
 * the client (although the caller may still need to disconnect after reporting
 * the error).
 */
1353 1354
static int nbd_co_receive_request(NBDRequestData *req, NBDRequest *request,
                                  Error **errp)
1355
{
1356
    NBDClient *client = req->client;
1357
    int valid_flags;
1358

1359
    g_assert(qemu_in_coroutine());
1360
    assert(client->recv_coroutine == qemu_coroutine_self());
1361
    if (nbd_receive_request(client->ioc, request, errp) < 0) {
1362
        return -EIO;
1363 1364
    }

1365 1366
    trace_nbd_co_receive_request_decode_type(request->handle, request->type,
                                             nbd_cmd_lookup(request->type));
1367

1368
    if (request->type != NBD_CMD_WRITE) {
1369 1370 1371 1372
        /* No payload, we are ready to read the next request.  */
        req->complete = true;
    }

1373
    if (request->type == NBD_CMD_DISC) {
1374 1375
        /* Special case: we're going to disconnect without a reply,
         * whether or not flags, from, or len are bogus */
1376
        return -EIO;
1377 1378
    }

1379
    if (request->type == NBD_CMD_READ || request->type == NBD_CMD_WRITE) {
1380
        if (request->len > NBD_MAX_BUFFER_SIZE) {
1381 1382
            error_setg(errp, "len (%" PRIu32" ) is larger than max len (%u)",
                       request->len, NBD_MAX_BUFFER_SIZE);
1383
            return -EINVAL;
1384 1385
        }

1386 1387
        req->data = blk_try_blockalign(client->exp->blk, request->len);
        if (req->data == NULL) {
1388
            error_setg(errp, "No memory");
1389
            return -ENOMEM;
1390
        }
1391
    }
1392
    if (request->type == NBD_CMD_WRITE) {
1393 1394
        if (nbd_read(client->ioc, req->data, request->len, errp) < 0) {
            error_prepend(errp, "reading from socket failed: ");
1395
            return -EIO;
1396
        }
1397
        req->complete = true;
1398

1399 1400
        trace_nbd_co_receive_request_payload_received(request->handle,
                                                      request->len);
1401
    }
1402

1403 1404 1405 1406 1407 1408 1409 1410 1411 1412
    /* Sanity checks. */
    if (client->exp->nbdflags & NBD_FLAG_READ_ONLY &&
        (request->type == NBD_CMD_WRITE ||
         request->type == NBD_CMD_WRITE_ZEROES ||
         request->type == NBD_CMD_TRIM)) {
        error_setg(errp, "Export is read-only");
        return -EROFS;
    }
    if (request->from > client->exp->size ||
        request->from + request->len > client->exp->size) {
1413 1414 1415
        error_setg(errp, "operation past EOF; From: %" PRIu64 ", Len: %" PRIu32
                   ", Size: %" PRIu64, request->from, request->len,
                   (uint64_t)client->exp->size);
1416 1417
        return (request->type == NBD_CMD_WRITE ||
                request->type == NBD_CMD_WRITE_ZEROES) ? -ENOSPC : -EINVAL;
1418
    }
1419 1420 1421 1422 1423
    valid_flags = NBD_CMD_FLAG_FUA;
    if (request->type == NBD_CMD_READ && client->structured_reply) {
        valid_flags |= NBD_CMD_FLAG_DF;
    } else if (request->type == NBD_CMD_WRITE_ZEROES) {
        valid_flags |= NBD_CMD_FLAG_NO_HOLE;
E
Eric Blake 已提交
1424
    }
1425 1426 1427
    if (request->flags & ~valid_flags) {
        error_setg(errp, "unsupported flags for command %s (got 0x%x)",
                   nbd_cmd_lookup(request->type), request->flags);
1428
        return -EINVAL;
1429
    }
1430

1431
    return 0;
1432 1433
}

1434 1435
/* Owns a reference to the NBDClient passed as opaque.  */
static coroutine_fn void nbd_trip(void *opaque)
1436
{
P
Paolo Bonzini 已提交
1437
    NBDClient *client = opaque;
1438
    NBDExport *exp = client->exp;
1439
    NBDRequestData *req;
1440
    NBDRequest request = { 0 };    /* GCC thinks it can be used uninitialized */
1441
    int ret;
1442
    int flags;
1443
    int reply_data_len = 0;
1444
    Error *local_err = NULL;
1445
    char *msg = NULL;
N
Nick Thomas 已提交
1446

1447
    trace_nbd_trip();
1448
    if (client->closing) {
1449
        nbd_client_put(client);
1450 1451
        return;
    }
N
Nick Thomas 已提交
1452

1453
    req = nbd_request_get(client);
1454
    ret = nbd_co_receive_request(req, &request, &local_err);
1455 1456
    client->recv_coroutine = NULL;
    nbd_client_receive_next_request(client);
1457
    if (ret == -EIO) {
1458
        goto disconnect;
1459
    }
N
Nick Thomas 已提交
1460

1461
    if (ret < 0) {
1462
        goto reply;
N
Nick Thomas 已提交
1463 1464
    }

1465 1466 1467 1468 1469 1470 1471 1472
    if (client->closing) {
        /*
         * The client may be closed when we are blocked in
         * nbd_co_receive_request()
         */
        goto done;
    }

1473
    switch (request.type) {
N
Nick Thomas 已提交
1474
    case NBD_CMD_READ:
1475 1476
        /* XXX: NBD Protocol only documents use of FUA with WRITE */
        if (request.flags & NBD_CMD_FLAG_FUA) {
M
Max Reitz 已提交
1477
            ret = blk_co_flush(exp->blk);
P
Paolo Bonzini 已提交
1478
            if (ret < 0) {
1479
                error_setg_errno(&local_err, -ret, "flush failed");
1480
                break;
P
Paolo Bonzini 已提交
1481 1482 1483
            }
        }

1484 1485
        ret = blk_pread(exp->blk, request.from + exp->dev_offset,
                        req->data, request.len);
1486
        if (ret < 0) {
1487
            error_setg_errno(&local_err, -ret, "reading from file failed");
1488
            break;
N
Nick Thomas 已提交
1489 1490
        }

1491 1492
        reply_data_len = request.len;

N
Nick Thomas 已提交
1493 1494
        break;
    case NBD_CMD_WRITE:
1495
        flags = 0;
1496
        if (request.flags & NBD_CMD_FLAG_FUA) {
1497 1498
            flags |= BDRV_REQ_FUA;
        }
1499
        ret = blk_pwrite(exp->blk, request.from + exp->dev_offset,
1500
                         req->data, request.len, flags);
1501
        if (ret < 0) {
1502
            error_setg_errno(&local_err, -ret, "writing to file failed");
1503
        }
N
Nick Thomas 已提交
1504

1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516
        break;
    case NBD_CMD_WRITE_ZEROES:
        flags = 0;
        if (request.flags & NBD_CMD_FLAG_FUA) {
            flags |= BDRV_REQ_FUA;
        }
        if (!(request.flags & NBD_CMD_FLAG_NO_HOLE)) {
            flags |= BDRV_REQ_MAY_UNMAP;
        }
        ret = blk_pwrite_zeroes(exp->blk, request.from + exp->dev_offset,
                                request.len, flags);
        if (ret < 0) {
1517
            error_setg_errno(&local_err, -ret, "writing to file failed");
1518 1519
        }

N
Nick Thomas 已提交
1520 1521
        break;
    case NBD_CMD_DISC:
1522 1523 1524
        /* unreachable, thanks to special case in nbd_co_receive_request() */
        abort();

P
Paolo Bonzini 已提交
1525
    case NBD_CMD_FLUSH:
M
Max Reitz 已提交
1526
        ret = blk_co_flush(exp->blk);
P
Paolo Bonzini 已提交
1527
        if (ret < 0) {
1528
            error_setg_errno(&local_err, -ret, "flush failed");
P
Paolo Bonzini 已提交
1529
        }
1530

P
Paolo Bonzini 已提交
1531 1532
        break;
    case NBD_CMD_TRIM:
1533 1534 1535
        ret = blk_co_pdiscard(exp->blk, request.from + exp->dev_offset,
                              request.len);
        if (ret < 0) {
1536
            error_setg_errno(&local_err, -ret, "discard failed");
P
Paolo Bonzini 已提交
1537
        }
1538

P
Paolo Bonzini 已提交
1539
        break;
N
Nick Thomas 已提交
1540
    default:
1541 1542
        error_setg(&local_err, "invalid request type (%" PRIu32 ") received",
                   request.type);
1543
        ret = -EINVAL;
1544 1545 1546
    }

reply:
1547
    if (local_err) {
1548 1549
        /* If we get here, local_err was not a fatal error, and should be sent
         * to the client. */
1550 1551
        assert(ret < 0);
        msg = g_strdup(error_get_pretty(local_err));
1552 1553 1554 1555
        error_report_err(local_err);
        local_err = NULL;
    }

1556 1557
    if (client->structured_reply &&
        (ret < 0 || request.type == NBD_CMD_READ)) {
1558 1559
        if (ret < 0) {
            ret = nbd_co_send_structured_error(req->client, request.handle,
1560
                                               -ret, msg, &local_err);
1561
        } else if (reply_data_len) {
1562 1563 1564
            ret = nbd_co_send_structured_read(req->client, request.handle,
                                              request.from, req->data,
                                              reply_data_len, &local_err);
1565 1566 1567
        } else {
            ret = nbd_co_send_structured_done(req->client, request.handle,
                                              &local_err);
1568 1569 1570 1571 1572 1573
        }
    } else {
        ret = nbd_co_send_simple_reply(req->client, request.handle,
                                       ret < 0 ? -ret : 0,
                                       req->data, reply_data_len, &local_err);
    }
1574
    g_free(msg);
1575
    if (ret < 0) {
1576
        error_prepend(&local_err, "Failed to send reply: ");
1577 1578 1579
        goto disconnect;
    }

1580 1581 1582
    /* We must disconnect after NBD_CMD_WRITE if we did not
     * read the payload.
     */
1583 1584
    if (!req->complete) {
        error_setg(&local_err, "Request handling failed in intermediate state");
1585
        goto disconnect;
N
Nick Thomas 已提交
1586 1587
    }

1588
done:
P
Paolo Bonzini 已提交
1589
    nbd_request_put(req);
1590
    nbd_client_put(client);
P
Paolo Bonzini 已提交
1591 1592
    return;

1593
disconnect:
1594 1595 1596
    if (local_err) {
        error_reportf_err(local_err, "Disconnect client, due to: ");
    }
1597
    nbd_request_put(req);
1598
    client_close(client, true);
1599
    nbd_client_put(client);
B
bellard 已提交
1600
}
P
Paolo Bonzini 已提交
1601

1602
static void nbd_client_receive_next_request(NBDClient *client)
M
Max Reitz 已提交
1603
{
1604 1605 1606 1607
    if (!client->recv_coroutine && client->nb_requests < MAX_NBD_REQUESTS) {
        nbd_client_get(client);
        client->recv_coroutine = qemu_coroutine_create(nbd_trip, client);
        aio_co_schedule(client->exp->ctx, client->recv_coroutine);
M
Max Reitz 已提交
1608 1609 1610
    }
}

1611 1612
static coroutine_fn void nbd_co_client_start(void *opaque)
{
1613
    NBDClient *client = opaque;
1614
    NBDExport *exp = client->exp;
1615
    Error *local_err = NULL;
1616 1617 1618

    if (exp) {
        nbd_export_get(exp);
1619
        QTAILQ_INSERT_TAIL(&exp->clients, client, next);
1620
    }
1621 1622
    qemu_co_mutex_init(&client->send_lock);

1623 1624 1625 1626
    if (nbd_negotiate(client, &local_err)) {
        if (local_err) {
            error_report_err(local_err);
        }
1627
        client_close(client, false);
1628
        return;
1629
    }
1630 1631

    nbd_client_receive_next_request(client);
1632 1633
}

1634 1635 1636 1637 1638 1639
/*
 * Create a new client listener on the given export @exp, using the
 * given channel @sioc.  Begin servicing it in a coroutine.  When the
 * connection closes, call @close_fn with an indication of whether the
 * client completed negotiation.
 */
1640 1641
void nbd_client_new(NBDExport *exp,
                    QIOChannelSocket *sioc,
1642 1643
                    QCryptoTLSCreds *tlscreds,
                    const char *tlsaclname,
1644
                    void (*close_fn)(NBDClient *, bool))
P
Paolo Bonzini 已提交
1645
{
1646
    NBDClient *client;
1647
    Coroutine *co;
1648

1649
    client = g_new0(NBDClient, 1);
1650 1651
    client->refcount = 1;
    client->exp = exp;
1652 1653 1654 1655 1656
    client->tlscreds = tlscreds;
    if (tlscreds) {
        object_ref(OBJECT(client->tlscreds));
    }
    client->tlsaclname = g_strdup(tlsaclname);
1657 1658 1659 1660
    client->sioc = sioc;
    object_ref(OBJECT(client->sioc));
    client->ioc = QIO_CHANNEL(sioc);
    object_ref(OBJECT(client->ioc));
1661
    client->close_fn = close_fn;
1662

1663 1664
    co = qemu_coroutine_create(nbd_co_client_start, client);
    qemu_coroutine_enter(co);
P
Paolo Bonzini 已提交
1665
}