From 608ae3ded15566900ee67d5e10e6747bebe99d2f Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Fri, 12 Aug 2011 15:38:11 +0200 Subject: [PATCH 03/15] block: add -drive copy-on-read=on|off RH-Author: Anthony Liguori Message-id: <1313163503-2523-4-git-send-email-aliguori@redhat.com> Patchwork-id: 31325 O-Subject: [RHEL6.2 qemu PATCH 03/15] block: add -drive copy-on-read=on|off Bugzilla: 633370 RH-Acked-by: Marcelo Tosatti RH-Acked-by: Daniel P. Berrange RH-Acked-by: Kevin Wolf RH-Acked-by: Orit Wasserman RH-Acked-by: Christoph Hellwig From: Stefan Hajnoczi This patch adds the -drive copy-on-read=on|off command-line option: copy-on-read=on|off copy-on-read is "on" or "off" and enables whether to copy read backing file sectors into the image file. Copy-on-read avoids accessing the same backing file sectors repeatedly and is useful when the backing file is over a slow network. By default copy-on-read is off. The new BlockDriverState.copy_on_read field indicates whether copy-on-read is enabled. Block drivers can use this as a hint to copy sectors read from the backing file into the image file. The point of copy-on-read is to avoid accessing the backing file again in the future. Block drivers that do not honor the copy-on-read hint simply read data without populating the image file. Signed-off-by: Stefan Hajnoczi Signed-off-by: Anthony Liguori Bugzilla: 633370 --- block.c | 5 +++++ block.h | 1 + block_int.h | 1 + blockdev.c | 6 ++++++ qemu-config.c | 4 ++++ qemu-monitor.hx | 3 ++- qemu-options.hx | 10 +++++++++- 7 files changed, 28 insertions(+), 2 deletions(-) Signed-off-by: Michal Novotny --- block.c | 5 +++++ block.h | 1 + block_int.h | 1 + blockdev.c | 6 ++++++ qemu-config.c | 4 ++++ qemu-monitor.hx | 3 ++- qemu-options.hx | 10 +++++++++- 7 files changed, 28 insertions(+), 2 deletions(-) diff --git a/block.c b/block.c index 22da5c7..383b62d 100644 --- a/block.c +++ b/block.c @@ -414,6 +414,11 @@ static int bdrv_open_common(BlockDriverState *bs, const char *filename, /* buffer_alignment defaulted to 512, drivers can change this value */ bs->buffer_alignment = 512; + bs->copy_on_read = 0; + if (flags & BDRV_O_RDWR) { + bs->copy_on_read = !!(flags & BDRV_O_COPY_ON_READ); + } + pstrcpy(bs->filename, sizeof(bs->filename), filename); if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) { diff --git a/block.h b/block.h index 216b496..b47c450 100644 --- a/block.h +++ b/block.h @@ -33,6 +33,7 @@ typedef struct QEMUSnapshotInfo { #define BDRV_O_NATIVE_AIO 0x0080 /* use native AIO instead of the thread pool */ #define BDRV_O_NO_BACKING 0x0100 /* don't open the backing file */ #define BDRV_O_NO_FLUSH 0x0200 /* disable flushing on this disk */ +#define BDRV_O_COPY_ON_READ 0x0400 /* copy read backing sectors into image */ #define BDRV_O_INCOMING 0x0800 /* consistency hint for incoming migration */ #define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_CACHE_WB) diff --git a/block_int.h b/block_int.h index ef162b9..3c36aa4 100644 --- a/block_int.h +++ b/block_int.h @@ -151,6 +151,7 @@ struct BlockDriverState { int encrypted; /* if true, the media is encrypted */ int valid_key; /* if true, a valid encryption key has been set */ int sg; /* if true, the device is a /dev/sg* */ + int copy_on_read; /* if true, copy read backing sectors into image */ /* event callback when inserting/removing */ void (*change_cb)(void *opaque, int reason); void *change_opaque; diff --git a/blockdev.c b/blockdev.c index 1f7ef2f..b1dc74f 100644 --- a/blockdev.c +++ b/blockdev.c @@ -279,6 +279,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi) DriveInfo *dinfo; int is_extboot = 0; int snapshot = 0; + int copy_on_read; translation = BIOS_ATA_TRANSLATION_AUTO; @@ -302,6 +303,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi) snapshot = qemu_opt_get_bool(opts, "snapshot", 0); ro = qemu_opt_get_bool(opts, "readonly", 0); + copy_on_read = qemu_opt_get_bool(opts, "copy-on-read", 0); file = qemu_opt_get(opts, "file"); serial = qemu_opt_get(opts, "serial"); @@ -569,6 +571,10 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi) bdrv_flags |= (BDRV_O_SNAPSHOT|BDRV_O_CACHE_WB); } + if (copy_on_read) { + bdrv_flags |= BDRV_O_COPY_ON_READ; + } + if (media == MEDIA_CDROM) { /* mark CDROM as read-only. CDROM is fine for any interface, don't check */ ro = 1; diff --git a/qemu-config.c b/qemu-config.c index 4a2afde..adb9970 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -83,6 +83,10 @@ QemuOptsList qemu_drive_opts = { .name = "boot", .type = QEMU_OPT_BOOL, .help = "make this a boot drive", + },{ + .name = "copy-on-read", + .type = QEMU_OPT_BOOL, + .help = "copy read data from backing file into image file", }, { /* end if list */ } }, diff --git a/qemu-monitor.hx b/qemu-monitor.hx index cb72152..cc70dba 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -1288,7 +1288,8 @@ EQMP "[file=file][,if=type][,bus=n]\n" "[,unit=m][,media=d][index=i]\n" "[,cyls=c,heads=h,secs=s[,trans=t]]\n" - "[snapshot=on|off][,cache=on|off]", + "[snapshot=on|off][,cache=on|off]\n" + "[,copy-on-read=on|off]", .help = "add drive to PCI storage controller", .mhandler.cmd = drive_hot_add, }, diff --git a/qemu-options.hx b/qemu-options.hx index e5a9d02..78ecd2c 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -104,7 +104,7 @@ DEF("drive", HAS_ARG, QEMU_OPTION_drive, " [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n" " [,cache=writethrough|writeback|none|unsafe][,format=f]\n" " [,serial=s][,addr=A][,id=name][,aio=threads|native]\n" - " [,readonly=on|off]\n" + " [,readonly=on|off][,copy-on-read=on|off]\n" " use 'file' as a drive image\n") DEF("set", HAS_ARG, QEMU_OPTION_set, "-set group.id.arg=value\n" @@ -150,6 +150,9 @@ an untrusted format header. This option specifies the serial number to assign to the device. @item addr=@var{addr} Specify the controller's PCI address (if=virtio only). +@item copy-on-read=@var{copy-on-read} +@var{copy-on-read} is "on" or "off" and enables whether to copy read backing +file sectors into the image file. @end table By default, writethrough caching is used for all block device. This means that @@ -177,6 +180,11 @@ to the disk but can instead keeps things in cache. If anything goes wrong, like your host losing power, the disk storage getting disconnected accidently, etc. you're image will most probably be rendered unusable. +Copy-on-read avoids accessing the same backing file sectors repeatedly and is +useful when the backing file is over a slow network. By default copy-on-read +is off. Note that copy-on-read is a hint and may by ignored by block drivers +which do not support it. + Instead of @option{-cdrom} you can use: @example qemu -drive file=file,index=2,media=cdrom -- 1.7.4.4