master
c 1,297 lines 51.9 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "stream.h"
4 #include "stream-thread.h"
5 #include "stream-receiver-internals.h"
6
7 #ifdef NETDATA_LOG_STREAM_RECEIVER
8 void stream_receiver_log_payload(struct receiver_state *rpt, const char *payload, STREAM_TRAFFIC_TYPE type __maybe_unused, bool inbound) {
9 if (!rpt || type != STREAM_TRAFFIC_TYPE_REPLICATION) return; // not a streaming parser
10
11 spinlock_lock(&rpt->log.spinlock);
12
13 if (!rpt->log.fp) {
14 char filename[FILENAME_MAX + 1];
15 snprintfz(
16 filename, FILENAME_MAX, "/tmp/stream-receiver-%s.txt", rpt->host ? rrdhost_hostname(rpt->host) : "unknown");
17
18 rpt->log.fp = fopen(filename, "w");
19
20 // Align first_call to wall clock time
21 clock_gettime(CLOCK_REALTIME, &rpt->log.first_call);
22 rpt->log.first_call.tv_nsec = 0; // Align to the start of the second
23 }
24
25 if (rpt->log.fp) {
26 struct timespec now;
27 clock_gettime(CLOCK_REALTIME, &now);
28
29 time_t elapsed_sec = now.tv_sec - rpt->log.first_call.tv_sec;
30 long elapsed_nsec = now.tv_nsec - rpt->log.first_call.tv_nsec;
31
32 if (elapsed_nsec < 0) {
33 elapsed_sec--;
34 elapsed_nsec += 1000000000;
35 }
36
37 uint16_t days = elapsed_sec / 86400;
38 uint8_t hours = (elapsed_sec % 86400) / 3600;
39 uint8_t minutes = (elapsed_sec % 3600) / 60;
40 uint8_t seconds = elapsed_sec % 60;
41 uint16_t milliseconds = elapsed_nsec / 1000000;
42
43 char prefix[30];
44 snprintf(prefix, sizeof(prefix), "%03ud.%02u:%02u:%02u.%03u ",
45 days, hours, minutes, seconds, milliseconds);
46
47 const char *line_start = payload;
48 const char *line_end;
49
50 while (line_start && *line_start) {
51 line_end = strchr(line_start, '\n');
52 if (line_end) {
53 fprintf(rpt->log.fp, "%s%s%.*s\n", prefix, inbound ? "> " : "< ", (int)(line_end - line_start), line_start);
54 line_start = line_end + 1;
55 } else {
56 fprintf(rpt->log.fp, "%s%s%s\n", prefix, inbound ? "> " : "< ", line_start);
57 break;
58 }
59 }
60 }
61
62 fflush(rpt->log.fp);
63 spinlock_unlock(&rpt->log.spinlock);
64 }
65 #endif
66
67 // help the IDE identify use after free
68 #define stream_receiver_remove(sth, rpt, reason) do { \
69 stream_receiver_remove_internal(sth, rpt, reason); \
70 (rpt) = NULL; \
71 } while(0)
72
73 static void stream_receiver_remove_internal(struct stream_thread *sth, struct receiver_state *rpt, STREAM_HANDSHAKE reason);
74
75 // When a child disconnects this is the maximum we will wait
76 // before we update the cloud that the child is offline
77 #define MAX_CHILD_DISC_DELAY (30000)
78 #define MAX_CHILD_DISC_TOLERANCE (125 / 100)
79
80 static uint32_t streaming_connected_receivers = 0;
81
82 bool plugin_is_enabled(struct plugind *cd);
83
84 uint32_t stream_receivers_currently_connected(void) {
85 return __atomic_load_n(&streaming_connected_receivers, __ATOMIC_RELAXED);
86 }
87
88 static void streaming_receiver_connected(void) {
89 __atomic_add_fetch(&streaming_connected_receivers, 1, __ATOMIC_RELAXED);
90 }
91
92 static void streaming_receiver_disconnected(void) {
93 __atomic_sub_fetch(&streaming_connected_receivers, 1, __ATOMIC_RELAXED);
94 }
95
96 // --------------------------------------------------------------------------------------------------------------------
97
98 static bool stream_receiver_log_capabilities(BUFFER *wb, void *ptr) {
99 struct receiver_state *rpt = ptr;
100 if(!rpt)
101 return false;
102
103 stream_capabilities_to_string(wb, rpt->capabilities);
104 return true;
105 }
106
107 static bool stream_receiver_log_transport(BUFFER *wb, void *ptr) {
108 struct receiver_state *rpt = ptr;
109 if(!rpt)
110 return false;
111
112 buffer_strcat(wb, nd_sock_is_ssl(&rpt->sock) ? "https" : "http");
113 return true;
114 }
115
116 // --------------------------------------------------------------------------------------------------------------------
117
118 ALWAYS_INLINE
119 static ssize_t write_stream(struct receiver_state *r, char* buffer, size_t size) {
120 if(unlikely(!size)) {
121 internal_error(true, "%s() asked to read zero bytes", __FUNCTION__);
122 errno_clear();
123 return -2;
124 }
125
126 ssize_t bytes_written = nd_sock_send_nowait(&r->sock, buffer, size);
127 return bytes_written;
128 }
129
130 ALWAYS_INLINE
131 static ssize_t read_stream(struct receiver_state *r, char* buffer, size_t size) {
132 if(unlikely(!size)) {
133 internal_error(true, "%s() asked to read zero bytes", __FUNCTION__);
134 errno_clear();
135 return -2;
136 }
137
138 ssize_t bytes_read = nd_sock_revc_nowait(&r->sock, buffer, size);
139 return bytes_read;
140 }
141
142 // --------------------------------------------------------------------------------------------------------------------
143
144 ALWAYS_INLINE
145 static ssize_t receiver_read_uncompressed(struct receiver_state *r) {
146 internal_fatal(r->thread.uncompressed.read_buffer[r->thread.uncompressed.read_len] != '\0',
147 "%s: read_buffer does not start with zero #2", __FUNCTION__ );
148
149 ssize_t bytes = read_stream(r, r->thread.uncompressed.read_buffer + r->thread.uncompressed.read_len, sizeof(r->thread.uncompressed.read_buffer) - r->thread.uncompressed.read_len - 1);
150 if(bytes > 0) {
151 worker_set_metric(WORKER_RECEIVER_JOB_BYTES_READ, (NETDATA_DOUBLE)bytes);
152 worker_set_metric(WORKER_RECEIVER_JOB_BYTES_UNCOMPRESSED, (NETDATA_DOUBLE)bytes);
153
154 r->thread.uncompressed.read_len += bytes;
155 r->thread.uncompressed.read_buffer[r->thread.uncompressed.read_len] = '\0';
156 pulse_stream_received_bytes(bytes);
157 }
158
159 return bytes;
160 }
161
162 typedef enum {
163 DECOMPRESS_NEED_MORE_DATA,
164 DECOMPRESS_FAILED,
165 DECOMPRESS_OK,
166 } decompressor_status_t;
167
168 static inline void receiver_move_compressed(struct receiver_state *r) {
169 size_t remaining = r->thread.compressed.used - r->thread.compressed.start;
170 if(remaining > 0) {
171 memmove(r->thread.compressed.buf, r->thread.compressed.buf + r->thread.compressed.start, remaining);
172 r->thread.compressed.start = 0;
173 r->thread.compressed.used = remaining;
174 }
175 else {
176 r->thread.compressed.start = 0;
177 r->thread.compressed.used = 0;
178 }
179 }
180
181 ALWAYS_INLINE_HOT_FLATTEN
182 static decompressor_status_t receiver_feed_decompressor(struct receiver_state *r) {
183 char *buf = r->thread.compressed.buf;
184 size_t start = r->thread.compressed.start;
185 size_t signature_size = r->thread.compressed.decompressor.signature_size;
186 size_t used = r->thread.compressed.used;
187
188 if(start + signature_size > used) {
189 // incomplete header, we need to wait for more data
190 receiver_move_compressed(r);
191 return DECOMPRESS_NEED_MORE_DATA;
192 }
193
194 size_t compressed_message_size =
195 stream_decompressor_start(&r->thread.compressed.decompressor, buf + start, signature_size);
196
197 if (unlikely(!compressed_message_size)) {
198 nd_log(NDLS_DAEMON, NDLP_ERR,
199 "STREAM RCV[x] '%s' [from [%s]:%s]: multiplexed uncompressed data in compressed stream!",
200 rrdhost_hostname(r->host), r->remote_ip, r->remote_port);
201 return DECOMPRESS_FAILED;
202 }
203
204 if(unlikely(compressed_message_size > COMPRESSION_MAX_MSG_SIZE)) {
205 nd_log(NDLS_DAEMON, NDLP_ERR,
206 "STREAM RCV[x] '%s' [from [%s]:%s]: received a compressed message of %zu bytes, "
207 "which is bigger than the max compressed message "
208 "size supported of %zu. Ignoring message.",
209 rrdhost_hostname(r->host), r->remote_ip, r->remote_port,
210 compressed_message_size, (size_t)COMPRESSION_MAX_MSG_SIZE);
211 return DECOMPRESS_FAILED;
212 }
213
214 if(start + signature_size + compressed_message_size > used) {
215 // incomplete compressed message, we need to wait for more data
216 receiver_move_compressed(r);
217 return DECOMPRESS_NEED_MORE_DATA;
218 }
219
220 size_t bytes_to_parse =
221 stream_decompress(&r->thread.compressed.decompressor, buf + start + signature_size, compressed_message_size);
222
223 if (unlikely(!bytes_to_parse)) {
224 nd_log(NDLS_DAEMON, NDLP_ERR,
225 "STREAM RCV[x] '%s' [from [%s]:%s]: no bytes to decompress.",
226 rrdhost_hostname(r->host), r->remote_ip, r->remote_port);
227 return DECOMPRESS_FAILED;
228 }
229
230 worker_set_metric(WORKER_RECEIVER_JOB_BYTES_UNCOMPRESSED, (NETDATA_DOUBLE)bytes_to_parse);
231
232 // move the header to the next message
233 r->thread.compressed.start += signature_size + compressed_message_size;
234
235 return DECOMPRESS_OK;
236 }
237
238 ALWAYS_INLINE_HOT_FLATTEN
239 static decompressor_status_t receiver_get_decompressed(struct receiver_state *r) {
240 if (unlikely(!stream_decompressed_bytes_in_buffer(&r->thread.compressed.decompressor)))
241 return DECOMPRESS_NEED_MORE_DATA;
242
243 size_t available = sizeof(r->thread.uncompressed.read_buffer) - r->thread.uncompressed.read_len - 1;
244 if (likely(available)) {
245 size_t len = stream_decompressor_get(
246 &r->thread.compressed.decompressor, r->thread.uncompressed.read_buffer + r->thread.uncompressed.read_len, available);
247 if (unlikely(!len)) {
248 internal_error(true, "decompressor returned zero length #1");
249 return DECOMPRESS_FAILED;
250 }
251
252 r->thread.uncompressed.read_len += (int)len;
253 r->thread.uncompressed.read_buffer[r->thread.uncompressed.read_len] = '\0';
254 }
255 else {
256 internal_fatal(true, "The line to read is too big! Already have %zd bytes in read_buffer.", r->thread.uncompressed.read_len);
257 return DECOMPRESS_FAILED;
258 }
259
260 return DECOMPRESS_OK;
261 }
262
263 ALWAYS_INLINE_HOT_FLATTEN
264 static ssize_t receiver_read_compressed(struct receiver_state *r) {
265
266 internal_fatal(r->thread.uncompressed.read_buffer[r->thread.uncompressed.read_len] != '\0',
267 "%s: read_buffer does not start with zero #2", __FUNCTION__ );
268
269 ssize_t bytes = read_stream(r, r->thread.compressed.buf + r->thread.compressed.used,
270 r->thread.compressed.size - r->thread.compressed.used);
271
272 if(bytes > 0) {
273 r->thread.compressed.used += bytes;
274 worker_set_metric(WORKER_RECEIVER_JOB_BYTES_READ, (NETDATA_DOUBLE)bytes);
275 pulse_stream_received_bytes(bytes);
276 }
277
278 return bytes;
279 }
280
281 // --------------------------------------------------------------------------------------------------------------------
282
283 static STREAM_HANDSHAKE receiver_set_exit_reason(struct receiver_state *rpt, STREAM_HANDSHAKE reason, bool force) {
284 if(force || !rpt->exit.reason)
285 rpt->exit.reason = reason;
286
287 return rpt->exit.reason;
288 }
289
290 ALWAYS_INLINE
291 static bool receiver_should_stop(struct receiver_state *rpt) {
292 if(unlikely(__atomic_load_n(&rpt->exit.shutdown, __ATOMIC_ACQUIRE))) {
293 receiver_set_exit_reason(rpt, STREAM_HANDSHAKE_DISCONNECT_SIGNALED_TO_STOP, false);
294 return true;
295 }
296
297 return false;
298 }
299
300 // --------------------------------------------------------------------------------------------------------------------
301
302 ALWAYS_INLINE
303 void stream_receiver_handle_op(struct stream_thread *sth, struct receiver_state *rpt, struct stream_opcode *msg) {
304 ND_LOG_STACK lgs[] = {
305 ND_LOG_FIELD_STR(NDF_NIDL_NODE, rpt->host->hostname),
306 ND_LOG_FIELD_TXT(NDF_SRC_IP, rpt->remote_ip),
307 ND_LOG_FIELD_TXT(NDF_SRC_PORT, rpt->remote_port),
308 ND_LOG_FIELD_CB(NDF_SRC_TRANSPORT, stream_receiver_log_transport, rpt),
309 ND_LOG_FIELD_CB(NDF_SRC_CAPABILITIES, stream_receiver_log_capabilities, rpt),
310 ND_LOG_FIELD_END(),
311 };
312 ND_LOG_STACK_PUSH(lgs);
313
314 if(msg->opcode & STREAM_OPCODE_RECEIVER_BUFFER_OVERFLOW) {
315 worker_is_busy(WORKER_SENDER_JOB_DISCONNECT_OVERFLOW);
316 errno_clear();
317 spinlock_lock(&rpt->thread.send_to_child.spinlock);
318 // copy the statistics
319 STREAM_CIRCULAR_BUFFER_STATS stats = *stream_circular_buffer_stats_unsafe(rpt->thread.send_to_child.scb);
320 spinlock_unlock(&rpt->thread.send_to_child.spinlock);
321 nd_log(NDLS_DAEMON, NDLP_ERR,
322 "STREAM RCV[%zu] '%s' [from [%s]:%s]: send buffer is full (buffer size %u, max %u, used %u, available %u). "
323 "Restarting connection.",
324 sth->id, rrdhost_hostname(rpt->host), rpt->remote_ip, rpt->remote_port,
325 stats.bytes_size, stats.bytes_max_size, stats.bytes_outstanding, stats.bytes_available);
326
327 stream_receiver_remove(sth, rpt, STREAM_HANDSHAKE_DISCONNECT_BUFFER_OVERFLOW);
328 return;
329 }
330
331 nd_log(NDLS_DAEMON, NDLP_ERR,
332 "STREAM RCV[%zu]: invalid msg id %u", sth->id, (unsigned)msg->opcode);
333 }
334
335 static ssize_t send_to_child(const char *txt, void *data, STREAM_TRAFFIC_TYPE type) {
336 struct receiver_state *rpt = data;
337 if(!rpt || rpt->thread.meta.type != POLLFD_TYPE_RECEIVER || !rpt->thread.send_to_child.scb)
338 return 0;
339
340 spinlock_lock(&rpt->thread.send_to_child.spinlock);
341 STREAM_CIRCULAR_BUFFER *scb = rpt->thread.send_to_child.scb;
342 STREAM_CIRCULAR_BUFFER_STATS *stats = stream_circular_buffer_stats_unsafe(scb);
343 bool was_empty = stats->bytes_outstanding == 0;
344 struct stream_opcode msg = rpt->thread.send_to_child.msg;
345 msg.opcode = STREAM_OPCODE_NONE;
346 msg.reason = 0;
347
348 size_t size = strlen(txt);
349 ssize_t rc = (ssize_t)size;
350 if(!stream_circular_buffer_add_unsafe(scb, txt, size, size, type, true)) {
351 // should never happen, because of autoscaling
352 msg.opcode = STREAM_OPCODE_RECEIVER_BUFFER_OVERFLOW;
353 msg.reason = STREAM_HANDSHAKE_DISCONNECT_BUFFER_OVERFLOW;
354 rc = -1;
355 }
356 else {
357 stream_receiver_log_payload(rpt, txt, type, false);
358
359 if(was_empty) {
360 msg.opcode = STREAM_OPCODE_RECEIVER_POLLOUT;
361 msg.reason = 0;
362 }
363 }
364
365 spinlock_unlock(&rpt->thread.send_to_child.spinlock);
366
367 if(msg.opcode != STREAM_OPCODE_NONE)
368 stream_receiver_send_opcode(rpt, msg);
369
370 return rc;
371 }
372
373 // --------------------------------------------------------------------------------------------------------------------
374
375 void stream_receiver_move_to_running_unsafe(struct stream_thread *sth, struct receiver_state *rpt) {
376 internal_fatal(sth->tid != gettid_cached(), "Function %s() should only be used by the dispatcher thread", __FUNCTION__ );
377
378 worker_is_busy(WORKER_STREAM_JOB_DEQUEUE);
379
380 ND_LOG_STACK lgs[] = {
381 ND_LOG_FIELD_STR(NDF_NIDL_NODE, rpt->host->hostname),
382 ND_LOG_FIELD_UUID(NDF_MESSAGE_ID, &streaming_from_child_msgid),
383 ND_LOG_FIELD_END(),
384 };
385 ND_LOG_STACK_PUSH(lgs);
386
387 nd_log(NDLS_DAEMON, NDLP_DEBUG,
388 "STREAM RCV[%zu] '%s' [from [%s]:%s]: moving host from receiver queue to receiver running...",
389 sth->id, rrdhost_hostname(rpt->host), rpt->remote_ip, rpt->remote_port);
390
391 sock_setcloexec(rpt->sock.fd, true);
392 sock_enlarge_rcv_buf(rpt->sock.fd);
393 sock_enlarge_snd_buf(rpt->sock.fd);
394 sock_setcork(rpt->sock.fd, false);
395 if(sock_setnonblock(rpt->sock.fd, true) != 1)
396 nd_log(NDLS_DAEMON, NDLP_ERR,
397 "STREAM RCV '%s' [from [%s]:%s]: failed to set non-blocking mode on socket %d",
398 rrdhost_hostname(rpt->host), rpt->remote_ip, rpt->remote_port, rpt->sock.fd);
399
400 __atomic_store_n(&rpt->host->stream.rcv.status.tid, gettid_cached(), __ATOMIC_RELAXED);
401 rpt->thread.meta.type = POLLFD_TYPE_RECEIVER;
402 rpt->thread.meta.rpt = rpt;
403
404 spinlock_lock(&rpt->thread.send_to_child.spinlock);
405 rpt->thread.send_to_child.scb = stream_circular_buffer_create();
406 rpt->thread.send_to_child.msg.thread_slot = (int32_t)sth->id;
407 rpt->thread.send_to_child.msg.session = os_random32();
408 rpt->thread.send_to_child.msg.meta = &rpt->thread.meta;
409 spinlock_unlock(&rpt->thread.send_to_child.spinlock);
410
411 internal_fatal(META_GET(&sth->run.meta, (Word_t)&rpt->thread.meta) != NULL, "Receiver to be added is already in the list of receivers");
412 META_SET(&sth->run.meta, (Word_t)&rpt->thread.meta, &rpt->thread.meta);
413
414 rpt->thread.wanted = ND_POLL_READ;
415 if(!nd_poll_add(sth->run.ndpl, rpt->sock.fd, rpt->thread.wanted, &rpt->thread.meta))
416 nd_log(NDLS_DAEMON, NDLP_ERR,
417 "STREAM RCV[%zu] '%s' [from [%s]:%s]:"
418 "Failed to add receiver socket to nd_poll()",
419 sth->id, rrdhost_hostname(rpt->host), rpt->remote_ip, rpt->remote_port);
420
421 rpt->thread.compressed.start = 0;
422 rpt->thread.compressed.used = 0;
423 rpt->thread.compressed.enabled = stream_decompression_initialize(rpt);
424 buffered_reader_init(&rpt->thread.uncompressed);
425
426 rpt->thread.line_buffer = buffer_create(sizeof(rpt->thread.uncompressed.read_buffer), NULL);
427
428 // help preferred_sender_buffer() select the right buffer
429 rpt->host->stream.snd.commit.receiver_tid = gettid_cached();
430
431 rpt->replication.last_progress_ut = now_monotonic_usec();
432
433 PARSER *parser = NULL;
434 {
435 char buf[CONFIG_MAX_NAME];
436 snprintfz(buf, sizeof(buf), "[%s]:%s", rpt->remote_ip, rpt->remote_port);
437 string_freez(rpt->thread.cd.id);
438 rpt->thread.cd.id = string_strdupz(buf);
439
440 string_freez(rpt->thread.cd.filename);
441 rpt->thread.cd.filename = NULL;
442
443 string_freez(rpt->thread.cd.fullfilename);
444 rpt->thread.cd.fullfilename = NULL;
445
446 string_freez(rpt->thread.cd.cmd);
447 rpt->thread.cd.cmd = NULL;
448
449 rpt->thread.cd.update_every = (int)nd_profile.update_every;
450 spinlock_init(&rpt->thread.cd.unsafe.spinlock);
451 rpt->thread.cd.unsafe.running = true;
452 rpt->thread.cd.unsafe.enabled = true;
453 rpt->thread.cd.started_t = now_realtime_sec();
454
455 PARSER_USER_OBJECT user = {
456 .enabled = plugin_is_enabled(&rpt->thread.cd),
457 .host = rpt->host,
458 .opaque = rpt,
459 .cd = &rpt->thread.cd,
460 .trust_durations = 1,
461 .capabilities = rpt->capabilities,
462 #ifdef NETDATA_LOG_STREAM_RECEIVER
463 .rpt = rpt,
464 #endif
465 };
466
467 parser = parser_init(&user, -1, -1, PARSER_INPUT_SPLIT, &rpt->sock);
468 parser->send_to_plugin_data = rpt;
469 parser->send_to_plugin_cb = send_to_child;
470
471 pluginsd_keywords_init(parser, PARSER_INIT_STREAMING);
472
473 __atomic_store_n(&rpt->thread.parser, parser, __ATOMIC_RELAXED);
474 }
475
476 if(stream_receive.replication.enabled)
477 pulse_host_status(rpt->host, PULSE_HOST_STATUS_RCV_REPLICATION_WAIT, 0);
478 else
479 pulse_host_status(rpt->host, PULSE_HOST_STATUS_RCV_RUNNING, 0);
480
481 // keep this last - it needs everything ready since to sends data to the child
482 stream_receiver_send_node_and_claim_id_to_child(rpt->host);
483 }
484
485 void stream_receiver_move_entire_queue_to_running_unsafe(struct stream_thread *sth) {
486 internal_fatal(sth->tid != gettid_cached(), "Function %s() should only be used by the dispatcher thread", __FUNCTION__ );
487
488 // process the queue
489 Word_t idx = 0;
490 for(struct receiver_state *rpt = RECEIVERS_FIRST(&sth->queue.receivers, &idx);
491 rpt;
492 rpt = RECEIVERS_NEXT(&sth->queue.receivers, &idx)) {
493 RECEIVERS_DEL(&sth->queue.receivers, idx);
494 stream_receiver_move_to_running_unsafe(sth, rpt);
495 }
496 }
497
498 static void stream_receiver_remove_internal(struct stream_thread *sth, struct receiver_state *rpt, STREAM_HANDSHAKE reason) {
499 internal_fatal(sth->tid != gettid_cached(), "Function %s() should only be used by the dispatcher thread", __FUNCTION__ );
500
501 receiver_set_exit_reason(rpt, reason, false);
502
503 ND_LOG_STACK lgs[] = {
504 ND_LOG_FIELD_STR(NDF_NIDL_NODE, rpt->host->hostname),
505 ND_LOG_FIELD_TXT(NDF_SRC_IP, rpt->remote_ip),
506 ND_LOG_FIELD_TXT(NDF_SRC_PORT, rpt->remote_port),
507 ND_LOG_FIELD_CB(NDF_SRC_TRANSPORT, stream_receiver_log_transport, rpt),
508 ND_LOG_FIELD_CB(NDF_SRC_CAPABILITIES, stream_receiver_log_capabilities, rpt),
509 ND_LOG_FIELD_UUID(NDF_MESSAGE_ID, &streaming_from_child_msgid),
510 ND_LOG_FIELD_END(),
511 };
512 ND_LOG_STACK_PUSH(lgs);
513
514 PARSER *parser = __atomic_load_n(&rpt->thread.parser, __ATOMIC_RELAXED);
515 size_t count = 0;
516 if(parser)
517 count = parser->user.data_collections_count;
518
519 errno_clear();
520 nd_log(NDLS_DAEMON, NDLP_ERR,
521 "STREAM RCV[%zu] '%s' [from [%s]:%s]: "
522 "receiver disconnected (after %zu received messages): %s"
523 , sth->id
524 , rpt->hostname ? rpt->hostname : "-"
525 , rpt->remote_ip ? rpt->remote_ip : "-"
526 , rpt->remote_port ? rpt->remote_port : "-"
527 , count
528 , stream_handshake_error_to_string(reason));
529
530 internal_fatal(META_GET(&sth->run.meta, (Word_t)&rpt->thread.meta) == NULL,
531 "Receiver to be removed is not found in the list of receivers");
532
533 META_DEL(&sth->run.meta, (Word_t)&rpt->thread.meta);
534
535 rpt->thread.wanted = 0;
536 if(!nd_poll_del(sth->run.ndpl, rpt->sock.fd))
537 nd_log(NDLS_DAEMON, NDLP_ERR, "Failed to delete receiver socket from nd_poll()");
538
539 __atomic_store_n(&rpt->host->stream.rcv.status.tid, 0, __ATOMIC_RELAXED);
540
541 // make sure send_to_plugin() will not write any data to the socket (or wait for it to finish)
542 if(parser) {
543 spinlock_lock(&parser->writer.spinlock);
544 parser->fd_input = -1;
545 parser->fd_output = -1;
546 parser->sock = NULL;
547 spinlock_unlock(&parser->writer.spinlock);
548
549 parser->user.v2.stream_buffer.wb = NULL;
550 }
551
552 stream_thread_node_removed(rpt->host);
553 pulse_host_status(rpt->host, PULSE_HOST_STATUS_RCV_OFFLINE, reason);
554
555 // set a default exit reason, if not set
556 receiver_set_exit_reason(rpt, reason, false);
557
558 // in case we are connected to netdata cloud,
559 // we inform cloud that a child got disconnected
560 uint64_t total_reboot = rrdhost_stream_path_total_reboot_time_ms(rpt->host);
561 schedule_node_state_update(rpt->host, MIN((total_reboot * MAX_CHILD_DISC_TOLERANCE), MAX_CHILD_DISC_DELAY));
562
563 rrdhost_clear_receiver(rpt, reason);
564 rrdhost_set_is_parent_label();
565
566 stream_receiver_free(rpt);
567 // DO NOT USE rpt after this point
568 }
569
570 static bool stream_receiver_dequeue_senders(struct stream_thread *sth, struct receiver_state *rpt, usec_t now_ut) {
571 internal_fatal(sth->tid != gettid_cached(), "Function %s() should only be used by the dispatcher thread", __FUNCTION__);
572
573 // re-check if we need to send data after reading - if we do, try now
574 if(rpt->thread.wanted & ND_POLL_WRITE) {
575 worker_is_busy(WORKER_STREAM_JOB_SOCKET_SEND);
576 if(!stream_receiver_send_data(sth, rpt, now_ut, false))
577 return false;
578 }
579
580 if(rpt->host->sender && // the host has a sender
581 rpt->host->stream.snd.status.tid == gettid_cached() && // the sender is mine
582 (rpt->host->sender->thread.wanted & ND_POLL_WRITE)) { // the sender needs to send data
583 // we return true even if this fais,
584 // so that we will not disconnect the receiver because the sender failed
585 stream_sender_send_data(sth, rpt->host->sender, now_ut, false);
586 }
587
588 return true;
589 }
590
591 static ssize_t
592 stream_receive_and_process(struct stream_thread *sth, struct receiver_state *rpt, PARSER *parser, usec_t now_ut __maybe_unused, bool *removed) {
593 internal_fatal(sth->tid != gettid_cached(), "Function %s() should only be used by the dispatcher thread", __FUNCTION__);
594 *removed = false;
595
596 ssize_t rc;
597 if(rpt->thread.compressed.enabled) {
598 rc = receiver_read_compressed(rpt);
599 if(unlikely(rc <= 0))
600 return rc;
601
602 while(!nd_thread_signaled_to_cancel() && service_running(SERVICE_STREAMING) && !receiver_should_stop(rpt)) {
603 worker_is_busy(WORKER_STREAM_JOB_DECOMPRESS);
604
605 // feed the decompressor with the new data we just read
606 decompressor_status_t feed_rc = receiver_feed_decompressor(rpt);
607
608 if(likely(feed_rc == DECOMPRESS_OK)) {
609 while (true) {
610 // feed our uncompressed data buffer with new data
611 decompressor_status_t decompress_rc = receiver_get_decompressed(rpt);
612
613 if (likely(decompress_rc == DECOMPRESS_OK)) {
614 // loop through all the complete lines found in the uncompressed buffer
615
616 while (buffered_reader_next_line(&rpt->thread.uncompressed, rpt->thread.line_buffer)) {
617 if (unlikely(parser_action(parser, rpt->thread.line_buffer->buffer))) {
618 stream_receiver_remove(sth, rpt, STREAM_HANDSHAKE_RCV_DISCONNECT_PARSER_FAILED);
619 *removed = true;
620 return -1;
621 }
622
623 rpt->thread.line_buffer->len = 0;
624 rpt->thread.line_buffer->buffer[0] = '\0';
625 }
626 }
627 else if (decompress_rc == DECOMPRESS_NEED_MORE_DATA)
628 break;
629
630 else {
631 stream_receiver_remove(sth, rpt, STREAM_HANDSHAKE_RCV_DECOMPRESSION_FAILED);
632 *removed = true;
633 return -1;
634 }
635 }
636 }
637 else if (feed_rc == DECOMPRESS_NEED_MORE_DATA)
638 break;
639 else {
640 stream_receiver_remove(sth, rpt, STREAM_HANDSHAKE_RCV_DECOMPRESSION_FAILED);
641 *removed = true;
642 return -1;
643 }
644 }
645
646 if(receiver_should_stop(rpt)) {
647 stream_receiver_remove(sth, rpt, STREAM_HANDSHAKE_DISCONNECT_SIGNALED_TO_STOP);
648 *removed = true;
649 return -1;
650 }
651 }
652 else {
653 rc = receiver_read_uncompressed(rpt);
654 if(rc <= 0)
655 return rc;
656
657 while(buffered_reader_next_line(&rpt->thread.uncompressed, rpt->thread.line_buffer)) {
658 if(unlikely(parser_action(parser, rpt->thread.line_buffer->buffer))) {
659 stream_receiver_remove(sth, rpt, STREAM_HANDSHAKE_RCV_DISCONNECT_PARSER_FAILED);
660 *removed = true;
661 return -1;
662 }
663
664 rpt->thread.line_buffer->len = 0;
665 rpt->thread.line_buffer->buffer[0] = '\0';
666 }
667 }
668
669 return rc;
670 }
671
672 bool stream_receiver_send_data(struct stream_thread *sth, struct receiver_state *rpt, usec_t now_ut, bool process_opcodes_and_enable_removal) {
673 internal_fatal(sth->tid != gettid_cached(), "Function %s() should only be used by the dispatcher thread", __FUNCTION__ );
674
675 EVLOOP_STATUS status = EVLOOP_STATUS_CONTINUE;
676 while(status == EVLOOP_STATUS_CONTINUE) {
677 if (!spinlock_trylock(&rpt->thread.send_to_child.spinlock)) {
678 status = EVLOOP_STATUS_CANT_GET_LOCK;
679 break;
680 }
681
682 char *chunk;
683 STREAM_CIRCULAR_BUFFER *scb = rpt->thread.send_to_child.scb;
684 STREAM_CIRCULAR_BUFFER_STATS *stats = stream_circular_buffer_stats_unsafe(scb);
685 size_t outstanding = stream_circular_buffer_get_unsafe(scb, &chunk);
686
687 if(!outstanding) {
688 status = EVLOOP_STATUS_NO_MORE_DATA;
689 spinlock_unlock(&rpt->thread.send_to_child.spinlock);
690 continue;
691 }
692
693 ssize_t rc = write_stream(rpt, chunk, outstanding);
694 if (likely(rc > 0)) {
695 pulse_stream_sent_bytes(rc);
696 rpt->thread.last_traffic_ut = now_ut;
697 stream_circular_buffer_del_unsafe(scb, rc, now_ut);
698 if (!stats->bytes_outstanding) {
699 rpt->thread.wanted = ND_POLL_READ;
700 if (!nd_poll_upd(sth->run.ndpl, rpt->sock.fd, rpt->thread.wanted))
701 nd_log(NDLS_DAEMON, NDLP_ERR,
702 "STREAM RCV[%zu] '%s' [from [%s]:%s]: cannot update nd_poll()",
703 sth->id, rrdhost_hostname(rpt->host), rpt->remote_ip, rpt->remote_port);
704
705 // recreate the circular buffer if we have to
706 stream_circular_buffer_recreate_timed_unsafe(rpt->thread.send_to_child.scb, now_ut, false);
707 status = EVLOOP_STATUS_NO_MORE_DATA;
708 }
709 }
710 else if (rc == 0 || errno == ECONNRESET)
711 status = EVLOOP_STATUS_SOCKET_CLOSED;
712
713 else if (rc < 0) {
714 if (errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR)
715 status = EVLOOP_STATUS_SOCKET_FULL;
716 else
717 status = EVLOOP_STATUS_SOCKET_ERROR;
718 }
719
720 spinlock_unlock(&rpt->thread.send_to_child.spinlock);
721
722 if (status == EVLOOP_STATUS_SOCKET_ERROR || status == EVLOOP_STATUS_SOCKET_CLOSED) {
723 STREAM_HANDSHAKE reason;
724
725 if(status == EVLOOP_STATUS_SOCKET_ERROR) {
726 worker_is_busy(WORKER_STREAM_JOB_DISCONNECT_SEND_ERROR);
727 reason = STREAM_HANDSHAKE_DISCONNECT_SOCKET_WRITE_FAILED;
728 }
729 else /* if(status == EVLOOP_STATUS_SOCKET_CLOSED) */ {
730 worker_is_busy(WORKER_STREAM_JOB_DISCONNECT_REMOTE_CLOSED);
731 reason = STREAM_HANDSHAKE_DISCONNECT_SOCKET_CLOSED_BY_REMOTE;
732 }
733
734 nd_log(NDLS_DAEMON, NDLP_ERR,
735 "STREAM RCV[%zu] '%s' [from [%s]:%s]: %s (%zd, on fd %d) - closing receiver connection - "
736 "we have sent %zu bytes in %zu operations.",
737 sth->id, rrdhost_hostname(rpt->host), rpt->remote_ip, rpt->remote_port,
738 stream_handshake_error_to_string(reason), rc, rpt->sock.fd, stats->bytes_sent, stats->sends);
739
740 if(process_opcodes_and_enable_removal) {
741 // this is not executed from the opcode handling mechanism
742 // so we can safely remove the receiver.
743 stream_receiver_remove(sth, rpt, reason);
744 }
745 else {
746 receiver_set_exit_reason(rpt, reason, false);
747
748 // protection against this case:
749 //
750 // 1. receiver gets a replication request
751 // 2. parser processes the request
752 // 3. parser decides to send back a message to the child (REPLAY_CHART)
753 // 4. send_to_child appends the data to the sending circular buffer
754 // 5. send_to_child sends opcode to enable sending
755 // 6. opcode bypasses the signal and runs this function inline to dispatch immediately
756 // 7. sending fails (child disconnected)
757 // 8. receiver is removed
758 //
759 // Point 2 above crashes. The parser is no longer there (freed at point 7)
760 // and there is no way for point 2 to know...
761 }
762 }
763 else if(process_opcodes_and_enable_removal &&
764 status == EVLOOP_STATUS_CONTINUE &&
765 stream_thread_process_opcodes(sth, &rpt->thread.meta))
766 status = EVLOOP_STATUS_OPCODE_ON_ME;
767 }
768
769 return EVLOOP_STATUS_STILL_ALIVE(status);
770 }
771
772 bool stream_receiver_receive_data(struct stream_thread *sth, struct receiver_state *rpt, usec_t now_ut, bool process_opcodes) {
773 internal_fatal(sth->tid != gettid_cached(), "Function %s() should only be used by the dispatcher thread", __FUNCTION__ );
774
775 PARSER *parser = __atomic_load_n(&rpt->thread.parser, __ATOMIC_RELAXED);
776 ND_LOG_STACK lgs[] = {
777 ND_LOG_FIELD_CB(NDF_REQUEST, line_splitter_reconstruct_line, &parser->line),
778 ND_LOG_FIELD_CB(NDF_NIDL_NODE, parser_reconstruct_node, parser),
779 ND_LOG_FIELD_CB(NDF_NIDL_INSTANCE, parser_reconstruct_instance, parser),
780 ND_LOG_FIELD_CB(NDF_NIDL_CONTEXT, parser_reconstruct_context, parser),
781 ND_LOG_FIELD_END(),
782 };
783 ND_LOG_STACK_PUSH(lgs);
784
785 size_t count = 1; // how many reads to do per host, before moving to the next host
786 EVLOOP_STATUS status = EVLOOP_STATUS_CONTINUE;
787 while(status == EVLOOP_STATUS_CONTINUE && count-- > 0) {
788 bool removed = false;
789 ssize_t rc = stream_receive_and_process(sth, rpt, parser, now_ut, &removed);
790 if(unlikely(removed))
791 status = EVLOOP_STATUS_PARSER_FAILED;
792
793 else if (likely(rc > 0)) {
794 rpt->thread.last_traffic_ut = now_ut;
795
796 if(!stream_receiver_dequeue_senders(sth, rpt, now_ut))
797 status = EVLOOP_STATUS_SOCKET_ERROR;
798 }
799 else if (rc == 0 || errno == ECONNRESET) {
800 status = EVLOOP_STATUS_SOCKET_CLOSED;
801 }
802 else if (rc < 0) {
803 if ((errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR))
804 status = EVLOOP_STATUS_SOCKET_FULL;
805 else
806 status = EVLOOP_STATUS_SOCKET_ERROR;
807 }
808
809 if(status == EVLOOP_STATUS_SOCKET_ERROR || status == EVLOOP_STATUS_SOCKET_CLOSED) {
810 STREAM_HANDSHAKE reason;
811
812 if(status == EVLOOP_STATUS_SOCKET_ERROR) {
813 worker_is_busy(WORKER_STREAM_JOB_DISCONNECT_RECEIVE_ERROR);
814 reason = STREAM_HANDSHAKE_DISCONNECT_SOCKET_READ_FAILED;
815 }
816 else /* if(status == EVLOOP_STATUS_SOCKET_CLOSED) */ {
817 worker_is_busy(WORKER_STREAM_JOB_DISCONNECT_REMOTE_CLOSED);
818 reason = STREAM_HANDSHAKE_DISCONNECT_SOCKET_CLOSED_BY_REMOTE;
819 }
820
821 nd_log(NDLS_DAEMON, NDLP_ERR,
822 "STREAM RCV[%zu] '%s' [from [%s]:%s]: %s (fd %d) - closing receiver connection.",
823 sth->id, rrdhost_hostname(rpt->host), rpt->remote_ip, rpt->remote_port,
824 stream_handshake_error_to_string(reason), rpt->sock.fd);
825
826 stream_receiver_remove(sth, rpt, reason);
827 break;
828 }
829 else if(status == EVLOOP_STATUS_CONTINUE && process_opcodes && stream_thread_process_opcodes(sth, &rpt->thread.meta))
830 status = EVLOOP_STATUS_OPCODE_ON_ME;
831 }
832
833 return EVLOOP_STATUS_STILL_ALIVE(status);
834 }
835
836 // process poll() events for streaming receivers
837 // returns true when the receiver is still there, false if it removed it
838 bool stream_receive_process_poll_events(struct stream_thread *sth, struct receiver_state *rpt, nd_poll_event_t events, usec_t now_ut) {
839 internal_fatal(sth->tid != gettid_cached(), "Function %s() should only be used by the dispatcher thread", __FUNCTION__);
840
841 ND_LOG_STACK lgs[] = {
842 ND_LOG_FIELD_TXT(NDF_SRC_IP, rpt->remote_ip),
843 ND_LOG_FIELD_TXT(NDF_SRC_PORT, rpt->remote_port),
844 ND_LOG_FIELD_TXT(NDF_NIDL_NODE, rpt->hostname),
845 ND_LOG_FIELD_CB(NDF_SRC_TRANSPORT, stream_receiver_log_transport, rpt),
846 ND_LOG_FIELD_CB(NDF_SRC_CAPABILITIES, stream_receiver_log_capabilities, rpt),
847 ND_LOG_FIELD_END(),
848 };
849 ND_LOG_STACK_PUSH(lgs);
850
851 if (receiver_should_stop(rpt)) {
852 stream_receiver_remove(sth, rpt, STREAM_HANDSHAKE_DISCONNECT_SIGNALED_TO_STOP);
853 return false;
854 }
855
856 if (unlikely(events & (ND_POLL_ERROR | ND_POLL_HUP | ND_POLL_INVALID))) {
857 // we have errors on this socket
858
859 worker_is_busy(WORKER_STREAM_JOB_DISCONNECT_SOCKET_ERROR);
860
861 STREAM_HANDSHAKE reason = events & ND_POLL_HUP ? STREAM_HANDSHAKE_DISCONNECT_SOCKET_CLOSED_BY_REMOTE : STREAM_HANDSHAKE_DISCONNECT_SOCKET_ERROR;
862
863 nd_log(NDLS_DAEMON, NDLP_ERR,
864 "STREAM RCV[%zu] '%s' [from [%s]:%s]: %s - closing connection",
865 sth->id, rrdhost_hostname(rpt->host), rpt->remote_ip, rpt->remote_port,
866 stream_handshake_error_to_string(reason));
867
868 stream_receiver_remove(sth, rpt, reason);
869 return false;
870 }
871
872 if (events & ND_POLL_WRITE) {
873 worker_is_busy(WORKER_STREAM_JOB_SOCKET_SEND);
874 if(!stream_receiver_send_data(sth, rpt, now_ut, true))
875 return false;
876 }
877
878 if (events & ND_POLL_READ) {
879 worker_is_busy(WORKER_STREAM_JOB_SOCKET_RECEIVE);
880 if(!stream_receiver_receive_data(sth, rpt, now_ut, true))
881 return false;
882 }
883
884 return true;
885 }
886
887 void stream_receiver_check_all_nodes_from_poll(struct stream_thread *sth, usec_t now_ut) {
888 internal_fatal(sth->tid != gettid_cached(), "Function %s() should only be used by the dispatcher thread", __FUNCTION__ );
889
890 NETDATA_DOUBLE overall_buffer_ratio = 0.0;
891
892 Word_t idx = 0;
893 for(struct pollfd_meta *m = META_FIRST(&sth->run.meta, &idx);
894 m;
895 m = META_NEXT(&sth->run.meta, &idx)) {
896 if (m->type != POLLFD_TYPE_RECEIVER) continue;
897 struct receiver_state *rpt = m->rpt;
898
899 // Probe socket to detect dead connections (e.g., from TCP keepalive)
900 // Uses nd_sock_peek_nowait() which handles both SSL and plain TCP:
901 // - For SSL: uses SSL_peek() to avoid corrupting SSL state
902 // - For plain TCP: uses recv(MSG_PEEK | MSG_DONTWAIT)
903 char probe_byte;
904 ssize_t probe_rc = nd_sock_peek_nowait(&rpt->sock, &probe_byte, 1);
905 if (probe_rc == 0 || (probe_rc < 0 && errno == ECONNRESET)) {
906 // Connection closed by remote (gracefully or via reset)
907 ND_LOG_STACK lgs[] = {
908 ND_LOG_FIELD_TXT(NDF_SRC_IP, rpt->remote_ip),
909 ND_LOG_FIELD_TXT(NDF_SRC_PORT, rpt->remote_port),
910 ND_LOG_FIELD_TXT(NDF_NIDL_NODE, rpt->hostname),
911 ND_LOG_FIELD_CB(NDF_SRC_TRANSPORT, stream_receiver_log_transport, rpt),
912 ND_LOG_FIELD_CB(NDF_SRC_CAPABILITIES, stream_receiver_log_capabilities, rpt),
913 ND_LOG_FIELD_END(),
914 };
915 ND_LOG_STACK_PUSH(lgs);
916
917 worker_is_busy(WORKER_STREAM_JOB_DISCONNECT_REMOTE_CLOSED);
918 nd_log(NDLS_DAEMON, NDLP_ERR,
919 "STREAM RCV[%zu] '%s' [from %s]: socket closed by remote - closing connection",
920 sth->id, rrdhost_hostname(rpt->host), rpt->remote_ip);
921
922 stream_receiver_remove(sth, rpt, STREAM_HANDSHAKE_DISCONNECT_SOCKET_CLOSED_BY_REMOTE);
923 continue;
924 }
925 if (probe_rc < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
926 // Socket error detected (keepalive timeout, etc.)
927 // Save errno immediately as subsequent calls may modify it
928 int saved_errno = errno;
929
930 ND_LOG_STACK lgs[] = {
931 ND_LOG_FIELD_TXT(NDF_SRC_IP, rpt->remote_ip),
932 ND_LOG_FIELD_TXT(NDF_SRC_PORT, rpt->remote_port),
933 ND_LOG_FIELD_TXT(NDF_NIDL_NODE, rpt->hostname),
934 ND_LOG_FIELD_CB(NDF_SRC_TRANSPORT, stream_receiver_log_transport, rpt),
935 ND_LOG_FIELD_CB(NDF_SRC_CAPABILITIES, stream_receiver_log_capabilities, rpt),
936 ND_LOG_FIELD_END(),
937 };
938 ND_LOG_STACK_PUSH(lgs);
939
940 worker_is_busy(WORKER_STREAM_JOB_DISCONNECT_SOCKET_ERROR);
941 nd_log(NDLS_DAEMON, NDLP_ERR,
942 "STREAM RCV[%zu] '%s' [from %s]: socket error detected: %s - closing connection",
943 sth->id, rrdhost_hostname(rpt->host), rpt->remote_ip, strerror(saved_errno));
944
945 stream_receiver_remove(sth, rpt, STREAM_HANDSHAKE_DISCONNECT_SOCKET_ERROR);
946 continue;
947 }
948 // probe_rc > 0: data available (normal)
949 // probe_rc < 0 with EAGAIN/EWOULDBLOCK: no data but connection alive
950
951 spinlock_lock(&rpt->thread.send_to_child.spinlock);
952 STREAM_CIRCULAR_BUFFER_STATS stats = *stream_circular_buffer_stats_unsafe(rpt->thread.send_to_child.scb);
953 spinlock_unlock(&rpt->thread.send_to_child.spinlock);
954
955 if (stats.buffer_ratio > overall_buffer_ratio)
956 overall_buffer_ratio = stats.buffer_ratio;
957
958 time_t timeout_s = 600;
959 if(unlikely(rpt->thread.last_traffic_ut + timeout_s * USEC_PER_SEC < now_ut &&
960 !rrdhost_receiver_replicating_charts(rpt->host))) {
961
962 ND_LOG_STACK lgs[] = {
963 ND_LOG_FIELD_TXT(NDF_SRC_IP, rpt->remote_ip),
964 ND_LOG_FIELD_TXT(NDF_SRC_PORT, rpt->remote_port),
965 ND_LOG_FIELD_TXT(NDF_NIDL_NODE, rpt->hostname),
966 ND_LOG_FIELD_CB(NDF_SRC_TRANSPORT, stream_receiver_log_transport, rpt),
967 ND_LOG_FIELD_CB(NDF_SRC_CAPABILITIES, stream_receiver_log_capabilities, rpt),
968 ND_LOG_FIELD_END(),
969 };
970 ND_LOG_STACK_PUSH(lgs);
971
972 worker_is_busy(WORKER_STREAM_JOB_DISCONNECT_TIMEOUT);
973
974 char duration[RFC3339_MAX_LENGTH];
975 duration_snprintf(duration, sizeof(duration), (int64_t)(now_monotonic_usec() - rpt->thread.last_traffic_ut), "us", true);
976
977 char pending[64] = "0";
978 if(stats.bytes_outstanding)
979 size_snprintf(pending, sizeof(pending), stats.bytes_outstanding, "B", false);
980
981 nd_log(NDLS_DAEMON, NDLP_ERR,
982 "STREAM RCV[%zu] '%s' [from %s]: there was not traffic for %ld seconds - closing connection - "
983 "we have sent %zu bytes in %zu operations, it is idle for %s, and we have %s pending to send "
984 "(buffer is used %.2f%%).",
985 sth->id, rrdhost_hostname(rpt->host), rpt->remote_ip, timeout_s,
986 stats.bytes_sent, stats.sends, duration, pending, stats.buffer_ratio);
987
988 stream_receiver_remove(sth, rpt, STREAM_HANDSHAKE_DISCONNECT_TIMEOUT);
989 continue;
990 }
991
992 nd_poll_event_t wanted = ND_POLL_READ | (stats.bytes_outstanding ? ND_POLL_WRITE : 0);
993 if(unlikely(rpt->thread.wanted != wanted)) {
994 // nd_log(NDLS_DAEMON, NDLP_DEBUG,
995 // "STREAM RCV[%zu] '%s' [from %s]: nd_poll() wanted events mismatch.",
996 // sth->id, rrdhost_hostname(rpt->host), rpt->remote_ip);
997
998 rpt->thread.wanted = wanted;
999 if(!nd_poll_upd(sth->run.ndpl, rpt->sock.fd, rpt->thread.wanted))
1000 nd_log(NDLS_DAEMON, NDLP_ERR,
1001 "STREAM RCV[%zu] '%s' [from %s]: failed to update nd_poll().",
1002 sth->id, rrdhost_hostname(rpt->host), rpt->remote_ip);
1003 }
1004 }
1005 }
1006
1007 static bool stream_receiver_did_replication_progress(struct receiver_state *rpt) {
1008 RRDHOST *host = rpt->host;
1009
1010 size_t host_counter_sum =
1011 __atomic_load_n(&host->stream.rcv.status.replication.counter_in, __ATOMIC_RELAXED) +
1012 __atomic_load_n(&host->stream.rcv.status.replication.counter_out, __ATOMIC_RELAXED);
1013
1014 if(rpt->replication.last_counter_sum != host_counter_sum) {
1015 // there has been some progress
1016 rpt->replication.last_counter_sum = host_counter_sum;
1017 rpt->replication.last_progress_ut = now_monotonic_usec();
1018 return true;
1019 }
1020
1021 if(!host_counter_sum)
1022 // we have not started yet
1023 return true;
1024
1025 if(__atomic_load_n(&host->stream.rcv.status.replication.backfill_pending, __ATOMIC_RELAXED))
1026 // we still have requests to execute
1027 return true;
1028
1029 return (now_monotonic_usec() - rpt->replication.last_progress_ut < 10ULL * 60 * USEC_PER_SEC);
1030 }
1031
1032 void stream_receiver_replication_check_from_poll(struct stream_thread *sth, usec_t now_ut __maybe_unused) {
1033 internal_fatal(sth->tid != gettid_cached(), "Function %s() should only be used by the dispatcher thread", __FUNCTION__);
1034
1035 Word_t idx = 0;
1036 for(struct pollfd_meta *m = META_FIRST(&sth->run.meta, &idx);
1037 m;
1038 m = META_NEXT(&sth->run.meta, &idx)) {
1039 if (m->type != POLLFD_TYPE_RECEIVER) continue;
1040 struct receiver_state *rpt = m->rpt;
1041 RRDHOST *host = rpt->host;
1042
1043
1044 if(stream_receiver_did_replication_progress(rpt)) {
1045 rpt->replication.last_checked_ut = 0;
1046 continue;
1047 }
1048
1049 if(rpt->replication.last_checked_ut == rpt->replication.last_progress_ut)
1050 continue;
1051
1052 size_t stalled = 0, finished = 0;
1053 RRDSET *st;
1054 rrdset_foreach_read(st, rpt->host) {
1055 RRDSET_FLAGS st_flags = rrdset_flag_get(st);
1056 if(st_flags & RRDSET_FLAG_OBSOLETE)
1057 continue;
1058
1059 if(st_flags & RRDSET_FLAG_RECEIVER_REPLICATION_FINISHED) {
1060 finished++;
1061 continue;
1062 }
1063
1064 nd_log(NDLS_DAEMON, NDLP_DEBUG,
1065 "STREAM RCV[%zu] '%s' [from %s]: REPLICATION EXCEPTIONS: instance '%s' %s replication yet.",
1066 sth->id, rrdhost_hostname(host), rpt->remote_ip,
1067 rrdset_id(st),
1068 (st_flags & RRDSET_FLAG_RECEIVER_REPLICATION_IN_PROGRESS) ? "has not finished" : "has not started");
1069
1070 stalled++;
1071 }
1072 rrdset_foreach_done(st);
1073
1074 if(stalled && !stream_receiver_did_replication_progress(rpt)) {
1075 nd_log(NDLS_DAEMON, NDLP_WARNING,
1076 "STREAM RCV[%zu] '%s' [from %s]: REPLICATION EXCEPTIONS SUMMARY: node has %zu stalled replication requests (%zu finished). "
1077 "We have requested %u and got replies for %u replication commands. "
1078 "Disconnecting node to restore streaming.",
1079 sth->id, rrdhost_hostname(rpt->host), rpt->remote_ip,
1080 stalled, finished,
1081 __atomic_load_n(&host->stream.rcv.status.replication.counter_out, __ATOMIC_RELAXED),
1082 __atomic_load_n(&host->stream.rcv.status.replication.counter_in, __ATOMIC_RELAXED));
1083
1084 stream_receiver_remove(sth, rpt, STREAM_HANDSHAKE_DISCONNECT_REPLICATION_STALLED);
1085 continue;
1086 }
1087
1088 rpt->replication.last_checked_ut = rpt->replication.last_progress_ut;
1089 }
1090 }
1091
1092 void stream_receiver_cleanup(struct stream_thread *sth) {
1093 Word_t idx = 0;
1094 for(struct pollfd_meta *m = META_FIRST(&sth->run.meta, &idx);
1095 m;
1096 m = META_NEXT(&sth->run.meta, &idx)) {
1097 if (m->type != POLLFD_TYPE_RECEIVER) continue;
1098 struct receiver_state *rpt = m->rpt;
1099 receiver_set_exit_reason(rpt, STREAM_HANDSHAKE_DISCONNECT_SHUTDOWN, true);
1100 stream_receiver_remove(sth, rpt, STREAM_HANDSHAKE_DISCONNECT_SHUTDOWN);
1101 }
1102 }
1103
1104 static void stream_receiver_replication_reset(RRDHOST *host) {
1105 RRDSET *st;
1106 rrdset_foreach_read(st, host) {
1107 RRDSET_FLAGS old = rrdset_flag_set_and_clear(st, RRDSET_FLAG_RECEIVER_REPLICATION_FINISHED, RRDSET_FLAG_RECEIVER_REPLICATION_IN_PROGRESS);
1108 if(!(old & RRDSET_FLAG_RECEIVER_REPLICATION_FINISHED))
1109 rrdhost_receiver_replicating_charts_minus_one(host);
1110
1111 #ifdef REPLICATION_TRACKING
1112 st->stream.rcv.who = REPLAY_WHO_UNKNOWN;
1113 #endif
1114 }
1115 rrdset_foreach_done(st);
1116
1117 if(rrdhost_receiver_replicating_charts(host) != 0) {
1118 nd_log(NDLS_DAEMON, NDLP_WARNING,
1119 "STREAM REPLAY ERROR: receiver replication instances counter should be zero, but it is %u"
1120 " - resetting it to zero",
1121 rrdhost_receiver_replicating_charts(host));
1122
1123 rrdhost_receiver_replicating_charts_zero(host);
1124 }
1125
1126 __atomic_store_n(&host->stream.rcv.status.replication.counter_in, 0, __ATOMIC_RELAXED);
1127 __atomic_store_n(&host->stream.rcv.status.replication.counter_out, 0, __ATOMIC_RELAXED);
1128 __atomic_store_n(&host->stream.rcv.status.replication.backfill_pending, 0, __ATOMIC_RELAXED);
1129 }
1130
1131 RRDHOST_SET_RECEIVER_RESULT rrdhost_set_receiver(RRDHOST *host, struct receiver_state *rpt) {
1132 bool signal_rrdcontext = false;
1133 bool set_this = false;
1134
1135 rrdhost_receiver_lock(host);
1136
1137 // If the obsolete-all cleanup is running on this host, refuse the attach.
1138 // The cleanup walks all charts marking them obsolete without holding
1139 // receiver_lock; attaching mid-pass would let it mark the new receiver's
1140 // charts obsolete and call ml_host_disconnected() on a connected host.
1141 // The child reconnects via normal backoff; by then the pass is done.
1142 if (rrdhost_flag_check(host, RRDHOST_FLAG_OBSOLETE_ALL_IN_PROGRESS)) {
1143 rrdhost_receiver_unlock(host);
1144 return RRDHOST_SET_RECEIVER_CLEANUP_BUSY;
1145 }
1146
1147 if (!host->receiver) {
1148 object_state_activate_if_not_activated(&host->state_id);
1149
1150 rrdhost_flag_clear(host, RRDHOST_FLAG_ORPHAN);
1151 rrdhost_set_health_evloop_iteration(host);
1152
1153 host->stream.rcv.status.connections++;
1154 streaming_receiver_connected();
1155
1156 host->receiver = rpt;
1157 rpt->host = host;
1158
1159 host->stream.rcv.status.reason = (STREAM_HANDSHAKE)rpt->capabilities;
1160 rpt->exit.reason = 0;
1161 __atomic_store_n(&rpt->exit.shutdown, false, __ATOMIC_RELEASE);
1162 host->stream.rcv.status.last_connected = now_realtime_sec();
1163 host->stream.rcv.status.last_disconnected = 0;
1164
1165 if (rpt->config.health.enabled != CONFIG_BOOLEAN_NO) {
1166 if (rpt->config.health.delay > 0) {
1167 host->health.delay_up_to = now_realtime_sec() + rpt->config.health.delay;
1168 nd_log(NDLS_DAEMON, NDLP_DEBUG,
1169 "STREAM RCV '%s' [from [%s]:%s]: "
1170 "Postponing health checks for %" PRId64 " seconds, because it was just connected.",
1171 rrdhost_hostname(host), rpt->remote_ip, rpt->remote_port,
1172 (int64_t) rpt->config.health.delay);
1173 }
1174 }
1175
1176 host->health_log.health_log_retention_s = rpt->config.health.history;
1177
1178 // this is a test
1179 // if(rpt->hops <= host->sender->hops)
1180 // stream_sender_thread_stop(host, "HOPS MISMATCH", false);
1181
1182 signal_rrdcontext = true;
1183 stream_receiver_replication_reset(host);
1184
1185 rrdhost_flag_set(rpt->host, RRDHOST_FLAG_COLLECTOR_ONLINE);
1186 aclk_queue_node_info(rpt->host, true);
1187
1188 stream_parents_host_reset(host, STREAM_HANDSHAKE_SP_PREPARING);
1189
1190 set_this = true;
1191 }
1192
1193 rrdhost_receiver_unlock(host);
1194
1195 if(signal_rrdcontext)
1196 rrdcontext_host_child_connected(host);
1197
1198 if(set_this)
1199 ml_host_start(host);
1200
1201 return set_this ? RRDHOST_SET_RECEIVER_OK : RRDHOST_SET_RECEIVER_ALREADY_ATTACHED;
1202 }
1203
1204 void rrdhost_clear_receiver(struct receiver_state *rpt, STREAM_HANDSHAKE reason) {
1205 RRDHOST *host = rpt->host;
1206 if(!host) return;
1207
1208 rrdhost_receiver_lock(host);
1209 {
1210 // Make sure that we detach this thread and don't kill a freshly arriving receiver
1211
1212 if (host->receiver == rpt) {
1213 rrdhost_flag_clear(host, RRDHOST_FLAG_COLLECTOR_ONLINE);
1214
1215 rrdhost_receiver_unlock(host);
1216 {
1217 // this will wait until all workers finish
1218 object_state_deactivate(&host->state_id);
1219
1220 // run all these without having the receiver lock
1221
1222 rrdhost_set_health_evloop_iteration(host);
1223 ml_host_stop(host);
1224 stream_path_child_disconnected(host);
1225 stream_sender_signal_to_stop_and_wait(host, reason, false);
1226 rrdcontext_host_child_disconnected(host);
1227
1228 if (rpt->config.health.enabled)
1229 rrdcalc_child_disconnected(host);
1230
1231 stream_parents_host_reset(host, reason);
1232 }
1233 rrdhost_receiver_lock(host);
1234
1235 // now we have the lock again
1236
1237 stream_receiver_replication_reset(host);
1238 streaming_receiver_disconnected();
1239
1240 host->stream.rcv.status.reason = rpt->exit.reason;
1241 rpt->exit.reason = 0;
1242 __atomic_store_n(&rpt->exit.shutdown, false, __ATOMIC_RELEASE);
1243 host->stream.rcv.status.last_connected = 0;
1244 host->stream.rcv.status.last_disconnected = now_realtime_sec();
1245 host->health.enabled = false;
1246
1247 rrdhost_flag_set(host, RRDHOST_FLAG_ORPHAN);
1248 host->receiver = NULL;
1249 }
1250 }
1251
1252 // this must be cleared with the receiver lock
1253 pluginsd_process_cleanup(rpt->thread.parser);
1254 __atomic_store_n(&rpt->thread.parser, NULL, __ATOMIC_RELAXED);
1255
1256 rrdhost_receiver_unlock(host);
1257 }
1258
1259 bool stream_receiver_signal_to_stop_and_wait(RRDHOST *host, STREAM_HANDSHAKE reason) {
1260 bool ret = false;
1261
1262 rrdhost_receiver_lock(host);
1263
1264 struct receiver_state *rpt = host->receiver;
1265
1266 if(rpt) {
1267 if(!__atomic_load_n(&rpt->exit.shutdown, __ATOMIC_ACQUIRE)) {
1268 receiver_set_exit_reason(rpt, reason, true);
1269 __atomic_store_n(&rpt->exit.shutdown, true, __ATOMIC_RELEASE);
1270 shutdown(rpt->sock.fd, SHUT_RDWR);
1271 }
1272
1273 int count = 2000;
1274 while (host->receiver == rpt && count-- > 0) {
1275 rrdhost_receiver_unlock(host);
1276
1277 // let the lock for the receiver thread to exit
1278 sleep_usec(1 * USEC_PER_MS);
1279
1280 rrdhost_receiver_lock(host);
1281 }
1282
1283 if(host->receiver == rpt)
1284 netdata_log_error("STREAM RCV[x] '%s' [from [%s]:%s]: "
1285 "streaming thread takes too long to stop, giving up..."
1286 , rrdhost_hostname(host)
1287 , rpt->remote_ip, rpt->remote_port);
1288 else
1289 ret = true;
1290 }
1291 else
1292 ret = true;
1293
1294 rrdhost_receiver_unlock(host);
1295
1296 return ret;
1297 }