Sessiond: Implement cmd_clear_session
authorJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Mon, 11 Feb 2019 16:18:22 +0000 (11:18 -0500)
committerJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Mon, 18 Feb 2019 19:25:02 +0000 (14:25 -0500)
Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
12 files changed:
include/lttng/lttng-error.h
src/bin/lttng-sessiond/Makefile.am
src/bin/lttng-sessiond/clear.c [new file with mode: 0644]
src/bin/lttng-sessiond/clear.h [new file with mode: 0644]
src/bin/lttng-sessiond/consumer.c
src/bin/lttng-sessiond/consumer.h
src/bin/lttng-sessiond/kernel.c
src/bin/lttng-sessiond/kernel.h
src/bin/lttng-sessiond/ust-app.c
src/bin/lttng-sessiond/ust-app.h
src/common/error.c
src/common/sessiond-comm/sessiond-comm.h

index 0ea77aadbcf9b5475497df2bd8c7a5fbe8cc7dbf..8b8f5ee0dd666a8754260f34678c6d990bc1d2aa 100644 (file)
@@ -167,7 +167,10 @@ enum lttng_error_code {
        LTTNG_ERR_ROTATION_PENDING_RELAY_FAIL_CONSUMER = 144, /* Rotation pending check (relay) failure on consumer */
        LTTNG_ERR_MKDIR_FAIL_CONSUMER    = 145, /* mkdir failure on consumer */
        LTTNG_ERR_CHAN_NOT_FOUND         = 146, /* Channel not found */
-
+       LTTNG_ERR_CLEAR_RELAY_DISALLOW   = 147, /* LTTng-relayd peer does not allow lttng clear command. */
+       LTTNG_ERR_CLEAR_NOT_AVAILABLE    = 148, /* Clear feature not available. */
+       LTTNG_ERR_CLEAR_NOT_AVAILABLE_RELAY = 149, /* Clear feature not available on the relay. */
+       LTTNG_ERR_CLEAR_FAIL_CONSUMER    = 150, /* Clear failure on consumer */
 
        /* MUST be last element */
        LTTNG_ERR_NR,                           /* Last element */
index 9800c4b2ccc065beb851b09d6a9c60d2658108c9..9d2631fc401e233381d3279c425096fc9b91c5ca 100644 (file)
@@ -49,7 +49,8 @@ lttng_sessiond_SOURCES = utils.c utils.h \
                        register.c register.h \
                        manage-apps.c manage-apps.h \
                        manage-kernel.c manage-kernel.h \
-                       manage-consumer.c manage-consumer.h
+                       manage-consumer.c manage-consumer.h \
+                       clear.c
 
 if HAVE_LIBLTTNG_UST_CTL
 lttng_sessiond_SOURCES += trace-ust.c ust-registry.c ust-app.c \
diff --git a/src/bin/lttng-sessiond/clear.c b/src/bin/lttng-sessiond/clear.c
new file mode 100644 (file)
index 0000000..a0917dc
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2019 - Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License, version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#define _LGPL_SOURCE
+#include <assert.h>
+#include <inttypes.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <common/defaults.h>
+#include <common/error.h>
+#include <common/utils.h>
+
+#include "clear.h"
+#include "session.h"
+#include "ust-app.h"
+#include "kernel.h"
+
+
+int cmd_clear_session(struct ltt_session *session)
+{
+       int ret;
+
+       if (!session->has_been_started) {
+                /* Nothing to be cleared, do not warn */
+                ret = LTTNG_OK;
+                goto end;
+       }
+
+       /*
+        * Unsupported feature in lttng-relayd before 2.12.
+        */
+       if (session->consumer->type == CONSUMER_DST_NET &&
+                       (session->consumer->relay_major_version == 2 &&
+                       session->consumer->relay_minor_version < 12)) {
+               ret = LTTNG_ERR_CLEAR_NOT_AVAILABLE_RELAY;
+               goto end;
+       }
+
+       /* TODO: Should we check for disallowed here or consumer side? */
+
+       /* Snapshot session are the only one supported for now */
+       if (!session->snapshot_mode) {
+               /*
+                * TODO: this error code is temporary and will be removed since
+                * we will be supporting all session type
+                */
+               ret = LTTNG_ERR_CLEAR_NOT_AVAILABLE;
+               goto end;
+       }
+
+       if (session->kernel_session) {
+               ret = kernel_clear_session(session);
+               if (ret != LTTNG_OK) {
+                       goto error;
+               }
+       }
+       if (session->ust_session) {
+               ret = ust_app_clear_session(session);
+               if (ret != LTTNG_OK) {
+                       goto error;
+               }
+       }
+error:
+end:
+       return ret;
+}
diff --git a/src/bin/lttng-sessiond/clear.h b/src/bin/lttng-sessiond/clear.h
new file mode 100644 (file)
index 0000000..bcaa2e1
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2019 - Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License, version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef CLEAR_H
+#define CLEAR_H
+
+#include "session.h"
+
+int cmd_clear_session(struct ltt_session *session);
+
+#endif /* CLEAT_H */
index 80e3137788ebc0c26da3302988a8ead922adf121..397d207253b84b02d1e8ab62538564bc5ec12adb 100644 (file)
@@ -1899,3 +1899,38 @@ error:
        health_code_update();
        return ret;
 }
+
+int consumer_clear_channel(struct consumer_socket *socket, uint64_t key,
+               struct consumer_output *output)
+{
+       int ret;
+       struct lttcomm_consumer_msg msg;
+
+       assert(socket);
+
+       DBG("Consumer clear channel %" PRIu64, key);
+
+       memset(&msg, 0, sizeof(msg));
+       msg.cmd_type = LTTNG_CONSUMER_CLEAR_CHANNEL;
+       msg.u.clear_channel.key = key;
+
+       if (output->type == CONSUMER_DST_NET) {
+               ERR("Relayd clear is not supported for now");
+               ret = -LTTNG_ERR_INVALID;
+               goto error;
+       }
+       health_code_update();
+
+       pthread_mutex_lock(socket->lock);
+       ret = consumer_send_msg(socket, &msg);
+       if (ret < 0) {
+               goto error_socket;
+       }
+
+error_socket:
+       pthread_mutex_unlock(socket->lock);
+
+error:
+       health_code_update();
+       return ret;
+}
index 0e7ed0017a5a9d42f2b15b5ff5c8c074ba3051d9..3846d9a7736a76f364472068623d933125826888 100644 (file)
@@ -313,4 +313,7 @@ int consumer_mkdir(struct consumer_socket *socket, uint64_t session_id,
                const struct consumer_output *output, const char *path,
                uid_t uid, gid_t gid);
 
+/* Clear command */
+int consumer_clear_channel(struct consumer_socket *socket, uint64_t key,
+               struct consumer_output *output);
 #endif /* _CONSUMER_H */
index 8e972b0693cc28362fe36e9a80b040d128bed62c..aac6665bef40a17021b03c88dc7f294be5e8553e 100644 (file)
@@ -1459,3 +1459,70 @@ error:
        rcu_read_unlock();
        return status;
 }
+
+/*
+ *  Clear a kernel session.
+ *
+ * Return LTTNG_OK on success or else an LTTng error code.
+ */
+enum lttng_error_code kernel_clear_session(struct ltt_session *session)
+{
+       int ret;
+       enum lttng_error_code status = LTTNG_OK;
+       struct consumer_socket *socket;
+       struct lttng_ht_iter iter;
+       struct ltt_kernel_session *ksess = session->kernel_session;
+
+       assert(ksess);
+       assert(ksess->consumer);
+
+       DBG("Cleat kernel session %s (session %" PRIu64 ")",
+                       session->name, session->id);
+
+       rcu_read_lock();
+
+       /*
+        * Note that this loop will end after one iteration given that there is
+        * only one kernel consumer.
+        */
+       cds_lfht_for_each_entry(ksess->consumer->socks->ht, &iter.iter,
+                       socket, node.node) {
+               struct ltt_kernel_channel *chan;
+
+               /* For each channel, ask the consumer to clear it. */
+               cds_list_for_each_entry(chan, &ksess->channel_list.head, list) {
+                       DBG("Clear kernel channel %" PRIu64 ", session %s",
+                                       chan->key, session->name);
+                       ret = consumer_clear_channel(socket, chan->key,
+                                       ksess->consumer);
+                       if (ret < 0) {
+                               goto error;
+                       }
+               }
+
+               /*
+                * Clear the metadata channel.
+                * Metadata channel is not cleared per se but we still need to
+                * perform rotation operation on it behind the scene.
+                */
+               ret = consumer_clear_channel(socket, ksess->metadata->key,
+                               ksess->consumer);
+               if (ret < 0) {
+                       goto error;
+               }
+       }
+
+       goto end;
+error:
+       switch (-ret) {
+       case LTTCOMM_CONSUMERD_RELAYD_DISALLOW_CLEAR:
+             status = LTTNG_ERR_CLEAR_RELAY_DISALLOW;
+             break;
+       default:
+             status = LTTNG_ERR_CLEAR_FAIL_CONSUMER;
+             break;
+       }
+end:
+       rcu_read_unlock();
+       return status;
+}
index 9b0c15cd14fd866fe71654b9ee41134b9d144de3..7437be556405a8b0b1c8132257d6db794e4a0433 100644 (file)
@@ -64,6 +64,7 @@ enum lttng_error_code kernel_snapshot_record(struct ltt_kernel_session *ksess,
                uint64_t nb_packets_per_stream);
 int kernel_syscall_mask(int chan_fd, char **syscall_mask, uint32_t *nr_bits);
 enum lttng_error_code kernel_rotate_session(struct ltt_session *session);
+enum lttng_error_code kernel_clear_session(struct ltt_session *session);
 
 int init_kernel_workarounds(void);
 ssize_t kernel_list_tracker_pids(struct ltt_kernel_session *session,
index 59d8a8fc49a96edf8327e85ea033879555e87487..fb39ce12b8197aef41858909c766d1aefedb531b 100644 (file)
@@ -6462,3 +6462,149 @@ error:
        rcu_read_unlock();
        return cmd_ret;
 }
+
+/*
+ * Clear all the channels of a session.
+ *
+ * Return LTTNG_OK on success or else an LTTng error code.
+ */
+enum lttng_error_code ust_app_clear_session(struct ltt_session *session)
+{
+       int ret;
+       enum lttng_error_code cmd_ret = LTTNG_OK;
+       struct lttng_ht_iter iter;
+       struct ust_app *app;
+       struct ltt_ust_session *usess = session->ust_session;
+
+       assert(usess);
+
+       rcu_read_lock();
+
+       switch (usess->buffer_type) {
+       case LTTNG_BUFFER_PER_UID:
+       {
+               struct buffer_reg_uid *reg;
+
+               cds_list_for_each_entry(reg, &usess->buffer_reg_uid_list, lnode) {
+                       struct buffer_reg_channel *reg_chan;
+                       struct consumer_socket *socket;
+
+                       /* Get consumer socket to use to push the metadata.*/
+                       socket = consumer_find_socket_by_bitness(reg->bits_per_long,
+                                       usess->consumer);
+                       if (!socket) {
+                               cmd_ret = LTTNG_ERR_INVALID;
+                               goto error_socket;
+                       }
+
+                       /* Clear the data channels. */
+                       cds_lfht_for_each_entry(reg->registry->channels->ht, &iter.iter,
+                                       reg_chan, node.node) {
+                               ret = consumer_clear_channel(socket,
+                                               reg_chan->consumer_key,
+                                               usess->consumer);
+                               if (ret < 0) {
+                                       goto error;
+                               }
+                       }
+
+                       (void) push_metadata(reg->registry->reg.ust, usess->consumer);
+
+                       /*
+                        * Clear the metadata channel.
+                        * Metadata channel is not cleared per se but we still need to
+                        * perform rotation operation on it behind the scene.
+                        */
+                       ret = consumer_clear_channel(socket,
+                                       reg->registry->reg.ust->metadata_key,
+                                       usess->consumer);
+                       if (ret < 0) {
+                               goto error;
+                       }
+               }
+               break;
+       }
+       case LTTNG_BUFFER_PER_PID:
+       {
+               cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+                       struct consumer_socket *socket;
+                       struct lttng_ht_iter chan_iter;
+                       struct ust_app_channel *ua_chan;
+                       struct ust_app_session *ua_sess;
+                       struct ust_registry_session *registry;
+
+                       ua_sess = lookup_session_by_app(usess, app);
+                       if (!ua_sess) {
+                               /* Session not associated with this app. */
+                               continue;
+                       }
+
+                       /* Get the right consumer socket for the application. */
+                       socket = consumer_find_socket_by_bitness(app->bits_per_long,
+                                       usess->consumer);
+                       if (!socket) {
+                               cmd_ret = LTTNG_ERR_INVALID;
+                               goto error_socket;
+                       }
+
+                       registry = get_session_registry(ua_sess);
+                       if (!registry) {
+                               DBG("Application session is being torn down. Skip application.");
+                               continue;
+                       }
+
+                       /* Rotate the data channels. */
+                       cds_lfht_for_each_entry(ua_sess->channels->ht, &chan_iter.iter,
+                                       ua_chan, node.node) {
+                               ret = consumer_clear_channel(socket, ua_chan->key,
+                                               ua_sess->consumer);
+                               if (ret < 0) {
+                                       /* Per-PID buffer and application going away. */
+                                       if (ret == -LTTNG_ERR_CHAN_NOT_FOUND) {
+                                               continue;
+                                       }
+                                       goto error;
+                               }
+                       }
+
+                       (void) push_metadata(registry, usess->consumer);
+
+                       /*
+                        * Clear the metadata channel.
+                        * Metadata channel is not cleared per se but we still need to
+                        * perform rotation operation on it behind the scene.
+                        */
+                       ret = consumer_clear_channel(socket, registry->metadata_key,
+                                       ua_sess->consumer);
+                       if (ret < 0) {
+                               /* Per-PID buffer and application going away. */
+                               if (ret == -LTTNG_ERR_CHAN_NOT_FOUND) {
+                                       continue;
+                               }
+                               goto error;
+                       }
+               }
+               break;
+       }
+       default:
+               assert(0);
+               break;
+       }
+
+       cmd_ret = LTTNG_OK;
+       goto end;
+
+error:
+       switch (-ret) {
+       case LTTCOMM_CONSUMERD_RELAYD_DISALLOW_CLEAR:
+               cmd_ret = LTTNG_ERR_CLEAR_RELAY_DISALLOW;
+               break;
+       default:
+               cmd_ret = LTTNG_ERR_CLEAR_FAIL_CONSUMER;
+       }
+
+error_socket:
+end:
+       rcu_read_unlock();
+       return cmd_ret;
+}
index b90ff4bcef8833459268ba02f62dfc2e40bfc7e8..8d6fdf037b2b0dd6d9ca64fe490c8cd1148466a3 100644 (file)
@@ -356,6 +356,7 @@ int ust_app_pid_get_channel_runtime_stats(struct ltt_ust_session *usess,
                int overwrite, uint64_t *discarded, uint64_t *lost);
 int ust_app_regenerate_statedump_all(struct ltt_ust_session *usess);
 enum lttng_error_code ust_app_rotate_session(struct ltt_session *session);
+enum lttng_error_code ust_app_clear_session(struct ltt_session *session);
 
 static inline
 int ust_app_supported(void)
@@ -589,6 +590,12 @@ enum lttng_error_code ust_app_rotate_session(struct ltt_session *session)
        return 0;
 }
 
+static inline
+enum lttng_error_code ust_app_clear_session(struct ltt_session *session)
+{
+       return 0;
+}
+
 #endif /* HAVE_LIBLTTNG_UST_CTL */
 
 #endif /* _LTT_UST_APP_H */
index dd1735dd4779094f35dd85c028ce156e488f6754..c7807a0133678643c91676b40032f03e93dd61d6 100644 (file)
@@ -208,6 +208,10 @@ static const char *error_string_array[] = {
        [ ERROR_INDEX(LTTNG_ERR_ROTATION_PENDING_RELAY_FAIL_CONSUMER) ] = "Rotation pending check (relay) failure on consumer",
        [ ERROR_INDEX(LTTNG_ERR_MKDIR_FAIL_CONSUMER) ] = "mkdir failure on consumer",
        [ ERROR_INDEX(LTTNG_ERR_CHAN_NOT_FOUND) ] = "Channel not found",
+       [ ERROR_INDEX(LTTNG_ERR_CLEAR_RELAY_DISALLOW) ] = "Relayd daemon peer does not allow lttng clear command",
+       [ ERROR_INDEX(LTTNG_ERR_CLEAR_NOT_AVAILABLE) ] = "Clear feature is not available for the session type",
+       [ ERROR_INDEX(LTTNG_ERR_CLEAR_NOT_AVAILABLE_RELAY) ] = "Clear feature is not available on the relay",
+       [ ERROR_INDEX(LTTNG_ERR_CLEAR_FAIL_CONSUMER) ] = "Clear failure on the consumer",
 
        /* Last element */
        [ ERROR_INDEX(LTTNG_ERR_NR) ] = "Unknown error code"
index 78b94532d096a2d0adb884b734b595b32660e1f5..336ebe978a76250220231b5536e5e0633a775cba 100644 (file)
@@ -170,6 +170,7 @@ enum lttcomm_return_code {
        LTTCOMM_CONSUMERD_ROTATION_PENDING_RELAY_FAILED, /* Rotation pending relay failed. */
        LTTCOMM_CONSUMERD_MKDIR_FAILED,             /* mkdir has failed. */
        LTTCOMM_CONSUMERD_SNAPSHOT_FAILED,          /* snapshot has failed. */
+       LTTCOMM_CONSUMERD_RELAYD_DISALLOW_CLEAR,    /* Relayd does not accept clear command. */
 
        /* MUST be last element */
        LTTCOMM_NR,                                             /* Last element */
This page took 0.03465 seconds and 5 git commands to generate.