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

Merge remote-tracking branch 'reddb/trace_faild_attaches_7580' into trace-failed-attach

This commit is contained in:
Dmitry Yemanov 2024-03-04 21:01:41 +03:00
commit 1ab2ad8af5
31 changed files with 956 additions and 420 deletions

View File

@ -65,9 +65,13 @@ SecDbCache:= $(call makeObjects,auth,SecDbCache.cpp)
# Remote # Remote
Remote_Trace:= $(call makeObjects,jrd/trace,TraceConfigStorage.cpp) \
$(call makeObjects,jrd/trace,TraceLog.cpp) \
$(call makeObjects,supplement/trace,TraceManager.cpp)
Remote_Common:= $(call dirObjects,remote) $(call dirObjects,auth/SecureRemotePassword) Remote_Common:= $(call dirObjects,remote) $(call dirObjects,auth/SecureRemotePassword)
Remote_Server:= $(call dirObjects,remote/server) $(call dirObjects,auth/SecureRemotePassword/server) \ Remote_Server:= $(call dirObjects,remote/server) $(call dirObjects,auth/SecureRemotePassword/server) \
$(call makeObjects,jrd/replication,Config.cpp Utils.cpp) $(SecDbCache) $(call makeObjects,jrd/replication,Config.cpp Utils.cpp) $(SecDbCache) \
$(Remote_Trace)
Remote_Client:= $(call dirObjects,remote/client) $(call dirObjects,auth/SecureRemotePassword/client) \ Remote_Client:= $(call dirObjects,remote/client) $(call dirObjects,auth/SecureRemotePassword/client) \
$(call makeObjects,auth/SecurityDatabase,LegacyClient.cpp) \ $(call makeObjects,auth/SecurityDatabase,LegacyClient.cpp) \
$(call dirObjects,plugins/crypt/arc4) $(call dirObjects,plugins/crypt/arc4)
@ -89,7 +93,8 @@ AllObjects += $(Profiler_Objects)
Engine_Objects:= $(call dirObjects,jrd) $(call dirObjects,dsql) $(call dirObjects,jrd/extds) \ Engine_Objects:= $(call dirObjects,jrd) $(call dirObjects,dsql) $(call dirObjects,jrd/extds) \
$(call dirObjects,jrd/optimizer) $(call dirObjects,jrd/recsrc) $(call dirObjects,jrd/replication) \ $(call dirObjects,jrd/optimizer) $(call dirObjects,jrd/recsrc) $(call dirObjects,jrd/replication) \
$(call dirObjects,jrd/sys-packages) $(call dirObjects,jrd/trace) \ $(call dirObjects,jrd/sys-packages) $(call dirObjects,jrd/trace) \
$(call makeObjects,lock,lock.cpp) $(call makeObjects,lock,lock.cpp) \
$(call dirObjects,supplement/trace)
Engine_Test_Objects:= $(call dirObjects,jrd/tests) Engine_Test_Objects:= $(call dirObjects,jrd/tests)

View File

@ -172,9 +172,10 @@
<ClCompile Include="..\..\..\src\jrd\trace\TraceCmdLine.cpp" /> <ClCompile Include="..\..\..\src\jrd\trace\TraceCmdLine.cpp" />
<ClCompile Include="..\..\..\src\jrd\trace\TraceConfigStorage.cpp" /> <ClCompile Include="..\..\..\src\jrd\trace\TraceConfigStorage.cpp" />
<ClCompile Include="..\..\..\src\jrd\trace\TraceLog.cpp" /> <ClCompile Include="..\..\..\src\jrd\trace\TraceLog.cpp" />
<ClCompile Include="..\..\..\src\jrd\trace\TraceManager.cpp" /> <ClCompile Include="..\..\..\src\supplement\trace\JrdTraceManager.cpp" />
<ClCompile Include="..\..\..\src\jrd\trace\TraceObjects.cpp" /> <ClCompile Include="..\..\..\src\jrd\trace\TraceObjects.cpp" />
<ClCompile Include="..\..\..\src\jrd\trace\TraceService.cpp" /> <ClCompile Include="..\..\..\src\jrd\trace\TraceService.cpp" />
<ClCompile Include="..\..\..\src\supplement\trace\TraceManager.cpp" />
<ClCompile Include="..\..\..\src\jrd\UserManagement.cpp" /> <ClCompile Include="..\..\..\src\jrd\UserManagement.cpp" />
<ClCompile Include="..\..\..\src\jrd\validation.cpp" /> <ClCompile Include="..\..\..\src\jrd\validation.cpp" />
<ClCompile Include="..\..\..\src\jrd\vio.cpp" /> <ClCompile Include="..\..\..\src\jrd\vio.cpp" />
@ -358,7 +359,7 @@
<ClInclude Include="..\..\..\src\jrd\trace\TraceDSQLHelpers.h" /> <ClInclude Include="..\..\..\src\jrd\trace\TraceDSQLHelpers.h" />
<ClInclude Include="..\..\..\src\jrd\trace\TraceJrdHelpers.h" /> <ClInclude Include="..\..\..\src\jrd\trace\TraceJrdHelpers.h" />
<ClInclude Include="..\..\..\src\jrd\trace\TraceLog.h" /> <ClInclude Include="..\..\..\src\jrd\trace\TraceLog.h" />
<ClInclude Include="..\..\..\src\jrd\trace\TraceManager.h" /> <ClInclude Include="..\..\..\src\supplement\trace\JrdTraceManager.h" />
<ClInclude Include="..\..\..\src\jrd\trace\TraceObjects.h" /> <ClInclude Include="..\..\..\src\jrd\trace\TraceObjects.h" />
<ClInclude Include="..\..\..\src\jrd\trace\TraceService.h" /> <ClInclude Include="..\..\..\src\jrd\trace\TraceService.h" />
<ClInclude Include="..\..\..\src\jrd\trace\TraceSession.h" /> <ClInclude Include="..\..\..\src\jrd\trace\TraceSession.h" />

View File

@ -198,7 +198,7 @@
<ClCompile Include="..\..\..\src\jrd\trace\TraceLog.cpp"> <ClCompile Include="..\..\..\src\jrd\trace\TraceLog.cpp">
<Filter>JRD files\Trace</Filter> <Filter>JRD files\Trace</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\jrd\trace\TraceManager.cpp"> <ClCompile Include="..\..\..\src\supplement\trace\JrdTraceManager.cpp">
<Filter>JRD files\Trace</Filter> <Filter>JRD files\Trace</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\jrd\trace\TraceObjects.cpp"> <ClCompile Include="..\..\..\src\jrd\trace\TraceObjects.cpp">
@ -207,6 +207,9 @@
<ClCompile Include="..\..\..\src\jrd\trace\TraceService.cpp"> <ClCompile Include="..\..\..\src\jrd\trace\TraceService.cpp">
<Filter>JRD files\Trace</Filter> <Filter>JRD files\Trace</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\supplement\trace\TraceManager.cpp">
<Filter>JRD files\Trace</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\jrd\VirtualTable.cpp"> <ClCompile Include="..\..\..\src\jrd\VirtualTable.cpp">
<Filter>JRD files</Filter> <Filter>JRD files</Filter>
</ClCompile> </ClCompile>
@ -656,7 +659,7 @@
<ClInclude Include="..\..\..\src\jrd\trace\TraceLog.h"> <ClInclude Include="..\..\..\src\jrd\trace\TraceLog.h">
<Filter>Header files</Filter> <Filter>Header files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\src\jrd\trace\TraceManager.h"> <ClInclude Include="..\..\..\src\supplement\trace\JrdTraceManager.h">
<Filter>Header files</Filter> <Filter>Header files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\src\jrd\trace\TraceObjects.h"> <ClInclude Include="..\..\..\src\jrd\trace\TraceObjects.h">

View File

@ -205,6 +205,9 @@
<ClCompile Include="..\..\..\src\remote\server\ReplServer.cpp" /> <ClCompile Include="..\..\..\src\remote\server\ReplServer.cpp" />
<ClCompile Include="..\..\..\src\jrd\replication\Config.cpp" /> <ClCompile Include="..\..\..\src\jrd\replication\Config.cpp" />
<ClCompile Include="..\..\..\src\jrd\replication\Utils.cpp" /> <ClCompile Include="..\..\..\src\jrd\replication\Utils.cpp" />
<ClCompile Include="..\..\..\src\supplement\trace\TraceManager.cpp" />
<ClCompile Include="..\..\..\src\jrd\trace\TraceConfigStorage.cpp" />
<ClCompile Include="..\..\..\src\jrd\trace\TraceLog.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\..\src\remote\server\os\win32\caution.ico" /> <None Include="..\..\..\src\remote\server\os\win32\caution.ico" />
@ -231,4 +234,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
</Project> </Project>

View File

@ -34,6 +34,15 @@
<ClCompile Include="..\..\..\src\remote\server\os\win32\srvr_w32.cpp"> <ClCompile Include="..\..\..\src\remote\server\os\win32\srvr_w32.cpp">
<Filter>Remote server</Filter> <Filter>Remote server</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\supplement\trace\TraceManager.cpp">
<Filter>Remote server</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\jrd\trace\TraceConfigStorage.cpp">
<Filter>Remote server</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\jrd\trace\TraceLog.cpp">
<Filter>Remote server</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\auth\SecureRemotePassword\server\SrpServer.cpp"> <ClCompile Include="..\..\..\src\auth\SecureRemotePassword\server\SrpServer.cpp">
<Filter>AUTH files</Filter> <Filter>AUTH files</Filter>
</ClCompile> </ClCompile>
@ -68,4 +77,4 @@
<Filter>AUTH files</Filter> <Filter>AUTH files</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -23,7 +23,7 @@
#include "firebird.h" #include "firebird.h"
#include "../common/classes/ClumpletWriter.h" #include "../common/classes/ClumpletWriter.h"
#include "../jrd/tra_proto.h" #include "../jrd/tra_proto.h"
#include "../jrd/trace/TraceManager.h" #include "../supplement/trace/JrdTraceManager.h"
#include "../jrd/trace/TraceDSQLHelpers.h" #include "../jrd/trace/TraceDSQLHelpers.h"
#include "../dsql/dsql_proto.h" #include "../dsql/dsql_proto.h"
@ -86,10 +86,10 @@ void DsqlCursor::close(thread_db* tdbb, DsqlCursor* cursor)
trace.fetch(true, ITracePlugin::RESULT_SUCCESS); trace.fetch(true, ITracePlugin::RESULT_SUCCESS);
} }
if (dsqlRequest->req_traced && TraceManager::need_dsql_free(attachment)) if (dsqlRequest->req_traced && JrdTraceManager::need_dsql_free(attachment))
{ {
TraceSQLStatementImpl stmt(dsqlRequest, NULL); TraceSQLStatementImpl stmt(dsqlRequest, NULL);
TraceManager::event_dsql_free(attachment, &stmt, DSQL_close); JrdTraceManager::event_dsql_free(attachment, &stmt, DSQL_close);
} }
JRD_unwind_request(tdbb, dsqlRequest->getRequest()); JRD_unwind_request(tdbb, dsqlRequest->getRequest());

View File

@ -200,11 +200,11 @@ void DsqlRequest::destroy(thread_db* tdbb, DsqlRequest* dsqlRequest)
} }
Jrd::Attachment* att = dsqlRequest->req_dbb->dbb_attachment; Jrd::Attachment* att = dsqlRequest->req_dbb->dbb_attachment;
const bool need_trace_free = dsqlRequest->req_traced && TraceManager::need_dsql_free(att); const bool need_trace_free = dsqlRequest->req_traced && JrdTraceManager::need_dsql_free(att);
if (need_trace_free) if (need_trace_free)
{ {
TraceSQLStatementImpl stmt(dsqlRequest, NULL); TraceSQLStatementImpl stmt(dsqlRequest, NULL);
TraceManager::event_dsql_free(att, &stmt, DSQL_drop); JrdTraceManager::event_dsql_free(att, &stmt, DSQL_drop);
} }
if (dsqlRequest->req_cursor_name.hasData()) if (dsqlRequest->req_cursor_name.hasData())
@ -818,7 +818,7 @@ void DsqlDmlRequest::executeReceiveWithRestarts(thread_db* tdbb, jrd_tra** traHa
"\tQuery:\n%s\n", numTries, request->getStatement()->sqlText->c_str() ); "\tQuery:\n%s\n", numTries, request->getStatement()->sqlText->c_str() );
} }
TraceManager::event_dsql_restart(req_dbb->dbb_attachment, req_transaction, this, numTries); JrdTraceManager::event_dsql_restart(req_dbb->dbb_attachment, req_transaction, this, numTries);
// When restart we must execute query // When restart we must execute query
exec = true; exec = true;

View File

@ -61,7 +61,7 @@
#include "../dsql/DSqlDataTypeUtil.h" #include "../dsql/DSqlDataTypeUtil.h"
#include "../jrd/DataTypeUtil.h" #include "../jrd/DataTypeUtil.h"
#include "../jrd/Collation.h" #include "../jrd/Collation.h"
#include "../jrd/trace/TraceManager.h" #include "../supplement/trace/JrdTraceManager.h"
#include "../jrd/trace/TraceObjects.h" #include "../jrd/trace/TraceObjects.h"
#include "../jrd/trace/TraceJrdHelpers.h" #include "../jrd/trace/TraceJrdHelpers.h"

View File

@ -41,7 +41,7 @@
#include "../jrd/recsrc/RecordSource.h" #include "../jrd/recsrc/RecordSource.h"
#include "../jrd/recsrc/Cursor.h" #include "../jrd/recsrc/Cursor.h"
#include "../jrd/replication/Publisher.h" #include "../jrd/replication/Publisher.h"
#include "../jrd/trace/TraceManager.h" #include "../supplement/trace/JrdTraceManager.h"
#include "../jrd/trace/TraceJrdHelpers.h" #include "../jrd/trace/TraceJrdHelpers.h"
#include "../jrd/cmp_proto.h" #include "../jrd/cmp_proto.h"
#include "../jrd/dfw_proto.h" #include "../jrd/dfw_proto.h"

View File

@ -66,7 +66,7 @@
#include "../jrd/optimizer/Optimizer.h" #include "../jrd/optimizer/Optimizer.h"
#include "../jrd/recsrc/RecordSource.h" #include "../jrd/recsrc/RecordSource.h"
#include "../jrd/replication/Publisher.h" #include "../jrd/replication/Publisher.h"
#include "../jrd/trace/TraceManager.h" #include "../supplement/trace/JrdTraceManager.h"
#include "../jrd/trace/TraceDSQLHelpers.h" #include "../jrd/trace/TraceDSQLHelpers.h"
#include "../common/classes/init.h" #include "../common/classes/init.h"
#include "../common/utils_proto.h" #include "../common/utils_proto.h"

View File

@ -28,7 +28,7 @@
#include "../jrd/Database.h" #include "../jrd/Database.h"
#include "../jrd/Function.h" #include "../jrd/Function.h"
#include "../jrd/nbak.h" #include "../jrd/nbak.h"
#include "../jrd/trace/TraceManager.h" #include "../supplement/trace/JrdTraceManager.h"
#include "../jrd/PreparedStatement.h" #include "../jrd/PreparedStatement.h"
#include "../jrd/tra.h" #include "../jrd/tra.h"
#include "../jrd/intl.h" #include "../jrd/intl.h"
@ -252,7 +252,7 @@ Jrd::Attachment::Attachment(MemoryPool* pool, Database* dbb, JProvider* provider
att_ext_connection(NULL), att_ext_connection(NULL),
att_ext_parent(NULL), att_ext_parent(NULL),
att_ext_call_depth(0), att_ext_call_depth(0),
att_trace_manager(FB_NEW_POOL(*att_pool) TraceManager(this)), att_trace_manager(FB_NEW_POOL(*att_pool) JrdTraceManager(this)),
att_bindings(*pool), att_bindings(*pool),
att_dest_bind(&att_bindings), att_dest_bind(&att_bindings),
att_original_timezone(TimeZoneUtil::getSystemTimeZone()), att_original_timezone(TimeZoneUtil::getSystemTimeZone()),

View File

@ -92,7 +92,7 @@ namespace Jrd
class jrd_fld; class jrd_fld;
class dsql_dbb; class dsql_dbb;
class PreparedStatement; class PreparedStatement;
class TraceManager; class JrdTraceManager;
template <typename T> class vec; template <typename T> class vec;
class jrd_rel; class jrd_rel;
class jrd_prc; class jrd_prc;
@ -636,7 +636,7 @@ public:
EDS::Connection* att_ext_connection; // external connection executed by this attachment EDS::Connection* att_ext_connection; // external connection executed by this attachment
EDS::Connection* att_ext_parent; // external connection, parent of this attachment EDS::Connection* att_ext_parent; // external connection, parent of this attachment
ULONG att_ext_call_depth; // external connection call depth, 0 for user attachment ULONG att_ext_call_depth; // external connection call depth, 0 for user attachment
TraceManager* att_trace_manager; // Trace API manager JrdTraceManager* att_trace_manager; // Trace API manager
CoercionArray att_bindings; CoercionArray att_bindings;
CoercionArray* att_dest_bind; CoercionArray* att_dest_bind;

View File

@ -54,7 +54,7 @@
#include "../jrd/scl_proto.h" #include "../jrd/scl_proto.h"
#include "../common/os/guid.h" #include "../common/os/guid.h"
#include "../jrd/license.h" #include "../jrd/license.h"
#include "../jrd/trace/TraceManager.h" #include "../supplement/trace/JrdTraceManager.h"
#include "../jrd/trace/TraceObjects.h" #include "../jrd/trace/TraceObjects.h"
#include "../jrd/Collation.h" #include "../jrd/Collation.h"
#include "../common/classes/FpeControl.h" #include "../common/classes/FpeControl.h"

View File

@ -102,7 +102,7 @@
#include "../jrd/rpb_chain.h" #include "../jrd/rpb_chain.h"
#include "../jrd/RecordSourceNodes.h" #include "../jrd/RecordSourceNodes.h"
#include "../jrd/VirtualTable.h" #include "../jrd/VirtualTable.h"
#include "../jrd/trace/TraceManager.h" #include "../supplement/trace/JrdTraceManager.h"
#include "../jrd/trace/TraceJrdHelpers.h" #include "../jrd/trace/TraceJrdHelpers.h"
#include "../dsql/Nodes.h" #include "../dsql/Nodes.h"

View File

@ -120,7 +120,7 @@
#include "../common/db_alias.h" #include "../common/db_alias.h"
#include "../jrd/replication/Publisher.h" #include "../jrd/replication/Publisher.h"
#include "../jrd/replication/Applier.h" #include "../jrd/replication/Applier.h"
#include "../jrd/trace/TraceManager.h" #include "../supplement/trace/JrdTraceManager.h"
#include "../jrd/trace/TraceObjects.h" #include "../jrd/trace/TraceObjects.h"
#include "../jrd/trace/TraceJrdHelpers.h" #include "../jrd/trace/TraceJrdHelpers.h"
#include "../jrd/IntlManager.h" #include "../jrd/IntlManager.h"
@ -1565,7 +1565,7 @@ static void trace_failed_attach(const char* filename, const DatabaseOptions& opt
const char* func = flags & UNWIND_CREATE ? "JProvider::createDatabase" : "JProvider::attachDatabase"; const char* func = flags & UNWIND_CREATE ? "JProvider::createDatabase" : "JProvider::attachDatabase";
// Perform actual trace // Perform actual trace
TraceManager tempMgr(origFilename, callback, flags & UNWIND_NEW); JrdTraceManager tempMgr(origFilename, callback, flags & UNWIND_NEW);
if (tempMgr.needs(ITraceFactory::TRACE_EVENT_ATTACH)) if (tempMgr.needs(ITraceFactory::TRACE_EVENT_ATTACH))
tempMgr.event_attach(&conn, flags & UNWIND_CREATE, result); tempMgr.event_attach(&conn, flags & UNWIND_CREATE, result);
@ -4696,9 +4696,9 @@ void JProvider::shutdown(CheckStatusWrapper* status, unsigned int timeout, const
shutdown_thread(NULL); shutdown_thread(NULL);
} }
// Do not put it into separate shutdown thread - during shutdown of TraceManager // Do not put it into separate shutdown thread - during shutdown of JrdTraceManager
// PluginManager wants to lock a mutex, which is sometimes already locked in current thread // PluginManager wants to lock a mutex, which is sometimes already locked in current thread
TraceManager::shutdown(); JrdTraceManager::shutdown();
Mapping::shutdownIpc(); Mapping::shutdownIpc();
} }
@ -8701,7 +8701,7 @@ static void unwindAttach(thread_db* tdbb, const char* filename, const Exception&
try try
{ {
const auto att = tdbb->getAttachment(); const auto att = tdbb->getAttachment();
TraceManager* traceManager = att ? att->att_trace_manager : nullptr; JrdTraceManager* traceManager = att ? att->att_trace_manager : nullptr;
if (att && traceManager && traceManager->isActive()) if (att && traceManager && traceManager->isActive())
{ {
TraceConnectionImpl conn(att); TraceConnectionImpl conn(att);
@ -8766,7 +8766,7 @@ static void unwindAttach(thread_db* tdbb, const char* filename, const Exception&
sAtt->manualLock(flags); sAtt->manualLock(flags);
if (sAtt->getHandle()) if (sAtt->getHandle())
{ {
TraceManager* traceManager = attachment->att_trace_manager; JrdTraceManager* traceManager = attachment->att_trace_manager;
TraceConnectionImpl conn(attachment); TraceConnectionImpl conn(attachment);
if (traceManager->needs(ITraceFactory::TRACE_EVENT_DETACH)) if (traceManager->needs(ITraceFactory::TRACE_EVENT_DETACH))

View File

@ -129,7 +129,7 @@ class Parameter;
class jrd_fld; class jrd_fld;
class dsql_dbb; class dsql_dbb;
class PreparedStatement; class PreparedStatement;
class TraceManager; class JrdTraceManager;
class MessageNode; class MessageNode;

View File

@ -27,7 +27,7 @@
#include "../jrd/exe_proto.h" #include "../jrd/exe_proto.h"
#include "../jrd/mov_proto.h" #include "../jrd/mov_proto.h"
#include "../jrd/vio_proto.h" #include "../jrd/vio_proto.h"
#include "../jrd/trace/TraceManager.h" #include "../supplement/trace/JrdTraceManager.h"
#include "../jrd/trace/TraceJrdHelpers.h" #include "../jrd/trace/TraceJrdHelpers.h"
#include "../jrd/optimizer/Optimizer.h" #include "../jrd/optimizer/Optimizer.h"

View File

@ -56,7 +56,7 @@
#include "../common/db_alias.h" #include "../common/db_alias.h"
#include "../jrd/scl.h" #include "../jrd/scl.h"
#include "../common/msg_encode.h" #include "../common/msg_encode.h"
#include "../jrd/trace/TraceManager.h" #include "../supplement/trace/JrdTraceManager.h"
#include "../jrd/trace/TraceObjects.h" #include "../jrd/trace/TraceObjects.h"
#include "../jrd/EngineInterface.h" #include "../jrd/EngineInterface.h"
#include "../jrd/Mapping.h" #include "../jrd/Mapping.h"
@ -739,7 +739,7 @@ Service::Service(const TEXT* service_name, USHORT spb_length, const UCHAR* spb_d
#ifdef DEV_BUILD #ifdef DEV_BUILD
if (svc_debug) if (svc_debug)
{ {
svc_trace_manager = FB_NEW_POOL(*getDefaultMemoryPool()) TraceManager(this); svc_trace_manager = FB_NEW_POOL(*getDefaultMemoryPool()) JrdTraceManager(this);
svc_user_flag = SVC_user_dba; svc_user_flag = SVC_user_dba;
return; return;
} }
@ -803,11 +803,11 @@ Service::Service(const TEXT* service_name, USHORT spb_length, const UCHAR* spb_d
svc_perm_sw = switches; svc_perm_sw = switches;
svc_user_flag = user_flag; svc_user_flag = user_flag;
svc_trace_manager = FB_NEW_POOL(*getDefaultMemoryPool()) TraceManager(this); svc_trace_manager = FB_NEW_POOL(*getDefaultMemoryPool()) JrdTraceManager(this);
} // try } // try
catch (const Firebird::Exception& ex) catch (const Firebird::Exception& ex)
{ {
TraceManager* trace_manager = NULL; JrdTraceManager* trace_manager = NULL;
FbLocalStatus status_vector; FbLocalStatus status_vector;
try try
@ -817,7 +817,7 @@ Service::Service(const TEXT* service_name, USHORT spb_length, const UCHAR* spb_d
if (hasTrace) if (hasTrace)
trace_manager = svc_trace_manager; trace_manager = svc_trace_manager;
else else
trace_manager = FB_NEW_POOL(*getDefaultMemoryPool()) TraceManager(this); trace_manager = FB_NEW_POOL(*getDefaultMemoryPool()) JrdTraceManager(this);
if (trace_manager->needs(ITraceFactory::TRACE_EVENT_SERVICE_ATTACH)) if (trace_manager->needs(ITraceFactory::TRACE_EVENT_SERVICE_ATTACH))
{ {

View File

@ -102,7 +102,7 @@ const int SVC_cmd_line = 0x80;
// forward decl. // forward decl.
class thread_db; class thread_db;
class TraceManager; class JrdTraceManager;
// Service manager // Service manager
class Service : public Firebird::UtilSvc, public TypedHandle<type_svc> class Service : public Firebird::UtilSvc, public TypedHandle<type_svc>
@ -151,7 +151,7 @@ public:
Firebird::ICryptKeyCallback* getCryptCallback() override; Firebird::ICryptKeyCallback* getCryptCallback() override;
int getParallelWorkers() override { return svc_parallel_workers; } int getParallelWorkers() override { return svc_parallel_workers; }
TraceManager* getTraceManager() virtual JrdTraceManager* getTraceManager()
{ {
return svc_trace_manager; return svc_trace_manager;
} }
@ -336,7 +336,7 @@ private:
Firebird::string svc_remote_process; Firebird::string svc_remote_process;
SLONG svc_remote_pid; SLONG svc_remote_pid;
TraceManager* svc_trace_manager; JrdTraceManager* svc_trace_manager;
Firebird::ICryptKeyCallback* svc_crypt_callback; Firebird::ICryptKeyCallback* svc_crypt_callback;
public: public:

View File

@ -69,7 +69,7 @@
#include "../dsql/dsql_proto.h" #include "../dsql/dsql_proto.h"
#include "../common/StatusArg.h" #include "../common/StatusArg.h"
#include "../jrd/replication/Publisher.h" #include "../jrd/replication/Publisher.h"
#include "../jrd/trace/TraceManager.h" #include "../supplement/trace/JrdTraceManager.h"
#include "../jrd/trace/TraceJrdHelpers.h" #include "../jrd/trace/TraceJrdHelpers.h"
#include "../jrd/Function.h" #include "../jrd/Function.h"
#include "../jrd/Collation.h" #include "../jrd/Collation.h"
@ -4183,7 +4183,7 @@ TraceSweepEvent::TraceSweepEvent(thread_db* tdbb)
m_sweep_info.getOST(), m_sweep_info.getOST(),
m_sweep_info.getNext()); m_sweep_info.getNext());
TraceManager* trace_mgr = att->att_trace_manager; JrdTraceManager* trace_mgr = att->att_trace_manager;
m_start_clock = fb_utils::query_performance_counter(); m_start_clock = fb_utils::query_performance_counter();
m_need_trace = trace_mgr->needs(ITraceFactory::TRACE_EVENT_SWEEP); m_need_trace = trace_mgr->needs(ITraceFactory::TRACE_EVENT_SWEEP);
@ -4250,7 +4250,7 @@ void TraceSweepEvent::endSweepRelation(jrd_rel* relation)
m_sweep_info.setPerf(stats.getPerf()); m_sweep_info.setPerf(stats.getPerf());
TraceConnectionImpl conn(att); TraceConnectionImpl conn(att);
TraceManager* trace_mgr = att->att_trace_manager; JrdTraceManager* trace_mgr = att->att_trace_manager;
trace_mgr->event_sweep(&conn, &m_sweep_info, ITracePlugin::SWEEP_STATE_PROGRESS); trace_mgr->event_sweep(&conn, &m_sweep_info, ITracePlugin::SWEEP_STATE_PROGRESS);
} }
@ -4282,7 +4282,7 @@ void TraceSweepEvent::report(ntrace_process_state_t state)
return; return;
Database* dbb = m_tdbb->getDatabase(); Database* dbb = m_tdbb->getDatabase();
TraceManager* trace_mgr = att->att_trace_manager; JrdTraceManager* trace_mgr = att->att_trace_manager;
TraceConnectionImpl conn(att); TraceConnectionImpl conn(att);

View File

@ -33,10 +33,12 @@
#include "../../jrd/err_proto.h" #include "../../jrd/err_proto.h"
#include "../../common/isc_proto.h" #include "../../common/isc_proto.h"
#include "../../common/isc_s_proto.h" #include "../../common/isc_s_proto.h"
#include "../../jrd/jrd.h"
#include "../../common/os/path_utils.h" #include "../../common/os/path_utils.h"
#include "../../common/os/os_utils.h" #include "../../common/os/os_utils.h"
#include "../../jrd/trace/TraceConfigStorage.h" #include "../../jrd/trace/TraceConfigStorage.h"
#include "../../common/file_params.h"
#include "../../common/config/config.h"
#include "../../common/status.h"
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>

View File

@ -28,7 +28,7 @@
#ifndef JRD_TRACE_DSQL_HELPERS_H #ifndef JRD_TRACE_DSQL_HELPERS_H
#define JRD_TRACE_DSQL_HELPERS_H #define JRD_TRACE_DSQL_HELPERS_H
#include "../../jrd/trace/TraceManager.h" #include "../../supplement/trace/JrdTraceManager.h"
#include "../../jrd/trace/TraceObjects.h" #include "../../jrd/trace/TraceObjects.h"
namespace Jrd { namespace Jrd {
@ -47,7 +47,7 @@ public:
m_string_len(string_length), m_string_len(string_length),
m_string(string) m_string(string)
{ {
m_need_trace = !isInternal && TraceManager::need_dsql_prepare(m_attachment); m_need_trace = !isInternal && JrdTraceManager::need_dsql_prepare(m_attachment);
if (!m_need_trace) if (!m_need_trace)
return; return;
@ -86,14 +86,14 @@ public:
if ((result == ITracePlugin::RESULT_SUCCESS) && m_request) if ((result == ITracePlugin::RESULT_SUCCESS) && m_request)
{ {
TraceSQLStatementImpl stmt(m_request, NULL); TraceSQLStatementImpl stmt(m_request, NULL);
TraceManager::event_dsql_prepare(m_attachment, m_transaction, &stmt, millis, result); JrdTraceManager::event_dsql_prepare(m_attachment, m_transaction, &stmt, millis, result);
} }
else else
{ {
Firebird::string str(*getDefaultMemoryPool(), m_string, m_string_len); Firebird::string str(*getDefaultMemoryPool(), m_string, m_string_len);
TraceFailedSQLStatement stmt(str); TraceFailedSQLStatement stmt(str);
TraceManager::event_dsql_prepare(m_attachment, m_transaction, &stmt, millis, result); JrdTraceManager::event_dsql_prepare(m_attachment, m_transaction, &stmt, millis, result);
} }
} }
@ -115,13 +115,13 @@ public:
m_attachment(attachment), m_attachment(attachment),
m_dsqlRequest(dsqlRequest) m_dsqlRequest(dsqlRequest)
{ {
m_need_trace = m_dsqlRequest->req_traced && TraceManager::need_dsql_execute(m_attachment); m_need_trace = m_dsqlRequest->req_traced && JrdTraceManager::need_dsql_execute(m_attachment);
if (!m_need_trace) if (!m_need_trace)
return; return;
{ // scope { // scope
TraceSQLStatementImpl stmt(dsqlRequest, NULL); TraceSQLStatementImpl stmt(dsqlRequest, NULL);
TraceManager::event_dsql_execute(m_attachment, dsqlRequest->req_transaction, &stmt, true, JrdTraceManager::event_dsql_execute(m_attachment, dsqlRequest->req_transaction, &stmt, true,
ITracePlugin::RESULT_SUCCESS); ITracePlugin::RESULT_SUCCESS);
} }
@ -157,7 +157,7 @@ public:
m_dsqlRequest->req_fetch_rowcount); m_dsqlRequest->req_fetch_rowcount);
TraceSQLStatementImpl stmt(m_dsqlRequest, stats.getPerf()); TraceSQLStatementImpl stmt(m_dsqlRequest, stats.getPerf());
TraceManager::event_dsql_execute(m_attachment, m_dsqlRequest->req_transaction, &stmt, false, result); JrdTraceManager::event_dsql_execute(m_attachment, m_dsqlRequest->req_transaction, &stmt, false, result);
m_dsqlRequest->req_fetch_baseline = NULL; m_dsqlRequest->req_fetch_baseline = NULL;
} }
@ -181,7 +181,7 @@ public:
m_attachment(attachment), m_attachment(attachment),
m_dsqlRequest(request) m_dsqlRequest(request)
{ {
m_need_trace = m_dsqlRequest->req_traced && TraceManager::need_dsql_execute(m_attachment) && m_need_trace = m_dsqlRequest->req_traced && JrdTraceManager::need_dsql_execute(m_attachment) &&
m_dsqlRequest->getRequest() && (m_dsqlRequest->getRequest()->req_flags & req_active); m_dsqlRequest->getRequest() && (m_dsqlRequest->getRequest()->req_flags & req_active);
if (!m_need_trace) if (!m_need_trace)
@ -217,7 +217,7 @@ public:
TraceSQLStatementImpl stmt(m_dsqlRequest, stats.getPerf()); TraceSQLStatementImpl stmt(m_dsqlRequest, stats.getPerf());
TraceManager::event_dsql_execute(m_attachment, m_dsqlRequest->req_transaction, JrdTraceManager::event_dsql_execute(m_attachment, m_dsqlRequest->req_transaction,
&stmt, false, result); &stmt, false, result);
m_dsqlRequest->req_fetch_elapsed = 0; m_dsqlRequest->req_fetch_elapsed = 0;

View File

@ -29,7 +29,7 @@
#define JRD_TRACE_JRD_HELPERS_H #define JRD_TRACE_JRD_HELPERS_H
#include "../../jrd/jrd.h" #include "../../jrd/jrd.h"
#include "../../jrd/trace/TraceManager.h" #include "../../supplement/trace/JrdTraceManager.h"
#include "../../jrd/trace/TraceObjects.h" #include "../../jrd/trace/TraceObjects.h"
namespace Jrd { namespace Jrd {
@ -616,7 +616,7 @@ public:
m_start_clock = (fb_utils::query_performance_counter() - m_start_clock) * 1000 / m_start_clock = (fb_utils::query_performance_counter() - m_start_clock) * 1000 /
fb_utils::query_performance_frequency(); fb_utils::query_performance_frequency();
TraceManager* trace_mgr = m_tdbb->getAttachment()->att_trace_manager; JrdTraceManager* trace_mgr = m_tdbb->getAttachment()->att_trace_manager;
TraceConnectionImpl conn(m_tdbb->getAttachment()); TraceConnectionImpl conn(m_tdbb->getAttachment());
TraceTransactionImpl tran(m_tdbb->getTransaction()); TraceTransactionImpl tran(m_tdbb->getTransaction());
@ -691,7 +691,7 @@ public:
TraceTransactionImpl tran(m_tdbb->getTransaction()); TraceTransactionImpl tran(m_tdbb->getTransaction());
TraceBLRStatementImpl stmt(m_request->getStatement(), stats.getPerf()); TraceBLRStatementImpl stmt(m_request->getStatement(), stats.getPerf());
TraceManager* trace_mgr = m_tdbb->getAttachment()->att_trace_manager; JrdTraceManager* trace_mgr = m_tdbb->getAttachment()->att_trace_manager;
trace_mgr->event_blr_execute(&conn, &tran, &stmt, result); trace_mgr->event_blr_execute(&conn, &tran, &stmt, result);
m_request->req_fetch_baseline = NULL; m_request->req_fetch_baseline = NULL;

View File

@ -29,7 +29,7 @@
#include "../../common/classes/auto.h" #include "../../common/classes/auto.h"
#include "../../common/utils_proto.h" #include "../../common/utils_proto.h"
#include "../../jrd/trace/TraceManager.h" #include "../../supplement/trace/JrdTraceManager.h"
#include "../../jrd/trace/TraceLog.h" #include "../../jrd/trace/TraceLog.h"
#include "../../jrd/trace/TraceObjects.h" #include "../../jrd/trace/TraceObjects.h"
#include "../../common/isc_proto.h" #include "../../common/isc_proto.h"
@ -475,73 +475,6 @@ void TraceDscFromMsg::fillParams()
} }
/// TraceLogWriterImpl
class TraceLogWriterImpl final :
public RefCntIface<ITraceLogWriterImpl<TraceLogWriterImpl, CheckStatusWrapper> >
{
public:
TraceLogWriterImpl(const TraceSession& session) :
m_log(getPool(), session.ses_logfile, false),
m_sesId(session.ses_id)
{
string s;
s.printf("\n--- Session %d is suspended as its log is full ---\n", session.ses_id);
m_log.setFullMsg(s.c_str());
}
// TraceLogWriter implementation
FB_SIZE_T write(const void* buf, FB_SIZE_T size);
FB_SIZE_T write_s(CheckStatusWrapper* status, const void* buf, FB_SIZE_T size);
private:
TraceLog m_log;
ULONG m_sesId;
};
FB_SIZE_T TraceLogWriterImpl::write(const void* buf, FB_SIZE_T size)
{
const FB_SIZE_T written = m_log.write(buf, size);
if (written == size)
return size;
if (!m_log.isFull())
return written;
ConfigStorage* storage = TraceManager::getStorage();
StorageGuard guard(storage);
TraceSession session(*getDefaultMemoryPool());
session.ses_id = m_sesId;
if (storage->getSession(session, ConfigStorage::FLAGS))
{
if (!(session.ses_flags & trs_log_full))
{
// suspend session
session.ses_flags |= trs_log_full;
storage->updateFlags(session);
}
}
// report successful write
return size;
}
FB_SIZE_T TraceLogWriterImpl::write_s(CheckStatusWrapper* status, const void* buf, FB_SIZE_T size)
{
try
{
return write(buf, size);
}
catch (Exception &ex)
{
ex.stuffException(status);
}
return 0;
}
/// TraceInitInfoImpl /// TraceInitInfoImpl
const char* TraceInitInfoImpl::getFirebirdRootDirectory() const char* TraceInitInfoImpl::getFirebirdRootDirectory()
@ -553,7 +486,7 @@ ITraceLogWriter* TraceInitInfoImpl::getLogWriter()
{ {
if (!m_logWriter && !m_session.ses_logfile.empty()) if (!m_logWriter && !m_session.ses_logfile.empty())
{ {
m_logWriter = FB_NEW TraceLogWriterImpl(m_session); m_logWriter = TraceManager::createSessionLogWriter(m_session);
} }
if (m_logWriter) if (m_logWriter)
{ {

View File

@ -37,7 +37,7 @@
#include "../../jrd/svc.h" #include "../../jrd/svc.h"
#include "../../common/os/guid.h" #include "../../common/os/guid.h"
#include "../../jrd/trace/TraceLog.h" #include "../../jrd/trace/TraceLog.h"
#include "../../jrd/trace/TraceManager.h" #include "../../supplement/trace/JrdTraceManager.h"
#include "../../jrd/trace/TraceService.h" #include "../../jrd/trace/TraceService.h"
#include "../../jrd/scl.h" #include "../../jrd/scl.h"
#include "../../jrd/Mapping.h" #include "../../jrd/Mapping.h"
@ -103,7 +103,7 @@ void TraceSvcJrd::setAttachInfo(const string& /*svc_name*/, const string& user,
void TraceSvcJrd::startSession(TraceSession& session, bool interactive) void TraceSvcJrd::startSession(TraceSession& session, bool interactive)
{ {
if (!TraceManager::pluginsCount()) if (!JrdTraceManager::pluginsCount())
{ {
m_svc.printf(false, "Can not start trace session. There are no trace plugins loaded\n"); m_svc.printf(false, "Can not start trace session. There are no trace plugins loaded\n");
return; return;
@ -148,7 +148,7 @@ void TraceSvcJrd::stopSession(ULONG id)
{ {
m_svc.started(); m_svc.started();
ConfigStorage* storage = TraceManager::getStorage(); ConfigStorage* storage = JrdTraceManager::getStorage();
StorageGuard guard(storage); StorageGuard guard(storage);
TraceSession session(*getDefaultMemoryPool()); TraceSession session(*getDefaultMemoryPool());
@ -187,7 +187,7 @@ void TraceSvcJrd::setActive(ULONG id, bool active)
bool TraceSvcJrd::changeFlags(ULONG id, int setFlags, int clearFlags) bool TraceSvcJrd::changeFlags(ULONG id, int setFlags, int clearFlags)
{ {
ConfigStorage* storage = TraceManager::getStorage(); ConfigStorage* storage = JrdTraceManager::getStorage();
StorageGuard guard(storage); StorageGuard guard(storage);
TraceSession session(*getDefaultMemoryPool()); TraceSession session(*getDefaultMemoryPool());
@ -219,7 +219,7 @@ void TraceSvcJrd::listSessions()
{ {
m_svc.started(); m_svc.started();
ConfigStorage* storage = TraceManager::getStorage(); ConfigStorage* storage = JrdTraceManager::getStorage();
StorageGuard guard(storage); StorageGuard guard(storage);
storage->restart(); storage->restart();
@ -307,7 +307,7 @@ void TraceSvcJrd::readSession(TraceSession& session)
bool TraceSvcJrd::checkAliveAndFlags(ULONG sesId, int& flags) bool TraceSvcJrd::checkAliveAndFlags(ULONG sesId, int& flags)
{ {
ConfigStorage* storage = TraceManager::getStorage(); ConfigStorage* storage = JrdTraceManager::getStorage();
bool alive = (m_chg_number == storage->getChangeNumber()); bool alive = (m_chg_number == storage->getChangeNumber());
if (!alive) if (!alive)

View File

@ -88,7 +88,7 @@
#include "../common/StatusArg.h" #include "../common/StatusArg.h"
#include "../jrd/GarbageCollector.h" #include "../jrd/GarbageCollector.h"
#include "../jrd/ProfilerManager.h" #include "../jrd/ProfilerManager.h"
#include "../jrd/trace/TraceManager.h" #include "../supplement/trace/JrdTraceManager.h"
#include "../jrd/trace/TraceJrdHelpers.h" #include "../jrd/trace/TraceJrdHelpers.h"
#include "../common/Task.h" #include "../common/Task.h"
#include "../jrd/WorkerAttachment.h" #include "../jrd/WorkerAttachment.h"

View File

@ -75,6 +75,13 @@
#include "../common/os/os_utils.h" #include "../common/os/os_utils.h"
#include "../common/security.h" #include "../common/security.h"
#include "../supplement/trace/TraceManager.h"
#include "../common/db_alias.h"
#ifdef WIN_NT
#include <process.h>
#define getpid _getpid
#endif
using namespace Firebird; using namespace Firebird;
@ -431,6 +438,151 @@ public:
} }
}; };
// For Trace
class TraceFailedAuthImpl :
public Firebird::AutoIface<Firebird::ITraceDatabaseConnectionImpl<TraceFailedAuthImpl, Firebird::CheckStatusWrapper> >
{
public:
TraceFailedAuthImpl() :
filename(NULL),
userName(*getDefaultMemoryPool()),
roleName(*getDefaultMemoryPool()),
charSet(*getDefaultMemoryPool()),
networkProtocol(*getDefaultMemoryPool()),
remoteAddress(*getDefaultMemoryPool()),
remotePid(0),
processName(*getDefaultMemoryPool()),
hasUtf8(false)
{ }
void setData(const UCHAR* dpb, USHORT dpb_length)
{
ClumpletReader rdr(ClumpletReader::dpbList, dpb, dpb_length);
dumpAuthBlock("TraceFailedAuthImpl::setData()", &rdr, isc_dpb_auth_block);
hasUtf8 = rdr.find(isc_dpb_utf8_filename);
for (rdr.rewind(); !rdr.isEof(); rdr.moveNext())
{
switch (rdr.getClumpTag())
{
case isc_dpb_user_name:
getString(rdr, userName);
break;
case isc_dpb_sql_role_name:
getString(rdr, roleName);
break;
case isc_dpb_set_db_charset:
getString(rdr, charSet);
fb_utils::dpbItemUpper(charSet);
break;
case isc_dpb_address_path:
{
ClumpletReader address_stack(ClumpletReader::UnTagged,
rdr.getBytes(), rdr.getClumpLength());
while (!address_stack.isEof())
{
if (address_stack.getClumpTag() != isc_dpb_address)
{
address_stack.moveNext();
continue;
}
ClumpletReader address(ClumpletReader::UnTagged,
address_stack.getBytes(), address_stack.getClumpLength());
while (!address.isEof())
{
switch (address.getClumpTag())
{
case isc_dpb_addr_protocol:
address.getString(networkProtocol);
break;
case isc_dpb_addr_endpoint:
address.getString(remoteAddress);
break;
default:
break;
}
address.moveNext();
}
break; // While
}
break; // Case
}
case isc_dpb_process_id:
remotePid = rdr.getInt();
break;
case isc_dpb_process_name:
getPath(rdr, processName);
break;
}
}
}
bool hasUtf8InDpb()
{
return hasUtf8;
}
void setFilename(const char* filename)
{
this->filename = filename;
}
unsigned getKind() { return KIND_DATABASE; };
int getProcessID() { return getpid(); }
const char* getUserName() { return userName.c_str(); }
const char* getRoleName() { return roleName.c_str(); }
const char* getCharSet() { return charSet.c_str(); }
const char* getRemoteProtocol() { return networkProtocol.c_str(); }
const char* getRemoteAddress() { return remoteAddress.c_str(); }
int getRemoteProcessID() { return remotePid; }
const char* getRemoteProcessName() { return processName.c_str(); }
// TraceDatabaseConnection implementation
ISC_INT64 getConnectionID() { return 0; }
const char* getDatabaseName() { return filename; }
private:
void getPath(ClumpletReader& reader, PathName& s)
{
reader.getPath(s);
if (!hasUtf8)
ISC_systemToUtf8(s);
ISC_unescape(s);
}
void getString(ClumpletReader& reader, string& s)
{
reader.getString(s);
if (!hasUtf8)
ISC_systemToUtf8(s);
ISC_unescape(s);
}
const char* filename;
string userName;
string roleName;
string charSet;
string networkProtocol;
string remoteAddress;
SLONG remotePid;
PathName processName;
bool hasUtf8;
};
void traceFailedConnection(const rem_port* port, const char* dbPath,
const string& userName, ntrace_result_t attResult);
// !Trace
GlobalPtr<FailedLogins> usernameFailedLogins; GlobalPtr<FailedLogins> usernameFailedLogins;
GlobalPtr<FailedLogins> remoteFailedLogins; GlobalPtr<FailedLogins> remoteFailedLogins;
bool server_shutdown = false; bool server_shutdown = false;
@ -510,12 +662,13 @@ public:
virtual void accept(PACKET* send, Auth::WriterImplementation* authBlock) = 0; virtual void accept(PACKET* send, Auth::WriterImplementation* authBlock) = 0;
ServerAuth(ClumpletReader* aPb, const ParametersSet& aTags, ServerAuth(ClumpletReader* aPb, const ParametersSet& aTags,
rem_port* port, bool multiPartData = false) rem_port* port, bool multiPartData = false, const PathName db = "")
: authItr(NULL), : authItr(NULL),
userName(getPool()), userName(getPool()),
authServer(NULL), authServer(NULL),
tags(&aTags), tags(&aTags),
hopsCount(0), hopsCount(0),
dbName(getPool(), db),
authPort(port) authPort(port)
{ {
if (!authPort->port_srv_auth_block) if (!authPort->port_srv_auth_block)
@ -603,6 +756,11 @@ public:
} }
} }
void saveForTrace(const PathName& db)
{
dbName = db;
}
~ServerAuth() ~ServerAuth()
{ } { }
@ -641,6 +799,8 @@ public:
} }
} }
int authResult = IAuth::AUTH_FAILED;
while (authItr && working && authItr->hasData()) while (authItr && working && authItr->hasData())
{ {
if (!authServer) if (!authServer)
@ -753,6 +913,11 @@ public:
// no success - perform failure processing // no success - perform failure processing
loginFail(userName, authPort->getRemoteId()); loginFail(userName, authPort->getRemoteId());
if (authResult != IAuth::AUTH_SUCCESS)
{
traceFailedConnection(authPort, dbName.c_str(), userName, ITracePlugin::RESULT_UNAUTHORIZED);
}
if (st.hasData()) if (st.hasData())
{ {
switch (st.getErrors()[1]) switch (st.getErrors()[1])
@ -784,6 +949,7 @@ private:
unsigned int hopsCount; unsigned int hopsCount;
protected: protected:
PathName dbName;
rem_port* authPort; rem_port* authPort;
}; };
@ -792,8 +958,7 @@ class DatabaseAuth : public ServerAuth
{ {
public: public:
DatabaseAuth(rem_port* port, const PathName& db, ClumpletWriter* dpb, P_OP op) DatabaseAuth(rem_port* port, const PathName& db, ClumpletWriter* dpb, P_OP op)
: ServerAuth(dpb, dpbParam, port), : ServerAuth(dpb, dpbParam, port, false, db),
dbName(getPool(), db),
pb(dpb), pb(dpb),
operation(op) operation(op)
{ } { }
@ -801,7 +966,6 @@ public:
void accept(PACKET* send, Auth::WriterImplementation* authBlock); void accept(PACKET* send, Auth::WriterImplementation* authBlock);
private: private:
PathName dbName;
AutoPtr<ClumpletWriter> pb; AutoPtr<ClumpletWriter> pb;
P_OP operation; P_OP operation;
}; };
@ -1247,6 +1411,46 @@ inline bool bad_service(IStatus* status_vector, Rdb* rdb)
} }
namespace {
void traceFailedConnection(const rem_port* port, const char* dbPath, const string& userName, ntrace_result_t attResult)
{
ClumpletWriter dpb(ClumpletReader::dpbList, MAX_DPB_SIZE);
dpb.insertString(isc_dpb_user_name, userName.c_str(), userName.length());
addClumplets(&dpb, dpbParam, port);
TraceFailedAuthImpl connection;
connection.setData(dpb.getBuffer(), dpb.getBufferLength());
Firebird::PathName originalPath(dbPath);
Firebird::PathName expandedName;
RefPtr<const Config> config;
// Resolve given alias name
if (!connection.hasUtf8InDpb())
ISC_systemToUtf8(originalPath);
ISC_unescape(originalPath);
bool is_alias = expandDatabaseName(originalPath, expandedName, &config);
if (!is_alias)
{
expandedName = originalPath;
}
connection.setFilename(expandedName.c_str());
TraceManager tempMgr(&connection, expandedName.c_str());
tempMgr.initServerTrace();
if (tempMgr.needs(ITraceFactory::TRACE_EVENT_ATTACH))
{
connection.setFilename(originalPath.c_str()); // Write alias
tempMgr.event_attach(&connection, false, attResult);
}
}
} // !namespace
class Worker class Worker
{ {
public: public:
@ -1995,6 +2199,7 @@ static bool accept_connection(rem_port* port, P_CNCT* connect, PACKET* send)
connect->p_cnct_user_id.cstr_address, connect->p_cnct_user_id.cstr_address,
connect->p_cnct_user_id.cstr_length); connect->p_cnct_user_id.cstr_length);
PathName bkDbName;
if (accepted) if (accepted)
{ {
// Setup correct configuration for port // Setup correct configuration for port
@ -2013,6 +2218,7 @@ static bool accept_connection(rem_port* port, P_CNCT* connect, PACKET* send)
if (version >= PROTOCOL_VERSION13) if (version >= PROTOCOL_VERSION13)
{ {
ConnectAuth* cnctAuth = FB_NEW ConnectAuth(port, id); ConnectAuth* cnctAuth = FB_NEW ConnectAuth(port, id);
cnctAuth->saveForTrace(bkDbName);
port->port_srv_auth = cnctAuth; port->port_srv_auth = cnctAuth;
if (port->port_srv_auth->authenticate(send, ServerAuth::AUTH_COND_ACCEPT)) if (port->port_srv_auth->authenticate(send, ServerAuth::AUTH_COND_ACCEPT))
{ {
@ -2127,9 +2333,15 @@ static bool accept_connection(rem_port* port, P_CNCT* connect, PACKET* send)
// Send off out gracious acceptance or flag rejection // Send off out gracious acceptance or flag rejection
if (!accepted) if (!accepted)
{ {
ntrace_result_t connectResult = ITracePlugin::RESULT_UNAUTHORIZED;
HANDSHAKE_DEBUG(fprintf(stderr, "!accepted, sending reject\n")); HANDSHAKE_DEBUG(fprintf(stderr, "!accepted, sending reject\n"));
if (status.getState() & Firebird::IStatus::STATE_ERRORS) if (status.getState() & Firebird::IStatus::STATE_ERRORS)
{ {
if (status.getErrors()[1] != isc_login)
connectResult = ITracePlugin::RESULT_FAILED;
switch (status.getErrors()[1]) switch (status.getErrors()[1])
{ {
case isc_missing_data_structures: case isc_missing_data_structures:
@ -2151,7 +2363,12 @@ static bool accept_connection(rem_port* port, P_CNCT* connect, PACKET* send)
} }
} }
else else
{
port->send(send); port->send(send);
}
::traceFailedConnection(port, bkDbName.c_str(), port->port_login, connectResult);
return false; return false;
} }
@ -7236,6 +7453,7 @@ void Worker::shutdown()
static int shut_server(const int, const int, void*) static int shut_server(const int, const int, void*)
{ {
TraceManager::shutdown(); // This storage is separate from the jrd one
server_shutdown = true; server_shutdown = true;
return 0; return 0;
} }

View File

@ -1,6 +1,6 @@
/* /*
* PROGRAM: JRD Access Method * PROGRAM: JRD Access Method
* MODULE: TraceManager.cpp * MODULE: JrdTraceManager.cpp
* DESCRIPTION: Trace API manager * DESCRIPTION: Trace API manager
* *
* The contents of this file are subject to the Initial * The contents of this file are subject to the Initial
@ -28,7 +28,7 @@
#include "firebird.h" #include "firebird.h"
#include "../../jrd/trace/TraceManager.h" #include "JrdTraceManager.h"
#include "../../jrd/trace/TraceObjects.h" #include "../../jrd/trace/TraceObjects.h"
#include "../../jrd/Mapping.h" #include "../../jrd/Mapping.h"
#include "../../common/os/path_utils.h" #include "../../common/os/path_utils.h"
@ -50,79 +50,43 @@ namespace
namespace Jrd { namespace Jrd {
GlobalPtr<StorageInstance, InstanceControl::PRIORITY_DELETE_FIRST> TraceManager::storageInstance;
TraceManager::Factories* TraceManager::factories = NULL;
GlobalPtr<RWLock> TraceManager::init_factories_lock;
volatile bool TraceManager::init_factories;
JrdTraceManager::JrdTraceManager(Attachment* in_att) :
bool TraceManager::check_result(ITracePlugin* plugin, const char* module, const char* function, TraceManager(NULL, *in_att->att_pool),
bool result)
{
if (result)
return true;
if (!plugin)
{
gds__log("Trace plugin %s returned error on call %s, "
"did not create plugin and provided no additional details on reasons of failure",
module, function);
return false;
}
const char* errorStr = plugin->trace_get_error();
if (!errorStr)
{
gds__log("Trace plugin %s returned error on call %s, "
"but provided no additional details on reasons of failure", module, function);
return false;
}
gds__log("Trace plugin %s returned error on call %s.\n\tError details: %s",
module, function, errorStr);
return false;
}
TraceManager::TraceManager(Attachment* in_att) :
attachment(in_att), attachment(in_att),
service(NULL), service(NULL),
filename(NULL),
callback(NULL), callback(NULL),
trace_sessions(*in_att->att_pool),
active(false) active(false)
{ {
init(); init();
} }
TraceManager::TraceManager(Service* in_svc) : JrdTraceManager::JrdTraceManager(Service* in_svc) :
TraceManager(NULL, in_svc->getPool()),
attachment(NULL), attachment(NULL),
service(in_svc), service(in_svc),
filename(NULL),
callback(NULL), callback(NULL),
trace_sessions(in_svc->getPool()),
active(true) active(true)
{ {
init(); init();
} }
TraceManager::TraceManager(const char* in_filename, ICryptKeyCallback* cb, bool failed) : JrdTraceManager::JrdTraceManager(const char* in_filename, ICryptKeyCallback* cb, bool failed) :
TraceManager(in_filename, *getDefaultMemoryPool()),
attachment(NULL), attachment(NULL),
service(NULL), service(NULL),
filename(in_filename),
callback(cb), callback(cb),
trace_sessions(*getDefaultMemoryPool()),
active(true), active(true),
failedAttach(failed) failedAttach(failed)
{ {
init(); init();
} }
TraceManager::~TraceManager() JrdTraceManager::~JrdTraceManager()
{ {
} }
void TraceManager::init() void JrdTraceManager::init()
{ {
// ensure storage is initialized // ensure storage is initialized
getStorage(); getStorage();
@ -130,100 +94,19 @@ void TraceManager::init()
changeNumber = 0; changeNumber = 0;
} }
void TraceManager::load_plugins()
{
// Initialize all trace needs to false
trace_needs = 0;
if (init_factories)
return;
WriteLockGuard guard(init_factories_lock, FB_FUNCTION);
if (init_factories)
return;
factories = FB_NEW_POOL(*getDefaultMemoryPool()) TraceManager::Factories(*getDefaultMemoryPool());
for (GetPlugins<ITraceFactory> traceItr(IPluginManager::TYPE_TRACE); traceItr.hasData(); traceItr.next())
{
FactoryInfo info;
info.factory = traceItr.plugin();
info.factory->addRef();
string name(traceItr.name());
name.copyTo(info.name, sizeof(info.name));
factories->add(info);
}
init_factories = true;
}
void TraceManager::shutdown() void JrdTraceManager::update_sessions()
{
if (init_factories)
{
WriteLockGuard guard(init_factories_lock, FB_FUNCTION);
if (init_factories)
{
init_factories = false;
delete factories;
factories = NULL;
}
}
getStorage()->shutdown();
}
void TraceManager::update_sessions()
{ {
// Let be inactive until database is creating // Let be inactive until database is creating
if (attachment && (attachment->att_database->dbb_flags & DBB_creating)) if (attachment && (attachment->att_database->dbb_flags & DBB_creating))
return; return;
MemoryPool& pool = *getDefaultMemoryPool(); MemoryPool& pool = *getDefaultMemoryPool();
SortedArray<ULONG, InlineStorage<ULONG, 64> > liveSessions(pool);
HalfStaticArray<TraceSession*, 64> newSessions(pool); HalfStaticArray<TraceSession*, 64> newSessions(pool);
{ // scope reload_sessions_lists(newSessions);
ConfigStorage* storage = getStorage();
StorageGuard guard(storage);
storage->restart();
TraceSession session(pool);
while (storage->getNextSession(session, ConfigStorage::FLAGS))
{
if ((session.ses_flags & trs_active) && !(session.ses_flags & trs_log_full))
{
FB_SIZE_T pos;
if (trace_sessions.find(session.ses_id, pos))
liveSessions.add(session.ses_id);
else
{
storage->getSession(session, ConfigStorage::ALL);
newSessions.add(FB_NEW_POOL(pool) TraceSession(pool, session));
}
}
}
changeNumber = storage->getChangeNumber();
}
// remove sessions not present in storage
FB_SIZE_T i = 0;
while (i < trace_sessions.getCount())
{
FB_SIZE_T pos;
if (liveSessions.find(trace_sessions[i].ses_id, pos)) {
i++;
}
else
{
trace_sessions[i].plugin->release();
trace_sessions.remove(i);
}
}
// add new sessions // add new sessions
new_needs = trace_needs; new_needs = trace_needs;
@ -246,7 +129,7 @@ void TraceManager::update_sessions()
} }
} }
void TraceManager::update_session(const TraceSession& session) void JrdTraceManager::update_session(const TraceSession& session)
{ {
// if this session is already known, nothing to do // if this session is already known, nothing to do
FB_SIZE_T pos; FB_SIZE_T pos;
@ -392,23 +275,24 @@ void TraceManager::update_session(const TraceSession& session)
} }
} }
bool TraceManager::need_dsql_prepare(Attachment* att) bool JrdTraceManager::need_dsql_prepare(Attachment* att)
{ {
return att->att_trace_manager->needs(ITraceFactory::TRACE_EVENT_DSQL_PREPARE); return att->att_trace_manager->needs(ITraceFactory::TRACE_EVENT_DSQL_PREPARE);
} }
bool TraceManager::need_dsql_free(Attachment* att) bool JrdTraceManager::need_dsql_free(Attachment* att)
{ {
return att->att_trace_manager->needs(ITraceFactory::TRACE_EVENT_DSQL_FREE); return att->att_trace_manager->needs(ITraceFactory::TRACE_EVENT_DSQL_FREE);
} }
bool TraceManager::need_dsql_execute(Attachment* att) bool JrdTraceManager::need_dsql_execute(Attachment* att)
{ {
return att->att_trace_manager->needs(ITraceFactory::TRACE_EVENT_DSQL_EXECUTE); return att->att_trace_manager->needs(ITraceFactory::TRACE_EVENT_DSQL_EXECUTE);
} }
void TraceManager::event_dsql_prepare(Attachment* att, jrd_tra* transaction, void JrdTraceManager::event_dsql_prepare(Attachment* att, jrd_tra* transaction,
ITraceSQLStatement* statement, ntrace_counter_t time_millis, ntrace_result_t req_result) ITraceSQLStatement* statement,
ntrace_counter_t time_millis, ntrace_result_t req_result)
{ {
TraceConnectionImpl conn(att); TraceConnectionImpl conn(att);
TraceTransactionImpl tran(transaction); TraceTransactionImpl tran(transaction);
@ -417,7 +301,7 @@ void TraceManager::event_dsql_prepare(Attachment* att, jrd_tra* transaction,
time_millis, req_result); time_millis, req_result);
} }
void TraceManager::event_dsql_free(Attachment* att, ITraceSQLStatement* statement, void JrdTraceManager::event_dsql_free(Attachment* att, ITraceSQLStatement* statement,
unsigned short option) unsigned short option)
{ {
TraceConnectionImpl conn(att); TraceConnectionImpl conn(att);
@ -425,7 +309,7 @@ void TraceManager::event_dsql_free(Attachment* att, ITraceSQLStatement* statemen
att->att_trace_manager->event_dsql_free(&conn, statement, option); att->att_trace_manager->event_dsql_free(&conn, statement, option);
} }
void TraceManager::event_dsql_execute(Attachment* att, jrd_tra* transaction, void JrdTraceManager::event_dsql_execute(Attachment* att, jrd_tra* transaction,
ITraceSQLStatement* statement, bool started, ntrace_result_t req_result) ITraceSQLStatement* statement, bool started, ntrace_result_t req_result)
{ {
TraceConnectionImpl conn(att); TraceConnectionImpl conn(att);
@ -435,7 +319,7 @@ void TraceManager::event_dsql_execute(Attachment* att, jrd_tra* transaction,
started, req_result); started, req_result);
} }
void TraceManager::event_dsql_restart(Attachment* att, jrd_tra* transaction, void JrdTraceManager::event_dsql_restart(Attachment* att, jrd_tra* transaction,
DsqlRequest* statement, int number) DsqlRequest* statement, int number)
{ {
TraceConnectionImpl conn(att); TraceConnectionImpl conn(att);
@ -446,40 +330,7 @@ void TraceManager::event_dsql_restart(Attachment* att, jrd_tra* transaction,
(unsigned) number); (unsigned) number);
} }
#define EXECUTE_HOOKS(METHOD, PARAMS) \ void JrdTraceManager::event_transaction_start(ITraceDatabaseConnection* connection,
FB_SIZE_T i = 0; \
while (i < trace_sessions.getCount()) \
{ \
SessionInfo* plug_info = &trace_sessions[i]; \
if (check_result(plug_info->plugin, plug_info->factory_info->name, #METHOD, \
plug_info->plugin->METHOD PARAMS)) \
{ \
i++; /* Move to next plugin */ \
} \
else { \
plug_info->plugin->release(); \
trace_sessions.remove(i); /* Remove broken plugin from the list */ \
} \
}
void TraceManager::event_attach(ITraceDatabaseConnection* connection,
bool create_db, ntrace_result_t att_result)
{
EXECUTE_HOOKS(trace_attach,
(connection, create_db, att_result));
trace_needs &= ~(FB_CONST64(1) << ITraceFactory::TRACE_EVENT_ATTACH);
}
void TraceManager::event_detach(ITraceDatabaseConnection* connection, bool drop_db)
{
EXECUTE_HOOKS(trace_detach, (connection, drop_db));
trace_needs &= ~(FB_CONST64(1) << ITraceFactory::TRACE_EVENT_DETACH);
}
void TraceManager::event_transaction_start(ITraceDatabaseConnection* connection,
ITraceTransaction* transaction, unsigned tpb_length, const ntrace_byte_t* tpb, ITraceTransaction* transaction, unsigned tpb_length, const ntrace_byte_t* tpb,
ntrace_result_t tra_result) ntrace_result_t tra_result)
{ {
@ -487,7 +338,7 @@ void TraceManager::event_transaction_start(ITraceDatabaseConnection* connection,
(connection, transaction, tpb_length, tpb, tra_result)); (connection, transaction, tpb_length, tpb, tra_result));
} }
void TraceManager::event_transaction_end(ITraceDatabaseConnection* connection, void JrdTraceManager::event_transaction_end(ITraceDatabaseConnection* connection,
ITraceTransaction* transaction, bool commit, bool retain_context, ITraceTransaction* transaction, bool commit, bool retain_context,
ntrace_result_t tra_result) ntrace_result_t tra_result)
{ {
@ -495,56 +346,56 @@ void TraceManager::event_transaction_end(ITraceDatabaseConnection* connection,
(connection, transaction, commit, retain_context, tra_result)); (connection, transaction, commit, retain_context, tra_result));
} }
void TraceManager::event_set_context(ITraceDatabaseConnection* connection, void JrdTraceManager::event_set_context(ITraceDatabaseConnection* connection,
ITraceTransaction* transaction, ITraceContextVariable* variable) ITraceTransaction* transaction, ITraceContextVariable* variable)
{ {
EXECUTE_HOOKS(trace_set_context, EXECUTE_HOOKS(trace_set_context,
(connection, transaction, variable)); (connection, transaction, variable));
} }
void TraceManager::event_proc_compile(ITraceDatabaseConnection* connection, void JrdTraceManager::event_proc_compile(ITraceDatabaseConnection* connection,
ITraceProcedure* procedure, ntrace_counter_t time_millis, ntrace_result_t proc_result) ITraceProcedure* procedure, ntrace_counter_t time_millis, ntrace_result_t proc_result)
{ {
EXECUTE_HOOKS(trace_proc_compile, EXECUTE_HOOKS(trace_proc_compile,
(connection, procedure, time_millis, proc_result)); (connection, procedure, time_millis, proc_result));
} }
void TraceManager::event_proc_execute(ITraceDatabaseConnection* connection, ITraceTransaction* transaction, void JrdTraceManager::event_proc_execute(ITraceDatabaseConnection* connection, ITraceTransaction* transaction,
ITraceProcedure* procedure, bool started, ntrace_result_t proc_result) ITraceProcedure* procedure, bool started, ntrace_result_t proc_result)
{ {
EXECUTE_HOOKS(trace_proc_execute, EXECUTE_HOOKS(trace_proc_execute,
(connection, transaction, procedure, started, proc_result)); (connection, transaction, procedure, started, proc_result));
} }
void TraceManager::event_func_compile(ITraceDatabaseConnection* connection, void JrdTraceManager::event_func_compile(ITraceDatabaseConnection* connection,
ITraceFunction* function, ntrace_counter_t time_millis, ntrace_result_t func_result) ITraceFunction* function, ntrace_counter_t time_millis, ntrace_result_t func_result)
{ {
EXECUTE_HOOKS(trace_func_compile, EXECUTE_HOOKS(trace_func_compile,
(connection, function, time_millis, func_result)); (connection, function, time_millis, func_result));
} }
void TraceManager::event_func_execute(ITraceDatabaseConnection* connection, ITraceTransaction* transaction, void JrdTraceManager::event_func_execute(ITraceDatabaseConnection* connection, ITraceTransaction* transaction,
ITraceFunction* function, bool started, ntrace_result_t func_result) ITraceFunction* function, bool started, ntrace_result_t func_result)
{ {
EXECUTE_HOOKS(trace_func_execute, EXECUTE_HOOKS(trace_func_execute,
(connection, transaction, function, started, func_result)); (connection, transaction, function, started, func_result));
} }
void TraceManager::event_trigger_compile(ITraceDatabaseConnection* connection, void JrdTraceManager::event_trigger_compile(ITraceDatabaseConnection* connection,
ITraceTrigger* trigger, ntrace_counter_t time_millis, ntrace_result_t trig_result) ITraceTrigger* trigger, ntrace_counter_t time_millis, ntrace_result_t trig_result)
{ {
EXECUTE_HOOKS(trace_trigger_compile, EXECUTE_HOOKS(trace_trigger_compile,
(connection, trigger, time_millis, trig_result)); (connection, trigger, time_millis, trig_result));
} }
void TraceManager::event_trigger_execute(ITraceDatabaseConnection* connection, ITraceTransaction* transaction, void JrdTraceManager::event_trigger_execute(ITraceDatabaseConnection* connection, ITraceTransaction* transaction,
ITraceTrigger* trigger, bool started, ntrace_result_t trig_result) ITraceTrigger* trigger, bool started, ntrace_result_t trig_result)
{ {
EXECUTE_HOOKS(trace_trigger_execute, EXECUTE_HOOKS(trace_trigger_execute,
(connection, transaction, trigger, started, trig_result)); (connection, transaction, trigger, started, trig_result));
} }
void TraceManager::event_dsql_prepare(ITraceDatabaseConnection* connection, ITraceTransaction* transaction, void JrdTraceManager::event_dsql_prepare(ITraceDatabaseConnection* connection, ITraceTransaction* transaction,
ITraceSQLStatement* statement, ntrace_counter_t time_millis, ntrace_result_t req_result) ITraceSQLStatement* statement, ntrace_counter_t time_millis, ntrace_result_t req_result)
{ {
EXECUTE_HOOKS(trace_dsql_prepare, EXECUTE_HOOKS(trace_dsql_prepare,
@ -552,37 +403,37 @@ void TraceManager::event_dsql_prepare(ITraceDatabaseConnection* connection, ITra
time_millis, req_result)); time_millis, req_result));
} }
void TraceManager::event_dsql_free(ITraceDatabaseConnection* connection, void JrdTraceManager::event_dsql_free(ITraceDatabaseConnection* connection,
ITraceSQLStatement* statement, unsigned short option) ITraceSQLStatement* statement, unsigned short option)
{ {
EXECUTE_HOOKS(trace_dsql_free, EXECUTE_HOOKS(trace_dsql_free,
(connection, statement, option)); (connection, statement, option));
} }
void TraceManager::event_dsql_execute(ITraceDatabaseConnection* connection, ITraceTransaction* transaction, void JrdTraceManager::event_dsql_execute(ITraceDatabaseConnection* connection, ITraceTransaction* transaction,
ITraceSQLStatement* statement, bool started, ntrace_result_t req_result) ITraceSQLStatement* statement, bool started, ntrace_result_t req_result)
{ {
EXECUTE_HOOKS(trace_dsql_execute, EXECUTE_HOOKS(trace_dsql_execute,
(connection, transaction, statement, started, req_result)); (connection, transaction, statement, started, req_result));
} }
void TraceManager::event_dsql_restart(ITraceDatabaseConnection* connection, ITraceTransaction* transaction, void JrdTraceManager::event_dsql_restart(ITraceDatabaseConnection* connection, ITraceTransaction* transaction,
ITraceSQLStatement* statement, unsigned number) ITraceSQLStatement* statement, unsigned number)
{ {
EXECUTE_HOOKS(trace_dsql_restart, EXECUTE_HOOKS(trace_dsql_restart,
(connection, transaction, statement, number)); (connection, transaction, statement, number));
} }
void TraceManager::event_blr_compile(ITraceDatabaseConnection* connection, void JrdTraceManager::event_blr_compile(ITraceDatabaseConnection* connection,
ITraceTransaction* transaction, ITraceBLRStatement* statement, ITraceTransaction* transaction, ITraceBLRStatement* statement,
ntrace_counter_t time_millis, ntrace_result_t req_result) ntrace_counter_t time_millis, ntrace_result_t req_result)
{ {
EXECUTE_HOOKS(trace_blr_compile, EXECUTE_HOOKS(trace_blr_compile,
(connection, transaction, statement, (connection, transaction, statement,
time_millis, req_result)); time_millis, req_result));
} }
void TraceManager::event_blr_execute(ITraceDatabaseConnection* connection, void JrdTraceManager::event_blr_execute(ITraceDatabaseConnection* connection,
ITraceTransaction* transaction, ITraceBLRStatement* statement, ITraceTransaction* transaction, ITraceBLRStatement* statement,
ntrace_result_t req_result) ntrace_result_t req_result)
{ {
@ -590,7 +441,7 @@ void TraceManager::event_blr_execute(ITraceDatabaseConnection* connection,
(connection, transaction, statement, req_result)); (connection, transaction, statement, req_result));
} }
void TraceManager::event_dyn_execute(ITraceDatabaseConnection* connection, void JrdTraceManager::event_dyn_execute(ITraceDatabaseConnection* connection,
ITraceTransaction* transaction, ITraceDYNRequest* request, ITraceTransaction* transaction, ITraceDYNRequest* request,
ntrace_counter_t time_millis, ntrace_result_t req_result) ntrace_counter_t time_millis, ntrace_result_t req_result)
{ {
@ -599,13 +450,13 @@ void TraceManager::event_dyn_execute(ITraceDatabaseConnection* connection,
req_result)); req_result));
} }
void TraceManager::event_service_attach(ITraceServiceConnection* service, ntrace_result_t att_result) void JrdTraceManager::event_service_attach(ITraceServiceConnection* service, ntrace_result_t att_result)
{ {
EXECUTE_HOOKS(trace_service_attach, EXECUTE_HOOKS(trace_service_attach,
(service, att_result)); (service, att_result));
} }
void TraceManager::event_service_start(ITraceServiceConnection* service, void JrdTraceManager::event_service_start(ITraceServiceConnection* service,
unsigned switches_length, const char* switches, unsigned switches_length, const char* switches,
ntrace_result_t start_result) ntrace_result_t start_result)
{ {
@ -613,7 +464,7 @@ void TraceManager::event_service_start(ITraceServiceConnection* service,
(service, switches_length, switches, start_result)); (service, switches_length, switches, start_result));
} }
void TraceManager::event_service_query(ITraceServiceConnection* service, void JrdTraceManager::event_service_query(ITraceServiceConnection* service,
unsigned send_item_length, const ntrace_byte_t* send_items, unsigned send_item_length, const ntrace_byte_t* send_items,
unsigned recv_item_length, const ntrace_byte_t* recv_items, unsigned recv_item_length, const ntrace_byte_t* recv_items,
ntrace_result_t query_result) ntrace_result_t query_result)
@ -623,20 +474,20 @@ void TraceManager::event_service_query(ITraceServiceConnection* service,
recv_item_length, recv_items, query_result)); recv_item_length, recv_items, query_result));
} }
void TraceManager::event_service_detach(ITraceServiceConnection* service, ntrace_result_t detach_result) void JrdTraceManager::event_service_detach(ITraceServiceConnection* service, ntrace_result_t detach_result)
{ {
EXECUTE_HOOKS(trace_service_detach, EXECUTE_HOOKS(trace_service_detach,
(service, detach_result)); (service, detach_result));
} }
void TraceManager::event_error(ITraceConnection* connection, ITraceStatusVector* status, const char* function) void JrdTraceManager::event_error(ITraceConnection* connection, ITraceStatusVector* status, const char* function)
{ {
EXECUTE_HOOKS(trace_event_error, EXECUTE_HOOKS(trace_event_error,
(connection, status, function)); (connection, status, function));
} }
void TraceManager::event_sweep(ITraceDatabaseConnection* connection, ITraceSweepInfo* sweep, void JrdTraceManager::event_sweep(ITraceDatabaseConnection* connection, ITraceSweepInfo* sweep,
ntrace_process_state_t sweep_state) ntrace_process_state_t sweep_state)
{ {
EXECUTE_HOOKS(trace_event_sweep, EXECUTE_HOOKS(trace_event_sweep,

View File

@ -1,6 +1,6 @@
/* /*
* PROGRAM: JRD Access Method * PROGRAM: JRD Access Method
* MODULE: TraceManager.h * MODULE: JrdTraceManager.h
* DESCRIPTION: Trace API manager * DESCRIPTION: Trace API manager
* *
* The contents of this file are subject to the Initial * The contents of this file are subject to the Initial
@ -29,15 +29,7 @@
#ifndef JRD_TRACEMANAGER_H #ifndef JRD_TRACEMANAGER_H
#define JRD_TRACEMANAGER_H #define JRD_TRACEMANAGER_H
#include <time.h> #include "TraceManager.h"
#include "../../jrd/ntrace.h"
#include "../../common/classes/array.h"
#include "../../common/classes/fb_string.h"
#include "../../common/classes/init.h"
#include "../../common/classes/rwlock.h"
#include "../../common/classes/ImplementHelper.h"
#include "../../jrd/trace/TraceConfigStorage.h"
#include "../../jrd/trace/TraceSession.h"
namespace Firebird { namespace Firebird {
@ -53,27 +45,17 @@ class jrd_tra;
class DsqlRequest; class DsqlRequest;
class Service; class Service;
class TraceManager class JrdTraceManager : public TraceManager
{ {
public: public:
/* Initializes plugins. */ /* Initializes plugins. */
explicit TraceManager(Attachment* in_att); explicit JrdTraceManager(Attachment* in_att);
explicit TraceManager(Service* in_svc); explicit JrdTraceManager(Service* in_svc);
TraceManager(const char* in_filename, Firebird::ICryptKeyCallback* callback, bool failedAttach); JrdTraceManager(const char* in_filename, Firebird::ICryptKeyCallback* callback, bool failedAttach);
/* Finalize plugins. Called when database is closed by the engine */ /* Finalize plugins. Called when database is closed by the engine */
~TraceManager(); ~JrdTraceManager();
static ConfigStorage* getStorage()
{ return storageInstance->getStorage(); }
static size_t pluginsCount()
{ return factories->getCount(); }
void event_attach(Firebird::ITraceDatabaseConnection* connection, bool create_db,
ntrace_result_t att_result);
void event_detach(Firebird::ITraceDatabaseConnection* connection, bool drop_db);
/* Start/end transaction */ /* Start/end transaction */
void event_transaction_start(Firebird::ITraceDatabaseConnection* connection, Firebird::ITraceTransaction* transaction, void event_transaction_start(Firebird::ITraceDatabaseConnection* connection, Firebird::ITraceTransaction* transaction,
@ -182,80 +164,18 @@ public:
static void event_dsql_restart(Attachment* att, jrd_tra* transaction, DsqlRequest* statement, static void event_dsql_restart(Attachment* att, jrd_tra* transaction, DsqlRequest* statement,
int number); int number);
static void shutdown();
private: private:
Attachment* attachment; Attachment* attachment;
Service* service; Service* service;
const char* filename;
Firebird::ICryptKeyCallback* callback; Firebird::ICryptKeyCallback* callback;
NotificationNeeds trace_needs, new_needs;
// This structure should be POD-like to be stored in Array
struct FactoryInfo
{
FactoryInfo() : factory(NULL)
{
memset(name, 0, sizeof(name));
}
Firebird::ITraceFactory* factory;
char name[MAXPATHLEN];
};
class Factories : public Firebird::Array<FactoryInfo>
{
public:
explicit Factories(Firebird::MemoryPool& p)
: Firebird::Array<FactoryInfo>(p)
{ }
~Factories()
{
Firebird::PluginManagerInterfacePtr pi;
for (unsigned int i = 0; i < getCount(); ++i)
pi->releasePlugin(getElement(i).factory);
}
};
static Factories* factories;
static Firebird::GlobalPtr<Firebird::RWLock> init_factories_lock;
static volatile bool init_factories;
struct SessionInfo
{
FactoryInfo* factory_info;
Firebird::ITracePlugin* plugin;
ULONG ses_id;
static ULONG generate(const SessionInfo& item)
{ return item.ses_id; }
};
class Sessions : public Firebird::SortedArray<SessionInfo, Firebird::EmptyStorage<SessionInfo>, ULONG, SessionInfo>
{
public:
explicit Sessions(MemoryPool& p)
: Firebird::SortedArray<SessionInfo, Firebird::EmptyStorage<SessionInfo>, ULONG, SessionInfo>(p)
{ }
~Sessions()
{
for (unsigned int i = 0; i < getCount(); ++i)
{
getElement(i).plugin->release();
}
}
};
Sessions trace_sessions;
void init(); void init();
void load_plugins();
void update_sessions(); void update_sessions();
void update_session(const Firebird::TraceSession& session); void update_session(const Firebird::TraceSession& session);
bool check_result(Firebird::ITracePlugin* plugin, const char* module, const char* function, bool result);
/* DSQL statement lifecycle. To be moved to public and used directly when DSQL becomes a part of JRD */ /* DSQL statement lifecycle. To be moved to public and used directly when DSQL becomes a part of JRD */
void event_dsql_prepare(Firebird::ITraceDatabaseConnection* connection, Firebird::ITraceTransaction* transaction, void event_dsql_prepare(Firebird::ITraceDatabaseConnection* connection, Firebird::ITraceTransaction* transaction,
Firebird::ITraceSQLStatement* statement, Firebird::ITraceSQLStatement* statement,
@ -271,9 +191,6 @@ private:
void event_dsql_restart(Firebird::ITraceDatabaseConnection* connection, Firebird::ITraceTransaction* transaction, Firebird::ITraceSQLStatement* statement, void event_dsql_restart(Firebird::ITraceDatabaseConnection* connection, Firebird::ITraceTransaction* transaction, Firebird::ITraceSQLStatement* statement,
unsigned number); unsigned number);
static Firebird::GlobalPtr<StorageInstance, Firebird::InstanceControl::PRIORITY_DELETE_FIRST> storageInstance;
ULONG changeNumber;
bool active, failedAttach; bool active, failedAttach;
}; };

View File

@ -0,0 +1,417 @@
/*
* PROGRAM: JRD Access Method
* MODULE: JrdTraceManager.cpp
* DESCRIPTION: Trace API manager
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Nickolay Samofatov
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2004 Nickolay Samofatov <nickolay@broadviewsoftware.com>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
* 2008 Khorsun Vladyslav
*/
#include "firebird.h"
#include "TraceManager.h"
#include "../../common/os/path_utils.h"
#include "../../common/ScanDir.h"
#include "../../common/isc_proto.h"
#include "../../common/classes/GetPlugins.h"
#include "../../common/db_alias.h"
#include "../../jrd/trace/TraceLog.h"
#ifdef WIN_NT
#include <process.h>
#endif
using namespace Firebird;
class TraceLogWriterImpl final :
public RefCntIface<ITraceLogWriterImpl<TraceLogWriterImpl, CheckStatusWrapper> >
{
public:
TraceLogWriterImpl(const TraceSession& session) :
m_log(*getDefaultMemoryPool(), session.ses_logfile, false),
m_sesId(session.ses_id)
{
string s;
s.printf("\n--- Session %d is suspended as its log is full ---\n", session.ses_id);
m_log.setFullMsg(s.c_str());
}
// TraceLogWriter implementation
FB_SIZE_T write(const void* buf, FB_SIZE_T size)
{
const FB_SIZE_T written = m_log.write(buf, size);
if (written == size)
return size;
if (!m_log.isFull())
return written;
Jrd::ConfigStorage* storage = TraceManager::getStorage();
Jrd::StorageGuard guard(storage);
TraceSession session(*getDefaultMemoryPool());
session.ses_id = m_sesId;
if (storage->getSession(session, Jrd::ConfigStorage::FLAGS))
{
if (!(session.ses_flags & trs_log_full))
{
// suspend session
session.ses_flags |= trs_log_full;
storage->updateFlags(session);
}
}
// report successful write
return size;
}
FB_SIZE_T write_s(CheckStatusWrapper* status, const void* buf, FB_SIZE_T size)
{
try
{
return write(buf, size);
}
catch (Exception &ex)
{
ex.stuffException(status);
}
return 0;
}
int release()
{
if (--refCounter == 0)
{
delete this;
return 0;
}
return 1;
}
private:
Jrd::TraceLog m_log;
ULONG m_sesId;
};
class ServerTraceInitInfoImpl :
public AutoIface<ITraceInitInfoImpl<ServerTraceInitInfoImpl, CheckStatusWrapper> >
{
public:
ServerTraceInitInfoImpl(const TraceSession& session, ITraceDatabaseConnection* conn,
const char* dbName) :
session(session),
dbName(dbName),
logWriter(),
connection(conn)
{ }
// TraceInitInfo implementation
const char* getConfigText() { return session.ses_config.c_str(); }
int getTraceSessionID() { return session.ses_id; }
const char* getTraceSessionName() { return session.ses_name.c_str(); }
int getTraceSessionFlags() { return session.ses_flags; }
const char* getFirebirdRootDirectory() { return Config::getRootDirectory(); }
const char* getDatabaseName() { return dbName; }
Firebird::ITraceDatabaseConnection* getConnection()
{
return connection;
}
Firebird::ITraceServiceConnection* getService()
{
return NULL;
}
Firebird::ITraceLogWriter* getLogWriter()
{
if (!logWriter && !session.ses_logfile.empty())
{
logWriter = FB_NEW TraceLogWriterImpl(session);
}
if (logWriter)
{
logWriter->addRef();
}
return logWriter;
}
private:
const Firebird::TraceSession& session;
const char* dbName;
Firebird::RefPtr<Firebird::ITraceLogWriter> logWriter;
ITraceDatabaseConnection* connection;
};
GlobalPtr<Jrd::StorageInstance, InstanceControl::PRIORITY_DELETE_FIRST> TraceManager::storageInstance;
TraceManager::Factories* TraceManager::factories = NULL;
GlobalPtr<Firebird::RWLock> TraceManager::init_factories_lock;
volatile bool TraceManager::init_factories;
bool TraceManager::check_result(ITracePlugin* plugin, const char* module, const char* function,
bool result)
{
if (result)
return true;
if (!plugin)
{
gds__log("Trace plugin %s returned error on call %s, "
"did not create plugin and provided no additional details on reasons of failure",
module, function);
return false;
}
const char* errorStr = plugin->trace_get_error();
if (!errorStr)
{
gds__log("Trace plugin %s returned error on call %s, "
"but provided no additional details on reasons of failure", module, function);
return false;
}
gds__log("Trace plugin %s returned error on call %s.\n\tError details: %s",
module, function, errorStr);
return false;
}
TraceManager::TraceManager(ITraceDatabaseConnection* conn, const char* in_filename) :
filename(in_filename),
trace_needs(0),
new_needs(0),
connection(conn),
trace_sessions(*getDefaultMemoryPool()),
changeNumber(0)
{
}
TraceManager::TraceManager(const char* in_filename, MemoryPool& pool) :
filename(in_filename),
trace_needs(0),
new_needs(0),
connection(NULL),
trace_sessions(pool),
changeNumber(0)
{ }
TraceManager::~TraceManager()
{
}
void TraceManager::initServerTrace()
{
// ensure storage is initialized
// In Classic mode this is the first getStorage call, so it always creates the storage
// but it may not reread the config
getStorage(); // Open storage
load_plugins();
changeNumber = 0;
}
void TraceManager::load_plugins()
{
// Initialize all trace needs to false
trace_needs = 0;
if (init_factories)
return;
Firebird::WriteLockGuard guard(init_factories_lock, FB_FUNCTION);
if (init_factories)
return;
factories = FB_NEW_POOL(*getDefaultMemoryPool()) TraceManager::Factories(*getDefaultMemoryPool());
for (GetPlugins<ITraceFactory> traceItr(IPluginManager::TYPE_TRACE); traceItr.hasData(); traceItr.next())
{
FactoryInfo info;
info.factory = traceItr.plugin();
info.factory->addRef();
string name(traceItr.name());
name.copyTo(info.name, sizeof(info.name));
factories->add(info);
}
init_factories = true;
}
void TraceManager::shutdown()
{
if (init_factories)
{
Firebird::WriteLockGuard guard(init_factories_lock, FB_FUNCTION);
if (init_factories)
{
init_factories = false;
delete factories;
factories = NULL;
}
}
getStorage()->shutdown();
}
ITraceLogWriter* TraceManager::createSessionLogWriter(const TraceSession& session)
{
return FB_NEW TraceLogWriterImpl(session);
}
void TraceManager::reload_sessions_lists(HalfStaticArray<TraceSession*, 64>& newSessions)
{
MemoryPool& pool = *getDefaultMemoryPool();
SortedArray<ULONG, InlineStorage<ULONG, 64> > liveSessions(pool);
{ // scope
Jrd::ConfigStorage* storage = getStorage();
Jrd::StorageGuard guard(storage);
storage->restart();
TraceSession session(pool);
while (storage->getNextSession(session, Jrd::ConfigStorage::FLAGS))
{
if ((session.ses_flags & trs_active) && !(session.ses_flags & trs_log_full))
{
FB_SIZE_T pos;
if (trace_sessions.find(session.ses_id, pos))
liveSessions.add(session.ses_id);
else
{
storage->getSession(session, Jrd::ConfigStorage::ALL);
newSessions.add(FB_NEW_POOL(pool) TraceSession(pool, session));
}
}
}
changeNumber = storage->getChangeNumber();
}
// remove sessions not present in storage
FB_SIZE_T i = 0;
while (i < trace_sessions.getCount())
{
FB_SIZE_T pos;
if (liveSessions.find(trace_sessions[i].ses_id, pos)) {
i++;
}
else
{
trace_sessions[i].plugin->release();
trace_sessions.remove(i);
}
}
}
void TraceManager::update_sessions()
{
MemoryPool& pool = *getDefaultMemoryPool();
HalfStaticArray<TraceSession*, 64> newSessions(pool);
reload_sessions_lists(newSessions);
// add new sessions
new_needs = trace_needs;
trace_needs = 0;
while (newSessions.hasData())
{
// Preventing memory leaks in case of an exception
Firebird::AutoPtr<TraceSession> s(newSessions.pop());
update_session(*s.get());
}
// nothing to trace, clear needs
if (trace_sessions.getCount() == 0)
{
trace_needs = 0;
}
else
{
trace_needs = new_needs;
}
}
void TraceManager::update_session(const TraceSession& session)
{
// if this session is already known, nothing to do
FB_SIZE_T pos;
if (trace_sessions.find(session.ses_id, pos)) {
return;
}
Firebird::ReadLockGuard guard(init_factories_lock, FB_FUNCTION);
if (!factories)
return;
for (FactoryInfo* info = factories->begin(); info != factories->end(); ++info)
{
Firebird::LocalStatus localStatus;
Firebird::CheckStatusWrapper status(&localStatus);
ServerTraceInitInfoImpl attachInfo(session, connection, filename);
ITracePlugin* plugin = info->factory->trace_create(&status, &attachInfo);
if (plugin)
{
plugin->addRef();
SessionInfo sesInfo;
sesInfo.plugin = plugin;
sesInfo.factory_info = info;
sesInfo.ses_id = session.ses_id;
trace_sessions.add(sesInfo);
new_needs |= info->factory->trace_needs();
}
else if (status.getState() & IStatus::STATE_ERRORS)
{
string header;
header.printf("Trace plugin %s returned error on call trace_create.", info->name);
iscLogStatus(header.c_str(), &status);
}
}
}
void TraceManager::event_attach(Firebird::ITraceDatabaseConnection* connection, bool create_db,
ntrace_result_t att_result)
{
EXECUTE_HOOKS(trace_attach,
(connection, create_db, att_result));
trace_needs &= ~(FB_CONST64(1) << ITraceFactory::TRACE_EVENT_ATTACH);
}
void TraceManager::event_detach(ITraceDatabaseConnection* connection, bool drop_db)
{
EXECUTE_HOOKS(trace_detach, (connection, drop_db));
trace_needs &= ~(FB_CONST64(1) << ITraceFactory::TRACE_EVENT_DETACH);
}

View File

@ -0,0 +1,177 @@
/*
* PROGRAM: Server Access Methods
* MODULE: TraceManager.h
* DESCRIPTION: Trace API manager
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Nickolay Samofatov
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2004 Nickolay Samofatov <nickolay@broadviewsoftware.com>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
* 2008 Khorsun Vladyslav
*/
#ifndef TRACEMANAGER_H
#define TRACEMANAGER_H
#include "../../jrd/ntrace.h"
#include "../../common/classes/array.h"
#include "../../common/classes/fb_string.h"
#include "../../common/classes/init.h"
#include "../../common/classes/rwlock.h"
#include "../../common/classes/ImplementHelper.h"
#include "../../jrd/trace/TraceConfigStorage.h"
#include "../../jrd/trace/TraceSession.h"
class TraceManager
{
public:
/* Initializes plugins. */
explicit TraceManager(Firebird::ITraceDatabaseConnection* conn, const char* in_filename);
explicit TraceManager(const char* in_filename, MemoryPool& pool);
void initServerTrace();
/* Finalize plugins. Called when database is closed by the engine */
~TraceManager();
static Jrd::ConfigStorage* getStorage()
{ return storageInstance->getStorage(); }
static size_t pluginsCount()
{ return factories->getCount(); }
void event_attach(Firebird::ITraceDatabaseConnection* connection, bool create_db,
ntrace_result_t att_result);
void event_detach(Firebird::ITraceDatabaseConnection* connection, bool drop_db);
typedef ntrace_mask_t NotificationNeeds;
inline bool needs(unsigned e)
{
if (!init_factories)
return false;
if (changeNumber != getStorage()->getChangeNumber())
update_sessions();
return trace_needs & (FB_CONST64(1) << e);
}
static void shutdown();
static Firebird::ITraceLogWriter* createSessionLogWriter(const Firebird::TraceSession& session);
#define EXECUTE_HOOKS(METHOD, PARAMS) \
FB_SIZE_T i = 0; \
while (i < trace_sessions.getCount()) \
{ \
SessionInfo* plug_info = &trace_sessions[i]; \
if (check_result(plug_info->plugin, plug_info->factory_info->name, #METHOD, \
plug_info->plugin->METHOD PARAMS)) \
{ \
i++; /* Move to next plugin */ \
} \
else { \
trace_sessions.remove(i); /* Remove broken plugin from the list */ \
} \
}
protected:
void reload_sessions_lists(Firebird::HalfStaticArray<Firebird::TraceSession*, 64>& newSessions);
private:
Firebird::ITraceDatabaseConnection* connection;
protected:
const char* filename;
NotificationNeeds trace_needs, new_needs;
// This structure should be POD-like to be stored in Array
struct FactoryInfo
{
FactoryInfo() : factory(NULL)
{
memset(name, 0, sizeof(name));
}
Firebird::ITraceFactory* factory;
char name[MAXPATHLEN];
};
class Factories : public Firebird::Array<FactoryInfo>
{
public:
explicit Factories(Firebird::MemoryPool& p)
: Firebird::Array<FactoryInfo>(p)
{ }
~Factories()
{
Firebird::PluginManagerInterfacePtr pi;
for (unsigned int i = 0; i < getCount(); ++i)
pi->releasePlugin(getElement(i).factory);
}
};
static Factories* factories;
static Firebird::GlobalPtr<Firebird::RWLock> init_factories_lock;
static volatile bool init_factories;
struct SessionInfo
{
FactoryInfo* factory_info;
Firebird::ITracePlugin* plugin;
ULONG ses_id;
static ULONG generate(const SessionInfo& item)
{ return item.ses_id; }
};
class Sessions : public Firebird::SortedArray<SessionInfo, Firebird::EmptyStorage<SessionInfo>, ULONG, SessionInfo>
{
public:
explicit Sessions(MemoryPool& p)
: Firebird::SortedArray<SessionInfo, Firebird::EmptyStorage<SessionInfo>, ULONG, SessionInfo>(p)
{ }
~Sessions()
{
for (unsigned int i = 0; i < getCount(); ++i)
{
getElement(i).plugin->release();
}
}
};
Sessions trace_sessions;
void load_plugins();
void update_sessions();
void update_session(const Firebird::TraceSession& session);
bool check_result(Firebird::ITracePlugin* plugin, const char* module, const char* function, bool result);
static Firebird::GlobalPtr<Jrd::StorageInstance, Firebird::InstanceControl::PRIORITY_DELETE_FIRST> storageInstance;
ULONG changeNumber;
};
#endif // !TRACEMANAGER_H