Re: Mount and unmount CD

David S. Ahern
2010-04-23T18:18:46Z

[-- Attachment #1: Type: text/plain, Size: 986 bytes --]

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@imparisystems.com
> 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@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>

[-- Attachment #2: qemu-cdrom-flush.patch --]
[-- Type: text/plain, Size: 2571 bytes --]

--- 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);
}
}