Implement PID tracker content listing
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 28 Jan 2015 14:50:07 +0000 (09:50 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Mon, 30 Mar 2015 18:27:16 +0000 (14:27 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
14 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/trace-ust.c
src/bin/lttng-sessiond/trace-ust.h
src/bin/lttng/commands/list.c
src/common/kernel-ctl/kernel-ctl.c
src/common/kernel-ctl/kernel-ctl.h
src/common/kernel-ctl/kernel-ioctl.h
src/common/sessiond-comm/sessiond-comm.h
src/lib/lttng-ctl/lttng-ctl.c

index 7b1c8da6aa10825f66ad06aaa9ee76a440542c08..302f0fc026fc112a1e7d2effd635ed04a4db7da3 100644 (file)
@@ -136,6 +136,19 @@ extern int lttng_track_pid(struct lttng_handle *handle, int pid);
  */
 extern int lttng_untrack_pid(struct lttng_handle *handle, int pid);
 
+/*
+ * List PIDs in the tracker.
+ *
+ * @enabled is set to whether the PID tracker is enabled.
+ * @pids is set to an allocated array of PIDs currently tracked. On
+ * success, @pids must be freed by the caller.
+ * @nr_pids is set to the number of entries contained by the @pids array.
+ *
+ * Returns 0 on success, else a negative LTTng error code.
+ */
+extern int lttng_list_tracker_pids(struct lttng_handle *handle,
+               int *enabled, int32_t **pids, size_t *nr_pids);
+
 #ifdef __cplusplus
 }
 #endif
index 9ae5cff392d49ae67ea83eeb99acf1340bf19508..4c1609fd20366f95438b240504e1ab20ca8229b5 100644 (file)
@@ -1949,6 +1949,57 @@ ssize_t cmd_list_syscalls(struct lttng_event **events)
        return syscall_table_list(events);
 }
 
+/*
+ * Command LTTNG_LIST_TRACKER_PIDS processed by the client thread.
+ *
+ * Called with session lock held.
+ */
+ssize_t cmd_list_tracker_pids(struct ltt_session *session,
+               int domain, int32_t **pids)
+{
+       int ret;
+       ssize_t nr_pids = 0;
+
+       switch (domain) {
+       case LTTNG_DOMAIN_KERNEL:
+       {
+               struct ltt_kernel_session *ksess;
+
+               ksess = session->kernel_session;
+               nr_pids = kernel_list_tracker_pids(ksess, pids);
+               if (nr_pids < 0) {
+                       ret = LTTNG_ERR_KERN_LIST_FAIL;
+                       goto error;
+               }
+               break;
+       }
+       case LTTNG_DOMAIN_UST:
+       {
+               struct ltt_ust_session *usess;
+
+               usess = session->ust_session;
+               nr_pids = trace_ust_list_tracker_pids(usess, pids);
+               if (nr_pids < 0) {
+                       ret = LTTNG_ERR_UST_LIST_FAIL;
+                       goto error;
+               }
+               break;
+       }
+       case LTTNG_DOMAIN_LOG4J:
+       case LTTNG_DOMAIN_JUL:
+       case LTTNG_DOMAIN_PYTHON:
+       default:
+               ret = LTTNG_ERR_UND;
+               goto error;
+       }
+
+       return nr_pids;
+
+error:
+       /* Return negative value to differentiate return code */
+       return -ret;
+}
+
 /*
  * Command LTTNG_START_TRACE processed by the client thread.
  *
index 869bc70096af9a32f2a07a0c8627ee4da821e55f..359d946a6aff8b682d46e11d6dcca207db1e9571 100644 (file)
@@ -86,6 +86,8 @@ ssize_t cmd_list_tracepoints(int domain, struct lttng_event **events);
 ssize_t cmd_snapshot_list_outputs(struct ltt_session *session,
                struct lttng_snapshot_output **outputs);
 ssize_t cmd_list_syscalls(struct lttng_event **events);
+ssize_t cmd_list_tracker_pids(struct ltt_session *session,
+               int domain, int32_t **pids);
 
 int cmd_calibrate(int domain, struct lttng_calibrate *calibrate);
 int cmd_data_pending(struct ltt_session *session);
index 4bb418949d3ea330b60397ed2352f5541c7fcbdc..59d86f45ae1b399866d8656228cedb9c49ce5a37 100644 (file)
@@ -381,6 +381,77 @@ int kernel_untrack_pid(struct ltt_kernel_session *session, int pid)
        return kernctl_untrack_pid(session->fd, pid);
 }
 
+ssize_t kernel_list_tracker_pids(struct ltt_kernel_session *session,
+               int **_pids)
+{
+       int fd, ret;
+       int pid;
+       ssize_t nbmem, count = 0;
+       FILE *fp;
+       int *pids;
+
+       fd = kernctl_list_tracker_pids(session->fd);
+       if (fd < 0) {
+               PERROR("kernel tracker pids list");
+               goto error;
+       }
+
+       fp = fdopen(fd, "r");
+       if (fp == NULL) {
+               PERROR("kernel tracker pids list fdopen");
+               goto error_fp;
+       }
+
+       nbmem = KERNEL_TRACKER_PIDS_INIT_LIST_SIZE;
+       pids = zmalloc(sizeof(*pids) * nbmem);
+       if (pids == NULL) {
+               PERROR("alloc list pids");
+               count = -ENOMEM;
+               goto end;
+       }
+
+       while (fscanf(fp, "process { pid = %u; };\n", &pid) == 1) {
+               if (count >= nbmem) {
+                       int *new_pids;
+                       size_t new_nbmem;
+
+                       new_nbmem = nbmem << 1;
+                       DBG("Reallocating pids list from %zu to %zu entries",
+                                       nbmem, new_nbmem);
+                       new_pids = realloc(pids, new_nbmem * sizeof(*new_pids));
+                       if (new_pids == NULL) {
+                               PERROR("realloc list events");
+                               free(pids);
+                               count = -ENOMEM;
+                               goto end;
+                       }
+                       /* Zero the new memory */
+                       memset(new_pids + nbmem, 0,
+                               (new_nbmem - nbmem) * sizeof(*new_pids));
+                       nbmem = new_nbmem;
+                       pids = new_pids;
+               }
+               pids[count++] = pid;
+       }
+
+       *_pids = pids;
+       DBG("Kernel list tracker pids done (%zd pids)", count);
+end:
+       ret = fclose(fp);       /* closes both fp and fd */
+       if (ret) {
+               PERROR("fclose");
+       }
+       return count;
+
+error_fp:
+       ret = close(fd);
+       if (ret) {
+               PERROR("close");
+       }
+error:
+       return -1;
+}
+
 /*
  * Create kernel metadata, open from the kernel tracer and add it to the
  * kernel session.
index 3739bc9998abf59479b0a8af9d6db2fda79eccd9..a2d19f1434102e2d15b1ce790c28b9f43e42e2f1 100644 (file)
@@ -30,6 +30,7 @@
  * dynamic reallocation is performed.
  */
 #define KERNEL_EVENT_INIT_LIST_SIZE 64
+#define KERNEL_TRACKER_PIDS_INIT_LIST_SIZE 64
 
 int kernel_add_channel_context(struct ltt_kernel_channel *chan,
                struct ltt_kernel_context *ctx);
@@ -66,5 +67,7 @@ int kernel_snapshot_record(struct ltt_kernel_session *ksess,
 int kernel_syscall_mask(int chan_fd, char **syscall_mask, uint32_t *nr_bits);
 
 int init_kernel_workarounds(void);
+ssize_t kernel_list_tracker_pids(struct ltt_kernel_session *session,
+               int **_pids);
 
 #endif /* _LTT_KERNEL_CTL_H */
index 966f609177ad0b28104de59f827ec73f7101de24..b2a8f555c5fc072b39e1e922a5eef84a2b1b8f43 100644 (file)
@@ -2960,6 +2960,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock,
        case LTTNG_LIST_CHANNELS:
        case LTTNG_LIST_EVENTS:
        case LTTNG_LIST_SYSCALLS:
+       case LTTNG_LIST_TRACKER_PIDS:
                break;
        default:
                /* Setup lttng message with no payload */
@@ -3495,6 +3496,38 @@ skip_domain:
                ret = LTTNG_OK;
                break;
        }
+       case LTTNG_LIST_TRACKER_PIDS:
+       {
+               int32_t *pids = NULL;
+               ssize_t nr_pids;
+
+               nr_pids = cmd_list_tracker_pids(cmd_ctx->session,
+                               cmd_ctx->lsm->domain.type, &pids);
+               if (nr_pids < 0) {
+                       /* Return value is a negative lttng_error_code. */
+                       ret = -nr_pids;
+                       goto error;
+               }
+
+               /*
+                * Setup lttng message with payload size set to the event list size in
+                * bytes and then copy list into the llm payload.
+                */
+               ret = setup_lttng_msg(cmd_ctx, sizeof(int32_t) * nr_pids);
+               if (ret < 0) {
+                       free(pids);
+                       goto setup_error;
+               }
+
+               /* Copy event list into message payload */
+               memcpy(cmd_ctx->llm->payload, pids,
+                               sizeof(int) * nr_pids);
+
+               free(pids);
+
+               ret = LTTNG_OK;
+               break;
+       }
        case LTTNG_SET_CONSUMER_URI:
        {
                size_t nb_uri, len;
index e74ed62ba894862394576d9991ba93e41ede9489..2740d0f803a6d3393a2431dac53e85e85f21e846 100644 (file)
@@ -808,6 +808,50 @@ end:
        return retval;
 }
 
+/*
+ * Called with session lock held.
+ */
+ssize_t trace_ust_list_tracker_pids(struct ltt_ust_session *session,
+               int32_t **_pids)
+{
+       struct ust_pid_tracker_node *tracker_node;
+       struct lttng_ht_iter iter;
+       unsigned long count, i = 0;
+       long approx[2];
+       int32_t *pids;
+       int ret = 0;
+
+       if (!session->pid_tracker.ht) {
+               /* Tracker disabled. Set first entry to -1. */
+               pids = zmalloc(sizeof(*pids));
+               if (!pids) {
+                       ret = -1;
+                       goto end;
+               }
+               pids[0] = -1;
+               *_pids = pids;
+               return 1;
+       }
+
+       rcu_read_lock();
+       cds_lfht_count_nodes(session->pid_tracker.ht->ht,
+               &approx[0], &count, &approx[1]);
+       pids = zmalloc(sizeof(*pids) * count);
+       if (!pids) {
+               ret = -1;
+               goto end;
+       }
+       cds_lfht_for_each_entry(session->pid_tracker.ht->ht,
+                       &iter.iter, tracker_node, node.node) {
+               pids[i++] = tracker_node->node.key;
+       }
+       *_pids = pids;
+       ret = count;
+end:
+       rcu_read_unlock();
+       return ret;
+}
+
 /*
  * RCU safe free context structure.
  */
index ed1883c76bd4f831df56ed64cd259ee92be1c0cc..7d64269089d7a4f140754505c624dab74c3a6c8e 100644 (file)
@@ -204,6 +204,9 @@ void trace_ust_destroy_event(struct ltt_ust_event *event);
 int trace_ust_track_pid(struct ltt_ust_session *session, int pid);
 int trace_ust_untrack_pid(struct ltt_ust_session *session, int pid);
 
+ssize_t trace_ust_list_tracker_pids(struct ltt_ust_session *session,
+               int32_t **_pids);
+
 #else /* HAVE_LIBLTTNG_UST_CTL */
 
 static inline int trace_ust_ht_match_event(struct cds_lfht_node *node,
@@ -295,7 +298,11 @@ int trace_ust_untrack_pid(struct ltt_ust_session *session, int pid)
 {
        return 0;
 }
-
+ssize_t trace_ust_list_tracker_pids(struct ltt_ust_session *session,
+               int32_t **_pids)
+{
+       return -1;
+}
 #endif /* HAVE_LIBLTTNG_UST_CTL */
 
 #endif /* _LTT_TRACE_UST_H */
index aaa8f47a9ec4b157e44ca68fe9b4e0a9d712f161..b8d0046aa50e4491d82fd92c89c5a3a702b516b6 100644 (file)
@@ -1246,6 +1246,37 @@ error_channels:
        return ret;
 }
 
+/*
+ * List tracker PID(s) of session and domain.
+ */
+static int list_tracker_pids(void)
+{
+       int enabled, ret;
+       int *pids = NULL;
+       size_t nr_pids, i;
+
+       ret = lttng_list_tracker_pids(handle,
+               &enabled, &pids, &nr_pids);
+       if (ret) {
+               return ret;
+       }
+       _MSG("PID tracker: [%s]", enabled ? "enabled" : "disabled");
+       if (enabled) {
+               _MSG(", pids: [");
+
+               for (i = 0; i < nr_pids; i++) {
+                       if (i) {
+                               _MSG(",");
+                       }
+                       _MSG(" %d", pids[i]);
+               }
+               _MSG(" ]");
+       }
+       _MSG("\n\n");
+       free(pids);
+       return 0;
+}
+
 /*
  * Machine interface
  * Find the session with session_name as name
@@ -1667,6 +1698,11 @@ int cmd_list(int argc, const char **argv)
 
                        }
 
+                       ret = list_tracker_pids();
+                       if (ret) {
+                               goto end;
+                       }
+
                        ret = list_channels(opt_channel);
                        if (ret) {
                                goto end;
@@ -1754,6 +1790,18 @@ int cmd_list(int argc, const char **argv)
                                        continue;
                                }
 
+                               switch (domains[i].type) {
+                               case LTTNG_DOMAIN_KERNEL:
+                               case LTTNG_DOMAIN_UST:
+                                       ret = list_tracker_pids();
+                                       if (ret) {
+                                               goto end;
+                                       }
+                                       break;
+                               default:
+                                       break;
+                               }
+
                                ret = list_channels(opt_channel);
                                if (ret) {
                                        goto end;
index 7168c362c9fdf9785833006e8fa5e2c5911f6954..c6ff5c4457bd362b25a8203567db906d6c34cc37 100644 (file)
@@ -227,6 +227,11 @@ int kernctl_untrack_pid(int fd, int pid)
        return ioctl(fd, LTTNG_KERNEL_SESSION_UNTRACK_PID, pid);
 }
 
+int kernctl_list_tracker_pids(int fd)
+{
+       return ioctl(fd, LTTNG_KERNEL_SESSION_LIST_TRACKER_PIDS);
+}
+
 int kernctl_create_stream(int fd)
 {
        return compat_ioctl_no_arg(fd, LTTNG_KERNEL_OLD_STREAM,
index e854eba0e3b31060473ab579a99355a6dc909da0..5f2e014d19c0b3cc984bdf2a8b2f6fb95894a227 100644 (file)
@@ -62,6 +62,7 @@ int kernctl_syscall_mask(int fd, char **syscall_mask,
 /* 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);
+int kernctl_list_tracker_pids(int fd);
 
 /* Buffer operations */
 
index 4050350ed6532d31d25c0496a92aa20a5497f3c2..528c8082bf338c63aa3de229c54c41d823893481 100644 (file)
        _IOR(0xF6, 0x58, int32_t)
 #define LTTNG_KERNEL_SESSION_UNTRACK_PID       \
        _IOR(0xF6, 0x59, int32_t)
+#define LTTNG_KERNEL_SESSION_LIST_TRACKER_PIDS _IO(0xF6, 0x58)
 
 /* Channel FD ioctl */
 #define LTTNG_KERNEL_STREAM                    _IO(0xF6, 0x62)
index a56c914fc067d500ec1612923ddfebc6e295b401..1e51ae12352af6334c9293c013e8064027e9fe04 100644 (file)
@@ -93,6 +93,7 @@ enum lttcomm_sessiond_command {
        LTTNG_SAVE_SESSION                  = 31,
        LTTNG_TRACK_PID                     = 32,
        LTTNG_UNTRACK_PID                   = 33,
+       LTTNG_LIST_TRACKER_PIDS             = 34,
        LTTNG_SET_SESSION_SHM_PATH          = 40,
 };
 
index c2210f48aa484c94393003e9f5b782ddbc5770c4..004b0ccebf1c7b24e49674e2f3d66d53bfde7abe 100644 (file)
@@ -1990,6 +1990,51 @@ end:
        return ret;
 }
 
+/*
+ * List PIDs in the tracker.
+ *
+ * @enabled is set to whether the PID tracker is enabled.
+ * @pids is set to an allocated array of PIDs currently tracked. On
+ * success, @pids must be freed by the caller.
+ * @nr_pids is set to the number of entries contained by the @pids array.
+ *
+ * Returns 0 on success, else a negative LTTng error code.
+ */
+int lttng_list_tracker_pids(struct lttng_handle *handle,
+               int *_enabled, int32_t **_pids, size_t *_nr_pids)
+{
+       int ret, enabled = 1;
+       struct lttcomm_session_msg lsm;
+       size_t nr_pids;
+       int32_t *pids;
+
+       if (handle == NULL) {
+               return -LTTNG_ERR_INVALID;
+       }
+
+       memset(&lsm, 0, sizeof(lsm));
+       lsm.cmd_type = LTTNG_LIST_TRACKER_PIDS;
+       lttng_ctl_copy_string(lsm.session.name, handle->session_name,
+                       sizeof(lsm.session.name));
+       lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain);
+
+       ret = lttng_ctl_ask_sessiond(&lsm, (void **) &pids);
+       if (ret < 0) {
+               return ret;
+       }
+       nr_pids = ret / sizeof(int32_t);
+       if (nr_pids == 1 && pids[0] == -1) {
+               free(pids);
+               pids = NULL;
+               enabled = 0;
+               nr_pids = 0;
+       }
+       *_enabled = enabled;
+       *_pids = pids;
+       *_nr_pids = nr_pids;
+       return 0;
+}
+
 /*
  * lib constructor
  */
This page took 0.05043 seconds and 4 git commands to generate.