2 * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: MIT
17 #include <lttng/condition/on-event.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
)
59 const char *trigger_name
= NULL
;
60 enum lttng_trigger_status trigger_status
;
61 const struct lttng_trigger
*trigger
;
64 trigger
= lttng_notification_get_trigger(notification
);
66 fprintf(stderr
, "Failed to get trigger from notification\n");
71 trigger_status
= lttng_trigger_get_name(trigger
, &trigger_name
);
72 if (trigger_status
!= LTTNG_TRIGGER_STATUS_OK
) {
73 fprintf(stderr
, "Failed to get name from notification's trigger\n");
78 names_match
= strcmp(expected_trigger_name
, trigger_name
) == 0;
83 int main(int argc
, char **argv
)
88 const char *expected_trigger_name
= NULL
;
89 struct lttng_triggers
*triggers
= NULL
;
90 unsigned int count
, i
, subcription_count
= 0;
91 enum lttng_trigger_status trigger_status
;
92 char *after_notif_register_file_path
= NULL
;
93 struct lttng_notification_channel
*notification_channel
= NULL
;
95 while ((option
= getopt_long(argc
, argv
, "a:t:",
96 long_options
, &option_index
)) != -1) {
99 after_notif_register_file_path
= strdup(optarg
);
102 expected_trigger_name
= strdup(optarg
);
105 /* getopt_long already printed an error message. */
112 if (optind
!= argc
) {
118 notification_channel
= lttng_notification_channel_create(
119 lttng_session_daemon_notification_endpoint
);
120 if (!notification_channel
) {
121 fprintf(stderr
, "Failed to create notification channel\n");
126 ret
= lttng_list_triggers(&triggers
);
127 if (ret
!= LTTNG_OK
) {
128 fprintf(stderr
, "Failed to list triggers\n");
132 trigger_status
= lttng_triggers_get_count(triggers
, &count
);
133 if (trigger_status
!= LTTNG_TRIGGER_STATUS_OK
) {
134 fprintf(stderr
, "Failed to get trigger count\n");
139 for (i
= 0; i
< count
; i
++) {
140 const struct lttng_trigger
*trigger
=
141 lttng_triggers_get_at_index(triggers
, i
);
142 const struct lttng_condition
*condition
=
143 lttng_trigger_get_const_condition(trigger
);
144 const struct lttng_action
*action
=
145 lttng_trigger_get_const_action(trigger
);
146 const enum lttng_action_type action_type
=
147 lttng_action_get_type(action
);
148 enum lttng_notification_channel_status channel_status
;
149 const char *trigger_name
= NULL
;
151 lttng_trigger_get_name(trigger
, &trigger_name
);
152 if (strcmp(trigger_name
, expected_trigger_name
)) {
156 if (!((action_type
== LTTNG_ACTION_TYPE_GROUP
&&
157 action_group_contains_notify(action
)) ||
158 action_type
== LTTNG_ACTION_TYPE_NOTIFY
)) {
159 /* "The action of trigger is not notify, skipping. */
163 channel_status
= lttng_notification_channel_subscribe(
164 notification_channel
, condition
);
165 if (channel_status
) {
166 fprintf(stderr
, "Failed to subscribe to notifications of trigger \"%s\"\n",
175 if (subcription_count
== 0) {
176 printf("No matching trigger with a notify action found.\n");
183 * We registered to the notification of our target trigger. We can now
184 * create the sync file to signify that we are ready.
186 ret
= create_file(after_notif_register_file_path
);
192 struct lttng_notification
*notification
;
193 enum lttng_notification_channel_status channel_status
;
196 lttng_notification_channel_get_next_notification(
197 notification_channel
,
199 switch (channel_status
) {
200 case LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED
:
201 printf("Dropped notification\n");
203 case LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED
:
206 case LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
:
208 case LTTNG_NOTIFICATION_CHANNEL_STATUS_CLOSED
:
209 printf("Notification channel was closed by peer.\n");
212 fprintf(stderr
, "A communication error occurred on the notification channel.\n");
217 ret
= is_expected_trigger_name(expected_trigger_name
,
219 lttng_notification_destroy(notification
);
226 lttng_triggers_destroy(triggers
);
227 lttng_notification_channel_destroy(notification_channel
);