#At file:///G:/bzr/bug39194/
2814 Vladislav Vaintroub 2008-09-10
Bug#39089: Invalid check for serial_log_directory.
Falcon throws exception telling serial log directory is invalid
and refuses to initialize. An attempt was already made to fix
this error in the past, and even this attempt did not work in
all cases (root directory on Windows like C: would not work for example)
Solution presented here is rather simple - we do not check for valid
directory at all. If serial log file cannot be opened or created during
database creation, the server does not start anyway.
We should not also try to create database if serial log cannot be opened.
(there will be no loss of data, since we do not overwrite existing files,
but error message coming from create database is misleading).
Hence, this patch also contains fix to trigger database creation only
if falcon_master.fts cannot be opened - trying to create database
otherwise makes no sense and in presence of master tablespace going to
fail anyway.
modified:
storage/falcon/Configuration.cpp
storage/falcon/Database.cpp
storage/falcon/IO.cpp
storage/falcon/IOx.h
storage/falcon/SQLException.h
storage/falcon/StorageHandler.cpp
per-file messages:
storage/falcon/Configuration.cpp
Remove existence check for falcon_serial_log_dir. If it is non-existent, open/create
for serial log files will fail anyway and falcon will not start.
storage/falcon/Database.cpp
Throw OPEN_MASTER_ERROR if falcon_master.fts cannot be opened
storage/falcon/IO.cpp
Remove IO::isDirectory (no used anymore)
storage/falcon/IOx.h
Remove IO::isDirectory(obsolete, not used anymore)
storage/falcon/StorageHandler.cpp
=== modified file 'storage/falcon/Configuration.cpp'
--- a/storage/falcon/Configuration.cpp 2008-08-29 20:41:13 +0000
+++ b/storage/falcon/Configuration.cpp 2008-09-10 16:37:47 +0000
@@ -130,33 +130,7 @@ Configuration::Configuration(const char
if (falcon_serial_log_dir)
{
- char fullLogPath[PATH_MAX];
- const char *baseName;
-
- // Fully qualify the serial log path using a dummy file name
-
- JString tempLogDir(falcon_serial_log_dir);
- tempLogDir += "/test.fl1";
- IO io;
- io.expandFileName(tempLogDir, sizeof(fullLogPath), fullLogPath, &baseName);
-
- // Set the path, remove the file name
-
- serialLogDir = JString(fullLogPath, (int)(baseName - fullLogPath));
-
- // Verify that the directory exists
-
- if (!io.isDirectory(serialLogDir.getString()))
- {
- fprintf(stderr,
- "Falcon: The specified serial log directory, \"%s\", "
- "does not exist.\n"
- "Falcon: The serial log directory must be created by "
- "the user before initializing Falcon.\n",
- falcon_serial_log_dir
- );
- throw SQLEXCEPTION (FILE_ACCESS_ERROR, "Invalid serial log directory path \"%s\"", falcon_serial_log_dir);
- }
+ serialLogDir = falcon_serial_log_dir;
}
#else
recordMemoryMax = getMemorySize(RECORD_MEMORY_UPPER);
=== modified file 'storage/falcon/Database.cpp'
--- a/storage/falcon/Database.cpp 2008-09-05 16:26:12 +0000
+++ b/storage/falcon/Database.cpp 2008-09-10 16:37:47 +0000
@@ -691,7 +691,18 @@ void Database::createDatabase(const char
void Database::openDatabase(const char * filename)
{
- cache = dbb->open (filename, configuration->pageCacheSize, 0);
+ try
+ {
+ cache = dbb->open (filename, configuration->pageCacheSize, 0);
+ }
+ catch(SQLException& e)
+ {
+ // Master cannot be opened - throw OPEN_MASTER error to initiate
+ // create database. Don't do it if file exists, but there is a problem
+ // with permissions and/or locking.
+ if(e.getSqlcode() != FILE_ACCESS_ERROR)
+ throw SQLError(OPEN_MASTER_ERROR, e.getText());
+ }
start();
if ( dbb->logRoot.IsEmpty()
=== modified file 'storage/falcon/IO.cpp'
--- a/storage/falcon/IO.cpp 2008-09-06 05:14:38 +0000
+++ b/storage/falcon/IO.cpp 2008-09-10 16:37:47 +0000
@@ -517,43 +517,6 @@ bool IO::doesFileExist(const char *fileN
return fileStat(fileName, &stats, &errnum) == 0;
}
-bool IO::isDirectory(const char *path)
-{
- struct stat buf;
- char tmpPath[PATH_MAX+1];
-
-#ifdef _WIN32
- strncpy(tmpPath, path, MIN(PATH_MAX, (int)strlen(path)+1));
- tmpPath[PATH_MAX] = '\0';
- char *last = tmpPath + strlen(tmpPath) - 1;
-
- // Win32 stat() fails for paths with a terminating backslash
- // If this is a non-empty string, then zap the trailing backslash
-
- if (last > tmpPath)
- {
- if (*last == '\\')
- *last = '\0';
-
- if (!stat(tmpPath, &buf))
- return ((buf.st_mode & S_IFDIR) != 0);
- }
-
- return false;
-#else
- const char *resolvedPath;
- resolvedPath = realpath (path, tmpPath);
-
- if (!resolvedPath)
- return false;
-
- if (stat(resolvedPath, &buf))
- return false;
-
- return S_ISDIR (buf.st_mode);
-#endif
-}
-
int IO::fileStat(const char *fileName, struct stat *fileStats, int *errnum)
{
struct stat stats;
=== modified file 'storage/falcon/IOx.h'
--- a/storage/falcon/IOx.h 2008-09-05 22:36:19 +0000
+++ b/storage/falcon/IOx.h 2008-09-10 16:37:47 +0000
@@ -55,7 +55,6 @@ public:
int read(int length, UCHAR *buffer);
void write(uint32 length, const UCHAR *data);
static bool doesFileExist(const char *fileName);
- static bool isDirectory(const char *path);
static int fileStat(const char *fileName, struct stat *stats = NULL, int *errnum = NULL);
void declareFatalError();
void seek (int pageNumber);
=== modified file 'storage/falcon/SQLException.h'
--- a/storage/falcon/SQLException.h 2008-09-04 10:49:57 +0000
+++ b/storage/falcon/SQLException.h 2008-09-10 16:37:47 +0000
@@ -70,7 +70,8 @@ enum SqlCode {
DEVICE_FULL = -36,
FILE_ACCESS_ERROR = -37,
TABLESPACE_DATAFILE_EXIST_ERROR = -38,
- RECOVERY_ERROR = -39
+ RECOVERY_ERROR = -39,
+ OPEN_MASTER_ERROR = -40
};
class DllExport SQLException {
=== modified file 'storage/falcon/StorageHandler.cpp'
--- a/storage/falcon/StorageHandler.cpp 2008-09-05 22:36:19 +0000
+++ b/storage/falcon/StorageHandler.cpp 2008-09-10 16:37:47 +0000
@@ -1003,8 +1003,7 @@ void StorageHandler::initialize(void)
// If got one of following errors, just rethrow. No point in
// trying to create database.
- if (err == OUT_OF_MEMORY_ERROR || err == FILE_ACCESS_ERROR ||
- err == VERSION_ERROR || err == RECOVERY_ERROR)
+ if (err != OPEN_MASTER_ERROR)
throw;
try