]> git.proxmox.com Git - pve-qemu-kvm.git/blob - debian/patches/backup-add-dir-format.patch
allow to backup into a directory
[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 06:05:10.000000000 +0100
4 +++ new/qapi-schema.json 2013-12-06 06:17:13.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 06:17:06.000000000 +0100
17 +++ new/blockdev.c 2013-12-06 06:17:13.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 @@ -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