ETEXI
DEF("resize", img_resize,
- "resize [--object objectdef] [--image-opts] [-q] filename [+ | -]size")
+ "resize [--object objectdef] [--image-opts] [-q] [--shrink] filename [+ | -]size")
STEXI
-@item resize [--object @var{objectdef}] [--image-opts] [-q] @var{filename} [+ | -]@var{size}
+@item resize [--object @var{objectdef}] [--image-opts] [-q] [--shrink] @var{filename} [+ | -]@var{size}
ETEXI
STEXI
OPTION_TARGET_IMAGE_OPTS = 263,
OPTION_SIZE = 264,
OPTION_PREALLOCATION = 265,
+ OPTION_SHRINK = 266,
};
typedef enum OutputFormat {
},
};
bool image_opts = false;
+ bool shrink = false;
/* Remove size from argv manually so that negative numbers are not treated
* as options by getopt. */
{"object", required_argument, 0, OPTION_OBJECT},
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
{"preallocation", required_argument, 0, OPTION_PREALLOCATION},
+ {"shrink", no_argument, 0, OPTION_SHRINK},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, ":f:hq",
return 1;
}
break;
+ case OPTION_SHRINK:
+ shrink = true;
+ break;
}
}
if (optind != argc - 1) {
goto out;
}
+ if (total_size < current_size && !shrink) {
+ warn_report("Shrinking an image will delete all data beyond the "
+ "shrunken image's end. Before performing such an "
+ "operation, make sure there is no important data there.");
+
+ if (g_strcmp0(bdrv_get_format_name(blk_bs(blk)), "raw") != 0) {
+ error_report(
+ "Use the --shrink option to perform a shrink operation.");
+ ret = -1;
+ goto out;
+ } else {
+ warn_report("Using the --shrink option will suppress this message. "
+ "Note that future versions of qemu-img may refuse to "
+ "shrink images without this option.");
+ }
+ }
+
ret = blk_truncate(blk, total_size, prealloc, &err);
if (!ret) {
qprintf(quiet, "Image resized.\n");
At this point, @code{modified.img} can be discarded, since
@code{base.img + diff.qcow2} contains the same information.
-@item resize [--preallocation=@var{prealloc}] @var{filename} [+ | -]@var{size}
+@item resize [--shrink] [--preallocation=@var{prealloc}] @var{filename} [+ | -]@var{size}
Change the disk image as if it had been created with @var{size}.
partitioning tools inside the VM to reduce allocated file systems and partition
sizes accordingly. Failure to do so will result in data loss!
+When shrinking images, the @code{--shrink} option must be given. This informs
+qemu-img that the user acknowledges all loss of data beyond the truncated
+image's end.
+
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.
$QEMU_IO -c 'write 0 64k' "$TEST_IMG" | _filter_qemu_io
# Remove data cluster from image (first cluster: image header, second: reftable,
# third: refblock, fourth: L1 table, fifth: L2 table)
-$QEMU_IMG resize -f raw "$TEST_IMG" $((5 * 64 * 1024))
+$QEMU_IMG resize -f raw --shrink "$TEST_IMG" $((5 * 64 * 1024))
$QEMU_IO -c map "$TEST_IMG"
$QEMU_IMG map "$TEST_IMG"
qemu_comm_method=monitor _launch_qemu -drive if=none,file="$TEST_IMG",id=drv0
-$QEMU_IMG resize -f raw "$TEST_IMG" $((5 * 64 * 1024))
+$QEMU_IMG resize -f raw --shrink "$TEST_IMG" $((5 * 64 * 1024))
_send_qemu_cmd $QEMU_HANDLE 'qemu-io drv0 map' 'allocated' \
| sed -e 's/^(qemu).*qemu-io drv0 map...$/(qemu) qemu-io drv0 map/'
for growth_mode in falloc full off; do
echo
echo "--- growth_mode=$growth_mode ---"
- $QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" -${GROWTH_SIZE}K
+ $QEMU_IMG resize -f "$IMGFMT" --shrink --preallocation=$growth_mode "$TEST_IMG" -${GROWTH_SIZE}K
done
# success, all done