Exemplo n.º 1
0
/*
 * Returns 0 on success, negative UST or system error value on error.
 */
int ustctl_recv_register_channel(int sock,
	int *session_objd,		/* session descriptor (output) */
	int *channel_objd,		/* channel descriptor (output) */
	size_t *nr_fields,
	struct ustctl_field **fields)
{
	ssize_t len;
	struct ustcomm_notify_channel_msg msg;
	size_t fields_len;
	struct ustctl_field *a_fields;

	len = ustcomm_recv_unix_sock(sock, &msg, sizeof(msg));
	if (len > 0 && len != sizeof(msg))
		return -EIO;
	if (len == 0)
		return -EPIPE;
	if (len < 0)
		return len;

	*session_objd = msg.session_objd;
	*channel_objd = msg.channel_objd;
	fields_len = msg.ctx_fields_len;

	if (fields_len % sizeof(*a_fields) != 0) {
		return -EINVAL;
	}

	/* recv fields */
	if (fields_len) {
		a_fields = zmalloc(fields_len);
		if (!a_fields) {
			len = -ENOMEM;
			goto alloc_error;
		}
		len = ustcomm_recv_unix_sock(sock, a_fields, fields_len);
		if (len > 0 && len != fields_len) {
			len = -EIO;
			goto fields_error;
		}
		if (len == 0) {
			len = -EPIPE;
			goto fields_error;
		}
		if (len < 0) {
			goto fields_error;
		}
		*fields = a_fields;
	} else {
		*fields = NULL;
	}
	*nr_fields = fields_len / sizeof(*a_fields);
	return 0;

fields_error:
	free(a_fields);
alloc_error:
	return len;
}
Exemplo n.º 2
0
int ustctl_tracepoint_field_list_get(int sock, int tp_field_list_handle,
		struct lttng_ust_field_iter *iter)
{
	struct ustcomm_ust_msg lum;
	struct ustcomm_ust_reply lur;
	int ret;
	ssize_t len;

	if (!iter)
		return -EINVAL;

	memset(&lum, 0, sizeof(lum));
	lum.handle = tp_field_list_handle;
	lum.cmd = LTTNG_UST_TRACEPOINT_FIELD_LIST_GET;
	ret = ustcomm_send_app_cmd(sock, &lum, &lur);
	if (ret)
		return ret;
	len = ustcomm_recv_unix_sock(sock, iter, sizeof(*iter));
	if (len != sizeof(*iter)) {
		return -EINVAL;
	}
	DBG("received tracepoint field list entry event_name %s event_loglevel %d field_name %s field_type %d",
		iter->event_name,
		iter->loglevel,
		iter->field_name,
		iter->type);
	return 0;
}
Exemplo n.º 3
0
int ustctl_recv_notify(int sock, enum ustctl_notify_cmd *notify_cmd)
{
	struct ustcomm_notify_hdr header;
	ssize_t len;

	len = ustcomm_recv_unix_sock(sock, &header, sizeof(header));
	if (len > 0 && len != sizeof(header))
		return -EIO;
	if (len == 0)
		return -EPIPE;
	if (len < 0)
		return len;
	switch (header.notify_cmd) {
	case 0:
		*notify_cmd = USTCTL_NOTIFY_CMD_EVENT;
		break;
	case 1:
		*notify_cmd = USTCTL_NOTIFY_CMD_CHANNEL;
		break;
	default:
		return -EINVAL;
	}
	return 0;
}
Exemplo n.º 4
0
int main(int argc, char **argv)
{
	const char *home_dir;
	char home_rundir[PATH_MAX];
	char *cmd = NULL;
	int ret, wait_shm_fd;
	struct sigaction act;
	mode_t old_umask = 0;
	long page_size;

	set_ulimit();

	/* Ignore sigpipe */
	memset(&act, 0, sizeof(act));
	ret = sigemptyset(&act.sa_mask);
	if (ret == -1) {
		perror("sigemptyset");
		return -1;
	}

	act.sa_handler = SIG_IGN;
	ret = sigaction(SIGPIPE, &act, NULL);
	if (ret == -1) {
		perror("sigaction");
		return -1;
	}

	/* Handle SIGTERM */
	act.sa_handler = handle_signals;
	ret = sigaction(SIGTERM, &act, NULL);
	if (ret == -1) {
		perror("sigaction");
		return -1;
	}
	/* Handle SIGINT */
	ret = sigaction(SIGINT, &act, NULL);
	if (ret == -1) {
		perror("sigaction");
		return -1;
	}

	page_size = sysconf(_SC_PAGE_SIZE);
	if (page_size <= 0) {
		if (!page_size) {
			errno = EINVAL;
		}
		perror("Error in sysconf(_SC_PAGE_SIZE)");
		return -1;
	}

	if (geteuid() == 0) {
		ret = mkdir(LTTNG_RUNDIR, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
		if (ret && errno != EEXIST) {
			perror("mkdir");
			return -1;
		}
		wait_shm_fd = get_wait_shm(DEFAULT_GLOBAL_APPS_WAIT_SHM_PATH,
					page_size, 1);
		if (wait_shm_fd < 0) {
			perror("global wait shm error");
			return -1;
		}
		strcpy(apps_sock_path, DEFAULT_GLOBAL_APPS_UNIX_SOCK);
		old_umask = umask(0);
	} else {
		home_dir = (const char *) getenv("HOME");
		if (!home_dir) {
			perror("getenv error");
			return -ENOENT;
		}

		snprintf(home_rundir, PATH_MAX,
			 LTTNG_HOME_RUNDIR, home_dir);

		ret = mkdir(home_rundir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
		if (ret && errno != EEXIST) {
			perror("mkdir");
			return -1;
		}

		snprintf(local_apps_wait_shm_path, PATH_MAX,
			 DEFAULT_HOME_APPS_WAIT_SHM_PATH, getuid());
		wait_shm_fd = get_wait_shm(local_apps_wait_shm_path,
					page_size, 0);
		if (wait_shm_fd < 0) {
			perror("local wait shm error");
			return -1;
		}
		snprintf(apps_sock_path, PATH_MAX,
			 DEFAULT_HOME_APPS_UNIX_SOCK, home_dir);
	}

	ret = ustcomm_create_unix_sock(apps_sock_path);
	if (ret < 0) {
		perror("create error");
		return ret;
	}
	apps_socket = ret;

	if (getuid() == 0) {
		/* File permission MUST be 666 */
		ret = chmod(apps_sock_path,
				S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
		if (ret < 0) {
			printf("Set file permissions failed: %s\n", apps_sock_path);
			perror("chmod");
			goto end;
		}
		umask(old_umask);
	}
	ret = ustcomm_listen_unix_sock(apps_socket);
	if (ret < 0) {
		perror("listen error");
		return ret;
	}

	/* wake up futexes */
	ret = update_futex(wait_shm_fd, 1);
	if (ret) {
		fprintf(stderr, "Error wakeup futex\n");
		return -1;
	}

	for (;;) {
		int sock;
		ssize_t len;
		struct {
			uint32_t major;
			uint32_t minor;
			pid_t pid;
			pid_t ppid;
			uid_t uid;
			gid_t gid;
			uint32_t bits_per_long;
			char name[16];	/* Process name */
		} reg_msg;
		char bufname[17];

		if (quit_program)
			break;

		printf("Accepting application registration\n");
		sock = ustcomm_accept_unix_sock(apps_socket);
		if (sock < 0) {
			perror("accept error");
			goto end;
		}

		/*
		 * Basic recv here to handle the very simple data
		 * that the libust send to register (reg_msg).
		 */
		len = ustcomm_recv_unix_sock(sock, &reg_msg, sizeof(reg_msg));
		if (len < 0 || len != sizeof(reg_msg)) {
			perror("ustcomm_recv_unix_sock");
			continue;
		}
		memcpy(bufname, reg_msg.name, 16);
		bufname[16] = '\0';
		printf("Application %s pid %u ppid %u uid %u gid %u has registered (version : %u.%u)\n",
			bufname, reg_msg.pid, reg_msg.ppid, reg_msg.uid,
			reg_msg.gid, reg_msg.major, reg_msg.minor);
		ret = send_app_msgs(sock);
		if (ret) {
			printf("Error in send_app_msgs.\n");
			sleep(1);
		}
		close(sock);
	}

end:
	printf("quitting.\n");
	/* Let applications know we are not responding anymore */
	ret = update_futex(wait_shm_fd, 0);
	if (ret) {
		fprintf(stderr, "Error wakeup futex\n");
		return -1;
	}

	if (geteuid()) {
		printf("Removing %s directory\n", home_rundir);
		ret = asprintf(&cmd, "rm -rf %s", home_rundir);
		if (ret < 0) {
			printf("asprintf failed. Something is really wrong!\n");
			return -1;
		}

		/* Remove lttng run directory */
		ret = system(cmd);
		if (ret < 0) {
			printf("Unable to clean %s\n", home_rundir);
			return -1;
		}
	}

	return 0;
}
Exemplo n.º 5
0
int ustctl_recv_stream_from_consumer(int sock,
		struct lttng_ust_object_data **_stream_data)
{
	struct lttng_ust_object_data *stream_data;
	ssize_t len;
	int ret;
	int fds[2];

	stream_data = zmalloc(sizeof(*stream_data));
	if (!stream_data) {
		ret = -ENOMEM;
		goto error_alloc;
	}

	stream_data->type = LTTNG_UST_OBJECT_TYPE_STREAM;
	stream_data->handle = -1;

	/* recv mmap size */
	len = ustcomm_recv_unix_sock(sock, &stream_data->size,
			sizeof(stream_data->size));
	if (len != sizeof(stream_data->size)) {
		if (len < 0)
			ret = len;
		else
			ret = -EINVAL;
		goto error;
	}
	if (stream_data->size == -1) {
		ret = -LTTNG_UST_ERR_NOENT;
		goto error;
	}

	/* recv stream nr */
	len = ustcomm_recv_unix_sock(sock, &stream_data->u.stream.stream_nr,
			sizeof(stream_data->u.stream.stream_nr));
	if (len != sizeof(stream_data->u.stream.stream_nr)) {
		if (len < 0)
			ret = len;
		else
			ret = -EINVAL;
		goto error;
	}

	/* recv shm fd and wakeup fd */
	len = ustcomm_recv_fds_unix_sock(sock, fds, 2);
	if (len <= 0) {
		if (len < 0) {
			ret = len;
			goto error;
		} else {
			ret = -EIO;
			goto error;
		}
	}
	stream_data->u.stream.shm_fd = fds[0];
	stream_data->u.stream.wakeup_fd = fds[1];
	*_stream_data = stream_data;
	return 0;

error:
	free(stream_data);
error_alloc:
	return ret;
}
Exemplo n.º 6
0
int ustctl_recv_channel_from_consumer(int sock,
		struct lttng_ust_object_data **_channel_data)
{
	struct lttng_ust_object_data *channel_data;
	ssize_t len;
	int wakeup_fd;
	int ret;

	channel_data = zmalloc(sizeof(*channel_data));
	if (!channel_data) {
		ret = -ENOMEM;
		goto error_alloc;
	}
	channel_data->type = LTTNG_UST_OBJECT_TYPE_CHANNEL;
	channel_data->handle = -1;

	/* recv mmap size */
	len = ustcomm_recv_unix_sock(sock, &channel_data->size,
			sizeof(channel_data->size));
	if (len != sizeof(channel_data->size)) {
		if (len < 0)
			ret = len;
		else
			ret = -EINVAL;
		goto error;
	}

	/* recv channel type */
	len = ustcomm_recv_unix_sock(sock, &channel_data->u.channel.type,
			sizeof(channel_data->u.channel.type));
	if (len != sizeof(channel_data->u.channel.type)) {
		if (len < 0)
			ret = len;
		else
			ret = -EINVAL;
		goto error;
	}

	/* recv channel data */
	channel_data->u.channel.data = zmalloc(channel_data->size);
	if (!channel_data->u.channel.data) {
		ret = -ENOMEM;
		goto error;
	}
	len = ustcomm_recv_unix_sock(sock, channel_data->u.channel.data,
			channel_data->size);
	if (len != channel_data->size) {
		if (len < 0)
			ret = len;
		else
			ret = -EINVAL;
		goto error_recv_data;
	}
	/* recv wakeup fd */
	len = ustcomm_recv_fds_unix_sock(sock, &wakeup_fd, 1);
	if (len <= 0) {
		if (len < 0) {
			ret = len;
			goto error_recv_data;
		} else {
			ret = -EIO;
			goto error_recv_data;
		}
	}
	channel_data->u.channel.wakeup_fd = wakeup_fd;
	*_channel_data = channel_data;
	return 0;

error_recv_data:
	free(channel_data->u.channel.data);
error:
	free(channel_data);
error_alloc:
	return ret;
}
Exemplo n.º 7
0
/*
 * Returns 0 on success, negative error value on error.
 */
int ustctl_recv_register_event(int sock,
	int *session_objd,
	int *channel_objd,
	char *event_name,
	int *loglevel,
	char **signature,
	size_t *nr_fields,
	struct ustctl_field **fields,
	char **model_emf_uri)
{
	ssize_t len;
	struct ustcomm_notify_event_msg msg;
	size_t signature_len, fields_len, model_emf_uri_len;
	char *a_sign = NULL, *a_model_emf_uri = NULL;
	struct ustctl_field *a_fields = NULL;

	len = ustcomm_recv_unix_sock(sock, &msg, sizeof(msg));
	if (len > 0 && len != sizeof(msg))
		return -EIO;
	if (len == 0)
		return -EPIPE;
	if (len < 0)
		return len;

	*session_objd = msg.session_objd;
	*channel_objd = msg.channel_objd;
	strncpy(event_name, msg.event_name, LTTNG_UST_SYM_NAME_LEN);
	event_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
	*loglevel = msg.loglevel;
	signature_len = msg.signature_len;
	fields_len = msg.fields_len;

	if (fields_len % sizeof(*a_fields) != 0) {
		return -EINVAL;
	}

	model_emf_uri_len = msg.model_emf_uri_len;

	/* recv signature. contains at least \0. */
	a_sign = zmalloc(signature_len);
	if (!a_sign)
		return -ENOMEM;
	len = ustcomm_recv_unix_sock(sock, a_sign, signature_len);
	if (len > 0 && len != signature_len) {
		len = -EIO;
		goto signature_error;
	}
	if (len == 0) {
		len = -EPIPE;
		goto signature_error;
	}
	if (len < 0) {
		goto signature_error;
	}
	/* Enforce end of string */
	a_sign[signature_len - 1] = '\0';

	/* recv fields */
	if (fields_len) {
		a_fields = zmalloc(fields_len);
		if (!a_fields) {
			len = -ENOMEM;
			goto signature_error;
		}
		len = ustcomm_recv_unix_sock(sock, a_fields, fields_len);
		if (len > 0 && len != fields_len) {
			len = -EIO;
			goto fields_error;
		}
		if (len == 0) {
			len = -EPIPE;
			goto fields_error;
		}
		if (len < 0) {
			goto fields_error;
		}
	}

	if (model_emf_uri_len) {
		/* recv model_emf_uri_len */
		a_model_emf_uri = zmalloc(model_emf_uri_len);
		if (!a_model_emf_uri) {
			len = -ENOMEM;
			goto fields_error;
		}
		len = ustcomm_recv_unix_sock(sock, a_model_emf_uri,
				model_emf_uri_len);
		if (len > 0 && len != model_emf_uri_len) {
			len = -EIO;
			goto model_error;
		}
		if (len == 0) {
			len = -EPIPE;
			goto model_error;
		}
		if (len < 0) {
			goto model_error;
		}
		/* Enforce end of string */
		a_model_emf_uri[model_emf_uri_len - 1] = '\0';
	}

	*signature = a_sign;
	*nr_fields = fields_len / sizeof(*a_fields);
	*fields = a_fields;
	*model_emf_uri = a_model_emf_uri;

	return 0;

model_error:
	free(a_model_emf_uri);
fields_error:
	free(a_fields);
signature_error:
	free(a_sign);
	return len;
}
Exemplo n.º 8
0
/*
 * Returns 0 on success, negative error value on error.
 */
int ustctl_recv_reg_msg(int sock,
	enum ustctl_socket_type *type,
	uint32_t *major,
	uint32_t *minor,
	uint32_t *pid,
	uint32_t *ppid,
	uint32_t *uid,
	uint32_t *gid,
	uint32_t *bits_per_long,
	uint32_t *uint8_t_alignment,
	uint32_t *uint16_t_alignment,
	uint32_t *uint32_t_alignment,
	uint32_t *uint64_t_alignment,
	uint32_t *long_alignment,
	int *byte_order,
	char *name)
{
	ssize_t len;
	struct ustctl_reg_msg reg_msg;

	len = ustcomm_recv_unix_sock(sock, &reg_msg, sizeof(reg_msg));
	if (len > 0 && len != sizeof(reg_msg))
		return -EIO;
	if (len == 0)
		return -EPIPE;
	if (len < 0)
		return len;

	if (reg_msg.magic == LTTNG_UST_COMM_MAGIC) {
		*byte_order = BYTE_ORDER == BIG_ENDIAN ?
				BIG_ENDIAN : LITTLE_ENDIAN;
	} else if (reg_msg.magic == bswap_32(LTTNG_UST_COMM_MAGIC)) {
		*byte_order = BYTE_ORDER == BIG_ENDIAN ?
				LITTLE_ENDIAN : BIG_ENDIAN;
	} else {
		return -LTTNG_UST_ERR_INVAL_MAGIC;
	}
	switch (reg_msg.socket_type) {
	case 0:	*type = USTCTL_SOCKET_CMD;
		break;
	case 1:	*type = USTCTL_SOCKET_NOTIFY;
		break;
	default:
		return -LTTNG_UST_ERR_INVAL_SOCKET_TYPE;
	}
	*major = reg_msg.major;
	*minor = reg_msg.minor;
	*pid = reg_msg.pid;
	*ppid = reg_msg.ppid;
	*uid = reg_msg.uid;
	*gid = reg_msg.gid;
	*bits_per_long = reg_msg.bits_per_long;
	*uint8_t_alignment = reg_msg.uint8_t_alignment;
	*uint16_t_alignment = reg_msg.uint16_t_alignment;
	*uint32_t_alignment = reg_msg.uint32_t_alignment;
	*uint64_t_alignment = reg_msg.uint64_t_alignment;
	*long_alignment = reg_msg.long_alignment;
	memcpy(name, reg_msg.name, LTTNG_UST_ABI_PROCNAME_LEN);
	if (reg_msg.major != LTTNG_UST_ABI_MAJOR_VERSION) {
		return -LTTNG_UST_ERR_UNSUP_MAJOR;
	}

	return 0;
}