update to 2.7
[pve-qemu-kvm.git] / debian / patches / pve / 0023-backup-vma-allow-empty-backups.patch
blob79df37aa4a7ceda1003bdf66f892481fb9fe1230
1 From 4e3757e9cb0235a3ff0093f982dc3a2b4f4bdfe4 Mon Sep 17 00:00:00 2001
2 From: Wolfgang Bumiller <w.bumiller@proxmox.com>
3 Date: Wed, 9 Dec 2015 16:31:51 +0100
4 Subject: [PATCH 23/41] backup: vma: allow empty backups
6 ---
7 vma-reader.c | 29 ++++++++++++-------------
8 vma-writer.c | 30 ++++++++++++++++----------
9 vma.c | 70 ++++++++++++++++++++++++++++++++++++------------------------
10 vma.h | 1 +
11 4 files changed, 76 insertions(+), 54 deletions(-)
13 diff --git a/vma-reader.c b/vma-reader.c
14 index 2aafb26..78f1de9 100644
15 --- a/vma-reader.c
16 +++ b/vma-reader.c
17 @@ -326,11 +326,6 @@ static int vma_reader_read_head(VmaReader *vmar, Error **errp)
21 - if (!count) {
22 - error_setg(errp, "vma does not contain data");
23 - return -1;
24 - }
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 @@ -822,16 +817,20 @@ static int vma_reader_restore_full(VmaReader *vmar, int vmstate_fd,
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));
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));
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");
59 return ret;
60 diff --git a/vma-writer.c b/vma-writer.c
61 index 79b7fd4..0d26fc6 100644
62 --- a/vma-writer.c
63 +++ b/vma-writer.c
64 @@ -252,7 +252,7 @@ vma_queue_write(VmaWriter *vmaw, const void *buf, size_t bytes)
67 vmaw->co_writer = NULL;
70 return (done == bytes) ? bytes : -1;
73 @@ -376,10 +376,6 @@ static int coroutine_fn vma_write_header(VmaWriter *vmaw)
74 time_t ctime = time(NULL);
75 head->ctime = GUINT64_TO_BE(ctime);
77 - if (!vmaw->stream_count) {
78 - return -1;
79 - }
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 @@ -496,6 +492,23 @@ static int vma_count_open_streams(VmaWriter *vmaw)
85 return open_drives;
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)
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");
102 + return ret;
106 * all jobs should call this when there is no more data
107 * Returns: number of remaining stream (0 ==> finished)
108 @@ -523,12 +536,7 @@ vma_writer_close_stream(VmaWriter *vmaw, uint8_t dev_id)
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");
118 + vma_writer_flush_output(vmaw);
121 return open_drives;
122 diff --git a/vma.c b/vma.c
123 index c88a4358..08e4725 100644
124 --- a/vma.c
125 +++ b/vma.c
126 @@ -27,7 +27,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"
135 @@ -395,6 +395,18 @@ typedef struct BackupJob {
137 #define BACKUP_SECTORS_PER_CLUSTER (VMA_CLUSTER_SIZE / BDRV_SECTOR_SIZE)
139 +static void coroutine_fn backup_run_empty(void *opaque)
141 + VmaWriter *vmaw = (VmaWriter *)opaque;
143 + vma_writer_flush_output(vmaw);
145 + Error *err = NULL;
146 + if (vma_writer_close(vmaw, &err) != 0) {
147 + g_warning("vma_writer_close failed %s", error_get_pretty(err));
151 static void coroutine_fn backup_run(void *opaque)
153 BackupJob *job = (BackupJob *)opaque;
154 @@ -468,8 +480,8 @@ static int create_archive(int argc, char **argv)
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();
165 @@ -504,11 +516,11 @@ static int create_archive(int argc, char **argv)
166 l = g_list_next(l);
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++);
177 Error *errp = NULL;
178 BlockDriverState *bs;
179 @@ -539,37 +551,39 @@ static int create_archive(int argc, char **argv)
180 int percent = 0;
181 int last_percent = -1;
183 - while (1) {
184 - main_loop_wait(false);
185 - vma_writer_get_status(vmaw, &vmastat);
186 + if (devcount) {
187 + while (1) {
188 + main_loop_wait(false);
189 + vma_writer_get_status(vmaw, &vmastat);
191 + if (verbose) {
193 - if (verbose) {
194 + uint64_t total = 0;
195 + uint64_t transferred = 0;
196 + uint64_t zero_bytes = 0;
198 - uint64_t total = 0;
199 - uint64_t transferred = 0;
200 - uint64_t zero_bytes = 0;
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;
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);
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;
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);
230 - last_percent = percent;
231 + if (vmastat.closed) {
232 + break;
236 - if (vmastat.closed) {
237 - break;
239 } else {
240 Coroutine *co = qemu_coroutine_create(backup_run_empty, vmaw);
241 qemu_coroutine_enter(co);
242 diff --git a/vma.h b/vma.h
243 index 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);
249 int coroutine_fn vma_writer_close_stream(VmaWriter *vmaw, uint8_t dev_id);
250 +int coroutine_fn vma_writer_flush_output(VmaWriter *vmaw);
252 int vma_writer_get_status(VmaWriter *vmaw, VmaStatus *status);
253 void vma_writer_set_error(VmaWriter *vmaw, const char *fmt, ...);
255 2.1.4