From fb1aace89d73b0c78e29ef93ab17dd42fd811e32 Mon Sep 17 00:00:00 2001 From: Egor Ivkov <e.o.ivkov@gmail.com> Date: Mon, 1 Apr 2024 17:53:11 +0300 Subject: [PATCH] feat: add integrity_violation audit log event (cherry picked from commit 46dfe8c102103adad168daa0f33a31cc0d46e160) --- src/audit.rs | 2 +- src/lib.rs | 16 ++++++++++++++++ test/int/test_audit.py | 25 +++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/audit.rs b/src/audit.rs index 9b8952af79..028b5e193b 100644 --- a/src/audit.rs +++ b/src/audit.rs @@ -1,4 +1,4 @@ -use crate::traft::{LogicalClock, RaftSpaceAccess}; +use crate::traft::LogicalClock; use once_cell::sync::OnceCell; use std::ffi::{CStr, CString}; use tarantool::{error::TarantoolError, log::SayLevel}; diff --git a/src/lib.rs b/src/lib.rs index e331d5bb1d..1218f03bce 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -553,6 +553,22 @@ fn init_common( tlog::set_core_logger_is_initialized(true); if let Err(e) = tarantool::set_cfg(cfg) { + let tnt_err = ::tarantool::error::TarantoolError::last(); + let err_ty = tnt_err.error_type(); + if err_ty == "XlogError" { + if let Some(config) = &config.instance.audit { + // Init log with stab values for raft_id and gen. + // We need to log the 'integrity_violation' event and + // there is nowhere to take raft state from at the moment. + audit::init(config, 0, 0); + crate::audit!( + message: "integrity violation detected", + title: "integrity_violation", + severity: High, + error: format!("{err_ty}: {}", tnt_err.message()), + ) + } + } tlog::set_core_logger_is_initialized(false); return Err(Error::other(format!("core initialization failed: {e}"))); } diff --git a/test/int/test_audit.py b/test/int/test_audit.py index 67a322f34f..3c4fb3a324 100644 --- a/test/int/test_audit.py +++ b/test/int/test_audit.py @@ -90,6 +90,31 @@ def test_startup(instance: Instance): assert event["initiator"] == "admin" +def test_integrity_violation(instance: Instance): + # Instance was up for some time + instance.start() + instance.terminate() + + # Then data files were modified and instance restarted + snap_name = f"{instance.data_dir}/00000000000000000000.snap" + with open(snap_name, "w") as snap: + snap.write("abc") + + # Instance should fail to start + instance.fail_to_start() + + # Instance should detect integrity violation + events = list(AuditFile(instance.audit_flag_value).events()) + event = take_until_title(iter(events), "integrity_violation") + assert event is not None + assert event["message"] == "integrity violation detected" + assert event["severity"] == "high" + assert ( + event["error"] + == "XlogError: Unexpected end of file, run with 'force_recovery = true'" + ) + + def test_recover_database(instance: Instance): instance.start() instance.wait_online() -- GitLab