2 * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
11 #include <urcu/uatomic.h>
13 #include <common/defaults.hpp>
15 #include "snapshot.hpp"
19 * Return the atomically incremented value of next_output_id.
21 static inline unsigned long get_next_output_id(struct snapshot
*snapshot
)
23 return uatomic_add_return(&snapshot
->next_output_id
, 1);
27 * Initialized snapshot output with the given values.
29 * Return 0 on success or else a negative value.
31 static int output_init(const struct ltt_session
*session
,
32 uint64_t max_size
, const char *name
,
33 struct lttng_uri
*uris
, size_t nb_uri
,
34 struct consumer_output
*consumer
, struct snapshot_output
*output
,
35 struct snapshot
*snapshot
)
39 memset(output
, 0, sizeof(struct snapshot_output
));
42 * max_size of -1ULL means unset. Set to default (unlimited).
44 if (max_size
== (uint64_t) -1ULL) {
47 output
->max_size
= max_size
;
50 output
->id
= get_next_output_id(snapshot
);
52 lttng_ht_node_init_ulong(&output
->node
, (unsigned long) output
->id
);
54 if (name
&& name
[0] != '\0') {
55 if (lttng_strncpy(output
->name
, name
, sizeof(output
->name
))) {
56 ret
= -LTTNG_ERR_INVALID
;
60 /* Set default name. */
61 ret
= snprintf(output
->name
, sizeof(output
->name
), "%s-%" PRIu32
,
62 DEFAULT_SNAPSHOT_NAME
, output
->id
);
73 output
->consumer
= consumer_copy_output(consumer
);
74 if (!output
->consumer
) {
78 output
->consumer
->snapshot
= 1;
86 if (uris
[0].dtype
== LTTNG_DST_PATH
) {
87 memset(output
->consumer
->dst
.session_root_path
, 0,
88 sizeof(output
->consumer
->dst
.session_root_path
));
89 if (lttng_strncpy(output
->consumer
->dst
.session_root_path
,
91 sizeof(output
->consumer
->dst
.session_root_path
))) {
92 ret
= -LTTNG_ERR_INVALID
;
95 output
->consumer
->type
= CONSUMER_DST_LOCAL
;
101 /* Absolutely needs two URIs for network. */
102 ret
= -LTTNG_ERR_INVALID
;
106 for (i
= 0; i
< nb_uri
; i
++) {
108 ret
= consumer_set_network_uri(session
, output
->consumer
,
121 * Initialize a snapshot output object using the given parameters and URI(s).
122 * The name value and uris can be NULL.
124 * Return 0 on success or else a negative value.
126 int snapshot_output_init_with_uri(const struct ltt_session
*session
,
127 uint64_t max_size
, const char *name
,
128 struct lttng_uri
*uris
, size_t nb_uri
,
129 struct consumer_output
*consumer
, struct snapshot_output
*output
,
130 struct snapshot
*snapshot
)
132 return output_init(session
, max_size
, name
, uris
, nb_uri
, consumer
,
137 * Initialize a snapshot output object using the given parameters. The name
138 * value and url can be NULL.
140 * Return 0 on success or else a negative value.
142 int snapshot_output_init(const struct ltt_session
*session
,
143 uint64_t max_size
, const char *name
,
144 const char *ctrl_url
, const char *data_url
,
145 struct consumer_output
*consumer
, struct snapshot_output
*output
,
146 struct snapshot
*snapshot
)
149 struct lttng_uri
*uris
= NULL
;
151 /* Create an array of URIs from URLs. */
152 nb_uri
= uri_parse_str_urls(ctrl_url
, data_url
, &uris
);
158 ret
= output_init(session
, max_size
, name
, uris
, nb_uri
, consumer
,
166 struct snapshot_output
*snapshot_output_alloc(void)
168 return zmalloc
<snapshot_output
>();
172 * Delete output from the snapshot object.
174 void snapshot_delete_output(struct snapshot
*snapshot
,
175 struct snapshot_output
*output
)
178 struct lttng_ht_iter iter
;
180 LTTNG_ASSERT(snapshot
);
181 LTTNG_ASSERT(snapshot
->output_ht
);
182 LTTNG_ASSERT(output
);
184 iter
.iter
.node
= &output
->node
.node
;
186 ret
= lttng_ht_del(snapshot
->output_ht
, &iter
);
190 * This is safe because the ownership of a snapshot object is in a session
191 * for which the session lock need to be acquired to read and modify it.
193 snapshot
->nb_output
--;
197 * Add output object to the snapshot.
199 void snapshot_add_output(struct snapshot
*snapshot
,
200 struct snapshot_output
*output
)
202 LTTNG_ASSERT(snapshot
);
203 LTTNG_ASSERT(snapshot
->output_ht
);
204 LTTNG_ASSERT(output
);
207 lttng_ht_add_unique_ulong(snapshot
->output_ht
, &output
->node
);
210 * This is safe because the ownership of a snapshot object is in a session
211 * for which the session lock need to be acquired to read and modify it.
213 snapshot
->nb_output
++;
217 * Destroy and free a snapshot output object.
219 void snapshot_output_destroy(struct snapshot_output
*obj
)
224 consumer_output_send_destroy_relayd(obj
->consumer
);
225 consumer_output_put(obj
->consumer
);
231 * RCU read side lock MUST be acquired before calling this since the returned
232 * pointer is in a RCU hash table.
234 * Return the reference on success or else NULL.
236 struct snapshot_output
*snapshot_find_output_by_name(const char *name
,
237 struct snapshot
*snapshot
)
239 struct lttng_ht_iter iter
;
240 struct snapshot_output
*output
= NULL
;
242 LTTNG_ASSERT(snapshot
);
244 ASSERT_RCU_READ_LOCKED();
246 cds_lfht_for_each_entry(snapshot
->output_ht
->ht
, &iter
.iter
, output
,
248 if (!strncmp(output
->name
, name
, strlen(name
))) {
258 * RCU read side lock MUST be acquired before calling this since the returned
259 * pointer is in a RCU hash table.
261 * Return the reference on success or else NULL.
263 struct snapshot_output
*snapshot_find_output_by_id(uint32_t id
,
264 struct snapshot
*snapshot
)
266 struct lttng_ht_node_ulong
*node
;
267 struct lttng_ht_iter iter
;
268 struct snapshot_output
*output
= NULL
;
270 LTTNG_ASSERT(snapshot
);
271 ASSERT_RCU_READ_LOCKED();
273 lttng_ht_lookup(snapshot
->output_ht
, (void *)((unsigned long) id
), &iter
);
274 node
= lttng_ht_iter_get_node_ulong(&iter
);
276 DBG3("Snapshot output not found with id %" PRId32
, id
);
279 output
= lttng::utils::container_of(node
, &snapshot_output::node
);
286 * Initialized a snapshot object that was already allocated.
288 * Return 0 on success or else a negative errno value.
290 int snapshot_init(struct snapshot
*obj
)
296 memset(obj
, 0, sizeof(struct snapshot
));
298 obj
->output_ht
= lttng_ht_new(0, LTTNG_HT_TYPE_ULONG
);
299 if (!obj
->output_ht
) {
311 * Destroy snapshot object but the pointer is not freed so it's safe to pass a
314 void snapshot_destroy(struct snapshot
*obj
)
316 struct lttng_ht_iter iter
;
317 struct snapshot_output
*output
;
319 if (!obj
->output_ht
) {
324 cds_lfht_for_each_entry(obj
->output_ht
->ht
, &iter
.iter
, output
,
326 snapshot_delete_output(obj
, output
);
327 snapshot_output_destroy(output
);
330 lttng_ht_destroy(obj
->output_ht
);
This page took 0.055508 seconds and 4 git commands to generate.