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