SoW-2019-0002: Dynamic Snapshot
[lttng-tools.git] / src / common / actions / action.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 <lttng/action/action-internal.h>
11 #include <lttng/action/group-internal.h>
12 #include <lttng/action/notify-internal.h>
13 #include <lttng/action/rotate-session-internal.h>
14 #include <lttng/action/snapshot-session-internal.h>
15 #include <lttng/action/start-session-internal.h>
16 #include <lttng/action/stop-session-internal.h>
17
18 LTTNG_HIDDEN
19 const char *lttng_action_type_string(enum lttng_action_type action_type)
20 {
21 switch (action_type) {
22 case LTTNG_ACTION_TYPE_UNKNOWN:
23 return "UNKNOWN";
24
25 case LTTNG_ACTION_TYPE_GROUP:
26 return "GROUP";
27
28 case LTTNG_ACTION_TYPE_NOTIFY:
29 return "NOTIFY";
30
31 case LTTNG_ACTION_TYPE_ROTATE_SESSION:
32 return "ROTATE_SESSION";
33
34 case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION:
35 return "SNAPSHOT_SESSION";
36
37 case LTTNG_ACTION_TYPE_START_SESSION:
38 return "START_SESSION";
39
40 case LTTNG_ACTION_TYPE_STOP_SESSION:
41 return "STOP_SESSION";
42
43 default:
44 return "???";
45 }
46 }
47
48 enum lttng_action_type lttng_action_get_type(const struct lttng_action *action)
49 {
50 return action ? action->type : LTTNG_ACTION_TYPE_UNKNOWN;
51 }
52
53 LTTNG_HIDDEN
54 enum lttng_action_type lttng_action_get_type_const(
55 const struct lttng_action *action)
56 {
57 return action->type;
58 }
59
60 LTTNG_HIDDEN
61 void lttng_action_init(
62 struct lttng_action *action,
63 enum lttng_action_type type,
64 action_validate_cb validate,
65 action_serialize_cb serialize,
66 action_equal_cb equal,
67 action_destroy_cb destroy)
68 {
69 urcu_ref_init(&action->ref);
70 action->type = type;
71 action->validate = validate;
72 action->serialize = serialize;
73 action->equal = equal;
74 action->destroy = destroy;
75 }
76
77 static
78 void action_destroy_ref(struct urcu_ref *ref)
79 {
80 struct lttng_action *action =
81 container_of(ref, struct lttng_action, ref);
82
83 action->destroy(action);
84 }
85
86 LTTNG_HIDDEN
87 void lttng_action_get(struct lttng_action *action)
88 {
89 urcu_ref_get(&action->ref);
90 }
91
92 LTTNG_HIDDEN
93 void lttng_action_put(struct lttng_action *action)
94 {
95 if (!action) {
96 return;
97 }
98
99 assert(action->destroy);
100 urcu_ref_put(&action->ref, action_destroy_ref);
101 }
102
103 void lttng_action_destroy(struct lttng_action *action)
104 {
105 lttng_action_put(action);
106 }
107
108 LTTNG_HIDDEN
109 bool lttng_action_validate(struct lttng_action *action)
110 {
111 bool valid;
112
113 if (!action) {
114 valid = false;
115 goto end;
116 }
117
118 if (!action->validate) {
119 /* Sub-class guarantees that it can never be invalid. */
120 valid = true;
121 goto end;
122 }
123
124 valid = action->validate(action);
125 end:
126 return valid;
127 }
128
129 LTTNG_HIDDEN
130 int lttng_action_serialize(struct lttng_action *action,
131 struct lttng_dynamic_buffer *buf)
132 {
133 int ret;
134 struct lttng_action_comm action_comm = {
135 .action_type = (int8_t) action->type,
136 };
137
138 ret = lttng_dynamic_buffer_append(buf, &action_comm,
139 sizeof(action_comm));
140 if (ret) {
141 goto end;
142 }
143
144 ret = action->serialize(action, buf);
145 if (ret) {
146 goto end;
147 }
148 end:
149 return ret;
150 }
151
152 LTTNG_HIDDEN
153 ssize_t lttng_action_create_from_buffer(const struct lttng_buffer_view *view,
154 struct lttng_action **action)
155 {
156 ssize_t consumed_len, specific_action_consumed_len;
157 const struct lttng_action_comm *action_comm;
158 action_create_from_buffer_cb create_from_buffer_cb;
159 struct lttng_buffer_view specific_action_view;
160
161 if (!view || !action) {
162 consumed_len = -1;
163 goto end;
164 }
165
166 action_comm = (const struct lttng_action_comm *) view->data;
167
168 DBG("Create action from buffer: action-type=%s",
169 lttng_action_type_string(action_comm->action_type));
170
171 switch (action_comm->action_type) {
172 case LTTNG_ACTION_TYPE_NOTIFY:
173 create_from_buffer_cb = lttng_action_notify_create_from_buffer;
174 break;
175
176 case LTTNG_ACTION_TYPE_ROTATE_SESSION:
177 create_from_buffer_cb =
178 lttng_action_rotate_session_create_from_buffer;
179 break;
180
181 case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION:
182 create_from_buffer_cb =
183 lttng_action_snapshot_session_create_from_buffer;
184 break;
185
186 case LTTNG_ACTION_TYPE_START_SESSION:
187 create_from_buffer_cb =
188 lttng_action_start_session_create_from_buffer;
189 break;
190
191 case LTTNG_ACTION_TYPE_STOP_SESSION:
192 create_from_buffer_cb =
193 lttng_action_stop_session_create_from_buffer;
194 break;
195
196 case LTTNG_ACTION_TYPE_GROUP:
197 create_from_buffer_cb = lttng_action_group_create_from_buffer;
198 break;
199
200 default:
201 ERR("Failed to create action from buffer, unhandled action type: action-type=%u (%s)",
202 action_comm->action_type,
203 lttng_action_type_string(
204 action_comm->action_type));
205 consumed_len = -1;
206 goto end;
207 }
208
209 /* Create buffer view for the action-type-specific data. */
210 specific_action_view = lttng_buffer_view_from_view(view,
211 sizeof(struct lttng_action_comm),
212 view->size - sizeof(struct lttng_action_comm));
213
214 specific_action_consumed_len =
215 create_from_buffer_cb(&specific_action_view, action);
216 if (specific_action_consumed_len < 0) {
217 ERR("Failed to create specific action from buffer.");
218 consumed_len = -1;
219 goto end;
220 }
221
222 assert(*action);
223
224 consumed_len = sizeof(struct lttng_action_comm) +
225 specific_action_consumed_len;
226
227 end:
228 return consumed_len;
229 }
230
231 LTTNG_HIDDEN
232 bool lttng_action_is_equal(const struct lttng_action *a,
233 const struct lttng_action *b)
234 {
235 bool is_equal = false;
236
237 if (!a || !b) {
238 goto end;
239 }
240
241 if (a->type != b->type) {
242 goto end;
243 }
244
245 if (a == b) {
246 is_equal = true;
247 goto end;
248 }
249
250 is_equal = a->equal ? a->equal(a, b) : true;
251 end:
252 return is_equal;
253 }
254
This page took 0.038247 seconds and 5 git commands to generate.