~drizzle-trunk/drizzle/development

0.1.84 by kinoyasu
some fixes for 32bit
1
diff -ru libtar-1.2.11_orig/lib/Makefile.in libtar-1.2.11/lib/Makefile.in
2
--- libtar-1.2.11_orig/lib/Makefile.in	2002-12-16 03:02:30.000000000 +0900
3
+++ libtar-1.2.11/lib/Makefile.in	2009-08-21 18:10:44.000000000 +0900
4
@@ -29,7 +29,7 @@
5
 		  -I${top_srcdir}/compat \
6
 		  -I../listhash \
7
 		  @CPPFLAGS@
8
-CFLAGS		= @CFLAGS@
9
+CFLAGS		= @CFLAGS@ -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
10
 LDFLAGS		= @LDFLAGS@
11
 LIBS		= @LIBS@
12
 LIBOBJS		= @LIBOBJS@
0.1.68 by kinoyasu
new mode of innobackupex --stream=tar4ibd; new command tar4ibd based on libtar-1.2.11
13
diff -ru libtar-1.2.11_orig/lib/append.c libtar-1.2.11/lib/append.c
14
--- libtar-1.2.11_orig/lib/append.c	2003-01-07 10:40:59.000000000 +0900
0.1.76 by kinoyasu
tar4ibd could not treat over 8GB file, now max 64GB
15
+++ libtar-1.2.11/lib/append.c	2009-07-09 17:49:26.000000000 +0900
0.1.68 by kinoyasu
new mode of innobackupex --stream=tar4ibd; new command tar4ibd based on libtar-1.2.11
16
@@ -27,6 +27,166 @@
17
 # include <unistd.h>
18
 #endif
19
 
20
+#ifdef POSIX_FADV_NORMAL
21
+#define USE_POSIX_FADVISE
22
+#endif
23
+
24
+/* all of these ripped from InnoDB code from MySQL 4.0.22 */
25
+#define UT_HASH_RANDOM_MASK     1463735687
26
+#define UT_HASH_RANDOM_MASK2    1653893711
27
+#define FIL_PAGE_LSN          16 
28
+#define FIL_PAGE_FILE_FLUSH_LSN 26
29
+#define FIL_PAGE_OFFSET     4
30
+#define FIL_PAGE_DATA       38
31
+#define FIL_PAGE_END_LSN_OLD_CHKSUM 8
32
+#define FIL_PAGE_SPACE_OR_CHKSUM 0
33
+#define UNIV_PAGE_SIZE          (2 * 8192)
34
+#define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL
35
+
36
+/* command line argument to do page checks (that's it) */
37
+/* another argument to specify page ranges... seek to right spot and go from there */
38
+
39
+typedef unsigned long int ulint;
40
+typedef unsigned char byte;
41
+
42
+/* innodb function in name; modified slightly to not have the ASM version (lots of #ifs that didn't apply) */
43
+ulint mach_read_from_4(byte *b)
44
+{
45
+  return( ((ulint)(b[0]) << 24)
46
+          + ((ulint)(b[1]) << 16)
47
+          + ((ulint)(b[2]) << 8)
48
+          + (ulint)(b[3])
49
+          );
50
+}
51
+
52
+ulint
53
+ut_fold_ulint_pair(
54
+/*===============*/
55
+            /* out: folded value */
56
+    ulint   n1, /* in: ulint */
57
+    ulint   n2) /* in: ulint */
58
+{
59
+    return(((((n1 ^ n2 ^ UT_HASH_RANDOM_MASK2) << 8) + n1)
60
+                        ^ UT_HASH_RANDOM_MASK) + n2);
61
+}
62
+
63
+ulint
64
+ut_fold_binary(
65
+/*===========*/
66
+            /* out: folded value */
67
+    byte*   str,    /* in: string of bytes */
68
+    ulint   len)    /* in: length */
69
+{
70
+    ulint   i;
71
+    ulint   fold= 0;
72
+
73
+    for (i= 0; i < len; i++)
74
+    {
75
+      fold= ut_fold_ulint_pair(fold, (ulint)(*str));
76
+
77
+      str++;
78
+    }
79
+
80
+    return(fold);
81
+}
82
+
83
+ulint
84
+buf_calc_page_new_checksum(
85
+/*=======================*/
86
+               /* out: checksum */
87
+    byte*    page) /* in: buffer page */
88
+{
89
+    ulint checksum;
90
+
91
+    /* Since the fields FIL_PAGE_FILE_FLUSH_LSN and ..._ARCH_LOG_NO
92
+    are written outside the buffer pool to the first pages of data
93
+    files, we have to skip them in the page checksum calculation.
94
+    We must also skip the field FIL_PAGE_SPACE_OR_CHKSUM where the
95
+    checksum is stored, and also the last 8 bytes of page because
96
+    there we store the old formula checksum. */
97
+
98
+    checksum= ut_fold_binary(page + FIL_PAGE_OFFSET,
99
+                             FIL_PAGE_FILE_FLUSH_LSN - FIL_PAGE_OFFSET)
100
+            + ut_fold_binary(page + FIL_PAGE_DATA,
101
+                             UNIV_PAGE_SIZE - FIL_PAGE_DATA
102
+                             - FIL_PAGE_END_LSN_OLD_CHKSUM);
103
+    checksum= checksum & 0xFFFFFFFF;
104
+
105
+    return(checksum);
106
+}
107
+
108
+ulint
109
+buf_calc_page_old_checksum(
110
+/*=======================*/
111
+               /* out: checksum */
112
+    byte*    page) /* in: buffer page */
113
+{
114
+    ulint checksum;
115
+
116
+    checksum= ut_fold_binary(page, FIL_PAGE_FILE_FLUSH_LSN);
117
+
118
+    checksum= checksum & 0xFFFFFFFF;
119
+
120
+    return(checksum);
121
+}
122
+
123
+int
124
+buf_page_is_corrupted(
125
+/*==================*/
126
+				/* out: TRUE if corrupted */
127
+	byte*	read_buf)	/* in: a database page */
128
+{
129
+	ulint	checksum;
130
+	ulint	old_checksum;
131
+	ulint	checksum_field;
132
+	ulint	old_checksum_field;
133
+
134
+	if (mach_read_from_4(read_buf + FIL_PAGE_LSN + 4)
135
+	     != mach_read_from_4(read_buf + UNIV_PAGE_SIZE
136
+				- FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
137
+
138
+		/* Stored log sequence numbers at the start and the end
139
+		of page do not match */
140
+
141
+		return(1);
142
+	}
143
+
144
+  /* If we use checksums validation, make additional check before returning
145
+  TRUE to ensure that the checksum is not equal to BUF_NO_CHECKSUM_MAGIC which
146
+  might be stored by InnoDB with checksums disabled.
147
+     Otherwise, skip checksum calculation and return FALSE */
148
+  
149
+    old_checksum = buf_calc_page_old_checksum(read_buf); 
150
+
151
+    old_checksum_field = mach_read_from_4(read_buf + UNIV_PAGE_SIZE
152
+					- FIL_PAGE_END_LSN_OLD_CHKSUM);
153
+
154
+    /* There are 2 valid formulas for old_checksum_field:
155
+	  1. Very old versions of InnoDB only stored 8 byte lsn to the start
156
+	  and the end of the page.
157
+	  2. Newer InnoDB versions store the old formula checksum there. */
158
+	
159
+    if (old_checksum_field != mach_read_from_4(read_buf + FIL_PAGE_LSN)
160
+        && old_checksum_field != old_checksum
161
+        && old_checksum_field != BUF_NO_CHECKSUM_MAGIC) {
162
+
163
+      return(1);
164
+    }
165
+
166
+    checksum = buf_calc_page_new_checksum(read_buf);
167
+    checksum_field = mach_read_from_4(read_buf + FIL_PAGE_SPACE_OR_CHKSUM);
168
+
169
+    /* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id
170
+	  (always equal to 0), to FIL_PAGE_SPACE_SPACE_OR_CHKSUM */
171
+
172
+    if (checksum_field != 0 && checksum_field != checksum
173
+        && checksum_field != BUF_NO_CHECKSUM_MAGIC) {
174
+
175
+      return(1);
176
+    }
177
+  
178
+	return(0);
179
+}
180
 
181
 struct tar_dev
182
 {
0.1.74 by kinoyasu
maybe fix bug 395977
183
@@ -210,10 +370,10 @@
0.1.68 by kinoyasu
new mode of innobackupex --stream=tar4ibd; new command tar4ibd based on libtar-1.2.11
184
 int
185
 tar_append_regfile(TAR *t, char *realname)
186
 {
187
-	char block[T_BLOCKSIZE];
188
+	unsigned char block[T_BLOCKSIZE * 32];
189
 	int filefd;
190
-	int i, j;
0.1.74 by kinoyasu
maybe fix bug 395977
191
-	size_t size;
192
+	int j, k, n_retry;
193
+	size_t i, size;
0.1.68 by kinoyasu
new mode of innobackupex --stream=tar4ibd; new command tar4ibd based on libtar-1.2.11
194
 
195
 	filefd = open(realname, O_RDONLY);
0.1.74 by kinoyasu
maybe fix bug 395977
196
 	if (filefd == -1)
0.1.68 by kinoyasu
new mode of innobackupex --stream=tar4ibd; new command tar4ibd based on libtar-1.2.11
197
@@ -224,28 +384,53 @@
198
 		return -1;
199
 	}
200
 
201
+#ifdef USE_POSIX_FADVISE
202
+	posix_fadvise(filefd, 0, 0, POSIX_FADV_SEQUENTIAL);
203
+	posix_fadvise(filefd, 0, 0, POSIX_FADV_DONTNEED);
204
+#endif
205
+
206
+	n_retry = 0;
207
 	size = th_get_size(t);
208
-	for (i = size; i > T_BLOCKSIZE; i -= T_BLOCKSIZE)
0.1.74 by kinoyasu
maybe fix bug 395977
209
+	for (i = size; i >= T_BLOCKSIZE * 32; i -= T_BLOCKSIZE * 32)
0.1.68 by kinoyasu
new mode of innobackupex --stream=tar4ibd; new command tar4ibd based on libtar-1.2.11
210
 	{
211
-		j = read(filefd, &block, T_BLOCKSIZE);
212
-		if (j != T_BLOCKSIZE)
213
+		j = read(filefd, &block[0], T_BLOCKSIZE * 32);
214
+		if (j != T_BLOCKSIZE * 32)
215
 		{
216
 			if (j != -1)
217
 				errno = EINVAL;
218
 			return -1;
219
 		}
220
-		if (tar_block_write(t, &block) == -1)
221
-			return -1;
222
+		if (buf_page_is_corrupted(block)) {
223
+			if (n_retry > 9) {
224
+				fprintf(stderr,
225
+"The file '%s' may not be InnoDB datafile or may be corrupted.\n",
226
+					realname);
227
+				errno = EIO;
228
+				return -1;
229
+			}
230
+
231
+			/* retry */
232
+			n_retry++;
233
+			if (lseek(filefd, - T_BLOCKSIZE * 32, SEEK_CUR) == -1)
234
+				return -1;
235
+			i += T_BLOCKSIZE * 32;
236
+			continue;
237
+		}
238
+		for (k = 0; k < 32; k++)
239
+			if (tar_block_write(t, &block[T_BLOCKSIZE * k]) == -1)
240
+				return -1;
241
+		n_retry = 0;
242
 	}
243
 
244
 	if (i > 0)
245
 	{
246
-		j = read(filefd, &block, i);
247
+		j = read(filefd, &block[0], i);
248
 		if (j == -1)
249
 			return -1;
250
-		memset(&(block[i]), 0, T_BLOCKSIZE - i);
251
-		if (tar_block_write(t, &block) == -1)
252
-			return -1;
253
+		memset(&(block[i]), 0, T_BLOCKSIZE * 32 - i);
254
+		for (k = 0; k < ((j - 1) / T_BLOCKSIZE + 1); k++)
255
+			if (tar_block_write(t, &block[T_BLOCKSIZE * k]) == -1)
256
+				return -1;
257
 	}
258
 
259
 	close(filefd);
0.1.74 by kinoyasu
maybe fix bug 395977
260
diff -ru libtar-1.2.11_orig/lib/extract.c libtar-1.2.11/lib/extract.c
261
--- libtar-1.2.11_orig/lib/extract.c	2003-03-03 08:58:07.000000000 +0900
0.1.76 by kinoyasu
tar4ibd could not treat over 8GB file, now max 64GB
262
+++ libtar-1.2.11/lib/extract.c	2009-07-09 17:49:26.000000000 +0900
0.1.74 by kinoyasu
maybe fix bug 395977
263
@@ -158,11 +158,11 @@
264
 tar_extract_regfile(TAR *t, char *realname)
265
 {
266
 	mode_t mode;
267
-	size_t size;
268
+	size_t i, size;
269
 	uid_t uid;
270
 	gid_t gid;
271
 	int fdout;
272
-	int i, k;
273
+	int k;
274
 	char buf[T_BLOCKSIZE];
275
 	char *filename;
276
 
277
diff -ru libtar-1.2.11_orig/lib/libtar.h libtar-1.2.11/lib/libtar.h
278
--- libtar-1.2.11_orig/lib/libtar.h	2003-01-07 10:40:59.000000000 +0900
0.1.76 by kinoyasu
tar4ibd could not treat over 8GB file, now max 64GB
279
+++ libtar-1.2.11/lib/libtar.h	2009-07-09 17:49:26.000000000 +0900
0.1.74 by kinoyasu
maybe fix bug 395977
280
@@ -180,7 +180,7 @@
281
 
282
 /* decode tar header info */
283
 #define th_get_crc(t) oct_to_int((t)->th_buf.chksum)
284
-#define th_get_size(t) oct_to_int((t)->th_buf.size)
285
+#define th_get_size(t) oct_to_long((t)->th_buf.size)
286
 #define th_get_mtime(t) oct_to_int((t)->th_buf.mtime)
287
 #define th_get_devmajor(t) oct_to_int((t)->th_buf.devmajor)
288
 #define th_get_devminor(t) oct_to_int((t)->th_buf.devminor)
289
@@ -206,7 +206,7 @@
290
 #define th_set_mtime(t, fmtime) \
291
 	int_to_oct_nonull((fmtime), (t)->th_buf.mtime, 12)
292
 #define th_set_size(t, fsize) \
293
-	int_to_oct_nonull((fsize), (t)->th_buf.size, 12)
0.1.84 by kinoyasu
some fixes for 32bit
294
+	longlong_to_oct_nonull((fsize), (t)->th_buf.size, 12)
0.1.74 by kinoyasu
maybe fix bug 395977
295
 
296
 /* encode everything at once (except the pathname and linkname) */
297
 void th_set_from_stat(TAR *t, struct stat *s);
298
@@ -268,6 +268,7 @@
299
 
300
 /* string-octal to integer conversion */
301
 int oct_to_int(char *oct);
302
+long oct_to_long(char *oct);
303
 
304
 /* integer to NULL-terminated string-octal conversion */
305
 #define int_to_oct(num, oct, octlen) \
306
@@ -275,6 +276,7 @@
307
 
308
 /* integer to string-octal conversion, no NULL */
309
 void int_to_oct_nonull(int num, char *oct, size_t octlen);
0.1.84 by kinoyasu
some fixes for 32bit
310
+void longlong_to_oct_nonull(long long num, char *oct, size_t octlen);
0.1.74 by kinoyasu
maybe fix bug 395977
311
 
312
 
313
 /***** wrapper.c **********************************************************/
314
diff -ru libtar-1.2.11_orig/lib/util.c libtar-1.2.11/lib/util.c
315
--- libtar-1.2.11_orig/lib/util.c	2003-01-07 10:41:00.000000000 +0900
0.1.76 by kinoyasu
tar4ibd could not treat over 8GB file, now max 64GB
316
+++ libtar-1.2.11/lib/util.c	2009-07-09 17:56:31.000000000 +0900
0.1.74 by kinoyasu
maybe fix bug 395977
317
@@ -138,6 +138,14 @@
318
 	return i;
319
 }
320
 
321
+long
322
+oct_to_long(char *oct)
323
+{
324
+	long i;
0.1.76 by kinoyasu
tar4ibd could not treat over 8GB file, now max 64GB
325
+	sscanf(oct, "%12lo", &i);
0.1.74 by kinoyasu
maybe fix bug 395977
326
+	return i;
327
+}
328
+
329
 
330
 /* integer to string-octal conversion, no NULL */
331
 void
0.1.76 by kinoyasu
tar4ibd could not treat over 8GB file, now max 64GB
332
@@ -147,4 +155,16 @@
0.1.74 by kinoyasu
maybe fix bug 395977
333
 	oct[octlen - 1] = ' ';
334
 }
335
 
336
+void
0.1.84 by kinoyasu
some fixes for 32bit
337
+longlong_to_oct_nonull(long long num, char *oct, size_t octlen)
0.1.74 by kinoyasu
maybe fix bug 395977
338
+{
0.1.76 by kinoyasu
tar4ibd could not treat over 8GB file, now max 64GB
339
+	char buf[100];
340
 
0.1.84 by kinoyasu
some fixes for 32bit
341
+	if (num >= (long long)64 * 1024 * 1024 * 1024) {
0.1.76 by kinoyasu
tar4ibd could not treat over 8GB file, now max 64GB
342
+		fprintf(stderr, "Error: tar format cannot treat over 64GB file.\n");
343
+		exit(-1);
344
+	}
345
+
0.1.84 by kinoyasu
some fixes for 32bit
346
+	snprintf(buf, octlen + 1, "%0*llo", octlen, num);
0.1.76 by kinoyasu
tar4ibd could not treat over 8GB file, now max 64GB
347
+	strncpy(oct, buf, octlen);
0.1.74 by kinoyasu
maybe fix bug 395977
348
+}
0.1.68 by kinoyasu
new mode of innobackupex --stream=tar4ibd; new command tar4ibd based on libtar-1.2.11
349
diff -ru libtar-1.2.11_orig/libtar/Makefile.in libtar-1.2.11/libtar/Makefile.in
350
--- libtar-1.2.11_orig/libtar/Makefile.in	2002-12-16 03:02:30.000000000 +0900
0.1.84 by kinoyasu
some fixes for 32bit
351
+++ libtar-1.2.11/libtar/Makefile.in	2009-08-21 18:14:52.000000000 +0900
352
@@ -29,7 +29,7 @@
353
 		  -I${top_srcdir}/lib \
354
 		  -I${top_srcdir}/compat \
355
 		  @CPPFLAGS@
356
-CFLAGS		= @CFLAGS@
357
+CFLAGS		= @CFLAGS@ -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
358
 LDFLAGS		= @LDFLAGS@
359
 LIBS		= @LIBS@
360
 LIBOBJS		= @LIBOBJS@
0.1.68 by kinoyasu
new mode of innobackupex --stream=tar4ibd; new command tar4ibd based on libtar-1.2.11
361
@@ -46,15 +46,15 @@
362
 		  ${top_srcdir}/lib/libtar.h \
363
 		  ../listhash/libtar_listhash.h
364
 LIBTAR_LIBS	= ../lib/libtar.a
365
-ALL		= libtar
366
+ALL		= tar4ibd
367
 
368
 
369
 all: ${ALL}
370
 
371
 .PHONY: clean distclean install
372
 
373
-libtar: ${LIBTAR_OBJS} ${LIBTAR_LIBS} ${LIBTAR_HDRS}
374
-	${CC} ${CFLAGS} ${LDFLAGS} -o libtar libtar.o ${LIBTAR_LIBS} ${LIBS}
375
+tar4ibd: ${LIBTAR_OBJS} ${LIBTAR_LIBS} ${LIBTAR_HDRS}
376
+	${CC} ${CFLAGS} ${LDFLAGS} -o tar4ibd libtar.o ${LIBTAR_LIBS} ${LIBS}
377
 
378
 ${LIBTAR_OBJS}: ${LIBTAR_HDRS}
379
 
380
@@ -69,5 +69,5 @@
381
 
382
 install: ${ALL}
383
 	${MKDIR} ${DESTDIR}${bindir}
384
-	${INSTALL_PROGRAM} libtar ${DESTDIR}${bindir}
385
+	${INSTALL_PROGRAM} tar4ibd ${DESTDIR}${bindir}
386
 
387
diff -ru libtar-1.2.11_orig/libtar/libtar.c libtar-1.2.11/libtar/libtar.c
388
--- libtar-1.2.11_orig/libtar/libtar.c	2003-01-07 10:41:00.000000000 +0900
0.1.76 by kinoyasu
tar4ibd could not treat over 8GB file, now max 64GB
389
+++ libtar-1.2.11/libtar/libtar.c	2009-07-09 17:49:26.000000000 +0900
0.1.68 by kinoyasu
new mode of innobackupex --stream=tar4ibd; new command tar4ibd based on libtar-1.2.11
390
@@ -109,7 +109,7 @@
391
 	char buf[MAXPATHLEN];
392
 	libtar_listptr_t lp;
393
 
394
-	if (tar_open(&t, tarfile,
395
+	if (tar_fdopen(&t, fileno(stdout), tarfile,
396
 #ifdef HAVE_LIBZ
397
 		     (use_zlib ? &gztype : NULL),
398
 #else
399
@@ -164,7 +164,7 @@
400
 	TAR *t;
401
 	int i;
402
 
403
-	if (tar_open(&t, tarfile,
404
+	if (tar_fdopen(&t, fileno(stdin), tarfile,
405
 #ifdef HAVE_LIBZ
406
 		     (use_zlib ? &gztype : NULL),
407
 #else
408
@@ -225,7 +225,7 @@
409
 #ifdef DEBUG
410
 	puts("opening tarfile...");
411
 #endif
412
-	if (tar_open(&t, tarfile,
413
+	if (tar_fdopen(&t, fileno(stdin), tarfile,
414
 #ifdef HAVE_LIBZ
415
 		     (use_zlib ? &gztype : NULL),
416
 #else
417
@@ -264,9 +264,9 @@
418
 void
419
 usage()
420
 {
421
-	printf("Usage: %s [-C rootdir] [-g] [-z] -x|-t filename.tar\n",
422
+	printf("Usage: %s [-C rootdir] [-g] [-z] -x|-t < filename.tar\n",
423
 	       progname);
424
-	printf("       %s [-C rootdir] [-g] [-z] -c filename.tar ...\n",
425
+	printf("       %s [-C rootdir] [-g] [-z] -c ... > filename.tar\n",
426
 	       progname);
427
 	exit(-1);
428
 }
429
@@ -327,7 +327,7 @@
430
 			usage();
431
 		}
432
 
433
-	if (!mode || ((argc - optind) < (mode == MODE_CREATE ? 2 : 1)))
434
+	if (!mode || ((argc - optind) < (mode == MODE_CREATE ? 1 : 0)))
435
 	{
436
 #ifdef DEBUG
437
 		printf("argc - optind == %d\tmode == %d\n", argc - optind,
438
@@ -343,15 +343,14 @@
439
 	switch (mode)
440
 	{
441
 	case MODE_EXTRACT:
442
-		return extract(argv[optind], rootdir);
443
+		return extract("<stdin>", rootdir);
444
 	case MODE_CREATE:
445
-		tarfile = argv[optind];
446
 		l = libtar_list_new(LIST_QUEUE, NULL);
447
-		for (c = optind + 1; c < argc; c++)
448
+		for (c = optind; c < argc; c++)
449
 			libtar_list_add(l, argv[c]);
450
-		return create(tarfile, rootdir, l);
451
+		return create("<stdout>", rootdir, l);
452
 	case MODE_LIST:
453
-		return list(argv[optind]);
454
+		return list("<stdin>");
455
 	default:
456
 		break;
457
 	}