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 */
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 \
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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 */
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;
+}
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 */
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;
+}
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,
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;
+}
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)
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 */
[ 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"
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 */