*/
#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();
+
+ if (uid != 0) {
+ /* Are we in the tracing group ? */
+ in_tgroup = check_tracing_group(tracing_group);
+ }
- /* Are we in the tracing group ? */
- ret = check_tracing_group(tracing_group);
- if (ret < 0 && getuid() != 0) {
+ 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;
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;
}
}
+/*
+ * Register an outside consumer.
+ */
+int lttng_register_consumer(struct lttng_handle *handle,
+ const char *socket_path)
+{
+ struct lttcomm_session_msg lsm;
+
+ lsm.cmd_type = LTTNG_REGISTER_CONSUMER;
+ copy_string(lsm.session.name, handle->session_name,
+ sizeof(lsm.session.name));
+ copy_lttng_domain(&lsm.domain, &handle->domain);
+
+ copy_string(lsm.u.reg.path, socket_path, sizeof(lsm.u.reg.path));
+
+ return ask_sessiond(&lsm, NULL);
+}
+
/*
* Start tracing for all trace of the session.
*/
{
struct lttcomm_session_msg lsm;
- if (!handle) {
+ if (!handle || ev == NULL) {
return -1;
}
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));
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 {
/*
* 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";
}
/*
- * lttng_check_session_daemon
+ * 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;