I saw this with RHEL5.3. I ended up hacking qemu to re_open the CD every so often. See attached. David On 04/23/2010 09:10 AM, Matt Burkhardt wrote: > I'm having a problem with a virtual machine running under RHEL 5.4 > 64-bit. I take out the CD / insert a new and the main machine sees the > new cd and makes it available. However, the virtual machines still see > the old CD. I've tried mounting the new CD, but it just keeps mounting > what it "thinks" is in there - the old one. > > Any ideas? > > > Matt Burkhardt > Impari Systems, Inc. > > mlb@xxxxxxxxxxxxxxxxx > http://www.imparisystems.com > http://www.linkedin.com/in/mlburkhardt > http://www.twitter.com/matthewboh > 502 Fairview Avenue > Frederick, MD 21701 > work (301) 682-7901 > cell (301) 802-3235 > > > > -- > To unsubscribe from this list: send the line "unsubscribe kvm" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html >
--- qemu/block-raw-posix.c.orig 2010-01-06 22:27:56.000000000 -0700 +++ qemu/block-raw-posix.c 2010-01-06 22:29:51.000000000 -0700 @@ -193,20 +193,40 @@ static int raw_pread_aligned(BlockDriverState *bs, int64_t offset, uint8_t *buf, int count) { BDRVRawState *s = bs->opaque; int ret; ret = fd_open(bs); if (ret < 0) return ret; + /* media changes are only detected at the host layer when + * somethin reopens the cdrom device. Without an event + * notice, we need a heuristic. Try the following which mimics + * what is done for floppy drives. Here we reopen the cdrom + * after 3 seconds of elapsed time - this should be short + * enough to cover a user inserting a new disk and then accessing + * it via the CLI/GUI. + */ + if (bs->type == BDRV_TYPE_CDROM) { + static int64_t last = 0; + int64_t now = qemu_get_clock(rt_clock); + if ((now - last) > 3000) + ret = cdrom_reopen(bs); + else + ret = 0; + last = now; + if (ret < 0) + return ret; + } + if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) { ++(s->lseek_err_cnt); if(s->lseek_err_cnt <= 10) { DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 "] lseek failed : %d = %s\n", s->fd, bs->filename, offset, buf, count, bs->total_sectors, errno, strerror(errno)); } return -1; } --- qemu/hw/ide.c.orig 2010-01-06 22:28:02.000000000 -0700 +++ qemu/hw/ide.c 2010-01-06 22:30:45.000000000 -0700 @@ -1456,20 +1456,28 @@ s->cd_sector_size = sector_size; /* XXX: check if BUSY_STAT should be set */ s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT; ide_dma_start(s, ide_atapi_cmd_read_dma_cb); } static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors, int sector_size) { + if (s->is_cdrom) { + static int64_t last = 0; + int64_t now = qemu_get_clock(rt_clock); + if ((now - last) > 3000) + (void) cdrom_reopen(s->bs); + last = now; + } + #ifdef DEBUG_IDE_ATAPI printf("read %s: LBA=%d nb_sectors=%d\n", s->atapi_dma ? "dma" : "pio", lba, nb_sectors); #endif if (s->atapi_dma) { ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size); } else { ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size); } }