Refactor: lttng-ctl: follow terminology of the tracker documentation
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 17 Mar 2020 20:14:30 +0000 (16:14 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 26 Mar 2020 22:01:40 +0000 (18:01 -0400)
This commit harmonizes the process attribute tracker API and
serialization formats (save/restore and MI) with the documentation
with regards to the terminology used.

The message of the parent commit adjusting the manual pages of the
lttng-track and lttng-untrack commands details those terminology
changes and their rationale.

Some problems with the API introduced during the 2.12 development
cycle are also adressed:

Type safety:
  - The process attribute tracker is made type safe with regards
    to the platform's native types to express process
    attributes. Where the original API casted all integral values to
    integers, this change introduces accessors for all process
    attribute types (pid_t, uid_t, gid_t). This makes it easier to
    use the API safely and without producing warnings in user's
    code.

    Another benefit of adopting this explicit type-safe approach is
    that is will make it easier to add new attributes which are not
    expressible (or non-ambiguously expressible) using `int` and
    `string` types (e.g. tracking a virtual PID within a given
    namespace).

Ambiguity of INCLUDE_ALL, EXCLUDE_ALL, and INCLUDE_SET states:
  - The original tracker API has a notion of 'enabled' pid_tracker
    which is confusing to users:
      - enable = 0: everything is tracked,
      - enable = 1: a list of tracked pids is provided, which may be
        empty.
      - pid '-1' is *special* and tracks or untracks everything.

    This was replaced with a 'special' opaque value meaning 'ALL'
    which, while being clearer, was still confusing and hard to
    document.

    The revised API explicitly expresses the notion of a tracking
    policy (`enum lttng_tracking_policy`). When that policy is set
    to `LTTNG_TRACKING_POLICY_INCLUDE_SET`, the inclusion set can
    be queried and/or mutated.

    On top of being clearer, this aligns more closely with the
    internal lttng-sessiond daemon API which gets rid of a lot
    of code to handle those special cases. The resulting code is
    more verbose, but a lot easier to understand.

    Moreover, the types introduced (e.g. lttng_process_attr_values)
    are meant to be re-used if a new
    `LTTNG_TRACKING_POLICY_EXCLUDE_SET` tracking policy is added in
    the future.

Documentation:
  - The revised API includes a complete documentation. It documents
    the API usage, but also adds implementation notes such explicitly
    mentionning when/where user names and group names are resolved.

Client:
  - While making the changes to use this new API, some error messages
    are clarified (or added). The resulting output when listing the
    trackers was also changed to be more compact.

    The CLI output now also makes use of the terminology used in
    the documentation for all commands interacting with process
    attribute trackers.

    It is now also possible to specify multiple process attribute
    trackers along with the --all option for the lttng-track and
    lttng-untrack command.  For instance: `lttng tracker --userspace
    --vpid --vuid --all` is now allowed.

    The same process attribute tracker can also be specified more than
    once in a command, as follows:
    `lttng track --userspace --vpid 43,11 --vpid 55,77`

Since the serialization had been changed during the 2.12 cycle, I
changed them further to use the API's terminology in the element
names.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I5f0ea2849eb024ea6944b2ee7dbadfd893cc0be4

43 files changed:
include/Makefile.am
include/lttng/lttng-error.h
include/lttng/tracker-internal.h [deleted file]
include/lttng/tracker.h
src/bin/lttng-sessiond/client.c
src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/cmd.h
src/bin/lttng-sessiond/kernel.c
src/bin/lttng-sessiond/kernel.h
src/bin/lttng-sessiond/save.c
src/bin/lttng-sessiond/trace-kernel.c
src/bin/lttng-sessiond/trace-kernel.h
src/bin/lttng-sessiond/trace-ust.c
src/bin/lttng-sessiond/trace-ust.h
src/bin/lttng-sessiond/tracker.c
src/bin/lttng-sessiond/tracker.h
src/bin/lttng-sessiond/ust-app.c
src/bin/lttng/commands/list.c
src/bin/lttng/commands/track-untrack.c
src/common/Makefile.am
src/common/config/config-session-abi.h
src/common/config/session-config.c
src/common/config/session.xsd
src/common/error.c
src/common/kernel-ctl/kernel-ctl.c
src/common/kernel-ctl/kernel-ctl.h
src/common/macros.h
src/common/mi-lttng-4.0.xsd
src/common/mi-lttng.c
src/common/mi-lttng.h
src/common/sessiond-comm/sessiond-comm.h
src/common/tracker.c
src/common/tracker.h [new file with mode: 0644]
src/common/utils.c
src/common/utils.h
src/lib/lttng-ctl/Makefile.am
src/lib/lttng-ctl/deprecated-symbols.c
src/lib/lttng-ctl/lttng-ctl-helper.h
src/lib/lttng-ctl/lttng-ctl.c
src/lib/lttng-ctl/tracker.c [new file with mode: 0644]
tests/regression/tools/mi/test_mi
tests/regression/tools/save-load/load-42-trackers.lttng
tests/regression/tools/save-load/test_load

index ccd0d87d62dc6ff3ecd9bfe0393cf84baaf44167..1f89b1bf6cb4405dd77fad9b7094a8fb12b099e7 100644 (file)
@@ -161,6 +161,5 @@ noinst_HEADERS = \
        lttng/userspace-probe-internal.h \
        lttng/session-internal.h \
        lttng/session-descriptor-internal.h \
-       lttng/tracker-internal.h \
        version.h \
        version.i
index 4757d3d60fcb046b6afd85b192d654ff8d1f2acf..38fe7837ca0019f178a219a000d242a4b50ea527 100644 (file)
@@ -124,8 +124,8 @@ enum lttng_error_code {
        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 */
@@ -172,13 +172,15 @@ enum lttng_error_code {
        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 */
 };
 
 /*
diff --git a/include/lttng/tracker-internal.h b/include/lttng/tracker-internal.h
deleted file mode 100644 (file)
index daa6d80..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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 */
index 4f813eeb9fdc040e045f1a644928246c9c1b6e50..fa91abab6225c98c032043e14151c2bf1d310e2f 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * 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.
  */
@@ -203,30 +594,42 @@ extern int lttng_list_tracker_pids(struct lttng_handle *handle,
                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
 }
index 473491f37965459ffb2d260601f05d273b0b7260..a36b81c18a127b536f0a11abf5d48ccc2fafe4be 100644 (file)
@@ -7,18 +7,23 @@
  *
  */
 
-#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"
@@ -780,11 +785,12 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int *sock,
        case LTTNG_LIST_CHANNELS:
        case LTTNG_LIST_EVENTS:
        case LTTNG_LIST_SYSCALLS:
-       case LTTNG_LIST_TRACKER_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 */
@@ -1196,141 +1202,189 @@ error_add_context:
                                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:
@@ -1556,49 +1610,6 @@ error_add_context:
                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;
index 5e522d6fe0886108b87df756e930a6519a5a8a09..2bd010f895c223f83136f1c234f8bead46fbe339 100644 (file)
@@ -6,6 +6,9 @@
  *
  */
 
+#include "bin/lttng-sessiond/tracker.h"
+#include "lttng/lttng-error.h"
+#include "lttng/tracker.h"
 #define _LGPL_SOURCE
 #include <assert.h>
 #include <inttypes.h>
@@ -1431,112 +1434,6 @@ error:
        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.
  *
@@ -1708,6 +1605,211 @@ end:
        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.
  */
@@ -2566,56 +2668,6 @@ ssize_t cmd_list_syscalls(struct lttng_event **events)
        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.
  *
index 23d9d5e026e0496ac31591f637e495873d7a8f31..1be746031146962372c0d465de19e4adeb3753f4 100644 (file)
@@ -9,8 +9,10 @@
 #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;
 
@@ -47,14 +49,33 @@ int cmd_disable_channel(struct ltt_session *session,
 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,
@@ -104,10 +125,6 @@ ssize_t cmd_list_tracepoints(enum lttng_domain_type domain,
 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);
 
index 4ee4bea64ff630abae9617624f86ce21cc87950d..547d2ec6cafa7567a6a9238f138eb5c15f4012cd 100644 (file)
@@ -5,6 +5,11 @@
  *
  */
 
+#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>
@@ -669,281 +674,370 @@ error:
        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;
 }
 
 /*
index 4f3bedea5c392d09f94e9fbdd43ab60583e4c9e1..53d480313ad456d63e8cecb869876ac78dc2d117 100644 (file)
@@ -8,6 +8,8 @@
 #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"
@@ -20,7 +22,6 @@
  * 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);
@@ -33,12 +34,21 @@ int kernel_disable_channel(struct ltt_kernel_channel *chan);
 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);
@@ -62,9 +72,6 @@ enum lttng_error_code kernel_rotate_session(struct ltt_session *session);
 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);
index f01c3186bf313864952610fca304f559f3b9bc08..c3ae627915e3e8994ceb32333ab5a16f56a12212 100644 (file)
@@ -1820,50 +1820,47 @@ const char *get_config_domain_str(enum lttng_domain_type domain)
 }
 
 /* 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;
@@ -1873,61 +1870,48 @@ static int save_id_tracker(struct config_writer *writer,
        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;
@@ -1941,47 +1925,68 @@ static int save_id_tracker(struct config_writer *writer,
                        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;
                        }
@@ -2011,12 +2016,12 @@ static int save_id_tracker(struct config_writer *writer,
 
        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)
 {
@@ -2024,40 +2029,60 @@ static int save_id_trackers(struct config_writer *writer,
 
        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. */
@@ -2138,14 +2163,15 @@ int save_ust_domain(struct config_writer *writer,
        }
 
        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;
                }
@@ -2202,14 +2228,15 @@ int save_domains(struct config_writer *writer, struct ltt_session *session)
                        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;
                }
index 52f819b3001390fba5fb71c253a6321497649a01..723ffddd33118ebfd639135decc22bbe1b2c54de 100644 (file)
@@ -154,28 +154,28 @@ struct ltt_kernel_session *trace_kernel_create_session(void)
        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);
@@ -186,12 +186,12 @@ struct ltt_kernel_session *trace_kernel_create_session(void)
        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:
@@ -738,12 +738,12 @@ void trace_kernel_free_session(struct ltt_kernel_session *session)
        /* 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);
 }
index b290ce492a6dac7e35ca8c8eac9a3000e0b90f7c..61dd8eae99dfbaba96cb0bdd31db92166ceb11be 100644 (file)
@@ -114,12 +114,12 @@ struct ltt_kernel_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;
 };
 
 /*
index 92fd0de8116b0d00500d0f5b324f1d88e0bb049f..4432fca2340d2db3116eef9c60020f8de88c252d 100644 (file)
@@ -16,6 +16,7 @@
 #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"
@@ -303,16 +304,16 @@ struct ltt_ust_session *trace_ust_create_session(uint64_t session_id)
        /* 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);
@@ -325,9 +326,9 @@ struct ltt_ust_session *trace_ust_create_session(uint64_t session_id)
        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);
@@ -804,7 +805,7 @@ static int id_tracker_add_id(struct ust_id_tracker *id_tracker, int id)
        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));
@@ -831,7 +832,7 @@ static int id_tracker_del_id(struct ust_id_tracker *id_tracker, int id)
        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);
@@ -843,47 +844,56 @@ end:
 }
 
 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();
        }
@@ -899,229 +909,283 @@ int trace_ust_id_tracker_lookup(enum lttng_tracker_type tracker_type,
 /*
  * 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;
 }
 
 /*
@@ -1353,9 +1417,9 @@ void trace_ust_destroy_session(struct ltt_ust_session *session)
                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);
index a06c471cce9a6c10a7673f10e86ab1d55da31eb7..ecd0b877166abf22e7453a62c1b3c243016d9e18 100644 (file)
 #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"
@@ -137,9 +138,9 @@ struct ltt_ust_session {
        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;
 };
 
 /*
@@ -217,20 +218,24 @@ void trace_ust_destroy_event(struct ltt_ust_event *event);
 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 */
 
@@ -323,32 +328,44 @@ struct agent *trace_ust_find_agent(struct ltt_ust_session *session,
 {
        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 */
index cff5af3a0612c750a431fea74e435fd0d5c89591..05e2fe6cd12d689269b4ba254e2f5b63f1f1ceb8 100644 (file)
 /*
  * 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;
 }
index 78a12a6c760b245cf9d2dae46abd2499576ce7ee..a45a250bbc4063bacad38d29713f542074a3ad13 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * 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
  *
@@ -8,47 +9,38 @@
 #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 */
index ba63922cb36c9041edf55814c211a6a90ec34089..ea3f860398d3ca35edb16e515f55f14cbebcdcf7 100644 (file)
@@ -5116,11 +5116,14 @@ void ust_app_global_update(struct ltt_ust_session *usess, struct ust_app *app)
        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.
index 334d4daf1f6bf02d8d77084e10d8ccbdacddfc53..70dc99b0afc55801067e6b224481977d597ba471 100644 (file)
@@ -1,10 +1,12 @@
 /*
  * 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>
@@ -15,6 +17,7 @@
 
 #include <common/mi-lttng.h>
 #include <common/time.h>
+#include <common/tracker.h>
 #include <lttng/constant.h>
 #include <lttng/tracker.h>
 
@@ -1503,140 +1506,274 @@ error_channels:
        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;
 }
 
@@ -1647,6 +1784,7 @@ static int list_trackers(const struct lttng_domain *domain)
 {
        int ret = 0;
 
+       MSG("Tracked process attributes");
        /* Trackers listing */
        if (lttng_opt_mi) {
                ret = mi_lttng_trackers_open(writer);
@@ -1658,49 +1796,55 @@ static int list_trackers(const struct lttng_domain *domain)
        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;
                }
@@ -1708,6 +1852,7 @@ static int list_trackers(const struct lttng_domain *domain)
        default:
                break;
        }
+       MSG();
        if (lttng_opt_mi) {
                /* Close trackers element */
                ret = mi_lttng_writer_close_element(writer);
index 498e7ed31e938cb5fbc7d0a39b4f6528f2418d46..d28f8a7e136b321989485976f9e007130655a36e 100644 (file)
@@ -1,11 +1,17 @@
 /*
  * 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;
@@ -608,61 +607,29 @@ int cmd_track_untrack(enum cmd_type cmd_type, const char *cmd_str,
                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;
@@ -677,33 +644,44 @@ int cmd_track_untrack(enum cmd_type cmd_type, const char *cmd_str,
                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;
+                       }
                }
        }
 
@@ -756,52 +734,18 @@ int cmd_track_untrack(enum cmd_type cmd_type, const char *cmd_str,
                }
        }
 
-       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;
+                       }
                }
        }
 
@@ -816,7 +760,8 @@ int cmd_track_untrack(enum cmd_type cmd_type, const char *cmd_str,
 
                /* 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;
@@ -841,6 +786,10 @@ 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;
 }
@@ -855,7 +804,7 @@ int cmd_track(int argc, const char **argv)
 #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)
@@ -868,5 +817,5 @@ 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);
 }
index a50123989475fe1b4235032719ab60834599e185..1c9c8e4f04ecfc3d677182cfe5674e0ed4308dc6 100644 (file)
@@ -64,7 +64,7 @@ libcommon_la_SOURCES = \
        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
 
index eeb9884798cb465a8377f1c9c1d18cff6c822f42..41f675041536aba6216412ac929c4253a9266d38 100644 (file)
@@ -75,26 +75,26 @@ extern const char * const config_element_control_uri;
 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;
index 35c5aeef97ea279df9ef08563137a3c40ac04473..c7f471a1c2162c3c40d9d8a35ce1d0d348a5a0f0 100644 (file)
@@ -5,6 +5,7 @@
  *
  */
 
+#include "lttng/tracker.h"
 #define _LGPL_SOURCE
 #include <assert.h>
 #include <ctype.h>
@@ -132,25 +133,26 @@ const char * const config_element_control_uri = "control_uri";
 const char * const config_element_data_uri = "data_uri";
 const char * const config_element_max_size = "max_size";
 const char * const config_element_pid = "pid";
-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";
@@ -2665,56 +2667,56 @@ end:
        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:
@@ -2725,9 +2727,9 @@ static int get_tracker_elements(enum lttng_tracker_type tracker_type,
 
 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;
@@ -2735,23 +2737,33 @@ static int process_id_tracker_node(xmlNodePtr id_tracker_node,
        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;
                }
@@ -2763,27 +2775,17 @@ static int process_id_tracker_node(xmlNodePtr id_tracker_node,
        }
 
        /* 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;
@@ -2796,10 +2798,8 @@ static int process_id_tracker_node(xmlNodePtr id_tracker_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;
@@ -2812,65 +2812,103 @@ static int process_id_tracker_node(xmlNodePtr id_tracker_node,
                                        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_