lttng/userspace-probe-internal.h \
lttng/session-internal.h \
lttng/session-descriptor-internal.h \
- lttng/tracker-internal.h \
version.h \
version.i
LTTNG_ERR_EXCLUSION_NOMEM = 111, /* Lack of memory while processing event exclusions */
LTTNG_ERR_INVALID_EVENT_NAME = 112, /* Invalid event name */
LTTNG_ERR_INVALID_CHANNEL_NAME = 113, /* Invalid channel name */
- LTTNG_ERR_ID_TRACKED = 114, /* ID already tracked */
- LTTNG_ERR_ID_NOT_TRACKED = 115, /* ID not tracked */
+ LTTNG_ERR_PROCESS_ATTR_EXISTS = 114, /* Process attribute is already tracked */
+ LTTNG_ERR_PROCESS_ATTR_MISSING = 115, /* Process attribute was not tracked */
LTTNG_ERR_INVALID_CHANNEL_DOMAIN = 116, /* Invalid channel domain */
LTTNG_ERR_OVERFLOW = 117, /* Overflow occurred. */
LTTNG_ERR_SESSION_NOT_STARTED = 118, /* Session not started */
LTTNG_ERR_ROTATION_AFTER_STOP_CLEAR = 159, /* Session was already cleared since it became inactive. */
LTTNG_ERR_USER_NOT_FOUND = 160, /* User not found. */
LTTNG_ERR_GROUP_NOT_FOUND = 161, /* Group not found. */
+ LTTNG_ERR_UNSUPPORTED_DOMAIN = 162, /* Unsupported domain used. */
+ LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY = 163, /* Operation does not apply to the process attribute tracker's tracking policy */
/* MUST be last element of the manually-assigned section of the enum */
LTTNG_ERR_NR,
/* Backward-compatibility assignments */
- LTTNG_ERR_PID_TRACKED = LTTNG_ERR_ID_TRACKED, /* Backward compat alias to LTTNG_ERR_ID_TRACKED */
- LTTNG_ERR_PID_NOT_TRACKED = LTTNG_ERR_ID_NOT_TRACKED, /* Backward compat alias to LTTNG_ERR_ID_NOT_TRACKED */
+ LTTNG_ERR_PID_TRACKED = LTTNG_ERR_PROCESS_ATTR_EXISTS, /* Backward compat alias */
+ LTTNG_ERR_PID_NOT_TRACKED = LTTNG_ERR_PROCESS_ATTR_MISSING, /* Backward compat alias */
};
/*
+++ /dev/null
-/*
- * Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
- *
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- */
-
-#ifndef LTTNG_TRACKER_INTERNAL_H
-#define LTTNG_TRACKER_INTERNAL_H
-
-#include <common/macros.h>
-#include <common/dynamic-buffer.h>
-#include <lttng/constant.h>
-#include <lttng/tracker.h>
-#include <stdbool.h>
-
-struct lttng_tracker_id {
- enum lttng_tracker_id_type type;
- int value;
- char *string;
-};
-
-struct lttng_tracker_ids {
- struct lttng_tracker_id *id_array;
- unsigned int count;
-};
-
-LTTNG_HIDDEN
-bool lttng_tracker_id_is_equal(const struct lttng_tracker_id *left,
- const struct lttng_tracker_id *right);
-
-/*
- * A copy acts like memcpy. It does not allocate new memory.
- */
-LTTNG_HIDDEN
-int lttng_tracker_id_copy(struct lttng_tracker_id *dest,
- const struct lttng_tracker_id *src);
-
-/*
- * Duplicate an lttng_tracker_id.
- * The returned object must be freed via lttng_tracker_id_destroy.
- */
-LTTNG_HIDDEN
-struct lttng_tracker_id *lttng_tracker_id_duplicate(
- const struct lttng_tracker_id *src);
-
-/*
- * Allocate a new list of lttng_tracker_id.
- * The returned object must be freed via lttng_tracker_ids_destroy.
- */
-LTTNG_HIDDEN
-struct lttng_tracker_ids *lttng_tracker_ids_create(unsigned int base_count);
-
-/*
- * Return the non-const pointer of an element at index "index" of a
- * lttng_tracker_ids.
- *
- * The ownership of the lttng_tracker_id element is NOT transfered.
- * The returned object can NOT be freed via lttng_tracker_id_destroy.
- */
-LTTNG_HIDDEN
-struct lttng_tracker_id *lttng_tracker_ids_get_pointer_of_index(
- const struct lttng_tracker_ids *list, unsigned int index);
-
-/*
- * Serialize a ids collection to a lttng_dynamic_buffer.
- * Return LTTNG_OK on success, negative lttng error code on error.
- */
-LTTNG_HIDDEN
-int lttng_tracker_ids_serialize(const struct lttng_tracker_ids *ids,
- struct lttng_dynamic_buffer *buffer);
-
-#endif /* LTTNG_TRACKER_INTERNAL_H */
/*
* Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
+ * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
* SPDX-License-Identifier: LGPL-2.1-only
*
#define LTTNG_TRACKER_H
#include <lttng/constant.h>
+#include <lttng/domain.h>
+#include <lttng/lttng-error.h>
#include <lttng/session.h>
+#include <sys/types.h>
+
#ifdef __cplusplus
extern "C" {
#endif
-enum lttng_tracker_type {
- LTTNG_TRACKER_PID = 0,
- LTTNG_TRACKER_VPID = 1,
- LTTNG_TRACKER_UID = 2,
- LTTNG_TRACKER_GID = 3,
- LTTNG_TRACKER_VUID = 4,
- LTTNG_TRACKER_VGID = 5,
+/*
+ * Process attribute tracked by a tracker.
+ */
+enum lttng_process_attr {
+ /* Kernel space domain only. */
+ LTTNG_PROCESS_ATTR_PROCESS_ID = 0,
+ /* Kernel and user space domains. */
+ LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID = 1,
+ /* Kernel space domain only. */
+ LTTNG_PROCESS_ATTR_USER_ID = 2,
+ /* Kernel and user space domains. */
+ LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID = 3,
+ /* Kernel space domain only. */
+ LTTNG_PROCESS_ATTR_GROUP_ID = 4,
+ /* Kernel and user space domains. */
+ LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID = 5,
+};
+
+/*
+ * Tracking (filtering) policy of a process attribute tracker.
+ */
+enum lttng_tracking_policy {
+ /*
+ * Track all possible process attribute value of a given type
+ * (i.e. no filtering).
+ * This is the default state of a process attribute tracker.
+ */
+ LTTNG_TRACKING_POLICY_INCLUDE_ALL = 0,
+ /* Exclude all possible process attribute values of a given type. */
+ LTTNG_TRACKING_POLICY_EXCLUDE_ALL = 1,
+ /* Track a set of specific process attribute values. */
+ LTTNG_TRACKING_POLICY_INCLUDE_SET = 2,
+};
+
+/*
+ * Type of a process attribute value.
+ *
+ * This allows the use of the matching accessor given the type of a value.
+ */
+enum lttng_process_attr_value_type {
+ LTTNG_PROCESS_ATTR_VALUE_TYPE_INVALID = -1,
+ LTTNG_PROCESS_ATTR_VALUE_TYPE_PID = 0,
+ LTTNG_PROCESS_ATTR_VALUE_TYPE_UID = 1,
+ LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME = 2,
+ LTTNG_PROCESS_ATTR_VALUE_TYPE_GID = 3,
+ LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME = 4,
};
-enum lttng_tracker_id_type {
- LTTNG_ID_UNKNOWN = -1,
- LTTNG_ID_ALL = 0,
- LTTNG_ID_VALUE = 1,
- LTTNG_ID_STRING = 2,
+enum lttng_process_attr_tracker_handle_status {
+ LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_GROUP_NOT_FOUND = -7,
+ LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_USER_NOT_FOUND = -6,
+ LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY = -5,
+ LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST = -4,
+ LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR = -3,
+ LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR = -2,
+ LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID = -1,
+ LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK = 0,
+ LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_EXISTS = 1,
+ LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_MISSING = 2,
};
-enum lttng_tracker_id_status {
- /* Invalid tracker id parameter. */
- LTTNG_TRACKER_ID_STATUS_INVALID = -1,
- LTTNG_TRACKER_ID_STATUS_OK = 0,
- /* Tracker id parameter is unset. */
- LTTNG_TRACKER_ID_STATUS_UNSET = 1,
+enum lttng_process_attr_values_status {
+ LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID_TYPE = -2,
+ LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID = -1,
+ LTTNG_PROCESS_ATTR_VALUES_STATUS_OK = 0,
};
/*
- * A tracker id.
+ * A process attribute tracker handle.
+ *
+ * A process attribute tracker is an _inclusion set_ of process
+ * attribute values. Tracked processes are allowed to emit events,
+ * provided those events are targeted by enabled event rules.
+ *
+ * An LTTng session is created with a number of process attribute
+ * trackers by default. The process attributes that can be tracked vary by
+ * domain (see enum lttng_process_attr).
+ *
+ * Trackers are per-domain (user and kernel space) and allow the filtering
+ * of events based on a process's attributes.
*/
-struct lttng_tracker_id;
+struct lttng_process_attr_tracker_handle;
+
+/* A set of process attribute values. */
+struct lttng_process_attr_values;
/*
- * A collection of tracker id.
+ * Get a handle to one of the process attribute trackers of a session's domain.
+ *
+ * Returns LTTNG_OK and a process attribute tracker handle on success,
+ * or an lttng_error_code on error.
+ *
+ * The tracker's ownership is transfered to the caller. Use
+ * lttng_process_attr_tracker_handle_destroy() to dispose of it.
+ */
+extern enum lttng_error_code lttng_session_get_tracker_handle(
+ const char *session_name,
+ enum lttng_domain_type domain,
+ enum lttng_process_attr process_attr,
+ struct lttng_process_attr_tracker_handle **out_tracker_handle);
+
+/*
+ * Destroy a process attribute tracker handle.
*/
-struct lttng_tracker_ids;
+extern void lttng_process_attr_tracker_handle_destroy(
+ struct lttng_process_attr_tracker_handle *tracker_handle);
/*
- * Create a tracker id for the passed tracker type.
- * Users must set the tracker id using the matching API call.
+ * Get the tracking policy of a process attribute tracker.
*
- * On success, the caller is responsible for calling lttng_tracker_id_destroy.
- * On error, return NULL.
+ * Returns the LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK and the tracking
+ * policy of a process attribute tracker on success,
+ * LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID on error.
*/
-extern struct lttng_tracker_id *lttng_tracker_id_create(void);
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_tracker_handle_get_tracking_policy(
+ const struct lttng_process_attr_tracker_handle *tracker_handle,
+ enum lttng_tracking_policy *policy);
/*
- * Configure the tracker id using the numerical representation of the resource
- * to be tracked/untracked.
+ * Set the tracking policy of a process attribute tracker.
*
- * If the tracker id was already configured, calling this function will replace
- * the previous configuration and free memory as necessary.
+ * Setting the tracking policy to the current tracking policy has no effect.
*
- * Returns LTTNG_TRACKER_ID_STATUS_OK on success,
- * LTTNG_TRACKER_ID_STATUS_INVALID is the passed parameter is invalid.
+ * Returns the LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID on error.
*/
-extern enum lttng_tracker_id_status lttng_tracker_id_set_value(
- struct lttng_tracker_id *id, int value);
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_tracker_handle_set_tracking_policy(
+ const struct lttng_process_attr_tracker_handle *tracker_handle,
+ enum lttng_tracking_policy policy);
/*
- * Configure the tracker id using the string representation of the resource to
- * be tracked/untracked.
+ * Add a numerical PID to the process ID process attribute tracker inclusion
+ * set.
*
- * If the tracker id was already configured, calling this function will replace
- * the previous configuration and free memory as necessary.
+ * Returns LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_EXISTS if it was already
+ * present in the inclusion set, and
+ * LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID if an invalid tracker
+ * argument was provided.
+ */
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_process_id_tracker_handle_add_pid(
+ const struct lttng_process_attr_tracker_handle
+ *process_id_tracker,
+ pid_t pid);
+
+/*
+ * Remove a numerical PID from the process ID process attribute tracker include
+ * set.
*
- * Returns LTTNG_TRACKER_ID_STATUS_OK on success,
- * LTTNG_TRACKER_ID_STATUS_INVALID if the passed parameter is invalid.
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_MISSING if it was not present
+ * in the inclusion set, and LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if
+ * an invalid tracker argument was provided.
*/
-extern enum lttng_tracker_id_status lttng_tracker_id_set_string(
- struct lttng_tracker_id *id, const char *value);
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_process_id_tracker_handle_remove_pid(
+ const struct lttng_process_attr_tracker_handle
+ *process_id_tracker,
+ pid_t pid);
/*
- * Configure the tracker id to track/untrack all resources for the tracker type.
+ * Add a numerical PID to the virtual process ID process attribute tracker
+ * inclusion set.
*
- * If the tracker id was already configured, calling this function will replace
- * the previous configuration and free memory as necessary.
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_EXISTS if it was already
+ * present in the inclusion set, and
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if an invalid tracker
+ * argument was provided.
+ */
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_virtual_process_id_tracker_handle_add_pid(
+ const struct lttng_process_attr_tracker_handle
+ *process_id_tracker,
+ pid_t vpid);
+
+/*
+ * Remove a numerical PID from the virtual process ID process attribute tracker
+ * inclusion set.
*
- * Returns LTTNG_TRACKER_ID_STATUS_OK on success,
- * LTTNG_TRACKER_ID_STATUS_INVALID if the passed parameter is invalid.
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_MISSING if it was not present
+ * in the inclusion set, and LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if
+ * an invalid tracker argument was provided.
*/
-extern enum lttng_tracker_id_status lttng_tracker_id_set_all(
- struct lttng_tracker_id *id);
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_virtual_process_id_tracker_handle_remove_pid(
+ const struct lttng_process_attr_tracker_handle
+ *process_id_tracker,
+ pid_t vpid);
/*
- * Destroy a tracker id.
+ * Add a numerical UID to the user ID process attribute tracker inclusion set.
+ *
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_EXISTS if it was already
+ * present in the inclusion set, and
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if an invalid tracker
+ * argument was provided.
*/
-extern void lttng_tracker_id_destroy(struct lttng_tracker_id *id);
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_user_id_tracker_handle_add_uid(
+ const struct lttng_process_attr_tracker_handle *user_id_tracker,
+ uid_t uid);
/*
- * Get the type of a tracker id.
+ * Remove a numerical UID from the user ID process attribute tracker include
+ * set.
+ *
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_MISSING if it was not present
+ * in the inclusion set, and LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if
+ * an invalid tracker argument was provided.
*/
-extern enum lttng_tracker_id_type lttng_tracker_id_get_type(
- const struct lttng_tracker_id *id);
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_user_id_tracker_handle_remove_uid(
+ const struct lttng_process_attr_tracker_handle *user_id_tracker,
+ uid_t uid);
/*
- * Get the value of a tracker id.
+ * Add a user name to the user ID process attribute tracker inclusion set.
+ *
+ * The user name resolution is performed by the session daemon on addition to
+ * the user ID inclusion set.
*
- * Returns LTTNG_TRACKER_ID_OK on success,
- * LTTNG_TRACKER_ID_STATUS_INVALID when the tracker is not of type
- * LTTNG_ID_VALUE,
- * LTTNG_TRACKER_ID_STATUS_UNSET when the tracker is not set.
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_EXISTS if it was already
+ * present in the inclusion set, and
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if an invalid tracker
+ * argument was provided.
*/
-extern enum lttng_tracker_id_status lttng_tracker_id_get_value(
- const struct lttng_tracker_id *id, int *value);
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_user_id_tracker_handle_add_user_name(
+ const struct lttng_process_attr_tracker_handle *user_id_tracker,
+ const char *user_name);
/*
- * Get the string representation of the tracker id.
+ * Remove a user name from the user ID process attribute tracker include
+ * set.
+ *
+ * No name resolution is performed; the user name will be matched against the
+ * names in the inclusion set.
*
- * Returns LTTNG_TRACKER_ID_OK on success,
- * LTTNG_TRACKER_ID_STATUS_INVALID when the tracker is not of type
- * LTTNG_ID_STRING,
- * LTTNG_TRACKER_ID_STATUS_UNSET when the tracker is not set.
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_MISSING if it was not present
+ * in the inclusion set, and LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if
+ * an invalid tracker argument was provided.
*/
-extern enum lttng_tracker_id_status lttng_tracker_id_get_string(
- const struct lttng_tracker_id *id, const char **value);
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_user_id_tracker_handle_remove_user_name(
+ const struct lttng_process_attr_tracker_handle *user_id_tracker,
+ const char *user_name);
/*
- * Add ID to session tracker.
+ * Add a numerical UID to the virtual user ID process attribute tracker
+ * inclusion set.
*
- * tracker_type is the type of tracker.
- * id is the lttng_tracker_type to track.
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_EXISTS if it was already
+ * present in the inclusion set, and
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if an invalid tracker
+ * argument was provided.
+ */
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_virtual_user_id_tracker_handle_add_uid(
+ const struct lttng_process_attr_tracker_handle *user_id_tracker,
+ uid_t vuid);
+
+/*
+ * Remove a numerical UID from the virtual user ID process attribute tracker
+ * inclusion set.
*
- * Returns 0 on success else a negative LTTng error code.
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_MISSING if it was not present
+ * in the inclusion set, and LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if
+ * an invalid tracker argument was provided.
*/
-extern int lttng_track_id(struct lttng_handle *handle,
- enum lttng_tracker_type tracker_type,
- const struct lttng_tracker_id *id);
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_virtual_user_id_tracker_handle_remove_uid(
+ const struct lttng_process_attr_tracker_handle *user_id_tracker,
+ uid_t vuid);
/*
- * Remove ID from session tracker.
+ * Add a user name to the virtual user ID process attribute tracker include
+ * set.
+ *
+ * The user name resolution is performed by the session daemon on addition to
+ * the virtual user ID inclusion set.
*
- * tracker_type is the type of tracker.
- * id is the lttng_tracker_type to untrack.
- * Returns 0 on success else a negative LTTng error code.
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_EXISTS if it was already
+ * present in the inclusion set, and
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if an invalid tracker
+ * argument was provided.
*/
-extern int lttng_untrack_id(struct lttng_handle *handle,
- enum lttng_tracker_type tracker_type,
- const struct lttng_tracker_id *id);
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_virtual_user_id_tracker_handle_add_user_name(
+ const struct lttng_process_attr_tracker_handle *user_id_tracker,
+ const char *virtual_user_name);
/*
- * List IDs of a tracker.
+ * Remove a user name from the virtual user ID process attribute tracker
+ * inclusion set.
*
- * On success, ids is allocated.
- * The ids collection must be freed by the caller with lttng_destroy_ids().
+ * No name resolution is performed; the user name will be matched against the
+ * names in the inclusion set.
*
- * Returns 0 on success, else a negative LTTng error code.
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_MISSING if it was not present
+ * in the inclusion set, and LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if
+ * an invalid tracker argument was provided.
*/
-extern int lttng_list_tracker_ids(struct lttng_handle *handle,
- enum lttng_tracker_type tracker_type,
- struct lttng_tracker_ids **ids);
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_virtual_user_id_tracker_handle_remove_user_name(
+ const struct lttng_process_attr_tracker_handle *user_id_tracker,
+ const char *virtual_user_name);
/*
- * Backward compatibility.
- * Add PID to session tracker.
+ * Add a numerical GID to the group ID process attribute tracker inclusion set.
*
- * A pid argument >= 0 adds the PID to the session tracker.
- * A pid argument of -1 means "track all PIDs".
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_EXISTS if it was already
+ * present in the inclusion set, and
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if an invalid tracker
+ * argument was provided.
+ */
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_group_id_tracker_handle_add_gid(
+ const struct lttng_process_attr_tracker_handle *group_id_tracker,
+ gid_t gid);
+
+/*
+ * Remove a numerical GID from the group ID process attribute tracker include
+ * set.
*
- * Returns 0 on success else a negative LTTng error code.
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_MISSING if it was not present
+ * in the inclusion set, and LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if
+ * an invalid tracker argument was provided.
*/
-extern int lttng_track_pid(struct lttng_handle *handle, int pid);
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_group_id_tracker_handle_remove_gid(
+ const struct lttng_process_attr_tracker_handle *group_id_tracker,
+ gid_t gid);
/*
- * Backward compatibility.
- * Remove PID from session tracker.
+ * Add a group name to the group ID process attribute tracker inclusion set.
*
- * A pid argument >= 0 removes the PID from the session tracker.
- * A pid argument of -1 means "untrack all PIDs".
+ * The group name resolution is performed by the session daemon on addition to
+ * the group ID inclusion set.
*
- * Returns 0 on success else a negative LTTng error code.
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_EXISTS if it was already
+ * present in the inclusion set, and
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if an invalid tracker
+ * argument was provided.
*/
-extern int lttng_untrack_pid(struct lttng_handle *handle, int pid);
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_group_id_tracker_handle_add_group_name(
+ const struct lttng_process_attr_tracker_handle *group_id_tracker,
+ const char *group_name);
+
+/*
+ * Remove a group name from the group ID process attribute tracker include
+ * set.
+ *
+ * No name resolution is performed; the user name will be matched against the
+ * names in the inclusion set.
+ *
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_MISSING if it was not present
+ * in the inclusion set, and LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if
+ * an invalid tracker argument was provided.
+ */
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_group_id_tracker_handle_remove_group_name(
+ const struct lttng_process_attr_tracker_handle *group_id_tracker,
+ const char *group_name);
+
+/*
+ * Add a numerical GID to the virtual group ID process attribute tracker
+ * inclusion set.
+ *
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_EXISTS if it was already
+ * present in the inclusion set, and
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if an invalid tracker
+ * argument was provided.
+ */
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_virtual_group_id_tracker_handle_add_gid(
+ const struct lttng_process_attr_tracker_handle *group_id_tracker,
+ gid_t vgid);
+
+/*
+ * Remove a numerical GID from the virtual group ID process attribute tracker
+ * inclusion set.
+ *
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_MISSING if it was not present
+ * in the inclusion set, and LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if
+ * an invalid tracker argument was provided.
+ */
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_virtual_group_id_tracker_handle_remove_gid(
+ const struct lttng_process_attr_tracker_handle *group_id_tracker,
+ gid_t vgid);
+
+/*
+ * Add a group name to the virtual group ID process attribute tracker include
+ * set.
+ *
+ * The group name resolution is performed by the session daemon on addition to
+ * the virtual group ID inclusion set.
+ *
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_EXISTS if it was already
+ * present in the inclusion set, and
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if an invalid tracker
+ * argument was provided.
+ */
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_virtual_group_id_tracker_handle_add_group_name(
+ const struct lttng_process_attr_tracker_handle *group_id_tracker,
+ const char *virtual_group_name);
+
+/*
+ * Remove a group name from the virtual group ID process attribute tracker
+ * inclusion set.
+ *
+ * No name resolution is performed; the user name will be matched against the
+ * names in the inclusion set.
+ *
+ * Returns LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_MISSING if it was not present
+ * in the inclusion set, and LTTNG_PROCESS_ATTR_TRACKED_HANDLE_STATUS_INVALID if
+ * an invalid tracker argument was provided.
+ */
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_virtual_group_id_tracker_handle_remove_group_name(
+ const struct lttng_process_attr_tracker_handle *group_id_tracker,
+ const char *virtual_group_name);
+
+/*
+ * Get the process attribute values that are part of a tracker's inclusion set.
+ *
+ * The values returned are a snapshot of the values that are part of the
+ * tracker's inclusion set at the moment of the invocation; it is not updated
+ * as entries are added or removed.
+ *
+ * The values remain valid until the tracker is destroyed.
+ *
+ * Returns LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID if the tracker's policy is
+ * not LTTNG_POLICY_INCLUDE_SET.
+ */
+extern enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_tracker_handle_get_inclusion_set(
+ struct lttng_process_attr_tracker_handle *tracker_handle,
+ const struct lttng_process_attr_values **values);
/*
- * Backward compatibility
- * List PIDs in the tracker.
+ * Get the count of values within a set of process attribute values.
*
- * 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 LTTNG_PROCESS_ATTR_VALUES_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID if an invalid argument is provided.
+ */
+extern enum lttng_process_attr_values_status
+lttng_process_attr_values_get_count(
+ const struct lttng_process_attr_values *values,
+ unsigned int *count);
+
+/*
+ * Get the type of a process attribute value at a given index.
+ *
+ * Returns a process attribute value type on success,
+ * LTTNG_PROCESS_ATTR_VALUE_TYPE_INVALID if an invalid argument is provided.
+ */
+extern enum lttng_process_attr_value_type
+lttng_process_attr_values_get_type_at_index(
+ const struct lttng_process_attr_values *values,
+ unsigned int index);
+
+/*
+ * Get a process ID process attribute value.
+ *
+ * Returns LTTNG_PROCESS_ATTR_VALUES_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID_TYPE if the process attribute value
+ * is not a process ID.
+ */
+extern enum lttng_process_attr_values_status
+lttng_process_attr_values_get_pid_at_index(
+ const struct lttng_process_attr_values *values,
+ unsigned int index,
+ pid_t *pid);
+
+/*
+ * Get a user ID process attribute value.
+ *
+ * Returns LTTNG_PROCESS_ATTR_VALUES_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID_TYPE if the process attribute value
+ * is not a user ID.
+ */
+extern enum lttng_process_attr_values_status
+lttng_process_attr_values_get_uid_at_index(
+ const struct lttng_process_attr_values *values,
+ unsigned int index,
+ uid_t *uid);
+
+/*
+ * Get a user name process attribute value.
+ *
+ * Returns LTTNG_PROCESS_ATTR_VALUES_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID_TYPE if the process attribute value
+ * is not a user name.
+ */
+extern enum lttng_process_attr_values_status
+lttng_process_attr_values_get_user_name_at_index(
+ const struct lttng_process_attr_values *values,
+ unsigned int index,
+ const char **user_name);
+
+/*
+ * Get a group ID process attribute value.
+ *
+ * Returns LTTNG_PROCESS_ATTR_VALUES_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID_TYPE if the process attribute value
+ * is not a group ID.
+ */
+extern enum lttng_process_attr_values_status
+lttng_process_attr_values_get_gid_at_index(
+ const struct lttng_process_attr_values *values,
+ unsigned int index,
+ gid_t *gid);
+
+/*
+ * Get a group name process attribute value.
+ *
+ * Returns LTTNG_PROCESS_ATTR_VALUES_STATUS_OK on success,
+ * LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID_TYPE if the process attribute value
+ * is not a group name.
+ */
+extern enum lttng_process_attr_values_status
+lttng_process_attr_values_get_group_name_at_index(
+ const struct lttng_process_attr_values *values,
+ unsigned int index,
+ const char **group_name);
+
+/* The following entry points are deprecated. */
+
+/*
+ * Deprecated: see `lttng_process_attr_tracker_handle_get_inclusion_set` and
+ * `lttng_process_tracker_handle_get_tracking_policy`.
+ *
+ * List tracked PIDs.
+ *
+ * `enabled` indicates whether or not the PID tracker is enabled.
+ *
+ * `pids` is set to an allocated array of PIDs currently being tracked. On
+ * success, `pids` must be freed by the caller.
+ *
+ * `nr_pids` is set to the number of entries contained in the `pids` array.
*
* Returns 0 on success, else a negative LTTng error code.
*/
size_t *nr_pids);
/*
- * Get a tracker id from the list at a given index.
+ * Deprecated: see `lttng_process_attr_process_id_tracker_handle_add_pid`.
+ *
+ * Add PID to session tracker.
*
- * Note that the list maintains the ownership of the returned tracker id.
- * It must not be destroyed by the user, nor should it be held beyond the
- * lifetime of the tracker id list.
+ * A pid argument >= 0 adds the PID to the session's PID tracker.
+ * A pid argument of -1 means "track all PIDs".
*
- * Returns a tracker id, or NULL on error.
- */
-extern const struct lttng_tracker_id *lttng_tracker_ids_get_at_index(
- const struct lttng_tracker_ids *ids, unsigned int index);
-
-/*
- * Get the number of tracker id in a tracker id list.
+ * Note on 'real' PIDs vs 'virtual' VPIDs:
+ * - With the user space domain specified, this function will add a VPID
+ * value to the virtual process ID process attribute tracker's inclusion
+ * set.
+ * - With the kernel space domain specified, this function will add a PID
+ * value to the process ID process attribute tracker's inclusion set.
*
- * Return LTTNG_TRACKER_ID_STATUS on sucess,
- * LTTNG_TRACKER_ID_STATUS_INVALID when passed invalid parameters.
+ * Returns 0 on success, else a negative LTTng error code.
*/
-extern enum lttng_tracker_id_status lttng_tracker_ids_get_count(
- const struct lttng_tracker_ids *ids, unsigned int *count);
+extern int lttng_track_pid(struct lttng_handle *handle, int pid);
/*
- * Destroy a tracker id list.
+ * Deprecated: see `lttng_process_attr_process_id_tracker_handle_remove_pid`.
+ *
+ * Remove PID from session tracker.
+ *
+ * A pid argument >= 0 removes the PID from the session's PID tracker.
+ * A pid argument of -1 means "untrack all PIDs".
+ *
+ * Note on 'real' PIDs vs 'virtual' VPIDs:
+ * - With the user space domain specified, this function will remove a VPID
+ * value from the virtual process ID process attribute tracker's inclusion
+ * set.
+ * - With the kernel space domain specified, this function will remove a PID
+ * value from the process ID process attribute tracker's inclusion set.
+ *
+ * Returns 0 on success, else a negative LTTng error code.
*/
-extern void lttng_tracker_ids_destroy(struct lttng_tracker_ids *ids);
+extern int lttng_untrack_pid(struct lttng_handle *handle, int pid);
#ifdef __cplusplus
}
*
*/
-#include <stddef.h>
-#include <pthread.h>
-#include <signal.h>
-#include <sys/stat.h>
+#include "common/buffer-view.h"
+#include "common/dynamic-buffer.h"
+#include "common/sessiond-comm/sessiond-comm.h"
+#include "lttng/lttng-error.h"
+#include "lttng/tracker.h"
#include <common/compat/getenv.h>
+#include <common/tracker.h>
#include <common/unix.h>
#include <common/utils.h>
-#include <lttng/userspace-probe-internal.h>
#include <lttng/event-internal.h>
-#include <lttng/session-internal.h>
#include <lttng/session-descriptor-internal.h>
-#include <lttng/tracker-internal.h>
+#include <lttng/session-internal.h>
+#include <lttng/userspace-probe-internal.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stddef.h>
+#include <sys/stat.h>
#include "client.h"
#include "lttng-sessiond.h"
case LTTNG_LIST_CHANNELS:
case LTTNG_LIST_EVENTS:
case LTTNG_LIST_SYSCALLS:
- case LTTNG_LIST_TRACKER_IDS:
+ case LTTNG_SESSION_LIST_ROTATION_SCHEDULES:
+ case LTTNG_PROCESS_ATTR_TRACKER_GET_POLICY:
+ case LTTNG_PROCESS_ATTR_TRACKER_GET_INCLUSION_SET:
case LTTNG_DATA_PENDING:
case LTTNG_ROTATE_SESSION:
case LTTNG_ROTATION_GET_INFO:
- case LTTNG_SESSION_LIST_ROTATION_SCHEDULES:
break;
default:
/* Setup lttng message with no payload */
kernel_poll_pipe[1]);
break;
}
- case LTTNG_TRACK_ID:
+ case LTTNG_PROCESS_ATTR_TRACKER_ADD_INCLUDE_VALUE:
+ case LTTNG_PROCESS_ATTR_TRACKER_REMOVE_INCLUDE_VALUE:
{
- struct lttng_tracker_id *id = NULL;
- enum lttng_tracker_id_status status;
-
- id = lttng_tracker_id_create();
- if (!id) {
- ret = LTTNG_ERR_NOMEM;
+ struct lttng_dynamic_buffer payload;
+ struct lttng_buffer_view payload_view;
+ const bool add_value =
+ cmd_ctx->lsm->cmd_type ==
+ LTTNG_PROCESS_ATTR_TRACKER_ADD_INCLUDE_VALUE;
+ const size_t name_len =
+ cmd_ctx->lsm->u.process_attr_tracker_add_remove_include_value
+ .name_len;
+ const enum lttng_domain_type domain_type =
+ (enum lttng_domain_type)
+ cmd_ctx->lsm->domain.type;
+ const enum lttng_process_attr process_attr =
+ (enum lttng_process_attr) cmd_ctx->lsm->u
+ .process_attr_tracker_add_remove_include_value
+ .process_attr;
+ const enum lttng_process_attr_value_type value_type =
+ (enum lttng_process_attr_value_type) cmd_ctx
+ ->lsm->u
+ .process_attr_tracker_add_remove_include_value
+ .value_type;
+ struct process_attr_value *value;
+ enum lttng_error_code ret_code;
+
+ /* Receive remaining variable length payload if applicable. */
+ if (name_len > LOGIN_NAME_MAX) {
+ /*
+ * POSIX mandates user and group names that are at least
+ * 8 characters long. Note that although shadow-utils
+ * (useradd, groupaadd, etc.) use 32 chars as their
+ * limit (from bits/utmp.h, UT_NAMESIZE),
+ * LOGIN_NAME_MAX is defined to 256.
+ */
+ ERR("Rejecting process attribute tracker value %s as the provided exceeds the maximal allowed length: argument length = %zu, maximal length = %d",
+ add_value ? "addition" : "removal",
+ name_len, LOGIN_NAME_MAX);
+ ret = LTTNG_ERR_INVALID;
goto error;
}
- switch (cmd_ctx->lsm->u.id_tracker.id_type) {
- case LTTNG_ID_ALL:
- status = lttng_tracker_id_set_all(id);
- break;
- case LTTNG_ID_VALUE:
- status = lttng_tracker_id_set_value(
- id, cmd_ctx->lsm->u.id_tracker.u.value);
- break;
- case LTTNG_ID_STRING:
- {
- const size_t var_len = cmd_ctx->lsm->u.id_tracker.u.var_len;
- char *string = NULL;
-
- string = zmalloc(var_len);
- if (!string) {
- lttng_tracker_id_destroy(id);
+ lttng_dynamic_buffer_init(&payload);
+ if (name_len != 0) {
+ /*
+ * Receive variable payload for user/group name
+ * arguments.
+ */
+ ret = lttng_dynamic_buffer_set_size(&payload, name_len);
+ if (ret) {
+ ERR("Failed to allocate buffer to receive payload of %s process attribute tracker value argument",
+ add_value ? "add" : "remove");
ret = LTTNG_ERR_NOMEM;
- goto error;
+ goto error_add_remove_tracker_value;
}
- DBG("Receiving var len tracker id string from client");
- ret = lttcomm_recv_unix_sock(*sock, string, var_len);
+
+ ret = lttcomm_recv_unix_sock(
+ *sock, payload.data, name_len);
if (ret <= 0) {
- DBG("Nothing received");
+ ERR("Failed to receive payload of %s process attribute tracker value argument",
+ add_value ? "add" : "remove");
*sock_error = 1;
- free(string);
- lttng_tracker_id_destroy(id);
- ret = LTTNG_ERR_INVALID;
- goto error;
- }
- if (strnlen(string, var_len) != var_len - 1) {
- DBG("String received as tracker ID is not NULL-terminated");
- free(string);
- lttng_tracker_id_destroy(id);
- ret = LTTNG_ERR_INVALID;
- goto error;
+ ret = LTTNG_ERR_INVALID_PROTOCOL;
+ goto error_add_remove_tracker_value;
}
+ }
- status = lttng_tracker_id_set_string(id, string);
- free(string);
- break;
+ payload_view = lttng_buffer_view_from_dynamic_buffer(
+ &payload, 0, name_len);
+ /*
+ * Validate the value type and domains are legal for the process
+ * attribute tracker that is specified and convert the value to
+ * add/remove to the internal sessiond representation.
+ */
+ ret_code = process_attr_value_from_comm(domain_type,
+ process_attr, value_type,
+ &cmd_ctx->lsm->u.process_attr_tracker_add_remove_include_value
+ .integral_value,
+ &payload_view, &value);
+ if (ret_code != LTTNG_OK) {
+ ret = ret_code;
+ goto error_add_remove_tracker_value;
+ }
+
+ if (add_value) {
+ ret = cmd_process_attr_tracker_inclusion_set_add_value(
+ cmd_ctx->session, domain_type,
+ process_attr, value);
+ } else {
+ ret = cmd_process_attr_tracker_inclusion_set_remove_value(
+ cmd_ctx->session, domain_type,
+ process_attr, value);
}
- default:
- lttng_tracker_id_destroy(id);
- ret = LTTNG_ERR_INVALID;
+ process_attr_value_destroy(value);
+ error_add_remove_tracker_value:
+ lttng_dynamic_buffer_reset(&payload);
+ break;
+ }
+ case LTTNG_PROCESS_ATTR_TRACKER_GET_POLICY:
+ {
+ enum lttng_tracking_policy tracking_policy;
+ const enum lttng_domain_type domain_type =
+ (enum lttng_domain_type)
+ cmd_ctx->lsm->domain.type;
+ const enum lttng_process_attr process_attr =
+ (enum lttng_process_attr) cmd_ctx->lsm->u
+ .process_attr_tracker_get_tracking_policy
+ .process_attr;
+
+ ret = cmd_process_attr_tracker_get_tracking_policy(
+ cmd_ctx->session, domain_type, process_attr,
+ &tracking_policy);
+ if (ret != LTTNG_OK) {
goto error;
}
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ERR("Invalid value for tracker id");
- ret = LTTNG_ERR_INVALID;
- lttng_tracker_id_destroy(id);
+ ret = setup_lttng_msg_no_cmd_header(cmd_ctx,
+ &(uint32_t){tracking_policy}, sizeof(uint32_t));
+ if (ret < 0) {
+ ret = LTTNG_ERR_NOMEM;
goto error;
}
-
- ret = cmd_track_id(cmd_ctx->session,
- cmd_ctx->lsm->u.id_tracker.tracker_type,
- cmd_ctx->lsm->domain.type, id);
- lttng_tracker_id_destroy(id);
+ ret = LTTNG_OK;
break;
}
- case LTTNG_UNTRACK_ID:
+ case LTTNG_PROCESS_ATTR_TRACKER_SET_POLICY:
{
- struct lttng_tracker_id *id = NULL;
- enum lttng_tracker_id_status status;
-
- id = lttng_tracker_id_create();
-
- switch (cmd_ctx->lsm->u.id_tracker.id_type) {
- case LTTNG_ID_ALL:
- status = lttng_tracker_id_set_all(id);
- break;
- case LTTNG_ID_VALUE:
- status = lttng_tracker_id_set_value(
- id, cmd_ctx->lsm->u.id_tracker.u.value);
- break;
- case LTTNG_ID_STRING:
- {
- const size_t var_len = cmd_ctx->lsm->u.id_tracker.u.var_len;
- char *string = NULL;
-
- string = zmalloc(var_len);
- if (!string) {
- ret = LTTNG_ERR_NOMEM;
- lttng_tracker_id_destroy(id);
- goto error;
- }
- DBG("Receiving var len tracker id string from client");
- ret = lttcomm_recv_unix_sock(*sock, string, var_len);
- if (ret <= 0) {
- DBG("Nothing received");
- *sock_error = 1;
- lttng_tracker_id_destroy(id);
- free(string);
- ret = LTTNG_ERR_INVALID;
- goto error;
- }
- if (strnlen(string, var_len) != var_len - 1) {
- DBG("String received as tracker ID is not NULL-terminated");
- lttng_tracker_id_destroy(id);
- free(string);
- ret = LTTNG_ERR_INVALID;
- goto error;
- }
- status = lttng_tracker_id_set_string(id, string);
- free(string);
- break;
+ const enum lttng_tracking_policy tracking_policy =
+ (enum lttng_tracking_policy) cmd_ctx->lsm->u
+ .process_attr_tracker_set_tracking_policy
+ .tracking_policy;
+ const enum lttng_domain_type domain_type =
+ (enum lttng_domain_type)
+ cmd_ctx->lsm->domain.type;
+ const enum lttng_process_attr process_attr =
+ (enum lttng_process_attr) cmd_ctx->lsm->u
+ .process_attr_tracker_set_tracking_policy
+ .process_attr;
+
+ ret = cmd_process_attr_tracker_set_tracking_policy(
+ cmd_ctx->session, domain_type, process_attr,
+ tracking_policy);
+ if (ret != LTTNG_OK) {
+ goto error;
}
- default:
- lttng_tracker_id_destroy(id);
- ret = LTTNG_ERR_INVALID;
+ break;
+ }
+ case LTTNG_PROCESS_ATTR_TRACKER_GET_INCLUSION_SET:
+ {
+ struct lttng_process_attr_values *values;
+ struct lttng_dynamic_buffer reply;
+ const enum lttng_domain_type domain_type =
+ (enum lttng_domain_type)
+ cmd_ctx->lsm->domain.type;
+ const enum lttng_process_attr process_attr =
+ (enum lttng_process_attr) cmd_ctx->lsm->u
+ .process_attr_tracker_get_inclusion_set
+ .process_attr;
+
+ ret = cmd_process_attr_tracker_get_inclusion_set(
+ cmd_ctx->session, domain_type, process_attr,
+ &values);
+ if (ret != LTTNG_OK) {
goto error;
}
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ERR("Invalid tracker id");
- lttng_tracker_id_destroy(id);
- ret = LTTNG_ERR_INVALID;
- goto error;
+ lttng_dynamic_buffer_init(&reply);
+ ret = lttng_process_attr_values_serialize(values, &reply);
+ if (ret < 0) {
+ goto error_tracker_get_inclusion_set;
}
- ret = cmd_untrack_id(cmd_ctx->session,
- cmd_ctx->lsm->u.id_tracker.tracker_type,
- cmd_ctx->lsm->domain.type, id);
- lttng_tracker_id_destroy(id);
+ ret = setup_lttng_msg_no_cmd_header(
+ cmd_ctx, reply.data, reply.size);
+ if (ret < 0) {
+ ret = LTTNG_ERR_NOMEM;
+ goto error_tracker_get_inclusion_set;
+ }
+ ret = LTTNG_OK;
+
+ error_tracker_get_inclusion_set:
+ lttng_process_attr_values_destroy(values);
+ lttng_dynamic_buffer_reset(&reply);
break;
}
case LTTNG_ENABLE_EVENT:
ret = LTTNG_OK;
break;
}
- case LTTNG_LIST_TRACKER_IDS:
- {
- struct lttcomm_tracker_command_header cmd_header;
- struct lttng_tracker_ids *ids = NULL;
- enum lttng_tracker_id_status status;
- unsigned int nr_ids;
- struct lttng_dynamic_buffer buf;
-
- ret = cmd_list_tracker_ids(
- cmd_ctx->lsm->u.id_tracker.tracker_type,
- cmd_ctx->session, cmd_ctx->lsm->domain.type,
- &ids);
- if (ret != LTTNG_OK) {
- goto error;
- }
-
- lttng_dynamic_buffer_init(&buf);
-
- status = lttng_tracker_ids_get_count(ids, &nr_ids);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ret = -LTTNG_ERR_INVALID;
- goto error_list_tracker;
- }
-
- cmd_header.nb_tracker_id = nr_ids;
-
- ret = lttng_tracker_ids_serialize(ids, &buf);
- if (ret < 0) {
- goto error_list_tracker;
- }
-
- ret = setup_lttng_msg(cmd_ctx, buf.data, buf.size, &cmd_header,
- sizeof(cmd_header));
- error_list_tracker:
- lttng_tracker_ids_destroy(ids);
- lttng_dynamic_buffer_reset(&buf);
- if (ret < 0) {
- goto error;
- }
-
- ret = LTTNG_OK;
- break;
- }
case LTTNG_SET_CONSUMER_URI:
{
size_t nb_uri, len;
*
*/
+#include "bin/lttng-sessiond/tracker.h"
+#include "lttng/lttng-error.h"
+#include "lttng/tracker.h"
#define _LGPL_SOURCE
#include <assert.h>
#include <inttypes.h>
return ret;
}
-/*
- * Command LTTNG_TRACK_ID processed by the client thread.
- *
- * Called with session lock held.
- */
-int cmd_track_id(struct ltt_session *session,
- enum lttng_tracker_type tracker_type,
- enum lttng_domain_type domain,
- const struct lttng_tracker_id *id)
-{
- int ret;
-
- rcu_read_lock();
-
- switch (domain) {
- case LTTNG_DOMAIN_KERNEL:
- {
- struct ltt_kernel_session *ksess;
-
- ksess = session->kernel_session;
-
- ret = kernel_track_id(tracker_type, ksess, id);
- if (ret != LTTNG_OK) {
- goto error;
- }
-
- kernel_wait_quiescent();
- break;
- }
- case LTTNG_DOMAIN_UST:
- {
- struct ltt_ust_session *usess;
-
- usess = session->ust_session;
-
- ret = trace_ust_track_id(tracker_type, usess, id);
- if (ret != LTTNG_OK) {
- goto error;
- }
- break;
- }
- default:
- ret = LTTNG_ERR_UNKNOWN_DOMAIN;
- goto error;
- }
-
- ret = LTTNG_OK;
-
-error:
- rcu_read_unlock();
- return ret;
-}
-
-/*
- * Command LTTNG_UNTRACK_ID processed by the client thread.
- *
- * Called with session lock held.
- */
-int cmd_untrack_id(struct ltt_session *session,
- enum lttng_tracker_type tracker_type,
- enum lttng_domain_type domain,
- const struct lttng_tracker_id *id)
-{
- int ret;
-
- rcu_read_lock();
-
- switch (domain) {
- case LTTNG_DOMAIN_KERNEL:
- {
- struct ltt_kernel_session *ksess;
-
- ksess = session->kernel_session;
-
- ret = kernel_untrack_id(tracker_type, ksess, id);
- if (ret != LTTNG_OK) {
- goto error;
- }
-
- kernel_wait_quiescent();
- break;
- }
- case LTTNG_DOMAIN_UST:
- {
- struct ltt_ust_session *usess;
-
- usess = session->ust_session;
-
- ret = trace_ust_untrack_id(tracker_type, usess, id);
- if (ret != LTTNG_OK) {
- goto error;
- }
- break;
- }
- 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.
*
return ret;
}
+enum lttng_error_code cmd_process_attr_tracker_get_tracking_policy(
+ struct ltt_session *session,
+ enum lttng_domain_type domain,
+ enum lttng_process_attr process_attr,
+ enum lttng_tracking_policy *policy)
+{
+ enum lttng_error_code ret_code = LTTNG_OK;
+ const struct process_attr_tracker *tracker;
+
+ switch (domain) {
+ case LTTNG_DOMAIN_KERNEL:
+ if (!session->kernel_session) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ tracker = kernel_get_process_attr_tracker(
+ session->kernel_session, process_attr);
+ break;
+ case LTTNG_DOMAIN_UST:
+ if (!session->ust_session) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ tracker = trace_ust_get_process_attr_tracker(
+ session->ust_session, process_attr);
+ break;
+ default:
+ ret_code = LTTNG_ERR_UNSUPPORTED_DOMAIN;
+ goto end;
+ }
+ if (tracker) {
+ *policy = process_attr_tracker_get_tracking_policy(tracker);
+ } else {
+ ret_code = LTTNG_ERR_INVALID;
+ }
+end:
+ return ret_code;
+}
+
+enum lttng_error_code cmd_process_attr_tracker_set_tracking_policy(
+ struct ltt_session *session,
+ enum lttng_domain_type domain,
+ enum lttng_process_attr process_attr,
+ enum lttng_tracking_policy policy)
+{
+ enum lttng_error_code ret_code = LTTNG_OK;
+
+ switch (policy) {
+ case LTTNG_TRACKING_POLICY_INCLUDE_SET:
+ case LTTNG_TRACKING_POLICY_EXCLUDE_ALL:
+ case LTTNG_TRACKING_POLICY_INCLUDE_ALL:
+ break;
+ default:
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ switch (domain) {
+ case LTTNG_DOMAIN_KERNEL:
+ if (!session->kernel_session) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ ret_code = kernel_process_attr_tracker_set_tracking_policy(
+ session->kernel_session, process_attr, policy);
+ break;
+ case LTTNG_DOMAIN_UST:
+ if (!session->ust_session) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ ret_code = trace_ust_process_attr_tracker_set_tracking_policy(
+ session->ust_session, process_attr, policy);
+ break;
+ default:
+ ret_code = LTTNG_ERR_UNSUPPORTED_DOMAIN;
+ break;
+ }
+end:
+ return ret_code;
+}
+
+enum lttng_error_code cmd_process_attr_tracker_inclusion_set_add_value(
+ struct ltt_session *session,
+ enum lttng_domain_type domain,
+ enum lttng_process_attr process_attr,
+ const struct process_attr_value *value)
+{
+ enum lttng_error_code ret_code = LTTNG_OK;
+
+ switch (domain) {
+ case LTTNG_DOMAIN_KERNEL:
+ if (!session->kernel_session) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ ret_code = kernel_process_attr_tracker_inclusion_set_add_value(
+ session->kernel_session, process_attr, value);
+ break;
+ case LTTNG_DOMAIN_UST:
+ if (!session->ust_session) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ ret_code = trace_ust_process_attr_tracker_inclusion_set_add_value(
+ session->ust_session, process_attr, value);
+ break;
+ default:
+ ret_code = LTTNG_ERR_UNSUPPORTED_DOMAIN;
+ break;
+ }
+end:
+ return ret_code;
+}
+
+enum lttng_error_code cmd_process_attr_tracker_inclusion_set_remove_value(
+ struct ltt_session *session,
+ enum lttng_domain_type domain,
+ enum lttng_process_attr process_attr,
+ const struct process_attr_value *value)
+{
+ enum lttng_error_code ret_code = LTTNG_OK;
+
+ switch (domain) {
+ case LTTNG_DOMAIN_KERNEL:
+ if (!session->kernel_session) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ ret_code = kernel_process_attr_tracker_inclusion_set_remove_value(
+ session->kernel_session, process_attr, value);
+ break;
+ case LTTNG_DOMAIN_UST:
+ if (!session->ust_session) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ ret_code = trace_ust_process_attr_tracker_inclusion_set_remove_value(
+ session->ust_session, process_attr, value);
+ break;
+ default:
+ ret_code = LTTNG_ERR_UNSUPPORTED_DOMAIN;
+ break;
+ }
+end:
+ return ret_code;
+}
+
+enum lttng_error_code cmd_process_attr_tracker_get_inclusion_set(
+ struct ltt_session *session,
+ enum lttng_domain_type domain,
+ enum lttng_process_attr process_attr,
+ struct lttng_process_attr_values **values)
+{
+ enum lttng_error_code ret_code = LTTNG_OK;
+ const struct process_attr_tracker *tracker;
+ enum process_attr_tracker_status status;
+
+ switch (domain) {
+ case LTTNG_DOMAIN_KERNEL:
+ if (!session->kernel_session) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ tracker = kernel_get_process_attr_tracker(
+ session->kernel_session, process_attr);
+ break;
+ case LTTNG_DOMAIN_UST:
+ if (!session->ust_session) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+ tracker = trace_ust_get_process_attr_tracker(
+ session->ust_session, process_attr);
+ break;
+ default:
+ ret_code = LTTNG_ERR_UNSUPPORTED_DOMAIN;
+ goto end;
+ }
+
+ if (!tracker) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ status = process_attr_tracker_get_inclusion_set(tracker, values);
+ switch (status) {
+ case PROCESS_ATTR_TRACKER_STATUS_OK:
+ ret_code = LTTNG_OK;
+ break;
+ case PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY:
+ ret_code = LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY;
+ break;
+ case PROCESS_ATTR_TRACKER_STATUS_ERROR:
+ ret_code = LTTNG_ERR_NOMEM;
+ break;
+ default:
+ ret_code = LTTNG_ERR_UNK;
+ break;
+ }
+
+end:
+ return ret_code;
+}
+
/*
* Command LTTNG_DISABLE_EVENT processed by the client thread.
*/
return syscall_table_list(events);
}
-/*
- * Command LTTNG_LIST_TRACKER_IDS processed by the client thread.
- *
- * Called with session lock held.
- */
-int cmd_list_tracker_ids(enum lttng_tracker_type tracker_type,
- struct ltt_session *session,
- enum lttng_domain_type domain,
- struct lttng_tracker_ids **ids)
-{
- int ret = LTTNG_OK;
-
- switch (domain) {
- case LTTNG_DOMAIN_KERNEL:
- {
- struct ltt_kernel_session *ksess;
-
- ksess = session->kernel_session;
- ret = kernel_list_tracker_ids(tracker_type, ksess, ids);
- if (ret != LTTNG_OK) {
- ret = -LTTNG_ERR_KERN_LIST_FAIL;
- goto error;
- }
- break;
- }
- case LTTNG_DOMAIN_UST:
- {
- struct ltt_ust_session *usess;
-
- usess = session->ust_session;
- ret = trace_ust_list_tracker_ids(tracker_type, usess, ids);
- if (ret != LTTNG_OK) {
- 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;
- }
-
-error:
- /* Return negative value to differentiate return code */
- return ret;
-}
-
/*
* Command LTTNG_START_TRACE processed by the client thread.
*
#define CMD_H
#include "context.h"
-#include "session.h"
#include "lttng-sessiond.h"
+#include "lttng/tracker.h"
+#include "session.h"
+#include <common/tracker.h>
struct notification_thread_handle;
int cmd_enable_channel(struct ltt_session *session,
const struct lttng_domain *domain, const struct lttng_channel *attr,
int wpipe);
-int cmd_track_id(struct ltt_session *session,
- enum lttng_tracker_type tracker_type,
+
+/* Process attribute tracker commands */
+enum lttng_error_code cmd_process_attr_tracker_get_tracking_policy(
+ struct ltt_session *session,
enum lttng_domain_type domain,
- const struct lttng_tracker_id *id);
-int cmd_untrack_id(struct ltt_session *session,
- enum lttng_tracker_type tracker_type,
+ enum lttng_process_attr process_attr,
+ enum lttng_tracking_policy *policy);
+enum lttng_error_code cmd_process_attr_tracker_set_tracking_policy(
+ struct ltt_session *session,
+ enum lttng_domain_type domain,
+ enum lttng_process_attr process_attr,
+ enum lttng_tracking_policy policy);
+enum lttng_error_code cmd_process_attr_tracker_inclusion_set_add_value(
+ struct ltt_session *session,
enum lttng_domain_type domain,
- const struct lttng_tracker_id *id);
+ enum lttng_process_attr process_attr,
+ const struct process_attr_value *value);
+enum lttng_error_code cmd_process_attr_tracker_inclusion_set_remove_value(
+ struct ltt_session *session,
+ enum lttng_domain_type domain,
+ enum lttng_process_attr process_attr,
+ const struct process_attr_value *value);
+enum lttng_error_code cmd_process_attr_tracker_get_inclusion_set(
+ struct ltt_session *session,
+ enum lttng_domain_type domain,
+ enum lttng_process_attr process_attr,
+ struct lttng_process_attr_values **values);
/* 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);
-int cmd_list_tracker_ids(enum lttng_tracker_type tracker_type,
- struct ltt_session *session,
- enum lttng_domain_type domain,
- struct lttng_tracker_ids **ids);
int cmd_data_pending(struct ltt_session *session);
*
*/
+#include "bin/lttng-sessiond/tracker.h"
+#include "common/tracker.h"
+#include "common/utils.h"
+#include "lttng/lttng-error.h"
+#include "lttng/tracker.h"
#define _LGPL_SOURCE
#include <fcntl.h>
#include <stdlib.h>
return ret;
}
-static struct lttng_tracker_list *get_id_tracker_list(
+static
+struct process_attr_tracker *_kernel_get_process_attr_tracker(
struct ltt_kernel_session *session,
- enum lttng_tracker_type tracker_type)
+ enum lttng_process_attr process_attr)
{
- 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;
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_PROCESS_ID:
+ return session->tracker_pid;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ return session->tracker_vpid;
+ case LTTNG_PROCESS_ATTR_USER_ID:
+ return session->tracker_uid;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ return session->tracker_vuid;
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
+ return session->tracker_gid;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ return session->tracker_vgid;
default:
return NULL;
}
}
-int kernel_track_id(enum lttng_tracker_type tracker_type,
+const struct process_attr_tracker *kernel_get_process_attr_tracker(
struct ltt_kernel_session *session,
- const struct lttng_tracker_id *id)
+ enum lttng_process_attr process_attr)
{
- int ret, value;
- struct lttng_tracker_list *tracker_list;
- struct lttng_tracker_ids *saved_ids;
+ return (const struct process_attr_tracker *)
+ _kernel_get_process_attr_tracker(session, process_attr);
+}
- ret = lttng_tracker_id_lookup_string(tracker_type, id, &value);
- if (ret != LTTNG_OK) {
- return ret;
- }
+enum lttng_error_code kernel_process_attr_tracker_set_tracking_policy(
+ struct ltt_kernel_session *session,
+ enum lttng_process_attr process_attr,
+ enum lttng_tracking_policy policy)
+{
+ int ret;
+ enum lttng_error_code ret_code = LTTNG_OK;
+ struct process_attr_tracker *tracker =
+ _kernel_get_process_attr_tracker(session, process_attr);
+ enum lttng_tracking_policy previous_policy;
- tracker_list = get_id_tracker_list(session, tracker_type);
- if (!tracker_list) {
- return LTTNG_ERR_INVALID;
+ if (!tracker) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
}
- /* Save list for restore on error. */
- ret = lttng_tracker_id_get_list(tracker_list, &saved_ids);
- if (ret != LTTNG_OK) {
- return LTTNG_ERR_INVALID;
+ previous_policy = process_attr_tracker_get_tracking_policy(tracker);
+ ret = process_attr_tracker_set_tracking_policy(tracker, policy);
+ if (ret) {
+ ret_code = LTTNG_ERR_UNK;
+ goto end;
}
- /* Add to list. */
- ret = lttng_tracker_list_add(tracker_list, id);
- if (ret != LTTNG_OK) {
+ if (previous_policy == policy) {
goto end;
}
- 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) {
- ret = LTTNG_OK;
- goto end;
- }
- 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) {
- ret = LTTNG_OK;
- goto end;
- }
- 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) {
- ret = LTTNG_OK;
- goto end;
- }
- 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) {
- ret = LTTNG_OK;
- goto end;
- }
- 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) {
- ret = LTTNG_OK;
- goto end;
+ switch (policy) {
+ case LTTNG_TRACKING_POLICY_INCLUDE_ALL:
+ if (process_attr == LTTNG_PROCESS_ATTR_PROCESS_ID) {
+ /*
+ * Maintain a special case for the process ID process
+ * attribute tracker as it was the only supported
+ * attribute prior to 2.12.
+ */
+ ret = kernctl_track_pid(session->fd, -1);
+ } else {
+ ret = kernctl_track_id(session->fd, process_attr, -1);
}
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) {
- ret = LTTNG_OK;
- goto end;
+ case LTTNG_TRACKING_POLICY_EXCLUDE_ALL:
+ case LTTNG_TRACKING_POLICY_INCLUDE_SET:
+ /* fall-through. */
+ if (process_attr == LTTNG_PROCESS_ATTR_PROCESS_ID) {
+ /*
+ * Maintain a special case for the process ID process
+ * attribute tracker as it was the only supported
+ * attribute prior to 2.12.
+ */
+ ret = kernctl_untrack_pid(session->fd, -1);
+ } else {
+ ret = kernctl_untrack_id(session->fd, process_attr, -1);
}
break;
default:
- ret = -EINVAL;
- break;
+ abort();
}
-
- /* Error handling. */
+ /* kern-ctl error handling */
switch (-ret) {
+ case 0:
+ ret_code = LTTNG_OK;
+ break;
case EINVAL:
- ret = LTTNG_ERR_INVALID;
+ ret_code = LTTNG_ERR_INVALID;
break;
case ENOMEM:
- ret = LTTNG_ERR_NOMEM;
+ ret_code = LTTNG_ERR_NOMEM;
break;
case EEXIST:
- ret = LTTNG_ERR_ID_TRACKED;
+ ret_code = LTTNG_ERR_PROCESS_ATTR_EXISTS;
break;
default:
- ret = LTTNG_ERR_UNK;
+ ret_code = LTTNG_ERR_UNK;
break;
}
-
- if (lttng_tracker_id_set_list(tracker_list, saved_ids) != LTTNG_OK) {
- ERR("Error on tracker add error handling.\n");
- }
end:
- lttng_tracker_ids_destroy(saved_ids);
- return ret;
+ return ret_code;
}
-int kernel_untrack_id(enum lttng_tracker_type tracker_type,
+enum lttng_error_code kernel_process_attr_tracker_inclusion_set_add_value(
struct ltt_kernel_session *session,
- const struct lttng_tracker_id *id)
+ enum lttng_process_attr process_attr,
+ const struct process_attr_value *value)
{
- int ret, value;
- struct lttng_tracker_list *tracker_list;
- struct lttng_tracker_ids *saved_ids;
-
- ret = lttng_tracker_id_lookup_string(tracker_type, id, &value);
- if (ret != LTTNG_OK) {
- return ret;
- }
+ int ret, integral_value;
+ enum lttng_error_code ret_code;
+ struct process_attr_tracker *tracker;
+ enum process_attr_tracker_status status;
- tracker_list = get_id_tracker_list(session, tracker_type);
- if (!tracker_list) {
- return LTTNG_ERR_INVALID;
- }
- /* Save list for restore on error. */
- ret = lttng_tracker_id_get_list(tracker_list, &saved_ids);
- if (ret != LTTNG_OK) {
- return LTTNG_ERR_INVALID;
- }
- /* Remove from list. */
- ret = lttng_tracker_list_remove(tracker_list, id);
- if (ret != LTTNG_OK) {
- goto end;
- }
-
- 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) {
- ret = LTTNG_OK;
- goto end;
- }
- 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) {
- ret = LTTNG_OK;
- goto end;
- }
- 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) {
- ret = LTTNG_OK;
- goto end;
- }
- 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) {
- ret = LTTNG_OK;
- goto end;
- }
+ /*
+ * Convert process attribute tracker value to the integral
+ * representation required by the kern-ctl API.
+ */
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_PROCESS_ID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ integral_value = (int) value->value.pid;
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) {
- ret = LTTNG_OK;
- goto end;
+ case LTTNG_PROCESS_ATTR_USER_ID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ if (value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME) {
+ uid_t uid;
+
+ ret_code = utils_user_id_from_name(
+ value->value.user_name, &uid);
+ if (ret_code != LTTNG_OK) {
+ goto end;
+ }
+ integral_value = (int) uid;
+ } else {
+ integral_value = (int) value->value.uid;
}
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) {
- ret = LTTNG_OK;
- goto end;
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ if (value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME) {
+ gid_t gid;
+
+ ret_code = utils_group_id_from_name(
+ value->value.group_name, &gid);
+ if (ret_code != LTTNG_OK) {
+ goto end;
+ }
+ integral_value = (int) gid;
+ } else {
+ integral_value = (int) value->value.gid;
}
break;
default:
- ret = -EINVAL;
- break;
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ tracker = _kernel_get_process_attr_tracker(session, process_attr);
+ if (!tracker) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ status = process_attr_tracker_inclusion_set_add_value(tracker, value);
+ if (status != PROCESS_ATTR_TRACKER_STATUS_OK) {
+ switch (status) {
+ case PROCESS_ATTR_TRACKER_STATUS_EXISTS:
+ ret_code = LTTNG_ERR_PROCESS_ATTR_EXISTS;
+ break;
+ case PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY:
+ ret_code = LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY;
+ break;
+ case PROCESS_ATTR_TRACKER_STATUS_ERROR:
+ default:
+ ret_code = LTTNG_ERR_UNK;
+ break;
+ }
+ goto end;
+ }
+
+ DBG("Kernel track %s %d for session id %" PRIu64,
+ lttng_process_attr_to_string(process_attr),
+ integral_value, session->id);
+ if (process_attr == LTTNG_PROCESS_ATTR_PROCESS_ID) {
+ /*
+ * Maintain a special case for the process ID process attribute
+ * tracker as it was the only supported attribute prior to 2.12.
+ */
+ ret = kernctl_track_pid(session->fd, integral_value);
+ } else {
+ ret = kernctl_track_id(
+ session->fd, process_attr, integral_value);
+ }
+ if (ret == 0) {
+ ret_code = LTTNG_OK;
+ goto end;
}
- /* Error handling. */
+ kernel_wait_quiescent();
+
+ /* kern-ctl error handling */
switch (-ret) {
+ case 0:
+ ret_code = LTTNG_OK;
+ break;
case EINVAL:
- ret = LTTNG_ERR_INVALID;
+ ret_code = LTTNG_ERR_INVALID;
break;
case ENOMEM:
- ret = LTTNG_ERR_NOMEM;
+ ret_code = LTTNG_ERR_NOMEM;
break;
case EEXIST:
- ret = LTTNG_ERR_ID_TRACKED;
+ ret_code = LTTNG_ERR_PROCESS_ATTR_EXISTS;
break;
default:
- ret = LTTNG_ERR_UNK;
+ ret_code = LTTNG_ERR_UNK;
break;
}
- if (lttng_tracker_id_set_list(tracker_list, saved_ids) != LTTNG_OK) {
- ERR("Error on tracker remove error handling.\n");
+ /* Attempt to remove the value from the tracker. */
+ status = process_attr_tracker_inclusion_set_remove_value(
+ tracker, value);
+ if (status != PROCESS_ATTR_TRACKER_STATUS_OK) {
+ ERR("Failed to roll-back the tracking of kernel %s process attribute %d while handling a kern-ctl error",
+ lttng_process_attr_to_string(process_attr),
+ integral_value);
}
end:
- lttng_tracker_ids_destroy(saved_ids);
- return ret;
+ return ret_code;
}
-/*
- * Called with session lock held.
- */
-int kernel_list_tracker_ids(enum lttng_tracker_type tracker_type,
+enum lttng_error_code kernel_process_attr_tracker_inclusion_set_remove_value(
struct ltt_kernel_session *session,
- struct lttng_tracker_ids **_ids)
+ enum lttng_process_attr process_attr,
+ const struct process_attr_value *value)
{
- int ret = 0;
- struct lttng_tracker_list *tracker_list;
+ int ret, integral_value;
+ enum lttng_error_code ret_code;
+ struct process_attr_tracker *tracker;
+ enum process_attr_tracker_status status;
+
+ /*
+ * Convert process attribute tracker value to the integral
+ * representation required by the kern-ctl API.
+ */
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_PROCESS_ID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ integral_value = (int) value->value.pid;
+ break;
+ case LTTNG_PROCESS_ATTR_USER_ID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ if (value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME) {
+ uid_t uid;
+
+ ret_code = utils_user_id_from_name(
+ value->value.user_name, &uid);
+ if (ret_code != LTTNG_OK) {
+ goto end;
+ }
+ integral_value = (int) uid;
+ } else {
+ integral_value = (int) value->value.uid;
+ }
+ break;
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ if (value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME) {
+ gid_t gid;
+
+ ret_code = utils_group_id_from_name(
+ value->value.group_name, &gid);
+ if (ret_code != LTTNG_OK) {
+ goto end;
+ }
+ integral_value = (int) gid;
+ } else {
+ integral_value = (int) value->value.gid;
+ }
+ break;
+ default:
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
- tracker_list = get_id_tracker_list(session, tracker_type);
- if (!tracker_list) {
- ret = -LTTNG_ERR_INVALID;
+ tracker = _kernel_get_process_attr_tracker(session, process_attr);
+ if (!tracker) {
+ ret_code = LTTNG_ERR_INVALID;
goto end;
}
- ret = lttng_tracker_id_get_list(tracker_list, _ids);
- if (ret != LTTNG_OK) {
- ret = -LTTNG_ERR_INVALID;
+ status = process_attr_tracker_inclusion_set_remove_value(
+ tracker, value);
+ if (status != PROCESS_ATTR_TRACKER_STATUS_OK) {
+ switch (status) {
+ case PROCESS_ATTR_TRACKER_STATUS_MISSING:
+ ret_code = LTTNG_ERR_PROCESS_ATTR_MISSING;
+ break;
+ case PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY:
+ ret_code = LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY;
+ break;
+ case PROCESS_ATTR_TRACKER_STATUS_ERROR:
+ default:
+ ret_code = LTTNG_ERR_UNK;
+ break;
+ }
+ goto end;
+ }
+
+ DBG("Kernel track %s %d for session id %" PRIu64,
+ lttng_process_attr_to_string(process_attr),
+ integral_value, session->id);
+ if (process_attr == LTTNG_PROCESS_ATTR_PROCESS_ID) {
+ /*
+ * Maintain a special case for the process ID process attribute
+ * tracker as it was the only supported attribute prior to 2.12.
+ */
+ ret = kernctl_untrack_pid(session->fd, integral_value);
+ } else {
+ ret = kernctl_untrack_id(
+ session->fd, process_attr, integral_value);
+ }
+ if (ret == 0) {
+ ret_code = LTTNG_OK;
goto end;
}
+ kernel_wait_quiescent();
+ /* kern-ctl error handling */
+ switch (-ret) {
+ case 0:
+ ret_code = LTTNG_OK;
+ break;
+ case EINVAL:
+ ret_code = LTTNG_ERR_INVALID;
+ break;
+ case ENOMEM:
+ ret_code = LTTNG_ERR_NOMEM;
+ break;
+ case ENOENT:
+ ret_code = LTTNG_ERR_PROCESS_ATTR_MISSING;
+ break;
+ default:
+ ret_code = LTTNG_ERR_UNK;
+ break;
+ }
+
+ /* Attempt to add the value to the tracker. */
+ status = process_attr_tracker_inclusion_set_add_value(
+ tracker, value);
+ if (status != PROCESS_ATTR_TRACKER_STATUS_OK) {
+ ERR("Failed to roll-back the tracking of kernel %s process attribute %d while handling a kern-ctl error",
+ lttng_process_attr_to_string(process_attr),
+ integral_value);
+ }
end:
- return ret;
+ return ret_code;
}
/*
#ifndef _LTT_KERNEL_CTL_H
#define _LTT_KERNEL_CTL_H
+#include "lttng/lttng-error.h"
+#include "lttng/tracker.h"
#include "session.h"
#include "snapshot.h"
#include "trace-kernel.h"
* dynamic reallocation is performed.
*/
#define KERNEL_EVENT_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_id(enum lttng_tracker_type tracker_type,
+enum lttng_error_code kernel_process_attr_tracker_set_tracking_policy(
struct ltt_kernel_session *session,
- const struct lttng_tracker_id *id);
-int kernel_untrack_id(enum lttng_tracker_type tracker_type,
+ enum lttng_process_attr process_attr,
+ enum lttng_tracking_policy policy);
+enum lttng_error_code kernel_process_attr_tracker_inclusion_set_add_value(
struct ltt_kernel_session *session,
- const struct lttng_tracker_id *id);
+ enum lttng_process_attr process_attr,
+ const struct process_attr_value *value);
+enum lttng_error_code kernel_process_attr_tracker_inclusion_set_remove_value(
+ struct ltt_kernel_session *session,
+ enum lttng_process_attr process_attr,
+ const struct process_attr_value *value);
+const struct process_attr_tracker *kernel_get_process_attr_tracker(
+ struct ltt_kernel_session *session,
+ enum lttng_process_attr process_attr);
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);
enum lttng_error_code kernel_clear_session(struct ltt_session *session);
int init_kernel_workarounds(void);
-int kernel_list_tracker_ids(enum lttng_tracker_type tracker_type,
- struct ltt_kernel_session *session,
- struct lttng_tracker_ids **ids);
int kernel_supports_ring_buffer_snapshot_sample_positions(void);
int kernel_supports_ring_buffer_packet_sequence_number(void);
int init_kernel_tracer(void);
}
/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
-static int save_id_tracker(struct config_writer *writer,
+static int save_process_attr_tracker(struct config_writer *writer,
struct ltt_session *sess,
int domain,
- enum lttng_tracker_type tracker_type)
+ enum lttng_process_attr process_attr)
{
int ret = LTTNG_OK;
- unsigned int nr_ids, i;
- struct lttng_tracker_ids *ids = NULL;
const char *element_id_tracker, *element_target_id, *element_id;
- const struct lttng_tracker_id *id;
- enum lttng_tracker_id_status status;
- int value;
- const char *string;
-
- 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;
+ const struct process_attr_tracker *tracker;
+ enum lttng_tracking_policy tracking_policy;
+ struct lttng_process_attr_values *values = NULL;
+
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_PROCESS_ID:
+ element_id_tracker = config_element_process_attr_tracker_pid;
+ element_target_id = config_element_process_attr_pid_value;
+ element_id = config_element_process_attr_id;
+ break;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ element_id_tracker = config_element_process_attr_tracker_vpid;
+ element_target_id = config_element_process_attr_vpid_value;
+ element_id = config_element_process_attr_id;
+ break;
+ case LTTNG_PROCESS_ATTR_USER_ID:
+ element_id_tracker = config_element_process_attr_tracker_uid;
+ element_target_id = config_element_process_attr_uid_value;
+ element_id = config_element_process_attr_id;
+ break;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ element_id_tracker = config_element_process_attr_tracker_vuid;
+ element_target_id = config_element_process_attr_vuid_value;
+ element_id = config_element_process_attr_id;
+ break;
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
+ element_id_tracker = config_element_process_attr_tracker_gid;
+ element_target_id = config_element_process_attr_gid_value;
+ element_id = config_element_process_attr_id;
+ break;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ element_id_tracker = config_element_process_attr_tracker_vgid;
+ element_target_id = config_element_process_attr_vgid_value;
+ element_id = config_element_process_attr_id;
break;
default:
ret = LTTNG_ERR_SAVE_IO_FAIL;
switch (domain) {
case LTTNG_DOMAIN_KERNEL:
{
- ret = kernel_list_tracker_ids(
- tracker_type, sess->kernel_session, &ids);
- if (ret != LTTNG_OK) {
- ret = LTTNG_ERR_KERN_LIST_FAIL;
- goto end;
- }
+ tracker = kernel_get_process_attr_tracker(
+ sess->kernel_session, process_attr);
+ assert(tracker);
break;
}
case LTTNG_DOMAIN_UST:
{
- ret = trace_ust_list_tracker_ids(
- tracker_type, sess->ust_session, &ids);
- if (ret != LTTNG_OK) {
- ret = LTTNG_ERR_UST_LIST_FAIL;
- goto end;
- }
+ tracker = trace_ust_get_process_attr_tracker(
+ sess->ust_session, process_attr);
+ assert(tracker);
break;
}
case LTTNG_DOMAIN_JUL:
case LTTNG_DOMAIN_LOG4J:
case LTTNG_DOMAIN_PYTHON:
default:
- ret = LTTNG_ERR_UNKNOWN_DOMAIN;
+ ret = LTTNG_ERR_UNSUPPORTED_DOMAIN;
goto end;
}
- status = lttng_tracker_ids_get_count(ids, &nr_ids);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ret = LTTNG_ERR_INVALID;
+ tracking_policy = process_attr_tracker_get_tracking_policy(tracker);
+ if (tracking_policy == LTTNG_TRACKING_POLICY_INCLUDE_ALL) {
+ /* Tracking all, nothing to output. */
+ ret = LTTNG_OK;
goto end;
}
- if (nr_ids == 1) {
- id = lttng_tracker_ids_get_at_index(ids, 0);
- if (id && lttng_tracker_id_get_type(id) == 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);
+ ret = config_writer_open_element(
+ writer, config_element_process_attr_values);
if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
- if (nr_ids == 0) {
- /* Tracking none: empty list. */
+ if (tracking_policy == LTTNG_TRACKING_POLICY_EXCLUDE_ALL) {
+ /* Tracking nothing; empty list. */
ret = config_writer_open_element(writer, element_target_id);
if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
} else {
- /* Tracking list. */
- for (i = 0; i < nr_ids; i++) {
- id = lttng_tracker_ids_get_at_index(ids, i);
- if (!id) {
+ unsigned int i, count;
+ enum process_attr_tracker_status status =
+ process_attr_tracker_get_inclusion_set(
+ tracker, &values);
+
+ if (status != PROCESS_ATTR_TRACKER_STATUS_OK) {
+ ret = LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ count = _lttng_process_attr_values_get_count(values);
+
+ for (i = 0; i < count; i++) {
+ unsigned int integral_value = UINT_MAX;
+ const char *name = NULL;
+ const struct process_attr_value *value =
+ lttng_process_attr_tracker_values_get_at_index(
+ values, i);
+
+ assert(value);
+ ret = config_writer_open_element(
+ writer, element_target_id);
+ if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
- switch (lttng_tracker_id_get_type(id)) {
- case LTTNG_ID_VALUE:
- ret = config_writer_open_element(
- writer, element_target_id);
- if (ret) {
- ret = LTTNG_ERR_SAVE_IO_FAIL;
- goto end;
- }
- status = lttng_tracker_id_get_value(id, &value);
- ret = config_writer_write_element_unsigned_int(
- writer, element_id, value);
+
+ switch (value->type) {
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_PID:
+ integral_value =
+ (unsigned int) value->value.pid;
break;
- case LTTNG_ID_STRING:
- ret = config_writer_open_element(
- writer, element_target_id);
- if (ret) {
- ret = LTTNG_ERR_SAVE_IO_FAIL;
- goto end;
- }
- status = lttng_tracker_id_get_string(
- id, &string);
- ret = config_writer_write_element_string(writer,
- config_element_name, string);
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_UID:
+ integral_value =
+ (unsigned int) value->value.uid;
+ break;
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_GID:
+ integral_value =
+ (unsigned int) value->value.gid;
+ break;
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME:
+ name = value->value.user_name;
+ assert(name);
+ break;
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME:
+ name = value->value.group_name;
+ assert(name);
break;
default:
- /* Unexpected. */
- ret = LTTNG_ERR_SAVE_IO_FAIL;
- goto end;
+ abort();
}
- if (ret) {
- ret = LTTNG_ERR_SAVE_IO_FAIL;
- goto end;
+
+ if (name) {
+ ret = config_writer_write_element_string(writer,
+ config_element_name, name);
+ } else {
+ ret = config_writer_write_element_unsigned_int(
+ writer, element_id,
+ integral_value);
}
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+
+ if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
ret = LTTNG_OK;
end:
- lttng_tracker_ids_destroy(ids);
+ lttng_process_attr_values_destroy(values);
return ret;
}
/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
-static int save_id_trackers(struct config_writer *writer,
+static int save_process_attr_trackers(struct config_writer *writer,
struct ltt_session *sess,
int domain)
{
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;
+ ret = save_process_attr_tracker(writer, sess, domain,
+ LTTNG_PROCESS_ATTR_PROCESS_ID);
+ if (ret != LTTNG_OK) {
+ goto end;
+ }
+ ret = save_process_attr_tracker(writer, sess, domain,
+ LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID);
+ if (ret != LTTNG_OK) {
+ goto end;
+ }
+ ret = save_process_attr_tracker(writer, sess, domain,
+ LTTNG_PROCESS_ATTR_USER_ID);
+ if (ret != LTTNG_OK) {
+ goto end;
+ }
+ ret = save_process_attr_tracker(writer, sess, domain,
+ LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID);
+ if (ret != LTTNG_OK) {
+ goto end;
+ }
+ ret = save_process_attr_tracker(writer, sess, domain,
+ LTTNG_PROCESS_ATTR_GROUP_ID);
+ if (ret != LTTNG_OK) {
+ goto end;
+ }
+ ret = save_process_attr_tracker(writer, sess, domain,
+ LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID);
+ if (ret != LTTNG_OK) {
+ goto end;
+ }
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;
+ ret = save_process_attr_tracker(writer, sess, domain,
+ LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID);
+ if (ret != LTTNG_OK) {
+ goto end;
+ }
+ ret = save_process_attr_tracker(writer, sess, domain,
+ LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID);
+ if (ret != LTTNG_OK) {
+ goto end;
+ }
+ ret = save_process_attr_tracker(writer, sess, domain,
+ LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID);
+ if (ret != LTTNG_OK) {
+ goto end;
+ }
break;
default:
- return LTTNG_ERR_INVALID;
+ ret = LTTNG_ERR_INVALID;
}
- return LTTNG_OK;
+ ret = LTTNG_OK;
+end:
+ return ret;
}
/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
}
if (domain == LTTNG_DOMAIN_UST) {
- ret = config_writer_open_element(writer,
- config_element_trackers);
+ ret = config_writer_open_element(
+ writer, config_element_process_attr_trackers);
if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
- ret = save_id_trackers(writer, session, LTTNG_DOMAIN_UST);
+ ret = save_process_attr_trackers(
+ writer, session, LTTNG_DOMAIN_UST);
if (ret != LTTNG_OK) {
goto end;
}
goto end;
}
- ret = config_writer_open_element(writer,
- config_element_trackers);
+ ret = config_writer_open_element(
+ writer, config_element_process_attr_trackers);
if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
- ret = save_id_trackers(writer, session, LTTNG_DOMAIN_KERNEL);
+ ret = save_process_attr_trackers(
+ writer, session, LTTNG_DOMAIN_KERNEL);
if (ret != LTTNG_OK) {
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) {
+ lks->tracker_pid = process_attr_tracker_create();
+ if (!lks->tracker_pid) {
goto error;
}
- lks->tracker_list_vpid = lttng_tracker_list_create();
- if (!lks->tracker_list_vpid) {
+ lks->tracker_vpid = process_attr_tracker_create();
+ if (!lks->tracker_vpid) {
goto error;
}
- lks->tracker_list_uid = lttng_tracker_list_create();
- if (!lks->tracker_list_uid) {
+ lks->tracker_uid = process_attr_tracker_create();
+ if (!lks->tracker_uid) {
goto error;
}
- lks->tracker_list_vuid = lttng_tracker_list_create();
- if (!lks->tracker_list_vuid) {
+ lks->tracker_vuid = process_attr_tracker_create();
+ if (!lks->tracker_vuid) {
goto error;
}
- lks->tracker_list_gid = lttng_tracker_list_create();
- if (!lks->tracker_list_gid) {
+ lks->tracker_gid = process_attr_tracker_create();
+ if (!lks->tracker_gid) {
goto error;
}
- lks->tracker_list_vgid = lttng_tracker_list_create();
- if (!lks->tracker_list_vgid) {
+ lks->tracker_vgid = process_attr_tracker_create();
+ if (!lks->tracker_vgid) {
goto error;
}
lks->consumer = consumer_create_output(CONSUMER_DST_LOCAL);
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);
+ process_attr_tracker_destroy(lks->tracker_pid);
+ process_attr_tracker_destroy(lks->tracker_vpid);
+ process_attr_tracker_destroy(lks->tracker_uid);
+ process_attr_tracker_destroy(lks->tracker_vuid);
+ process_attr_tracker_destroy(lks->tracker_gid);
+ process_attr_tracker_destroy(lks->tracker_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);
+ process_attr_tracker_destroy(session->tracker_pid);
+ process_attr_tracker_destroy(session->tracker_vpid);
+ process_attr_tracker_destroy(session->tracker_uid);
+ process_attr_tracker_destroy(session->tracker_vuid);
+ process_attr_tracker_destroy(session->tracker_gid);
+ process_attr_tracker_destroy(session->tracker_vgid);
free(session);
}
/* Current trace chunk of the ltt_session. */
struct lttng_trace_chunk *current_trace_chunk;
/* Tracker lists */
- 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;
+ struct process_attr_tracker *tracker_pid;
+ struct process_attr_tracker *tracker_vpid;
+ struct process_attr_tracker *tracker_uid;
+ struct process_attr_tracker *tracker_vuid;
+ struct process_attr_tracker *tracker_gid;
+ struct process_attr_tracker *tracker_vgid;
};
/*
#include <common/common.h>
#include <common/defaults.h>
#include <common/trace-chunk.h>
+#include <common/utils.h>
#include "buffer-registry.h"
#include "trace-ust.h"
/* 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) {
+ lus->tracker_vpid = process_attr_tracker_create();
+ if (!lus->tracker_vpid) {
goto error;
}
- lus->tracker_list_vuid = lttng_tracker_list_create();
- if (!lus->tracker_list_vuid) {
+ lus->tracker_vuid = process_attr_tracker_create();
+ if (!lus->tracker_vuid) {
goto error;
}
- lus->tracker_list_vgid = lttng_tracker_list_create();
- if (!lus->tracker_list_vgid) {
+ lus->tracker_vgid = process_attr_tracker_create();
+ if (!lus->tracker_vgid) {
goto error;
}
lus->consumer = consumer_create_output(CONSUMER_DST_LOCAL);
return lus;
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);
+ process_attr_tracker_destroy(lus->tracker_vpid);
+ process_attr_tracker_destroy(lus->tracker_vuid);
+ process_attr_tracker_destroy(lus->tracker_vgid);
ht_cleanup_push(lus->domain_global.channels);
ht_cleanup_push(lus->agents);
free(lus);
tracker_node = id_tracker_lookup(id_tracker, id, &iter);
if (tracker_node) {
/* Already exists. */
- retval = LTTNG_ERR_ID_TRACKED;
+ retval = LTTNG_ERR_PROCESS_ATTR_EXISTS;
goto end;
}
tracker_node = zmalloc(sizeof(*tracker_node));
tracker_node = id_tracker_lookup(id_tracker, id, &iter);
if (!tracker_node) {
/* Not found */
- retval = LTTNG_ERR_ID_NOT_TRACKED;
+ retval = LTTNG_ERR_PROCESS_ATTR_MISSING;
goto end;
}
ret = lttng_ht_del(id_tracker->ht, &iter);
}
static struct ust_id_tracker *get_id_tracker(struct ltt_ust_session *session,
- enum lttng_tracker_type tracker_type)
+ enum lttng_process_attr process_attr)
{
- switch (tracker_type) {
- case LTTNG_TRACKER_VPID:
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
return &session->vpid_tracker;
- case LTTNG_TRACKER_VUID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
return &session->vuid_tracker;
- case LTTNG_TRACKER_VGID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
return &session->vgid_tracker;
default:
return NULL;
}
}
-static struct lttng_tracker_list *get_id_tracker_list(
+static struct process_attr_tracker *_trace_ust_get_process_attr_tracker(
struct ltt_ust_session *session,
- enum lttng_tracker_type tracker_type)
+ enum lttng_process_attr process_attr)
{
- 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;
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ return session->tracker_vpid;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ return session->tracker_vuid;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ return session->tracker_vgid;
default:
return NULL;
}
}
+const struct process_attr_tracker *trace_ust_get_process_attr_tracker(
+ struct ltt_ust_session *session,
+ enum lttng_process_attr process_attr)
+{
+ return (const struct process_attr_tracker *)
+ _trace_ust_get_process_attr_tracker(
+ session, process_attr);
+}
+
/*
* The session lock is held when calling this function.
*/
-int trace_ust_id_tracker_lookup(enum lttng_tracker_type tracker_type,
+int trace_ust_id_tracker_lookup(enum lttng_process_attr process_attr,
struct ltt_ust_session *session,
int id)
{
struct lttng_ht_iter iter;
struct ust_id_tracker *id_tracker;
- id_tracker = get_id_tracker(session, tracker_type);
+ id_tracker = get_id_tracker(session, process_attr);
if (!id_tracker) {
abort();
}
/*
* Called with the session lock held.
*/
-int trace_ust_track_id(enum lttng_tracker_type tracker_type,
+enum lttng_error_code trace_ust_process_attr_tracker_set_tracking_policy(
struct ltt_ust_session *session,
- const struct lttng_tracker_id *id)
+ enum lttng_process_attr process_attr,
+ enum lttng_tracking_policy policy)
{
- int retval = LTTNG_OK;
+ int ret;
+ enum lttng_error_code ret_code = LTTNG_OK;
+ struct ust_id_tracker *id_tracker =
+ get_id_tracker(session, process_attr);
+ struct process_attr_tracker *tracker =
+ _trace_ust_get_process_attr_tracker(
+ session, process_attr);
bool should_update_apps = false;
- struct ust_id_tracker *id_tracker;
- struct lttng_tracker_list *tracker_list;
- int value;
- struct lttng_tracker_ids *saved_ids;
+ enum lttng_tracking_policy previous_policy;
- 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 (!tracker) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
}
- retval = lttng_tracker_id_lookup_string(tracker_type, id, &value);
- if (retval != LTTNG_OK) {
- return retval;
- }
- tracker_list = get_id_tracker_list(session, tracker_type);
- if (!tracker_list) {
- return LTTNG_ERR_INVALID;
- }
- /* Save list for restore on error. */
- retval = lttng_tracker_id_get_list(tracker_list, &saved_ids);
- if (retval != LTTNG_OK) {
- return LTTNG_ERR_INVALID;
- }
- /* Add to list. */
- retval = lttng_tracker_list_add(tracker_list, id);
- if (retval != LTTNG_OK) {
+ previous_policy = process_attr_tracker_get_tracking_policy(tracker);
+ ret = process_attr_tracker_set_tracking_policy(tracker, policy);
+ if (ret) {
+ ret_code = LTTNG_ERR_UNK;
goto end;
}
- id_tracker = get_id_tracker(session, tracker_type);
- if (!id_tracker) {
- abort();
+ if (previous_policy == policy) {
+ goto end;
}
- if (value == -1) {
- /* Track all ids: destroy tracker if exists. */
+
+ switch (policy) {
+ case LTTNG_TRACKING_POLICY_INCLUDE_ALL:
+ /* Track all values: destroy tracker if exists. */
if (id_tracker->ht) {
fini_id_tracker(id_tracker);
/* Ensure all apps have session. */
should_update_apps = true;
}
- } else {
- if (!id_tracker->ht) {
- /* Create tracker. */
- retval = init_id_tracker(id_tracker);
- if (retval != LTTNG_OK) {
- ERR("Error initializing ID tracker");
- goto end_restore;
- }
- retval = id_tracker_add_id(id_tracker, value);
- if (retval != LTTNG_OK) {
- fini_id_tracker(id_tracker);
- goto end_restore;
- }
- /* Remove all apps from session except pid. */
- should_update_apps = true;
- } else {
- struct ust_app *app;
-
- retval = id_tracker_add_id(id_tracker, value);
- if (retval != LTTNG_OK) {
- goto end_restore;
- }
- /* Add session to application */
- switch (tracker_type) {
- case LTTNG_TRACKER_VPID:
- app = ust_app_find_by_pid(value);
- if (app) {
- should_update_apps = true;
- }
- break;
- default:
- should_update_apps = true;
- }
+ break;
+ case LTTNG_TRACKING_POLICY_EXCLUDE_ALL:
+ case LTTNG_TRACKING_POLICY_INCLUDE_SET:
+ /* fall-through. */
+ fini_id_tracker(id_tracker);
+ ret_code = init_id_tracker(id_tracker);
+ if (ret_code != LTTNG_OK) {
+ ERR("Error initializing ID tracker");
+ goto end;
}
+ /* Remove all apps from session. */
+ should_update_apps = true;
+ break;
+ default:
+ abort();
}
if (should_update_apps && session->active) {
ust_app_global_update_all(session);
}
- goto end;
-
-end_restore:
- if (lttng_tracker_id_set_list(tracker_list, saved_ids) != LTTNG_OK) {
- ERR("Error on tracker add error handling.\n");
- }
end:
- lttng_tracker_ids_destroy(saved_ids);
- return retval;
+ return ret_code;
}
-/*
- * Called with the session lock held.
- */
-int trace_ust_untrack_id(enum lttng_tracker_type tracker_type,
+/* Called with the session lock held. */
+enum lttng_error_code trace_ust_process_attr_tracker_inclusion_set_add_value(
struct ltt_ust_session *session,
- const struct lttng_tracker_id *id)
+ enum lttng_process_attr process_attr,
+ const struct process_attr_value *value)
{
- int retval = LTTNG_OK;
+ enum lttng_error_code ret_code = LTTNG_OK;
bool should_update_apps = false;
- struct ust_id_tracker *id_tracker;
- struct lttng_tracker_list *tracker_list;
- int value;
- struct lttng_tracker_ids *saved_ids;
+ struct ust_id_tracker *id_tracker =
+ get_id_tracker(session, process_attr);
+ struct process_attr_tracker *tracker;
+ int integral_value;
+ enum process_attr_tracker_status status;
+ struct ust_app *app;
- 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;
- }
-
- tracker_list = get_id_tracker_list(session, tracker_type);
- if (!tracker_list) {
- return LTTNG_ERR_INVALID;
- }
- /* Save list for restore on error. */
- retval = lttng_tracker_id_get_list(tracker_list, &saved_ids);
- if (retval != LTTNG_OK) {
- return LTTNG_ERR_INVALID;
- }
- /* Remove from list. */
- retval = lttng_tracker_list_remove(tracker_list, id);
- if (retval != LTTNG_OK) {
+ /*
+ * Convert process attribute tracker value to the integral
+ * representation required by the kern-ctl API.
+ */
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_PROCESS_ID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ integral_value = (int) value->value.pid;
+ break;
+ case LTTNG_PROCESS_ATTR_USER_ID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ if (value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME) {
+ uid_t uid;
+
+ ret_code = utils_user_id_from_name(
+ value->value.user_name, &uid);
+ if (ret_code != LTTNG_OK) {
+ goto end;
+ }
+ integral_value = (int) uid;
+ } else {
+ integral_value = (int) value->value.uid;
+ }
+ break;
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ if (value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME) {
+ gid_t gid;
+
+ ret_code = utils_group_id_from_name(
+ value->value.group_name, &gid);
+ if (ret_code != LTTNG_OK) {
+ goto end;
+ }
+ integral_value = (int) gid;
+ } else {
+ integral_value = (int) value->value.gid;
+ }
+ break;
+ default:
+ ret_code = LTTNG_ERR_INVALID;
goto end;
}
- id_tracker = get_id_tracker(session, tracker_type);
- if (!id_tracker) {
- abort();
+ tracker = _trace_ust_get_process_attr_tracker(session, process_attr);
+ if (!tracker) {
+ ret_code = LTTNG_ERR_INVALID;
}
- if (value == -1) {
- /* Create empty tracker, replace old tracker. */
- struct ust_id_tracker tmp_tracker;
-
- tmp_tracker = *id_tracker;
- retval = init_id_tracker(id_tracker);
- if (retval != LTTNG_OK) {
- ERR("Error initializing ID tracker");
- /* Rollback operation. */
- *id_tracker = tmp_tracker;
- goto end_restore;
+ status = process_attr_tracker_inclusion_set_add_value(tracker, value);
+ if (status != PROCESS_ATTR_TRACKER_STATUS_OK) {
+ switch (status) {
+ case PROCESS_ATTR_TRACKER_STATUS_EXISTS:
+ ret_code = LTTNG_ERR_PROCESS_ATTR_EXISTS;
+ break;
+ case PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY:
+ ret_code = LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY;
+ break;
+ case PROCESS_ATTR_TRACKER_STATUS_ERROR:
+ default:
+ ret_code = LTTNG_ERR_UNK;
+ break;
}
- fini_id_tracker(&tmp_tracker);
+ goto end;
+ }
- /* Remove session from all applications */
- should_update_apps = true;
- } else {
- struct ust_app *app;
+ DBG("User space track %s %d for session id %" PRIu64,
+ lttng_process_attr_to_string(process_attr),
+ integral_value, session->id);
- if (!id_tracker->ht) {
- /* No ID being tracked. */
- retval = LTTNG_ERR_ID_NOT_TRACKED;
- goto end_restore;
- }
- /* Remove ID from tracker */
- retval = id_tracker_del_id(id_tracker, value);
- if (retval != LTTNG_OK) {
- goto end_restore;
- }
- switch (tracker_type) {
- case LTTNG_TRACKER_VPID:
- /* Remove session from application. */
- app = ust_app_find_by_pid(value);
- if (app) {
- should_update_apps = true;
- }
- break;
- default:
- /* Keep only apps matching ID. */
+ ret_code = id_tracker_add_id(id_tracker, integral_value);
+ if (ret_code != LTTNG_OK) {
+ goto end;
+ }
+ /* Add session to application */
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ app = ust_app_find_by_pid(integral_value);
+ if (app) {
should_update_apps = true;
}
+ break;
+ default:
+ should_update_apps = true;
+ break;
}
if (should_update_apps && session->active) {
ust_app_global_update_all(session);
}
- goto end;
-
-end_restore:
- if (lttng_tracker_id_set_list(tracker_list, saved_ids) != LTTNG_OK) {
- ERR("Error on tracker remove error handling.\n");
- }
end:
- lttng_tracker_ids_destroy(saved_ids);
- return retval;
+ return ret_code;
}
-/*
- * Called with session lock held.
- */
-int trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type,
+/* Called with the session lock held. */
+enum lttng_error_code trace_ust_process_attr_tracker_inclusion_set_remove_value(
struct ltt_ust_session *session,
- struct lttng_tracker_ids **_ids)
+ enum lttng_process_attr process_attr,
+ const struct process_attr_value *value)
{
- int ret = LTTNG_OK;
- struct lttng_tracker_list *tracker_list;
+ enum lttng_error_code ret_code = LTTNG_OK;
+ bool should_update_apps = false;
+ struct ust_id_tracker *id_tracker =
+ get_id_tracker(session, process_attr);
+ struct process_attr_tracker *tracker;
+ int integral_value;
+ enum process_attr_tracker_status status;
+ struct ust_app *app;
- if (tracker_type == LTTNG_TRACKER_PID) {
- DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain.");
- tracker_type = LTTNG_TRACKER_VPID;
+ /*
+ * Convert process attribute tracker value to the integral
+ * representation required by the kern-ctl API.
+ */
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_PROCESS_ID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ integral_value = (int) value->value.pid;
+ break;
+ case LTTNG_PROCESS_ATTR_USER_ID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ if (value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME) {
+ uid_t uid;
+
+ ret_code = utils_user_id_from_name(
+ value->value.user_name, &uid);
+ if (ret_code != LTTNG_OK) {
+ goto end;
+ }
+ integral_value = (int) uid;
+ } else {
+ integral_value = (int) value->value.uid;
+ }
+ break;
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ if (value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME) {
+ gid_t gid;
+
+ ret_code = utils_group_id_from_name(
+ value->value.group_name, &gid);
+ if (ret_code != LTTNG_OK) {
+ goto end;
+ }
+ integral_value = (int) gid;
+ } else {
+ integral_value = (int) value->value.gid;
+ }
+ break;
+ default:
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
}
- tracker_list = get_id_tracker_list(session, tracker_type);
- if (!tracker_list) {
- ret = -LTTNG_ERR_INVALID;
+ tracker = _trace_ust_get_process_attr_tracker(session, process_attr);
+ if (!tracker) {
+ ret_code = LTTNG_ERR_INVALID;
+ }
+
+ status = process_attr_tracker_inclusion_set_remove_value(
+ tracker, value);
+ if (status != PROCESS_ATTR_TRACKER_STATUS_OK) {
+ switch (status) {
+ case PROCESS_ATTR_TRACKER_STATUS_MISSING:
+ ret_code = LTTNG_ERR_PROCESS_ATTR_MISSING;
+ break;
+ case PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY:
+ ret_code = LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY;
+ break;
+ case PROCESS_ATTR_TRACKER_STATUS_ERROR:
+ default:
+ ret_code = LTTNG_ERR_UNK;
+ break;
+ }
goto end;
}
- ret = lttng_tracker_id_get_list(tracker_list, _ids);
- if (ret != LTTNG_OK) {
- ret = -LTTNG_ERR_INVALID;
+ DBG("User space untrack %s %d for session id %" PRIu64,
+ lttng_process_attr_to_string(process_attr),
+ integral_value, session->id);
+
+ ret_code = id_tracker_del_id(id_tracker, integral_value);
+ if (ret_code != LTTNG_OK) {
goto end;
}
+ /* Add session to application */
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ app = ust_app_find_by_pid(integral_value);
+ if (app) {
+ should_update_apps = true;
+ }
+ break;
+ default:
+ should_update_apps = true;
+ break;
+ }
+ if (should_update_apps && session->active) {
+ ust_app_global_update_all(session);
+ }
end:
- return ret;
+ return ret_code;
}
/*
buffer_reg_uid_destroy(reg, session->consumer);
}
- lttng_tracker_list_destroy(session->tracker_list_vpid);
- lttng_tracker_list_destroy(session->tracker_list_vuid);
- lttng_tracker_list_destroy(session->tracker_list_vgid);
+ process_attr_tracker_destroy(session->tracker_vpid);
+ process_attr_tracker_destroy(session->tracker_vuid);
+ process_attr_tracker_destroy(session->tracker_vgid);
fini_id_tracker(&session->vpid_tracker);
fini_id_tracker(&session->vuid_tracker);
#include <limits.h>
#include <urcu/list.h>
-#include <lttng/lttng.h>
-#include <common/hashtable/hashtable.h>
#include <common/defaults.h>
+#include <common/hashtable/hashtable.h>
+#include <common/tracker.h>
+#include <lttng/lttng.h>
#include "consumer.h"
#include "lttng-ust-ctl.h"
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;
+ struct process_attr_tracker *tracker_vpid;
+ struct process_attr_tracker *tracker_vuid;
+ struct process_attr_tracker *tracker_vgid;
};
/*
void trace_ust_destroy_context(struct ltt_ust_context *ctx);
void trace_ust_free_session(struct ltt_ust_session *session);
-int trace_ust_track_id(enum lttng_tracker_type tracker_type,
+int trace_ust_id_tracker_lookup(enum lttng_process_attr process_attr,
struct ltt_ust_session *session,
- const struct lttng_tracker_id *id);
-int trace_ust_untrack_id(enum lttng_tracker_type tracker_type,
+ int id);
+enum lttng_error_code trace_ust_process_attr_tracker_set_tracking_policy(
struct ltt_ust_session *session,
- const struct lttng_tracker_id *id);
-
-int trace_ust_id_tracker_lookup(enum lttng_tracker_type tracker_type,
+ enum lttng_process_attr process_attr,
+ enum lttng_tracking_policy policy);
+enum lttng_error_code trace_ust_process_attr_tracker_inclusion_set_add_value(
struct ltt_ust_session *session,
- int id);
-
-int trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type,
+ enum lttng_process_attr process_attr,
+ const struct process_attr_value *value);
+enum lttng_error_code trace_ust_process_attr_tracker_inclusion_set_remove_value(
+ struct ltt_ust_session *session,
+ enum lttng_process_attr process_attr,
+ const struct process_attr_value *value);
+const struct process_attr_tracker *trace_ust_get_process_attr_tracker(
struct ltt_ust_session *session,
- struct lttng_tracker_ids **_ids);
+ enum lttng_process_attr process_attr);
#else /* HAVE_LIBLTTNG_UST_CTL */
{
return NULL;
}
-static inline int trace_ust_track_id(enum lttng_tracker_type tracker_type,
+static inline int trace_ust_id_tracker_lookup(
+ enum lttng_process_attr process_attr,
struct ltt_ust_session *session,
- const struct lttng_tracker_id *id)
+ int id)
{
return 0;
}
-static inline int trace_ust_untrack_id(enum lttng_tracker_type tracker_type,
+static inline enum lttng_error_code
+trace_ust_process_attr_tracker_set_tracking_policy(
struct ltt_ust_session *session,
- const struct lttng_tracker_id *id)
+ enum lttng_process_attr process_attr,
+ enum lttng_tracking_policy policy)
{
- return 0;
+ return LTTNG_OK;
}
-static inline int trace_ust_id_tracker_lookup(
- enum lttng_tracker_type tracker_type,
+static inline enum lttng_error_code
+trace_ust_process_attr_tracker_inclusion_set_add_value(
struct ltt_ust_session *session,
- int pid)
+ enum lttng_process_attr process_attr,
+ const struct process_attr_value *value)
{
- return 0;
+ return LTTNG_OK;
}
-static inline int trace_ust_list_tracker_ids(
- enum lttng_tracker_type tracker_type,
+static inline enum lttng_error_code
+trace_ust_process_attr_tracker_inclusion_set_remove_value(
struct ltt_ust_session *session,
- struct lttng_tracker_ids **_ids)
+ enum lttng_process_attr process_attr,
+ const struct process_attr_value *value)
{
- return -1;
+ return LTTNG_OK;
}
+static inline const struct process_attr_tracker *
+trace_ust_get_process_attr_tracker(struct ltt_ust_session *session,
+ enum lttng_process_attr process_attr)
+{
+ return NULL;
+}
+
#endif /* HAVE_LIBLTTNG_UST_CTL */
#endif /* _LTT_TRACE_UST_H */
/*
* Copyright (C) 2018 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
* SPDX-License-Identifier: GPL-2.0-only
*
*/
+#include "lttng/tracker.h"
+#include "common/dynamic-array.h"
+#include "common/macros.h"
#define _LGPL_SOURCE
#include <grp.h>
#include <pwd.h>
#include <sys/types.h>
#include <unistd.h>
+#include <urcu.h>
+#include <urcu/list.h>
+#include <urcu/rculfhash.h>
#include "tracker.h"
#include <common/defaults.h>
#include <common/error.h>
#include <common/hashtable/hashtable.h>
#include <common/hashtable/utils.h>
+#include <common/tracker.h>
#include <lttng/lttng-error.h>
-#include <lttng/tracker-internal.h>
-#define FALLBACK_USER_BUFLEN 16384
-#define FALLBACK_GROUP_BUFLEN 16384
+struct process_attr_tracker_value_node {
+ struct process_attr_value *value;
+ struct cds_lfht_node inclusion_set_ht_node;
+ struct rcu_head rcu_head;
+};
-struct lttng_tracker_list *lttng_tracker_list_create(void)
+struct process_attr_tracker {
+ enum lttng_tracking_policy policy;
+ struct cds_lfht *inclusion_set_ht;
+};
+
+static void process_attr_tracker_value_node_rcu_free(struct rcu_head *rcu_head)
+{
+ struct process_attr_tracker_value_node *node =
+ container_of(rcu_head, typeof(*node), rcu_head);
+
+ free(node);
+}
+
+struct process_attr_tracker *process_attr_tracker_create(void)
{
- struct lttng_tracker_list *t;
+ struct process_attr_tracker *tracker;
- t = zmalloc(sizeof(*t));
- if (!t) {
+ tracker = zmalloc(sizeof(*tracker));
+ if (!tracker) {
return NULL;
}
- t->ht = cds_lfht_new(DEFAULT_HT_SIZE, 1, 0,
+
+ (void) process_attr_tracker_set_tracking_policy(
+ tracker, LTTNG_TRACKING_POLICY_INCLUDE_ALL);
+
+ tracker->inclusion_set_ht = cds_lfht_new(DEFAULT_HT_SIZE, 1, 0,
CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
- if (!t->ht) {
+ if (!tracker->inclusion_set_ht) {
goto error;
}
- CDS_INIT_LIST_HEAD(&t->list_head);
- t->state = LTTNG_TRACK_ALL;
- return t;
+ return tracker;
error:
- free(t);
+ process_attr_tracker_destroy(tracker);
return NULL;
}
-static int match_tracker_key(struct cds_lfht_node *node, const void *key)
+static void process_attr_tracker_remove_value_node(
+ struct process_attr_tracker *tracker,
+ struct process_attr_tracker_value_node *value_node)
{
- const struct lttng_tracker_id *tracker_key = key;
- struct lttng_tracker_list_node *tracker_node;
-
- tracker_node = caa_container_of(
- node, struct lttng_tracker_list_node, ht_node);
-
- return lttng_tracker_id_is_equal(tracker_node->id, tracker_key);
+ cds_lfht_del(tracker->inclusion_set_ht,
+ &value_node->inclusion_set_ht_node);
+ process_attr_value_destroy(value_node->value);
+ call_rcu(&value_node->rcu_head,
+ process_attr_tracker_value_node_rcu_free);
}
-static unsigned long hash_tracker_key(
- const struct lttng_tracker_id *tracker_key)
+static void process_attr_tracker_clear_inclusion_set(
+ struct process_attr_tracker *tracker)
{
- unsigned long key_hash = 0;
- int value;
- const char *string;
- enum lttng_tracker_id_type type;
-
- /* We do not care for invalid state during hash computation */
- type = lttng_tracker_id_get_type(tracker_key);
- (void) lttng_tracker_id_get_value(tracker_key, &value);
- (void) lttng_tracker_id_get_string(tracker_key, &string);
-
- switch (type) {
- case LTTNG_ID_ALL:
- break;
- case LTTNG_ID_VALUE:
- key_hash ^= hash_key_ulong(
- (void *) (unsigned long) value, lttng_ht_seed);
- break;
- case LTTNG_ID_STRING:
- key_hash ^= hash_key_str(string, lttng_ht_seed);
- break;
- case LTTNG_ID_UNKNOWN:
- break;
- }
- key_hash ^= hash_key_ulong(
- (void *) (unsigned long) type, lttng_ht_seed);
- return key_hash;
-}
+ int ret;
+ struct lttng_ht_iter iter;
+ struct process_attr_tracker_value_node *value_node;
-static struct lttng_tracker_id **lttng_tracker_list_lookup(
- const struct lttng_tracker_list *tracker_list,
- const struct lttng_tracker_id *key)
-{
- struct lttng_tracker_list_node *list_node;
- struct cds_lfht_iter iter;
- struct cds_lfht_node *node;
+ if (!tracker->inclusion_set_ht) {
+ return;
+ }
- cds_lfht_lookup(tracker_list->ht, hash_tracker_key(key),
- match_tracker_key, key, &iter);
- node = cds_lfht_iter_get_node(&iter);
- if (!node) {
- return NULL;
+ rcu_read_lock();
+ cds_lfht_for_each_entry (tracker->inclusion_set_ht, &iter.iter,
+ value_node, inclusion_set_ht_node) {
+ process_attr_tracker_remove_value_node(tracker, value_node);
}
- list_node = caa_container_of(
- node, struct lttng_tracker_list_node, ht_node);
- return &list_node->id;
+ rcu_read_unlock();
+ ret = cds_lfht_destroy(tracker->inclusion_set_ht, NULL);
+ assert(ret == 0);
+ tracker->inclusion_set_ht = NULL;
}
-static void destroy_list_node_rcu(struct rcu_head *head)
+static int process_attr_tracker_create_inclusion_set(
+ struct process_attr_tracker *tracker)
{
- struct lttng_tracker_list_node *n = caa_container_of(
- head, struct lttng_tracker_list_node, rcu_head);
-
- lttng_tracker_id_destroy(n->id);
- free(n);
+ assert(!tracker->inclusion_set_ht);
+ tracker->inclusion_set_ht = cds_lfht_new(DEFAULT_HT_SIZE, 1, 0,
+ CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
+ return tracker->inclusion_set_ht ? 0 : -1;
}
-static void _lttng_tracker_list_remove(struct lttng_tracker_list *tracker_list,
- struct lttng_tracker_list_node *n)
+void process_attr_tracker_destroy(struct process_attr_tracker *tracker)
{
- cds_list_del(&n->list_node);
-
- rcu_read_lock();
- cds_lfht_del(tracker_list->ht, &n->ht_node);
- rcu_read_unlock();
+ if (!tracker) {
+ return;
+ }
- call_rcu(&n->rcu_head, destroy_list_node_rcu);
+ process_attr_tracker_clear_inclusion_set(tracker);
+ free(tracker);
}
-static void lttng_tracker_list_reset(struct lttng_tracker_list *tracker_list)
+enum lttng_tracking_policy process_attr_tracker_get_tracking_policy(
+ const struct process_attr_tracker *tracker)
{
- struct lttng_tracker_list_node *n, *t;
-
- cds_list_for_each_entry_safe (
- n, t, &tracker_list->list_head, list_node) {
- _lttng_tracker_list_remove(tracker_list, n);
- }
- tracker_list->state = LTTNG_TRACK_ALL;
+ return tracker->policy;
}
-/* Protected by session mutex held by caller. */
-int lttng_tracker_list_add(struct lttng_tracker_list *tracker_list,
- const struct lttng_tracker_id *_id)
+int process_attr_tracker_set_tracking_policy(
+ struct process_attr_tracker *tracker,
+ enum lttng_tracking_policy tracking_policy)
{
- struct lttng_tracker_id **id;
- struct lttng_tracker_list_node *n = NULL;
- int ret;
+ int ret = 0;
- if (lttng_tracker_id_get_type(_id) == LTTNG_ID_ALL) {
- /* Track all, so remove each individual item. */
- lttng_tracker_list_reset(tracker_list);
- ret = LTTNG_OK;
- goto error;
- }
- rcu_read_lock();
- id = lttng_tracker_list_lookup(tracker_list, _id);
- /*
- * It is okay to release the RCU read lock here since id is only checked
- * for != NULL and not dereferenced.
- */
- rcu_read_unlock();
- if (id) {
- ret = LTTNG_ERR_ID_TRACKED;
- goto error;
- }
- n = zmalloc(sizeof(*n));
- if (!n) {
- ret = LTTNG_ERR_NOMEM;
- goto error;
+ if (tracker->policy == tracking_policy) {
+ goto end;
}
- n->id = lttng_tracker_id_duplicate(_id);
- if (!n->id) {
- ret = LTTNG_ERR_NOMEM;
- goto error;
+ process_attr_tracker_clear_inclusion_set(tracker);
+ ret = process_attr_tracker_create_inclusion_set(tracker);
+ if (ret) {
+ goto end;
}
-
- cds_list_add_tail(&n->list_node, &tracker_list->list_head);
- tracker_list->state = LTTNG_TRACK_LIST;
-
- rcu_read_lock();
- cds_lfht_add(tracker_list->ht, hash_tracker_key(n->id), &n->ht_node);
- rcu_read_unlock();
-
- return LTTNG_OK;
-
-error:
- free(n);
+ tracker->policy = tracking_policy;
+end:
return ret;
}
-/*
- * Lookup and remove.
- * Protected by session mutex held by caller.
- */
-int lttng_tracker_list_remove(struct lttng_tracker_list *tracker_list,
- const struct lttng_tracker_id *_id)
+static int match_inclusion_set_value(
+ struct cds_lfht_node *node, const void *key)
{
- enum lttng_error_code ret = LTTNG_OK;
- struct lttng_tracker_id **id;
- struct lttng_tracker_list_node *n;
-
- if (lttng_tracker_id_get_type(_id) == LTTNG_ID_ALL) {
- /* Untrack all. */
- lttng_tracker_list_reset(tracker_list);
- /* Set state to "track none". */
- tracker_list->state = LTTNG_TRACK_NONE;
- goto end;
- }
+ const struct process_attr_value *value_key = key;
+ const struct process_attr_tracker_value_node *value_node =
+ caa_container_of(node,
+ struct process_attr_tracker_value_node,
+ inclusion_set_ht_node);
- rcu_read_lock();
- id = lttng_tracker_list_lookup(tracker_list, _id);
- if (!id) {
- ret = LTTNG_ERR_ID_NOT_TRACKED;
- goto rcu_unlock;
- }
+ return process_attr_tracker_value_equal(value_node->value, value_key);
+}
- n = caa_container_of(id, struct lttng_tracker_list_node, id);
- _lttng_tracker_list_remove(tracker_list, n);
+static struct process_attr_tracker_value_node *process_attr_tracker_lookup(
+ const struct process_attr_tracker *tracker,
+ const struct process_attr_value *value)
+{
+ struct cds_lfht_iter iter;
+ struct cds_lfht_node *node;
-rcu_unlock:
+ assert(tracker->policy == LTTNG_TRACKING_POLICY_INCLUDE_SET);
+
+ rcu_read_lock();
+ cds_lfht_lookup(tracker->inclusion_set_ht,
+ process_attr_value_hash(value),
+ match_inclusion_set_value, value, &iter);
+ node = cds_lfht_iter_get_node(&iter);
rcu_read_unlock();
-end:
- return ret;
+
+ return node ? container_of(node, struct process_attr_tracker_value_node,
+ inclusion_set_ht_node) :
+ NULL;
}
-void lttng_tracker_list_destroy(struct lttng_tracker_list *tracker_list)
+/* Protected by session mutex held by caller. */
+enum process_attr_tracker_status process_attr_tracker_inclusion_set_add_value(
+ struct process_attr_tracker *tracker,
+ const struct process_attr_value *value)
{
- int ret;
+ enum process_attr_tracker_status status =
+ PROCESS_ATTR_TRACKER_STATUS_OK;
+ struct process_attr_value *value_copy = NULL;
+ struct process_attr_tracker_value_node *value_node = NULL;
- if (!tracker_list) {
- return;
+ rcu_read_lock();
+ if (tracker->policy != LTTNG_TRACKING_POLICY_INCLUDE_SET) {
+ status = PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY;
+ goto end;
}
- lttng_tracker_list_reset(tracker_list);
- ret = cds_lfht_destroy(tracker_list->ht, NULL);
- assert(!ret);
- free(tracker_list);
-}
-static int lttng_lookup_user(const char *username, int *result)
-{
- struct passwd p, *pres;
- int ret, retval = LTTNG_OK;
- char *buf = NULL;
- ssize_t buflen;
-
- buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
- if (buflen < 0) {
- buflen = FALLBACK_USER_BUFLEN;
- }
- buf = zmalloc(buflen);
- if (!buf) {
- retval = LTTNG_ERR_NOMEM;
+ if (process_attr_tracker_lookup(tracker, value)) {
+ status = PROCESS_ATTR_TRACKER_STATUS_EXISTS;
goto end;
}
- for (;;) {
- ret = getpwnam_r(username, &p, buf, buflen, &pres);
- switch (ret) {
- case EINTR:
- continue;
- case ERANGE:
- buflen *= 2;
- free(buf);
- buf = zmalloc(buflen);
- if (!buf) {
- retval = LTTNG_ERR_NOMEM;
- goto end;
- }
- continue;
- default:
- goto end_loop;
- }
- }
-end_loop:
-
- switch (ret) {
- case 0:
- if (pres == NULL) {
- retval = LTTNG_ERR_USER_NOT_FOUND;
- } else {
- *result = (int) p.pw_uid;
- DBG("Lookup of tracker UID/VUID: name '%s' maps to id %d.",
- username, *result);
- retval = LTTNG_OK;
- }
- break;
- case ENOENT:
- case ESRCH:
- case EBADF:
- case EPERM:
- retval = LTTNG_ERR_USER_NOT_FOUND;
- break;
- default:
- retval = LTTNG_ERR_NOMEM;
- }
-end:
- free(buf);
- return retval;
-}
-static int lttng_lookup_group(const char *groupname, int *result)
-{
- struct group g, *gres;
- int ret, retval = LTTNG_OK;
- char *buf = NULL;
- ssize_t buflen;
-
- buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
- if (buflen < 0) {
- buflen = FALLBACK_GROUP_BUFLEN;
+ value_node = zmalloc(sizeof(*value_node));
+ if (!value_node) {
+ status = PROCESS_ATTR_TRACKER_STATUS_ERROR;
+ goto end;
}
- buf = zmalloc(buflen);
- if (!buf) {
- retval = LTTNG_ERR_NOMEM;
+
+ value_copy = process_attr_value_copy(value);
+ if (!value_copy) {
+ status = PROCESS_ATTR_TRACKER_STATUS_ERROR;
goto end;
}
- for (;;) {
- ret = getgrnam_r(groupname, &g, buf, buflen, &gres);
- switch (ret) {
- case EINTR:
- continue;
- case ERANGE:
- buflen *= 2;
- free(buf);
- buf = zmalloc(buflen);
- if (!buf) {
- retval = LTTNG_ERR_NOMEM;
- goto end;
- }
- continue;
- default:
- goto end_loop;
- }
+
+ value_node->value = value_copy;
+ cds_lfht_add(tracker->inclusion_set_ht,
+ process_attr_value_hash(value_copy),
+ &value_node->inclusion_set_ht_node);
+ value_copy = NULL;
+ value_node = NULL;
+end:
+ if (value_copy) {
+ process_attr_value_destroy(value_copy);
}
-end_loop:
-
- switch (ret) {
- case 0:
- if (gres == NULL) {
- retval = LTTNG_ERR_GROUP_NOT_FOUND;
- } else {
- *result = (int) g.gr_gid;
- DBG("Lookup of tracker GID/GUID: name '%s' maps to id %d.",
- groupname, *result);
- retval = LTTNG_OK;
- }
- break;
- case ENOENT:
- case ESRCH:
- case EBADF:
- case EPERM:
- retval = LTTNG_ERR_GROUP_NOT_FOUND;
- break;
- default:
- retval = LTTNG_ERR_NOMEM;
+ if (value_node) {
+ free(value_node);
}
-end:
- free(buf);
- return retval;
+ rcu_read_unlock();
+ return status;
}
-int lttng_tracker_id_lookup_string(enum lttng_tracker_type tracker_type,
- const struct lttng_tracker_id *id,
- int *result)
+/* Protected by session mutex held by caller. */
+enum process_attr_tracker_status
+process_attr_tracker_inclusion_set_remove_value(
+ struct process_attr_tracker *tracker,
+ const struct process_attr_value *value)
{
- enum lttng_tracker_id_status status;
- int value;
- const char *string;
-
- switch (lttng_tracker_id_get_type(id)) {
- case LTTNG_ID_ALL:
- *result = -1;
- return LTTNG_OK;
- case LTTNG_ID_VALUE:
- status = lttng_tracker_id_get_value(id, &value);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- return LTTNG_ERR_INVALID;
- }
- *result = id->value;
- return LTTNG_OK;
- case LTTNG_ID_STRING:
- status = lttng_tracker_id_get_string(id, &string);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- return LTTNG_ERR_INVALID;
- }
- switch (tracker_type) {
- case LTTNG_TRACKER_PID:
- case LTTNG_TRACKER_VPID:
- ERR("Lookup of tracker PID/VPID by name unsupported.");
- return LTTNG_ERR_INVALID;
- case LTTNG_TRACKER_UID:
- case LTTNG_TRACKER_VUID:
- DBG("Lookup of tracker UID/VUID by name.");
- return lttng_lookup_user(string, result);
- case LTTNG_TRACKER_GID:
- case LTTNG_TRACKER_VGID:
- DBG("Lookup of tracker GID/VGID by name.");
- return lttng_lookup_group(string, result);
- default:
- return LTTNG_ERR_INVALID;
- }
- default:
- return LTTNG_ERR_INVALID;
- }
-}
+ struct process_attr_tracker_value_node *value_node;
+ enum process_attr_tracker_status status =
+ PROCESS_ATTR_TRACKER_STATUS_OK;
-/*
- * Protected by session mutex held by caller.
- * On success, _ids and the ids it contains must be freed by the caller.
- */
-int lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list,
- struct lttng_tracker_ids **_ids)
-{
- int retval = LTTNG_OK, ret;
- struct lttng_tracker_list_node *n;
- ssize_t count = 0, i = 0;
- struct lttng_tracker_ids *ids = NULL;
- struct lttng_tracker_id *id;
- enum lttng_tracker_id_status status;
-
- switch (tracker_list->state) {
- case LTTNG_TRACK_LIST:
- cds_list_for_each_entry (
- n, &tracker_list->list_head, list_node) {
- count++;
- }
- ids = lttng_tracker_ids_create(count);
- if (ids == NULL) {
- PERROR("Failed to allocate tracked ID list");
- retval = -LTTNG_ERR_NOMEM;
- goto end;
- }
- cds_list_for_each_entry (
- n, &tracker_list->list_head, list_node) {
- id = lttng_tracker_ids_get_pointer_of_index(ids, i);
- if (!id) {
- retval = -LTTNG_ERR_INVALID;
- goto error;
- }
-
- ret = lttng_tracker_id_copy(id, n->id);
- if (ret) {
- retval = -LTTNG_ERR_NOMEM;
- goto error;
- }
- i++;
- }
- break;
- case LTTNG_TRACK_ALL:
-
- ids = lttng_tracker_ids_create(1);
- if (ids == NULL) {
- PERROR("Failed to allocate tracked ID list");
- retval = -LTTNG_ERR_NOMEM;
- goto end;
- }
+ rcu_read_lock();
+ if (tracker->policy != LTTNG_TRACKING_POLICY_INCLUDE_SET) {
+ status = PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY;
+ goto end;
+ }
- id = lttng_tracker_ids_get_pointer_of_index(ids, 0);
- status = lttng_tracker_id_set_all(id);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ERR("Invalid tracker id for track all");
- retval = -LTTNG_ERR_INVALID;
- goto error;
- }
- break;
- case LTTNG_TRACK_NONE:
- /* No ids track, so we return 0 element collection. */
- ids = lttng_tracker_ids_create(0);
- if (ids == NULL) {
- PERROR("alloc list ids");
- retval = -LTTNG_ERR_NOMEM;
- goto end;
- }
- break;
+ value_node = process_attr_tracker_lookup(tracker, value);
+ if (!value_node) {
+ status = PROCESS_ATTR_TRACKER_STATUS_MISSING;
+ goto end;
}
- *_ids = ids;
+ process_attr_tracker_remove_value_node(tracker, value_node);
end:
- return retval;
-
-error:
- lttng_tracker_ids_destroy(ids);
- return retval;
+ rcu_read_unlock();
+ return status;
}
-int lttng_tracker_id_set_list(struct lttng_tracker_list *tracker_list,
- const struct lttng_tracker_ids *ids)
+enum process_attr_tracker_status process_attr_tracker_get_inclusion_set(
+ const struct process_attr_tracker *tracker,
+ struct lttng_process_attr_values **_values)
{
- unsigned int i, count;
- const struct lttng_tracker_id *id;
- enum lttng_tracker_id_status status;
-
- assert(tracker_list);
- assert(ids);
-
- lttng_tracker_list_reset(tracker_list);
-
- status = lttng_tracker_ids_get_count(ids, &count);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- return LTTNG_ERR_INVALID;
+ struct lttng_ht_iter iter;
+ struct process_attr_tracker_value_node *value_node;
+ enum process_attr_tracker_status status =
+ PROCESS_ATTR_TRACKER_STATUS_OK;
+ struct lttng_process_attr_values *values;
+ struct process_attr_value *new_value = NULL;
+
+ values = lttng_process_attr_values_create();
+ if (!values) {
+ status = PROCESS_ATTR_TRACKER_STATUS_ERROR;
+ goto error;
}
- if (count == 0) {
- /* Set state to "track none". */
- tracker_list->state = LTTNG_TRACK_NONE;
- return LTTNG_OK;
+ if (tracker->policy != LTTNG_TRACKING_POLICY_INCLUDE_SET) {
+ status = PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY;
+ goto error;
}
- if (count == 1) {
- id = lttng_tracker_ids_get_at_index(ids, 0);
- if (lttng_tracker_id_get_type(id) == LTTNG_ID_ALL) {
- /* Track all. */
- return LTTNG_OK;
+ rcu_read_lock();
+ cds_lfht_for_each_entry (tracker->inclusion_set_ht, &iter.iter,
+ value_node, inclusion_set_ht_node) {
+ int ret;
+
+ new_value = process_attr_value_copy(value_node->value);
+ if (!new_value) {
+ status = PROCESS_ATTR_TRACKER_STATUS_ERROR;
+ goto error_unlock;
}
- }
- for (i = 0; i < count; i++) {
- int ret;
- id = lttng_tracker_ids_get_at_index(ids, i);
- ret = lttng_tracker_list_add(tracker_list, id);
- if (ret != LTTNG_OK) {
- return ret;
+ ret = lttng_dynamic_pointer_array_add_pointer(
+ &values->array, new_value);
+ if (ret) {
+ status = PROCESS_ATTR_TRACKER_STATUS_ERROR;
+ goto error_unlock;
}
+
+ new_value = NULL;
}
- return LTTNG_OK;
+ rcu_read_unlock();
+ *_values = values;
+ return status;
+error_unlock:
+ rcu_read_unlock();
+error:
+ lttng_process_attr_values_destroy(values);
+ process_attr_value_destroy(new_value);
+ return status;
}
/*
* Copyright (C) 2018 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
* SPDX-License-Identifier: GPL-2.0-only
*
#ifndef _LTT_TRACKER_H
#define _LTT_TRACKER_H
+#include <common/tracker.h>
#include <lttng/tracker.h>
-#include <urcu.h>
-#include <urcu/list.h>
-#include <urcu/rculfhash.h>
-
-enum lttng_tracker_list_state {
- LTTNG_TRACK_ALL,
- LTTNG_TRACK_NONE,
- LTTNG_TRACK_LIST,
-};
-
-/* Tracker ID */
-struct lttng_tracker_list_node {
- struct lttng_tracker_id *id;
- struct cds_list_head list_node;
- struct cds_lfht_node ht_node;
- struct rcu_head rcu_head;
-};
+struct process_attr_tracker;
-struct lttng_tracker_list {
- struct cds_list_head list_head;
- /* Hash table for O(1) removal lookup. */
- struct cds_lfht *ht;
- enum lttng_tracker_list_state state;
+enum process_attr_tracker_status {
+ PROCESS_ATTR_TRACKER_STATUS_OK,
+ PROCESS_ATTR_TRACKER_STATUS_ERROR,
+ PROCESS_ATTR_TRACKER_STATUS_EXISTS,
+ PROCESS_ATTR_TRACKER_STATUS_MISSING,
+ PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY,
};
-struct lttng_tracker_list *lttng_tracker_list_create(void);
-void lttng_tracker_list_destroy(struct lttng_tracker_list *tracker_list);
-
-int lttng_tracker_list_add(struct lttng_tracker_list *tracker_list,
- const struct lttng_tracker_id *id);
-int lttng_tracker_list_remove(struct lttng_tracker_list *tracker_list,
- const struct lttng_tracker_id *id);
-
-int lttng_tracker_id_lookup_string(enum lttng_tracker_type tracker_type,
- const struct lttng_tracker_id *id,
- int *result);
-int lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list,
- struct lttng_tracker_ids **_ids);
-int lttng_tracker_id_set_list(struct lttng_tracker_list *tracker_list,
- const struct lttng_tracker_ids *_ids);
+struct process_attr_tracker *process_attr_tracker_create(void);
+void process_attr_tracker_destroy(struct process_attr_tracker *tracker);
+
+enum lttng_tracking_policy process_attr_tracker_get_tracking_policy(
+ const struct process_attr_tracker *tracker);
+int process_attr_tracker_set_tracking_policy(
+ struct process_attr_tracker *tracker,
+ enum lttng_tracking_policy tracking_policy);
+
+enum process_attr_tracker_status process_attr_tracker_inclusion_set_add_value(
+ struct process_attr_tracker *tracker,
+ const struct process_attr_value *value);
+enum process_attr_tracker_status
+process_attr_tracker_inclusion_set_remove_value(
+ struct process_attr_tracker *tracker,
+ const struct process_attr_value *value);
+
+enum process_attr_tracker_status process_attr_tracker_get_inclusion_set(
+ const struct process_attr_tracker *tracker,
+ struct lttng_process_attr_values **values);
#endif /* _LTT_TRACKER_H */
if (!app->compatible) {
return;
}
- if (trace_ust_id_tracker_lookup(LTTNG_TRACKER_VPID, usess, app->pid) &&
+ if (trace_ust_id_tracker_lookup(LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID,
+ usess, app->pid) &&
trace_ust_id_tracker_lookup(
- LTTNG_TRACKER_VUID, usess, app->uid) &&
+ LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID,
+ usess, app->uid) &&
trace_ust_id_tracker_lookup(
- LTTNG_TRACKER_VGID, usess, app->gid)) {
+ LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID,
+ usess, app->gid)) {
/*
* Synchronize the application's internal tracing configuration
* and start tracing.
/*
* Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
+ * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
* SPDX-License-Identifier: GPL-2.0-only
*
*/
+#include <stdint.h>
#define _LGPL_SOURCE
#include <inttypes.h>
#include <popt.h>
#include <common/mi-lttng.h>
#include <common/time.h>
+#include <common/tracker.h>
#include <lttng/constant.h>
#include <lttng/tracker.h>
return ret;
}
-static const char *get_tracker_str(enum lttng_tracker_type tracker_type)
+static const char *get_capitalized_process_attr_str(enum lttng_process_attr process_attr)
{
- switch (tracker_type) {
- case LTTNG_TRACKER_PID:
- return "PID";
- case LTTNG_TRACKER_VPID:
- return "VPID";
- case LTTNG_TRACKER_UID:
- return "UID";
- case LTTNG_TRACKER_VUID:
- return "VUID";
- case LTTNG_TRACKER_GID:
- return "GID";
- case LTTNG_TRACKER_VGID:
- return "VGID";
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_PROCESS_ID:
+ return "Process ID";
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ return "Virtual process ID";
+ case LTTNG_PROCESS_ATTR_USER_ID:
+ return "User ID";
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ return "Virtual user ID";
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
+ return "Group ID";
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ return "Virtual group ID";
+ default:
+ return "Unknown";
}
return NULL;
}
+static int handle_process_attr_status(enum lttng_process_attr process_attr,
+ enum lttng_process_attr_tracker_handle_status status)
+{
+ int ret = CMD_SUCCESS;
+
+ switch (status) {
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY:
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK:
+ /* Carry on. */
+ break;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR:
+ ERR("Communication occurred while fetching %s tracker",
+ lttng_process_attr_to_string(process_attr));
+ ret = CMD_ERROR;
+ break;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST:
+ ERR("Failed to get the inclusion set of the %s tracker: session `%s` no longer exists",
+ lttng_process_attr_to_string(process_attr),
+ handle->session_name);
+ ret = CMD_ERROR;
+ break;
+ default:
+ ERR("Unknown error occurred while fetching the inclusion set of the %s tracker",
+ lttng_process_attr_to_string(process_attr));
+ ret = CMD_ERROR;
+ break;
+ }
+
+ return ret;
+}
+
+static int mi_output_empty_tracker(enum lttng_process_attr process_attr)
+{
+ int ret;
+
+ ret = mi_lttng_process_attribute_tracker_open(writer, process_attr);
+ if (ret) {
+ goto end;
+ }
+
+ ret = mi_lttng_close_multi_element(writer, 2);
+end:
+ return ret;
+}
+
+static inline bool is_value_type_name(
+ enum lttng_process_attr_value_type value_type)
+{
+ return value_type == LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME ||
+ value_type == LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME;
+}
+
/*
- * List tracker ID(s) of session and domain.
+ * List a process attribute tracker for a session and domain tuple.
*/
-static int list_tracker_ids(enum lttng_tracker_type tracker_type)
+static int list_process_attr_tracker(enum lttng_process_attr process_attr)
{
int ret = 0;
- int enabled = 1;
- struct lttng_tracker_ids *ids = NULL;
- unsigned int nr_ids, i;
- const struct lttng_tracker_id *id;
- enum lttng_tracker_id_status status;
+ unsigned int count, i;
+ enum lttng_tracking_policy policy;
+ enum lttng_error_code ret_code;
+ enum lttng_process_attr_tracker_handle_status handle_status;
+ enum lttng_process_attr_values_status values_status;
+ const struct lttng_process_attr_values *values;
+ struct lttng_process_attr_tracker_handle *tracker_handle = NULL;
+
+ ret_code = lttng_session_get_tracker_handle(handle->session_name,
+ handle->domain.type, process_attr, &tracker_handle);
+ if (ret_code != LTTNG_OK) {
+ ERR("Failed to get process attribute tracker handle: %s",
+ lttng_strerror(ret_code));
+ ret = CMD_ERROR;
+ goto end;
+ }
- ret = lttng_list_tracker_ids(handle, tracker_type, &ids);
- if (ret) {
- return ret;
+ handle_status = lttng_process_attr_tracker_handle_get_inclusion_set(
+ tracker_handle, &values);
+ ret = handle_process_attr_status(process_attr, handle_status);
+ if (ret != CMD_SUCCESS) {
+ goto end;
}
- status = lttng_tracker_ids_get_count(ids, &nr_ids);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ret = CMD_ERROR;
+ handle_status = lttng_process_attr_tracker_handle_get_tracking_policy(
+ tracker_handle, &policy);
+ ret = handle_process_attr_status(process_attr, handle_status);
+ if (ret != CMD_SUCCESS) {
goto end;
}
- if (nr_ids == 1) {
- id = lttng_tracker_ids_get_at_index(ids, 0);
- if (id && lttng_tracker_id_get_type(id) == LTTNG_ID_ALL) {
- enabled = 0;
+ {
+ char *process_attr_name;
+ const int print_ret = asprintf(&process_attr_name, "%ss:",
+ get_capitalized_process_attr_str(process_attr));
+
+ if (print_ret == -1) {
+ ret = CMD_FATAL;
+ goto end;
}
+ _MSG(" %-22s", process_attr_name);
+ free(process_attr_name);
+ }
+ switch (policy) {
+ case LTTNG_TRACKING_POLICY_INCLUDE_SET:
+ break;
+ case LTTNG_TRACKING_POLICY_EXCLUDE_ALL:
+ if (writer) {
+ mi_output_empty_tracker(process_attr);
+ }
+ MSG("none");
+ ret = CMD_SUCCESS;
+ goto end;
+ case LTTNG_TRACKING_POLICY_INCLUDE_ALL:
+ MSG("all");
+ ret = CMD_SUCCESS;
+ goto end;
+ default:
+ ERR("Unknown tracking policy encoutered while listing the %s process attribute tracker of session `%s`",
+ lttng_process_attr_to_string(process_attr),
+ handle->session_name);
+ ret = CMD_FATAL;
+ goto end;
}
- if (enabled) {
- _MSG("%s tracker: [", get_tracker_str(tracker_type));
+ values_status = lttng_process_attr_values_get_count(values, &count);
+ if (values_status != LTTNG_PROCESS_ATTR_VALUES_STATUS_OK) {
+ ERR("Failed to get the count of values in the inclusion set of the %s process attribute tracker of session `%s`",
+ lttng_process_attr_to_string(process_attr),
+ handle->session_name);
+ ret = CMD_FATAL;
+ goto end;
+ }
- /* Mi tracker_id element */
+ if (count == 0) {
+ /* Functionally equivalent to the 'exclude all' policy. */
if (writer) {
- /* Open tracker_id and targets elements */
- ret = mi_lttng_id_tracker_open(writer, tracker_type);
- if (ret) {
- goto end;
- }
+ mi_output_empty_tracker(process_attr);
}
+ MSG("none");
+ ret = CMD_SUCCESS;
+ goto end;
+ }
- for (i = 0; i < nr_ids; i++) {
- enum lttng_tracker_id_status status =
- LTTNG_TRACKER_ID_STATUS_OK;
- int value;
- const char *value_string;
+ /* Mi tracker_id element */
+ if (writer) {
+ /* Open tracker_id and targets elements */
+ ret = mi_lttng_process_attribute_tracker_open(
+ writer, process_attr);
+ if (ret) {
+ goto end;
+ }
+ }
- id = lttng_tracker_ids_get_at_index(ids, i);
- if (!id) {
- ret = CMD_ERROR;
- goto end;
- }
+ for (i = 0; i < count; i++) {
+ const enum lttng_process_attr_value_type value_type =
+ lttng_process_attr_values_get_type_at_index(
+ values, i);
+ int64_t integral_value = INT64_MAX;
+ const char *name = "error";
+
+ if (i >= 1) {
+ _MSG(", ");
+ }
+ switch (value_type) {
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_PID:
+ {
+ pid_t pid;
+
+ values_status = lttng_process_attr_values_get_pid_at_index(
+ values, i, &pid);
+ integral_value = (int64_t) pid;
+ break;
+ }
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_UID:
+ {
+ uid_t uid;
- switch (lttng_tracker_id_get_type(id)) {
- case LTTNG_ID_ALL:
- break;
- case LTTNG_ID_VALUE:
- status = lttng_tracker_id_get_value(id, &value);
- break;
- case LTTNG_ID_STRING:
- status = lttng_tracker_id_get_string(
- id, &value_string);
- break;
- case LTTNG_ID_UNKNOWN:
- ret = CMD_ERROR;
- goto end;
- }
+ values_status = lttng_process_attr_values_get_uid_at_index(
+ values, i, &uid);
+ integral_value = (int64_t) uid;
+ break;
+ }
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_GID:
+ {
+ gid_t gid;
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ERR("Invalid state for tracker id");
- ret = CMD_ERROR;
- goto end;
- }
+ values_status = lttng_process_attr_values_get_gid_at_index(
+ values, i, &gid);
+ integral_value = (int64_t) gid;
+ break;
+ }
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME:
+ values_status = lttng_process_attr_values_get_user_name_at_index(
+ values, i, &name);
+ break;
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME:
+ values_status = lttng_process_attr_values_get_group_name_at_index(
+ values, i, &name);
+ break;
+ default:
+ ret = CMD_ERROR;
+ goto end;
+ }
- if (i) {
- _MSG(",");
- }
- switch (lttng_tracker_id_get_type(id)) {
- case LTTNG_ID_ALL:
- _MSG(" *");
- break;
- case LTTNG_ID_VALUE:
- _MSG(" %d", value);
- break;
- case LTTNG_ID_STRING:
- _MSG(" %s", value_string);
- break;
- case LTTNG_ID_UNKNOWN:
- ERR("Invalid state for tracker id");
- ret = CMD_ERROR;
- goto end;
- }
+ if (values_status != LTTNG_PROCESS_ATTR_VALUES_STATUS_OK) {
+ /*
+ * Not possible given the current liblttng-ctl
+ * implementation.
+ */
+ ERR("Unknown error occurred while fetching process attribute value in inclusion list");
+ ret = CMD_FATAL;
+ goto end;
+ }
- /* Mi */
- if (writer) {
- ret = mi_lttng_id_target(
- writer, tracker_type, id, 0);
- if (ret) {
- goto end;
- }
- }
+ if (is_value_type_name(value_type)) {
+ _MSG("`%s`", name);
+ } else {
+ _MSG("%" PRIi64, integral_value);
}
- _MSG(" ]\n\n");
- /* Mi close tracker_id and targets */
+ /* Mi */
if (writer) {
- ret = mi_lttng_close_multi_element(writer, 2);
+ ret = is_value_type_name(value_type) ?
+ mi_lttng_string_process_attribute_value(
+ writer,
+ process_attr,
+ name, false) :
+ mi_lttng_integral_process_attribute_value(
+ writer,
+ process_attr,
+ integral_value,
+ false);
if (ret) {
goto end;
}
}
}
+ MSG("");
+
+ /* Mi close tracker_id and targets */
+ if (writer) {
+ ret = mi_lttng_close_multi_element(writer, 2);
+ if (ret) {
+ goto end;
+ }
+ }
end:
- lttng_tracker_ids_destroy(ids);
+ lttng_process_attr_tracker_handle_destroy(tracker_handle);
return ret;
}
{
int ret = 0;
+ MSG("Tracked process attributes");
/* Trackers listing */
if (lttng_opt_mi) {
ret = mi_lttng_trackers_open(writer);
switch (domain->type) {
case LTTNG_DOMAIN_KERNEL:
/* pid tracker */
- ret = list_tracker_ids(LTTNG_TRACKER_PID);
+ ret = list_process_attr_tracker(LTTNG_PROCESS_ATTR_PROCESS_ID);
if (ret) {
goto end;
}
/* vpid tracker */
- ret = list_tracker_ids(LTTNG_TRACKER_VPID);
+ ret = list_process_attr_tracker(
+ LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID);
if (ret) {
goto end;
}
/* uid tracker */
- ret = list_tracker_ids(LTTNG_TRACKER_UID);
+ ret = list_process_attr_tracker(LTTNG_PROCESS_ATTR_USER_ID);
if (ret) {
goto end;
}
/* vuid tracker */
- ret = list_tracker_ids(LTTNG_TRACKER_VUID);
+ ret = list_process_attr_tracker(
+ LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID);
if (ret) {
goto end;
}
/* gid tracker */
- ret = list_tracker_ids(LTTNG_TRACKER_GID);
+ ret = list_process_attr_tracker(LTTNG_PROCESS_ATTR_GROUP_ID);
if (ret) {
goto end;
}
/* vgid tracker */
- ret = list_tracker_ids(LTTNG_TRACKER_VGID);
+ ret = list_process_attr_tracker(
+ LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID);
if (ret) {
goto end;
}
break;
case LTTNG_DOMAIN_UST:
/* vpid tracker */
- ret = list_tracker_ids(LTTNG_TRACKER_VPID);
+ ret = list_process_attr_tracker(
+ LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID);
if (ret) {
goto end;
}
/* vuid tracker */
- ret = list_tracker_ids(LTTNG_TRACKER_VUID);
+ ret = list_process_attr_tracker(
+ LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID);
if (ret) {
goto end;
}
/* vgid tracker */
- ret = list_tracker_ids(LTTNG_TRACKER_VGID);
+ ret = list_process_attr_tracker(
+ LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID);
if (ret) {
goto end;
}
default:
break;
}
+ MSG();
if (lttng_opt_mi) {
/* Close trackers element */
ret = mi_lttng_writer_close_element(writer);
/*
* Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
* Copyright (C) 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
* SPDX-License-Identifier: GPL-2.0-only
*
*/
+#include "common/dynamic-buffer.h"
+#include "common/tracker.h"
+#include "lttng/domain.h"
+#include "lttng/lttng-error.h"
+#include "lttng/tracker.h"
#define _LGPL_SOURCE
#include <ctype.h>
#include <popt.h>
#include <urcu/list.h>
+#include <common/dynamic-array.h>
#include <common/mi-lttng.h>
+#include <common/optional.h>
#include "../command.h"
+struct process_attr_command_args {
+ enum lttng_process_attr process_attr;
+ /* Present in the user's command. */
+ bool requested;
+ bool all;
+ struct lttng_dynamic_pointer_array string_args;
+};
+
enum cmd_type {
CMD_TRACK,
CMD_UNTRACK,
};
-enum tracker_type_state {
- STATE_NONE = 0,
- STATE_PID,
- STATE_VPID,
- STATE_UID,
- STATE_VUID,
- STATE_GID,
- STATE_VGID,
-};
-
-struct opt_type {
- int used;
- int all;
- char *string;
-};
-
-struct id_list {
- size_t nr;
- struct lttng_tracker_id **array;
-};
-
-static char *opt_session_name;
-static int opt_kernel;
-static int opt_userspace;
-
-static struct opt_type opt_pid, opt_vpid, opt_uid, opt_vuid, opt_gid, opt_vgid;
-
-static enum tracker_type_state type_state;
-
+/* Offset OPT_ values by one since libpopt gives '0' a special meaning. */
enum {
- OPT_HELP = 1,
+ OPT_PID = LTTNG_PROCESS_ATTR_PROCESS_ID + 1,
+ OPT_VPID = LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID + 1,
+ OPT_UID = LTTNG_PROCESS_ATTR_USER_ID + 1,
+ OPT_VUID = LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID + 1,
+ OPT_GID = LTTNG_PROCESS_ATTR_GROUP_ID + 1,
+ OPT_VGID = LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID + 1,
+ OPT_HELP,
OPT_LIST_OPTIONS,
OPT_SESSION,
- OPT_PID,
- OPT_VPID,
- OPT_UID,
- OPT_VUID,
- OPT_GID,
- OPT_VGID,
OPT_ALL,
};
+static char *opt_session_name;
+static int opt_kernel;
+static int opt_userspace;
+static char *opt_str_arg;
+
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, },
- { "vpid", 0, POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_vpid.string, OPT_VPID, 0, 0, },
- { "uid", 0, POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_uid.string, OPT_UID, 0, 0, },
- { "vuid", 0, POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_vuid.string, OPT_VUID, 0, 0, },
- { "gid", 0, POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_gid.string, OPT_GID, 0, 0, },
- { "vgid", 0, POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_vgid.string, OPT_VGID, 0, 0, },
+ { "pid", 'p', POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_str_arg, OPT_PID, 0, 0, },
+ { "vpid", 0, POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_str_arg, OPT_VPID, 0, 0, },
+ { "uid", 0, POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_str_arg, OPT_UID, 0, 0, },
+ { "vuid", 0, POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_str_arg, OPT_VUID, 0, 0, },
+ { "gid", 0, POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_str_arg, OPT_GID, 0, 0, },
+ { "vgid", 0, POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_str_arg, OPT_VGID, 0, 0, },
{ "all", 'a', POPT_ARG_NONE, 0, OPT_ALL, 0, 0, },
{ "list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, 0, 0, },
{ 0, 0, 0, 0, 0, 0, 0, },
};
-static struct id_list *alloc_id_list(size_t nr_items)
-{
- struct id_list *id_list;
- struct lttng_tracker_id **items;
-
- id_list = zmalloc(sizeof(*id_list));
- if (!id_list) {
- goto error;
- }
- items = zmalloc(nr_items * sizeof(*items));
- if (!items) {
- goto error;
- }
- id_list->nr = nr_items;
- id_list->array = items;
- return id_list;
-error:
- free(id_list);
- return NULL;
-}
+static struct process_attr_command_args
+ process_attr_commands[LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID + 1];
-static void free_id_list(struct id_list *list)
+static void process_attr_command_init(struct process_attr_command_args *cmd,
+ enum lttng_process_attr process_attr)
{
- size_t nr_items;
- int i;
-
- if (!list) {
- return;
- }
- nr_items = list->nr;
- for (i = 0; i < nr_items; i++) {
- struct lttng_tracker_id *item = list->array[i];
- lttng_tracker_id_destroy(item);
- }
- free(list);
+ cmd->process_attr = process_attr;
+ cmd->all = false;
+ lttng_dynamic_pointer_array_init(&cmd->string_args, NULL);
}
-static int parse_id_string(const char *_id_string,
- int all,
- struct id_list **_id_list,
- enum lttng_tracker_type tracker_type)
+static void process_attr_command_fini(struct process_attr_command_args *cmd)
{
- const char *one_id_str;
- char *iter;
- int retval = CMD_SUCCESS;
- int count = 0;
- struct id_list *id_list = NULL;
- char *id_string = NULL;
- char *endptr;
-
- if (all && _id_string) {
- ERR("An empty ID string is expected with --all");
- retval = CMD_ERROR;
- goto error;
- }
- if (!all && !_id_string) {
- ERR("An ID string is expected");
- retval = CMD_ERROR;
- goto error;
- }
- if (all) {
- enum lttng_tracker_id_status status;
- /* Empty `ID string means all IDs */
- id_list = alloc_id_list(1);
- if (!id_list) {
- ERR("Out of memory");
- retval = CMD_ERROR;
- goto error;
- }
-
- id_list->array[0] = lttng_tracker_id_create();
- if (id_list->array[0] == NULL) {
- ERR("Out of memory");
- retval = CMD_ERROR;
- goto error;
- }
-
- status = lttng_tracker_id_set_all(id_list->array[0]);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ERR("Invalid value for tracker id");
- retval = CMD_ERROR;
- goto error;
- }
- goto assign;
- }
-
- id_string = strdup(_id_string);
- if (!id_string) {
- ERR("Out of memory");
- retval = CMD_ERROR;
- goto error;
- }
-
- /* Count */
- one_id_str = strtok_r(id_string, ",", &iter);
- while (one_id_str != NULL) {
- unsigned long v;
-
- if (isdigit(one_id_str[0])) {
- errno = 0;
- v = strtoul(one_id_str, &endptr, 10);
- if ((v == 0 && errno == EINVAL) ||
- (v == ULONG_MAX && errno == ERANGE) ||
- (*one_id_str != '\0' &&
- *endptr != '\0')) {
- ERR("Error parsing ID %s", one_id_str);
- retval = CMD_ERROR;
- goto error;
- }
-
- if ((long) v > INT_MAX || (int) v < 0) {
- ERR("Invalid ID value %ld", (long) v);
- retval = CMD_ERROR;
- goto error;
- }
- }
- count++;
-
- /* For next loop */
- one_id_str = strtok_r(NULL, ",", &iter);
- }
- if (count == 0) {
- ERR("Fatal error occurred when parsing pid string");
- retval = CMD_ERROR;
- goto error;
- }
-
- free(id_string);
- /* Identity of delimiter has been lost in first pass. */
- id_string = strdup(_id_string);
- if (!id_string) {
- ERR("Out of memory");
- retval = CMD_ERROR;
- goto error;
- }
-
- /* Allocate */
- id_list = alloc_id_list(count);
- if (!id_list) {
- ERR("Out of memory");
- retval = CMD_ERROR;
- goto error;
- }
-
- /* Reparse string and populate the id list. */
- count = 0;
- one_id_str = strtok_r(id_string, ",", &iter);
- while (one_id_str != NULL) {
- enum lttng_tracker_id_status status;
- struct lttng_tracker_id *item;
- item = lttng_tracker_id_create();
- if (item == NULL) {
- ERR("Out of memory");
- retval = CMD_ERROR;
- goto error;
- }
-
- id_list->array[count++] = item;
- if (isdigit(one_id_str[0])) {
- unsigned long v;
-
- v = strtoul(one_id_str, NULL, 10);
- status = lttng_tracker_id_set_value(item, (int) v);
- if (status == LTTNG_TRACKER_ID_STATUS_INVALID) {
- ERR("Invalid value");
- retval = CMD_ERROR;
- goto error;
- }
- } else {
- status = lttng_tracker_id_set_string(item, one_id_str);
- if (status == LTTNG_TRACKER_ID_STATUS_INVALID) {
- ERR("Failed to set ID string");
- retval = CMD_ERROR;
- goto error;
- }
- }
-
- /* For next loop */
- one_id_str = strtok_r(NULL, ",", &iter);
- }
-
-assign:
- /* SUCCESS */
- *_id_list = id_list;
- goto end;
-
-error:
- /* ERROR */
- free_id_list(id_list);
-end:
- free(id_string);
- return retval;
+ lttng_dynamic_pointer_array_reset(&cmd->string_args);
}
-static const char *get_tracker_str(enum lttng_tracker_type tracker_type)
+static const char *get_capitalized_process_attr_str(enum lttng_process_attr process_attr)
{
- switch (tracker_type) {
- case LTTNG_TRACKER_PID:
- return "PID";
- case LTTNG_TRACKER_VPID:
- return "VPID";
- case LTTNG_TRACKER_UID:
- return "UID";
- case LTTNG_TRACKER_VUID:
- return "VUID";
- case LTTNG_TRACKER_GID:
- return "GID";
- case LTTNG_TRACKER_VGID:
- return "VGID";
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_PROCESS_ID:
+ return "Process ID";
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ return "Virtual process ID";
+ case LTTNG_PROCESS_ATTR_USER_ID:
+ return "User ID";
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ return "Virtual user ID";
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
+ return "Group ID";
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ return "Virtual group ID";
default:
- return NULL;
+ return "Unknown";
}
return NULL;
}
-static int ust_tracker_type_support(enum lttng_tracker_type *tracker_type)
+static bool ust_process_attr_supported(enum lttng_process_attr *process_attr)
{
- int ret;
-
- switch (*tracker_type) {
- case LTTNG_TRACKER_PID:
- *tracker_type = LTTNG_TRACKER_VPID;
- ret = 0;
- break;
- case LTTNG_TRACKER_VPID:
- case LTTNG_TRACKER_VUID:
- case LTTNG_TRACKER_VGID:
- ret = 0;
- break;
- case LTTNG_TRACKER_UID:
- case LTTNG_TRACKER_GID:
- ERR("The %s tracker is invalid for UST domain.",
- get_tracker_str(*tracker_type));
- ret = -1;
+ bool supported;
+
+ switch (*process_attr) {
+ case LTTNG_PROCESS_ATTR_PROCESS_ID:
+ *process_attr = LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID;
+ /* fall-through. */
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ supported = true;
break;
default:
- ret = -1;
+ ERR("The %s process attribute cannot be tracked in the user space domain.",
+ lttng_process_attr_to_string(*process_attr));
+ supported = false;
break;
}
-
- return ret;
+ return supported;
}
-static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type,
- const char *cmd_str,
- const char *session_name,
- const char *id_string,
- int all,
- struct mi_writer *writer,
- enum lttng_tracker_type tracker_type)
+static const char *get_mi_element_command(enum cmd_type cmd_type)
{
- int ret, success = 1 , i;
- enum cmd_error_code retval = CMD_SUCCESS;
- struct id_list *id_list = NULL;
- struct lttng_domain dom;
- struct lttng_handle *handle = NULL;
- int (*cmd_func)(struct lttng_handle *handle,
- enum lttng_tracker_type tracker_type,
- const struct lttng_tracker_id *id);
- const char *tracker_str;
-
switch (cmd_type) {
case CMD_TRACK:
- cmd_func = lttng_track_id;
- break;
+ return mi_lttng_element_command_track;
case CMD_UNTRACK:
- cmd_func = lttng_untrack_id;
- break;
+ return mi_lttng_element_command_untrack;
default:
- ERR("Unknown command");
- retval = CMD_ERROR;
- goto end;
+ abort();
}
- memset(&dom, 0, sizeof(dom));
- if (opt_kernel) {
- dom.type = LTTNG_DOMAIN_KERNEL;
- } else if (opt_userspace) {
- dom.type = LTTNG_DOMAIN_UST;
- ret = ust_tracker_type_support(&tracker_type);
+}
+
+static enum cmd_error_code run_command_all(enum cmd_type cmd_type,
+ const char *session_name,
+ enum lttng_domain_type domain_type,
+ enum lttng_process_attr process_attr,
+ struct mi_writer *writer)
+{
+ struct lttng_process_attr_tracker_handle *tracker_handle = NULL;
+ const enum lttng_error_code handle_ret_code =
+ lttng_session_get_tracker_handle(session_name,
+ domain_type, process_attr,
+ &tracker_handle);
+ enum cmd_error_code cmd_ret = CMD_SUCCESS;
+ enum lttng_process_attr_tracker_handle_status status;
+
+ if (writer) {
+ const int ret = mi_lttng_all_process_attribute_value(
+ writer, process_attr, true);
if (ret) {
- ERR("Invalid parameter");
- retval = CMD_ERROR;
+ cmd_ret = CMD_FATAL;
goto end;
}
- } else {
- /* Checked by the caller. */
- assert(0);
- }
- tracker_str = get_tracker_str(tracker_type);
- if (!tracker_str) {
- ERR("Unknown tracker type");
- retval = CMD_ERROR;
- goto end;
- }
- ret = parse_id_string(id_string, all, &id_list, tracker_type);
- if (ret != CMD_SUCCESS) {
- ERR("Error parsing %s string", tracker_str);
- retval = CMD_ERROR;
- goto end;
}
- handle = lttng_create_handle(session_name, &dom);
- if (handle == NULL) {
- retval = CMD_ERROR;
+ if (handle_ret_code != LTTNG_OK) {
+ ERR("Session `%s` does not exist", session_name);
+ cmd_ret = CMD_FATAL;
goto end;
}
+ status = lttng_process_attr_tracker_handle_set_tracking_policy(
+ tracker_handle,
+ cmd_type == CMD_TRACK ?
+ LTTNG_TRACKING_POLICY_INCLUDE_ALL :
+ LTTNG_TRACKING_POLICY_EXCLUDE_ALL);
+ switch (status) {
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK:
+ if (cmd_type == CMD_TRACK) {
+ MSG("%s tracking policy set to `include all`",
+ get_capitalized_process_attr_str(process_attr));
+ } else {
+ MSG("%s tracking policy set to `exclude all`",
+ get_capitalized_process_attr_str(process_attr));
+ }
+ break;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST:
+ ERR("%s", lttng_strerror(-LTTNG_ERR_SESS_NOT_FOUND));
+ break;
+ default:
+ ERR("Unknown error encountered while setting tracking policy of %s tracker to `%s`",
+ lttng_process_attr_to_string(process_attr),
+ cmd_type == CMD_TRACK ? "include all" :
+ "exclude all");
+ cmd_ret = CMD_FATAL;
+ break;
+ }
+end:
if (writer) {
- /* Open tracker_id and targets elements */
- ret = mi_lttng_id_tracker_open(writer, tracker_type);
+ int ret = mi_lttng_writer_write_element_bool(writer,
+ mi_lttng_element_success,
+ cmd_ret == CMD_SUCCESS);
+
if (ret) {
- goto end;
+ cmd_ret = CMD_FATAL;
+ } else {
+ ret = mi_lttng_writer_close_element(writer);
+ cmd_ret = ret == 0 ? cmd_ret : CMD_FATAL;
}
}
+ lttng_process_attr_tracker_handle_destroy(tracker_handle);
+ return cmd_ret;
+}
- for (i = 0; i < id_list->nr; i++) {
- struct lttng_tracker_id *item = id_list->array[i];
- enum lttng_tracker_id_type type =
- lttng_tracker_id_get_type(item);
- enum lttng_tracker_id_status status =
- LTTNG_TRACKER_ID_STATUS_OK;
- int value;
- const char *value_string;
-
- switch (type) {
- case LTTNG_ID_ALL:
- /* Nothing to check */
- break;
- case LTTNG_ID_VALUE:
- status = lttng_tracker_id_get_value(item, &value);
- break;
- case LTTNG_ID_STRING:
- status = lttng_tracker_id_get_string(
- item, &value_string);
- break;
- default:
- retval = CMD_ERROR;
- goto end;
- }
+static enum cmd_error_code run_command_string(enum cmd_type cmd_type,
+ const char *session_name,
+ enum lttng_domain_type domain_type,
+ enum lttng_process_attr process_attr,
+ const char *_args,
+ struct mi_writer *writer)
+{
+ struct lttng_process_attr_tracker_handle *tracker_handle;
+ const enum lttng_error_code handle_ret_code =
+ lttng_session_get_tracker_handle(session_name,
+ domain_type, process_attr,
+ &tracker_handle);
+ enum cmd_error_code cmd_ret = CMD_SUCCESS;
+ const char *one_value_str;
+ char *args = strdup(_args);
+ char *iter = args;
+ bool policy_set = false;
+
+ if (!args) {
+ ERR("%s", lttng_strerror(-LTTNG_ERR_NOMEM));
+ cmd_ret = CMD_FATAL;
+ goto end;
+ }
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ERR("Tracker id object is in an invalid state");
- retval = CMD_ERROR;
- goto end;
- }
+ if (handle_ret_code != LTTNG_OK) {
+ ERR("%s", lttng_strerror(-handle_ret_code));
+ cmd_ret = CMD_FATAL;
+ goto end;
+ }
- switch (type) {
- case LTTNG_ID_ALL:
- DBG("%s all IDs", cmd_str);
- break;
- case LTTNG_ID_VALUE:
- DBG("%s ID %d", cmd_str, value);
- break;
- case LTTNG_ID_STRING:
- DBG("%s ID '%s'", cmd_str, value_string);
- break;
- default:
- retval = CMD_ERROR;
- goto end;
+ while ((one_value_str = strtok_r(iter, ",", &iter)) != NULL) {
+ const bool is_numerical_argument = isdigit(one_value_str[0]);
+ enum lttng_process_attr_tracker_handle_status status;
+ enum lttng_tracking_policy policy;
+ int ret;
+ char *prettified_arg;
+
+ if (!policy_set) {
+ status = lttng_process_attr_tracker_handle_get_tracking_policy(
+ tracker_handle, &policy);
+ if (status != LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK) {
+ break;
+ }
+
+ if (policy != LTTNG_TRACKING_POLICY_INCLUDE_SET) {
+ status = lttng_process_attr_tracker_handle_set_tracking_policy(
+ tracker_handle,
+ LTTNG_TRACKING_POLICY_INCLUDE_SET);
+ if (status != LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK) {
+ break;
+ }
+ }
+ policy_set = true;
}
- ret = cmd_func(handle, tracker_type, item);
- if (ret) {
- const char *msg = NULL;
+ if (is_numerical_argument) {
+ const unsigned long one_value_int =
+ strtoul(one_value_str, NULL, 10);
+
+ if (writer) {
+ const int ret = mi_lttng_integral_process_attribute_value(
+ writer, process_attr,
+ (int64_t) one_value_int, true);
+ if (ret) {
+ cmd_ret = CMD_FATAL;
+ goto end;
+ }
+ }
- switch (-ret) {
- case LTTNG_ERR_ID_TRACKED:
- msg = "already tracked";
- success = 1;
- retval = CMD_SUCCESS;
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_PROCESS_ID:
+ status = cmd_type == CMD_TRACK ?
+ lttng_process_attr_process_id_tracker_handle_add_pid(
+ tracker_handle,
+ (pid_t) one_value_int) :
+ lttng_process_attr_process_id_tracker_handle_remove_pid(
+ tracker_handle,
+ (pid_t) one_value_int);
break;
- case LTTNG_ERR_ID_NOT_TRACKED:
- msg = "already not tracked";
- success = 1;
- retval = CMD_SUCCESS;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ status = cmd_type == CMD_TRACK ?
+ lttng_process_attr_virtual_process_id_tracker_handle_add_pid(
+ tracker_handle,
+ (pid_t) one_value_int) :
+ lttng_process_attr_virtual_process_id_tracker_handle_remove_pid(
+ tracker_handle,
+ (pid_t) one_value_int);
break;
- default:
- ERR("%s", lttng_strerror(ret));
- success = 0;
- retval = CMD_ERROR;
+ case LTTNG_PROCESS_ATTR_USER_ID:
+ status = cmd_type == CMD_TRACK ?
+ lttng_process_attr_user_id_tracker_handle_add_uid(
+ tracker_handle,
+ (uid_t) one_value_int) :
+ lttng_process_attr_user_id_tracker_handle_remove_uid(
+ tracker_handle,
+ (uid_t) one_value_int);
+ break;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ status = cmd_type == CMD_TRACK ?
+ lttng_process_attr_virtual_user_id_tracker_handle_add_uid(
+ tracker_handle,
+ (uid_t) one_value_int) :
+ lttng_process_attr_virtual_user_id_tracker_handle_remove_uid(
+ tracker_handle,
+ (uid_t) one_value_int);
+ break;
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
+ status = cmd_type == CMD_TRACK ?
+ lttng_process_attr_group_id_tracker_handle_add_gid(
+ tracker_handle,
+ (gid_t) one_value_int) :
+ lttng_process_attr_group_id_tracker_handle_remove_gid(
+ tracker_handle,
+ (gid_t) one_value_int);
break;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ status = cmd_type == CMD_TRACK ?
+ lttng_process_attr_virtual_group_id_tracker_handle_add_gid(
+ tracker_handle,
+ (gid_t) one_value_int) :
+ lttng_process_attr_virtual_group_id_tracker_handle_remove_gid(
+ tracker_handle,
+ (gid_t) one_value_int);
+ break;
+ default:
+ abort();
}
- if (msg) {
- switch (type) {
- case LTTNG_ID_ALL:
- WARN("All %ss %s in session %s",
- tracker_str, msg,
- session_name);
- break;
- case LTTNG_ID_VALUE:
- WARN("%s %i %s in session %s",
- tracker_str, value, msg,
- session_name);
- break;
- case LTTNG_ID_STRING:
- WARN("%s '%s' %s in session %s",
- tracker_str,
- value_string, msg,
- session_name);
- break;
- default:
- retval = CMD_ERROR;
+
+ } else {
+ if (writer) {
+ const int ret = mi_lttng_string_process_attribute_value(
+ writer, process_attr,
+ one_value_str, true);
+ if (ret) {
+ cmd_ret = CMD_FATAL;
goto end;
}
}
- } else {
- switch (type) {
- case LTTNG_ID_ALL:
- MSG("All %ss %sed in session %s", tracker_str,
- cmd_str, session_name);
+
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_USER_ID:
+ status = cmd_type == CMD_TRACK ?
+ lttng_process_attr_user_id_tracker_handle_add_user_name(
+ tracker_handle,
+ one_value_str) :
+ lttng_process_attr_user_id_tracker_handle_remove_user_name(
+ tracker_handle,
+ one_value_str);
break;
- case LTTNG_ID_VALUE:
- MSG("%s %i %sed in session %s", tracker_str,
- value, cmd_str, session_name);
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ status = cmd_type == CMD_TRACK ?
+ lttng_process_attr_virtual_user_id_tracker_handle_add_user_name(
+ tracker_handle,
+ one_value_str) :
+ lttng_process_attr_virtual_user_id_tracker_handle_remove_user_name(
+ tracker_handle,
+ one_value_str);
break;
- case LTTNG_ID_STRING:
- MSG("%s '%s' %sed in session %s", tracker_str,
- value_string, cmd_str,
- session_name);
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
+ status = cmd_type == CMD_TRACK ?
+ lttng_process_attr_group_id_tracker_handle_add_group_name(
+ tracker_handle,
+ one_value_str) :
+ lttng_process_attr_group_id_tracker_handle_remove_group_name(
+ tracker_handle,
+ one_value_str);
+ break;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ status = cmd_type == CMD_TRACK ?
+ lttng_process_attr_virtual_group_id_tracker_handle_add_group_name(
+ tracker_handle,
+ one_value_str) :
+ lttng_process_attr_virtual_group_id_tracker_handle_remove_group_name(
+ tracker_handle,
+ one_value_str);
break;
default:
- retval = CMD_ERROR;
+ ERR("%s is not a valid %s value; expected an integer",
+ one_value_str,
+ lttng_process_attr_to_string(
+ process_attr));
+ cmd_ret = CMD_FATAL;
goto end;
}
- success = 1;
}
- /* Mi */
- if (writer) {
- ret = mi_lttng_id_target(writer, tracker_type, item, 1);
- if (ret) {
- retval = CMD_ERROR;
- goto end;
- }
+ ret = asprintf(&prettified_arg,
+ is_numerical_argument ? "%s" : "`%s`",
+ one_value_str);
+ if (ret < 0) {
+ PERROR("Failed to format argument `%s`", one_value_str);
+ cmd_ret = CMD_FATAL;
+ goto end;
+ }
- ret = mi_lttng_writer_write_element_bool(writer,
- mi_lttng_element_success, success);
- if (ret) {
- retval = CMD_ERROR;
- goto end;
+ switch (status) {
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK:
+ if (cmd_type == CMD_TRACK) {
+ MSG("Added %s to the %s tracker inclusion set",
+ one_value_str,
+ lttng_process_attr_to_string(
+ process_attr));
+ } else {
+ MSG("Removed %s from the %s tracker inclusion set",
+ one_value_str,
+ lttng_process_attr_to_string(
+ process_attr));
}
+ break;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST:
+ ERR("Session `%s` not found", session_name);
+ break;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_EXISTS:
+ WARN("%s is already in the %s inclusion set",
+ prettified_arg,
+ lttng_process_attr_to_string(
+ process_attr));
+ break;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_MISSING:
+ WARN("%s is not in the %s the inclusion set",
+ prettified_arg,
+ lttng_process_attr_to_string(
+ process_attr));
+ break;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_USER_NOT_FOUND:
+ ERR("User %s was not found", prettified_arg);
+ cmd_ret = CMD_ERROR;
+ break;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_GROUP_NOT_FOUND:
+ ERR("Group %s was not found", prettified_arg);
+ cmd_ret = CMD_ERROR;
+ break;
+ default:
+ ERR("Unknown error encountered while %s %s %s %s tracker's inclusion set",
+ cmd_type == CMD_TRACK ? "adding" :
+ "removing",
+ lttng_process_attr_to_string(
+ process_attr),
+ prettified_arg,
+ cmd_type == CMD_TRACK ? "to" : "from");
+ cmd_ret = CMD_FATAL;
+ break;
+ }
+ free(prettified_arg);
+
+ if (writer) {
+ int ret = mi_lttng_writer_write_element_bool(writer,
+ mi_lttng_element_success,
+ cmd_ret == CMD_SUCCESS);
- ret = mi_lttng_writer_close_element(writer);
if (ret) {
- retval = CMD_ERROR;
- goto end;
+ cmd_ret = CMD_FATAL;
+ } else {
+ ret = mi_lttng_writer_close_element(writer);
+ cmd_ret = ret == 0 ? cmd_ret : CMD_FATAL;
}
}
}
+end:
+ free(args);
+ lttng_process_attr_tracker_handle_destroy(tracker_handle);
+ return cmd_ret;
+}
+
+static enum cmd_error_code run_command(enum cmd_type cmd_type,
+ const char *session_name,
+ const struct process_attr_command_args *command_args,
+ struct mi_writer *writer)
+{
+ const enum lttng_domain_type domain_type =
+ opt_kernel ? LTTNG_DOMAIN_KERNEL : LTTNG_DOMAIN_UST;
+ enum cmd_error_code cmd_ret = CMD_SUCCESS;
+ unsigned int i;
+ const unsigned int string_arg_count =
+ lttng_dynamic_pointer_array_get_count(
+ &command_args->string_args);
+ enum lttng_process_attr process_attr = command_args->process_attr;
+
+ if (opt_userspace) {
+ /*
+ * Check that this process attribute can be tracked
+ * in the user space domain. Backward-compatibility
+ * changes are be applied to process_attr as needed.
+ */
+ if (!ust_process_attr_supported(&process_attr)) {
+ cmd_ret = CMD_ERROR;
+ goto end;
+ }
+ }
if (writer) {
- /* Close targets and tracker_id elements */
- ret = mi_lttng_close_multi_element(writer, 2);
+ /* Open tracker and trackers elements */
+ const int ret = mi_lttng_process_attribute_tracker_open(
+ writer, process_attr);
if (ret) {
- retval = CMD_ERROR;
+ cmd_ret = CMD_FATAL;
goto end;
}
}
-end:
- if (handle) {
- lttng_destroy_handle(handle);
- }
- free_id_list(id_list);
- return retval;
-}
+ if (command_args->all) {
+ cmd_ret = run_command_all(cmd_type, session_name, domain_type,
+ process_attr, writer);
+ } else {
+ bool error_occurred = false;
-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;
+ for (i = 0; i < string_arg_count; i++) {
+ const char *arg = lttng_dynamic_pointer_array_get_pointer(
+ &command_args->string_args, i);
+
+ cmd_ret = run_command_string(cmd_type, session_name,
+ domain_type, process_attr, arg, writer);
+ if (cmd_ret != CMD_SUCCESS) {
+ error_occurred = true;
+ if (cmd_ret == CMD_FATAL) {
+ break;
+ }
+ goto end;
+ }
+ }
+ if (error_occurred) {
+ cmd_ret = CMD_ERROR;
+ }
}
-}
-static void print_err_duplicate(const char *type)
-{
- ERR("The --%s option can only be used once. A list of comma-separated values can be specified.",
- type);
+ if (writer) {
+ /* Close tracker and trackers elements */
+ const int ret = mi_lttng_close_multi_element(
+ writer, 2);
+ if (ret) {
+ cmd_ret = CMD_FATAL;
+ goto end;
+ }
+ }
+end:
+ return cmd_ret;
}
/*
* 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, const char *help_msg)
+static int cmd_track_untrack(enum cmd_type cmd_type,
+ int argc,
+ const char **argv,
+ const char *help_msg)
{
- int opt, ret = 0, success = 1;
- bool opt_all_present = false;
+ int opt, ret = 0;
+ bool sub_command_failed = false;
+ bool opt_all = false;
+ unsigned int selected_process_attr_tracker_count = 0;
+ const unsigned int command_count =
+ sizeof(process_attr_commands) /
+ sizeof(struct process_attr_command_args);
enum cmd_error_code command_ret = CMD_SUCCESS;
static poptContext pc;
char *session_name = NULL;
const char *leftover = NULL;
struct mi_writer *writer = NULL;
+ size_t i;
+
+ for (i = 0; i < command_count; i++) {
+ process_attr_command_init(&process_attr_commands[i], i);
+ }
if (argc < 1) {
command_ret = CMD_ERROR;
case OPT_SESSION:
break;
case OPT_PID:
- if (opt_pid.used) {
- print_err_duplicate("pid");
- command_ret = CMD_ERROR;
- goto end;
- }
- opt_pid.used = 1;
- type_state = STATE_PID;
- break;
case OPT_VPID:
- if (opt_vpid.used) {
- print_err_duplicate("vpid");
- command_ret = CMD_ERROR;
- goto end;
- }
- opt_vpid.used = 1;
- type_state = STATE_VPID;
- break;
case OPT_UID:
- if (opt_uid.used) {
- print_err_duplicate("uid");
- command_ret = CMD_ERROR;
- goto end;
- }
- opt_uid.used = 1;
- type_state = STATE_UID;
- break;
case OPT_VUID:
- if (opt_vuid.used) {
- print_err_duplicate("vuid");
- command_ret = CMD_ERROR;
- goto end;
- }
- opt_vuid.used = 1;
- type_state = STATE_VUID;
- break;
case OPT_GID:
- if (opt_gid.used) {
- print_err_duplicate("gid");
- command_ret = CMD_ERROR;
- goto end;
- }
- opt_gid.used = 1;
- type_state = STATE_GID;
- break;
case OPT_VGID:
- if (opt_vgid.used) {
- print_err_duplicate("vgid");
+ /* See OPT_ enum declaration comment. */
+ opt--;
+ selected_process_attr_tracker_count++;
+ process_attr_commands[opt].requested = true;
+ if (!opt_str_arg) {
+ continue;
+ }
+ ret = lttng_dynamic_pointer_array_add_pointer(
+ &process_attr_commands[opt].string_args,
+ opt_str_arg);
+ if (ret) {
+ ERR("Allocation failed while parsing command arguments");
command_ret = CMD_ERROR;
goto end;
}
- opt_vgid.used = 1;
- type_state = STATE_VGID;
break;
case OPT_ALL:
- opt_all_present = true;
+ opt_all = true;
break;
default:
command_ret = CMD_UNDEFINED;
goto end;
}
- /*
- * If the `--all` option is present set the appropriate tracker's `all`
- * field.
- */
- if (opt_all_present) {
- switch (type_state) {
- case STATE_PID:
- opt_pid.all = 1;
- break;
- case STATE_VPID:
- opt_vpid.all = 1;
- break;
- case STATE_UID:
- opt_uid.all = 1;
- break;
- case STATE_VUID:
- opt_vuid.all = 1;
- break;
- case STATE_GID:
- opt_gid.all = 1;
- break;
- case STATE_VGID:
- opt_vgid.all = 1;
- break;
- default:
- command_ret = CMD_ERROR;
- goto end;
+ if (selected_process_attr_tracker_count == 0) {
+ ERR("At least one process attribute must be specified");
+ command_ret = CMD_ERROR;
+ goto end;
+ }
+ if (opt_all) {
+ /*
+ * Only one process attribute tracker was specified; find it
+ * and set it in 'all' mode.
+ */
+ for (i = 0; i < command_count; i++) {
+ if (!process_attr_commands[i].requested) {
+ continue;
+ }
+ process_attr_commands[i].all = true;
+ if (lttng_dynamic_pointer_array_get_count(
+ &process_attr_commands[i]
+ .string_args)) {
+ ERR("The --all option cannot be used with a list of process attribute values");
+ command_ret = CMD_ERROR;
+ goto end;
+ }
+ }
+ } else {
+ for (i = 0; i < command_count; i++) {
+ if (!process_attr_commands[i].requested) {
+ continue;
+ }
+ if (lttng_dynamic_pointer_array_get_count(
+ &process_attr_commands[i]
+ .string_args) == 0) {
+ ERR("No process attribute value specified for %s tracker",
+ get_capitalized_process_attr_str(
+ process_attr_commands[i]
+ .process_attr));
+ command_ret = CMD_ERROR;
+ goto end;
+ }
}
}
}
}
- if (opt_pid.used) {
- command_ret = track_untrack_id(cmd_type, cmd_str, session_name,
- opt_pid.string, opt_pid.all, writer,
- LTTNG_TRACKER_PID);
- if (command_ret != CMD_SUCCESS) {
- success = 0;
- }
- }
- if (opt_vpid.used) {
- command_ret = track_untrack_id(cmd_type, cmd_str, session_name,
- opt_vpid.string, opt_vpid.all, writer,
- LTTNG_TRACKER_VPID);
- if (command_ret != CMD_SUCCESS) {
- success = 0;
- }
- }
- if (opt_uid.used) {
- command_ret = track_untrack_id(cmd_type, cmd_str, session_name,
- opt_uid.string, opt_uid.all, writer,
- LTTNG_TRACKER_UID);
- if (command_ret != CMD_SUCCESS) {
- success = 0;
- }
- }
- if (opt_vuid.used) {
- command_ret = track_untrack_id(cmd_type, cmd_str, session_name,
- opt_vuid.string, opt_vuid.all, writer,
- LTTNG_TRACKER_VUID);
- if (command_ret != CMD_SUCCESS) {
- success = 0;
+ /* Execute sub-commands. */
+ for (i = 0; i < command_count; i++) {
+ if (!process_attr_commands[i].requested) {
+ continue;
}
- }
- if (opt_gid.used) {
- command_ret = track_untrack_id(cmd_type, cmd_str, session_name,
- opt_gid.string, opt_gid.all, writer,
- LTTNG_TRACKER_GID);
- if (command_ret != CMD_SUCCESS) {
- success = 0;
- }
- }
- if (opt_vgid.used) {
- command_ret = track_untrack_id(cmd_type, cmd_str, session_name,
- opt_vgid.string, opt_vgid.all, writer,
- LTTNG_TRACKER_VGID);
+ command_ret = run_command(cmd_type, session_name,
+ &process_attr_commands[i], writer);
if (command_ret != CMD_SUCCESS) {
- success = 0;
+ sub_command_failed = true;
+ if (command_ret == CMD_FATAL) {
+ break;
+ }
}
}
/* Success ? */
ret = mi_lttng_writer_write_element_bool(writer,
- mi_lttng_element_command_success, success);
+ mi_lttng_element_command_success,
+ !sub_command_failed);
if (ret) {
command_ret = CMD_ERROR;
goto end;
command_ret = CMD_ERROR;
}
+ for (i = 0; i < command_count; i++) {
+ process_attr_command_fini(&process_attr_commands[i]);
+ }
+
poptFreeContext(pc);
return (int) command_ret;
}
#endif
;
- return cmd_track_untrack(CMD_TRACK, "track", argc, argv, help_msg);
+ return cmd_track_untrack(CMD_TRACK, argc, argv, help_msg);
}
int cmd_untrack(int argc, const char **argv)
#endif
;
- return cmd_track_untrack(CMD_UNTRACK, "untrack", argc, argv, help_msg);
+ return cmd_track_untrack(CMD_UNTRACK, argc, argv, help_msg);
}
userspace-probe.c \
utils.c utils.h \
uuid.c uuid.h \
- tracker.c \
+ tracker.c tracker.h \
waiter.c waiter.h \
fs-handle.h fs-handle-internal.h fs-handle.c
extern const char * const config_element_data_uri;
extern const char * const config_element_max_size;
extern const char * const config_element_pid;
-extern const char * const config_element_id;
+extern const char * const config_element_process_attr_id;
extern const char * const config_element_pids;
extern const char * const config_element_name;
extern const char * const config_element_shared_memory_path;
-extern const char * const config_element_pid_tracker;
-extern const char * const config_element_vpid_tracker;
-extern const char * const config_element_uid_tracker;
-extern const char * const config_element_vuid_tracker;
-extern const char * const config_element_gid_tracker;
-extern const char * const config_element_vgid_tracker;
-extern const char * const config_element_trackers;
-extern const char * const config_element_targets;
-extern const char * const config_element_target_type;
-extern const char * const config_element_target_pid;
-extern const char * const config_element_target_vpid;
-extern const char * const config_element_target_uid;
-extern const char * const config_element_target_vuid;
-extern const char * const config_element_target_gid;
-extern const char * const config_element_target_vgid;
-extern const char * const config_element_tracker_type;
+extern const char * const config_element_process_attr_tracker_pid;
+extern const char * const config_element_process_attr_tracker_vpid;
+extern const char * const config_element_process_attr_tracker_uid;
+extern const char * const config_element_process_attr_tracker_vuid;
+extern const char * const config_element_process_attr_tracker_gid;
+extern const char * const config_element_process_attr_tracker_vgid;
+extern const char * const config_element_process_attr_trackers;
+extern const char * const config_element_process_attr_values;
+extern const char * const config_element_process_attr_value_type;
+extern const char * const config_element_process_attr_pid_value;
+extern const char * const config_element_process_attr_vpid_value;
+extern const char * const config_element_process_attr_uid_value;
+extern const char * const config_element_process_attr_vuid_value;
+extern const char * const config_element_process_attr_gid_value;
+extern const char * const config_element_process_attr_vgid_value;
+extern const char * const config_element_process_attr_tracker_type;
extern const char * const config_element_rotation_timer_interval;
extern const char * const config_element_rotation_size;
extern const char * const config_element_rotation_schedule;
*
*/
+#include "lttng/tracker.h"
#define _LGPL_SOURCE
#include <assert.h>
#include <ctype.h>
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";
-LTTNG_HIDDEN const char * const config_element_id = "id";
const char * const config_element_pids = "pids";
const char * const config_element_shared_memory_path = "shared_memory_path";
-const char * const config_element_pid_tracker = "pid_tracker";
-LTTNG_HIDDEN const char * const config_element_vpid_tracker = "vpid_tracker";
-LTTNG_HIDDEN const char * const config_element_uid_tracker = "uid_tracker";
-LTTNG_HIDDEN const char * const config_element_vuid_tracker = "vuid_tracker";
-LTTNG_HIDDEN const char * const config_element_gid_tracker = "gid_tracker";
-LTTNG_HIDDEN const char * const config_element_vgid_tracker = "vgid_tracker";
-const char * const config_element_trackers = "trackers";
-const char * const config_element_targets = "targets";
-LTTNG_HIDDEN const char * const config_element_target_type = "target_type";
-const char * const config_element_target_pid = "pid_target";
-LTTNG_HIDDEN const char * const config_element_target_vpid = "vpid_target";
-LTTNG_HIDDEN const char * const config_element_target_uid = "uid_target";
-LTTNG_HIDDEN const char * const config_element_target_vuid = "vuid_target";
-LTTNG_HIDDEN const char * const config_element_target_gid = "gid_target";
-LTTNG_HIDDEN const char * const config_element_target_vgid = "vgid_target";
-LTTNG_HIDDEN const char * const config_element_tracker_type = "tracker_type";
+
+LTTNG_HIDDEN const char * const config_element_process_attr_id = "id";
+LTTNG_HIDDEN const char * const config_element_process_attr_tracker_pid = "pid_process_attr_tracker";
+LTTNG_HIDDEN const char * const config_element_process_attr_tracker_vpid = "vpid_process_attr_tracker";
+LTTNG_HIDDEN const char * const config_element_process_attr_tracker_uid = "uid_process_attr_tracker";
+LTTNG_HIDDEN const char * const config_element_process_attr_tracker_vuid = "vuid_process_attr_tracker";
+LTTNG_HIDDEN const char * const config_element_process_attr_tracker_gid = "gid_process_attr_tracker";
+LTTNG_HIDDEN const char * const config_element_process_attr_tracker_vgid = "vgid_process_attr_tracker";
+LTTNG_HIDDEN const char * const config_element_process_attr_trackers = "process_attr_trackers";
+LTTNG_HIDDEN const char * const config_element_process_attr_values = "process_attr_values";
+LTTNG_HIDDEN const char * const config_element_process_attr_value_type = "process_attr_value_type";
+LTTNG_HIDDEN const char * const config_element_process_attr_pid_value = "pid";
+LTTNG_HIDDEN const char * const config_element_process_attr_vpid_value = "vpid";
+LTTNG_HIDDEN const char * const config_element_process_attr_uid_value = "uid";
+LTTNG_HIDDEN const char * const config_element_process_attr_vuid_value = "vuid";
+LTTNG_HIDDEN const char * const config_element_process_attr_gid_value = "gid";
+LTTNG_HIDDEN const char * const config_element_process_attr_vgid_value = "vgid";
+LTTNG_HIDDEN const char * const config_element_process_attr_tracker_type = "process_attr_tracker_type";
LTTNG_HIDDEN const char * const config_element_rotation_schedules = "rotation_schedules";
LTTNG_HIDDEN const char * const config_element_rotation_schedule_periodic = "periodic";
return ret;
}
-static int get_tracker_elements(enum lttng_tracker_type tracker_type,
+static int get_tracker_elements(enum lttng_process_attr process_attr,
const char **element_id_tracker,
- const char **element_target_id,
- const char **element_id,
- const char **element_id_alias,
+ const char **element_value_type,
+ const char **element_value,
+ const char **element_value_alias,
const char **element_name)
{
int ret = 0;
- 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_id;
- *element_id_alias = config_element_pid;
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_PROCESS_ID:
+ *element_id_tracker = config_element_process_attr_tracker_pid;
+ *element_value_type = config_element_process_attr_pid_value;
+ *element_value = config_element_process_attr_id;
+ *element_value_alias = config_element_process_attr_id;
*element_name = NULL;
break;
- case LTTNG_TRACKER_VPID:
- *element_id_tracker = config_element_vpid_tracker;
- *element_target_id = config_element_target_vpid;
- *element_id = config_element_id;
- *element_id_alias = NULL;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ *element_id_tracker = config_element_process_attr_tracker_vpid;
+ *element_value_type = config_element_process_attr_vpid_value;
+ *element_value = config_element_process_attr_id;
+ *element_value_alias = NULL;
*element_name = NULL;
break;
- case LTTNG_TRACKER_UID:
- *element_id_tracker = config_element_uid_tracker;
- *element_target_id = config_element_target_uid;
- *element_id = config_element_id;
- *element_id_alias = NULL;
+ case LTTNG_PROCESS_ATTR_USER_ID:
+ *element_id_tracker = config_element_process_attr_tracker_uid;
+ *element_value_type = config_element_process_attr_uid_value;
+ *element_value = config_element_process_attr_id;
+ *element_value_alias = NULL;
*element_name = config_element_name;
break;
- case LTTNG_TRACKER_VUID:
- *element_id_tracker = config_element_vuid_tracker;
- *element_target_id = config_element_target_vuid;
- *element_id = config_element_id;
- *element_id_alias = NULL;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ *element_id_tracker = config_element_process_attr_tracker_vuid;
+ *element_value_type = config_element_process_attr_vuid_value;
+ *element_value = config_element_process_attr_id;
+ *element_value_alias = NULL;
*element_name = config_element_name;
break;
- case LTTNG_TRACKER_GID:
- *element_id_tracker = config_element_gid_tracker;
- *element_target_id = config_element_target_gid;
- *element_id = config_element_id;
- *element_id_alias = NULL;
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
+ *element_id_tracker = config_element_process_attr_tracker_gid;
+ *element_value_type = config_element_process_attr_gid_value;
+ *element_value = config_element_process_attr_id;
+ *element_value_alias = NULL;
*element_name = config_element_name;
break;
- case LTTNG_TRACKER_VGID:
- *element_id_tracker = config_element_vgid_tracker;
- *element_target_id = config_element_target_vgid;
- *element_id = config_element_id;
- *element_id_alias = NULL;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ *element_id_tracker = config_element_process_attr_tracker_vgid;
+ *element_value_type = config_element_process_attr_vgid_value;
+ *element_value = config_element_process_attr_id;
+ *element_value_alias = NULL;
*element_name = config_element_name;
break;
default:
static int process_id_tracker_node(xmlNodePtr id_tracker_node,
struct lttng_handle *handle,
- enum lttng_tracker_type tracker_type)
+ enum lttng_process_attr process_attr)
{
- int ret = 0, child;
+ int ret = 0, child_count;
xmlNodePtr targets_node = NULL;
xmlNodePtr node;
const char *element_id_tracker;
const char *element_id;
const char *element_id_alias;
const char *element_name;
- enum lttng_tracker_id_status status;
+ enum lttng_error_code tracker_handle_ret_code;
+ struct lttng_process_attr_tracker_handle *tracker_handle = NULL;
+ enum lttng_process_attr_tracker_handle_status status;
assert(handle);
assert(id_tracker_node);
- ret = get_tracker_elements(tracker_type, &element_id_tracker,
+ tracker_handle_ret_code = lttng_session_get_tracker_handle(
+ handle->session_name, handle->domain.type, process_attr,
+ &tracker_handle);
+ if (tracker_handle_ret_code != LTTNG_OK) {
+ ret = LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ ret = get_tracker_elements(process_attr, &element_id_tracker,
&element_target_id, &element_id, &element_id_alias,
&element_name);
if (ret) {
- return ret;
+ goto end;
}
/* get the targets node */
for (node = xmlFirstElementChild(id_tracker_node); node;
node = xmlNextElementSibling(node)) {
if (!strcmp((const char *) node->name,
- config_element_targets)) {
+ config_element_process_attr_values)) {
targets_node = node;
break;
}
}
/* Go through all id target node */
- child = xmlChildElementCount(targets_node);
- if (child == 0) {
- struct lttng_tracker_id *tracker_id = NULL;
- tracker_id = lttng_tracker_id_create();
- if (tracker_id == NULL) {
- ret = LTTNG_ERR_NOMEM;
- goto end;
- }
- status = lttng_tracker_id_set_all(tracker_id);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ret = LTTNG_ERR_INVALID;
- goto end;
- }
-
- /* The session is explicitly set to target nothing. */
- ret = lttng_untrack_id(handle, tracker_type, tracker_id);
- lttng_tracker_id_destroy(tracker_id);
- if (ret) {
- goto end;
- }
+ child_count = xmlChildElementCount(targets_node);
+ status = lttng_process_attr_tracker_handle_set_tracking_policy(
+ tracker_handle,
+ child_count == 0 ? LTTNG_TRACKING_POLICY_EXCLUDE_ALL :
+ LTTNG_TRACKING_POLICY_INCLUDE_SET);
+ if (status != LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK) {
+ ret = LTTNG_ERR_UNK;
+ goto end;
}
+
+ /* Add all tracked values. */
for (node = xmlFirstElementChild(targets_node); node;
node = xmlNextElementSibling(node)) {
xmlNodePtr id_target_node = node;
!strcmp((const char *) node->name,
element_id_alias))) {
int64_t id;
- xmlChar *content = NULL;
- struct lttng_tracker_id *tracker_id = NULL;
+ xmlChar *content = xmlNodeGetContent(node);
- content = xmlNodeGetContent(node);
if (!content) {
ret = LTTNG_ERR_LOAD_INVALID_CONFIG;
goto end;
goto end;
}
- tracker_id = lttng_tracker_id_create();
- if (tracker_id == NULL) {
- ret = LTTNG_ERR_NOMEM;
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_PROCESS_ID:
+ status = lttng_process_attr_process_id_tracker_handle_add_pid(
+ tracker_handle,
+ (pid_t) id);
+ break;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ status = lttng_process_attr_virtual_process_id_tracker_handle_add_pid(
+ tracker_handle,
+ (pid_t) id);
+ break;
+ case LTTNG_PROCESS_ATTR_USER_ID:
+ status = lttng_process_attr_user_id_tracker_handle_add_uid(
+ tracker_handle,
+ (uid_t) id);
+ break;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ status = lttng_process_attr_virtual_user_id_tracker_handle_add_uid(
+ tracker_handle,
+ (uid_t) id);
+ break;
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
+ status = lttng_process_attr_group_id_tracker_handle_add_gid(
+ tracker_handle,
+ (gid_t) id);
+ break;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ status = lttng_process_attr_virtual_group_id_tracker_handle_add_gid(
+ tracker_handle,
+ (gid_t) id);
+ break;
+ default:
+ ret = LTTNG_ERR_INVALID;
goto end;
}
+ } else if (element_name &&
+ !strcmp((const char *) node->name,
+ element_name)) {
+ xmlChar *content = xmlNodeGetContent(node);
- status = lttng_tracker_id_set_value(
- tracker_id, id);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- lttng_tracker_id_destroy(tracker_id);
- ret = LTTNG_ERR_LOAD_INVALID_CONFIG;
- goto end;
- }
-
- ret = lttng_track_id(handle, tracker_type,
- tracker_id);
- lttng_tracker_id_destroy(tracker_id);
- if (ret) {
- goto end;
- }
- }
- if (element_name && !strcmp((const char *) node->name,
- element_name)) {
- xmlChar *content = NULL;
- struct lttng_tracker_id *tracker_id = NULL;
-
- content = xmlNodeGetContent(node);
if (!content) {
ret = LTTNG_ERR_LOAD_INVALID_CONFIG;
goto end;
}
- tracker_id = lttng_tracker_id_create();
- if (tracker_id == NULL) {
- ret = LTTNG_ERR_NOMEM;
- goto end;
- }
-
- status = lttng_tracker_id_set_string(tracker_id,
- (const char *) content);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- lttng_tracker_id_destroy(tracker_id);
- ret = LTTNG_ERR_LOAD_INVALID_CONFIG;
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_USER_ID:
+ status = lttng_process_attr_user_id_tracker_handle_add_user_name(
+ tracker_handle,
+ (const char *) content);
+ break;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ status = lttng_process_attr_virtual_user_id_tracker_handle_add_user_name(
+ tracker_handle,
+ (const char *) content);
+ break;
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
+ status = lttng_process_attr_group_id_tracker_handle_add_group_name(
+ tracker_handle,
+ (const char *) content);
+ break;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ status = lttng_process_attr_virtual_group_id_tracker_handle_add_group_name(
+ tracker_handle,
+ (const char *) content);
+ break;
+ default:
+ free(content);
+ ret = LTTNG_ERR_INVALID;
goto end;
}
-
- ret = lttng_track_id(handle, tracker_type,
- tracker_id);
- lttng_tracker_id_destroy(tracker_id);
free(content);
- if (ret) {
- goto end;
- }
+ }
+ switch (status) {
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK:
+ continue;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID:
+ ret = LTTNG_ERR_INVALID;
+ break;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_EXISTS:
+ ret = LTTNG_ERR_PROCESS_ATTR_EXISTS;
+ break;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_MISSING:
+ ret = LTTNG_ERR_PROCESS_ATTR_MISSING;
+ break;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR:
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR:
+ default:
+ ret = LTTNG_ERR_UNK;
+ goto end;
}
}
node = id_target_node;
}
end:
+ lttng_process_attr_tracker_handle_destroy(tracker_handle);
return ret;
}
for (node = xmlFirstElementChild(domain_node); node;
node = xmlNextElementSibling(node)) {
if (!strcmp((const char *) node->name,
- config_element_trackers)) {
+ config_element_process_attr_trackers)) {
trackers_node = node;
break;
}
for (node = xmlFirstElementChild(trackers_node); node;
node = xmlNextElementSibling(node)) {
if (!strcmp((const char *) node->name,
- config_element_pid_tracker)) {
+ config_element_process_attr_tracker_pid)) {
pid_tracker_node = node;
ret = process_id_tracker_node(pid_tracker_node, handle,
- LTTNG_TRACKER_PID);
+ LTTNG_PROCESS_ATTR_PROCESS_ID);
if (ret) {
goto end;
}
}
if (!strcmp((const char *) node->name,
- config_element_vpid_tracker)) {
+ config_element_process_attr_tracker_vpid)) {
vpid_tracker_node = node;
ret = process_id_tracker_node(vpid_tracker_node, handle,
- LTTNG_TRACKER_VPID);
+ LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID);
if (ret) {
goto end;
}
}
if (!strcmp((const char *) node->name,
- config_element_uid_tracker)) {
+ config_element_process_attr_tracker_uid)) {
uid_tracker_node = node;
ret = process_id_tracker_node(uid_tracker_node, handle,
- LTTNG_TRACKER_UID);
+ LTTNG_PROCESS_ATTR_USER_ID);
if (ret) {
goto end;
}
}
if (!strcmp((const char *) node->name,
- config_element_vuid_tracker)) {
+ config_element_process_attr_tracker_vuid)) {
vuid_tracker_node = node;
ret = process_id_tracker_node(vuid_tracker_node, handle,
- LTTNG_TRACKER_VUID);
+ LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID);
if (ret) {
goto end;
}
}
if (!strcmp((const char *) node->name,
- config_element_gid_tracker)) {
+ config_element_process_attr_tracker_gid)) {
gid_tracker_node = node;
ret = process_id_tracker_node(gid_tracker_node, handle,
- LTTNG_TRACKER_GID);
+ LTTNG_PROCESS_ATTR_GROUP_ID);
if (ret) {
goto end;
}
}
if (!strcmp((const char *) node->name,
- config_element_vgid_tracker)) {
+ config_element_process_attr_tracker_vgid)) {
vgid_tracker_node = node;
ret = process_id_tracker_node(vgid_tracker_node, handle,
- LTTNG_TRACKER_VGID);
+ LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID);
if (ret) {
goto end;
}
</xs:sequence>
</xs:complexType>
-<xs:complexType name="pid_target_type">
+<xs:complexType name="pid_value_type">
<xs:choice minOccurs="0">
- <xs:element name="pid" type="xs:integer" />
<xs:element name="id" type="xs:integer" />
</xs:choice>
</xs:complexType>
-<!-- Maps to a list of pid_targets-->
-<xs:complexType name="pid_targets_type">
+<!-- Maps to a list of pid_process_attr_values-->
+<xs:complexType name="pid_process_attr_values_type">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded" >
- <xs:element name="pid_target" type="pid_target_type" />
+ <xs:element name="pid" type="pid_value_type" />
</xs:choice>
</xs:sequence>
</xs:complexType>
-<!-- Maps to a pid_tracker-->
-<xs:complexType name="pid_tracker_type">
+<!-- Maps to a pid_process_attr_tracker-->
+<xs:complexType name="pid_process_attr_tracker_type">
<xs:all>
- <xs:element name="targets" type="pid_targets_type" />
+ <xs:element name="process_attr_values" type="pid_process_attr_values_type" />
</xs:all>
</xs:complexType>
-<xs:complexType name="vpid_target_type">
+<xs:complexType name="vpid_value_type">
<xs:all>
<xs:element name="id" type="xs:integer" />
</xs:all>
</xs:complexType>
-<!-- Maps to a list of vpid_targets-->
-<xs:complexType name="vpid_targets_type">
+<!-- Maps to a list of vpid_process_attr_values-->
+<xs:complexType name="vpid_process_attr_values_type">
<xs:sequence>
- <xs:element name="vpid_target" type="vpid_target_type" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="vpid" type="vpid_value_type" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
-<!-- Maps to a pid_tracker-->
-<xs:complexType name="vpid_tracker_type">
+<!-- Maps to a pid_process_attr_tracker-->
+<xs:complexType name="vpid_process_attr_tracker_type">
<xs:all>
- <xs:element name="targets" type="vpid_targets_type" />
+ <xs:element name="process_attr_values" type="vpid_process_attr_values_type" />
</xs:all>
</xs:complexType>
-<xs:complexType name="uid_target_type">
+<xs:complexType name="uid_value_type">
<xs:choice>
<xs:element name="id" type="xs:integer" />
<xs:element name="name" type="xs:string" />
</xs:choice>
</xs:complexType>
-<!-- Maps to a list of uid_targets-->
-<xs:complexType name="uid_targets_type">
+<!-- Maps to a list of uid_process_attr_values-->
+<xs:complexType name="uid_process_attr_values_type">
<xs:sequence>
- <xs:element name="uid_target" type="uid_target_type" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="uid" type="uid_value_type" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
-<!-- Maps to a uid_tracker-->
-<xs:complexType name="uid_tracker_type">
+<!-- Maps to a uid_process_attr_tracker-->
+<xs:complexType name="uid_process_attr_tracker_type">
<xs:all>
- <xs:element name="targets" type="uid_targets_type" />
+ <xs:element name="process_attr_values" type="uid_process_attr_values_type" />
</xs:all>
</xs:complexType>
-<xs:complexType name="vuid_target_type">
+<xs:complexType name="vuid_value_type">
<xs:choice>
<xs:element name="id" type="xs:integer" />
<xs:element name="name" type="xs:string" />
</xs:choice>
</xs:complexType>
-<!-- Maps to a list of vuid_targets-->
-<xs:complexType name="vuid_targets_type">
+<!-- Maps to a list of vuid_process_attr_values-->
+<xs:complexType name="vuid_process_attr_values_type">
<xs:sequence>
- <xs:element name="vuid_target" type="vuid_target_type" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="vuid" type="vuid_value_type" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
-<!-- Maps to a uid_tracker-->
-<xs:complexType name="vuid_tracker_type">
+<!-- Maps to a vuid_process_attr_tracker-->
+<xs:complexType name="vuid_process_attr_tracker_type">
<xs:all>
- <xs:element name="targets" type="vuid_targets_type" />
+ <xs:element name="process_attr_values" type="vuid_process_attr_values_type" />
</xs:all>
</xs:complexType>
-<xs:complexType name="gid_target_type">
+<xs:complexType name="gid_value_type">
<xs:choice>
<xs:element name="id" type="xs:integer" />
<xs:element name="name" type="xs:string" />
</xs:choice>
</xs:complexType>
-<!-- Maps to a list of gid_targets-->
-<xs:complexType name="gid_targets_type">
+<!-- Maps to a list of gid_process_attr_values-->
+<xs:complexType name="gid_process_attr_values_type">
<xs:sequence>
- <xs:element name="gid_target" type="gid_target_type" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="gid" type="gid_value_type" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
-<!-- Maps to a gid_tracker-->
-<xs:complexType name="gid_tracker_type">
+<!-- Maps to a gid_process_attr_tracker-->
+<xs:complexType name="gid_process_attr_tracker_type">
<xs:all>
- <xs:element name="targets" type="gid_targets_type" />
+ <xs:element name="process_attr_values" type="gid_process_attr_values_type" />
</xs:all>
</xs:complexType>
-<xs:complexType name="vgid_target_type">
+<xs:complexType name="vgid_value_type">
<xs:choice>
<xs:element name="id" type="xs:integer" />
<xs:element name="name" type="xs:string" />
</xs:choice>
</xs:complexType>
-<!-- Maps to a list of vgid_targets-->
-<xs:complexType name="vgid_targets_type">
+<!-- Maps to a list of vgid_process_attr_values-->
+<xs:complexType name="vgid_process_attr_values_type">
<xs:sequence>
- <xs:element name="vgid_target" type="vgid_target_type" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="vgid" type="vgid_value_type" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
-<!-- Maps to a gid_tracker-->
-<xs:complexType name="vgid_tracker_type">
+<!-- Maps to a vgid_process_attr_tracker-->
+<xs:complexType name="vgid_process_attr_tracker_type">
<xs:all>
- <xs:element name="targets" type="vgid_targets_type" />
+ <xs:element name="process_attr_values" type="vgid_process_attr_values_type" />
</xs:all>
</xs:complexType>
<!-- Maps to a list of trackers-->
-<xs:complexType name="trackers_type">
+<xs:complexType name="process_attr_tracker_type">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded" >
- <xs:element name="pid_tracker" type="pid_tracker_type" maxOccurs="1" />
- <xs:element name="vpid_tracker" type="vpid_tracker_type" maxOccurs="1" />
- <xs:element name="uid_tracker" type="uid_tracker_type" maxOccurs="1" />
- <xs:element name="vuid_tracker" type="vuid_tracker_type" maxOccurs="1" />
- <xs:element name="gid_tracker" type="gid_tracker_type" maxOccurs="1" />
- <xs:element name="vgid_tracker" type="vgid_tracker_type" maxOccurs="1" />
+ <xs:element name="pid_process_attr_tracker" type="pid_process_attr_tracker_type" maxOccurs="1" />
+ <xs:element name="vpid_process_attr_tracker" type="vpid_process_attr_tracker_type" maxOccurs="1" />
+ <xs:element name="uid_process_attr_tracker" type="uid_process_attr_tracker_type" maxOccurs="1" />
+ <xs:element name="vuid_process_attr_tracker" type="vuid_process_attr_tracker_type" maxOccurs="1" />
+ <xs:element name="gid_process_attr_tracker" type="gid_process_attr_tracker_type" maxOccurs="1" />
+ <xs:element name="vgid_process_attr_tracker" type="vgid_process_attr_tracker_type" maxOccurs="1" />
</xs:choice>
</xs:sequence>
</xs:complexType>
-<!-- Maps to struct lttng_domain, contains channels and pid_tracker -->
+<!-- Maps to struct lttng_domain, contains channels and pid_process_attr_tracker -->
<xs:complexType name="domain_type">
<xs:all>
<xs:element name="type" type="domain_type_type"/>
<xs:element name="buffer_type" type="domain_buffer_type"/>
<xs:element name="channels" type="channel_list_type" minOccurs="0"/>
- <xs:element name="trackers" type="trackers_type" minOccurs="0"/>
+ <xs:element name="process_attr_trackers" type="process_attr_tracker_type" minOccurs="0"/>
</xs:all>
</xs:complexType>
[ ERROR_INDEX(LTTNG_ERR_MI_NOT_IMPLEMENTED) ] = "Mi feature not implemented",
[ ERROR_INDEX(LTTNG_ERR_INVALID_EVENT_NAME) ] = "Invalid event name",
[ ERROR_INDEX(LTTNG_ERR_INVALID_CHANNEL_NAME) ] = "Invalid channel name",
- [ ERROR_INDEX(LTTNG_ERR_ID_TRACKED) ] = "ID already tracked",
- [ ERROR_INDEX(LTTNG_ERR_ID_NOT_TRACKED) ] = "ID not tracked",
+ [ ERROR_INDEX(LTTNG_ERR_PROCESS_ATTR_EXISTS) ] = "Process attribute is already tracked",
+ [ ERROR_INDEX(LTTNG_ERR_PROCESS_ATTR_MISSING) ] = "Process attribute was not tracked",
[ ERROR_INDEX(LTTNG_ERR_INVALID_CHANNEL_DOMAIN) ] = "Invalid channel domain",
[ ERROR_INDEX(LTTNG_ERR_OVERFLOW) ] = "Overflow occurred",
[ ERROR_INDEX(LTTNG_ERR_SESSION_NOT_STARTED) ] = "Session not started",
[ ERROR_INDEX(LTTNG_ERR_ROTATION_AFTER_STOP_CLEAR) ] = "Session was already cleared since it became inactive",
[ ERROR_INDEX(LTTNG_ERR_USER_NOT_FOUND) ] = "User not found",
[ ERROR_INDEX(LTTNG_ERR_GROUP_NOT_FOUND) ] = "Group not found",
+ [ ERROR_INDEX(LTTNG_ERR_UNSUPPORTED_DOMAIN) ] = "Unsupported domain used",
+ [ ERROR_INDEX(LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY) ] = "Operation does not apply to the process attribute tracker's tracking policy",
/* Last element */
[ ERROR_INDEX(LTTNG_ERR_NR) ] = "Unknown error code"
*
*/
+#include "lttng/tracker.h"
#define _LGPL_SOURCE
#define __USE_LINUX_IOCTL_DEFS
#include <sys/ioctl.h>
}
static enum lttng_kernel_tracker_type get_kernel_tracker_type(
- enum lttng_tracker_type type)
+ enum lttng_process_attr process_attr)
{
- switch (type) {
- case LTTNG_TRACKER_PID:
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_PROCESS_ID:
return LTTNG_KERNEL_TRACKER_PID;
- case LTTNG_TRACKER_VPID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
return LTTNG_KERNEL_TRACKER_VPID;
- case LTTNG_TRACKER_UID:
+ case LTTNG_PROCESS_ATTR_USER_ID:
return LTTNG_KERNEL_TRACKER_UID;
- case LTTNG_TRACKER_VUID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
return LTTNG_KERNEL_TRACKER_VUID;
- case LTTNG_TRACKER_GID:
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
return LTTNG_KERNEL_TRACKER_GID;
- case LTTNG_TRACKER_VGID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
return LTTNG_KERNEL_TRACKER_VGID;
default:
return LTTNG_KERNEL_TRACKER_UNKNOWN;
}
}
-int kernctl_track_id(int fd, enum lttng_tracker_type tracker_type, int id)
+int kernctl_track_id(int fd, enum lttng_process_attr process_attr, int id)
{
struct lttng_kernel_tracker_args args;
args.id = id;
- args.type = get_kernel_tracker_type(tracker_type);
+ args.type = get_kernel_tracker_type(process_attr);
if (args.type == LTTNG_KERNEL_TRACKER_UNKNOWN) {
errno = EINVAL;
return -1;
return LTTNG_IOCTL_CHECK(fd, LTTNG_KERNEL_SESSION_TRACK_ID, &args);
}
-int kernctl_untrack_id(int fd, enum lttng_tracker_type tracker_type, int id)
+int kernctl_untrack_id(int fd, enum lttng_process_attr process_attr, int id)
{
struct lttng_kernel_tracker_args args;
args.id = id;
- args.type = get_kernel_tracker_type(tracker_type);
+ args.type = get_kernel_tracker_type(process_attr);
if (args.type == LTTNG_KERNEL_TRACKER_UNKNOWN) {
errno = EINVAL;
return -1;
return LTTNG_IOCTL_CHECK(fd, LTTNG_KERNEL_SESSION_UNTRACK_ID, &args);
}
-int kernctl_list_tracker_ids(int fd, enum lttng_tracker_type tracker_type)
+int kernctl_list_tracker_ids(int fd, enum lttng_process_attr process_attr)
{
struct lttng_kernel_tracker_args args;
args.id = -1;
- args.type = get_kernel_tracker_type(tracker_type);
+ args.type = get_kernel_tracker_type(process_attr);
if (args.type == LTTNG_KERNEL_TRACKER_UNKNOWN) {
errno = EINVAL;
return -1;
int kernctl_untrack_pid(int fd, int pid);
int kernctl_list_tracker_pids(int fd);
-int kernctl_track_id(int fd, enum lttng_tracker_type tracker_type, int id);
-int kernctl_untrack_id(int fd, enum lttng_tracker_type tracker_type, int id);
-int kernctl_list_tracker_ids(int fd, enum lttng_tracker_type tracker_type);
+int kernctl_track_id(int fd, enum lttng_process_attr process_attr, int id);
+int kernctl_untrack_id(int fd, enum lttng_process_attr process_attr, int id);
+int kernctl_list_tracker_ids(int fd, enum lttng_process_attr process_attr);
int kernctl_session_regenerate_metadata(int fd);
int kernctl_session_regenerate_statedump(int fd);
#define LTTNG_PACKED __attribute__((__packed__))
#endif
+#define is_signed(type) (((type) (-1)) < 0)
+
/*
* Align value to the next multiple of align. Returns val if it already is a
* multiple of align. Align must be a power of two.
</xs:sequence>
</xs:complexType>
- <xs:simpleType name="tracker_target_type">
- <xs:restriction base="xs:string">
- <xs:enumeration value="ALL" />
- <xs:enumeration value="NONE" />
- <xs:enumeration value="LIST" />
- </xs:restriction>
- </xs:simpleType>
-
<xs:simpleType name="pidbyint">
<xs:restriction base="xs:integer">
<xs:minInclusive value="0"/>
</xs:restriction>
</xs:simpleType>
- <xs:complexType name="pid_target_type_choice">
+ <xs:complexType name="pid_value_type_choice">
<xs:choice>
<xs:element name="id" type="tns:pidbyint" />
- <xs:element name="name" type="xs:string" />
<xs:element name="all" type="xs:boolean" />
</xs:choice>
</xs:complexType>
- <xs:complexType name="pid_target_type">
+ <xs:complexType name="pid_value_type">
<xs:all>
- <xs:element name="type" type="tns:pid_target_type_choice" />
+ <xs:element name="type" type="tns:pid_value_type_choice" />
<xs:element name="success" type="xs:boolean" default="false" minOccurs="0" />
</xs:all>
</xs:complexType>
- <!-- Maps to a list of pid_targets-->
- <xs:complexType name="pid_targets_type">
+ <!-- Maps to a list of pid_process_attr_values-->
+ <xs:complexType name="pid_process_attr_values_type">
<xs:sequence>
- <xs:element name="pid_target" type="tns:pid_target_type" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="pid" type="tns:pid_value_type" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- Maps to a pid_tracker-->
- <xs:complexType name="pid_tracker_type">
+ <xs:complexType name="pid_process_attr_tracker_type">
<xs:all>
- <xs:element name="target_type" type="tns:tracker_target_type" minOccurs="0" maxOccurs="1" />
- <xs:element name="targets" type="tns:pid_targets_type" minOccurs="0" />
+ <xs:element name="process_attr_values" type="tns:pid_process_attr_values_type" minOccurs="0" />
</xs:all>
</xs:complexType>
</xs:restriction>
</xs:simpleType>
- <xs:complexType name="vpid_target_type_choice">
+ <xs:complexType name="vpid_value_type_choice">
<xs:choice>
<xs:element name="id" type="tns:vpidbyint" />
- <xs:element name="name" type="xs:string" />
<xs:element name="all" type="xs:boolean" />
</xs:choice>
</xs:complexType>
- <xs:complexType name="vpid_target_type">
+ <xs:complexType name="vpid_value_type">
<xs:all>
- <xs:element name="type" type="tns:vpid_target_type_choice" minOccurs="0" maxOccurs="1" />
+ <xs:element name="type" type="tns:vpid_value_type_choice" minOccurs="0" maxOccurs="1" />
<xs:element name="success" type="xs:boolean" default="false" minOccurs="0" />
</xs:all>
</xs:complexType>
- <!-- Maps to a list of vpid_targets-->
- <xs:complexType name="vpid_targets_type">
+ <!-- Maps to a list of vpid_process_attr_values-->
+ <xs:complexType name="vpid_process_attr_values_type">
<xs:sequence>
- <xs:element name="vpid_target" type="tns:vpid_target_type" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="vpid" type="tns:vpid_value_type" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- Maps to a vpid_tracker-->
- <xs:complexType name="vpid_tracker_type">
+ <xs:complexType name="vpid_process_attr_tracker_type">
<xs:all>
- <xs:element name="target_type" type="tns:tracker_target_type" minOccurs="0" maxOccurs="1" />
- <xs:element name="targets" type="tns:vpid_targets_type" minOccurs="0" />
+ <xs:element name="process_attr_values" type="tns:vpid_process_attr_values_type" minOccurs="0" />
</xs:all>
</xs:complexType>
</xs:restriction>
</xs:simpleType>
- <xs:complexType name="uid_target_type_choice">
+ <xs:complexType name="uid_value_type_choice">
<xs:choice>
<xs:element name="id" type="tns:uidbyint" />
<xs:element name="name" type="xs:string" />
</xs:choice>
</xs:complexType>
- <xs:complexType name="uid_target_type">
+ <xs:complexType name="uid_value_type">
<xs:all>
- <xs:element name="type" type="tns:uid_target_type_choice" minOccurs="0" maxOccurs="1" />
+ <xs:element name="type" type="tns:uid_value_type_choice" minOccurs="0" maxOccurs="1" />
<xs:element name="success" type="xs:boolean" default="false" minOccurs="0" />
</xs:all>
</xs:complexType>
- <!-- Maps to a list of uid_targets-->
- <xs:complexType name="uid_targets_type">
+ <!-- Maps to a list of uid_process_attr_values-->
+ <xs:complexType name="uid_process_attr_values_type">
<xs:sequence>
- <xs:element name="uid_target" type="tns:uid_target_type" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="uid" type="tns:uid_value_type" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
- <!-- Maps to a uid_tracker-->
- <xs:complexType name="uid_tracker_type">
+ <!-- Maps to a uid_process_attr_tracker-->
+ <xs:complexType name="uid_process_attr_tracker_type">
<xs:all>
- <xs:element name="target_type" type="tns:tracker_target_type" minOccurs="0" maxOccurs="1" />
- <xs:element name="targets" type="tns:uid_targets_type" minOccurs="0" />
+ <xs:element name="process_attr_values" type="tns:uid_process_attr_values_type" minOccurs="0" />
</xs:all>
</xs:complexType>
</xs:restriction>
</xs:simpleType>
- <xs:complexType name="vuid_target_type_choice">
+ <xs:complexType name="vuid_value_type_choice">
<xs:choice>
<xs:element name="id" type="tns:vuidbyint" />
<xs:element name="name" type="xs:string" />
</xs:choice>
</xs:complexType>
- <xs:complexType name="vuid_target_type">
+ <xs:complexType name="vuid_value_type">
<xs:all>
- <xs:element name="type" type="tns:vuid_target_type_choice" minOccurs="0" maxOccurs="1" />
+ <xs:element name="type" type="tns:vuid_value_type_choice" minOccurs="0" maxOccurs="1" />
<xs:element name="success" type="xs:boolean" default="false" minOccurs="0" />
</xs:all>
</xs:complexType>
- <!-- Maps to a list of vuid_targets-->
- <xs:complexType name="vuid_targets_type">
+ <!-- Maps to a list of vuid_process_attr_values-->
+ <xs:complexType name="vuid_process_attr_values_type">
<xs:sequence>
- <xs:element name="vuid_target" type="tns:vuid_target_type" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="vuid" type="tns:vuid_value_type" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
- <!-- Maps to a vuid_tracker-->
- <xs:complexType name="vuid_tracker_type">
+ <!-- Maps to a vuid_process_attr_tracker-->
+ <xs:complexType name="vuid_process_attr_tracker_type">
<xs:all>
- <xs:element name="target_type" type="tns:tracker_target_type" minOccurs="0" maxOccurs="1" />
- <xs:element name="targets" type="tns:vuid_targets_type" minOccurs="0" />
+ <xs:element name="process_attr_values" type="tns:vuid_process_attr_values_type" minOccurs="0" />
</xs:all>
</xs:complexType>
</xs:restriction>
</xs:simpleType>
- <xs:complexType name="gid_target_type_choice">
+ <xs:complexType name="gid_value_type_choice">
<xs:choice>
<xs:element name="id" type="tns:gidbyint" />
<xs:element name="name" type="xs:string" />
</xs:choice>
</xs:complexType>
- <xs:complexType name="gid_target_type">
+ <xs:complexType name="gid_value_type">
<xs:all>
- <xs:element name="type" type="tns:gid_target_type_choice" minOccurs="0" maxOccurs="1" />
+ <xs:element name="type" type="tns:gid_value_type_choice" minOccurs="0" maxOccurs="1" />
<xs:element name="success" type="xs:boolean" default="false" minOccurs="0" />
</xs:all>
</xs:complexType>
- <!-- Maps to a list of gid_targets-->
- <xs:complexType name="gid_targets_type">
+ <!-- Maps to a list of gid_process_attr_values-->
+ <xs:complexType name="gid_process_attr_values_type">
<xs:sequence>
- <xs:element name="gid_target" type="tns:gid_target_type" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="gid" type="tns:gid_value_type" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
- <!-- Maps to a gid_tracker-->
- <xs:complexType name="gid_tracker_type">
+ <!-- Maps to a gid_process_attr_tracker-->
+ <xs:complexType name="gid_process_attr_tracker_type">
<xs:all>
- <xs:element name="target_type" type="tns:tracker_target_type" minOccurs="0" maxOccurs="1" />
- <xs:element name="targets" type="tns:gid_targets_type" minOccurs="0" />
+ <xs:element name="process_attr_values" type="tns:gid_process_attr_values_type" minOccurs="0" />
</xs:all>
</xs:complexType>
</xs:restriction>
</xs:simpleType>
- <xs:complexType name="vgid_target_type_choice">
+ <xs:complexType name="vgid_value_type_choice">
<xs:choice>
<xs:element name="id" type="tns:vgidbyint" />
<xs:element name="name" type="xs:string" />
</xs:choice>
</xs:complexType>
- <xs:complexType name="vgid_target_type">
+ <xs:complexType name="vgid_value_type">
<xs:all>
- <xs:element name="type" type="tns:vgid_target_type_choice" minOccurs="0" maxOccurs="1" />
+ <xs:element name="type" type="tns:vgid_value_type_choice" minOccurs="0" maxOccurs="1" />
<xs:element name="success" type="xs:boolean" default="false" minOccurs="0" />
</xs:all>
</xs:complexType>
- <!-- Maps to a list of vgid_targets-->
- <xs:complexType name="vgid_targets_type">
+ <!-- Maps to a list of vgid_process_attr_values-->
+ <xs:complexType name="vgid_process_attr_values_type">
<xs:sequence>
- <xs:element name="vgid_target" type="tns:vgid_target_type" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="vgid" type="tns:vgid_value_type" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
- <!-- Maps to a vgid_tracker-->
- <xs:complexType name="vgid_tracker_type">
+ <!-- Maps to a vgid_process_attr_tracker-->
+ <xs:complexType name="vgid_process_attr_tracker_type">
<xs:all>
- <xs:element name="target_type" type="tns:tracker_target_type" minOccurs="0" maxOccurs="1" />
- <xs:element name="targets" type="tns:vgid_targets_type" minOccurs="0" />
+ <xs:element name="process_attr_values" type="tns:vgid_process_attr_values_type" minOccurs="0" />
</xs:all>
</xs:complexType>
- <!-- Maps to a list of trackers-->
- <xs:complexType name="trackers_type">
+ <!-- Maps to a list of process_attr_trackers-->
+ <xs:complexType name="process_attr_trackers_type">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
- <xs:element name="pid_tracker" type="tns:pid_tracker_type" maxOccurs="1" />
- <xs:element name="vpid_tracker" type="tns:vpid_tracker_type" maxOccurs="1" />
- <xs:element name="uid_tracker" type="tns:uid_tracker_type" maxOccurs="1" />
- <xs:element name="vuid_tracker" type="tns:vuid_tracker_type" maxOccurs="1" />
- <xs:element name="gid_tracker" type="tns:gid_tracker_type" maxOccurs="1" />
- <xs:element name="vgid_tracker" type="tns:vgid_tracker_type" maxOccurs="1" />
+ <xs:element name="pid_process_attr_tracker" type="tns:pid_process_attr_tracker_type" maxOccurs="1" />
+ <xs:element name="vpid_process_attr_tracker" type="tns:vpid_process_attr_tracker_type" maxOccurs="1" />
+ <xs:element name="uid_process_attr_tracker" type="tns:uid_process_attr_tracker_type" maxOccurs="1" />
+ <xs:element name="vuid_process_attr_tracker" type="tns:vuid_process_attr_tracker_type" maxOccurs="1" />
+ <xs:element name="gid_process_attr_tracker" type="tns:gid_process_attr_tracker_type" maxOccurs="1" />
+ <xs:element name="vgid_process_attr_tracker" type="tns:vgid_process_attr_tracker_type" maxOccurs="1" />
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:element name="pids" type="tns:pids_type" minOccurs="0" />
<xs:element name="channels" type="tns:channels_type" minOccurs="0" />
<xs:element name="events" type="tns:event_list_type" minOccurs="0" />
- <xs:element name="trackers" type="tns:trackers_type" minOccurs="0" />
+ <xs:element name="process_attr_trackers" type="tns:process_attr_trackers_type" minOccurs="0" />
</xs:all>
</xs:complexType>
<xs:element name="channels" type="tns:channels_type" minOccurs="0" />
<xs:element name="events" type="tns:event_list_type" minOccurs="0" />
<xs:element name="channel" type="tns:channel_type" minOccurs="0" />
- <xs:element name="trackers" type="tns:trackers_type" minOccurs="0" />
+ <xs:element name="process_attr_trackers" type="tns:process_attr_trackers_type" minOccurs="0" />
<xs:element name="metadata_action" type="tns:metadata_cmd_type" minOccurs="0" />
<xs:element name="regenerate_action" type="tns:regenerate_cmd_type" minOccurs="0" />
<xs:element name="rotation" type="tns:rotate_type" minOccurs="0" />
*
*/
+#include "lttng/tracker.h"
#define _LGPL_SOURCE
+#include "mi-lttng.h"
#include <common/config/session-config.h>
#include <common/defaults.h>
-#include <lttng/snapshot-internal.h>
-#include <lttng/tracker-internal.h>
+#include <common/tracker.h>
#include <lttng/channel.h>
-#include "mi-lttng.h"
+#include <lttng/snapshot-internal.h>
#include <assert.h>
LTTNG_HIDDEN
int mi_lttng_trackers_open(struct mi_writer *writer)
{
- return mi_lttng_writer_open_element(writer, config_element_trackers);
+ return mi_lttng_writer_open_element(
+ writer, config_element_process_attr_trackers);
}
-static int get_tracker_elements(enum lttng_tracker_type tracker_type,
- const char **element_id_tracker,
- const char **element_target_id)
+static int get_tracker_elements(enum lttng_process_attr process_attr,
+ const char **element_process_attr_tracker,
+ const char **element_process_attr_value)
{
int ret = 0;
- switch (tracker_type) {
- case LTTNG_TRACKER_PID:
- *element_id_tracker = config_element_pid_tracker;
- *element_target_id = config_element_target_pid;
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_PROCESS_ID:
+ *element_process_attr_tracker =
+ config_element_process_attr_tracker_pid;
+ *element_process_attr_value =
+ config_element_process_attr_pid_value;
break;
- case LTTNG_TRACKER_VPID:
- *element_id_tracker = config_element_vpid_tracker;
- *element_target_id = config_element_target_vpid;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ *element_process_attr_tracker =
+ config_element_process_attr_tracker_vpid;
+ *element_process_attr_value =
+ config_element_process_attr_vpid_value;
break;
- case LTTNG_TRACKER_UID:
- *element_id_tracker = config_element_uid_tracker;
- *element_target_id = config_element_target_uid;
+ case LTTNG_PROCESS_ATTR_USER_ID:
+ *element_process_attr_tracker =
+ config_element_process_attr_tracker_uid;
+ *element_process_attr_value =
+ config_element_process_attr_uid_value;
break;
- case LTTNG_TRACKER_VUID:
- *element_id_tracker = config_element_vuid_tracker;
- *element_target_id = config_element_target_vuid;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ *element_process_attr_tracker =
+ config_element_process_attr_tracker_vuid;
+ *element_process_attr_value =
+ config_element_process_attr_vuid_value;
break;
- case LTTNG_TRACKER_GID:
- *element_id_tracker = config_element_gid_tracker;
- *element_target_id = config_element_target_gid;
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
+ *element_process_attr_tracker =
+ config_element_process_attr_tracker_gid;
+ *element_process_attr_value =
+ config_element_process_attr_gid_value;
break;
- case LTTNG_TRACKER_VGID:
- *element_id_tracker = config_element_vgid_tracker;
- *element_target_id = config_element_target_vgid;
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ *element_process_attr_tracker =
+ config_element_process_attr_tracker_vgid;
+ *element_process_attr_value =
+ config_element_process_attr_vgid_value;
break;
default:
ret = LTTNG_ERR_SAVE_IO_FAIL;
}
LTTNG_HIDDEN
-int mi_lttng_id_tracker_open(
- struct mi_writer *writer, enum lttng_tracker_type tracker_type)
+int mi_lttng_process_attribute_tracker_open(
+ struct mi_writer *writer, enum lttng_process_attr process_attr)
{
int ret;
- const char *element_id_tracker, *element_target_id;
+ const char *element_tracker, *element_value;
ret = get_tracker_elements(
- tracker_type, &element_id_tracker, &element_target_id);
+ process_attr, &element_tracker, &element_value);
if (ret) {
return ret;
}
- /* Open element $id_tracker */
- ret = mi_lttng_writer_open_element(writer, element_id_tracker);
+ /* Open process attribute tracker element */
+ ret = mi_lttng_writer_open_element(writer, element_tracker);
if (ret) {
goto end;
}
- /* Open targets element */
- ret = mi_lttng_targets_open(writer);
+ /* Open values element */
+ ret = mi_lttng_process_attr_values_open(writer);
end:
return ret;
}
}
LTTNG_HIDDEN
-int mi_lttng_targets_open(struct mi_writer *writer)
+int mi_lttng_process_attr_values_open(struct mi_writer *writer)
{
- return mi_lttng_writer_open_element(writer,
- config_element_targets);
+ return mi_lttng_writer_open_element(
+ writer, config_element_process_attr_values);
}
LTTNG_HIDDEN
-int mi_lttng_id_target(struct mi_writer *writer,
- enum lttng_tracker_type tracker_type,
- const struct lttng_tracker_id *id,
- int is_open)
+int mi_lttng_all_process_attribute_value(struct mi_writer *writer,
+ enum lttng_process_attr process_attr,
+ bool is_open)
{
int ret;
const char *element_id_tracker, *element_target_id;
- enum lttng_tracker_id_status status;
- int value;
- const char *string;
ret = get_tracker_elements(
- tracker_type, &element_id_tracker, &element_target_id);
+ process_attr, &element_id_tracker, &element_target_id);
if (ret) {
return ret;
}
- switch (lttng_tracker_id_get_type(id)) {
- case LTTNG_ID_ALL:
- ret = mi_lttng_writer_open_element(writer, element_target_id);
- if (ret) {
- goto end;
- }
- ret = mi_lttng_writer_open_element(writer, config_element_type);
- if (ret) {
- goto end;
- }
- ret = mi_lttng_writer_write_element_bool(
- writer, config_element_all, 1);
- if (ret) {
- goto end;
- }
- ret = mi_lttng_writer_close_element(writer);
- if (ret) {
- goto end;
- }
- break;
- case LTTNG_ID_VALUE:
- ret = mi_lttng_writer_open_element(writer, element_target_id);
- if (ret) {
- goto end;
- }
- ret = mi_lttng_writer_open_element(writer, config_element_type);
- if (ret) {
- goto end;
- }
+ ret = mi_lttng_writer_open_element(writer, element_target_id);
+ if (ret) {
+ goto end;
+ }
- status = lttng_tracker_id_get_value(id, &value);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ret = -1;
- goto end;
- }
+ ret = mi_lttng_writer_open_element(writer, config_element_type);
+ if (ret) {
+ goto end;
+ }
- ret = mi_lttng_writer_write_element_signed_int(
- writer, config_element_id, value);
- if (ret) {
- goto end;
- }
+ ret = mi_lttng_writer_write_element_bool(writer, config_element_all, 1);
+ if (ret) {
+ goto end;
+ }
+
+ ret = mi_lttng_writer_close_element(writer);
+ if (ret) {
+ goto end;
+ }
+
+ if (!is_open) {
ret = mi_lttng_writer_close_element(writer);
if (ret) {
goto end;
}
- break;
- case LTTNG_ID_STRING:
- ret = mi_lttng_writer_open_element(writer, element_target_id);
- if (ret) {
- goto end;
- }
- ret = mi_lttng_writer_open_element(writer, config_element_type);
- if (ret) {
- goto end;
- }
+ }
+end:
+ return ret;
+}
- status = lttng_tracker_id_get_string(id, &string);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ret = -1;
- goto end;
- }
+LTTNG_HIDDEN
+int mi_lttng_integral_process_attribute_value(struct mi_writer *writer,
+ enum lttng_process_attr process_attr,
+ int64_t value,
+ bool is_open)
+{
+ int ret;
+ const char *element_id_tracker, *element_target_id;
- ret = mi_lttng_writer_write_element_string(
- writer, config_element_name, string);
- if (ret) {
- goto end;
- }
+ ret = get_tracker_elements(
+ process_attr, &element_id_tracker, &element_target_id);
+ if (ret) {
+ return ret;
+ }
+
+ ret = mi_lttng_writer_open_element(writer, element_target_id);
+ if (ret) {
+ goto end;
+ }
+
+ ret = mi_lttng_writer_open_element(writer, config_element_type);
+ if (ret) {
+ goto end;
+ }
+
+ ret = mi_lttng_writer_write_element_signed_int(
+ writer, config_element_process_attr_id, value);
+ if (ret) {
+ goto end;
+ }
+
+ ret = mi_lttng_writer_close_element(writer);
+ if (ret) {
+ goto end;
+ }
+
+ if (!is_open) {
ret = mi_lttng_writer_close_element(writer);
if (ret) {
goto end;
}
- break;
- case LTTNG_ID_UNKNOWN:
- ret = -LTTNG_ERR_INVALID;
+ }
+
+end:
+ return ret;
+}
+
+LTTNG_HIDDEN
+int mi_lttng_string_process_attribute_value(struct mi_writer *writer,
+ enum lttng_process_attr process_attr,
+ const char *value,
+ bool is_open)
+
+{
+ int ret;
+ const char *element_id_tracker, *element_target_id;
+
+ ret = get_tracker_elements(
+ process_attr, &element_id_tracker, &element_target_id);
+ if (ret) {
+ return ret;
+ }
+
+ ret = mi_lttng_writer_open_element(writer, element_target_id);
+ if (ret) {
+ goto end;
+ }
+
+ ret = mi_lttng_writer_open_element(writer, config_element_type);
+ if (ret) {
+ goto end;
+ }
+
+ ret = mi_lttng_writer_write_element_string(
+ writer, config_element_name, value);
+ if (ret) {
+ goto end;
+ }
+
+ ret = mi_lttng_writer_close_element(writer);
+ if (ret) {
goto end;
}
int mi_lttng_trackers_open(struct mi_writer *writer);
/*
- * Machine interface: open a id tracker element.
+ * Machine interface: open a process attribute tracker element.
*
* writer An instance of a machine interface writer.
*
*
* Note: A targets element is also opened for each tracker definition
*/
-int mi_lttng_id_tracker_open(
- struct mi_writer *writer, enum lttng_tracker_type tracker_type);
+int mi_lttng_process_attribute_tracker_open(
+ struct mi_writer *writer, enum lttng_process_attr process_attr);
/*
* Machine interface: open a PIDs element.
*/
int mi_lttng_pid(struct mi_writer *writer, pid_t pid , const char *name,
int is_open);
+
/*
- * Machine interface: open a targets element.
+ * Machine interface: open a process attribute values element.
*
* writer An instance of a machine interface writer.
*
* Returns zero if the element's value could be written.
* Negative values indicate an error.
*/
-int mi_lttng_targets_open(struct mi_writer *writer);
+int mi_lttng_process_attr_values_open(struct mi_writer *writer);
/*
- * Machine interface for track/untrack an id_target
+ * Machine interface for track/untrack of all process attribute values.
*
* writer An instance of a machine interface writer.
*
* Returns zero if the element's value could be written.
* Negative values indicate an error.
*/
-int mi_lttng_id_target(struct mi_writer *writer,
- enum lttng_tracker_type tracker_type,
- const struct lttng_tracker_id *id,
- int is_open);
+int mi_lttng_all_process_attribute_value(struct mi_writer *writer,
+ enum lttng_process_attr process_attr,
+ bool is_open);
+
+/*
+ * Machine interface for track/untrack of an integral process attribute value.
+ *
+ * writer An instance of a machine interface writer.
+ *
+ * Returns zero if the element's value could be written.
+ * Negative values indicate an error.
+ */
+int mi_lttng_integral_process_attribute_value(struct mi_writer *writer,
+ enum lttng_process_attr process_attr,
+ int64_t value,
+ bool is_open);
+
+/*
+ * Machine interface for track/untrack of a string process attribute value.
+ *
+ * writer An instance of a machine interface writer.
+ *
+ * Returns zero if the element's value could be written.
+ * Negative values indicate an error.
+ */
+int mi_lttng_string_process_attribute_value(struct mi_writer *writer,
+ enum lttng_process_attr process_attr,
+ const char *value,
+ bool is_open);
/*
* Machine interface of a context.
enum lttcomm_sessiond_command {
/* Tracer command */
- LTTNG_ADD_CONTEXT = 0,
+ LTTNG_ADD_CONTEXT = 0,
/* LTTNG_CALIBRATE used to be here */
- LTTNG_DISABLE_CHANNEL = 2,
- LTTNG_DISABLE_EVENT = 3,
- LTTNG_LIST_SYSCALLS = 4,
- LTTNG_ENABLE_CHANNEL = 5,
- LTTNG_ENABLE_EVENT = 6,
+ LTTNG_DISABLE_CHANNEL = 2,
+ LTTNG_DISABLE_EVENT = 3,
+ LTTNG_LIST_SYSCALLS = 4,
+ LTTNG_ENABLE_CHANNEL = 5,
+ LTTNG_ENABLE_EVENT = 6,
/* 7 */
/* Session daemon command */
/* 8 */
- LTTNG_DESTROY_SESSION = 9,
- LTTNG_LIST_CHANNELS = 10,
- LTTNG_LIST_DOMAINS = 11,
- LTTNG_LIST_EVENTS = 12,
- LTTNG_LIST_SESSIONS = 13,
- LTTNG_LIST_TRACEPOINTS = 14,
- LTTNG_REGISTER_CONSUMER = 15,
- LTTNG_START_TRACE = 16,
- LTTNG_STOP_TRACE = 17,
- LTTNG_LIST_TRACEPOINT_FIELDS = 18,
+ LTTNG_DESTROY_SESSION = 9,
+ LTTNG_LIST_CHANNELS = 10,
+ LTTNG_LIST_DOMAINS = 11,
+ LTTNG_LIST_EVENTS = 12,
+ LTTNG_LIST_SESSIONS = 13,
+ LTTNG_LIST_TRACEPOINTS = 14,
+ LTTNG_REGISTER_CONSUMER = 15,
+ LTTNG_START_TRACE = 16,
+ LTTNG_STOP_TRACE = 17,
+ LTTNG_LIST_TRACEPOINT_FIELDS = 18,
/* Consumer */
- LTTNG_DISABLE_CONSUMER = 19,
- LTTNG_ENABLE_CONSUMER = 20,
- LTTNG_SET_CONSUMER_URI = 21,
+ LTTNG_DISABLE_CONSUMER = 19,
+ LTTNG_ENABLE_CONSUMER = 20,
+ LTTNG_SET_CONSUMER_URI = 21,
/* 22 */
/* 23 */
- LTTNG_DATA_PENDING = 24,
- LTTNG_SNAPSHOT_ADD_OUTPUT = 25,
- LTTNG_SNAPSHOT_DEL_OUTPUT = 26,
- LTTNG_SNAPSHOT_LIST_OUTPUT = 27,
- LTTNG_SNAPSHOT_RECORD = 28,
+ LTTNG_DATA_PENDING = 24,
+ LTTNG_SNAPSHOT_ADD_OUTPUT = 25,
+ LTTNG_SNAPSHOT_DEL_OUTPUT = 26,
+ LTTNG_SNAPSHOT_LIST_OUTPUT = 27,
+ LTTNG_SNAPSHOT_RECORD = 28,
/* 29 */
/* 30 */
- LTTNG_SAVE_SESSION = 31,
- LTTNG_TRACK_ID = 32,
- LTTNG_UNTRACK_ID = 33,
- LTTNG_LIST_TRACKER_IDS = 34,
- LTTNG_SET_SESSION_SHM_PATH = 40,
- LTTNG_REGENERATE_METADATA = 41,
- LTTNG_REGENERATE_STATEDUMP = 42,
- LTTNG_REGISTER_TRIGGER = 43,
- LTTNG_UNREGISTER_TRIGGER = 44,
- LTTNG_ROTATE_SESSION = 45,
- LTTNG_ROTATION_GET_INFO = 46,
- LTTNG_ROTATION_SET_SCHEDULE = 47,
- LTTNG_SESSION_LIST_ROTATION_SCHEDULES = 48,
- LTTNG_CREATE_SESSION_EXT = 49,
- LTTNG_CLEAR_SESSION = 50,
+ LTTNG_SAVE_SESSION = 31,
+ LTTNG_PROCESS_ATTR_TRACKER_ADD_INCLUDE_VALUE = 32,
+ LTTNG_PROCESS_ATTR_TRACKER_REMOVE_INCLUDE_VALUE = 33,
+ LTTNG_PROCESS_ATTR_TRACKER_GET_POLICY = 34,
+ LTTNG_PROCESS_ATTR_TRACKER_SET_POLICY = 35,
+ LTTNG_PROCESS_ATTR_TRACKER_GET_INCLUSION_SET = 36,
+ LTTNG_SET_SESSION_SHM_PATH = 40,
+ LTTNG_REGENERATE_METADATA = 41,
+ LTTNG_REGENERATE_STATEDUMP = 42,
+ LTTNG_REGISTER_TRIGGER = 43,
+ LTTNG_UNREGISTER_TRIGGER = 44,
+ LTTNG_ROTATE_SESSION = 45,
+ LTTNG_ROTATION_GET_INFO = 46,
+ LTTNG_ROTATION_SET_SCHEDULE = 47,
+ LTTNG_SESSION_LIST_ROTATION_SCHEDULES = 48,
+ LTTNG_CREATE_SESSION_EXT = 49,
+ LTTNG_CLEAR_SESSION = 50,
};
enum lttcomm_relayd_command {
size_t len, int flags);
};
+struct process_attr_integral_value_comm {
+ union {
+ int64_t _signed;
+ uint64_t _unsigned;
+ } u;
+} LTTNG_PACKED;
+
/*
* Data structure received from lttng client to session daemon.
*/
char shm_path[PATH_MAX];
} LTTNG_PACKED set_shm_path;
struct {
- uint32_t tracker_type; /* enum lttng_tracker_type */
- uint32_t id_type; /* enum lttng_tracker_id_type */
- union {
- int32_t value;
- uint32_t var_len;
- } u;
+ /* enum lttng_process_attr */
+ int32_t process_attr;
+ /* enum lttng_process_attr_value_type */
+ int32_t value_type;
+
+ struct process_attr_integral_value_comm integral_value;
/*
- * for LTTNG_ID_STRING, followed by a variable length
- * zero-terminated string of length "var_len", which
- * includes the final \0.
+ * For user/group names, a variable length,
+ * zero-terminated, string of length 'name_len'
+ * (including the terminator) follows.
+ *
+ * integral_value should not be used in those cases.
*/
- } LTTNG_PACKED id_tracker;
+ uint32_t name_len;
+ } LTTNG_PACKED process_attr_tracker_add_remove_include_value;
struct {
- uint32_t tracker_type; /* enum lttng_tracker_type */
- } LTTNG_PACKED id_tracker_list;
+ /* enum lttng_process_attr */
+ int32_t process_attr;
+ } LTTNG_PACKED process_attr_tracker_get_inclusion_set;
+ struct {
+ /* enum lttng_process_attr */
+ int32_t process_attr;
+ } LTTNG_PACKED process_attr_tracker_get_tracking_policy;
+ struct {
+ /* enum lttng_process_attr */
+ int32_t process_attr;
+ /* enum lttng_tracking_policy */
+ int32_t tracking_policy;
+ } LTTNG_PACKED process_attr_tracker_set_tracking_policy;
struct {
uint32_t length;
} LTTNG_PACKED trigger;
uint32_t nb_tracker_id;
} LTTNG_PACKED;
-struct lttcomm_tracker_id_header {
- uint32_t type; /* enum lttng_tracker_id_type */
- union {
- int32_t value;
- uint32_t var_data_len;
- } u;
-} LTTNG_PACKED;
-
/*
* Data structure for the response from sessiond to the lttng client.
*/
/*
* Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
+ * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
* SPDX-License-Identifier: LGPL-2.1-only
*
*/
-#include <assert.h>
-#include <common/defaults.h>
-#include <common/error.h>
-#include <common/macros.h>
-#include <common/sessiond-comm/sessiond-comm.h>
-#include <common/uri.h>
-#include <lttng/tracker-internal.h>
-#include <stdio.h>
-#include <time.h>
-
-struct lttng_tracker_id *lttng_tracker_id_create(void)
-{
- struct lttng_tracker_id *id;
+#include <lttng/domain.h>
+#include <lttng/lttng-error.h>
+#include <lttng/tracker.h>
- id = zmalloc(sizeof(*id));
- if (!id) {
- goto error;
+#include <common/dynamic-array.h>
+#include <common/error.h>
+#include <common/hashtable/hashtable.h>
+#include <common/hashtable/utils.h>
+#include <common/tracker.h>
+
+#include <stdbool.h>
+
+struct process_attr_tracker_values_comm_header {
+ uint32_t count;
+};
+
+struct process_attr_tracker_value_comm {
+ /* enum lttng_process_attr_value_type */
+ int32_t type;
+ union {
+ struct process_attr_integral_value_comm integral;
+ /* Includes the '\0' terminator. */
+ uint32_t name_len;
+ } value;
+};
+
+#define GET_INTEGRAL_COMM_VALUE(value_ptr, as_type) \
+ ((as_type)(is_signed(as_type) ? (value_ptr)->u._signed : \
+ (value_ptr)->u._unsigned))
+
+#define SET_INTEGRAL_COMM_VALUE(comm_value, value) \
+ if (is_signed(typeof(value))) { \
+ (comm_value)->u._signed = \
+ (typeof((comm_value)->u._signed)) value; \
+ } else { \
+ (comm_value)->u._unsigned = \
+ (typeof((comm_value)->u._unsigned)) value; \
}
- id->type = LTTNG_ID_UNKNOWN;
- id->string = NULL;
- id->value = -1;
- return id;
-error:
- lttng_tracker_id_destroy(id);
- return NULL;
+static inline bool is_virtual_process_attr(enum lttng_process_attr process_attr)
+{
+ return process_attr == LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID ||
+ process_attr == LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID ||
+ process_attr == LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID;
}
-enum lttng_tracker_id_status lttng_tracker_id_set_value(
- struct lttng_tracker_id *id, int value)
+static inline bool is_value_type_name(
+ enum lttng_process_attr_value_type value_type)
{
- assert(id);
-
- if (value < 0) {
- return LTTNG_TRACKER_ID_STATUS_INVALID;
- }
-
- id->type = LTTNG_ID_VALUE;
- id->value = value;
- return LTTNG_TRACKER_ID_STATUS_OK;
+ return value_type == LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME ||
+ value_type == LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME;
}
-enum lttng_tracker_id_status lttng_tracker_id_set_string(
- struct lttng_tracker_id *id, const char *value)
+LTTNG_HIDDEN
+enum lttng_error_code process_attr_value_from_comm(
+ enum lttng_domain_type domain,
+ enum lttng_process_attr process_attr,
+ enum lttng_process_attr_value_type value_type,
+ const struct process_attr_integral_value_comm *integral_value,
+ const struct lttng_buffer_view *value_view,
+ struct process_attr_value **_value)
{
- assert(id);
- assert(value);
+ char *name = NULL;
+ enum lttng_error_code ret = LTTNG_OK;
+ struct process_attr_value *value = zmalloc(sizeof(*value));
- id->type = LTTNG_ID_STRING;
- id->string = strdup(value);
- if (id->string == NULL) {
- /* No memory left */
+ if (!value) {
+ ret = LTTNG_ERR_NOMEM;
goto error;
}
- return LTTNG_TRACKER_ID_STATUS_OK;
-error:
- return LTTNG_TRACKER_ID_STATUS_INVALID;
-}
-
-enum lttng_tracker_id_status lttng_tracker_id_set_all(
- struct lttng_tracker_id *id)
-{
- assert(id);
+ if (value_view && value_view->size > 0) {
+ if (value_view->data[value_view->size - 1] != '\0') {
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+ name = strdup(value_view->data);
+ if (!name) {
+ ret = LTTNG_ERR_NOMEM;
+ }
+ }
- id->type = LTTNG_ID_ALL;
+ if (domain != LTTNG_DOMAIN_UST && domain != LTTNG_DOMAIN_KERNEL) {
+ ERR("Only the user space and kernel space domains may be specified to configure process attribute trackers");
+ ret = LTTNG_ERR_UNSUPPORTED_DOMAIN;
+ goto error;
+ }
- return LTTNG_TRACKER_ID_STATUS_OK;
-}
+ if (!is_virtual_process_attr(process_attr) &&
+ domain != LTTNG_DOMAIN_KERNEL) {
+ ERR("Non-virtual process attributes can only be used in the kernel domain");
+ ret = LTTNG_ERR_UNSUPPORTED_DOMAIN;
+ goto error;
+ }
-static void lttng_tracker_id_reset(struct lttng_tracker_id *id)
-{
- if (id == NULL) {
- return;
+ /* Only expect a payload for name value types. */
+ if (is_value_type_name(value_type) && value_view->size == 0) {
+ ret = LTTNG_ERR_INVALID_PROTOCOL;
+ goto error;
+ } else if (!is_value_type_name(value_type) && value_view->size != 0) {
+ ret = LTTNG_ERR_INVALID_PROTOCOL;
+ goto error;
}
- if (id->string != NULL) {
- free(id->string);
- id->string = NULL;
+ value->type = value_type;
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_PROCESS_ID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ if (value_type != LTTNG_PROCESS_ATTR_VALUE_TYPE_PID) {
+ ERR("Invalid value type used for process ID process attribute");
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+ value->value.pid =
+ GET_INTEGRAL_COMM_VALUE(integral_value, pid_t);
+ break;
+ case LTTNG_PROCESS_ATTR_USER_ID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ switch (value_type) {
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_UID:
+ value->value.uid = GET_INTEGRAL_COMM_VALUE(
+ integral_value, uid_t);
+ break;
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME:
+ if (!name) {
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+
+ value->value.user_name = name;
+ name = NULL;
+ break;
+ default:
+ ERR("Invalid value type used for user ID process attribute");
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+ break;
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ switch (value_type) {
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_GID:
+ value->value.gid = GET_INTEGRAL_COMM_VALUE(
+ integral_value, gid_t);
+ break;
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME:
+ if (!name) {
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+
+ value->value.group_name = name;
+ name = NULL;
+ break;
+ default:
+ ERR("Invalid value type used for group ID process attribute");
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+ break;
+ default:
+ ret = LTTNG_ERR_INVALID_PROTOCOL;
+ goto error;
}
- id->type = LTTNG_ID_UNKNOWN;
- id->value = -1;
+ *_value = value;
+ value = NULL;
+ return LTTNG_OK;
+error:
+ free(name);
+ process_attr_value_destroy(value);
+ return ret;
}
-void lttng_tracker_id_destroy(struct lttng_tracker_id *id)
+LTTNG_HIDDEN
+const char *lttng_process_attr_to_string(enum lttng_process_attr process_attr)
{
- if (id == NULL) {
- return;
+ switch (process_attr) {
+ case LTTNG_PROCESS_ATTR_PROCESS_ID:
+ return "process ID";
+ case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
+ return "virtual process ID";
+ case LTTNG_PROCESS_ATTR_USER_ID:
+ return "user ID";
+ case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
+ return "virtual user ID";
+ case LTTNG_PROCESS_ATTR_GROUP_ID:
+ return "group ID";
+ case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
+ return "virtual group ID";
+ default:
+ return "unknown process attribute";
}
-
- lttng_tracker_id_reset(id);
-
- free(id);
}
-enum lttng_tracker_id_type lttng_tracker_id_get_type(
- const struct lttng_tracker_id *id)
+static void process_attr_tracker_value_destructor(void *ptr)
{
- assert(id);
- return id->type;
+ struct process_attr_value *value = (typeof(value)) ptr;
+
+ process_attr_value_destroy(value);
}
-enum lttng_tracker_id_status lttng_tracker_id_get_value(
- const struct lttng_tracker_id *id, int *value)
+LTTNG_HIDDEN
+struct lttng_process_attr_values *lttng_process_attr_values_create(void)
{
- assert(id);
- if (id->type == LTTNG_ID_UNKNOWN) {
- return LTTNG_TRACKER_ID_STATUS_UNSET;
- }
+ struct lttng_process_attr_values *values = zmalloc(sizeof(*values));
- if (id->type != LTTNG_ID_VALUE) {
- return LTTNG_TRACKER_ID_STATUS_INVALID;
+ if (!values) {
+ goto end;
}
- *value = id->value;
- return LTTNG_TRACKER_ID_STATUS_OK;
+ lttng_dynamic_pointer_array_init(
+ &values->array, process_attr_tracker_value_destructor);
+end:
+ return values;
}
-bool lttng_tracker_id_is_equal(const struct lttng_tracker_id *left,
- const struct lttng_tracker_id *right)
+LTTNG_HIDDEN
+unsigned int _lttng_process_attr_values_get_count(
+ const struct lttng_process_attr_values *values)
{
- if (left->type != right->type) {
- return 0;
- }
-
- switch (left->type) {
- case LTTNG_ID_ALL:
- return 1;
- case LTTNG_ID_VALUE:
- if (left->value != right->value) {
- return 0;
- }
- break;
- case LTTNG_ID_STRING:
- if (strcmp(left->string, right->string) != 0) {
- return 0;
- }
- break;
- default:
- /*
- * Normally this should return true, but comparing unset tracker
- * id is "invalid".
- */
- return 0;
- }
- return 1;
+ return (unsigned int) lttng_dynamic_pointer_array_get_count(
+ &values->array);
}
-int lttng_tracker_id_copy(struct lttng_tracker_id *dest,
- const struct lttng_tracker_id *orig)
+LTTNG_HIDDEN
+const struct process_attr_value *lttng_process_attr_tracker_values_get_at_index(
+ const struct lttng_process_attr_values *values,
+ unsigned int index)
{
- int ret = 0;
- enum lttng_tracker_id_status status;
-
- assert(dest);
- assert(orig);
+ return lttng_dynamic_pointer_array_get_pointer(&values->array, index);
+}
- switch (orig->type) {
- case LTTNG_ID_ALL:
- status = lttng_tracker_id_set_all(dest);
+static
+int process_attr_tracker_value_serialize(const struct process_attr_value *value,
+ struct lttng_dynamic_buffer *buffer)
+{
+ int ret;
+ struct process_attr_tracker_value_comm value_comm = {
+ .type = (int32_t) value->type,
+ };
+ const char *name = NULL;
+
+ switch (value->type) {
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_PID:
+ SET_INTEGRAL_COMM_VALUE(
+ &value_comm.value.integral, value->value.pid);
break;
- case LTTNG_ID_VALUE:
- status = lttng_tracker_id_set_value(dest, orig->value);
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_UID:
+ SET_INTEGRAL_COMM_VALUE(
+ &value_comm.value.integral, value->value.uid);
break;
- case LTTNG_ID_STRING:
- status = lttng_tracker_id_set_string(dest, orig->string);
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_GID:
+ SET_INTEGRAL_COMM_VALUE(
+ &value_comm.value.integral, value->value.gid);
break;
- default:
- status = LTTNG_TRACKER_ID_STATUS_OK;
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME:
+ name = value->value.user_name;
break;
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME:
+ name = value->value.group_name;
+ break;
+ default:
+ abort();
}
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ret = -1;
- goto error;
+ if (name) {
+ value_comm.value.name_len = strlen(name) + 1;
}
-error:
+
+ ret = lttng_dynamic_buffer_append(
+ buffer, &value_comm, sizeof(value_comm));
+ if (ret) {
+ goto end;
+ }
+
+ if (name) {
+ ret = lttng_dynamic_buffer_append(
+ buffer, name, value_comm.value.name_len);
+ }
+end:
return ret;
}
-struct lttng_tracker_id *lttng_tracker_id_duplicate(
- const struct lttng_tracker_id *orig)
+LTTNG_HIDDEN
+int lttng_process_attr_values_serialize(
+ const struct lttng_process_attr_values *values,
+ struct lttng_dynamic_buffer *buffer)
{
int ret;
- struct lttng_tracker_id *copy = NULL;
+ unsigned int count, i;
+ struct process_attr_tracker_values_comm_header header = {};
- copy = lttng_tracker_id_create();
- if (copy == NULL) {
- goto error;
- }
+ count = _lttng_process_attr_values_get_count(values);
+ header.count = (uint32_t) count;
- ret = lttng_tracker_id_copy(copy, orig);
+ ret = lttng_dynamic_buffer_append(buffer, &header, sizeof(header));
if (ret) {
- goto error;
+ goto end;
}
- return copy;
-error:
- lttng_tracker_id_destroy(copy);
- return NULL;
-}
-
-enum lttng_tracker_id_status lttng_tracker_id_get_string(
- const struct lttng_tracker_id *id, const char **value)
-{
- assert(id);
- if (id->type == LTTNG_ID_UNKNOWN) {
- *value = NULL;
- return LTTNG_TRACKER_ID_STATUS_UNSET;
- }
+ for (i = 0; i < count; i++) {
+ const struct process_attr_value *value =
+ lttng_process_attr_tracker_values_get_at_index(
+ values, i);
- if (id->type != LTTNG_ID_STRING) {
- *value = NULL;
- return LTTNG_TRACKER_ID_STATUS_INVALID;
+ ret = process_attr_tracker_value_serialize(value, buffer);
+ if (ret) {
+ goto end;
+ }
}
-
- *value = id->string;
- return LTTNG_TRACKER_ID_STATUS_OK;
+end:
+ return ret;
}
-struct lttng_tracker_ids *lttng_tracker_ids_create(unsigned int count)
+LTTNG_HIDDEN
+ssize_t lttng_process_attr_values_create_from_buffer(
+ enum lttng_domain_type domain,
+ enum lttng_process_attr process_attr,
+ const struct lttng_buffer_view *buffer_view,
+ struct lttng_process_attr_values **_values)
{
- struct lttng_tracker_ids *ids = NULL;
+ ssize_t offset;
+ unsigned int i;
+ struct lttng_process_attr_values *values;
+ struct lttng_buffer_view header_view;
+ const struct process_attr_tracker_values_comm_header *header;
- ids = zmalloc(sizeof(*ids));
- if (!ids) {
+ values = lttng_process_attr_values_create();
+ if (!values) {
goto error;
}
- ids->id_array = zmalloc(sizeof(struct lttng_tracker_id) * count);
- if (!ids->id_array) {
+ header_view = lttng_buffer_view_from_view(
+ buffer_view, 0, sizeof(*header));
+ if (!header_view.data) {
goto error;
}
+ offset = header_view.size;
+ header = (typeof(header)) header_view.data;
+
+ /*
+ * Check that the number of values is not absurdly large with respect to
+ * the received buffer's size.
+ */
+ if (buffer_view->size <
+ header->count * sizeof(struct process_attr_tracker_value_comm)) {
+ goto error;
+ }
+ for (i = 0; i < (unsigned int) header->count; i++) {
+ int ret;
+ enum lttng_error_code ret_code;
+ const struct process_attr_tracker_value_comm *value_comm;
+ struct process_attr_value *value;
+ enum lttng_process_attr_value_type type;
+ struct lttng_buffer_view value_view;
+ struct lttng_buffer_view value_name_view = {};
+
+ value_view = lttng_buffer_view_from_view(
+ buffer_view, offset, sizeof(*value_comm));
+ if (!value_view.data) {
+ goto error;
+ }
- ids->count = count;
+ offset += value_view.size;
+ value_comm = (typeof(value_comm)) value_view.data;
+ type = (typeof(type)) value_comm->type;
- return ids;
-error:
- free(ids);
- return NULL;
-}
+ if (is_value_type_name(type)) {
+ value_name_view = lttng_buffer_view_from_view(
+ buffer_view, offset,
+ value_comm->value.name_len);
+ offset += value_name_view.size;
+ }
+ ret_code = process_attr_value_from_comm(domain, process_attr,
+ type, &value_comm->value.integral,
+ &value_name_view, &value);
+ if (ret_code != LTTNG_OK) {
+ goto error;
+ }
-LTTNG_HIDDEN
-struct lttng_tracker_id *lttng_tracker_ids_get_pointer_of_index(
- const struct lttng_tracker_ids *ids, unsigned int index)
-{
- assert(ids);
- if (index >= ids->count) {
- return NULL;
+ ret = lttng_dynamic_pointer_array_add_pointer(
+ &values->array, value);
+ if (ret) {
+ process_attr_value_destroy(value);
+ goto error;
+ }
}
- return &ids->id_array[index];
+ *_values = values;
+ return offset;
+error:
+ lttng_process_attr_values_destroy(values);
+ return -1;
}
-const struct lttng_tracker_id *lttng_tracker_ids_get_at_index(
- const struct lttng_tracker_ids *ids, unsigned int index)
+LTTNG_HIDDEN
+void lttng_process_attr_values_destroy(struct lttng_process_attr_values *values)
{
- assert(ids);
- return lttng_tracker_ids_get_pointer_of_index(ids, index);
+ if (!values) {
+ return;
+ }
+ lttng_dynamic_pointer_array_reset(&values->array);
+ free(values);
}
-enum lttng_tracker_id_status lttng_tracker_ids_get_count(const struct lttng_tracker_ids *ids, unsigned int *count)
+LTTNG_HIDDEN
+struct process_attr_value *process_attr_value_copy(
+ const struct process_attr_value *value)
{
+ struct process_attr_value *new_value = NULL;
- enum lttng_tracker_id_status status = LTTNG_TRACKER_ID_STATUS_OK;
-
- if (!ids || !count) {
- status = LTTNG_TRACKER_ID_STATUS_INVALID;
+ if (!value) {
goto end;
}
- *count = ids->count;
+ new_value = zmalloc(sizeof(*new_value));
+ if (!new_value) {
+ goto end;
+ }
+ if (is_value_type_name(value->type)) {
+ const char *src =
+ value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME ?
+ value->value.user_name :
+ value->value.group_name;
+ char **dst = value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME ?
+ &new_value->value.user_name :
+ &new_value->value.group_name;
+
+ new_value->type = value->type;
+ *dst = strdup(src);
+ if (!*dst) {
+ goto error;
+ }
+ } else {
+ *new_value = *value;
+ }
end:
- return status;
+ return new_value;
+error:
+ free(new_value);
+ return NULL;
}
-void lttng_tracker_ids_destroy(struct lttng_tracker_ids *ids)
+LTTNG_HIDDEN
+unsigned long process_attr_value_hash(const struct process_attr_value *a)
{
- int i;
+ unsigned long hash = hash_key_ulong((void *) a->type, lttng_ht_seed);
- if (!ids) {
- return;
+ switch (a->type) {
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_PID:
+ hash ^= hash_key_ulong((void *) (unsigned long) a->value.pid,
+ lttng_ht_seed);
+ break;
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_UID:
+ hash ^= hash_key_ulong((void *) (unsigned long) a->value.uid,
+ lttng_ht_seed);
+ break;
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_GID:
+ hash ^= hash_key_ulong((void *) (unsigned long) a->value.gid,
+ lttng_ht_seed);
+ break;
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME:
+ hash ^= hash_key_str(a->value.user_name, lttng_ht_seed);
+ break;
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME:
+ hash ^= hash_key_str(a->value.group_name, lttng_ht_seed);
+ break;
+ default:
+ abort();
}
- for (i = 0; i < ids->count; i++) {
- lttng_tracker_id_reset(&ids->id_array[i]);
- }
- free(ids->id_array);
- free(ids);
+ return hash;
}
-int lttng_tracker_ids_serialize(const struct lttng_tracker_ids *ids,
- struct lttng_dynamic_buffer *buffer)
+LTTNG_HIDDEN
+bool process_attr_tracker_value_equal(const struct process_attr_value *a,
+ const struct process_attr_value *b)
{
- int ret = 0;
- int value;
- const char *string = NULL;
- unsigned int count;
- enum lttng_tracker_id_status status;
- const struct lttng_tracker_id *id;
- unsigned int i;
-
- status = lttng_tracker_ids_get_count(ids, &count);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ret = LTTNG_ERR_INVALID;
- goto error;
+ if (a->type != b->type) {
+ return false;
}
+ switch (a->type) {
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_PID:
+ return a->value.pid == b->value.pid;
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_UID:
+ return a->value.uid == b->value.uid;
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_GID:
+ return a->value.gid == b->value.gid;
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME:
+ return !strcmp(a->value.user_name, b->value.user_name);
+ case LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME:
+ return !strcmp(a->value.group_name, b->value.group_name);
+ default:
+ abort();
+ }
+}
- for (i = 0; i < count; i++) {
- struct lttcomm_tracker_id_header id_hdr;
- size_t var_data_len = 0;
-
- id = lttng_tracker_ids_get_at_index(ids, i);
- if (!id) {
- ret = -LTTNG_ERR_INVALID;
- goto error;
- }
-
- memset(&id_hdr, 0, sizeof(id_hdr));
- id_hdr.type = lttng_tracker_id_get_type(id);
- switch (id_hdr.type) {
- case LTTNG_ID_ALL:
- break;
- case LTTNG_ID_VALUE:
- status = lttng_tracker_id_get_value(id, &value);
- id_hdr.u.value = value;
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ret = -LTTNG_ERR_INVALID;
- goto error;
- }
- break;
- case LTTNG_ID_STRING:
- status = lttng_tracker_id_get_string(
- id, &string);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ret = -LTTNG_ERR_INVALID;
- goto error;
- }
-
- id_hdr.u.var_data_len = var_data_len =
- strlen(string) + 1;
- break;
- default:
- ret = -LTTNG_ERR_INVALID;
- goto error;
- }
- ret = lttng_dynamic_buffer_append(
- buffer, &id_hdr, sizeof(id_hdr));
- if (ret) {
- ret = -LTTNG_ERR_NOMEM;
- goto error;
- }
- ret = lttng_dynamic_buffer_append(
- buffer, string, var_data_len);
- if (ret) {
- ret = -LTTNG_ERR_NOMEM;
- goto error;
- }
+LTTNG_HIDDEN
+void process_attr_value_destroy(struct process_attr_value *value)
+{
+ if (!value) {
+ return;
}
-error:
- return ret;
+ if (is_value_type_name(value->type)) {
+ free(value->type == LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME ?
+ value->value.user_name :
+ value->value.group_name);
+ }
+ free(value);
}
--- /dev/null
+/*
+ * Copyright (C) 2019 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
+ * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#ifndef LTTNG_COMMON_TRACKER_H
+#define LTTNG_COMMON_TRACKER_H
+
+#include <lttng/lttng-error.h>
+#include <lttng/tracker.h>
+
+#include <common/buffer-view.h>
+#include <common/dynamic-array.h>
+#include <common/macros.h>
+#include <common/sessiond-comm/sessiond-comm.h>
+
+struct process_attr_value {
+ enum lttng_process_attr_value_type type;
+ union value {
+ pid_t pid;
+ uid_t uid;
+ char *user_name;
+ gid_t gid;
+ char *group_name;
+ } value;
+};
+
+struct lttng_process_attr_values {
+ /* Array of struct process_attr_tracker_value. */
+ struct lttng_dynamic_pointer_array array;
+};
+
+LTTNG_HIDDEN
+const char *lttng_process_attr_to_string(enum lttng_process_attr process_attr);
+
+LTTNG_HIDDEN
+struct lttng_process_attr_values *lttng_process_attr_values_create(void);
+
+/* Prefixed with '_' since the name conflicts with a public API. */
+LTTNG_HIDDEN
+unsigned int _lttng_process_attr_values_get_count(
+ const struct lttng_process_attr_values *values);
+
+LTTNG_HIDDEN
+const struct process_attr_value *lttng_process_attr_tracker_values_get_at_index(
+ const struct lttng_process_attr_values *values,
+ unsigned int index);
+
+LTTNG_HIDDEN
+int lttng_process_attr_values_serialize(
+ const struct lttng_process_attr_values *values,
+ struct lttng_dynamic_buffer *buffer);
+
+LTTNG_HIDDEN
+ssize_t lttng_process_attr_values_create_from_buffer(
+ enum lttng_domain_type domain,
+ enum lttng_process_attr process_attr,
+ const struct lttng_buffer_view *buffer_view,
+ struct lttng_process_attr_values **_values);
+
+LTTNG_HIDDEN
+void lttng_process_attr_values_destroy(
+ struct lttng_process_attr_values *values);
+
+LTTNG_HIDDEN
+struct process_attr_value *process_attr_value_copy(
+ const struct process_attr_value *value);
+
+LTTNG_HIDDEN
+unsigned long process_attr_value_hash(const struct process_attr_value *a);
+
+LTTNG_HIDDEN
+bool process_attr_tracker_value_equal(const struct process_attr_value *a,
+ const struct process_attr_value *b);
+
+LTTNG_HIDDEN
+void process_attr_value_destroy(struct process_attr_value *value);
+
+LTTNG_HIDDEN
+enum lttng_error_code process_attr_value_from_comm(
+ enum lttng_domain_type domain,
+ enum lttng_process_attr process_attr,
+ enum lttng_process_attr_value_type value_type,
+ const struct process_attr_integral_value_comm *integral_value,
+ const struct lttng_buffer_view *value_view,
+ struct process_attr_value **value);
+
+#endif /* LTTNG_COMMON_TRACKER_H */
*
*/
+#include "common/macros.h"
#define _LGPL_SOURCE
#include <assert.h>
#include <ctype.h>
#error MAX_NAME_LEN_SCANF_IS_A_BROKEN_API must be updated to match (PROC_MEMINFO_FIELD_MAX_NAME_LEN - 1)
#endif
+#define FALLBACK_USER_BUFLEN 16384
+#define FALLBACK_GROUP_BUFLEN 16384
+
/*
* Return a partial realpath(3) of the path even if the full path does not
* exist. For instance, with /tmp/test1/test2/test3, if test2/ does not exist
end:
return ret;
}
+
+LTTNG_HIDDEN
+enum lttng_error_code utils_user_id_from_name(const char *user_name, uid_t *uid)
+{
+ struct passwd p, *pres;
+ int ret;
+ enum lttng_error_code ret_val = LTTNG_OK;
+ char *buf = NULL;
+ ssize_t buflen;
+
+ buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (buflen < 0) {
+ buflen = FALLBACK_USER_BUFLEN;
+ }
+
+ buf = zmalloc(buflen);
+ if (!buf) {
+ ret_val = LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ for (;;) {
+ ret = getpwnam_r(user_name, &p, buf, buflen, &pres);
+ switch (ret) {
+ case EINTR:
+ continue;
+ case ERANGE:
+ buflen *= 2;
+ free(buf);
+ buf = zmalloc(buflen);
+ if (!buf) {
+ ret_val = LTTNG_ERR_NOMEM;
+ goto end;
+ }
+ continue;
+ default:
+ goto end_loop;
+ }
+ }
+end_loop:
+
+ switch (ret) {
+ case 0:
+ if (pres == NULL) {
+ ret_val = LTTNG_ERR_USER_NOT_FOUND;
+ } else {
+ *uid = p.pw_uid;
+ DBG("Lookup of tracker UID/VUID: name '%s' maps to uid %" PRId64,
+ user_name, (int64_t) *uid);
+ ret_val = LTTNG_OK;
+ }
+ break;
+ case ENOENT:
+ case ESRCH:
+ case EBADF:
+ case EPERM:
+ ret_val = LTTNG_ERR_USER_NOT_FOUND;
+ break;
+ default:
+ ret_val = LTTNG_ERR_NOMEM;
+ }
+end:
+ free(buf);
+ return ret_val;
+}
+
+LTTNG_HIDDEN
+enum lttng_error_code utils_group_id_from_name(
+ const char *group_name, gid_t *gid)
+{
+ struct group g, *gres;
+ int ret;
+ enum lttng_error_code ret_val = LTTNG_OK;
+ char *buf = NULL;
+ ssize_t buflen;
+
+ buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
+ if (buflen < 0) {
+ buflen = FALLBACK_GROUP_BUFLEN;
+ }
+
+ buf = zmalloc(buflen);
+ if (!buf) {
+ ret_val = LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ for (;;) {
+ ret = getgrnam_r(group_name, &g, buf, buflen, &gres);
+ switch (ret) {
+ case EINTR:
+ continue;
+ case ERANGE:
+ buflen *= 2;
+ free(buf);
+ buf = zmalloc(buflen);
+ if (!buf) {
+ ret_val = LTTNG_ERR_NOMEM;
+ goto end;
+ }
+ continue;
+ default:
+ goto end_loop;
+ }
+ }
+end_loop:
+
+ switch (ret) {
+ case 0:
+ if (gres == NULL) {
+ ret_val = LTTNG_ERR_GROUP_NOT_FOUND;
+ } else {
+ *gid = g.gr_gid;
+ DBG("Lookup of tracker GID/GUID: name '%s' maps to gid %" PRId64,
+ group_name, (int64_t) *gid);
+ ret_val = LTTNG_OK;
+ }
+ break;
+ case ENOENT:
+ case ESRCH:
+ case EBADF:
+ case EPERM:
+ ret_val = LTTNG_ERR_GROUP_NOT_FOUND;
+ break;
+ default:
+ ret_val = LTTNG_ERR_NOMEM;
+ }
+end:
+ free(buf);
+ return ret_val;
+}
#ifndef _COMMON_UTILS_H
#define _COMMON_UTILS_H
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdint.h>
#include <getopt.h>
+#include <lttng/lttng-error.h>
#include <stdbool.h>
+#include <stdint.h>
#include <sys/types.h>
+#include <unistd.h>
#include <common/compat/directory-handle.h>
int utils_get_memory_available(size_t *value);
int utils_get_memory_total(size_t *value);
int utils_change_working_directory(const char *path);
+enum lttng_error_code utils_user_id_from_name(
+ const char *user_name, uid_t *user_id);
+enum lttng_error_code utils_group_id_from_name(
+ const char *group_name, gid_t *group_id);
#endif /* _COMMON_UTILS_H */
liblttng_ctl_la_SOURCES = lttng-ctl.c snapshot.c lttng-ctl-helper.h \
lttng-ctl-health.c save.c load.c deprecated-symbols.c \
- channel.c rotate.c event.c destruction-handle.c clear.c
+ channel.c rotate.c event.c destruction-handle.c clear.c \
+ tracker.c
liblttng_ctl_la_LDFLAGS = \
$(LT_NO_UNDEFINED)
size_t default_metadata_subbuf_size;
size_t default_ust_pid_channel_subbuf_size;
size_t default_ust_uid_channel_subbuf_size;
+
+const char * const config_element_pid_tracker;
+const char * const config_element_target_pid;
+const char * const config_element_targets;
+const char * const config_element_trackers;
/*
* Calls lttng_ctl_ask_sessiond_fds_varlen() with no expected command header.
*/
-static inline
-int lttng_ctl_ask_sessiond_varlen_no_cmd_header(struct lttcomm_session_msg *lsm,
- void *vardata, size_t vardata_len, void **user_payload_buf)
+static inline int lttng_ctl_ask_sessiond_varlen_no_cmd_header(
+ struct lttcomm_session_msg *lsm,
+ const void *vardata,
+ size_t vardata_len,
+ void **user_payload_buf)
{
return lttng_ctl_ask_sessiond_fds_varlen(lsm, NULL, 0, vardata,
vardata_len, user_payload_buf, NULL, NULL);
#include <common/common.h>
#include <common/compat/string.h>
#include <common/defaults.h>
+#include <common/dynamic-buffer.h>
#include <common/sessiond-comm/sessiond-comm.h>
+#include <common/tracker.h>
#include <common/uri.h>
#include <common/utils.h>
-#include <common/dynamic-buffer.h>
-#include <lttng/lttng.h>
-#include <lttng/health-internal.h>
-#include <lttng/trigger/trigger-internal.h>
-#include <lttng/endpoint.h>
#include <lttng/channel-internal.h>
+#include <lttng/destruction-handle.h>
+#include <lttng/endpoint.h>
#include <lttng/event-internal.h>
-#include <lttng/userspace-probe-internal.h>
-#include <lttng/session-internal.h>
+#include <lttng/health-internal.h>
+#include <lttng/lttng.h>
#include <lttng/session-descriptor-internal.h>
-#include <lttng/destruction-handle.h>
-#include <lttng/tracker-internal.h>
+#include <lttng/session-internal.h>
+#include <lttng/trigger/trigger-internal.h>
+#include <lttng/userspace-probe-internal.h>
#include "filter/filter-ast.h"
#include "filter/filter-parser.h"
return ret;
}
-/*
- * List IDs in the tracker.
- *
- * tracker_type is the type of tracker.
- * ids is set to an allocated array of IDs currently tracked. On
- * success, ids and contained ids must be freed/destroy by the caller.
- * nr_ids is set to the number of entries contained by the ids array.
- *
- * Returns 0 on success, else a negative LTTng error code.
- */
-int lttng_list_tracker_ids(struct lttng_handle *handle,
- enum lttng_tracker_type tracker_type,
- struct lttng_tracker_ids **_ids)
-{
- int ret, i;
- struct lttcomm_session_msg lsm;
- struct lttcomm_tracker_command_header *cmd_header = NULL;
- char *cmd_payload = NULL, *p;
- size_t cmd_header_len;
- size_t nr_ids = 0;
- struct lttng_tracker_ids *ids = NULL;
-
- if (handle == NULL) {
- return -LTTNG_ERR_INVALID;
- }
-
- memset(&lsm, 0, sizeof(lsm));
- lsm.cmd_type = LTTNG_LIST_TRACKER_IDS;
- lsm.u.id_tracker_list.tracker_type = tracker_type;
- lttng_ctl_copy_string(lsm.session.name, handle->session_name,
- sizeof(lsm.session.name));
- COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
-
- ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm, NULL, 0, NULL, 0,
- (void **) &cmd_payload, (void **) &cmd_header,
- &cmd_header_len);
- if (ret < 0) {
- goto error;
- }
-
- /* Set number of tracker_id and free command header */
- nr_ids = cmd_header->nb_tracker_id;
- if (nr_ids > INT_MAX) {
- ret = -LTTNG_ERR_OVERFLOW;
- goto error;
- }
- free(cmd_header);
- cmd_header = NULL;
-
- ids = lttng_tracker_ids_create(nr_ids);
- if (!ids) {
- ret = -LTTNG_ERR_NOMEM;
- goto error;
- }
-
- p = cmd_payload;
- for (i = 0; i < nr_ids; i++) {
- struct lttcomm_tracker_id_header *tracker_id;
- struct lttng_tracker_id *id;
- enum lttng_tracker_id_status status;
-
- tracker_id = (struct lttcomm_tracker_id_header *) p;
- p += sizeof(struct lttcomm_tracker_id_header);
- id = lttng_tracker_ids_get_pointer_of_index(ids, i);
- if (!id) {
- ret = -LTTNG_ERR_INVALID;
- goto error;
- }
-
- switch (tracker_id->type) {
- case LTTNG_ID_ALL:
- status = lttng_tracker_id_set_all(id);
- break;
- case LTTNG_ID_VALUE:
- id->value = tracker_id->u.value;
- status = lttng_tracker_id_set_value(
- id, tracker_id->u.value);
- break;
- case LTTNG_ID_STRING:
- status = lttng_tracker_id_set_string(id, p);
- p += tracker_id->u.var_data_len;
- break;
- default:
- goto error;
- }
-
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ret = -LTTNG_ERR_INVALID;
- goto error;
- }
- }
- free(cmd_payload);
- *_ids = ids;
- return 0;
-
-error:
- lttng_tracker_ids_destroy(ids);
- free(cmd_payload);
- free(cmd_header);
- 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)
-{
- struct lttng_tracker_ids *ids = NULL;
- unsigned int nr_ids = 0;
- int *pids = NULL;
- int ret = 0, i;
- enum lttng_tracker_id_status status;
- const struct lttng_tracker_id *id;
-
- ret = lttng_list_tracker_ids(handle, LTTNG_TRACKER_PID, &ids);
- if (ret < 0) {
- return ret;
- }
-
- status = lttng_tracker_ids_get_count(ids, &nr_ids);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ret = -LTTNG_ERR_INVALID;
- goto end;
- }
-
- if (nr_ids == 1) {
- id = lttng_tracker_ids_get_at_index(ids, 0);
- if (id && lttng_tracker_id_get_type(id) == LTTNG_ID_ALL) {
- *_enabled = 0;
- goto end;
- }
- }
-
- *_enabled = 1;
-
- pids = zmalloc(nr_ids * sizeof(*pids));
- if (!pids) {
- ret = -LTTNG_ERR_NOMEM;
- goto end;
- }
- for (i = 0; i < nr_ids; i++) {
- id = lttng_tracker_ids_get_at_index(ids, i);
- status = lttng_tracker_id_get_value(id, &pids[i]);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- ret = -LTTNG_ERR_UNK;
- goto end;
- }
- }
- *_pids = pids;
- *_nr_pids = nr_ids;
-end:
- lttng_tracker_ids_destroy(ids);
- if (ret < 0) {
- free(pids);
- }
- return ret;
-}
-
/*
* Regenerate the metadata for a session.
* Return 0 on success, a negative error code on error.
return ret;
}
-static int lttng_track_untrack_id(struct lttng_handle *handle,
- enum lttng_tracker_type tracker_type,
- const struct lttng_tracker_id *id,
- enum lttcomm_sessiond_command cmd)
-{
- int ret;
- struct lttcomm_session_msg lsm;
- const char *var_data = NULL;
- size_t var_data_len = 0;
- int value;
- enum lttng_tracker_id_status status;
-
- /* NULL arguments are forbidden. No default values. */
- if (handle == NULL) {
- goto error;
- }
-
- memset(&lsm, 0, sizeof(lsm));
-
- lsm.cmd_type = cmd;
- lsm.u.id_tracker.tracker_type = tracker_type;
- lsm.u.id_tracker.id_type = lttng_tracker_id_get_type(id);
- switch (lsm.u.id_tracker.id_type) {
- case LTTNG_ID_ALL:
- break;
- case LTTNG_ID_VALUE:
- status = lttng_tracker_id_get_value(id, &value);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- goto error;
- }
- lsm.u.id_tracker.u.value = value;
- break;
- case LTTNG_ID_STRING:
- status = lttng_tracker_id_get_string(id, &var_data);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- goto error;
- }
- var_data_len = strlen(var_data) + 1; /* Includes \0. */
- lsm.u.id_tracker.u.var_len = var_data_len;
- break;
- default:
- goto error;
- }
-
- COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
-
- lttng_ctl_copy_string(lsm.session.name, handle->session_name,
- sizeof(lsm.session.name));
-
- ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(
- &lsm, (char *) var_data, var_data_len, NULL);
- return ret;
-error:
- return -LTTNG_ERR_INVALID;
-}
-
-/*
- * Add ID to session tracker.
- * Return 0 on success else a negative LTTng error code.
- */
-int lttng_track_id(struct lttng_handle *handle,
- enum lttng_tracker_type tracker_type,
- const struct lttng_tracker_id *id)
-{
- return lttng_track_untrack_id(handle, tracker_type, id, LTTNG_TRACK_ID);
-}
-
-/*
- * Remove ID from session tracker.
- * Return 0 on success else a negative LTTng error code.
- */
-int lttng_untrack_id(struct lttng_handle *handle,
- enum lttng_tracker_type tracker_type,
- const struct lttng_tracker_id *id)
-{
- return lttng_track_untrack_id(
- handle, tracker_type, id, LTTNG_UNTRACK_ID);
-}
-
-/*
- * 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)
-{
- int ret;
- struct lttng_tracker_id *id = NULL;
- enum lttng_tracker_id_status status;
-
- id = lttng_tracker_id_create();
- status = lttng_tracker_id_set_value(id, pid);
- if (status == LTTNG_TRACKER_ID_STATUS_INVALID) {
- ret = -LTTNG_ERR_INVALID;
- goto error;
- }
-
- ret = lttng_track_id(handle, LTTNG_TRACKER_PID, id);
-error:
- lttng_tracker_id_destroy(id);
- return ret;
-}
-
-/*
- * 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)
-{
- int ret;
- struct lttng_tracker_id *id = NULL;
- enum lttng_tracker_id_status status;
-
- id = lttng_tracker_id_create();
- status = lttng_tracker_id_set_value(id, pid);
- if (status == LTTNG_TRACKER_ID_STATUS_INVALID) {
- ret = -LTTNG_ERR_INVALID;
- goto error;
- }
-
- ret = lttng_untrack_id(handle, LTTNG_TRACKER_PID, id);
-error:
- lttng_tracker_id_destroy(id);
- return ret;
-}
-
/*
* lib constructor.
*/
--- /dev/null
+/*
+ * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#include "lttng-ctl-helper.h"
+#include "lttng/domain.h"
+#include "lttng/lttng-error.h"
+#include <common/sessiond-comm/sessiond-comm.h>
+#include <common/tracker.h>
+#include <lttng/tracker.h>
+
+struct lttng_process_attr_tracker_handle {
+ char *session_name;
+ enum lttng_domain_type domain;
+ enum lttng_process_attr process_attr;
+ struct lttng_process_attr_values *inclusion_set;
+};
+
+void lttng_process_attr_tracker_handle_destroy(
+ struct lttng_process_attr_tracker_handle *tracker)
+{
+ if (!tracker) {
+ return;
+ }
+
+ lttng_process_attr_values_destroy(tracker->inclusion_set);
+ free(tracker->session_name);
+ free(tracker);
+}
+
+enum lttng_error_code lttng_session_get_tracker_handle(const char *session_name,
+ enum lttng_domain_type domain,
+ enum lttng_process_attr process_attr,
+ struct lttng_process_attr_tracker_handle **out_tracker_handle)
+{
+ enum lttng_error_code ret_code = LTTNG_OK;
+ struct lttng_process_attr_tracker_handle *handle = NULL;
+ enum lttng_process_attr_tracker_handle_status status;
+ enum lttng_tracking_policy policy;
+
+ if (!session_name || !out_tracker_handle) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto error;
+ }
+
+ if (domain != LTTNG_DOMAIN_KERNEL && domain != LTTNG_DOMAIN_UST) {
+ ret_code = LTTNG_ERR_UNSUPPORTED_DOMAIN;
+ goto error;
+ }
+
+ handle = zmalloc(sizeof(*handle));
+ if (!handle) {
+ ret_code = LTTNG_ERR_NOMEM;
+ goto error;
+ }
+
+ handle->session_name = strdup(session_name);
+ if (!handle->session_name) {
+ ret_code = LTTNG_ERR_NOMEM;
+ goto error;
+ }
+
+ handle->domain = domain;
+ handle->process_attr = process_attr;
+
+ /*
+ * Use the `get_tracking_policy` command to validate the tracker's
+ * existance.
+ */
+ status = lttng_process_attr_tracker_handle_get_tracking_policy(
+ handle, &policy);
+ switch (status) {
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK:
+ break;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST:
+ ret_code = LTTNG_ERR_SESSION_NOT_EXIST;
+ goto error;
+ default:
+ ret_code = LTTNG_ERR_UNK;
+ goto error;
+ }
+
+ *out_tracker_handle = handle;
+ return ret_code;
+error:
+ lttng_process_attr_tracker_handle_destroy(handle);
+ return ret_code;
+}
+
+enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_tracker_handle_get_tracking_policy(
+ const struct lttng_process_attr_tracker_handle *tracker,
+ enum lttng_tracking_policy *policy)
+{
+ void *reply = NULL;
+ int reply_ret;
+ enum lttng_process_attr_tracker_handle_status status =
+ LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK;
+ struct lttcomm_session_msg lsm = {
+ .cmd_type = LTTNG_PROCESS_ATTR_TRACKER_GET_POLICY,
+ };
+
+ if (!tracker || !policy) {
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID;
+ goto end;
+ }
+
+ lttng_ctl_copy_string(lsm.session.name, tracker->session_name,
+ sizeof(lsm.session.name));
+ lsm.domain.type = tracker->domain;
+ lsm.u.process_attr_tracker_get_tracking_policy.process_attr =
+ (int32_t) tracker->process_attr;
+
+ /* Command returns a session descriptor on success. */
+ reply_ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(
+ &lsm, NULL, 0, &reply);
+ if (reply_ret != sizeof(uint32_t)) {
+ if (reply_ret == -LTTNG_ERR_SESSION_NOT_EXIST ||
+ reply_ret == -LTTNG_ERR_SESS_NOT_FOUND) {
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST;
+ } else {
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR;
+ }
+ goto end;
+ }
+
+ *policy = (enum lttng_tracking_policy)(*((const uint32_t *) reply));
+end:
+ free(reply);
+ return status;
+}
+
+enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_tracker_handle_set_tracking_policy(
+ const struct lttng_process_attr_tracker_handle *tracker,
+ enum lttng_tracking_policy policy)
+{
+ int reply_ret;
+ enum lttng_process_attr_tracker_handle_status status =
+ LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK;
+ struct lttcomm_session_msg lsm = {
+ .cmd_type = LTTNG_PROCESS_ATTR_TRACKER_SET_POLICY,
+ };
+
+ if (!tracker) {
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID;
+ goto end;
+ }
+
+ lttng_ctl_copy_string(lsm.session.name, tracker->session_name,
+ sizeof(lsm.session.name));
+ lsm.domain.type = tracker->domain;
+ lsm.u.process_attr_tracker_set_tracking_policy.process_attr =
+ (int32_t) tracker->process_attr;
+ lsm.u.process_attr_tracker_set_tracking_policy.tracking_policy =
+ (int32_t) policy;
+
+ /* Command returns a session descriptor on success. */
+ reply_ret = lttng_ctl_ask_sessiond(&lsm, NULL);
+ if (reply_ret < 0) {
+ if (reply_ret == -LTTNG_ERR_SESSION_NOT_EXIST) {
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST;
+ } else {
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR;
+ }
+ goto end;
+ }
+end:
+ return status;
+}
+
+#define DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(command_upper, \
+ command_lower, process_attr_name, value_type_name, \
+ value_type_c, value_type_enum) \
+ enum lttng_process_attr_tracker_handle_status \
+ lttng_process_attr_##process_attr_name##_tracker_handle_##command_lower##_##value_type_name( \
+ const struct lttng_process_attr_tracker_handle \
+ *tracker, \
+ value_type_c value) \
+ { \
+ int ret; \
+ enum lttng_process_attr_tracker_handle_status status = \
+ LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK; \
+ struct lttcomm_session_msg lsm = { \
+ .cmd_type = LTTNG_PROCESS_ATTR_TRACKER_##command_upper##_INCLUDE_VALUE}; \
+ \
+ if (!tracker) { \
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID; \
+ goto end; \
+ } \
+ \
+ lttng_ctl_copy_string(lsm.session.name, tracker->session_name, \
+ sizeof(lsm.session.name)); \
+ lsm.domain.type = tracker->domain; \
+ lsm.u.process_attr_tracker_add_remove_include_value \
+ .process_attr = \
+ (int32_t) tracker->process_attr; \
+ lsm.u.process_attr_tracker_add_remove_include_value \
+ .value_type = (uint32_t) \
+ LTTNG_PROCESS_ATTR_VALUE_TYPE_##value_type_enum; \
+ \
+ if (is_signed(value_type_c)) { \
+ lsm.u.process_attr_tracker_add_remove_include_value \
+ .integral_value.u._signed = value; \
+ } else { \
+ lsm.u.process_attr_tracker_add_remove_include_value \
+ .integral_value.u._unsigned = value; \
+ } \
+ \
+ ret = lttng_ctl_ask_sessiond(&lsm, NULL); \
+ if (ret < 0) { \
+ switch (-ret) { \
+ case LTTNG_ERR_PROCESS_ATTR_EXISTS: \
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_EXISTS; \
+ break; \
+ case LTTNG_ERR_PROCESS_ATTR_MISSING: \
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_MISSING; \
+ break; \
+ case LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY: \
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY; \
+ break; \
+ default: \
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR; \
+ } \
+ } \
+ end: \
+ return status; \
+ }
+
+#define DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(command_upper, \
+ command_lower, process_attr_name, value_type_name, \
+ value_type_enum) \
+ enum lttng_process_attr_tracker_handle_status \
+ lttng_process_attr_##process_attr_name##_tracker_handle_##command_lower##_##value_type_name( \
+ const struct lttng_process_attr_tracker_handle \
+ *tracker, \
+ const char *value) \
+ { \
+ int ret; \
+ enum lttng_process_attr_tracker_handle_status status = \
+ LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK; \
+ struct lttcomm_session_msg lsm = { \
+ .cmd_type = LTTNG_PROCESS_ATTR_TRACKER_##command_upper##_INCLUDE_VALUE}; \
+ const size_t len = value ? strlen(value) + 1 : 0; \
+ \
+ if (!tracker || !value) { \
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID; \
+ goto end; \
+ } \
+ \
+ lttng_ctl_copy_string(lsm.session.name, tracker->session_name, \
+ sizeof(lsm.session.name)); \
+ lsm.domain.type = tracker->domain; \
+ lsm.u.process_attr_tracker_add_remove_include_value \
+ .process_attr = \
+ (int32_t) tracker->process_attr; \
+ lsm.u.process_attr_tracker_add_remove_include_value.name_len = \
+ (uint32_t) len; \
+ lsm.u.process_attr_tracker_add_remove_include_value \
+ .value_type = (uint32_t) \
+ LTTNG_PROCESS_ATTR_VALUE_TYPE_##value_type_enum; \
+ \
+ ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header( \
+ &lsm, value, len, NULL); \
+ if (ret < 0) { \
+ switch (-ret) { \
+ case LTTNG_ERR_PROCESS_ATTR_EXISTS: \
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_EXISTS; \
+ break; \
+ case LTTNG_ERR_PROCESS_ATTR_MISSING: \
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_MISSING; \
+ break; \
+ case LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY: \
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY; \
+ break; \
+ case LTTNG_ERR_USER_NOT_FOUND: \
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_USER_NOT_FOUND; \
+ break; \
+ case LTTNG_ERR_GROUP_NOT_FOUND: \
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_GROUP_NOT_FOUND; \
+ break; \
+ default: \
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR; \
+ } \
+ } \
+ end: \
+ return status; \
+ }
+
+/* PID */
+DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
+ ADD, add, process_id, pid, pid_t, PID);
+DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
+ REMOVE, remove, process_id, pid, pid_t, PID);
+
+/* VPID */
+DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
+ ADD, add, virtual_process_id, pid, pid_t, PID);
+DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
+ REMOVE, remove, virtual_process_id, pid, pid_t, PID);
+
+/* UID */
+DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
+ ADD, add, user_id, uid, uid_t, UID);
+DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
+ REMOVE, remove, user_id, uid, uid_t, UID);
+DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(
+ ADD, add, user_id, user_name, USER_NAME);
+DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(
+ REMOVE, remove, user_id, user_name, USER_NAME);
+
+/* VUID */
+DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
+ ADD, add, virtual_user_id, uid, uid_t, UID);
+DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
+ REMOVE, remove, virtual_user_id, uid, uid_t, UID);
+DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(
+ ADD, add, virtual_user_id, user_name, USER_NAME);
+DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(
+ REMOVE, remove, virtual_user_id, user_name, USER_NAME);
+
+/* GID */
+DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
+ ADD, add, group_id, gid, gid_t, GID);
+DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
+ REMOVE, remove, group_id, gid, gid_t, GID);
+DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(
+ ADD, add, group_id, group_name, GROUP_NAME);
+DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(
+ REMOVE, remove, group_id, group_name, GROUP_NAME);
+
+/* VGID */
+DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
+ ADD, add, virtual_group_id, gid, gid_t, GID);
+DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
+ REMOVE, remove, virtual_group_id, gid, gid_t, GID);
+DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(
+ ADD, add, virtual_group_id, group_name, GROUP_NAME);
+DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(
+ REMOVE, remove, virtual_group_id, group_name, GROUP_NAME);
+
+enum lttng_process_attr_tracker_handle_status
+lttng_process_attr_tracker_handle_get_inclusion_set(
+ struct lttng_process_attr_tracker_handle *tracker,
+ const struct lttng_process_attr_values **values)
+{
+ void *reply = NULL;
+ int reply_ret;
+ enum lttng_process_attr_tracker_handle_status status =
+ LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK;
+ struct lttcomm_session_msg lsm = {
+ .cmd_type = LTTNG_PROCESS_ATTR_TRACKER_GET_INCLUSION_SET,
+ };
+ struct lttng_buffer_view inclusion_set_view;
+ ssize_t inclusion_set_ret;
+
+ if (!tracker || !values) {
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID;
+ goto end;
+ }
+
+ lttng_process_attr_values_destroy(tracker->inclusion_set);
+ tracker->inclusion_set = NULL;
+
+ lttng_ctl_copy_string(lsm.session.name, tracker->session_name,
+ sizeof(lsm.session.name));
+ lsm.domain.type = tracker->domain;
+ lsm.u.process_attr_tracker_get_tracking_policy.process_attr =
+ (int32_t) tracker->process_attr;
+
+ /* Command returns a session descriptor on success. */
+ reply_ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(
+ &lsm, NULL, 0, &reply);
+ if (reply_ret < 0) {
+ if (reply_ret == -LTTNG_ERR_SESSION_NOT_EXIST) {
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST;
+ } else if (reply_ret ==
+ -LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY) {
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY;
+ } else {
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR;
+ }
+ goto end;
+ } else if (reply_ret == 0) {
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR;
+ goto end;
+ }
+
+ inclusion_set_view = lttng_buffer_view_init(reply, 0, reply_ret);
+ if (!inclusion_set_view.data) {
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR;
+ goto end;
+ }
+
+ inclusion_set_ret = lttng_process_attr_values_create_from_buffer(
+ tracker->domain, tracker->process_attr,
+ &inclusion_set_view, &tracker->inclusion_set);
+ if (inclusion_set_ret < 0) {
+ status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR;
+ goto end;
+ }
+ *values = tracker->inclusion_set;
+end:
+ free(reply);
+ return status;
+}
+
+enum lttng_process_attr_values_status lttng_process_attr_values_get_count(
+ const struct lttng_process_attr_values *values,
+ unsigned int *count)
+{
+ enum lttng_process_attr_values_status status =
+ LTTNG_PROCESS_ATTR_VALUES_STATUS_OK;
+
+ if (!values || !count) {
+ status = LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID;
+ goto end;
+ }
+
+ *count = _lttng_process_attr_values_get_count(values);
+end:
+ return status;
+}
+
+enum lttng_process_attr_value_type lttng_process_attr_values_get_type_at_index(
+ const struct lttng_process_attr_values *values,
+ unsigned int index)
+{
+ enum lttng_process_attr_value_type type;
+ const struct process_attr_value *value;
+
+ if (!values) {
+ type = LTTNG_PROCESS_ATTR_VALUE_TYPE_INVALID;
+ goto end;
+ }
+
+ if (_lttng_process_attr_values_get_count(values) <= index) {
+ type = LTTNG_PROCESS_ATTR_VALUE_TYPE_INVALID;
+ goto end;
+ }
+
+ value = lttng_process_attr_tracker_values_get_at_index(values, index);
+ type = value->type;
+end:
+ return type;
+}
+
+#define DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER( \
+ value_type_name, value_type, expected_value_type) \
+ enum lttng_process_attr_values_status \
+ lttng_process_attr_values_get_##value_type_name##_at_index( \
+ const struct lttng_process_attr_values \
+ *values, \
+ unsigned int index, \
+ value_type *out_value) \
+ { \
+ enum lttng_process_attr_values_status status = \
+ LTTNG_PROCESS_ATTR_VALUES_STATUS_OK; \
+ const struct process_attr_value *value; \
+ \
+ if (!values) { \
+ status = LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID; \
+ goto end; \
+ } \
+ \
+ if (_lttng_process_attr_values_get_count(values) <= index) { \
+ status = LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID; \
+ goto end; \
+ } \
+ \
+ value = lttng_process_attr_tracker_values_get_at_index( \
+ values, index); \
+ if (value->type != \
+ LTTNG_PROCESS_ATTR_VALUE_TYPE_##expected_value_type) { \
+ status = LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID_TYPE; \
+ goto end; \
+ } \
+ *out_value = value->value.value_type_name; \
+ end: \
+ return status; \
+ }
+
+DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(pid, pid_t, PID);
+DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(uid, uid_t, UID);
+DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(gid, gid_t, GID);
+DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(user_name, const char *, USER_NAME);
+DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(group_name, const char *, GROUP_NAME);
+
+static enum lttng_error_code handle_status_to_error_code(
+ enum lttng_process_attr_tracker_handle_status handle_status)
+{
+ switch (handle_status) {
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY:
+ return LTTNG_ERR_INVALID;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST:
+ return LTTNG_ERR_SESSION_NOT_EXIST;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR:
+ return LTTNG_ERR_INVALID_PROTOCOL;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_EXISTS:
+ return LTTNG_ERR_PID_TRACKED;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_MISSING:
+ return LTTNG_ERR_PID_NOT_TRACKED;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK:
+ return LTTNG_OK;
+ case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR:
+ default:
+ /* fall-through. */
+ return LTTNG_ERR_UNK;
+ }
+}
+
+/*
+ * 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)
+{
+ enum lttng_error_code ret_code;
+ struct lttng_process_attr_tracker_handle *tracker_handle = NULL;
+ enum lttng_process_attr_tracker_handle_status handle_status;
+ enum lttng_tracking_policy policy;
+ enum lttng_process_attr process_attr;
+
+ if (!handle) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ process_attr = handle->domain.type == LTTNG_DOMAIN_KERNEL ?
+ LTTNG_PROCESS_ATTR_PROCESS_ID :
+ LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID;
+
+ ret_code = lttng_session_get_tracker_handle(handle->session_name,
+ handle->domain.type,
+ process_attr, &tracker_handle);
+ if (ret_code != LTTNG_OK) {
+ goto end;
+ }
+
+ if (pid == -1) {
+ handle_status = lttng_process_attr_tracker_handle_set_tracking_policy(
+ tracker_handle,
+ LTTNG_TRACKING_POLICY_INCLUDE_ALL);
+ ret_code = handle_status_to_error_code(handle_status);
+ goto end;
+ }
+
+ handle_status = lttng_process_attr_tracker_handle_get_tracking_policy(
+ tracker_handle, &policy);
+ if (handle_status != LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK) {
+ ret_code = handle_status_to_error_code(handle_status);
+ goto end;
+ }
+
+ if (policy != LTTNG_TRACKING_POLICY_INCLUDE_SET) {
+ handle_status = lttng_process_attr_tracker_handle_set_tracking_policy(
+ tracker_handle,
+ LTTNG_TRACKING_POLICY_INCLUDE_SET);
+ if (handle_status != LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK) {
+ ret_code = handle_status_to_error_code(handle_status);
+ goto end;
+ }
+ }
+
+ handle_status = process_attr == LTTNG_PROCESS_ATTR_PROCESS_ID ?
+ lttng_process_attr_process_id_tracker_handle_add_pid(
+ tracker_handle,
+ (pid_t) pid) :
+ lttng_process_attr_virtual_process_id_tracker_handle_add_pid(
+ tracker_handle,
+ (pid_t) pid);
+ ret_code = handle_status_to_error_code(handle_status);
+end:
+ return ret_code == LTTNG_OK ? 0 : -ret_code;
+}
+
+/*
+ * 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)
+{
+ enum lttng_error_code ret_code;
+ struct lttng_process_attr_tracker_handle *tracker_handle = NULL;
+ enum lttng_process_attr_tracker_handle_status handle_status;
+ enum lttng_tracking_policy policy;
+ enum lttng_process_attr process_attr;
+
+ if (!handle) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ process_attr = handle->domain.type == LTTNG_DOMAIN_KERNEL ?
+ LTTNG_PROCESS_ATTR_PROCESS_ID :
+ LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID;
+ ret_code = lttng_session_get_tracker_handle(handle->session_name,
+ handle->domain.type, process_attr, &tracker_handle);
+ if (ret_code != LTTNG_OK) {
+ goto end;
+ }
+
+ if (pid == -1) {
+ handle_status = lttng_process_attr_tracker_handle_set_tracking_policy(
+ tracker_handle,
+ LTTNG_TRACKING_POLICY_EXCLUDE_ALL);
+ ret_code = handle_status_to_error_code(handle_status);
+ goto end;
+ }
+
+ handle_status = lttng_process_attr_tracker_handle_get_tracking_policy(
+ tracker_handle, &policy);
+ if (handle_status != LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK) {
+ ret_code = handle_status_to_error_code(handle_status);
+ goto end;
+ }
+
+ if (policy == LTTNG_TRACKING_POLICY_EXCLUDE_ALL) {
+ ret_code = LTTNG_ERR_PID_NOT_TRACKED;
+ goto end;
+ } else if (policy == LTTNG_TRACKING_POLICY_INCLUDE_ALL) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ handle_status = process_attr == LTTNG_PROCESS_ATTR_PROCESS_ID ?
+ lttng_process_attr_process_id_tracker_handle_remove_pid(
+ tracker_handle,
+ (pid_t) pid) :
+ lttng_process_attr_virtual_process_id_tracker_handle_remove_pid(
+ tracker_handle,
+ (pid_t) pid);
+ if (handle_status == LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY) {
+ ret_code = LTTNG_ERR_PID_NOT_TRACKED;
+ }
+end:
+ return ret_code == LTTNG_OK ? 0 : -ret_code;
+}
+
+/*
+ * 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)
+{
+ enum lttng_error_code ret_code;
+ struct lttng_process_attr_tracker_handle *tracker_handle = NULL;
+ enum lttng_process_attr_tracker_handle_status handle_status;
+ const struct lttng_process_attr_values *values;
+ enum lttng_tracking_policy policy;
+ unsigned int pid_count, i;
+ int32_t *pid_array = NULL;
+
+ if (!handle || !_enabled || !_pids || !_nr_pids) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ ret_code = lttng_session_get_tracker_handle(handle->session_name,
+ handle->domain.type,
+ LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID, &tracker_handle);
+ if (ret_code != LTTNG_OK) {
+ goto end;
+ }
+
+ while (true) {
+ handle_status = lttng_process_attr_tracker_handle_get_inclusion_set(
+ tracker_handle, &values);
+ if (handle_status ==
+ LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK) {
+ policy = LTTNG_TRACKING_POLICY_INCLUDE_SET;
+ break;
+ } else if (handle_status !=
+ LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY) {
+ ret_code = handle_status_to_error_code(handle_status);
+ goto end;
+ }
+
+ handle_status = lttng_process_attr_tracker_handle_get_tracking_policy(
+ tracker_handle, &policy);
+ if (handle_status !=
+ LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK) {
+ ret_code = handle_status_to_error_code(handle_status);
+ goto end;
+ }
+
+ /* Tracking policy changed in the meantime, retry. */
+ if (policy == LTTNG_TRACKING_POLICY_INCLUDE_SET) {
+ continue;
+ }
+ break;
+ }
+
+ switch (policy) {
+ case LTTNG_TRACKING_POLICY_INCLUDE_ALL:
+ *_enabled = 0;
+ goto end;
+ case LTTNG_TRACKING_POLICY_EXCLUDE_ALL:
+ *_enabled = 1;
+ pid_count = 0;
+ break;
+ case LTTNG_TRACKING_POLICY_INCLUDE_SET:
+ {
+ const enum lttng_process_attr_values_status values_status =
+ lttng_process_attr_values_get_count(
+ values, &pid_count);
+
+ if (values_status != LTTNG_PROCESS_ATTR_VALUES_STATUS_OK) {
+ ret_code = LTTNG_ERR_UNK;
+ goto end;
+ }
+ break;
+ }
+ default:
+ ret_code = LTTNG_ERR_INVALID_PROTOCOL;
+ goto end;
+ }
+
+ pid_array = zmalloc(pid_count * sizeof(int32_t));
+ if (!pid_array) {
+ ret_code = LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ /* Extract values to a raw array. */
+ for (i = 0; i < pid_count; i++) {
+ pid_t pid;
+ const enum lttng_process_attr_values_status values_status =
+ lttng_process_attr_values_get_pid_at_index(
+ values, i, &pid);
+
+ if (values_status != LTTNG_PROCESS_ATTR_VALUES_STATUS_OK) {
+ ret_code = LTTNG_ERR_UNK;
+ goto end;
+ }
+ pid_array[i] = (int32_t) pid;
+ }
+ *_nr_pids = (size_t) pid_count;
+ *_pids = pid_array;
+ pid_array = NULL;
+end:
+ lttng_process_attr_tracker_handle_destroy(tracker_handle);
+ free(pid_array);
+ return ret_code == LTTNG_OK ? 0 : -ret_code;
+}
XPATH_SNAPSHOT_ADD_SNAPSHOT="$XPATH_CMD_OUTPUT/lttng:snapshot_action[./lttng:name = 'add-output']/lttng:output"
XPATH_SNAPSHOT_LIST="$XPATH_CMD_OUTPUT/lttng:snapshot_action[./lttng:name = 'list-output']/lttng:output"
XPATH_SNAPSHOT_DEL="$XPATH_CMD_OUTPUT/lttng:snapshot_action[./lttng:name = 'del-output']/lttng:output"
-XPATH_TRACK_UNTRACK_VPID="$XPATH_CMD_OUTPUT/lttng:trackers/lttng:vpid_tracker/lttng:targets/lttng:vpid_target/lttng:type"
-XPATH_VPID_TRACKER="$XPATH_CMD_OUTPUT/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:trackers/lttng:vpid_tracker"
+XPATH_TRACK_UNTRACK_VPID="$XPATH_CMD_OUTPUT/lttng:process_attr_trackers/lttng:vpid_process_attr_tracker/lttng:process_attr_values/lttng:vpid/lttng:type"
+XPATH_VPID_TRACKER="$XPATH_CMD_OUTPUT/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:process_attr_trackers/lttng:vpid_process_attr_tracker"
DEVNULL=/dev/null 2>&1
ok $? "Mi test: session list with pid_tracker validate"
#Check the good count
- extract_xml $OUTPUT_DEST $XPATH_VPID_TRACKER"/lttng:targets/lttng:vpid_target/lttng:type/lttng:id" result
+ extract_xml $OUTPUT_DEST $XPATH_VPID_TRACKER"/lttng:process_attr_values/lttng:vpid/lttng:type/lttng:id" result
num=$(echo "$result" | wc -l)
test "$num" -eq "3"
ok $? "Mi test: tracker pid listing expecting 3 target got $num"
<contexts/>
</channel>
</channels>
- <trackers>
- <vpid_tracker>
- <targets>
- <vpid_target>
+ <process_attr_trackers>
+ <vpid_process_attr_tracker>
+ <process_attr_values>
+ <vpid>
<id>666</id>
- </vpid_target>
- </targets>
- </vpid_tracker>
- <vuid_tracker>
- <targets>
- <vuid_target>
+ </vpid>
+ </process_attr_values>
+ </vpid_process_attr_tracker>
+ <vuid_process_attr_tracker>
+ <process_attr_values>
+ <vuid>
<id>777</id>
- </vuid_target>
- </targets>
- </vuid_tracker>
- <vgid_tracker>
- <targets>
- <vgid_target>
+ </vuid>
+ </process_attr_values>
+ </vuid_process_attr_tracker>
+ <vgid_process_attr_tracker>
+ <process_attr_values>
+ <vgid>
<id>888</id>
- </vgid_target>
- </targets>
- </vgid_tracker>
- <pid_tracker>
- <targets>
- <pid_target>
- <pid>999</pid>
- </pid_target>
- </targets>
- </pid_tracker>
- </trackers>
+ </vgid>
+ </process_attr_values>
+ </vgid_process_attr_tracker>
+ <vpid_process_attr_tracker>
+ <process_attr_values>
+ <vpid>
+ <id>999</id>
+ </vpid>
+ </process_attr_values>
+ </vpid_process_attr_tracker>
+ </process_attr_trackers>
</domain>
</domains>
<started>false</started>
break;
fi
$TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML list "$SESSION_NAME-trackers" > $mi_output_file
- mi_result=$($CURDIR/../mi/extract_xml -e $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:trackers/lttng:vpid_tracker/lttng:targets/lttng:vpid_target")
+ mi_result=$($CURDIR/../mi/extract_xml -e $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:process_attr_trackers/lttng:vpid_process_attr_tracker/lttng:process_attr_values/lttng:vpid")
if [[ $mi_result = "true" ]]; then
ok 0 "VPID target is present"
else
fail "VPID target missing"
fi
- mi_result=$($CURDIR/../mi/extract_xml -e $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:trackers/lttng:vuid_tracker/lttng:targets/lttng:vuid_target")
+ mi_result=$($CURDIR/../mi/extract_xml -e $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:process_attr_trackers/lttng:vuid_process_attr_tracker/lttng:process_attr_values/lttng:vuid")
if [[ $mi_result = "true" ]]; then
ok 0 "VUID target is present"
else
fail "VUID target missing"
fi
- mi_result=$($CURDIR/../mi/extract_xml -e $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:trackers/lttng:vgid_tracker/lttng:targets/lttng:vgid_target")
+ mi_result=$($CURDIR/../mi/extract_xml -e $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:process_attr_trackers/lttng:vgid_process_attr_tracker/lttng:process_attr_values/lttng:vgid")
if [[ $mi_result = "true" ]]; then
ok 0 "VGID target is present"
else