]> git.proxmox.com Git - pve-qemu-kvm.git/blame - debian/patches/backup-add-dir-format.patch
allow to start directory backup using hmp command
[pve-qemu-kvm.git] / debian / patches / backup-add-dir-format.patch
CommitLineData
2bde36a4
DM
1Index: new/qapi-schema.json
2===================================================================
c9df43dd
DM
3--- new.orig/qapi-schema.json 2013-12-06 07:46:40.000000000 +0100
4+++ new/qapi-schema.json 2013-12-06 07:46:45.000000000 +0100
2bde36a4
DM
5@@ -586,7 +586,7 @@
6 # @vma: Proxmox vma backup format
7 ##
8 { 'enum': 'BackupFormat',
9- 'data': [ 'vma' ] }
10+ 'data': [ 'vma', 'dir' ] }
11
12 ##
13 # @backup:
14Index: new/blockdev.c
15===================================================================
c9df43dd
DM
16--- new.orig/blockdev.c 2013-12-06 07:46:40.000000000 +0100
17+++ new/blockdev.c 2013-12-06 07:46:45.000000000 +0100
2bde36a4
DM
18@@ -1463,6 +1463,8 @@
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@@ -1534,8 +1536,11 @@
28
29 di->completed = true;
30 di->bs = NULL;
31+ di->target = NULL;
32
33- vma_writer_close_stream(backup_state.vmaw, di->dev_id);
34+ if (backup_state.vmaw) {
35+ vma_writer_close_stream(backup_state.vmaw, di->dev_id);
36+ }
37
38 if (!backup_state.cancel) {
39 pvebackup_run_next_job();
40@@ -1610,6 +1615,7 @@
41 bool has_speed, int64_t speed, Error **errp)
42 {
43 BlockDriverState *bs;
44+ const char *backup_dir = NULL;
45 Error *local_err = NULL;
46 uuid_t uuid;
47 VmaWriter *vmaw = NULL;
48@@ -1626,11 +1632,6 @@
49 /* Todo: try to auto-detect format based on file name */
50 format = has_format ? format : BACKUP_FORMAT_VMA;
51
52- if (format != BACKUP_FORMAT_VMA) {
53- error_set(errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
54- return NULL;
55- }
56-
57 if (has_devlist) {
58 devs = g_strsplit_set(devlist, ",;:", -1);
59
60@@ -1698,27 +1699,63 @@
61
62 uuid_generate(uuid);
63
64- vmaw = vma_writer_create(backup_file, uuid, &local_err);
65- if (!vmaw) {
66- if (error_is_set(&local_err)) {
67- error_propagate(errp, local_err);
68+ if (format == BACKUP_FORMAT_VMA) {
69+ vmaw = vma_writer_create(backup_file, uuid, &local_err);
70+ if (!vmaw) {
71+ if (error_is_set(&local_err)) {
72+ error_propagate(errp, local_err);
73+ }
74+ goto err;
75 }
76- goto err;
77- }
78
79- /* register all devices for vma writer */
80- l = di_list;
81- while (l) {
82- PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
83- l = g_list_next(l);
84+ /* register all devices for vma writer */
85+ l = di_list;
86+ while (l) {
87+ PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
88+ l = g_list_next(l);
89
90- const char *devname = bdrv_get_device_name(di->bs);
91- di->dev_id = vma_writer_register_stream(vmaw, devname, di->size);
92- if (di->dev_id <= 0) {
93- error_set(errp, ERROR_CLASS_GENERIC_ERROR,
94- "register_stream failed");
95+ const char *devname = bdrv_get_device_name(di->bs);
96+ di->dev_id = vma_writer_register_stream(vmaw, devname, di->size);
97+ if (di->dev_id <= 0) {
98+ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
99+ "register_stream failed");
100+ goto err;
101+ }
102+ }
103+ } else if (format == BACKUP_FORMAT_DIR) {
104+ if (mkdir(backup_file, 0640) != 0) {
105+ error_setg_errno(errp, errno, "can't create directory '%s'\n",
106+ backup_file);
107 goto err;
108 }
109+ backup_dir = backup_file;
110+
111+ l = di_list;
112+ while (l) {
113+ PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
114+ l = g_list_next(l);
115+
116+ const char *devname = bdrv_get_device_name(di->bs);
117+ snprintf(di->targetfile, PATH_MAX, "%s/%s.raw", backup_dir, devname);
118+
119+ int flags = BDRV_O_RDWR|BDRV_O_CACHE_WB;
120+ bdrv_img_create(di->targetfile, "raw", NULL, NULL, NULL,
121+ di->size, flags, &local_err, false);
122+ if (error_is_set(&local_err)) {
123+ error_propagate(errp, local_err);
124+ goto err;
125+ }
126+
127+ di->target = bdrv_new("");
128+ if (bdrv_open(di->target, di->targetfile, NULL, flags, NULL, &local_err) < 0) {
129+ bdrv_unref(di->target);
130+ error_propagate(errp, local_err);
131+ goto err;
132+ }
133+ }
134+ } else {
135+ error_set(errp, ERROR_CLASS_GENERIC_ERROR, "unknown backup format");
136+ goto err;
137 }
138
139 /* add configuration file to archive */
140@@ -1731,12 +1768,27 @@
141 goto err;
142 }
143
144- const char *basename = g_path_get_basename(config_file);
145- if (vma_writer_add_config(vmaw, basename, cdata, clen) != 0) {
146- error_setg(errp, "unable to add config data to vma archive");
147- g_free(cdata);
148- goto err;
149+ char *basename = g_path_get_basename(config_file);
150+
151+ if (format == BACKUP_FORMAT_VMA) {
152+ if (vma_writer_add_config(vmaw, basename, cdata, clen) != 0) {
153+ error_setg(errp, "unable to add config data to vma archive");
154+ g_free(cdata);
155+ g_free(basename);
156+ goto err;
157+ }
158+ } else if (format == BACKUP_FORMAT_DIR) {
159+ char config_path[PATH_MAX];
160+ snprintf(config_path, PATH_MAX, "%s/%s.raw", backup_dir, basename);
161+ if (!g_file_set_contents(config_path, cdata, clen, &err)) {
162+ error_setg(errp, "unable to write config file '%s'", config_path);
163+ g_free(cdata);
164+ g_free(basename);
165+ goto err;
166+ }
167 }
168+
169+ g_free(basename);
170 g_free(cdata);
171 }
172
173@@ -1776,10 +1828,11 @@
174 PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
175 l = g_list_next(l);
176
177- backup_start(di->bs, NULL, speed, MIRROR_SYNC_MODE_FULL,
178+ backup_start(di->bs, di->target, speed, MIRROR_SYNC_MODE_FULL,
179 BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
180 pvebackup_dump_cb, pvebackup_complete_cb, di,
181 true, &local_err);
182+
183 if (local_err != NULL) {
184 error_setg(&backup_state.error, "backup_job_create failed");
185 pvebackup_cancel(NULL);
186@@ -1796,8 +1849,17 @@
187
188 l = di_list;
189 while (l) {
190- g_free(l->data);
191+ PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
192 l = g_list_next(l);
193+
194+ if (di->target) {
195+ bdrv_unref(di->target);
196+ }
197+
198+ if (di->targetfile[0]) {
199+ unlink(di->targetfile);
200+ }
201+ g_free(di);
202 }
203 g_list_free(di_list);
204
205@@ -1811,6 +1873,10 @@
206 unlink(backup_file);
207 }
208
209+ if (backup_dir) {
210+ rmdir(backup_dir);
211+ }
212+
213 return NULL;
214 }
215
c9df43dd
DM
216Index: new/hmp-commands.hx
217===================================================================
218--- new.orig/hmp-commands.hx 2013-12-06 07:46:38.000000000 +0100
219+++ new/hmp-commands.hx 2013-12-06 07:57:20.000000000 +0100
220@@ -85,9 +85,11 @@
221
222 {
223 .name = "backup",
224- .args_type = "backupfile:s,speed:o?,devlist:s?",
225- .params = "backupfile [speed [devlist]]",
226- .help = "create a VM Backup.",
227+ .args_type = "directory:-d,backupfile:s,speed:o?,devlist:s?",
228+ .params = "[-d] backupfile [speed [devlist]]",
229+ .help = "create a VM Backup."
230+ "\n\t\t\t Use -d to dump data into a directory instead"
231+ "\n\t\t\t of using VMA format.",
232 .mhandler.cmd = hmp_backup,
233 },
234
235Index: new/hmp.c
236===================================================================
237--- new.orig/hmp.c 2013-12-06 07:46:38.000000000 +0100
238+++ new/hmp.c 2013-12-06 07:50:58.000000000 +0100
239@@ -1245,11 +1245,13 @@
240 {
241 Error *error = NULL;
242
243+ int dir = qdict_get_try_bool(qdict, "directory", 0);
244 const char *backup_file = qdict_get_str(qdict, "backupfile");
245 const char *devlist = qdict_get_try_str(qdict, "devlist");
246 int64_t speed = qdict_get_try_int(qdict, "speed", 0);
247
248- qmp_backup(backup_file, true, BACKUP_FORMAT_VMA, false, NULL, !!devlist,
249+ qmp_backup(backup_file, true, dir ? BACKUP_FORMAT_DIR : BACKUP_FORMAT_VMA,
250+ false, NULL, !!devlist,
251 devlist, qdict_haskey(qdict, "speed"), speed, &error);
252
253 hmp_handle_error(mon, &error);