aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--block-raw-posix.c16
-rw-r--r--nbd.c14
-rw-r--r--nbd.h3
-rw-r--r--qemu-nbd.c22
-rw-r--r--qemu-nbd.texi4
6 files changed, 40 insertions, 24 deletions
diff --git a/Makefile b/Makefile
index a4dcc58450..aabae78cdb 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/nbd.c b/nbd.c
index 9f8fda9247..49ee7dfad6 100644
--- a/nbd.c
+++ b/nbd.c
@@ -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;
}
diff --git a/nbd.h b/nbd.h
index 4bb185bf85..01e4a6af1d 100644
--- a/nbd.h
+++ b/nbd.h
@@ -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