From 72ffaae5e4824671aec0ec3643663a13450c3a44 Mon Sep 17 00:00:00 2001 From: Robert Wang Date: Tue, 9 Aug 2011 16:13:17 +0800 Subject: [PATCH] block.c --- block.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/block.c b/block.c index 26910ca143..41da58980e 100644 --- a/block.c +++ b/block.c @@ -29,6 +29,7 @@ #include "module.h" #include "qemu-objects.h" #include "qemu-coroutine.h" +#include "block/add-cow.h" #ifdef CONFIG_BSD #include @@ -324,12 +325,18 @@ static BlockDriver *find_hdev_driver(const char *filename) return drv; } -BlockDriver *bdrv_find_protocol(const char *filename) +BlockDriver *bdrv_find_protocol(const char *filename1) { BlockDriver *drv1; char protocol[128]; int len; const char *p; + char *filename = NULL; + char *cow_file = NULL; + char filename_buff[1024]; + snprintf(filename_buff,sizeof(filename_buff),"%s",filename1); + filename = strtok(filename_buff,":"); + cow_file = strtok(NULL, ":" ); /* TODO Drivers without bdrv_file_open must be specified explicitly */ @@ -370,8 +377,19 @@ static int find_image_format(const char *filename, BlockDriver **pdrv) BlockDriver *drv1, *drv; uint8_t buf[2048]; BlockDriverState *bs; + char *image_file = NULL; + char *cow_file = NULL; + char filename_buff[1024]; + snprintf(filename_buff,sizeof(filename_buff),"%s",filename); + + image_file = strtok(filename_buff,":"); + cow_file = strtok(NULL,":"); + + ret = bdrv_file_open(&bs, image_file, 0); + + if(cow_file) + sprintf(bs->cow_file,"%s",cow_file); - ret = bdrv_file_open(&bs, filename, 0); if (ret < 0) { *pdrv = NULL; return ret; @@ -547,10 +565,18 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags) /* * Opens a disk image (raw, qcow2, vmdk, ...) */ -int bdrv_open(BlockDriverState *bs, const char *filename, int flags, +int bdrv_open(BlockDriverState *bs, const char *filename1, int flags, BlockDriver *drv) { int ret; + char *filename = NULL; + char *cowfile = NULL; + struct add_cow_head header; + + char filename_buff[1024]; + snprintf(filename_buff,sizeof(filename_buff),"%s",filename1); + filename = strtok(filename_buff,":"); + cowfile = strtok(NULL,":"); if (flags & BDRV_O_SNAPSHOT) { BlockDriverState *bs1; @@ -608,6 +634,12 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, bs->is_temporary = 1; } + if(cowfile) { + snprintf(bs->cow_file, sizeof(bs->cow_file), "%s", cowfile); + get_add_cow_head(cowfile, &header); + sprintf(bs->backing_file,"%s",header.backing_file); + } + /* Find the right image format driver */ if (!drv) { ret = find_image_format(filename, &drv); @@ -3143,6 +3175,7 @@ int bdrv_img_create(const char *filename, const char *fmt, BlockDriver *drv, *proto_drv; BlockDriver *backing_drv = NULL; int ret = 0; + QEMUOptionParameter *cow_file; /* Find driver and parse its options */ drv = bdrv_find_format(fmt); @@ -3219,6 +3252,27 @@ int bdrv_img_create(const char *filename, const char *fmt, } } + + // add cow support + if (!strcmp(fmt, "raw")) { + cow_file = get_option_parameter(param, BLOCK_OPT_COW_FILE); + if(cow_file->value.s && cow_file->value.s) { + if( !strcmp(cow_file->value.s,backing_file->value.s)) { + error_report("Error: Trying to create an cow file with the " + "same filename as the backing file"); + ret = -EINVAL; + goto out; + } + + if( !strcmp(cow_file->value.s, filename)) { + error_report("Error: Trying to create an cow file with the " + "same filename as the image file"); + ret = -EINVAL; + goto out; + } + } + } + // The size for the image must always be specified, with one exception: // If we are using a backing file, we can obtain the size from there size = get_option_parameter(param, BLOCK_OPT_SIZE); -- 2.11.4.GIT