]> git.proxmox.com Git - pve-qemu-kvm.git/blame - debian/patches/pve/0023-backup-vma-allow-empty-backups.patch
bump version to 2.9.0-1~rc2+5
[pve-qemu-kvm.git] / debian / patches / pve / 0023-backup-vma-allow-empty-backups.patch
CommitLineData
87ba737b 1From b5ac1badd1810f87aae5091f44bee54e3c45e979 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
adeb0c7a 4Subject: [PATCH 23/48] backup: vma: allow empty backups
ca0fe5f5
WB
5
6---
68a30562
WB
7 vma-reader.c | 29 ++++++++++++-------------
8 vma-writer.c | 30 ++++++++++++++++----------
9 vma.c | 70 ++++++++++++++++++++++++++++++++++++------------------------
ca0fe5f5 10 vma.h | 1 +
68a30562 11 4 files changed, 76 insertions(+), 54 deletions(-)
ca0fe5f5
WB
12
13diff --git a/vma-reader.c b/vma-reader.c
68a30562 14index 2aafb26..78f1de9 100644
ca0fe5f5
WB
15--- a/vma-reader.c
16+++ b/vma-reader.c
68a30562 17@@ -326,11 +326,6 @@ static int vma_reader_read_head(VmaReader *vmar, Error **errp)
ca0fe5f5
WB
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]);
68a30562 29@@ -822,16 +817,20 @@ static int vma_reader_restore_full(VmaReader *vmar, int vmstate_fd,
ca0fe5f5
WB
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
1a91ab45 61index 216577a..0dd668b 100644
ca0fe5f5
WB
62--- a/vma-writer.c
63+++ b/vma-writer.c
68a30562 64@@ -252,7 +252,7 @@ vma_queue_write(VmaWriter *vmaw, const void *buf, size_t bytes)
ca0fe5f5
WB
65 }
66
67 vmaw->co_writer = NULL;
68-
69+
70 return (done == bytes) ? bytes : -1;
71 }
72
68a30562 73@@ -376,10 +376,6 @@ static int coroutine_fn vma_write_header(VmaWriter *vmaw)
ca0fe5f5
WB
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]);
68a30562 84@@ -496,6 +492,23 @@ static int vma_count_open_streams(VmaWriter *vmaw)
ca0fe5f5
WB
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)
68a30562 108@@ -523,12 +536,7 @@ vma_writer_close_stream(VmaWriter *vmaw, uint8_t dev_id)
ca0fe5f5
WB
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
1a91ab45 123index 1ffaced..c7c0538 100644
ca0fe5f5
WB
124--- a/vma.c
125+++ b/vma.c
1a91ab45 126@@ -28,7 +28,7 @@ static void help(void)
ca0fe5f5
WB
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 ;
1a91ab45 135@@ -396,6 +396,18 @@ typedef struct BackupJob {
ca0fe5f5
WB
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;
1a91ab45 154@@ -469,8 +481,8 @@ static int create_archive(int argc, char **argv)
ca0fe5f5
WB
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
1a91ab45 165@@ -505,11 +517,11 @@ static int create_archive(int argc, char **argv)
ca0fe5f5
WB
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
ca0fe5f5 177 Error *errp = NULL;
68a30562 178 BlockDriverState *bs;
1a91ab45 179@@ -540,37 +552,39 @@ static int create_archive(int argc, char **argv)
ca0fe5f5
WB
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);
ca0fe5f5
WB
186+ if (devcount) {
187+ while (1) {
188+ main_loop_wait(false);
189+ vma_writer_get_status(vmaw, &vmastat);
190+
191+ if (verbose) {
68a30562
WB
192
193- if (verbose) {
ca0fe5f5
WB
194+ uint64_t total = 0;
195+ uint64_t transferred = 0;
196+ uint64_t zero_bytes = 0;
68a30562
WB
197
198- uint64_t total = 0;
199- uint64_t transferred = 0;
200- uint64_t zero_bytes = 0;
ca0fe5f5
WB
201+ int i;
202+ for (i = 0; i < 256; i++) {
203+ if (vmastat.stream_info[i].size) {
204+ total += vmastat.stream_info[i].size;
205+ transferred += vmastat.stream_info[i].transferred;
206+ zero_bytes += vmastat.stream_info[i].zero_bytes;
207+ }
208+ }
209+ percent = (transferred*100)/total;
210+ if (percent != last_percent) {
211+ fprintf(stderr, "progress %d%% %zd/%zd %zd\n", percent,
212+ transferred, total, zero_bytes);
213+ fflush(stderr);
214
215- int i;
216- for (i = 0; i < 256; i++) {
217- if (vmastat.stream_info[i].size) {
218- total += vmastat.stream_info[i].size;
219- transferred += vmastat.stream_info[i].transferred;
220- zero_bytes += vmastat.stream_info[i].zero_bytes;
221+ last_percent = percent;
222 }
223 }
224- percent = (transferred*100)/total;
225- if (percent != last_percent) {
226- fprintf(stderr, "progress %d%% %zd/%zd %zd\n", percent,
227- transferred, total, zero_bytes);
228- fflush(stderr);
229
230- last_percent = percent;
231+ if (vmastat.closed) {
232+ break;
233 }
234 }
235-
236- if (vmastat.closed) {
237- break;
238- }
68a30562
WB
239 } else {
240 Coroutine *co = qemu_coroutine_create(backup_run_empty, vmaw);
241 qemu_coroutine_enter(co);
ca0fe5f5
WB
242diff --git a/vma.h b/vma.h
243index 98377e4..365ceb2 100644
244--- a/vma.h
245+++ b/vma.h
246@@ -128,6 +128,7 @@ int64_t coroutine_fn vma_writer_write(VmaWriter *vmaw, uint8_t dev_id,
247 size_t *zero_bytes);
248
249 int coroutine_fn vma_writer_close_stream(VmaWriter *vmaw, uint8_t dev_id);
250+int coroutine_fn vma_writer_flush_output(VmaWriter *vmaw);
251
252 int vma_writer_get_status(VmaWriter *vmaw, VmaStatus *status);
253 void vma_writer_set_error(VmaWriter *vmaw, const char *fmt, ...);
254--
2552.1.4
256