2 * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: MIT
17 #include <lttng/condition/event-rule.h>
18 #include <lttng/lttng.h>
22 static struct option long_options
[] =
24 /* These options set a flag. */
25 {"trigger", required_argument
, 0, 'i'},
26 {"sync-after-notif-register", required_argument
, 0, 'a'},
30 static bool action_group_contains_notify(
31 const struct lttng_action
*action_group
)
33 unsigned int i
, count
;
34 enum lttng_action_status status
=
35 lttng_action_group_get_count(action_group
, &count
);
37 if (status
!= LTTNG_ACTION_STATUS_OK
) {
38 printf("Failed to get action count from action group\n");
42 for (i
= 0; i
< count
; i
++) {
43 const struct lttng_action
*action
=
44 lttng_action_group_get_at_index(
46 const enum lttng_action_type action_type
=
47 lttng_action_get_type(action
);
49 if (action_type
== LTTNG_ACTION_TYPE_NOTIFY
) {
56 static bool is_expected_trigger_name(const char *expected_trigger_name
,
57 struct lttng_notification
*notification
)
60 const struct lttng_evaluation
*evaluation
=
61 lttng_notification_get_evaluation(notification
);
62 const enum lttng_condition_type type
=
63 lttng_evaluation_get_type(evaluation
);
66 case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
:
67 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
:
68 case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
:
69 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
:
70 case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
:
72 case LTTNG_CONDITION_TYPE_ON_EVENT
:
74 const char *trigger_name
;
75 enum lttng_evaluation_status evaluation_status
;
78 lttng_evaluation_on_event_get_trigger_name(
79 evaluation
, &trigger_name
);
80 if (evaluation_status
!= LTTNG_EVALUATION_STATUS_OK
) {
81 fprintf(stderr
, "Failed to get trigger name of event rule notification\n");
90 fprintf(stderr
, "Unknown notification type (%d)\n", type
);
96 int main(int argc
, char **argv
)
101 const char *expected_trigger_name
= NULL
;
102 struct lttng_triggers
*triggers
= NULL
;
103 unsigned int count
, i
, subcription_count
= 0;
104 enum lttng_trigger_status trigger_status
;
105 char *after_notif_register_file_path
= NULL
;
106 struct lttng_notification_channel
*notification_channel
= NULL
;
108 while ((option
= getopt_long(argc
, argv
, "a:t:",
109 long_options
, &option_index
)) != -1) {
112 after_notif_register_file_path
= strdup(optarg
);
115 expected_trigger_name
= strdup(optarg
);
118 /* getopt_long already printed an error message. */
125 if (optind
!= argc
) {
131 notification_channel
= lttng_notification_channel_create(
132 lttng_session_daemon_notification_endpoint
);
133 if (!notification_channel
) {
134 fprintf(stderr
, "Failed to create notification channel\n");
139 ret
= lttng_list_triggers(&triggers
);
140 if (ret
!= LTTNG_OK
) {
141 fprintf(stderr
, "Failed to list triggers\n");
145 trigger_status
= lttng_triggers_get_count(triggers
, &count
);
146 if (trigger_status
!= LTTNG_TRIGGER_STATUS_OK
) {
147 fprintf(stderr
, "Failed to get trigger count\n");
152 for (i
= 0; i
< count
; i
++) {
153 const struct lttng_trigger
*trigger
=
154 lttng_triggers_get_at_index(triggers
, i
);
155 const struct lttng_condition
*condition
=
156 lttng_trigger_get_const_condition(trigger
);
157 const struct lttng_action
*action
=
158 lttng_trigger_get_const_action(trigger
);
159 const enum lttng_action_type action_type
=
160 lttng_action_get_type(action
);
161 enum lttng_notification_channel_status channel_status
;
162 const char *trigger_name
= NULL
;
164 lttng_trigger_get_name(trigger
, &trigger_name
);
165 if (strcmp(trigger_name
, expected_trigger_name
)) {
169 if (!((action_type
== LTTNG_ACTION_TYPE_GROUP
&&
170 action_group_contains_notify(action
)) ||
171 action_type
== LTTNG_ACTION_TYPE_NOTIFY
)) {
172 /* "The action of trigger is not notify, skipping. */
176 channel_status
= lttng_notification_channel_subscribe(
177 notification_channel
, condition
);
178 if (channel_status
) {
179 fprintf(stderr
, "Failed to subscribe to notifications of trigger \"%s\"\n",
188 if (subcription_count
== 0) {
189 printf("No matching trigger with a notify action found.\n");
196 * We registered to the notification of our target trigger. We can now
197 * create the sync file to signify that we are ready.
199 ret
= create_file(after_notif_register_file_path
);
205 struct lttng_notification
*notification
;
206 enum lttng_notification_channel_status channel_status
;
209 lttng_notification_channel_get_next_notification(
210 notification_channel
,
212 switch (channel_status
) {
213 case LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED
:
214 printf("Dropped notification\n");
216 case LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED
:
219 case LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
:
221 case LTTNG_NOTIFICATION_CHANNEL_STATUS_CLOSED
:
222 printf("Notification channel was closed by peer.\n");
225 fprintf(stderr
, "A communication error occurred on the notification channel.\n");
230 ret
= is_expected_trigger_name(expected_trigger_name
,
232 lttng_notification_destroy(notification
);
239 lttng_triggers_destroy(triggers
);
240 lttng_notification_channel_destroy(notification_channel
);