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