qemu-img: Add 'resize' command to grow/shrink disk images

This patch adds a 'resize' command to grow/shrink disk images.  This
allows changing the size of disk images without copying to a new image
file.  Currently only raw files support resize.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2010-04-24 09:12:12 +01:00 committed by Kevin Wolf
parent 51762288b4
commit ae6b0ed6d4
3 changed files with 110 additions and 0 deletions

View file

@ -49,5 +49,11 @@ DEF("rebase", img_rebase,
"rebase [-f fmt] [-u] -b backing_file [-F backing_fmt] filename")
STEXI
@item rebase [-f @var{fmt}] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
ETEXI
DEF("resize", img_resize,
"resize filename [+ | -]size")
STEXI
@item rebase @var{filename} [+ | -]@var{size}
@end table
ETEXI

View file

@ -1225,6 +1225,98 @@ static int img_rebase(int argc, char **argv)
return 0;
}
static int img_resize(int argc, char **argv)
{
int c, ret, relative;
const char *filename, *fmt, *size;
int64_t n, total_size;
BlockDriverState *bs;
QEMUOptionParameter *param;
QEMUOptionParameter resize_options[] = {
{
.name = BLOCK_OPT_SIZE,
.type = OPT_SIZE,
.help = "Virtual disk size"
},
{ NULL }
};
fmt = NULL;
for(;;) {
c = getopt(argc, argv, "f:h");
if (c == -1) {
break;
}
switch(c) {
case 'h':
help();
break;
case 'f':
fmt = optarg;
break;
}
}
if (optind + 1 >= argc) {
help();
}
filename = argv[optind++];
size = argv[optind++];
/* Choose grow, shrink, or absolute resize mode */
switch (size[0]) {
case '+':
relative = 1;
size++;
break;
case '-':
relative = -1;
size++;
break;
default:
relative = 0;
break;
}
/* Parse size */
param = parse_option_parameters("", resize_options, NULL);
if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) {
/* Error message already printed when size parsing fails */
exit(1);
}
n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n;
free_option_parameters(param);
bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
if (relative) {
total_size = bdrv_getlength(bs) + n * relative;
} else {
total_size = n;
}
if (total_size <= 0) {
error("New image size must be positive");
}
ret = bdrv_truncate(bs, total_size);
switch (ret) {
case 0:
printf("Image resized.\n");
break;
case -ENOTSUP:
error("This image format does not support resize");
break;
case -EACCES:
error("Image is read-only");
break;
default:
error("Error resizing image (%d)", -ret);
break;
}
bdrv_delete(bs);
return 0;
}
static const img_cmd_t img_cmds[] = {
#define DEF(option, callback, arg_string) \
{ option, callback },

View file

@ -106,6 +106,18 @@ they are displayed too.
@item snapshot [-l | -a @var{snapshot} | -c @var{snapshot} | -d @var{snapshot} ] @var{filename}
List, apply, create or delete snapshots in image @var{filename}.
@item resize @var{filename} [+ | -]@var{size}
Change the disk image as if it had been created with @var{size}.
Before using this command to shrink a disk image, you MUST use file system and
partitioning tools inside the VM to reduce allocated file systems and partition
sizes accordingly. Failure to do so will result in data loss!
After using this command to grow a disk image, you must use file system and
partitioning tools inside the VM to actually begin using the new space on the
device.
@end table
Supported image file formats: