]> git.proxmox.com Git - pve-qemu.git/blame - debian/patches/pve/0050-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch
vma: restore: call blk_unref for all opened block devices
[pve-qemu.git] / debian / patches / pve / 0050-qemu-img-dd-add-l-option-for-loading-a-snapshot.patch
CommitLineData
f6d40bfd
FE
1From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2From: Fabian Ebner <f.ebner@proxmox.com>
3Date: Mon, 7 Feb 2022 14:21:01 +0100
4Subject: [PATCH] qemu-img: dd: add -l option for loading a snapshot
5
6Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
7---
8 docs/tools/qemu-img.rst | 6 +++---
9 qemu-img-cmds.hx | 4 ++--
10 qemu-img.c | 33 +++++++++++++++++++++++++++++++--
11 3 files changed, 36 insertions(+), 7 deletions(-)
12
13diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
14index a49badb158..1039aec01c 100644
15--- a/docs/tools/qemu-img.rst
16+++ b/docs/tools/qemu-img.rst
17@@ -492,10 +492,10 @@ Command description:
18 it doesn't need to be specified separately in this case.
19
20
21-.. option:: dd [--image-opts] [-U] [-f FMT] [-O OUTPUT_FMT] [-n] [bs=BLOCK_SIZE] [count=BLOCKS] [skip=BLOCKS] if=INPUT of=OUTPUT
22+.. option:: dd [--image-opts] [-U] [-f FMT] [-O OUTPUT_FMT] [-n] [-l SNAPSHOT_PARAM] [bs=BLOCK_SIZE] [count=BLOCKS] [skip=BLOCKS] if=INPUT of=OUTPUT
23
24- dd copies from *INPUT* file to *OUTPUT* file converting it from
25- *FMT* format to *OUTPUT_FMT* format.
26+ dd copies from *INPUT* file or snapshot *SNAPSHOT_PARAM* to *OUTPUT* file
27+ converting it from *FMT* format to *OUTPUT_FMT* format.
28
29 The data is by default read and written using blocks of 512 bytes but can be
30 modified by specifying *BLOCK_SIZE*. If count=\ *BLOCKS* is specified
31diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
32index f3b2b1b4de..e77ed9347f 100644
33--- a/qemu-img-cmds.hx
34+++ b/qemu-img-cmds.hx
35@@ -58,9 +58,9 @@ SRST
36 ERST
37
38 DEF("dd", img_dd,
39- "dd [--image-opts] [-U] [-f fmt] [-O output_fmt] [-n] [bs=block_size] [count=blocks] [skip=blocks] [osize=output_size] if=input of=output")
40+ "dd [--image-opts] [-U] [-f fmt] [-O output_fmt] [-n] [-l snapshot_param] [bs=block_size] [count=blocks] [skip=blocks] [osize=output_size] if=input of=output")
41 SRST
42-.. option:: dd [--image-opts] [-U] [-f FMT] [-O OUTPUT_FMT] [-n] [bs=BLOCK_SIZE] [count=BLOCKS] [skip=BLOCKS] [osize=OUTPUT_SIZE] if=INPUT of=OUTPUT
43+.. option:: dd [--image-opts] [-U] [-f FMT] [-O OUTPUT_FMT] [-n] [-l SNAPSHOT_PARAM] [bs=BLOCK_SIZE] [count=BLOCKS] [skip=BLOCKS] [osize=OUTPUT_SIZE] if=INPUT of=OUTPUT
44 ERST
45
46 DEF("info", img_info,
47diff --git a/qemu-img.c b/qemu-img.c
48index 015d6d2ce4..7031195e32 100644
49--- a/qemu-img.c
50+++ b/qemu-img.c
51@@ -4922,6 +4922,7 @@ static int img_dd(int argc, char **argv)
52 BlockDriver *drv = NULL, *proto_drv = NULL;
53 BlockBackend *blk1 = NULL, *blk2 = NULL;
54 QemuOpts *opts = NULL;
55+ QemuOpts *sn_opts = NULL;
56 QemuOptsList *create_opts = NULL;
57 Error *local_err = NULL;
58 bool image_opts = false;
59@@ -4931,6 +4932,7 @@ static int img_dd(int argc, char **argv)
60 int64_t size = 0, readsize = 0;
61 int64_t block_count = 0, out_pos, in_pos;
62 bool force_share = false, skip_create = false;
63+ const char *snapshot_name = NULL;
64 struct DdInfo dd = {
65 .flags = 0,
66 .count = 0,
67@@ -4968,7 +4970,7 @@ static int img_dd(int argc, char **argv)
68 { 0, 0, 0, 0 }
69 };
70
71- while ((c = getopt_long(argc, argv, ":hf:O:Un", long_options, NULL))) {
72+ while ((c = getopt_long(argc, argv, ":hf:O:l:Un", long_options, NULL))) {
73 if (c == EOF) {
74 break;
75 }
76@@ -4991,6 +4993,19 @@ static int img_dd(int argc, char **argv)
77 case 'n':
78 skip_create = true;
79 break;
80+ case 'l':
81+ if (strstart(optarg, SNAPSHOT_OPT_BASE, NULL)) {
82+ sn_opts = qemu_opts_parse_noisily(&internal_snapshot_opts,
83+ optarg, false);
84+ if (!sn_opts) {
85+ error_report("Failed in parsing snapshot param '%s'",
86+ optarg);
87+ goto out;
88+ }
89+ } else {
90+ snapshot_name = optarg;
91+ }
92+ break;
93 case 'U':
94 force_share = true;
95 break;
96@@ -5050,11 +5065,24 @@ static int img_dd(int argc, char **argv)
97 if (dd.flags & C_IF) {
98 blk1 = img_open(image_opts, in.filename, fmt, 0, false, false,
99 force_share);
100-
101 if (!blk1) {
102 ret = -1;
103 goto out;
104 }
105+ if (sn_opts) {
106+ bdrv_snapshot_load_tmp(blk_bs(blk1),
107+ qemu_opt_get(sn_opts, SNAPSHOT_OPT_ID),
108+ qemu_opt_get(sn_opts, SNAPSHOT_OPT_NAME),
109+ &local_err);
110+ } else if (snapshot_name != NULL) {
111+ bdrv_snapshot_load_tmp_by_id_or_name(blk_bs(blk1), snapshot_name,
112+ &local_err);
113+ }
114+ if (local_err) {
115+ error_reportf_err(local_err, "Failed to load snapshot: ");
116+ ret = -1;
117+ goto out;
118+ }
119 }
120
121 if (dd.flags & C_OSIZE) {
122@@ -5203,6 +5231,7 @@ static int img_dd(int argc, char **argv)
123 out:
124 g_free(arg);
125 qemu_opts_del(opts);
126+ qemu_opts_del(sn_opts);
127 qemu_opts_free(create_opts);
128 blk_unref(blk1);
129 blk_unref(blk2);