WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [qemu-xen-unstable] Fix read-only image file handling

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [qemu-xen-unstable] Fix read-only image file handling
From: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
Date: Wed, 9 Jun 2010 09:20:04 -0700
Delivery-date: Wed, 09 Jun 2010 09:20:14 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
commit 6392763643311272590ef5c6f75ba11d5b132585
Author: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Date:   Wed Jun 9 17:10:59 2010 +0100

    Fix read-only image file handling
    
    Hi,
    this is the patch for qemu-xen-3.4-testing to fix the read-only
    image file handling since the image file was always treated as
    read-write which means that all the HVM guests were able to
    write to all the disk images available in domain configuration
    file no matter what the mode of the image was defined. This
    patch fixes this functionality to honor the O_RDONLY in the
    BDRV_O_ACCESS flag in block.c and also fixes the IDE and SCSI
    interfaces that uses it.
    
    It's been tested on RHEL-5 with xen-3.4-testing version of
    upstream xen with xen-3.4-testing qemu implementation. The
    patch is applicable to qemu-xen-unstable.git as well with no
    modifications.
    
    When you want to mount an image that is set as read-only in the
    domain configuration file but you omit to set mode to read-only
    it results into I/O errors when processing the requests.
    Remounting as read-only or unmounting and remounting using the
    `mount /dev/* /path/to/mount -o ro` shall do the mounting the
    correct way, i.e. with no I/O errors, so make sure you mount
    those disks as read-only otherwise you can be getting errors like:
    
    end_request: I/O error, dev hdb, sector 52
    Buffer I/O error on device hdb1, logical block 1
    lost page write due to I/O error on hdb1
    
    and for IDE devices you'll be getting several additional DeviceFault
    errors since mounting the device read-write (default setting) writes
    some data onto a disk at the mount-time.
    
    For SCSI devices the DATA PROTECT request sense has been added
    as found at: http://en.wikipedia.org/wiki/SCSI_Request_Sense_Command
    
    Michal
    
    Signed-off-by: Michal Novotny <minovotn@xxxxxxxxxx>
---
 block.c        |    2 +-
 hw/ide.c       |   27 +++++++++++++++++++++++++++
 hw/scsi-disk.c |    9 +++++++++
 xenstore.c     |   25 ++++++++++++++++++++++++-
 4 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/block.c b/block.c
index 88e70d3..05ff8cb 100644
--- a/block.c
+++ b/block.c
@@ -422,7 +422,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, 
int flags,
     /* Note: for compatibility, we open disk image files as RDWR, and
        RDONLY as fallback */
     if (!(flags & BDRV_O_FILE))
-        open_flags = BDRV_O_RDWR | (flags & BDRV_O_CACHE_MASK);
+        open_flags = (flags & BDRV_O_ACCESS) | (flags & BDRV_O_CACHE_MASK);
     else
         open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
     ret = drv->bdrv_open(bs, filename, open_flags);
diff --git a/hw/ide.c b/hw/ide.c
index b38de55..791666b 100644
--- a/hw/ide.c
+++ b/hw/ide.c
@@ -2551,6 +2551,15 @@ static void ide_ioport_write(void *opaque, uint32_t 
addr, uint32_t val)
         case WIN_WRITE_ONCE:
         case CFA_WRITE_SECT_WO_ERASE:
         case WIN_WRITE_VERIFY:
+            if (bdrv_is_read_only(s->bs)) {
+#if defined(DEBUG_IDE)
+                printf("Attempt to write on read-only device %s\n", 
s->bs->filename);
+#endif
+                s->status = WRERR_STAT;
+                s->error = ABRT_ERR;
+                ide_set_irq(s);
+                break;
+            }
            ide_cmd_lba48_transform(s, lba48);
             s->error = 0;
             s->status = SEEK_STAT | READY_STAT;
@@ -2573,6 +2582,15 @@ static void ide_ioport_write(void *opaque, uint32_t 
addr, uint32_t val)
         case CFA_WRITE_MULTI_WO_ERASE:
             if (!s->mult_sectors)
                 goto abort_cmd;
+           if (bdrv_is_read_only(s->bs)) {
+#if defined(DEBUG_IDE)
+                printf("Attempt to multiwrite on read-only device %s\n", 
s->bs->filename);
+#endif
+                s->status = WRERR_STAT;
+                s->error = ABRT_ERR;
+                ide_set_irq(s);
+                break;
+           }
            ide_cmd_lba48_transform(s, lba48);
             s->error = 0;
             s->status = SEEK_STAT | READY_STAT;
@@ -2598,6 +2616,15 @@ static void ide_ioport_write(void *opaque, uint32_t 
addr, uint32_t val)
         case WIN_WRITEDMA_ONCE:
             if (!s->bs)
                 goto abort_cmd;
+            if (bdrv_is_read_only(s->bs)) {
+#if defined(DEBUG_IDE)
+                printf("Attempt to DMA write to read-only device %s\n", 
s->bs->filename);
+#endif
+                s->status = WRERR_STAT;
+                s->error = ABRT_ERR;
+                ide_set_irq(s);
+                break;
+            }
            ide_cmd_lba48_transform(s, lba48);
             ide_sector_write_dma(s);
             s->media_changed = 1;
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 4fc18f0..520009e 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -35,6 +35,7 @@ do { fprintf(stderr, "scsi-disk: " fmt , ##args); } while (0)
 #define SENSE_NOT_READY       2
 #define SENSE_HARDWARE_ERROR  4
 #define SENSE_ILLEGAL_REQUEST 5
+#define SENSE_DATA_PROTECT    7
 
 #define STATUS_GOOD            0
 #define STATUS_CHECK_CONDITION 2
@@ -234,6 +235,9 @@ static int scsi_handle_write_error(SCSIRequest *r, int 
error)
             || action == BLOCK_ERR_STOP_ANY) {
         r->status |= SCSI_REQ_STATUS_RETRY;
         vm_stop(0);
+    } else if (error == SENSE_DATA_PROTECT) {
+        scsi_command_complete(r, STATUS_CHECK_CONDITION,
+                SENSE_DATA_PROTECT);
     } else {
         scsi_command_complete(r, STATUS_CHECK_CONDITION,
                 SENSE_HARDWARE_ERROR);
@@ -305,6 +309,11 @@ static int scsi_write_data(SCSIDevice *d, uint32_t tag)
         return 1;
     }
 
+    if (bdrv_is_read_only(r->dev->bdrv)) {
+        scsi_write_complete(r, SENSE_DATA_PROTECT);
+        return 1;
+    }
+
     if (r->aiocb)
         BADF("Data transfer already in progress\n");
 
diff --git a/xenstore.c b/xenstore.c
index c824459..4a35f55 100644
--- a/xenstore.c
+++ b/xenstore.c
@@ -403,6 +403,11 @@ void xenstore_parse_domain_config(int hvm_domid)
     BlockDriverState *bs;
     BlockDriver *format;
 
+    /* Read-only handling for image files */
+    char *mode = NULL;
+    int flags;
+    int is_readonly;
+
     /* paths controlled by untrustworthy guest, and values read from them */
     char *danger_path;
     char *danger_buf = NULL;
@@ -595,7 +600,24 @@ void xenstore_parse_domain_config(int hvm_domid)
                }
            }
             pstrcpy(bs->filename, sizeof(bs->filename), params);
-            if (bdrv_open2(bs, params, BDRV_O_CACHE_WB /* snapshot and 
write-back */, format) < 0)
+
+            flags = BDRV_O_CACHE_WB; /* snapshot and write-back */
+            is_readonly = 0;
+            if (pasprintf(&buf, "%s/mode", bpath) == -1)
+                continue;
+            free(mode);
+            mode = xs_read(xsh, XBT_NULL, buf, &len);
+            if (mode == NULL)
+                continue;
+            if (strchr(mode, 'r') && !strchr(mode, 'w'))
+                is_readonly = 1;
+
+            if (!is_readonly)
+                flags |= BDRV_O_ACCESS & O_RDWR;
+
+            fprintf(stderr, "Using file %s in read-%s mode\n", bs->filename, 
is_readonly ? "only" : "write");
+
+            if (bdrv_open2(bs, params, flags, format) < 0)
                 fprintf(stderr, "qemu: could not open vbd '%s' or hard disk 
image '%s' (drv '%s' format '%s')\n", buf, params, drv ? drv : "?", format ? 
format->format_name : "0");
         }
 
@@ -703,6 +725,7 @@ void xenstore_parse_domain_config(int hvm_domid)
 
  out:
     free(danger_type);
+    free(mode);
     free(params);
     free(dev);
     free(bpath);
--
generated by git-patchbot for /home/xen/git/qemu-xen-unstable.git

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [qemu-xen-unstable] Fix read-only image file handling, Ian Jackson <=