From patchwork Fri Apr 23 18:52:58 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "David S. Ahern" X-Patchwork-Id: 94741 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o3NIr5es003532 for ; Fri, 23 Apr 2010 18:53:06 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752826Ab0DWSxA (ORCPT ); Fri, 23 Apr 2010 14:53:00 -0400 Received: from sj-iport-4.cisco.com ([171.68.10.86]:48751 "EHLO sj-iport-4.cisco.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752231Ab0DWSxA (ORCPT ); Fri, 23 Apr 2010 14:53:00 -0400 Authentication-Results: sj-iport-4.cisco.com; dkim=neutral (message not signed) header.i=none X-Files: qemu-reopen-cdrom.patch : 4080 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av0EAKaJ0UurR7H+/2dsb2JhbACDFpkWcaQpiGmRQoJxgS1tBIM3 X-IronPort-AV: E=Sophos;i="4.52,263,1270425600"; d="scan'208";a="119742111" Received: from sj-core-2.cisco.com ([171.71.177.254]) by sj-iport-4.cisco.com with ESMTP; 23 Apr 2010 18:52:59 +0000 Received: from [10.89.5.213] (rcdn-vpn-client-10-89-5-213.cisco.com [10.89.5.213]) by sj-core-2.cisco.com (8.13.8/8.14.3) with ESMTP id o3NIqwSu005884; Fri, 23 Apr 2010 18:52:58 GMT Message-ID: <4BD1EC8A.8000008@cisco.com> Date: Fri, 23 Apr 2010 12:52:58 -0600 From: "David S. Ahern" User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.9) Gecko/20100330 Fedora/3.0.4-1.fc12 Thunderbird/3.0.4 MIME-Version: 1.0 To: Matt Burkhardt CC: kvm@vger.kernel.org Subject: Re: Mount and unmount CD References: <1272035406.2911.16.camel@mlb-dell> <4BD1E485.2090104@cisco.com> In-Reply-To: <4BD1E485.2090104@cisco.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Fri, 23 Apr 2010 18:53:06 +0000 (UTC) --- 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 #include +#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