216ee3657e
In order to test that the NBD server is properly advertising dirty bitmaps, we need a bare minimum client that can request and read the context. Since feature freeze for 3.0 is imminent, this is the smallest workable patch, which replaces the qemu block status report with the results of the NBD server's dirty bitmap (making it very easy to use 'qemu-img map --output=json' to learn where the dirty portions are). Note that the NBD protocol defines a dirty section with the same bit but opposite sense that normal "base:allocation" uses to report an allocated section; so in qemu-img map output, "data":true corresponds to clean, "data":false corresponds to dirty. A more complete solution that allows dirty bitmaps to be queried at the same time as normal block status will be required before this addition can lose the x- prefix. Until then, the fact that this replaces normal status with dirty status means actions like 'qemu-img convert' will likely misbehave due to treating dirty regions of the file as if they are unallocated. The next patch adds an iotest to exercise this new code. Signed-off-by: Eric Blake <eblake@redhat.com> Message-Id: <20180702191458.28741-2-eblake@redhat.com>
72 lines
2.4 KiB
C
72 lines
2.4 KiB
C
#ifndef NBD_CLIENT_H
|
|
#define NBD_CLIENT_H
|
|
|
|
#include "qemu-common.h"
|
|
#include "block/nbd.h"
|
|
#include "block/block_int.h"
|
|
#include "io/channel-socket.h"
|
|
|
|
/* #define DEBUG_NBD */
|
|
|
|
#if defined(DEBUG_NBD)
|
|
#define logout(fmt, ...) \
|
|
fprintf(stderr, "nbd\t%-24s" fmt, __func__, ##__VA_ARGS__)
|
|
#else
|
|
#define logout(fmt, ...) ((void)0)
|
|
#endif
|
|
|
|
#define MAX_NBD_REQUESTS 16
|
|
|
|
typedef struct {
|
|
Coroutine *coroutine;
|
|
uint64_t offset; /* original offset of the request */
|
|
bool receiving; /* waiting for read_reply_co? */
|
|
} NBDClientRequest;
|
|
|
|
typedef struct NBDClientSession {
|
|
QIOChannelSocket *sioc; /* The master data channel */
|
|
QIOChannel *ioc; /* The current I/O channel which may differ (eg TLS) */
|
|
NBDExportInfo info;
|
|
|
|
CoMutex send_mutex;
|
|
CoQueue free_sema;
|
|
Coroutine *read_reply_co;
|
|
int in_flight;
|
|
|
|
NBDClientRequest requests[MAX_NBD_REQUESTS];
|
|
NBDReply reply;
|
|
bool quit;
|
|
} NBDClientSession;
|
|
|
|
NBDClientSession *nbd_get_client_session(BlockDriverState *bs);
|
|
|
|
int nbd_client_init(BlockDriverState *bs,
|
|
QIOChannelSocket *sock,
|
|
const char *export_name,
|
|
QCryptoTLSCreds *tlscreds,
|
|
const char *hostname,
|
|
const char *x_dirty_bitmap,
|
|
Error **errp);
|
|
void nbd_client_close(BlockDriverState *bs);
|
|
|
|
int nbd_client_co_pdiscard(BlockDriverState *bs, int64_t offset, int bytes);
|
|
int nbd_client_co_flush(BlockDriverState *bs);
|
|
int nbd_client_co_pwritev(BlockDriverState *bs, uint64_t offset,
|
|
uint64_t bytes, QEMUIOVector *qiov, int flags);
|
|
int nbd_client_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
|
|
int bytes, BdrvRequestFlags flags);
|
|
int nbd_client_co_preadv(BlockDriverState *bs, uint64_t offset,
|
|
uint64_t bytes, QEMUIOVector *qiov, int flags);
|
|
|
|
void nbd_client_detach_aio_context(BlockDriverState *bs);
|
|
void nbd_client_attach_aio_context(BlockDriverState *bs,
|
|
AioContext *new_context);
|
|
|
|
int coroutine_fn nbd_client_co_block_status(BlockDriverState *bs,
|
|
bool want_zero,
|
|
int64_t offset, int64_t bytes,
|
|
int64_t *pnum, int64_t *map,
|
|
BlockDriverState **file);
|
|
|
|
#endif /* NBD_CLIENT_H */
|