]> git.proxmox.com Git - pve-qemu-kvm.git/blame - debian/patches/backup-vma-allow-empty-backups.patch
Two more fixes
[pve-qemu-kvm.git] / debian / patches / backup-vma-allow-empty-backups.patch
CommitLineData
b3ac4811
DM
1This patch allows the creation of vma files without data streams.
2
3Such files only contain configuration data. This is useful if a
4user set backup=no to all VM disks.
5
6Index: new/vma-reader.c
7===================================================================
0a1952dd
DM
8--- new.orig/vma-reader.c
9+++ new/vma-reader.c
10@@ -334,11 +334,6 @@ static int vma_reader_read_head(VmaReade
b3ac4811
DM
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]);
0a1952dd 22@@ -830,16 +825,20 @@ static int vma_reader_restore_full(VmaRe
b3ac4811
DM
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
27f6b7fc 34- printf("space reduction due to 4K zero blocks %.3g%%\n",
b3ac4811
DM
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
27f6b7fc 45+ printf("space reduction due to 4K zero blocks %.3g%%\n",
b3ac4811
DM
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;
53Index: new/vma-writer.c
54===================================================================
0a1952dd
DM
55--- new.orig/vma-writer.c
56+++ new/vma-writer.c
57@@ -258,7 +258,7 @@ vma_queue_write(VmaWriter *vmaw, const v
b3ac4811
DM
58 }
59
60 vmaw->co_writer = NULL;
61-
62+
63 return (done == bytes) ? bytes : -1;
64 }
65
0a1952dd 66@@ -382,10 +382,6 @@ static int coroutine_fn vma_write_header
b3ac4811
DM
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]);
0a1952dd 77@@ -502,6 +498,23 @@ static int vma_count_open_streams(VmaWri
b3ac4811
DM
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)
0a1952dd 101@@ -529,12 +542,7 @@ vma_writer_close_stream(VmaWriter *vmaw,
b3ac4811
DM
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;
115Index: new/vma.c
116===================================================================
0a1952dd
DM
117--- new.orig/vma.c
118+++ new/vma.c
119@@ -33,7 +33,7 @@ static void help(void)
b3ac4811
DM
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 ;
0a1952dd 128@@ -401,6 +401,18 @@ typedef struct BackupJob {
b3ac4811
DM
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;
0a1952dd 147@@ -474,8 +486,8 @@ static int create_archive(int argc, char
b3ac4811
DM
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
0a1952dd 158@@ -510,11 +522,11 @@ static int create_archive(int argc, char
b3ac4811
DM
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;
023017f8 171 Error *errp = NULL;
0a1952dd 172@@ -546,37 +558,49 @@ static int create_archive(int argc, char
b3ac4811
DM
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);
0a1952dd
DM
238+ while (1) {
239+ main_loop_wait(false);
240+ vma_writer_get_status(vmaw, &vmastat);
241+ if (vmastat.closed) {
242+ break;
243+ }
244+ }
b3ac4811
DM
245 }
246
247 bdrv_drain_all();
248Index: new/vma.h
249===================================================================
0a1952dd
DM
250--- new.orig/vma.h
251+++ new/vma.h
252@@ -128,6 +128,7 @@ int64_t coroutine_fn vma_writer_write(Vm
b3ac4811
DM
253 size_t *zero_bytes);
254
255 int coroutine_fn vma_writer_close_stream(VmaWriter *vmaw, uint8_t dev_id);
256+int coroutine_fn vma_writer_flush_output(VmaWriter *vmaw);
257
258 int vma_writer_get_status(VmaWriter *vmaw, VmaStatus *status);
259 void vma_writer_set_error(VmaWriter *vmaw, const char *fmt, ...);