~akopytov/percona-xtrabackup/bug1166888-2.1

« back to all changes in this revision

Viewing changes to src/libarchive/libarchive/test/test_write_format_tar_ustar.c

  • Committer: Alexey Kopytov
  • Date: 2012-02-10 20:05:56 UTC
  • mto: (391.1.5 staging)
  • mto: This revision was merged to the branch mainline in revision 390.
  • Revision ID: akopytov@gmail.com-20120210200556-6kx41z8wwrqfucro
Rebase of the parallel compression patch on new trunk + post-review
fixes.

Implementation of parallel compression and streaming for XtraBackup.

This revision implements the following changes:

* InnoDB files are now streamed by the xtrabackup binary rather than
innobackupex. As a result, integrity is now verified by xtrabackup and
thus tar4ibd is no longer needed, so it was removed.

* xtrabackup binary now accepts the new '--stream' option which has
exactly the same semantics as the '--stream' option in
innobackupex: it tells xtrabackup to stream all files to the standard
output in the specified format rather than storing them locally.

* The xtrabackup binary can now do parallel compression using the
quicklz library. Two new options were added to xtrabackup to support
this feature:

- '--compress' tells xtrabackup to compress all output data, including
the transaction log file and meta data files, using the specified
compression algorithm. The only currently supported algorithm is
'quicklz'. The resulting files have the qpress archive format,
i.e. every *.qp file produced by xtrabackup is essentially a one-file
qpress archive and can be extracted and uncompressed by the qpress
file archiver (http://www.quicklz.com/).

- '--compress-threads' specifies the number of worker threads used by
xtrabackup for parallel data compression. This option defaults to 1.

Parallel compression ('--compress-threads') can be used together with
parallel file copying ('--parallel'). For example, '--parallel=4
--compress --compress-threads=2' will create 4 IO threads that will
read the data and pipe it to 2 compression threads.

* To support simultaneous compression and streaming, a new custom
streaming format called 'xbstream' was introduced to XtraBackup in
addition to the 'tar' format. That was required to overcome some
limitations of traditional archive formats such as 'tar', 'cpio' and
others that do not allow streaming dynamically generated files, for
example dynamically compressed files.  Other advantages of xbstream over
traditional streaming/archive formats include ability to stream multiple
files concurrently (so it is possible to use streaming in the xbstream
format together with the --parallel option) and more compact data
storage.

* To allow streaming and extracting files to/from the xbstream format
produced by xtrabackup, a new utility aptly called 'xbstream' was
added to the XtraBackup distribution. This utility has a tar-like
interface:

- with the '-x' option it extracts files from the stream read from its
standard input to the current directory unless specified otherwise
with the '-C' option.

- with the '-c' option it streams files specified on the command line
to its standard output.

The utility also tries to minimize its impact on the OS page cache by
using the appropriate posix_fadvise() calls when available.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-
 
2
 * Copyright (c) 2003-2007 Tim Kientzle
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 * 1. Redistributions of source code must retain the above copyright
 
9
 *    notice, this list of conditions and the following disclaimer.
 
10
 * 2. Redistributions in binary form must reproduce the above copyright
 
11
 *    notice, this list of conditions and the following disclaimer in the
 
12
 *    documentation and/or other materials provided with the distribution.
 
13
 *
 
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 
15
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
16
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
17
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 
18
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
19
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
20
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
21
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
23
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
24
 */
 
25
#include "test.h"
 
26
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_tar_ustar.c 201247 2009-12-30 05:59:21Z kientzle $");
 
27
 
 
28
static int
 
29
is_null(const char *p, size_t l)
 
30
{
 
31
        while (l > 0) {
 
32
                if (*p != '\0')
 
33
                        return (0);
 
34
                --l;
 
35
                ++p;
 
36
        }
 
37
        return (1);
 
38
}
 
39
 
 
40
/* Verify the contents, then erase them to NUL bytes. */
 
41
/* Tar requires all "unused" bytes be set to NUL; this allows us
 
42
 * to easily verify that by invoking is_null() over the entire header
 
43
 * after verifying each field. */
 
44
#define myAssertEqualMem(a,b,s) assertEqualMem(a, b, s); memset(a, 0, s)
 
45
 
 
46
/*
 
47
 * Detailed verification that 'ustar' archives are written with
 
48
 * the correct format.
 
49
 */
 
50
DEFINE_TEST(test_write_format_tar_ustar)
 
51
{
 
52
        struct archive *a;
 
53
        struct archive_entry *entry;
 
54
        char *buff, *e;
 
55
        size_t buffsize = 100000;
 
56
        size_t used;
 
57
        int i;
 
58
        char f99[100];
 
59
        char f100[101];
 
60
        char f256[257];
 
61
 
 
62
        for (i = 0; i < 99; ++i)
 
63
                f99[i] = 'a' + i % 26;
 
64
        f99[99] = '\0';
 
65
 
 
66
        for (i = 0; i < 100; ++i)
 
67
                f100[i] = 'A' + i % 26;
 
68
        f100[100] = '\0';
 
69
 
 
70
        for (i = 0; i < 256; ++i)
 
71
                f256[i] = 'A' + i % 26;
 
72
        f256[155] = '/';
 
73
        f256[256] = '\0';
 
74
 
 
75
        buff = malloc(buffsize);
 
76
 
 
77
        /* Create a new archive in memory. */
 
78
        assert((a = archive_write_new()) != NULL);
 
79
        assertEqualIntA(a, 0, archive_write_set_format_ustar(a));
 
80
        assertEqualIntA(a, 0, archive_write_set_compression_none(a));
 
81
        assertEqualIntA(a, 0, archive_write_open_memory(a, buff, buffsize, &used));
 
82
 
 
83
        /*
 
84
         * Add various files to it.
 
85
         * TODO: Extend this to cover more filetypes.
 
86
         */
 
87
 
 
88
        /* "file" with 10 bytes of content */
 
89
        assert((entry = archive_entry_new()) != NULL);
 
90
        archive_entry_set_mtime(entry, 1, 10);
 
91
        archive_entry_set_pathname(entry, "file");
 
92
        archive_entry_set_mode(entry, S_IFREG | 0664);
 
93
        archive_entry_set_size(entry, 10);
 
94
        archive_entry_set_uid(entry, 80);
 
95
        archive_entry_set_gid(entry, 90);
 
96
        archive_entry_set_dev(entry, 12);
 
97
        archive_entry_set_ino(entry, 89);
 
98
        archive_entry_set_nlink(entry, 2);
 
99
        assertEqualIntA(a, 0, archive_write_header(a, entry));
 
100
        archive_entry_free(entry);
 
101
        assertEqualIntA(a, 10, archive_write_data(a, "1234567890", 10));
 
102
 
 
103
        /* Hardlink to "file" with 10 bytes of content */
 
104
        assert((entry = archive_entry_new()) != NULL);
 
105
        archive_entry_set_mtime(entry, 1, 10);
 
106
        archive_entry_set_pathname(entry, "linkfile");
 
107
        archive_entry_set_mode(entry, S_IFREG | 0664);
 
108
        /* TODO: Put this back and fix the bug. */
 
109
        /* archive_entry_set_size(entry, 10); */
 
110
        archive_entry_set_uid(entry, 80);
 
111
        archive_entry_set_gid(entry, 90);
 
112
        archive_entry_set_dev(entry, 12);
 
113
        archive_entry_set_ino(entry, 89);
 
114
        archive_entry_set_nlink(entry, 2);
 
115
        assertEqualIntA(a, 0, archive_write_header(a, entry));
 
116
        archive_entry_free(entry);
 
117
        /* Write of data to dir should fail == zero bytes get written. */
 
118
        assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10));
 
119
 
 
120
        /* "dir" */
 
121
        assert((entry = archive_entry_new()) != NULL);
 
122
        archive_entry_set_mtime(entry, 2, 20);
 
123
        archive_entry_set_pathname(entry, "dir");
 
124
        archive_entry_set_mode(entry, S_IFDIR | 0775);
 
125
        archive_entry_set_size(entry, 10);
 
126
        archive_entry_set_nlink(entry, 2);
 
127
        assertEqualIntA(a, 0, archive_write_header(a, entry));
 
128
        archive_entry_free(entry);
 
129
        /* Write of data to dir should fail == zero bytes get written. */
 
130
        assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10));
 
131
 
 
132
        /* "symlink" pointing to "file" */
 
133
        assert((entry = archive_entry_new()) != NULL);
 
134
        archive_entry_set_mtime(entry, 3, 30);
 
135
        archive_entry_set_pathname(entry, "symlink");
 
136
        archive_entry_set_mode(entry, 0664);
 
137
        archive_entry_set_filetype(entry, AE_IFLNK);
 
138
        archive_entry_set_symlink(entry,"file");
 
139
        archive_entry_set_size(entry, 0);
 
140
        archive_entry_set_uid(entry, 88);
 
141
        archive_entry_set_gid(entry, 98);
 
142
        archive_entry_set_dev(entry, 12);
 
143
        archive_entry_set_ino(entry, 90);
 
144
        archive_entry_set_nlink(entry, 1);
 
145
        assertEqualIntA(a, 0, archive_write_header(a, entry));
 
146
        archive_entry_free(entry);
 
147
        /* Write of data to symlink should fail == zero bytes get written. */
 
148
        assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10));
 
149
 
 
150
        /* file with 99-char filename. */
 
151
        assert((entry = archive_entry_new()) != NULL);
 
152
        archive_entry_set_mtime(entry, 1, 10);
 
153
        archive_entry_set_pathname(entry, f99);
 
154
        archive_entry_set_mode(entry, S_IFREG | 0664);
 
155
        archive_entry_set_size(entry, 0);
 
156
        archive_entry_set_uid(entry, 82);
 
157
        archive_entry_set_gid(entry, 93);
 
158
        archive_entry_set_dev(entry, 102);
 
159
        archive_entry_set_ino(entry, 7);
 
160
        archive_entry_set_nlink(entry, 1);
 
161
        assertEqualIntA(a, 0, archive_write_header(a, entry));
 
162
        archive_entry_free(entry);
 
163
 
 
164
        /* file with 100-char filename. */
 
165
        assert((entry = archive_entry_new()) != NULL);
 
166
        archive_entry_set_mtime(entry, 1, 10);
 
167
        archive_entry_set_pathname(entry, f100);
 
168
        archive_entry_set_mode(entry, S_IFREG | 0664);
 
169
        archive_entry_set_size(entry, 0);
 
170
        archive_entry_set_uid(entry, 82);
 
171
        archive_entry_set_gid(entry, 93);
 
172
        archive_entry_set_dev(entry, 102);
 
173
        archive_entry_set_ino(entry, 7);
 
174
        archive_entry_set_nlink(entry, 1);
 
175
        assertEqualIntA(a, 0, archive_write_header(a, entry));
 
176
        archive_entry_free(entry);
 
177
 
 
178
        /* file with 256-char filename. */
 
179
        assert((entry = archive_entry_new()) != NULL);
 
180
        archive_entry_set_mtime(entry, 1, 10);
 
181
        archive_entry_set_pathname(entry, f256);
 
182
        archive_entry_set_mode(entry, S_IFREG | 0664);
 
183
        archive_entry_set_size(entry, 0);
 
184
        archive_entry_set_uid(entry, 82);
 
185
        archive_entry_set_gid(entry, 93);
 
186
        archive_entry_set_dev(entry, 102);
 
187
        archive_entry_set_ino(entry, 7);
 
188
        archive_entry_set_nlink(entry, 1);
 
189
        assertEqualIntA(a, 0, archive_write_header(a, entry));
 
190
        archive_entry_free(entry);
 
191
 
 
192
#if ARCHIVE_VERSION_NUMBER < 2000000
 
193
        archive_write_finish(a);
 
194
#else
 
195
        assert(0 == archive_write_finish(a));
 
196
#endif
 
197
 
 
198
        /*
 
199
         * Verify the archive format.
 
200
         */
 
201
        e = buff;
 
202
 
 
203
        /* "file" */
 
204
        myAssertEqualMem(e + 0, "file", 5); /* Filename */
 
205
        myAssertEqualMem(e + 100, "000664 ", 8); /* mode */
 
206
        myAssertEqualMem(e + 108, "000120 ", 8); /* uid */
 
207
        myAssertEqualMem(e + 116, "000132 ", 8); /* gid */
 
208
        myAssertEqualMem(e + 124, "00000000012 ", 12); /* size */
 
209
        myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */
 
210
        myAssertEqualMem(e + 148, "010034\0 ", 8); /* checksum */
 
211
        myAssertEqualMem(e + 156, "0", 1); /* linkflag */
 
212
        myAssertEqualMem(e + 157, "", 1); /* linkname */
 
213
        myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */
 
214
        myAssertEqualMem(e + 265, "", 1); /* uname */
 
215
        myAssertEqualMem(e + 297, "", 1); /* gname */
 
216
        myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */
 
217
        myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */
 
218
        myAssertEqualMem(e + 345, "", 1); /* prefix */
 
219
        assert(is_null(e + 0, 512));
 
220
        myAssertEqualMem(e + 512, "1234567890", 10);
 
221
        assert(is_null(e + 512, 512));
 
222
        e += 1024;
 
223
 
 
224
        /* hardlink to "file" */
 
225
        myAssertEqualMem(e + 0, "linkfile", 9); /* Filename */
 
226
        myAssertEqualMem(e + 100, "000664 ", 8); /* mode */
 
227
        myAssertEqualMem(e + 108, "000120 ", 8); /* uid */
 
228
        myAssertEqualMem(e + 116, "000132 ", 8); /* gid */
 
229
        myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */
 
230
        myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */
 
231
        myAssertEqualMem(e + 148, "010707\0 ", 8); /* checksum */
 
232
        myAssertEqualMem(e + 156, "0", 1); /* linkflag */
 
233
        myAssertEqualMem(e + 157, "", 1); /* linkname */
 
234
        myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */
 
235
        myAssertEqualMem(e + 265, "", 1); /* uname */
 
236
        myAssertEqualMem(e + 297, "", 1); /* gname */
 
237
        myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */
 
238
        myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */
 
239
        myAssertEqualMem(e + 345, "", 1); /* prefix */
 
240
        assert(is_null(e + 0, 512));
 
241
        e += 512;
 
242
 
 
243
        /* "dir" */
 
244
        myAssertEqualMem(e + 0, "dir/", 4); /* Filename */
 
245
        myAssertEqualMem(e + 100, "000775 ", 8); /* mode */
 
246
        myAssertEqualMem(e + 108, "000000 ", 8); /* uid */
 
247
        myAssertEqualMem(e + 116, "000000 ", 8); /* gid */
 
248
        myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */
 
249
        myAssertEqualMem(e + 136, "00000000002 ", 12); /* mtime */
 
250
        myAssertEqualMem(e + 148, "007747\0 ", 8); /* checksum */
 
251
        myAssertEqualMem(e + 156, "5", 1); /* typeflag */
 
252
        myAssertEqualMem(e + 157, "", 1); /* linkname */
 
253
        myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */
 
254
        myAssertEqualMem(e + 265, "", 1); /* uname */
 
255
        myAssertEqualMem(e + 297, "", 1); /* gname */
 
256
        myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */
 
257
        myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */
 
258
        myAssertEqualMem(e + 345, "", 1); /* prefix */
 
259
        assert(is_null(e + 0, 512));
 
260
        e += 512;
 
261
 
 
262
        /* "symlink" pointing to "file" */
 
263
        myAssertEqualMem(e + 0, "symlink", 8); /* Filename */
 
264
        myAssertEqualMem(e + 100, "000664 ", 8); /* mode */
 
265
        myAssertEqualMem(e + 108, "000130 ", 8); /* uid */
 
266
        myAssertEqualMem(e + 116, "000142 ", 8); /* gid */
 
267
        myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */
 
268
        myAssertEqualMem(e + 136, "00000000003 ", 12); /* mtime */
 
269
        myAssertEqualMem(e + 148, "011446\0 ", 8); /* checksum */
 
270
        myAssertEqualMem(e + 156, "2", 1); /* linkflag */
 
271
        myAssertEqualMem(e + 157, "file", 5); /* linkname */
 
272
        myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */
 
273
        myAssertEqualMem(e + 265, "", 1); /* uname */
 
274
        myAssertEqualMem(e + 297, "", 1); /* gname */
 
275
        myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */
 
276
        myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */
 
277
        myAssertEqualMem(e + 345, "", 1); /* prefix */
 
278
        assert(is_null(e + 0, 512));
 
279
        e += 512;
 
280
 
 
281
        /* File with 99-char filename */
 
282
        myAssertEqualMem(e + 0, f99, 100); /* Filename */
 
283
        myAssertEqualMem(e + 100, "000664 ", 8); /* mode */
 
284
        myAssertEqualMem(e + 108, "000122 ", 8); /* uid */
 
285
        myAssertEqualMem(e + 116, "000135 ", 8); /* gid */
 
286
        myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */
 
287
        myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */
 
288
        myAssertEqualMem(e + 148, "034242\0 ", 8); /* checksum */
 
289
        myAssertEqualMem(e + 156, "0", 1); /* linkflag */
 
290
        myAssertEqualMem(e + 157, "", 1); /* linkname */
 
291
        myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */
 
292
        myAssertEqualMem(e + 265, "", 1); /* uname */
 
293
        myAssertEqualMem(e + 297, "", 1); /* gname */
 
294
        myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */
 
295
        myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */
 
296
        myAssertEqualMem(e + 345, "", 1); /* prefix */
 
297
        assert(is_null(e + 0, 512));
 
298
        e += 512;
 
299
 
 
300
        /* File with 100-char filename */
 
301
        myAssertEqualMem(e + 0, f100, 100); /* Filename */
 
302
        myAssertEqualMem(e + 100, "000664 ", 8); /* mode */
 
303
        myAssertEqualMem(e + 108, "000122 ", 8); /* uid */
 
304
        myAssertEqualMem(e + 116, "000135 ", 8); /* gid */
 
305
        myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */
 
306
        myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */
 
307
        myAssertEqualMem(e + 148, "026230\0 ", 8); /* checksum */
 
308
        myAssertEqualMem(e + 156, "0", 1); /* linkflag */
 
309
        myAssertEqualMem(e + 157, "", 1); /* linkname */
 
310
        myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */
 
311
        myAssertEqualMem(e + 265, "", 1); /* uname */
 
312
        myAssertEqualMem(e + 297, "", 1); /* gname */
 
313
        myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */
 
314
        myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */
 
315
        myAssertEqualMem(e + 345, "", 1); /* prefix */
 
316
        assert(is_null(e + 0, 512));
 
317
        e += 512;
 
318
 
 
319
        /* File with 256-char filename */
 
320
        myAssertEqualMem(e + 0, f256 + 156, 100); /* Filename */
 
321
        myAssertEqualMem(e + 100, "000664 ", 8); /* mode */
 
322
        myAssertEqualMem(e + 108, "000122 ", 8); /* uid */
 
323
        myAssertEqualMem(e + 116, "000135 ", 8); /* gid */
 
324
        myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */
 
325
        myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */
 
326
        myAssertEqualMem(e + 148, "055570\0 ", 8); /* checksum */
 
327
        myAssertEqualMem(e + 156, "0", 1); /* linkflag */
 
328
        myAssertEqualMem(e + 157, "", 1); /* linkname */
 
329
        myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */
 
330
        myAssertEqualMem(e + 265, "", 1); /* uname */
 
331
        myAssertEqualMem(e + 297, "", 1); /* gname */
 
332
        myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */
 
333
        myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */
 
334
        myAssertEqualMem(e + 345, f256, 155); /* prefix */
 
335
        assert(is_null(e + 0, 512));
 
336
        e += 512;
 
337
 
 
338
        /* TODO: Verify other types of entries. */
 
339
 
 
340
        /* Last entry is end-of-archive marker. */
 
341
        assert(is_null(e, 1024));
 
342
        e += 1024;
 
343
 
 
344
        assertEqualInt((int)used, e - buff);
 
345
 
 
346
        free(buff);
 
347
}