|
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