clang-tidy: apply suggested fixes
[lttng-tools.git] / src / bin / lttng-sessiond / snapshot.cpp
CommitLineData
6dc3064a 1/*
ab5be9fa 2 * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
6dc3064a 3 *
ab5be9fa 4 * SPDX-License-Identifier: GPL-2.0-only
6dc3064a 5 *
6dc3064a
DG
6 */
7
6c1c0768 8#define _LGPL_SOURCE
a0a4f314
JG
9#include "consumer-output.hpp"
10#include "snapshot-output.hpp"
28ab034a
JG
11#include "snapshot.hpp"
12#include "utils.hpp"
6dc3064a 13
c9e313bc 14#include <common/defaults.hpp>
56047f5a 15#include <common/urcu.hpp>
6dc3064a 16
28ab034a
JG
17#include <inttypes.h>
18#include <string.h>
19#include <urcu/uatomic.h>
6dc3064a
DG
20
21/*
22 * Return the atomically incremented value of next_output_id.
23 */
24static inline unsigned long get_next_output_id(struct snapshot *snapshot)
25{
26 return uatomic_add_return(&snapshot->next_output_id, 1);
27}
28
29/*
5288612f 30 * Initialized snapshot output with the given values.
6dc3064a
DG
31 *
32 * Return 0 on success or else a negative value.
33 */
a0a4f314 34static int output_init(const ltt_session::locked_ref& session,
28ab034a
JG
35 uint64_t max_size,
36 const char *name,
37 struct lttng_uri *uris,
38 size_t nb_uri,
39 struct consumer_output *consumer,
40 struct snapshot_output *output,
41 struct snapshot *snapshot)
6dc3064a 42{
5288612f 43 int ret = 0, i;
6dc3064a 44
d4b5a90c
DG
45 memset(output, 0, sizeof(struct snapshot_output));
46
d07ceecd
MD
47 /*
48 * max_size of -1ULL means unset. Set to default (unlimited).
49 */
e1986656
DG
50 if (max_size == (uint64_t) -1ULL) {
51 max_size = 0;
52 }
6dc3064a 53 output->max_size = max_size;
e1986656 54
6dc3064a
DG
55 if (snapshot) {
56 output->id = get_next_output_id(snapshot);
57 }
58 lttng_ht_node_init_ulong(&output->node, (unsigned long) output->id);
59
ee91bab2 60 if (name && name[0] != '\0') {
35f3ec96
MD
61 if (lttng_strncpy(output->name, name, sizeof(output->name))) {
62 ret = -LTTNG_ERR_INVALID;
63 goto error;
64 }
6dc3064a
DG
65 } else {
66 /* Set default name. */
28ab034a
JG
67 ret = snprintf(output->name,
68 sizeof(output->name),
69 "%s-%" PRIu32,
70 DEFAULT_SNAPSHOT_NAME,
71 output->id);
6dc3064a
DG
72 if (ret < 0) {
73 ret = -ENOMEM;
74 goto error;
75 }
76 }
77
78 if (!consumer) {
79 goto end;
80 }
81
6dc3064a
DG
82 output->consumer = consumer_copy_output(consumer);
83 if (!output->consumer) {
84 ret = -ENOMEM;
85 goto error;
86 }
7d2f7452 87 output->consumer->snapshot = 1;
6dc3064a
DG
88
89 /* No URL given. */
90 if (nb_uri == 0) {
91 ret = 0;
92 goto end;
93 }
94
95 if (uris[0].dtype == LTTNG_DST_PATH) {
28ab034a
JG
96 memset(output->consumer->dst.session_root_path,
97 0,
98 sizeof(output->consumer->dst.session_root_path));
366a9222 99 if (lttng_strncpy(output->consumer->dst.session_root_path,
28ab034a
JG
100 uris[0].dst.path,
101 sizeof(output->consumer->dst.session_root_path))) {
35f3ec96
MD
102 ret = -LTTNG_ERR_INVALID;
103 goto error;
104 }
6dc3064a
DG
105 output->consumer->type = CONSUMER_DST_LOCAL;
106 ret = 0;
107 goto end;
108 }
109
110 if (nb_uri != 2) {
111 /* Absolutely needs two URIs for network. */
112 ret = -LTTNG_ERR_INVALID;
113 goto error;
114 }
115
28ab034a 116 for (i = 0; i < nb_uri; i++) {
6dc3064a 117 /* Network URIs */
28ab034a 118 ret = consumer_set_network_uri(session, output->consumer, &uris[i]);
6dc3064a
DG
119 if (ret < 0) {
120 goto error;
121 }
122 }
123
124error:
125end:
5288612f
DG
126 return ret;
127}
128
129/*
130 * Initialize a snapshot output object using the given parameters and URI(s).
131 * The name value and uris can be NULL.
132 *
133 * Return 0 on success or else a negative value.
134 */
a0a4f314 135int snapshot_output_init_with_uri(const ltt_session::locked_ref& session,
28ab034a
JG
136 uint64_t max_size,
137 const char *name,
138 struct lttng_uri *uris,
139 size_t nb_uri,
140 struct consumer_output *consumer,
141 struct snapshot_output *output,
142 struct snapshot *snapshot)
5288612f 143{
28ab034a 144 return output_init(session, max_size, name, uris, nb_uri, consumer, output, snapshot);
5288612f
DG
145}
146
147/*
148 * Initialize a snapshot output object using the given parameters. The name
149 * value and url can be NULL.
150 *
151 * Return 0 on success or else a negative value.
152 */
a0a4f314 153int snapshot_output_init(const ltt_session::locked_ref& session,
28ab034a
JG
154 uint64_t max_size,
155 const char *name,
156 const char *ctrl_url,
157 const char *data_url,
158 struct consumer_output *consumer,
159 struct snapshot_output *output,
160 struct snapshot *snapshot)
5288612f
DG
161{
162 int ret = 0, nb_uri;
cd9adb8b 163 struct lttng_uri *uris = nullptr;
5288612f
DG
164
165 /* Create an array of URIs from URLs. */
166 nb_uri = uri_parse_str_urls(ctrl_url, data_url, &uris);
167 if (nb_uri < 0) {
168 ret = nb_uri;
169 goto error;
170 }
171
28ab034a 172 ret = output_init(session, max_size, name, uris, nb_uri, consumer, output, snapshot);
5288612f
DG
173
174error:
6dc3064a
DG
175 free(uris);
176 return ret;
177}
178
cd9adb8b 179struct snapshot_output *snapshot_output_alloc()
6dc3064a 180{
64803277 181 return zmalloc<snapshot_output>();
6dc3064a
DG
182}
183
184/*
185 * Delete output from the snapshot object.
186 */
28ab034a 187void snapshot_delete_output(struct snapshot *snapshot, struct snapshot_output *output)
6dc3064a
DG
188{
189 int ret;
190 struct lttng_ht_iter iter;
191
a0377dfe
FD
192 LTTNG_ASSERT(snapshot);
193 LTTNG_ASSERT(snapshot->output_ht);
194 LTTNG_ASSERT(output);
6dc3064a
DG
195
196 iter.iter.node = &output->node.node;
07c4863f 197 const lttng::urcu::read_lock_guard read_lock;
6dc3064a 198 ret = lttng_ht_del(snapshot->output_ht, &iter);
a0377dfe 199 LTTNG_ASSERT(!ret);
6dc3064a
DG
200 /*
201 * This is safe because the ownership of a snapshot object is in a session
202 * for which the session lock need to be acquired to read and modify it.
203 */
204 snapshot->nb_output--;
205}
206
207/*
208 * Add output object to the snapshot.
209 */
28ab034a 210void snapshot_add_output(struct snapshot *snapshot, struct snapshot_output *output)
6dc3064a 211{
a0377dfe
FD
212 LTTNG_ASSERT(snapshot);
213 LTTNG_ASSERT(snapshot->output_ht);
214 LTTNG_ASSERT(output);
6dc3064a 215
07c4863f 216 const lttng::urcu::read_lock_guard read_lock;
6dc3064a 217 lttng_ht_add_unique_ulong(snapshot->output_ht, &output->node);
6dc3064a
DG
218 /*
219 * This is safe because the ownership of a snapshot object is in a session
220 * for which the session lock need to be acquired to read and modify it.
221 */
222 snapshot->nb_output++;
223}
224
225/*
226 * Destroy and free a snapshot output object.
227 */
228void snapshot_output_destroy(struct snapshot_output *obj)
229{
a0377dfe 230 LTTNG_ASSERT(obj);
6dc3064a
DG
231
232 if (obj->consumer) {
233 consumer_output_send_destroy_relayd(obj->consumer);
6addfa37 234 consumer_output_put(obj->consumer);
6dc3064a
DG
235 }
236 free(obj);
237}
238
eb240553
DG
239/*
240 * RCU read side lock MUST be acquired before calling this since the returned
241 * pointer is in a RCU hash table.
242 *
243 * Return the reference on success or else NULL.
244 */
28ab034a 245struct snapshot_output *snapshot_find_output_by_name(const char *name, struct snapshot *snapshot)
eb240553
DG
246{
247 struct lttng_ht_iter iter;
cd9adb8b 248 struct snapshot_output *output = nullptr;
eb240553 249
a0377dfe
FD
250 LTTNG_ASSERT(snapshot);
251 LTTNG_ASSERT(name);
48b7cdc2 252 ASSERT_RCU_READ_LOCKED();
eb240553 253
28ab034a 254 cds_lfht_for_each_entry (snapshot->output_ht->ht, &iter.iter, output, node.node) {
eb240553
DG
255 if (!strncmp(output->name, name, strlen(name))) {
256 return output;
257 }
258 }
259
260 /* Not found */
cd9adb8b 261 return nullptr;
eb240553
DG
262}
263
6dc3064a
DG
264/*
265 * RCU read side lock MUST be acquired before calling this since the returned
266 * pointer is in a RCU hash table.
267 *
268 * Return the reference on success or else NULL.
269 */
28ab034a 270struct snapshot_output *snapshot_find_output_by_id(uint32_t id, struct snapshot *snapshot)
6dc3064a
DG
271{
272 struct lttng_ht_node_ulong *node;
273 struct lttng_ht_iter iter;
cd9adb8b 274 struct snapshot_output *output = nullptr;
6dc3064a 275
a0377dfe 276 LTTNG_ASSERT(snapshot);
48b7cdc2 277 ASSERT_RCU_READ_LOCKED();
6dc3064a 278
28ab034a 279 lttng_ht_lookup(snapshot->output_ht, (void *) ((unsigned long) id), &iter);
00d7d903 280 node = lttng_ht_iter_get_node<lttng_ht_node_ulong>(&iter);
6dc3064a
DG
281 if (!node) {
282 DBG3("Snapshot output not found with id %" PRId32, id);
283 goto error;
284 }
0114db0e 285 output = lttng::utils::container_of(node, &snapshot_output::node);
6dc3064a
DG
286
287error:
288 return output;
289}
290
6dc3064a
DG
291/*
292 * Initialized a snapshot object that was already allocated.
293 *
294 * Return 0 on success or else a negative errno value.
295 */
296int snapshot_init(struct snapshot *obj)
297{
298 int ret;
299
a0377dfe 300 LTTNG_ASSERT(obj);
6dc3064a
DG
301
302 memset(obj, 0, sizeof(struct snapshot));
303
304 obj->output_ht = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
305 if (!obj->output_ht) {
306 ret = -ENOMEM;
307 goto error;
308 }
309
310 ret = 0;
311
312error:
313 return ret;
314}
315
316/*
317 * Destroy snapshot object but the pointer is not freed so it's safe to pass a
318 * static reference.
319 */
320void snapshot_destroy(struct snapshot *obj)
321{
322 struct lttng_ht_iter iter;
323 struct snapshot_output *output;
324
f4cc5e83
JG
325 if (!obj->output_ht) {
326 return;
327 }
6dc3064a 328
56047f5a 329 {
07c4863f 330 const lttng::urcu::read_lock_guard read_lock;
56047f5a
JG
331
332 cds_lfht_for_each_entry (obj->output_ht->ht, &iter.iter, output, node.node) {
333 snapshot_delete_output(obj, output);
334 snapshot_output_destroy(output);
335 }
6dc3064a 336 }
56047f5a 337
3c339053 338 lttng_ht_destroy(obj->output_ht);
6dc3064a 339}
This page took 0.097008 seconds and 4 git commands to generate.