|
32 | 32 | #include <memcached/isotime.h> |
33 | 33 | #include <platform/string_hex.h> |
34 | 34 |
|
| 35 | +#include <folly/Synchronized.h> |
35 | 36 | #include <nlohmann/json.hpp> |
36 | 37 |
|
37 | 38 | #include <sstream> |
38 | 39 |
|
39 | | -static cb::audit::UniqueAuditPtr auditHandle; |
| 40 | +static folly::Synchronized<cb::audit::UniqueAuditPtr> auditHandle; |
40 | 41 |
|
41 | 42 | static std::atomic_bool audit_enabled{false}; |
42 | 43 |
|
@@ -113,9 +114,13 @@ static void do_audit(uint32_t id, |
113 | 114 | const nlohmann::json& event, |
114 | 115 | const char* warn) { |
115 | 116 | auto text = event.dump(); |
116 | | - if (!auditHandle->put_event(id, text)) { |
117 | | - LOG_WARNING("{}: {}", warn, text); |
118 | | - } |
| 117 | + auditHandle.withRLock([id, warn, &text](auto& handle) { |
| 118 | + if (handle) { |
| 119 | + if (!handle->put_event(id, text)) { |
| 120 | + LOG_WARNING("{}: {}", warn, text); |
| 121 | + } |
| 122 | + } |
| 123 | + }); |
119 | 124 | } |
120 | 125 |
|
121 | 126 | void audit_auth_failure(const Connection& c, const char* reason) { |
@@ -263,7 +268,12 @@ bool mc_audit_event(uint32_t audit_eventid, cb::const_byte_buffer payload) { |
263 | 268 |
|
264 | 269 | cb::const_char_buffer buffer{reinterpret_cast<const char*>(payload.data()), |
265 | 270 | payload.size()}; |
266 | | - return auditHandle->put_event(audit_eventid, buffer); |
| 271 | + return auditHandle.withRLock([audit_eventid, buffer](auto& handle) { |
| 272 | + if (!handle) { |
| 273 | + return false; |
| 274 | + } |
| 275 | + return handle->put_event(audit_eventid, buffer); |
| 276 | + }); |
267 | 277 | } |
268 | 278 |
|
269 | 279 | namespace cb { |
@@ -335,28 +345,37 @@ static void event_state_listener(uint32_t id, bool enabled) { |
335 | 345 |
|
336 | 346 | void initialize_audit() { |
337 | 347 | /* Start the audit daemon */ |
338 | | - auditHandle = cb::audit::create_audit_daemon( |
| 348 | + auto audit = cb::audit::create_audit_daemon( |
339 | 349 | Settings::instance().getAuditFile(), get_server_api()->cookie); |
340 | | - if (!auditHandle) { |
| 350 | + if (!audit) { |
341 | 351 | FATAL_ERROR(EXIT_FAILURE, "FATAL: Failed to start audit daemon"); |
342 | 352 | } |
343 | | - auditHandle->add_event_state_listener(event_state_listener); |
344 | | - auditHandle->notify_all_event_states(); |
| 353 | + audit->add_event_state_listener(event_state_listener); |
| 354 | + audit->notify_all_event_states(); |
| 355 | + *auditHandle.wlock() = std::move(audit); |
345 | 356 | } |
346 | 357 |
|
347 | 358 | void shutdown_audit() { |
348 | | - auditHandle.reset(); |
| 359 | + auditHandle.wlock()->reset(); |
349 | 360 | } |
350 | 361 |
|
351 | 362 | ENGINE_ERROR_CODE reconfigure_audit(Cookie& cookie) { |
352 | | - if (auditHandle->configure_auditdaemon(Settings::instance().getAuditFile(), |
353 | | - static_cast<void*>(&cookie))) { |
354 | | - return ENGINE_EWOULDBLOCK; |
355 | | - } |
356 | | - |
357 | | - return ENGINE_FAILED; |
| 363 | + return auditHandle.withRLock([&cookie](auto& handle) { |
| 364 | + if (!handle) { |
| 365 | + return ENGINE_FAILED; |
| 366 | + } |
| 367 | + if (handle->configure_auditdaemon(Settings::instance().getAuditFile(), |
| 368 | + static_cast<void*>(&cookie))) { |
| 369 | + return ENGINE_EWOULDBLOCK; |
| 370 | + } |
| 371 | + return ENGINE_FAILED; |
| 372 | + }); |
358 | 373 | } |
359 | 374 |
|
360 | 375 | void stats_audit(const AddStatFn& add_stats, Cookie& cookie) { |
361 | | - auditHandle->stats(add_stats, &cookie); |
| 376 | + auditHandle.withRLock([&add_stats, &cookie](auto& handle) { |
| 377 | + if (handle) { |
| 378 | + handle->stats(add_stats, &cookie); |
| 379 | + } |
| 380 | + }); |
362 | 381 | } |
0 commit comments