diff mbox

[lttng-tools] Fix: use "flush empty" ioctl for snapshots

Message ID 1494539638-10775-1-git-send-email-mathieu.desnoyers@efficios.com
State Accepted, archived
Delegated to: Jérémie Galarneau
Headers show

Commit Message

Mathieu Desnoyers May 11, 2017, 9:53 p.m. UTC
When the flush empty ioctl is available, use it to produce an empty
packet at the end of the snapshot, which ensures the stream intersection
feature works.

If this specific ioctl is not available, fallback on the "flush" ioctl,
which does not produce empty packets.

In that situation, there were two prior behaviors possible for
lttng-modules: earlier versions implement a "snapshot" command which
does not perform an implicit "flush_empty". In that case, the stream
intersection feature may not be reliable. In more recent lttng-modules
versions (included stable branch) which did not implement the
flush_empty ioctl, the snapshot ioctl implicitly performed a
flush_empty, which makes the stream intersection feature work, but has
side-effects on the snapshot ioctl performed by the live timer (produces
a stream of empty packets in live mode).

[ Please apply to master, 2.10, 2.9, 2.8 branches. ]

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
 src/common/kernel-consumer/kernel-consumer.c | 15 +++++++++++++--
 src/common/kernel-ctl/kernel-ctl.c           |  5 +++++
 src/common/kernel-ctl/kernel-ctl.h           |  1 +
 src/common/kernel-ctl/kernel-ioctl.h         |  4 +++-
 4 files changed, 22 insertions(+), 3 deletions(-)

Comments

Jérémie Galarneau May 22, 2017, 3:31 p.m. UTC | #1
Merged in master, stable-2.10, stable-2.9, and stable-2.8 (slightly adapted).

Thanks!
Jérémie

On 11 May 2017 at 17:53, Mathieu Desnoyers
<mathieu.desnoyers at efficios.com> wrote:
> When the flush empty ioctl is available, use it to produce an empty
> packet at the end of the snapshot, which ensures the stream intersection
> feature works.
>
> If this specific ioctl is not available, fallback on the "flush" ioctl,
> which does not produce empty packets.
>
> In that situation, there were two prior behaviors possible for
> lttng-modules: earlier versions implement a "snapshot" command which
> does not perform an implicit "flush_empty". In that case, the stream
> intersection feature may not be reliable. In more recent lttng-modules
> versions (included stable branch) which did not implement the
> flush_empty ioctl, the snapshot ioctl implicitly performed a
> flush_empty, which makes the stream intersection feature work, but has
> side-effects on the snapshot ioctl performed by the live timer (produces
> a stream of empty packets in live mode).
>
> [ Please apply to master, 2.10, 2.9, 2.8 branches. ]
>
> Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
> ---
>  src/common/kernel-consumer/kernel-consumer.c | 15 +++++++++++++--
>  src/common/kernel-ctl/kernel-ctl.c           |  5 +++++
>  src/common/kernel-ctl/kernel-ctl.h           |  1 +
>  src/common/kernel-ctl/kernel-ioctl.h         |  4 +++-
>  4 files changed, 22 insertions(+), 3 deletions(-)
>
> diff --git a/src/common/kernel-consumer/kernel-consumer.c b/src/common/kernel-consumer/kernel-consumer.c
> index 16aeae1..0a8256f 100644
> --- a/src/common/kernel-consumer/kernel-consumer.c
> +++ b/src/common/kernel-consumer/kernel-consumer.c
> @@ -199,9 +199,20 @@ int lttng_kconsumer_snapshot_channel(uint64_t key, char *path,
>                         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;
>                 }
>
> diff --git a/src/common/kernel-ctl/kernel-ctl.c b/src/common/kernel-ctl/kernel-ctl.c
> index 4911d86..6a256fe 100644
> --- a/src/common/kernel-ctl/kernel-ctl.c
> +++ b/src/common/kernel-ctl/kernel-ctl.c
> @@ -408,6 +408,11 @@ int kernctl_buffer_flush(int fd)
>         return LTTNG_IOCTL_CHECK(fd, RING_BUFFER_FLUSH);
>  }
>
> +int kernctl_buffer_flush_empty(int fd)
> +{
> +       return LTTNG_IOCTL_CHECK(fd, RING_BUFFER_FLUSH_EMPTY);
> +}
> +
>  /* returns the version of the metadata. */
>  int kernctl_get_metadata_version(int fd, uint64_t *version)
>  {
> diff --git a/src/common/kernel-ctl/kernel-ctl.h b/src/common/kernel-ctl/kernel-ctl.h
> index 952fb6f..d88f5e7 100644
> --- a/src/common/kernel-ctl/kernel-ctl.h
> +++ b/src/common/kernel-ctl/kernel-ctl.h
> @@ -93,6 +93,7 @@ int kernctl_get_subbuf(int fd, unsigned long *pos);
>  int kernctl_put_subbuf(int fd);
>
>  int kernctl_buffer_flush(int fd);
> +int kernctl_buffer_flush_empty(int fd);
>  int kernctl_get_metadata_version(int fd, uint64_t *version);
>
>  /* index */
> diff --git a/src/common/kernel-ctl/kernel-ioctl.h b/src/common/kernel-ctl/kernel-ioctl.h
> index cb23620..3c4f412 100644
> --- a/src/common/kernel-ctl/kernel-ioctl.h
> +++ b/src/common/kernel-ctl/kernel-ioctl.h
> @@ -47,7 +47,7 @@
>  #define RING_BUFFER_GET_MMAP_LEN            _IOR(0xF6, 0x0A, unsigned long)
>  /* returns the offset of the subbuffer belonging to the mmap reader. */
>  #define RING_BUFFER_GET_MMAP_READ_OFFSET    _IOR(0xF6, 0x0B, unsigned long)
> -/* flush the current sub-buffer */
> +/* Flush the current sub-buffer, if non-empty. */
>  #define RING_BUFFER_FLUSH                   _IO(0xF6, 0x0C)
>  /* Get the current version of the metadata cache (after a get_next). */
>  #define RING_BUFFER_GET_METADATA_VERSION    _IOR(0xF6, 0x0D, uint64_t)
> @@ -57,6 +57,8 @@
>   * sub-buffer.
>   */
>  #define RING_BUFFER_SNAPSHOT_SAMPLE_POSITIONS  _IO(0xF6, 0x0E)
> +/* Flush the current sub-buffer, even if empty. */
> +#define RING_BUFFER_FLUSH_EMPTY                        _IO(0xF6, 0x0F)
>
>  /* returns the timestamp begin of the current sub-buffer */
>  #define LTTNG_RING_BUFFER_GET_TIMESTAMP_BEGIN     _IOR(0xF6, 0x20, uint64_t)
> --
> 2.1.4
>
diff mbox

Patch

diff --git a/src/common/kernel-consumer/kernel-consumer.c b/src/common/kernel-consumer/kernel-consumer.c
index 16aeae1..0a8256f 100644
--- a/src/common/kernel-consumer/kernel-consumer.c
+++ b/src/common/kernel-consumer/kernel-consumer.c
@@ -199,9 +199,20 @@  int lttng_kconsumer_snapshot_channel(uint64_t key, char *path,
 			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;
 		}
 
diff --git a/src/common/kernel-ctl/kernel-ctl.c b/src/common/kernel-ctl/kernel-ctl.c
index 4911d86..6a256fe 100644
--- a/src/common/kernel-ctl/kernel-ctl.c
+++ b/src/common/kernel-ctl/kernel-ctl.c
@@ -408,6 +408,11 @@  int kernctl_buffer_flush(int fd)
 	return LTTNG_IOCTL_CHECK(fd, RING_BUFFER_FLUSH);
 }
 
+int kernctl_buffer_flush_empty(int fd)
+{
+	return LTTNG_IOCTL_CHECK(fd, RING_BUFFER_FLUSH_EMPTY);
+}
+
 /* returns the version of the metadata. */
 int kernctl_get_metadata_version(int fd, uint64_t *version)
 {
diff --git a/src/common/kernel-ctl/kernel-ctl.h b/src/common/kernel-ctl/kernel-ctl.h
index 952fb6f..d88f5e7 100644
--- a/src/common/kernel-ctl/kernel-ctl.h
+++ b/src/common/kernel-ctl/kernel-ctl.h
@@ -93,6 +93,7 @@  int kernctl_get_subbuf(int fd, unsigned long *pos);
 int kernctl_put_subbuf(int fd);
 
 int kernctl_buffer_flush(int fd);
+int kernctl_buffer_flush_empty(int fd);
 int kernctl_get_metadata_version(int fd, uint64_t *version);
 
 /* index */
diff --git a/src/common/kernel-ctl/kernel-ioctl.h b/src/common/kernel-ctl/kernel-ioctl.h
index cb23620..3c4f412 100644
--- a/src/common/kernel-ctl/kernel-ioctl.h
+++ b/src/common/kernel-ctl/kernel-ioctl.h
@@ -47,7 +47,7 @@ 
 #define RING_BUFFER_GET_MMAP_LEN            _IOR(0xF6, 0x0A, unsigned long)
 /* returns the offset of the subbuffer belonging to the mmap reader. */
 #define RING_BUFFER_GET_MMAP_READ_OFFSET    _IOR(0xF6, 0x0B, unsigned long)
-/* flush the current sub-buffer */
+/* Flush the current sub-buffer, if non-empty. */
 #define RING_BUFFER_FLUSH                   _IO(0xF6, 0x0C)
 /* Get the current version of the metadata cache (after a get_next). */
 #define RING_BUFFER_GET_METADATA_VERSION    _IOR(0xF6, 0x0D, uint64_t)
@@ -57,6 +57,8 @@ 
  * sub-buffer.
  */
 #define RING_BUFFER_SNAPSHOT_SAMPLE_POSITIONS	_IO(0xF6, 0x0E)
+/* Flush the current sub-buffer, even if empty. */
+#define RING_BUFFER_FLUSH_EMPTY			_IO(0xF6, 0x0F)
 
 /* returns the timestamp begin of the current sub-buffer */
 #define LTTNG_RING_BUFFER_GET_TIMESTAMP_BEGIN     _IOR(0xF6, 0x20, uint64_t)