~akopytov/percona-xtrabackup/bug1166888-2.0

« back to all changes in this revision

Viewing changes to src/libarchive/tar/test/test_windows.c

  • Committer: Alexey Kopytov
  • Date: 2012-02-10 20:05:56 UTC
  • 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) 2009 Michihiro NAKAJIMA
 
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
 
 
27
#if defined(_WIN32) && !defined(__CYGWIN__)
 
28
#include <windows.h>
 
29
 
 
30
static void
 
31
mkfile(const char *name)
 
32
{
 
33
        FILE *f;
 
34
 
 
35
        f = fopen(name, "wb");
 
36
        assert(f != NULL);
 
37
        assertEqualInt(5, fwrite("01234", 1, 5, f));
 
38
        fclose(f);
 
39
}
 
40
 
 
41
static void
 
42
mkfullpath(char **path1, char **path2, const char *tpath, int type)
 
43
{
 
44
        char *fp1 = NULL, *fp2 = NULL, *p1 = NULL, *p2 = NULL;
 
45
        size_t l;
 
46
 
 
47
        /*
 
48
         * Get full path name of "tpath"
 
49
         */
 
50
        l = GetFullPathNameA(tpath, 0, NULL, NULL);
 
51
        assert(0 != l);
 
52
        fp1 = malloc(l);
 
53
        assert(NULL != fp1);
 
54
        fp2 = malloc(l*2);
 
55
        assert(NULL != fp2);
 
56
        l = GetFullPathNameA(tpath, l, fp1, NULL);
 
57
        if ((type & 0x01) == 0) {
 
58
                for (p1 = fp1; *p1 != '\0'; p1++)
 
59
                        if (*p1 == '\\')
 
60
                                *p1 = '/';
 
61
        }
 
62
 
 
63
        switch(type) {
 
64
        case 0: /* start with "/" */
 
65
        case 1: /* start with "\" */
 
66
                /* strip "c:" */
 
67
                memmove(fp1, fp1 + 2, l - 2);
 
68
                fp1[l -2] = '\0';
 
69
                p1 = fp1 + 1;
 
70
                break;
 
71
        case 2: /* start with "c:/" */
 
72
        case 3: /* start with "c:\" */
 
73
                p1 = fp1 + 3;
 
74
                break;
 
75
        case 4: /* start with "//./c:/" */
 
76
        case 5: /* start with "\\.\c:\" */
 
77
        case 6: /* start with "//?/c:/" */
 
78
        case 7: /* start with "\\?\c:\" */
 
79
                p1 = malloc(l + 4 + 1);
 
80
                assert(NULL != p1);
 
81
                if (type & 0x1)
 
82
                        memcpy(p1, "\\\\.\\", 4);
 
83
                else
 
84
                        memcpy(p1, "//./", 4);
 
85
                if (type == 6 || type == 7)
 
86
                        p1[2] = '?';
 
87
                memcpy(p1 + 4, fp1, l);
 
88
                p1[l + 4] = '\0';
 
89
                free(fp1);
 
90
                fp1 = p1;
 
91
                p1 = fp1 + 7;
 
92
                break;
 
93
        }
 
94
 
 
95
        /*
 
96
         * Strip leading drive names and converting "\" to "\\"
 
97
         */
 
98
        p2 = fp2;
 
99
        while (*p1 != '\0') {
 
100
                if (*p1 == '\\')
 
101
                        *p2 = '/';
 
102
                else
 
103
                        *p2 = *p1;
 
104
                ++p1;
 
105
                ++p2;
 
106
        }
 
107
        *p2++ = '\r';
 
108
        *p2++ = '\n';
 
109
        *p2 = '\0';
 
110
 
 
111
        *path1 = fp1;
 
112
        *path2 = fp2;
 
113
}
 
114
 
 
115
static const char *list1[] = {"aaa/", "aaa/file1", "aaa/xxa/", "aaa/xxb/",
 
116
        "aaa/zzc/", "aaa/zzc/file1", "aaa/xxb/file1", "aaa/xxa/file1",
 
117
        "aab/", "aac/", "abb/", "abc/", "abd/", NULL};
 
118
static const char *list2[] = {"bbb/", "bbb/file1", "bbb/xxa/", "bbb/xxb/",
 
119
        "bbb/zzc/", "bbb/zzc/file1", "bbb/xxb/file1", "bbb/xxa/file1", "bbc/",
 
120
        "bbd/", "bcc/", "bcd/", "bce/", NULL};
 
121
static const char *list3[] = {"aac/", "abc/", "bbc/", "bcc/", "ccc/", NULL};
 
122
static const char *list4[] = {"fff/abca", "fff/acca", NULL};
 
123
static const char *list5[] = {"aaa/file1", "aaa/xxa/", "aaa/xxa/file1",
 
124
        "aaa/xxb/", "aaa/xxb/file1", "aaa/zzc/", "aaa/zzc/file1", NULL};
 
125
static const char *list6[] = {"fff/abca", "fff/acca", "aaa/xxa/",
 
126
        "aaa/xxa/file1", "aaa/xxb/", "aaa/xxb/file1", NULL};
 
127
#endif /* _WIN32 && !__CYGWIN__ */
 
128
 
 
129
DEFINE_TEST(test_windows)
 
130
{
 
131
#if defined(_WIN32) && !defined(__CYGWIN__)
 
132
        char *fp1, *fp2;
 
133
 
 
134
        /*
 
135
         * Preparre tests.
 
136
         * Create directories and files.
 
137
         */
 
138
        assertMakeDir("tmp", 0775);
 
139
        assertChdir("tmp");
 
140
 
 
141
        assertMakeDir("aaa", 0775);
 
142
        assertMakeDir("aaa/xxa", 0775);
 
143
        assertMakeDir("aaa/xxb", 0775);
 
144
        assertMakeDir("aaa/zzc", 0775);
 
145
        mkfile("aaa/file1");
 
146
        mkfile("aaa/xxa/file1");
 
147
        mkfile("aaa/xxb/file1");
 
148
        mkfile("aaa/zzc/file1");
 
149
        assertMakeDir("aab", 0775);
 
150
        assertMakeDir("aac", 0775);
 
151
        assertMakeDir("abb", 0775);
 
152
        assertMakeDir("abc", 0775);
 
153
        assertMakeDir("abd", 0775);
 
154
        assertMakeDir("bbb", 0775);
 
155
        assertMakeDir("bbb/xxa", 0775);
 
156
        assertMakeDir("bbb/xxb", 0775);
 
157
        assertMakeDir("bbb/zzc", 0775);
 
158
        mkfile("bbb/file1");
 
159
        mkfile("bbb/xxa/file1");
 
160
        mkfile("bbb/xxb/file1");
 
161
        mkfile("bbb/zzc/file1");
 
162
        assertMakeDir("bbc", 0775);
 
163
        assertMakeDir("bbd", 0775);
 
164
        assertMakeDir("bcc", 0775);
 
165
        assertMakeDir("bcd", 0775);
 
166
        assertEqualInt(0, _mkdir("bce"));
 
167
        assertEqualInt(0, _mkdir("ccc"));
 
168
        assertEqualInt(0, _mkdir("fff"));
 
169
        mkfile("fff/aaaa");
 
170
        mkfile("fff/abba");
 
171
        mkfile("fff/abca");
 
172
        mkfile("fff/acba");
 
173
        mkfile("fff/acca");
 
174
 
 
175
        /*
 
176
         * Test1: Command line pattern matching.
 
177
         */
 
178
        assertEqualInt(0,
 
179
            systemf("%s -cf ../archive1.tar a*", testprog));
 
180
        assertEqualInt(0,
 
181
            systemf("%s -tf ../archive1.tar > ../list1", testprog));
 
182
        assertFileContainsLinesAnyOrder("../list1", list1);
 
183
 
 
184
        assertEqualInt(0,
 
185
            systemf("%s -cf ../archive2.tar b*", testprog));
 
186
        assertEqualInt(0,
 
187
            systemf("%s -tf ../archive2.tar > ../list2", testprog));
 
188
        assertFileContainsLinesAnyOrder("../list2", list2);
 
189
 
 
190
        assertEqualInt(0,
 
191
            systemf("%s -cf ../archive3.tar ??c", testprog));
 
192
        assertEqualInt(0,
 
193
            systemf("%s -tf ../archive3.tar > ../list3", testprog));
 
194
        assertFileContainsLinesAnyOrder("../list3", list3);
 
195
 
 
196
        assertEqualInt(0,
 
197
            systemf("%s -cf ../archive3b.tar *c", testprog));
 
198
        assertEqualInt(0,
 
199
            systemf("%s -tf ../archive3b.tar > ../list3b", testprog));
 
200
        assertFileContainsLinesAnyOrder("../list3b", list3);
 
201
 
 
202
        assertEqualInt(0,
 
203
            systemf("%s -cf ../archive4.tar fff/a?ca", testprog));
 
204
        assertEqualInt(0,
 
205
            systemf("%s -tf ../archive4.tar > ../list4", testprog));
 
206
        assertFileContainsLinesAnyOrder("../list4", list4);
 
207
 
 
208
        assertEqualInt(0,
 
209
            systemf("%s -cf ../archive5.tar aaa\\*", testprog));
 
210
        assertEqualInt(0,
 
211
            systemf("%s -tf ../archive5.tar > ../list5", testprog));
 
212
        assertFileContainsLinesAnyOrder("../list5", list5);
 
213
 
 
214
        assertEqualInt(0,
 
215
            systemf("%s -cf ../archive6.tar fff\\a?ca aaa\\xx*", testprog));
 
216
        assertEqualInt(0,
 
217
            systemf("%s -tf ../archive6.tar > ../list6", testprog));
 
218
        assertFileContainsLinesAnyOrder("../list6", list6);
 
219
 
 
220
        /*
 
221
         * Test2: Archive the file start with drive letters.
 
222
         */
 
223
        /* Test2a: start with "/" */
 
224
        mkfullpath(&fp1, &fp2, "aaa/file1", 0);
 
225
        assertEqualInt(0,
 
226
            systemf("%s -cf ../archive10.tar %s > ../out10 2> ../err10",
 
227
                testprog, fp1));
 
228
        assertEqualInt(0,
 
229
            systemf("%s -tf ../archive10.tar > ../list10", testprog));
 
230
        /* Check drive letters have been stripped. */
 
231
        assertFileContents(fp2, strlen(fp2), "../list10");
 
232
        free(fp1);
 
233
        free(fp2);
 
234
 
 
235
        /* Test2b: start with "\" */
 
236
        mkfullpath(&fp1, &fp2, "aaa/file1", 1);
 
237
        assertEqualInt(0,
 
238
            systemf("%s -cf ../archive11.tar %s > ../out11 2> ../err11",
 
239
                testprog, fp1));
 
240
        assertEqualInt(0,
 
241
            systemf("%s -tf ../archive11.tar > ../list11", testprog));
 
242
        /* Check drive letters have been stripped. */
 
243
        assertFileContents(fp2, strlen(fp2), "../list11");
 
244
        free(fp1);
 
245
        free(fp2);
 
246
 
 
247
        /* Test2c: start with "c:/" */
 
248
        mkfullpath(&fp1, &fp2, "aaa/file1", 2);
 
249
        assertEqualInt(0,
 
250
            systemf("%s -cf ../archive12.tar %s > ../out12 2> ../err12",
 
251
                testprog, fp1));
 
252
        assertEqualInt(0,
 
253
            systemf("%s -tf ../archive12.tar > ../list12", testprog));
 
254
        /* Check drive letters have been stripped. */
 
255
        assertFileContents(fp2, strlen(fp2), "../list12");
 
256
        free(fp1);
 
257
        free(fp2);
 
258
 
 
259
        /* Test2d: start with "c:\" */
 
260
        mkfullpath(&fp1, &fp2, "aaa/file1", 3);
 
261
        assertEqualInt(0,
 
262
            systemf("%s -cf ../archive13.tar %s > ../out13 2> ../err13",
 
263
                testprog, fp1));
 
264
        assertEqualInt(0,
 
265
            systemf("%s -tf ../archive13.tar > ../list13", testprog));
 
266
        /* Check drive letters have been stripped. */
 
267
        assertFileContents(fp2, strlen(fp2), "../list13");
 
268
        free(fp1);
 
269
        free(fp2);
 
270
 
 
271
        /* Test2e: start with "//./c:/" */
 
272
        mkfullpath(&fp1, &fp2, "aaa/file1", 4);
 
273
        assertEqualInt(0,
 
274
            systemf("%s -cf ../archive14.tar %s > ../out14 2> ../err14",
 
275
                testprog, fp1));
 
276
        assertEqualInt(0,
 
277
            systemf("%s -tf ../archive14.tar > ../list14", testprog));
 
278
        /* Check drive letters have been stripped. */
 
279
        assertFileContents(fp2, strlen(fp2), "../list14");
 
280
        free(fp1);
 
281
        free(fp2);
 
282
 
 
283
        /* Test2f: start with "\\.\c:\" */
 
284
        mkfullpath(&fp1, &fp2, "aaa/file1", 5);
 
285
        assertEqualInt(0,
 
286
            systemf("%s -cf ../archive15.tar %s > ../out15 2> ../err15",
 
287
                testprog, fp1));
 
288
        assertEqualInt(0,
 
289
            systemf("%s -tf ../archive15.tar > ../list15", testprog));
 
290
        /* Check drive letters have been stripped. */
 
291
        assertFileContents(fp2, strlen(fp2), "../list15");
 
292
        free(fp1);
 
293
        free(fp2);
 
294
 
 
295
        /* Test2g: start with "//?/c:/" */
 
296
        mkfullpath(&fp1, &fp2, "aaa/file1", 6);
 
297
        failure("fp1=%s, fp2=%s", fp1, fp2);
 
298
        assertEqualInt(0,
 
299
            systemf("%s -cf ../archive16.tar %s > ../out16 2> ../err16",
 
300
                testprog, fp1));
 
301
        assertEqualInt(0,
 
302
            systemf("%s -tf ../archive16.tar > ../list16", testprog));
 
303
        /* Check drive letters have been stripped. */
 
304
        assertFileContents(fp2, strlen(fp2), "../list16");
 
305
        free(fp1);
 
306
        free(fp2);
 
307
 
 
308
        /* Test2h: start with "\\?\c:\" */
 
309
        mkfullpath(&fp1, &fp2, "aaa/file1", 7);
 
310
        failure("fp1=%s, fp2=%s", fp1, fp2);
 
311
        assertEqualInt(0,
 
312
            systemf("%s -cf ../archive17.tar %s > ../out17 2> ../err17",
 
313
                testprog, fp1));
 
314
        assertEqualInt(0,
 
315
            systemf("%s -tf ../archive17.tar > ../list17", testprog));
 
316
        /* Check drive letters have been stripped. */
 
317
        assertFileContents(fp2, strlen(fp2), "../list17");
 
318
        free(fp1);
 
319
        free(fp2);
 
320
#else
 
321
        skipping("Windows specific test");
 
322
#endif /* _WIN32 && !__CYGWIN__ */
 
323
}