fix sync with last babeltrace updates to live handling
[lttngtop.git] / src / network-live.c
CommitLineData
b1acd2b3
JD
1/*
2 * Copyright (C) 2013 - Julien Desfossez <jdesfossez@efficios.com>
3 * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24#include <sys/socket.h>
25#include <sys/types.h>
26#include <netinet/in.h>
27#include <netdb.h>
28#include <stdio.h>
29#include <string.h>
30#include <stdlib.h>
31#include <unistd.h>
32#include <errno.h>
33#include <inttypes.h>
34#include <fcntl.h>
35#include <sys/mman.h>
36
0c445945 37#include "lttng-viewer-abi.h"
b1acd2b3 38#include "network-live.h"
3bac1a1f 39#include "lttng-live-comm.h"
b1acd2b3
JD
40
41#include <babeltrace/babeltrace.h>
42#include <babeltrace/ctf/events.h>
43#include <babeltrace/ctf/callbacks.h>
44#include <babeltrace/ctf/iterator.h>
45
46/* for packet_index */
47#include <babeltrace/ctf/types.h>
48
49#include <babeltrace/ctf/metadata.h>
50#include <babeltrace/ctf-text/types.h>
51#include <babeltrace/ctf/events-internal.h>
12a91e9d 52#include <lib/babeltrace/ctf/ctf-index.h>
b1acd2b3
JD
53
54/*
12a91e9d 55 * hostname parameter needs to hold NAME_MAX chars.
b1acd2b3 56 */
d81179de
JD
57static
58int parse_url(const char *path, struct lttng_live_ctx *ctx)
b1acd2b3 59{
d81179de 60 char remain[3][NAME_MAX];
12a91e9d
JD
61 int ret = -1, proto, proto_offset = 0;
62 size_t path_len = strlen(path);
b1acd2b3 63
12a91e9d
JD
64 /*
65 * Since sscanf API does not allow easily checking string length
66 * against a size defined by a macro. Test it beforehand on the
67 * input. We know the output is always <= than the input length.
68 */
69 if (path_len > NAME_MAX) {
b1acd2b3
JD
70 goto end;
71 }
12a91e9d
JD
72 ret = sscanf(path, "net%d://", &proto);
73 if (ret < 1) {
74 proto = 4;
75 /* net:// */
76 proto_offset = strlen("net://");
77 } else {
78 /* net4:// or net6:// */
79 proto_offset = strlen("netX://");
b1acd2b3 80 }
12a91e9d 81 if (proto_offset > path_len) {
b1acd2b3
JD
82 goto end;
83 }
12a91e9d
JD
84 /* TODO : parse for IPv6 as well */
85 /* Parse the hostname or IP */
86 ret = sscanf(&path[proto_offset], "%[a-zA-Z.0-9%-]%s",
d81179de 87 ctx->relay_hostname, remain[0]);
12a91e9d
JD
88 if (ret == 2) {
89 /* Optional port number */
90 switch (remain[0][0]) {
91 case ':':
d81179de 92 ret = sscanf(remain[0], ":%d%s", &ctx->port, remain[1]);
12a91e9d
JD
93 /* Optional session ID with port number */
94 if (ret == 2) {
d81179de 95 ret = sscanf(remain[1], "/%s", remain[2]);
12a91e9d
JD
96 /* Accept 0 or 1 (optional) */
97 if (ret < 0) {
98 goto end;
99 }
100 }
101 break;
102 case '/':
103 /* Optional session ID */
d81179de 104 ret = sscanf(remain[0], "/%s", remain[2]);
12a91e9d
JD
105 /* Accept 0 or 1 (optional) */
106 if (ret < 0) {
107 goto end;
108 }
109 break;
110 default:
111 fprintf(stderr, "[error] wrong delimitor : %c\n",
112 remain[0][0]);
113 ret = -1;
114 goto end;
115 }
116 }
b1acd2b3 117
d81179de
JD
118 if (ctx->port < 0)
119 ctx->port = LTTNG_DEFAULT_NETWORK_VIEWER_PORT;
b1acd2b3 120
d81179de 121 if (strlen(remain[2]) == 0) {
12a91e9d
JD
122 printf_verbose("Connecting to hostname : %s, port : %d, "
123 "proto : IPv%d\n",
d81179de
JD
124 ctx->relay_hostname, ctx->port, proto);
125 ret = 0;
126 goto end;
127 }
128 ret = sscanf(remain[2], "host/%[a-zA-Z.0-9%-]/%s",
129 ctx->traced_hostname, ctx->session_name);
130 if (ret != 2) {
131 fprintf(stderr, "[error] Format : "
132 "net://<hostname>/host/<traced_hostname>/<session_name>\n");
133 goto end;
134 }
135
136 printf_verbose("Connecting to hostname : %s, port : %d, "
137 "traced hostname : %s, session name : %s, "
138 "proto : IPv%d\n",
139 ctx->relay_hostname, ctx->port, ctx->traced_hostname,
140 ctx->session_name, proto);
b1acd2b3
JD
141 ret = 0;
142
143end:
144 return ret;
145}
146
12a91e9d 147static int lttng_live_open_trace_read(const char *path)
b1acd2b3 148{
12a91e9d 149 int ret = 0;
d81179de 150 struct lttng_live_ctx *ctx;
b1acd2b3 151
d81179de
JD
152 ctx = g_new0(struct lttng_live_ctx, 1);
153 ctx->session = g_new0(struct lttng_live_session, 1);
b1acd2b3 154
12a91e9d 155 /* We need a pointer to the context from the packet_seek function. */
d81179de 156 ctx->session->ctx = ctx;
b1acd2b3 157
12a91e9d 158 /* HT to store the CTF traces. */
d81179de 159 ctx->session->ctf_traces = g_hash_table_new(g_direct_hash,
12a91e9d 160 g_direct_equal);
d81179de
JD
161 ctx->port = -1;
162 ctx->session_ids = g_array_new(FALSE, TRUE, sizeof(uint64_t));
b1acd2b3 163
d81179de 164 ret = parse_url(path, ctx);
b1acd2b3 165 if (ret < 0) {
12a91e9d 166 goto end_free;
b1acd2b3 167 }
b1acd2b3 168
d81179de 169 ret = lttng_live_connect_viewer(ctx);
b1acd2b3 170 if (ret < 0) {
12a91e9d
JD
171 fprintf(stderr, "[error] Connection failed\n");
172 goto end_free;
b1acd2b3 173 }
12a91e9d 174 printf_verbose("LTTng-live connected to relayd\n");
b1acd2b3 175
d81179de 176 ret = lttng_live_establish_connection(ctx);
b1acd2b3 177 if (ret < 0) {
12a91e9d 178 goto end_free;
b1acd2b3 179 }
d81179de
JD
180 printf_verbose("Listing sessions\n");
181 ret = lttng_live_list_sessions(ctx, path);
182 if (ret < 0) {
183 fprintf(stderr, "[error] List error\n");
184 goto end_free;
b1acd2b3
JD
185 }
186
d81179de
JD
187 if (ctx->session_ids->len > 0)
188 lttng_live_read(ctx);
189
12a91e9d 190end_free:
d81179de
JD
191 g_hash_table_destroy(ctx->session->ctf_traces);
192 g_free(ctx->session);
193 g_free(ctx->session->streams);
194 g_free(ctx);
b1acd2b3
JD
195 return ret;
196}
197
b1acd2b3 198static
12a91e9d
JD
199struct bt_trace_descriptor *lttng_live_open_trace(const char *path, int flags,
200 void (*packet_seek)(struct bt_stream_pos *pos, size_t index,
201 int whence), FILE *metadata_fp)
b1acd2b3 202{
12a91e9d 203 struct ctf_text_stream_pos *pos;
b1acd2b3 204
12a91e9d
JD
205 switch (flags & O_ACCMODE) {
206 case O_RDONLY:
207 /* OK */
b1acd2b3 208 break;
12a91e9d
JD
209 case O_RDWR:
210 fprintf(stderr, "[error] lttng live plugin cannot be used as output plugin.\n");
211 goto error;
b1acd2b3 212 default:
12a91e9d 213 fprintf(stderr, "[error] Incorrect open flags.\n");
b1acd2b3
JD
214 goto error;
215 }
216
12a91e9d
JD
217 pos = g_new0(struct ctf_text_stream_pos, 1);
218 pos->parent.rw_table = NULL;
219 pos->parent.event_cb = NULL;
220 pos->parent.trace = &pos->trace_descriptor;
221 lttng_live_open_trace_read(path);
222 return &pos->trace_descriptor;
b1acd2b3 223
b1acd2b3 224error:
12a91e9d 225 return NULL;
b1acd2b3
JD
226}
227
b1acd2b3 228static
12a91e9d 229int lttng_live_close_trace(struct bt_trace_descriptor *td)
b1acd2b3 230{
12a91e9d
JD
231 struct ctf_text_stream_pos *pos =
232 container_of(td, struct ctf_text_stream_pos,
233 trace_descriptor);
234 free(pos);
235 return 0;
b1acd2b3
JD
236}
237
12a91e9d
JD
238static
239struct bt_format lttng_live_format = {
240 .open_trace = lttng_live_open_trace,
241 .close_trace = lttng_live_close_trace,
242};
b1acd2b3 243
12a91e9d
JD
244static
245void __attribute__((constructor)) lttng_live_init(void)
b1acd2b3 246{
b1acd2b3
JD
247 int ret;
248
12a91e9d
JD
249 lttng_live_format.name = g_quark_from_static_string("lttng-live");
250 ret = bt_register_format(&lttng_live_format);
251 assert(!ret);
b1acd2b3
JD
252}
253
12a91e9d
JD
254static
255void __attribute__((destructor)) lttng_live_exit(void)
b1acd2b3 256{
12a91e9d 257 bt_unregister_format(&lttng_live_format);
b1acd2b3 258}
This page took 0.049811 seconds and 4 git commands to generate.