Commit 2f7264888ab4a9595a40bd045f58101e5ccd2f0a
1 parent
23fb600b
Add a parameter to disable host cache, by Laurent Vivier.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4836 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
6 changed files
with
40 additions
and
24 deletions
Makefile
| ... | ... | @@ -177,8 +177,11 @@ qemu-img-%.o: %.c |
| 177 | 177 | %.o: %.c |
| 178 | 178 | $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< |
| 179 | 179 | |
| 180 | +qemu-nbd-%.o: %.c | |
| 181 | + $(CC) $(CFLAGS) $(CPPFLAGS) -DQEMU_NBD -c -o $@ $< | |
| 182 | + | |
| 180 | 183 | qemu-nbd$(EXESUF): qemu-nbd.o nbd.o qemu-img-block.o \ |
| 181 | - $(QEMU_IMG_BLOCK_OBJS) | |
| 184 | + osdep.o qemu-nbd-block-raw-posix.o $(BLOCK_OBJS) | |
| 182 | 185 | $(CC) $(LDFLAGS) -o $@ $^ -lz $(LIBS) |
| 183 | 186 | |
| 184 | 187 | # dyngen host tool | ... | ... |
block-raw-posix.c
| ... | ... | @@ -22,7 +22,7 @@ |
| 22 | 22 | * THE SOFTWARE. |
| 23 | 23 | */ |
| 24 | 24 | #include "qemu-common.h" |
| 25 | -#ifndef QEMU_IMG | |
| 25 | +#if !defined(QEMU_IMG) && !defined(QEMU_NBD) | |
| 26 | 26 | #include "qemu-timer.h" |
| 27 | 27 | #include "exec-all.h" |
| 28 | 28 | #endif |
| ... | ... | @@ -59,7 +59,7 @@ |
| 59 | 59 | //#define DEBUG_FLOPPY |
| 60 | 60 | |
| 61 | 61 | //#define DEBUG_BLOCK |
| 62 | -#if defined(DEBUG_BLOCK) && !defined(QEMU_IMG) | |
| 62 | +#if defined(DEBUG_BLOCK) && !defined(QEMU_IMG) && !defined(QEMU_NBD) | |
| 63 | 63 | #define DEBUG_BLOCK_PRINT(formatCstr, args...) do { if (loglevel != 0) \ |
| 64 | 64 | { fprintf(logfile, formatCstr, ##args); fflush(logfile); } } while (0) |
| 65 | 65 | #else |
| ... | ... | @@ -434,7 +434,7 @@ static int aio_initialized = 0; |
| 434 | 434 | |
| 435 | 435 | static void aio_signal_handler(int signum) |
| 436 | 436 | { |
| 437 | -#ifndef QEMU_IMG | |
| 437 | +#if !defined(QEMU_IMG) && !defined(QEMU_NBD) | |
| 438 | 438 | CPUState *env = cpu_single_env; |
| 439 | 439 | if (env) { |
| 440 | 440 | /* stop the currently executing cpu because a timer occured */ |
| ... | ... | @@ -544,7 +544,7 @@ void qemu_aio_wait(void) |
| 544 | 544 | sigset_t set; |
| 545 | 545 | int nb_sigs; |
| 546 | 546 | |
| 547 | -#ifndef QEMU_IMG | |
| 547 | +#if !defined(QEMU_IMG) && !defined(QEMU_NBD) | |
| 548 | 548 | if (qemu_bh_poll()) |
| 549 | 549 | return; |
| 550 | 550 | #endif |
| ... | ... | @@ -586,7 +586,7 @@ static RawAIOCB *raw_aio_setup(BlockDriverState *bs, |
| 586 | 586 | return acb; |
| 587 | 587 | } |
| 588 | 588 | |
| 589 | -#ifndef QEMU_IMG | |
| 589 | +#if !defined(QEMU_IMG) && !defined(QEMU_NBD) | |
| 590 | 590 | static void raw_aio_em_cb(void* opaque) |
| 591 | 591 | { |
| 592 | 592 | RawAIOCB *acb = opaque; |
| ... | ... | @@ -605,7 +605,7 @@ static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs, |
| 605 | 605 | * If O_DIRECT is used and the buffer is not aligned fall back |
| 606 | 606 | * to synchronous IO. |
| 607 | 607 | */ |
| 608 | -#if defined(O_DIRECT) && !defined(QEMU_IMG) | |
| 608 | +#if defined(O_DIRECT) && !defined(QEMU_IMG) && !defined(QEMU_NBD) | |
| 609 | 609 | BDRVRawState *s = bs->opaque; |
| 610 | 610 | |
| 611 | 611 | if (unlikely(s->aligned_buf != NULL && ((uintptr_t) buf % 512))) { |
| ... | ... | @@ -638,7 +638,7 @@ static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs, |
| 638 | 638 | * If O_DIRECT is used and the buffer is not aligned fall back |
| 639 | 639 | * to synchronous IO. |
| 640 | 640 | */ |
| 641 | -#if defined(O_DIRECT) && !defined(QEMU_IMG) | |
| 641 | +#if defined(O_DIRECT) && !defined(QEMU_IMG) && !defined(QEMU_NBD) | |
| 642 | 642 | BDRVRawState *s = bs->opaque; |
| 643 | 643 | |
| 644 | 644 | 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) |
| 941 | 941 | return 0; |
| 942 | 942 | } |
| 943 | 943 | |
| 944 | -#if defined(__linux__) && !defined(QEMU_IMG) | |
| 944 | +#if defined(__linux__) && !defined(QEMU_IMG) && !defined(QEMU_NBD) | |
| 945 | 945 | |
| 946 | 946 | /* Note: we do not have a reliable method to detect if the floppy is |
| 947 | 947 | present. The current method is to try to open the floppy at every | ... | ... |
nbd.c
| ... | ... | @@ -404,13 +404,9 @@ int nbd_client(int fd, int csock) |
| 404 | 404 | return ret; |
| 405 | 405 | } |
| 406 | 406 | |
| 407 | -int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset, off_t *offset, bool readonly) | |
| 407 | +int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset, | |
| 408 | + off_t *offset, bool readonly, uint8_t *data, int data_size) | |
| 408 | 409 | { |
| 409 | -#ifndef _REENTRANT | |
| 410 | - static uint8_t data[1024 * 1024]; // keep this off of the stack | |
| 411 | -#else | |
| 412 | - uint8_t data[1024 * 1024]; | |
| 413 | -#endif | |
| 414 | 410 | uint8_t buf[4 + 4 + 8 + 8 + 4]; |
| 415 | 411 | uint32_t magic; |
| 416 | 412 | uint32_t type; |
| ... | ... | @@ -449,9 +445,9 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset, o |
| 449 | 445 | return -1; |
| 450 | 446 | } |
| 451 | 447 | |
| 452 | - if (len > sizeof(data)) { | |
| 453 | - LOG("len (%u) is larger than max len (%lu)", | |
| 454 | - len, (unsigned long)sizeof(data)); | |
| 448 | + if (len > data_size) { | |
| 449 | + LOG("len (%u) is larger than max len (%u)", | |
| 450 | + len, data_size); | |
| 455 | 451 | errno = EINVAL; |
| 456 | 452 | return -1; |
| 457 | 453 | } | ... | ... |
nbd.h
| ... | ... | @@ -33,7 +33,8 @@ int unix_socket_incoming(const char *path); |
| 33 | 33 | int nbd_negotiate(BlockDriverState *bs, int csock, off_t size); |
| 34 | 34 | int nbd_receive_negotiate(int csock, off_t *size, size_t *blocksize); |
| 35 | 35 | int nbd_init(int fd, int csock, off_t size, size_t blocksize); |
| 36 | -int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset, off_t *offset, bool readonly); | |
| 36 | +int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset, | |
| 37 | + off_t *offset, bool readonly, uint8_t *data, int data_size); | |
| 37 | 38 | int nbd_client(int fd, int csock); |
| 38 | 39 | int nbd_disconnect(int fd); |
| 39 | 40 | ... | ... |
qemu-nbd.c
| ... | ... | @@ -34,6 +34,8 @@ |
| 34 | 34 | |
| 35 | 35 | #define SOCKET_PATH "/var/lock/qemu-nbd-%s" |
| 36 | 36 | |
| 37 | +#define NBD_BUFFER_SIZE (1024*1024) | |
| 38 | + | |
| 37 | 39 | int verbose; |
| 38 | 40 | |
| 39 | 41 | static void usage(const char *name) |
| ... | ... | @@ -49,6 +51,8 @@ static void usage(const char *name) |
| 49 | 51 | " (default '"SOCKET_PATH"')\n" |
| 50 | 52 | " -r, --read-only export read-only\n" |
| 51 | 53 | " -P, --partition=NUM only expose partition NUM\n" |
| 54 | +" -s, --snapshot use snapshot file\n" | |
| 55 | +" -n, --nocache disable host cache\n" | |
| 52 | 56 | " -c, --connect=DEV connect FILE to the local NBD device DEV\n" |
| 53 | 57 | " -d, --disconnect disconnect the specified device\n" |
| 54 | 58 | " -v, --verbose display extra debugging information\n" |
| ... | ... | @@ -185,7 +189,7 @@ int main(int argc, char **argv) |
| 185 | 189 | char *device = NULL; |
| 186 | 190 | char *socket = NULL; |
| 187 | 191 | char sockpath[128]; |
| 188 | - const char *sopt = "hVbo:p:rsP:c:dvk:"; | |
| 192 | + const char *sopt = "hVbo:p:rsnP:c:dvk:"; | |
| 189 | 193 | struct option lopt[] = { |
| 190 | 194 | { "help", 0, 0, 'h' }, |
| 191 | 195 | { "version", 0, 0, 'V' }, |
| ... | ... | @@ -198,6 +202,7 @@ int main(int argc, char **argv) |
| 198 | 202 | { "connect", 1, 0, 'c' }, |
| 199 | 203 | { "disconnect", 0, 0, 'd' }, |
| 200 | 204 | { "snapshot", 0, 0, 's' }, |
| 205 | + { "nocache", 0, 0, 'n' }, | |
| 201 | 206 | { "verbose", 0, 0, 'v' }, |
| 202 | 207 | { NULL, 0, 0, 0 } |
| 203 | 208 | }; |
| ... | ... | @@ -205,15 +210,19 @@ int main(int argc, char **argv) |
| 205 | 210 | int opt_ind = 0; |
| 206 | 211 | int li; |
| 207 | 212 | char *end; |
| 208 | - bool snapshot = false; | |
| 213 | + int flags = 0; | |
| 209 | 214 | int partition = -1; |
| 210 | 215 | int fd; |
| 211 | 216 | int ret; |
| 217 | + uint8_t *data; | |
| 212 | 218 | |
| 213 | 219 | while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) { |
| 214 | 220 | switch (ch) { |
| 215 | 221 | case 's': |
| 216 | - snapshot = true; | |
| 222 | + flags |= BDRV_O_SNAPSHOT; | |
| 223 | + break; | |
| 224 | + case 'n': | |
| 225 | + flags |= BDRV_O_DIRECT; | |
| 217 | 226 | break; |
| 218 | 227 | case 'b': |
| 219 | 228 | bindto = optarg; |
| ... | ... | @@ -301,7 +310,7 @@ int main(int argc, char **argv) |
| 301 | 310 | if (bs == NULL) |
| 302 | 311 | return 1; |
| 303 | 312 | |
| 304 | - if (bdrv_open(bs, argv[optind], snapshot) == -1) | |
| 313 | + if (bdrv_open(bs, argv[optind], flags) == -1) | |
| 305 | 314 | return 1; |
| 306 | 315 | |
| 307 | 316 | fd_size = bs->total_sectors * 512; |
| ... | ... | @@ -394,7 +403,10 @@ int main(int argc, char **argv) |
| 394 | 403 | if (nbd_negotiate(bs, csock, fd_size) == -1) |
| 395 | 404 | return 1; |
| 396 | 405 | |
| 397 | - while (nbd_trip(bs, csock, fd_size, dev_offset, &offset, readonly) == 0); | |
| 406 | + data = qemu_memalign(512, NBD_BUFFER_SIZE); | |
| 407 | + while (nbd_trip(bs, csock, fd_size, dev_offset, &offset, readonly, | |
| 408 | + data, NBD_BUFFER_SIZE) == 0); | |
| 409 | + qemu_free(data); | |
| 398 | 410 | |
| 399 | 411 | close(csock); |
| 400 | 412 | close(sock); | ... | ... |
qemu-nbd.texi
| ... | ... | @@ -26,6 +26,10 @@ Export Qemu disk image using NBD protocol. |
| 26 | 26 | export read-only |
| 27 | 27 | @item -P, --partition=NUM |
| 28 | 28 | only expose partition NUM |
| 29 | +@item -s, --snapshot | |
| 30 | + use snapshot file | |
| 31 | +@item -n, --nocache | |
| 32 | + disable host cache | |
| 29 | 33 | @item -c, --connect |
| 30 | 34 | connect FILE to NBD device DEV |
| 31 | 35 | @item -d, --disconnect | ... | ... |