diff options
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | block-raw-posix.c | 16 | ||||
-rw-r--r-- | nbd.c | 14 | ||||
-rw-r--r-- | nbd.h | 3 | ||||
-rw-r--r-- | qemu-nbd.c | 22 | ||||
-rw-r--r-- | qemu-nbd.texi | 4 |
6 files changed, 40 insertions, 24 deletions
@@ -177,8 +177,11 @@ qemu-img-%.o: %.c %.o: %.c $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< +qemu-nbd-%.o: %.c + $(CC) $(CFLAGS) $(CPPFLAGS) -DQEMU_NBD -c -o $@ $< + qemu-nbd$(EXESUF): qemu-nbd.o nbd.o qemu-img-block.o \ - $(QEMU_IMG_BLOCK_OBJS) + osdep.o qemu-nbd-block-raw-posix.o $(BLOCK_OBJS) $(CC) $(LDFLAGS) -o $@ $^ -lz $(LIBS) # dyngen host tool diff --git a/block-raw-posix.c b/block-raw-posix.c index fd40dda449..81382b5255 100644 --- a/block-raw-posix.c +++ b/block-raw-posix.c @@ -22,7 +22,7 @@ * THE SOFTWARE. */ #include "qemu-common.h" -#ifndef QEMU_IMG +#if !defined(QEMU_IMG) && !defined(QEMU_NBD) #include "qemu-timer.h" #include "exec-all.h" #endif @@ -59,7 +59,7 @@ //#define DEBUG_FLOPPY //#define DEBUG_BLOCK -#if defined(DEBUG_BLOCK) && !defined(QEMU_IMG) +#if defined(DEBUG_BLOCK) && !defined(QEMU_IMG) && !defined(QEMU_NBD) #define DEBUG_BLOCK_PRINT(formatCstr, args...) do { if (loglevel != 0) \ { fprintf(logfile, formatCstr, ##args); fflush(logfile); } } while (0) #else @@ -434,7 +434,7 @@ static int aio_initialized = 0; static void aio_signal_handler(int signum) { -#ifndef QEMU_IMG +#if !defined(QEMU_IMG) && !defined(QEMU_NBD) CPUState *env = cpu_single_env; if (env) { /* stop the currently executing cpu because a timer occured */ @@ -544,7 +544,7 @@ void qemu_aio_wait(void) sigset_t set; int nb_sigs; -#ifndef QEMU_IMG +#if !defined(QEMU_IMG) && !defined(QEMU_NBD) if (qemu_bh_poll()) return; #endif @@ -586,7 +586,7 @@ static RawAIOCB *raw_aio_setup(BlockDriverState *bs, return acb; } -#ifndef QEMU_IMG +#if !defined(QEMU_IMG) && !defined(QEMU_NBD) static void raw_aio_em_cb(void* opaque) { RawAIOCB *acb = opaque; @@ -605,7 +605,7 @@ static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs, * If O_DIRECT is used and the buffer is not aligned fall back * to synchronous IO. */ -#if defined(O_DIRECT) && !defined(QEMU_IMG) +#if defined(O_DIRECT) && !defined(QEMU_IMG) && !defined(QEMU_NBD) BDRVRawState *s = bs->opaque; if (unlikely(s->aligned_buf != NULL && ((uintptr_t) buf % 512))) { @@ -638,7 +638,7 @@ static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs, * If O_DIRECT is used and the buffer is not aligned fall back * to synchronous IO. */ -#if defined(O_DIRECT) && !defined(QEMU_IMG) +#if defined(O_DIRECT) && !defined(QEMU_IMG) && !defined(QEMU_NBD) BDRVRawState *s = bs->opaque; if (unlikely(s->aligned_buf != NULL && ((uintptr_t) buf % 512))) { @@ -941,7 +941,7 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) return 0; } -#if defined(__linux__) && !defined(QEMU_IMG) +#if defined(__linux__) && !defined(QEMU_IMG) && !defined(QEMU_NBD) /* Note: we do not have a reliable method to detect if the floppy is present. The current method is to try to open the floppy at every @@ -404,13 +404,9 @@ int nbd_client(int fd, int csock) return ret; } -int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset, off_t *offset, bool readonly) +int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset, + off_t *offset, bool readonly, uint8_t *data, int data_size) { -#ifndef _REENTRANT - static uint8_t data[1024 * 1024]; // keep this off of the stack -#else - uint8_t data[1024 * 1024]; -#endif uint8_t buf[4 + 4 + 8 + 8 + 4]; uint32_t magic; uint32_t type; @@ -449,9 +445,9 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset, o return -1; } - if (len > sizeof(data)) { - LOG("len (%u) is larger than max len (%lu)", - len, (unsigned long)sizeof(data)); + if (len > data_size) { + LOG("len (%u) is larger than max len (%u)", + len, data_size); errno = EINVAL; return -1; } @@ -33,7 +33,8 @@ int unix_socket_incoming(const char *path); int nbd_negotiate(BlockDriverState *bs, int csock, off_t size); int nbd_receive_negotiate(int csock, off_t *size, size_t *blocksize); int nbd_init(int fd, int csock, off_t size, size_t blocksize); -int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset, off_t *offset, bool readonly); +int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset, + off_t *offset, bool readonly, uint8_t *data, int data_size); int nbd_client(int fd, int csock); int nbd_disconnect(int fd); diff --git a/qemu-nbd.c b/qemu-nbd.c index 3bcf87984d..bac0e4f164 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -34,6 +34,8 @@ #define SOCKET_PATH "/var/lock/qemu-nbd-%s" +#define NBD_BUFFER_SIZE (1024*1024) + int verbose; static void usage(const char *name) @@ -49,6 +51,8 @@ static void usage(const char *name) " (default '"SOCKET_PATH"')\n" " -r, --read-only export read-only\n" " -P, --partition=NUM only expose partition NUM\n" +" -s, --snapshot use snapshot file\n" +" -n, --nocache disable host cache\n" " -c, --connect=DEV connect FILE to the local NBD device DEV\n" " -d, --disconnect disconnect the specified device\n" " -v, --verbose display extra debugging information\n" @@ -185,7 +189,7 @@ int main(int argc, char **argv) char *device = NULL; char *socket = NULL; char sockpath[128]; - const char *sopt = "hVbo:p:rsP:c:dvk:"; + const char *sopt = "hVbo:p:rsnP:c:dvk:"; struct option lopt[] = { { "help", 0, 0, 'h' }, { "version", 0, 0, 'V' }, @@ -198,6 +202,7 @@ int main(int argc, char **argv) { "connect", 1, 0, 'c' }, { "disconnect", 0, 0, 'd' }, { "snapshot", 0, 0, 's' }, + { "nocache", 0, 0, 'n' }, { "verbose", 0, 0, 'v' }, { NULL, 0, 0, 0 } }; @@ -205,15 +210,19 @@ int main(int argc, char **argv) int opt_ind = 0; int li; char *end; - bool snapshot = false; + int flags = 0; int partition = -1; int fd; int ret; + uint8_t *data; while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) { switch (ch) { case 's': - snapshot = true; + flags |= BDRV_O_SNAPSHOT; + break; + case 'n': + flags |= BDRV_O_DIRECT; break; case 'b': bindto = optarg; @@ -301,7 +310,7 @@ int main(int argc, char **argv) if (bs == NULL) return 1; - if (bdrv_open(bs, argv[optind], snapshot) == -1) + if (bdrv_open(bs, argv[optind], flags) == -1) return 1; fd_size = bs->total_sectors * 512; @@ -394,7 +403,10 @@ int main(int argc, char **argv) if (nbd_negotiate(bs, csock, fd_size) == -1) return 1; - while (nbd_trip(bs, csock, fd_size, dev_offset, &offset, readonly) == 0); + data = qemu_memalign(512, NBD_BUFFER_SIZE); + while (nbd_trip(bs, csock, fd_size, dev_offset, &offset, readonly, + data, NBD_BUFFER_SIZE) == 0); + qemu_free(data); close(csock); close(sock); diff --git a/qemu-nbd.texi b/qemu-nbd.texi index 37b68f5fce..3a4cb92545 100644 --- a/qemu-nbd.texi +++ b/qemu-nbd.texi @@ -26,6 +26,10 @@ Export Qemu disk image using NBD protocol. export read-only @item -P, --partition=NUM only expose partition NUM +@item -s, --snapshot + use snapshot file +@item -n, --nocache + disable host cache @item -c, --connect connect FILE to NBD device DEV @item -d, --disconnect |