MI: implement all objects related to trigger machine interface
[lttng-tools.git] / src / common / actions / notify.c
1 /*
2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8 #include <assert.h>
9 #include <common/error.h>
10 #include <common/macros.h>
11 #include <common/mi-lttng.h>
12 #include <lttng/action/action-internal.h>
13 #include <lttng/action/notify-internal.h>
14 #include <lttng/action/rate-policy-internal.h>
15 #include <lttng/lttng-error.h>
16
17 #define IS_NOTIFY_ACTION(action) \
18 (lttng_action_get_type(action) == LTTNG_ACTION_TYPE_NOTIFY)
19
20 static struct lttng_action_notify *action_notify_from_action(
21 struct lttng_action *action)
22 {
23 assert(action);
24
25 return container_of(action, struct lttng_action_notify, parent);
26 }
27
28 static const struct lttng_action_notify *action_notify_from_action_const(
29 const struct lttng_action *action)
30 {
31 assert(action);
32
33 return container_of(action, struct lttng_action_notify, parent);
34 }
35
36 static
37 void lttng_action_notify_destroy(struct lttng_action *action)
38 {
39 struct lttng_action_notify *notify_action;
40 notify_action = action_notify_from_action(action);
41 lttng_rate_policy_destroy(notify_action->policy);
42 free(notify_action);
43 }
44
45 static
46 int lttng_action_notify_serialize(struct lttng_action *action,
47 struct lttng_payload *payload)
48 {
49 int ret;
50 struct lttng_action_notify *notify_action;
51
52 if (!action || !IS_NOTIFY_ACTION(action) || !payload) {
53 ret = -1;
54 goto end;
55 }
56
57 DBG("Serializing notify action");
58
59 notify_action = action_notify_from_action(action);
60 DBG("Serializing notify action rate policy");
61 ret = lttng_rate_policy_serialize(notify_action->policy, payload);
62
63 end:
64 return ret;
65 }
66
67 static
68 bool lttng_action_notify_is_equal(const struct lttng_action *a,
69 const struct lttng_action *b)
70 {
71 const struct lttng_action_notify *_a, *_b;
72
73 _a = action_notify_from_action_const(a);
74 _b = action_notify_from_action_const(b);
75 return lttng_rate_policy_is_equal(_a->policy, _b->policy);
76 }
77
78 static const struct lttng_rate_policy *
79 lttng_action_notify_internal_get_rate_policy(const struct lttng_action *action)
80 {
81 const struct lttng_action_notify *_action;
82 _action = action_notify_from_action_const(action);
83
84 return _action->policy;
85 }
86
87 static enum lttng_error_code lttng_action_notify_mi_serialize(
88 const struct lttng_action *action, struct mi_writer *writer)
89 {
90 int ret;
91 enum lttng_action_status status;
92 enum lttng_error_code ret_code;
93 const struct lttng_rate_policy *policy = NULL;
94
95 assert(action);
96 assert(IS_NOTIFY_ACTION(action));
97 assert(writer);
98
99 status = lttng_action_notify_get_rate_policy(action, &policy);
100 assert(status == LTTNG_ACTION_STATUS_OK);
101 assert(policy != NULL);
102
103 /* Open action notify. */
104 ret = mi_lttng_writer_open_element(
105 writer, mi_lttng_element_action_notify);
106 if (ret) {
107 goto mi_error;
108 }
109
110 ret_code = lttng_rate_policy_mi_serialize(policy, writer);
111 if (ret_code != LTTNG_OK) {
112 goto end;
113 }
114
115 /* Close action notify element. */
116 ret = mi_lttng_writer_close_element(writer);
117 if (ret) {
118 goto mi_error;
119 }
120
121 ret_code = LTTNG_OK;
122 goto end;
123
124 mi_error:
125 ret_code = LTTNG_ERR_MI_IO_FAIL;
126 end:
127 return ret_code;
128 }
129
130 struct lttng_action *lttng_action_notify_create(void)
131 {
132 struct lttng_rate_policy *policy = NULL;
133 struct lttng_action_notify *notify = NULL;
134 struct lttng_action *action = NULL;
135
136 notify = zmalloc(sizeof(struct lttng_action_notify));
137 if (!notify) {
138 goto end;
139 }
140
141 /* Default policy. */
142 policy = lttng_rate_policy_every_n_create(1);
143 if (!policy) {
144 goto end;
145 }
146
147 lttng_action_init(&notify->parent, LTTNG_ACTION_TYPE_NOTIFY, NULL,
148 lttng_action_notify_serialize,
149 lttng_action_notify_is_equal,
150 lttng_action_notify_destroy,
151 lttng_action_notify_internal_get_rate_policy,
152 lttng_action_generic_add_error_query_results,
153 lttng_action_notify_mi_serialize);
154
155 notify->policy = policy;
156 policy = NULL;
157
158 action = &notify->parent;
159 notify = NULL;
160
161 end:
162 free(notify);
163 lttng_rate_policy_destroy(policy);
164 return action;
165 }
166
167 ssize_t lttng_action_notify_create_from_payload(
168 struct lttng_payload_view *view,
169 struct lttng_action **action)
170 {
171 enum lttng_action_status status;
172 ssize_t consumed_length;
173 struct lttng_rate_policy *rate_policy = NULL;
174 struct lttng_action *_action = NULL;
175
176 consumed_length = lttng_rate_policy_create_from_payload(
177 view, &rate_policy);
178 if (!rate_policy) {
179 consumed_length = -1;
180 goto end;
181 }
182
183 _action = lttng_action_notify_create();
184 if (!_action) {
185 consumed_length = -1;
186 goto end;
187 }
188
189 status = lttng_action_notify_set_rate_policy(_action, rate_policy);
190 if (status != LTTNG_ACTION_STATUS_OK) {
191 consumed_length = -1;
192 goto end;
193 }
194
195 *action = _action;
196 _action = NULL;
197
198 end:
199 lttng_rate_policy_destroy(rate_policy);
200 lttng_action_destroy(_action);
201 return consumed_length;
202 }
203
204 enum lttng_action_status lttng_action_notify_set_rate_policy(
205 struct lttng_action *action,
206 const struct lttng_rate_policy *policy)
207 {
208 enum lttng_action_status status;
209 struct lttng_action_notify *notify_action;
210 struct lttng_rate_policy *copy = NULL;
211
212 if (!action || !policy || !IS_NOTIFY_ACTION(action)) {
213 status = LTTNG_ACTION_STATUS_INVALID;
214 goto end;
215 }
216
217 copy = lttng_rate_policy_copy(policy);
218 if (!copy) {
219 status = LTTNG_ACTION_STATUS_ERROR;
220 goto end;
221 }
222
223 notify_action = action_notify_from_action(action);
224
225 /* Free the previous rate policy .*/
226 lttng_rate_policy_destroy(notify_action->policy);
227
228 /* Assign the policy. */
229 notify_action->policy = copy;
230 status = LTTNG_ACTION_STATUS_OK;
231 copy = NULL;
232
233 end:
234 lttng_rate_policy_destroy(copy);
235 return status;
236 }
237
238 enum lttng_action_status lttng_action_notify_get_rate_policy(
239 const struct lttng_action *action,
240 const struct lttng_rate_policy **policy)
241 {
242 enum lttng_action_status status;
243 const struct lttng_action_notify *notify_action;
244
245 if (!action || !policy || !IS_NOTIFY_ACTION(action)) {
246 status = LTTNG_ACTION_STATUS_INVALID;
247 goto end;
248 }
249
250 notify_action = action_notify_from_action_const(action);
251
252 *policy = notify_action->policy;
253 status = LTTNG_ACTION_STATUS_OK;
254 end:
255 return status;
256 }
This page took 0.035603 seconds and 5 git commands to generate.