mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 14:03:03 +01:00
Merge remote-tracking branch 'reddb/trace_faild_attaches_7580' into trace-failed-attach
This commit is contained in:
commit
1ab2ad8af5
@ -65,9 +65,13 @@ SecDbCache:= $(call makeObjects,auth,SecDbCache.cpp)
|
||||
|
||||
|
||||
# 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_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) \
|
||||
$(call makeObjects,auth/SecurityDatabase,LegacyClient.cpp) \
|
||||
$(call dirObjects,plugins/crypt/arc4)
|
||||
@ -89,7 +93,8 @@ AllObjects += $(Profiler_Objects)
|
||||
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/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)
|
||||
|
||||
|
@ -172,9 +172,10 @@
|
||||
<ClCompile Include="..\..\..\src\jrd\trace\TraceCmdLine.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\trace\TraceConfigStorage.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\TraceService.cpp" />
|
||||
<ClCompile Include="..\..\..\src\supplement\trace\TraceManager.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\UserManagement.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\validation.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\vio.cpp" />
|
||||
@ -358,7 +359,7 @@
|
||||
<ClInclude Include="..\..\..\src\jrd\trace\TraceDSQLHelpers.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\trace\TraceJrdHelpers.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\TraceService.h" />
|
||||
<ClInclude Include="..\..\..\src\jrd\trace\TraceSession.h" />
|
||||
|
@ -198,7 +198,7 @@
|
||||
<ClCompile Include="..\..\..\src\jrd\trace\TraceLog.cpp">
|
||||
<Filter>JRD files\Trace</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\jrd\trace\TraceManager.cpp">
|
||||
<ClCompile Include="..\..\..\src\supplement\trace\JrdTraceManager.cpp">
|
||||
<Filter>JRD files\Trace</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\jrd\trace\TraceObjects.cpp">
|
||||
@ -207,6 +207,9 @@
|
||||
<ClCompile Include="..\..\..\src\jrd\trace\TraceService.cpp">
|
||||
<Filter>JRD files\Trace</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\supplement\trace\TraceManager.cpp">
|
||||
<Filter>JRD files\Trace</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\src\jrd\VirtualTable.cpp">
|
||||
<Filter>JRD files</Filter>
|
||||
</ClCompile>
|
||||
@ -656,7 +659,7 @@
|
||||
<ClInclude Include="..\..\..\src\jrd\trace\TraceLog.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\jrd\trace\TraceManager.h">
|
||||
<ClInclude Include="..\..\..\src\supplement\trace\JrdTraceManager.h">
|
||||
<Filter>Header files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\jrd\trace\TraceObjects.h">
|
||||
|
@ -205,6 +205,9 @@
|
||||
<ClCompile Include="..\..\..\src\remote\server\ReplServer.cpp" />
|
||||
<ClCompile Include="..\..\..\src\jrd\replication\Config.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>
|
||||
<None Include="..\..\..\src\remote\server\os\win32\caution.ico" />
|
||||
@ -231,4 +234,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
@ -34,6 +34,15 @@
|
||||
<ClCompile Include="..\..\..\src\remote\server\os\win32\srvr_w32.cpp">
|
||||
<Filter>Remote server</Filter>
|
||||
</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">
|
||||
<Filter>AUTH files</Filter>
|
||||
</ClCompile>
|
||||
@ -68,4 +77,4 @@
|
||||
<Filter>AUTH files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "firebird.h"
|
||||
#include "../common/classes/ClumpletWriter.h"
|
||||
#include "../jrd/tra_proto.h"
|
||||
#include "../jrd/trace/TraceManager.h"
|
||||
#include "../supplement/trace/JrdTraceManager.h"
|
||||
#include "../jrd/trace/TraceDSQLHelpers.h"
|
||||
|
||||
#include "../dsql/dsql_proto.h"
|
||||
@ -86,10 +86,10 @@ void DsqlCursor::close(thread_db* tdbb, DsqlCursor* cursor)
|
||||
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);
|
||||
TraceManager::event_dsql_free(attachment, &stmt, DSQL_close);
|
||||
JrdTraceManager::event_dsql_free(attachment, &stmt, DSQL_close);
|
||||
}
|
||||
|
||||
JRD_unwind_request(tdbb, dsqlRequest->getRequest());
|
||||
|
@ -200,11 +200,11 @@ void DsqlRequest::destroy(thread_db* tdbb, DsqlRequest* dsqlRequest)
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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())
|
||||
@ -818,7 +818,7 @@ void DsqlDmlRequest::executeReceiveWithRestarts(thread_db* tdbb, jrd_tra** traHa
|
||||
"\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
|
||||
exec = true;
|
||||
|
@ -61,7 +61,7 @@
|
||||
#include "../dsql/DSqlDataTypeUtil.h"
|
||||
#include "../jrd/DataTypeUtil.h"
|
||||
#include "../jrd/Collation.h"
|
||||
#include "../jrd/trace/TraceManager.h"
|
||||
#include "../supplement/trace/JrdTraceManager.h"
|
||||
#include "../jrd/trace/TraceObjects.h"
|
||||
#include "../jrd/trace/TraceJrdHelpers.h"
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
||||
#include "../jrd/recsrc/RecordSource.h"
|
||||
#include "../jrd/recsrc/Cursor.h"
|
||||
#include "../jrd/replication/Publisher.h"
|
||||
#include "../jrd/trace/TraceManager.h"
|
||||
#include "../supplement/trace/JrdTraceManager.h"
|
||||
#include "../jrd/trace/TraceJrdHelpers.h"
|
||||
#include "../jrd/cmp_proto.h"
|
||||
#include "../jrd/dfw_proto.h"
|
||||
|
@ -66,7 +66,7 @@
|
||||
#include "../jrd/optimizer/Optimizer.h"
|
||||
#include "../jrd/recsrc/RecordSource.h"
|
||||
#include "../jrd/replication/Publisher.h"
|
||||
#include "../jrd/trace/TraceManager.h"
|
||||
#include "../supplement/trace/JrdTraceManager.h"
|
||||
#include "../jrd/trace/TraceDSQLHelpers.h"
|
||||
#include "../common/classes/init.h"
|
||||
#include "../common/utils_proto.h"
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include "../jrd/Database.h"
|
||||
#include "../jrd/Function.h"
|
||||
#include "../jrd/nbak.h"
|
||||
#include "../jrd/trace/TraceManager.h"
|
||||
#include "../supplement/trace/JrdTraceManager.h"
|
||||
#include "../jrd/PreparedStatement.h"
|
||||
#include "../jrd/tra.h"
|
||||
#include "../jrd/intl.h"
|
||||
@ -252,7 +252,7 @@ Jrd::Attachment::Attachment(MemoryPool* pool, Database* dbb, JProvider* provider
|
||||
att_ext_connection(NULL),
|
||||
att_ext_parent(NULL),
|
||||
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_dest_bind(&att_bindings),
|
||||
att_original_timezone(TimeZoneUtil::getSystemTimeZone()),
|
||||
|
@ -92,7 +92,7 @@ namespace Jrd
|
||||
class jrd_fld;
|
||||
class dsql_dbb;
|
||||
class PreparedStatement;
|
||||
class TraceManager;
|
||||
class JrdTraceManager;
|
||||
template <typename T> class vec;
|
||||
class jrd_rel;
|
||||
class jrd_prc;
|
||||
@ -636,7 +636,7 @@ public:
|
||||
EDS::Connection* att_ext_connection; // external connection executed by 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
|
||||
TraceManager* att_trace_manager; // Trace API manager
|
||||
JrdTraceManager* att_trace_manager; // Trace API manager
|
||||
|
||||
CoercionArray att_bindings;
|
||||
CoercionArray* att_dest_bind;
|
||||
|
@ -54,7 +54,7 @@
|
||||
#include "../jrd/scl_proto.h"
|
||||
#include "../common/os/guid.h"
|
||||
#include "../jrd/license.h"
|
||||
#include "../jrd/trace/TraceManager.h"
|
||||
#include "../supplement/trace/JrdTraceManager.h"
|
||||
#include "../jrd/trace/TraceObjects.h"
|
||||
#include "../jrd/Collation.h"
|
||||
#include "../common/classes/FpeControl.h"
|
||||
|
@ -102,7 +102,7 @@
|
||||
#include "../jrd/rpb_chain.h"
|
||||
#include "../jrd/RecordSourceNodes.h"
|
||||
#include "../jrd/VirtualTable.h"
|
||||
#include "../jrd/trace/TraceManager.h"
|
||||
#include "../supplement/trace/JrdTraceManager.h"
|
||||
#include "../jrd/trace/TraceJrdHelpers.h"
|
||||
|
||||
#include "../dsql/Nodes.h"
|
||||
|
@ -120,7 +120,7 @@
|
||||
#include "../common/db_alias.h"
|
||||
#include "../jrd/replication/Publisher.h"
|
||||
#include "../jrd/replication/Applier.h"
|
||||
#include "../jrd/trace/TraceManager.h"
|
||||
#include "../supplement/trace/JrdTraceManager.h"
|
||||
#include "../jrd/trace/TraceObjects.h"
|
||||
#include "../jrd/trace/TraceJrdHelpers.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";
|
||||
|
||||
// Perform actual trace
|
||||
TraceManager tempMgr(origFilename, callback, flags & UNWIND_NEW);
|
||||
JrdTraceManager tempMgr(origFilename, callback, flags & UNWIND_NEW);
|
||||
|
||||
if (tempMgr.needs(ITraceFactory::TRACE_EVENT_ATTACH))
|
||||
tempMgr.event_attach(&conn, flags & UNWIND_CREATE, result);
|
||||
@ -4696,9 +4696,9 @@ void JProvider::shutdown(CheckStatusWrapper* status, unsigned int timeout, const
|
||||
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
|
||||
TraceManager::shutdown();
|
||||
JrdTraceManager::shutdown();
|
||||
Mapping::shutdownIpc();
|
||||
}
|
||||
|
||||
@ -8701,7 +8701,7 @@ static void unwindAttach(thread_db* tdbb, const char* filename, const Exception&
|
||||
try
|
||||
{
|
||||
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())
|
||||
{
|
||||
TraceConnectionImpl conn(att);
|
||||
@ -8766,7 +8766,7 @@ static void unwindAttach(thread_db* tdbb, const char* filename, const Exception&
|
||||
sAtt->manualLock(flags);
|
||||
if (sAtt->getHandle())
|
||||
{
|
||||
TraceManager* traceManager = attachment->att_trace_manager;
|
||||
JrdTraceManager* traceManager = attachment->att_trace_manager;
|
||||
TraceConnectionImpl conn(attachment);
|
||||
|
||||
if (traceManager->needs(ITraceFactory::TRACE_EVENT_DETACH))
|
||||
|
@ -129,7 +129,7 @@ class Parameter;
|
||||
class jrd_fld;
|
||||
class dsql_dbb;
|
||||
class PreparedStatement;
|
||||
class TraceManager;
|
||||
class JrdTraceManager;
|
||||
class MessageNode;
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "../jrd/exe_proto.h"
|
||||
#include "../jrd/mov_proto.h"
|
||||
#include "../jrd/vio_proto.h"
|
||||
#include "../jrd/trace/TraceManager.h"
|
||||
#include "../supplement/trace/JrdTraceManager.h"
|
||||
#include "../jrd/trace/TraceJrdHelpers.h"
|
||||
#include "../jrd/optimizer/Optimizer.h"
|
||||
|
||||
|
@ -56,7 +56,7 @@
|
||||
#include "../common/db_alias.h"
|
||||
#include "../jrd/scl.h"
|
||||
#include "../common/msg_encode.h"
|
||||
#include "../jrd/trace/TraceManager.h"
|
||||
#include "../supplement/trace/JrdTraceManager.h"
|
||||
#include "../jrd/trace/TraceObjects.h"
|
||||
#include "../jrd/EngineInterface.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
|
||||
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;
|
||||
return;
|
||||
}
|
||||
@ -803,11 +803,11 @@ Service::Service(const TEXT* service_name, USHORT spb_length, const UCHAR* spb_d
|
||||
svc_perm_sw = switches;
|
||||
svc_user_flag = user_flag;
|
||||
|
||||
svc_trace_manager = FB_NEW_POOL(*getDefaultMemoryPool()) TraceManager(this);
|
||||
svc_trace_manager = FB_NEW_POOL(*getDefaultMemoryPool()) JrdTraceManager(this);
|
||||
} // try
|
||||
catch (const Firebird::Exception& ex)
|
||||
{
|
||||
TraceManager* trace_manager = NULL;
|
||||
JrdTraceManager* trace_manager = NULL;
|
||||
FbLocalStatus status_vector;
|
||||
|
||||
try
|
||||
@ -817,7 +817,7 @@ Service::Service(const TEXT* service_name, USHORT spb_length, const UCHAR* spb_d
|
||||
if (hasTrace)
|
||||
trace_manager = svc_trace_manager;
|
||||
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))
|
||||
{
|
||||
|
@ -102,7 +102,7 @@ const int SVC_cmd_line = 0x80;
|
||||
|
||||
// forward decl.
|
||||
class thread_db;
|
||||
class TraceManager;
|
||||
class JrdTraceManager;
|
||||
|
||||
// Service manager
|
||||
class Service : public Firebird::UtilSvc, public TypedHandle<type_svc>
|
||||
@ -151,7 +151,7 @@ public:
|
||||
Firebird::ICryptKeyCallback* getCryptCallback() override;
|
||||
int getParallelWorkers() override { return svc_parallel_workers; }
|
||||
|
||||
TraceManager* getTraceManager()
|
||||
virtual JrdTraceManager* getTraceManager()
|
||||
{
|
||||
return svc_trace_manager;
|
||||
}
|
||||
@ -336,7 +336,7 @@ private:
|
||||
Firebird::string svc_remote_process;
|
||||
SLONG svc_remote_pid;
|
||||
|
||||
TraceManager* svc_trace_manager;
|
||||
JrdTraceManager* svc_trace_manager;
|
||||
Firebird::ICryptKeyCallback* svc_crypt_callback;
|
||||
|
||||
public:
|
||||
|
@ -69,7 +69,7 @@
|
||||
#include "../dsql/dsql_proto.h"
|
||||
#include "../common/StatusArg.h"
|
||||
#include "../jrd/replication/Publisher.h"
|
||||
#include "../jrd/trace/TraceManager.h"
|
||||
#include "../supplement/trace/JrdTraceManager.h"
|
||||
#include "../jrd/trace/TraceJrdHelpers.h"
|
||||
#include "../jrd/Function.h"
|
||||
#include "../jrd/Collation.h"
|
||||
@ -4183,7 +4183,7 @@ TraceSweepEvent::TraceSweepEvent(thread_db* tdbb)
|
||||
m_sweep_info.getOST(),
|
||||
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_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());
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -4282,7 +4282,7 @@ void TraceSweepEvent::report(ntrace_process_state_t state)
|
||||
return;
|
||||
|
||||
Database* dbb = m_tdbb->getDatabase();
|
||||
TraceManager* trace_mgr = att->att_trace_manager;
|
||||
JrdTraceManager* trace_mgr = att->att_trace_manager;
|
||||
|
||||
TraceConnectionImpl conn(att);
|
||||
|
||||
|
@ -33,10 +33,12 @@
|
||||
#include "../../jrd/err_proto.h"
|
||||
#include "../../common/isc_proto.h"
|
||||
#include "../../common/isc_s_proto.h"
|
||||
#include "../../jrd/jrd.h"
|
||||
#include "../../common/os/path_utils.h"
|
||||
#include "../../common/os/os_utils.h"
|
||||
#include "../../jrd/trace/TraceConfigStorage.h"
|
||||
#include "../../common/file_params.h"
|
||||
#include "../../common/config/config.h"
|
||||
#include "../../common/status.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
|
@ -28,7 +28,7 @@
|
||||
#ifndef 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"
|
||||
|
||||
namespace Jrd {
|
||||
@ -47,7 +47,7 @@ public:
|
||||
m_string_len(string_length),
|
||||
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)
|
||||
return;
|
||||
|
||||
@ -86,14 +86,14 @@ public:
|
||||
if ((result == ITracePlugin::RESULT_SUCCESS) && m_request)
|
||||
{
|
||||
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
|
||||
{
|
||||
Firebird::string str(*getDefaultMemoryPool(), m_string, m_string_len);
|
||||
|
||||
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_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)
|
||||
return;
|
||||
|
||||
{ // scope
|
||||
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);
|
||||
}
|
||||
|
||||
@ -157,7 +157,7 @@ public:
|
||||
m_dsqlRequest->req_fetch_rowcount);
|
||||
|
||||
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;
|
||||
}
|
||||
@ -181,7 +181,7 @@ public:
|
||||
m_attachment(attachment),
|
||||
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);
|
||||
|
||||
if (!m_need_trace)
|
||||
@ -217,7 +217,7 @@ public:
|
||||
|
||||
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);
|
||||
|
||||
m_dsqlRequest->req_fetch_elapsed = 0;
|
||||
|
@ -29,7 +29,7 @@
|
||||
#define JRD_TRACE_JRD_HELPERS_H
|
||||
|
||||
#include "../../jrd/jrd.h"
|
||||
#include "../../jrd/trace/TraceManager.h"
|
||||
#include "../../supplement/trace/JrdTraceManager.h"
|
||||
#include "../../jrd/trace/TraceObjects.h"
|
||||
|
||||
namespace Jrd {
|
||||
@ -616,7 +616,7 @@ public:
|
||||
|
||||
m_start_clock = (fb_utils::query_performance_counter() - m_start_clock) * 1000 /
|
||||
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());
|
||||
TraceTransactionImpl tran(m_tdbb->getTransaction());
|
||||
@ -691,7 +691,7 @@ public:
|
||||
TraceTransactionImpl tran(m_tdbb->getTransaction());
|
||||
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);
|
||||
|
||||
m_request->req_fetch_baseline = NULL;
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
#include "../../common/classes/auto.h"
|
||||
#include "../../common/utils_proto.h"
|
||||
#include "../../jrd/trace/TraceManager.h"
|
||||
#include "../../supplement/trace/JrdTraceManager.h"
|
||||
#include "../../jrd/trace/TraceLog.h"
|
||||
#include "../../jrd/trace/TraceObjects.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
|
||||
|
||||
const char* TraceInitInfoImpl::getFirebirdRootDirectory()
|
||||
@ -553,7 +486,7 @@ ITraceLogWriter* TraceInitInfoImpl::getLogWriter()
|
||||
{
|
||||
if (!m_logWriter && !m_session.ses_logfile.empty())
|
||||
{
|
||||
m_logWriter = FB_NEW TraceLogWriterImpl(m_session);
|
||||
m_logWriter = TraceManager::createSessionLogWriter(m_session);
|
||||
}
|
||||
if (m_logWriter)
|
||||
{
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include "../../jrd/svc.h"
|
||||
#include "../../common/os/guid.h"
|
||||
#include "../../jrd/trace/TraceLog.h"
|
||||
#include "../../jrd/trace/TraceManager.h"
|
||||
#include "../../supplement/trace/JrdTraceManager.h"
|
||||
#include "../../jrd/trace/TraceService.h"
|
||||
#include "../../jrd/scl.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)
|
||||
{
|
||||
if (!TraceManager::pluginsCount())
|
||||
if (!JrdTraceManager::pluginsCount())
|
||||
{
|
||||
m_svc.printf(false, "Can not start trace session. There are no trace plugins loaded\n");
|
||||
return;
|
||||
@ -148,7 +148,7 @@ void TraceSvcJrd::stopSession(ULONG id)
|
||||
{
|
||||
m_svc.started();
|
||||
|
||||
ConfigStorage* storage = TraceManager::getStorage();
|
||||
ConfigStorage* storage = JrdTraceManager::getStorage();
|
||||
StorageGuard guard(storage);
|
||||
|
||||
TraceSession session(*getDefaultMemoryPool());
|
||||
@ -187,7 +187,7 @@ void TraceSvcJrd::setActive(ULONG id, bool active)
|
||||
|
||||
bool TraceSvcJrd::changeFlags(ULONG id, int setFlags, int clearFlags)
|
||||
{
|
||||
ConfigStorage* storage = TraceManager::getStorage();
|
||||
ConfigStorage* storage = JrdTraceManager::getStorage();
|
||||
StorageGuard guard(storage);
|
||||
|
||||
TraceSession session(*getDefaultMemoryPool());
|
||||
@ -219,7 +219,7 @@ void TraceSvcJrd::listSessions()
|
||||
{
|
||||
m_svc.started();
|
||||
|
||||
ConfigStorage* storage = TraceManager::getStorage();
|
||||
ConfigStorage* storage = JrdTraceManager::getStorage();
|
||||
StorageGuard guard(storage);
|
||||
|
||||
storage->restart();
|
||||
@ -307,7 +307,7 @@ void TraceSvcJrd::readSession(TraceSession& session)
|
||||
|
||||
bool TraceSvcJrd::checkAliveAndFlags(ULONG sesId, int& flags)
|
||||
{
|
||||
ConfigStorage* storage = TraceManager::getStorage();
|
||||
ConfigStorage* storage = JrdTraceManager::getStorage();
|
||||
|
||||
bool alive = (m_chg_number == storage->getChangeNumber());
|
||||
if (!alive)
|
||||
|
@ -88,7 +88,7 @@
|
||||
#include "../common/StatusArg.h"
|
||||
#include "../jrd/GarbageCollector.h"
|
||||
#include "../jrd/ProfilerManager.h"
|
||||
#include "../jrd/trace/TraceManager.h"
|
||||
#include "../supplement/trace/JrdTraceManager.h"
|
||||
#include "../jrd/trace/TraceJrdHelpers.h"
|
||||
#include "../common/Task.h"
|
||||
#include "../jrd/WorkerAttachment.h"
|
||||
|
@ -75,6 +75,13 @@
|
||||
#include "../common/os/os_utils.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;
|
||||
|
||||
|
||||
@ -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> remoteFailedLogins;
|
||||
bool server_shutdown = false;
|
||||
@ -510,12 +662,13 @@ public:
|
||||
virtual void accept(PACKET* send, Auth::WriterImplementation* authBlock) = 0;
|
||||
|
||||
ServerAuth(ClumpletReader* aPb, const ParametersSet& aTags,
|
||||
rem_port* port, bool multiPartData = false)
|
||||
rem_port* port, bool multiPartData = false, const PathName db = "")
|
||||
: authItr(NULL),
|
||||
userName(getPool()),
|
||||
authServer(NULL),
|
||||
tags(&aTags),
|
||||
hopsCount(0),
|
||||
dbName(getPool(), db),
|
||||
authPort(port)
|
||||
{
|
||||
if (!authPort->port_srv_auth_block)
|
||||
@ -603,6 +756,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void saveForTrace(const PathName& db)
|
||||
{
|
||||
dbName = db;
|
||||
}
|
||||
|
||||
~ServerAuth()
|
||||
{ }
|
||||
|
||||
@ -641,6 +799,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
int authResult = IAuth::AUTH_FAILED;
|
||||
|
||||
while (authItr && working && authItr->hasData())
|
||||
{
|
||||
if (!authServer)
|
||||
@ -753,6 +913,11 @@ public:
|
||||
// no success - perform failure processing
|
||||
loginFail(userName, authPort->getRemoteId());
|
||||
|
||||
if (authResult != IAuth::AUTH_SUCCESS)
|
||||
{
|
||||
traceFailedConnection(authPort, dbName.c_str(), userName, ITracePlugin::RESULT_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
if (st.hasData())
|
||||
{
|
||||
switch (st.getErrors()[1])
|
||||
@ -784,6 +949,7 @@ private:
|
||||
unsigned int hopsCount;
|
||||
|
||||
protected:
|
||||
PathName dbName;
|
||||
rem_port* authPort;
|
||||
};
|
||||
|
||||
@ -792,8 +958,7 @@ class DatabaseAuth : public ServerAuth
|
||||
{
|
||||
public:
|
||||
DatabaseAuth(rem_port* port, const PathName& db, ClumpletWriter* dpb, P_OP op)
|
||||
: ServerAuth(dpb, dpbParam, port),
|
||||
dbName(getPool(), db),
|
||||
: ServerAuth(dpb, dpbParam, port, false, db),
|
||||
pb(dpb),
|
||||
operation(op)
|
||||
{ }
|
||||
@ -801,7 +966,6 @@ public:
|
||||
void accept(PACKET* send, Auth::WriterImplementation* authBlock);
|
||||
|
||||
private:
|
||||
PathName dbName;
|
||||
AutoPtr<ClumpletWriter> pb;
|
||||
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
|
||||
{
|
||||
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_length);
|
||||
|
||||
PathName bkDbName;
|
||||
if (accepted)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
ConnectAuth* cnctAuth = FB_NEW ConnectAuth(port, id);
|
||||
cnctAuth->saveForTrace(bkDbName);
|
||||
port->port_srv_auth = cnctAuth;
|
||||
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
|
||||
if (!accepted)
|
||||
{
|
||||
ntrace_result_t connectResult = ITracePlugin::RESULT_UNAUTHORIZED;
|
||||
|
||||
HANDSHAKE_DEBUG(fprintf(stderr, "!accepted, sending reject\n"));
|
||||
|
||||
if (status.getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
{
|
||||
if (status.getErrors()[1] != isc_login)
|
||||
connectResult = ITracePlugin::RESULT_FAILED;
|
||||
|
||||
switch (status.getErrors()[1])
|
||||
{
|
||||
case isc_missing_data_structures:
|
||||
@ -2151,7 +2363,12 @@ static bool accept_connection(rem_port* port, P_CNCT* connect, PACKET* send)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
port->send(send);
|
||||
}
|
||||
|
||||
::traceFailedConnection(port, bkDbName.c_str(), port->port_login, connectResult);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -7236,6 +7453,7 @@ void Worker::shutdown()
|
||||
|
||||
static int shut_server(const int, const int, void*)
|
||||
{
|
||||
TraceManager::shutdown(); // This storage is separate from the jrd one
|
||||
server_shutdown = true;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* PROGRAM: JRD Access Method
|
||||
* MODULE: TraceManager.cpp
|
||||
* MODULE: JrdTraceManager.cpp
|
||||
* DESCRIPTION: Trace API manager
|
||||
*
|
||||
* The contents of this file are subject to the Initial
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
#include "firebird.h"
|
||||
|
||||
#include "../../jrd/trace/TraceManager.h"
|
||||
#include "JrdTraceManager.h"
|
||||
#include "../../jrd/trace/TraceObjects.h"
|
||||
#include "../../jrd/Mapping.h"
|
||||
#include "../../common/os/path_utils.h"
|
||||
@ -50,79 +50,43 @@ namespace
|
||||
|
||||
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;
|
||||
|
||||
|
||||
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(Attachment* in_att) :
|
||||
JrdTraceManager::JrdTraceManager(Attachment* in_att) :
|
||||
TraceManager(NULL, *in_att->att_pool),
|
||||
attachment(in_att),
|
||||
service(NULL),
|
||||
filename(NULL),
|
||||
callback(NULL),
|
||||
trace_sessions(*in_att->att_pool),
|
||||
active(false)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
TraceManager::TraceManager(Service* in_svc) :
|
||||
JrdTraceManager::JrdTraceManager(Service* in_svc) :
|
||||
TraceManager(NULL, in_svc->getPool()),
|
||||
attachment(NULL),
|
||||
service(in_svc),
|
||||
filename(NULL),
|
||||
callback(NULL),
|
||||
trace_sessions(in_svc->getPool()),
|
||||
active(true)
|
||||
{
|
||||
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),
|
||||
service(NULL),
|
||||
filename(in_filename),
|
||||
callback(cb),
|
||||
trace_sessions(*getDefaultMemoryPool()),
|
||||
active(true),
|
||||
failedAttach(failed)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
TraceManager::~TraceManager()
|
||||
JrdTraceManager::~JrdTraceManager()
|
||||
{
|
||||
}
|
||||
|
||||
void TraceManager::init()
|
||||
void JrdTraceManager::init()
|
||||
{
|
||||
// ensure storage is initialized
|
||||
getStorage();
|
||||
@ -130,100 +94,19 @@ void TraceManager::init()
|
||||
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()
|
||||
{
|
||||
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()
|
||||
void JrdTraceManager::update_sessions()
|
||||
{
|
||||
// Let be inactive until database is creating
|
||||
if (attachment && (attachment->att_database->dbb_flags & DBB_creating))
|
||||
return;
|
||||
|
||||
MemoryPool& pool = *getDefaultMemoryPool();
|
||||
SortedArray<ULONG, InlineStorage<ULONG, 64> > liveSessions(pool);
|
||||
HalfStaticArray<TraceSession*, 64> newSessions(pool);
|
||||
|
||||
{ // scope
|
||||
ConfigStorage* storage = getStorage();
|
||||
reload_sessions_lists(newSessions);
|
||||
|
||||
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
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void TraceManager::event_dsql_prepare(Attachment* att, jrd_tra* transaction,
|
||||
ITraceSQLStatement* statement, ntrace_counter_t time_millis, ntrace_result_t req_result)
|
||||
void JrdTraceManager::event_dsql_prepare(Attachment* att, jrd_tra* transaction,
|
||||
ITraceSQLStatement* statement,
|
||||
ntrace_counter_t time_millis, ntrace_result_t req_result)
|
||||
{
|
||||
TraceConnectionImpl conn(att);
|
||||
TraceTransactionImpl tran(transaction);
|
||||
@ -417,7 +301,7 @@ void TraceManager::event_dsql_prepare(Attachment* att, jrd_tra* transaction,
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
TraceConnectionImpl conn(att);
|
||||
@ -435,7 +319,7 @@ void TraceManager::event_dsql_execute(Attachment* att, jrd_tra* transaction,
|
||||
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)
|
||||
{
|
||||
TraceConnectionImpl conn(att);
|
||||
@ -446,40 +330,7 @@ void TraceManager::event_dsql_restart(Attachment* att, jrd_tra* transaction,
|
||||
(unsigned) number);
|
||||
}
|
||||
|
||||
#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 { \
|
||||
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,
|
||||
void JrdTraceManager::event_transaction_start(ITraceDatabaseConnection* connection,
|
||||
ITraceTransaction* transaction, unsigned tpb_length, const ntrace_byte_t* tpb,
|
||||
ntrace_result_t tra_result)
|
||||
{
|
||||
@ -487,7 +338,7 @@ void TraceManager::event_transaction_start(ITraceDatabaseConnection* connection,
|
||||
(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,
|
||||
ntrace_result_t tra_result)
|
||||
{
|
||||
@ -495,56 +346,56 @@ void TraceManager::event_transaction_end(ITraceDatabaseConnection* connection,
|
||||
(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)
|
||||
{
|
||||
EXECUTE_HOOKS(trace_set_context,
|
||||
(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)
|
||||
{
|
||||
EXECUTE_HOOKS(trace_proc_compile,
|
||||
(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)
|
||||
{
|
||||
EXECUTE_HOOKS(trace_proc_execute,
|
||||
(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)
|
||||
{
|
||||
EXECUTE_HOOKS(trace_func_compile,
|
||||
(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)
|
||||
{
|
||||
EXECUTE_HOOKS(trace_func_execute,
|
||||
(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)
|
||||
{
|
||||
EXECUTE_HOOKS(trace_trigger_compile,
|
||||
(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)
|
||||
{
|
||||
EXECUTE_HOOKS(trace_trigger_execute,
|
||||
(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)
|
||||
{
|
||||
EXECUTE_HOOKS(trace_dsql_prepare,
|
||||
@ -552,37 +403,37 @@ void TraceManager::event_dsql_prepare(ITraceDatabaseConnection* connection, ITra
|
||||
time_millis, req_result));
|
||||
}
|
||||
|
||||
void TraceManager::event_dsql_free(ITraceDatabaseConnection* connection,
|
||||
void JrdTraceManager::event_dsql_free(ITraceDatabaseConnection* connection,
|
||||
ITraceSQLStatement* statement, unsigned short option)
|
||||
{
|
||||
EXECUTE_HOOKS(trace_dsql_free,
|
||||
(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)
|
||||
{
|
||||
EXECUTE_HOOKS(trace_dsql_execute,
|
||||
(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)
|
||||
{
|
||||
EXECUTE_HOOKS(trace_dsql_restart,
|
||||
(connection, transaction, statement, number));
|
||||
}
|
||||
|
||||
void TraceManager::event_blr_compile(ITraceDatabaseConnection* connection,
|
||||
void JrdTraceManager::event_blr_compile(ITraceDatabaseConnection* connection,
|
||||
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,
|
||||
(connection, transaction, statement,
|
||||
time_millis, req_result));
|
||||
}
|
||||
|
||||
void TraceManager::event_blr_execute(ITraceDatabaseConnection* connection,
|
||||
void JrdTraceManager::event_blr_execute(ITraceDatabaseConnection* connection,
|
||||
ITraceTransaction* transaction, ITraceBLRStatement* statement,
|
||||
ntrace_result_t req_result)
|
||||
{
|
||||
@ -590,7 +441,7 @@ void TraceManager::event_blr_execute(ITraceDatabaseConnection* connection,
|
||||
(connection, transaction, statement, req_result));
|
||||
}
|
||||
|
||||
void TraceManager::event_dyn_execute(ITraceDatabaseConnection* connection,
|
||||
void JrdTraceManager::event_dyn_execute(ITraceDatabaseConnection* connection,
|
||||
ITraceTransaction* transaction, ITraceDYNRequest* request,
|
||||
ntrace_counter_t time_millis, ntrace_result_t req_result)
|
||||
{
|
||||
@ -599,13 +450,13 @@ void TraceManager::event_dyn_execute(ITraceDatabaseConnection* connection,
|
||||
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,
|
||||
(service, att_result));
|
||||
}
|
||||
|
||||
void TraceManager::event_service_start(ITraceServiceConnection* service,
|
||||
void JrdTraceManager::event_service_start(ITraceServiceConnection* service,
|
||||
unsigned switches_length, const char* switches,
|
||||
ntrace_result_t start_result)
|
||||
{
|
||||
@ -613,7 +464,7 @@ void TraceManager::event_service_start(ITraceServiceConnection* service,
|
||||
(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 recv_item_length, const ntrace_byte_t* recv_items,
|
||||
ntrace_result_t query_result)
|
||||
@ -623,20 +474,20 @@ void TraceManager::event_service_query(ITraceServiceConnection* service,
|
||||
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,
|
||||
(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,
|
||||
(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)
|
||||
{
|
||||
EXECUTE_HOOKS(trace_event_sweep,
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* PROGRAM: JRD Access Method
|
||||
* MODULE: TraceManager.h
|
||||
* MODULE: JrdTraceManager.h
|
||||
* DESCRIPTION: Trace API manager
|
||||
*
|
||||
* The contents of this file are subject to the Initial
|
||||
@ -29,15 +29,7 @@
|
||||
#ifndef JRD_TRACEMANAGER_H
|
||||
#define JRD_TRACEMANAGER_H
|
||||
|
||||
#include <time.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"
|
||||
#include "TraceManager.h"
|
||||
|
||||
namespace Firebird {
|
||||
|
||||
@ -53,27 +45,17 @@ class jrd_tra;
|
||||
class DsqlRequest;
|
||||
class Service;
|
||||
|
||||
class TraceManager
|
||||
class JrdTraceManager : public TraceManager
|
||||
{
|
||||
public:
|
||||
/* Initializes plugins. */
|
||||
explicit TraceManager(Attachment* in_att);
|
||||
explicit TraceManager(Service* in_svc);
|
||||
TraceManager(const char* in_filename, Firebird::ICryptKeyCallback* callback, bool failedAttach);
|
||||
explicit JrdTraceManager(Attachment* in_att);
|
||||
explicit JrdTraceManager(Service* in_svc);
|
||||
JrdTraceManager(const char* in_filename, Firebird::ICryptKeyCallback* callback, bool failedAttach);
|
||||
|
||||
/* 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 */
|
||||
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,
|
||||
int number);
|
||||
|
||||
static void shutdown();
|
||||
|
||||
private:
|
||||
Attachment* attachment;
|
||||
Service* service;
|
||||
const char* filename;
|
||||
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 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);
|
||||
|
||||
/* 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,
|
||||
Firebird::ITraceSQLStatement* statement,
|
||||
@ -271,9 +191,6 @@ private:
|
||||
void event_dsql_restart(Firebird::ITraceDatabaseConnection* connection, Firebird::ITraceTransaction* transaction, Firebird::ITraceSQLStatement* statement,
|
||||
unsigned number);
|
||||
|
||||
static Firebird::GlobalPtr<StorageInstance, Firebird::InstanceControl::PRIORITY_DELETE_FIRST> storageInstance;
|
||||
|
||||
ULONG changeNumber;
|
||||
bool active, failedAttach;
|
||||
};
|
||||
|
417
src/supplement/trace/TraceManager.cpp
Normal file
417
src/supplement/trace/TraceManager.cpp
Normal 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);
|
||||
}
|
177
src/supplement/trace/TraceManager.h
Normal file
177
src/supplement/trace/TraceManager.h
Normal 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
|
Loading…
Reference in New Issue
Block a user