/****************************************************** Copyright (c) 2011-2013 Percona LLC and/or its affiliates. Common declarations for XtraBackup. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA *******************************************************/ #ifndef XB_COMMON_H #define XB_COMMON_H #include #include #include #include /** Determine if (i) is a user tablespace id or not. */ # define fil_is_user_tablespace_id(i) (i != 0 \ && !srv_is_undo_tablespace(i)) #ifdef _MSC_VER #define stat _stati64 #define PATH_MAX MAX_PATH #endif #ifndef HAVE_VASPRINTF static inline int vasprintf(char **strp, const char *fmt, va_list args) { int len; #ifdef _MSC_VER len = _vscprintf(fmt, args); #else len = vsnprintf(NULL, 0, fmt, args); #endif if (len < 0) { return -1; } *strp = (char *)malloc(len + 1); if (!*strp) { return -1; } vsprintf(*strp, fmt, args); return len; } static inline int asprintf(char **strp, const char *fmt,...) { va_list args; va_start(args, fmt); int len = vasprintf(strp, fmt, args); va_end(args); return len; } #endif #define xb_a(expr) \ do { \ if (!(expr)) { \ fprintf(stderr,"Assertion \"%s\" failed at %s:%lu\n", \ #expr, __FILE__, (ulong) __LINE__); \ abort(); \ } \ } while (0); #ifdef XB_DEBUG #define xb_ad(expr) xb_a(expr) #else #define xb_ad(expr) #endif #define XB_DELTA_INFO_SUFFIX ".meta" static inline int msg1(uint thread_num, const char *prefix, const char *fmt, va_list args) { int result; time_t t = time(NULL); char date[100]; char *line; strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&t)); result = vasprintf(&line, fmt, args); if (result != -1) { if (fmt && fmt[strlen(fmt)] != '\n') result = fprintf(stderr, "[%02u] %s%s %s\n", thread_num, prefix, date, line); else result = fprintf(stderr, "[%02u] %s%s %s", thread_num, prefix, date, line); free(line); } return result; } static inline ATTRIBUTE_FORMAT(printf, 2, 3) int msg(unsigned int thread_num, const char *fmt, ...) { int result; va_list args; va_start(args, fmt); result = msg1(thread_num,"", fmt, args); va_end(args); return result; } static inline ATTRIBUTE_FORMAT(printf, 1, 2) int msg(const char *fmt, ...) { int result; va_list args; va_start(args, fmt); result = msg1(0, "", fmt, args); va_end(args); return result; } static inline ATTRIBUTE_FORMAT(printf, 1,2) ATTRIBUTE_NORETURN void die(const char *fmt, ...) { va_list args; va_start(args, fmt); msg1(0, "FATAL ERROR: ", fmt, args); va_end(args); fflush(stderr); _exit(EXIT_FAILURE); } /* Use POSIX_FADV_NORMAL when available */ #ifdef POSIX_FADV_NORMAL # define USE_POSIX_FADVISE #else # define POSIX_FADV_NORMAL # define POSIX_FADV_SEQUENTIAL # define POSIX_FADV_DONTNEED # define posix_fadvise(fd, offset, len, advice) do { (void)offset; } while(0) #endif /*********************************************************************** Computes bit shift for a given value. If the argument is not a power of 2, returns 0.*/ static inline unsigned get_bit_shift(size_t value) { unsigned shift; if (value == 0) return 0; for (shift = 0; !(value & 1); shift++) { value >>= 1; } return (value >> 1) ? 0 : shift; } /**************************************************************************** Read 'len' bytes from 'fd'. It is identical to my_read(..., MYF(MY_FULL_IO)), i.e. tries to combine partial reads into a single block of size 'len', except that it bails out on EOF or error, and returns the number of successfully read bytes instead. */ static inline size_t xb_read_full(File fd, uchar *buf, size_t len) { size_t tlen = 0; size_t tbytes; while (tlen < len) { tbytes = my_read(fd, buf, len - tlen, MYF(MY_WME)); if (tbytes == 0 || tbytes == MY_FILE_ERROR) { break; } buf += tbytes; tlen += tbytes; } return tlen; } #endif