agent.c agent.h \
save.h save.c \
load-session-thread.h load-session-thread.c \
- syscall.h syscall.c
+ syscall.h syscall.c \
+ tracker.c tracker.h
if HAVE_LIBLTTNG_UST_CTL
lttng_sessiond_SOURCES += trace-ust.c ust-registry.c ust-app.c \
}
/*
- * Command LTTNG_TRACK_PID processed by the client thread.
+ * Command LTTNG_TRACK_ID processed by the client thread.
*
* Called with session lock held.
*/
-int cmd_track_pid(struct ltt_session *session, enum lttng_domain_type domain,
- int pid)
+int cmd_track_id(struct ltt_session *session,
+ enum lttng_tracker_type tracker_type,
+ enum lttng_domain_type domain,
+ struct lttng_tracker_id *id)
{
int ret;
ksess = session->kernel_session;
- ret = kernel_track_pid(ksess, pid);
+ ret = kernel_track_id(tracker_type, ksess, id);
if (ret != LTTNG_OK) {
goto error;
}
usess = session->ust_session;
- ret = trace_ust_track_pid(usess, pid);
+ ret = trace_ust_track_id(tracker_type, usess, id);
if (ret != LTTNG_OK) {
goto error;
}
}
/*
- * Command LTTNG_UNTRACK_PID processed by the client thread.
+ * Command LTTNG_UNTRACK_ID processed by the client thread.
*
* Called with session lock held.
*/
-int cmd_untrack_pid(struct ltt_session *session, enum lttng_domain_type domain,
- int pid)
+int cmd_untrack_id(struct ltt_session *session,
+ enum lttng_tracker_type tracker_type,
+ enum lttng_domain_type domain,
+ struct lttng_tracker_id *id)
{
int ret;
ksess = session->kernel_session;
- ret = kernel_untrack_pid(ksess, pid);
+ ret = kernel_untrack_id(tracker_type, ksess, id);
if (ret != LTTNG_OK) {
goto error;
}
usess = session->ust_session;
- ret = trace_ust_untrack_pid(usess, pid);
+ ret = trace_ust_untrack_id(tracker_type, usess, id);
if (ret != LTTNG_OK) {
goto error;
}
}
/*
- * Command LTTNG_LIST_TRACKER_PIDS processed by the client thread.
+ * Command LTTNG_LIST_TRACKER_IDS processed by the client thread.
*
* Called with session lock held.
*/
-ssize_t cmd_list_tracker_pids(struct ltt_session *session,
- enum lttng_domain_type domain, int32_t **pids)
+ssize_t cmd_list_tracker_ids(enum lttng_tracker_type tracker_type,
+ struct ltt_session *session,
+ enum lttng_domain_type domain,
+ struct lttng_tracker_id **ids)
{
int ret;
ssize_t nr_pids = 0;
struct ltt_kernel_session *ksess;
ksess = session->kernel_session;
- nr_pids = kernel_list_tracker_pids(ksess, pids);
+ nr_pids = kernel_list_tracker_ids(tracker_type, ksess, ids);
if (nr_pids < 0) {
ret = LTTNG_ERR_KERN_LIST_FAIL;
goto error;
struct ltt_ust_session *usess;
usess = session->ust_session;
- nr_pids = trace_ust_list_tracker_pids(usess, pids);
+ nr_pids = trace_ust_list_tracker_ids(tracker_type, usess, ids);
if (nr_pids < 0) {
ret = LTTNG_ERR_UST_LIST_FAIL;
goto error;
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, enum lttng_domain_type domain,
- int pid);
-int cmd_untrack_pid(struct ltt_session *session, enum lttng_domain_type domain,
- int pid);
+int cmd_track_id(struct ltt_session *session,
+ enum lttng_tracker_type tracker_type,
+ enum lttng_domain_type domain,
+ struct lttng_tracker_id *id);
+int cmd_untrack_id(struct ltt_session *session,
+ enum lttng_tracker_type tracker_type,
+ enum lttng_domain_type domain,
+ struct lttng_tracker_id *id);
/* Event commands */
int cmd_disable_event(struct ltt_session *session,
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,
- enum lttng_domain_type domain, int32_t **pids);
+ssize_t cmd_list_tracker_ids(enum lttng_tracker_type tracker_type,
+ struct ltt_session *session,
+ enum lttng_domain_type domain,
+ struct lttng_tracker_id **ids);
int cmd_data_pending(struct ltt_session *session);
return ret;
}
+static
+struct lttng_tracker_list *get_id_tracker_list(struct ltt_kernel_session *session,
+ enum lttng_tracker_type tracker_type)
+{
+ switch (tracker_type) {
+ case LTTNG_TRACKER_PID:
+ return session->tracker_list_pid;
+ case LTTNG_TRACKER_VPID:
+ return session->tracker_list_vpid;
+ case LTTNG_TRACKER_UID:
+ return session->tracker_list_uid;
+ case LTTNG_TRACKER_VUID:
+ return session->tracker_list_vuid;
+ case LTTNG_TRACKER_GID:
+ return session->tracker_list_gid;
+ case LTTNG_TRACKER_VGID:
+ return session->tracker_list_vgid;
+ default:
+ return NULL;
+ }
+}
-int kernel_track_pid(struct ltt_kernel_session *session, int pid)
+int kernel_track_id(enum lttng_tracker_type tracker_type,
+ struct ltt_kernel_session *session,
+ struct lttng_tracker_id *id)
{
- int ret;
+ int ret, value;
+ struct lttng_tracker_list *tracker_list;
+
+ ret = lttng_tracker_id_lookup_string(tracker_type,
+ id, &value);
+ if (ret != LTTNG_OK) {
+ return ret;
+ }
+
+ /* Add to list. */
+ tracker_list = get_id_tracker_list(session, tracker_type);
+ if (!tracker_list) {
+ return LTTNG_ERR_INVALID;
+ }
+ ret = lttng_tracker_list_add(tracker_list, id);
+ if (ret != LTTNG_OK) {
+ return ret;
+ }
- DBG("Kernel track PID %d for session id %" PRIu64 ".",
- pid, session->id);
- ret = kernctl_track_pid(session->fd, pid);
- if (!ret) {
- return LTTNG_OK;
+ switch (tracker_type) {
+ case LTTNG_TRACKER_PID:
+ DBG("Kernel track PID %d for session id %" PRIu64 ".",
+ value, session->id);
+ ret = kernctl_track_pid(session->fd, value);
+ if (!ret) {
+ return LTTNG_OK;
+ }
+ break;
+ case LTTNG_TRACKER_VPID:
+ DBG("Kernel track VPID %d for session id %" PRIu64 ".",
+ value, session->id);
+ ret = kernctl_track_id(session->fd, LTTNG_TRACKER_VPID, value);
+ if (!ret) {
+ return LTTNG_OK;
+ }
+ break;
+ case LTTNG_TRACKER_UID:
+ DBG("Kernel track UID %d for session id %" PRIu64 ".",
+ value, session->id);
+ ret = kernctl_track_id(session->fd, LTTNG_TRACKER_UID, value);
+ if (!ret) {
+ return LTTNG_OK;
+ }
+ break;
+ case LTTNG_TRACKER_GID:
+ DBG("Kernel track GID %d for session id %" PRIu64 ".",
+ value, session->id);
+ ret = kernctl_track_id(session->fd, LTTNG_TRACKER_GID, value);
+ if (!ret) {
+ return LTTNG_OK;
+ }
+ break;
+ case LTTNG_TRACKER_VUID:
+ DBG("Kernel track VUID %d for session id %" PRIu64 ".",
+ value, session->id);
+ ret = kernctl_track_id(session->fd, LTTNG_TRACKER_VUID, value);
+ if (!ret) {
+ return LTTNG_OK;
+ }
+ break;
+ case LTTNG_TRACKER_VGID:
+ DBG("Kernel track VGID %d for session id %" PRIu64 ".",
+ value, session->id);
+ ret = kernctl_track_id(session->fd, LTTNG_TRACKER_VGID, value);
+ if (!ret) {
+ return LTTNG_OK;
+ }
+ break;
+ default:
+ return LTTNG_ERR_INVALID;
}
switch (-ret) {
case EINVAL:
case ENOMEM:
return LTTNG_ERR_NOMEM;
case EEXIST:
- return LTTNG_ERR_PID_TRACKED;
+ return LTTNG_ERR_ID_TRACKED;
default:
return LTTNG_ERR_UNK;
}
}
-int kernel_untrack_pid(struct ltt_kernel_session *session, int pid)
+int kernel_untrack_id(enum lttng_tracker_type tracker_type,
+ struct ltt_kernel_session *session,
+ struct lttng_tracker_id *id)
{
- int ret;
+ int ret, value;
+ struct lttng_tracker_list *tracker_list;
- DBG("Kernel untrack PID %d for session id %" PRIu64 ".",
- pid, session->id);
- ret = kernctl_untrack_pid(session->fd, pid);
- if (!ret) {
- return LTTNG_OK;
+ ret = lttng_tracker_id_lookup_string(tracker_type,
+ id, &value);
+ if (ret != LTTNG_OK) {
+ return ret;
}
+
+ /* Remove from list. */
+ tracker_list = get_id_tracker_list(session, tracker_type);
+ if (!tracker_list) {
+ return LTTNG_ERR_INVALID;
+ }
+ ret = lttng_tracker_list_remove(tracker_list, id);
+ if (ret != LTTNG_OK) {
+ return ret;
+ }
+
+ switch (tracker_type) {
+ case LTTNG_TRACKER_PID:
+ DBG("Kernel untrack PID %d for session id %" PRIu64 ".",
+ value, session->id);
+ ret = kernctl_untrack_pid(session->fd, value);
+ if (!ret) {
+ return LTTNG_OK;
+ }
+ break;
+ case LTTNG_TRACKER_VPID:
+ DBG("Kernel untrack VPID %d for session id %" PRIu64 ".",
+ value, session->id);
+ ret = kernctl_untrack_id(session->fd, LTTNG_TRACKER_VPID, value);
+ if (!ret) {
+ return LTTNG_OK;
+ }
+ break;
+ case LTTNG_TRACKER_UID:
+ DBG("Kernel untrack UID %d for session id %" PRIu64 ".",
+ value, session->id);
+ ret = kernctl_untrack_id(session->fd, LTTNG_TRACKER_UID, value);
+ if (!ret) {
+ return LTTNG_OK;
+ }
+ break;
+ case LTTNG_TRACKER_GID:
+ DBG("Kernel untrack GID %d for session id %" PRIu64 ".",
+ value, session->id);
+ ret = kernctl_untrack_id(session->fd, LTTNG_TRACKER_GID, value);
+ if (!ret) {
+ return LTTNG_OK;
+ }
+ break;
+ case LTTNG_TRACKER_VUID:
+ DBG("Kernel untrack VUID %d for session id %" PRIu64 ".",
+ value, session->id);
+ ret = kernctl_untrack_id(session->fd, LTTNG_TRACKER_VUID, value);
+ if (!ret) {
+ return LTTNG_OK;
+ }
+ break;
+ case LTTNG_TRACKER_VGID:
+ DBG("Kernel untrack VGID %d for session id %" PRIu64 ".",
+ value, session->id);
+ ret = kernctl_untrack_id(session->fd, LTTNG_TRACKER_VGID, value);
+ if (!ret) {
+ return LTTNG_OK;
+ }
+ break;
+ default:
+ return LTTNG_ERR_INVALID;
+ }
+
switch (-ret) {
case EINVAL:
return LTTNG_ERR_INVALID;
case ENOMEM:
return LTTNG_ERR_NOMEM;
case ENOENT:
- return LTTNG_ERR_PID_NOT_TRACKED;
+ return LTTNG_ERR_ID_NOT_TRACKED;
default:
return LTTNG_ERR_UNK;
}
}
-ssize_t kernel_list_tracker_pids(struct ltt_kernel_session *session,
- int **_pids)
+/*
+ * Called with session lock held.
+ */
+ssize_t kernel_list_tracker_ids(enum lttng_tracker_type tracker_type,
+ struct ltt_kernel_session *session,
+ struct lttng_tracker_id **_ids)
{
- int fd, ret;
- int pid;
- ssize_t nbmem, count = 0;
- FILE *fp;
- int *pids;
+ struct lttng_tracker_list *tracker_list;
- 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;
+ tracker_list = get_id_tracker_list(session, tracker_type);
+ if (!tracker_list) {
+ return -LTTNG_ERR_INVALID;
}
-
- 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;
+ return lttng_tracker_id_get_list(tracker_list, _ids);
}
/*
* dynamic reallocation is performed.
*/
#define KERNEL_EVENT_INIT_LIST_SIZE 64
-#define KERNEL_TRACKER_PIDS_INIT_LIST_SIZE 64
+#define KERNEL_TRACKER_IDS_INIT_LIST_SIZE 64
int kernel_add_channel_context(struct ltt_kernel_channel *chan,
struct ltt_kernel_context *ctx);
int kernel_disable_event(struct ltt_kernel_event *event);
int kernel_enable_event(struct ltt_kernel_event *event);
int kernel_enable_channel(struct ltt_kernel_channel *chan);
-int kernel_track_pid(struct ltt_kernel_session *session, int pid);
-int kernel_untrack_pid(struct ltt_kernel_session *session, int pid);
+int kernel_track_id(enum lttng_tracker_type tracker_type,
+ struct ltt_kernel_session *session,
+ struct lttng_tracker_id *id);
+int kernel_untrack_id(enum lttng_tracker_type tracker_type,
+ struct ltt_kernel_session *session,
+ struct lttng_tracker_id *id);
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);
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);
+ssize_t kernel_list_tracker_ids(enum lttng_tracker_type tracker_type,
+ struct ltt_kernel_session *session,
+ struct lttng_tracker_id **_ids);
#endif /* _LTT_KERNEL_CTL_H */
#include <common/utils.h>
#include <common/daemonize.h>
#include <common/config/session-config.h>
+#include <common/dynamic-buffer.h>
#include "lttng-sessiond.h"
#include "buffer-registry.h"
case LTTNG_LIST_CHANNELS:
case LTTNG_LIST_EVENTS:
case LTTNG_LIST_SYSCALLS:
- case LTTNG_LIST_TRACKER_PIDS:
+ case LTTNG_LIST_TRACKER_IDS:
case LTTNG_DATA_PENDING:
break;
default:
&cmd_ctx->lsm->u.channel.chan, kernel_poll_pipe[1]);
break;
}
- case LTTNG_TRACK_PID:
+ case LTTNG_TRACK_ID:
{
- ret = cmd_track_pid(cmd_ctx->session,
+ struct lttng_tracker_id id;
+
+ memset(&id, 0, sizeof(id));
+ id.type = cmd_ctx->lsm->u.id_tracker.id_type;
+ switch (id.type) {
+ case LTTNG_ID_ALL:
+ break;
+ case LTTNG_ID_VALUE:
+ id.value = cmd_ctx->lsm->u.id_tracker.u.value;
+ break;
+ case LTTNG_ID_STRING:
+ {
+ size_t var_len = cmd_ctx->lsm->u.id_tracker.u.var_len;
+
+ id.string = zmalloc(var_len);
+ if (!id.string) {
+ ret = LTTNG_ERR_NOMEM;
+ goto error;
+ }
+ DBG("Receiving var len tracker id string from client.");
+ ret = lttcomm_recv_unix_sock(sock, id.string, var_len);
+ if (ret <= 0) {
+ DBG("Nothing received.");
+ *sock_error = 1;
+ free(id.string);
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+ if (strnlen(id.string, var_len) != var_len - 1) {
+ DBG("Corrupted string.");
+ free(id.string);
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+ break;
+ }
+ default:
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+ ret = cmd_track_id(cmd_ctx->session,
+ cmd_ctx->lsm->u.id_tracker.tracker_type,
cmd_ctx->lsm->domain.type,
- cmd_ctx->lsm->u.pid_tracker.pid);
+ &id);
break;
}
- case LTTNG_UNTRACK_PID:
+ case LTTNG_UNTRACK_ID:
{
- ret = cmd_untrack_pid(cmd_ctx->session,
+ struct lttng_tracker_id id;
+
+ memset(&id, 0, sizeof(id));
+ id.type = cmd_ctx->lsm->u.id_tracker.id_type;
+ switch (id.type) {
+ case LTTNG_ID_ALL:
+ break;
+ case LTTNG_ID_VALUE:
+ id.value = cmd_ctx->lsm->u.id_tracker.u.value;
+ break;
+ case LTTNG_ID_STRING:
+ {
+ size_t var_len = cmd_ctx->lsm->u.id_tracker.u.var_len;
+
+ id.string = zmalloc(var_len);
+ if (!id.string) {
+ ret = LTTNG_ERR_NOMEM;
+ goto error;
+ }
+ DBG("Receiving var len tracker id string from client.");
+ ret = lttcomm_recv_unix_sock(sock, id.string, var_len);
+ if (ret <= 0) {
+ DBG("Nothing received.");
+ *sock_error = 1;
+ free(id.string);
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+ if (strnlen(id.string, var_len) != var_len - 1) {
+ DBG("Corrupted string.");
+ free(id.string);
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+ break;
+ }
+ default:
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+ ret = cmd_untrack_id(cmd_ctx->session,
+ cmd_ctx->lsm->u.id_tracker.tracker_type,
cmd_ctx->lsm->domain.type,
- cmd_ctx->lsm->u.pid_tracker.pid);
+ &id);
break;
}
case LTTNG_ENABLE_EVENT:
ret = LTTNG_OK;
break;
}
- case LTTNG_LIST_TRACKER_PIDS:
+ case LTTNG_LIST_TRACKER_IDS:
{
- 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) {
+ struct lttcomm_tracker_command_header cmd_header;
+ struct lttng_tracker_id *ids = NULL;
+ ssize_t nr_ids, i;
+ struct lttng_dynamic_buffer buf;
+
+ nr_ids = cmd_list_tracker_ids(cmd_ctx->lsm->u.id_tracker.tracker_type,
+ cmd_ctx->session,
+ cmd_ctx->lsm->domain.type, &ids);
+ if (nr_ids < 0) {
/* Return value is a negative lttng_error_code. */
- ret = -nr_pids;
+ ret = -nr_ids;
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_no_cmd_header(cmd_ctx, pids,
- sizeof(int32_t) * nr_pids);
- free(pids);
+ lttng_dynamic_buffer_init(&buf);
+ for (i = 0; i < nr_ids; i++) {
+ struct lttng_tracker_id *id = &ids[i];
+ struct lttcomm_tracker_id_header id_hdr;
+ size_t var_data_len = 0;
+
+ memset(&id_hdr, 0, sizeof(id_hdr));
+ id_hdr.type = id->type;
+ switch (id->type) {
+ case LTTNG_ID_ALL:
+ break;
+ case LTTNG_ID_VALUE:
+ id_hdr.u.value = id->value;
+ break;
+ case LTTNG_ID_STRING:
+ id_hdr.u.var_data_len = var_data_len = strlen(id->string) + 1;
+ break;
+ default:
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+ ret = lttng_dynamic_buffer_append(&buf, &id_hdr, sizeof(id_hdr));
+ if (ret) {
+ ret = LTTNG_ERR_NOMEM;
+ goto error;
+ }
+ ret = lttng_dynamic_buffer_append(&buf, id->string, var_data_len);
+ if (ret) {
+ ret = LTTNG_ERR_NOMEM;
+ goto error;
+ }
+ }
+ cmd_header.nb_tracker_id = nr_ids;
+ ret = setup_lttng_msg(cmd_ctx, buf.data, buf.size, &cmd_header,
+ sizeof(cmd_header));
+ free(ids);
+ lttng_dynamic_buffer_reset(&buf);
if (ret < 0) {
goto setup_error;
}
#include "trace-ust.h"
#include "agent.h"
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_kernel_channel_attributes(struct config_writer *writer,
struct lttng_channel_attr *attr)
attr->overwrite ? config_overwrite_mode_overwrite :
config_overwrite_mode_discard);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
ret = config_writer_write_element_unsigned_int(writer,
config_element_subbuf_size, attr->subbuf_size);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_num_subbuf,
attr->num_subbuf);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_switch_timer_interval,
attr->switch_timer_interval);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_read_timer_interval,
attr->read_timer_interval);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
attr->output == LTTNG_EVENT_SPLICE ?
config_output_type_splice : config_output_type_mmap);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
ret = config_writer_write_element_unsigned_int(writer,
config_element_tracefile_size, attr->tracefile_size);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_tracefile_count,
attr->tracefile_count);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_live_timer_interval,
attr->live_timer_interval);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
end:
- return ret ? LTTNG_ERR_SAVE_IO_FAIL : 0;
+ return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_ust_channel_attributes(struct config_writer *writer,
struct lttng_ust_channel_attr *attr)
attr->overwrite ? config_overwrite_mode_overwrite :
config_overwrite_mode_discard);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
ret = config_writer_write_element_unsigned_int(writer,
config_element_subbuf_size, attr->subbuf_size);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_num_subbuf,
attr->num_subbuf);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_switch_timer_interval,
attr->switch_timer_interval);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_read_timer_interval,
attr->read_timer_interval);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
attr->output == LTTNG_UST_MMAP ?
config_output_type_mmap : config_output_type_splice);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
- return ret ? LTTNG_ERR_SAVE_IO_FAIL : 0;
+ return ret;
}
static
return loglevel_type_string;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_kernel_event(struct config_writer *writer,
struct ltt_kernel_event *event)
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_kernel_events(struct config_writer *writer,
struct ltt_kernel_channel *kchan)
cds_list_for_each_entry(event, &kchan->events_list.head, list) {
ret = save_kernel_event(writer, event);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_ust_event(struct config_writer *writer,
struct ltt_ust_event *event)
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_ust_events(struct config_writer *writer,
struct lttng_ht *events)
continue;
}
ret = save_ust_event(writer, event);
- if (ret) {
+ if (ret != LTTNG_OK) {
rcu_read_unlock();
goto end;
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int init_ust_event_from_agent_event(struct ltt_ust_event *ust_event,
struct agent_event *agent_event)
{
- int ret = 0;
+ int ret;
enum lttng_ust_loglevel_type ust_loglevel_type;
ust_event->enabled = agent_event->enabled;
ust_event->attr.instrumentation = LTTNG_UST_TRACEPOINT;
if (lttng_strncpy(ust_event->attr.name, agent_event->name,
LTTNG_SYMBOL_NAME_LEN)) {
- ret = -1;
+ ret = LTTNG_ERR_INVALID;
goto end;
}
switch (agent_event->loglevel_type) {
break;
default:
ERR("Invalid agent_event loglevel_type.");
- ret = -1;
+ ret = LTTNG_ERR_INVALID;
goto end;
}
ust_event->attr.loglevel = agent_event->loglevel_value;
ust_event->filter_expression = agent_event->filter_expression;
ust_event->exclusion = agent_event->exclusion;
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_agent_events(struct config_writer *writer,
struct ltt_ust_channel *chan,
* structures...).
*/
ret = init_ust_event_from_agent_event(&fake_event, agent_event);
- if (ret) {
+ if (ret != LTTNG_OK) {
rcu_read_unlock();
goto end;
}
ret = save_ust_event(writer, &fake_event);
- if (ret) {
+ if (ret != LTTNG_OK) {
rcu_read_unlock();
goto end;
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_kernel_context(struct config_writer *writer,
struct lttng_kernel_context *ctx)
{
- int ret = 0;
+ int ret = LTTNG_OK;
if (!ctx) {
goto end;
goto end;
}
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_kernel_contexts(struct config_writer *writer,
struct ltt_kernel_channel *kchan)
struct ltt_kernel_context *ctx;
if (cds_list_empty(&kchan->ctx_list)) {
- ret = 0;
+ ret = LTTNG_OK;
goto end;
}
cds_list_for_each_entry(ctx, &kchan->ctx_list, list) {
ret = save_kernel_context(writer, &ctx->ctx);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_ust_context_perf_thread_counter(struct config_writer *writer,
struct ltt_ust_context *ctx)
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_ust_context_app_ctx(struct config_writer *writer,
struct ltt_ust_context *ctx)
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_ust_context_generic(struct config_writer *writer,
struct ltt_ust_context *ctx)
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_ust_context(struct config_writer *writer,
struct cds_list_head *ctx_list)
/* Save generic context. */
ret = save_ust_context_generic(writer, ctx);
}
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_kernel_channel(struct config_writer *writer,
struct ltt_kernel_channel *kchan)
}
ret = save_kernel_channel_attributes(writer, &kchan->channel->attr);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
ret = save_kernel_events(writer, kchan);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
ret = save_kernel_contexts(writer, kchan);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_ust_channel(struct config_writer *writer,
struct ltt_ust_channel *ust_chan,
}
ret = save_ust_channel_attributes(writer, &ust_chan->attr);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
if (ust_chan->domain == LTTNG_DOMAIN_UST) {
ret = save_ust_events(writer, ust_chan->events);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
} else {
* them.
*/
ret = save_agent_events(writer, ust_chan, agent);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
}
ret = save_ust_context(writer, &ust_chan->ctx_list);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_kernel_session(struct config_writer *writer,
struct ltt_session *session)
cds_list_for_each_entry(kchan, &session->kernel_session->channel_list.head,
list) {
ret = save_kernel_channel(writer, kchan);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
return str_dom;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
-int save_pid_tracker(struct config_writer *writer,
- struct ltt_session *sess, int domain)
+int save_id_tracker(struct config_writer *writer,
+ struct ltt_session *sess, int domain,
+ enum lttng_tracker_type tracker_type)
{
- int ret = 0;
- ssize_t nr_pids = 0, i;
- int32_t *pids = NULL;
+ int ret = LTTNG_OK;
+ ssize_t nr_ids = 0, i;
+ struct lttng_tracker_id *ids = NULL;
+ const char *element_id_tracker, *element_target_id, *element_id;
+
+ switch (tracker_type) {
+ case LTTNG_TRACKER_PID:
+ element_id_tracker = config_element_pid_tracker;
+ element_target_id = config_element_target_pid;
+ element_id = config_element_pid;
+ break;
+ case LTTNG_TRACKER_VPID:
+ element_id_tracker = config_element_vpid_tracker;
+ element_target_id = config_element_target_vpid;
+ element_id = config_element_id;
+ break;
+ case LTTNG_TRACKER_UID:
+ element_id_tracker = config_element_uid_tracker;
+ element_target_id = config_element_target_uid;
+ element_id = config_element_id;
+ break;
+ case LTTNG_TRACKER_VUID:
+ element_id_tracker = config_element_vuid_tracker;
+ element_target_id = config_element_target_vuid;
+ element_id = config_element_id;
+ break;
+ case LTTNG_TRACKER_GID:
+ element_id_tracker = config_element_gid_tracker;
+ element_target_id = config_element_target_gid;
+ element_id = config_element_id;
+ break;
+ case LTTNG_TRACKER_VGID:
+ element_id_tracker = config_element_vgid_tracker;
+ element_target_id = config_element_target_vgid;
+ element_id = config_element_id;
+ break;
+ default:
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
switch (domain) {
case LTTNG_DOMAIN_KERNEL:
{
- nr_pids = kernel_list_tracker_pids(sess->kernel_session, &pids);
- if (nr_pids < 0) {
+ nr_ids = kernel_list_tracker_ids(tracker_type, sess->kernel_session, &ids);
+ if (nr_ids < 0) {
ret = LTTNG_ERR_KERN_LIST_FAIL;
goto end;
}
}
case LTTNG_DOMAIN_UST:
{
- nr_pids = trace_ust_list_tracker_pids(sess->ust_session, &pids);
- if (nr_pids < 0) {
+ nr_ids = trace_ust_list_tracker_ids(tracker_type, sess->ust_session, &ids);
+ if (nr_ids < 0) {
ret = LTTNG_ERR_UST_LIST_FAIL;
goto end;
}
goto end;
}
- /* Only create a pid_tracker if enabled or untrack all */
- if (nr_pids != 1 || (nr_pids == 1 && pids[0] != -1)) {
+
+ if (nr_ids == 1 && ids[0].type == LTTNG_ID_ALL) {
+ /* Tracking all, nothing to output. */
+ ret = LTTNG_OK;
+ goto end;
+ }
+
+ ret = config_writer_open_element(writer, element_id_tracker);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ ret = config_writer_open_element(writer,
+ config_element_targets);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ if (nr_ids == 0) {
+ /* Tracking none: empty list. */
ret = config_writer_open_element(writer,
- config_element_pid_tracker);
+ element_target_id);
if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
- ret = config_writer_open_element(writer,
- config_element_targets);
+ /* /$element_target_id */
+ ret = config_writer_close_element(writer);
if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
-
- for (i = 0; i < nr_pids; i++) {
- ret = config_writer_open_element(writer,
- config_element_target_pid);
- if (ret) {
+ } else {
+ /* Tracking list. */
+ for (i = 0; i < nr_ids; i++) {
+ switch (ids[i].type) {
+ case LTTNG_ID_VALUE:
+ ret = config_writer_open_element(writer,
+ element_target_id);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+ ret = config_writer_write_element_unsigned_int(writer,
+ element_id, ids[i].value);
+ break;
+ case LTTNG_ID_STRING:
+ ret = config_writer_open_element(writer,
+ element_target_id);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+ ret = config_writer_write_element_string(writer,
+ config_element_name, ids[i].string);
+ break;
+ default:
+ /* Unexpected. */
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
-
- ret = config_writer_write_element_unsigned_int(writer,
- config_element_pid, pids[i]);
if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
- /* /pid_target */
+ /* /$element_target_id */
ret = config_writer_close_element(writer);
if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
}
+ }
- /* /targets */
- ret = config_writer_close_element(writer);
- if (ret) {
- ret = LTTNG_ERR_SAVE_IO_FAIL;
- goto end;
- }
+ /* /targets */
+ ret = config_writer_close_element(writer);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
- /* /pid_tracker */
- ret = config_writer_close_element(writer);
- if (ret) {
- ret = LTTNG_ERR_SAVE_IO_FAIL;
- goto end;
- }
+ /* /$element_id_tracker */
+ ret = config_writer_close_element(writer);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
}
+
+ ret = LTTNG_OK;
end:
- free(pids);
+ free(ids);
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
+static
+int save_id_trackers(struct config_writer *writer,
+ struct ltt_session *sess, int domain)
+{
+ int ret;
+
+ switch (domain) {
+ case LTTNG_DOMAIN_KERNEL:
+ ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_PID);
+ if (ret != LTTNG_OK)
+ return ret;
+ ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_VPID);
+ if (ret != LTTNG_OK)
+ return ret;
+ ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_UID);
+ if (ret != LTTNG_OK)
+ return ret;
+ ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_VUID);
+ if (ret != LTTNG_OK)
+ return ret;
+ ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_GID);
+ if (ret != LTTNG_OK)
+ return ret;
+ ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_VGID);
+ if (ret != LTTNG_OK)
+ return ret;
+ break;
+ case LTTNG_DOMAIN_UST:
+ ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_VPID);
+ if (ret != LTTNG_OK)
+ return ret;
+ ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_VUID);
+ if (ret != LTTNG_OK)
+ return ret;
+ ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_VGID);
+ if (ret != LTTNG_OK)
+ return ret;
+ break;
+ default:
+ return LTTNG_ERR_INVALID;
+ }
+ return LTTNG_OK;
+}
+
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_ust_domain(struct config_writer *writer,
struct ltt_session *session, enum lttng_domain_type domain)
ust_chan = caa_container_of(node, struct ltt_ust_channel, node);
if (domain == ust_chan->domain) {
ret = save_ust_channel(writer, ust_chan, session->ust_session);
- if (ret) {
+ if (ret != LTTNG_OK) {
rcu_read_unlock();
goto end;
}
goto end;
}
- ret = save_pid_tracker(writer, session, LTTNG_DOMAIN_UST);
- if (ret) {
+ ret = save_id_trackers(writer, session, LTTNG_DOMAIN_UST);
+ if (ret != LTTNG_OK) {
goto end;
}
/* /trackers */
ret = config_writer_close_element(writer);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
}
goto end;
}
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_domains(struct config_writer *writer, struct ltt_session *session)
{
- int ret = 0;
+ int ret = LTTNG_OK;
assert(writer);
assert(session);
goto end;
}
-
if (session->kernel_session) {
ret = config_writer_open_element(writer,
config_element_domain);
}
ret = save_kernel_session(writer, session);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
goto end;
}
- ret = save_pid_tracker(writer, session, LTTNG_DOMAIN_KERNEL);
- if (ret) {
+ ret = save_id_trackers(writer, session, LTTNG_DOMAIN_KERNEL);
+ if (ret != LTTNG_OK) {
goto end;
}
if (session->ust_session) {
ret = save_ust_domain(writer, session, LTTNG_DOMAIN_UST);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
ret = save_ust_domain(writer, session, LTTNG_DOMAIN_JUL);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
ret = save_ust_domain(writer, session, LTTNG_DOMAIN_LOG4J);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
ret = save_ust_domain(writer, session, LTTNG_DOMAIN_PYTHON);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_consumer_output(struct config_writer *writer,
struct consumer_output *output)
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end_net_output;
}
-
+ ret = LTTNG_OK;
end_net_output:
free(uri);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
} else {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_snapshot_outputs(struct config_writer *writer,
struct snapshot *snapshot)
}
ret = save_consumer_output(writer, output->consumer);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end_unlock;
}
goto end;
}
+ ret = LTTNG_OK;
end:
return ret;
end_unlock:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_session_output(struct config_writer *writer,
struct ltt_session *session)
if ((session->snapshot_mode && session->snapshot.nb_output == 0) ||
(!session->snapshot_mode && !session->consumer)) {
/* Session is in no output mode */
- ret = 0;
+ ret = LTTNG_OK;
goto end;
}
if (session->snapshot_mode) {
ret = save_snapshot_outputs(writer, &session->snapshot);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
} else {
if (session->consumer) {
ret = save_consumer_output(writer, session->consumer);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+ ret = LTTNG_OK;
end:
return ret;
}
/*
* Save the given session.
*
- * Return 0 on success else a LTTNG_ERR* code.
+ * Return LTTNG_OK on success else a LTTNG_ERR* code.
*/
static
int save_session(struct ltt_session *session,
goto end;
}
- if(session->shm_path[0] != '\0') {
+ if (session->shm_path[0] != '\0') {
ret = config_writer_write_element_string(writer,
config_element_shared_memory_path,
session->shm_path);
}
ret = save_domains(writer, session);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
}
ret = save_session_output(writer, session);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
if (writer && config_writer_destroy(writer)) {
/* Preserve the original error code */
- ret = ret ? ret : LTTNG_ERR_SAVE_IO_FAIL;
+ ret = ret != LTTNG_OK ? ret : LTTNG_ERR_SAVE_IO_FAIL;
}
- if (ret) {
+ if (ret != LTTNG_OK) {
/* Delete file in case of error */
if (file_opened && unlink(config_file_path)) {
PERROR("Unlinking XML session configuration.");
}
if (file_opened) {
- ret = close(fd);
- if (ret) {
+ int closeret;
+
+ closeret = close(fd);
+ if (closeret) {
PERROR("Closing XML session configuration");
}
}
session_lock(session);
ret = save_session(session, attr, creds);
session_unlock(session);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
} else {
session_unlock(session);
/* Don't abort if we don't have the required permissions. */
- if (ret && ret != LTTNG_ERR_EPERM) {
+ if (ret != LTTNG_OK && ret != LTTNG_ERR_EPERM) {
goto end;
}
}
lks->metadata = NULL;
CDS_INIT_LIST_HEAD(&lks->channel_list.head);
+ lks->tracker_list_pid = lttng_tracker_list_create();
+ if (!lks->tracker_list_pid) {
+ goto error;
+ }
+ lks->tracker_list_vpid = lttng_tracker_list_create();
+ if (!lks->tracker_list_vpid) {
+ goto error;
+ }
+ lks->tracker_list_uid = lttng_tracker_list_create();
+ if (!lks->tracker_list_uid) {
+ goto error;
+ }
+ lks->tracker_list_vuid = lttng_tracker_list_create();
+ if (!lks->tracker_list_vuid) {
+ goto error;
+ }
+ lks->tracker_list_gid = lttng_tracker_list_create();
+ if (!lks->tracker_list_gid) {
+ goto error;
+ }
+ lks->tracker_list_vgid = lttng_tracker_list_create();
+ if (!lks->tracker_list_vgid) {
+ goto error;
+ }
lks->consumer = consumer_create_output(CONSUMER_DST_LOCAL);
if (lks->consumer == NULL) {
goto error;
return lks;
error:
+ lttng_tracker_list_destroy(lks->tracker_list_pid);
+ lttng_tracker_list_destroy(lks->tracker_list_vpid);
+ lttng_tracker_list_destroy(lks->tracker_list_uid);
+ lttng_tracker_list_destroy(lks->tracker_list_vuid);
+ lttng_tracker_list_destroy(lks->tracker_list_gid);
+ lttng_tracker_list_destroy(lks->tracker_list_vgid);
free(lks);
alloc_error:
/* Wipe consumer output object */
consumer_output_put(session->consumer);
+ lttng_tracker_list_destroy(session->tracker_list_pid);
+ lttng_tracker_list_destroy(session->tracker_list_vpid);
+ lttng_tracker_list_destroy(session->tracker_list_uid);
+ lttng_tracker_list_destroy(session->tracker_list_vuid);
+ lttng_tracker_list_destroy(session->tracker_list_gid);
+ lttng_tracker_list_destroy(session->tracker_list_vgid);
+
free(session);
}
#include <common/defaults.h>
#include "consumer.h"
+#include "tracker.h"
/* Kernel event list */
struct ltt_kernel_event_list {
unsigned int output_traces;
unsigned int snapshot_mode;
unsigned int has_non_default_channel;
+
+ struct lttng_tracker_list *tracker_list_pid;
+ struct lttng_tracker_list *tracker_list_vpid;
+ struct lttng_tracker_list *tracker_list_uid;
+ struct lttng_tracker_list *tracker_list_vuid;
+ struct lttng_tracker_list *tracker_list_gid;
+ struct lttng_tracker_list *tracker_list_vgid;
};
/*
#include "utils.h"
#include "ust-app.h"
#include "agent.h"
+#include "tracker.h"
/*
* Match function for the events hash table lookup.
lus = zmalloc(sizeof(struct ltt_ust_session));
if (lus == NULL) {
PERROR("create ust session zmalloc");
- goto error;
+ goto error_alloc;
}
/* Init data structure */
/* Alloc agent hash table. */
lus->agents = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
+ lus->tracker_list_vpid = lttng_tracker_list_create();
+ if (!lus->tracker_list_vpid) {
+ goto error;
+ }
+ lus->tracker_list_vuid = lttng_tracker_list_create();
+ if (!lus->tracker_list_vuid) {
+ goto error;
+ }
+ lus->tracker_list_vgid = lttng_tracker_list_create();
+ if (!lus->tracker_list_vgid) {
+ goto error;
+ }
lus->consumer = consumer_create_output(CONSUMER_DST_LOCAL);
if (lus->consumer == NULL) {
- goto error_consumer;
+ goto error;
}
DBG2("UST trace session create successful");
return lus;
-error_consumer:
+error:
+ lttng_tracker_list_destroy(lus->tracker_list_vpid);
+ lttng_tracker_list_destroy(lus->tracker_list_vuid);
+ lttng_tracker_list_destroy(lus->tracker_list_vgid);
ht_cleanup_push(lus->domain_global.channels);
ht_cleanup_push(lus->agents);
free(lus);
-error:
+error_alloc:
return NULL;
}
}
static
-void destroy_pid_tracker_node_rcu(struct rcu_head *head)
+void destroy_id_tracker_node_rcu(struct rcu_head *head)
{
- struct ust_pid_tracker_node *tracker_node =
- caa_container_of(head, struct ust_pid_tracker_node, node.head);
+ struct ust_id_tracker_node *tracker_node =
+ caa_container_of(head, struct ust_id_tracker_node, node.head);
free(tracker_node);
}
static
-void destroy_pid_tracker_node(struct ust_pid_tracker_node *tracker_node)
+void destroy_id_tracker_node(struct ust_id_tracker_node *tracker_node)
{
- call_rcu(&tracker_node->node.head, destroy_pid_tracker_node_rcu);
+ call_rcu(&tracker_node->node.head, destroy_id_tracker_node_rcu);
}
static
-int init_pid_tracker(struct ust_pid_tracker *pid_tracker)
+int init_id_tracker(struct ust_id_tracker *id_tracker)
{
- int ret = 0;
+ int ret = LTTNG_OK;
- pid_tracker->ht = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
- if (!pid_tracker->ht) {
- ret = -1;
+ id_tracker->ht = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
+ if (!id_tracker->ht) {
+ ret = LTTNG_ERR_NOMEM;
goto end;
}
}
/*
- * Teardown pid tracker content, but don't free pid_tracker object.
+ * Teardown id tracker content, but don't free id_tracker object.
*/
static
-void fini_pid_tracker(struct ust_pid_tracker *pid_tracker)
+void fini_id_tracker(struct ust_id_tracker *id_tracker)
{
- struct ust_pid_tracker_node *tracker_node;
+ struct ust_id_tracker_node *tracker_node;
struct lttng_ht_iter iter;
- if (!pid_tracker->ht) {
+ if (!id_tracker->ht) {
return;
}
rcu_read_lock();
- cds_lfht_for_each_entry(pid_tracker->ht->ht,
+ cds_lfht_for_each_entry(id_tracker->ht->ht,
&iter.iter, tracker_node, node.node) {
- int ret = lttng_ht_del(pid_tracker->ht, &iter);
+ int ret = lttng_ht_del(id_tracker->ht, &iter);
assert(!ret);
- destroy_pid_tracker_node(tracker_node);
+ destroy_id_tracker_node(tracker_node);
}
rcu_read_unlock();
- ht_cleanup_push(pid_tracker->ht);
- pid_tracker->ht = NULL;
+ ht_cleanup_push(id_tracker->ht);
+ id_tracker->ht = NULL;
}
static
-struct ust_pid_tracker_node *pid_tracker_lookup(
- struct ust_pid_tracker *pid_tracker, int pid,
+struct ust_id_tracker_node *id_tracker_lookup(
+ struct ust_id_tracker *id_tracker, int id,
struct lttng_ht_iter *iter)
{
- unsigned long _pid = (unsigned long) pid;
+ unsigned long _id = (unsigned long) id;
struct lttng_ht_node_ulong *node;
- lttng_ht_lookup(pid_tracker->ht, (void *) _pid, iter);
+ lttng_ht_lookup(id_tracker->ht, (void *) _id, iter);
node = lttng_ht_iter_get_node_ulong(iter);
if (node) {
- return caa_container_of(node, struct ust_pid_tracker_node,
+ return caa_container_of(node, struct ust_id_tracker_node,
node);
} else {
return NULL;
}
static
-int pid_tracker_add_pid(struct ust_pid_tracker *pid_tracker, int pid)
+int id_tracker_add_id(struct ust_id_tracker *id_tracker, int id)
{
int retval = LTTNG_OK;
- struct ust_pid_tracker_node *tracker_node;
+ struct ust_id_tracker_node *tracker_node;
struct lttng_ht_iter iter;
- if (pid < 0) {
+ if (id < 0) {
retval = LTTNG_ERR_INVALID;
goto end;
}
- tracker_node = pid_tracker_lookup(pid_tracker, pid, &iter);
+ tracker_node = id_tracker_lookup(id_tracker, id, &iter);
if (tracker_node) {
/* Already exists. */
- retval = LTTNG_ERR_PID_TRACKED;
+ retval = LTTNG_ERR_ID_TRACKED;
goto end;
}
tracker_node = zmalloc(sizeof(*tracker_node));
retval = LTTNG_ERR_NOMEM;
goto end;
}
- lttng_ht_node_init_ulong(&tracker_node->node, (unsigned long) pid);
- lttng_ht_add_unique_ulong(pid_tracker->ht, &tracker_node->node);
+ lttng_ht_node_init_ulong(&tracker_node->node, (unsigned long) id);
+ lttng_ht_add_unique_ulong(id_tracker->ht, &tracker_node->node);
end:
return retval;
}
static
-int pid_tracker_del_pid(struct ust_pid_tracker *pid_tracker, int pid)
+int id_tracker_del_id(struct ust_id_tracker *id_tracker, int id)
{
int retval = LTTNG_OK, ret;
- struct ust_pid_tracker_node *tracker_node;
+ struct ust_id_tracker_node *tracker_node;
struct lttng_ht_iter iter;
- if (pid < 0) {
+ if (id < 0) {
retval = LTTNG_ERR_INVALID;
goto end;
}
- tracker_node = pid_tracker_lookup(pid_tracker, pid, &iter);
+ tracker_node = id_tracker_lookup(id_tracker, id, &iter);
if (!tracker_node) {
/* Not found */
- retval = LTTNG_ERR_PID_NOT_TRACKED;
+ retval = LTTNG_ERR_ID_NOT_TRACKED;
goto end;
}
- ret = lttng_ht_del(pid_tracker->ht, &iter);
+ ret = lttng_ht_del(id_tracker->ht, &iter);
assert(!ret);
- destroy_pid_tracker_node(tracker_node);
+ destroy_id_tracker_node(tracker_node);
end:
return retval;
}
+static
+struct ust_id_tracker *get_id_tracker(struct ltt_ust_session *session,
+ enum lttng_tracker_type tracker_type)
+{
+ switch (tracker_type) {
+ case LTTNG_TRACKER_VPID:
+ return &session->vpid_tracker;
+ case LTTNG_TRACKER_VUID:
+ return &session->vuid_tracker;
+ case LTTNG_TRACKER_VGID:
+ return &session->vgid_tracker;
+ default:
+ return NULL;
+ }
+}
+
+static
+struct lttng_tracker_list *get_id_tracker_list(struct ltt_ust_session *session,
+ enum lttng_tracker_type tracker_type)
+{
+ switch (tracker_type) {
+ case LTTNG_TRACKER_VPID:
+ return session->tracker_list_vpid;
+ case LTTNG_TRACKER_VUID:
+ return session->tracker_list_vuid;
+ case LTTNG_TRACKER_VGID:
+ return session->tracker_list_vgid;
+ default:
+ return NULL;
+ }
+}
+
/*
* The session lock is held when calling this function.
*/
-int trace_ust_pid_tracker_lookup(struct ltt_ust_session *session, int pid)
+int trace_ust_id_tracker_lookup(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session, int id)
{
struct lttng_ht_iter iter;
+ struct ust_id_tracker *id_tracker;
- if (!session->pid_tracker.ht) {
+ id_tracker = get_id_tracker(session, tracker_type);
+ if (!id_tracker) {
+ abort();
+ }
+ if (!id_tracker->ht) {
return 1;
}
- if (pid_tracker_lookup(&session->pid_tracker, pid, &iter)) {
+ if (id_tracker_lookup(id_tracker, id, &iter)) {
return 1;
}
return 0;
/*
* Called with the session lock held.
*/
-int trace_ust_track_pid(struct ltt_ust_session *session, int pid)
+int trace_ust_track_id(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session,
+ struct lttng_tracker_id *id)
{
int retval = LTTNG_OK;
+ struct ust_id_tracker *id_tracker;
+ struct lttng_tracker_list *tracker_list;
+ int value;
+
+ if (tracker_type == LTTNG_TRACKER_PID) {
+ DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain.");
+ tracker_type = LTTNG_TRACKER_VPID;
+ }
+
+ retval = lttng_tracker_id_lookup_string(tracker_type,
+ id, &value);
+ if (retval != LTTNG_OK) {
+ return retval;
+ }
+
+ /* Add to list. */
+ tracker_list = get_id_tracker_list(session, tracker_type);
+ if (!tracker_list) {
+ return LTTNG_ERR_INVALID;
+ }
+ retval = lttng_tracker_list_add(tracker_list, id);
+ if (retval != LTTNG_OK) {
+ return retval;
+ }
- if (pid == -1) {
- /* Track all pids: destroy tracker if exists. */
- if (session->pid_tracker.ht) {
- fini_pid_tracker(&session->pid_tracker);
+ id_tracker = get_id_tracker(session, tracker_type);
+ if (!id_tracker) {
+ abort();
+ }
+ if (value == -1) {
+ /* Track all ids: destroy tracker if exists. */
+ if (id_tracker->ht) {
+ fini_id_tracker(id_tracker);
/* Ensure all apps have session. */
ust_app_global_update_all(session);
}
} else {
- int ret;
-
- if (!session->pid_tracker.ht) {
+ if (!id_tracker->ht) {
/* Create tracker. */
- if (init_pid_tracker(&session->pid_tracker)) {
- ERR("Error initializing PID tracker");
- retval = LTTNG_ERR_NOMEM;
+ retval = init_id_tracker(id_tracker);
+ if (retval != LTTNG_OK) {
+ ERR("Error initializing ID tracker");
goto end;
}
- ret = pid_tracker_add_pid(&session->pid_tracker, pid);
- if (ret != LTTNG_OK) {
- retval = ret;
- fini_pid_tracker(&session->pid_tracker);
+ retval = id_tracker_add_id(id_tracker, value);
+ if (retval != LTTNG_OK) {
+ fini_id_tracker(id_tracker);
goto end;
}
- /* Remove all apps from session except pid. */
+ /* Keep only apps matching ID. */
ust_app_global_update_all(session);
} else {
struct ust_app *app;
- ret = pid_tracker_add_pid(&session->pid_tracker, pid);
- if (ret != LTTNG_OK) {
- retval = ret;
+ retval = id_tracker_add_id(id_tracker, value);
+ if (retval != LTTNG_OK) {
goto end;
}
/* Add session to application */
- app = ust_app_find_by_pid(pid);
- if (app) {
- ust_app_global_update(session, app);
+ switch (tracker_type) {
+ case LTTNG_TRACKER_VPID:
+ app = ust_app_find_by_pid(value);
+ if (app) {
+ ust_app_global_update(session, app);
+ }
+ break;
+ default:
+ /* Keep only apps matching ID. */
+ ust_app_global_update_all(session);
}
}
}
/*
* Called with the session lock held.
*/
-int trace_ust_untrack_pid(struct ltt_ust_session *session, int pid)
+int trace_ust_untrack_id(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session, struct lttng_tracker_id *id)
{
int retval = LTTNG_OK;
+ struct ust_id_tracker *id_tracker;
+ struct lttng_tracker_list *tracker_list;
+ int value;
+
+ if (tracker_type == LTTNG_TRACKER_PID) {
+ DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain.");
+ tracker_type = LTTNG_TRACKER_VPID;
+ }
- if (pid == -1) {
+ retval = lttng_tracker_id_lookup_string(tracker_type,
+ id, &value);
+ if (retval != LTTNG_OK) {
+ return retval;
+ }
+
+ /* Remove from list. */
+ tracker_list = get_id_tracker_list(session, tracker_type);
+ if (!tracker_list) {
+ return LTTNG_ERR_INVALID;
+ }
+ retval = lttng_tracker_list_remove(tracker_list, id);
+ if (retval != LTTNG_OK) {
+ return retval;
+ }
+
+ id_tracker = get_id_tracker(session, tracker_type);
+ if (!id_tracker) {
+ abort();
+ }
+
+ if (value == -1) {
/* Create empty tracker, replace old tracker. */
- struct ust_pid_tracker tmp_tracker;
+ struct ust_id_tracker tmp_tracker;
- tmp_tracker = session->pid_tracker;
- if (init_pid_tracker(&session->pid_tracker)) {
- ERR("Error initializing PID tracker");
- retval = LTTNG_ERR_NOMEM;
+ tmp_tracker = *id_tracker;
+ retval = init_id_tracker(id_tracker);
+ if (retval != LTTNG_OK) {
+ ERR("Error initializing ID tracker");
/* Rollback operation. */
- session->pid_tracker = tmp_tracker;
+ *id_tracker = tmp_tracker;
goto end;
}
- fini_pid_tracker(&tmp_tracker);
+ fini_id_tracker(&tmp_tracker);
- /* Remove session from all applications */
+ /* Keep only apps matching ID. */
ust_app_global_update_all(session);
} else {
- int ret;
struct ust_app *app;
- if (!session->pid_tracker.ht) {
- /* No PID being tracked. */
- retval = LTTNG_ERR_PID_NOT_TRACKED;
+ if (!id_tracker->ht) {
+ /* No ID being tracked. */
+ retval = LTTNG_ERR_ID_NOT_TRACKED;
goto end;
}
- /* Remove PID from tracker */
- ret = pid_tracker_del_pid(&session->pid_tracker, pid);
- if (ret != LTTNG_OK) {
- retval = ret;
+ /* Remove ID from tracker */
+ retval = id_tracker_del_id(id_tracker, value);
+ if (retval != LTTNG_OK) {
goto end;
}
- /* Remove session from application. */
- app = ust_app_find_by_pid(pid);
- if (app) {
- ust_app_global_update(session, app);
+ switch (tracker_type) {
+ case LTTNG_TRACKER_VPID:
+ /* Remove session from application. */
+ app = ust_app_find_by_pid(value);
+ if (app) {
+ ust_app_global_update(session, app);
+ }
+ break;
+ default:
+ /* Keep only apps matching ID. */
+ ust_app_global_update_all(session);
}
}
end:
/*
* Called with session lock held.
*/
-ssize_t trace_ust_list_tracker_pids(struct ltt_ust_session *session,
- int32_t **_pids)
+ssize_t trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session,
+ struct lttng_tracker_id **_ids)
{
- 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;
+ struct lttng_tracker_list *tracker_list;
- 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;
+ if (tracker_type == LTTNG_TRACKER_PID) {
+ DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain.");
+ tracker_type = LTTNG_TRACKER_VPID;
}
- 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;
+ tracker_list = get_id_tracker_list(session, tracker_type);
+ if (!tracker_list) {
+ return -LTTNG_ERR_INVALID;
}
- *_pids = pids;
- ret = count;
-end:
- rcu_read_unlock();
- return ret;
+ return lttng_tracker_id_get_list(tracker_list, _ids);
}
/*
consumer_output_put(session->consumer);
- fini_pid_tracker(&session->pid_tracker);
+ lttng_tracker_list_destroy(session->tracker_list_vpid);
+ lttng_tracker_list_destroy(session->tracker_list_vuid);
+ lttng_tracker_list_destroy(session->tracker_list_vgid);
+
+ fini_id_tracker(&session->vpid_tracker);
+ fini_id_tracker(&session->vuid_tracker);
+ fini_id_tracker(&session->vgid_tracker);
free(session);
}
struct cds_list_head registry_buffer_uid_list;
};
-struct ust_pid_tracker_node {
+struct ust_id_tracker_node {
struct lttng_ht_node_ulong node;
};
-struct ust_pid_tracker {
+struct ust_id_tracker {
struct lttng_ht *ht;
};
char root_shm_path[PATH_MAX];
char shm_path[PATH_MAX];
- struct ust_pid_tracker pid_tracker;
+ /* Trackers used for actual lookup on app registration. */
+ struct ust_id_tracker vpid_tracker;
+ struct ust_id_tracker vuid_tracker;
+ struct ust_id_tracker vgid_tracker;
+
+ /* Tracker list of keys requested by users. */
+ struct lttng_tracker_list *tracker_list_vpid;
+ struct lttng_tracker_list *tracker_list_vuid;
+ struct lttng_tracker_list *tracker_list_vgid;
};
/*
void trace_ust_destroy_event(struct ltt_ust_event *event);
void trace_ust_destroy_context(struct ltt_ust_context *ctx);
-int trace_ust_track_pid(struct ltt_ust_session *session, int pid);
-int trace_ust_untrack_pid(struct ltt_ust_session *session, int pid);
+int trace_ust_track_id(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session,
+ struct lttng_tracker_id *id);
+int trace_ust_untrack_id(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session,
+ struct lttng_tracker_id *id);
-int trace_ust_pid_tracker_lookup(struct ltt_ust_session *session, int pid);
+int trace_ust_id_tracker_lookup(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session, int id);
-ssize_t trace_ust_list_tracker_pids(struct ltt_ust_session *session,
- int32_t **_pids);
+ssize_t trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session,
+ struct lttng_tracker_id **_ids);
#else /* HAVE_LIBLTTNG_UST_CTL */
return NULL;
}
static inline
-int trace_ust_track_pid(struct ltt_ust_session *session, int pid)
+int trace_ust_track_id(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session, int id)
{
return 0;
}
static inline
-int trace_ust_untrack_pid(struct ltt_ust_session *session, int pid)
+int trace_ust_untrack_id(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session, int id)
{
return 0;
}
static inline
-int trace_ust_pid_tracker_lookup(struct ltt_ust_session *session, int pid)
+int trace_ust_id_tracker_lookup(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session, int pid)
{
return 0;
}
static inline
-ssize_t trace_ust_list_tracker_pids(struct ltt_ust_session *session,
- int32_t **_pids)
+ssize_t trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session,
+ struct lttng_tracker_id **_ids)
{
return -1;
}
*/
continue;
}
- if (!trace_ust_pid_tracker_lookup(usess, app->pid)) {
+ if (!(trace_ust_id_tracker_lookup(LTTNG_TRACKER_VPID, usess, app->pid)
+ && trace_ust_id_tracker_lookup(LTTNG_TRACKER_VUID, usess, app->uid)
+ && trace_ust_id_tracker_lookup(LTTNG_TRACKER_VGID, usess, app->gid))) {
/* Skip. */
continue;
}
return;
}
- if (trace_ust_pid_tracker_lookup(usess, app->pid)) {
+ if (trace_ust_id_tracker_lookup(LTTNG_TRACKER_VPID, usess, app->pid)
+ && trace_ust_id_tracker_lookup(LTTNG_TRACKER_VUID, usess, app->uid)
+ && trace_ust_id_tracker_lookup(LTTNG_TRACKER_VGID, usess, app->gid)) {
ust_app_global_create(usess, app);
} else {
ust_app_global_destroy(usess, app);