enum lttng_trigger_status trigger_status;
trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
- assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
+ switch (trigger_status) {
+ case LTTNG_TRIGGER_STATUS_OK:
+ break;
+ case LTTNG_TRIGGER_STATUS_UNSET:
+ trigger_name = "(anonymous)";
+ break;
+ default:
+ trigger_name = "(failed to get name)";
+ break;
+ }
return trigger_name;
}
uid_t trigger_owner_uid;
enum lttng_trigger_status trigger_status;
- trigger_status = lttng_trigger_get_name(
- work_item->trigger, &trigger_name);
- switch (trigger_status) {
- case LTTNG_TRIGGER_STATUS_OK:
- break;
- case LTTNG_TRIGGER_STATUS_UNSET:
- trigger_name = "(unset)";
- break;
- default:
- abort();
- }
+ trigger_name = get_trigger_name(work_item->trigger);
trigger_status = lttng_trigger_get_owner_uid(
work_item->trigger, &trigger_owner_uid);
original_reply_payload_size = cmd_ctx->reply_payload.buffer.size;
ret = cmd_register_trigger(&cmd_creds, payload_trigger,
+ cmd_ctx->lsm.u.trigger.is_trigger_anonymous,
the_notification_thread_handle,
&return_trigger);
if (ret != LTTNG_OK) {
trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ?
- trigger_name :
- "(unnamed)";
+ trigger_name : "(anonymous)";
session_lock_list();
switch (trigger_domain) {
enum lttng_error_code cmd_register_trigger(const struct lttng_credentials *cmd_creds,
struct lttng_trigger *trigger,
+ bool is_trigger_anonymous,
struct notification_thread_handle *notification_thread,
struct lttng_trigger **return_trigger)
{
trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ?
- trigger_name : "(unnamed)";
+ trigger_name : "(anonymous)";
trigger_status = lttng_trigger_get_owner_uid(
trigger, &trigger_owner);
* it is safe to use without any locking as its properties are
* immutable.
*/
- ret_code = notification_thread_command_register_trigger(notification_thread,
- trigger);
+ ret_code = notification_thread_command_register_trigger(
+ notification_thread, trigger, is_trigger_anonymous);
if (ret_code != LTTNG_OK) {
DBG("Failed to register trigger to notification thread: trigger name = '%s', trigger owner uid = %d, error code = %d",
trigger_name, (int) trigger_owner, ret_code);
trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ?
- trigger_name : "(unnamed)";
+ trigger_name : "(anonymous)";
/*
* Synchronize tracers if the trigger adds an event notifier.
struct lttng_trigger *sessiond_trigger = NULL;
trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
- trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ? trigger_name : "(unnamed)";
+ trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ? trigger_name : "(anonymous)";
trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_owner);
assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
trigger_status = lttng_trigger_get_name(matching_trigger, &trigger_name);
trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ?
- trigger_name : "(unnamed)";
+ trigger_name : "(anonymous)";
trigger_status = lttng_trigger_get_owner_uid(matching_trigger,
&trigger_owner);
assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
enum lttng_error_code cmd_register_trigger(
const struct lttng_credentials *cmd_creds,
struct lttng_trigger *trigger,
+ bool is_anonymous_trigger,
struct notification_thread_handle *notification_thread_handle,
struct lttng_trigger **return_trigger);
enum lttng_error_code cmd_unregister_trigger(
case LTTNG_TRIGGER_STATUS_OK:
break;
case LTTNG_TRIGGER_STATUS_UNSET:
- *trigger_name = "(unset)";
+ *trigger_name = "(anonymous)";
break;
default:
abort();
t_status = lttng_trigger_get_name(trigger, &trigger_name);
if (t_status != LTTNG_TRIGGER_STATUS_OK) {
- trigger_name = "(unnamed)";
+ trigger_name = "(anonymous)";
}
t_status = lttng_trigger_get_owner_uid(trigger, &trigger_owner_uid);
assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
- assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
+ trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ?
+ trigger_name : "(anonymous)";
DBG("Unregistering trigger: trigger owner uid = %d, trigger name = '%s'",
(int) trigger_owner, trigger_name);
enum lttng_error_code notification_thread_command_register_trigger(
struct notification_thread_handle *handle,
- struct lttng_trigger *trigger)
+ struct lttng_trigger *trigger,
+ bool is_trigger_anonymous)
{
int ret;
enum lttng_error_code ret_code;
cmd.type = NOTIFICATION_COMMAND_TYPE_REGISTER_TRIGGER;
lttng_trigger_get(trigger);
cmd.parameters.register_trigger.trigger = trigger;
+ cmd.parameters.register_trigger.is_trigger_anonymous =
+ is_trigger_anonymous;
ret = run_command_wait(handle, &cmd);
if (ret) {
/* Register trigger. */
struct {
struct lttng_trigger *trigger;
+ bool is_trigger_anonymous;
} register_trigger;
/* Unregister trigger. */
struct {
enum lttng_error_code notification_thread_command_register_trigger(
struct notification_thread_handle *handle,
- struct lttng_trigger *trigger);
+ struct lttng_trigger *trigger,
+ bool is_anonymous_trigger);
enum lttng_error_code notification_thread_command_unregister_trigger(
struct notification_thread_handle *handle,
const void *key)
{
bool match = false;
- const char *name;
+ const char *element_trigger_name;
const char *key_name;
enum lttng_trigger_status status;
const struct lttng_credentials *key_creds;
struct lttng_trigger_ht_element,
node_by_name_uid);
- status = lttng_trigger_get_name(trigger_ht_element->trigger, &name);
- assert(status == LTTNG_TRIGGER_STATUS_OK);
+ status = lttng_trigger_get_name(trigger_ht_element->trigger,
+ &element_trigger_name);
+ element_trigger_name = status == LTTNG_TRIGGER_STATUS_OK ?
+ element_trigger_name : NULL;
status = lttng_trigger_get_name(trigger_key, &key_name);
- assert(status == LTTNG_TRIGGER_STATUS_OK);
+ key_name = status == LTTNG_TRIGGER_STATUS_OK ? key_name : NULL;
- /* Compare the names. */
- if (strcmp(name, key_name) != 0) {
+ /*
+ * Compare the names.
+ * Consider null names as not equal. This is to maintain backwards
+ * compatibility with pre-2.13 anonymous triggers. Multiples anonymous
+ * triggers are allowed for a given user.
+ */
+ if (!element_trigger_name || !key_name) {
+ goto end;
+ }
+
+ if (strcmp(element_trigger_name, key_name) != 0) {
goto end;
}
case LTTNG_TRIGGER_STATUS_OK:
break;
case LTTNG_TRIGGER_STATUS_UNSET:
- *trigger_name = "(unset)";
+ *trigger_name = "(anonymous)";
break;
default:
abort();
int handle_notification_thread_command_register_trigger(
struct notification_thread_state *state,
struct lttng_trigger *trigger,
+ bool is_trigger_anonymous,
enum lttng_error_code *cmd_result)
{
int ret = 0;
/* Set the trigger's tracer token. */
lttng_trigger_set_tracer_token(trigger, trigger_tracer_token);
- if (lttng_trigger_get_name(trigger, &trigger_name) ==
- LTTNG_TRIGGER_STATUS_UNSET) {
- const enum lttng_error_code ret_code = generate_trigger_name(
- state, trigger, &trigger_name);
+ if (!is_trigger_anonymous) {
+ if (lttng_trigger_get_name(trigger, &trigger_name) ==
+ LTTNG_TRIGGER_STATUS_UNSET) {
+ const enum lttng_error_code ret_code =
+ generate_trigger_name(state, trigger,
+ &trigger_name);
- if (ret_code != LTTNG_OK) {
- /* Fatal error. */
- ret = -1;
- *cmd_result = ret_code;
+ if (ret_code != LTTNG_OK) {
+ /* Fatal error. */
+ ret = -1;
+ *cmd_result = ret_code;
+ goto error;
+ }
+ } else if (trigger_name_taken(state, trigger)) {
+ /* Not a fatal error. */
+ *cmd_result = LTTNG_ERR_TRIGGER_EXISTS;
+ ret = 0;
goto error;
}
- } else if (trigger_name_taken(state, trigger)) {
- /* Not a fatal error. */
- *cmd_result = LTTNG_ERR_TRIGGER_EXISTS;
- ret = 0;
- goto error;
+ } else {
+ trigger_name = "(anonymous)";
}
condition = lttng_trigger_get_condition(trigger);
case NOTIFICATION_COMMAND_TYPE_REGISTER_TRIGGER:
ret = handle_notification_thread_command_register_trigger(state,
cmd->parameters.register_trigger.trigger,
+ cmd->parameters.register_trigger.is_trigger_anonymous,
&cmd->reply_code);
break;
case NOTIFICATION_COMMAND_TYPE_UNREGISTER_TRIGGER:
struct cds_lfht_node *node;
struct cds_lfht_iter iter;
struct notification_trigger_tokens_ht_element *element;
- enum lttng_trigger_status trigger_status;
struct lttng_evaluation *evaluation = NULL;
enum action_executor_status executor_status;
struct notification_client_list *client_list = NULL;
- const char *trigger_name;
int ret;
unsigned int capture_count = 0;
struct notification_trigger_tokens_ht_element,
node);
- trigger_status = lttng_trigger_get_name(element->trigger, &trigger_name);
- assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
-
if (lttng_condition_event_rule_matches_get_capture_descriptor_count(
lttng_trigger_get_const_condition(element->trigger),
&capture_count) != LTTNG_CONDITION_STATUS_OK) {
}
ret = notification_thread_command_register_trigger(
- notification_thread_handle, session->rotate_trigger);
+ notification_thread_handle, session->rotate_trigger,
+ true);
if (ret < 0 && ret != -LTTNG_ERR_TRIGGER_EXISTS) {
ERR("Register trigger, %s", lttng_strerror(ret));
ret = -1;
status = lttng_trigger_get_name(trigger, &trigger_name);
trigger_name = status == LTTNG_TRIGGER_STATUS_OK ?
- trigger_name : "(unnamed)";
+ trigger_name : "(anonymous)";
status = lttng_trigger_get_owner_uid(trigger,
&trigger_owner);
assert(status == LTTNG_TRIGGER_STATUS_OK);
status = lttng_trigger_get_name(trigger, &trigger_name);
trigger_name = status == LTTNG_TRIGGER_STATUS_OK ?
- trigger_name : "(unnamed)";
+ trigger_name : "(anonymous)";
status = lttng_trigger_get_owner_uid(trigger,
&trigger_owner);
assert(status == LTTNG_TRIGGER_STATUS_OK);
assert(query);
trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
+ /*
+ * Anonymous triggers are not listed; this would be an internal error.
+ */
assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
lttng_error_query_trigger_create(trigger);
assert(query);
-
+ /*
+ * Anonymous triggers are not listed; this would be an internal error.
+ */
trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
const char *name;
uid_t trigger_uid;
+ /*
+ * Anonymous triggers are not listed since they can't be specified nor
+ * referenced through the CLI.
+ */
trigger_status = lttng_trigger_get_name(trigger, &name);
+ if (trigger_status == LTTNG_TRIGGER_STATUS_UNSET) {
+ goto end;
+ }
+
assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
}
print_trigger_errors(trigger);
+end:
+ return;
}
static
const char *name_a, *name_b;
enum lttng_trigger_status trigger_status;
+ /* Anonymous triggers are not reachable here. */
trigger_status = lttng_trigger_get_name(trigger_a, &name_a);
assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
}
for (i = 0; i < num_triggers; i++) {
- const int add_ret = lttng_dynamic_pointer_array_add_pointer(
- &sorted_triggers,
- (void *) lttng_triggers_get_at_index(triggers, i));
+ int add_ret;
+ const char *unused_name;
+ const struct lttng_trigger *trigger =
+ lttng_triggers_get_at_index(triggers, i);
+
+ trigger_status = lttng_trigger_get_name(trigger, &unused_name);
+ switch (trigger_status) {
+ case LTTNG_TRIGGER_STATUS_OK:
+ break;
+ case LTTNG_TRIGGER_STATUS_UNSET:
+ /* Don't list anonymous triggers. */
+ continue;
+ default:
+ abort();
+ }
+
+ add_ret = lttng_dynamic_pointer_array_add_pointer(
+ &sorted_triggers, (void *) trigger);
if (add_ret) {
ERR("Failed to allocate array of struct lttng_trigger *.");
trigger = lttng_triggers_get_at_index(triggers, i);
trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
- assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
+ switch (trigger_status) {
+ case LTTNG_TRIGGER_STATUS_OK:
+ break;
+ case LTTNG_TRIGGER_STATUS_UNSET:
+ /* Don't compare against anonymous triggers. */
+ continue;
+ default:
+ abort();
+ }
trigger_status = lttng_trigger_get_owner_uid(
trigger, &trigger_uid);
} LTTNG_PACKED process_attr_tracker_set_tracking_policy;
struct {
uint32_t length;
+ uint8_t is_trigger_anonymous;
} LTTNG_PACKED trigger;
struct {
uint32_t length;
bool lttng_trigger_is_equal(
const struct lttng_trigger *a, const struct lttng_trigger *b)
{
- if (strcmp(a->name, b->name) != 0) {
+ if (!!a->name != !!b->name) {
+ /* Both must be either anonymous or named. */
+ return false;
+ }
+
+ if (a->name && strcmp(a->name, b->name) != 0) {
return false;
}
}
trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
- if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
+ switch (trigger_status) {
+ case LTTNG_TRIGGER_STATUS_OK:
+ break;
+ case LTTNG_TRIGGER_STATUS_UNSET:
+ trigger_name = "(anonymous)";
+ break;
+ default:
fail("Failed to get name from notification's trigger");
goto end;
}
return false;
}
+/* Only expects named triggers. */
static bool is_trigger_name(const char *expected_trigger_name,
struct lttng_notification *notification)
{