qemu-img: Add --start-offset and --max-length to map
The mapping operation of large disks especially ones stored over a long chain of QCOW2 files can take a long time to finish. Additionally when mapping fails there was no way recover by restarting the mapping from the failed location. The new options, --start-offset and --max-length allows the user to divide these type of map operations into shorter independent tasks. Reviewed-by: Eric Blake <eblake@redhat.com> Acked-by: Mark Kanda <mark.kanda@oracle.com> Co-developed-by: Yoav Elnekave <yoav.elnekave@oracle.com> Signed-off-by: Yoav Elnekave <yoav.elnekave@oracle.com> Signed-off-by: Eyal Moscovici <eyal.moscovici@oracle.com> Message-Id: <20200513133629.18508-5-eyal.moscovici@oracle.com> Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
e46c0b18cf
commit
c0469496b3
@ -519,7 +519,7 @@ Command description:
|
|||||||
``ImageInfoSpecific*`` QAPI object (e.g. ``ImageInfoSpecificQCow2``
|
``ImageInfoSpecific*`` QAPI object (e.g. ``ImageInfoSpecificQCow2``
|
||||||
for qcow2 images).
|
for qcow2 images).
|
||||||
|
|
||||||
.. option:: map [--object OBJECTDEF] [--image-opts] [-f FMT] [--output=OFMT] [-U] FILENAME
|
.. option:: map [--object OBJECTDEF] [--image-opts] [-f FMT] [--start-offset=OFFSET] [--max-length=LEN] [--output=OFMT] [-U] FILENAME
|
||||||
|
|
||||||
Dump the metadata of image *FILENAME* and its backing file chain.
|
Dump the metadata of image *FILENAME* and its backing file chain.
|
||||||
In particular, this commands dumps the allocation state of every sector
|
In particular, this commands dumps the allocation state of every sector
|
||||||
|
@ -63,9 +63,9 @@ SRST
|
|||||||
ERST
|
ERST
|
||||||
|
|
||||||
DEF("map", img_map,
|
DEF("map", img_map,
|
||||||
"map [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] [-U] filename")
|
"map [--object objectdef] [--image-opts] [-f fmt] [--start-offset=offset] [--max-length=len] [--output=ofmt] [-U] filename")
|
||||||
SRST
|
SRST
|
||||||
.. option:: map [--object OBJECTDEF] [--image-opts] [-f FMT] [--output=OFMT] [-U] FILENAME
|
.. option:: map [--object OBJECTDEF] [--image-opts] [-f FMT] [--start-offset=OFFSET] [--max-length=LEN] [--output=OFMT] [-U] FILENAME
|
||||||
ERST
|
ERST
|
||||||
|
|
||||||
DEF("measure", img_measure,
|
DEF("measure", img_measure,
|
||||||
|
22
qemu-img.c
22
qemu-img.c
@ -3009,6 +3009,8 @@ static int img_map(int argc, char **argv)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
bool image_opts = false;
|
bool image_opts = false;
|
||||||
bool force_share = false;
|
bool force_share = false;
|
||||||
|
int64_t start_offset = 0;
|
||||||
|
int64_t max_length = -1;
|
||||||
|
|
||||||
fmt = NULL;
|
fmt = NULL;
|
||||||
output = NULL;
|
output = NULL;
|
||||||
@ -3021,9 +3023,11 @@ static int img_map(int argc, char **argv)
|
|||||||
{"object", required_argument, 0, OPTION_OBJECT},
|
{"object", required_argument, 0, OPTION_OBJECT},
|
||||||
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
|
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
|
||||||
{"force-share", no_argument, 0, 'U'},
|
{"force-share", no_argument, 0, 'U'},
|
||||||
|
{"start-offset", required_argument, 0, 's'},
|
||||||
|
{"max-length", required_argument, 0, 'l'},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
c = getopt_long(argc, argv, ":f:hU",
|
c = getopt_long(argc, argv, ":f:s:l:hU",
|
||||||
long_options, &option_index);
|
long_options, &option_index);
|
||||||
if (c == -1) {
|
if (c == -1) {
|
||||||
break;
|
break;
|
||||||
@ -3047,6 +3051,18 @@ static int img_map(int argc, char **argv)
|
|||||||
case OPTION_OUTPUT:
|
case OPTION_OUTPUT:
|
||||||
output = optarg;
|
output = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 's':
|
||||||
|
start_offset = cvtnum("start offset", optarg);
|
||||||
|
if (start_offset < 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
max_length = cvtnum("max length", optarg);
|
||||||
|
if (max_length < 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case OPTION_OBJECT: {
|
case OPTION_OBJECT: {
|
||||||
QemuOpts *opts;
|
QemuOpts *opts;
|
||||||
opts = qemu_opts_parse_noisily(&qemu_object_opts,
|
opts = qemu_opts_parse_noisily(&qemu_object_opts,
|
||||||
@ -3097,7 +3113,11 @@ static int img_map(int argc, char **argv)
|
|||||||
error_report("Failed to get size for '%s'", filename);
|
error_report("Failed to get size for '%s'", filename);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (max_length != -1) {
|
||||||
|
length = MIN(start_offset + max_length, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
curr.start = start_offset;
|
||||||
while (curr.start + curr.length < length) {
|
while (curr.start + curr.length < length) {
|
||||||
int64_t offset = curr.start + curr.length;
|
int64_t offset = curr.start + curr.length;
|
||||||
int64_t n;
|
int64_t n;
|
||||||
|
Loading…
Reference in New Issue
Block a user