Implement PID tracking for kernel tracing
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 27 Sep 2014 21:29:12 +0000 (17:29 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Mon, 30 Mar 2015 18:27:15 +0000 (14:27 -0400)
Implement PID tracking (per-session) for kernel tracing. Only
save/restore and MI are missing.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
20 files changed:
include/lttng/session.h
src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/cmd.h
src/bin/lttng-sessiond/kernel.c
src/bin/lttng-sessiond/kernel.h
src/bin/lttng-sessiond/main.c
src/bin/lttng-sessiond/save.c
src/bin/lttng/Makefile.am
src/bin/lttng/command.h
src/bin/lttng/commands/track-untrack.c [new file with mode: 0644]
src/bin/lttng/lttng.c
src/common/config/config-session-abi.h
src/common/config/config.c
src/common/kernel-ctl/kernel-ctl.c
src/common/kernel-ctl/kernel-ctl.h
src/common/kernel-ctl/kernel-ioctl.h
src/common/mi-lttng.c
src/common/mi-lttng.h
src/common/sessiond-comm/sessiond-comm.h
src/lib/lttng-ctl/lttng-ctl.c

index c87efbd1d1b54c7291b76ead401ddb0498220d7c..7b1c8da6aa10825f66ad06aaa9ee76a440542c08 100644 (file)
@@ -116,6 +116,26 @@ extern int lttng_list_sessions(struct lttng_session **sessions);
 extern int lttng_set_session_shm_path(const char *session_name,
                const char *shm_path);
 
+/*
+ * Add PID to session tracker.
+ *
+ * A pid argument >= 0 adds the PID to the session tracker.
+ * A pid argument of -1 means "track all PIDs".
+ *
+ * Return 0 on success else a negative LTTng error code.
+ */
+extern int lttng_track_pid(struct lttng_handle *handle, int pid);
+
+/*
+ * Remove PID from session tracker.
+ *
+ * A pid argument >= 0 removes the PID from the session tracker.
+ * A pid argument of -1 means "untrack all PIDs".
+ *
+ * Return 0 on success else a negative LTTng error code.
+ */
+extern int lttng_untrack_pid(struct lttng_handle *handle, int pid);
+
 #ifdef __cplusplus
 }
 #endif
index bf6097b64609097b1cdf60d97400baf72098cc27..91ea88cb7c593a5c5f8cb010016a4f5f9816b8d4 100644 (file)
@@ -929,6 +929,90 @@ error:
        return ret;
 }
 
+/*
+ * Command LTTNG_TRACK_PID processed by the client thread.
+ */
+int cmd_track_pid(struct ltt_session *session, int domain, int pid)
+{
+       int ret;
+
+       rcu_read_lock();
+
+       switch (domain) {
+       case LTTNG_DOMAIN_KERNEL:
+       {
+               struct ltt_kernel_session *ksess;
+
+               ksess = session->kernel_session;
+
+               ret = kernel_track_pid(ksess, pid);
+               if (ret != LTTNG_OK) {
+                       goto error;
+               }
+
+               kernel_wait_quiescent(kernel_tracer_fd);
+               break;
+       }
+#if 0
+       case LTTNG_DOMAIN_UST:
+       case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN:
+       case LTTNG_DOMAIN_UST_EXEC_NAME:
+       case LTTNG_DOMAIN_UST_PID:
+#endif
+       default:
+               ret = LTTNG_ERR_UNKNOWN_DOMAIN;
+               goto error;
+       }
+
+       ret = LTTNG_OK;
+
+error:
+       rcu_read_unlock();
+       return ret;
+}
+
+/*
+ * Command LTTNG_UNTRACK_PID processed by the client thread.
+ */
+int cmd_untrack_pid(struct ltt_session *session, int domain, int pid)
+{
+       int ret;
+
+       rcu_read_lock();
+
+       switch (domain) {
+       case LTTNG_DOMAIN_KERNEL:
+       {
+               struct ltt_kernel_session *ksess;
+
+               ksess = session->kernel_session;
+
+               ret = kernel_untrack_pid(ksess, pid);
+               if (ret != LTTNG_OK) {
+                       goto error;
+               }
+
+               kernel_wait_quiescent(kernel_tracer_fd);
+               break;
+       }
+#if 0
+       case LTTNG_DOMAIN_UST:
+       case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN:
+       case LTTNG_DOMAIN_UST_EXEC_NAME:
+       case LTTNG_DOMAIN_UST_PID:
+#endif
+       default:
+               ret = LTTNG_ERR_UNKNOWN_DOMAIN;
+               goto error;
+       }
+
+       ret = LTTNG_OK;
+
+error:
+       rcu_read_unlock();
+       return ret;
+}
+
 /*
  * Command LTTNG_ENABLE_CHANNEL processed by the client thread.
  *
index 7144690ca5f5d2eb96f0c0191ee15ecd584dc747..869bc70096af9a32f2a07a0c8627ee4da821e55f 100644 (file)
@@ -37,9 +37,10 @@ int cmd_destroy_session(struct ltt_session *session, int wpipe);
 /* Channel commands */
 int cmd_disable_channel(struct ltt_session *session, int domain,
                char *channel_name);
-
 int cmd_enable_channel(struct ltt_session *session,
                struct lttng_domain *domain, struct lttng_channel *attr, int wpipe);
+int cmd_track_pid(struct ltt_session *session, int domain, int pid);
+int cmd_untrack_pid(struct ltt_session *session, int domain, int pid);
 
 /* Event commands */
 int cmd_disable_event(struct ltt_session *session, int domain,
index 9464a84f088ebd285cde162819e620741e5a2e92..4bb418949d3ea330b60397ed2352f5541c7fcbdc 100644 (file)
@@ -367,6 +367,20 @@ int kernel_disable_syscall(const char *syscall_name,
        return kernctl_disable_syscall(channel->fd, syscall_name);
 }
 
+int kernel_track_pid(struct ltt_kernel_session *session, int pid)
+{
+       DBG("Kernel track PID %d for session id %" PRIu64 ".",
+                       pid, session->id);
+       return kernctl_track_pid(session->fd, pid);
+}
+
+int kernel_untrack_pid(struct ltt_kernel_session *session, int pid)
+{
+       DBG("Kernel untrack PID %d for session id %" PRIu64 ".",
+                       pid, session->id);
+       return kernctl_untrack_pid(session->fd, pid);
+}
+
 /*
  * Create kernel metadata, open from the kernel tracer and add it to the
  * kernel session.
index 09c3ed9929513804966da17fe9af42dc62d6cc04..3739bc9998abf59479b0a8af9d6db2fda79eccd9 100644 (file)
@@ -45,6 +45,8 @@ int kernel_enable_syscall(const char *syscall_name,
                struct ltt_kernel_channel *channel);
 int kernel_disable_syscall(const char *syscall_name,
                struct ltt_kernel_channel *channel);
+int kernel_track_pid(struct ltt_kernel_session *session, int pid);
+int kernel_untrack_pid(struct ltt_kernel_session *session, int pid);
 int kernel_open_metadata(struct ltt_kernel_session *session);
 int kernel_open_metadata_stream(struct ltt_kernel_session *session);
 int kernel_open_channel_stream(struct ltt_kernel_channel *channel);
index 89ef3b092737d23ae83c17af76d826df953fb0b3..21b4cf326bd49e48f0f2a1b2caeee34554578981 100644 (file)
@@ -3252,6 +3252,20 @@ skip_domain:
                                &cmd_ctx->lsm->u.channel.chan, kernel_poll_pipe[1]);
                break;
        }
+       case LTTNG_TRACK_PID:
+       {
+               ret = cmd_track_pid(cmd_ctx->session,
+                               cmd_ctx->lsm->domain.type,
+                               cmd_ctx->lsm->u.pid_tracker.pid);
+               break;
+       }
+       case LTTNG_UNTRACK_PID:
+       {
+               ret = cmd_untrack_pid(cmd_ctx->session,
+                               cmd_ctx->lsm->domain.type,
+                               cmd_ctx->lsm->u.pid_tracker.pid);
+               break;
+       }
        case LTTNG_ENABLE_EVENT:
        {
                struct lttng_event_exclusion *exclusion = NULL;
index c6fc33e7bb83c5b02b6fdc7c4c8b38517d5f9aea..6cb220c2f28d1e56bffeef8dbf49a68d4cd6d516 100644 (file)
@@ -716,6 +716,8 @@ end:
        return ret;
 }
 
+/* TODO: save/restore tracker pid */
+
 static
 int save_kernel_context(struct config_writer *writer,
        struct lttng_kernel_context *ctx)
index ec04e4d7b6b2acca4140e4a659d0355de80e6acd..9f00caeae0199ef2d74aa04e84cc16046a5b0ad8 100644 (file)
@@ -15,6 +15,7 @@ lttng_SOURCES = command.h conf.c conf.h commands/start.c \
                                commands/snapshot.c \
                                commands/save.c \
                                commands/load.c \
+                               commands/track-untrack.c \
                                utils.c utils.h lttng.c
 
 lttng_LDADD = $(top_builddir)/src/lib/lttng-ctl/liblttng-ctl.la \
index 3d4bbf8ebe37aa3ed64082bee9d37076cc9b46f9..a4f06d446011809783f4613bf083edb608ff567d 100644 (file)
@@ -58,5 +58,7 @@ extern int cmd_disable_consumer(int argc, const char **argv);
 extern int cmd_snapshot(int argc, const char **argv);
 extern int cmd_save(int argc, const char **argv);
 extern int cmd_load(int argc, const char **argv);
+extern int cmd_track(int argc, const char **argv);
+extern int cmd_untrack(int argc, const char **argv);
 
 #endif /* _LTTNG_CMD_H */
diff --git a/src/bin/lttng/commands/track-untrack.c b/src/bin/lttng/commands/track-untrack.c
new file mode 100644 (file)
index 0000000..52442cc
--- /dev/null
@@ -0,0 +1,447 @@
+/*
+ * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
+ * Copyright (C) 2015 - Mathieu Desnoyers <mathieu.desnoyers@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 _GNU_SOURCE
+#define _LGPL_SOURCE
+#include <ctype.h>
+#include <popt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <urcu/list.h>
+
+#include <common/mi-lttng.h>
+
+#include "../command.h"
+
+enum cmd_type {
+       CMD_TRACK,
+       CMD_UNTRACK,
+};
+
+static char *opt_session_name;
+static int opt_kernel;
+static int opt_userspace;
+static int opt_all;
+static char *opt_pid_string;
+static int opt_pid;
+
+enum {
+       OPT_HELP = 1,
+       OPT_LIST_OPTIONS,
+       OPT_SESSION,
+       OPT_PID,
+};
+
+static struct poptOption long_options[] = {
+       /* { longName, shortName, argInfo, argPtr, value, descrip, argDesc, } */
+       { "help",               'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0, },
+       { "session",            's', POPT_ARG_STRING, &opt_session_name, OPT_SESSION, 0, 0, },
+       { "kernel",             'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0, },
+       { "userspace",          'u', POPT_ARG_VAL, &opt_userspace, 1, 0, 0, },
+       { "pid",                'p', POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_pid_string, OPT_PID, 0, 0, },
+       { "all",                'a', POPT_ARG_VAL, &opt_all, 1, 0, 0, },
+       { "list-options",       0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, 0, 0, },
+       { 0, 0, 0, 0, 0, 0, 0, },
+};
+
+/*
+ * usage
+ */
+static void usage(FILE *ofp, const char *cmd_str)
+{
+       fprintf(ofp, "usage: lttng %s [-k|-u] [OPTIONS]\n", cmd_str);
+       fprintf(ofp, "\n");
+       fprintf(ofp, "If no session is given (-s), the context is added to\n");
+       fprintf(ofp, "the current sesssion. Exactly one domain (-k or -u)\n");
+       fprintf(ofp, "must be specified.\n");
+       fprintf(ofp, "\n");
+       fprintf(ofp, "Options:\n");
+       fprintf(ofp, "  -h, --help               Show this help.\n");
+       fprintf(ofp, "      --list-options       Simple listing of options.\n");
+       fprintf(ofp, "  -s, --session NAME       Apply to session name.\n");
+       fprintf(ofp, "  -k, --kernel             Apply to the kernel tracer.\n");
+       fprintf(ofp, "  -u, --userspace          Apply to the user-space tracer.\n");
+       fprintf(ofp, "  -p, --pid [PID]          Process ID tracker. Leave PID empty when used with --all.\n");
+       fprintf(ofp, "  -a, --all                All PIDs (use with --pid).\n");
+       fprintf(ofp, "\n");
+}
+
+static
+int parse_pid_string(const char *_pid_string,
+               int all, int **_pid_list, int *nr_pids)
+{
+       const char *one_pid_str;
+       char *iter;
+       int retval = CMD_SUCCESS;
+       int count = 0;
+       int *pid_list = NULL;
+       char *pid_string = NULL;
+
+       if (all && _pid_string) {
+               ERR("An empty PID string is expected with --all");
+               retval = CMD_ERROR;
+               goto error;
+       }
+       if (!all && !_pid_string) {
+               ERR("Please specify --all with an empty PID string");
+               retval = CMD_ERROR;
+               goto error;
+       }
+       if (all) {
+               pid_list = zmalloc(sizeof(*_pid_list));
+               if (!pid_list) {
+                       ERR("Out of memory");
+                       retval = CMD_ERROR;
+                       goto error;
+               }
+               /* Empty PID string means all PIDs */
+               count = 1;
+               pid_list[0] = -1;
+               goto assign;
+       }
+
+       pid_string = strdup(_pid_string);
+       if (!pid_string) {
+               ERR("Out of memory");
+               retval = CMD_ERROR;
+               goto error;
+       }
+
+       /* Count */
+       one_pid_str = strtok_r(pid_string, ",", &iter);
+       while (one_pid_str != NULL) {
+               unsigned long v;
+
+               v = strtoul(one_pid_str, NULL, 10);
+               if ((v == 0 && errno == EINVAL)
+                               || (v == ULONG_MAX && errno == ERANGE)) {
+                       ERR("Error parsing PID %s", one_pid_str);
+                       retval = CMD_ERROR;
+                       goto error;
+               }
+               if ((long) v > INT_MAX || (int) v < 0) {
+                       ERR("Invalid PID value %ld", (long) v);
+                       retval = CMD_ERROR;
+                       goto error;
+               }
+               count++;
+
+               /* For next loop */
+               one_pid_str = strtok_r(NULL, ",", &iter);
+       }
+
+       free(pid_string);
+       /* Identity of delimiter has been lost in first pass. */
+       pid_string = strdup(_pid_string);
+       if (!pid_string) {
+               ERR("Out of memory");
+               retval = CMD_ERROR;
+               goto error;
+       }
+
+       /* Allocate */
+       pid_list = zmalloc(count * sizeof(*pid_list));
+       if (!pid_list) {
+               ERR("Out of memory");
+               retval = CMD_ERROR;
+               goto error;
+       }
+
+       /* Copy */
+       count = 0;
+       one_pid_str = strtok_r(pid_string, ",", &iter);
+       while (one_pid_str != NULL) {
+               unsigned long v;
+
+               v = strtoul(one_pid_str, NULL, 10);
+               pid_list[count++] = (int) v;
+
+               /* For next loop */
+               one_pid_str = strtok_r(NULL, ",", &iter);
+       }
+
+assign:
+       *nr_pids = count;
+       *_pid_list = pid_list;
+       goto end;       /* SUCCESS */
+
+       /* ERROR */
+error:
+       free(pid_list);
+end:
+       free(pid_string);
+       return retval;
+}
+
+static
+int track_untrack_pid(enum cmd_type cmd_type, const char *cmd_str,
+               const char *session_name, const char *pid_string,
+               int all, struct mi_writer *writer)
+{
+       int ret, retval = CMD_SUCCESS, i;
+       int *pid_list = NULL;
+       int nr_pids;
+       struct lttng_domain dom;
+       struct lttng_handle *handle = NULL;
+       int (*lib_func)(struct lttng_handle *handle, int pid);
+
+       switch (cmd_type) {
+       case CMD_TRACK:
+               lib_func = lttng_track_pid;
+               break;
+       case CMD_UNTRACK:
+               lib_func = lttng_untrack_pid;
+               break;
+       default:
+               ERR("Unknown command");
+               retval = CMD_ERROR;
+               goto end;
+       }
+
+       memset(&dom, 0, sizeof(dom));
+       if (opt_kernel) {
+               dom.type = LTTNG_DOMAIN_KERNEL;
+       } else if (opt_userspace) {
+               dom.type = LTTNG_DOMAIN_UST;
+       } else {
+               print_missing_domain();
+               ret = CMD_ERROR;
+               goto end;
+       }
+
+       ret = parse_pid_string(pid_string, all, &pid_list, &nr_pids);
+       if (ret != CMD_SUCCESS) {
+               ERR("Error parsing PID string");
+               usage(stderr, cmd_str);
+               retval = CMD_ERROR;
+               goto end;
+       }
+
+       handle = lttng_create_handle(session_name, &dom);
+       if (handle == NULL) {
+               retval = CMD_ERROR;
+               goto end;
+       }
+
+       if (writer) {
+               /* Open pids element */
+               ret = mi_lttng_writer_open_element(writer, config_element_pids);
+               if (ret) {
+                       retval = CMD_ERROR;
+                       goto end;
+               }
+       }
+
+       /* TODO: MI */
+       for (i = 0; i < nr_pids; i++) {
+               DBG("%s PID %d", cmd_str, pid_list[i]);
+               ret = lib_func(handle, pid_list[i]);
+               if (ret) {
+                       retval = CMD_ERROR;
+                       goto end;
+               }
+       }
+
+       if (writer) {
+               /* Close pids element */
+               ret = mi_lttng_writer_close_element(writer);
+               if (ret) {
+                       retval = CMD_ERROR;
+                       goto end;
+               }
+       }
+
+       /* SUCCESS */
+end:
+       if (handle) {
+               lttng_destroy_handle(handle);
+       }
+       free(pid_list);
+       return retval;
+}
+
+static
+const char *get_mi_element_command(enum cmd_type cmd_type)
+{
+       switch (cmd_type) {
+       case CMD_TRACK:
+               return mi_lttng_element_command_track;
+       case CMD_UNTRACK:
+               return mi_lttng_element_command_untrack;
+       default:
+               return NULL;
+       }
+}
+
+/*
+ * Add/remove tracker to/from session.
+ */
+static
+int cmd_track_untrack(enum cmd_type cmd_type, const char *cmd_str,
+               int argc, const char **argv)
+{
+       int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS;
+       int success = 1;
+       static poptContext pc;
+       char *session_name = NULL;
+       struct mi_writer *writer = NULL;
+
+       if (argc < 1) {
+               usage(stderr, cmd_str);
+               ret = CMD_ERROR;
+               goto end;
+       }
+
+       pc = poptGetContext(NULL, argc, argv, long_options, 0);
+       poptReadDefaultConfig(pc, 0);
+
+       while ((opt = poptGetNextOpt(pc)) != -1) {
+               switch (opt) {
+               case OPT_HELP:
+                       usage(stdout, cmd_str);
+                       goto end;
+               case OPT_LIST_OPTIONS:
+                       list_cmd_options(stdout, long_options);
+                       goto end;
+               case OPT_SESSION:
+               case OPT_PID:
+                       opt_pid = 1;
+                       break;
+               default:
+                       usage(stderr, cmd_str);
+                       ret = CMD_UNDEFINED;
+                       goto end;
+               }
+       }
+
+       if (!(opt_userspace ^ opt_kernel)) {
+               ERR("Exactly one of -u or -k needs to be specified.");
+               usage(stderr, cmd_str);
+               ret = CMD_ERROR;
+               goto end;
+       }
+
+       if (!opt_session_name) {
+               session_name = get_session_name();
+               if (session_name == NULL) {
+                       ret = CMD_ERROR;
+                       goto end;
+               }
+       } else {
+               session_name = opt_session_name;
+       }
+
+       /* Currently only PID tracker is supported */
+       if (!opt_pid) {
+               ERR("Please specify at least one tracker with its expected arguments");
+               usage(stderr, cmd_str);
+               ret = CMD_ERROR;
+               goto end;
+       }
+
+       /* Mi check */
+       if (lttng_opt_mi) {
+               writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
+               if (!writer) {
+                       ret = CMD_ERROR;
+                       goto end;
+               }
+       }
+
+       if (writer) {
+               /* Open command element */
+               ret = mi_lttng_writer_command_open(writer,
+                               get_mi_element_command(cmd_type));
+               if (ret) {
+                       ret = CMD_ERROR;
+                       goto end;
+               }
+
+               /* Open output element */
+               ret = mi_lttng_writer_open_element(writer,
+                               mi_lttng_element_command_output);
+               if (ret) {
+                       ret = CMD_ERROR;
+                       goto end;
+               }
+       }
+
+       command_ret = track_untrack_pid(cmd_type,
+                       cmd_str, session_name, opt_pid_string,
+                       opt_all, writer);
+       if (command_ret) {
+               success = 0;
+       }
+
+       /* Mi closing */
+       if (writer) {
+               /* Close  output element */
+               ret = mi_lttng_writer_close_element(writer);
+               if (ret) {
+                       ret = CMD_ERROR;
+                       goto end;
+               }
+
+               /* Success ? */
+               ret = mi_lttng_writer_write_element_bool(writer,
+                               mi_lttng_element_command_success, success);
+               if (ret) {
+                       ret = CMD_ERROR;
+                       goto end;
+               }
+
+               /* Command element close */
+               ret = mi_lttng_writer_command_close(writer);
+               if (ret) {
+                       ret = CMD_ERROR;
+                       goto end;
+               }
+       }
+
+end:
+       if (!opt_session_name) {
+               free(session_name);
+       }
+
+       /* Mi clean-up */
+       if (writer && mi_lttng_writer_destroy(writer)) {
+               /* Preserve original error code */
+               ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL;
+       }
+
+       /* Overwrite ret if an error occurred during track() */
+       ret = command_ret ? command_ret : ret;
+
+       poptFreeContext(pc);
+       return ret;
+}
+
+int cmd_track(int argc, const char **argv)
+{
+       return cmd_track_untrack(CMD_TRACK, "track", argc, argv);
+}
+
+int cmd_untrack(int argc, const char **argv)
+{
+       return cmd_track_untrack(CMD_UNTRACK, "untrack", argc, argv);
+}
index 8e5bb0fd468cd52b670f8dfef3b62250b7ec5aed..13c77321eb1a208544161e7317f9ad8e0379344a 100644 (file)
@@ -85,6 +85,8 @@ static struct cmd_struct commands[] =  {
        { "snapshot", cmd_snapshot},
        { "save", cmd_save},
        { "load", cmd_load},
+       { "track", cmd_track},
+       { "untrack", cmd_untrack},
        { NULL, NULL}   /* Array closure */
 };
 
@@ -126,6 +128,8 @@ static void usage(FILE *ofp)
        fprintf(ofp, "    view              Start trace viewer\n");
        fprintf(ofp, "    save              Save session configuration\n");
        fprintf(ofp, "    load              Load session configuration\n");
+       fprintf(ofp, "    track             Track specific system resources\n");
+       fprintf(ofp, "    untrack           Untrack specific system resources\n");
        fprintf(ofp, "\n");
        fprintf(ofp, "Each command also has its own -h, --help option.\n");
        fprintf(ofp, "\n");
index 1a1feec0676ddd8c101e7ba4e4d5cb604e923655..8cbff25f5e33bda443ed32fd1e93b728fa37a215 100644 (file)
@@ -65,6 +65,8 @@ const char * const config_element_net_output;
 const char * const config_element_control_uri;
 const char * const config_element_data_uri;
 const char * const config_element_max_size;
+const char * const config_element_pid;
+const char * const config_element_pids;
 
 const char * const config_domain_type_kernel;
 const char * const config_domain_type_ust;
index ece7cdb2a0e161339f661cfa1bd8b6cb37fc7138..d84e38b9fa7b25b71de57bdc07ecb90997811b72 100644 (file)
@@ -115,6 +115,8 @@ const char * const config_element_net_output = "net_output";
 const char * const config_element_control_uri = "control_uri";
 const char * const config_element_data_uri = "data_uri";
 const char * const config_element_max_size = "max_size";
+const char * const config_element_pid = "pid";
+const char * const config_element_pids = "pids";
 
 const char * const config_domain_type_kernel = "KERNEL";
 const char * const config_domain_type_ust = "UST";
index b223ceac80f3bdab1a6ba6fd84d160802da6467e..7168c362c9fdf9785833006e8fa5e2c5911f6954 100644 (file)
@@ -217,6 +217,16 @@ end:
        return ret;
 }
 
+int kernctl_track_pid(int fd, int pid)
+{
+       return ioctl(fd, LTTNG_KERNEL_SESSION_TRACK_PID, pid);
+}
+
+int kernctl_untrack_pid(int fd, int pid)
+{
+       return ioctl(fd, LTTNG_KERNEL_SESSION_UNTRACK_PID, pid);
+}
+
 int kernctl_create_stream(int fd)
 {
        return compat_ioctl_no_arg(fd, LTTNG_KERNEL_OLD_STREAM,
index d9e6c54a4a408313e35c660fccc62476987d87b2..e854eba0e3b31060473ab579a99355a6dc909da0 100644 (file)
@@ -59,6 +59,10 @@ int kernctl_disable_syscall(int fd, const char *syscall_name);
 int kernctl_syscall_mask(int fd, char **syscall_mask,
                uint32_t *nr_bits);
 
+/* Process ID tracking can be applied to session FD */
+int kernctl_track_pid(int fd, int pid);
+int kernctl_untrack_pid(int fd, int pid);
+
 /* Buffer operations */
 
 /* For mmap mode, readable without "get" operation */
index 927de6fd69409f3e8e25119b36715b1ec753547f..4050350ed6532d31d25c0496a92aa20a5497f3c2 100644 (file)
        _IOW(0xF6, 0x55, struct lttng_kernel_channel)
 #define LTTNG_KERNEL_SESSION_START             _IO(0xF6, 0x56)
 #define LTTNG_KERNEL_SESSION_STOP              _IO(0xF6, 0x57)
+#define LTTNG_KERNEL_SESSION_TRACK_PID         \
+       _IOR(0xF6, 0x58, int32_t)
+#define LTTNG_KERNEL_SESSION_UNTRACK_PID       \
+       _IOR(0xF6, 0x59, int32_t)
 
 /* Channel FD ioctl */
 #define LTTNG_KERNEL_STREAM                    _IO(0xF6, 0x62)
index fed09854a206012482d320b770f666ed9b3cdb53..44ff56f1e4ccf16aee5d097b39faa4d233d0f04c 100644 (file)
@@ -50,6 +50,8 @@ const char * const mi_lttng_element_command_snapshot_record = "record_snapshot";
 const char * const mi_lttng_element_command_start = "start";
 const char * const mi_lttng_element_command_stop = "stop";
 const char * const mi_lttng_element_command_success = "success";
+const char * const mi_lttng_element_command_track = "track";
+const char * const mi_lttng_element_command_untrack = "untrack";
 const char * const mi_lttng_element_command_version = "version";
 
 /* Strings related to version command */
@@ -1238,6 +1240,9 @@ int mi_lttng_calibrate(struct mi_writer *writer,
 end:
        return ret;
 }
+
+/* TODO: mi tracker */
+
 LTTNG_HIDDEN
 int mi_lttng_context(struct mi_writer *writer,
                struct lttng_event_context *context, int is_open)
index fd1ef936eb4167fb409c4c34a5cb5f55ac7b9d42..02c6b731e10217cccd04d97547b47fcb0940f523 100644 (file)
@@ -73,6 +73,8 @@ const char * const mi_lttng_element_command_snapshot_record;
 const char * const mi_lttng_element_command_start;
 const char * const mi_lttng_element_command_stop;
 const char * const mi_lttng_element_command_success;
+const char * const mi_lttng_element_command_track;
+const char * const mi_lttng_element_command_untrack;
 const char * const mi_lttng_element_command_version;
 
 /* Strings related to version command */
index 5078b522b08280baea722578cb712f0bc0d26e9f..a56c914fc067d500ec1612923ddfebc6e295b401 100644 (file)
@@ -91,8 +91,8 @@ enum lttcomm_sessiond_command {
        LTTNG_CREATE_SESSION_SNAPSHOT       = 29,
        LTTNG_CREATE_SESSION_LIVE           = 30,
        LTTNG_SAVE_SESSION                  = 31,
-
-       /* Session daemon commands (cont.) */
+       LTTNG_TRACK_PID                     = 32,
+       LTTNG_UNTRACK_PID                   = 33,
        LTTNG_SET_SESSION_SHM_PATH          = 40,
 };
 
@@ -302,6 +302,9 @@ struct lttcomm_session_msg {
                struct {
                        char shm_path[PATH_MAX];
                } LTTNG_PACKED set_shm_path;
+               struct {
+                       uint32_t pid;
+               } LTTNG_PACKED pid_tracker;
        } u;
 } LTTNG_PACKED;
 
index 4332881c6eb7a41f538189a3dd3dcc41aed0ae30..c2210f48aa484c94393003e9f5b782ddbc5770c4 100644 (file)
@@ -1280,6 +1280,62 @@ int lttng_disable_channel(struct lttng_handle *handle, const char *name)
        return lttng_ctl_ask_sessiond(&lsm, NULL);
 }
 
+/*
+ *  Add PID to session tracker.
+ *  Return 0 on success else a negative LTTng error code.
+ */
+int lttng_track_pid(struct lttng_handle *handle, int pid)
+{
+       struct lttcomm_session_msg lsm;
+
+       /*
+        * NULL arguments are forbidden. No default values.
+        */
+       if (handle == NULL) {
+               return -LTTNG_ERR_INVALID;
+       }
+
+       memset(&lsm, 0, sizeof(lsm));
+
+       lsm.cmd_type = LTTNG_TRACK_PID;
+       lsm.u.pid_tracker.pid = pid;
+
+       lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain);
+
+       lttng_ctl_copy_string(lsm.session.name, handle->session_name,
+                       sizeof(lsm.session.name));
+
+       return lttng_ctl_ask_sessiond(&lsm, NULL);
+}
+
+/*
+ *  Remove PID from session tracker.
+ *  Return 0 on success else a negative LTTng error code.
+ */
+int lttng_untrack_pid(struct lttng_handle *handle, int pid)
+{
+       struct lttcomm_session_msg lsm;
+
+       /*
+        * NULL arguments are forbidden. No default values.
+        */
+       if (handle == NULL) {
+               return -LTTNG_ERR_INVALID;
+       }
+
+       memset(&lsm, 0, sizeof(lsm));
+
+       lsm.cmd_type = LTTNG_UNTRACK_PID;
+       lsm.u.pid_tracker.pid = pid;
+
+       lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain);
+
+       lttng_ctl_copy_string(lsm.session.name, handle->session_name,
+                       sizeof(lsm.session.name));
+
+       return lttng_ctl_ask_sessiond(&lsm, NULL);
+}
+
 /*
  *  Lists all available tracepoints of domain.
  *  Sets the contents of the events array.
This page took 0.039564 seconds and 4 git commands to generate.