8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 22:43:03 +01:00

Merge pull request #7232 from FirebirdSQL/work/shmemInit

Work/shmem init
This commit is contained in:
Vlad Khorsun 2022-07-14 13:20:38 +03:00 committed by GitHub
commit 2e2221fd39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 196 additions and 109 deletions

View File

@ -51,6 +51,9 @@ static const char* const USER_MAP_FILE = "fb" COMMON_FILE_PREFIX "_user_mapping"
// Per-log file usage (for audit logging) // Per-log file usage (for audit logging)
static const char* const FB_TRACE_LOG_MUTEX = "fb_trace_log_mutex"; static const char* const FB_TRACE_LOG_MUTEX = "fb_trace_log_mutex";
// Per-trace session usage (for interactive trace)
static const char* const FB_TRACE_FILE = "fb_trace.";
#ifdef UNIX #ifdef UNIX
static const char* const INIT_FILE = "fb_init"; static const char* const INIT_FILE = "fb_init";
static const char* const SEM_FILE = "fb_sem"; static const char* const SEM_FILE = "fb_sem";

View File

@ -147,6 +147,8 @@ public:
#endif #endif
} }
bool check(const char* name, USHORT type, USHORT version, bool raiseError = true) const;
void markAsDeleted() void markAsDeleted()
{ {
mhb_flags |= FLAG_DELETED; mhb_flags |= FLAG_DELETED;
@ -227,6 +229,20 @@ public:
virtual bool initialize(SharedMemoryBase*, bool) = 0; virtual bool initialize(SharedMemoryBase*, bool) = 0;
virtual void mutexBug(int osErrorCode, const char* text) = 0; virtual void mutexBug(int osErrorCode, const char* text) = 0;
//virtual void eventBug(int osErrorCode, const char* text) = 0; //virtual void eventBug(int osErrorCode, const char* text) = 0;
virtual USHORT getType() const = 0;
virtual USHORT getVersion() const = 0;
virtual const char* getName() const = 0;
virtual void initHeader(MemoryHeader* header)
{
header->init(getType(), getVersion());
}
virtual bool checkHeader(const MemoryHeader* header, bool raiseError = true)
{
return header->check(getName(), getType(), getVersion(), raiseError);
}
}; };
@ -313,7 +329,8 @@ public:
SRAM_TPC_HEADER = 0xF9, SRAM_TPC_HEADER = 0xF9,
SRAM_TPC_BLOCK = 0xF8, SRAM_TPC_BLOCK = 0xF8,
SRAM_TPC_SNAPSHOTS = 0xF7, SRAM_TPC_SNAPSHOTS = 0xF7,
SRAM_CHANGELOG_STATE = 0xF6 SRAM_CHANGELOG_STATE = 0xF6,
SRAM_TRACE_AUDIT_MTX = 0xF5
}; };
protected: protected:

View File

@ -640,6 +640,23 @@ namespace {
#define PTHREAD_ERR_RAISE(x) { int tmpState = (x); if (tmpState) { system_call_failed::raise(#x, tmpState); } } #define PTHREAD_ERR_RAISE(x) { int tmpState = (x); if (tmpState) { system_call_failed::raise(#x, tmpState); } }
bool MemoryHeader::check(const char* name, USHORT type, USHORT version, bool raiseError) const
{
if (mhb_type == type && mhb_header_version == HEADER_VERSION && mhb_version == version)
return true;
if (!raiseError)
return false;
string found, expected;
found.printf("%d/%d:%d", mhb_type, mhb_header_version, mhb_version);
expected.printf("%d/%d:%d", type, HEADER_VERSION, version);
// @1: inconsistent shared memory type/version; found @2, expected @3
(Arg::Gds(isc_wrong_shmem_ver) <<
Arg::Str(name) << Arg::Str(found) << Arg::Str(expected)).raise();
}
int SharedMemoryBase::eventInit(event_t* event) int SharedMemoryBase::eventInit(event_t* event)
{ {

View File

@ -958,3 +958,5 @@ FB_IMPL_MSG(JRD, 956, sysf_invalid_null_empty, -901, "22", "023", "Empty or NULL
FB_IMPL_MSG(JRD, 957, bad_loctab_num, -901, "HY", "000", "Undefined local table number @1") FB_IMPL_MSG(JRD, 957, bad_loctab_num, -901, "HY", "000", "Undefined local table number @1")
FB_IMPL_MSG(JRD, 958, quoted_str_bad, -901, "22", "024", "Invalid text <@1> after quoted string") FB_IMPL_MSG(JRD, 958, quoted_str_bad, -901, "22", "024", "Invalid text <@1> after quoted string")
FB_IMPL_MSG(JRD, 959, quoted_str_miss, -901, "22", "024", "Missing terminating quote <@1> in the end of quoted string") FB_IMPL_MSG(JRD, 959, quoted_str_miss, -901, "22", "024", "Missing terminating quote <@1> in the end of quoted string")
FB_IMPL_MSG(JRD, 960, wrong_shmem_ver, -902, "08", "006", "@1: inconsistent shared memory type/version; found @2, expected @3")
FB_IMPL_MSG(JRD, 961, wrong_shmem_bitness, -902, "08", "006", "@1-bit engine can't open database already opened by @2-bit engine")

View File

@ -784,25 +784,12 @@ public:
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
StaticStatusVector s;
ex.stuffException(s);
iscLogException("MappingIpc: Cannot initialize the shared memory region", ex); iscLogException("MappingIpc: Cannot initialize the shared memory region", ex);
throw; throw;
} }
MappingHeader* sMem = tempSharedMemory->getHeader(); MappingHeader* sMem = tempSharedMemory->getHeader();
checkHeader(sMem);
if (sMem->mhb_type != SharedMemoryBase::SRAM_MAPPING_RESET ||
sMem->mhb_header_version != MemoryHeader::HEADER_VERSION ||
sMem->mhb_version != MAPPING_VERSION)
{
string err;
err.printf("MappingIpc: inconsistent shared memory type/version; found %d/%d:%d, expected %d/%d:%d",
sMem->mhb_type, sMem->mhb_header_version, sMem->mhb_version,
SharedMemoryBase::SRAM_MAPPING_RESET, MemoryHeader::HEADER_VERSION, MAPPING_VERSION);
(Arg::Gds(isc_random) << Arg::Str(err)).raise();
}
Guard gShared(tempSharedMemory); Guard gShared(tempSharedMemory);
@ -906,14 +893,14 @@ private:
} }
// implement pure virtual functions // implement pure virtual functions
bool initialize(SharedMemoryBase* sm, bool initFlag) bool initialize(SharedMemoryBase* sm, bool initFlag) override
{ {
if (initFlag) if (initFlag)
{ {
MappingHeader* header = reinterpret_cast<MappingHeader*>(sm->sh_mem_header); MappingHeader* header = reinterpret_cast<MappingHeader*>(sm->sh_mem_header);
// Initialize the shared data header // Initialize the shared data header
header->init(SharedMemoryBase::SRAM_MAPPING_RESET, MAPPING_VERSION); initHeader(header);
header->processes = 0; header->processes = 0;
header->currentProcess = -1; header->currentProcess = -1;
@ -922,12 +909,16 @@ private:
return true; return true;
} }
void mutexBug(int osErrorCode, const char* text) void mutexBug(int osErrorCode, const char* text) override
{ {
iscLogStatus("Error when working with user mapping shared memory", iscLogStatus("Error when working with user mapping shared memory",
(Arg::Gds(isc_sys_request) << text << Arg::OsError(osErrorCode)).value()); (Arg::Gds(isc_sys_request) << text << Arg::OsError(osErrorCode)).value());
} }
USHORT getType() const override { return SharedMemoryBase::SRAM_MAPPING_RESET; }
USHORT getVersion() const override { return MAPPING_VERSION; }
const char* getName() const override { return "MappingIpc"; }
// copying is prohibited // copying is prohibited
MappingIpc(const MappingIpc&); MappingIpc(const MappingIpc&);
MappingIpc& operator =(const MappingIpc&); MappingIpc& operator =(const MappingIpc&);

View File

@ -190,16 +190,15 @@ void MonitoringData::initSharedFile()
{ {
m_sharedMemory.reset(FB_NEW_POOL(getPool()) m_sharedMemory.reset(FB_NEW_POOL(getPool())
SharedMemory<MonitoringHeader>(name.c_str(), DEFAULT_SIZE, this)); SharedMemory<MonitoringHeader>(name.c_str(), DEFAULT_SIZE, this));
const auto header = m_sharedMemory->getHeader();
checkHeader(header);
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
iscLogException("MonitoringData: Cannot initialize the shared memory region", ex); iscLogException("MonitoringData: Cannot initialize the shared memory region", ex);
throw; throw;
} }
fb_assert(m_sharedMemory->getHeader()->mhb_type == SharedMemoryBase::SRAM_DATABASE_SNAPSHOT);
fb_assert(m_sharedMemory->getHeader()->mhb_header_version == MemoryHeader::HEADER_VERSION);
fb_assert(m_sharedMemory->getHeader()->mhb_version == MONITOR_VERSION);
} }
@ -389,7 +388,7 @@ bool MonitoringData::initialize(SharedMemoryBase* sm, bool initialize)
MonitoringHeader* const header = reinterpret_cast<MonitoringHeader*>(sm->sh_mem_header); MonitoringHeader* const header = reinterpret_cast<MonitoringHeader*>(sm->sh_mem_header);
// Initialize the shared data header // Initialize the shared data header
header->init(SharedMemoryBase::SRAM_DATABASE_SNAPSHOT, MONITOR_VERSION); initHeader(header);
header->used = alignOffset(sizeof(Header)); header->used = alignOffset(sizeof(Header));
header->allocated = sm->sh_mem_length_mapped; header->allocated = sm->sh_mem_length_mapped;

View File

@ -319,8 +319,12 @@ public:
explicit MonitoringData(Database*); explicit MonitoringData(Database*);
~MonitoringData(); ~MonitoringData();
bool initialize(Firebird::SharedMemoryBase*, bool); bool initialize(Firebird::SharedMemoryBase*, bool) override;
void mutexBug(int osErrorCode, const char* text); void mutexBug(int osErrorCode, const char* text) override;
virtual USHORT getType() const override { return Firebird::SharedMemoryBase::SRAM_DATABASE_SNAPSHOT; }
virtual USHORT getVersion() const override { return MONITOR_VERSION; }
virtual const char* getName() const override { return "MonitoringData"; }
void initSharedFile(); void initSharedFile();

View File

@ -134,9 +134,9 @@ void EventManager::init_shared_file()
// initialize will reset m_sharedMemory // initialize will reset m_sharedMemory
fb_assert(m_sharedMemory == tmp); fb_assert(m_sharedMemory == tmp);
fb_assert(m_sharedMemory->getHeader()->mhb_type == SharedMemoryBase::SRAM_EVENT_MANAGER);
fb_assert(m_sharedMemory->getHeader()->mhb_header_version == MemoryHeader::HEADER_VERSION); const auto* header = m_sharedMemory->getHeader();
fb_assert(m_sharedMemory->getHeader()->mhb_version == EVENT_VERSION); checkHeader(header);
} }
@ -1031,7 +1031,7 @@ bool EventManager::initialize(SharedMemoryBase* sm, bool init)
{ {
evh* header = m_sharedMemory->getHeader(); evh* header = m_sharedMemory->getHeader();
header->init(SharedMemoryBase::SRAM_EVENT_MANAGER, EVENT_VERSION); initHeader(header);
header->evh_length = sm->sh_mem_length_mapped; header->evh_length = sm->sh_mem_length_mapped;
header->evh_request_id = 0; header->evh_request_id = 0;

View File

@ -55,8 +55,13 @@ public:
void postEvent(USHORT, const TEXT*, USHORT); void postEvent(USHORT, const TEXT*, USHORT);
void deliverEvents(); void deliverEvents();
bool initialize(Firebird::SharedMemoryBase*, bool); bool initialize(Firebird::SharedMemoryBase*, bool) override;
void mutexBug(int osErrorCode, const char* text); void mutexBug(int osErrorCode, const char* text) override;
virtual USHORT getType() const override { return Firebird::SharedMemoryBase::SRAM_EVENT_MANAGER; }
virtual USHORT getVersion() const override { return EVENT_VERSION; }
virtual const char* getName() const override { return "EventManager";}
void exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<EventManager*>::ThreadRoutine* routine); void exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<EventManager*>::ThreadRoutine* routine);
private: private:

View File

@ -392,9 +392,8 @@ void ChangeLog::initSharedFile()
m_sharedMemory.reset(FB_NEW_POOL(getPool()) m_sharedMemory.reset(FB_NEW_POOL(getPool())
SharedMemory<State>(filename.c_str(), STATE_MAPPING_SIZE, this)); SharedMemory<State>(filename.c_str(), STATE_MAPPING_SIZE, this));
fb_assert(m_sharedMemory->getHeader()->mhb_type == SharedMemoryBase::SRAM_CHANGELOG_STATE); const auto* header = m_sharedMemory->getHeader();
fb_assert(m_sharedMemory->getHeader()->mhb_header_version == MemoryHeader::HEADER_VERSION); checkHeader(header);
fb_assert(m_sharedMemory->getHeader()->mhb_version == STATE_VERSION);
} }
void ChangeLog::lockState() void ChangeLog::lockState()
@ -535,7 +534,7 @@ bool ChangeLog::initialize(SharedMemoryBase* shmem, bool init)
const auto state = reinterpret_cast<State*>(shmem->sh_mem_header); const auto state = reinterpret_cast<State*>(shmem->sh_mem_header);
memset(state, 0, sizeof(State)); memset(state, 0, sizeof(State));
state->init(SharedMemoryBase::SRAM_CHANGELOG_STATE, STATE_VERSION); initHeader(state);
state->timestamp = time(NULL); state->timestamp = time(NULL);
state->sequence = m_sequence; state->sequence = m_sequence;

View File

@ -216,8 +216,12 @@ namespace Replication
void linkSelf(); void linkSelf();
bool unlinkSelf(); bool unlinkSelf();
bool initialize(Firebird::SharedMemoryBase* shmem, bool init); bool initialize(Firebird::SharedMemoryBase* shmem, bool init) override;
void mutexBug(int osErrorCode, const char* text); void mutexBug(int osErrorCode, const char* text) override;
virtual USHORT getType() const override { return Firebird::SharedMemoryBase::SRAM_CHANGELOG_STATE; }
virtual USHORT getVersion() const override { return STATE_VERSION; };
virtual const char* getName() const override { return "ChangeLog"; }
bool validateSegment(const Segment* segment) bool validateSegment(const Segment* segment)
{ {

View File

@ -47,12 +47,15 @@ void TipCache::MemoryInitializer::mutexBug(int osErrorCode, const char* text)
fb_utils::logAndDie(msg.c_str()); fb_utils::logAndDie(msg.c_str());
} }
bool TipCache::GlobalTpcInitializer::initialize(Firebird::SharedMemoryBase* sm, bool initFlag) bool TipCache::GlobalTpcInitializer::initialize(SharedMemoryBase* sm, bool initFlag)
{ {
GlobalTpcHeader* header = static_cast<GlobalTpcHeader*>(sm->sh_mem_header); GlobalTpcHeader* header = static_cast<GlobalTpcHeader*>(sm->sh_mem_header);
if (!initFlag) if (!initFlag)
{ {
if (!checkHeader(header, false))
return false;
m_cache->initTransactionsPerBlock(header->tpc_block_size); m_cache->initTransactionsPerBlock(header->tpc_block_size);
m_cache->mapInventoryPages(header); m_cache->mapInventoryPages(header);
return true; return true;
@ -62,7 +65,7 @@ bool TipCache::GlobalTpcInitializer::initialize(Firebird::SharedMemoryBase* sm,
Database* dbb = tdbb->getDatabase(); Database* dbb = tdbb->getDatabase();
// Initialize the shared data header // Initialize the shared data header
header->init(SharedMemoryBase::SRAM_TPC_HEADER, TPC_VERSION); initHeader(header);
header->latest_commit_number.store(CN_PREHISTORIC, std::memory_order_relaxed); header->latest_commit_number.store(CN_PREHISTORIC, std::memory_order_relaxed);
header->latest_statement_id.store(0, std::memory_order_relaxed); header->latest_statement_id.store(0, std::memory_order_relaxed);
@ -74,7 +77,7 @@ bool TipCache::GlobalTpcInitializer::initialize(Firebird::SharedMemoryBase* sm,
return true; return true;
} }
bool TipCache::SnapshotsInitializer::initialize(Firebird::SharedMemoryBase* sm, bool initFlag) bool TipCache::SnapshotsInitializer::initialize(SharedMemoryBase* sm, bool initFlag)
{ {
if (!initFlag) if (!initFlag)
return true; return true;
@ -82,7 +85,7 @@ bool TipCache::SnapshotsInitializer::initialize(Firebird::SharedMemoryBase* sm,
SnapshotList* header = static_cast<SnapshotList*>(sm->sh_mem_header); SnapshotList* header = static_cast<SnapshotList*>(sm->sh_mem_header);
// Initialize the shared data header // Initialize the shared data header
header->init(SharedMemoryBase::SRAM_TPC_SNAPSHOTS, TPC_VERSION); initHeader(header);
header->slots_used.store(0, std::memory_order_relaxed); header->slots_used.store(0, std::memory_order_relaxed);
header->min_free_slot = 0; header->min_free_slot = 0;
@ -92,7 +95,7 @@ bool TipCache::SnapshotsInitializer::initialize(Firebird::SharedMemoryBase* sm,
return true; return true;
} }
bool TipCache::MemBlockInitializer::initialize(Firebird::SharedMemoryBase* sm, bool initFlag) bool TipCache::MemBlockInitializer::initialize(SharedMemoryBase* sm, bool initFlag)
{ {
if (!initFlag) if (!initFlag)
return true; return true;
@ -100,7 +103,7 @@ bool TipCache::MemBlockInitializer::initialize(Firebird::SharedMemoryBase* sm, b
TransactionStatusBlock* header = static_cast<TransactionStatusBlock*>(sm->sh_mem_header); TransactionStatusBlock* header = static_cast<TransactionStatusBlock*>(sm->sh_mem_header);
// Initialize the shared data header // Initialize the shared data header
header->init(SharedMemoryBase::SRAM_TPC_BLOCK, TPC_VERSION); initHeader(header);
memset(header->data, 0, sm->sh_mem_length_mapped - offsetof(TransactionStatusBlock, data[0])); memset(header->data, 0, sm->sh_mem_length_mapped - offsetof(TransactionStatusBlock, data[0]));
@ -219,6 +222,9 @@ void TipCache::initializeTpc(thread_db *tdbb)
fileName.printf(TPC_HDR_FILE, dbb->getUniqueFileId().c_str()); fileName.printf(TPC_HDR_FILE, dbb->getUniqueFileId().c_str());
m_tpcHeader = FB_NEW_POOL(*dbb->dbb_permanent) SharedMemory<GlobalTpcHeader>( m_tpcHeader = FB_NEW_POOL(*dbb->dbb_permanent) SharedMemory<GlobalTpcHeader>(
fileName.c_str(), sizeof(GlobalTpcHeader), &globalTpcInitializer); fileName.c_str(), sizeof(GlobalTpcHeader), &globalTpcInitializer);
const auto* header = m_tpcHeader->getHeader();
globalTpcInitializer.checkHeader(header);
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
@ -229,13 +235,14 @@ void TipCache::initializeTpc(thread_db *tdbb)
throw; throw;
} }
fb_assert(m_tpcHeader->getHeader()->mhb_version == TPC_VERSION);
try try
{ {
fileName.printf(SNAPSHOTS_FILE, dbb->getUniqueFileId().c_str()); fileName.printf(SNAPSHOTS_FILE, dbb->getUniqueFileId().c_str());
m_snapshots = FB_NEW_POOL(*dbb->dbb_permanent) SharedMemory<SnapshotList>( m_snapshots = FB_NEW_POOL(*dbb->dbb_permanent) SharedMemory<SnapshotList>(
fileName.c_str(), dbb->dbb_config->getSnapshotsMemSize(), &snapshotsInitializer); fileName.c_str(), dbb->dbb_config->getSnapshotsMemSize(), &snapshotsInitializer);
const auto* header = m_snapshots->getHeader();
snapshotsInitializer.checkHeader(header);
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
@ -246,8 +253,6 @@ void TipCache::initializeTpc(thread_db *tdbb)
throw; throw;
} }
fb_assert(m_snapshots->getHeader()->mhb_version == TPC_VERSION);
LCK_release(tdbb, &lock); LCK_release(tdbb, &lock);
} }
@ -292,7 +297,7 @@ void TipCache::loadInventoryPages(thread_db* tdbb, GlobalTpcHeader* header)
TraNumber base = hdr_oldest_transaction & ~TRA_MASK; TraNumber base = hdr_oldest_transaction & ~TRA_MASK;
const FB_SIZE_T buffer_length = (hdr_next_transaction + 1 - base + TRA_MASK) / 4; const FB_SIZE_T buffer_length = (hdr_next_transaction + 1 - base + TRA_MASK) / 4;
Firebird::Array<UCHAR> transactions(buffer_length); Array<UCHAR> transactions(buffer_length);
UCHAR* buffer = transactions.begin(); UCHAR* buffer = transactions.begin();
TRA_get_inventory(tdbb, buffer, base, hdr_next_transaction); TRA_get_inventory(tdbb, buffer, base, hdr_next_transaction);
@ -352,13 +357,16 @@ TipCache::StatusBlockData::StatusBlockData(thread_db* tdbb, TipCache* tipCache,
try try
{ {
memory = FB_NEW_POOL(*dbb->dbb_permanent) Firebird::SharedMemory<TransactionStatusBlock>( memory = FB_NEW_POOL(*dbb->dbb_permanent) SharedMemory<TransactionStatusBlock>(
fileName.c_str(), blockSize, fileName.c_str(), blockSize,
&cache->memBlockInitializer, true); &cache->memBlockInitializer, true);
const auto* header = memory->getHeader();
cache->memBlockInitializer.checkHeader(header);
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
iscLogException("TPC: Cannot initialize the shared memory region (header)", ex); iscLogException("TPC: Cannot initialize the shared memory region (transactions status block)", ex);
LCK_release(tdbb, &existenceLock); LCK_release(tdbb, &existenceLock);
throw; throw;
} }
@ -667,7 +675,7 @@ void TipCache::releaseSharedMemory(thread_db* tdbb, TraNumber oldest_old, TraNum
// We scan for blocks to clean up in descending order, but delete them in // We scan for blocks to clean up in descending order, but delete them in
// ascending order to ensure for robust operation. // ascending order to ensure for robust operation.
string fileName; string fileName;
Firebird::HalfStaticArray<TpcBlockNumber, 16> blocksToCleanup; HalfStaticArray<TpcBlockNumber, 16> blocksToCleanup;
for (TpcBlockNumber cleanupCounter = lastInterestingBlockNumber - SAFETY_GAP_BLOCKS; for (TpcBlockNumber cleanupCounter = lastInterestingBlockNumber - SAFETY_GAP_BLOCKS;
cleanupCounter; cleanupCounter--) cleanupCounter; cleanupCounter--)
@ -932,7 +940,7 @@ void TipCache::updateActiveSnapshots(thread_db* tdbb, ActiveSnapshots* activeSna
snapshots = m_snapshots->getHeader(); snapshots = m_snapshots->getHeader();
Firebird::GenericMap<Pair<NonPooled<AttNumber, bool> > > att_states; GenericMap<Pair<NonPooled<AttNumber, bool> > > att_states;
// We modify snapshots list only while holding a mutex // We modify snapshots list only while holding a mutex
SharedMutexGuard guard(m_snapshots, false); SharedMutexGuard guard(m_snapshots, false);

View File

@ -225,7 +225,8 @@ private:
{ {
public: public:
explicit MemoryInitializer(TipCache *cache) : m_cache(cache) {} explicit MemoryInitializer(TipCache *cache) : m_cache(cache) {}
void mutexBug(int osErrorCode, const char* text); void mutexBug(int osErrorCode, const char* text) override;
USHORT getVersion() const override { return TPC_VERSION; }
protected: protected:
TipCache* m_cache; TipCache* m_cache;
}; };
@ -234,21 +235,30 @@ private:
{ {
public: public:
explicit GlobalTpcInitializer(TipCache *cache) : MemoryInitializer(cache) {} explicit GlobalTpcInitializer(TipCache *cache) : MemoryInitializer(cache) {}
bool initialize(Firebird::SharedMemoryBase* sm, bool initFlag); bool initialize(Firebird::SharedMemoryBase* sm, bool initFlag) override;
USHORT getType() const override { return Firebird::SharedMemoryBase::SRAM_TPC_HEADER; }
const char* getName() const override { return "TipCache:Global"; }
}; };
class SnapshotsInitializer : public MemoryInitializer class SnapshotsInitializer : public MemoryInitializer
{ {
public: public:
explicit SnapshotsInitializer(TipCache *cache) : MemoryInitializer(cache) {} explicit SnapshotsInitializer(TipCache *cache) : MemoryInitializer(cache) {}
bool initialize(Firebird::SharedMemoryBase* sm, bool initFlag); bool initialize(Firebird::SharedMemoryBase* sm, bool initFlag) override;
USHORT getType() const override { return Firebird::SharedMemoryBase::SRAM_TPC_SNAPSHOTS; }
const char* getName() const override { return "TipCache:Snapshots"; }
}; };
class MemBlockInitializer : public MemoryInitializer class MemBlockInitializer : public MemoryInitializer
{ {
public: public:
explicit MemBlockInitializer(TipCache *cache) : MemoryInitializer(cache) {} explicit MemBlockInitializer(TipCache *cache) : MemoryInitializer(cache) {}
bool initialize(Firebird::SharedMemoryBase* sm, bool initFlag); bool initialize(Firebird::SharedMemoryBase* sm, bool initFlag) override;
USHORT getType() const override { return Firebird::SharedMemoryBase::SRAM_TPC_BLOCK; }
const char* getName() const override { return "TipCache:TranBlock"; }
}; };
typedef Firebird::BePlusTree<StatusBlockData*, TpcBlockNumber, Firebird::MemoryPool, StatusBlockData> BlocksMemoryMap; typedef Firebird::BePlusTree<StatusBlockData*, TpcBlockNumber, Firebird::MemoryPool, StatusBlockData> BlocksMemoryMap;

View File

@ -123,6 +123,8 @@ ConfigStorage::ConfigStorage()
{ {
m_sharedMemory.reset(FB_NEW_POOL(getPool()) m_sharedMemory.reset(FB_NEW_POOL(getPool())
SharedMemory<TraceCSHeader>(filename.c_str(), TraceCSHeader::TRACE_STORAGE_MIN_SIZE, this)); SharedMemory<TraceCSHeader>(filename.c_str(), TraceCSHeader::TRACE_STORAGE_MIN_SIZE, this));
checkHeader(m_sharedMemory->getHeader());
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
@ -130,9 +132,6 @@ ConfigStorage::ConfigStorage()
throw; throw;
} }
fb_assert(m_sharedMemory->getHeader());
fb_assert(m_sharedMemory->getHeader()->mhb_version == TraceCSHeader::TRACE_STORAGE_VERSION);
StorageGuard guard(this); StorageGuard guard(this);
checkAudit(); checkAudit();
@ -187,7 +186,7 @@ bool ConfigStorage::initialize(SharedMemoryBase* sm, bool init)
// Initialize the shared data header // Initialize the shared data header
if (init) if (init)
{ {
header->init(SharedMemoryBase::SRAM_TRACE_CONFIG, TraceCSHeader::TRACE_STORAGE_VERSION); initHeader(header);
header->change_number = 0; header->change_number = 0;
header->session_number = 1; header->session_number = 1;
@ -201,12 +200,6 @@ bool ConfigStorage::initialize(SharedMemoryBase* sm, bool init)
header->slots_cnt = 0; header->slots_cnt = 0;
memset(header->slots, 0, sizeof(TraceCSHeader::slots)); memset(header->slots, 0, sizeof(TraceCSHeader::slots));
} }
else
{
fb_assert(header->mhb_type == SharedMemoryBase::SRAM_TRACE_CONFIG);
fb_assert(header->mhb_header_version == MemoryHeader::HEADER_VERSION);
fb_assert(header->mhb_version == TraceCSHeader::TRACE_STORAGE_VERSION);
}
return true; return true;
} }

View File

@ -111,8 +111,12 @@ public:
Firebird::Mutex m_localMutex; Firebird::Mutex m_localMutex;
private: private:
void mutexBug(int osErrorCode, const char* text); void mutexBug(int osErrorCode, const char* text) override;
bool initialize(Firebird::SharedMemoryBase*, bool); bool initialize(Firebird::SharedMemoryBase*, bool) override;
USHORT getType() const override { return Firebird::SharedMemoryBase::SRAM_TRACE_CONFIG; }
USHORT getVersion() const override { return TraceCSHeader::TRACE_STORAGE_VERSION; }
const char* getName() const override { return "TraceConfigStorage"; }
void checkAudit(); void checkAudit();

View File

@ -63,6 +63,9 @@ TraceLog::TraceLog(MemoryPool& pool, const PathName& fileName, bool reader) :
{ {
m_sharedMemory.reset(FB_NEW_POOL(pool) m_sharedMemory.reset(FB_NEW_POOL(pool)
SharedMemory<TraceLogHeader>(fileName.c_str(), INIT_LOG_SIZE, this)); SharedMemory<TraceLogHeader>(fileName.c_str(), INIT_LOG_SIZE, this));
const auto* header = m_sharedMemory->getHeader();
checkHeader(header);
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
@ -293,19 +296,13 @@ bool TraceLog::initialize(SharedMemoryBase* sm, bool initialize)
TraceLogHeader* hdr = reinterpret_cast<TraceLogHeader*>(sm->sh_mem_header); TraceLogHeader* hdr = reinterpret_cast<TraceLogHeader*>(sm->sh_mem_header);
if (initialize) if (initialize)
{ {
hdr->init(SharedMemoryBase::SRAM_TRACE_LOG, TraceLogHeader::TRACE_LOG_VERSION); initHeader(hdr);
hdr->readPos = hdr->writePos = sizeof(TraceLogHeader); hdr->readPos = hdr->writePos = sizeof(TraceLogHeader);
hdr->maxSize = Config::getMaxUserTraceLogSize() * 1024 * 1024; hdr->maxSize = Config::getMaxUserTraceLogSize() * 1024 * 1024;
hdr->allocated = sm->sh_mem_length_mapped; hdr->allocated = sm->sh_mem_length_mapped;
hdr->flags = 0; hdr->flags = 0;
} }
else
{
fb_assert(hdr->mhb_type == SharedMemoryBase::SRAM_TRACE_LOG);
fb_assert(hdr->mhb_header_version == MemoryHeader::HEADER_VERSION);
fb_assert(hdr->mhb_version == TraceLogHeader::TRACE_LOG_VERSION);
}
return true; return true;
} }

View File

@ -61,8 +61,12 @@ private:
const ULONG FLAG_FULL = 0x0001; // log is full, set by writer, reset by reader const ULONG FLAG_FULL = 0x0001; // log is full, set by writer, reset by reader
const ULONG FLAG_DONE = 0x0002; // set when reader is gone const ULONG FLAG_DONE = 0x0002; // set when reader is gone
void mutexBug(int osErrorCode, const char* text); void mutexBug(int osErrorCode, const char* text) override;
bool initialize(Firebird::SharedMemoryBase*, bool); bool initialize(Firebird::SharedMemoryBase*, bool) override;
USHORT getType() const override { return Firebird::SharedMemoryBase::SRAM_TRACE_LOG; }
USHORT getVersion() const override { return TraceLogHeader::TRACE_LOG_VERSION; }
const char* getName() const override { return "TraceLog"; }
void lock(); void lock();
void unlock(); void unlock();

View File

@ -133,7 +133,7 @@ void TraceSvcJrd::startSession(TraceSession& session, bool interactive)
char* buff = session.ses_logfile.getBuffer(GUID_BUFF_SIZE); char* buff = session.ses_logfile.getBuffer(GUID_BUFF_SIZE);
GuidToString(buff, &guid); GuidToString(buff, &guid);
session.ses_logfile.insert(0, "fb_trace."); session.ses_logfile.insert(0, FB_TRACE_FILE);
} }
storage->addSession(session); storage->addSession(session);

View File

@ -302,6 +302,9 @@ bool LockManager::init_shared_file(CheckStatusWrapper* statusVector)
SharedMemory<lhb>* tmp = FB_NEW_POOL(getPool()) SharedMemory<lhb>(name.c_str(), m_memorySize, this); SharedMemory<lhb>* tmp = FB_NEW_POOL(getPool()) SharedMemory<lhb>(name.c_str(), m_memorySize, this);
// initialize will reset m_sharedMemory // initialize will reset m_sharedMemory
fb_assert(m_sharedMemory == tmp); fb_assert(m_sharedMemory == tmp);
const auto header = tmp->getHeader();
checkHeader(header);
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
@ -309,10 +312,6 @@ bool LockManager::init_shared_file(CheckStatusWrapper* statusVector)
return false; return false;
} }
fb_assert(m_sharedMemory->getHeader()->mhb_type == SharedMemoryBase::SRAM_LOCK_MANAGER);
fb_assert(m_sharedMemory->getHeader()->mhb_header_version == MemoryHeader::HEADER_VERSION);
fb_assert(m_sharedMemory->getHeader()->mhb_version == LHB_VERSION);
#ifdef USE_SHMEM_EXT #ifdef USE_SHMEM_EXT
m_extents[0] = *this; m_extents[0] = *this;
#endif #endif
@ -1643,19 +1642,6 @@ SRQ_PTR LockManager::create_owner(CheckStatusWrapper* statusVector,
* Create an owner block. * Create an owner block.
* *
**************************************/ **************************************/
if (m_sharedMemory->getHeader()->mhb_type != SharedMemoryBase::SRAM_LOCK_MANAGER ||
m_sharedMemory->getHeader()->mhb_header_version != MemoryHeader::HEADER_VERSION ||
m_sharedMemory->getHeader()->mhb_version != LHB_VERSION)
{
TEXT bug_buffer[BUFFER_TINY];
sprintf(bug_buffer, "inconsistent lock table type/version; found %d/%d:%d, expected %d/%d:%d",
m_sharedMemory->getHeader()->mhb_type,
m_sharedMemory->getHeader()->mhb_header_version,
m_sharedMemory->getHeader()->mhb_version,
SharedMemoryBase::SRAM_LOCK_MANAGER, MemoryHeader::HEADER_VERSION, LHB_VERSION);
bug(statusVector, bug_buffer);
return 0;
}
// Allocate a process block, if required // Allocate a process block, if required
@ -2294,8 +2280,8 @@ bool LockManager::initialize(SharedMemoryBase* sm, bool initializeMemory)
lhb* hdr = m_sharedMemory->getHeader(); lhb* hdr = m_sharedMemory->getHeader();
memset(hdr, 0, sizeof(lhb)); memset(hdr, 0, sizeof(lhb));
hdr->init(SharedMemoryBase::SRAM_LOCK_MANAGER, LHB_VERSION);
initHeader(hdr);
hdr->lhb_type = type_lhb; hdr->lhb_type = type_lhb;
// Mark ourselves as active owner to prevent fb_assert() checks // Mark ourselves as active owner to prevent fb_assert() checks
@ -3279,9 +3265,7 @@ void LockManager::validate_lhb(const lhb* alhb)
return; return;
CHECK(alhb != NULL); CHECK(alhb != NULL);
CHECK(alhb->mhb_type == SharedMemoryBase::SRAM_LOCK_MANAGER); CHECK(checkHeader(alhb, false));
CHECK(alhb->mhb_header_version == MemoryHeader::HEADER_VERSION);
CHECK(alhb->mhb_version == LHB_VERSION);
CHECK(alhb->lhb_type == type_lhb); CHECK(alhb->lhb_type == type_lhb);
@ -4000,6 +3984,26 @@ void LockManager::mutexBug(int state, char const* text)
bug(NULL, message.c_str()); bug(NULL, message.c_str());
} }
bool LockManager::checkHeader(const MemoryHeader* header, bool raiseError)
{
fb_assert(header);
if (raiseError &&
header->mhb_type == getType() &&
header->mhb_header_version == MemoryHeader::HEADER_VERSION &&
header->mhb_version != getVersion() &&
(header->mhb_version & ~PLATFORM_LHB_VERSION) == BASE_LHB_VERSION)
{
// @1-bit engine can't open database already opened by @2-bit engine
if (LHB_VERSION == BASE_LHB_VERSION)
(Arg::Gds(isc_wrong_shmem_bitness) << Arg::Num(32) << Arg::Num(64)).raise();
else
(Arg::Gds(isc_wrong_shmem_bitness) << Arg::Num(64) << Arg::Num(32)).raise();
}
return IpcObject::checkHeader(header, raiseError);
};
#ifdef USE_SHMEM_EXT #ifdef USE_SHMEM_EXT
void LockManager::Extent::assign(const SharedMemoryBase& p) void LockManager::Extent::assign(const SharedMemoryBase& p)
{ {

View File

@ -93,15 +93,15 @@ const UCHAR type_lpr = 7;
// Version number of the lock table. // Version number of the lock table.
// Must be increased every time the shmem layout is changed. // Must be increased every time the shmem layout is changed.
const USHORT BASE_LHB_VERSION = 18; const USHORT BASE_LHB_VERSION = 19;
const USHORT PLATFORM_LHB_VERSION = 128; // 64-bit target
#if SIZEOF_VOID_P == 8 #if SIZEOF_VOID_P == 8
const USHORT PLATFORM_LHB_VERSION = 128; // 64-bit target const USHORT LHB_VERSION = PLATFORM_LHB_VERSION | BASE_LHB_VERSION;
#else #else
const USHORT PLATFORM_LHB_VERSION = 0; // 32-bit target const USHORT LHB_VERSION = BASE_LHB_VERSION;
#endif #endif
const USHORT LHB_VERSION = PLATFORM_LHB_VERSION + BASE_LHB_VERSION;
// Lock header block -- one per lock file, lives up front // Lock header block -- one per lock file, lives up front
@ -467,8 +467,13 @@ private:
lockMgr->blocking_action_thread(); lockMgr->blocking_action_thread();
} }
bool initialize(Firebird::SharedMemoryBase* sm, bool init); bool initialize(Firebird::SharedMemoryBase* sm, bool init) override;
void mutexBug(int osErrorCode, const char* text); void mutexBug(int osErrorCode, const char* text) override;
bool checkHeader(const Firebird::MemoryHeader* header, bool raiseError = true) override;
USHORT getType() const override { return Firebird::SharedMemoryBase::SRAM_LOCK_MANAGER; }
USHORT getVersion() const override { return LHB_VERSION; }
const char* getName() const override { return "LockManager"; }
bool m_bugcheck; bool m_bugcheck;
prc* m_process; prc* m_process;

View File

@ -148,17 +148,21 @@ namespace
shared_memory(FB_NEW_POOL(*getDefaultMemoryPool()) SharedMemory<lhb>(filename, 0, this)) shared_memory(FB_NEW_POOL(*getDefaultMemoryPool()) SharedMemory<lhb>(filename, 0, this))
{ } { }
bool initialize(SharedMemoryBase*, bool) bool initialize(SharedMemoryBase*, bool) override
{ {
// Initialize a lock table to looking -- i.e. don't do nuthin. // Initialize a lock table to looking -- i.e. don't do nuthin.
return sh_mem_consistency; return sh_mem_consistency;
} }
void mutexBug(int /*osErrorCode*/, const char* /*text*/) void mutexBug(int /*osErrorCode*/, const char* /*text*/) override
{ {
// Do nothing - lock print always ignored mutex errors // Do nothing - lock print always ignored mutex errors
} }
USHORT getType() const override { return Firebird::SharedMemoryBase::SRAM_LOCK_MANAGER; }
USHORT getVersion() const override { return LHB_VERSION; }
const char* getName() const override { return "LockManager"; }
private: private:
bool sh_mem_consistency; bool sh_mem_consistency;

View File

@ -75,6 +75,9 @@ PluginLogWriter::PluginLogWriter(const char* fileName, size_t maxSize) :
{ {
m_sharedMemory.reset(FB_NEW_POOL(getPool()) m_sharedMemory.reset(FB_NEW_POOL(getPool())
SharedMemory<PluginLogWriterHeader>(mapFile.c_str(), sizeof(PluginLogWriterHeader), this)); SharedMemory<PluginLogWriterHeader>(mapFile.c_str(), sizeof(PluginLogWriterHeader), this));
auto header = m_sharedMemory->getHeader();
checkHeader(header);
} }
catch (const Exception& ex) catch (const Exception& ex)
{ {
@ -96,6 +99,9 @@ PluginLogWriter::~PluginLogWriter()
if (m_fileHandle != -1) if (m_fileHandle != -1)
::close(m_fileHandle); ::close(m_fileHandle);
if (m_sharedMemory && m_sharedMemory->getHeader())
m_sharedMemory->removeMapFile();
} }
SINT64 PluginLogWriter::seekToEnd() SINT64 PluginLogWriter::seekToEnd()
@ -268,6 +274,11 @@ void PluginLogWriter::mutexBug(int state, const TEXT* string)
bool PluginLogWriter::initialize(SharedMemoryBase* sm, bool init) bool PluginLogWriter::initialize(SharedMemoryBase* sm, bool init)
{ {
auto header = reinterpret_cast<PluginLogWriterHeader*>(sm->sh_mem_header);
if (init)
initHeader(header);
return true; return true;
} }

View File

@ -66,6 +66,8 @@ public:
virtual FB_SIZE_T write_s(Firebird::CheckStatusWrapper* status, const void* buf, unsigned size); virtual FB_SIZE_T write_s(Firebird::CheckStatusWrapper* status, const void* buf, unsigned size);
private: private:
const USHORT PLUGIN_LOG_VERSION = 1;
SINT64 seekToEnd(); SINT64 seekToEnd();
void reopen(); void reopen();
void checkErrno(const char* operation); void checkErrno(const char* operation);
@ -81,8 +83,12 @@ private:
// better as in this case syncronization is performed by OS kernel itself. // better as in this case syncronization is performed by OS kernel itself.
// Mutex on Posix is needed to rotate log file. // Mutex on Posix is needed to rotate log file.
void mutexBug(int osErrorCode, const char* text); void mutexBug(int osErrorCode, const char* text) override;
bool initialize(Firebird::SharedMemoryBase*, bool); bool initialize(Firebird::SharedMemoryBase*, bool) override;
USHORT getType() const override { return Firebird::SharedMemoryBase::SRAM_TRACE_AUDIT_MTX; };
USHORT getVersion() const override { return PLUGIN_LOG_VERSION; };
const char* getName() const override { return "AuditLogMutex"; };
void lock(); void lock();
void unlock(); void unlock();