public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: "David S. Ahern" <daahern@cisco.com>
To: Matt Burkhardt <mlb@imparisystems.com>
Cc: kvm@vger.kernel.org
Subject: Re: Mount and unmount CD
Date: Fri, 23 Apr 2010 12:52:58 -0600	[thread overview]
Message-ID: <4BD1EC8A.8000008@cisco.com> (raw)
In-Reply-To: <4BD1E485.2090104@cisco.com>

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

  reply	other threads:[~2010-04-23 18:53 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-23 15:10 Mount and unmount CD Matt Burkhardt
2010-04-23 18:18 ` David S. Ahern
2010-04-23 18:52   ` David S. Ahern [this message]
     [not found]     ` <1272209538.8137.7.camel@mlb-dell>
2010-04-25 15:45       ` Mount and unmount CD Bug reporting David S. Ahern

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4BD1EC8A.8000008@cisco.com \
    --to=daahern@cisco.com \
    --cc=kvm@vger.kernel.org \
    --cc=mlb@imparisystems.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox