Fix: rename close_stream and use it in delete session
[lttng-tools.git] / src / bin / lttng-relayd / index.c
CommitLineData
1c20f0e2
JD
1/*
2 * Copyright (C) 2013 - Julien Desfossez <jdesfossez@efficios.com>
3 * David Goulet <dgoulet@efficios.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License, version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 51
16 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#define _GNU_SOURCE
20#include <assert.h>
21
22#include <common/common.h>
23#include <common/utils.h>
24
25#include "index.h"
26
27/*
28 * Deferred free of a relay index object. MUST only be called by a call RCU.
29 */
30static void deferred_free_relay_index(struct rcu_head *head)
31{
32 struct relay_index *index =
33 caa_container_of(head, struct relay_index, rcu_node);
34
35 if (index->to_close_fd >= 0) {
36 int ret;
37
38 ret = close(index->to_close_fd);
39 if (ret < 0) {
40 PERROR("Relay index to close fd %d", index->to_close_fd);
41 }
42 }
43
44 relay_index_free(index);
45}
46
47/*
48 * Allocate a new relay index object using the given stream ID and sequence
49 * number as the hash table key.
50 *
51 * Return allocated object or else NULL on error.
52 */
53struct relay_index *relay_index_create(uint64_t stream_id,
54 uint64_t net_seq_num)
55{
56 struct relay_index *index;
57
58 DBG2("Creating relay index with stream id %" PRIu64 " and seqnum %" PRIu64,
59 stream_id, net_seq_num);
60
61 index = zmalloc(sizeof(*index));
62 if (index == NULL) {
63 PERROR("Relay index zmalloc");
64 goto error;
65 }
66
67 index->to_close_fd = -1;
68 lttng_ht_node_init_two_u64(&index->index_n, stream_id, net_seq_num);
69
70error:
71 return index;
72}
73
74/*
75 * Find a relayd index in the given hash table.
76 *
77 * Return index object or else NULL on error.
78 */
79struct relay_index *relay_index_find(uint64_t stream_id,
80 uint64_t net_seq_num, struct lttng_ht *ht)
81{
82 struct lttng_ht_node_two_u64 *node;
83 struct lttng_ht_iter iter;
84 struct lttng_ht_two_u64 key;
85 struct relay_index *index = NULL;
86
87 assert(ht);
88
89 DBG3("Finding index for stream id %" PRIu64 " and seq_num %" PRIu64,
90 stream_id, net_seq_num);
91
92 key.key1 = stream_id;
93 key.key2 = net_seq_num;
94
95 lttng_ht_lookup(ht, (void *)(&key), &iter);
96 node = lttng_ht_iter_get_node_two_u64(&iter);
97 if (node == NULL) {
98 goto end;
99 }
100 index = caa_container_of(node, struct relay_index, index_n);
101
102end:
103 DBG2("Index %sfound in HT for stream ID %" PRIu64 " and seqnum %" PRIu64,
104 (index == NULL) ? "NOT " : "", stream_id, net_seq_num);
105 return index;
106}
107
108/*
109 * Add unique relay index to the given hash table. In case of a collision, the
110 * already existing object is put in the given _index variable.
111 *
112 * RCU read side lock MUST be acquired.
113 */
114void relay_index_add(struct relay_index *index, struct lttng_ht *ht,
115 struct relay_index **_index)
116{
117 struct cds_lfht_node *node_ptr;
118
119 assert(index);
120 assert(ht);
121 assert(_index);
122
123 DBG2("Adding relay index with stream id %" PRIu64 " and seqnum %" PRIu64,
124 index->key.key1, index->key.key2);
125
126 node_ptr = cds_lfht_add_unique(ht->ht,
127 ht->hash_fct((void *) &index->index_n.key, lttng_ht_seed),
128 ht->match_fct, (void *) &index->index_n.key,
129 &index->index_n.node);
130 if (node_ptr != &index->index_n.node) {
131 *_index = caa_container_of(node_ptr, struct relay_index, index_n.node);
132 }
133}
134
135/*
136 * Write index on disk to the given fd. Once done error or not, it is removed
137 * from the hash table and destroy the object.
138 *
139 * MUST be called with a RCU read side lock held.
140 *
141 * Return 0 on success else a negative value.
142 */
143int relay_index_write(int fd, struct relay_index *index, struct lttng_ht *ht)
144{
145 int ret;
146 struct lttng_ht_iter iter;
147
148 DBG2("Writing index for stream ID %" PRIu64 " and seq num %" PRIu64
149 " on fd %d", index->key.key1, index->key.key2, fd);
150
151 /* Delete index from hash table. */
152 iter.iter.node = &index->index_n.node;
153 ret = lttng_ht_del(ht, &iter);
154 assert(!ret);
155 call_rcu(&index->rcu_node, deferred_free_relay_index);
156
157 return index_write(fd, &index->index_data, sizeof(index->index_data));
158}
159
160/*
161 * Free the given index.
162 */
163void relay_index_free(struct relay_index *index)
164{
165 free(index);
166}
167
168/*
169 * Safely free the given index using a call RCU.
170 */
171void relay_index_free_safe(struct relay_index *index)
172{
173 if (!index) {
174 return;
175 }
176
177 call_rcu(&index->rcu_node, deferred_free_relay_index);
178}
179
180/*
181 * Delete index from the given hash table.
182 *
183 * RCU read side lock MUST be acquired.
184 */
185void relay_index_delete(struct relay_index *index, struct lttng_ht *ht)
186{
187 int ret;
188 struct lttng_ht_iter iter;
189
190 DBG3("Relay index with stream ID %" PRIu64 " and seq num %" PRIu64
191 "deleted.", index->key.key1, index->key.key2);
192
193 /* Delete index from hash table. */
194 iter.iter.node = &index->index_n.node;
195 ret = lttng_ht_del(ht, &iter);
196 assert(!ret);
197}
198
199/*
200 * Destroy every relay index with the given stream id as part of the key.
201 */
202void relay_index_destroy_by_stream_id(uint64_t stream_id, struct lttng_ht *ht)
203{
204 struct lttng_ht_iter iter;
205 struct relay_index *index;
206
207 assert(ht);
208 assert(ht->ht);
209
210 rcu_read_lock();
211 cds_lfht_for_each_entry(ht->ht, &iter.iter, index, index_n.node) {
212 if (index->key.key1 == stream_id) {
213 relay_index_delete(index, ht);
214 relay_index_free_safe(index);
215 }
216 }
217 rcu_read_unlock();
218}
This page took 0.030379 seconds and 4 git commands to generate.