Commit 722a8ebe authored by unknown's avatar unknown

Store maximum transaction id into control file at clean shutdown.

This can serve to maria_chk to check that trids found in rows and keys
are not too big. Also used by Recovery when logs are lost.
Options --require-control-file, --datadir, --log-dir (yes, the dashes are
inconsistent but I imitated mysqld --datadir and --maria-log-dir) for
maria_chk.
Lock control file _before_ reading its content.


storage/maria/ha_maria.cc:
  new prototype
storage/maria/ma_check.c:
  A function to find the max trid in the system (consults transaction
  manager and control file), to check tables.
storage/maria/ma_checkpoint.c:
  new prototype
storage/maria/ma_control_file.c:
  Store max trid into control file, in a backward-compatible way
  (can still read old control files).
  Parameter to ma_control_file_open(), to not create the log if it's
  missing (maria_chk needs that).
  Lock control file _before_ reading its content.
  Fix for a segfault when reading an old control file (bzero() with a
  negative second argument)
storage/maria/ma_control_file.h:
  changes to the control file module's API
storage/maria/ma_init.c:
  When Maria shuts down cleanly, store max trid into control file.
storage/maria/ma_loghandler.c:
  new prototype
storage/maria/ma_recovery.c:
  During recovery, consult max trid stored in control file, in case it is
  bigger than what we found in log (case of logs manually removed by user).
storage/maria/ma_test1.c:
  new prototype
storage/maria/ma_test2.c:
  new prototype
storage/maria/maria_chk.c:
  New option --require-control-file (abort if control file not found),
  --datadir (path for control file (and for logs if --log-dir not specified)),
  --log-dir (path for logs).
  Try to open control file when maria_chk starts.
storage/maria/maria_read_log.c:
  new prototype
storage/maria/trnman.c:
  A new function to know max trid in transaction manager
storage/maria/trnman_public.h:
  New function
storage/maria/unittest/ma_control_file-t.c:
  new prototypes. Testing storing and retrieving the max trid to/from
  control file
storage/maria/unittest/ma_test_loghandler-t.c:
  new prototype
storage/maria/unittest/ma_test_loghandler_first_lsn-t.c:
  new prototype
storage/maria/unittest/ma_test_loghandler_max_lsn-t.c:
  new prototype
storage/maria/unittest/ma_test_loghandler_multigroup-t.c:
  new prototype
storage/maria/unittest/ma_test_loghandler_multithread-t.c:
  new prototype
storage/maria/unittest/ma_test_loghandler_noflush-t.c:
  new prototype
storage/maria/unittest/ma_test_loghandler_nologs-t.c:
  new prototype
storage/maria/unittest/ma_test_loghandler_pagecache-t.c:
  new prototype
storage/maria/unittest/ma_test_loghandler_purge-t.c:
  new prototype
parent 42f970de
......@@ -2768,7 +2768,7 @@ static int ha_maria_init(void *p)
maria_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES;
bzero(maria_log_pagecache, sizeof(*maria_log_pagecache));
maria_tmpdir= &mysql_tmpdir_list; /* For REDO */
res= maria_init() || ma_control_file_create_or_open() ||
res= maria_init() || ma_control_file_open(TRUE) ||
!init_pagecache(maria_pagecache,
(size_t) pagecache_buffer_size, pagecache_division_limit,
pagecache_age_threshold, maria_block_size, 0) ||
......
......@@ -98,6 +98,7 @@ static void report_keypage_fault(HA_CHECK *param, MARIA_HA *info,
static my_bool create_new_data_handle(MARIA_SORT_PARAM *param, File new_file);
static my_bool _ma_flush_table_files_before_swap(HA_CHECK *param,
MARIA_HA *info);
static TrID max_trid_in_system(void);
void maria_chk_init(HA_CHECK *param)
......@@ -6444,3 +6445,21 @@ static void report_keypage_fault(HA_CHECK *param, MARIA_HA *info,
"error: %d",
llstr(position / block_size, buff), my_errno);
}
/**
When we want to check a table, we verify that the transaction ids of rows
and keys are not bigger than the biggest id generated by Maria so far, which
is returned by the function below.
@note If control file is not open, 0 may be returned; to not confuse
this with a valid max trid of 0, the caller should notice that it failed to
open the control file (ma_control_file_inited() can serve for that).
*/
static TrID max_trid_in_system(void)
{
TrID id= trnman_get_max_trid(); /* 0 if transac manager not initialized */
/* 'id' may be far bigger, if last shutdown is old */
return max(id, max_trid_in_control_file);
}
......@@ -244,8 +244,8 @@ static int really_execute_checkpoint(void)
such hook would be called before translog_flush (and we must be sure
that log was flushed before we write to the control file).
*/
if (unlikely(ma_control_file_write_and_force(lsn, FILENO_IMPOSSIBLE,
CONTROL_FILE_UPDATE_ONLY_LSN)))
if (unlikely(ma_control_file_write_and_force(lsn, last_logno,
max_trid_in_control_file)))
{
translog_unlock();
goto err;
......
......@@ -77,8 +77,9 @@ one should increment the control file version number.
#define CF_LSN_SIZE LSN_STORE_SIZE
#define CF_FILENO_OFFSET (CF_LSN_OFFSET + CF_LSN_SIZE)
#define CF_FILENO_SIZE 4
#define CF_CHANGEABLE_TOTAL_SIZE (CF_FILENO_OFFSET + CF_FILENO_SIZE)
#define CF_MAX_TRID_OFFSET (CF_FILENO_OFFSET + CF_FILENO_SIZE)
#define CF_MAX_TRID_SIZE TRANSID_SIZE
#define CF_CHANGEABLE_TOTAL_SIZE (CF_MAX_TRID_OFFSET + CF_MAX_TRID_SIZE)
/*
The following values should not be changed, except when changing version
......@@ -100,6 +101,11 @@ one should increment the control file version number.
*/
LSN last_checkpoint_lsn= LSN_IMPOSSIBLE;
uint32 last_logno= FILENO_IMPOSSIBLE;
/**
The maximum transaction id given to a transaction. It is only updated at
clean shutdown (in case of crash, logs have better information).
*/
TrID max_trid_in_control_file= 0;
/**
@brief If log's lock should be asserted when writing to control file.
......@@ -131,9 +137,6 @@ static CONTROL_FILE_ERROR create_control_file(const char *name,
uchar buffer[CF_CREATE_TIME_TOTAL_SIZE];
DBUG_ENTER("maria_create_control_file");
/* in a recovery, we expect to find a control file */
if (maria_in_recovery)
DBUG_RETURN(CONTROL_FILE_MISSING);
if ((control_file_fd= my_create(name, 0,
open_flags,
MYF(MY_SYNC_DIR | MY_WME))) < 0)
......@@ -164,7 +167,7 @@ static CONTROL_FILE_ERROR create_control_file(const char *name,
if (my_pwrite(control_file_fd, buffer, cf_create_time_size,
0, MYF(MY_FNABP | MY_WME)))
DBUG_RETURN(1);
DBUG_RETURN(CONTROL_FILE_UNKNOWN_ERROR);
/*
To be safer we should make sure that there are no logs or data/index
......@@ -184,10 +187,50 @@ static CONTROL_FILE_ERROR create_control_file(const char *name,
/* init the file with these "undefined" values */
DBUG_RETURN(ma_control_file_write_and_force(LSN_IMPOSSIBLE,
FILENO_IMPOSSIBLE,
CONTROL_FILE_UPDATE_ALL));
FILENO_IMPOSSIBLE, 0));
}
/**
Locks control file exclusively. This is kept for the duration of the engine
process, to prevent another Maria instance to write to our logs or control
file.
*/
static int lock_control_file(const char *name)
{
uint retry= 0;
/*
On Windows, my_lock() uses locking() which is mandatory locking and so
prevents maria-recovery.test from copying the control file. And in case of
crash, it may take a while for Windows to unlock file, causing downtime.
*/
/**
@todo BUG We should explore my_sopen(_SH_DENYWRD) to open or create the
file under Windows.
*/
#ifndef __WIN__
/*
We can't here use the automatic wait in my_lock() as the alarm thread
may not yet exists.
*/
while (my_lock(control_file_fd, F_WRLCK, 0L, F_TO_EOF,
MYF(MY_SEEK_NOT_DONE | MY_FORCE_LOCK | MY_NO_WAIT)))
{
if (retry == 0)
my_printf_error(HA_ERR_INITIALIZATION,
"Can't lock maria control file '%s' for exclusive use, "
"error: %d. Will retry for %d seconds", 0,
name, my_errno, MARIA_MAX_CONTROL_FILE_LOCK_RETRY);
if (retry++ > MARIA_MAX_CONTROL_FILE_LOCK_RETRY)
return 1;
sleep(1);
}
#endif
return 0;
}
/*
@brief Initialize control file subsystem
......@@ -200,24 +243,24 @@ static CONTROL_FILE_ERROR create_control_file(const char *name,
The format of the control file is defined in the comments and defines
at the start of this file.
@note If in recovery, file is not created
@param create_if_missing create file if not found
@return Operation status
@retval 0 OK
@retval 1 Error (in which case the file is left closed)
*/
CONTROL_FILE_ERROR ma_control_file_create_or_open()
CONTROL_FILE_ERROR ma_control_file_open(my_bool create_if_missing)
{
uchar buffer[CF_MAX_SIZE];
char name[FN_REFLEN], errmsg_buff[256];
const char *errmsg;
const char *errmsg, *lock_failed_errmsg= "Could not get an exclusive lock;"
" file is probably in use by another process";
uint new_cf_create_time_size, new_cf_changeable_size, new_block_size;
uint retry;
my_off_t file_size;
int open_flags= O_BINARY | /*O_DIRECT |*/ O_RDWR;
int error= CONTROL_FILE_UNKNOWN_ERROR;
DBUG_ENTER("ma_control_file_create_or_open");
DBUG_ENTER("ma_control_file_open");
/*
If you change sizes in the #defines, you at least have to change the
......@@ -236,12 +279,25 @@ CONTROL_FILE_ERROR ma_control_file_create_or_open()
if (my_access(name,F_OK))
{
if (create_control_file(name, open_flags))
CONTROL_FILE_ERROR create_error;
if (!create_if_missing)
{
error= CONTROL_FILE_MISSING;
errmsg= "Can't find file";
goto err;
}
if ((create_error= create_control_file(name, open_flags)))
{
error= create_error;
errmsg= "Can't create file";
goto err;
}
goto lock_file;
if (lock_control_file(name))
{
errmsg= lock_failed_errmsg;
goto err;
}
goto ok;
}
/* Otherwise, file exists */
......@@ -252,6 +308,12 @@ CONTROL_FILE_ERROR ma_control_file_create_or_open()
goto err;
}
if (lock_control_file(name)) /* lock it before reading content */
{
errmsg= lock_failed_errmsg;
goto err;
}
file_size= my_seek(control_file_fd, 0, SEEK_END, MYF(MY_WME));
if (file_size == MY_FILEPOS_ERROR)
{
......@@ -343,7 +405,7 @@ CONTROL_FILE_ERROR ma_control_file_create_or_open()
uint4korr(buffer + new_cf_create_time_size))
{
error= CONTROL_FILE_BAD_CHECKSUM;
errmsg= "Changeable part (end of control file) checksum missmatch";
errmsg= "Changeable part (end of control file) checksum mismatch";
goto err;
}
......@@ -353,57 +415,29 @@ CONTROL_FILE_ERROR ma_control_file_create_or_open()
last_checkpoint_lsn= lsn_korr(buffer + new_cf_create_time_size +
CF_LSN_OFFSET);
last_logno= uint4korr(buffer + new_cf_create_time_size + CF_FILENO_OFFSET);
if (new_cf_changeable_size >= (CF_MAX_TRID_OFFSET + CF_MAX_TRID_SIZE))
max_trid_in_control_file=
transid_korr(buffer + new_cf_create_time_size + CF_MAX_TRID_OFFSET);
lock_file:
retry= 0;
/*
On Windows, my_lock() uses locking() which is mandatory locking and so
prevents maria-recovery.test from copying the control file. And in case of
crash, it may take a while for Windows to unlock file, causing downtime.
*/
/**
@todo BUG We should explore my_sopen(_SH_DENYWRD) to open or create the
file under Windows.
*/
#ifndef __WIN__
/*
We can't here use the automatic wait in my_lock() as the alarm thread
may not yet exists.
*/
while (my_lock(control_file_fd, F_WRLCK, 0L, F_TO_EOF,
MYF(MY_SEEK_NOT_DONE | MY_FORCE_LOCK | MY_NO_WAIT)))
{
if (retry == 0)
my_printf_error(HA_ERR_INITIALIZATION,
"Can't lock maria control file '%s' for exclusive use, "
"error: %d. Will retry for %d seconds", 0,
name, my_errno, MARIA_MAX_CONTROL_FILE_LOCK_RETRY);
if (retry++ > MARIA_MAX_CONTROL_FILE_LOCK_RETRY)
{
errmsg= "Could not get an exclusive lock; file is probably in use by another process";
goto err;
}
sleep(1);
}
#endif
ok:
DBUG_RETURN(0);
err:
my_printf_error(HA_ERR_INITIALIZATION,
"Error when trying to use maria control file '%s': %s", 0,
name, errmsg);
ma_control_file_end();
ma_control_file_end(); /* will unlock file if needed */
DBUG_RETURN(error);
}
/*
Write information durably to the control file; stores this information into
the last_checkpoint_lsn and last_logno global variables.
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).
the last_checkpoint_lsn, last_logno, max_trid_in_control_file global
variables.
Called when we have created a new log (after syncing this log's creation),
when we have written a checkpoint (after syncing this log record), and at
shutdown (for storing trid in case logs are soon removed by user).
Variables last_checkpoint_lsn and last_logno must be protected by caller
using log's lock, unless this function is called at startup.
......@@ -411,13 +445,7 @@ CONTROL_FILE_ERROR ma_control_file_create_or_open()
ma_control_file_write_and_force()
checkpoint_lsn LSN of last checkpoint
logno last log file number
objs_to_write which of the arguments should be used as new values
(for example, CF_UPDATE_ONLY_LSN will not
write the logno argument to the control file and will
not update the last_logno global variable); can be:
CF_UPDATE_ALL
CF_UPDATE_ONLY_LSN
CF_UPDATE_ONLY_LOGNO.
trid maximum transaction longid.
NOTE
We always want to do one single my_pwrite() here to be as atomic as
......@@ -428,11 +456,10 @@ CONTROL_FILE_ERROR ma_control_file_create_or_open()
1 - Error
*/
int ma_control_file_write_and_force(const LSN checkpoint_lsn, uint32 logno,
uint objs_to_write)
int ma_control_file_write_and_force(LSN checkpoint_lsn, uint32 logno,
TrID trid)
{
char buffer[CF_MAX_SIZE];
my_bool update_checkpoint_lsn= FALSE, update_logno= FALSE;
uchar buffer[CF_MAX_SIZE];
uint32 sum;
DBUG_ENTER("ma_control_file_write_and_force");
......@@ -442,48 +469,38 @@ int ma_control_file_write_and_force(const LSN checkpoint_lsn, uint32 logno,
translog_lock_handler_assert_owner();
#endif
if (objs_to_write == CONTROL_FILE_UPDATE_ONLY_LSN)
update_checkpoint_lsn= TRUE;
else if (objs_to_write == CONTROL_FILE_UPDATE_ONLY_LOGNO)
update_logno= TRUE;
else if (objs_to_write == CONTROL_FILE_UPDATE_ALL)
update_checkpoint_lsn= update_logno= TRUE;
else /* incorrect value of objs_to_write */
DBUG_ASSERT(0);
if (update_checkpoint_lsn)
lsn_store(buffer + CF_LSN_OFFSET, checkpoint_lsn);
else /* store old value == change nothing */
lsn_store(buffer + CF_LSN_OFFSET, last_checkpoint_lsn);
if (update_logno)
int4store(buffer + CF_FILENO_OFFSET, logno);
else
int4store(buffer + CF_FILENO_OFFSET, last_logno);
transid_store(buffer + CF_MAX_TRID_OFFSET, trid);
/*
Clear unknown part of changeable part.
Clear unknown part of changeable part, if bigger than ours.
Other option would be to remember the original values in the file
and copy them here, but this should be safer.
*/
if (cf_changeable_size > CF_CHANGEABLE_TOTAL_SIZE)
bzero(buffer + CF_CHANGEABLE_TOTAL_SIZE,
cf_changeable_size - CF_CHANGEABLE_TOTAL_SIZE);
/* Checksum is stored first */
compile_time_assert(CF_CHECKSUM_OFFSET == 0);
sum= my_checksum(0, (const uchar *) buffer + CF_CHECKSUM_SIZE,
sum= my_checksum(0, buffer + CF_CHECKSUM_SIZE,
cf_changeable_size - CF_CHECKSUM_SIZE);
int4store(buffer, sum);
if (my_pwrite(control_file_fd, (uchar *) buffer, cf_changeable_size,
/**
@todo BUG by reusing the cf_changeable_size of the old control file (from
an old server), it does not write the new parts featured by the running
server (like max_trid), is it expected?
*/
if (my_pwrite(control_file_fd, buffer, cf_changeable_size,
cf_create_time_size, MYF(MY_FNABP | MY_WME)) ||
my_sync(control_file_fd, MYF(MY_WME)))
DBUG_RETURN(1);
if (update_checkpoint_lsn)
last_checkpoint_lsn= checkpoint_lsn;
if (update_logno)
last_logno= logno;
max_trid_in_control_file= trid;
DBUG_RETURN(0);
}
......@@ -496,7 +513,7 @@ int ma_control_file_write_and_force(const LSN checkpoint_lsn, uint32 logno,
ma_control_file_end()
*/
int ma_control_file_end()
int ma_control_file_end(void)
{
int close_error;
DBUG_ENTER("ma_control_file_end");
......@@ -521,8 +538,19 @@ int ma_control_file_end()
*/
last_checkpoint_lsn= LSN_IMPOSSIBLE;
last_logno= FILENO_IMPOSSIBLE;
max_trid_in_control_file= 0;
DBUG_RETURN(close_error);
}
/**
Tells if control file is initialized.
*/
my_bool ma_control_file_inited(void)
{
return (control_file_fd >= 0);
}
#endif /* EXTRACT_DEFINITIONS */
......@@ -42,6 +42,8 @@ extern LSN last_checkpoint_lsn;
*/
extern uint32 last_logno;
extern TrID max_trid_in_control_file;
extern my_bool maria_multi_threaded, maria_in_recovery;
typedef enum enum_control_file_error {
......@@ -58,33 +60,10 @@ typedef enum enum_control_file_error {
CONTROL_FILE_UNKNOWN_ERROR /* any other error */
} CONTROL_FILE_ERROR;
#define CONTROL_FILE_UPDATE_ALL 0
#define CONTROL_FILE_UPDATE_ONLY_LSN 1
#define CONTROL_FILE_UPDATE_ONLY_LOGNO 2
#ifdef __cplusplus
extern "C" {
#endif
/*
Looks for the control file. If none and creation was requested, creates file.
If present, reads it to find out last checkpoint's LSN and last log.
Called at engine's start.
*/
CONTROL_FILE_ERROR ma_control_file_create_or_open();
/*
Write information durably to the control file.
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).
*/
int ma_control_file_write_and_force(const LSN checkpoint_lsn, uint32 logno,
uint objs_to_write);
/* Free resources taken by control file subsystem */
int ma_control_file_end();
#ifdef __cplusplus
}
#endif
C_MODE_START
CONTROL_FILE_ERROR ma_control_file_open(my_bool create_if_missing);
int ma_control_file_write_and_force(LSN checkpoint_lsn, uint32 logno, TrID trid);
int ma_control_file_end(void);
my_bool ma_control_file_inited(void);
C_MODE_END
#endif
......@@ -52,9 +52,20 @@ void maria_end(void)
{
if (maria_inited)
{
TrID trid;
maria_inited= maria_multi_threaded= FALSE;
ft_free_stopwords();
ma_checkpoint_end();
if (ma_control_file_inited() &&
((trid= trnman_get_max_trid()) > max_trid_in_control_file))
{
/*
Store max transaction id into control file, in case logs are removed
by user, or maria_chk wants to check tables (it cannot access max trid
from the log, as it cannot process REDOs).
*/
ma_control_file_write_and_force(last_checkpoint_lsn, last_logno, trid);
}
trnman_destroy();
if (translog_status == TRANSLOG_OK)
translog_destroy();
......
......@@ -1519,8 +1519,8 @@ static my_bool translog_create_new_file()
if (translog_write_file_header())
DBUG_RETURN(1);
if (ma_control_file_write_and_force(LSN_IMPOSSIBLE, file_no,
CONTROL_FILE_UPDATE_ONLY_LOGNO))
if (ma_control_file_write_and_force(last_checkpoint_lsn, file_no,
max_trid_in_control_file))
{
translog_stop_writing();
DBUG_RETURN(1);
......@@ -3697,7 +3697,7 @@ my_bool translog_init_with_table(const char *directory,
log_descriptor.open_files.elements);
if (ma_control_file_write_and_force(checkpoint_lsn, start_file_num,
CONTROL_FILE_UPDATE_ALL))
max_trid_in_control_file))
DBUG_RETURN(1);
/* assign buffer 0 */
translog_start_buffer(log_descriptor.buffers, &log_descriptor.bc, 0);
......
......@@ -2509,6 +2509,14 @@ static uint end_of_redo_phase(my_bool prepare_for_undo_phase)
llstr(max_long_trid, llbuf);
tprint(tracef, "Maximum transaction long id seen: %s\n", llbuf);
llstr(max_trid_in_control_file, llbuf);
tprint(tracef, "Maximum transaction long id seen in control file: %s\n",
llbuf);
/*
If logs were deleted, or lost, trid in control file is needed to set
trnman's generator:
*/
set_if_bigger(max_long_trid, max_trid_in_control_file);
if (prepare_for_undo_phase && trnman_init(max_long_trid))
return -1;
......
......@@ -77,7 +77,7 @@ int main(int argc,char *argv[])
if (maria_init() ||
(init_pagecache(maria_pagecache, maria_block_size * 16, 0, 0,
maria_block_size, MY_WME) == 0) ||
ma_control_file_create_or_open() ||
ma_control_file_open(TRUE) ||
(init_pagecache(maria_log_pagecache,
TRANSLOG_PAGECACHE_SIZE, 0, 0,
TRANSLOG_PAGE_SIZE, MY_WME) == 0) ||
......
......@@ -83,7 +83,7 @@ int main(int argc, char *argv[])
if (maria_init() ||
(init_pagecache(maria_pagecache, pagecache_size, 0, 0,
maria_block_size, MY_WME) == 0) ||
ma_control_file_create_or_open() ||
ma_control_file_open(TRUE) ||
(init_pagecache(maria_log_pagecache,
TRANSLOG_PAGECACHE_SIZE, 0, 0,
TRANSLOG_PAGE_SIZE, MY_WME) == 0) ||
......
......@@ -37,11 +37,11 @@ SET_STACK_SIZE(9000) /* Minimum stack size for program */
static uint decode_bits;
static char **default_argv;
static const char *load_default_groups[]= { "maria_chk", 0 };
static const char *set_collation_name, *opt_tmpdir;
static const char *set_collation_name, *opt_tmpdir, *opt_log_dir;
static CHARSET_INFO *set_collation;
static int stopwords_inited= 0;
static MY_TMPDIR maria_chk_tmpdir;
static my_bool opt_transaction_logging, opt_debug;
static my_bool opt_transaction_logging, opt_debug, opt_require_control_file;
static const char *type_names[]=
{
......@@ -97,7 +97,7 @@ int main(int argc, char **argv)
int error;
MY_INIT(argv[0]);
maria_data_root= (char *)".";
opt_log_dir= maria_data_root= (char *)".";
maria_chk_init(&check_param);
check_param.opt_lock_memory= 1; /* Lock memory if possible */
check_param.using_global_keycache = 0;
......@@ -110,20 +110,30 @@ int main(int argc, char **argv)
If we are doing a repair, user may want to store this repair into the log
so that the log has a complete history and can be used to replay.
*/
if (opt_transaction_logging && (check_param.testflag & T_REP_ANY) &&
(ma_control_file_create_or_open() ||
if (opt_transaction_logging && (check_param.testflag & T_REP_ANY))
{
if (ma_control_file_open(FALSE) ||
init_pagecache(maria_log_pagecache,
TRANSLOG_PAGECACHE_SIZE, 0, 0,
TRANSLOG_PAGE_SIZE, MY_WME) == 0 ||
translog_init(maria_data_root, TRANSLOG_FILE_SIZE,
translog_init(opt_log_dir, TRANSLOG_FILE_SIZE,
0, 0, maria_log_pagecache,
TRANSLOG_DEFAULT_FLAGS, 0)))
TRANSLOG_DEFAULT_FLAGS, 0))
{
_ma_check_print_error(&check_param,
"Can't initialize transaction logging. Run "
"recovery with switch --skip-transaction-log");
error= 1;
argc= 1; /* Force loop out */
goto end;
}
}
else
{
if (ma_control_file_open(FALSE) && opt_require_control_file)
{
error= 1;
goto end;
}
}
while (--argc >= 0)
......@@ -156,6 +166,7 @@ int main(int argc, char **argv)
VOID(fflush(stdout));
}
}
end:
if (check_param.total_files > 1)
{ /* Only if descript */
char buff[22],buff2[22];
......@@ -183,7 +194,8 @@ enum options_mc {
OPT_SORT_KEY_BLOCKS, OPT_DECODE_BITS, OPT_FT_MIN_WORD_LEN,
OPT_FT_MAX_WORD_LEN, OPT_FT_STOPWORD_FILE,
OPT_MAX_RECORD_LENGTH, OPT_AUTO_CLOSE, OPT_STATS_METHOD, OPT_TRANSACTION_LOG,
OPT_SKIP_SAFEMALLOC, OPT_ZEROFILL_KEEP_LSN
OPT_SKIP_SAFEMALLOC, OPT_ZEROFILL_KEEP_LSN, OPT_REQUIRE_CONTROL_FILE,
OPT_LOG_DIR, OPT_DATADIR
};
static struct my_option my_long_options[] =
......@@ -249,6 +261,13 @@ static struct my_option my_long_options[] =
(uchar**) &check_param.keys_in_use,
(uchar**) &check_param.keys_in_use,
0, GET_ULL, REQUIRED_ARG, -1, 0, 0, 0, 0, 0},
{"datadir", OPT_DATADIR,
"Path for control file (and logs if --log-dir not used).",
(uchar**) &maria_data_root, 0, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
{"log-dir", OPT_LOG_DIR,
"Path for log files.",
(uchar**) &opt_log_dir, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"max-record-length", OPT_MAX_RECORD_LENGTH,
"Skip rows bigger than this if maria_chk can't allocate memory to hold it",
(uchar**) &check_param.max_record_length,
......@@ -274,6 +293,10 @@ static struct my_option my_long_options[] =
{"sort-recover", 'n',
"Force recovering with sorting even if the temporary file was very big.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{ "require-control-file", OPT_REQUIRE_CONTROL_FILE,
"Abort if cannot find control file",
(uchar**)&opt_require_control_file, 0, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
#ifdef DEBUG
{"start-check-pos", OPT_START_CHECK_POS,
"No help available.",
......
......@@ -56,7 +56,7 @@ int main(int argc, char **argv)
goto err;
}
/* we don't want to create a control file, it MUST exist */
if (ma_control_file_create_or_open())
if (ma_control_file_open(FALSE))
{
fprintf(stderr, "Can't open control file (%d)\n", errno);
goto err;
......
......@@ -745,3 +745,18 @@ TRN *trnman_get_any_trn()
TRN *trn= active_list_min.next;
return (trn != &active_list_max) ? trn : NULL;
}
/**
Returns maximum transaction id given to a transaction so far.
*/
TrID trnman_get_max_trid()
{
TrID id;
if (short_trid_to_active_trn == NULL)
return 0;
pthread_mutex_lock(&LOCK_trn_list);
id= global_trid_generator;
pthread_mutex_unlock(&LOCK_trn_list);
return id;
}
......@@ -54,7 +54,8 @@ uint trnman_decrement_locked_tables(TRN *trn);
uint trnman_has_locked_tables(TRN *trn);
void trnman_reset_locked_tables(TRN *trn, uint locked_tables);
TRN *trnman_recreate_trn_from_recovery(uint16 shortid, TrID longid);
TRN *trnman_get_any_trn();
TRN *trnman_get_any_trn(void);
TrID trnman_get_max_trid(void);
#define TRANSID_SIZE 6
#define transid_store(dst, id) int6store(dst,id)
#define transid_korr(P) uint6korr(P)
......
......@@ -44,34 +44,37 @@ char file_name[FN_REFLEN];
/* The values we'll set and expect the control file module to return */
LSN expect_checkpoint_lsn;
uint32 expect_logno;
TrID expect_max_trid;
static int delete_file(myf my_flags);
/*
Those are test-specific wrappers around the module's API functions: after
calling the module's API functions they perform checks on the result.
*/
static int close_file(); /* wraps ma_control_file_end */
static int create_or_open_file(); /* wraps ma_control_file_open_or_create */
static int write_file(); /* wraps ma_control_file_write_and_force */
static int close_file(void); /* wraps ma_control_file_end */
/* wraps ma_control_file_open_or_create */
static int open_file(void);
/* wraps ma_control_file_write_and_force */
static int write_file(LSN checkpoint_lsn, uint32 logno, TrID trid);
/* Tests */
static int test_one_log();
static int test_five_logs();
static int test_3_checkpoints_and_2_logs();
static int test_binary_content();
static int test_start_stop();
static int test_2_open_and_2_close();
static int test_bad_magic_string();
static int test_bad_checksum();
static int test_bad_hchecksum();
static int test_future_size();
static int test_bad_blocksize();
static int test_bad_size();
static int test_one_log(void);
static int test_five_logs_and_max_trid(void);
static int test_3_checkpoints_and_2_logs(void);
static int test_binary_content(void);
static int test_start_stop(void);
static int test_2_open_and_2_close(void);
static int test_bad_magic_string(void);
static int test_bad_checksum(void);
static int test_bad_hchecksum(void);
static int test_future_size(void);
static int test_bad_blocksize(void);
static int test_bad_size(void);
/* Utility */
static int verify_module_values_match_expected();
static int verify_module_values_are_impossible();
static void usage();
static int verify_module_values_match_expected(void);
static int verify_module_values_are_impossible(void);
static void usage(void);
static void get_options(int argc, char *argv[]);
/*
......@@ -83,10 +86,10 @@ static void get_options(int argc, char *argv[]);
*/
#define RET_ERR_UNLESS(expr) \
{if (!(expr)) {diag("line %d: failure: '%s'", __LINE__, #expr); return 1;}}
{if (!(expr)) {diag("line %d: failure: '%s'", __LINE__, #expr); assert(0);return 1;}}
/* Used to ignore error messages from ma_control_file_create_or_open */
/* Used to ignore error messages from ma_control_file_open() */
static int my_ignore_message(uint error __attribute__((unused)),
const char *str __attribute__((unused)),
......@@ -101,13 +104,13 @@ int (*default_error_handler_hook)(uint my_err, const char *str,
myf MyFlags) = 0;
/* like ma_control_file_create_or_open(), but without error messages */
/* like ma_control_file_open(), but without error messages */
static CONTROL_FILE_ERROR local_ma_control_file_create_or_open(void)
static CONTROL_FILE_ERROR local_ma_control_file_open(void)
{
CONTROL_FILE_ERROR error;
error_handler_hook= my_ignore_message;
error= ma_control_file_create_or_open();
error= ma_control_file_open(TRUE);
error_handler_hook= default_error_handler_hook;
return error;
}
......@@ -133,7 +136,8 @@ int main(int argc,char *argv[])
diag("Tests of normal conditions");
ok(0 == test_one_log(), "test of creating one log");
ok(0 == test_five_logs(), "test of creating five logs");
ok(0 == test_five_logs_and_max_trid(),
"test of creating five logs and many transactions");
ok(0 == test_3_checkpoints_and_2_logs(),
"test of creating three checkpoints and two logs");
ok(0 == test_binary_content(), "test of the binary content of the file");
......@@ -163,19 +167,20 @@ static int delete_file(myf my_flags)
my_delete(file_name, my_flags);
expect_checkpoint_lsn= LSN_IMPOSSIBLE;
expect_logno= FILENO_IMPOSSIBLE;
expect_max_trid= 0;
return 0;
}
/*
Verifies that global values last_checkpoint_lsn and last_logno (belonging
to the module) match what we expect.
Verifies that global values last_checkpoint_lsn, last_logno,
max_trid_in_control_file (belonging to the module) match what we expect.
*/
static int verify_module_values_match_expected()
static int verify_module_values_match_expected(void)
{
RET_ERR_UNLESS(last_logno == expect_logno);
RET_ERR_UNLESS(last_checkpoint_lsn ==
expect_checkpoint_lsn);
RET_ERR_UNLESS(last_checkpoint_lsn == expect_checkpoint_lsn);
RET_ERR_UNLESS(max_trid_in_control_file == expect_max_trid);
return 0;
}
......@@ -184,16 +189,16 @@ static int verify_module_values_match_expected()
Verifies that global values last_checkpoint_lsn and last_logno (belonging
to the module) are impossible (this is used when the file has been closed).
*/
static int verify_module_values_are_impossible()
static int verify_module_values_are_impossible(void)
{
RET_ERR_UNLESS(last_logno == FILENO_IMPOSSIBLE);
RET_ERR_UNLESS(last_checkpoint_lsn ==
LSN_IMPOSSIBLE);
RET_ERR_UNLESS(last_checkpoint_lsn == LSN_IMPOSSIBLE);
RET_ERR_UNLESS(max_trid_in_control_file == 0);
return 0;
}
static int close_file()
static int close_file(void)
{
/* Simulate shutdown */
ma_control_file_end();
......@@ -202,94 +207,81 @@ static int close_file()
return 0;
}
static int create_or_open_file()
static int open_file(void)
{
RET_ERR_UNLESS(local_ma_control_file_create_or_open() == CONTROL_FILE_OK);
RET_ERR_UNLESS(local_ma_control_file_open() == CONTROL_FILE_OK);
/* Check that the module reports expected information */
RET_ERR_UNLESS(verify_module_values_match_expected() == 0);
return 0;
}
static int write_file(const LSN checkpoint_lsn,
uint32 logno,
uint objs_to_write)
static int write_file(LSN checkpoint_lsn, uint32 logno, TrID trid)
{
RET_ERR_UNLESS(ma_control_file_write_and_force(checkpoint_lsn, logno,
objs_to_write) == 0);
RET_ERR_UNLESS(ma_control_file_write_and_force(checkpoint_lsn, logno, trid)
== 0);
/* Check that the module reports expected information */
RET_ERR_UNLESS(verify_module_values_match_expected() == 0);
return 0;
}
static int test_one_log()
static int test_one_log(void)
{
uint objs_to_write;
RET_ERR_UNLESS(create_or_open_file() == CONTROL_FILE_OK);
objs_to_write= CONTROL_FILE_UPDATE_ONLY_LOGNO;
RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
expect_logno= 123;
RET_ERR_UNLESS(write_file(LSN_IMPOSSIBLE,
expect_logno,
objs_to_write) == 0);
RET_ERR_UNLESS(write_file(last_checkpoint_lsn, expect_logno,
max_trid_in_control_file) == 0);
RET_ERR_UNLESS(close_file() == 0);
return 0;
}
static int test_five_logs()
static int test_five_logs_and_max_trid(void)
{
uint objs_to_write;
uint i;
RET_ERR_UNLESS(create_or_open_file() == CONTROL_FILE_OK);
objs_to_write= CONTROL_FILE_UPDATE_ONLY_LOGNO;
RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
expect_logno= 100;
expect_max_trid= ULL(14111978111);
for (i= 0; i<5; i++)
{
expect_logno*= 3;
RET_ERR_UNLESS(write_file(LSN_IMPOSSIBLE, expect_logno,
objs_to_write) == 0);
RET_ERR_UNLESS(write_file(last_checkpoint_lsn, expect_logno,
expect_max_trid) == 0);
}
RET_ERR_UNLESS(close_file() == 0);
return 0;
}
static int test_3_checkpoints_and_2_logs()
static int test_3_checkpoints_and_2_logs(void)
{
uint objs_to_write;
/*
Simulate one checkpoint, one log creation, two checkpoints, one
log creation.
*/
RET_ERR_UNLESS(create_or_open_file() == CONTROL_FILE_OK);
objs_to_write= CONTROL_FILE_UPDATE_ONLY_LSN;
RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
expect_checkpoint_lsn= MAKE_LSN(5, 10000);
RET_ERR_UNLESS(write_file(expect_checkpoint_lsn,
expect_logno, objs_to_write) == 0);
RET_ERR_UNLESS(write_file(expect_checkpoint_lsn, expect_logno,
max_trid_in_control_file) == 0);
objs_to_write= CONTROL_FILE_UPDATE_ONLY_LOGNO;
expect_logno= 17;
RET_ERR_UNLESS(write_file(expect_checkpoint_lsn,
expect_logno, objs_to_write) == 0);
RET_ERR_UNLESS(write_file(expect_checkpoint_lsn, expect_logno,
max_trid_in_control_file) == 0);
objs_to_write= CONTROL_FILE_UPDATE_ONLY_LSN;
expect_checkpoint_lsn= MAKE_LSN(17, 20000);
RET_ERR_UNLESS(write_file(expect_checkpoint_lsn,
expect_logno, objs_to_write) == 0);
RET_ERR_UNLESS(write_file(expect_checkpoint_lsn, expect_logno,
max_trid_in_control_file) == 0);
objs_to_write= CONTROL_FILE_UPDATE_ONLY_LSN;
expect_checkpoint_lsn= MAKE_LSN(17, 45000);
RET_ERR_UNLESS(write_file(expect_checkpoint_lsn,
expect_logno, objs_to_write) == 0);
RET_ERR_UNLESS(write_file(expect_checkpoint_lsn, expect_logno,
max_trid_in_control_file) == 0);
objs_to_write= CONTROL_FILE_UPDATE_ONLY_LOGNO;
expect_logno= 19;
RET_ERR_UNLESS(write_file(expect_checkpoint_lsn,
expect_logno, objs_to_write) == 0);
RET_ERR_UNLESS(write_file(expect_checkpoint_lsn, expect_logno,
max_trid_in_control_file) == 0);
RET_ERR_UNLESS(close_file() == 0);
return 0;
}
static int test_binary_content()
static int test_binary_content(void)
{
uint i;
int fd;
......@@ -310,7 +302,7 @@ static int test_binary_content()
MYF(MY_WME))) >= 0);
RET_ERR_UNLESS(my_read(fd, buffer, 45, MYF(MY_FNABP | MY_WME)) == 0);
RET_ERR_UNLESS(my_close(fd, MYF(MY_WME)) == 0);
RET_ERR_UNLESS(create_or_open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
i= uint3korr(buffer + 34 );
RET_ERR_UNLESS(i == LSN_FILE_NO(last_checkpoint_lsn));
i= uint4korr(buffer + 37);
......@@ -321,35 +313,35 @@ static int test_binary_content()
return 0;
}
static int test_start_stop()
static int test_start_stop(void)
{
/* TEST5: Simulate start/nothing/stop/start/nothing/stop/start */
RET_ERR_UNLESS(create_or_open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(close_file() == 0);
RET_ERR_UNLESS(create_or_open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(close_file() == 0);
RET_ERR_UNLESS(create_or_open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(close_file() == 0);
return 0;
}
static int test_2_open_and_2_close()
static int test_2_open_and_2_close(void)
{
RET_ERR_UNLESS(create_or_open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(create_or_open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(close_file() == 0);
RET_ERR_UNLESS(close_file() == 0);
return 0;
}
static int test_bad_magic_string()
static int test_bad_magic_string(void)
{
uchar buffer[4];
int fd;
RET_ERR_UNLESS(create_or_open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(close_file() == 0);
/* Corrupt magic string */
......@@ -361,22 +353,22 @@ static int test_bad_magic_string()
MYF(MY_FNABP | MY_WME)) == 0);
/* Check that control file module sees the problem */
RET_ERR_UNLESS(local_ma_control_file_create_or_open() ==
RET_ERR_UNLESS(local_ma_control_file_open() ==
CONTROL_FILE_BAD_MAGIC_STRING);
/* Restore magic string */
RET_ERR_UNLESS(my_pwrite(fd, buffer, 4, 0, MYF(MY_FNABP | MY_WME)) == 0);
RET_ERR_UNLESS(my_close(fd, MYF(MY_WME)) == 0);
RET_ERR_UNLESS(create_or_open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(close_file() == 0);
return 0;
}
static int test_bad_checksum()
static int test_bad_checksum(void)
{
uchar buffer[4];
int fd;
RET_ERR_UNLESS(create_or_open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(close_file() == 0);
/* Corrupt checksum */
......@@ -387,7 +379,7 @@ static int test_bad_checksum()
buffer[0]+= 3; /* mangle checksum */
RET_ERR_UNLESS(my_pwrite(fd, buffer, 1, 30, MYF(MY_FNABP | MY_WME)) == 0);
/* Check that control file module sees the problem */
RET_ERR_UNLESS(local_ma_control_file_create_or_open() ==
RET_ERR_UNLESS(local_ma_control_file_open() ==
CONTROL_FILE_BAD_CHECKSUM);
/* Restore checksum */
buffer[0]-= 3;
......@@ -398,22 +390,22 @@ static int test_bad_checksum()
}
static int test_bad_blocksize()
static int test_bad_blocksize(void)
{
maria_block_size<<= 1;
/* Check that control file module sees the problem */
RET_ERR_UNLESS(local_ma_control_file_create_or_open() ==
RET_ERR_UNLESS(local_ma_control_file_open() ==
CONTROL_FILE_WRONG_BLOCKSIZE);
/* Restore blocksize */
maria_block_size>>= 1;
RET_ERR_UNLESS(create_or_open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(close_file() == 0);
return 0;
}
static int test_future_size()
static int test_future_size(void)
{
/*
Here we check ability to add fields only so we can use
......@@ -455,18 +447,18 @@ static int test_future_size()
CF_CHANGEABLE_TOTAL_SIZE + 2,
0, MYF(MY_FNABP | MY_WME)) == 0);
RET_ERR_UNLESS(my_close(fd, MYF(MY_WME)) == 0);
RET_ERR_UNLESS(create_or_open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(close_file() == 0);
return(0);
}
static int test_bad_hchecksum()
static int test_bad_hchecksum(void)
{
uchar buffer[4];
int fd;
RET_ERR_UNLESS(create_or_open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(close_file() == 0);
/* Corrupt checksum */
......@@ -477,7 +469,7 @@ static int test_bad_hchecksum()
buffer[0]+= 3; /* mangle checksum */
RET_ERR_UNLESS(my_pwrite(fd, buffer, 1, 26, MYF(MY_FNABP | MY_WME)) == 0);
/* Check that control file module sees the problem */
RET_ERR_UNLESS(local_ma_control_file_create_or_open() ==
RET_ERR_UNLESS(local_ma_control_file_open() ==
CONTROL_FILE_BAD_HEAD_CHECKSUM);
/* Restore checksum */
buffer[0]-= 3;
......@@ -488,7 +480,7 @@ static int test_bad_hchecksum()
}
static int test_bad_size()
static int test_bad_size(void)
{
uchar buffer[]=
"123456789012345678901234567890123456789012345678901234567890123456";
......@@ -501,20 +493,20 @@ static int test_bad_size()
MYF(MY_WME))) >= 0);
RET_ERR_UNLESS(my_write(fd, buffer, 10, MYF(MY_FNABP | MY_WME)) == 0);
/* Check that control file module sees the problem */
RET_ERR_UNLESS(local_ma_control_file_create_or_open() ==
RET_ERR_UNLESS(local_ma_control_file_open() ==
CONTROL_FILE_TOO_SMALL);
for (i= 0; i < 8; i++)
{
RET_ERR_UNLESS(my_write(fd, buffer, 66, MYF(MY_FNABP | MY_WME)) == 0);
}
/* Check that control file module sees the problem */
RET_ERR_UNLESS(local_ma_control_file_create_or_open() ==
RET_ERR_UNLESS(local_ma_control_file_open() ==
CONTROL_FILE_TOO_BIG);
RET_ERR_UNLESS(my_close(fd, MYF(MY_WME)) == 0);
/* Leave a correct control file */
RET_ERR_UNLESS(delete_file(MYF(MY_WME)) == 0);
RET_ERR_UNLESS(create_or_open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(open_file() == CONTROL_FILE_OK);
RET_ERR_UNLESS(close_file() == 0);
return 0;
......@@ -535,7 +527,7 @@ static struct my_option my_long_options[] =
};
static void version()
static void version(void)
{
printf("ma_control_file_test: unit test for the control file "
"module of the Maria storage engine. Ver 1.0 \n");
......@@ -575,7 +567,7 @@ static void get_options(int argc, char *argv[])
} /* get options */
static void usage()
static void usage(void)
{
printf("Usage: %s [options]\n\n", my_progname);
my_print_help(my_long_options);
......
......@@ -196,7 +196,7 @@ int main(int argc __attribute__((unused)), char *argv[])
}
#endif
if (ma_control_file_create_or_open(TRUE))
if (ma_control_file_open(TRUE))
{
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
......
......@@ -67,7 +67,7 @@ int main(int argc __attribute__((unused)), char *argv[])
}
#endif
if (ma_control_file_create_or_open(TRUE))
if (ma_control_file_open(TRUE))
{
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
......
......@@ -64,7 +64,7 @@ int main(int argc __attribute__((unused)), char *argv[])
}
#endif
if (ma_control_file_create_or_open(TRUE))
if (ma_control_file_open(TRUE))
{
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
......
......@@ -184,7 +184,7 @@ int main(int argc __attribute__((unused)), char *argv[])
}
#endif
if (ma_control_file_create_or_open(TRUE))
if (ma_control_file_open(TRUE))
{
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
......@@ -348,7 +348,7 @@ int main(int argc __attribute__((unused)), char *argv[])
end_pagecache(&pagecache, 1);
ma_control_file_end();
if (ma_control_file_create_or_open(TRUE))
if (ma_control_file_open(TRUE))
{
fprintf(stderr, "pass2: Can't init control file (%d)\n", errno);
exit(1);
......
......@@ -283,7 +283,7 @@ int main(int argc __attribute__((unused)),
my_thread_global_init();
if (ma_control_file_create_or_open(TRUE))
if (ma_control_file_open(TRUE))
{
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
......
......@@ -70,7 +70,7 @@ int main(int argc __attribute__((unused)), char *argv[])
}
#endif
if (ma_control_file_create_or_open(TRUE))
if (ma_control_file_open(TRUE))
{
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
......
......@@ -67,7 +67,7 @@ int main(int argc __attribute__((unused)), char *argv[])
}
#endif
if (ma_control_file_create_or_open(TRUE))
if (ma_control_file_open(TRUE))
{
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
......@@ -140,7 +140,7 @@ int main(int argc __attribute__((unused)), char *argv[])
}
}
if (ma_control_file_create_or_open(TRUE))
if (ma_control_file_open(TRUE))
{
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
......
......@@ -95,7 +95,7 @@ int main(int argc __attribute__((unused)), char *argv[])
}
#endif
if (ma_control_file_create_or_open(TRUE))
if (ma_control_file_open(TRUE))
{
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
......
......@@ -67,7 +67,7 @@ int main(int argc __attribute__((unused)), char *argv[])
}
#endif
if (ma_control_file_create_or_open(TRUE))
if (ma_control_file_open(TRUE))
{
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
......
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