From 01fac81494c061d122404aa1dbafc8d7bc93fb3d Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 5 Jul 2018 11:08:40 -0400 Subject: [PATCH 01/16] trackers: bump MI version to 4.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Mathieu Desnoyers Change-Id: I0a44262016cf90e0629be5cb7d8b5976462c62d9 Signed-off-by: Jérémie Galarneau --- src/common/Makefile.am | 2 +- src/common/{mi-lttng-3.0.xsd => mi-lttng-4.0.xsd} | 2 +- tests/regression/tools/mi/test_mi | 2 +- tests/regression/tools/relayd-grouping/test_ust | 2 +- tests/regression/tools/rotation/test_save_load_mi | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename src/common/{mi-lttng-3.0.xsd => mi-lttng-4.0.xsd} (99%) diff --git a/src/common/Makefile.am b/src/common/Makefile.am index a40ec0d29..95935b76e 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -22,7 +22,7 @@ DIST_SUBDIRS = \ # Common library noinst_LTLIBRARIES = libcommon.la -EXTRA_DIST = mi-lttng-3.0.xsd +EXTRA_DIST = mi-lttng-4.0.xsd libcommon_la_SOURCES = \ action.c \ diff --git a/src/common/mi-lttng-3.0.xsd b/src/common/mi-lttng-4.0.xsd similarity index 99% rename from src/common/mi-lttng-3.0.xsd rename to src/common/mi-lttng-4.0.xsd index 218d5bd98..a6a7af699 100644 --- a/src/common/mi-lttng-3.0.xsd +++ b/src/common/mi-lttng-4.0.xsd @@ -25,7 +25,7 @@ THE SOFTWARE. + elementFormDefault="qualified" version="4.0"> diff --git a/tests/regression/tools/mi/test_mi b/tests/regression/tools/mi/test_mi index 8eb049122..3feff4ac5 100755 --- a/tests/regression/tools/mi/test_mi +++ b/tests/regression/tools/mi/test_mi @@ -19,7 +19,7 @@ TEST_DESC="Machine interface testing" CURDIR=$(dirname $0)/ TESTDIR=$CURDIR/../../../ -XSD_PATH=$TESTDIR/../src/common/mi-lttng-3.0.xsd +XSD_PATH=$TESTDIR/../src/common/mi-lttng-4.0.xsd #Test app for ust event TESTAPP_PATH="$TESTDIR/utils/testapp" diff --git a/tests/regression/tools/relayd-grouping/test_ust b/tests/regression/tools/relayd-grouping/test_ust index 85d7197e6..5749f5a47 100755 --- a/tests/regression/tools/relayd-grouping/test_ust +++ b/tests/regression/tools/relayd-grouping/test_ust @@ -27,7 +27,7 @@ TESTAPP_BIN="$TESTAPP_PATH/$TESTAPP_NAME/$TESTAPP_NAME" EVENT_NAME="tp:tptest" CHANNEL_NAME="my_channel" -XSD_PATH=$TESTDIR/../src/common/mi-lttng-3.0.xsd +XSD_PATH=$TESTDIR/../src/common/mi-lttng-4.0.xsd XML_VALIDATE="$TESTDIR/regression/tools/mi/validate_xml $XSD_PATH" XML_EXTRACT="$TESTDIR/regression/tools/mi/extract_xml" diff --git a/tests/regression/tools/rotation/test_save_load_mi b/tests/regression/tools/rotation/test_save_load_mi index 494d375f6..80500b40f 100755 --- a/tests/regression/tools/rotation/test_save_load_mi +++ b/tests/regression/tools/rotation/test_save_load_mi @@ -29,7 +29,7 @@ source $CURDIR/rotate_utils.sh # Overwrite the lttng_bin to get mi output LTTNG_BIN="lttng --mi xml" -XSD_PATH=$TESTDIR/../src/common/mi-lttng-3.0.xsd +XSD_PATH=$TESTDIR/../src/common/mi-lttng-4.0.xsd XML_VALIDATE="$TESTDIR/regression/tools/mi/validate_xml $XSD_PATH" XML_EXTRACT="$TESTDIR/regression/tools/mi/extract_xml" -- 2.34.1 From 14d3fca9eddbb059a9dae789affd561cf87337e4 Mon Sep 17 00:00:00 2001 From: Jonathan Rajotte Date: Thu, 9 Aug 2018 17:21:40 -0400 Subject: [PATCH 02/16] Fix: Skip uid registry when metadata key value is 0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit A value of 0 for the metadata key indicates that the metadata channel was never created/pushed on the consumer side. This can occur in scenario where a tracker(s) (vuid/vgid/vpid) is present. The metadata channel might never be created/pushed since no applications are actually tracing. Still, the uid registry exists due to the order in which the sessiond received the client commands (create, enable-channel, lttng track/untrack). See included test for a complete reproducer. Signed-off-by: Jonathan Rajotte Change-Id: Id7ef34ebc48333f47db4bdca907cf81911b60d1d Signed-off-by: Jérémie Galarneau --- src/bin/lttng-sessiond/ust-app.c | 5 +++ .../tools/tracker/test_event_tracker | 36 ++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index d0980220d..b1dba0a09 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -6343,6 +6343,11 @@ enum lttng_error_code ust_app_rotate_session(struct ltt_session *session) struct buffer_reg_channel *reg_chan; struct consumer_socket *socket; + if (!reg->registry->reg.ust->metadata_key) { + /* Skip since no metadata is present */ + continue; + } + /* Get consumer socket to use to push the metadata.*/ socket = consumer_find_socket_by_bitness(reg->bits_per_long, usess->consumer); diff --git a/tests/regression/tools/tracker/test_event_tracker b/tests/regression/tools/tracker/test_event_tracker index 0daa2f8b5..b4563b333 100755 --- a/tests/regression/tools/tracker/test_event_tracker +++ b/tests/regression/tools/tracker/test_event_tracker @@ -28,7 +28,7 @@ TESTAPP_KERNEL_BIN="$TESTAPP_PATH/$TESTAPP_KERNEL_NAME/$TESTAPP_KERNEL_NAME" SESSION_NAME="tracker" NR_ITER=100 NUM_GLOBAL_TESTS=2 -NUM_UST_TESTS=256 +NUM_UST_TESTS=265 NUM_KERNEL_TESTS=462 NUM_TESTS=$((NUM_UST_TESTS+NUM_KERNEL_TESTS+NUM_GLOBAL_TESTS)) @@ -345,6 +345,36 @@ function test_event_pid_track_untrack() rm -rf "$trace_path" } +function test_event_ust_vpid_untrack_snapshot() +{ + local trace_path + + trace_path=$(mktemp -d) + + diag "Test_event_ust_vpid_untrack_snapshot" + + create_lttng_session_ok $SESSION_NAME "$trace_path" "--snapshot" + + enable_ust_lttng_event_ok $SESSION_NAME "$EVENT_NAME" + + prepare_ust_app + + lttng_untrack_ust_ok "--vpid --all" + + start_lttng_tracing_ok + + trace_ust_app + lttng_snapshot_record $SESSION_NAME + + stop_lttng_tracing_ok + destroy_lttng_session_ok $SESSION_NAME + + snapshot_count=$(find "$trace_path" -name metadata | wc -l) + is "$snapshot_count" 0 "Number of snapshot is zero" + + rm -rf "$trace_path" +} + # MUST set TESTDIR before calling those functions plan_tests $NUM_TESTS @@ -402,6 +432,10 @@ test_event_vpid_track_untrack ust 0 "${EVENT_NAME}" test_event_tracker ust 1 "${EVENT_NAME}" "--vpid --all" test_event_vpid_tracker ust 1 "${EVENT_NAME}" +#snapshot untrack vpid + +test_event_ust_vpid_untrack_snapshot + #pid (backward compat) #non-matching -- 2.34.1 From 4b5ab17b3aec396cfa096ecac1b990242072d644 Mon Sep 17 00:00:00 2001 From: Jonathan Rajotte Date: Thu, 31 Oct 2019 17:20:43 -0400 Subject: [PATCH 03/16] ust-app: remove dead code MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This code path is not possible since all callsite are fenced with a check to "has_been_started". Hence, a session cannot be active at the same time. Change-Id: I53785017989ed7afc8755a41428087d988e5ae88 Signed-off-by: Jérémie Galarneau --- src/bin/lttng-sessiond/channel.c | 9 ---- src/bin/lttng-sessiond/ust-app.c | 82 -------------------------------- src/bin/lttng-sessiond/ust-app.h | 8 ---- 3 files changed, 99 deletions(-) diff --git a/src/bin/lttng-sessiond/channel.c b/src/bin/lttng-sessiond/channel.c index 6989fd890..46256208d 100644 --- a/src/bin/lttng-sessiond/channel.c +++ b/src/bin/lttng-sessiond/channel.c @@ -471,15 +471,6 @@ int channel_ust_create(struct ltt_ust_session *usess, goto error_free_chan; } - if (usess->active) { - /* Enable channel for global domain */ - ret = ust_app_create_channel_glb(usess, uchan); - if (ret < 0 && ret != -LTTNG_UST_ERR_EXIST) { - ret = LTTNG_ERR_UST_CHAN_FAIL; - goto error_free_chan; - } - } - /* Adding the channel to the channel hash table. */ rcu_read_lock(); if (strncmp(uchan->name, DEFAULT_METADATA_NAME, diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index b1dba0a09..823de9478 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -4161,88 +4161,6 @@ end: return ret; } -/* - * For a specific UST session, create the channel for all registered apps. - */ -int ust_app_create_channel_glb(struct ltt_ust_session *usess, - struct ltt_ust_channel *uchan) -{ - int ret = 0; - struct cds_lfht_iter iter; - struct ust_app *app; - - assert(usess); - assert(usess->active); - assert(uchan); - - DBG2("UST app adding channel %s to UST domain for session id %" PRIu64, - uchan->name, usess->id); - - rcu_read_lock(); - /* For every registered applications */ - cds_lfht_for_each_entry(ust_app_ht->ht, &iter, app, pid_n.node) { - struct ust_app_session *ua_sess; - int session_was_created = 0; - bool present_in_tracker = - trace_ust_id_tracker_lookup(LTTNG_TRACKER_VPID, - usess, app->pid) && - trace_ust_id_tracker_lookup(LTTNG_TRACKER_VUID, - usess, app->uid) && - trace_ust_id_tracker_lookup(LTTNG_TRACKER_VGID, - usess, app->gid); - - if (!app->compatible || !(present_in_tracker)) { - /* - * This is probably an error this MUST BE TESTED - * Introduced by - * 88e3c2f5610b9ac89b0923d448fee34140fc46fb On app not - * in tracker we should skip it. not sure what to do on - * app !compatible - */ - goto error_rcu_unlock; - } - - /* - * Create session on the tracer side and add it to app session HT. Note - * that if session exist, it will simply return a pointer to the ust - * app session. - */ - ret = find_or_create_ust_app_session(usess, app, &ua_sess, - &session_was_created); - if (ret < 0) { - switch (ret) { - case -ENOTCONN: - /* - * The application's socket is not valid. Either a bad - * socket or a timeout on it. We can't inform the caller - * that for a specific app, the session failed so lets - * continue here; it is not an error. - */ - ret = 0; - goto error_rcu_unlock; - case -ENOMEM: - default: - goto error_rcu_unlock; - } - } - - if (ua_sess->deleted) { - continue; - } - ret = ust_app_channel_create(usess, ua_sess, uchan, app, NULL); - if (ret) { - if (session_was_created) { - destroy_app_session(app, ua_sess); - } - /* Continue to the next application. */ - } - } - -error_rcu_unlock: - rcu_read_unlock(); - return ret; -} - /* * Enable event for a specific session and channel on the tracer. */ diff --git a/src/bin/lttng-sessiond/ust-app.h b/src/bin/lttng-sessiond/ust-app.h index 25aeada65..957d1f95d 100644 --- a/src/bin/lttng-sessiond/ust-app.h +++ b/src/bin/lttng-sessiond/ust-app.h @@ -315,8 +315,6 @@ int ust_app_stop_trace_all(struct ltt_ust_session *usess); int ust_app_destroy_trace_all(struct ltt_ust_session *usess); int ust_app_list_events(struct lttng_event **events); int ust_app_list_event_fields(struct lttng_event_field **fields); -int ust_app_create_channel_glb(struct ltt_ust_session *usess, - struct ltt_ust_channel *uchan); int ust_app_create_event_glb(struct ltt_ust_session *usess, struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent); int ust_app_disable_channel_glb(struct ltt_ust_session *usess, @@ -467,12 +465,6 @@ int ust_app_enable_channel_glb(struct ltt_ust_session *usess, return 0; } static inline -int ust_app_create_channel_glb(struct ltt_ust_session *usess, - struct ltt_ust_channel *uchan) -{ - return 0; -} -static inline int ust_app_create_event_glb(struct ltt_ust_session *usess, struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent) { -- 2.34.1 From ef440343c0d6372c1aaca74d0cdecfcd700a5785 Mon Sep 17 00:00:00 2001 From: Jonathan Rajotte Date: Mon, 4 Nov 2019 17:35:27 -0500 Subject: [PATCH 04/16] Error early on invalid tracker type for UST domain MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonathan Rajotte Change-Id: Iea182575c99c1fcf84cb8c313af5904581b5023d Signed-off-by: Jérémie Galarneau --- src/bin/lttng/commands/track-untrack.c | 35 ++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/bin/lttng/commands/track-untrack.c b/src/bin/lttng/commands/track-untrack.c index 4f51ffa30..25b4461f6 100644 --- a/src/bin/lttng/commands/track-untrack.c +++ b/src/bin/lttng/commands/track-untrack.c @@ -286,6 +286,34 @@ static const char *get_tracker_str(enum lttng_tracker_type tracker_type) return NULL; } +static int ust_tracker_type_support(enum lttng_tracker_type *tracker_type) +{ + 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; + break; + default: + ret = -1; + break; + } + + return ret; +} + static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type, const char *cmd_str, const char *session_name, @@ -321,8 +349,11 @@ static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type, dom.type = LTTNG_DOMAIN_KERNEL; } else if (opt_userspace) { dom.type = LTTNG_DOMAIN_UST; - if (tracker_type == LTTNG_TRACKER_PID) { - tracker_type = LTTNG_TRACKER_VPID; + ret = ust_tracker_type_support(&tracker_type); + if (ret) { + ERR("Invalid parameter"); + retval = CMD_ERROR; + goto end; } } else { /* Checked by the caller. */ -- 2.34.1 From 9bd01b5ed9029cd66faf8934d13542b75e598531 Mon Sep 17 00:00:00 2001 From: Jonathan Rajotte Date: Wed, 6 Nov 2019 14:51:22 -0500 Subject: [PATCH 05/16] Update track/untrack man page MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonathan Rajotte Change-Id: Ie7092993034f2fb71fc3b1fad0ce5a6f61a31493 Signed-off-by: Jérémie Galarneau --- doc/man/lttng-track.1.txt | 81 +++++++++++++++++++++++++++++++-------- 1 file changed, 66 insertions(+), 15 deletions(-) diff --git a/doc/man/lttng-track.1.txt b/doc/man/lttng-track.1.txt index d8c381292..646b55cad 100644 --- a/doc/man/lttng-track.1.txt +++ b/doc/man/lttng-track.1.txt @@ -1,6 +1,6 @@ lttng-track(1) ============== -:revdate: 14 March 2017 +:revdate: 04 November 2019 NAME @@ -12,7 +12,13 @@ SYNOPSIS -------- [verse] *lttng* ['linkgenoptions:(GENERAL OPTIONS)'] *track* (option:--kernel | option:--userspace) - [option:--session='SESSION'] (option:--pid='PID'[,'PID']... | option:--all option:--pid) + [option:--session='SESSION'] (option:--pid='PID'[,'PID']... | + option:--uid='UID'[,'UID'][,'USERNAME']... | + option:--gid='GID'[,'GID'][,'GROUPNAME']... | + option:--vpid='VPID'[,'VPID']... | + option:--vuid='VUID'[,'VUID'][,'USERNAME']... | + option:--vgid='VGID'[,'VGID'][,'GROUPNAME']... | + option:--all (option:--pid | option:--uid | option:--gid | option:--vpid | option:--vuid | option:--vgid)) DESCRIPTION @@ -27,11 +33,12 @@ event rules (see man:lttng-enable-event(1)). Tracker entries can be removed from the whitelist with man:lttng-untrack(1). -As of this version, the only available tracker is the *PID tracker*. The -process ID (PID) tracker follows one or more process IDs; only the -processes with a tracked PID are allowed to emit events. By default, all -possible PIDs on the system are tracked: any process may emit enabled -events (equivalent of `lttng track --pid --all` for all domains). +The following tracker are available: PID, UID, GID, VPID, VUID, VGID. + +A tracker follows one or more IDs; only the processes with a tracked ID are +allowed to emit events. By default, all possible IDs on the system are tracked: +any process may emit enabled events (equivalent of `lttng track --pid --uid +--gid --vpid --vuid --vgid --all` for all domains). With the PID tracker, it is possible, for example, to record all system calls called by a given process: @@ -52,7 +59,7 @@ specified PIDs. Example ~~~~~~~ -Assume the maximum system PID is 7 for this example. +Assume the maximum system VPID is 7 for this example. Initial whitelist: @@ -64,7 +71,7 @@ Command: [role="term"] ---- -$ lttng track --userspace --pid=3,6,7 +$ lttng track --userspace --vpid=3,6,7 ---- Whitelist: @@ -77,7 +84,7 @@ Command: [role="term"] ---- -$ lttng untrack --userspace --pid=7 +$ lttng untrack --userspace --vpid=7 ---- Whitelist: @@ -90,7 +97,7 @@ Command: [role="term"] ---- -$ lttng track --userspace --pid=1,5 +$ lttng track --userspace --vpid=1,5 ---- Whitelist: @@ -99,9 +106,9 @@ Whitelist: [ ] [1] [ ] [3] [ ] [5] [6] [ ] ------------------------------- -It should be noted that the PID tracker tracks the numeric process IDs. -Should a process with a given ID exit and another process be given this -ID, then the latter would also be allowed to emit events. +It should be noted that the VPID tracker tracks the numeric namespaced process +IDs. Should a process with a given ID exit and another process be given this ID, +then the latter would also be allowed to emit events. See the man:lttng-untrack(1) for more details about removing entries. @@ -131,15 +138,59 @@ option:-s 'SESSION', option:--session='SESSION':: Tracking ~~~~~~~~ option:-a, option:--all:: - Used in conjunction with an empty option:--pid option: track _all_ + Used in conjunction with an empty tracker option, e.g: options:--pid track _all_ process IDs (add all entries to the whitelist). option:-p ['PID'[,'PID']...], option:--pid[='PID'[,'PID']...]:: Track process IDs 'PID' (add them to the current whitelist). + PID is the non-namespaced value for the process. + The 'PID' argument must be omitted when also using the option:--all option. +option:-p ['UID'[,'UID']...], option:--uid[='UID'[,'UID'][,'USERNAME']...]:: + Track process IDs 'UID' (add them to the current whitelist). + User name can also be used, name resolution is performed by + lttng-sessiond. + UID is the non-namespaced user id value for the process. ++ +The 'UID' argument must be omitted when also using the option:--all +option. + +option:-p ['GID'[,'GID']...], option:--gid[='GID'[,'GID'][,'GROUPNAME']...]:: + Track process IDs 'GID' (add them to the current whitelist). + Group name can also be used, name resolution is performed by + lttng-sessiond. + GID is the non-namespaced group id value for the process. ++ +The 'GID' argument must be omitted when also using the option:--all +option. + +option:-p ['VPID'[,'VPID']...], option:--vpid[='VPID'[,'VPID']...]:: + Track process IDs 'VPID' (add them to the current whitelist). + VPID is the namespaced PID of the process for its current context. ++ +The 'VPID' argument must be omitted when also using the option:--all +option. + +option:-p ['VUID'[,'VUID']...], option:--vuid[='VUID'[,'VUID'][,'USERNAME']...]:: + Track process IDs 'VUID' (add them to the current whitelist). + User name can also be used, name resolution is performed by + lttng-sessiond. + VUID is the namespaced UID of the process for its current context. ++ +The 'VUID' argument must be omitted when also using the option:--all +option. + +option:-p ['VGID'[,'VGID']...], option:--vgid[='VGID'[,'VGID'][,'GROUPNAME']...]:: + Track process IDs 'VGID' (add them to the current whitelist). + Group name can also be used, name resolution is performed by + lttng-sessiond. + VGID is the namespaced GID of the process for its current context. ++ +The 'VGID' argument must be omitted when also using the option:--all +option. + include::common-cmd-help-options.txt[] -- 2.34.1 From 0dda67289b8a86fd3f117d644f00f2985d399208 Mon Sep 17 00:00:00 2001 From: Jonathan Rajotte Date: Fri, 8 Nov 2019 16:28:00 -0500 Subject: [PATCH 06/16] Fix: Initialize ret to zero MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit For the improbable case that the domain is unknown the return value ret would not be initialized. Signed-off-by: Jonathan Rajotte Change-Id: I22ae6b98bbbc4f4fe3e9c28985e2400f7c668525 Signed-off-by: Jérémie Galarneau --- src/bin/lttng/commands/list.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/lttng/commands/list.c b/src/bin/lttng/commands/list.c index fb891beb7..226eb4c87 100644 --- a/src/bin/lttng/commands/list.c +++ b/src/bin/lttng/commands/list.c @@ -1612,7 +1612,7 @@ end: */ static int list_trackers(const struct lttng_domain *domain) { - int ret; + int ret = 0; /* Trackers listing */ if (lttng_opt_mi) { -- 2.34.1 From 2d97a0067600335f07eecb2c1d9ba68fc164583e Mon Sep 17 00:00:00 2001 From: Jonathan Rajotte Date: Sun, 17 Nov 2019 21:38:21 -0500 Subject: [PATCH 07/16] Refactoring: use an opaque lttng_tracker_id type MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Move the tracker and tracker id related API to tracker.h and tracker-internal.h. The use of an opaque object mimics the new API for rotation and trigger etc. Signed-off-by: Jonathan Rajotte Change-Id: I00b876c618d7dcb0dd940189e5250c3f3d64c7e0 Signed-off-by: Jérémie Galarneau --- include/Makefile.am | 4 +- include/lttng/lttng.h | 1 + include/lttng/session.h | 95 --------- include/lttng/tracker-internal.h | 40 ++++ include/lttng/tracker.h | 222 ++++++++++++++++++++ src/bin/lttng-sessiond/client.c | 131 ++++++++---- src/bin/lttng-sessiond/cmd.c | 2 +- src/bin/lttng-sessiond/cmd.h | 2 +- src/bin/lttng-sessiond/kernel.c | 18 +- src/bin/lttng-sessiond/kernel.h | 2 +- src/bin/lttng-sessiond/save.c | 25 ++- src/bin/lttng-sessiond/trace-ust.c | 18 +- src/bin/lttng-sessiond/trace-ust.h | 2 +- src/bin/lttng-sessiond/tracker.c | 136 +++++++------ src/bin/lttng-sessiond/tracker.h | 8 +- src/bin/lttng/commands/list.c | 46 ++++- src/bin/lttng/commands/track-untrack.c | 115 ++++++++--- src/common/Makefile.am | 1 + src/common/config/session-config.c | 60 +++++- src/common/mi-lttng.c | 24 ++- src/common/tracker.c | 223 ++++++++++++++++++++ src/lib/lttng-ctl/lttng-ctl.c | 272 ++++++++++++++----------- 22 files changed, 1038 insertions(+), 409 deletions(-) create mode 100644 include/lttng/tracker-internal.h create mode 100644 include/lttng/tracker.h create mode 100644 src/common/tracker.c diff --git a/include/Makefile.am b/include/Makefile.am index ab5aa5375..610f1cb73 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -115,7 +115,8 @@ lttnginclude_HEADERS = \ lttng/session-descriptor.h \ lttng/destruction-handle.h \ lttng/clear.h \ - lttng/clear-handle.h + lttng/clear-handle.h \ + lttng/tracker.h lttngactioninclude_HEADERS= \ lttng/action/action.h \ @@ -159,5 +160,6 @@ noinst_HEADERS = \ lttng/userspace-probe-internal.h \ lttng/session-internal.h \ lttng/session-descriptor-internal.h \ + lttng/tracker-internal.h \ version.h \ version.i diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index 5279bc57d..8d001a21f 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -48,6 +48,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { diff --git a/include/lttng/session.h b/include/lttng/session.h index 06d4f8b9d..b8a2b7dcc 100644 --- a/include/lttng/session.h +++ b/include/lttng/session.h @@ -25,28 +25,6 @@ extern "C" { #include -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, -}; - -enum lttng_tracker_id_type { - LTTNG_ID_UNKNOWN = -1, - LTTNG_ID_ALL = 0, - LTTNG_ID_VALUE = 1, - LTTNG_ID_STRING = 2, -}; - -struct lttng_tracker_id { - enum lttng_tracker_id_type type; - int value; - char *string; -}; - struct lttng_handle; struct lttng_session_descriptor; struct lttng_destruction_handle; @@ -239,79 +217,6 @@ extern enum lttng_error_code lttng_session_get_creation_time( extern int lttng_set_session_shm_path(const char *session_name, const char *shm_path); -/* - * Add ID to session tracker. - * - * tracker_type is the type of tracker. - * id the id to track. - * - * Return 0 on success else a negative LTTng error code. - */ -extern int lttng_track_id(struct lttng_handle *handle, - enum lttng_tracker_type tracker_type, - const struct lttng_tracker_id *id); - -/* - * Remove ID from session tracker. - * - * tracker_type is the type of tracker. - * id the id to untrack. - * - * Return 0 on success else a negative LTTng error code. - */ -extern int lttng_untrack_id(struct lttng_handle *handle, - enum lttng_tracker_type tracker_type, - const struct lttng_tracker_id *id); - -/* - * List IDs in the tracker. - * - * tracker_type is the type of tracker. - * ids is set to an allocated array of IDs currently tracked. On - * success, ids and the strings it contains must be freed by the - * caller. - * nr_ids is set to the number of entries contained by the ids array. - * - * Returns 0 on success, else a negative LTTng error code. - */ -extern int lttng_list_tracker_ids(struct lttng_handle *handle, - enum lttng_tracker_type tracker_type, - struct lttng_tracker_id **ids, - size_t *nr_ids); - -/* - * Add PID to session tracker. - * - * A pid argument >= 0 adds the PID to the session tracker. - * A pid argument of -1 means "track all PIDs". - * - * Return 0 on success else a negative LTTng error code. - */ -extern int lttng_track_pid(struct lttng_handle *handle, int pid); - -/* - * Remove PID from session tracker. - * - * A pid argument >= 0 removes the PID from the session tracker. - * A pid argument of -1 means "untrack all PIDs". - * - * Return 0 on success else a negative LTTng error code. - */ -extern int lttng_untrack_pid(struct lttng_handle *handle, int pid); - -/* - * List PIDs in the tracker. - * - * enabled is set to whether the PID tracker is enabled. - * pids is set to an allocated array of PIDs currently tracked. On - * success, pids must be freed by the caller. - * nr_pids is set to the number of entries contained by the pids array. - * - * Returns 0 on success, else a negative LTTng error code. - */ -extern int lttng_list_tracker_pids(struct lttng_handle *handle, - int *enabled, int32_t **pids, size_t *nr_pids); - #ifdef __cplusplus } #endif diff --git a/include/lttng/tracker-internal.h b/include/lttng/tracker-internal.h new file mode 100644 index 000000000..a84d419d6 --- /dev/null +++ b/include/lttng/tracker-internal.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2019 - Jonathan Rajotte-Julien + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License, version 2.1 only, + * as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LTTNG_TRACKER_INTERNAL_H +#define LTTNG_TRACKER_INTERNAL_H + +#include +#include +#include +#include + +struct lttng_tracker_id { + enum lttng_tracker_id_type type; + int value; + char *string; +}; + +LTTNG_HIDDEN +bool lttng_tracker_id_is_equal(const struct lttng_tracker_id *left, + const struct lttng_tracker_id *right); + +LTTNG_HIDDEN +struct lttng_tracker_id *lttng_tracker_id_copy( + const struct lttng_tracker_id *orig); + +#endif /* LTTNG_TRACKER_INTERNAL_H */ diff --git a/include/lttng/tracker.h b/include/lttng/tracker.h new file mode 100644 index 000000000..2d952a6e3 --- /dev/null +++ b/include/lttng/tracker.h @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2019 - Jonathan Rajotte-Julien + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License, version 2.1 only, + * as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LTTNG_TRACKER_H +#define LTTNG_TRACKER_H + +#include +#include + +#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, +}; + +enum lttng_tracker_id_type { + LTTNG_ID_UNKNOWN = -1, + LTTNG_ID_ALL = 0, + LTTNG_ID_VALUE = 1, + LTTNG_ID_STRING = 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, +}; + +struct lttng_handle; +struct lttng_tracker_id; + +/* + * Create a tracker id for the passed tracker type. + * Users must set the tracker id using the matching API call. + * + * On success, the caller is responsible for calling lttng_tracker_id_destroy. + * On error, return NULL. + */ +extern struct lttng_tracker_id *lttng_tracker_id_create(void); + +/* + * Configure the tracker id using the numerical representation of the resource + * to be tracked/untracked. + * + * If the tracker id was already configured, calling this function will replace + * the previous configuration and free memory as necessary. + * + * Returns LTTNG_TRACKER_ID_STATUS_OK on success, + * LTTNG_TRACKER_ID_STATUS_INVALID is the passed parameter is invalid. + */ +extern enum lttng_tracker_id_status lttng_tracker_id_set_value( + struct lttng_tracker_id *id, int value); + +/* + * Configure the tracker id using the string representation of the resource to + * be tracked/untracked. + * + * If the tracker id was already configured, calling this function will replace + * the previous configuration and free memory as necessary. + * + * Returns LTTNG_TRACKER_ID_STATUS_OK on success, + * LTTNG_TRACKER_ID_STATUS_INVALID if the passed parameter is invalid. + */ +extern enum lttng_tracker_id_status lttng_tracker_id_set_string( + struct lttng_tracker_id *id, const char *value); + +/* + * Configure the tracker id to track/untrack all resources for the tracker type. + * + * If the tracker id was already configured, calling this function will replace + * the previous configuration and free memory as necessary. + * + * Returns LTTNG_TRACKER_ID_STATUS_OK on success, + * LTTNG_TRACKER_ID_STATUS_INVALID if the passed parameter is invalid. + */ +extern enum lttng_tracker_id_status lttng_tracker_id_set_all( + struct lttng_tracker_id *id); + +/* + * Destroys (frees) a tracker id. + */ +extern void lttng_tracker_id_destroy(struct lttng_tracker_id *id); + +/* + * Returns the type of the tracker id. + */ +extern enum lttng_tracker_id_type lttng_tracker_id_get_type( + const struct lttng_tracker_id *id); + +/* + * Returns the value of the tracker id. + * + * 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. + */ +extern enum lttng_tracker_id_status lttng_tracker_id_get_value( + const struct lttng_tracker_id *id, int *value); + +/* + * Returns the string representation of the tracker id. + * + * 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. + */ +extern enum lttng_tracker_id_status lttng_tracker_id_get_string( + const struct lttng_tracker_id *id, const char **value); + +/* + * Destroys (frees) an array of tracker id. + */ +extern void lttng_tracker_ids_destroy( + struct lttng_tracker_id **ids, size_t nr_ids); + +/* + * Add ID to session tracker. + * + * tracker_type is the type of tracker. + * id is the lttng_tracker_type to track. + * + * Returns 0 on success else a negative LTTng error code. + */ +extern int lttng_track_id(struct lttng_handle *handle, + enum lttng_tracker_type tracker_type, + const struct lttng_tracker_id *id); + +/* + * Remove ID from session tracker. + * + * 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. + */ +extern int lttng_untrack_id(struct lttng_handle *handle, + enum lttng_tracker_type tracker_type, + const struct lttng_tracker_id *id); + +/* + * List IDs in the tracker. + * + * tracker_type is the type of tracker. + * ids is set to an allocated array of IDs currently tracked. + * On success, ids must be freed using lttng_tracker_id_destroy on each + * constituent of the returned array or using lttng_tracker_ids_destroy. + * nr_ids is set to the number of entries contained by the ids array. + * + * Returns 0 on success, else a negative LTTng error code. + */ +extern int lttng_list_tracker_ids(struct lttng_handle *handle, + enum lttng_tracker_type tracker_type, + struct lttng_tracker_id ***ids, + size_t *nr_ids); + +/* + * Backward compatibility. + * Add PID to session tracker. + * + * A pid argument >= 0 adds the PID to the session tracker. + * A pid argument of -1 means "track all PIDs". + * + * Returns 0 on success else a negative LTTng error code. + */ +extern int lttng_track_pid(struct lttng_handle *handle, int pid); + +/* + * Backward compatibility. + * Remove PID from session tracker. + * + * A pid argument >= 0 removes the PID from the session tracker. + * A pid argument of -1 means "untrack all PIDs". + * + * Returns 0 on success else a negative LTTng error code. + */ +extern int lttng_untrack_pid(struct lttng_handle *handle, int pid); + +/* + * Backward compatibility + * List PIDs in the tracker. + * + * enabled is set to whether the PID tracker is enabled. + * pids is set to an allocated array of PIDs currently tracked. On + * success, pids must be freed by the caller. + * nr_pids is set to the number of entries contained by the pids array. + * + * Returns 0 on success, else a negative LTTng error code. + */ +extern int lttng_list_tracker_pids(struct lttng_handle *handle, + int *enabled, + int32_t **pids, + size_t *nr_pids); + +#ifdef __cplusplus +} +#endif + +#endif /* LTTNG_TRACKER_H */ diff --git a/src/bin/lttng-sessiond/client.c b/src/bin/lttng-sessiond/client.c index ae027d5e0..2c7bd4787 100644 --- a/src/bin/lttng-sessiond/client.c +++ b/src/bin/lttng-sessiond/client.c @@ -1207,98 +1207,139 @@ error_add_context: } case LTTNG_TRACK_ID: { - struct lttng_tracker_id id; + struct lttng_tracker_id *id = NULL; + enum lttng_tracker_id_status status; - memset(&id, 0, sizeof(id)); - id.type = cmd_ctx->lsm->u.id_tracker.id_type; - switch (id.type) { + id = lttng_tracker_id_create(); + if (!id) { + ret = LTTNG_ERR_NOMEM; + 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: - id.value = cmd_ctx->lsm->u.id_tracker.u.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; - id.string = zmalloc(var_len); - if (!id.string) { + string = zmalloc(var_len); + if (!string) { + lttng_tracker_id_destroy(id); ret = LTTNG_ERR_NOMEM; goto error; } DBG("Receiving var len tracker id string from client"); - ret = lttcomm_recv_unix_sock(*sock, id.string, var_len); + ret = lttcomm_recv_unix_sock(*sock, string, var_len); if (ret <= 0) { DBG("Nothing received"); *sock_error = 1; - free(id.string); + free(string); + lttng_tracker_id_destroy(id); ret = LTTNG_ERR_INVALID; goto error; } - if (strnlen(id.string, var_len) != var_len - 1) { + if (strnlen(string, var_len) != var_len - 1) { DBG("String received as tracker ID is not NULL-terminated"); - free(id.string); + free(string); + lttng_tracker_id_destroy(id); ret = LTTNG_ERR_INVALID; goto error; } + + status = lttng_tracker_id_set_string(id, string); + free(string); break; } default: + lttng_tracker_id_destroy(id); ret = LTTNG_ERR_INVALID; goto error; } + + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ERR("Invalid value for tracker id"); + ret = LTTNG_ERR_INVALID; + lttng_tracker_id_destroy(id); + goto error; + } + ret = cmd_track_id(cmd_ctx->session, cmd_ctx->lsm->u.id_tracker.tracker_type, - cmd_ctx->lsm->domain.type, &id); - free(id.string); + cmd_ctx->lsm->domain.type, id); + lttng_tracker_id_destroy(id); break; } case LTTNG_UNTRACK_ID: { - struct lttng_tracker_id id; + struct lttng_tracker_id *id = NULL; + enum lttng_tracker_id_status status; + + id = lttng_tracker_id_create(); - memset(&id, 0, sizeof(id)); - id.type = cmd_ctx->lsm->u.id_tracker.id_type; - switch (id.type) { + 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: - id.value = cmd_ctx->lsm->u.id_tracker.u.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; - id.string = zmalloc(var_len); - if (!id.string) { + 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, id.string, var_len); + ret = lttcomm_recv_unix_sock(*sock, string, var_len); if (ret <= 0) { DBG("Nothing received"); *sock_error = 1; - free(id.string); + lttng_tracker_id_destroy(id); + free(string); ret = LTTNG_ERR_INVALID; goto error; } - if (strnlen(id.string, var_len) != var_len - 1) { + if (strnlen(string, var_len) != var_len - 1) { DBG("String received as tracker ID is not NULL-terminated"); - free(id.string); + lttng_tracker_id_destroy(id); + free(string); ret = LTTNG_ERR_INVALID; goto error; } + status = lttng_tracker_id_set_string(id, string); + free(string); break; } default: + lttng_tracker_id_destroy(id); ret = LTTNG_ERR_INVALID; goto error; } + + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ERR("Invalid tracker id"); + lttng_tracker_id_destroy(id); + ret = LTTNG_ERR_INVALID; + goto error; + } + ret = cmd_untrack_id(cmd_ctx->session, cmd_ctx->lsm->u.id_tracker.tracker_type, - cmd_ctx->lsm->domain.type, &id); - free(id.string); + cmd_ctx->lsm->domain.type, id); + lttng_tracker_id_destroy(id); break; } case LTTNG_ENABLE_EVENT: @@ -1527,7 +1568,7 @@ error_add_context: case LTTNG_LIST_TRACKER_IDS: { struct lttcomm_tracker_command_header cmd_header; - struct lttng_tracker_id *ids = NULL; + struct lttng_tracker_id **ids = NULL; ssize_t nr_ids, i; struct lttng_dynamic_buffer buf; @@ -1543,44 +1584,60 @@ error_add_context: lttng_dynamic_buffer_init(&buf); for (i = 0; i < nr_ids; i++) { - struct lttng_tracker_id *id = &ids[i]; + struct lttng_tracker_id *id = ids[i]; struct lttcomm_tracker_id_header id_hdr; size_t var_data_len = 0; + enum lttng_tracker_id_status status; + const char *string; + int value; memset(&id_hdr, 0, sizeof(id_hdr)); - id_hdr.type = id->type; - switch (id->type) { + id_hdr.type = lttng_tracker_id_get_type(id); + switch (id_hdr.type) { case LTTNG_ID_ALL: break; case LTTNG_ID_VALUE: - id_hdr.u.value = id->value; + status = lttng_tracker_id_get_value(id, &value); + id_hdr.u.value = value; + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ret = LTTNG_ERR_INVALID; + goto error_list_tracker; + } break; case LTTNG_ID_STRING: + status = lttng_tracker_id_get_string( + id, &string); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ret = LTTNG_ERR_INVALID; + goto error_list_tracker; + } + id_hdr.u.var_data_len = var_data_len = - strlen(id->string) + 1; + strlen(string) + 1; break; default: ret = LTTNG_ERR_INVALID; - goto error; + goto error_list_tracker; } ret = lttng_dynamic_buffer_append( &buf, &id_hdr, sizeof(id_hdr)); if (ret) { ret = LTTNG_ERR_NOMEM; - goto error; + goto error_list_tracker; } ret = lttng_dynamic_buffer_append( - &buf, id->string, var_data_len); + &buf, string, var_data_len); if (ret) { ret = LTTNG_ERR_NOMEM; - goto error; + goto error_list_tracker; } - free(id->string); } cmd_header.nb_tracker_id = nr_ids; ret = setup_lttng_msg(cmd_ctx, buf.data, buf.size, &cmd_header, sizeof(cmd_header)); + error_list_tracker: + lttng_tracker_ids_destroy(ids, nr_ids); free(ids); lttng_dynamic_buffer_reset(&buf); if (ret < 0) { diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index f152c1c2e..b668b56d4 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -2584,7 +2584,7 @@ ssize_t cmd_list_syscalls(struct lttng_event **events) ssize_t cmd_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_session *session, enum lttng_domain_type domain, - struct lttng_tracker_id **ids) + struct lttng_tracker_id ***ids) { int ret; ssize_t nr_pids = 0; diff --git a/src/bin/lttng-sessiond/cmd.h b/src/bin/lttng-sessiond/cmd.h index 9329f42cf..ee4bf65e7 100644 --- a/src/bin/lttng-sessiond/cmd.h +++ b/src/bin/lttng-sessiond/cmd.h @@ -117,7 +117,7 @@ ssize_t cmd_list_syscalls(struct lttng_event **events); ssize_t cmd_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_session *session, enum lttng_domain_type domain, - struct lttng_tracker_id **ids); + struct lttng_tracker_id ***ids); int cmd_data_pending(struct ltt_session *session); diff --git a/src/bin/lttng-sessiond/kernel.c b/src/bin/lttng-sessiond/kernel.c index 113937536..c5fd30b7e 100644 --- a/src/bin/lttng-sessiond/kernel.c +++ b/src/bin/lttng-sessiond/kernel.c @@ -707,8 +707,8 @@ int kernel_track_id(enum lttng_tracker_type tracker_type, { int ret, value; struct lttng_tracker_list *tracker_list; - struct lttng_tracker_id *saved_ids; - ssize_t saved_ids_count, i; + struct lttng_tracker_id **saved_ids; + ssize_t saved_ids_count; ret = lttng_tracker_id_lookup_string(tracker_type, id, &value); if (ret != LTTNG_OK) { @@ -813,9 +813,7 @@ int kernel_track_id(enum lttng_tracker_type tracker_type, ERR("Error on tracker add error handling.\n"); } end: - for (i = 0; i < saved_ids_count; i++) { - free(saved_ids[i].string); - } + lttng_tracker_ids_destroy(saved_ids, saved_ids_count); free(saved_ids); return ret; } @@ -826,8 +824,8 @@ int kernel_untrack_id(enum lttng_tracker_type tracker_type, { int ret, value; struct lttng_tracker_list *tracker_list; - struct lttng_tracker_id *saved_ids; - ssize_t saved_ids_count, i; + struct lttng_tracker_id **saved_ids; + ssize_t saved_ids_count; ret = lttng_tracker_id_lookup_string(tracker_type, id, &value); if (ret != LTTNG_OK) { @@ -933,9 +931,7 @@ int kernel_untrack_id(enum lttng_tracker_type tracker_type, ERR("Error on tracker remove error handling.\n"); } end: - for (i = 0; i < saved_ids_count; i++) { - free(saved_ids[i].string); - } + lttng_tracker_ids_destroy(saved_ids, saved_ids_count); free(saved_ids); return ret; } @@ -945,7 +941,7 @@ end: */ ssize_t kernel_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_kernel_session *session, - struct lttng_tracker_id **_ids) + struct lttng_tracker_id ***_ids) { struct lttng_tracker_list *tracker_list; diff --git a/src/bin/lttng-sessiond/kernel.h b/src/bin/lttng-sessiond/kernel.h index cf91cab1b..64d95d235 100644 --- a/src/bin/lttng-sessiond/kernel.h +++ b/src/bin/lttng-sessiond/kernel.h @@ -74,7 +74,7 @@ enum lttng_error_code kernel_clear_session(struct ltt_session *session); int init_kernel_workarounds(void); ssize_t kernel_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_kernel_session *session, - struct lttng_tracker_id **_ids); + struct lttng_tracker_id ***_ids); int kernel_supports_ring_buffer_snapshot_sample_positions(void); int kernel_supports_ring_buffer_packet_sequence_number(void); int init_kernel_tracer(void); diff --git a/src/bin/lttng-sessiond/save.c b/src/bin/lttng-sessiond/save.c index 59715d0b9..83019842d 100644 --- a/src/bin/lttng-sessiond/save.c +++ b/src/bin/lttng-sessiond/save.c @@ -1837,8 +1837,12 @@ static int save_id_tracker(struct config_writer *writer, { int ret = LTTNG_OK; ssize_t nr_ids = 0, i; - struct lttng_tracker_id *ids = NULL; + struct lttng_tracker_id **ids = NULL; const char *element_id_tracker, *element_target_id, *element_id; + struct lttng_tracker_id *id; + enum lttng_tracker_id_status status; + int value; + const char *string; switch (tracker_type) { case LTTNG_TRACKER_PID: @@ -1905,7 +1909,7 @@ static int save_id_tracker(struct config_writer *writer, goto end; } - if (nr_ids == 1 && ids[0].type == LTTNG_ID_ALL) { + if (nr_ids == 1 && lttng_tracker_id_get_type(ids[0]) == LTTNG_ID_ALL) { /* Tracking all, nothing to output. */ ret = LTTNG_OK; goto end; @@ -1940,7 +1944,8 @@ static int save_id_tracker(struct config_writer *writer, } else { /* Tracking list. */ for (i = 0; i < nr_ids; i++) { - switch (ids[i].type) { + id = ids[i]; + switch (lttng_tracker_id_get_type(id)) { case LTTNG_ID_VALUE: ret = config_writer_open_element( writer, element_target_id); @@ -1948,9 +1953,9 @@ static int save_id_tracker(struct config_writer *writer, 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, - ids[i].value); + writer, element_id, value); break; case LTTNG_ID_STRING: ret = config_writer_open_element( @@ -1959,9 +1964,10 @@ static int save_id_tracker(struct config_writer *writer, 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, - ids[i].string); + config_element_name, string); break; default: /* Unexpected. */ @@ -1972,6 +1978,10 @@ static int save_id_tracker(struct config_writer *writer, ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } /* /$element_target_id */ ret = config_writer_close_element(writer); @@ -1998,6 +2008,7 @@ static int save_id_tracker(struct config_writer *writer, ret = LTTNG_OK; end: + lttng_tracker_ids_destroy(ids, nr_ids); free(ids); return ret; } diff --git a/src/bin/lttng-sessiond/trace-ust.c b/src/bin/lttng-sessiond/trace-ust.c index f64f51c28..4a7e26105 100644 --- a/src/bin/lttng-sessiond/trace-ust.c +++ b/src/bin/lttng-sessiond/trace-ust.c @@ -918,8 +918,8 @@ int trace_ust_track_id(enum lttng_tracker_type tracker_type, struct ust_id_tracker *id_tracker; struct lttng_tracker_list *tracker_list; int value; - struct lttng_tracker_id *saved_ids; - ssize_t saved_ids_count, i; + struct lttng_tracker_id **saved_ids; + ssize_t saved_ids_count; if (tracker_type == LTTNG_TRACKER_PID) { DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain."); @@ -1002,9 +1002,7 @@ end_restore: ERR("Error on tracker add error handling.\n"); } end: - for (i = 0; i < saved_ids_count; i++) { - free(saved_ids[i].string); - } + lttng_tracker_ids_destroy(saved_ids, saved_ids_count); free(saved_ids); return retval; } @@ -1021,8 +1019,8 @@ int trace_ust_untrack_id(enum lttng_tracker_type tracker_type, struct ust_id_tracker *id_tracker; struct lttng_tracker_list *tracker_list; int value; - struct lttng_tracker_id *saved_ids; - ssize_t saved_ids_count, i; + struct lttng_tracker_id **saved_ids; + ssize_t saved_ids_count; if (tracker_type == LTTNG_TRACKER_PID) { DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain."); @@ -1107,9 +1105,7 @@ end_restore: ERR("Error on tracker remove error handling.\n"); } end: - for (i = 0; i < saved_ids_count; i++) { - free(saved_ids[i].string); - } + lttng_tracker_ids_destroy(saved_ids, saved_ids_count); free(saved_ids); return retval; } @@ -1119,7 +1115,7 @@ end: */ ssize_t trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_ust_session *session, - struct lttng_tracker_id **_ids) + struct lttng_tracker_id ***_ids) { struct lttng_tracker_list *tracker_list; diff --git a/src/bin/lttng-sessiond/trace-ust.h b/src/bin/lttng-sessiond/trace-ust.h index 1f6f534fe..2d0b042e5 100644 --- a/src/bin/lttng-sessiond/trace-ust.h +++ b/src/bin/lttng-sessiond/trace-ust.h @@ -240,7 +240,7 @@ int trace_ust_id_tracker_lookup(enum lttng_tracker_type tracker_type, ssize_t trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_ust_session *session, - struct lttng_tracker_id **_ids); + struct lttng_tracker_id ***_ids); #else /* HAVE_LIBLTTNG_UST_CTL */ diff --git a/src/bin/lttng-sessiond/tracker.c b/src/bin/lttng-sessiond/tracker.c index af527b4fd..909a04845 100644 --- a/src/bin/lttng-sessiond/tracker.c +++ b/src/bin/lttng-sessiond/tracker.c @@ -27,6 +27,7 @@ #include #include #include +#include #define FALLBACK_USER_BUFLEN 16384 #define FALLBACK_GROUP_BUFLEN 16384 @@ -60,53 +61,42 @@ static int match_tracker_key(struct cds_lfht_node *node, const void *key) tracker_node = caa_container_of( node, struct lttng_tracker_list_node, ht_node); - if (tracker_node->id.type != tracker_key->type) { - return 0; - } - switch (tracker_node->id.type) { - case LTTNG_ID_ALL: - return 1; - case LTTNG_ID_VALUE: - if (tracker_node->id.value != tracker_key->value) { - return 0; - } - break; - case LTTNG_ID_STRING: - if (strcmp(tracker_node->id.string, tracker_key->string) != 0) { - return 0; - } - break; - default: - return 0; - } - return 1; + + return lttng_tracker_id_is_equal(tracker_node->id, tracker_key); } static unsigned long hash_tracker_key( const struct lttng_tracker_id *tracker_key) { 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 (tracker_key->type) { + switch (type) { case LTTNG_ID_ALL: break; case LTTNG_ID_VALUE: key_hash ^= hash_key_ulong( - (void *) (unsigned long) tracker_key->value, - lttng_ht_seed); + (void *) (unsigned long) value, lttng_ht_seed); break; case LTTNG_ID_STRING: - key_hash ^= hash_key_str(tracker_key->string, lttng_ht_seed); + key_hash ^= hash_key_str(string, lttng_ht_seed); break; case LTTNG_ID_UNKNOWN: break; } - key_hash ^= hash_key_ulong((void *) (unsigned long) tracker_key->type, - lttng_ht_seed); + key_hash ^= hash_key_ulong( + (void *) (unsigned long) type, lttng_ht_seed); return key_hash; } -static struct lttng_tracker_id *lttng_tracker_list_lookup( +static struct lttng_tracker_id **lttng_tracker_list_lookup( const struct lttng_tracker_list *tracker_list, const struct lttng_tracker_id *key) { @@ -130,7 +120,7 @@ static void destroy_list_node_rcu(struct rcu_head *head) struct lttng_tracker_list_node *n = caa_container_of( head, struct lttng_tracker_list_node, rcu_head); - free(n->id.string); + lttng_tracker_id_destroy(n->id); free(n); } @@ -161,14 +151,15 @@ static void lttng_tracker_list_reset(struct lttng_tracker_list *tracker_list) int lttng_tracker_list_add(struct lttng_tracker_list *tracker_list, const struct lttng_tracker_id *_id) { - struct lttng_tracker_id *id; - struct lttng_tracker_list_node *n; + struct lttng_tracker_id **id; + struct lttng_tracker_list_node *n = NULL; int ret; - if (_id->type == LTTNG_ID_ALL) { + if (lttng_tracker_id_get_type(_id) == LTTNG_ID_ALL) { /* Track all, so remove each individual item. */ lttng_tracker_list_reset(tracker_list); - return LTTNG_OK; + ret = LTTNG_OK; + goto error; } rcu_read_lock(); id = lttng_tracker_list_lookup(tracker_list, _id); @@ -178,28 +169,26 @@ int lttng_tracker_list_add(struct lttng_tracker_list *tracker_list, */ rcu_read_unlock(); if (id) { - return LTTNG_ERR_ID_TRACKED; + ret = LTTNG_ERR_ID_TRACKED; + goto error; } n = zmalloc(sizeof(*n)); if (!n) { - return LTTNG_ERR_NOMEM; + ret = LTTNG_ERR_NOMEM; + goto error; } - n->id = *_id; - if (_id->type == LTTNG_ID_STRING) { - n->id.string = strdup(_id->string); - if (!n->id.string) { - ret = LTTNG_ERR_NOMEM; - goto error; - } - } else { - n->id.string = NULL; + + n->id = lttng_tracker_id_copy(_id); + if (!n->id) { + ret = LTTNG_ERR_NOMEM; + goto error; } 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); + cds_lfht_add(tracker_list->ht, hash_tracker_key(n->id), &n->ht_node); rcu_read_unlock(); return LTTNG_OK; @@ -217,10 +206,10 @@ int lttng_tracker_list_remove(struct lttng_tracker_list *tracker_list, const struct lttng_tracker_id *_id) { enum lttng_error_code ret = LTTNG_OK; - struct lttng_tracker_id *id; + struct lttng_tracker_id **id; struct lttng_tracker_list_node *n; - if (_id->type == LTTNG_ID_ALL) { + if (lttng_tracker_id_get_type(_id) == LTTNG_ID_ALL) { /* Untrack all. */ lttng_tracker_list_reset(tracker_list); /* Set state to "track none". */ @@ -380,14 +369,26 @@ int lttng_tracker_id_lookup_string(enum lttng_tracker_type tracker_type, const struct lttng_tracker_id *id, int *result) { - switch (id->type) { + 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: @@ -396,11 +397,11 @@ int lttng_tracker_id_lookup_string(enum lttng_tracker_type tracker_type, case LTTNG_TRACKER_UID: case LTTNG_TRACKER_VUID: DBG("Lookup of tracker UID/VUID by name."); - return lttng_lookup_user(id->string, result); + 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(id->string, result); + return lttng_lookup_group(string, result); default: return LTTNG_ERR_INVALID; } @@ -412,14 +413,15 @@ int lttng_tracker_id_lookup_string(enum lttng_tracker_type tracker_type, /* * Protected by session mutex held by caller. - * On success, _ids and the strings it contains must be freed by caller. + * On success, _ids and the ids it contains must be freed by the caller. */ ssize_t lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list, - struct lttng_tracker_id **_ids) + struct lttng_tracker_id ***_ids) { struct lttng_tracker_list_node *n; ssize_t count = 0, i = 0, retval = 0; - struct lttng_tracker_id *ids; + struct lttng_tracker_id **ids; + enum lttng_tracker_id_status status; switch (tracker_list->state) { case LTTNG_TRACK_LIST: @@ -435,14 +437,10 @@ ssize_t lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list, } cds_list_for_each_entry ( n, &tracker_list->list_head, list_node) { - ids[i].type = n->id.type; - ids[i].value = n->id.value; - if (ids[i].type == LTTNG_ID_STRING) { - ids[i].string = strdup(n->id.string); - if (!ids[i].string) { - retval = -LTTNG_ERR_NOMEM; - goto error; - } + ids[i] = lttng_tracker_id_copy(n->id); + if (!ids[i]) { + retval = -LTTNG_ERR_NOMEM; + goto error; } i++; } @@ -456,7 +454,13 @@ ssize_t lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list, retval = -LTTNG_ERR_NOMEM; goto end; } - ids->type = LTTNG_TRACK_ALL; + ids[0] = lttng_tracker_id_create(); + status = lttng_tracker_id_set_all(ids[0]); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ERR("Invalid tracker id for track all"); + retval = -LTTNG_ERR_INVALID; + goto error; + } *_ids = ids; retval = 1; break; @@ -469,21 +473,19 @@ end: return retval; error: - for (i = 0; i < count; i++) { - free(ids[i].string); - } + lttng_tracker_ids_destroy(ids, count); free(ids); return retval; } int lttng_tracker_id_set_list(struct lttng_tracker_list *tracker_list, - struct lttng_tracker_id *_ids, + struct lttng_tracker_id **_ids, size_t count) { size_t i; lttng_tracker_list_reset(tracker_list); - if (count == 1 && _ids[0].type == LTTNG_ID_ALL) { + if (count == 1 && lttng_tracker_id_get_type(_ids[0])) { /* Track all. */ return LTTNG_OK; } @@ -493,7 +495,7 @@ int lttng_tracker_id_set_list(struct lttng_tracker_list *tracker_list, return LTTNG_OK; } for (i = 0; i < count; i++) { - struct lttng_tracker_id *id = &_ids[i]; + struct lttng_tracker_id *id = _ids[i]; int ret; ret = lttng_tracker_list_add(tracker_list, id); diff --git a/src/bin/lttng-sessiond/tracker.h b/src/bin/lttng-sessiond/tracker.h index 1df4a0ce7..812b3b127 100644 --- a/src/bin/lttng-sessiond/tracker.h +++ b/src/bin/lttng-sessiond/tracker.h @@ -18,7 +18,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include +#include #include #include #include @@ -31,7 +31,7 @@ enum lttng_tracker_list_state { /* Tracker ID */ struct lttng_tracker_list_node { - struct lttng_tracker_id id; + struct lttng_tracker_id *id; struct cds_list_head list_node; struct cds_lfht_node ht_node; @@ -57,9 +57,9 @@ int lttng_tracker_id_lookup_string(enum lttng_tracker_type tracker_type, const struct lttng_tracker_id *id, int *result); ssize_t lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list, - struct lttng_tracker_id **_ids); + struct lttng_tracker_id ***_ids); int lttng_tracker_id_set_list(struct lttng_tracker_list *tracker_list, - struct lttng_tracker_id *_ids, + struct lttng_tracker_id **_ids, size_t count); #endif /* _LTT_TRACKER_H */ diff --git a/src/bin/lttng/commands/list.c b/src/bin/lttng/commands/list.c index 226eb4c87..49470ab86 100644 --- a/src/bin/lttng/commands/list.c +++ b/src/bin/lttng/commands/list.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "../command.h" @@ -1538,14 +1539,14 @@ static int list_tracker_ids(enum lttng_tracker_type tracker_type) { int ret = 0; int enabled = 1; - struct lttng_tracker_id *ids = NULL; + struct lttng_tracker_id **ids = NULL; size_t nr_ids, i; ret = lttng_list_tracker_ids(handle, tracker_type, &ids, &nr_ids); if (ret) { return ret; } - if (nr_ids == 1 && ids[0].type == LTTNG_ID_ALL) { + if (nr_ids == 1 && lttng_tracker_id_get_type(ids[0]) == LTTNG_ID_ALL) { enabled = 0; } if (enabled) { @@ -1561,23 +1562,49 @@ static int list_tracker_ids(enum lttng_tracker_type tracker_type) } for (i = 0; i < nr_ids; i++) { - struct lttng_tracker_id *id = &ids[i]; + struct lttng_tracker_id *id = ids[i]; + enum lttng_tracker_id_status status; + int value; + const char *value_string; + + 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; + } + + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ERR("Invalid state for tracker id"); + ret = CMD_ERROR; + goto end; + } if (i) { _MSG(","); } - switch (id->type) { + switch (lttng_tracker_id_get_type(id)) { case LTTNG_ID_ALL: _MSG(" *"); break; case LTTNG_ID_VALUE: - _MSG(" %d", ids[i].value); + _MSG(" %d", value); break; case LTTNG_ID_STRING: - _MSG(" %s", ids[i].string); + _MSG(" %s", value_string); break; case LTTNG_ID_UNKNOWN: - return CMD_ERROR; + ERR("Invalid state for tracker id"); + ret = CMD_ERROR; + goto end; } /* Mi */ @@ -1600,10 +1627,7 @@ static int list_tracker_ids(enum lttng_tracker_type tracker_type) } } end: - for (i = 0; i < nr_ids; i++) { - free(ids[i].string); - } - free(ids); + lttng_tracker_ids_destroy(ids, nr_ids); return ret; } diff --git a/src/bin/lttng/commands/track-untrack.c b/src/bin/lttng/commands/track-untrack.c index 25b4461f6..c54b64078 100644 --- a/src/bin/lttng/commands/track-untrack.c +++ b/src/bin/lttng/commands/track-untrack.c @@ -56,7 +56,7 @@ struct opt_type { struct id_list { size_t nr; - struct lttng_tracker_id *array; + struct lttng_tracker_id **array; }; static char *opt_session_name; @@ -100,7 +100,7 @@ static struct poptOption long_options[] = { static struct id_list *alloc_id_list(size_t nr_items) { struct id_list *id_list; - struct lttng_tracker_id *items; + struct lttng_tracker_id **items; id_list = zmalloc(sizeof(*id_list)); if (!id_list) { @@ -128,15 +128,16 @@ static void free_id_list(struct id_list *list) } nr_items = list->nr; for (i = 0; i < nr_items; i++) { - struct lttng_tracker_id *item = &list->array[i]; - - free(item->string); + struct lttng_tracker_id *item = list->array[i]; + lttng_tracker_id_destroy(item); } free(list); } -static int parse_id_string( - const char *_id_string, int all, struct id_list **_id_list) +static int parse_id_string(const char *_id_string, + int all, + struct id_list **_id_list, + enum lttng_tracker_type tracker_type) { const char *one_id_str; char *iter; @@ -157,14 +158,28 @@ static int parse_id_string( goto error; } if (all) { - /* Empty ID string means all IDs */ + 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].type = LTTNG_ID_ALL; + + 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; } @@ -230,20 +245,30 @@ static int parse_id_string( 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; + } - item = &id_list->array[count++]; + id_list->array[count++] = item; if (isdigit(one_id_str[0])) { unsigned long v; v = strtoul(one_id_str, NULL, 10); - item->type = LTTNG_ID_VALUE; - item->value = (int) v; + 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 { - item->type = LTTNG_ID_STRING; - item->string = strdup(one_id_str); - if (!item->string) { - PERROR("Failed to allocate ID string"); + 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; } @@ -254,11 +279,12 @@ static int parse_id_string( } assign: + /* SUCCESS */ *_id_list = id_list; - goto end; /* SUCCESS */ + goto end; - /* ERROR */ error: + /* ERROR */ free_id_list(id_list); end: free(id_string); @@ -365,7 +391,7 @@ static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type, retval = CMD_ERROR; goto end; } - ret = parse_id_string(id_string, all, &id_list); + 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; @@ -387,22 +413,51 @@ static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type, } for (i = 0; i < id_list->nr; i++) { - struct lttng_tracker_id *item = &id_list->array[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; + } - switch (item->type) { + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ERR("Tracker id object is in an invalid state"); + retval = CMD_ERROR; + 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, item->value); + DBG("%s ID %d", cmd_str, value); break; case LTTNG_ID_STRING: - DBG("%s ID '%s'", cmd_str, item->string); + DBG("%s ID '%s'", cmd_str, value_string); break; default: retval = CMD_ERROR; goto end; } + ret = cmd_func(handle, tracker_type, item); if (ret) { char *msg = NULL; @@ -425,7 +480,7 @@ static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type, break; } if (msg) { - switch (item->type) { + switch (type) { case LTTNG_ID_ALL: WARN("All %ss %s in session %s", tracker_str, msg, @@ -433,14 +488,13 @@ static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type, break; case LTTNG_ID_VALUE: WARN("%s %i %s in session %s", - tracker_str, - item->value, msg, + tracker_str, value, msg, session_name); break; case LTTNG_ID_STRING: WARN("%s '%s' %s in session %s", tracker_str, - item->string, msg, + value_string, msg, session_name); break; default: @@ -449,19 +503,18 @@ static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type, } } } else { - switch (item->type) { + switch (type) { case LTTNG_ID_ALL: MSG("All %ss %sed in session %s", tracker_str, cmd_str, session_name); break; case LTTNG_ID_VALUE: MSG("%s %i %sed in session %s", tracker_str, - item->value, cmd_str, - session_name); + value, cmd_str, session_name); break; case LTTNG_ID_STRING: MSG("%s '%s' %sed in session %s", tracker_str, - item->string, cmd_str, + value_string, cmd_str, session_name); break; default: diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 95935b76e..e7ceefe47 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -62,6 +62,7 @@ libcommon_la_SOURCES = \ userspace-probe.c \ utils.c utils.h \ uuid.c uuid.h \ + tracker.c \ waiter.c waiter.h if HAVE_ELF_H diff --git a/src/common/config/session-config.c b/src/common/config/session-config.c index e625f316a..695142a29 100644 --- a/src/common/config/session-config.c +++ b/src/common/config/session-config.c @@ -2745,6 +2745,7 @@ 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; assert(handle); assert(id_tracker_node); @@ -2774,11 +2775,21 @@ 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; + 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; + } - tracker_id.type = LTTNG_ID_ALL; /* The session is explicitly set to target nothing. */ - ret = lttng_untrack_id(handle, tracker_type, &tracker_id); + ret = lttng_untrack_id(handle, tracker_type, tracker_id); + lttng_tracker_id_destroy(tracker_id); if (ret) { goto end; } @@ -2796,7 +2807,7 @@ static int process_id_tracker_node(xmlNodePtr id_tracker_node, element_id_alias))) { int64_t id; xmlChar *content = NULL; - struct lttng_tracker_id tracker_id; + struct lttng_tracker_id *tracker_id = NULL; content = xmlNodeGetContent(node); if (!content) { @@ -2811,10 +2822,23 @@ static int process_id_tracker_node(xmlNodePtr id_tracker_node, goto end; } - tracker_id.type = LTTNG_ID_VALUE; - tracker_id.value = (int) id; + tracker_id = lttng_tracker_id_create(); + if (tracker_id == NULL) { + ret = LTTNG_ERR_NOMEM; + goto end; + } + + 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); + tracker_id); + lttng_tracker_id_destroy(tracker_id); if (ret) { goto end; } @@ -2822,17 +2846,31 @@ static int process_id_tracker_node(xmlNodePtr id_tracker_node, if (element_name && !strcmp((const char *) node->name, element_name)) { xmlChar *content = NULL; - struct lttng_tracker_id tracker_id; + struct lttng_tracker_id *tracker_id = NULL; content = xmlNodeGetContent(node); if (!content) { ret = LTTNG_ERR_LOAD_INVALID_CONFIG; goto end; } - tracker_id.type = LTTNG_ID_STRING; - tracker_id.string = (char *) content; + + 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; + goto end; + } + ret = lttng_track_id(handle, tracker_type, - &tracker_id); + tracker_id); + lttng_tracker_id_destroy(tracker_id); free(content); if (ret) { goto end; diff --git a/src/common/mi-lttng.c b/src/common/mi-lttng.c index f884f9385..7b0d9cf02 100644 --- a/src/common/mi-lttng.c +++ b/src/common/mi-lttng.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "mi-lttng.h" @@ -1666,6 +1667,9 @@ int mi_lttng_id_target(struct mi_writer *writer, { int ret; const char *element_id_tracker, *element_target_id; + enum lttng_tracker_id_status status; + int value; + const char *string; ret = get_tracker_elements( tracker_type, &element_id_tracker, &element_target_id); @@ -1673,7 +1677,7 @@ int mi_lttng_id_target(struct mi_writer *writer, return ret; } - switch (id->type) { + switch (lttng_tracker_id_get_type(id)) { case LTTNG_ID_ALL: ret = mi_lttng_writer_open_element(writer, element_target_id); if (ret) { @@ -1702,8 +1706,15 @@ int mi_lttng_id_target(struct mi_writer *writer, if (ret) { goto end; } + + status = lttng_tracker_id_get_value(id, &value); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ret = -1; + goto end; + } + ret = mi_lttng_writer_write_element_signed_int( - writer, config_element_id, id->value); + writer, config_element_id, value); if (ret) { goto end; } @@ -1721,8 +1732,15 @@ int mi_lttng_id_target(struct mi_writer *writer, if (ret) { goto end; } + + status = lttng_tracker_id_get_string(id, &string); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ret = -1; + goto end; + } + ret = mi_lttng_writer_write_element_string( - writer, config_element_name, id->string); + writer, config_element_name, string); if (ret) { goto end; } diff --git a/src/common/tracker.c b/src/common/tracker.c new file mode 100644 index 000000000..f8a4fba0f --- /dev/null +++ b/src/common/tracker.c @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2019 - Jonathan Rajotte-Julien + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License, version 2.1 only, + * as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct lttng_tracker_id *lttng_tracker_id_create(void) +{ + struct lttng_tracker_id *id; + + id = zmalloc(sizeof(*id)); + if (!id) { + goto error; + } + + id->type = LTTNG_ID_UNKNOWN; + id->string = NULL; + id->value = -1; + return id; +error: + lttng_tracker_id_destroy(id); + return NULL; +} + +enum lttng_tracker_id_status lttng_tracker_id_set_value( + struct lttng_tracker_id *id, int value) +{ + assert(id); + + if (value < 0) { + return LTTNG_TRACKER_ID_STATUS_INVALID; + } + + id->type = LTTNG_ID_VALUE; + id->value = value; + return LTTNG_TRACKER_ID_STATUS_OK; +} + +enum lttng_tracker_id_status lttng_tracker_id_set_string( + struct lttng_tracker_id *id, const char *value) +{ + assert(id); + assert(value); + + id->type = LTTNG_ID_STRING; + id->string = strdup(value); + if (id->string == NULL) { + /* No memory left */ + goto error; + } + + return LTTNG_TRACKER_ID_STATUS_OK; +error: + return LTTNG_TRACKER_ID_STATUS_INVALID; +} + +enum lttng_tracker_id_status lttng_tracker_id_set_all( + struct lttng_tracker_id *id) +{ + assert(id); + + id->type = LTTNG_ID_ALL; + + return LTTNG_TRACKER_ID_STATUS_OK; +} + +void lttng_tracker_id_destroy(struct lttng_tracker_id *id) +{ + if (id == NULL) { + return; + } + + if (id->string != NULL) { + free(id->string); + } + + free(id); +} + +void lttng_tracker_ids_destroy(struct lttng_tracker_id **ids, size_t nr_ids) +{ + if (ids == NULL) { + return; + } + + for (int i = 0; i < nr_ids; i++) { + lttng_tracker_id_destroy(ids[i]); + } +} + +enum lttng_tracker_id_type lttng_tracker_id_get_type( + const struct lttng_tracker_id *id) +{ + assert(id); + return id->type; +} + +enum lttng_tracker_id_status lttng_tracker_id_get_value( + const struct lttng_tracker_id *id, int *value) +{ + assert(id); + if (id->type == LTTNG_ID_UNKNOWN) { + return LTTNG_TRACKER_ID_STATUS_UNSET; + } + + if (id->type != LTTNG_ID_VALUE) { + return LTTNG_TRACKER_ID_STATUS_INVALID; + } + + *value = id->value; + return LTTNG_TRACKER_ID_STATUS_OK; +} + +bool lttng_tracker_id_is_equal(const struct lttng_tracker_id *left, + const struct lttng_tracker_id *right) +{ + if (left->type != right->type) { + return 0; + } + + switch (left->type) { + case LTTNG_ID_ALL: + return 1; + case LTTNG_ID_VALUE: + if (left->value != right->value) { + return 0; + } + break; + case LTTNG_ID_STRING: + if (strcmp(left->string, right->string) != 0) { + return 0; + } + break; + default: + /* + * Normally this should return true, but comparing unset tracker + * id is "invalid". + */ + return 0; + } + return 1; +} + +struct lttng_tracker_id *lttng_tracker_id_copy( + const struct lttng_tracker_id *orig) +{ + struct lttng_tracker_id *copy = NULL; + enum lttng_tracker_id_status status; + + copy = lttng_tracker_id_create(); + if (copy == NULL) { + goto error; + } + + switch (orig->type) { + case LTTNG_ID_ALL: + status = lttng_tracker_id_set_all(copy); + break; + case LTTNG_ID_VALUE: + status = lttng_tracker_id_set_value(copy, orig->value); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + goto error; + } + break; + case LTTNG_ID_STRING: + status = lttng_tracker_id_set_string(copy, orig->string); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + goto error; + } + break; + default: + status = LTTNG_TRACKER_ID_STATUS_OK; + break; + } + + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + goto error; + } + + return copy; +error: + lttng_tracker_id_destroy(copy); + return NULL; +} + +enum lttng_tracker_id_status lttng_tracker_id_get_string( + const struct lttng_tracker_id *id, const char **value) +{ + assert(id); + if (id->type == LTTNG_ID_UNKNOWN) { + *value = NULL; + return LTTNG_TRACKER_ID_STATUS_UNSET; + } + + if (id->type != LTTNG_ID_STRING) { + *value = NULL; + return LTTNG_TRACKER_ID_STATUS_INVALID; + } + + *value = id->string; + return LTTNG_TRACKER_ID_STATUS_OK; +} diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 085005c39..406de885c 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -46,6 +46,7 @@ #include #include #include +#include #include "filter/filter-ast.h" #include "filter/filter-parser.h" @@ -1606,98 +1607,6 @@ int lttng_disable_channel(struct lttng_handle *handle, const char *name) return lttng_ctl_ask_sessiond(&lsm, NULL); } -static int lttng_track_untrack_id(struct lttng_handle *handle, - enum lttng_tracker_type tracker_type, - const struct lttng_tracker_id *id, - enum lttcomm_sessiond_command cmd) -{ - struct lttcomm_session_msg lsm; - char *var_data = NULL; - size_t var_data_len = 0; - - /* NULL arguments are forbidden. No default values. */ - if (handle == NULL) { - return -LTTNG_ERR_INVALID; - } - - memset(&lsm, 0, sizeof(lsm)); - - lsm.cmd_type = cmd; - lsm.u.id_tracker.tracker_type = tracker_type; - lsm.u.id_tracker.id_type = id->type; - switch (id->type) { - case LTTNG_ID_ALL: - break; - case LTTNG_ID_VALUE: - lsm.u.id_tracker.u.value = id->value; - break; - case LTTNG_ID_STRING: - var_data = id->string; - var_data_len = strlen(var_data) + 1; /* Includes \0. */ - lsm.u.id_tracker.u.var_len = var_data_len; - break; - default: - return -LTTNG_ERR_INVALID; - } - - COPY_DOMAIN_PACKED(lsm.domain, handle->domain); - - lttng_ctl_copy_string(lsm.session.name, handle->session_name, - sizeof(lsm.session.name)); - - return lttng_ctl_ask_sessiond_varlen_no_cmd_header( - &lsm, var_data, var_data_len, NULL); -} - -/* - * Add ID to session tracker. - * Return 0 on success else a negative LTTng error code. - */ -int lttng_track_id(struct lttng_handle *handle, - enum lttng_tracker_type tracker_type, - const struct lttng_tracker_id *id) -{ - return lttng_track_untrack_id(handle, tracker_type, id, LTTNG_TRACK_ID); -} - -/* - * Remove ID from session tracker. - * Return 0 on success else a negative LTTng error code. - */ -int lttng_untrack_id(struct lttng_handle *handle, - enum lttng_tracker_type tracker_type, - const struct lttng_tracker_id *id) -{ - return lttng_track_untrack_id( - handle, tracker_type, id, LTTNG_UNTRACK_ID); -} - -/* - * Add PID to session tracker. - * Return 0 on success else a negative LTTng error code. - */ -int lttng_track_pid(struct lttng_handle *handle, int pid) -{ - struct lttng_tracker_id id; - - id.type = LTTNG_TRACKER_PID; - id.value = pid; - return lttng_track_id(handle, LTTNG_TRACKER_PID, &id); -} - -/* - * Remove PID from session tracker. - * Return 0 on success else a negative LTTng error code. - */ -int lttng_untrack_pid(struct lttng_handle *handle, int pid) -{ - struct lttng_tracker_id id; - - id.type = LTTNG_TRACKER_PID; - id.value = pid; - return lttng_untrack_id(handle, LTTNG_TRACKER_PID, &id); -} - /* * Lists all available tracepoints of domain. * Sets the contents of the events array. @@ -2923,14 +2832,14 @@ end: * * tracker_type is the type of tracker. * ids is set to an allocated array of IDs currently tracked. On - * success, ids and all the strings it contains must be freed by the caller. + * success, ids and contained ids must be freed/destroy by the caller. * nr_ids is set to the number of entries contained by the ids array. * * Returns 0 on success, else a negative LTTng error code. */ int lttng_list_tracker_ids(struct lttng_handle *handle, enum lttng_tracker_type tracker_type, - struct lttng_tracker_id **_ids, + struct lttng_tracker_id ***_ids, size_t *_nr_ids) { int ret, i; @@ -2939,7 +2848,7 @@ int lttng_list_tracker_ids(struct lttng_handle *handle, char *cmd_payload = NULL, *p; size_t cmd_header_len; size_t nr_ids = 0; - struct lttng_tracker_id *ids = NULL; + struct lttng_tracker_id **ids = NULL; if (handle == NULL) { return -LTTNG_ERR_INVALID; @@ -2978,29 +2887,40 @@ int lttng_list_tracker_ids(struct lttng_handle *handle, for (i = 0; i < nr_ids; i++) { struct lttcomm_tracker_id_header *tracker_id; struct lttng_tracker_id *id; + enum lttng_tracker_id_status status; tracker_id = (struct lttcomm_tracker_id_header *) p; p += sizeof(struct lttcomm_tracker_id_header); - id = &ids[i]; + id = lttng_tracker_id_create(); + if (!id) { + ret = -LTTNG_ERR_NOMEM; + goto error; + } - id->type = tracker_id->type; switch (tracker_id->type) { case LTTNG_ID_ALL: + status = lttng_tracker_id_set_all(id); break; case LTTNG_ID_VALUE: id->value = tracker_id->u.value; + status = lttng_tracker_id_set_value( + id, tracker_id->u.value); break; case LTTNG_ID_STRING: - id->string = strdup(p); - if (!id->string) { - ret = -LTTNG_ERR_NOMEM; - goto error; - } + status = lttng_tracker_id_set_string(id, p); p += tracker_id->u.var_data_len; break; default: goto error; } + + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ret = -LTTNG_ERR_INVALID; + goto error; + } + + /* Assign the new object to the list */ + ids[i] = id; } free(cmd_payload); *_ids = ids; @@ -3008,12 +2928,8 @@ int lttng_list_tracker_ids(struct lttng_handle *handle, return 0; error: - if (ids) { - for (i = 0; i < nr_ids; i++) { - free(ids[i].string); - } - free(ids); - } + lttng_tracker_ids_destroy(ids, nr_ids); + free(ids); free(cmd_payload); free(cmd_header); return ret; @@ -3032,16 +2948,17 @@ error: int lttng_list_tracker_pids(struct lttng_handle *handle, int *_enabled, int32_t **_pids, size_t *_nr_pids) { - struct lttng_tracker_id *ids = NULL; + struct lttng_tracker_id **ids = NULL; size_t nr_ids = 0; int *pids = NULL; int ret = 0, i; + enum lttng_tracker_id_status status; ret = lttng_list_tracker_ids(handle, LTTNG_TRACKER_PID, &ids, &nr_ids); if (ret < 0) return ret; - if (nr_ids == 1 && ids[0].type == LTTNG_ID_ALL) { + if (nr_ids == 1 && lttng_tracker_id_get_type(ids[0]) == LTTNG_ID_ALL) { *_enabled = 0; goto end; } @@ -3053,20 +2970,18 @@ int lttng_list_tracker_pids(struct lttng_handle *handle, goto end; } for (i = 0; i < nr_ids; i++) { - struct lttng_tracker_id *id = &ids[i]; + struct lttng_tracker_id *id = ids[i]; - if (id->type != LTTNG_ID_VALUE) { + status = lttng_tracker_id_get_value(id, &pids[i]); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { ret = -LTTNG_ERR_UNK; goto end; } - pids[i] = id->value; } *_pids = pids; *_nr_pids = nr_ids; end: - for (i = 0; i < nr_ids; i++) { - free(ids[i].string); - } + lttng_tracker_ids_destroy(ids, nr_ids); free(ids); if (ret < 0) { free(pids); @@ -3208,6 +3123,131 @@ end: return ret; } +static int lttng_track_untrack_id(struct lttng_handle *handle, + enum lttng_tracker_type tracker_type, + const struct lttng_tracker_id *id, + enum lttcomm_sessiond_command cmd) +{ + int ret; + struct lttcomm_session_msg lsm; + const char *var_data; + size_t var_data_len = 0; + int value; + enum lttng_tracker_id_status status; + + /* NULL arguments are forbidden. No default values. */ + if (handle == NULL) { + goto error; + } + + memset(&lsm, 0, sizeof(lsm)); + + lsm.cmd_type = cmd; + lsm.u.id_tracker.tracker_type = tracker_type; + lsm.u.id_tracker.id_type = lttng_tracker_id_get_type(id); + switch (lsm.u.id_tracker.id_type) { + case LTTNG_ID_ALL: + break; + case LTTNG_ID_VALUE: + status = lttng_tracker_id_get_value(id, &value); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + goto error; + } + lsm.u.id_tracker.u.value = value; + break; + case LTTNG_ID_STRING: + status = lttng_tracker_id_get_string(id, &var_data); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + goto error; + } + var_data_len = strlen(var_data) + 1; /* Includes \0. */ + lsm.u.id_tracker.u.var_len = var_data_len; + break; + default: + goto error; + } + + COPY_DOMAIN_PACKED(lsm.domain, handle->domain); + + lttng_ctl_copy_string(lsm.session.name, handle->session_name, + sizeof(lsm.session.name)); + + ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header( + &lsm, (char *) var_data, var_data_len, NULL); + return ret; +error: + return -LTTNG_ERR_INVALID; +} + +/* + * Add ID to session tracker. + * Return 0 on success else a negative LTTng error code. + */ +int lttng_track_id(struct lttng_handle *handle, + enum lttng_tracker_type tracker_type, + const struct lttng_tracker_id *id) +{ + return lttng_track_untrack_id(handle, tracker_type, id, LTTNG_TRACK_ID); +} + +/* + * Remove ID from session tracker. + * Return 0 on success else a negative LTTng error code. + */ +int lttng_untrack_id(struct lttng_handle *handle, + enum lttng_tracker_type tracker_type, + const struct lttng_tracker_id *id) +{ + return lttng_track_untrack_id( + handle, tracker_type, id, LTTNG_UNTRACK_ID); +} + +/* + * Add PID to session tracker. + * Return 0 on success else a negative LTTng error code. + */ +int lttng_track_pid(struct lttng_handle *handle, int pid) +{ + int ret; + struct lttng_tracker_id *id = NULL; + enum lttng_tracker_id_status status; + + id = lttng_tracker_id_create(); + status = lttng_tracker_id_set_value(id, pid); + if (status == LTTNG_TRACKER_ID_STATUS_INVALID) { + ret = -LTTNG_ERR_INVALID; + goto error; + } + + ret = lttng_track_id(handle, LTTNG_TRACKER_PID, id); +error: + lttng_tracker_id_destroy(id); + return ret; +} + +/* + * Remove PID from session tracker. + * Return 0 on success else a negative LTTng error code. + */ +int lttng_untrack_pid(struct lttng_handle *handle, int pid) +{ + int ret; + struct lttng_tracker_id *id = NULL; + enum lttng_tracker_id_status status; + + id = lttng_tracker_id_create(); + status = lttng_tracker_id_set_value(id, pid); + if (status == LTTNG_TRACKER_ID_STATUS_INVALID) { + ret = -LTTNG_ERR_INVALID; + goto error; + } + + ret = lttng_untrack_id(handle, LTTNG_TRACKER_PID, id); +error: + lttng_tracker_id_destroy(id); + return ret; +} + /* * lib constructor. */ -- 2.34.1 From a7a533cd65d544e8beebabcca5fe906e27af4707 Mon Sep 17 00:00:00 2001 From: Jonathan Rajotte Date: Tue, 19 Nov 2019 22:48:00 -0500 Subject: [PATCH 08/16] Refactoring: introduce lttng_tracker_ids data structure MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This data structure is opaque to allow for back-end implementation change in the future. For now, only the following functions concerning lttng_tracker_ids are public: lttng_list_tracker_ids lttng_tracker_ids_get_count lttng_tracker_ids_get_at_index lttng_tracker_ids_destroy Signed-off-by: Jonathan Rajotte Change-Id: Iae1c10d0b578b402ab91378dd49f69f605b316b2 Signed-off-by: Jérémie Galarneau --- include/lttng/tracker-internal.h | 38 +++++++++- include/lttng/tracker.h | 40 +++++++--- src/bin/lttng-sessiond/client.c | 22 +++--- src/bin/lttng-sessiond/cmd.c | 25 +++--- src/bin/lttng-sessiond/cmd.h | 4 +- src/bin/lttng-sessiond/kernel.c | 44 ++++++----- src/bin/lttng-sessiond/kernel.h | 4 +- src/bin/lttng-sessiond/save.c | 36 +++++---- src/bin/lttng-sessiond/trace-ust.c | 43 ++++++----- src/bin/lttng-sessiond/trace-ust.h | 8 +- src/bin/lttng-sessiond/tracker.c | 77 ++++++++++++------- src/bin/lttng-sessiond/tracker.h | 7 +- src/bin/lttng/commands/list.c | 27 +++++-- src/common/mi-lttng.c | 2 +- src/common/mi-lttng.h | 2 +- src/common/tracker.c | 118 +++++++++++++++++++++++------ src/lib/lttng-ctl/lttng-ctl.c | 44 +++++------ 17 files changed, 357 insertions(+), 184 deletions(-) diff --git a/include/lttng/tracker-internal.h b/include/lttng/tracker-internal.h index a84d419d6..0debf7523 100644 --- a/include/lttng/tracker-internal.h +++ b/include/lttng/tracker-internal.h @@ -29,12 +29,46 @@ struct lttng_tracker_id { 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_id_copy( - const struct lttng_tracker_id *orig); +struct lttng_tracker_id *lttng_tracker_ids_get_pointer_of_index( + const struct lttng_tracker_ids *list, unsigned int index); #endif /* LTTNG_TRACKER_INTERNAL_H */ diff --git a/include/lttng/tracker.h b/include/lttng/tracker.h index 2d952a6e3..a66a2cfce 100644 --- a/include/lttng/tracker.h +++ b/include/lttng/tracker.h @@ -51,6 +51,7 @@ enum lttng_tracker_id_status { struct lttng_handle; struct lttng_tracker_id; +struct lttng_tracker_ids; /* * Create a tracker id for the passed tracker type. @@ -132,12 +133,6 @@ extern enum lttng_tracker_id_status lttng_tracker_id_get_value( extern enum lttng_tracker_id_status lttng_tracker_id_get_string( const struct lttng_tracker_id *id, const char **value); -/* - * Destroys (frees) an array of tracker id. - */ -extern void lttng_tracker_ids_destroy( - struct lttng_tracker_id **ids, size_t nr_ids); - /* * Add ID to session tracker. * @@ -165,17 +160,16 @@ extern int lttng_untrack_id(struct lttng_handle *handle, * List IDs in the tracker. * * tracker_type is the type of tracker. - * ids is set to an allocated array of IDs currently tracked. - * On success, ids must be freed using lttng_tracker_id_destroy on each - * constituent of the returned array or using lttng_tracker_ids_destroy. - * nr_ids is set to the number of entries contained by the ids array. + * ids is set to an allocated lttng_tracker_ids representing IDs + * currently tracked. + * On success, caller is responsible for freeing ids + * using lttng_tracker_ids_destroy. * * Returns 0 on success, else a negative LTTng error code. */ extern int lttng_list_tracker_ids(struct lttng_handle *handle, enum lttng_tracker_type tracker_type, - struct lttng_tracker_id ***ids, - size_t *nr_ids); + struct lttng_tracker_ids **ids); /* * Backward compatibility. @@ -215,6 +209,28 @@ extern int lttng_list_tracker_pids(struct lttng_handle *handle, int32_t **pids, size_t *nr_pids); +/* + * Get a tracker id from the list at a given index. + * + * 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. + * + * 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. + */ +extern int lttng_tracker_ids_get_count(const struct lttng_tracker_ids *ids); + +/* + * Destroy a tracker id list. + */ +extern void lttng_tracker_ids_destroy(struct lttng_tracker_ids *ids); + #ifdef __cplusplus } #endif diff --git a/src/bin/lttng-sessiond/client.c b/src/bin/lttng-sessiond/client.c index 2c7bd4787..8eff1650e 100644 --- a/src/bin/lttng-sessiond/client.c +++ b/src/bin/lttng-sessiond/client.c @@ -1568,29 +1568,34 @@ error_add_context: case LTTNG_LIST_TRACKER_IDS: { struct lttcomm_tracker_command_header cmd_header; - struct lttng_tracker_id **ids = NULL; - ssize_t nr_ids, i; + struct lttng_tracker_ids *ids = NULL; + size_t nr_ids, i; struct lttng_dynamic_buffer buf; - nr_ids = cmd_list_tracker_ids( + ret = cmd_list_tracker_ids( cmd_ctx->lsm->u.id_tracker.tracker_type, cmd_ctx->session, cmd_ctx->lsm->domain.type, &ids); - if (nr_ids < 0) { - /* Return value is a negative lttng_error_code. */ - ret = -nr_ids; + if (ret != LTTNG_OK) { goto error; } + nr_ids = lttng_tracker_ids_get_count(ids); lttng_dynamic_buffer_init(&buf); for (i = 0; i < nr_ids; i++) { - struct lttng_tracker_id *id = ids[i]; + const struct lttng_tracker_id *id; struct lttcomm_tracker_id_header id_hdr; size_t var_data_len = 0; enum lttng_tracker_id_status status; const char *string; int value; + id = lttng_tracker_ids_get_at_index(ids, i); + if (!id) { + ret = LTTNG_ERR_INVALID; + goto error_list_tracker; + } + memset(&id_hdr, 0, sizeof(id_hdr)); id_hdr.type = lttng_tracker_id_get_type(id); switch (id_hdr.type) { @@ -1637,8 +1642,7 @@ error_add_context: ret = setup_lttng_msg(cmd_ctx, buf.data, buf.size, &cmd_header, sizeof(cmd_header)); error_list_tracker: - lttng_tracker_ids_destroy(ids, nr_ids); - free(ids); + lttng_tracker_ids_destroy(ids); lttng_dynamic_buffer_reset(&buf); if (ret < 0) { goto setup_error; diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index b668b56d4..4ce2d43fa 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -2581,13 +2581,12 @@ ssize_t cmd_list_syscalls(struct lttng_event **events) * * Called with session lock held. */ -ssize_t cmd_list_tracker_ids(enum lttng_tracker_type tracker_type, +int cmd_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_session *session, enum lttng_domain_type domain, - struct lttng_tracker_id ***ids) + struct lttng_tracker_ids **ids) { - int ret; - ssize_t nr_pids = 0; + int ret = LTTNG_OK; switch (domain) { case LTTNG_DOMAIN_KERNEL: @@ -2595,9 +2594,9 @@ ssize_t cmd_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_kernel_session *ksess; ksess = session->kernel_session; - nr_pids = kernel_list_tracker_ids(tracker_type, ksess, ids); - if (nr_pids < 0) { - ret = LTTNG_ERR_KERN_LIST_FAIL; + ret = kernel_list_tracker_ids(tracker_type, ksess, ids); + if (ret != LTTNG_OK) { + ret = -LTTNG_ERR_KERN_LIST_FAIL; goto error; } break; @@ -2607,9 +2606,9 @@ ssize_t cmd_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_ust_session *usess; usess = session->ust_session; - nr_pids = trace_ust_list_tracker_ids(tracker_type, usess, ids); - if (nr_pids < 0) { - ret = LTTNG_ERR_UST_LIST_FAIL; + ret = trace_ust_list_tracker_ids(tracker_type, usess, ids); + if (ret != LTTNG_OK) { + ret = -LTTNG_ERR_UST_LIST_FAIL; goto error; } break; @@ -2618,15 +2617,13 @@ ssize_t cmd_list_tracker_ids(enum lttng_tracker_type tracker_type, case LTTNG_DOMAIN_JUL: case LTTNG_DOMAIN_PYTHON: default: - ret = LTTNG_ERR_UND; + ret = -LTTNG_ERR_UND; goto error; } - return nr_pids; - error: /* Return negative value to differentiate return code */ - return -ret; + return ret; } /* diff --git a/src/bin/lttng-sessiond/cmd.h b/src/bin/lttng-sessiond/cmd.h index ee4bf65e7..42145002f 100644 --- a/src/bin/lttng-sessiond/cmd.h +++ b/src/bin/lttng-sessiond/cmd.h @@ -114,10 +114,10 @@ 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); -ssize_t cmd_list_tracker_ids(enum lttng_tracker_type tracker_type, +int cmd_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_session *session, enum lttng_domain_type domain, - struct lttng_tracker_id ***ids); + struct lttng_tracker_ids **ids); int cmd_data_pending(struct ltt_session *session); diff --git a/src/bin/lttng-sessiond/kernel.c b/src/bin/lttng-sessiond/kernel.c index c5fd30b7e..8ec20e71b 100644 --- a/src/bin/lttng-sessiond/kernel.c +++ b/src/bin/lttng-sessiond/kernel.c @@ -707,8 +707,7 @@ int kernel_track_id(enum lttng_tracker_type tracker_type, { int ret, value; struct lttng_tracker_list *tracker_list; - struct lttng_tracker_id **saved_ids; - ssize_t saved_ids_count; + struct lttng_tracker_ids *saved_ids; ret = lttng_tracker_id_lookup_string(tracker_type, id, &value); if (ret != LTTNG_OK) { @@ -721,8 +720,8 @@ int kernel_track_id(enum lttng_tracker_type tracker_type, } /* Save list for restore on error. */ - saved_ids_count = lttng_tracker_id_get_list(tracker_list, &saved_ids); - if (saved_ids_count < 0) { + ret = lttng_tracker_id_get_list(tracker_list, &saved_ids); + if (ret != LTTNG_OK) { return LTTNG_ERR_INVALID; } @@ -808,13 +807,11 @@ int kernel_track_id(enum lttng_tracker_type tracker_type, break; } - if (lttng_tracker_id_set_list(tracker_list, saved_ids, - saved_ids_count) != LTTNG_OK) { + 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, saved_ids_count); - free(saved_ids); + lttng_tracker_ids_destroy(saved_ids); return ret; } @@ -824,8 +821,7 @@ int kernel_untrack_id(enum lttng_tracker_type tracker_type, { int ret, value; struct lttng_tracker_list *tracker_list; - struct lttng_tracker_id **saved_ids; - ssize_t saved_ids_count; + struct lttng_tracker_ids *saved_ids; ret = lttng_tracker_id_lookup_string(tracker_type, id, &value); if (ret != LTTNG_OK) { @@ -837,8 +833,8 @@ int kernel_untrack_id(enum lttng_tracker_type tracker_type, return LTTNG_ERR_INVALID; } /* Save list for restore on error. */ - saved_ids_count = lttng_tracker_id_get_list(tracker_list, &saved_ids); - if (saved_ids_count < 0) { + ret = lttng_tracker_id_get_list(tracker_list, &saved_ids); + if (ret != LTTNG_OK) { return LTTNG_ERR_INVALID; } /* Remove from list. */ @@ -926,30 +922,38 @@ int kernel_untrack_id(enum lttng_tracker_type tracker_type, break; } - if (lttng_tracker_id_set_list(tracker_list, saved_ids, - saved_ids_count) != LTTNG_OK) { + 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, saved_ids_count); - free(saved_ids); + lttng_tracker_ids_destroy(saved_ids); return ret; } /* * Called with session lock held. */ -ssize_t kernel_list_tracker_ids(enum lttng_tracker_type tracker_type, +int kernel_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_kernel_session *session, - struct lttng_tracker_id ***_ids) + struct lttng_tracker_ids **_ids) { + int ret = 0; struct lttng_tracker_list *tracker_list; tracker_list = get_id_tracker_list(session, tracker_type); if (!tracker_list) { - return -LTTNG_ERR_INVALID; + ret = -LTTNG_ERR_INVALID; + goto end; } - return lttng_tracker_id_get_list(tracker_list, _ids); + + ret = lttng_tracker_id_get_list(tracker_list, _ids); + if (ret != LTTNG_OK) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + +end: + return ret; } /* diff --git a/src/bin/lttng-sessiond/kernel.h b/src/bin/lttng-sessiond/kernel.h index 64d95d235..e28f0d2e0 100644 --- a/src/bin/lttng-sessiond/kernel.h +++ b/src/bin/lttng-sessiond/kernel.h @@ -72,9 +72,9 @@ 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); -ssize_t kernel_list_tracker_ids(enum lttng_tracker_type tracker_type, +int kernel_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_kernel_session *session, - struct lttng_tracker_id ***_ids); + 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); diff --git a/src/bin/lttng-sessiond/save.c b/src/bin/lttng-sessiond/save.c index 83019842d..b95ee2df0 100644 --- a/src/bin/lttng-sessiond/save.c +++ b/src/bin/lttng-sessiond/save.c @@ -1836,10 +1836,10 @@ static int save_id_tracker(struct config_writer *writer, enum lttng_tracker_type tracker_type) { int ret = LTTNG_OK; - ssize_t nr_ids = 0, i; - struct lttng_tracker_id **ids = NULL; + size_t nr_ids = 0, i; + struct lttng_tracker_ids *ids = NULL; const char *element_id_tracker, *element_target_id, *element_id; - struct lttng_tracker_id *id; + const struct lttng_tracker_id *id; enum lttng_tracker_id_status status; int value; const char *string; @@ -1883,9 +1883,9 @@ static int save_id_tracker(struct config_writer *writer, switch (domain) { case LTTNG_DOMAIN_KERNEL: { - nr_ids = kernel_list_tracker_ids( + ret = kernel_list_tracker_ids( tracker_type, sess->kernel_session, &ids); - if (nr_ids < 0) { + if (ret != LTTNG_OK) { ret = LTTNG_ERR_KERN_LIST_FAIL; goto end; } @@ -1893,9 +1893,9 @@ static int save_id_tracker(struct config_writer *writer, } case LTTNG_DOMAIN_UST: { - nr_ids = trace_ust_list_tracker_ids( + ret = trace_ust_list_tracker_ids( tracker_type, sess->ust_session, &ids); - if (nr_ids < 0) { + if (ret != LTTNG_OK) { ret = LTTNG_ERR_UST_LIST_FAIL; goto end; } @@ -1909,10 +1909,15 @@ static int save_id_tracker(struct config_writer *writer, goto end; } - if (nr_ids == 1 && lttng_tracker_id_get_type(ids[0]) == LTTNG_ID_ALL) { - /* Tracking all, nothing to output. */ - ret = LTTNG_OK; - goto end; + nr_ids = lttng_tracker_ids_get_count(ids); + + 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); @@ -1944,7 +1949,11 @@ static int save_id_tracker(struct config_writer *writer, } else { /* Tracking list. */ for (i = 0; i < nr_ids; i++) { - id = ids[i]; + id = lttng_tracker_ids_get_at_index(ids, i); + if (!id) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } switch (lttng_tracker_id_get_type(id)) { case LTTNG_ID_VALUE: ret = config_writer_open_element( @@ -2008,8 +2017,7 @@ static int save_id_tracker(struct config_writer *writer, ret = LTTNG_OK; end: - lttng_tracker_ids_destroy(ids, nr_ids); - free(ids); + lttng_tracker_ids_destroy(ids); return ret; } diff --git a/src/bin/lttng-sessiond/trace-ust.c b/src/bin/lttng-sessiond/trace-ust.c index 4a7e26105..a5192ffbe 100644 --- a/src/bin/lttng-sessiond/trace-ust.c +++ b/src/bin/lttng-sessiond/trace-ust.c @@ -918,8 +918,7 @@ int trace_ust_track_id(enum lttng_tracker_type tracker_type, struct ust_id_tracker *id_tracker; struct lttng_tracker_list *tracker_list; int value; - struct lttng_tracker_id **saved_ids; - ssize_t saved_ids_count; + struct lttng_tracker_ids *saved_ids; if (tracker_type == LTTNG_TRACKER_PID) { DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain."); @@ -935,8 +934,8 @@ int trace_ust_track_id(enum lttng_tracker_type tracker_type, return LTTNG_ERR_INVALID; } /* Save list for restore on error. */ - saved_ids_count = lttng_tracker_id_get_list(tracker_list, &saved_ids); - if (saved_ids_count < 0) { + retval = lttng_tracker_id_get_list(tracker_list, &saved_ids); + if (retval != LTTNG_OK) { return LTTNG_ERR_INVALID; } /* Add to list. */ @@ -997,13 +996,11 @@ int trace_ust_track_id(enum lttng_tracker_type tracker_type, goto end; end_restore: - if (lttng_tracker_id_set_list(tracker_list, saved_ids, - saved_ids_count) != LTTNG_OK) { + 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, saved_ids_count); - free(saved_ids); + lttng_tracker_ids_destroy(saved_ids); return retval; } @@ -1019,8 +1016,7 @@ int trace_ust_untrack_id(enum lttng_tracker_type tracker_type, struct ust_id_tracker *id_tracker; struct lttng_tracker_list *tracker_list; int value; - struct lttng_tracker_id **saved_ids; - ssize_t saved_ids_count; + struct lttng_tracker_ids *saved_ids; if (tracker_type == LTTNG_TRACKER_PID) { DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain."); @@ -1037,8 +1033,8 @@ int trace_ust_untrack_id(enum lttng_tracker_type tracker_type, return LTTNG_ERR_INVALID; } /* Save list for restore on error. */ - saved_ids_count = lttng_tracker_id_get_list(tracker_list, &saved_ids); - if (saved_ids_count < 0) { + retval = lttng_tracker_id_get_list(tracker_list, &saved_ids); + if (retval != LTTNG_OK) { return LTTNG_ERR_INVALID; } /* Remove from list. */ @@ -1100,23 +1096,22 @@ int trace_ust_untrack_id(enum lttng_tracker_type tracker_type, goto end; end_restore: - if (lttng_tracker_id_set_list(tracker_list, saved_ids, - saved_ids_count) != LTTNG_OK) { + 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, saved_ids_count); - free(saved_ids); + lttng_tracker_ids_destroy(saved_ids); return retval; } /* * Called with session lock held. */ -ssize_t trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type, +int trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_ust_session *session, - struct lttng_tracker_id ***_ids) + struct lttng_tracker_ids **_ids) { + int ret = LTTNG_OK; struct lttng_tracker_list *tracker_list; if (tracker_type == LTTNG_TRACKER_PID) { @@ -1126,9 +1121,17 @@ ssize_t trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type, tracker_list = get_id_tracker_list(session, tracker_type); if (!tracker_list) { - return -LTTNG_ERR_INVALID; + ret = -LTTNG_ERR_INVALID; + goto end; } - return lttng_tracker_id_get_list(tracker_list, _ids); + + ret = lttng_tracker_id_get_list(tracker_list, _ids); + if (ret != LTTNG_OK) { + ret = -LTTNG_ERR_INVALID; + goto end; + } +end: + return ret; } /* diff --git a/src/bin/lttng-sessiond/trace-ust.h b/src/bin/lttng-sessiond/trace-ust.h index 2d0b042e5..11486ddd0 100644 --- a/src/bin/lttng-sessiond/trace-ust.h +++ b/src/bin/lttng-sessiond/trace-ust.h @@ -238,9 +238,9 @@ int trace_ust_id_tracker_lookup(enum lttng_tracker_type tracker_type, struct ltt_ust_session *session, int id); -ssize_t trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type, +int trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_ust_session *session, - struct lttng_tracker_id ***_ids); + struct lttng_tracker_ids **_ids); #else /* HAVE_LIBLTTNG_UST_CTL */ @@ -352,10 +352,10 @@ static inline int trace_ust_id_tracker_lookup( { return 0; } -static inline ssize_t trace_ust_list_tracker_ids( +static inline int trace_ust_list_tracker_ids( enum lttng_tracker_type tracker_type, struct ltt_ust_session *session, - struct lttng_tracker_id **_ids) + struct lttng_tracker_ids **_ids) { return -1; } diff --git a/src/bin/lttng-sessiond/tracker.c b/src/bin/lttng-sessiond/tracker.c index 909a04845..48dc176c1 100644 --- a/src/bin/lttng-sessiond/tracker.c +++ b/src/bin/lttng-sessiond/tracker.c @@ -178,7 +178,7 @@ int lttng_tracker_list_add(struct lttng_tracker_list *tracker_list, goto error; } - n->id = lttng_tracker_id_copy(_id); + n->id = lttng_tracker_id_duplicate(_id); if (!n->id) { ret = LTTNG_ERR_NOMEM; goto error; @@ -415,12 +415,14 @@ int lttng_tracker_id_lookup_string(enum lttng_tracker_type tracker_type, * Protected by session mutex held by caller. * On success, _ids and the ids it contains must be freed by the caller. */ -ssize_t lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list, - struct lttng_tracker_id ***_ids) +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, retval = 0; - struct lttng_tracker_id **ids; + 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) { @@ -429,7 +431,7 @@ ssize_t lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list, n, &tracker_list->list_head, list_node) { count++; } - ids = zmalloc(sizeof(*ids) * count); + ids = lttng_tracker_ids_create(count); if (ids == NULL) { PERROR("Failed to allocate tracked ID list"); retval = -LTTNG_ERR_NOMEM; @@ -437,67 +439,86 @@ ssize_t lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list, } cds_list_for_each_entry ( n, &tracker_list->list_head, list_node) { - ids[i] = lttng_tracker_id_copy(n->id); - if (!ids[i]) { + 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++; } - *_ids = ids; - retval = count; break; case LTTNG_TRACK_ALL: - ids = zmalloc(sizeof(*ids)); + + ids = lttng_tracker_ids_create(1); if (ids == NULL) { PERROR("Failed to allocate tracked ID list"); retval = -LTTNG_ERR_NOMEM; goto end; } - ids[0] = lttng_tracker_id_create(); - status = lttng_tracker_id_set_all(ids[0]); + + 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; } - *_ids = ids; - retval = 1; break; case LTTNG_TRACK_NONE: - /* No ids track, so we return 0 element. */ - *_ids = NULL; + /* 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; } + *_ids = ids; + end: return retval; error: - lttng_tracker_ids_destroy(ids, count); - free(ids); + lttng_tracker_ids_destroy(ids); return retval; } int lttng_tracker_id_set_list(struct lttng_tracker_list *tracker_list, - struct lttng_tracker_id **_ids, - size_t count) + const struct lttng_tracker_ids *ids) { - size_t i; + size_t i, count; + const struct lttng_tracker_id *id; + + assert(tracker_list); + assert(ids); lttng_tracker_list_reset(tracker_list); - if (count == 1 && lttng_tracker_id_get_type(_ids[0])) { - /* Track all. */ - return LTTNG_OK; - } + count = lttng_tracker_ids_get_count(ids); + if (count == 0) { /* Set state to "track none". */ tracker_list->state = LTTNG_TRACK_NONE; return LTTNG_OK; } + + 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; + } + } + for (i = 0; i < count; i++) { - struct lttng_tracker_id *id = _ids[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; diff --git a/src/bin/lttng-sessiond/tracker.h b/src/bin/lttng-sessiond/tracker.h index 812b3b127..7497abd0c 100644 --- a/src/bin/lttng-sessiond/tracker.h +++ b/src/bin/lttng-sessiond/tracker.h @@ -56,10 +56,9 @@ int lttng_tracker_list_remove(struct lttng_tracker_list *tracker_list, int lttng_tracker_id_lookup_string(enum lttng_tracker_type tracker_type, const struct lttng_tracker_id *id, int *result); -ssize_t lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list, - struct lttng_tracker_id ***_ids); +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, - struct lttng_tracker_id **_ids, - size_t count); + const struct lttng_tracker_ids *_ids); #endif /* _LTT_TRACKER_H */ diff --git a/src/bin/lttng/commands/list.c b/src/bin/lttng/commands/list.c index 49470ab86..229648e07 100644 --- a/src/bin/lttng/commands/list.c +++ b/src/bin/lttng/commands/list.c @@ -1539,16 +1539,23 @@ static int list_tracker_ids(enum lttng_tracker_type tracker_type) { int ret = 0; int enabled = 1; - struct lttng_tracker_id **ids = NULL; + struct lttng_tracker_ids *ids = NULL; size_t nr_ids, i; + const struct lttng_tracker_id *id; - ret = lttng_list_tracker_ids(handle, tracker_type, &ids, &nr_ids); + ret = lttng_list_tracker_ids(handle, tracker_type, &ids); if (ret) { return ret; } - if (nr_ids == 1 && lttng_tracker_id_get_type(ids[0]) == LTTNG_ID_ALL) { - enabled = 0; + + nr_ids = lttng_tracker_ids_get_count(ids); + 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; + } } + if (enabled) { _MSG("%s tracker: [", get_tracker_str(tracker_type)); @@ -1562,11 +1569,17 @@ static int list_tracker_ids(enum lttng_tracker_type tracker_type) } for (i = 0; i < nr_ids; i++) { - struct lttng_tracker_id *id = ids[i]; - enum lttng_tracker_id_status status; + enum lttng_tracker_id_status status = + LTTNG_TRACKER_ID_STATUS_OK; int value; const char *value_string; + id = lttng_tracker_ids_get_at_index(ids, i); + if (!id) { + ret = CMD_ERROR; + goto end; + } + switch (lttng_tracker_id_get_type(id)) { case LTTNG_ID_ALL: break; @@ -1627,7 +1640,7 @@ static int list_tracker_ids(enum lttng_tracker_type tracker_type) } } end: - lttng_tracker_ids_destroy(ids, nr_ids); + lttng_tracker_ids_destroy(ids); return ret; } diff --git a/src/common/mi-lttng.c b/src/common/mi-lttng.c index 7b0d9cf02..bc2d3f3d0 100644 --- a/src/common/mi-lttng.c +++ b/src/common/mi-lttng.c @@ -1662,7 +1662,7 @@ int mi_lttng_targets_open(struct mi_writer *writer) LTTNG_HIDDEN int mi_lttng_id_target(struct mi_writer *writer, enum lttng_tracker_type tracker_type, - struct lttng_tracker_id *id, + const struct lttng_tracker_id *id, int is_open) { int ret; diff --git a/src/common/mi-lttng.h b/src/common/mi-lttng.h index 3ea6bc6d7..2e4592b53 100644 --- a/src/common/mi-lttng.h +++ b/src/common/mi-lttng.h @@ -694,7 +694,7 @@ int mi_lttng_targets_open(struct mi_writer *writer); */ int mi_lttng_id_target(struct mi_writer *writer, enum lttng_tracker_type tracker_type, - struct lttng_tracker_id *id, + const struct lttng_tracker_id *id, int is_open); /* diff --git a/src/common/tracker.c b/src/common/tracker.c index f8a4fba0f..7742f47bc 100644 --- a/src/common/tracker.c +++ b/src/common/tracker.c @@ -85,7 +85,7 @@ enum lttng_tracker_id_status lttng_tracker_id_set_all( return LTTNG_TRACKER_ID_STATUS_OK; } -void lttng_tracker_id_destroy(struct lttng_tracker_id *id) +static void lttng_tracker_id_reset(struct lttng_tracker_id *id) { if (id == NULL) { return; @@ -93,20 +93,22 @@ void lttng_tracker_id_destroy(struct lttng_tracker_id *id) if (id->string != NULL) { free(id->string); + id->string = NULL; } - free(id); + id->type = LTTNG_ID_UNKNOWN; + id->value = -1; } -void lttng_tracker_ids_destroy(struct lttng_tracker_id **ids, size_t nr_ids) +void lttng_tracker_id_destroy(struct lttng_tracker_id *id) { - if (ids == NULL) { + if (id == NULL) { return; } - for (int i = 0; i < nr_ids; i++) { - lttng_tracker_id_destroy(ids[i]); - } + lttng_tracker_id_reset(id); + + free(id); } enum lttng_tracker_id_type lttng_tracker_id_get_type( @@ -162,32 +164,24 @@ bool lttng_tracker_id_is_equal(const struct lttng_tracker_id *left, return 1; } -struct lttng_tracker_id *lttng_tracker_id_copy( +int lttng_tracker_id_copy(struct lttng_tracker_id *dest, const struct lttng_tracker_id *orig) { - struct lttng_tracker_id *copy = NULL; + int ret = 0; enum lttng_tracker_id_status status; - copy = lttng_tracker_id_create(); - if (copy == NULL) { - goto error; - } + assert(dest); + assert(orig); switch (orig->type) { case LTTNG_ID_ALL: - status = lttng_tracker_id_set_all(copy); + status = lttng_tracker_id_set_all(dest); break; case LTTNG_ID_VALUE: - status = lttng_tracker_id_set_value(copy, orig->value); - if (status != LTTNG_TRACKER_ID_STATUS_OK) { - goto error; - } + status = lttng_tracker_id_set_value(dest, orig->value); break; case LTTNG_ID_STRING: - status = lttng_tracker_id_set_string(copy, orig->string); - if (status != LTTNG_TRACKER_ID_STATUS_OK) { - goto error; - } + status = lttng_tracker_id_set_string(dest, orig->string); break; default: status = LTTNG_TRACKER_ID_STATUS_OK; @@ -195,6 +189,26 @@ struct lttng_tracker_id *lttng_tracker_id_copy( } if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ret = -1; + goto error; + } +error: + return ret; +} + +struct lttng_tracker_id *lttng_tracker_id_duplicate( + const struct lttng_tracker_id *orig) +{ + int ret; + struct lttng_tracker_id *copy = NULL; + + copy = lttng_tracker_id_create(); + if (copy == NULL) { + goto error; + } + + ret = lttng_tracker_id_copy(copy, orig); + if (ret) { goto error; } @@ -221,3 +235,63 @@ enum lttng_tracker_id_status lttng_tracker_id_get_string( *value = id->string; return LTTNG_TRACKER_ID_STATUS_OK; } + +struct lttng_tracker_ids *lttng_tracker_ids_create(unsigned int count) +{ + struct lttng_tracker_ids *ids = NULL; + + ids = zmalloc(sizeof(*ids)); + if (!ids) { + goto error; + } + + ids->id_array = zmalloc(sizeof(struct lttng_tracker_id) * count); + if (!ids->id_array) { + goto error; + } + + ids->count = count; + + return ids; +error: + free(ids); + return NULL; +} + +LTTNG_HIDDEN +struct lttng_tracker_id *lttng_tracker_ids_get_pointer_of_index( + const struct lttng_tracker_ids *ids, unsigned int index) +{ + assert(ids); + if (index >= ids->count) { + return NULL; + } + + return &ids->id_array[index]; +} + +const struct lttng_tracker_id *lttng_tracker_ids_get_at_index( + const struct lttng_tracker_ids *ids, unsigned int index) +{ + assert(ids); + return lttng_tracker_ids_get_pointer_of_index(ids, index); +} + +int lttng_tracker_ids_get_count(const struct lttng_tracker_ids *ids) +{ + assert(ids); + return ids->count; +} + +void lttng_tracker_ids_destroy(struct lttng_tracker_ids *ids) +{ + if (!ids) { + return; + } + + for (int i = 0; i < ids->count; i++) { + lttng_tracker_id_reset(&ids->id_array[i]); + } + free(ids->id_array); + free(ids); +} diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 406de885c..88daf45aa 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -2839,8 +2839,7 @@ end: */ int lttng_list_tracker_ids(struct lttng_handle *handle, enum lttng_tracker_type tracker_type, - struct lttng_tracker_id ***_ids, - size_t *_nr_ids) + struct lttng_tracker_ids **_ids) { int ret, i; struct lttcomm_session_msg lsm; @@ -2848,7 +2847,7 @@ int lttng_list_tracker_ids(struct lttng_handle *handle, char *cmd_payload = NULL, *p; size_t cmd_header_len; size_t nr_ids = 0; - struct lttng_tracker_id **ids = NULL; + struct lttng_tracker_ids *ids = NULL; if (handle == NULL) { return -LTTNG_ERR_INVALID; @@ -2877,7 +2876,7 @@ int lttng_list_tracker_ids(struct lttng_handle *handle, free(cmd_header); cmd_header = NULL; - ids = zmalloc(sizeof(*ids) * nr_ids); + ids = lttng_tracker_ids_create(nr_ids); if (!ids) { ret = -LTTNG_ERR_NOMEM; goto error; @@ -2891,9 +2890,9 @@ int lttng_list_tracker_ids(struct lttng_handle *handle, tracker_id = (struct lttcomm_tracker_id_header *) p; p += sizeof(struct lttcomm_tracker_id_header); - id = lttng_tracker_id_create(); + id = lttng_tracker_ids_get_pointer_of_index(ids, i); if (!id) { - ret = -LTTNG_ERR_NOMEM; + ret = -LTTNG_ERR_INVALID; goto error; } @@ -2918,18 +2917,13 @@ int lttng_list_tracker_ids(struct lttng_handle *handle, ret = -LTTNG_ERR_INVALID; goto error; } - - /* Assign the new object to the list */ - ids[i] = id; } free(cmd_payload); *_ids = ids; - *_nr_ids = nr_ids; return 0; error: - lttng_tracker_ids_destroy(ids, nr_ids); - free(ids); + lttng_tracker_ids_destroy(ids); free(cmd_payload); free(cmd_header); return ret; @@ -2948,20 +2942,28 @@ error: int lttng_list_tracker_pids(struct lttng_handle *handle, int *_enabled, int32_t **_pids, size_t *_nr_pids) { - struct lttng_tracker_id **ids = NULL; + struct lttng_tracker_ids *ids = NULL; size_t nr_ids = 0; int *pids = NULL; int ret = 0, i; enum lttng_tracker_id_status status; + const struct lttng_tracker_id *id; - ret = lttng_list_tracker_ids(handle, LTTNG_TRACKER_PID, &ids, &nr_ids); - if (ret < 0) + ret = lttng_list_tracker_ids(handle, LTTNG_TRACKER_PID, &ids); + if (ret < 0) { return ret; + } - if (nr_ids == 1 && lttng_tracker_id_get_type(ids[0]) == LTTNG_ID_ALL) { - *_enabled = 0; - goto end; + nr_ids = lttng_tracker_ids_get_count(ids); + + if (nr_ids == 1) { + id = lttng_tracker_ids_get_at_index(ids, 0); + if (id && lttng_tracker_id_get_type(id) == LTTNG_ID_ALL) { + *_enabled = 0; + goto end; + } } + *_enabled = 1; pids = zmalloc(nr_ids * sizeof(*pids)); @@ -2970,8 +2972,7 @@ int lttng_list_tracker_pids(struct lttng_handle *handle, goto end; } for (i = 0; i < nr_ids; i++) { - struct lttng_tracker_id *id = ids[i]; - + id = lttng_tracker_ids_get_at_index(ids, i); status = lttng_tracker_id_get_value(id, &pids[i]); if (status != LTTNG_TRACKER_ID_STATUS_OK) { ret = -LTTNG_ERR_UNK; @@ -2981,8 +2982,7 @@ int lttng_list_tracker_pids(struct lttng_handle *handle, *_pids = pids; *_nr_pids = nr_ids; end: - lttng_tracker_ids_destroy(ids, nr_ids); - free(ids); + lttng_tracker_ids_destroy(ids); if (ret < 0) { free(pids); } -- 2.34.1 From e283e4a062cc16b5839a8a479e12498789320b5e Mon Sep 17 00:00:00 2001 From: Jonathan Rajotte Date: Wed, 20 Nov 2019 14:40:22 -0500 Subject: [PATCH 09/16] Refactoring: move count to an output parameter MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This mimics what is done for lttng_rotation_schedules_get_count. Signed-off-by: Jonathan Rajotte Change-Id: I576d112de4a9bfa258a78cb52b8da8a5f25adefb Signed-off-by: Jérémie Galarneau --- include/lttng/tracker.h | 6 +++++- src/bin/lttng-sessiond/client.c | 10 ++++++++-- src/bin/lttng-sessiond/save.c | 8 ++++++-- src/bin/lttng-sessiond/tracker.c | 9 +++++++-- src/bin/lttng/commands/list.c | 10 ++++++++-- src/common/tracker.c | 15 ++++++++++++--- src/lib/lttng-ctl/lttng-ctl.c | 8 ++++++-- 7 files changed, 52 insertions(+), 14 deletions(-) diff --git a/include/lttng/tracker.h b/include/lttng/tracker.h index a66a2cfce..1da12f82b 100644 --- a/include/lttng/tracker.h +++ b/include/lttng/tracker.h @@ -223,8 +223,12 @@ extern const struct lttng_tracker_id *lttng_tracker_ids_get_at_index( /* * Get the number of tracker id in a tracker id list. + * + * Return LTTNG_TRACKER_ID_STATUS on sucess, + * LTTNG_TRACKER_ID_STATUS_INVALID when passed invalid parameters. */ -extern int lttng_tracker_ids_get_count(const struct lttng_tracker_ids *ids); +extern enum lttng_tracker_id_status lttng_tracker_ids_get_count( + const struct lttng_tracker_ids *ids, unsigned int *count); /* * Destroy a tracker id list. diff --git a/src/bin/lttng-sessiond/client.c b/src/bin/lttng-sessiond/client.c index 8eff1650e..ed0498ffa 100644 --- a/src/bin/lttng-sessiond/client.c +++ b/src/bin/lttng-sessiond/client.c @@ -1569,7 +1569,8 @@ error_add_context: { struct lttcomm_tracker_command_header cmd_header; struct lttng_tracker_ids *ids = NULL; - size_t nr_ids, i; + enum lttng_tracker_id_status status; + unsigned int nr_ids, i; struct lttng_dynamic_buffer buf; ret = cmd_list_tracker_ids( @@ -1580,7 +1581,12 @@ error_add_context: goto error; } - nr_ids = lttng_tracker_ids_get_count(ids); + status = lttng_tracker_ids_get_count(ids, &nr_ids); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ret = LTTNG_ERR_INVALID; + goto error_list_tracker; + } + lttng_dynamic_buffer_init(&buf); for (i = 0; i < nr_ids; i++) { const struct lttng_tracker_id *id; diff --git a/src/bin/lttng-sessiond/save.c b/src/bin/lttng-sessiond/save.c index b95ee2df0..395c0f65c 100644 --- a/src/bin/lttng-sessiond/save.c +++ b/src/bin/lttng-sessiond/save.c @@ -1836,7 +1836,7 @@ static int save_id_tracker(struct config_writer *writer, enum lttng_tracker_type tracker_type) { int ret = LTTNG_OK; - size_t nr_ids = 0, i; + 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; @@ -1909,7 +1909,11 @@ static int save_id_tracker(struct config_writer *writer, goto end; } - nr_ids = lttng_tracker_ids_get_count(ids); + status = lttng_tracker_ids_get_count(ids, &nr_ids); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ret = LTTNG_ERR_INVALID; + goto end; + } if (nr_ids == 1) { id = lttng_tracker_ids_get_at_index(ids, 0); diff --git a/src/bin/lttng-sessiond/tracker.c b/src/bin/lttng-sessiond/tracker.c index 48dc176c1..38bf8a473 100644 --- a/src/bin/lttng-sessiond/tracker.c +++ b/src/bin/lttng-sessiond/tracker.c @@ -493,14 +493,19 @@ error: int lttng_tracker_id_set_list(struct lttng_tracker_list *tracker_list, const struct lttng_tracker_ids *ids) { - size_t i, count; + 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); - count = lttng_tracker_ids_get_count(ids); + + status = lttng_tracker_ids_get_count(ids, &count); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + return LTTNG_ERR_INVALID; + } if (count == 0) { /* Set state to "track none". */ diff --git a/src/bin/lttng/commands/list.c b/src/bin/lttng/commands/list.c index 229648e07..2af59c433 100644 --- a/src/bin/lttng/commands/list.c +++ b/src/bin/lttng/commands/list.c @@ -1540,15 +1540,21 @@ static int list_tracker_ids(enum lttng_tracker_type tracker_type) int ret = 0; int enabled = 1; struct lttng_tracker_ids *ids = NULL; - size_t nr_ids, i; + unsigned int nr_ids, i; const struct lttng_tracker_id *id; + enum lttng_tracker_id_status status; ret = lttng_list_tracker_ids(handle, tracker_type, &ids); if (ret) { return ret; } - nr_ids = lttng_tracker_ids_get_count(ids); + status = lttng_tracker_ids_get_count(ids, &nr_ids); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ret = CMD_ERROR; + 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) { diff --git a/src/common/tracker.c b/src/common/tracker.c index 7742f47bc..afc253def 100644 --- a/src/common/tracker.c +++ b/src/common/tracker.c @@ -277,10 +277,19 @@ const struct lttng_tracker_id *lttng_tracker_ids_get_at_index( return lttng_tracker_ids_get_pointer_of_index(ids, index); } -int lttng_tracker_ids_get_count(const struct lttng_tracker_ids *ids) +int lttng_tracker_ids_get_count(const struct lttng_tracker_ids *ids, unsigned int *count) { - assert(ids); - return ids->count; + + enum lttng_tracker_id_status status = LTTNG_ROTATION_STATUS_OK; + + if (!ids || !count) { + status = LTTNG_ROTATION_STATUS_INVALID; + goto end; + } + + *count = ids->count; +end: + return status; } void lttng_tracker_ids_destroy(struct lttng_tracker_ids *ids) diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 88daf45aa..cfe437118 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -2943,7 +2943,7 @@ int lttng_list_tracker_pids(struct lttng_handle *handle, int *_enabled, int32_t **_pids, size_t *_nr_pids) { struct lttng_tracker_ids *ids = NULL; - size_t nr_ids = 0; + unsigned int nr_ids = 0; int *pids = NULL; int ret = 0, i; enum lttng_tracker_id_status status; @@ -2954,7 +2954,11 @@ int lttng_list_tracker_pids(struct lttng_handle *handle, return ret; } - nr_ids = lttng_tracker_ids_get_count(ids); + status = lttng_tracker_ids_get_count(ids, &nr_ids); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ret = -LTTNG_ERR_INVALID; + goto end; + } if (nr_ids == 1) { id = lttng_tracker_ids_get_at_index(ids, 0); -- 2.34.1 From f19f5c968f63a83a83c47390020e6ff0dd7c85aa Mon Sep 17 00:00:00 2001 From: Jonathan Rajotte Date: Wed, 20 Nov 2019 22:02:09 -0500 Subject: [PATCH 10/16] Refactoring: introduce lttng_tracker_ids_serialize MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonathan Rajotte Change-Id: I0d43b85241b7097ac722724d9fef0ca352422495 Signed-off-by: Jérémie Galarneau --- include/lttng/tracker-internal.h | 11 ++++- src/bin/lttng-sessiond/client.c | 68 +++++------------------------- src/common/tracker.c | 71 ++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 59 deletions(-) diff --git a/include/lttng/tracker-internal.h b/include/lttng/tracker-internal.h index 0debf7523..a0a394479 100644 --- a/include/lttng/tracker-internal.h +++ b/include/lttng/tracker-internal.h @@ -18,8 +18,9 @@ #ifndef LTTNG_TRACKER_INTERNAL_H #define LTTNG_TRACKER_INTERNAL_H -#include #include +#include +#include #include #include @@ -71,4 +72,12 @@ 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 */ diff --git a/src/bin/lttng-sessiond/client.c b/src/bin/lttng-sessiond/client.c index ed0498ffa..f0b0efd3c 100644 --- a/src/bin/lttng-sessiond/client.c +++ b/src/bin/lttng-sessiond/client.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "client.h" #include "lttng-sessiond.h" @@ -1570,7 +1571,7 @@ error_add_context: struct lttcomm_tracker_command_header cmd_header; struct lttng_tracker_ids *ids = NULL; enum lttng_tracker_id_status status; - unsigned int nr_ids, i; + unsigned int nr_ids; struct lttng_dynamic_buffer buf; ret = cmd_list_tracker_ids( @@ -1581,77 +1582,28 @@ error_add_context: 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; + ret = -LTTNG_ERR_INVALID; goto error_list_tracker; } - lttng_dynamic_buffer_init(&buf); - for (i = 0; i < nr_ids; i++) { - const struct lttng_tracker_id *id; - struct lttcomm_tracker_id_header id_hdr; - size_t var_data_len = 0; - enum lttng_tracker_id_status status; - const char *string; - int value; - - id = lttng_tracker_ids_get_at_index(ids, i); - if (!id) { - ret = LTTNG_ERR_INVALID; - goto error_list_tracker; - } - - memset(&id_hdr, 0, sizeof(id_hdr)); - id_hdr.type = lttng_tracker_id_get_type(id); - switch (id_hdr.type) { - case LTTNG_ID_ALL: - break; - case LTTNG_ID_VALUE: - status = lttng_tracker_id_get_value(id, &value); - id_hdr.u.value = value; - if (status != LTTNG_TRACKER_ID_STATUS_OK) { - ret = LTTNG_ERR_INVALID; - goto error_list_tracker; - } - break; - case LTTNG_ID_STRING: - status = lttng_tracker_id_get_string( - id, &string); - if (status != LTTNG_TRACKER_ID_STATUS_OK) { - ret = LTTNG_ERR_INVALID; - goto error_list_tracker; - } + cmd_header.nb_tracker_id = nr_ids; - id_hdr.u.var_data_len = var_data_len = - strlen(string) + 1; - break; - default: - ret = LTTNG_ERR_INVALID; - goto error_list_tracker; - } - ret = lttng_dynamic_buffer_append( - &buf, &id_hdr, sizeof(id_hdr)); - if (ret) { - ret = LTTNG_ERR_NOMEM; - goto error_list_tracker; - } - ret = lttng_dynamic_buffer_append( - &buf, string, var_data_len); - if (ret) { - ret = LTTNG_ERR_NOMEM; - goto error_list_tracker; - } + ret = lttng_tracker_ids_serialize(ids, &buf); + if (ret < 0) { + goto error_list_tracker; } - cmd_header.nb_tracker_id = nr_ids; 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 setup_error; + goto error; } ret = LTTNG_OK; diff --git a/src/common/tracker.c b/src/common/tracker.c index afc253def..ec908081c 100644 --- a/src/common/tracker.c +++ b/src/common/tracker.c @@ -304,3 +304,74 @@ void lttng_tracker_ids_destroy(struct lttng_tracker_ids *ids) free(ids->id_array); free(ids); } + +int lttng_tracker_ids_serialize(const struct lttng_tracker_ids *ids, + struct lttng_dynamic_buffer *buffer) +{ + int ret; + int value; + const char *string; + unsigned int count; + enum lttng_tracker_id_status status; + const struct lttng_tracker_id *id; + + status = lttng_tracker_ids_get_count(ids, &count); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ret = LTTNG_ERR_INVALID; + goto error; + } + + for (unsigned int i = 0; i < count; i++) { + struct lttcomm_tracker_id_header id_hdr; + size_t var_data_len = 0; + + id = lttng_tracker_ids_get_at_index(ids, i); + if (!id) { + ret = -LTTNG_ERR_INVALID; + goto error; + } + + memset(&id_hdr, 0, sizeof(id_hdr)); + id_hdr.type = lttng_tracker_id_get_type(id); + switch (id_hdr.type) { + case LTTNG_ID_ALL: + break; + case LTTNG_ID_VALUE: + status = lttng_tracker_id_get_value(id, &value); + id_hdr.u.value = value; + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ret = -LTTNG_ERR_INVALID; + goto error; + } + break; + case LTTNG_ID_STRING: + status = lttng_tracker_id_get_string( + id, &string); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ret = -LTTNG_ERR_INVALID; + goto error; + } + + id_hdr.u.var_data_len = var_data_len = + strlen(string) + 1; + break; + default: + ret = -LTTNG_ERR_INVALID; + goto error; + } + ret = lttng_dynamic_buffer_append( + buffer, &id_hdr, sizeof(id_hdr)); + if (ret) { + ret = -LTTNG_ERR_NOMEM; + goto error; + } + ret = lttng_dynamic_buffer_append( + buffer, string, var_data_len); + if (ret) { + ret = -LTTNG_ERR_NOMEM; + goto error; + } + } +error: + return ret; +} -- 2.34.1 From 2497f1f54318c8a0b9f214bfeaf5fd28e72929ab Mon Sep 17 00:00:00 2001 From: Jonathan Rajotte Date: Wed, 20 Nov 2019 15:17:49 -0500 Subject: [PATCH 11/16] Cleanup: remove struct lttng_handle from tracker.h MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonathan Rajotte Change-Id: I8b9fd5c86200013cbd60c57505621cb851556b01 Signed-off-by: Jérémie Galarneau --- include/lttng/tracker.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/lttng/tracker.h b/include/lttng/tracker.h index 1da12f82b..51e1680c1 100644 --- a/include/lttng/tracker.h +++ b/include/lttng/tracker.h @@ -20,6 +20,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -49,7 +50,6 @@ enum lttng_tracker_id_status { LTTNG_TRACKER_ID_STATUS_UNSET = 1, }; -struct lttng_handle; struct lttng_tracker_id; struct lttng_tracker_ids; -- 2.34.1 From 3997aaaea8359ce02da6eee1bb127e2c166425b2 Mon Sep 17 00:00:00 2001 From: Jonathan Rajotte Date: Wed, 20 Nov 2019 15:25:16 -0500 Subject: [PATCH 12/16] tracker: update API documentation MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonathan Rajotte Change-Id: I71f02c5cbebe7ed8e19aee6bc0d2af7741ed272f Signed-off-by: Jérémie Galarneau --- include/lttng/tracker.h | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/include/lttng/tracker.h b/include/lttng/tracker.h index 51e1680c1..7427cf157 100644 --- a/include/lttng/tracker.h +++ b/include/lttng/tracker.h @@ -50,7 +50,14 @@ enum lttng_tracker_id_status { LTTNG_TRACKER_ID_STATUS_UNSET = 1, }; +/* + * A tracker id. + */ struct lttng_tracker_id; + +/* + * A collection of tracker id. + */ struct lttng_tracker_ids; /* @@ -101,18 +108,18 @@ extern enum lttng_tracker_id_status lttng_tracker_id_set_all( struct lttng_tracker_id *id); /* - * Destroys (frees) a tracker id. + * Destroy a tracker id. */ extern void lttng_tracker_id_destroy(struct lttng_tracker_id *id); /* - * Returns the type of the tracker id. + * Get the type of a tracker id. */ extern enum lttng_tracker_id_type lttng_tracker_id_get_type( const struct lttng_tracker_id *id); /* - * Returns the value of the tracker id. + * Get the value of a tracker id. * * Returns LTTNG_TRACKER_ID_OK on success, * LTTNG_TRACKER_ID_STATUS_INVALID when the tracker is not of type @@ -123,7 +130,7 @@ extern enum lttng_tracker_id_status lttng_tracker_id_get_value( const struct lttng_tracker_id *id, int *value); /* - * Returns the string representation of the tracker id. + * Get the string representation of the tracker id. * * Returns LTTNG_TRACKER_ID_OK on success, * LTTNG_TRACKER_ID_STATUS_INVALID when the tracker is not of type @@ -157,13 +164,10 @@ extern int lttng_untrack_id(struct lttng_handle *handle, const struct lttng_tracker_id *id); /* - * List IDs in the tracker. + * List IDs of a tracker. * - * tracker_type is the type of tracker. - * ids is set to an allocated lttng_tracker_ids representing IDs - * currently tracked. - * On success, caller is responsible for freeing ids - * using lttng_tracker_ids_destroy. + * On success, ids is allocated. + * The ids collection must be freed by the caller with lttng_destroy_ids(). * * Returns 0 on success, else a negative LTTng error code. */ -- 2.34.1 From 6186e5b839c77af387614eec6a1c24053e46c849 Mon Sep 17 00:00:00 2001 From: Jonathan Rajotte Date: Wed, 20 Nov 2019 16:14:39 -0500 Subject: [PATCH 13/16] Fix: initialize var_data to NULL MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Remove a false-positive from scan-build. Initialization of var_data_len should have been enough but scan build is not smart enough to understand this. Signed-off-by: Jonathan Rajotte Change-Id: I90cb449f3092db432967a3f2ea5eedb0728b8678 Signed-off-by: Jérémie Galarneau --- src/lib/lttng-ctl/lttng-ctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index cfe437118..95515007c 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -3134,7 +3134,7 @@ static int lttng_track_untrack_id(struct lttng_handle *handle, { int ret; struct lttcomm_session_msg lsm; - const char *var_data; + const char *var_data = NULL; size_t var_data_len = 0; int value; enum lttng_tracker_id_status status; -- 2.34.1 From 8539125677fb0761db1fa2e4b2118eddd5765868 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Fri, 20 Dec 2019 01:39:17 -0500 Subject: [PATCH 14/16] Fix: lttng-clear: invalid free of session name MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Valgrind reports an invalid free of session_name when it is sourced from the popt args. Only free it when it comes from the .lttngrc file. This also caused spurious core dumps when running the tests on one of my machines. Signed-off-by: Jérémie Galarneau Change-Id: I194cd36147a1028aad503b4e5d3ea23732a30bc5 --- src/bin/lttng/commands/clear.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/bin/lttng/commands/clear.c b/src/bin/lttng/commands/clear.c index 353c855c6..24db9f37e 100644 --- a/src/bin/lttng/commands/clear.c +++ b/src/bin/lttng/commands/clear.c @@ -168,7 +168,7 @@ int cmd_clear(int argc, const char **argv) static poptContext pc; char *session_name = NULL; const char *leftover = NULL; - + bool free_session_name = false; struct lttng_session *sessions = NULL; int count; int found; @@ -224,13 +224,7 @@ int cmd_clear(int argc, const char **argv) } if (!opt_clear_all) { - /* - * popt expects us to free this even if it returns a const char *. - * See https://www.mail-archive.com/popt-devel@rpm5.org/msg00193.html - * Force cast to char * allowing later freeing if necessary. - */ session_name = (char *) poptGetArg(pc); - if (!session_name) { /* No session name specified, lookup default */ session_name = get_session_name(); @@ -239,6 +233,7 @@ int cmd_clear(int argc, const char **argv) success = 0; goto mi_closing; } + free_session_name = true; } } else { session_name = NULL; @@ -323,7 +318,9 @@ end: } free(sessions); - free(session_name); + if (free_session_name) { + free(session_name); + } /* Overwrite ret if an error occurred during clear_session/all */ ret = command_ret ? command_ret : ret; -- 2.34.1 From 74e89a8c6a6824c4ca8179a3ae7b9cc4c99bddc5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Fri, 20 Dec 2019 15:55:27 -0500 Subject: [PATCH 15/16] Sync lttng-modules ABI version in internal kernel-ioctl.h MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérémie Galarneau Change-Id: I67eafac24bc8db62831b6bc72497c706ff383a07 --- src/common/kernel-ctl/kernel-ioctl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/kernel-ctl/kernel-ioctl.h b/src/common/kernel-ctl/kernel-ioctl.h index 4fef928d6..8922f58d0 100644 --- a/src/common/kernel-ctl/kernel-ioctl.h +++ b/src/common/kernel-ctl/kernel-ioctl.h @@ -20,7 +20,7 @@ #define _LTT_KERNEL_IOCTL_H #define LTTNG_MODULES_ABI_MAJOR_VERSION 2 -#define LTTNG_MODULES_ABI_MINOR_VERSION 3 +#define LTTNG_MODULES_ABI_MINOR_VERSION 5 /* Get a snapshot of the current ring buffer producer and consumer positions */ #define RING_BUFFER_SNAPSHOT _IO(0xF6, 0x00) -- 2.34.1 From 208ddc0608797ba50c3ce007ba7b4f887e83d87c Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Fri, 20 Dec 2019 16:26:17 -0500 Subject: [PATCH 16/16] Sync lttng-ust ABI version in ust-abi-internal.h MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Bump LTTNG_UST_ABI_MINOR_VERSION to 1 Increment the minor version of lttng-ust ABI to 1, to take into account that the "clear" command was added in this release cycle. This will allow future LTTng-tools versions to check for this capability. Signed-off-by: Jérémie Galarneau Change-Id: I472eb11589547a9fa119d061a2c1886371b87f69 --- src/bin/lttng-sessiond/ust-abi-internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/lttng-sessiond/ust-abi-internal.h b/src/bin/lttng-sessiond/ust-abi-internal.h index 8944d0593..5c22378cd 100644 --- a/src/bin/lttng-sessiond/ust-abi-internal.h +++ b/src/bin/lttng-sessiond/ust-abi-internal.h @@ -47,7 +47,7 @@ /* Version for ABI between liblttng-ust, sessiond, consumerd */ #define LTTNG_UST_ABI_MAJOR_VERSION 8 -#define LTTNG_UST_ABI_MINOR_VERSION 0 +#define LTTNG_UST_ABI_MINOR_VERSION 1 enum lttng_ust_instrumentation { LTTNG_UST_TRACEPOINT = 0, -- 2.34.1