2 * Copyright (C) 2013 - Julien Desfossez <jdesfossez@efficios.com>
3 * David Goulet <dgoulet@efficios.com>
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.
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
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.
22 #include <common/common.h>
23 #include <common/utils.h>
28 * Deferred free of a relay index object. MUST only be called by a call RCU.
30 static void deferred_free_relay_index(struct rcu_head
*head
)
32 struct relay_index
*index
=
33 caa_container_of(head
, struct relay_index
, rcu_node
);
35 if (index
->to_close_fd
>= 0) {
38 ret
= close(index
->to_close_fd
);
40 PERROR("Relay index to close fd %d", index
->to_close_fd
);
44 relay_index_free(index
);
48 * Allocate a new relay index object using the given stream ID and sequence
49 * number as the hash table key.
51 * Return allocated object or else NULL on error.
53 struct relay_index
*relay_index_create(uint64_t stream_id
,
56 struct relay_index
*index
;
58 DBG2("Creating relay index with stream id %" PRIu64
" and seqnum %" PRIu64
,
59 stream_id
, net_seq_num
);
61 index
= zmalloc(sizeof(*index
));
63 PERROR("Relay index zmalloc");
67 index
->to_close_fd
= -1;
68 lttng_ht_node_init_two_u64(&index
->index_n
, stream_id
, net_seq_num
);
75 * Find a relayd index in the given hash table.
77 * Return index object or else NULL on error.
79 struct relay_index
*relay_index_find(uint64_t stream_id
,
80 uint64_t net_seq_num
, struct lttng_ht
*ht
)
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
;
89 DBG3("Finding index for stream id %" PRIu64
" and seq_num %" PRIu64
,
90 stream_id
, net_seq_num
);
93 key
.key2
= net_seq_num
;
95 lttng_ht_lookup(ht
, (void *)(&key
), &iter
);
96 node
= lttng_ht_iter_get_node_two_u64(&iter
);
100 index
= caa_container_of(node
, struct relay_index
, index_n
);
103 DBG2("Index %sfound in HT for stream ID %" PRIu64
" and seqnum %" PRIu64
,
104 (index
== NULL
) ? "NOT " : "", stream_id
, net_seq_num
);
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.
112 * RCU read side lock MUST be acquired.
114 void relay_index_add(struct relay_index
*index
, struct lttng_ht
*ht
,
115 struct relay_index
**_index
)
117 struct cds_lfht_node
*node_ptr
;
123 DBG2("Adding relay index with stream id %" PRIu64
" and seqnum %" PRIu64
,
124 index
->key
.key1
, index
->key
.key2
);
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
);
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.
139 * MUST be called with a RCU read side lock held.
141 * Return 0 on success else a negative value.
143 int relay_index_write(int fd
, struct relay_index
*index
, struct lttng_ht
*ht
)
146 struct lttng_ht_iter iter
;
148 DBG2("Writing index for stream ID %" PRIu64
" and seq num %" PRIu64
149 " on fd %d", index
->key
.key1
, index
->key
.key2
, fd
);
151 /* Delete index from hash table. */
152 iter
.iter
.node
= &index
->index_n
.node
;
153 ret
= lttng_ht_del(ht
, &iter
);
155 call_rcu(&index
->rcu_node
, deferred_free_relay_index
);
157 return index_write(fd
, &index
->index_data
, sizeof(index
->index_data
));
161 * Free the given index.
163 void relay_index_free(struct relay_index
*index
)
169 * Safely free the given index using a call RCU.
171 void relay_index_free_safe(struct relay_index
*index
)
177 call_rcu(&index
->rcu_node
, deferred_free_relay_index
);
181 * Delete index from the given hash table.
183 * RCU read side lock MUST be acquired.
185 void relay_index_delete(struct relay_index
*index
, struct lttng_ht
*ht
)
188 struct lttng_ht_iter iter
;
190 DBG3("Relay index with stream ID %" PRIu64
" and seq num %" PRIu64
191 "deleted.", index
->key
.key1
, index
->key
.key2
);
193 /* Delete index from hash table. */
194 iter
.iter
.node
= &index
->index_n
.node
;
195 ret
= lttng_ht_del(ht
, &iter
);
200 * Destroy every relay index with the given stream id as part of the key.
202 void relay_index_destroy_by_stream_id(uint64_t stream_id
, struct lttng_ht
*ht
)
204 struct lttng_ht_iter iter
;
205 struct relay_index
*index
;
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
);