diff --git a/block.c b/block.c
index 33f3d65..cffd95e 100644
--- a/block.c
+++ b/block.c
@@ -331,11 +331,10 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
 int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
                BlockDriver *drv)
 {
-    int ret, open_flags;
+    int ret, open_flags, try_rw;
     char tmp_filename[PATH_MAX];
     char backing_filename[PATH_MAX];
 
-    bs->read_only = 0;
     bs->is_temporary = 0;
     bs->encrypted = 0;
     bs->valid_key = 0;
@@ -422,9 +421,10 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
 
     /* Note: for compatibility, we open disk image files as RDWR, and
        RDONLY as fallback */
+    try_rw = !bs->read_only || bs->is_temporary;
     if (!(flags & BDRV_O_FILE))
-        open_flags = BDRV_O_RDWR |
-		(flags & (BDRV_O_CACHE_MASK|BDRV_O_NATIVE_AIO));
+        open_flags = (try_rw ? BDRV_O_RDWR : 0) |
+            (flags & (BDRV_O_CACHE_MASK|BDRV_O_NATIVE_AIO));
     else
         open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
     ret = drv->bdrv_open(bs, filename, open_flags);
@@ -453,6 +453,8 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
         /* if there is a backing file, use it */
         BlockDriver *back_drv = NULL;
         bs->backing_hd = bdrv_new("");
+        /* pass on read_only property to the backing_hd */
+        bs->backing_hd->read_only = bs->read_only;
         path_combine(backing_filename, sizeof(backing_filename),
                      filename, bs->backing_file);
         if (bs->backing_format[0] != '\0')
@@ -731,6 +733,8 @@ int bdrv_truncate(BlockDriverState *bs, int64_t offset)
         return -ENOMEDIUM;
     if (!drv->bdrv_truncate)
         return -ENOTSUP;
+    if (bs->read_only)
+        return -EACCES;
     return drv->bdrv_truncate(bs, offset);
 }
 
@@ -925,6 +929,13 @@ int bdrv_is_read_only(BlockDriverState *bs)
     return bs->read_only;
 }
 
+int bdrv_set_read_only(BlockDriverState *bs, int read_only)
+{
+    int ret = bs->read_only;
+    bs->read_only = read_only;
+    return ret;
+}
+
 int bdrv_is_sg(BlockDriverState *bs)
 {
     return bs->sg;
diff --git a/block.h b/block.h
index a966afb..302010d 100644
--- a/block.h
+++ b/block.h
@@ -136,6 +136,7 @@ int bdrv_get_type_hint(BlockDriverState *bs);
 int bdrv_get_translation_hint(BlockDriverState *bs);
 int bdrv_is_removable(BlockDriverState *bs);
 int bdrv_is_read_only(BlockDriverState *bs);
+int bdrv_set_read_only(BlockDriverState *bs, int read_only);
 int bdrv_is_sg(BlockDriverState *bs);
 int bdrv_enable_write_cache(BlockDriverState *bs);
 int bdrv_is_inserted(BlockDriverState *bs);
diff --git a/qemu-config.c b/qemu-config.c
index cae92f7..4ac8fa0 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -71,6 +71,9 @@ QemuOptsList qemu_drive_opts = {
             .name = "addr",
             .type = QEMU_OPT_STRING,
             .help = "pci address (virtio only)",
+        },{
+            .name = "readonly",
+            .type = QEMU_OPT_BOOL,
         },
         { /* end if list */ }
     },
diff --git a/vl.c b/vl.c
index eb2744e..97a940e 100644
--- a/vl.c
+++ b/vl.c
@@ -2007,6 +2007,7 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
     int index;
     int cache;
     int aio = 0;
+    int ro = 0;
     int bdrv_flags, onerror;
     const char *devaddr;
     DriveInfo *dinfo;
@@ -2038,6 +2039,7 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
     secs  = qemu_opt_get_number(opts, "secs", 0);
 
     snapshot = qemu_opt_get_bool(opts, "snapshot", 0);
+    ro = qemu_opt_get_bool(opts, "readonly", 0);
 
     file = qemu_opt_get(opts, "file");
     serial = qemu_opt_get(opts, "serial");
@@ -2329,6 +2331,14 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
         bdrv_flags &= ~BDRV_O_NATIVE_AIO;
     }
 
+    if (ro == 1) {
+        if (type == IF_IDE) {
+            fprintf(stderr, "qemu: readonly flag not supported for drive with ide interface\n");
+            return NULL;
+        }
+        (void)bdrv_set_read_only(dinfo->bdrv, 1);
+    }
+
     if (bdrv_open2(dinfo->bdrv, file, bdrv_flags, drv) < 0) {
         fprintf(stderr, "qemu: could not open disk image %s: %s\n",
                         file, strerror(errno));
