2 * Copyright (C) 2013 - David Goulet <dgoulet@efficios.com>
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License, version 2 only, as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 51
15 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include <urcu/uatomic.h>
25 #include <common/defaults.h>
31 * Return the atomically incremented value of next_output_id.
33 static inline unsigned long get_next_output_id(struct snapshot
*snapshot
)
35 return uatomic_add_return(&snapshot
->next_output_id
, 1);
39 * Initialized snapshot output with the given values.
41 * Return 0 on success or else a negative value.
43 static int output_init(uint64_t max_size
, const char *name
,
44 struct lttng_uri
*uris
, size_t nb_uri
,
45 struct consumer_output
*consumer
, struct snapshot_output
*output
,
46 struct snapshot
*snapshot
)
50 memset(output
, 0, sizeof(struct snapshot_output
));
53 * max_size of -1ULL means unset. Set to default (unlimited).
55 if (max_size
== (uint64_t) -1ULL) {
58 output
->max_size
= max_size
;
61 output
->id
= get_next_output_id(snapshot
);
63 lttng_ht_node_init_ulong(&output
->node
, (unsigned long) output
->id
);
65 if (name
&& name
[0] != '\0') {
66 if (lttng_strncpy(output
->name
, name
, sizeof(output
->name
))) {
67 ret
= -LTTNG_ERR_INVALID
;
71 /* Set default name. */
72 ret
= snprintf(output
->name
, sizeof(output
->name
), "%s-%" PRIu32
,
73 DEFAULT_SNAPSHOT_NAME
, output
->id
);
84 output
->consumer
= consumer_copy_output(consumer
);
85 if (!output
->consumer
) {
89 output
->consumer
->snapshot
= 1;
97 if (uris
[0].dtype
== LTTNG_DST_PATH
) {
98 memset(output
->consumer
->dst
.trace_path
, 0,
99 sizeof(output
->consumer
->dst
.trace_path
));
100 if (lttng_strncpy(output
->consumer
->dst
.trace_path
,
102 sizeof(output
->consumer
->dst
.trace_path
))) {
103 ret
= -LTTNG_ERR_INVALID
;
106 output
->consumer
->type
= CONSUMER_DST_LOCAL
;
112 /* Absolutely needs two URIs for network. */
113 ret
= -LTTNG_ERR_INVALID
;
117 for (i
= 0; i
< nb_uri
; i
++) {
119 ret
= consumer_set_network_uri(output
->consumer
, &uris
[i
]);
131 * Initialize a snapshot output object using the given parameters and URI(s).
132 * The name value and uris can be NULL.
134 * Return 0 on success or else a negative value.
136 int snapshot_output_init_with_uri(uint64_t max_size
, const char *name
,
137 struct lttng_uri
*uris
, size_t nb_uri
,
138 struct consumer_output
*consumer
, struct snapshot_output
*output
,
139 struct snapshot
*snapshot
)
141 return output_init(max_size
, name
, uris
, nb_uri
, consumer
, output
,
146 * Initialize a snapshot output object using the given parameters. The name
147 * value and url can be NULL.
149 * Return 0 on success or else a negative value.
151 int snapshot_output_init(uint64_t max_size
, const char *name
,
152 const char *ctrl_url
, const char *data_url
,
153 struct consumer_output
*consumer
, struct snapshot_output
*output
,
154 struct snapshot
*snapshot
)
157 struct lttng_uri
*uris
= NULL
;
159 /* Create an array of URIs from URLs. */
160 nb_uri
= uri_parse_str_urls(ctrl_url
, data_url
, &uris
);
166 ret
= output_init(max_size
, name
, uris
, nb_uri
, consumer
, output
,
174 struct snapshot_output
*snapshot_output_alloc(void)
176 return zmalloc(sizeof(struct snapshot_output
));
180 * Delete output from the snapshot object.
182 void snapshot_delete_output(struct snapshot
*snapshot
,
183 struct snapshot_output
*output
)
186 struct lttng_ht_iter iter
;
189 assert(snapshot
->output_ht
);
192 iter
.iter
.node
= &output
->node
.node
;
194 ret
= lttng_ht_del(snapshot
->output_ht
, &iter
);
198 * This is safe because the ownership of a snapshot object is in a session
199 * for which the session lock need to be acquired to read and modify it.
201 snapshot
->nb_output
--;
205 * Add output object to the snapshot.
207 void snapshot_add_output(struct snapshot
*snapshot
,
208 struct snapshot_output
*output
)
211 assert(snapshot
->output_ht
);
215 lttng_ht_add_unique_ulong(snapshot
->output_ht
, &output
->node
);
218 * This is safe because the ownership of a snapshot object is in a session
219 * for which the session lock need to be acquired to read and modify it.
221 snapshot
->nb_output
++;
225 * Destroy and free a snapshot output object.
227 void snapshot_output_destroy(struct snapshot_output
*obj
)
232 consumer_output_send_destroy_relayd(obj
->consumer
);
233 consumer_output_put(obj
->consumer
);
239 * RCU read side lock MUST be acquired before calling this since the returned
240 * pointer is in a RCU hash table.
242 * Return the reference on success or else NULL.
244 struct snapshot_output
*snapshot_find_output_by_name(const char *name
,
245 struct snapshot
*snapshot
)
247 struct lttng_ht_iter iter
;
248 struct snapshot_output
*output
= NULL
;
253 cds_lfht_for_each_entry(snapshot
->output_ht
->ht
, &iter
.iter
, output
,
255 if (!strncmp(output
->name
, name
, strlen(name
))) {
265 * RCU read side lock MUST be acquired before calling this since the returned
266 * pointer is in a RCU hash table.
268 * Return the reference on success or else NULL.
270 struct snapshot_output
*snapshot_find_output_by_id(uint32_t id
,
271 struct snapshot
*snapshot
)
273 struct lttng_ht_node_ulong
*node
;
274 struct lttng_ht_iter iter
;
275 struct snapshot_output
*output
= NULL
;
279 lttng_ht_lookup(snapshot
->output_ht
, (void *)((unsigned long) id
), &iter
);
280 node
= lttng_ht_iter_get_node_ulong(&iter
);
282 DBG3("Snapshot output not found with id %" PRId32
, id
);
285 output
= caa_container_of(node
, struct snapshot_output
, node
);
292 * Initialized a snapshot object that was already allocated.
294 * Return 0 on success or else a negative errno value.
296 int snapshot_init(struct snapshot
*obj
)
302 memset(obj
, 0, sizeof(struct snapshot
));
304 obj
->output_ht
= lttng_ht_new(0, LTTNG_HT_TYPE_ULONG
);
305 if (!obj
->output_ht
) {
317 * Destroy snapshot object but the pointer is not freed so it's safe to pass a
320 void snapshot_destroy(struct snapshot
*obj
)
322 struct lttng_ht_iter iter
;
323 struct snapshot_output
*output
;
328 cds_lfht_for_each_entry(obj
->output_ht
->ht
, &iter
.iter
, output
,
330 snapshot_delete_output(obj
, output
);
331 snapshot_output_destroy(output
);
334 ht_cleanup_push(obj
->output_ht
);
This page took 0.037297 seconds and 4 git commands to generate.