/*
- * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
- * Copyright (C) 2015 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
+ * Copyright (C) 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2 only,
- * as published by the Free Software Foundation.
+ * SPDX-License-Identifier: GPL-2.0-only
*
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define _LGPL_SOURCE
#include <ctype.h>
#include <popt.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct id_list {
size_t nr;
- struct lttng_tracker_id *array;
+ struct lttng_tracker_id **array;
};
static char *opt_session_name;
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) {
}
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;
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;
}
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;
}
}
assign:
+ /* SUCCESS */
*_id_list = id_list;
- goto end; /* SUCCESS */
+ goto end;
- /* ERROR */
error:
+ /* ERROR */
free_id_list(id_list);
end:
free(id_string);
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,
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. */
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;
}
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;
+ const char *msg = NULL;
switch (-ret) {
case LTTNG_ERR_ID_TRACKED:
break;
}
if (msg) {
- switch (item->type) {
+ switch (type) {
case LTTNG_ID_ALL:
WARN("All %ss %s in session %s",
tracker_str, msg,
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:
}
}
} 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:
int cmd_track_untrack(enum cmd_type cmd_type, const char *cmd_str,
int argc, const char **argv, const char *help_msg)
{
- int opt, ret = 0;
+ int opt, ret = 0, success = 1;
+ bool opt_all_present = false;
enum cmd_error_code command_ret = CMD_SUCCESS;
- int success = 1;
static poptContext pc;
char *session_name = NULL;
+ const char *leftover = NULL;
struct mi_writer *writer = NULL;
if (argc < 1) {
type_state = STATE_VGID;
break;
case OPT_ALL:
- switch (type_state) {
- case STATE_PID:
- opt_pid.all = 1;
- break;
- case STATE_VPID:
- opt_vpid.all = 1;
- break;
- case STATE_UID:
- opt_uid.all = 1;
- break;
- case STATE_VUID:
- opt_vuid.all = 1;
- break;
- case STATE_GID:
- opt_gid.all = 1;
- break;
- case STATE_VGID:
- opt_vgid.all = 1;
- break;
- default:
- command_ret = CMD_ERROR;
- goto end;
- }
+ opt_all_present = true;
break;
default:
command_ret = CMD_UNDEFINED;
goto end;
}
+ /*
+ * If the `--all` option is present set the appropriate tracker's `all`
+ * field.
+ */
+ if (opt_all_present) {
+ switch (type_state) {
+ case STATE_PID:
+ opt_pid.all = 1;
+ break;
+ case STATE_VPID:
+ opt_vpid.all = 1;
+ break;
+ case STATE_UID:
+ opt_uid.all = 1;
+ break;
+ case STATE_VUID:
+ opt_vuid.all = 1;
+ break;
+ case STATE_GID:
+ opt_gid.all = 1;
+ break;
+ case STATE_VGID:
+ opt_vgid.all = 1;
+ break;
+ default:
+ command_ret = CMD_ERROR;
+ goto end;
+ }
+ }
+
if (!opt_session_name) {
session_name = get_session_name();
if (session_name == NULL) {
session_name = opt_session_name;
}
+ leftover = poptGetArg(pc);
+ if (leftover) {
+ ERR("Unknown argument: %s", leftover);
+ command_ret = CMD_ERROR;
+ goto end;
+ }
+
/* Mi check */
if (lttng_opt_mi) {
writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);