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