]> git.proxmox.com Git - pve-qemu-kvm.git/blame - debian/patches/pve/0016-backup-vma-add-dir-format.patch
update to qemu-2.9.0-rc2
[pve-qemu-kvm.git] / debian / patches / pve / 0016-backup-vma-add-dir-format.patch
CommitLineData
1a91ab45 1From 7a74d0bf611d5a700970ae5000235d9345104bf3 Mon Sep 17 00:00:00 2001
ca0fe5f5
WB
2From: Wolfgang Bumiller <w.bumiller@proxmox.com>
3Date: Wed, 9 Dec 2015 15:21:54 +0100
9c3bec39 4Subject: [PATCH 16/47] backup: vma: add dir format
ca0fe5f5
WB
5
6---
1a91ab45 7 blockdev.c | 127 +++++++++++++++++++++++++++++++++++++++++--------------
ca0fe5f5
WB
8 hmp-commands.hx | 8 ++--
9 hmp.c | 4 +-
10 qapi-schema.json | 2 +-
68a30562 11 vma.c | 2 +-
1a91ab45 12 5 files changed, 105 insertions(+), 38 deletions(-)
ca0fe5f5
WB
13
14diff --git a/blockdev.c b/blockdev.c
1a91ab45 15index 3e5c9ce..e065922 100644
ca0fe5f5
WB
16--- a/blockdev.c
17+++ b/blockdev.c
1a91ab45 18@@ -3007,6 +3007,8 @@ typedef struct PVEBackupDevInfo {
ca0fe5f5
WB
19 uint8_t dev_id;
20 //bool started;
21 bool completed;
22+ char targetfile[PATH_MAX];
23+ BlockDriverState *target;
24 } PVEBackupDevInfo;
25
26 static void pvebackup_run_next_job(void);
1a91ab45 27@@ -3075,8 +3077,6 @@ static void pvebackup_complete_cb(void *opaque, int ret)
ca0fe5f5
WB
28 {
29 PVEBackupDevInfo *di = opaque;
30
31- assert(backup_state.vmaw);
32-
33 di->completed = true;
34
35 if (ret < 0 && !backup_state.error) {
1a91ab45 36@@ -3087,8 +3087,11 @@ static void pvebackup_complete_cb(void *opaque, int ret)
ca0fe5f5
WB
37 BlockDriverState *bs = di->bs;
38
39 di->bs = NULL;
40+ di->target = NULL;
41
42- vma_writer_close_stream(backup_state.vmaw, di->dev_id);
43+ if (backup_state.vmaw) {
44+ vma_writer_close_stream(backup_state.vmaw, di->dev_id);
45+ }
46
47 block_job_cb(bs, ret);
48
1a91ab45 49@@ -3168,6 +3171,7 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
ca0fe5f5
WB
50 {
51 BlockBackend *blk;
52 BlockDriverState *bs = NULL;
53+ const char *backup_dir = NULL;
54 Error *local_err = NULL;
55 uuid_t uuid;
56 VmaWriter *vmaw = NULL;
1a91ab45 57@@ -3185,11 +3189,6 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
ca0fe5f5
WB
58 /* Todo: try to auto-detect format based on file name */
59 format = has_format ? format : BACKUP_FORMAT_VMA;
60
61- if (format != BACKUP_FORMAT_VMA) {
62- error_set(errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
63- return NULL;
64- }
65-
66 if (has_devlist) {
67 devs = g_strsplit_set(devlist, ",;:", -1);
68
1a91ab45 69@@ -3258,27 +3257,62 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
ca0fe5f5
WB
70
71 uuid_generate(uuid);
72
73- vmaw = vma_writer_create(backup_file, uuid, &local_err);
74- if (!vmaw) {
75- if (local_err) {
76- error_propagate(errp, local_err);
77+ if (format == BACKUP_FORMAT_VMA) {
78+ vmaw = vma_writer_create(backup_file, uuid, &local_err);
79+ if (!vmaw) {
80+ if (local_err) {
81+ error_propagate(errp, local_err);
82+ }
83+ goto err;
84 }
85- goto err;
86- }
87
88- /* register all devices for vma writer */
89- l = di_list;
90- while (l) {
91- PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
92- l = g_list_next(l);
93+ /* register all devices for vma writer */
94+ l = di_list;
95+ while (l) {
96+ PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
97+ l = g_list_next(l);
98
99- const char *devname = bdrv_get_device_name(di->bs);
100- di->dev_id = vma_writer_register_stream(vmaw, devname, di->size);
101- if (di->dev_id <= 0) {
102- error_set(errp, ERROR_CLASS_GENERIC_ERROR,
103- "register_stream failed");
104+ const char *devname = bdrv_get_device_name(di->bs);
105+ di->dev_id = vma_writer_register_stream(vmaw, devname, di->size);
106+ if (di->dev_id <= 0) {
107+ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
108+ "register_stream failed");
109+ goto err;
110+ }
111+ }
112+ } else if (format == BACKUP_FORMAT_DIR) {
113+ if (mkdir(backup_file, 0640) != 0) {
114+ error_setg_errno(errp, errno, "can't create directory '%s'\n",
115+ backup_file);
116 goto err;
117 }
118+ backup_dir = backup_file;
119+
120+ l = di_list;
121+ while (l) {
122+ PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
123+ l = g_list_next(l);
124+
125+ const char *devname = bdrv_get_device_name(di->bs);
126+ snprintf(di->targetfile, PATH_MAX, "%s/%s.raw", backup_dir, devname);
127+
68a30562 128+ int flags = BDRV_O_RDWR;
ca0fe5f5
WB
129+ bdrv_img_create(di->targetfile, "raw", NULL, NULL, NULL,
130+ di->size, flags, &local_err, false);
131+ if (local_err) {
132+ error_propagate(errp, local_err);
133+ goto err;
134+ }
135+
68a30562
WB
136+ di->target = bdrv_open(di->targetfile, NULL, NULL, flags, &local_err);
137+ if (!di->target) {
ca0fe5f5
WB
138+ error_propagate(errp, local_err);
139+ goto err;
140+ }
141+ }
142+ } else {
143+ error_set(errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
144+ goto err;
145 }
146
147 /* add configuration file to archive */
1a91ab45 148@@ -3291,12 +3325,27 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
ca0fe5f5
WB
149 goto err;
150 }
151
152- const char *basename = g_path_get_basename(config_file);
153- if (vma_writer_add_config(vmaw, basename, cdata, clen) != 0) {
154- error_setg(errp, "unable to add config data to vma archive");
155- g_free(cdata);
156- goto err;
157+ char *basename = g_path_get_basename(config_file);
158+
159+ if (format == BACKUP_FORMAT_VMA) {
160+ if (vma_writer_add_config(vmaw, basename, cdata, clen) != 0) {
161+ error_setg(errp, "unable to add config data to vma archive");
162+ g_free(cdata);
163+ g_free(basename);
164+ goto err;
165+ }
166+ } else if (format == BACKUP_FORMAT_DIR) {
167+ char config_path[PATH_MAX];
168+ snprintf(config_path, PATH_MAX, "%s/%s", backup_dir, basename);
169+ if (!g_file_set_contents(config_path, cdata, clen, &err)) {
170+ error_setg(errp, "unable to write config file '%s'", config_path);
171+ g_free(cdata);
172+ g_free(basename);
173+ goto err;
174+ }
175 }
176+
177+ g_free(basename);
178 g_free(cdata);
179 }
180
1a91ab45 181@@ -3336,8 +3385,9 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
ca0fe5f5
WB
182 PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
183 l = g_list_next(l);
184
1a91ab45
WB
185- backup_job_create(NULL, di->bs, NULL, speed, MIRROR_SYNC_MODE_FULL, NULL,
186- BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
187+ backup_job_create(NULL, di->bs, di->target, speed, MIRROR_SYNC_MODE_FULL, NULL,
188+ false, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
189+ BLOCK_JOB_DEFAULT,
190 pvebackup_dump_cb, pvebackup_complete_cb, di,
191 1, NULL, &local_err);
192 if (local_err != NULL) {
193@@ -3358,8 +3408,17 @@ err:
ca0fe5f5
WB
194
195 l = di_list;
196 while (l) {
197- g_free(l->data);
198+ PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
199 l = g_list_next(l);
200+
201+ if (di->target) {
202+ bdrv_unref(di->target);
203+ }
204+
205+ if (di->targetfile[0]) {
206+ unlink(di->targetfile);
207+ }
208+ g_free(di);
209 }
210 g_list_free(di_list);
211
1a91ab45 212@@ -3373,6 +3432,10 @@ err:
ca0fe5f5
WB
213 unlink(backup_file);
214 }
215
216+ if (backup_dir) {
217+ rmdir(backup_dir);
218+ }
219+
220 return NULL;
221 }
222
223diff --git a/hmp-commands.hx b/hmp-commands.hx
1a91ab45 224index aea39d0..7288203 100644
ca0fe5f5
WB
225--- a/hmp-commands.hx
226+++ b/hmp-commands.hx
227@@ -89,9 +89,11 @@ ETEXI
228
229 {
230 .name = "backup",
231- .args_type = "backupfile:s,speed:o?,devlist:s?",
232- .params = "backupfile [speed [devlist]]",
233- .help = "create a VM Backup.",
234+ .args_type = "directory:-d,backupfile:s,speed:o?,devlist:s?",
235+ .params = "[-d] backupfile [speed [devlist]]",
236+ .help = "create a VM Backup."
237+ "\n\t\t\t Use -d to dump data into a directory instead"
238+ "\n\t\t\t of using VMA format.",
1a91ab45 239 .cmd = hmp_backup,
ca0fe5f5
WB
240 },
241
242diff --git a/hmp.c b/hmp.c
1a91ab45 243index c685ba5..465d7fa 100644
ca0fe5f5
WB
244--- a/hmp.c
245+++ b/hmp.c
1a91ab45 246@@ -1664,11 +1664,13 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
ca0fe5f5
WB
247 {
248 Error *error = NULL;
249
250+ int dir = qdict_get_try_bool(qdict, "directory", 0);
251 const char *backup_file = qdict_get_str(qdict, "backupfile");
252 const char *devlist = qdict_get_try_str(qdict, "devlist");
253 int64_t speed = qdict_get_try_int(qdict, "speed", 0);
254
255- qmp_backup(backup_file, true, BACKUP_FORMAT_VMA, false, NULL, !!devlist,
256+ qmp_backup(backup_file, true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
257+ false, NULL, !!devlist,
258 devlist, qdict_haskey(qdict, "speed"), speed, &error);
259
260 hmp_handle_error(mon, &error);
261diff --git a/qapi-schema.json b/qapi-schema.json
1a91ab45 262index 059cbfc..1127f2c 100644
ca0fe5f5
WB
263--- a/qapi-schema.json
264+++ b/qapi-schema.json
1a91ab45 265@@ -609,7 +609,7 @@
ca0fe5f5
WB
266 # @vma: Proxmox vma backup format
267 ##
268 { 'enum': 'BackupFormat',
269- 'data': [ 'vma' ] }
270+ 'data': [ 'vma', 'dir' ] }
271
272 ##
273 # @backup:
68a30562 274diff --git a/vma.c b/vma.c
1a91ab45 275index 8925407..1ffaced 100644
68a30562
WB
276--- a/vma.c
277+++ b/vma.c
1a91ab45 278@@ -264,7 +264,7 @@ static int extract_content(int argc, char **argv)
68a30562
WB
279 g_free(statefn);
280 } else if (di) {
281 char *devfn = NULL;
282- int flags = BDRV_O_RDWR|BDRV_O_CACHE_WB;
283+ int flags = BDRV_O_RDWR;
284 bool write_zero = true;
285
286 if (readmap) {
ca0fe5f5
WB
287--
2882.1.4
289