]> git.proxmox.com Git - pve-qemu-kvm.git/blame - debian/patches/pve/0024-backup-vma-allow-empty-backups.patch
bump version to 2.6.2-2
[pve-qemu-kvm.git] / debian / patches / pve / 0024-backup-vma-allow-empty-backups.patch
CommitLineData
6fb04df7 1From 7136f6d83dee1ee791c142ab0bb3d406589e9e13 Mon Sep 17 00:00:00 2001
ca0fe5f5
WB
2From: Wolfgang Bumiller <w.bumiller@proxmox.com>
3Date: Wed, 9 Dec 2015 16:31:51 +0100
6fb04df7 4Subject: [PATCH 24/55] backup: vma: allow empty backups
ca0fe5f5
WB
5
6---
7 vma-reader.c | 29 ++++++++++-----------
8 vma-writer.c | 30 ++++++++++++++--------
9 vma.c | 84 ++++++++++++++++++++++++++++++++++++++----------------------
10 vma.h | 1 +
11 4 files changed, 88 insertions(+), 56 deletions(-)
12
13diff --git a/vma-reader.c b/vma-reader.c
14index d9f43fe..5d0d3ea 100644
15--- a/vma-reader.c
16+++ b/vma-reader.c
17@@ -334,11 +334,6 @@ static int vma_reader_read_head(VmaReader *vmar, Error **errp)
18 }
19 }
20
21- if (!count) {
22- error_setg(errp, "vma does not contain data");
23- return -1;
24- }
25-
26 for (i = 0; i < VMA_MAX_CONFIGS; i++) {
27 uint32_t name_ptr = GUINT32_FROM_BE(h->config_names[i]);
28 uint32_t data_ptr = GUINT32_FROM_BE(h->config_data[i]);
29@@ -830,16 +825,20 @@ static int vma_reader_restore_full(VmaReader *vmar, int vmstate_fd,
30 }
31
32 if (verbose) {
33- printf("total bytes read %zd, sparse bytes %zd (%.3g%%)\n",
34- vmar->clusters_read*VMA_CLUSTER_SIZE,
35- vmar->zero_cluster_data,
36- (double)(100.0*vmar->zero_cluster_data)/
37- (vmar->clusters_read*VMA_CLUSTER_SIZE));
38-
39- int64_t datasize = vmar->clusters_read*VMA_CLUSTER_SIZE-vmar->zero_cluster_data;
40- if (datasize) { // this does not make sense for empty files
41- printf("space reduction due to 4K zero blocks %.3g%%\n",
42- (double)(100.0*vmar->partial_zero_cluster_data) / datasize);
43+ if (vmar->clusters_read) {
44+ printf("total bytes read %zd, sparse bytes %zd (%.3g%%)\n",
45+ vmar->clusters_read*VMA_CLUSTER_SIZE,
46+ vmar->zero_cluster_data,
47+ (double)(100.0*vmar->zero_cluster_data)/
48+ (vmar->clusters_read*VMA_CLUSTER_SIZE));
49+
50+ int64_t datasize = vmar->clusters_read*VMA_CLUSTER_SIZE-vmar->zero_cluster_data;
51+ if (datasize) { // this does not make sense for empty files
52+ printf("space reduction due to 4K zero blocks %.3g%%\n",
53+ (double)(100.0*vmar->partial_zero_cluster_data) / datasize);
54+ }
55+ } else {
56+ printf("vma archive contains no image data\n");
57 }
58 }
59 return ret;
60diff --git a/vma-writer.c b/vma-writer.c
61index 3c77e98..5cc4564 100644
62--- a/vma-writer.c
63+++ b/vma-writer.c
64@@ -258,7 +258,7 @@ vma_queue_write(VmaWriter *vmaw, const void *buf, size_t bytes)
65 }
66
67 vmaw->co_writer = NULL;
68-
69+
70 return (done == bytes) ? bytes : -1;
71 }
72
73@@ -382,10 +382,6 @@ static int coroutine_fn vma_write_header(VmaWriter *vmaw)
74 time_t ctime = time(NULL);
75 head->ctime = GUINT64_TO_BE(ctime);
76
77- if (!vmaw->stream_count) {
78- return -1;
79- }
80-
81 for (i = 0; i < VMA_MAX_CONFIGS; i++) {
82 head->config_names[i] = GUINT32_TO_BE(vmaw->config_names[i]);
83 head->config_data[i] = GUINT32_TO_BE(vmaw->config_data[i]);
84@@ -502,6 +498,23 @@ static int vma_count_open_streams(VmaWriter *vmaw)
85 return open_drives;
86 }
87
88+
89+/**
90+ * You need to call this if the vma archive does not contain
91+ * any data stream.
92+ */
93+int coroutine_fn
94+vma_writer_flush_output(VmaWriter *vmaw)
95+{
96+ qemu_co_mutex_lock(&vmaw->flush_lock);
97+ int ret = vma_writer_flush(vmaw);
98+ qemu_co_mutex_unlock(&vmaw->flush_lock);
99+ if (ret < 0) {
100+ vma_writer_set_error(vmaw, "vma_writer_flush_header failed");
101+ }
102+ return ret;
103+}
104+
105 /**
106 * all jobs should call this when there is no more data
107 * Returns: number of remaining stream (0 ==> finished)
108@@ -529,12 +542,7 @@ vma_writer_close_stream(VmaWriter *vmaw, uint8_t dev_id)
109
110 if (open_drives <= 0) {
111 DPRINTF("vma_writer_set_status all drives completed\n");
112- qemu_co_mutex_lock(&vmaw->flush_lock);
113- int ret = vma_writer_flush(vmaw);
114- qemu_co_mutex_unlock(&vmaw->flush_lock);
115- if (ret < 0) {
116- vma_writer_set_error(vmaw, "vma_writer_close_stream: flush failed");
117- }
118+ vma_writer_flush_output(vmaw);
119 }
120
121 return open_drives;
122diff --git a/vma.c b/vma.c
123index 6a33352..00f20b0 100644
124--- a/vma.c
125+++ b/vma.c
126@@ -33,7 +33,7 @@ static void help(void)
127 "\n"
128 "vma list <filename>\n"
129 "vma config <filename> [-c config]\n"
130- "vma create <filename> [-c config] <archive> pathname ...\n"
131+ "vma create <filename> [-c config] pathname ...\n"
132 "vma extract <filename> [-r <fifo>] <targetdir>\n"
133 "vma verify <filename> [-v]\n"
134 ;
135@@ -401,6 +401,18 @@ typedef struct BackupJob {
136
137 #define BACKUP_SECTORS_PER_CLUSTER (VMA_CLUSTER_SIZE / BDRV_SECTOR_SIZE)
138
139+static void coroutine_fn backup_run_empty(void *opaque)
140+{
141+ VmaWriter *vmaw = (VmaWriter *)opaque;
142+
143+ vma_writer_flush_output(vmaw);
144+
145+ Error *err = NULL;
146+ if (vma_writer_close(vmaw, &err) != 0) {
147+ g_warning("vma_writer_close failed %s", error_get_pretty(err));
148+ }
149+}
150+
151 static void coroutine_fn backup_run(void *opaque)
152 {
153 BackupJob *job = (BackupJob *)opaque;
154@@ -474,8 +486,8 @@ static int create_archive(int argc, char **argv)
155 }
156
157
158- /* make sure we have archive name and at least one path */
159- if ((optind + 2) > argc) {
160+ /* make sure we an archive name */
161+ if ((optind + 1) > argc) {
162 help();
163 }
164
165@@ -510,11 +522,11 @@ static int create_archive(int argc, char **argv)
166 l = g_list_next(l);
167 }
168
169- int ind = 0;
170+ int devcount = 0;
171 while (optind < argc) {
172 const char *path = argv[optind++];
173 char *devname = NULL;
174- path = extract_devname(path, &devname, ind++);
175+ path = extract_devname(path, &devname, devcount++);
176
177 BlockDriver *drv = NULL;
178 Error *errp = NULL;
179@@ -546,37 +558,49 @@ static int create_archive(int argc, char **argv)
180 int percent = 0;
181 int last_percent = -1;
182
183- while (1) {
184- main_loop_wait(false);
185- vma_writer_get_status(vmaw, &vmastat);
186-
187- if (verbose) {
188-
189- uint64_t total = 0;
190- uint64_t transferred = 0;
191- uint64_t zero_bytes = 0;
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+ percent = (transferred*100)/total;
212+ if (percent != last_percent) {
213+ fprintf(stderr, "progress %d%% %zd/%zd %zd\n", percent,
214+ transferred, total, zero_bytes);
215+ fflush(stderr);
216
217- int i;
218- for (i = 0; i < 256; i++) {
219- if (vmastat.stream_info[i].size) {
220- total += vmastat.stream_info[i].size;
221- transferred += vmastat.stream_info[i].transferred;
222- zero_bytes += vmastat.stream_info[i].zero_bytes;
223+ last_percent = percent;
224 }
225 }
226- percent = (transferred*100)/total;
227- if (percent != last_percent) {
228- fprintf(stderr, "progress %d%% %zd/%zd %zd\n", percent,
229- transferred, total, zero_bytes);
230- fflush(stderr);
231
232- last_percent = percent;
233+ if (vmastat.closed) {
234+ break;
235 }
236 }
237-
238- if (vmastat.closed) {
239- break;
240- }
241+ } else {
242+ Coroutine *co = qemu_coroutine_create(backup_run_empty);
243+ qemu_coroutine_enter(co, vmaw);
244+ while (1) {
245+ main_loop_wait(false);
246+ vma_writer_get_status(vmaw, &vmastat);
247+ if (vmastat.closed) {
248+ break;
249+ }
250+ }
251 }
252
253 bdrv_drain_all();
254diff --git a/vma.h b/vma.h
255index 98377e4..365ceb2 100644
256--- a/vma.h
257+++ b/vma.h
258@@ -128,6 +128,7 @@ int64_t coroutine_fn vma_writer_write(VmaWriter *vmaw, uint8_t dev_id,
259 size_t *zero_bytes);
260
261 int coroutine_fn vma_writer_close_stream(VmaWriter *vmaw, uint8_t dev_id);
262+int coroutine_fn vma_writer_flush_output(VmaWriter *vmaw);
263
264 int vma_writer_get_status(VmaWriter *vmaw, VmaStatus *status);
265 void vma_writer_set_error(VmaWriter *vmaw, const char *fmt, ...);
266--
2672.1.4
268