Commit | Line | Data |
---|---|---|
db66e574 | 1 | /* |
ab5be9fa MJ |
2 | * Copyright (C) 2017 Julien Desfossez <jdesfossez@efficios.com> |
3 | * Copyright (C) 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
db66e574 | 4 | * |
ab5be9fa | 5 | * SPDX-License-Identifier: GPL-2.0-only |
db66e574 | 6 | * |
db66e574 JD |
7 | */ |
8 | ||
9 | #define _LGPL_SOURCE | |
10 | #include <lttng/trigger/trigger.h> | |
11 | #include <common/error.h> | |
12 | #include <common/config/session-config.h> | |
13 | #include <common/defaults.h> | |
14 | #include <common/utils.h> | |
15 | #include <common/futex.h> | |
16 | #include <common/align.h> | |
17 | #include <common/time.h> | |
18 | #include <common/hashtable/utils.h> | |
19 | #include <common/kernel-ctl/kernel-ctl.h> | |
3da864a9 | 20 | #include <common/credentials.h> |
db66e574 JD |
21 | #include <sys/stat.h> |
22 | #include <time.h> | |
23 | #include <signal.h> | |
24 | #include <inttypes.h> | |
25 | ||
90936dcf | 26 | #include <lttng/notification/channel-internal.h> |
d88744a4 | 27 | #include <lttng/rotate-internal.h> |
a7d0c51c JG |
28 | #include <lttng/condition/condition-internal.h> |
29 | #include <lttng/action/action-internal.h> | |
d88744a4 | 30 | |
db66e574 JD |
31 | #include "session.h" |
32 | #include "rotate.h" | |
33 | #include "rotation-thread.h" | |
34 | #include "lttng-sessiond.h" | |
35 | #include "health-sessiond.h" | |
36 | #include "cmd.h" | |
37 | #include "utils.h" | |
90936dcf | 38 | #include "notification-thread-commands.h" |
db66e574 JD |
39 | |
40 | #include <urcu.h> | |
41 | #include <urcu/list.h> | |
42 | #include <urcu/rculfhash.h> | |
43 | ||
90936dcf JD |
44 | int subscribe_session_consumed_size_rotation(struct ltt_session *session, uint64_t size, |
45 | struct notification_thread_handle *notification_thread_handle) | |
46 | { | |
47 | int ret; | |
48 | enum lttng_condition_status condition_status; | |
49 | enum lttng_notification_channel_status nc_status; | |
0331d3e5 | 50 | const uint64_t eventfd_increment_value = 1; |
3da864a9 | 51 | const struct lttng_credentials session_creds = { |
ff588497 JR |
52 | .uid = LTTNG_OPTIONAL_INIT_VALUE(session->uid), |
53 | .gid = LTTNG_OPTIONAL_INIT_VALUE(session->gid), | |
3da864a9 | 54 | }; |
0331d3e5 JG |
55 | struct lttng_condition *rotate_condition; |
56 | struct lttng_action *notify_action = NULL; | |
90936dcf | 57 | |
a7d0c51c JG |
58 | rotate_condition = lttng_condition_session_consumed_size_create(); |
59 | if (!rotate_condition) { | |
90936dcf JD |
60 | ERR("Failed to create session consumed size condition object"); |
61 | ret = -1; | |
62 | goto end; | |
63 | } | |
64 | ||
65 | condition_status = lttng_condition_session_consumed_size_set_threshold( | |
a7d0c51c | 66 | rotate_condition, size); |
90936dcf JD |
67 | if (condition_status != LTTNG_CONDITION_STATUS_OK) { |
68 | ERR("Could not set session consumed size condition threshold (size = %" PRIu64 ")", | |
69 | size); | |
70 | ret = -1; | |
71 | goto end; | |
72 | } | |
73 | ||
74 | condition_status = | |
75 | lttng_condition_session_consumed_size_set_session_name( | |
a7d0c51c | 76 | rotate_condition, session->name); |
90936dcf JD |
77 | if (condition_status != LTTNG_CONDITION_STATUS_OK) { |
78 | ERR("Could not set session consumed size condition session name (name = %s)", | |
79 | session->name); | |
80 | ret = -1; | |
81 | goto end; | |
82 | } | |
83 | ||
a7d0c51c JG |
84 | notify_action = lttng_action_notify_create(); |
85 | if (!notify_action) { | |
90936dcf JD |
86 | ERR("Could not create notify action"); |
87 | ret = -1; | |
88 | goto end; | |
89 | } | |
90 | ||
a7d0c51c JG |
91 | assert(!session->rotate_trigger); |
92 | session->rotate_trigger = lttng_trigger_create(rotate_condition, | |
93 | notify_action); | |
90936dcf JD |
94 | if (!session->rotate_trigger) { |
95 | ERR("Could not create size-based rotation trigger"); | |
96 | ret = -1; | |
97 | goto end; | |
98 | } | |
99 | ||
5682b2e6 JG |
100 | /* Ensure this trigger is not visible to external users. */ |
101 | lttng_trigger_set_hidden(session->rotate_trigger); | |
3da864a9 JR |
102 | lttng_trigger_set_credentials( |
103 | session->rotate_trigger, &session_creds); | |
104 | ||
90936dcf | 105 | nc_status = lttng_notification_channel_subscribe( |
a7d0c51c | 106 | rotate_notification_channel, rotate_condition); |
90936dcf JD |
107 | if (nc_status != LTTNG_NOTIFICATION_CHANNEL_STATUS_OK) { |
108 | ERR("Could not subscribe to session consumed size notification"); | |
109 | ret = -1; | |
110 | goto end; | |
111 | } | |
112 | ||
0331d3e5 JG |
113 | ret = lttng_write(rotate_notification_channel_subscription_change_eventfd, |
114 | &eventfd_increment_value, | |
115 | sizeof(eventfd_increment_value)); | |
116 | if (ret != sizeof(eventfd_increment_value)) { | |
117 | PERROR("Failed to wake up rotation thread as writing to the rotation thread notification channel subscription change eventfd failed"); | |
118 | ret = -1; | |
119 | goto end; | |
120 | } | |
121 | ||
90936dcf | 122 | ret = notification_thread_command_register_trigger( |
0efb2ad7 JG |
123 | notification_thread_handle, session->rotate_trigger, |
124 | true); | |
90936dcf JD |
125 | if (ret < 0 && ret != -LTTNG_ERR_TRIGGER_EXISTS) { |
126 | ERR("Register trigger, %s", lttng_strerror(ret)); | |
127 | ret = -1; | |
128 | goto end; | |
129 | } | |
130 | ||
131 | ret = 0; | |
132 | ||
133 | end: | |
a7d0c51c JG |
134 | lttng_condition_put(rotate_condition); |
135 | lttng_action_put(notify_action); | |
136 | if (ret) { | |
137 | lttng_trigger_put(session->rotate_trigger); | |
138 | } | |
90936dcf JD |
139 | return ret; |
140 | } | |
141 | ||
142 | int unsubscribe_session_consumed_size_rotation(struct ltt_session *session, | |
143 | struct notification_thread_handle *notification_thread_handle) | |
144 | { | |
145 | int ret = 0; | |
146 | enum lttng_notification_channel_status status; | |
0331d3e5 | 147 | const uint64_t eventfd_increment_value = 1; |
90936dcf | 148 | |
a7d0c51c | 149 | assert(session->rotate_trigger); |
90936dcf JD |
150 | status = lttng_notification_channel_unsubscribe( |
151 | rotate_notification_channel, | |
a7d0c51c | 152 | lttng_trigger_get_const_condition(session->rotate_trigger)); |
90936dcf JD |
153 | if (status != LTTNG_NOTIFICATION_CHANNEL_STATUS_OK) { |
154 | ERR("Session unsubscribe error: %d", (int) status); | |
155 | ret = -1; | |
156 | goto end; | |
157 | } | |
158 | ||
0331d3e5 JG |
159 | ret = lttng_write(rotate_notification_channel_subscription_change_eventfd, |
160 | &eventfd_increment_value, | |
161 | sizeof(eventfd_increment_value)); | |
162 | if (ret != sizeof(eventfd_increment_value)) { | |
163 | PERROR("Failed to wake up rotation thread as writing to the rotation thread notification channel subscription change eventfd failed"); | |
164 | ret = -1; | |
165 | goto end; | |
166 | } | |
167 | ||
168 | ret = notification_thread_command_unregister_trigger(notification_thread_handle, | |
169 | session->rotate_trigger); | |
90936dcf JD |
170 | if (ret != LTTNG_OK) { |
171 | ERR("Session unregister trigger error: %d", ret); | |
172 | goto end; | |
173 | } | |
174 | ||
a7d0c51c JG |
175 | lttng_trigger_put(session->rotate_trigger); |
176 | session->rotate_trigger = NULL; | |
177 | ||
90936dcf JD |
178 | ret = 0; |
179 | end: | |
180 | return ret; | |
181 | } |