]> git.proxmox.com Git - pve-qemu-kvm.git/blob - debian/patches/pve/0017-backup-vma-add-dir-format.patch
adding 2.5 pve patches and left-over extra fixes
[pve-qemu-kvm.git] / debian / patches / pve / 0017-backup-vma-add-dir-format.patch
1 From bbf1558fc870eb4e72604b4d340ec317a59ac459 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 17/41] backup: vma: add dir format
5
6 ---
7 blockdev.c | 126 +++++++++++++++++++++++++++++++++++++++++--------------
8 hmp-commands.hx | 8 ++--
9 hmp.c | 4 +-
10 qapi-schema.json | 2 +-
11 4 files changed, 104 insertions(+), 36 deletions(-)
12
13 diff --git a/blockdev.c b/blockdev.c
14 index a346c55..29a33c0 100644
15 --- a/blockdev.c
16 +++ b/blockdev.c
17 @@ -2900,6 +2900,8 @@ typedef struct PVEBackupDevInfo {
18 uint8_t dev_id;
19 //bool started;
20 bool completed;
21 + char targetfile[PATH_MAX];
22 + BlockDriverState *target;
23 } PVEBackupDevInfo;
24
25 static void pvebackup_run_next_job(void);
26 @@ -2968,8 +2970,6 @@ static void pvebackup_complete_cb(void *opaque, int ret)
27 {
28 PVEBackupDevInfo *di = opaque;
29
30 - assert(backup_state.vmaw);
31 -
32 di->completed = true;
33
34 if (ret < 0 && !backup_state.error) {
35 @@ -2980,8 +2980,11 @@ static void pvebackup_complete_cb(void *opaque, int ret)
36 BlockDriverState *bs = di->bs;
37
38 di->bs = NULL;
39 + di->target = NULL;
40
41 - vma_writer_close_stream(backup_state.vmaw, di->dev_id);
42 + if (backup_state.vmaw) {
43 + vma_writer_close_stream(backup_state.vmaw, di->dev_id);
44 + }
45
46 block_job_cb(bs, ret);
47
48 @@ -3060,6 +3063,7 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
49 {
50 BlockBackend *blk;
51 BlockDriverState *bs = NULL;
52 + const char *backup_dir = NULL;
53 Error *local_err = NULL;
54 uuid_t uuid;
55 VmaWriter *vmaw = NULL;
56 @@ -3077,11 +3081,6 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
57 /* Todo: try to auto-detect format based on file name */
58 format = has_format ? format : BACKUP_FORMAT_VMA;
59
60 - if (format != BACKUP_FORMAT_VMA) {
61 - error_set(errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
62 - return NULL;
63 - }
64 -
65 if (has_devlist) {
66 devs = g_strsplit_set(devlist, ",;:", -1);
67
68 @@ -3150,27 +3149,63 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
69
70 uuid_generate(uuid);
71
72 - vmaw = vma_writer_create(backup_file, uuid, &local_err);
73 - if (!vmaw) {
74 - if (local_err) {
75 - error_propagate(errp, local_err);
76 + if (format == BACKUP_FORMAT_VMA) {
77 + vmaw = vma_writer_create(backup_file, uuid, &local_err);
78 + if (!vmaw) {
79 + if (local_err) {
80 + error_propagate(errp, local_err);
81 + }
82 + goto err;
83 }
84 - goto err;
85 - }
86
87 - /* register all devices for vma writer */
88 - l = di_list;
89 - while (l) {
90 - PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
91 - l = g_list_next(l);
92 + /* register all devices for vma writer */
93 + l = di_list;
94 + while (l) {
95 + PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
96 + l = g_list_next(l);
97
98 - const char *devname = bdrv_get_device_name(di->bs);
99 - di->dev_id = vma_writer_register_stream(vmaw, devname, di->size);
100 - if (di->dev_id <= 0) {
101 - error_set(errp, ERROR_CLASS_GENERIC_ERROR,
102 - "register_stream failed");
103 + const char *devname = bdrv_get_device_name(di->bs);
104 + di->dev_id = vma_writer_register_stream(vmaw, devname, di->size);
105 + if (di->dev_id <= 0) {
106 + error_set(errp, ERROR_CLASS_GENERIC_ERROR,
107 + "register_stream failed");
108 + goto err;
109 + }
110 + }
111 + } else if (format == BACKUP_FORMAT_DIR) {
112 + if (mkdir(backup_file, 0640) != 0) {
113 + error_setg_errno(errp, errno, "can't create directory '%s'\n",
114 + backup_file);
115 goto err;
116 }
117 + backup_dir = backup_file;
118 +
119 + l = di_list;
120 + while (l) {
121 + PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
122 + l = g_list_next(l);
123 +
124 + const char *devname = bdrv_get_device_name(di->bs);
125 + snprintf(di->targetfile, PATH_MAX, "%s/%s.raw", backup_dir, devname);
126 +
127 + int flags = BDRV_O_RDWR|BDRV_O_CACHE_WB;
128 + bdrv_img_create(di->targetfile, "raw", NULL, NULL, NULL,
129 + di->size, flags, &local_err, false);
130 + if (local_err) {
131 + error_propagate(errp, local_err);
132 + goto err;
133 + }
134 +
135 + di->target = bdrv_new();
136 + if (bdrv_open(&di->target, di->targetfile, NULL, NULL, flags, NULL, &local_err) < 0) {
137 + bdrv_unref(di->target);
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 */
148 @@ -3183,12 +3218,27 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
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
181 @@ -3228,10 +3278,11 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
182 PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
183 l = g_list_next(l);
184
185 - backup_start(di->bs, NULL, speed, MIRROR_SYNC_MODE_FULL, NULL,
186 + backup_start(di->bs, di->target, speed, MIRROR_SYNC_MODE_FULL, NULL,
187 BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
188 pvebackup_dump_cb, pvebackup_complete_cb, di,
189 1, &local_err);
190 +
191 if (local_err != NULL) {
192 error_setg(&backup_state.error, "backup_job_create failed");
193 pvebackup_cancel(NULL);
194 @@ -3250,8 +3301,17 @@ err:
195
196 l = di_list;
197 while (l) {
198 - g_free(l->data);
199 + PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
200 l = g_list_next(l);
201 +
202 + if (di->target) {
203 + bdrv_unref(di->target);
204 + }
205 +
206 + if (di->targetfile[0]) {
207 + unlink(di->targetfile);
208 + }
209 + g_free(di);
210 }
211 g_list_free(di_list);
212
213 @@ -3265,6 +3325,10 @@ err:
214 unlink(backup_file);
215 }
216
217 + if (backup_dir) {
218 + rmdir(backup_dir);
219 + }
220 +
221 return NULL;
222 }
223
224 diff --git a/hmp-commands.hx b/hmp-commands.hx
225 index 324125f..f6cc0e5 100644
226 --- a/hmp-commands.hx
227 +++ b/hmp-commands.hx
228 @@ -89,9 +89,11 @@ ETEXI
229
230 {
231 .name = "backup",
232 - .args_type = "backupfile:s,speed:o?,devlist:s?",
233 - .params = "backupfile [speed [devlist]]",
234 - .help = "create a VM Backup.",
235 + .args_type = "directory:-d,backupfile:s,speed:o?,devlist:s?",
236 + .params = "[-d] backupfile [speed [devlist]]",
237 + .help = "create a VM Backup."
238 + "\n\t\t\t Use -d to dump data into a directory instead"
239 + "\n\t\t\t of using VMA format.",
240 .mhandler.cmd = hmp_backup,
241 },
242
243 diff --git a/hmp.c b/hmp.c
244 index ebb16c1..acc4aea 100644
245 --- a/hmp.c
246 +++ b/hmp.c
247 @@ -1512,11 +1512,13 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
248 {
249 Error *error = NULL;
250
251 + int dir = qdict_get_try_bool(qdict, "directory", 0);
252 const char *backup_file = qdict_get_str(qdict, "backupfile");
253 const char *devlist = qdict_get_try_str(qdict, "devlist");
254 int64_t speed = qdict_get_try_int(qdict, "speed", 0);
255
256 - qmp_backup(backup_file, true, BACKUP_FORMAT_VMA, false, NULL, !!devlist,
257 + qmp_backup(backup_file, true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
258 + false, NULL, !!devlist,
259 devlist, qdict_haskey(qdict, "speed"), speed, &error);
260
261 hmp_handle_error(mon, &error);
262 diff --git a/qapi-schema.json b/qapi-schema.json
263 index edfb3a4..84978bd 100644
264 --- a/qapi-schema.json
265 +++ b/qapi-schema.json
266 @@ -397,7 +397,7 @@
267 # @vma: Proxmox vma backup format
268 ##
269 { 'enum': 'BackupFormat',
270 - 'data': [ 'vma' ] }
271 + 'data': [ 'vma', 'dir' ] }
272
273 ##
274 # @backup:
275 --
276 2.1.4
277