From ebf01db331b22f7e10c6470ac72e2dfd38b35a75 Mon Sep 17 00:00:00 2001 From: Christophe Grenier Date: Thu, 17 Sep 2015 20:55:11 +0200 Subject: [PATCH] PhotoRec: recover InnoDB .ibd database file --- src/Makefile.am | 1 + src/file_ibd.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++ src/file_list.c | 2 + 3 files changed, 109 insertions(+) create mode 100644 src/file_ibd.c diff --git a/src/Makefile.am b/src/Makefile.am index 04a960ed..d70788df 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -152,6 +152,7 @@ file_C = filegen.c \ file_hfsp.c \ file_hr9.c \ file_http.c \ + file_ibd.c \ file_icc.c \ file_icns.c \ file_ico.c \ diff --git a/src/file_ibd.c b/src/file_ibd.c new file mode 100644 index 00000000..1129149a --- /dev/null +++ b/src/file_ibd.c @@ -0,0 +1,106 @@ +/* + + File: file_ibd.c + + Copyright (C) 2015 Christophe GRENIER + + This software 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; either version 2 of the License, or + (at your option) any later version. + + 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 the Free Software Foundation, Inc., 51 + Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif +#include +#include "types.h" +#include "filegen.h" +#include "common.h" +#include "log.h" + +static void register_header_check_ibd(file_stat_t *file_stat); + +const file_hint_t file_hint_ibd= { + .extension="ibd", + .description="InnoDB database file", + .max_filesize=PHOTOREC_MAX_FILE_SIZE, + .recover=1, + .enable_by_default=1, + .register_header_check=®ister_header_check_ibd +}; + +#define FSP_HEADER_OFFSET 38 +#define FSP_SPACE_FLAGS 16 /* fsp_space_t.flags, similar to dict_table_t::flags */ +#define FIL_PAGE_TYPE_FSP_HDR 8 /* File space header */ +#define DICT_TF_BITS 6 /* number of flag bits */ +#define DICT_TF_FORMAT_SHIFT 5 /* file format */ +#define DICT_TF_FORMAT_MASK \ + ((~(~0 << (DICT_TF_BITS - DICT_TF_FORMAT_SHIFT))) << DICT_TF_FORMAT_SHIFT) + +#define DICT_TF_FORMAT_ZIP 1 /* InnoDB plugin for 5.1: compressed tables */ + +struct innodb_fil_header +{ + uint32_t space_or_chksum; + uint32_t offset; + uint32_t prev; + uint32_t next; + uint64_t lsn; + uint16_t type; + uint64_t file_flush_lsn; + uint32_t arch_log_no_or_space_id; +} __attribute__ ((gcc_struct, __packed__)); + +static int header_check_ibd(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new) +{ + const struct innodb_fil_header *hdr=(const struct innodb_fil_header *)buffer; + const uint32_t *flags_ptr=(const uint32_t *)&buffer[FSP_HEADER_OFFSET + FSP_SPACE_FLAGS]; + const uint32_t flags=be32(*flags_ptr); + if(be16(hdr->type)==0) + { + /* Antelope (pre-5.1.7) */ + if(flags==0) + return 0; + } + else if(be16(hdr->type)==FIL_PAGE_TYPE_FSP_HDR) + { + const unsigned int format = flags & DICT_TF_FORMAT_MASK >> DICT_TF_FORMAT_SHIFT; + if(flags==0) + { + /* Antelope (5.1.7 or newer) */ + } + else if(format==DICT_TF_FORMAT_ZIP) + { + /* Barracuda */ + } + else + return 0; + } + else + return 0; + if(buffer_size >= 0xc078 && memcmp(&buffer[0xc070], "supremum", 8)!=0) + return 0; + reset_file_recovery(file_recovery_new); + file_recovery_new->extension=file_hint_ibd.extension; + file_recovery_new->min_filesize=0xc078; + return 1; +} + +static void register_header_check_ibd(file_stat_t *file_stat) +{ + register_header_check(0xc063, "infimum", 7, &header_check_ibd, file_stat); +} diff --git a/src/file_list.c b/src/file_list.c index c507119f..957684bd 100644 --- a/src/file_list.c +++ b/src/file_list.c @@ -154,6 +154,7 @@ extern const file_hint_t file_hint_hds; extern const file_hint_t file_hint_hfsp; extern const file_hint_t file_hint_hr9; extern const file_hint_t file_hint_http; +extern const file_hint_t file_hint_ibd; extern const file_hint_t file_hint_icc; extern const file_hint_t file_hint_icns; extern const file_hint_t file_hint_ico; @@ -454,6 +455,7 @@ file_enable_t list_file_enable[]= { .enable=0, .file_hint=&file_hint_hfsp }, { .enable=0, .file_hint=&file_hint_hr9 }, { .enable=0, .file_hint=&file_hint_http }, + { .enable=0, .file_hint=&file_hint_ibd }, { .enable=0, .file_hint=&file_hint_icc }, { .enable=0, .file_hint=&file_hint_icns }, { .enable=0, .file_hint=&file_hint_ico },