Commit | Line | Data |
---|---|---|
1b368955 | 1 | /* |
9d16b343 | 2 | * Copyright (C) 2013 Julien Desfossez <jdesfossez@efficios.com> |
1b368955 | 3 | * |
9d16b343 | 4 | * SPDX-License-Identifier: GPL-2.0-only |
1b368955 | 5 | * |
1b368955 JD |
6 | */ |
7 | ||
1b368955 JD |
8 | #include <stdio.h> |
9 | #include <stdlib.h> | |
10 | #include <string.h> | |
11 | #include <unistd.h> | |
389fbf04 | 12 | #include <common/compat/time.h> |
1b368955 JD |
13 | #include <sys/types.h> |
14 | #include <inttypes.h> | |
15 | #include <stdlib.h> | |
16 | #include <sys/socket.h> | |
17 | #include <netinet/in.h> | |
18 | #include <netdb.h> | |
19 | #include <fcntl.h> | |
20 | #include <sys/mman.h> | |
21 | #include <sys/stat.h> | |
22 | ||
23 | #include <tap/tap.h> | |
24 | #include <lttng/lttng.h> | |
25 | ||
26 | #include <urcu/list.h> | |
1b368955 JD |
27 | #include <common/common.h> |
28 | ||
2f8f53af | 29 | #include <bin/lttng-relayd/lttng-viewer-abi.h> |
50adc264 | 30 | #include <common/index/ctf-index.h> |
1b368955 | 31 | |
edf4b93e | 32 | #include <common/compat/errno.h> |
f263b7fd JD |
33 | #include <common/compat/endian.h> |
34 | ||
1b368955 JD |
35 | #define SESSION1 "test1" |
36 | #define RELAYD_URL "net://localhost" | |
37 | #define LIVE_TIMER 2000000 | |
38 | ||
39 | /* Number of TAP tests in this file */ | |
e22ba966 | 40 | #define NUM_TESTS 11 |
1b368955 JD |
41 | #define mmap_size 524288 |
42 | ||
48c6e03e MJ |
43 | #ifdef HAVE_LIBLTTNG_UST_CTL |
44 | #include <lttng/ust-sigbus.h> | |
e207fe73 | 45 | DEFINE_LTTNG_UST_SIGBUS_STATE(); |
48c6e03e | 46 | #endif |
e207fe73 | 47 | |
1b368955 JD |
48 | static int control_sock; |
49 | struct live_session *session; | |
50 | ||
51 | static int first_packet_offset; | |
52 | static int first_packet_len; | |
7409dd34 | 53 | static int first_packet_stream_id = -1; |
1b368955 JD |
54 | |
55 | struct viewer_stream { | |
56 | uint64_t id; | |
57 | uint64_t ctf_trace_id; | |
58 | void *mmap_base; | |
59 | int fd; | |
60 | int metadata_flag; | |
61 | int first_read; | |
62 | char path[PATH_MAX]; | |
63 | }; | |
64 | ||
65 | struct live_session { | |
66 | struct viewer_stream *streams; | |
67 | uint64_t live_timer_interval; | |
68 | uint64_t stream_count; | |
69 | }; | |
70 | ||
10236918 MD |
71 | static |
72 | ssize_t lttng_live_recv(int fd, void *buf, size_t len) | |
73 | { | |
74 | ssize_t ret; | |
75 | size_t copied = 0, to_copy = len; | |
76 | ||
77 | do { | |
78 | ret = recv(fd, buf + copied, to_copy, 0); | |
79 | if (ret > 0) { | |
a0377dfe | 80 | LTTNG_ASSERT(ret <= to_copy); |
10236918 MD |
81 | copied += ret; |
82 | to_copy -= ret; | |
83 | } | |
84 | } while ((ret > 0 && to_copy > 0) | |
85 | || (ret < 0 && errno == EINTR)); | |
86 | if (ret > 0) | |
87 | ret = copied; | |
88 | /* ret = 0 means orderly shutdown, ret < 0 is error. */ | |
89 | return ret; | |
90 | } | |
91 | ||
92 | static | |
93 | ssize_t lttng_live_send(int fd, const void *buf, size_t len) | |
94 | { | |
95 | ssize_t ret; | |
96 | ||
97 | do { | |
98 | ret = send(fd, buf, len, MSG_NOSIGNAL); | |
99 | } while (ret < 0 && errno == EINTR); | |
100 | return ret; | |
101 | } | |
102 | ||
1b368955 | 103 | static |
b53d4e59 | 104 | int connect_viewer(const char *hostname) |
1b368955 JD |
105 | { |
106 | struct hostent *host; | |
107 | struct sockaddr_in server_addr; | |
108 | int ret; | |
109 | ||
110 | host = gethostbyname(hostname); | |
111 | if (!host) { | |
112 | ret = -1; | |
113 | goto end; | |
114 | } | |
115 | ||
116 | if ((control_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { | |
6f04ed72 | 117 | PERROR("Socket"); |
1b368955 JD |
118 | ret = -1; |
119 | goto end; | |
120 | } | |
121 | ||
122 | server_addr.sin_family = AF_INET; | |
123 | server_addr.sin_port = htons(5344); | |
124 | server_addr.sin_addr = *((struct in_addr *) host->h_addr); | |
125 | bzero(&(server_addr.sin_zero), 8); | |
126 | ||
127 | if (connect(control_sock, (struct sockaddr *) &server_addr, | |
128 | sizeof(struct sockaddr)) == -1) { | |
6f04ed72 | 129 | PERROR("Connect"); |
1b368955 JD |
130 | ret = -1; |
131 | goto end; | |
132 | } | |
133 | ||
134 | server_addr.sin_family = AF_INET; | |
135 | server_addr.sin_port = htons(5345); | |
136 | server_addr.sin_addr = *((struct in_addr *) host->h_addr); | |
137 | bzero(&(server_addr.sin_zero), 8); | |
138 | ||
139 | ret = 0; | |
140 | ||
141 | end: | |
142 | return ret; | |
143 | } | |
144 | ||
8f92cd08 | 145 | static |
1b368955 JD |
146 | int establish_connection(void) |
147 | { | |
148 | struct lttng_viewer_cmd cmd; | |
149 | struct lttng_viewer_connect connect; | |
10236918 | 150 | ssize_t ret_len; |
1b368955 | 151 | |
c4e361a4 | 152 | cmd.cmd = htobe32(LTTNG_VIEWER_CONNECT); |
2dc797f3 JD |
153 | cmd.data_size = htobe64(sizeof(connect)); |
154 | cmd.cmd_version = htobe32(0); | |
1b368955 | 155 | |
dcf5c25e | 156 | memset(&connect, 0, sizeof(connect)); |
1b368955 JD |
157 | connect.major = htobe32(VERSION_MAJOR); |
158 | connect.minor = htobe32(VERSION_MINOR); | |
c4e361a4 | 159 | connect.type = htobe32(LTTNG_VIEWER_CLIENT_COMMAND); |
1b368955 | 160 | |
10236918 MD |
161 | ret_len = lttng_live_send(control_sock, &cmd, sizeof(cmd)); |
162 | if (ret_len < 0) { | |
7409dd34 | 163 | diag("Error sending cmd"); |
1b368955 JD |
164 | goto error; |
165 | } | |
10236918 MD |
166 | ret_len = lttng_live_send(control_sock, &connect, sizeof(connect)); |
167 | if (ret_len < 0) { | |
7409dd34 | 168 | diag("Error sending version"); |
1b368955 JD |
169 | goto error; |
170 | } | |
171 | ||
10236918 MD |
172 | ret_len = lttng_live_recv(control_sock, &connect, sizeof(connect)); |
173 | if (ret_len == 0) { | |
7409dd34 | 174 | diag("[error] Remote side has closed connection"); |
10236918 MD |
175 | goto error; |
176 | } | |
177 | if (ret_len < 0) { | |
7409dd34 | 178 | diag("Error receiving version"); |
1b368955 JD |
179 | goto error; |
180 | } | |
10236918 | 181 | return 0; |
1b368955 JD |
182 | |
183 | error: | |
10236918 | 184 | return -1; |
1b368955 JD |
185 | } |
186 | ||
187 | /* | |
188 | * Returns the number of sessions, should be 1 during the unit test. | |
189 | */ | |
8f92cd08 | 190 | static |
7409dd34 | 191 | int list_sessions(uint64_t *session_id) |
1b368955 JD |
192 | { |
193 | struct lttng_viewer_cmd cmd; | |
194 | struct lttng_viewer_list_sessions list; | |
195 | struct lttng_viewer_session lsession; | |
10236918 MD |
196 | int i; |
197 | ssize_t ret_len; | |
1b368955 JD |
198 | int first_session = 0; |
199 | ||
c4e361a4 | 200 | cmd.cmd = htobe32(LTTNG_VIEWER_LIST_SESSIONS); |
2dc797f3 JD |
201 | cmd.data_size = htobe64(0); |
202 | cmd.cmd_version = htobe32(0); | |
1b368955 | 203 | |
10236918 MD |
204 | ret_len = lttng_live_send(control_sock, &cmd, sizeof(cmd)); |
205 | if (ret_len < 0) { | |
7409dd34 | 206 | diag("Error sending cmd"); |
1b368955 JD |
207 | goto error; |
208 | } | |
209 | ||
10236918 MD |
210 | ret_len = lttng_live_recv(control_sock, &list, sizeof(list)); |
211 | if (ret_len == 0) { | |
7409dd34 | 212 | diag("[error] Remote side has closed connection"); |
10236918 MD |
213 | goto error; |
214 | } | |
215 | if (ret_len < 0) { | |
7409dd34 | 216 | diag("Error receiving session list"); |
1b368955 JD |
217 | goto error; |
218 | } | |
219 | ||
220 | for (i = 0; i < be32toh(list.sessions_count); i++) { | |
10236918 MD |
221 | ret_len = lttng_live_recv(control_sock, &lsession, sizeof(lsession)); |
222 | if (ret_len < 0) { | |
7409dd34 | 223 | diag("Error receiving session"); |
1b368955 JD |
224 | goto error; |
225 | } | |
226 | if (lsession.streams > 0 && first_session <= 0) { | |
227 | first_session = be64toh(lsession.id); | |
228 | *session_id = first_session; | |
229 | } | |
230 | } | |
231 | ||
10236918 | 232 | return be32toh(list.sessions_count); |
1b368955 JD |
233 | |
234 | error: | |
10236918 | 235 | return -1; |
1b368955 JD |
236 | } |
237 | ||
8f92cd08 | 238 | static |
10236918 | 239 | int create_viewer_session(void) |
25b50f8f JD |
240 | { |
241 | struct lttng_viewer_cmd cmd; | |
242 | struct lttng_viewer_create_session_response resp; | |
25b50f8f JD |
243 | ssize_t ret_len; |
244 | ||
245 | cmd.cmd = htobe32(LTTNG_VIEWER_CREATE_SESSION); | |
2dc797f3 JD |
246 | cmd.data_size = htobe64(0); |
247 | cmd.cmd_version = htobe32(0); | |
25b50f8f | 248 | |
10236918 | 249 | ret_len = lttng_live_send(control_sock, &cmd, sizeof(cmd)); |
25b50f8f | 250 | if (ret_len < 0) { |
7409dd34 | 251 | diag("[error] Error sending cmd"); |
25b50f8f JD |
252 | goto error; |
253 | } | |
a0377dfe | 254 | LTTNG_ASSERT(ret_len == sizeof(cmd)); |
25b50f8f | 255 | |
10236918 MD |
256 | ret_len = lttng_live_recv(control_sock, &resp, sizeof(resp)); |
257 | if (ret_len == 0) { | |
7409dd34 | 258 | diag("[error] Remote side has closed connection"); |
10236918 MD |
259 | goto error; |
260 | } | |
25b50f8f | 261 | if (ret_len < 0) { |
7409dd34 | 262 | diag("[error] Error receiving create session reply"); |
25b50f8f JD |
263 | goto error; |
264 | } | |
a0377dfe | 265 | LTTNG_ASSERT(ret_len == sizeof(resp)); |
25b50f8f JD |
266 | |
267 | if (be32toh(resp.status) != LTTNG_VIEWER_CREATE_SESSION_OK) { | |
7409dd34 | 268 | diag("[error] Error creating viewer session"); |
25b50f8f JD |
269 | goto error; |
270 | } | |
10236918 | 271 | return 0; |
25b50f8f JD |
272 | |
273 | error: | |
10236918 | 274 | return -1; |
25b50f8f JD |
275 | } |
276 | ||
8f92cd08 | 277 | static |
7409dd34 | 278 | int attach_session(uint64_t id) |
1b368955 JD |
279 | { |
280 | struct lttng_viewer_cmd cmd; | |
281 | struct lttng_viewer_attach_session_request rq; | |
282 | struct lttng_viewer_attach_session_response rp; | |
283 | struct lttng_viewer_stream stream; | |
10236918 MD |
284 | int i; |
285 | ssize_t ret_len; | |
1b368955 JD |
286 | |
287 | session = zmalloc(sizeof(struct live_session)); | |
288 | if (!session) { | |
1b368955 JD |
289 | goto error; |
290 | } | |
291 | ||
c4e361a4 | 292 | cmd.cmd = htobe32(LTTNG_VIEWER_ATTACH_SESSION); |
2dc797f3 JD |
293 | cmd.data_size = htobe64(sizeof(rq)); |
294 | cmd.cmd_version = htobe32(0); | |
1b368955 | 295 | |
dcf5c25e | 296 | memset(&rq, 0, sizeof(rq)); |
1b368955 | 297 | rq.session_id = htobe64(id); |
c4e361a4 | 298 | rq.seek = htobe32(LTTNG_VIEWER_SEEK_BEGINNING); |
1b368955 | 299 | |
10236918 MD |
300 | ret_len = lttng_live_send(control_sock, &cmd, sizeof(cmd)); |
301 | if (ret_len < 0) { | |
7409dd34 | 302 | diag("Error sending cmd LTTNG_VIEWER_ATTACH_SESSION"); |
1b368955 JD |
303 | goto error; |
304 | } | |
10236918 MD |
305 | ret_len = lttng_live_send(control_sock, &rq, sizeof(rq)); |
306 | if (ret_len < 0) { | |
7409dd34 | 307 | diag("Error sending attach request"); |
1b368955 JD |
308 | goto error; |
309 | } | |
310 | ||
10236918 MD |
311 | ret_len = lttng_live_recv(control_sock, &rp, sizeof(rp)); |
312 | if (ret_len == 0) { | |
7409dd34 | 313 | diag("[error] Remote side has closed connection"); |
10236918 MD |
314 | goto error; |
315 | } | |
316 | if (ret_len < 0) { | |
7409dd34 | 317 | diag("Error receiving attach response"); |
1b368955 JD |
318 | goto error; |
319 | } | |
c4e361a4 | 320 | if (be32toh(rp.status) != LTTNG_VIEWER_ATTACH_OK) { |
10236918 | 321 | goto error; |
1b368955 JD |
322 | } |
323 | ||
324 | session->stream_count = be32toh(rp.streams_count); | |
7409dd34 JG |
325 | if (session->stream_count == 0) { |
326 | diag("Got session stream count == 0"); | |
327 | goto error; | |
328 | } | |
1b368955 JD |
329 | session->streams = zmalloc(session->stream_count * |
330 | sizeof(struct viewer_stream)); | |
331 | if (!session->streams) { | |
1b368955 JD |
332 | goto error; |
333 | } | |
334 | ||
335 | for (i = 0; i < be32toh(rp.streams_count); i++) { | |
10236918 MD |
336 | ret_len = lttng_live_recv(control_sock, &stream, sizeof(stream)); |
337 | if (ret_len == 0) { | |
7409dd34 | 338 | diag("[error] Remote side has closed connection"); |
10236918 MD |
339 | goto error; |
340 | } | |
341 | if (ret_len < 0) { | |
7409dd34 | 342 | diag("Error receiving stream"); |
1b368955 JD |
343 | goto error; |
344 | } | |
345 | session->streams[i].id = be64toh(stream.id); | |
346 | ||
347 | session->streams[i].ctf_trace_id = be64toh(stream.ctf_trace_id); | |
348 | session->streams[i].first_read = 1; | |
7409dd34 JG |
349 | session->streams[i].mmap_base = mmap(NULL, mmap_size, |
350 | PROT_READ | PROT_WRITE, | |
1b368955 JD |
351 | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
352 | if (session->streams[i].mmap_base == MAP_FAILED) { | |
7409dd34 | 353 | diag("mmap error"); |
1b368955 JD |
354 | goto error; |
355 | } | |
356 | ||
357 | if (be32toh(stream.metadata_flag)) { | |
358 | session->streams[i].metadata_flag = 1; | |
359 | } | |
360 | } | |
10236918 | 361 | return session->stream_count; |
1b368955 | 362 | |
1b368955 | 363 | error: |
10236918 | 364 | return -1; |
1b368955 JD |
365 | } |
366 | ||
8f92cd08 | 367 | static |
1b368955 JD |
368 | int get_metadata(void) |
369 | { | |
370 | struct lttng_viewer_cmd cmd; | |
371 | struct lttng_viewer_get_metadata rq; | |
372 | struct lttng_viewer_metadata_packet rp; | |
10236918 | 373 | ssize_t ret_len; |
1b368955 JD |
374 | int ret; |
375 | uint64_t i; | |
376 | char *data = NULL; | |
377 | uint64_t len = 0; | |
378 | int metadata_stream_id = -1; | |
379 | ||
c4e361a4 | 380 | cmd.cmd = htobe32(LTTNG_VIEWER_GET_METADATA); |
2dc797f3 JD |
381 | cmd.data_size = htobe64(sizeof(rq)); |
382 | cmd.cmd_version = htobe32(0); | |
1b368955 JD |
383 | |
384 | for (i = 0; i < session->stream_count; i++) { | |
385 | if (session->streams[i].metadata_flag) { | |
386 | metadata_stream_id = i; | |
387 | break; | |
388 | } | |
389 | } | |
390 | ||
391 | if (metadata_stream_id < 0) { | |
7409dd34 | 392 | diag("No metadata stream found"); |
1b368955 JD |
393 | goto error; |
394 | } | |
395 | ||
396 | rq.stream_id = htobe64(session->streams[metadata_stream_id].id); | |
397 | ||
a648b489 | 398 | retry: |
10236918 MD |
399 | ret_len = lttng_live_send(control_sock, &cmd, sizeof(cmd)); |
400 | if (ret_len < 0) { | |
7409dd34 | 401 | diag("Error sending cmd"); |
1b368955 JD |
402 | goto error; |
403 | } | |
10236918 MD |
404 | ret_len = lttng_live_send(control_sock, &rq, sizeof(rq)); |
405 | if (ret_len < 0) { | |
7409dd34 | 406 | diag("Error sending get_metadata request"); |
1b368955 JD |
407 | goto error; |
408 | } | |
10236918 MD |
409 | ret_len = lttng_live_recv(control_sock, &rp, sizeof(rp)); |
410 | if (ret_len == 0) { | |
7409dd34 | 411 | diag("[error] Remote side has closed connection"); |
10236918 MD |
412 | goto error; |
413 | } | |
414 | if (ret_len < 0) { | |
7409dd34 | 415 | diag("Error receiving metadata response"); |
1b368955 JD |
416 | goto error; |
417 | } | |
418 | switch (be32toh(rp.status)) { | |
7409dd34 JG |
419 | case LTTNG_VIEWER_METADATA_OK: |
420 | break; | |
421 | case LTTNG_VIEWER_NO_NEW_METADATA: | |
422 | diag("Got LTTNG_VIEWER_NO_NEW_METADATA:"); | |
a648b489 JR |
423 | usleep(50); |
424 | goto retry; | |
7409dd34 JG |
425 | case LTTNG_VIEWER_METADATA_ERR: |
426 | diag("Got LTTNG_VIEWER_METADATA_ERR:"); | |
427 | goto error; | |
428 | default: | |
429 | diag("Got unknown status during LTTNG_VIEWER_GET_METADATA"); | |
430 | goto error; | |
1b368955 JD |
431 | } |
432 | ||
433 | len = be64toh(rp.len); | |
434 | if (len <= 0) { | |
10236918 | 435 | goto error; |
1b368955 JD |
436 | } |
437 | ||
438 | data = zmalloc(len); | |
439 | if (!data) { | |
6f04ed72 | 440 | PERROR("relay data zmalloc"); |
1b368955 JD |
441 | goto error; |
442 | } | |
10236918 MD |
443 | ret_len = lttng_live_recv(control_sock, data, len); |
444 | if (ret_len == 0) { | |
7409dd34 | 445 | diag("[error] Remote side has closed connection"); |
10236918 MD |
446 | goto error_free_data; |
447 | } | |
448 | if (ret_len < 0) { | |
7409dd34 | 449 | diag("Error receiving trace packet"); |
10236918 | 450 | goto error_free_data; |
1b368955 JD |
451 | } |
452 | free(data); | |
10236918 | 453 | ret = len; |
a648b489 | 454 | |
1b368955 | 455 | return ret; |
10236918 MD |
456 | |
457 | error_free_data: | |
458 | free(data); | |
459 | error: | |
460 | return -1; | |
1b368955 JD |
461 | } |
462 | ||
8f92cd08 | 463 | static |
1b368955 JD |
464 | int get_next_index(void) |
465 | { | |
466 | struct lttng_viewer_cmd cmd; | |
467 | struct lttng_viewer_get_next_index rq; | |
468 | struct lttng_viewer_index rp; | |
10236918 | 469 | ssize_t ret_len; |
1b368955 JD |
470 | int id; |
471 | ||
c4e361a4 | 472 | cmd.cmd = htobe32(LTTNG_VIEWER_GET_NEXT_INDEX); |
2dc797f3 JD |
473 | cmd.data_size = htobe64(sizeof(rq)); |
474 | cmd.cmd_version = htobe32(0); | |
1b368955 JD |
475 | |
476 | for (id = 0; id < session->stream_count; id++) { | |
477 | if (session->streams[id].metadata_flag) { | |
478 | continue; | |
479 | } | |
10236918 | 480 | memset(&rq, 0, sizeof(rq)); |
1b368955 JD |
481 | rq.stream_id = htobe64(session->streams[id].id); |
482 | ||
483 | retry: | |
10236918 MD |
484 | ret_len = lttng_live_send(control_sock, &cmd, sizeof(cmd)); |
485 | if (ret_len < 0) { | |
7409dd34 | 486 | diag("Error sending cmd"); |
1b368955 JD |
487 | goto error; |
488 | } | |
10236918 MD |
489 | ret_len = lttng_live_send(control_sock, &rq, sizeof(rq)); |
490 | if (ret_len < 0) { | |
7409dd34 | 491 | diag("Error sending get_next_index request"); |
1b368955 JD |
492 | goto error; |
493 | } | |
10236918 MD |
494 | ret_len = lttng_live_recv(control_sock, &rp, sizeof(rp)); |
495 | if (ret_len == 0) { | |
7409dd34 | 496 | diag("[error] Remote side has closed connection"); |
10236918 MD |
497 | goto error; |
498 | } | |
499 | if (ret_len < 0) { | |
7409dd34 | 500 | diag("Error receiving index response"); |
1b368955 JD |
501 | goto error; |
502 | } | |
503 | ||
504 | rp.flags = be32toh(rp.flags); | |
505 | ||
506 | switch (be32toh(rp.status)) { | |
7409dd34 JG |
507 | case LTTNG_VIEWER_INDEX_INACTIVE: |
508 | /* Skip this stream. */ | |
509 | diag("Got LTTNG_VIEWER_INDEX_INACTIVE"); | |
510 | continue; | |
511 | case LTTNG_VIEWER_INDEX_OK: | |
512 | break; | |
513 | case LTTNG_VIEWER_INDEX_RETRY: | |
514 | sleep(1); | |
515 | goto retry; | |
516 | case LTTNG_VIEWER_INDEX_HUP: | |
517 | diag("Got LTTNG_VIEWER_INDEX_HUP"); | |
518 | session->streams[id].id = -1ULL; | |
519 | session->streams[id].fd = -1; | |
520 | goto error; | |
521 | case LTTNG_VIEWER_INDEX_ERR: | |
522 | diag("Got LTTNG_VIEWER_INDEX_ERR"); | |
523 | goto error; | |
524 | default: | |
525 | diag("Unknown reply status during LTTNG_VIEWER_GET_NEXT_INDEX (%d)", be32toh(rp.status)); | |
526 | goto error; | |
1b368955 | 527 | } |
7409dd34 JG |
528 | if (first_packet_stream_id < 0) { |
529 | /* | |
530 | * Initialize the first packet stream id. That is, | |
531 | * the first active stream encoutered. | |
532 | */ | |
1b368955 JD |
533 | first_packet_offset = be64toh(rp.offset); |
534 | first_packet_len = be64toh(rp.packet_size) / CHAR_BIT; | |
535 | first_packet_stream_id = id; | |
7409dd34 JG |
536 | diag("Got first packet index with offset %d and len %d", |
537 | first_packet_offset, first_packet_len); | |
1b368955 JD |
538 | } |
539 | } | |
10236918 | 540 | return 0; |
1b368955 JD |
541 | |
542 | error: | |
10236918 | 543 | return -1; |
1b368955 JD |
544 | } |
545 | ||
546 | static | |
547 | int get_data_packet(int id, uint64_t offset, | |
548 | uint64_t len) | |
549 | { | |
550 | struct lttng_viewer_cmd cmd; | |
551 | struct lttng_viewer_get_packet rq; | |
552 | struct lttng_viewer_trace_packet rp; | |
10236918 | 553 | ssize_t ret_len; |
1b368955 | 554 | |
c4e361a4 | 555 | cmd.cmd = htobe32(LTTNG_VIEWER_GET_PACKET); |
2dc797f3 JD |
556 | cmd.data_size = htobe64(sizeof(rq)); |
557 | cmd.cmd_version = htobe32(0); | |
1b368955 | 558 | |
10236918 | 559 | memset(&rq, 0, sizeof(rq)); |
1b368955 JD |
560 | rq.stream_id = htobe64(session->streams[id].id); |
561 | /* Already in big endian. */ | |
562 | rq.offset = offset; | |
563 | rq.len = htobe32(len); | |
564 | ||
10236918 MD |
565 | ret_len = lttng_live_send(control_sock, &cmd, sizeof(cmd)); |
566 | if (ret_len < 0) { | |
7409dd34 | 567 | diag("Error sending cmd"); |
1b368955 JD |
568 | goto error; |
569 | } | |
10236918 MD |
570 | ret_len = lttng_live_send(control_sock, &rq, sizeof(rq)); |
571 | if (ret_len < 0) { | |
7409dd34 | 572 | diag("Error sending get_data_packet request"); |
1b368955 JD |
573 | goto error; |
574 | } | |
10236918 MD |
575 | ret_len = lttng_live_recv(control_sock, &rp, sizeof(rp)); |
576 | if (ret_len == 0) { | |
7409dd34 | 577 | diag("[error] Remote side has closed connection"); |
10236918 MD |
578 | goto error; |
579 | } | |
580 | if (ret_len < 0) { | |
7409dd34 | 581 | diag("Error receiving data response"); |
1b368955 JD |
582 | goto error; |
583 | } | |
584 | rp.flags = be32toh(rp.flags); | |
585 | ||
586 | switch (be32toh(rp.status)) { | |
c4e361a4 | 587 | case LTTNG_VIEWER_GET_PACKET_OK: |
10236918 | 588 | len = be32toh(rp.len); |
7409dd34 JG |
589 | if (len == 0) { |
590 | diag("Got LTTNG_VIEWER_GET_PACKET_OK, but len == 0"); | |
591 | goto error; | |
592 | } | |
1b368955 | 593 | break; |
c4e361a4 | 594 | case LTTNG_VIEWER_GET_PACKET_RETRY: |
7409dd34 | 595 | diag("Got LTTNG_VIEWER_GET_PACKET_RETRY:"); |
10236918 | 596 | goto error; |
c4e361a4 | 597 | case LTTNG_VIEWER_GET_PACKET_ERR: |
1b368955 | 598 | if (rp.flags & LTTNG_VIEWER_FLAG_NEW_METADATA) { |
7409dd34 | 599 | diag("Got LTTNG_VIEWER_GET_PACKET_ERR with NEW_METADATA flag"); |
1b368955 JD |
600 | goto end; |
601 | } | |
7409dd34 | 602 | diag("Got LTTNG_VIEWER_GET_PACKET_ERR:"); |
10236918 | 603 | goto error; |
1b368955 | 604 | default: |
7409dd34 | 605 | diag("Got unknown status code during LTTNG_VIEWER_GET_PACKET"); |
10236918 | 606 | goto error; |
1b368955 JD |
607 | } |
608 | ||
609 | if (len > mmap_size) { | |
7409dd34 | 610 | diag("mmap_size not big enough"); |
1b368955 JD |
611 | goto error; |
612 | } | |
613 | ||
10236918 MD |
614 | ret_len = lttng_live_recv(control_sock, session->streams[id].mmap_base, len); |
615 | if (ret_len == 0) { | |
7409dd34 | 616 | diag("[error] Remote side has closed connection"); |
10236918 MD |
617 | goto error; |
618 | } | |
619 | if (ret_len < 0) { | |
7409dd34 | 620 | diag("Error receiving trace packet"); |
1b368955 JD |
621 | goto error; |
622 | } | |
1b368955 | 623 | end: |
10236918 | 624 | return 0; |
1b368955 | 625 | error: |
10236918 | 626 | return -1; |
1b368955 JD |
627 | } |
628 | ||
8f92cd08 | 629 | static |
e22ba966 JD |
630 | int detach_viewer_session(uint64_t id) |
631 | { | |
632 | struct lttng_viewer_cmd cmd; | |
633 | struct lttng_viewer_detach_session_response resp; | |
634 | struct lttng_viewer_detach_session_request rq; | |
635 | int ret; | |
636 | ssize_t ret_len; | |
637 | ||
638 | cmd.cmd = htobe32(LTTNG_VIEWER_DETACH_SESSION); | |
2dc797f3 JD |
639 | cmd.data_size = htobe64(sizeof(rq)); |
640 | cmd.cmd_version = htobe32(0); | |
e22ba966 JD |
641 | |
642 | memset(&rq, 0, sizeof(rq)); | |
643 | rq.session_id = htobe64(id); | |
644 | ||
645 | ret_len = lttng_live_send(control_sock, &cmd, sizeof(cmd)); | |
646 | if (ret_len < 0) { | |
647 | fprintf(stderr, "[error] Error sending cmd\n"); | |
648 | ret = ret_len; | |
649 | goto error; | |
650 | } | |
651 | ||
652 | ret_len = lttng_live_send(control_sock, &rq, sizeof(rq)); | |
653 | if (ret_len < 0) { | |
654 | fprintf(stderr, "Error sending attach request\n"); | |
655 | ret = ret_len; | |
656 | goto error; | |
657 | } | |
658 | ||
659 | ret_len = lttng_live_recv(control_sock, &resp, sizeof(resp)); | |
660 | if (ret_len < 0) { | |
661 | fprintf(stderr, "[error] Error receiving detach session reply\n"); | |
662 | ret = ret_len; | |
663 | goto error; | |
664 | } | |
665 | ||
666 | if (be32toh(resp.status) != LTTNG_VIEWER_DETACH_SESSION_OK) { | |
667 | fprintf(stderr, "[error] Error detaching viewer session\n"); | |
668 | ret = -1; | |
669 | goto error; | |
670 | } | |
671 | ret = 0; | |
672 | ||
673 | error: | |
674 | return ret; | |
675 | } | |
676 | ||
1b368955 JD |
677 | int main(int argc, char **argv) |
678 | { | |
679 | int ret; | |
7409dd34 | 680 | uint64_t session_id; |
1b368955 JD |
681 | |
682 | plan_tests(NUM_TESTS); | |
683 | ||
684 | diag("Live unit tests"); | |
685 | ||
686 | ret = connect_viewer("localhost"); | |
687 | ok(ret == 0, "Connect viewer to relayd"); | |
688 | ||
689 | ret = establish_connection(); | |
690 | ok(ret == 0, "Established connection and version check with %d.%d", | |
691 | VERSION_MAJOR, VERSION_MINOR); | |
692 | ||
693 | ret = list_sessions(&session_id); | |
694 | ok(ret > 0, "List sessions : %d session(s)", ret); | |
8674c9bf JG |
695 | if (ret < 0) { |
696 | goto end; | |
697 | } | |
1b368955 | 698 | |
25b50f8f JD |
699 | ret = create_viewer_session(); |
700 | ok(ret == 0, "Create viewer session"); | |
701 | ||
1b368955 | 702 | ret = attach_session(session_id); |
7409dd34 | 703 | ok(ret > 0, "Attach to session, %d stream(s) received", ret); |
1b368955 JD |
704 | |
705 | ret = get_metadata(); | |
706 | ok(ret > 0, "Get metadata, received %d bytes", ret); | |
707 | ||
708 | ret = get_next_index(); | |
709 | ok(ret == 0, "Get one index per stream"); | |
710 | ||
711 | ret = get_data_packet(first_packet_stream_id, first_packet_offset, | |
712 | first_packet_len); | |
10236918 | 713 | ok(ret == 0, |
1b368955 JD |
714 | "Get one data packet for stream %d, offset %d, len %d", |
715 | first_packet_stream_id, first_packet_offset, | |
716 | first_packet_len); | |
717 | ||
e22ba966 JD |
718 | ret = detach_viewer_session(session_id); |
719 | ok(ret == 0, "Detach viewer session"); | |
720 | ||
721 | ret = list_sessions(&session_id); | |
722 | ok(ret > 0, "List sessions : %d session(s)", ret); | |
723 | ||
724 | ret = attach_session(session_id); | |
725 | ok(ret > 0, "Attach to session, %d streams received", ret); | |
8674c9bf | 726 | end: |
1b368955 JD |
727 | return exit_status(); |
728 | } |