Commit | Line | Data |
---|---|---|
a58c490f | 1 | /* |
ab5be9fa | 2 | * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com> |
a58c490f | 3 | * |
ab5be9fa | 4 | * SPDX-License-Identifier: LGPL-2.1-only |
a58c490f | 5 | * |
a58c490f JG |
6 | */ |
7 | ||
8 | #include <lttng/trigger/trigger-internal.h> | |
9 | #include <lttng/condition/condition-internal.h> | |
10 | #include <lttng/action/action-internal.h> | |
9e620ea7 JG |
11 | #include <common/payload.h> |
12 | #include <common/payload-view.h> | |
a58c490f JG |
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 | ||
9b63a4aa JG |
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 | ||
e2ba1c78 | 66 | struct lttng_action *lttng_trigger_get_action( |
a58c490f JG |
67 | struct lttng_trigger *trigger) |
68 | { | |
69 | return trigger ? trigger->action : NULL; | |
70 | } | |
71 | ||
9b63a4aa JG |
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 | ||
a58c490f JG |
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 | |
c0a66c84 JG |
89 | ssize_t lttng_trigger_create_from_payload( |
90 | struct lttng_payload_view *src_view, | |
a58c490f JG |
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; | |
a58c490f JG |
97 | |
98 | if (!src_view || !trigger) { | |
99 | ret = -1; | |
100 | goto end; | |
101 | } | |
102 | ||
103 | /* lttng_trigger_comm header */ | |
c0a66c84 | 104 | trigger_comm = (typeof(trigger_comm)) src_view->buffer.data; |
a58c490f | 105 | offset += sizeof(*trigger_comm); |
c0a66c84 JG |
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 | } | |
a58c490f | 115 | |
a58c490f JG |
116 | if (condition_size < 0) { |
117 | ret = condition_size; | |
118 | goto end; | |
119 | } | |
c0a66c84 | 120 | |
a58c490f | 121 | offset += condition_size; |
c0a66c84 JG |
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 | } | |
a58c490f | 130 | |
a58c490f JG |
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 | } | |
c0a66c84 | 148 | |
a58c490f JG |
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 | /* | |
a58c490f JG |
159 | * Both elements are stored contiguously, see their "*_comm" structure |
160 | * for the detailed format. | |
161 | */ | |
162 | LTTNG_HIDDEN | |
3647288f | 163 | int lttng_trigger_serialize(struct lttng_trigger *trigger, |
c0a66c84 | 164 | struct lttng_payload *payload) |
a58c490f | 165 | { |
3647288f JG |
166 | int ret; |
167 | size_t header_offset, size_before_payload; | |
c0a66c84 | 168 | struct lttng_trigger_comm trigger_comm = {}; |
3647288f | 169 | struct lttng_trigger_comm *header; |
a58c490f | 170 | |
c0a66c84 JG |
171 | header_offset = payload->buffer.size; |
172 | ret = lttng_dynamic_buffer_append(&payload->buffer, &trigger_comm, | |
3647288f JG |
173 | sizeof(trigger_comm)); |
174 | if (ret) { | |
a58c490f JG |
175 | goto end; |
176 | } | |
177 | ||
c0a66c84 JG |
178 | size_before_payload = payload->buffer.size; |
179 | ret = lttng_condition_serialize(trigger->condition, payload); | |
3647288f | 180 | if (ret) { |
a58c490f JG |
181 | goto end; |
182 | } | |
a58c490f | 183 | |
c0a66c84 | 184 | ret = lttng_action_serialize(trigger->action, payload); |
3647288f | 185 | if (ret) { |
a58c490f JG |
186 | goto end; |
187 | } | |
a58c490f | 188 | |
3647288f | 189 | /* Update payload size. */ |
c0a66c84 JG |
190 | header = (typeof(header)) (payload->buffer.data + header_offset); |
191 | header->length = payload->buffer.size - size_before_payload; | |
a58c490f JG |
192 | end: |
193 | return ret; | |
194 | } |