]> git.proxmox.com Git - pve-qemu-kvm.git/blob - debian/patches/backup-vma-allow-empty-backups.patch
allow the creation of vma files without data streams
[pve-qemu-kvm.git] / debian / patches / backup-vma-allow-empty-backups.patch
1 This patch allows the creation of vma files without data streams.
2
3 Such files only contain configuration data. This is useful if a
4 user set backup=no to all VM disks.
5
6 Index: new/vma-reader.c
7 ===================================================================
8 --- new.orig/vma-reader.c 2014-04-14 08:40:47.000000000 +0200
9 +++ new/vma-reader.c 2014-04-14 10:33:00.000000000 +0200
10 @@ -334,11 +334,6 @@
11 }
12 }
13
14 - if (!count) {
15 - error_setg(errp, "vma does not contain data");
16 - return -1;
17 - }
18 -
19 for (i = 0; i < VMA_MAX_CONFIGS; i++) {
20 uint32_t name_ptr = GUINT32_FROM_BE(h->config_names[i]);
21 uint32_t data_ptr = GUINT32_FROM_BE(h->config_data[i]);
22 @@ -830,16 +825,20 @@
23 }
24
25 if (verbose) {
26 - printf("total bytes read %zd, sparse bytes %zd (%.3g%%)\n",
27 - vmar->clusters_read*VMA_CLUSTER_SIZE,
28 - vmar->zero_cluster_data,
29 - (double)(100.0*vmar->zero_cluster_data)/
30 - (vmar->clusters_read*VMA_CLUSTER_SIZE));
31 -
32 - int64_t datasize = vmar->clusters_read*VMA_CLUSTER_SIZE-vmar->zero_cluster_data;
33 - if (datasize) { // this does not make sense for empty files
34 - printf("space reduction due to 4K zero bocks %.3g%%\n",
35 - (double)(100.0*vmar->partial_zero_cluster_data) / datasize);
36 + if (vmar->clusters_read) {
37 + printf("total bytes read %zd, sparse bytes %zd (%.3g%%)\n",
38 + vmar->clusters_read*VMA_CLUSTER_SIZE,
39 + vmar->zero_cluster_data,
40 + (double)(100.0*vmar->zero_cluster_data)/
41 + (vmar->clusters_read*VMA_CLUSTER_SIZE));
42 +
43 + int64_t datasize = vmar->clusters_read*VMA_CLUSTER_SIZE-vmar->zero_cluster_data;
44 + if (datasize) { // this does not make sense for empty files
45 + printf("space reduction due to 4K zero bocks %.3g%%\n",
46 + (double)(100.0*vmar->partial_zero_cluster_data) / datasize);
47 + }
48 + } else {
49 + printf("vma archive contains no image data\n");
50 }
51 }
52 return ret;
53 Index: new/vma-writer.c
54 ===================================================================
55 --- new.orig/vma-writer.c 2014-04-14 08:40:47.000000000 +0200
56 +++ new/vma-writer.c 2014-04-14 11:00:45.000000000 +0200
57 @@ -257,7 +257,7 @@
58 }
59
60 vmaw->co_writer = NULL;
61 -
62 +
63 return (done == bytes) ? bytes : -1;
64 }
65
66 @@ -381,10 +381,6 @@
67 time_t ctime = time(NULL);
68 head->ctime = GUINT64_TO_BE(ctime);
69
70 - if (!vmaw->stream_count) {
71 - return -1;
72 - }
73 -
74 for (i = 0; i < VMA_MAX_CONFIGS; i++) {
75 head->config_names[i] = GUINT32_TO_BE(vmaw->config_names[i]);
76 head->config_data[i] = GUINT32_TO_BE(vmaw->config_data[i]);
77 @@ -501,6 +497,23 @@
78 return open_drives;
79 }
80
81 +
82 +/**
83 + * You need to call this if the vma archive does not contain
84 + * any data stream.
85 + */
86 +int coroutine_fn
87 +vma_writer_flush_output(VmaWriter *vmaw)
88 +{
89 + qemu_co_mutex_lock(&vmaw->flush_lock);
90 + int ret = vma_writer_flush(vmaw);
91 + qemu_co_mutex_unlock(&vmaw->flush_lock);
92 + if (ret < 0) {
93 + vma_writer_set_error(vmaw, "vma_writer_flush_header failed");
94 + }
95 + return ret;
96 +}
97 +
98 /**
99 * all jobs should call this when there is no more data
100 * Returns: number of remaining stream (0 ==> finished)
101 @@ -528,12 +541,7 @@
102
103 if (open_drives <= 0) {
104 DPRINTF("vma_writer_set_status all drives completed\n");
105 - qemu_co_mutex_lock(&vmaw->flush_lock);
106 - int ret = vma_writer_flush(vmaw);
107 - qemu_co_mutex_unlock(&vmaw->flush_lock);
108 - if (ret < 0) {
109 - vma_writer_set_error(vmaw, "vma_writer_close_stream: flush failed");
110 - }
111 + vma_writer_flush_output(vmaw);
112 }
113
114 return open_drives;
115 Index: new/vma.c
116 ===================================================================
117 --- new.orig/vma.c 2014-04-14 08:40:47.000000000 +0200
118 +++ new/vma.c 2014-04-14 10:50:24.000000000 +0200
119 @@ -33,7 +33,7 @@
120 "\n"
121 "vma list <filename>\n"
122 "vma config <filename> [-c config]\n"
123 - "vma create <filename> [-c config] <archive> pathname ...\n"
124 + "vma create <filename> [-c config] pathname ...\n"
125 "vma extract <filename> [-r <fifo>] <targetdir>\n"
126 "vma verify <filename> [-v]\n"
127 ;
128 @@ -401,6 +401,18 @@
129
130 #define BACKUP_SECTORS_PER_CLUSTER (VMA_CLUSTER_SIZE / BDRV_SECTOR_SIZE)
131
132 +static void coroutine_fn backup_run_empty(void *opaque)
133 +{
134 + VmaWriter *vmaw = (VmaWriter *)opaque;
135 +
136 + vma_writer_flush_output(vmaw);
137 +
138 + Error *err = NULL;
139 + if (vma_writer_close(vmaw, &err) != 0) {
140 + g_warning("vma_writer_close failed %s", error_get_pretty(err));
141 + }
142 +}
143 +
144 static void coroutine_fn backup_run(void *opaque)
145 {
146 BackupJob *job = (BackupJob *)opaque;
147 @@ -474,8 +486,8 @@
148 }
149
150
151 - /* make sure we have archive name and at least one path */
152 - if ((optind + 2) > argc) {
153 + /* make sure we an archive name */
154 + if ((optind + 1) > argc) {
155 help();
156 }
157
158 @@ -510,11 +522,11 @@
159 l = g_list_next(l);
160 }
161
162 - int ind = 0;
163 + int devcount = 0;
164 while (optind < argc) {
165 const char *path = argv[optind++];
166 char *devname = NULL;
167 - path = extract_devname(path, &devname, ind++);
168 + path = extract_devname(path, &devname, devcount++);
169
170 BlockDriver *drv = NULL;
171 BlockDriverState *bs = bdrv_new(devname);
172 @@ -546,37 +558,42 @@
173 int percent = 0;
174 int last_percent = -1;
175
176 - while (1) {
177 - main_loop_wait(false);
178 - vma_writer_get_status(vmaw, &vmastat);
179 -
180 - if (verbose) {
181 -
182 - uint64_t total = 0;
183 - uint64_t transferred = 0;
184 - uint64_t zero_bytes = 0;
185 -
186 - int i;
187 - for (i = 0; i < 256; i++) {
188 - if (vmastat.stream_info[i].size) {
189 - total += vmastat.stream_info[i].size;
190 - transferred += vmastat.stream_info[i].transferred;
191 - zero_bytes += vmastat.stream_info[i].zero_bytes;
192 + if (devcount) {
193 + while (1) {
194 + main_loop_wait(false);
195 + vma_writer_get_status(vmaw, &vmastat);
196 +
197 + if (verbose) {
198 +
199 + uint64_t total = 0;
200 + uint64_t transferred = 0;
201 + uint64_t zero_bytes = 0;
202 +
203 + int i;
204 + for (i = 0; i < 256; i++) {
205 + if (vmastat.stream_info[i].size) {
206 + total += vmastat.stream_info[i].size;
207 + transferred += vmastat.stream_info[i].transferred;
208 + zero_bytes += vmastat.stream_info[i].zero_bytes;
209 + }
210 }
211 - }
212 - percent = (transferred*100)/total;
213 - if (percent != last_percent) {
214 - fprintf(stderr, "progress %d%% %zd/%zd %zd\n", percent,
215 - transferred, total, zero_bytes);
216 - fflush(stderr);
217 + percent = (transferred*100)/total;
218 + if (percent != last_percent) {
219 + fprintf(stderr, "progress %d%% %zd/%zd %zd\n", percent,
220 + transferred, total, zero_bytes);
221 + fflush(stderr);
222
223 - last_percent = percent;
224 + last_percent = percent;
225 + }
226 }
227 - }
228
229 - if (vmastat.closed) {
230 - break;
231 + if (vmastat.closed) {
232 + break;
233 + }
234 }
235 + } else {
236 + Coroutine *co = qemu_coroutine_create(backup_run_empty);
237 + qemu_coroutine_enter(co, vmaw);
238 }
239
240 bdrv_drain_all();
241 Index: new/vma.h
242 ===================================================================
243 --- new.orig/vma.h 2014-04-14 08:40:47.000000000 +0200
244 +++ new/vma.h 2014-04-14 10:50:00.000000000 +0200
245 @@ -128,6 +128,7 @@
246 size_t *zero_bytes);
247
248 int coroutine_fn vma_writer_close_stream(VmaWriter *vmaw, uint8_t dev_id);
249 +int coroutine_fn vma_writer_flush_output(VmaWriter *vmaw);
250
251 int vma_writer_get_status(VmaWriter *vmaw, VmaStatus *status);
252 void vma_writer_set_error(VmaWriter *vmaw, const char *fmt, ...);