server.c 50.2 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 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413
    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;
    }
    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));
414 415 416 417 418
        /* 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 已提交
419
            sendname = true;
420 421 422 423
            break;
        case NBD_INFO_BLOCK_SIZE:
            blocksize = true;
            break;
E
Eric Blake 已提交
424 425
        }
    }
426
    assert(length == 0);
E
Eric Blake 已提交
427 428 429 430 431 432 433 434 435 436

    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) {
437
        rc = nbd_negotiate_send_info(client, opt, NBD_INFO_NAME, namelen, name,
E
Eric Blake 已提交
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
                                     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;
        }
    }

456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476
    /* 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 已提交
477 478 479 480 481 482 483 484 485 486 487
    /* 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;
    }

488 489 490 491 492 493 494 495 496 497 498 499
    /* 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 已提交
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
    /* 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);
}


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

532
    trace_nbd_negotiate_handle_starttls();
533 534
    ioc = client->ioc;

535
    if (nbd_negotiate_send_rep(client->ioc, NBD_REP_ACK,
536
                               NBD_OPT_STARTTLS, errp) < 0) {
537 538
        return NULL;
    }
539 540 541 542

    tioc = qio_channel_tls_new_server(ioc,
                                      client->tlscreds,
                                      client->tlsaclname,
543
                                      errp);
544 545 546 547
    if (!tioc) {
        return NULL;
    }

548
    qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-server-tls");
549
    trace_nbd_negotiate_handle_starttls_handshake();
550 551 552 553 554 555 556 557 558 559 560 561
    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));
562
        error_propagate(errp, data.error);
563 564 565 566 567 568
        return NULL;
    }

    return QIO_CHANNEL(tioc);
}

569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
/* 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;
}

597
/* nbd_negotiate_options
E
Eric Blake 已提交
598 599
 * Process all NBD_OPT_* client option commands, during fixed newstyle
 * negotiation.
600
 * Return:
601 602 603 604
 * -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
605
 */
606 607
static int nbd_negotiate_options(NBDClient *client, uint16_t myflags,
                                 Error **errp)
608
{
M
Max Reitz 已提交
609
    uint32_t flags;
610
    bool fixedNewstyle = false;
611
    bool no_zeroes = false;
M
Max Reitz 已提交
612 613 614 615

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

E
Eric Blake 已提交
616
       Then we loop until NBD_OPT_EXPORT_NAME or NBD_OPT_GO:
M
Max Reitz 已提交
617 618 619 620 621 622 623 624 625 626 627
        [ 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
    */

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

647
    while (1) {
M
Max Reitz 已提交
648
        int ret;
649
        uint32_t option, length;
650 651
        uint64_t magic;

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

663 664
        if (nbd_read(client->ioc, &option,
                     sizeof(option), errp) < 0) {
665
            error_prepend(errp, "read failed: ");
666 667
            return -EINVAL;
        }
668
        option = be32_to_cpu(option);
669

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

676 677
        trace_nbd_negotiate_options_check_option(option,
                                                 nbd_opt_lookup(option));
678 679 680 681
        if (client->tlscreds &&
            client->ioc == (QIOChannel *)client->sioc) {
            QIOChannel *tioc;
            if (!fixedNewstyle) {
682
                error_setg(errp, "Unsupported option 0x%" PRIx32, option);
683 684
                return -EINVAL;
            }
685
            switch (option) {
686
            case NBD_OPT_STARTTLS:
687 688 689 690 691 692 693
                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);
694 695 696
                if (!tioc) {
                    return -EIO;
                }
697
                ret = 0;
698 699 700 701
                object_unref(OBJECT(client->ioc));
                client->ioc = QIO_CHANNEL(tioc);
                break;

702 703
            case NBD_OPT_EXPORT_NAME:
                /* No way to return an error to client, so drop connection */
704
                error_setg(errp, "Option 0x%x not permitted before TLS",
705
                           option);
706 707
                return -EINVAL;

708
            default:
709
                if (nbd_drop(client->ioc, length, errp) < 0) {
710 711
                    return -EIO;
                }
712 713
                ret = nbd_negotiate_send_rep_err(client->ioc,
                                                 NBD_REP_ERR_TLS_REQD,
714
                                                 option, errp,
715 716
                                                 "Option 0x%" PRIx32
                                                 "not permitted before TLS",
717
                                                 option);
718 719 720
                /* 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.  */
721
                if (option == NBD_OPT_ABORT) {
722
                    return 1;
723
                }
724
                break;
725 726
            }
        } else if (fixedNewstyle) {
727
            switch (option) {
728
            case NBD_OPT_LIST:
729 730 731 732 733 734
                if (length) {
                    ret = nbd_reject_length(client, length, option, false,
                                            errp);
                } else {
                    ret = nbd_negotiate_handle_list(client, errp);
                }
735 736 737
                break;

            case NBD_OPT_ABORT:
738 739 740
                /* NBD spec says we must try to reply before
                 * disconnecting, but that we must also tolerate
                 * guests that don't wait for our reply. */
741
                nbd_negotiate_send_rep(client->ioc, NBD_REP_ACK, option, NULL);
742
                return 1;
743 744

            case NBD_OPT_EXPORT_NAME:
745 746 747
                return nbd_negotiate_handle_export_name(client, length,
                                                        myflags, no_zeroes,
                                                        errp);
748

E
Eric Blake 已提交
749 750 751 752 753 754 755 756 757 758
            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;

759
            case NBD_OPT_STARTTLS:
760 761 762 763
                if (length) {
                    ret = nbd_reject_length(client, length, option, false,
                                            errp);
                } else if (client->tlscreds) {
764 765
                    ret = nbd_negotiate_send_rep_err(client->ioc,
                                                     NBD_REP_ERR_INVALID,
766
                                                     option, errp,
767
                                                     "TLS already enabled");
768
                } else {
769 770
                    ret = nbd_negotiate_send_rep_err(client->ioc,
                                                     NBD_REP_ERR_POLICY,
771
                                                     option, errp,
772
                                                     "TLS not configured");
773
                }
774
                break;
775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791

            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;

792
            default:
793
                if (nbd_drop(client->ioc, length, errp) < 0) {
794 795
                    return -EIO;
                }
796 797
                ret = nbd_negotiate_send_rep_err(client->ioc,
                                                 NBD_REP_ERR_UNSUP,
798
                                                 option, errp,
799
                                                 "Unsupported option 0x%"
800 801
                                                 PRIx32 " (%s)", option,
                                                 nbd_opt_lookup(option));
802
                break;
803 804 805 806 807 808
            }
        } else {
            /*
             * If broken new-style we should drop the connection
             * for anything except NBD_OPT_EXPORT_NAME
             */
809
            switch (option) {
810
            case NBD_OPT_EXPORT_NAME:
811 812 813
                return nbd_negotiate_handle_export_name(client, length,
                                                        myflags, no_zeroes,
                                                        errp);
814 815

            default:
816 817
                error_setg(errp, "Unsupported option 0x%" PRIx32 " (%s)",
                           option, nbd_opt_lookup(option));
818
                return -EINVAL;
819
            }
820
        }
821 822 823
        if (ret < 0) {
            return ret;
        }
824 825 826
    }
}

827 828
/* nbd_negotiate
 * Return:
829 830 831 832
 * -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
833
 */
834
static coroutine_fn int nbd_negotiate(NBDClient *client, Error **errp)
B
bellard 已提交
835
{
836
    char buf[NBD_OLDSTYLE_NEGOTIATE_SIZE] = "";
837
    int ret;
E
Eric Blake 已提交
838
    const uint16_t myflags = (NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
839 840
                              NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA |
                              NBD_FLAG_SEND_WRITE_ZEROES);
841
    bool oldStyle;
N
Nick Thomas 已提交
842

843
    /* Old style negotiation header, no room for options
844 845
        [ 0 ..   7]   passwd       ("NBDMAGIC")
        [ 8 ..  15]   magic        (NBD_CLIENT_MAGIC)
N
Nick Thomas 已提交
846
        [16 ..  23]   size
847
        [24 ..  27]   export flags (zero-extended)
848 849
        [28 .. 151]   reserved     (0)

850
       New style negotiation header, client can send options
851 852 853
        [ 0 ..   7]   passwd       ("NBDMAGIC")
        [ 8 ..  15]   magic        (NBD_OPTS_MAGIC)
        [16 ..  17]   server flags (0)
E
Eric Blake 已提交
854
        ....options sent, ending in NBD_OPT_EXPORT_NAME or NBD_OPT_GO....
N
Nick Thomas 已提交
855 856
     */

857
    qio_channel_set_blocking(client->ioc, false, NULL);
858

859
    trace_nbd_negotiate_begin();
N
Nick Thomas 已提交
860
    memcpy(buf, "NBDMAGIC", 8);
861 862 863

    oldStyle = client->exp != NULL && !client->tlscreds;
    if (oldStyle) {
864 865
        trace_nbd_negotiate_old_style(client->exp->size,
                                      client->exp->nbdflags | myflags);
J
John Snow 已提交
866 867
        stq_be_p(buf + 8, NBD_CLIENT_MAGIC);
        stq_be_p(buf + 16, client->exp->size);
868
        stl_be_p(buf + 24, client->exp->nbdflags | myflags);
N
Nick Thomas 已提交
869

870 871
        if (nbd_write(client->ioc, buf, sizeof(buf), errp) < 0) {
            error_prepend(errp, "write failed: ");
872
            return -EINVAL;
873 874
        }
    } else {
875 876 877
        stq_be_p(buf + 8, NBD_OPTS_MAGIC);
        stw_be_p(buf + 16, NBD_FLAG_FIXED_NEWSTYLE | NBD_FLAG_NO_ZEROES);

878 879
        if (nbd_write(client->ioc, buf, 18, errp) < 0) {
            error_prepend(errp, "write failed: ");
880
            return -EINVAL;
881
        }
882
        ret = nbd_negotiate_options(client, myflags, errp);
883
        if (ret != 0) {
884 885 886
            if (ret < 0) {
                error_prepend(errp, "option negotiation failed: ");
            }
887
            return ret;
888
        }
N
Nick Thomas 已提交
889 890
    }

891
    trace_nbd_negotiate_success();
892 893

    return 0;
B
bellard 已提交
894 895
}

896 897
static int nbd_receive_request(QIOChannel *ioc, NBDRequest *request,
                               Error **errp)
898
{
P
Paolo Bonzini 已提交
899
    uint8_t buf[NBD_REQUEST_SIZE];
N
Nick Thomas 已提交
900
    uint32_t magic;
901
    int ret;
N
Nick Thomas 已提交
902

903
    ret = nbd_read(ioc, buf, sizeof(buf), errp);
904 905 906 907
    if (ret < 0) {
        return ret;
    }

N
Nick Thomas 已提交
908 909
    /* Request
       [ 0 ..  3]   magic   (NBD_REQUEST_MAGIC)
910 911
       [ 4 ..  5]   flags   (NBD_CMD_FLAG_FUA, ...)
       [ 6 ..  7]   type    (NBD_CMD_READ, ...)
N
Nick Thomas 已提交
912 913 914 915 916
       [ 8 .. 15]   handle
       [16 .. 23]   from
       [24 .. 27]   len
     */

917
    magic = ldl_be_p(buf);
918 919
    request->flags  = lduw_be_p(buf + 4);
    request->type   = lduw_be_p(buf + 6);
920 921 922
    request->handle = ldq_be_p(buf + 8);
    request->from   = ldq_be_p(buf + 16);
    request->len    = ldl_be_p(buf + 24);
N
Nick Thomas 已提交
923

924 925
    trace_nbd_receive_request(magic, request->flags, request->type,
                              request->from, request->len);
N
Nick Thomas 已提交
926 927

    if (magic != NBD_REQUEST_MAGIC) {
928
        error_setg(errp, "invalid magic (got 0x%" PRIx32 ")", magic);
929
        return -EINVAL;
N
Nick Thomas 已提交
930 931
    }
    return 0;
932 933
}

P
Paolo Bonzini 已提交
934 935
#define MAX_NBD_REQUESTS 16

936
void nbd_client_get(NBDClient *client)
937 938 939 940
{
    client->refcount++;
}

941
void nbd_client_put(NBDClient *client)
942 943
{
    if (--client->refcount == 0) {
944
        /* The last reference should be dropped by client->close,
M
Max Reitz 已提交
945
         * which is called by client_close.
946 947 948
         */
        assert(client->closing);

949
        qio_channel_detach_aio_context(client->ioc);
950 951
        object_unref(OBJECT(client->sioc));
        object_unref(OBJECT(client->ioc));
952 953 954 955
        if (client->tlscreds) {
            object_unref(OBJECT(client->tlscreds));
        }
        g_free(client->tlsaclname);
956 957 958 959
        if (client->exp) {
            QTAILQ_REMOVE(&client->exp->clients, client, next);
            nbd_export_put(client->exp);
        }
960 961 962 963
        g_free(client);
    }
}

964
static void client_close(NBDClient *client, bool negotiated)
965
{
966 967 968 969 970 971 972 973 974
    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.
     */
975 976
    qio_channel_shutdown(client->ioc, QIO_CHANNEL_SHUTDOWN_BOTH,
                         NULL);
977 978

    /* Also tell the client, so that they release their reference.  */
979 980
    if (client->close_fn) {
        client->close_fn(client, negotiated);
981 982 983
    }
}

984
static NBDRequestData *nbd_request_get(NBDClient *client)
P
Paolo Bonzini 已提交
985
{
986
    NBDRequestData *req;
987

P
Paolo Bonzini 已提交
988 989 990
    assert(client->nb_requests <= MAX_NBD_REQUESTS - 1);
    client->nb_requests++;

991
    req = g_new0(NBDRequestData, 1);
992 993
    nbd_client_get(client);
    req->client = client;
P
Paolo Bonzini 已提交
994 995 996
    return req;
}

997
static void nbd_request_put(NBDRequestData *req)
P
Paolo Bonzini 已提交
998
{
999
    NBDClient *client = req->client;
1000

1001 1002 1003
    if (req->data) {
        qemu_vfree(req->data);
    }
1004
    g_free(req);
1005

M
Max Reitz 已提交
1006
    client->nb_requests--;
1007 1008
    nbd_client_receive_next_request(client);

1009
    nbd_client_put(client);
P
Paolo Bonzini 已提交
1010 1011
}

M
Max Reitz 已提交
1012
static void blk_aio_attached(AioContext *ctx, void *opaque)
M
Max Reitz 已提交
1013 1014 1015 1016
{
    NBDExport *exp = opaque;
    NBDClient *client;

1017
    trace_nbd_blk_aio_attached(exp->name, ctx);
M
Max Reitz 已提交
1018 1019 1020 1021

    exp->ctx = ctx;

    QTAILQ_FOREACH(client, &exp->clients, next) {
1022 1023 1024 1025 1026 1027 1028
        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 已提交
1029 1030 1031
    }
}

M
Max Reitz 已提交
1032
static void blk_aio_detach(void *opaque)
M
Max Reitz 已提交
1033 1034 1035 1036
{
    NBDExport *exp = opaque;
    NBDClient *client;

1037
    trace_nbd_blk_aio_detach(exp->name, exp->ctx);
M
Max Reitz 已提交
1038 1039

    QTAILQ_FOREACH(client, &exp->clients, next) {
1040
        qio_channel_detach_aio_context(client->ioc);
M
Max Reitz 已提交
1041 1042 1043 1044 1045
    }

    exp->ctx = NULL;
}

1046 1047 1048 1049 1050 1051
static void nbd_eject_notifier(Notifier *n, void *data)
{
    NBDExport *exp = container_of(n, NBDExport, eject_notifier);
    nbd_export_close(exp);
}

1052
NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size,
E
Eric Blake 已提交
1053
                          uint16_t nbdflags, void (*close)(NBDExport *),
1054
                          bool writethrough, BlockBackend *on_eject_blk,
M
Max Reitz 已提交
1055
                          Error **errp)
P
Paolo Bonzini 已提交
1056
{
1057
    AioContext *ctx;
1058
    BlockBackend *blk;
1059
    NBDExport *exp = g_new0(NBDExport, 1);
1060
    uint64_t perm;
1061
    int ret;
1062

1063 1064 1065 1066 1067 1068 1069 1070 1071 1072
    /*
     * 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);

1073 1074 1075 1076 1077 1078 1079 1080
    /* 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);
1081 1082 1083 1084
    ret = blk_insert_bs(blk, bs, errp);
    if (ret < 0) {
        goto fail;
    }
1085 1086
    blk_set_enable_write_cache(blk, !writethrough);

1087
    exp->refcount = 1;
1088
    QTAILQ_INIT(&exp->clients);
M
Max Reitz 已提交
1089
    exp->blk = blk;
P
Paolo Bonzini 已提交
1090 1091
    exp->dev_offset = dev_offset;
    exp->nbdflags = nbdflags;
M
Max Reitz 已提交
1092 1093 1094 1095 1096 1097 1098 1099
    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;

1100
    exp->close = close;
M
Max Reitz 已提交
1101 1102
    exp->ctx = blk_get_aio_context(blk);
    blk_add_aio_context_notifier(blk, blk_aio_attached, blk_aio_detach, exp);
1103

1104 1105 1106 1107 1108 1109
    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 已提交
1110
    return exp;
M
Max Reitz 已提交
1111 1112

fail:
1113
    blk_unref(blk);
M
Max Reitz 已提交
1114 1115
    g_free(exp);
    return NULL;
P
Paolo Bonzini 已提交
1116 1117
}

P
Paolo Bonzini 已提交
1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150
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);
}

1151 1152 1153 1154 1155 1156
void nbd_export_set_description(NBDExport *exp, const char *description)
{
    g_free(exp->description);
    exp->description = g_strdup(description);
}

P
Paolo Bonzini 已提交
1157 1158
void nbd_export_close(NBDExport *exp)
{
1159
    NBDClient *client, *next;
1160

1161 1162
    nbd_export_get(exp);
    QTAILQ_FOREACH_SAFE(client, &exp->clients, next, next) {
1163
        client_close(client, true);
1164
    }
P
Paolo Bonzini 已提交
1165
    nbd_export_set_name(exp, NULL);
1166
    nbd_export_set_description(exp, NULL);
1167
    nbd_export_put(exp);
1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180
}

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 已提交
1181 1182
    }

1183
    if (--exp->refcount == 0) {
P
Paolo Bonzini 已提交
1184
        assert(exp->name == NULL);
1185
        assert(exp->description == NULL);
P
Paolo Bonzini 已提交
1186

1187 1188 1189 1190
        if (exp->close) {
            exp->close(exp);
        }

1191
        if (exp->blk) {
1192 1193 1194 1195
            if (exp->eject_notifier_blk) {
                notifier_remove(&exp->eject_notifier);
                blk_unref(exp->eject_notifier_blk);
            }
1196 1197 1198 1199 1200 1201
            blk_remove_aio_context_notifier(exp->blk, blk_aio_attached,
                                            blk_aio_detach, exp);
            blk_unref(exp->blk);
            exp->blk = NULL;
        }

1202 1203
        g_free(exp);
    }
P
Paolo Bonzini 已提交
1204 1205
}

1206
BlockBackend *nbd_export_get_blockdev(NBDExport *exp)
P
Paolo Bonzini 已提交
1207
{
M
Max Reitz 已提交
1208
    return exp->blk;
P
Paolo Bonzini 已提交
1209 1210
}

P
Paolo Bonzini 已提交
1211 1212 1213 1214 1215 1216 1217 1218 1219
void nbd_export_close_all(void)
{
    NBDExport *exp, *next;

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

1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236
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;
}

1237 1238 1239 1240 1241 1242 1243 1244
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);
}

1245
static int nbd_co_send_simple_reply(NBDClient *client,
1246 1247
                                    uint64_t handle,
                                    uint32_t error,
1248 1249 1250
                                    void *data,
                                    size_t len,
                                    Error **errp)
1251
{
1252
    NBDSimpleReply reply;
1253
    int nbd_err = system_errno_to_nbd_errno(error);
1254 1255 1256 1257
    struct iovec iov[] = {
        {.iov_base = &reply, .iov_len = sizeof(reply)},
        {.iov_base = data, .iov_len = len}
    };
1258

1259 1260
    trace_nbd_co_send_simple_reply(handle, nbd_err, nbd_err_lookup(nbd_err),
                                   len);
1261
    set_be_simple_reply(&reply, nbd_err, handle);
P
Paolo Bonzini 已提交
1262

1263
    return nbd_co_send_iov(client, iov, len ? 2 : 1, errp);
1264 1265
}

1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282
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);
}

static int coroutine_fn nbd_co_send_structured_read(NBDClient *client,
                                                    uint64_t handle,
                                                    uint64_t offset,
                                                    void *data,
                                                    size_t size,
                                                    Error **errp)
{
1283
    NBDStructuredReadData chunk;
1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299
    struct iovec iov[] = {
        {.iov_base = &chunk, .iov_len = sizeof(chunk)},
        {.iov_base = data, .iov_len = size}
    };

    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,
1300
                                                     const char *msg,
1301 1302 1303 1304 1305 1306
                                                     Error **errp)
{
    NBDStructuredError chunk;
    int nbd_err = system_errno_to_nbd_errno(error);
    struct iovec iov[] = {
        {.iov_base = &chunk, .iov_len = sizeof(chunk)},
1307
        {.iov_base = (char *)msg, .iov_len = msg ? strlen(msg) : 0},
1308 1309 1310 1311
    };

    assert(nbd_err);
    trace_nbd_co_send_structured_error(handle, nbd_err,
1312
                                       nbd_err_lookup(nbd_err), msg ? msg : "");
1313
    set_be_chunk(&chunk.h, NBD_REPLY_FLAG_DONE, NBD_REPLY_TYPE_ERROR, handle,
1314
                 sizeof(chunk) - sizeof(chunk.h) + iov[1].iov_len);
1315
    stl_be_p(&chunk.error, nbd_err);
1316
    stw_be_p(&chunk.message_length, iov[1].iov_len);
1317

1318
    return nbd_co_send_iov(client, iov, 1 + !!iov[1].iov_len, errp);
1319 1320
}

1321 1322 1323 1324 1325 1326
/* 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).
 */
1327 1328
static int nbd_co_receive_request(NBDRequestData *req, NBDRequest *request,
                                  Error **errp)
1329
{
1330
    NBDClient *client = req->client;
1331
    int valid_flags;
1332

1333
    g_assert(qemu_in_coroutine());
1334
    assert(client->recv_coroutine == qemu_coroutine_self());
1335
    if (nbd_receive_request(client->ioc, request, errp) < 0) {
1336
        return -EIO;
1337 1338
    }

1339 1340
    trace_nbd_co_receive_request_decode_type(request->handle, request->type,
                                             nbd_cmd_lookup(request->type));
1341

1342
    if (request->type != NBD_CMD_WRITE) {
1343 1344 1345 1346
        /* No payload, we are ready to read the next request.  */
        req->complete = true;
    }

1347
    if (request->type == NBD_CMD_DISC) {
1348 1349
        /* Special case: we're going to disconnect without a reply,
         * whether or not flags, from, or len are bogus */
1350
        return -EIO;
1351 1352 1353 1354 1355
    }

    /* Check for sanity in the parameters, part 1.  Defer as many
     * checks as possible until after reading any NBD_CMD_WRITE
     * payload, so we can try and keep the connection alive.  */
1356
    if ((request->from + request->len) < request->from) {
1357 1358
        error_setg(errp,
                   "integer overflow detected, you're probably being attacked");
1359
        return -EINVAL;
1360 1361
    }

1362
    if (request->type == NBD_CMD_READ || request->type == NBD_CMD_WRITE) {
1363
        if (request->len > NBD_MAX_BUFFER_SIZE) {
1364 1365
            error_setg(errp, "len (%" PRIu32" ) is larger than max len (%u)",
                       request->len, NBD_MAX_BUFFER_SIZE);
1366
            return -EINVAL;
1367 1368
        }

1369 1370
        req->data = blk_try_blockalign(client->exp->blk, request->len);
        if (req->data == NULL) {
1371
            error_setg(errp, "No memory");
1372
            return -ENOMEM;
1373
        }
1374
    }
1375
    if (request->type == NBD_CMD_WRITE) {
1376 1377
        if (nbd_read(client->ioc, req->data, request->len, errp) < 0) {
            error_prepend(errp, "reading from socket failed: ");
1378
            return -EIO;
1379
        }
1380
        req->complete = true;
1381

1382 1383
        trace_nbd_co_receive_request_payload_received(request->handle,
                                                      request->len);
1384
    }
1385 1386 1387

    /* Sanity checks, part 2. */
    if (request->from + request->len > client->exp->size) {
1388 1389 1390
        error_setg(errp, "operation past EOF; From: %" PRIu64 ", Len: %" PRIu32
                   ", Size: %" PRIu64, request->from, request->len,
                   (uint64_t)client->exp->size);
1391
        return request->type == NBD_CMD_WRITE ? -ENOSPC : -EINVAL;
1392
    }
1393 1394 1395 1396 1397
    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 已提交
1398
    }
1399 1400 1401
    if (request->flags & ~valid_flags) {
        error_setg(errp, "unsupported flags for command %s (got 0x%x)",
                   nbd_cmd_lookup(request->type), request->flags);
1402
        return -EINVAL;
1403
    }
1404

1405
    return 0;
1406 1407
}

1408 1409
/* Owns a reference to the NBDClient passed as opaque.  */
static coroutine_fn void nbd_trip(void *opaque)
1410
{
P
Paolo Bonzini 已提交
1411
    NBDClient *client = opaque;
1412
    NBDExport *exp = client->exp;
1413
    NBDRequestData *req;
1414
    NBDRequest request = { 0 };    /* GCC thinks it can be used uninitialized */
1415
    int ret;
1416
    int flags;
1417
    int reply_data_len = 0;
1418
    Error *local_err = NULL;
1419
    char *msg = NULL;
N
Nick Thomas 已提交
1420

1421
    trace_nbd_trip();
1422
    if (client->closing) {
1423
        nbd_client_put(client);
1424 1425
        return;
    }
N
Nick Thomas 已提交
1426

1427
    req = nbd_request_get(client);
1428
    ret = nbd_co_receive_request(req, &request, &local_err);
1429 1430
    client->recv_coroutine = NULL;
    nbd_client_receive_next_request(client);
1431
    if (ret == -EIO) {
1432
        goto disconnect;
1433
    }
N
Nick Thomas 已提交
1434

1435
    if (ret < 0) {
1436
        goto reply;
N
Nick Thomas 已提交
1437 1438
    }

1439 1440 1441 1442 1443 1444 1445 1446
    if (client->closing) {
        /*
         * The client may be closed when we are blocked in
         * nbd_co_receive_request()
         */
        goto done;
    }

1447
    switch (request.type) {
N
Nick Thomas 已提交
1448
    case NBD_CMD_READ:
1449 1450
        /* XXX: NBD Protocol only documents use of FUA with WRITE */
        if (request.flags & NBD_CMD_FLAG_FUA) {
M
Max Reitz 已提交
1451
            ret = blk_co_flush(exp->blk);
P
Paolo Bonzini 已提交
1452
            if (ret < 0) {
1453
                error_setg_errno(&local_err, -ret, "flush failed");
1454
                break;
P
Paolo Bonzini 已提交
1455 1456 1457
            }
        }

1458 1459
        ret = blk_pread(exp->blk, request.from + exp->dev_offset,
                        req->data, request.len);
1460
        if (ret < 0) {
1461
            error_setg_errno(&local_err, -ret, "reading from file failed");
1462
            break;
N
Nick Thomas 已提交
1463 1464
        }

1465 1466
        reply_data_len = request.len;

N
Nick Thomas 已提交
1467 1468
        break;
    case NBD_CMD_WRITE:
P
Paolo Bonzini 已提交
1469
        if (exp->nbdflags & NBD_FLAG_READ_ONLY) {
1470
            error_setg(&local_err, "Export is read-only");
1471
            ret = -EROFS;
1472
            break;
1473 1474
        }

1475
        flags = 0;
1476
        if (request.flags & NBD_CMD_FLAG_FUA) {
1477 1478
            flags |= BDRV_REQ_FUA;
        }
1479
        ret = blk_pwrite(exp->blk, request.from + exp->dev_offset,
1480
                         req->data, request.len, flags);
1481
        if (ret < 0) {
1482
            error_setg_errno(&local_err, -ret, "writing to file failed");
1483
        }
N
Nick Thomas 已提交
1484

1485 1486 1487
        break;
    case NBD_CMD_WRITE_ZEROES:
        if (exp->nbdflags & NBD_FLAG_READ_ONLY) {
1488
            error_setg(&local_err, "Export is read-only");
1489
            ret = -EROFS;
1490
            break;
1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502
        }

        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) {
1503
            error_setg_errno(&local_err, -ret, "writing to file failed");
1504 1505
        }

N
Nick Thomas 已提交
1506 1507
        break;
    case NBD_CMD_DISC:
1508 1509 1510
        /* unreachable, thanks to special case in nbd_co_receive_request() */
        abort();

P
Paolo Bonzini 已提交
1511
    case NBD_CMD_FLUSH:
M
Max Reitz 已提交
1512
        ret = blk_co_flush(exp->blk);
P
Paolo Bonzini 已提交
1513
        if (ret < 0) {
1514
            error_setg_errno(&local_err, -ret, "flush failed");
P
Paolo Bonzini 已提交
1515
        }
1516

P
Paolo Bonzini 已提交
1517 1518
        break;
    case NBD_CMD_TRIM:
1519 1520 1521
        ret = blk_co_pdiscard(exp->blk, request.from + exp->dev_offset,
                              request.len);
        if (ret < 0) {
1522
            error_setg_errno(&local_err, -ret, "discard failed");
P
Paolo Bonzini 已提交
1523
        }
1524

P
Paolo Bonzini 已提交
1525
        break;
N
Nick Thomas 已提交
1526
    default:
1527 1528
        error_setg(&local_err, "invalid request type (%" PRIu32 ") received",
                   request.type);
1529
        ret = -EINVAL;
1530 1531 1532
    }

reply:
1533
    if (local_err) {
1534 1535
        /* If we get here, local_err was not a fatal error, and should be sent
         * to the client. */
1536 1537
        assert(ret < 0);
        msg = g_strdup(error_get_pretty(local_err));
1538 1539 1540 1541
        error_report_err(local_err);
        local_err = NULL;
    }

1542 1543
    if (client->structured_reply &&
        (ret < 0 || request.type == NBD_CMD_READ)) {
1544 1545
        if (ret < 0) {
            ret = nbd_co_send_structured_error(req->client, request.handle,
1546
                                               -ret, msg, &local_err);
1547 1548 1549 1550 1551 1552 1553 1554 1555 1556
        } else {
            ret = nbd_co_send_structured_read(req->client, request.handle,
                                              request.from, req->data,
                                              reply_data_len, &local_err);
        }
    } else {
        ret = nbd_co_send_simple_reply(req->client, request.handle,
                                       ret < 0 ? -ret : 0,
                                       req->data, reply_data_len, &local_err);
    }
1557
    g_free(msg);
1558
    if (ret < 0) {
1559
        error_prepend(&local_err, "Failed to send reply: ");
1560 1561 1562
        goto disconnect;
    }

1563 1564 1565
    /* We must disconnect after NBD_CMD_WRITE if we did not
     * read the payload.
     */
1566 1567
    if (!req->complete) {
        error_setg(&local_err, "Request handling failed in intermediate state");
1568
        goto disconnect;
N
Nick Thomas 已提交
1569 1570
    }

1571
done:
P
Paolo Bonzini 已提交
1572
    nbd_request_put(req);
1573
    nbd_client_put(client);
P
Paolo Bonzini 已提交
1574 1575
    return;

1576
disconnect:
1577 1578 1579
    if (local_err) {
        error_reportf_err(local_err, "Disconnect client, due to: ");
    }
1580
    nbd_request_put(req);
1581
    client_close(client, true);
1582
    nbd_client_put(client);
B
bellard 已提交
1583
}
P
Paolo Bonzini 已提交
1584

1585
static void nbd_client_receive_next_request(NBDClient *client)
M
Max Reitz 已提交
1586
{
1587 1588 1589 1590
    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 已提交
1591 1592 1593
    }
}

1594 1595
static coroutine_fn void nbd_co_client_start(void *opaque)
{
1596
    NBDClient *client = opaque;
1597
    NBDExport *exp = client->exp;
1598
    Error *local_err = NULL;
1599 1600 1601

    if (exp) {
        nbd_export_get(exp);
1602
        QTAILQ_INSERT_TAIL(&exp->clients, client, next);
1603
    }
1604 1605
    qemu_co_mutex_init(&client->send_lock);

1606 1607 1608 1609
    if (nbd_negotiate(client, &local_err)) {
        if (local_err) {
            error_report_err(local_err);
        }
1610
        client_close(client, false);
1611
        return;
1612
    }
1613 1614

    nbd_client_receive_next_request(client);
1615 1616
}

1617 1618 1619 1620 1621 1622
/*
 * 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.
 */
1623 1624
void nbd_client_new(NBDExport *exp,
                    QIOChannelSocket *sioc,
1625 1626
                    QCryptoTLSCreds *tlscreds,
                    const char *tlsaclname,
1627
                    void (*close_fn)(NBDClient *, bool))
P
Paolo Bonzini 已提交
1628
{
1629
    NBDClient *client;
1630
    Coroutine *co;
1631

1632
    client = g_new0(NBDClient, 1);
1633 1634
    client->refcount = 1;
    client->exp = exp;
1635 1636 1637 1638 1639
    client->tlscreds = tlscreds;
    if (tlscreds) {
        object_ref(OBJECT(client->tlscreds));
    }
    client->tlsaclname = g_strdup(tlsaclname);
1640 1641 1642 1643
    client->sioc = sioc;
    object_ref(OBJECT(client->sioc));
    client->ioc = QIO_CHANNEL(sioc);
    object_ref(OBJECT(client->ioc));
1644
    client->close_fn = close_fn;
1645

1646 1647
    co = qemu_coroutine_create(nbd_co_client_start, client);
    qemu_coroutine_enter(co);
P
Paolo Bonzini 已提交
1648
}