Revision baf35cb9
b/Makefile | ||
---|---|---|
177 | 177 |
ifdef CONFIG_WIN32 |
178 | 178 |
QEMU_IMG_BLOCK_OBJS += qemu-img-block-raw-win32.o |
179 | 179 |
else |
180 |
QEMU_IMG_BLOCK_OBJS += nbd.o qemu-img-block-raw-posix.o |
|
180 |
QEMU_IMG_BLOCK_OBJS += nbd.o qemu-img-block-raw-posix.o compatfd.o
|
|
181 | 181 |
endif |
182 | 182 |
|
183 | 183 |
###################################################################### |
... | ... | |
195 | 195 |
$(CC) $(CFLAGS) $(CPPFLAGS) -DQEMU_NBD -c -o $@ $< |
196 | 196 |
|
197 | 197 |
qemu-nbd$(EXESUF): qemu-nbd.o qemu-nbd-nbd.o qemu-img-block.o \ |
198 |
osdep.o qemu-nbd-block-raw-posix.o $(BLOCK_OBJS) |
|
198 |
osdep.o qemu-nbd-block-raw-posix.o compatfd.o $(BLOCK_OBJS)
|
|
199 | 199 |
$(CC) $(LDFLAGS) -o $@ $^ -lz $(LIBS) |
200 | 200 |
|
201 | 201 |
# dyngen host tool |
b/Makefile.target | ||
---|---|---|
476 | 476 |
ifdef CONFIG_WIN32 |
477 | 477 |
OBJS+=block-raw-win32.o |
478 | 478 |
else |
479 |
OBJS+=block-raw-posix.o |
|
479 |
OBJS+=block-raw-posix.o compatfd.o
|
|
480 | 480 |
endif |
481 | 481 |
|
482 | 482 |
LIBS+=-lz |
b/block-raw-posix.c | ||
---|---|---|
25 | 25 |
#if !defined(QEMU_IMG) && !defined(QEMU_NBD) |
26 | 26 |
#include "qemu-timer.h" |
27 | 27 |
#include "exec-all.h" |
28 |
#include "qemu-char.h" |
|
28 | 29 |
#endif |
29 | 30 |
#include "block_int.h" |
31 |
#include "compatfd.h" |
|
30 | 32 |
#include <assert.h> |
31 | 33 |
#ifdef CONFIG_AIO |
32 | 34 |
#include <aio.h> |
... | ... | |
438 | 440 |
int ret; |
439 | 441 |
} RawAIOCB; |
440 | 442 |
|
443 |
static int aio_sig_fd = -1; |
|
441 | 444 |
static int aio_sig_num = SIGUSR2; |
442 | 445 |
static RawAIOCB *first_aio; /* AIO issued */ |
443 | 446 |
static int aio_initialized = 0; |
444 | 447 |
|
445 |
static void aio_signal_handler(int signum) |
|
446 |
{ |
|
447 |
#if !defined(QEMU_IMG) && !defined(QEMU_NBD) |
|
448 |
CPUState *env = cpu_single_env; |
|
449 |
if (env) { |
|
450 |
/* stop the currently executing cpu because a timer occured */ |
|
451 |
cpu_interrupt(env, CPU_INTERRUPT_EXIT); |
|
452 |
#ifdef USE_KQEMU |
|
453 |
if (env->kqemu_enabled) { |
|
454 |
kqemu_cpu_interrupt(env); |
|
455 |
} |
|
456 |
#endif |
|
457 |
} |
|
458 |
#endif |
|
459 |
} |
|
460 |
|
|
461 |
void qemu_aio_init(void) |
|
462 |
{ |
|
463 |
struct sigaction act; |
|
464 |
|
|
465 |
aio_initialized = 1; |
|
466 |
|
|
467 |
sigfillset(&act.sa_mask); |
|
468 |
act.sa_flags = 0; /* do not restart syscalls to interrupt select() */ |
|
469 |
act.sa_handler = aio_signal_handler; |
|
470 |
sigaction(aio_sig_num, &act, NULL); |
|
471 |
|
|
472 |
#if defined(__GLIBC__) && defined(__linux__) |
|
473 |
{ |
|
474 |
/* XXX: aio thread exit seems to hang on RedHat 9 and this init |
|
475 |
seems to fix the problem. */ |
|
476 |
struct aioinit ai; |
|
477 |
memset(&ai, 0, sizeof(ai)); |
|
478 |
ai.aio_threads = 1; |
|
479 |
ai.aio_num = 1; |
|
480 |
ai.aio_idle_time = 365 * 100000; |
|
481 |
aio_init(&ai); |
|
482 |
} |
|
483 |
#endif |
|
484 |
} |
|
485 |
|
|
486 |
void qemu_aio_poll(void) |
|
448 |
static void qemu_aio_poll(void *opaque) |
|
487 | 449 |
{ |
488 | 450 |
RawAIOCB *acb, **pacb; |
489 | 451 |
int ret; |
... | ... | |
524 | 486 |
the_end: ; |
525 | 487 |
} |
526 | 488 |
|
489 |
void qemu_aio_init(void) |
|
490 |
{ |
|
491 |
sigset_t mask; |
|
492 |
|
|
493 |
aio_initialized = 1; |
|
494 |
|
|
495 |
/* Make sure to block AIO signal */ |
|
496 |
sigemptyset(&mask); |
|
497 |
sigaddset(&mask, aio_sig_num); |
|
498 |
sigprocmask(SIG_BLOCK, &mask, NULL); |
|
499 |
|
|
500 |
aio_sig_fd = qemu_signalfd(&mask); |
|
501 |
#if !defined(QEMU_IMG) && !defined(QEMU_NBD) |
|
502 |
qemu_set_fd_handler2(aio_sig_fd, NULL, qemu_aio_poll, NULL, NULL); |
|
503 |
#endif |
|
504 |
|
|
505 |
#if defined(__GLIBC__) && defined(__linux__) |
|
506 |
{ |
|
507 |
/* XXX: aio thread exit seems to hang on RedHat 9 and this init |
|
508 |
seems to fix the problem. */ |
|
509 |
struct aioinit ai; |
|
510 |
memset(&ai, 0, sizeof(ai)); |
|
511 |
ai.aio_threads = 1; |
|
512 |
ai.aio_num = 1; |
|
513 |
ai.aio_idle_time = 365 * 100000; |
|
514 |
aio_init(&ai); |
|
515 |
} |
|
516 |
#endif |
|
517 |
} |
|
518 |
|
|
527 | 519 |
/* Wait for all IO requests to complete. */ |
528 | 520 |
void qemu_aio_flush(void) |
529 | 521 |
{ |
530 |
qemu_aio_wait_start(); |
|
531 |
qemu_aio_poll(); |
|
522 |
qemu_aio_poll(NULL); |
|
532 | 523 |
while (first_aio) { |
533 | 524 |
qemu_aio_wait(); |
534 | 525 |
} |
535 |
qemu_aio_wait_end(); |
|
536 |
} |
|
537 |
|
|
538 |
/* wait until at least one AIO was handled */ |
|
539 |
static sigset_t wait_oset; |
|
540 |
|
|
541 |
void qemu_aio_wait_start(void) |
|
542 |
{ |
|
543 |
sigset_t set; |
|
544 |
|
|
545 |
if (!aio_initialized) |
|
546 |
qemu_aio_init(); |
|
547 |
sigemptyset(&set); |
|
548 |
sigaddset(&set, aio_sig_num); |
|
549 |
sigprocmask(SIG_BLOCK, &set, &wait_oset); |
|
550 | 526 |
} |
551 | 527 |
|
552 | 528 |
void qemu_aio_wait(void) |
553 | 529 |
{ |
554 |
sigset_t set; |
|
555 |
int nb_sigs; |
|
530 |
int ret; |
|
556 | 531 |
|
557 | 532 |
#if !defined(QEMU_IMG) && !defined(QEMU_NBD) |
558 | 533 |
if (qemu_bh_poll()) |
559 | 534 |
return; |
560 | 535 |
#endif |
561 |
sigemptyset(&set); |
|
562 |
sigaddset(&set, aio_sig_num); |
|
563 |
sigwait(&set, &nb_sigs); |
|
564 |
qemu_aio_poll(); |
|
565 |
} |
|
566 | 536 |
|
567 |
void qemu_aio_wait_end(void) |
|
568 |
{ |
|
569 |
sigprocmask(SIG_SETMASK, &wait_oset, NULL); |
|
537 |
do { |
|
538 |
fd_set rdfds; |
|
539 |
|
|
540 |
FD_ZERO(&rdfds); |
|
541 |
FD_SET(aio_sig_fd, &rdfds); |
|
542 |
|
|
543 |
ret = select(aio_sig_fd + 1, &rdfds, NULL, NULL, NULL); |
|
544 |
if (ret == -1 && errno == EINTR) |
|
545 |
continue; |
|
546 |
} while (ret == 0); |
|
547 |
|
|
548 |
qemu_aio_poll(NULL); |
|
570 | 549 |
} |
571 | 550 |
|
572 | 551 |
static RawAIOCB *raw_aio_setup(BlockDriverState *bs, |
... | ... | |
704 | 683 |
{ |
705 | 684 |
} |
706 | 685 |
|
707 |
void qemu_aio_poll(void) |
|
708 |
{ |
|
709 |
} |
|
710 |
|
|
711 | 686 |
void qemu_aio_flush(void) |
712 | 687 |
{ |
713 | 688 |
} |
714 | 689 |
|
715 |
void qemu_aio_wait_start(void) |
|
716 |
{ |
|
717 |
} |
|
718 |
|
|
719 | 690 |
void qemu_aio_wait(void) |
720 | 691 |
{ |
721 | 692 |
#if !defined(QEMU_IMG) && !defined(QEMU_NBD) |
... | ... | |
723 | 694 |
#endif |
724 | 695 |
} |
725 | 696 |
|
726 |
void qemu_aio_wait_end(void) |
|
727 |
{ |
|
728 |
} |
|
729 |
|
|
730 | 697 |
#endif /* CONFIG_AIO */ |
731 | 698 |
|
732 | 699 |
static void raw_close(BlockDriverState *bs) |
b/block-raw-win32.c | ||
---|---|---|
350 | 350 |
{ |
351 | 351 |
} |
352 | 352 |
|
353 |
void qemu_aio_poll(void) |
|
354 |
{ |
|
355 |
} |
|
356 |
|
|
357 | 353 |
void qemu_aio_flush(void) |
358 | 354 |
{ |
359 | 355 |
} |
360 | 356 |
|
361 |
void qemu_aio_wait_start(void) |
|
362 |
{ |
|
363 |
} |
|
364 |
|
|
365 | 357 |
void qemu_aio_wait(void) |
366 | 358 |
{ |
367 | 359 |
#ifndef QEMU_IMG |
... | ... | |
369 | 361 |
#endif |
370 | 362 |
} |
371 | 363 |
|
372 |
void qemu_aio_wait_end(void) |
|
373 |
{ |
|
374 |
} |
|
375 |
|
|
376 | 364 |
BlockDriver bdrv_raw = { |
377 | 365 |
"raw", |
378 | 366 |
sizeof(BDRVRawState), |
b/block.c | ||
---|---|---|
1280 | 1280 |
BlockDriverAIOCB *acb; |
1281 | 1281 |
|
1282 | 1282 |
async_ret = NOT_DONE; |
1283 |
qemu_aio_wait_start(); |
|
1284 | 1283 |
acb = bdrv_aio_read(bs, sector_num, buf, nb_sectors, |
1285 | 1284 |
bdrv_rw_em_cb, &async_ret); |
1286 |
if (acb == NULL) { |
|
1287 |
qemu_aio_wait_end(); |
|
1285 |
if (acb == NULL) |
|
1288 | 1286 |
return -1; |
1289 |
} |
|
1287 |
|
|
1290 | 1288 |
while (async_ret == NOT_DONE) { |
1291 | 1289 |
qemu_aio_wait(); |
1292 | 1290 |
} |
1293 |
qemu_aio_wait_end(); |
|
1291 |
|
|
1294 | 1292 |
return async_ret; |
1295 | 1293 |
} |
1296 | 1294 |
|
... | ... | |
1301 | 1299 |
BlockDriverAIOCB *acb; |
1302 | 1300 |
|
1303 | 1301 |
async_ret = NOT_DONE; |
1304 |
qemu_aio_wait_start(); |
|
1305 | 1302 |
acb = bdrv_aio_write(bs, sector_num, buf, nb_sectors, |
1306 | 1303 |
bdrv_rw_em_cb, &async_ret); |
1307 |
if (acb == NULL) { |
|
1308 |
qemu_aio_wait_end(); |
|
1304 |
if (acb == NULL) |
|
1309 | 1305 |
return -1; |
1310 |
} |
|
1311 | 1306 |
while (async_ret == NOT_DONE) { |
1312 | 1307 |
qemu_aio_wait(); |
1313 | 1308 |
} |
1314 |
qemu_aio_wait_end(); |
|
1315 | 1309 |
return async_ret; |
1316 | 1310 |
} |
1317 | 1311 |
|
b/block.h | ||
---|---|---|
90 | 90 |
void bdrv_aio_cancel(BlockDriverAIOCB *acb); |
91 | 91 |
|
92 | 92 |
void qemu_aio_init(void); |
93 |
void qemu_aio_poll(void); |
|
94 | 93 |
void qemu_aio_flush(void); |
95 |
void qemu_aio_wait_start(void); |
|
96 | 94 |
void qemu_aio_wait(void); |
97 |
void qemu_aio_wait_end(void); |
|
98 | 95 |
|
99 | 96 |
int qemu_key_check(BlockDriverState *bs, const char *name); |
100 | 97 |
|
b/vl.c | ||
---|---|---|
7482 | 7482 |
slirp_select_poll(&rfds, &wfds, &xfds); |
7483 | 7483 |
} |
7484 | 7484 |
#endif |
7485 |
qemu_aio_poll(); |
|
7486 | 7485 |
|
7487 | 7486 |
if (vm_running) { |
7488 | 7487 |
if (likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER))) |
Also available in: Unified diff