[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 22/26] FVD: add impl of interface bdrv_update()
From: |
Chunqiang Tang |
Subject: |
[Qemu-devel] [PATCH 22/26] FVD: add impl of interface bdrv_update() |
Date: |
Fri, 25 Feb 2011 17:38:02 -0500 |
This patch is part of the Fast Virtual Disk (FVD) proposal.
See http://wiki.qemu.org/Features/FVD.
This patch adds FVD's implementation of the bdrv_update() interface.
Signed-off-by: Chunqiang Tang <address@hidden>
---
block/fvd-update.c | 274 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 272 insertions(+), 2 deletions(-)
diff --git a/block/fvd-update.c b/block/fvd-update.c
index 2498618..4ef4969 100644
--- a/block/fvd-update.c
+++ b/block/fvd-update.c
@@ -1,5 +1,5 @@
/*
- * QEMU Fast Virtual Disk Format bdrv_update
+ * QEMU Fast Virtual Disk Format Misc Functions of BlockDriver Interface
*
* Copyright IBM, Corp. 2010
*
@@ -13,9 +13,279 @@
static int fvd_update(BlockDriverState * bs, QEMUOptionParameter * options)
{
- return -ENOTSUP;
+ BDRVFvdState *s = bs->opaque;
+ FvdHeader header;
+ int ret;
+
+ read_fvd_header(s, &header);
+
+ while (options && options->name) {
+ if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
+ if (header.table_offset > 0) {
+ fprintf(stderr, "Cannot resize a compact FVD image.\n");
+ return -EINVAL;
+ }
+ if (options->value.n < header.virtual_disk_size) {
+ printf("Warning: image's new size %" PRId64
+ " is smaller than the original size %" PRId64
+ ". Some image data will be truncated.\n",
+ options->value.n, header.virtual_disk_size);
+ }
+ header.virtual_disk_size = options->value.n;
+ printf("Image resized to %" PRId64 " bytes.\n", options->value.n);
+ } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
+ if (strlen(options->value.s) > 1023) {
+ fprintf(stderr, "Error: the new base image name is longer "
+ "than 1023, which is not allowed.\n");
+ return -EINVAL;
+ }
+ memset(header.base_img, 0, 1024);
+ pstrcpy(header.base_img, 1024, options->value.s);
+ printf("Backing file updated to '%s'.\n", options->value.s);
+ } else if (!strcmp(options->name, "data_file")) {
+ if (strlen(options->value.s) > 1023) {
+ fprintf(stderr, "Error: the new data file name is longer "
+ "than 1023, which is not allowed.\n");
+ return -EINVAL;
+ }
+
+ memset(header.data_file, 0, 1024);
+ pstrcpy(header.data_file, 1024, options->value.s);
+ printf("Data file updated to '%s'.\n", options->value.s);
+ } else if (!strcmp(options->name, "need_zero_init")) {
+ header.need_zero_init = options->value.n;
+ if (header.need_zero_init) {
+ printf("need_zero_init is turned on.\n");
+ } else {
+ printf("need_zero_init is turned off.\n");
+ }
+ } else if (!strcmp(options->name, "copy_on_read")) {
+ header.copy_on_read = options->value.n;
+ if (header.copy_on_read) {
+ printf("Copy on read is enabled for this disk.\n");
+ } else {
+ printf("Copy on read is disabled for this disk.\n");
+ }
+ } else if (!strcmp(options->name, "clean_shutdown")) {
+ header.clean_shutdown = options->value.n;
+ if (header.clean_shutdown) {
+ printf("clean_shutdown is manually set to true\n");
+ } else {
+ printf("clean_shutdown is manually set to false\n");
+ }
+ } else if (!strcmp(options->name, "journal_buf_size")) {
+ header.journal_buf_size = options->value.n;
+ printf("journal_buf_size is updated to %"PRIu64" bytes.\n",
+ header.journal_buf_size);
+ } else if (!strcmp(options->name, "journal_clean_buf_period")) {
+ header.journal_clean_buf_period = options->value.n;
+ printf("journal_clean_buf_period is updated to %"PRIu64
+ " milliseconds.\n",
+ header.journal_clean_buf_period);
+ } else if (!strcmp(options->name,"max_outstanding_copy_on_read_data"))
{
+ header.max_outstanding_copy_on_read_data = options->value.n;
+ if (header.max_outstanding_copy_on_read_data <= 0) {
+ fprintf(stderr, "Error: max_outstanding_copy_on_read_data "
+ "must be positive.\n");
+ return -EINVAL;
+ }
+ printf("max_outstanding_copy_on_read_data updated to %" PRId64
+ ".\n", header.max_outstanding_copy_on_read_data);
+ } else if (!strcmp(options->name, "init_data_region")) {
+ if (options->value.n && !s->data_region_prepared) {
+ init_data_region(s);
+ }
+ } else if (!strcmp(options->name, "prefetch_start_delay")) {
+ if (options->value.n <= 0) {
+ header.prefetch_start_delay = -1;
+ } else {
+ header.prefetch_start_delay = options->value.n;
+ }
+ if (header.prefetch_start_delay > 0) {
+ printf("Prefetch starting delay updated to %" PRId64
+ " seconds.\n", header.prefetch_start_delay);
+ } else {
+ printf("Prefetch starting delay updated to %" PRId64
+ " seconds. "
+ "Because of the negative value, prefetching is "
+ "disabled for this image.\n",
+ header.prefetch_start_delay);
+ }
+ } else if (!strcmp(options->name, "num_prefetch_slots")) {
+ header.num_prefetch_slots = options->value.n;
+ if (header.num_prefetch_slots < 1) {
+ fprintf(stderr, "Error: num_prefetch_slots "
+ "%d is not a positive integer.\n",
+ header.num_prefetch_slots);
+ return -EINVAL;
+ }
+ printf("num_prefetch_slots updated to %d.\n",
+ header.num_prefetch_slots);
+ } else if (!strcmp(options->name, "bytes_per_prefetch")) {
+ header.bytes_per_prefetch = options->value.n;
+ if (header.bytes_per_prefetch < DEF_PAGE_SIZE) {
+ fprintf(stderr, "Error: bytes_per_prefetch cannot be smaller "
+ "than %d.\n", DEF_PAGE_SIZE);
+ return -EINVAL;
+ }
+ printf("bytes_per_prefetch updated to %" PRIu64 ".\n",
+ header.bytes_per_prefetch);
+ } else if (!strcmp(options->name, "prefetch_min_read_throughput")) {
+ header.prefetch_min_read_throughput = options->value.n;
+ printf("prefetch_min_read_throughput updated to %"
+ PRIu64 " KB/s\n", header.prefetch_min_read_throughput);
+ } else if (!strcmp(options->name, "prefetch_min_write_throughput")) {
+ header.prefetch_min_write_throughput = options->value.n;
+ printf("prefetch_min_write_throughput updated to %"
+ PRIu64 "KB/s\n", header.prefetch_min_write_throughput);
+ } else if (!strcmp(options->name,
+ "prefetch_read_throughput_measure_time")) {
+ header.prefetch_read_throughput_measure_time = options->value.n;
+ printf("prefetch_read_throughput_measure_time updated to %" PRIu64
+ " ms\n", header.prefetch_read_throughput_measure_time);
+ } else if (!strcmp(options->name,
+ "prefetch_write_throughput_measure_time")) {
+ header.prefetch_write_throughput_measure_time = options->value.n;
+ printf("prefetch_write_throughput_measure_time updated to %" PRIu64
+ " ms\n", header.prefetch_write_throughput_measure_time);
+ } else if (!strcmp(options->name,
+ "prefetch_over_threshold_throttle_time")) {
+ header.prefetch_throttle_time = options->value.n;
+ if (header.prefetch_throttle_time > 0) {
+ printf("prefetch_over_threshold_throttle_time updated to %"
+ PRIu64 "ms.\n", header.prefetch_throttle_time);
+ } else {
+ printf("prefetch_over_threshold_throttle_time updated to %"
+ PRIu64 "ms. It is not positive and hence no "
+ "throttling will be applied to prefetch.\n",
+ header.prefetch_throttle_time);
+ }
+ } else if (!strcmp(options->name, "storage_grow_unit")) {
+ header.storage_grow_unit = options->value.n;
+ if (header.storage_grow_unit < header.chunk_size) {
+ header.storage_grow_unit = header.chunk_size;
+ }
+ printf("storage_grow_unit updated to %" PRIu64 "\n",
+ header.storage_grow_unit);
+ } else if (!strcmp(options->name, "add_storage_cmd")) {
+ if (strlen(options->value.s) > 1023) {
+ fprintf(stderr, "Error: add_storage_cmd is longer than 1023, "
+ "which is not allowed.\n");
+ return -EINVAL;
+ }
+ pstrcpy(header.add_storage_cmd, 1024, options->value.s);
+ } else {
+ fprintf(stderr, "Error: unknown option '%s=%s'\n",
+ options->name, options->value.s);
+ return -EINVAL;
+ }
+ options++;
+ }
+
+ if ((ret = update_fvd_header(s, &header))) {
+ return ret;
+ }
+ ret = bdrv_flush(s->fvd_metadata);
+ return ret;
}
static QEMUOptionParameter fvd_update_options[] = {
+ {
+ .name = BLOCK_OPT_SIZE,
+ .type = OPT_SIZE,
+ .help = "Virtual disk size"},
+ {
+ .name = "storage_grow_unit",
+ .type = OPT_SIZE,
+ .help = "Storage grow unit"},
+ {
+ .name = "add_storage_cmd",
+ .type = OPT_STRING,
+ .help = "Command to add storage when running out of space"},
+ {
+ .name = BLOCK_OPT_BACKING_FILE,
+ .type = OPT_STRING,
+ .help = "File name of a backing image"},
+ {
+ .name = BLOCK_OPT_BACKING_FMT,
+ .type = OPT_STRING,
+ .help = "Image format of the backing image"},
+ {
+ .name = "data_file",
+ .type = OPT_STRING,
+ .help = "File name of a data file"},
+ {
+ .name = "data_file_fmt",
+ .type = OPT_STRING,
+ .help = "Image format of the data file"},
+ {
+ .name = "copy_on_read",
+ .type = OPT_FLAG,
+ .help = "copy_on_read=on|off"},
+ {
+ .name = "prefetch_start_delay",
+ .type = OPT_NUMBER,
+ .help = "Delay in seconds before starting whole image prefetching. "},
+ {
+ .name = "journal_size",
+ .type = OPT_SIZE,
+ .help = "Journal size"},
+ {
+ .name = "need_zero_init",
+ .type = OPT_FLAG,
+ .help = "compact_image=on|off"},
+ {
+ .name = "max_outstanding_copy_on_read_data",
+ .type = OPT_SIZE,
+ .help = "copy_on_read is temporarily disabled when unsaved data exceed "
+ "this threshold (in bytes)"},
+ {
+ .name = "init_data_region",
+ .type = OPT_FLAG,
+ .help = "if enabled the image file will be expanded to its full size"},
+ {
+ .name = "journal_buf_size",
+ .type = OPT_SIZE,
+ .help = "size of in-memory journal buffer (in bytes)"},
+ {
+ .name = "journal_clean_buf_period",
+ .type = OPT_NUMBER,
+ .help = "(milliseconds)"},
+ {
+ .name = "num_prefetch_slots",
+ .type = OPT_NUMBER,
+ .help = "Number of concurrent prefetches allowed"},
+ {
+ .name = "bytes_per_prefetch",
+ .type = OPT_NUMBER,
+ .help = "Data to read per prefetch"},
+ {
+ .name = "prefetch_over_threshold_throttle_time",
+ .type = OPT_NUMBER,
+ .help = "(in milliseconds)"},
+ {
+ .name = "prefetch_read_throughput_measure_time",
+ .type = OPT_NUMBER,
+ .help = "(in milliseconds)"},
+ {
+ .name = "prefetch_write_throughput_measure_time",
+ .type = OPT_NUMBER,
+ .help = "(in milliseconds)"},
+ {
+ .name = "prefetch_min_read_throughput",
+ .type = OPT_NUMBER,
+ .help = "(in KB/s)"},
+ {
+ .name = "prefetch_max_read_throughput",
+ .type = OPT_NUMBER,
+ .help = "(in KB/s)"},
+ {
+ .name = "prefetch_min_write_throughput",
+ .type = OPT_NUMBER,
+ .help = "(in KB/s)"},
+ {
+ .name = "prefetch_max_write_throughput",
+ .type = OPT_NUMBER,
+ .help = "(in KB/s)"},
{NULL}
};
--
1.7.0.4
- [Qemu-devel] [PATCH 10/26] FVD: add impl of interface bdrv_file_open(), (continued)
- [Qemu-devel] [PATCH 10/26] FVD: add impl of interface bdrv_file_open(), Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 08/26] FVD: add debugging utilities, Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 16/26] FVD: add impl for buffered journal updates, Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 20/26] FVD: add impl of interface bdrv_get_info(), Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 24/26] FVD: add impl of interface bdrv_has_zero_init(), Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 21/26] FVD: add impl of interface bdrv_close(), Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 14/26] FVD: add impl of loading data from compact image, Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 26/26] FVD: add fully automated test-fvd.sh, Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 23/26] FVD: add impl of interface bdrv_is_allocated(), Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 17/26] FVD: add impl of bdrv_flush() and bdrv_aio_flush(), Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 22/26] FVD: add impl of interface bdrv_update(),
Chunqiang Tang <=
- [Qemu-devel] [PATCH 13/26] FVD: add impl of storing data in compact image, Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 19/26] FVD: add support for aio_cancel, Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 25/26] FVD: add impl of interface bdrv_probe(), Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 15/26] FVD: add basic journal functionality, Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 18/26] FVD: add support for base image prefetching, Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 03/26] FVD: add fully automated test-qcow2.sh, Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 02/26] FVD: extend qemu-io to do fully automated testing, Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 07/26] FVD: extend FVD header fvd.h to be more complete, Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 12/26] FVD: add impl of interface bdrv_aio_readv(), Chunqiang Tang, 2011/02/25
- [Qemu-devel] [PATCH 11/26] FVD: add impl of interface bdrv_aio_writev(), Chunqiang Tang, 2011/02/25