*
*/
-#include "action-executor.h"
-#include "cmd.h"
-#include "health-sessiond.h"
-#include "lttng-sessiond.h"
-#include "notification-thread-internal.h"
-#include "session.h"
-#include "thread.h"
-#include <common/dynamic-array.h>
-#include <common/macros.h>
-#include <common/optional.h>
-#include <lttng/action/action-internal.h>
-#include <lttng/action/list-internal.h>
+#include "action-executor.hpp"
+#include "cmd.hpp"
+#include "health-sessiond.hpp"
+#include "lttng-sessiond.hpp"
+#include "notification-thread-internal.hpp"
+#include "session.hpp"
+#include "thread.hpp"
+#include <common/dynamic-array.hpp>
+#include <common/macros.hpp>
+#include <common/optional.hpp>
+#include <lttng/action/action-internal.hpp>
+#include <lttng/action/list-internal.hpp>
#include <lttng/action/list.h>
-#include <lttng/action/notify-internal.h>
+#include <lttng/action/notify-internal.hpp>
#include <lttng/action/notify.h>
#include <lttng/action/rotate-session.h>
#include <lttng/action/snapshot-session.h>
#include <lttng/action/start-session.h>
#include <lttng/action/stop-session.h>
#include <lttng/condition/evaluation.h>
-#include <lttng/condition/event-rule-matches-internal.h>
+#include <lttng/condition/event-rule-matches-internal.hpp>
#include <lttng/lttng-error.h>
-#include <lttng/trigger/trigger-internal.h>
+#include <lttng/trigger/trigger-internal.hpp>
#include <pthread.h>
#include <stdbool.h>
#include <stddef.h>
static int action_executor_notify_handler(struct action_executor *executor,
const struct action_work_item *work_item,
- struct action_work_subitem *item)
+ struct action_work_subitem *item __attribute__((unused)))
{
return notification_client_list_send_evaluation(work_item->client_list,
work_item->trigger,
}
static int action_executor_start_session_handler(
- struct action_executor *executor,
+ struct action_executor *executor __attribute__((unused)),
const struct action_work_item *work_item,
struct action_work_subitem *item)
{
* existed. If not skip the action altogether.
*/
if (!item->context.session_id.is_set) {
- DBG("Session `%s` was not present at the moment the work item was enqueued for %s` action of trigger `%s`",
+ DBG("Session `%s` was not present at the moment the work item was enqueued for `%s` action of trigger `%s`",
session_name, get_action_name(action),
get_trigger_name(work_item->trigger));
lttng_action_increase_execution_failure_count(action);
- ret = 0;
goto end;
}
session_lock_list();
- session = session_find_by_name(session_name);
+ rcu_read_lock();
+ session = session_find_by_id(LTTNG_OPTIONAL_GET(item->context.session_id));
if (!session) {
DBG("Failed to find session `%s` by name while executing `%s` action of trigger `%s`",
session_name, get_action_name(action),
get_trigger_name(work_item->trigger));
+ lttng_action_increase_execution_failure_count(action);
goto error_unlock_list;
}
- /*
- * Check if the session id is the same as when the work item was
- * enqueued.
- */
- if (session->id != LTTNG_OPTIONAL_GET(item->context.session_id)) {
- DBG("Session id for session `%s` (id: %" PRIu64
- " is not the same that was sampled (id: %" PRIu64
- " at the moment the work item was enqueued for %s` action of trigger `%s`",
- session_name, session->id,
- LTTNG_OPTIONAL_GET(item->context.session_id),
+ session_lock(session);
+ if (session->destroyed) {
+ DBG("Session `%s` with id = %" PRIu64 " is flagged as destroyed. Skipping: action = `%s`, trigger = `%s`",
+ session->name, session->id,
get_action_name(action),
get_trigger_name(work_item->trigger));
- ret = 0;
- goto error_put_session;
+ goto error_unlock_session;
}
- session_lock(session);
if (!is_trigger_allowed_for_session(work_item->trigger, session)) {
goto error_unlock_session;
}
error_unlock_session:
session_unlock(session);
-error_put_session:
session_put(session);
error_unlock_list:
+ rcu_read_unlock();
session_unlock_list();
end:
return ret;
}
static int action_executor_stop_session_handler(
- struct action_executor *executor,
+ struct action_executor *executor __attribute__((unused)),
const struct action_work_item *work_item,
struct action_work_subitem *item)
{
* existed. If not, skip the action altogether.
*/
if (!item->context.session_id.is_set) {
- DBG("Session `%s` was not present at the moment the work item was enqueued for %s` action of trigger `%s`",
+ DBG("Session `%s` was not present at the moment the work item was enqueued for `%s` action of trigger `%s`",
session_name, get_action_name(action),
get_trigger_name(work_item->trigger));
lttng_action_increase_execution_failure_count(action);
- ret = 0;
goto end;
}
session_lock_list();
- session = session_find_by_name(session_name);
+ rcu_read_lock();
+ session = session_find_by_id(LTTNG_OPTIONAL_GET(item->context.session_id));
if (!session) {
DBG("Failed to find session `%s` by name while executing `%s` action of trigger `%s`",
session_name, get_action_name(action),
goto error_unlock_list;
}
- /*
- * Check if the session id is the same as when the work item was
- * enqueued
- */
- if (session->id != LTTNG_OPTIONAL_GET(item->context.session_id)) {
- DBG("Session id for session `%s` (id: %" PRIu64
- " is not the same that was sampled (id: %" PRIu64
- " at the moment the work item was enqueued for %s` action of trigger `%s`",
- session_name, session->id,
- LTTNG_OPTIONAL_GET(item->context.session_id),
+ session_lock(session);
+ if (session->destroyed) {
+ DBG("Session `%s` with id = %" PRIu64 " is flagged as destroyed. Skipping: action = `%s`, trigger = `%s`",
+ session->name, session->id,
get_action_name(action),
get_trigger_name(work_item->trigger));
- ret = 0;
- goto error_put_session;
+ goto error_unlock_session;
}
- session_lock(session);
if (!is_trigger_allowed_for_session(work_item->trigger, session)) {
goto error_unlock_session;
}
error_unlock_session:
session_unlock(session);
-error_put_session:
session_put(session);
error_unlock_list:
+ rcu_read_unlock();
session_unlock_list();
end:
return ret;
}
static int action_executor_rotate_session_handler(
- struct action_executor *executor,
+ struct action_executor *executor __attribute__((unused)),
const struct action_work_item *work_item,
struct action_work_subitem *item)
{
* existed. If not, skip the action altogether.
*/
if (!item->context.session_id.is_set) {
- DBG("Session `%s` was not present at the moment the work item was enqueued for %s` action of trigger `%s`",
+ DBG("Session `%s` was not present at the moment the work item was enqueued for `%s` action of trigger `%s`",
session_name, get_action_name(action),
get_trigger_name(work_item->trigger));
lttng_action_increase_execution_failure_count(action);
- ret = 0;
goto end;
}
session_lock_list();
- session = session_find_by_name(session_name);
+ rcu_read_lock();
+ session = session_find_by_id(LTTNG_OPTIONAL_GET(item->context.session_id));
if (!session) {
DBG("Failed to find session `%s` by name while executing `%s` action of trigger `%s`",
session_name, get_action_name(action),
goto error_unlock_list;
}
- /*
- * Check if the session id is the same as when the work item was
- * enqueued.
- */
- if (session->id != LTTNG_OPTIONAL_GET(item->context.session_id)) {
- DBG("Session id for session `%s` (id: %" PRIu64
- " is not the same that was sampled (id: %" PRIu64
- " at the moment the work item was enqueued for %s` action of trigger `%s`",
- session_name, session->id,
- LTTNG_OPTIONAL_GET(item->context.session_id),
+ session_lock(session);
+ if (session->destroyed) {
+ DBG("Session `%s` with id = %" PRIu64 " is flagged as destroyed. Skipping: action = `%s`, trigger = `%s`",
+ session->name, session->id,
get_action_name(action),
get_trigger_name(work_item->trigger));
- ret = 0;
- goto error_put_session;
+ goto error_unlock_session;
}
- session_lock(session);
if (!is_trigger_allowed_for_session(work_item->trigger, session)) {
goto error_unlock_session;
}
error_unlock_session:
session_unlock(session);
-error_put_session:
session_put(session);
error_unlock_list:
+ rcu_read_unlock();
session_unlock_list();
end:
return ret;
}
static int action_executor_snapshot_session_handler(
- struct action_executor *executor,
+ struct action_executor *executor __attribute__((unused)),
const struct action_work_item *work_item,
struct action_work_subitem *item)
{
* existed. If not, skip the action altogether.
*/
if (!item->context.session_id.is_set) {
- DBG("Session was not present at the moment the work item was enqueued for %s` action of trigger `%s`",
+ DBG("Session was not present at the moment the work item was enqueued for `%s` action of trigger `%s`",
get_action_name(action),
get_trigger_name(work_item->trigger));
lttng_action_increase_execution_failure_count(action);
- ret = 0;
goto end;
}
}
session_lock_list();
- session = session_find_by_name(session_name);
+ rcu_read_lock();
+ session = session_find_by_id(LTTNG_OPTIONAL_GET(item->context.session_id));
if (!session) {
DBG("Failed to find session `%s` by name while executing `%s` action of trigger `%s`",
session_name, get_action_name(action),
goto error_unlock_list;
}
- /*
- * Check if the session id is the same as when the work item was
- * enqueued.
- */
- if (session->id != LTTNG_OPTIONAL_GET(item->context.session_id)) {
- DBG("Session id for session `%s` (id: %" PRIu64
- " is not the same that was sampled (id: %" PRIu64
- " at the moment the work item was enqueued for %s` action of trigger `%s`",
- session_name, session->id,
- LTTNG_OPTIONAL_GET(item->context.session_id),
+ session_lock(session);
+ if (session->destroyed) {
+ DBG("Session `%s` with id = %" PRIu64 " is flagged as destroyed. Skipping: action = `%s`, trigger = `%s`",
+ session->name, session->id,
get_action_name(action),
get_trigger_name(work_item->trigger));
- ret = 0;
- goto error_put_session;
+ goto error_unlock_session;
}
- session_lock(session);
if (!is_trigger_allowed_for_session(work_item->trigger, session)) {
goto error_unlock_session;
}
error_unlock_session:
session_unlock(session);
-error_put_session:
session_put(session);
error_unlock_list:
+ rcu_read_unlock();
session_unlock_list();
end:
return ret;
}
-static int action_executor_list_handler(struct action_executor *executor,
- const struct action_work_item *work_item,
- struct action_work_subitem *item)
+static int action_executor_list_handler(
+ struct action_executor *executor __attribute__((unused)),
+ const struct action_work_item *work_item __attribute__((unused)),
+ struct action_work_subitem *item __attribute__((unused)))
{
ERR("Execution of a list action by the action executor should never occur");
abort();
work_item->trigger, &trigger_owner_uid);
LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
- DBG("Work item skipped since the associated trigger is no longer registered: work item id = %" PRIu64 ", trigger name = '%s', trigger owner uid = %d",
+ DBG("Work item skipped since the associated trigger is no longer registered: work item id = %" PRIu64 ", trigger name = `%s`, trigger owner uid = %d",
work_item->id, trigger_name,
(int) trigger_owner_uid);
ret = 0;
bool signal = false;
LTTNG_ASSERT(trigger);
+ ASSERT_RCU_READ_LOCKED();
pthread_mutex_lock(&executor->work.lock);
/* Check for queue overflow. */
work_item = (action_work_item *) zmalloc(sizeof(*work_item));
if (!work_item) {
- PERROR("Failed to allocate action executor work item: trigger name = '%s'",
+ PERROR("Failed to allocate action executor work item: trigger name = `%s`",
get_trigger_name(trigger));
executor_status = ACTION_EXECUTOR_STATUS_ERROR;
goto error_unlock;