Skip to content

Commit

Permalink
Fixed CORE-4475: attempt to create lock files directory fails during …
Browse files Browse the repository at this point in the history
…cleanup
  • Loading branch information
AlexPeshkoff committed Jun 30, 2014
1 parent 8e94a32 commit f1e3ba6
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 57 deletions.
60 changes: 60 additions & 0 deletions src/common/isc.cpp
Expand Up @@ -46,6 +46,8 @@
#include "../yvalve/gds_proto.h"
#include "../common/isc_proto.h"
#include "../jrd/jrd_proto.h"
#include "../common/os/os_utils.h"
#include "../common/os/path_utils.h"

#include "../common/classes/init.h"

Expand Down Expand Up @@ -598,3 +600,61 @@ void iscLogException(const char* text, const Firebird::Exception& e)
iscLogStatus(text, s);
}


void iscPrefixLock(TEXT* string, const TEXT* root, bool createLockDir)
{
/**************************************
*
* i s c P r e f i x L o c k
*
**************************************
*
* Functional description
* Find appropriate Firebird lock file prefix.
*
**************************************/
gds__prefix_lock(string, "");

if (createLockDir)
os_utils::createLockDirectory(string);

iscSafeConcatPath(string, root);
}


void iscSafeConcatPath(TEXT *resultString, const TEXT *appendString)
{
/**************************************
*
* i s c S a f e C o n c a t P a t h
*
**************************************
*
* Functional description
* Safely appends appendString to resultString using paths rules.
* resultString must be at most MAXPATHLEN size.
* Thread/signal safe code.
*
**************************************/
size_t len = strlen(resultString);
fb_assert(len > 0);

if (resultString[len - 1] != PathUtils::dir_sep && len < MAXPATHLEN - 1)
{
resultString[len++] = PathUtils::dir_sep;
resultString[len] = 0;
}

size_t alen = strlen(appendString);
if (len + alen > MAXPATHLEN - 1)
{
alen = MAXPATHLEN - 1 - len;
}

fb_assert(len < MAXPATHLEN);
fb_assert(alen < MAXPATHLEN);
fb_assert(len + alen < MAXPATHLEN);

memcpy(&resultString[len], appendString, alen);
resultString[len + alen] = 0;
}
3 changes: 3 additions & 0 deletions src/common/isc_proto.h
Expand Up @@ -44,4 +44,7 @@ bool ISC_is_WinNT();
struct _SECURITY_ATTRIBUTES* ISC_get_security_desc();
#endif

void iscPrefixLock(TEXT* string, const TEXT* root, bool createLockDir);
void iscSafeConcatPath(TEXT *resultString, const TEXT *appendString);

#endif // JRD_ISC_PROTO_H
12 changes: 6 additions & 6 deletions src/common/isc_sync.cpp
Expand Up @@ -1732,7 +1732,7 @@ void SharedMemoryBase::removeMapFile()
void SharedMemoryBase::unlinkFile()
{
TEXT expanded_filename[MAXPATHLEN];
gds__prefix_lock(expanded_filename, sh_mem_name);
iscPrefixLock(expanded_filename, sh_mem_name, false);

// We can't do much (specially in dtors) when it fails
// therefore do not check for errors - at least it's just /tmp.
Expand Down Expand Up @@ -1786,15 +1786,15 @@ SharedMemoryBase::SharedMemoryBase(const TEXT* filename, ULONG length, IpcObject
sh_mem_name[0] = '\0';

TEXT expanded_filename[MAXPATHLEN];
gds__prefix_lock(expanded_filename, filename);
iscPrefixLock(expanded_filename, filename, true);

// make the complete filename for the init file this file is to be used as a
// master lock to eliminate possible race conditions with just a single file
// locking. The race condition is caused as the conversion of an EXCLUSIVE
// lock to a SHARED lock is not atomic

TEXT init_filename[MAXPATHLEN];
gds__prefix_lock(init_filename, INIT_FILE);
iscPrefixLock(init_filename, INIT_FILE, true);

const bool trunc_flag = (length != 0);

Expand Down Expand Up @@ -1825,7 +1825,7 @@ SharedMemoryBase::SharedMemoryBase(const TEXT* filename, ULONG length, IpcObject


TEXT sem_filename[MAXPATHLEN];
gds__prefix_lock(sem_filename, SEM_FILE);
iscPrefixLock(sem_filename, SEM_FILE, true);

semFile.reset(FB_NEW(*getDefaultMemoryPool()) FileLock(sem_filename, Sem5Init::init));

Expand Down Expand Up @@ -2109,7 +2109,7 @@ SharedMemoryBase::SharedMemoryBase(const TEXT* filename, ULONG length, IpcObject
int retry_count = 0;

TEXT expanded_filename[MAXPATHLEN];
gds__prefix_lock(expanded_filename, filename);
iscPrefixLock(expanded_filename, filename, false);

const bool trunc_flag = (length != 0);
bool init_flag = false;
Expand Down Expand Up @@ -3597,7 +3597,7 @@ SharedMemoryBase::~SharedMemoryBase()
CloseHandle(sh_mem_hdr_object);

TEXT expanded_filename[MAXPATHLEN];
gds__prefix_lock(expanded_filename, sh_mem_name);
iscPrefixLock(expanded_filename, sh_mem_name, false);

// Delete file only if it is not used by anyone else
HANDLE hFile = CreateFile(expanded_filename,
Expand Down
4 changes: 2 additions & 2 deletions src/jrd/svc.cpp
Expand Up @@ -1247,7 +1247,7 @@ ISC_STATUS Service::query2(thread_db* /*tdbb*/,
gds__prefix(auxBuf, "");
break;
case isc_info_svc_get_env_lock:
gds__prefix_lock(auxBuf, "");
iscPrefixLock(auxBuf, "", false);
break;
case isc_info_svc_get_env_msg:
gds__prefix_msg(auxBuf, "");
Expand Down Expand Up @@ -1717,7 +1717,7 @@ void Service::query(USHORT send_item_length,
gds__prefix(PathBuffer, "");
break;
case isc_info_svc_get_env_lock:
gds__prefix_lock(PathBuffer, "");
iscPrefixLock(PathBuffer, "", false);
break;
case isc_info_svc_get_env_msg:
gds__prefix_msg(PathBuffer, "");
Expand Down
2 changes: 1 addition & 1 deletion src/jrd/trace/TraceConfigStorage.cpp
Expand Up @@ -201,7 +201,7 @@ void ConfigStorage::checkFile()
fb_assert(m_sharedMemory->getHeader()->cnt_uses == 0);

char dir[MAXPATHLEN];
gds__prefix_lock(dir, "");
iscPrefixLock(dir, "", true);

PathName filename = TempFile::create("fb_trace_", dir);
filename.copyTo(cfg_file_name, sizeof(m_sharedMemory->getHeader()->cfg_file_name));
Expand Down
2 changes: 1 addition & 1 deletion src/jrd/trace/TraceLog.cpp
Expand Up @@ -72,7 +72,7 @@ TraceLog::TraceLog(MemoryPool& pool, const PathName& fileName, bool reader) :
}

char dir[MAXPATHLEN];
gds__prefix_lock(dir, "");
iscPrefixLock(dir, "", true);
PathUtils::concatPath(m_baseFileName, dir, fileName);

TraceLogGuard guard(this);
Expand Down
50 changes: 3 additions & 47 deletions src/yvalve/gds.cpp
Expand Up @@ -180,8 +180,6 @@ static int blr_print_word(gds_ctl*);

static void sanitize(Firebird::string& locale);

static void safe_concat_path(TEXT* destbuf, const TEXT* srcbuf);

// New functions that try to be safe.
static SLONG safe_interpret(char* const s, const size_t bufsize,
const ISC_STATUS** const vector, bool legacy = false);
Expand Down Expand Up @@ -1739,7 +1737,7 @@ void API_ROUTINE gds__prefix(TEXT* resultString, const TEXT* file)
GDS_init_prefix();

strcpy(resultString, fb_prefix); // safe - no BO
safe_concat_path(resultString, file);
iscSafeConcatPath(resultString, file);
}


Expand All @@ -1760,12 +1758,7 @@ void API_ROUTINE gds__prefix_lock(TEXT* string, const TEXT* root)
GDS_init_prefix();

strcpy(string, fb_prefix_lock); // safe - no BO

// if someone wants to know prefix for lock files,
// sooner of all he wants that directory to exist
os_utils::createLockDirectory(string);

safe_concat_path(string, root);
iscSafeConcatPath(string, root);
}


Expand All @@ -1789,7 +1782,7 @@ void API_ROUTINE gds__prefix_msg(TEXT* string, const TEXT* root)
GDS_init_prefix();

strcpy(string, fb_prefix_msg); // safe - no BO
safe_concat_path(string, root);
iscSafeConcatPath(string, root);
}


Expand Down Expand Up @@ -3672,43 +3665,6 @@ static void sanitize(Firebird::string& locale)
}
}

static void safe_concat_path(TEXT *resultString, const TEXT *appendString)
{
/**************************************
*
* s a f e _ c o n c a t _ p a t h
*
**************************************
*
* Functional description
* Safely appends appendString to resultString using paths rules.
* resultString must be at most MAXPATHLEN size.
* Thread/signal safe code.
*
**************************************/
size_t len = strlen(resultString);
fb_assert(len > 0);

if (resultString[len - 1] != PathUtils::dir_sep && len < MAXPATHLEN - 1)
{
resultString[len++] = PathUtils::dir_sep;
resultString[len] = 0;
}

size_t alen = strlen(appendString);
if (len + alen > MAXPATHLEN - 1)
{
alen = MAXPATHLEN - 1 - len;
}

fb_assert(len < MAXPATHLEN);
fb_assert(alen < MAXPATHLEN);
fb_assert(len + alen < MAXPATHLEN);

memcpy(&resultString[len], appendString, alen);
resultString[len + alen] = 0;
}


void FB_EXPORTED gds__default_printer(void* /*arg*/, SSHORT offset, const TEXT* line)
{
Expand Down

0 comments on commit f1e3ba6

Please sign in to comment.