*/
bool registered;
+ /*
+ * A "hidden" trigger is a trigger that is not externally listed.
+ * It is used to hide triggers that are used internally by the session
+ * daemon so that they can't be listed nor unregistered by external
+ * clients.
+ *
+ * This is a property that can only be set internally by the session
+ * daemon. As such, it is not serialized nor set by a
+ * "create_from_buffer" constructor.
+ *
+ * The hidden property is preserved by copies.
+ *
+ * Note that notifications originating from an "hidden" trigger will not
+ * be sent to clients that are not within the session daemon's process.
+ */
+ bool is_hidden;
+
/*
* The lock is used to protect against concurrent trigger execution and
* trigger removal.
bool lttng_trigger_is_equal(
const struct lttng_trigger *a, const struct lttng_trigger *b);
+LTTNG_HIDDEN
+bool lttng_trigger_is_hidden(const struct lttng_trigger *trigger);
+
+LTTNG_HIDDEN
+void lttng_trigger_set_hidden(struct lttng_trigger *trigger);
+
LTTNG_HIDDEN
void lttng_trigger_get(struct lttng_trigger *trigger);
int lttng_triggers_add(
struct lttng_triggers *triggers, struct lttng_trigger *trigger);
+/*
+ * Remove all triggers marked as hidden from the provided trigger set.
+ */
+LTTNG_HIDDEN
+int lttng_triggers_remove_hidden_triggers(struct lttng_triggers *triggers);
+
/*
* Serialize a trigger set to an lttng_payload object.
* Return LTTNG_OK on success, negative lttng error code on error.
struct notification_thread_handle *notification_thread,
struct lttng_triggers **return_triggers)
{
+ int ret;
enum lttng_error_code ret_code;
struct lttng_triggers *triggers = NULL;
goto end;
}
+ ret = lttng_triggers_remove_hidden_triggers(triggers);
+ if (ret) {
+ ret_code = LTTNG_ERR_UNK;
+ goto end;
+ }
+
*return_triggers = triggers;
triggers = NULL;
ret_code = LTTNG_OK;
&client->communication.inbound.creds);
client->gid = LTTNG_SOCK_GET_GID_CRED(
&client->communication.inbound.creds);
- DBG("Received handshake from client (uid = %u, gid = %u) with version %i.%i",
+ client->is_sessiond = LTTNG_SOCK_GET_PID_CRED(&client->communication.inbound.creds) == getpid();
+ DBG("Received handshake from client: uid = %u, gid = %u, protocol version = %i.%i, client is sessiond = %s",
client->uid, client->gid, (int) client->major,
- (int) client->minor);
+ (int) client->minor,
+ client->is_sessiond ? "true" : "false");
if (handshake_client->major !=
LTTNG_NOTIFICATION_CHANNEL_VERSION_MAJOR) {
goto skip_client;
}
+ if (lttng_trigger_is_hidden(trigger) && !client->is_sessiond) {
+ /*
+ * Notifications resulting from an hidden trigger are
+ * only sent to the session daemon.
+ */
+ continue;
+ }
+
if (source_object_creds) {
if (client->uid != lttng_credentials_get_uid(source_object_creds) &&
client->gid != lttng_credentials_get_gid(source_object_creds) &&
uint8_t major, minor;
uid_t uid;
gid_t gid;
+ bool is_sessiond;
/*
* Indicates if the credentials and versions of the client have been
* checked.
goto end;
}
+ /* Ensure this trigger is not visible to external users. */
+ lttng_trigger_set_hidden(session->rotate_trigger);
lttng_trigger_set_credentials(
session->rotate_trigger, &session_creds);
return false;
}
+ if (a->is_hidden != b->is_hidden) {
+ return false;
+ }
+
return true;
}
+LTTNG_HIDDEN
+bool lttng_trigger_is_hidden(const struct lttng_trigger *trigger)
+{
+ return trigger->is_hidden;
+}
+
+LTTNG_HIDDEN
+void lttng_trigger_set_hidden(struct lttng_trigger *trigger)
+{
+ assert(!trigger->is_hidden);
+ trigger->is_hidden = true;
+}
+
LTTNG_HIDDEN
enum lttng_trigger_status lttng_trigger_set_name(struct lttng_trigger *trigger,
const char* name)
return ret;
}
+LTTNG_HIDDEN
+int lttng_triggers_remove_hidden_triggers(struct lttng_triggers *triggers)
+{
+ int ret;
+ unsigned int trigger_count, i = 0;
+ enum lttng_trigger_status trigger_status;
+
+ assert(triggers);
+
+ trigger_status = lttng_triggers_get_count(triggers, &trigger_count);
+ assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
+
+ while (i < trigger_count) {
+ const struct lttng_trigger *trigger =
+ lttng_triggers_get_at_index(triggers, i);
+
+ if (lttng_trigger_is_hidden(trigger)) {
+ ret = lttng_dynamic_pointer_array_remove_pointer(
+ &triggers->array, i);
+ if (ret) {
+ goto end;
+ }
+
+ trigger_count--;
+ } else {
+ i++;
+ }
+ }
+
+ ret = 0;
+end:
+ return ret;
+}
+
const struct lttng_trigger *lttng_triggers_get_at_index(
const struct lttng_triggers *triggers, unsigned int index)
{
copy->tracer_token = trigger->tracer_token;
copy->registered = trigger->registered;
+ copy->is_hidden = trigger->is_hidden;
goto end;
error_cleanup_trigger: