*
* Linux Trace Toolkit Control Library
*
- * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
+ * Copyright (C) 2011 EfficiOS Inc.
* Copyright (C) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
* SPDX-License-Identifier: LGPL-2.1-only
#include <grp.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stdint.h>
#include <string.h>
#include <unistd.h>
return ret;
}
-static int check_enough_available_memory(size_t num_bytes_requested_per_cpu)
+static enum lttng_error_code check_enough_available_memory(
+ uint64_t num_bytes_requested_per_cpu)
{
int ret;
+ enum lttng_error_code ret_code;
long num_cpu;
- size_t best_mem_info;
- size_t num_bytes_requested_total;
+ uint64_t best_mem_info;
+ uint64_t num_bytes_requested_total;
/*
* Get the number of CPU currently online to compute the amount of
*/
num_cpu = sysconf(_SC_NPROCESSORS_ONLN);
if (num_cpu == -1) {
- goto error;
+ ret_code = LTTNG_ERR_FATAL;
+ goto end;
}
- num_bytes_requested_total = num_bytes_requested_per_cpu * num_cpu;
+ if (num_bytes_requested_per_cpu > UINT64_MAX / (uint64_t) num_cpu) {
+ /* Overflow */
+ ret_code = LTTNG_ERR_OVERFLOW;
+ goto end;
+ }
+
+ num_bytes_requested_total =
+ num_bytes_requested_per_cpu * (uint64_t) num_cpu;
/*
* Try to get the `MemAvail` field of `/proc/meminfo`. This is the most
goto success;
}
-error:
- return -1;
+ /* No valid source of information. */
+ ret_code = LTTNG_ERR_NOMEM;
+ goto end;
+
success:
- return best_mem_info >= num_bytes_requested_total;
+ if (best_mem_info >= num_bytes_requested_total) {
+ ret_code = LTTNG_OK;
+ } else {
+ ret_code = LTTNG_ERR_NOMEM;
+ }
+end:
+ return ret_code;
}
/*
for (i = 0; i < exclusion_count; i++) {
size_t exclusion_len;
- exclusion_len = lttng_strnlen(*(exclusion_list + i),
+ exclusion_len = lttng_strnlen(exclusion_list[i],
LTTNG_SYMBOL_NAME_LEN);
if (exclusion_len == LTTNG_SYMBOL_NAME_LEN) {
/* Exclusion is not NULL-terminated. */
}
ret = lttng_dynamic_buffer_append(&payload.buffer,
- *(exclusion_list + i), LTTNG_SYMBOL_NAME_LEN);
+ exclusion_list[i], exclusion_len);
+ if (ret) {
+ goto mem_error;
+ }
+
+ /*
+ * Padding the rest of the entry with zeros. Every exclusion
+ * entries take LTTNG_SYMBOL_NAME_LEN bytes in the buffer.
+ */
+ ret = lttng_dynamic_buffer_set_size(&payload.buffer,
+ LTTNG_SYMBOL_NAME_LEN * (i + 1));
if (ret) {
goto mem_error;
}
int lttng_enable_channel(struct lttng_handle *handle,
struct lttng_channel *in_chan)
{
+ enum lttng_error_code ret_code;
int ret;
struct lttcomm_session_msg lsm;
- size_t total_buffer_size_needed_per_cpu = 0;
+ uint64_t total_buffer_size_needed_per_cpu = 0;
/* NULL arguments are forbidden. No default values. */
if (handle == NULL || in_chan == NULL) {
* Verify that the amount of memory required to create the requested
* buffer is available on the system at the moment.
*/
+ if (lsm.u.channel.chan.attr.num_subbuf >
+ UINT64_MAX / lsm.u.channel.chan.attr.subbuf_size) {
+ /* Overflow */
+ ret = -LTTNG_ERR_OVERFLOW;
+ goto end;
+ }
+
total_buffer_size_needed_per_cpu = lsm.u.channel.chan.attr.num_subbuf *
lsm.u.channel.chan.attr.subbuf_size;
- if (!check_enough_available_memory(total_buffer_size_needed_per_cpu)) {
- return -LTTNG_ERR_NOMEM;
+ ret_code = check_enough_available_memory(
+ total_buffer_size_needed_per_cpu);
+ if (ret_code != LTTNG_OK) {
+ ret = -ret_code;
+ goto end;
}
lsm.cmd_type = LTTNG_ENABLE_CHANNEL;
memset(&lsm, 0, sizeof(lsm));
lsm.cmd_type = LTTNG_LIST_SESSIONS;
+ /*
+ * Initialize out_sessions to NULL so it is initialized when
+ * lttng_list_sessions returns 0, thus allowing *out_sessions to
+ * be subsequently freed.
+ */
+ *out_sessions = NULL;
ret = lttng_ctl_ask_sessiond(&lsm, (void**) &sessions);
if (ret <= 0) {
goto end;
if (ret % session_size) {
ret = -LTTNG_ERR_UNK;
free(sessions);
- *out_sessions = NULL;
goto end;
}
session_count = (size_t) ret / session_size;
*/
int lttng_set_tracing_group(const char *name)
{
+ char *new_group;
if (name == NULL) {
return -LTTNG_ERR_INVALID;
}
- if (asprintf(&tracing_group, "%s", name) < 0) {
+ if (asprintf(&new_group, "%s", name) < 0) {
return -LTTNG_ERR_FATAL;
}
+ free(tracing_group);
+ tracing_group = new_group;
+ new_group = NULL;
+
return 0;
}