]> git.proxmox.com Git - pve-qemu-kvm.git/blame - debian/patches/pve/0016-backup-vma-add-dir-format.patch
bump version to 2.9.0-1~rc2+5
[pve-qemu-kvm.git] / debian / patches / pve / 0016-backup-vma-add-dir-format.patch
CommitLineData
87ba737b 1From 99a526d92531d64ff0c31a83d0d55f38651a32a5 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
adeb0c7a 4Subject: [PATCH 16/48] backup: vma: add dir format
ca0fe5f5
WB
5
6---
e9ee6d7c 7 blockdev.c | 137 ++++++++++++++++++++++++++++++++++++++++---------------
ca0fe5f5
WB
8 hmp-commands.hx | 8 ++--
9 hmp.c | 4 +-
10 qapi-schema.json | 2 +-
68a30562 11 vma.c | 2 +-
e9ee6d7c 12 5 files changed, 111 insertions(+), 42 deletions(-)
ca0fe5f5
WB
13
14diff --git a/blockdev.c b/blockdev.c
87ba737b 15index 3e5c9ce..af1b9d4 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;
e9ee6d7c
WB
57@@ -3175,6 +3179,7 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
58 GList *di_list = NULL;
59 GList *l;
60 UuidInfo *uuid_info;
61+ BlockJob *job;
62
63 if (backup_state.di_list) {
64 error_set(errp, ERROR_CLASS_GENERIC_ERROR,
65@@ -3185,11 +3190,6 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
ca0fe5f5
WB
66 /* Todo: try to auto-detect format based on file name */
67 format = has_format ? format : BACKUP_FORMAT_VMA;
68
69- if (format != BACKUP_FORMAT_VMA) {
70- error_set(errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
71- return NULL;
72- }
73-
74 if (has_devlist) {
75 devs = g_strsplit_set(devlist, ",;:", -1);
76
e9ee6d7c 77@@ -3258,27 +3258,62 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
ca0fe5f5
WB
78
79 uuid_generate(uuid);
80
81- vmaw = vma_writer_create(backup_file, uuid, &local_err);
82- if (!vmaw) {
83- if (local_err) {
84- error_propagate(errp, local_err);
85+ if (format == BACKUP_FORMAT_VMA) {
86+ vmaw = vma_writer_create(backup_file, uuid, &local_err);
87+ if (!vmaw) {
88+ if (local_err) {
89+ error_propagate(errp, local_err);
90+ }
91+ goto err;
92 }
93- goto err;
94- }
95
96- /* register all devices for vma writer */
97- l = di_list;
98- while (l) {
99- PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
100- l = g_list_next(l);
101+ /* register all devices for vma writer */
102+ l = di_list;
103+ while (l) {
104+ PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
105+ l = g_list_next(l);
106
107- const char *devname = bdrv_get_device_name(di->bs);
108- di->dev_id = vma_writer_register_stream(vmaw, devname, di->size);
109- if (di->dev_id <= 0) {
110- error_set(errp, ERROR_CLASS_GENERIC_ERROR,
111- "register_stream failed");
112+ const char *devname = bdrv_get_device_name(di->bs);
113+ di->dev_id = vma_writer_register_stream(vmaw, devname, di->size);
114+ if (di->dev_id <= 0) {
115+ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
116+ "register_stream failed");
117+ goto err;
118+ }
119+ }
120+ } else if (format == BACKUP_FORMAT_DIR) {
121+ if (mkdir(backup_file, 0640) != 0) {
122+ error_setg_errno(errp, errno, "can't create directory '%s'\n",
123+ backup_file);
124 goto err;
125 }
126+ backup_dir = backup_file;
127+
128+ l = di_list;
129+ while (l) {
130+ PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
131+ l = g_list_next(l);
132+
133+ const char *devname = bdrv_get_device_name(di->bs);
134+ snprintf(di->targetfile, PATH_MAX, "%s/%s.raw", backup_dir, devname);
135+
68a30562 136+ int flags = BDRV_O_RDWR;
ca0fe5f5
WB
137+ bdrv_img_create(di->targetfile, "raw", NULL, NULL, NULL,
138+ di->size, flags, &local_err, false);
139+ if (local_err) {
140+ error_propagate(errp, local_err);
141+ goto err;
142+ }
143+
68a30562
WB
144+ di->target = bdrv_open(di->targetfile, NULL, NULL, flags, &local_err);
145+ if (!di->target) {
ca0fe5f5
WB
146+ error_propagate(errp, local_err);
147+ goto err;
148+ }
149+ }
150+ } else {
151+ error_set(errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
152+ goto err;
153 }
154
155 /* add configuration file to archive */
e9ee6d7c 156@@ -3291,12 +3326,27 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
ca0fe5f5
WB
157 goto err;
158 }
159
160- const char *basename = g_path_get_basename(config_file);
161- if (vma_writer_add_config(vmaw, basename, cdata, clen) != 0) {
162- error_setg(errp, "unable to add config data to vma archive");
163- g_free(cdata);
164- goto err;
165+ char *basename = g_path_get_basename(config_file);
166+
167+ if (format == BACKUP_FORMAT_VMA) {
168+ if (vma_writer_add_config(vmaw, basename, cdata, clen) != 0) {
169+ error_setg(errp, "unable to add config data to vma archive");
170+ g_free(cdata);
171+ g_free(basename);
172+ goto err;
173+ }
174+ } else if (format == BACKUP_FORMAT_DIR) {
175+ char config_path[PATH_MAX];
176+ snprintf(config_path, PATH_MAX, "%s/%s", backup_dir, basename);
177+ if (!g_file_set_contents(config_path, cdata, clen, &err)) {
178+ error_setg(errp, "unable to write config file '%s'", config_path);
179+ g_free(cdata);
180+ g_free(basename);
181+ goto err;
182+ }
183 }
184+
185+ g_free(basename);
186 g_free(cdata);
187 }
188
87ba737b 189@@ -3335,15 +3385,16 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
e9ee6d7c 190 while (l) {
ca0fe5f5
WB
191 PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
192 l = g_list_next(l);
e9ee6d7c 193-
1a91ab45
WB
194- backup_job_create(NULL, di->bs, NULL, speed, MIRROR_SYNC_MODE_FULL, NULL,
195- BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
e9ee6d7c
WB
196- pvebackup_dump_cb, pvebackup_complete_cb, di,
197- 1, NULL, &local_err);
198- if (local_err != NULL) {
199+ job = backup_job_create(NULL, di->bs, di->target, speed, MIRROR_SYNC_MODE_FULL, NULL,
200+ false, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
201+ BLOCK_JOB_DEFAULT,
202+ pvebackup_dump_cb, pvebackup_complete_cb, di,
203+ 1, NULL, &local_err);
204+ if (!job || local_err != NULL) {
205 error_setg(&backup_state.error, "backup_job_create failed");
206 pvebackup_cancel(NULL);
207 }
87ba737b
WB
208+ block_job_start(job);
209 }
210
211 if (!backup_state.error) {
212@@ -3352,14 +3403,24 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
e9ee6d7c
WB
213
214 uuid_info = g_malloc0(sizeof(*uuid_info));
215 uuid_info->UUID = g_strdup(backup_state.uuid_str);
216+
e9ee6d7c
WB
217 return uuid_info;
218
219 err:
ca0fe5f5
WB
220
221 l = di_list;
222 while (l) {
223- g_free(l->data);
224+ PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
225 l = g_list_next(l);
226+
227+ if (di->target) {
228+ bdrv_unref(di->target);
229+ }
230+
231+ if (di->targetfile[0]) {
232+ unlink(di->targetfile);
233+ }
234+ g_free(di);
235 }
236 g_list_free(di_list);
237
e9ee6d7c 238@@ -3373,6 +3434,10 @@ err:
ca0fe5f5
WB
239 unlink(backup_file);
240 }
241
242+ if (backup_dir) {
243+ rmdir(backup_dir);
244+ }
245+
246 return NULL;
247 }
248
249diff --git a/hmp-commands.hx b/hmp-commands.hx
1a91ab45 250index aea39d0..7288203 100644
ca0fe5f5
WB
251--- a/hmp-commands.hx
252+++ b/hmp-commands.hx
253@@ -89,9 +89,11 @@ ETEXI
254
255 {
256 .name = "backup",
257- .args_type = "backupfile:s,speed:o?,devlist:s?",
258- .params = "backupfile [speed [devlist]]",
259- .help = "create a VM Backup.",
260+ .args_type = "directory:-d,backupfile:s,speed:o?,devlist:s?",
261+ .params = "[-d] backupfile [speed [devlist]]",
262+ .help = "create a VM Backup."
263+ "\n\t\t\t Use -d to dump data into a directory instead"
264+ "\n\t\t\t of using VMA format.",
1a91ab45 265 .cmd = hmp_backup,
ca0fe5f5
WB
266 },
267
268diff --git a/hmp.c b/hmp.c
1a91ab45 269index c685ba5..465d7fa 100644
ca0fe5f5
WB
270--- a/hmp.c
271+++ b/hmp.c
1a91ab45 272@@ -1664,11 +1664,13 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
ca0fe5f5
WB
273 {
274 Error *error = NULL;
275
276+ int dir = qdict_get_try_bool(qdict, "directory", 0);
277 const char *backup_file = qdict_get_str(qdict, "backupfile");
278 const char *devlist = qdict_get_try_str(qdict, "devlist");
279 int64_t speed = qdict_get_try_int(qdict, "speed", 0);
280
281- qmp_backup(backup_file, true, BACKUP_FORMAT_VMA, false, NULL, !!devlist,
282+ qmp_backup(backup_file, true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
283+ false, NULL, !!devlist,
284 devlist, qdict_haskey(qdict, "speed"), speed, &error);
285
286 hmp_handle_error(mon, &error);
287diff --git a/qapi-schema.json b/qapi-schema.json
1a91ab45 288index 059cbfc..1127f2c 100644
ca0fe5f5
WB
289--- a/qapi-schema.json
290+++ b/qapi-schema.json
1a91ab45 291@@ -609,7 +609,7 @@
ca0fe5f5
WB
292 # @vma: Proxmox vma backup format
293 ##
294 { 'enum': 'BackupFormat',
295- 'data': [ 'vma' ] }
296+ 'data': [ 'vma', 'dir' ] }
297
298 ##
299 # @backup:
68a30562 300diff --git a/vma.c b/vma.c
1a91ab45 301index 8925407..1ffaced 100644
68a30562
WB
302--- a/vma.c
303+++ b/vma.c
1a91ab45 304@@ -264,7 +264,7 @@ static int extract_content(int argc, char **argv)
68a30562
WB
305 g_free(statefn);
306 } else if (di) {
307 char *devfn = NULL;
308- int flags = BDRV_O_RDWR|BDRV_O_CACHE_WB;
309+ int flags = BDRV_O_RDWR;
310 bool write_zero = true;
311
312 if (readmap) {
ca0fe5f5
WB
313--
3142.1.4
315