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