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, 't'},
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_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;
80 fprintf(stderr
, "Got an unexpected trigger name: name = '%s', expected name = '%s'\n",
81 trigger_name
, expected_trigger_name
);
87 int main(int argc
, char **argv
)
92 const char *expected_trigger_name
= NULL
;
93 struct lttng_triggers
*triggers
= NULL
;
94 unsigned int count
, i
, subcription_count
= 0;
95 enum lttng_trigger_status trigger_status
;
96 char *after_notif_register_file_path
= NULL
;
97 struct lttng_notification_channel
*notification_channel
= NULL
;
99 while ((option
= getopt_long(argc
, argv
, "a:t:",
100 long_options
, &option_index
)) != -1) {
103 after_notif_register_file_path
= strdup(optarg
);
106 expected_trigger_name
= strdup(optarg
);
109 /* getopt_long already printed an error message. */
116 if (optind
!= argc
) {
122 notification_channel
= lttng_notification_channel_create(
123 lttng_session_daemon_notification_endpoint
);
124 if (!notification_channel
) {
125 fprintf(stderr
, "Failed to create notification channel\n");
130 ret
= lttng_list_triggers(&triggers
);
131 if (ret
!= LTTNG_OK
) {
132 fprintf(stderr
, "Failed to list triggers\n");
137 trigger_status
= lttng_triggers_get_count(triggers
, &count
);
138 if (trigger_status
!= LTTNG_TRIGGER_STATUS_OK
) {
139 fprintf(stderr
, "Failed to get trigger count\n");
144 /* Look for the trigger we want to subscribe to. */
145 for (i
= 0; i
< count
; i
++) {
146 const struct lttng_trigger
*trigger
=
147 lttng_triggers_get_at_index(triggers
, i
);
148 const struct lttng_condition
*condition
=
149 lttng_trigger_get_const_condition(trigger
);
150 const struct lttng_action
*action
=
151 lttng_trigger_get_const_action(trigger
);
152 const enum lttng_action_type action_type
=
153 lttng_action_get_type(action
);
154 enum lttng_notification_channel_status channel_status
;
155 const char *trigger_name
= NULL
;
157 lttng_trigger_get_name(trigger
, &trigger_name
);
158 if (strcmp(trigger_name
, expected_trigger_name
)) {
162 if (!((action_type
== LTTNG_ACTION_TYPE_GROUP
&&
163 action_group_contains_notify(action
)) ||
164 action_type
== LTTNG_ACTION_TYPE_NOTIFY
)) {
165 /* "The action of trigger is not notify, skipping. */
169 channel_status
= lttng_notification_channel_subscribe(
170 notification_channel
, condition
);
171 if (channel_status
) {
172 fprintf(stderr
, "Failed to subscribe to notifications of trigger \"%s\"\n",
181 if (subcription_count
== 0) {
182 printf("No matching trigger with a notify action found.\n");
189 * We registered to the notification of our target trigger. We can now
190 * create the sync file to signify that we are ready.
192 ret
= create_file(after_notif_register_file_path
);
198 struct lttng_notification
*notification
;
199 enum lttng_notification_channel_status channel_status
;
202 lttng_notification_channel_get_next_notification(
203 notification_channel
,
205 switch (channel_status
) {
206 case LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED
:
207 printf("Dropped notification\n");
210 case LTTNG_NOTIFICATION_CHANNEL_STATUS_INTERRUPTED
:
213 case LTTNG_NOTIFICATION_CHANNEL_STATUS_OK
:
215 case LTTNG_NOTIFICATION_CHANNEL_STATUS_CLOSED
:
216 printf("Notification channel was closed by peer.\n");
220 fprintf(stderr
, "A communication error occurred on the notification channel.\n");
225 ret
= is_trigger_name(expected_trigger_name
, notification
);
226 lttng_notification_destroy(notification
);
236 lttng_triggers_destroy(triggers
);
237 lttng_notification_channel_destroy(notification_channel
);