Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:muzazzi:experimental
xtrabackup
tar4ibd_libtar-1.2.11.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File tar4ibd_libtar-1.2.11.patch of Package xtrabackup
diff -ru a/libtar-1.2.11/lib/Makefile.in b/libtar-1.2.11/lib/Makefile.in --- a/libtar-1.2.11/lib/Makefile.in 2002-12-16 03:02:30.000000000 +0900 +++ b/libtar-1.2.11/lib/Makefile.in 2009-08-21 18:10:44.000000000 +0900 @@ -29,7 +29,7 @@ -I${top_srcdir}/compat \ -I../listhash \ @CPPFLAGS@ -CFLAGS = @CFLAGS@ +CFLAGS = @CFLAGS@ -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ LIBOBJS = @LIBOBJS@ diff -ru a/libtar-1.2.11/lib/append.c b/libtar-1.2.11/lib/append.c --- a/libtar-1.2.11/lib/append.c 2003-01-07 10:40:59.000000000 +0900 +++ b/libtar-1.2.11/lib/append.c 2009-07-09 17:49:26.000000000 +0900 @@ -27,6 +27,215 @@ # include <unistd.h> #endif +#ifdef POSIX_FADV_NORMAL +#define USE_POSIX_FADVISE +#endif + +/* all of these ripped from InnoDB code from MySQL 4.0.22 */ +#define UT_HASH_RANDOM_MASK 1463735687 +#define UT_HASH_RANDOM_MASK2 1653893711 +#define FIL_PAGE_LSN 16 +#define FIL_PAGE_FILE_FLUSH_LSN 26 +#define FIL_PAGE_OFFSET 4 +#define FIL_PAGE_DATA 38 +#define FIL_PAGE_DATA_ALIGN_32 40 +#define FIL_PAGE_END_LSN_OLD_CHKSUM 8 +#define FIL_PAGE_SPACE_OR_CHKSUM 0 +//#define UNIV_PAGE_SIZE (2 * 8192) +#define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL + +/* command line argument to do page checks (that's it) */ +/* another argument to specify page ranges... seek to right spot and go from there */ + +typedef unsigned long int ulint; +typedef unsigned char byte; + +/* innodb function in name; modified slightly to not have the ASM version (lots of #ifs that didn't apply) */ +ulint mach_read_from_4(byte *b) +{ + return( ((ulint)(b[0]) << 24) + + ((ulint)(b[1]) << 16) + + ((ulint)(b[2]) << 8) + + (ulint)(b[3]) + ); +} + +ulint +ut_fold_ulint_pair( +/*===============*/ + /* out: folded value */ + ulint n1, /* in: ulint */ + ulint n2) /* in: ulint */ +{ + return(((((n1 ^ n2 ^ UT_HASH_RANDOM_MASK2) << 8) + n1) + ^ UT_HASH_RANDOM_MASK) + n2); +} + +ulint +ut_fold_binary( +/*===========*/ + /* out: folded value */ + byte* str, /* in: string of bytes */ + ulint len) /* in: length */ +{ + ulint i; + ulint fold= 0; + + for (i= 0; i < len; i++) + { + fold= ut_fold_ulint_pair(fold, (ulint)(*str)); + + str++; + } + + return(fold); +} + +ulint +ut_fold_binary_32( +/*==============*/ + byte* str, + ulint len) +{ + unsigned int* str_end = (unsigned int*) (str + len); + unsigned int* str_32 = (unsigned int*) str; + ulint fold = 0; + + if (sizeof(unsigned int) != 4) { + fprintf(stderr, + "size of int is not 32bit.\n"); + exit(-1); + } + + while (str_32 < str_end) { + fold = ut_fold_ulint_pair(fold, (ulint)(*str_32)); + + str_32++; + } + + return(fold); +} + +ulint +buf_calc_page_new_checksum( +/*=======================*/ + /* out: checksum */ + byte* page, /* in: buffer page */ + ulint page_size) +{ + ulint checksum; + + /* Since the fields FIL_PAGE_FILE_FLUSH_LSN and ..._ARCH_LOG_NO + are written outside the buffer pool to the first pages of data + files, we have to skip them in the page checksum calculation. + We must also skip the field FIL_PAGE_SPACE_OR_CHKSUM where the + checksum is stored, and also the last 8 bytes of page because + there we store the old formula checksum. */ + + checksum= ut_fold_binary(page + FIL_PAGE_OFFSET, + FIL_PAGE_FILE_FLUSH_LSN - FIL_PAGE_OFFSET) + + ut_fold_binary(page + FIL_PAGE_DATA, + page_size - FIL_PAGE_DATA + - FIL_PAGE_END_LSN_OLD_CHKSUM); + checksum= checksum & 0xFFFFFFFF; + + return(checksum); +} + +ulint +buf_calc_page_new_checksum_32( +/*==========================*/ + byte* page, + ulint page_size) +{ + ulint checksum; + + checksum = ut_fold_binary(page + FIL_PAGE_OFFSET, + FIL_PAGE_FILE_FLUSH_LSN - FIL_PAGE_OFFSET) + + ut_fold_binary(page + FIL_PAGE_DATA, + FIL_PAGE_DATA_ALIGN_32 - FIL_PAGE_DATA) + + ut_fold_binary_32(page + FIL_PAGE_DATA_ALIGN_32, + page_size - FIL_PAGE_DATA_ALIGN_32 + - FIL_PAGE_END_LSN_OLD_CHKSUM); + checksum= checksum & 0xFFFFFFFF; + + return(checksum); +} + +ulint +buf_calc_page_old_checksum( +/*=======================*/ + /* out: checksum */ + byte* page) /* in: buffer page */ +{ + ulint checksum; + + checksum= ut_fold_binary(page, FIL_PAGE_FILE_FLUSH_LSN); + + checksum= checksum & 0xFFFFFFFF; + + return(checksum); +} + +int +buf_page_is_corrupted( +/*==================*/ + /* out: TRUE if corrupted */ + byte* read_buf, /* in: a database page */ + ulint page_size) +{ + ulint checksum; + ulint old_checksum; + ulint checksum_field; + ulint old_checksum_field; + + if (mach_read_from_4(read_buf + FIL_PAGE_LSN + 4) + != mach_read_from_4(read_buf + page_size + - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) { + + /* Stored log sequence numbers at the start and the end + of page do not match */ + + return(1); + } + + /* If we use checksums validation, make additional check before returning + TRUE to ensure that the checksum is not equal to BUF_NO_CHECKSUM_MAGIC which + might be stored by InnoDB with checksums disabled. + Otherwise, skip checksum calculation and return FALSE */ + + old_checksum = buf_calc_page_old_checksum(read_buf); + + old_checksum_field = mach_read_from_4(read_buf + page_size + - FIL_PAGE_END_LSN_OLD_CHKSUM); + + /* There are 2 valid formulas for old_checksum_field: + 1. Very old versions of InnoDB only stored 8 byte lsn to the start + and the end of the page. + 2. Newer InnoDB versions store the old formula checksum there. */ + + if (old_checksum_field != mach_read_from_4(read_buf + FIL_PAGE_LSN) + && old_checksum_field != old_checksum + && old_checksum_field != BUF_NO_CHECKSUM_MAGIC) { + + return(1); + } + + checksum = buf_calc_page_new_checksum(read_buf, page_size); + checksum_field = mach_read_from_4(read_buf + FIL_PAGE_SPACE_OR_CHKSUM); + + /* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id + (always equal to 0), to FIL_PAGE_SPACE_SPACE_OR_CHKSUM */ + + if (checksum_field != 0 && checksum_field != checksum + && checksum_field != buf_calc_page_new_checksum_32(read_buf, page_size) + && checksum_field != BUF_NO_CHECKSUM_MAGIC) { + + return(1); + } + + return(0); +} struct tar_dev { @@ -210,10 +419,11 @@ int tar_append_regfile(TAR *t, char *realname) { - char block[T_BLOCKSIZE]; + unsigned char block[T_BLOCKSIZE * 32]; /* 16KB is MAX */ int filefd; - int i, j; - size_t size; + int j, k, n_retry; + size_t i, size; + int page_size = 4 * 1024; /* check 4K, 8K and 16K */ filefd = open(realname, O_RDONLY); if (filefd == -1) @@ -224,28 +434,61 @@ return -1; } +#ifdef USE_POSIX_FADVISE + posix_fadvise(filefd, 0, 0, POSIX_FADV_SEQUENTIAL); + posix_fadvise(filefd, 0, 0, POSIX_FADV_DONTNEED); +#endif + + n_retry = 0; size = th_get_size(t); - for (i = size; i > T_BLOCKSIZE; i -= T_BLOCKSIZE) + for (i = size; i >= page_size; i -= page_size) { - j = read(filefd, &block, T_BLOCKSIZE); - if (j != T_BLOCKSIZE) + j = read(filefd, &block[0], page_size); + if (j != page_size) { if (j != -1) errno = EINVAL; return -1; } - if (tar_block_write(t, &block) == -1) - return -1; + if (buf_page_is_corrupted(block, (ulint)page_size)) { + if (n_retry > 9) { + fprintf(stderr, +"The file '%s' may not be InnoDB datafile or may be corrupted.\n", + realname); + errno = EIO; + return -1; + } + + /* retry */ + if (lseek(filefd, - page_size, SEEK_CUR) == -1) + return -1; + + if (i == size + && page_size < 16 * 1024) { + page_size *= 2; + } else { + n_retry++; + } + + i += page_size; + + continue; + } + for (k = 0; k < page_size / T_BLOCKSIZE; k++) + if (tar_block_write(t, &block[T_BLOCKSIZE * k]) == -1) + return -1; + n_retry = 0; } if (i > 0) { - j = read(filefd, &block, i); + j = read(filefd, &block[0], i); if (j == -1) return -1; - memset(&(block[i]), 0, T_BLOCKSIZE - i); - if (tar_block_write(t, &block) == -1) - return -1; + memset(&(block[i]), 0, T_BLOCKSIZE * 32 - i); + for (k = 0; k < ((j - 1) / T_BLOCKSIZE + 1); k++) + if (tar_block_write(t, &block[T_BLOCKSIZE * k]) == -1) + return -1; } close(filefd); diff -ru a/libtar-1.2.11/lib/extract.c b/libtar-1.2.11/lib/extract.c --- a/libtar-1.2.11/lib/extract.c 2003-03-03 08:58:07.000000000 +0900 +++ b/libtar-1.2.11/lib/extract.c 2009-07-09 17:49:26.000000000 +0900 @@ -158,11 +158,11 @@ tar_extract_regfile(TAR *t, char *realname) { mode_t mode; - size_t size; + size_t i, size; uid_t uid; gid_t gid; int fdout; - int i, k; + int k; char buf[T_BLOCKSIZE]; char *filename; diff -ru a/libtar-1.2.11/lib/libtar.h b/libtar-1.2.11/lib/libtar.h --- a/libtar-1.2.11/lib/libtar.h 2003-01-07 10:40:59.000000000 +0900 +++ b/libtar-1.2.11/lib/libtar.h 2010-02-03 17:03:22.000000000 +0900 @@ -180,7 +180,7 @@ /* decode tar header info */ #define th_get_crc(t) oct_to_int((t)->th_buf.chksum) -#define th_get_size(t) oct_to_int((t)->th_buf.size) +#define th_get_size(t) oct_to_longlong((t)->th_buf.size) #define th_get_mtime(t) oct_to_int((t)->th_buf.mtime) #define th_get_devmajor(t) oct_to_int((t)->th_buf.devmajor) #define th_get_devminor(t) oct_to_int((t)->th_buf.devminor) @@ -204,9 +204,9 @@ void th_set_group(TAR *t, gid_t gid); void th_set_mode(TAR *t, mode_t fmode); #define th_set_mtime(t, fmtime) \ - int_to_oct_nonull((fmtime), (t)->th_buf.mtime, 12) + int_to_oct((fmtime), (t)->th_buf.mtime, 12) #define th_set_size(t, fsize) \ - int_to_oct_nonull((fsize), (t)->th_buf.size, 12) + longlong_to_oct_nonull((fsize), (t)->th_buf.size, 12) /* encode everything at once (except the pathname and linkname) */ void th_set_from_stat(TAR *t, struct stat *s); @@ -268,13 +268,16 @@ /* string-octal to integer conversion */ int oct_to_int(char *oct); +long oct_to_long(char *oct); +long long oct_to_longlong(char *oct); /* integer to NULL-terminated string-octal conversion */ #define int_to_oct(num, oct, octlen) \ - snprintf((oct), (octlen), "%*lo ", (octlen) - 2, (unsigned long)(num)) + snprintf((oct), (octlen), "%0*lo", (octlen) - 1, (unsigned long)(num)) /* integer to string-octal conversion, no NULL */ void int_to_oct_nonull(int num, char *oct, size_t octlen); +void longlong_to_oct_nonull(long long num, char *oct, size_t octlen); /***** wrapper.c **********************************************************/ diff -ru a/libtar-1.2.11/lib/util.c b/libtar-1.2.11/lib/util.c --- a/libtar-1.2.11_orig/lib/util.c 2003-01-07 10:41:00.000000000 +0900 +++ b/libtar-1.2.11/lib/util.c 2009-07-09 17:56:31.000000000 +0900 @@ -138,6 +138,14 @@ return i; } +long +oct_to_long(char *oct) +{ + long i; + sscanf(oct, "%12lo", &i); + return i; +} + /* integer to string-octal conversion, no NULL */ void @@ -147,4 +155,46 @@ oct[octlen - 1] = ' '; } +void +longlong_to_oct_nonull(long long num, char *oct, size_t octlen) +{ + char buf[100]; + + if (num >= (long long)64 * 1024 * 1024 * 1024) { + oct[0] = 0x80; + oct[1] = 0; + oct[2] = 0; + oct[3] = 0; + oct[4] = (char)((num >> 56) & 0xFF); + oct[5] = (char)((num >> 48) & 0xFF); + oct[6] = (char)((num >> 40) & 0xFF); + oct[7] = (char)((num >> 32) & 0xFF); + oct[8] = (char)((num >> 24) & 0xFF); + oct[9] = (char)((num >> 16) & 0xFF); + oct[10] = (char)((num >> 8) & 0xFF); + oct[11] = (char)((num) & 0xFF); + } else { + snprintf(buf, octlen + 1, "%0*llo", octlen, num); + strncpy(oct, buf, octlen); + } +} + +long long +oct_to_longlong(char *oct) +{ + long long i; + if (oct[0] & 0x80) { + i = ((long long)((unsigned char)oct[4]) << 56) + | ((long long)((unsigned char)oct[5]) << 48) + | ((long long)((unsigned char)oct[6]) << 40) + | ((long long)((unsigned char)oct[7]) << 32) + | ((long long)((unsigned char)oct[8]) << 24) + | ((long long)((unsigned char)oct[9]) << 16) + | ((long long)((unsigned char)oct[10]) << 8) + | ((long long)((unsigned char)oct[11])); + } else { + sscanf(oct, "%12llo", &i); + } + return i; +} diff -ru a/libtar-1.2.11/libtar/Makefile.in b/libtar-1.2.11/libtar/Makefile.in --- a/libtar-1.2.11/libtar/Makefile.in 2002-12-16 03:02:30.000000000 +0900 +++ b/libtar-1.2.11/libtar/Makefile.in 2009-08-21 18:14:52.000000000 +0900 @@ -29,7 +29,7 @@ -I${top_srcdir}/lib \ -I${top_srcdir}/compat \ @CPPFLAGS@ -CFLAGS = @CFLAGS@ +CFLAGS = @CFLAGS@ -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ LIBOBJS = @LIBOBJS@ @@ -46,15 +46,15 @@ ${top_srcdir}/lib/libtar.h \ ../listhash/libtar_listhash.h LIBTAR_LIBS = ../lib/libtar.a -ALL = libtar +ALL = tar4ibd all: ${ALL} .PHONY: clean distclean install -libtar: ${LIBTAR_OBJS} ${LIBTAR_LIBS} ${LIBTAR_HDRS} - ${CC} ${CFLAGS} ${LDFLAGS} -o libtar libtar.o ${LIBTAR_LIBS} ${LIBS} +tar4ibd: ${LIBTAR_OBJS} ${LIBTAR_LIBS} ${LIBTAR_HDRS} + ${CC} ${CFLAGS} ${LDFLAGS} -o tar4ibd libtar.o ${LIBTAR_LIBS} ${LIBS} ${LIBTAR_OBJS}: ${LIBTAR_HDRS} @@ -69,5 +69,5 @@ install: ${ALL} ${MKDIR} ${DESTDIR}${bindir} - ${INSTALL_PROGRAM} libtar ${DESTDIR}${bindir} + ${INSTALL_PROGRAM} tar4ibd ${DESTDIR}${bindir} diff -ru a/libtar-1.2.11/libtar/libtar.c b/libtar-1.2.11/libtar/libtar.c --- a/libtar-1.2.11/libtar/libtar.c 2003-01-07 10:41:00.000000000 +0900 +++ b/libtar-1.2.11/libtar/libtar.c 2009-07-09 17:49:26.000000000 +0900 @@ -109,7 +109,7 @@ char buf[MAXPATHLEN]; libtar_listptr_t lp; - if (tar_open(&t, tarfile, + if (tar_fdopen(&t, fileno(stdout), tarfile, #ifdef HAVE_LIBZ (use_zlib ? &gztype : NULL), #else @@ -164,7 +164,7 @@ TAR *t; int i; - if (tar_open(&t, tarfile, + if (tar_fdopen(&t, fileno(stdin), tarfile, #ifdef HAVE_LIBZ (use_zlib ? &gztype : NULL), #else @@ -225,7 +225,7 @@ #ifdef DEBUG puts("opening tarfile..."); #endif - if (tar_open(&t, tarfile, + if (tar_fdopen(&t, fileno(stdin), tarfile, #ifdef HAVE_LIBZ (use_zlib ? &gztype : NULL), #else @@ -264,9 +264,9 @@ void usage() { - printf("Usage: %s [-C rootdir] [-g] [-z] -x|-t filename.tar\n", + printf("Usage: %s [-C rootdir] [-g] [-z] -x|-t < filename.tar\n", progname); - printf(" %s [-C rootdir] [-g] [-z] -c filename.tar ...\n", + printf(" %s [-C rootdir] [-g] [-z] -c ... > filename.tar\n", progname); exit(-1); } @@ -327,7 +327,7 @@ usage(); } - if (!mode || ((argc - optind) < (mode == MODE_CREATE ? 2 : 1))) + if (!mode || ((argc - optind) < (mode == MODE_CREATE ? 1 : 0))) { #ifdef DEBUG printf("argc - optind == %d\tmode == %d\n", argc - optind, @@ -343,15 +343,14 @@ switch (mode) { case MODE_EXTRACT: - return extract(argv[optind], rootdir); + return extract("<stdin>", rootdir); case MODE_CREATE: - tarfile = argv[optind]; l = libtar_list_new(LIST_QUEUE, NULL); - for (c = optind + 1; c < argc; c++) + for (c = optind; c < argc; c++) libtar_list_add(l, argv[c]); - return create(tarfile, rootdir, l); + return create("<stdout>", rootdir, l); case MODE_LIST: - return list(argv[optind]); + return list("<stdin>"); default: break; }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor