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 | ... | ... |