actions: introduce action group
[lttng-tools.git] / src / common / trigger.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 <lttng/trigger/trigger-internal.h>
9 #include <lttng/condition/condition-internal.h>
10 #include <lttng/action/action-internal.h>
11 #include <common/sessiond-comm/payload.h>
12 #include <common/sessiond-comm/payload-view.h>
13 #include <common/error.h>
14 #include <assert.h>
15
16 LTTNG_HIDDEN
17 bool lttng_trigger_validate(struct lttng_trigger *trigger)
18 {
19 bool valid;
20
21 if (!trigger) {
22 valid = false;
23 goto end;
24 }
25
26 valid = lttng_condition_validate(trigger->condition) &&
27 lttng_action_validate(trigger->action);
28 end:
29 return valid;
30 }
31
32 struct lttng_trigger *lttng_trigger_create(
33 struct lttng_condition *condition,
34 struct lttng_action *action)
35 {
36 struct lttng_trigger *trigger = NULL;
37
38 if (!condition || !action) {
39 goto end;
40 }
41
42 trigger = zmalloc(sizeof(struct lttng_trigger));
43 if (!trigger) {
44 goto end;
45 }
46
47 trigger->condition = condition;
48 trigger->action = action;
49 end:
50 return trigger;
51 }
52
53 struct lttng_condition *lttng_trigger_get_condition(
54 struct lttng_trigger *trigger)
55 {
56 return trigger ? trigger->condition : NULL;
57 }
58
59 LTTNG_HIDDEN
60 const struct lttng_condition *lttng_trigger_get_const_condition(
61 const struct lttng_trigger *trigger)
62 {
63 return trigger->condition;
64 }
65
66 struct lttng_action *lttng_trigger_get_action(
67 struct lttng_trigger *trigger)
68 {
69 return trigger ? trigger->action : NULL;
70 }
71
72 LTTNG_HIDDEN
73 const struct lttng_action *lttng_trigger_get_const_action(
74 const struct lttng_trigger *trigger)
75 {
76 return trigger->action;
77 }
78
79 void lttng_trigger_destroy(struct lttng_trigger *trigger)
80 {
81 if (!trigger) {
82 return;
83 }
84
85 free(trigger);
86 }
87
88 LTTNG_HIDDEN
89 ssize_t lttng_trigger_create_from_payload(
90 struct lttng_payload_view *src_view,
91 struct lttng_trigger **trigger)
92 {
93 ssize_t ret, offset = 0, condition_size, action_size;
94 struct lttng_condition *condition = NULL;
95 struct lttng_action *action = NULL;
96 const struct lttng_trigger_comm *trigger_comm;
97
98 if (!src_view || !trigger) {
99 ret = -1;
100 goto end;
101 }
102
103 /* lttng_trigger_comm header */
104 trigger_comm = (typeof(trigger_comm)) src_view->buffer.data;
105 offset += sizeof(*trigger_comm);
106 {
107 /* struct lttng_condition */
108 struct lttng_payload_view condition_view =
109 lttng_payload_view_from_view(
110 src_view, offset, -1);
111
112 condition_size = lttng_condition_create_from_payload(&condition_view,
113 &condition);
114 }
115
116 if (condition_size < 0) {
117 ret = condition_size;
118 goto end;
119 }
120
121 offset += condition_size;
122 {
123 /* struct lttng_action */
124 struct lttng_payload_view action_view =
125 lttng_payload_view_from_view(
126 src_view, offset, -1);
127
128 action_size = lttng_action_create_from_payload(&action_view, &action);
129 }
130
131 if (action_size < 0) {
132 ret = action_size;
133 goto end;
134 }
135 offset += action_size;
136
137 /* Unexpected size of inner-elements; the buffer is corrupted. */
138 if ((ssize_t) trigger_comm->length != condition_size + action_size) {
139 ret = -1;
140 goto error;
141 }
142
143 *trigger = lttng_trigger_create(condition, action);
144 if (!*trigger) {
145 ret = -1;
146 goto error;
147 }
148
149 ret = offset;
150 end:
151 return ret;
152 error:
153 lttng_condition_destroy(condition);
154 lttng_action_destroy(action);
155 return ret;
156 }
157
158 /*
159 * Both elements are stored contiguously, see their "*_comm" structure
160 * for the detailed format.
161 */
162 LTTNG_HIDDEN
163 int lttng_trigger_serialize(struct lttng_trigger *trigger,
164 struct lttng_payload *payload)
165 {
166 int ret;
167 size_t header_offset, size_before_payload;
168 struct lttng_trigger_comm trigger_comm = {};
169 struct lttng_trigger_comm *header;
170
171 header_offset = payload->buffer.size;
172 ret = lttng_dynamic_buffer_append(&payload->buffer, &trigger_comm,
173 sizeof(trigger_comm));
174 if (ret) {
175 goto end;
176 }
177
178 size_before_payload = payload->buffer.size;
179 ret = lttng_condition_serialize(trigger->condition, payload);
180 if (ret) {
181 goto end;
182 }
183
184 ret = lttng_action_serialize(trigger->action, payload);
185 if (ret) {
186 goto end;
187 }
188
189 /* Update payload size. */
190 header = (typeof(header)) (payload->buffer.data + header_offset);
191 header->length = payload->buffer.size - size_before_payload;
192 end:
193 return ret;
194 }
This page took 0.033261 seconds and 5 git commands to generate.