]> git.proxmox.com Git - pve-qemu-kvm.git/blob - debian/patches/pve/0016-backup-vma-add-dir-format.patch
fix backup jobs
[pve-qemu-kvm.git] / debian / patches / pve / 0016-backup-vma-add-dir-format.patch
1 From cc5b1446be5c3501881f7968edb645425db839d1 Mon Sep 17 00:00:00 2001
2 From: Wolfgang Bumiller <w.bumiller@proxmox.com>
3 Date: Wed, 9 Dec 2015 15:21:54 +0100
4 Subject: [PATCH 16/47] backup: vma: add dir format
5
6 ---
7 blockdev.c | 137 ++++++++++++++++++++++++++++++++++++++++---------------
8 hmp-commands.hx | 8 ++--
9 hmp.c | 4 +-
10 qapi-schema.json | 2 +-
11 vma.c | 2 +-
12 5 files changed, 111 insertions(+), 42 deletions(-)
13
14 diff --git a/blockdev.c b/blockdev.c
15 index 3e5c9ce..4958a5f 100644
16 --- a/blockdev.c
17 +++ b/blockdev.c
18 @@ -3007,6 +3007,8 @@ typedef struct PVEBackupDevInfo {
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);
27 @@ -3075,8 +3077,6 @@ static void pvebackup_complete_cb(void *opaque, int ret)
28 {
29 PVEBackupDevInfo *di = opaque;
30
31 - assert(backup_state.vmaw);
32 -
33 di->completed = true;
34
35 if (ret < 0 && !backup_state.error) {
36 @@ -3087,8 +3087,11 @@ static void pvebackup_complete_cb(void *opaque, int ret)
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
49 @@ -3168,6 +3171,7 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
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;
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,
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
77 @@ -3258,27 +3258,62 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
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 +
136 + int flags = BDRV_O_RDWR;
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 +
144 + di->target = bdrv_open(di->targetfile, NULL, NULL, flags, &local_err);
145 + if (!di->target) {
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 */
156 @@ -3291,12 +3326,27 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
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
189 @@ -3335,12 +3385,12 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
190 while (l) {
191 PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
192 l = g_list_next(l);
193 -
194 - backup_job_create(NULL, di->bs, NULL, speed, MIRROR_SYNC_MODE_FULL, NULL,
195 - BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
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 }
208 @@ -3352,14 +3402,25 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
209
210 uuid_info = g_malloc0(sizeof(*uuid_info));
211 uuid_info->UUID = g_strdup(backup_state.uuid_str);
212 +
213 + block_job_start(job);
214 return uuid_info;
215
216 err:
217
218 l = di_list;
219 while (l) {
220 - g_free(l->data);
221 + PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
222 l = g_list_next(l);
223 +
224 + if (di->target) {
225 + bdrv_unref(di->target);
226 + }
227 +
228 + if (di->targetfile[0]) {
229 + unlink(di->targetfile);
230 + }
231 + g_free(di);
232 }
233 g_list_free(di_list);
234
235 @@ -3373,6 +3434,10 @@ err:
236 unlink(backup_file);
237 }
238
239 + if (backup_dir) {
240 + rmdir(backup_dir);
241 + }
242 +
243 return NULL;
244 }
245
246 diff --git a/hmp-commands.hx b/hmp-commands.hx
247 index aea39d0..7288203 100644
248 --- a/hmp-commands.hx
249 +++ b/hmp-commands.hx
250 @@ -89,9 +89,11 @@ ETEXI
251
252 {
253 .name = "backup",
254 - .args_type = "backupfile:s,speed:o?,devlist:s?",
255 - .params = "backupfile [speed [devlist]]",
256 - .help = "create a VM Backup.",
257 + .args_type = "directory:-d,backupfile:s,speed:o?,devlist:s?",
258 + .params = "[-d] backupfile [speed [devlist]]",
259 + .help = "create a VM Backup."
260 + "\n\t\t\t Use -d to dump data into a directory instead"
261 + "\n\t\t\t of using VMA format.",
262 .cmd = hmp_backup,
263 },
264
265 diff --git a/hmp.c b/hmp.c
266 index c685ba5..465d7fa 100644
267 --- a/hmp.c
268 +++ b/hmp.c
269 @@ -1664,11 +1664,13 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
270 {
271 Error *error = NULL;
272
273 + int dir = qdict_get_try_bool(qdict, "directory", 0);
274 const char *backup_file = qdict_get_str(qdict, "backupfile");
275 const char *devlist = qdict_get_try_str(qdict, "devlist");
276 int64_t speed = qdict_get_try_int(qdict, "speed", 0);
277
278 - qmp_backup(backup_file, true, BACKUP_FORMAT_VMA, false, NULL, !!devlist,
279 + qmp_backup(backup_file, true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
280 + false, NULL, !!devlist,
281 devlist, qdict_haskey(qdict, "speed"), speed, &error);
282
283 hmp_handle_error(mon, &error);
284 diff --git a/qapi-schema.json b/qapi-schema.json
285 index 059cbfc..1127f2c 100644
286 --- a/qapi-schema.json
287 +++ b/qapi-schema.json
288 @@ -609,7 +609,7 @@
289 # @vma: Proxmox vma backup format
290 ##
291 { 'enum': 'BackupFormat',
292 - 'data': [ 'vma' ] }
293 + 'data': [ 'vma', 'dir' ] }
294
295 ##
296 # @backup:
297 diff --git a/vma.c b/vma.c
298 index 8925407..1ffaced 100644
299 --- a/vma.c
300 +++ b/vma.c
301 @@ -264,7 +264,7 @@ static int extract_content(int argc, char **argv)
302 g_free(statefn);
303 } else if (di) {
304 char *devfn = NULL;
305 - int flags = BDRV_O_RDWR|BDRV_O_CACHE_WB;
306 + int flags = BDRV_O_RDWR;
307 bool write_zero = true;
308
309 if (readmap) {
310 --
311 2.1.4
312