Commit fa793bca authored by unknown's avatar unknown

WL#3234 "Maria - control file manager":

added checksum of the file. Now we have size + magic string + checksum
to detect that all is ok.
Plus misc fixes for "make dist" to work and the resulting tarball to build


include/Makefile.am:
  adding pagecache.h to help the tarball build.
  The model of pagecache.h, keycache.h, is in pkginclude_HEADERS,
  wonder why. Adding pagecache.h to noinst_HEADERS for now.
storage/maria/Makefile.am:
  adding ma_control_file.h to help the tarball build
storage/maria/ma_control_file.c:
  adding a simple checksum to the control file.
  We protect against corruption of this file like this:
  - test size
  - test magic string at start
  - test checksum
  I also add some simple my_message() errors (to be changed to a better
  reporting later).
storage/maria/ma_control_file.h:
  comments
storage/maria/ma_control_file_test.c:
  test of wrong checksum in control file
storage/maria/CMakeLists.txt:
  just to make "make dist" happy for now.
parent a1f25544
......@@ -33,7 +33,7 @@ noinst_HEADERS = config-win.h config-netware.h \
mysql_version.h.in my_handler.h my_time.h decimal.h \
my_vle.h my_user.h my_atomic.h atomic/nolock.h \
atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \
my_libwrap.h
my_libwrap.h pagecache.h
# mysql_version.h are generated
CLEANFILES = mysql_version.h my_config.h readline openssl
......
# empty for the moment; will fill it when we build under Windows
......@@ -28,7 +28,9 @@ bin_PROGRAMS = maria_chk maria_pack maria_ftdump
maria_chk_DEPENDENCIES= $(LIBRARIES)
maria_pack_DEPENDENCIES=$(LIBRARIES)
noinst_PROGRAMS = ma_test1 ma_test2 ma_test3 ma_rt_test ma_sp_test ma_control_file_test
noinst_HEADERS = maria_def.h ma_rt_index.h ma_rt_key.h ma_rt_mbr.h ma_sp_defs.h ma_fulltext.h ma_ftdefs.h ma_ft_test1.h ma_ft_eval.h
noinst_HEADERS = maria_def.h ma_rt_index.h ma_rt_key.h ma_rt_mbr.h \
ma_sp_defs.h ma_fulltext.h ma_ftdefs.h ma_ft_test1.h ma_ft_eval.h \
ma_control_file.h
ma_test1_DEPENDENCIES= $(LIBRARIES)
ma_test2_DEPENDENCIES= $(LIBRARIES)
ma_test3_DEPENDENCIES= $(LIBRARIES)
......
This diff is collapsed.
......@@ -62,9 +62,9 @@ int ma_control_file_create_or_open();
Called when we have created a new log (after syncing this log's creation)
and when we have written a checkpoint (after syncing this log record).
*/
#define CONTROL_FILE_WRITE_ALL 0 /* write all 3 objects */
#define CONTROL_FILE_WRITE_ONLY_LSN 1
#define CONTROL_FILE_WRITE_ONLY_LOGNO 2
#define CONTROL_FILE_UPDATE_ALL 0
#define CONTROL_FILE_UPDATE_ONLY_LSN 1
#define CONTROL_FILE_UPDATE_ONLY_LOGNO 2
int ma_control_file_write_and_force(const LSN *checkpoint_lsn, uint32 logno,
uint objs_to_write);
......
......@@ -45,7 +45,8 @@ int main(int argc,char *argv[])
clean_files();
run_test_normal();
run_test_abnormal();
fprintf(stderr, "All tests succeeded\n");
exit(0); /* all ok, if some test failed, we will have aborted */
}
......@@ -92,7 +93,7 @@ static void run_test_normal()
uint32 logno;
uint objs_to_write;
uint i;
char buffer[4];
char buffer[17];
/* TEST0: Instance starts from scratch (control file does not exist) */
DIE_UNLESS(ma_control_file_create_or_open() == 0);
......@@ -103,7 +104,7 @@ static void run_test_normal()
/* TEST1: Simulate creation of one log */
objs_to_write= CONTROL_FILE_WRITE_ONLY_LOGNO;
objs_to_write= CONTROL_FILE_UPDATE_ONLY_LOGNO;
logno= 123;
DIE_UNLESS(ma_control_file_write_and_force(NULL, logno,
objs_to_write) == 0);
......@@ -121,7 +122,7 @@ static void run_test_normal()
/* TEST2: Simulate creation of 5 logs */
objs_to_write= CONTROL_FILE_WRITE_ONLY_LOGNO;
objs_to_write= CONTROL_FILE_UPDATE_ONLY_LOGNO;
logno= 100;
for (i= 0; i<5; i++)
{
......@@ -141,7 +142,7 @@ static void run_test_normal()
log creation.
*/
objs_to_write= CONTROL_FILE_WRITE_ONLY_LSN;
objs_to_write= CONTROL_FILE_UPDATE_ONLY_LSN;
checkpoint_lsn= (LSN){5, 10000};
logno= 10;
DIE_UNLESS(ma_control_file_write_and_force(&checkpoint_lsn, logno,
......@@ -152,22 +153,22 @@ static void run_test_normal()
DIE_UNLESS(last_checkpoint_lsn.file_no == checkpoint_lsn.file_no);
DIE_UNLESS(last_checkpoint_lsn.rec_offset == checkpoint_lsn.rec_offset);
objs_to_write= CONTROL_FILE_WRITE_ONLY_LOGNO;
objs_to_write= CONTROL_FILE_UPDATE_ONLY_LOGNO;
checkpoint_lsn= (LSN){5, 20000};
logno= 17;
DIE_UNLESS(ma_control_file_write_and_force(&checkpoint_lsn, logno,
objs_to_write) == 0);
/* Check that checkpoint LSN was not updated */
DIE_UNLESS(last_checkpoint_lsn.rec_offset != checkpoint_lsn.rec_offset);
objs_to_write= CONTROL_FILE_WRITE_ONLY_LSN;
objs_to_write= CONTROL_FILE_UPDATE_ONLY_LSN;
checkpoint_lsn= (LSN){17, 20000};
DIE_UNLESS(ma_control_file_write_and_force(&checkpoint_lsn, logno,
objs_to_write) == 0);
objs_to_write= CONTROL_FILE_WRITE_ONLY_LSN;
objs_to_write= CONTROL_FILE_UPDATE_ONLY_LSN;
checkpoint_lsn= (LSN){17, 45000};
DIE_UNLESS(ma_control_file_write_and_force(&checkpoint_lsn, logno,
objs_to_write) == 0);
objs_to_write= CONTROL_FILE_WRITE_ONLY_LOGNO;
objs_to_write= CONTROL_FILE_UPDATE_ONLY_LOGNO;
logno= 19;
DIE_UNLESS(ma_control_file_write_and_force(&checkpoint_lsn, logno,
objs_to_write) == 0);
......@@ -186,18 +187,21 @@ static void run_test_normal()
Note that constants (offsets) are hard-coded here, precisely to prevent
someone from changing them in the control file module and breaking
backward-compatibility.
TODO: when we reach the format-freeze state, we may even just do a
comparison with a raw binary string, to not depend on any uint4korr
future change/breakage.
*/
DIE_IF((fd= my_open(file_name,
O_BINARY | O_RDWR,
MYF(MY_WME))) < 0);
DIE_IF(my_read(fd, buffer, 16, MYF(MY_FNABP | MY_WME)) != 0);
DIE_IF(my_close(fd, MYF(MY_WME)) != 0);
i= uint4korr(buffer+4);
DIE_IF(my_read(fd, buffer, 17, MYF(MY_FNABP | MY_WME)) != 0);
DIE_IF(my_close(fd, MYF(MY_WME)) != 0);
i= uint4korr(buffer+5);
DIE_UNLESS(i == last_checkpoint_lsn.file_no);
i= uint4korr(buffer+8);
i= uint4korr(buffer+9);
DIE_UNLESS(i == last_checkpoint_lsn.rec_offset);
i= uint4korr(buffer+12);
i= uint4korr(buffer+13);
DIE_UNLESS(i == last_logno);
......@@ -217,15 +221,33 @@ static void run_test_normal()
static void run_test_abnormal()
{
char buffer[4];
/* Corrupt the control file */
DIE_IF((fd= my_open(file_name,
O_BINARY | O_RDWR,
MYF(MY_WME))) < 0);
DIE_IF(my_write(fd, "papa", 4, MYF(MY_FNABP | MY_WME)) != 0);
DIE_IF(my_pread(fd, buffer, 4, 0, MYF(MY_FNABP | MY_WME)) != 0);
DIE_IF(my_pwrite(fd, "papa", 4, 0, MYF(MY_FNABP | MY_WME)) != 0);
DIE_IF(my_close(fd, MYF(MY_WME)) != 0);
/* Check that control file module sees the problem */
DIE_IF(ma_control_file_create_or_open() == 0);
/* Restore it and corrupt it differently */
DIE_IF((fd= my_open(file_name,
O_BINARY | O_RDWR,
MYF(MY_WME))) < 0);
/* Restore magic string */
DIE_IF(my_pwrite(fd, buffer, 4, 0, MYF(MY_FNABP | MY_WME)) != 0);
DIE_IF(my_pread(fd, buffer, 1, 4, MYF(MY_FNABP | MY_WME)) != 0);
buffer[1]= buffer[0]+3; /* mangle checksum */
DIE_IF(my_pwrite(fd, buffer+1, 1, 4, MYF(MY_FNABP | MY_WME)) != 0);
DIE_IF(my_close(fd, MYF(MY_WME)) != 0);
/* Check that control file module sees the problem */
DIE_IF(ma_control_file_create_or_open() == 0);
/* Note that control file is left corrupted at this point */
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment