ia64/xen-unstable

changeset 15878:5352a7cc4f2a

[QEMU] Enhance raw io reliability

For raw block device only :
log any I/O error and perform automatic read retry for CDrom
(improves MediaCheck with old installers).

Signed-off-by: Ben Guthro <bguthro@virtualiron.com>
Signed-off-by: Josh Nicholas <jnicholas@virtualiron.com>
author kfraser@localhost.localdomain
date Tue Sep 11 17:02:03 2007 +0100 (2007-09-11)
parents 2e4912a256a4
children fec8b52b1a7f
files tools/ioemu/block-raw.c
line diff
     1.1 --- a/tools/ioemu/block-raw.c	Tue Sep 11 17:00:25 2007 +0100
     1.2 +++ b/tools/ioemu/block-raw.c	Tue Sep 11 17:02:03 2007 +0100
     1.3 @@ -59,6 +59,13 @@
     1.4  
     1.5  //#define DEBUG_FLOPPY
     1.6  
     1.7 +#define DEBUG_BLOCK
     1.8 +#ifdef  DEBUG_BLOCK
     1.9 +#define DEBUG_BLOCK_PRINT( formatCstr, args... ) fprintf( logfile, formatCstr, ##args ); fflush( logfile )
    1.10 +#else
    1.11 +#define DEBUG_BLOCK_PRINT( formatCstr, args... )
    1.12 +#endif
    1.13 +
    1.14  #define FTYPE_FILE   0
    1.15  #define FTYPE_CD     1
    1.16  #define FTYPE_FD     2
    1.17 @@ -70,6 +77,7 @@
    1.18  typedef struct BDRVRawState {
    1.19      int fd;
    1.20      int type;
    1.21 +    unsigned int lseek_err_cnt;
    1.22  #if defined(__linux__)
    1.23      /* linux floppy specific */
    1.24      int fd_open_flags;
    1.25 @@ -87,6 +95,8 @@ static int raw_open(BlockDriverState *bs
    1.26      BDRVRawState *s = bs->opaque;
    1.27      int fd, open_flags, ret;
    1.28  
    1.29 +    s->lseek_err_cnt = 0;
    1.30 +
    1.31      open_flags = O_BINARY;
    1.32      if ((flags & BDRV_O_ACCESS) == O_RDWR) {
    1.33          open_flags |= O_RDWR;
    1.34 @@ -137,8 +147,58 @@ static int raw_pread(BlockDriverState *b
    1.35      if (ret < 0)
    1.36          return ret;
    1.37  
    1.38 -    lseek(s->fd, offset, SEEK_SET);
    1.39 +    if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
    1.40 +        ++(s->lseek_err_cnt);
    1.41 +        if(s->lseek_err_cnt <= 10) {
    1.42 +                DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %ld, %p, %d) [%ld] lseek failed : %d = %s\n", 
    1.43 +                        s->fd, 
    1.44 +                        bs->filename, 
    1.45 +                        offset, 
    1.46 +                        buf, 
    1.47 +                        count, 
    1.48 +                        bs->total_sectors, errno, strerror(errno) );
    1.49 +       }
    1.50 +       return -1;
    1.51 +    }
    1.52 +    s->lseek_err_cnt=0;
    1.53 +
    1.54      ret = read(s->fd, buf, count);
    1.55 +    if (ret == count) 
    1.56 +        goto label__raw_read__success;
    1.57 +    
    1.58 +    DEBUG_BLOCK_PRINT("raw_read(%d:%s, %ld, %p, %d) [%ld] read failed %d : %d = %s\n", 
    1.59 +        s->fd, 
    1.60 +        bs->filename, 
    1.61 +        offset, 
    1.62 +        buf, 
    1.63 +        count, 
    1.64 +        bs->total_sectors, 
    1.65 +        ret, errno, strerror(errno) );
    1.66 +    
    1.67 +    if (bs->type == BDRV_TYPE_CDROM) {  // Try harder for CDrom
    1.68 +        lseek(s->fd, offset, SEEK_SET);
    1.69 +        ret = read(s->fd, buf, count);
    1.70 +        if (ret == count) 
    1.71 +            goto label__raw_read__success;
    1.72 +        lseek(s->fd, offset, SEEK_SET);
    1.73 +        ret = read(s->fd, buf, count);
    1.74 +        if (ret == count)
    1.75 +            goto label__raw_read__success;
    1.76 +        
    1.77 +        DEBUG_BLOCK_PRINT("raw_read(%d:%s, %ld, %p, %d) [%ld] retry read failed %d : %d = %s\n", 
    1.78 +            s->fd, 
    1.79 +            bs->filename, 
    1.80 +            offset, 
    1.81 +            buf, 
    1.82 +            count, 
    1.83 +            bs->total_sectors, 
    1.84 +            ret, errno, strerror(errno) );
    1.85 +    }
    1.86 +    
    1.87 +    return -1;
    1.88 +    
    1.89 +label__raw_read__success:
    1.90 +
    1.91      return ret;
    1.92  }
    1.93  
    1.94 @@ -152,8 +212,38 @@ static int raw_pwrite(BlockDriverState *
    1.95      if (ret < 0)
    1.96          return ret;
    1.97  
    1.98 -    lseek(s->fd, offset, SEEK_SET);
    1.99 +    if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
   1.100 +        ++(s->lseek_err_cnt);
   1.101 +        if(s->lseek_err_cnt) {
   1.102 +                DEBUG_BLOCK_PRINT("raw_write(%d:%s, %ld, %p, %d) [%ld] lseek failed : %d = %s\n", 
   1.103 +                        s->fd, 
   1.104 +                        bs->filename, 
   1.105 +                        offset, 
   1.106 +                        buf, 
   1.107 +                        count, 
   1.108 +                        bs->total_sectors, errno, strerror(errno) );
   1.109 +        }
   1.110 +        return -1;
   1.111 +    }
   1.112 +    s->lseek_err_cnt = 0;
   1.113 +
   1.114      ret = write(s->fd, buf, count);
   1.115 +    if (ret == count) 
   1.116 +        goto label__raw_write__success;
   1.117 +    
   1.118 +    DEBUG_BLOCK_PRINT("raw_write(%d:%s, %ld, %p, %d) [%ld] write failed %d : %d = %s\n", 
   1.119 +        s->fd, 
   1.120 +        bs->filename, 
   1.121 +        offset, 
   1.122 +        buf, 
   1.123 +        count, 
   1.124 +        bs->total_sectors, 
   1.125 +        ret, errno, strerror(errno) );
   1.126 +    
   1.127 +    return -1;
   1.128 +    
   1.129 +label__raw_write__success:
   1.130 +
   1.131      return ret;
   1.132  }
   1.133