Re: Mount and unmount CD

David S. Ahern
2010-04-23T18:53:00Z

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

oops. the previous patch rides on top of this one.

David

On 04/23/2010 12:18 PM, David S. Ahern wrote:
> 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-reopen-cdrom.patch --]
[-- Type: text/plain, Size: 4080 bytes --]

--- qemu/block-raw-posix.c.orig 2010-01-06 21:46:31.000000000 -0700
+++ qemu/block-raw-posix.c 2010-01-06 21:54:22.000000000 -0700
@@ -107,20 +107,24 @@
int fd_got_error;
int fd_media_changed;
#endif
uint8_t* aligned_buf;
} BDRVRawState;

static int posix_aio_init(void);

static int fd_open(BlockDriverState *bs);

+#if defined(__linux__)
+int cdrom_reopen(BlockDriverState *bs);
+#endif
+
static int raw_open(BlockDriverState *bs, const char *filename, int flags)
{
BDRVRawState *s = bs->opaque;
int fd, open_flags, ret;

posix_aio_init();

s->lseek_err_cnt = 0;

open_flags = O_BINARY;
@@ -212,29 +216,32 @@
if (ret == count)
goto label__raw_read__success;

DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
"] read failed %d : %d = %s\n",
s->fd, bs->filename, offset, buf, count,
bs->total_sectors, ret, errno, strerror(errno));

/* Try harder for CDrom. */
if (bs->type == BDRV_TYPE_CDROM) {
- lseek(s->fd, offset, SEEK_SET);
- ret = read(s->fd, buf, count);
- if (ret == count)
- goto label__raw_read__success;
- lseek(s->fd, offset, SEEK_SET);
- ret = read(s->fd, buf, count);
- if (ret == count)
+ int i;
+ for (i = 0; i < 2; ++i) {
+#if defined(__linux__)
+ ret = cdrom_reopen(bs);
+ if (ret < 0)
goto label__raw_read__success;
-
+#endif
+ lseek(s->fd, offset, SEEK_SET);
+ ret = read(s->fd, buf, count);
+ if (ret == count)
+ goto label__raw_read__success;
+ }
DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
"] retry read failed %d : %d = %s\n",
s->fd, bs->filename, offset, buf, count,
bs->total_sectors, ret, errno, strerror(errno));
}

label__raw_read__success:

return ret;
}
@@ -1025,20 +1032,27 @@
printf("Floppy opened\n");
#endif
}
if (!last_media_present)
s->fd_media_changed = 1;
s->fd_open_time = qemu_get_clock(rt_clock);
s->fd_got_error = 0;
return 0;
}

+int cdrom_reopen(BlockDriverState *bs)
+{
+ /* mimics a 'change' monitor command - without the eject */
+ bdrv_close(bs);
+ return bdrv_open2(bs, bs->filename, 0, bs->drv);
+}
+
static int raw_is_inserted(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;
int ret;

switch(s->type) {
case FTYPE_CD:
ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
if (ret == CDS_DISC_OK)
return 1;
--- qemu/hw/ide.c.orig 2010-01-06 21:54:33.000000000 -0700
+++ qemu/hw/ide.c 2010-01-06 21:56:16.000000000 -0700
@@ -29,20 +29,24 @@
#include "pcmcia.h"
#include "block.h"
#include "block_int.h"
#include "qemu-timer.h"
#include "sysemu.h"
#include "ppc_mac.h"
#include "sh.h"
#include <console.h>
#include <syslog.h>

+#if defined(__linux__)
+int cdrom_reopen(BlockDriverState *bs);
+#endif
+
/* debug IDE devices */
//#define DEBUG_IDE
//#define DEBUG_IDE_ATAPI
//#define DEBUG_AIO
#define USE_DMA_CDROM

/* Bits of HD_STATUS */
#define ERR_STAT 0x01
#define INDEX_STAT 0x02
#define ECC_STAT 0x04 /* Corrected error */
@@ -1363,20 +1367,25 @@
/* ATAPI DMA support */

/* XXX: handle read errors */
static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
{
BMDMAState *bm = opaque;
IDEState *s = bm->ide_if;
int data_offset, n;

if (ret < 0) {
+#if defined(__linux__)
+ /* on EIO failure try re-opening file */
+ if (ret == -EIO)
+ (void) cdrom_reopen(s->bs);
+#endif
ide_atapi_io_error(s, ret);
goto eot;
}

if (s->io_buffer_size > 0) {
/*
* For a cdrom read sector command (s->lba != -1),
* adjust the lba for the next s->io_buffer_size chunk
* and dma the current chunk.
* For a command != read (s->lba == -1), just transfer