*/
#define _GNU_SOURCE
-#include <errno.h>
#include <grp.h>
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <lttng/lttng.h>
-
#include <lttng-sessiond-comm.h>
-#include "lttngerr.h"
-#include "lttng-share.h"
+#include <lttng-share.h>
+#include <lttng/lttng.h>
+#include <lttngerr.h>
/* Socket to session daemon for communication */
static int sessiond_socket;
/*
* Check if the specified group name exist.
*
- * If yes return 0, else return -1.
+ * If yes return 1, else return -1.
*/
static int check_tracing_group(const char *grp_name)
{
/* Alloc group list of the right size */
grp_list = malloc(grp_list_size * sizeof(gid_t));
+ if (!grp_list) {
+ ret = -1;
+ goto end;
+ }
grp_id = getgroups(grp_list_size, grp_list);
if (grp_id < -1) {
perror("getgroups");
for (i = 0; i < grp_list_size; i++) {
if (grp_list[i] == grp_tracing->gr_gid) {
- ret = 0;
+ ret = 1;
break;
}
}
}
/*
- * Set sessiond socket path by putting it in the global sessiond_sock_path
- * variable.
+ * Try connect to session daemon with sock_path.
+ *
+ * Return 0 on success, else -1
+ */
+static int try_connect_sessiond(const char *sock_path)
+{
+ int ret;
+
+ /* If socket exist, we check if the daemon listens for connect. */
+ ret = access(sock_path, F_OK);
+ if (ret < 0) {
+ /* Not alive */
+ return -1;
+ }
+
+ ret = lttcomm_connect_unix_sock(sock_path);
+ if (ret < 0) {
+ /* Not alive */
+ return -1;
+ }
+
+ ret = lttcomm_close_unix_sock(ret);
+ if (ret < 0) {
+ perror("lttcomm_close_unix_sock");
+ }
+
+ return 0;
+}
+
+/*
+ * Set sessiond socket path by putting it in the global sessiond_sock_path
+ * variable.
*/
static int set_session_daemon_path(void)
{
int ret;
+ int in_tgroup = 0; /* In tracing group */
+ uid_t uid;
+
+ uid = getuid();
- /* Are we in the tracing group ? */
- ret = check_tracing_group(tracing_group);
- if (ret < 0 && getuid() != 0) {
+ if (uid != 0) {
+ /* Are we in the tracing group ? */
+ in_tgroup = check_tracing_group(tracing_group);
+ }
+
+ if (uid == 0) {
+ /* Root */
+ copy_string(sessiond_sock_path,
+ DEFAULT_GLOBAL_CLIENT_UNIX_SOCK,
+ sizeof(sessiond_sock_path));
+ } else if (in_tgroup) {
+ /* Tracing group */
+ copy_string(sessiond_sock_path,
+ DEFAULT_GLOBAL_CLIENT_UNIX_SOCK,
+ sizeof(sessiond_sock_path));
+
+ ret = try_connect_sessiond(sessiond_sock_path);
+ if (ret < 0) {
+ /* Global session daemon not available */
+ if (snprintf(sessiond_sock_path, sizeof(sessiond_sock_path),
+ DEFAULT_HOME_CLIENT_UNIX_SOCK,
+ getenv("HOME")) < 0) {
+ return -ENOMEM;
+ }
+ }
+ } else {
+ /* Not in tracing group and not root, default */
if (snprintf(sessiond_sock_path, PATH_MAX,
DEFAULT_HOME_CLIENT_UNIX_SOCK,
getenv("HOME")) < 0) {
return -ENOMEM;
}
- } else {
- copy_string(sessiond_sock_path,
- DEFAULT_GLOBAL_CLIENT_UNIX_SOCK,
- PATH_MAX);
}
return 0;
size = llm.data_size;
if (size == 0) {
+ /* If client free with size 0 */
+ if (buf != NULL) {
+ *buf = NULL;
+ }
ret = 0;
goto end;
}
goto end;
}
+ /*
+ * Extra protection not to dereference a NULL pointer. If buf is NULL at
+ * this point, an error is returned and data is freed.
+ */
+ if (buf == NULL) {
+ ret = -1;
+ free(data);
+ goto end;
+ }
+
*buf = data;
ret = size;
{
struct lttcomm_session_msg lsm;
- if (!handle) {
+ if (handle == NULL) {
return -1;
}
{
struct lttcomm_session_msg lsm;
- if (!handle) {
+ /* Safety check. Both are mandatory */
+ if (handle == NULL || ctx == NULL) {
return -1;
}
copy_lttng_domain(&lsm.domain, &handle->domain);
- if (ctx) {
- memcpy(&lsm.u.context.ctx, ctx, sizeof(struct lttng_event_context));
- }
+ memcpy(&lsm.u.context.ctx, ctx, sizeof(struct lttng_event_context));
copy_string(lsm.session.name, handle->session_name,
sizeof(lsm.session.name));
{
struct lttcomm_session_msg lsm;
- if (!handle) {
+ if (handle == NULL || ev == NULL) {
return -1;
}
+ /* If no channel name, we put the default name */
if (channel_name == NULL) {
copy_string(lsm.u.enable.channel_name, DEFAULT_CHANNEL_NAME,
sizeof(lsm.u.enable.channel_name));
copy_lttng_domain(&lsm.domain, &handle->domain);
- if (ev) {
+ if (ev->name[0] != '\0') {
lsm.cmd_type = LTTNG_ENABLE_EVENT;
- memcpy(&lsm.u.enable.event, ev, sizeof(lsm.u.enable.event));
} else {
lsm.cmd_type = LTTNG_ENABLE_ALL_EVENT;
}
+ memcpy(&lsm.u.enable.event, ev, sizeof(lsm.u.enable.event));
copy_string(lsm.session.name, handle->session_name,
sizeof(lsm.session.name));
{
struct lttcomm_session_msg lsm;
- if (!handle) {
+ if (handle == NULL) {
return -1;
}
copy_lttng_domain(&lsm.domain, &handle->domain);
- if (name == NULL) {
+ if (name != NULL) {
copy_string(lsm.u.disable.name, name, sizeof(lsm.u.disable.name));
lsm.cmd_type = LTTNG_DISABLE_EVENT;
} else {
{
struct lttcomm_session_msg lsm;
- if (!handle) {
+ /*
+ * NULL arguments are forbidden. No default values.
+ */
+ if (handle == NULL || chan == NULL) {
return -1;
}
- if (chan) {
- memcpy(&lsm.u.channel.chan, chan, sizeof(lsm.u.channel.chan));
- }
+ memcpy(&lsm.u.channel.chan, chan, sizeof(lsm.u.channel.chan));
lsm.cmd_type = LTTNG_ENABLE_CHANNEL;
{
struct lttcomm_session_msg lsm;
- if (!handle) {
+ /* Safety check. Both are mandatory */
+ if (handle == NULL || name == NULL) {
return -1;
}
- if (name) {
- copy_string(lsm.u.disable.channel_name, name,
- sizeof(lsm.u.disable.channel_name));
- }
-
lsm.cmd_type = LTTNG_DISABLE_CHANNEL;
+ copy_string(lsm.u.disable.channel_name, name,
+ sizeof(lsm.u.disable.channel_name));
+
copy_lttng_domain(&lsm.domain, &handle->domain);
copy_string(lsm.session.name, handle->session_name,
int ret;
struct lttcomm_session_msg lsm;
- if (!handle) {
+ if (handle == NULL) {
return -1;
}
/*
* Return a human readable string of code
*/
-const char *lttng_get_readable_code(int code)
+const char *lttng_strerror(int code)
{
if (code > -LTTCOMM_OK) {
return "Ended with errors";
{
struct lttcomm_session_msg lsm;
- if (!handle) {
+ if (handle == NULL) {
return -1;
}
int ret;
struct lttcomm_session_msg lsm;
- if (!handle) {
+ if (handle == NULL) {
return -1;
}
int ret;
struct lttcomm_session_msg lsm;
- if (!handle) {
+ if (handle == NULL) {
return -1;
}
int ret;
struct lttcomm_session_msg lsm;
- if (!handle) {
+ /* Safety check. An handle and channel name are mandatory */
+ if (handle == NULL || channel_name == NULL) {
return -1;
}
}
/*
- * lttng_set_tracing_group
- *
- * Set tracing group variable with name. This function
- * allocate memory pointed by tracing_group.
+ * Set tracing group variable with name. This function allocate memory pointed
+ * by tracing_group.
*/
int lttng_set_tracing_group(const char *name)
{
+ if (name == NULL) {
+ return -1;
+ }
+
if (asprintf(&tracing_group, "%s", name) < 0) {
return -ENOMEM;
}
{
struct lttcomm_session_msg lsm;
- if (!handle) {
+ /* Safety check. NULL pointer are forbidden */
+ if (handle == NULL || calibrate == NULL) {
return -1;
}
}
/*
- * lttng_check_session_daemon
+ * Set default channel attributes.
+ */
+void lttng_channel_set_default_attr(struct lttng_domain *domain,
+ struct lttng_channel_attr *attr)
+{
+ /* Safety check */
+ if (attr == NULL || domain == NULL) {
+ return;
+ }
+
+ switch (domain->type) {
+ case LTTNG_DOMAIN_KERNEL:
+ attr->overwrite = DEFAULT_CHANNEL_OVERWRITE;
+ attr->switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER;
+ attr->read_timer_interval = DEFAULT_CHANNEL_READ_TIMER;
+
+ attr->subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE;
+ attr->num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM;
+ attr->output = DEFAULT_KERNEL_CHANNEL_OUTPUT;
+ break;
+ case LTTNG_DOMAIN_UST:
+ case LTTNG_DOMAIN_UST_EXEC_NAME:
+ case LTTNG_DOMAIN_UST_PID:
+ case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN:
+ attr->overwrite = DEFAULT_CHANNEL_OVERWRITE;
+ attr->switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER;
+ attr->read_timer_interval = DEFAULT_CHANNEL_READ_TIMER;
+
+ attr->subbuf_size = DEFAULT_UST_CHANNEL_SUBBUF_SIZE;
+ attr->num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM;
+ attr->output = DEFAULT_UST_CHANNEL_OUTPUT;
+ break;
+ default:
+ /* Default behavior */
+ memset(attr, 0, sizeof(struct lttng_channel_attr));
+ break;
+ }
+}
+
+/*
+ * Check if session daemon is alive.
*
- * Yes, return 1
- * No, return 0
- * Error, return negative value
+ * Return 1 if alive or 0 if not.
+ * On error return -1
*/
int lttng_session_daemon_alive(void)
{
return ret;
}
- /* If socket exist, we check if the daemon listens to connect. */
- ret = access(sessiond_sock_path, F_OK);
- if (ret < 0) {
- /* Not alive */
- return 0;
+ if (strlen(sessiond_sock_path) == 0) {
+ /* No socket path set. Weird error */
+ return -1;
}
- ret = lttcomm_connect_unix_sock(sessiond_sock_path);
+ ret = try_connect_sessiond(sessiond_sock_path);
if (ret < 0) {
/* Not alive */
return 0;
}
- ret = lttcomm_close_unix_sock(ret);
- if (ret < 0)
- perror("lttcomm_close_unix_sock");
/* Is alive */
return 1;