Fix: lost packet accounting always lost on snapshot
[lttng-tools.git] / src / common / kernel-consumer / kernel-consumer.c
index cc06847c9d8f57ecd8f1467d49e9cd3b0f2c1f2f..1079047f0137ce5b0d992e6b723998137288b288 100644 (file)
@@ -137,8 +137,6 @@ int lttng_kconsumer_snapshot_channel(uint64_t key, char *path,
        }
 
        cds_list_for_each_entry(stream, &channel->streams.head, send_node) {
-               /* Are we at a position _before_ the first available packet ? */
-               bool before_first_packet = true;
                unsigned long consumed_pos, produced_pos;
 
                health_code_update();
@@ -182,11 +180,23 @@ int lttng_kconsumer_snapshot_channel(uint64_t key, char *path,
                                ERR("sending streams sent to relayd");
                                goto end_unlock;
                        }
+                       channel->streams_sent_to_relayd = true;
                }
 
-               ret = kernctl_buffer_flush(stream->wait_fd);
+               ret = kernctl_buffer_flush_empty(stream->wait_fd);
                if (ret < 0) {
-                       ERR("Failed to flush kernel stream");
+                       /*
+                        * Doing a buffer flush which does not take into
+                        * account empty packets. This is not perfect
+                        * for stream intersection, but required as a
+                        * fall-back when "flush_empty" is not
+                        * implemented by lttng-modules.
+                        */
+                       ret = kernctl_buffer_flush(stream->wait_fd);
+                       if (ret < 0) {
+                               ERR("Failed to flush kernel stream");
+                               goto end_unlock;
+                       }
                        goto end_unlock;
                }
 
@@ -224,7 +234,6 @@ int lttng_kconsumer_snapshot_channel(uint64_t key, char *path,
                while (consumed_pos < produced_pos) {
                        ssize_t read_len;
                        unsigned long len, padded_len;
-                       int lost_packet = 0;
 
                        health_code_update();
 
@@ -238,15 +247,7 @@ int lttng_kconsumer_snapshot_channel(uint64_t key, char *path,
                                }
                                DBG("Kernel consumer get subbuf failed. Skipping it.");
                                consumed_pos += stream->max_sb_size;
-
-                               /*
-                                * Start accounting lost packets only when we
-                                * already have extracted packets (to match the
-                                * content of the final snapshot).
-                                */
-                               if (!before_first_packet) {
-                                       lost_packet = 1;
-                               }
+                               stream->chan->lost_packets++;
                                continue;
                        }
 
@@ -287,16 +288,6 @@ int lttng_kconsumer_snapshot_channel(uint64_t key, char *path,
                                goto end_unlock;
                        }
                        consumed_pos += stream->max_sb_size;
-
-                       /*
-                        * Only account lost packets located between
-                        * succesfully extracted packets (do not account before
-                        * and after since they are not visible in the
-                        * resulting snapshot).
-                        */
-                       stream->chan->lost_packets += lost_packet;
-                       lost_packet = 0;
-                       before_first_packet = false;
                }
 
                if (relayd_id == (uint64_t) -1ULL) {
@@ -716,6 +707,19 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                                consumer_stream_free(new_stream);
                                goto end_nosignal;
                        }
+
+                       /*
+                        * If adding an extra stream to an already
+                        * existing channel (e.g. cpu hotplug), we need
+                        * to send the "streams_sent" command to relayd.
+                        */
+                       if (channel->streams_sent_to_relayd) {
+                               ret = consumer_send_relayd_streams_sent(
+                                               new_stream->net_seq_idx);
+                               if (ret < 0) {
+                                       goto end_nosignal;
+                               }
+                       }
                }
 
                /* Get the right pipe where the stream will be sent. */
@@ -809,6 +813,7 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                        if (ret < 0) {
                                goto end_nosignal;
                        }
+                       channel->streams_sent_to_relayd = true;
                }
                break;
        }
This page took 0.027885 seconds and 4 git commands to generate.