*/
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
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.
*
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);
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.
* 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);
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 */
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 */
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;
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.
*/
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,
{
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 */
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
}
+ ret = list_tracker_pids();
+ if (ret) {
+ goto end;
+ }
+
ret = list_channels(opt_channel);
if (ret) {
goto end;
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;
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,
/* 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 */
_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)
LTTNG_SAVE_SESSION = 31,
LTTNG_TRACK_PID = 32,
LTTNG_UNTRACK_PID = 33,
+ LTTNG_LIST_TRACKER_PIDS = 34,
LTTNG_SET_SESSION_SHM_PATH = 40,
};
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
*/