Move away files that will be deprecated
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 16 Jun 2011 18:59:54 +0000 (14:59 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 16 Jun 2011 18:59:54 +0000 (14:59 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
46 files changed:
deprecated/libustcomm/Makefile.am [new file with mode: 0644]
deprecated/libustcomm/ustcomm.c [new file with mode: 0644]
deprecated/libustcomm/ustcomm.h [new file with mode: 0644]
deprecated/libustconsumer/Makefile.am [new file with mode: 0644]
deprecated/libustconsumer/libustconsumer.c [new file with mode: 0644]
deprecated/libustconsumer/lowlevel.c [new file with mode: 0644]
deprecated/libustconsumer/lowlevel.h [new file with mode: 0644]
deprecated/libustctl/Makefile.am [new file with mode: 0644]
deprecated/libustctl/README [new file with mode: 0644]
deprecated/libustctl/libustctl.c [new file with mode: 0644]
deprecated/ust-consumerd/Makefile.am [new file with mode: 0644]
deprecated/ust-consumerd/README [new file with mode: 0644]
deprecated/ust-consumerd/ust-consumerd.c [new file with mode: 0644]
deprecated/ustctl/Makefile.am [new file with mode: 0644]
deprecated/ustctl/README [new file with mode: 0644]
deprecated/ustctl/channel_cmds.c [new file with mode: 0644]
deprecated/ustctl/cli.c [new file with mode: 0644]
deprecated/ustctl/cli.h [new file with mode: 0644]
deprecated/ustctl/marker_cmds.c [new file with mode: 0644]
deprecated/ustctl/scanning_functions.c [new file with mode: 0644]
deprecated/ustctl/scanning_functions.h [new file with mode: 0644]
deprecated/ustctl/trace_cmds.c [new file with mode: 0644]
deprecated/ustctl/ustctl.c [new file with mode: 0644]
libustcomm/Makefile.am [deleted file]
libustcomm/ustcomm.c [deleted file]
libustcomm/ustcomm.h [deleted file]
libustconsumer/Makefile.am [deleted file]
libustconsumer/libustconsumer.c [deleted file]
libustconsumer/lowlevel.c [deleted file]
libustconsumer/lowlevel.h [deleted file]
libustctl/Makefile.am [deleted file]
libustctl/README [deleted file]
libustctl/libustctl.c [deleted file]
ust-consumerd/Makefile.am [deleted file]
ust-consumerd/README [deleted file]
ust-consumerd/ust-consumerd.c [deleted file]
ustctl/Makefile.am [deleted file]
ustctl/README [deleted file]
ustctl/channel_cmds.c [deleted file]
ustctl/cli.c [deleted file]
ustctl/cli.h [deleted file]
ustctl/marker_cmds.c [deleted file]
ustctl/scanning_functions.c [deleted file]
ustctl/scanning_functions.h [deleted file]
ustctl/trace_cmds.c [deleted file]
ustctl/ustctl.c [deleted file]

diff --git a/deprecated/libustcomm/Makefile.am b/deprecated/libustcomm/Makefile.am
new file mode 100644 (file)
index 0000000..3ae96d5
--- /dev/null
@@ -0,0 +1,10 @@
+AM_CPPFLAGS = -I$(top_srcdir)/include
+AM_CFLAGS = -fno-strict-aliasing
+
+noinst_LTLIBRARIES = libustcomm.la
+libustcomm_la_SOURCES = \
+       ustcomm.h \
+       ustcomm.c
+
+libustcomm_la_LDFLAGS = -no-undefined -static
+libustcomm_la_CFLAGS = -DUST_COMPONENT="libustcomm" -fPIC -fno-strict-aliasing
diff --git a/deprecated/libustcomm/ustcomm.c b/deprecated/libustcomm/ustcomm.c
new file mode 100644 (file)
index 0000000..07f7f87
--- /dev/null
@@ -0,0 +1,1028 @@
+/* Copyright (C) 2009  Pierre-Marc Fournier
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+/* API used by UST components to communicate with each other via sockets. */
+
+#define _GNU_SOURCE
+#include <dirent.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <poll.h>
+#include <sys/epoll.h>
+#include <sys/stat.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ustcomm.h"
+#include "usterr.h"
+#include "share.h"
+
+static int mkdir_p(const char *path, mode_t mode)
+{
+       const char *path_p;
+       char *tmp;
+
+       int retval = 0;
+       int result;
+       mode_t old_umask;
+
+       tmp = zmalloc(strlen(path) + 1);
+       if (tmp == NULL)
+               return -1;
+
+       /* skip first / */
+       path_p = path+1;
+
+       old_umask = umask(0);
+       for(;;) {
+               while (*path_p != '/') {
+                       if(*path_p == 0)
+                               break;
+                       ++path_p;
+               }
+               if (*path_p == '/') {
+                       strncpy(tmp, path, path_p - path);
+                       tmp[path_p-path] = '\0';
+                       if (tmp[path_p - path - 1] != '/') {
+                               result = mkdir(tmp, mode);
+                               if(result == -1) {
+                                       if (!(errno == EEXIST || errno == EACCES || errno == EROFS)) {
+                                               /* Then this is a real error */
+                                               retval = -1;
+                                               break;
+                                       }
+                               }
+                       }
+                       /* pass / */
+                       path_p++;
+               } else {
+                       /* last component */
+                       result = mkdir(path, mode);
+                       if (result == -1)
+                               retval = -1;
+                       break;
+               }
+       }
+
+       free(tmp);
+       umask(old_umask);
+       return retval;
+}
+
+static struct sockaddr_un * create_sock_addr(const char *name,
+                                            size_t *sock_addr_size)
+{
+       struct sockaddr_un * addr;
+       size_t alloc_size;
+
+       alloc_size = (size_t) (((struct sockaddr_un *) 0)->sun_path) +
+               strlen(name) + 1;
+
+       addr = malloc(alloc_size);
+       if (addr < 0) {
+               ERR("allocating addr failed");
+               return NULL;
+       }
+
+       addr->sun_family = AF_UNIX;
+       strcpy(addr->sun_path, name);
+
+       *sock_addr_size = alloc_size;
+
+       return addr;
+}
+
+struct ustcomm_sock * ustcomm_init_sock(int fd, int epoll_fd,
+                                       struct cds_list_head *list)
+{
+       struct epoll_event ev;
+       struct ustcomm_sock *sock;
+
+       sock = malloc(sizeof(struct ustcomm_sock));
+       if (!sock) {
+               perror("malloc: couldn't allocate ustcomm_sock");
+               return NULL;
+       }
+
+       ev.events = EPOLLIN;
+       ev.data.ptr = sock;
+       sock->fd = fd;
+
+       if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sock->fd, &ev) == -1) {
+               perror("epoll_ctl: failed to add socket\n");
+               free(sock);
+               return NULL;
+       }
+
+       sock->epoll_fd = epoll_fd;
+       if (list) {
+               cds_list_add(&sock->list, list);
+       } else {
+               CDS_INIT_LIST_HEAD(&sock->list);
+       }
+
+       return sock;
+}
+
+void ustcomm_del_sock(struct ustcomm_sock *sock, int keep_in_epoll)
+{
+       cds_list_del(&sock->list);
+       if (!keep_in_epoll) {
+               if (epoll_ctl(sock->epoll_fd, EPOLL_CTL_DEL, sock->fd, NULL) == -1) {
+                       PERROR("epoll_ctl: failed to delete socket");
+               }
+       }
+       close(sock->fd);
+       free(sock);
+}
+
+struct ustcomm_sock * ustcomm_init_named_socket(const char *name,
+                                               int epoll_fd)
+{
+       int result;
+       int fd;
+       size_t sock_addr_size;
+       struct sockaddr_un * addr;
+       struct ustcomm_sock *sock;
+
+       fd = socket(PF_UNIX, SOCK_STREAM, 0);
+       if(fd == -1) {
+               PERROR("socket");
+               return NULL;
+       }
+
+       addr = create_sock_addr(name, &sock_addr_size);
+       if (addr == NULL) {
+               ERR("allocating addr, UST thread bailing");
+               goto close_sock;
+       }
+
+       result = access(name, F_OK);
+       if(result == 0) {
+               /* file exists */
+               result = unlink(name);
+               if(result == -1) {
+                       PERROR("unlink of socket file");
+                       goto free_addr;
+               }
+               DBG("socket already exists; overwriting");
+       }
+
+       result = bind(fd, (struct sockaddr *)addr, sock_addr_size);
+       if(result == -1) {
+               PERROR("bind");
+               goto free_addr;
+       }
+
+       result = listen(fd, 1);
+       if(result == -1) {
+               PERROR("listen");
+               goto free_addr;
+       }
+
+       sock = ustcomm_init_sock(fd, epoll_fd,
+                                NULL);
+       if (!sock) {
+               ERR("failed to create ustcomm_sock");
+               goto free_addr;
+       }
+
+       free(addr);
+
+       return sock;
+
+free_addr:
+       free(addr);
+close_sock:
+       close(fd);
+
+       return NULL;
+}
+
+void ustcomm_del_named_sock(struct ustcomm_sock *sock,
+                           int keep_socket_file)
+{
+       int result, fd;
+       struct stat st;
+       struct sockaddr dummy;
+       struct sockaddr_un *sockaddr = NULL;
+       int alloc_size;
+
+       fd = sock->fd;
+
+       if(!keep_socket_file) {
+
+               /* Get the socket name */
+               alloc_size = sizeof(dummy);
+               if (getsockname(fd, &dummy, (socklen_t *)&alloc_size) < 0) {
+                       PERROR("getsockname failed");
+                       goto del_sock;
+               }
+
+               sockaddr = zmalloc(alloc_size);
+               if (!sockaddr) {
+                       ERR("failed to allocate sockaddr");
+                       goto del_sock;
+               }
+
+               if (getsockname(fd, sockaddr, (socklen_t *)&alloc_size) < 0) {
+                       PERROR("getsockname failed");
+                       goto free_sockaddr;
+               }
+
+               /* Destroy socket */
+               result = stat(sockaddr->sun_path, &st);
+               if(result < 0) {
+                       PERROR("stat (%s)", sockaddr->sun_path);
+                       goto free_sockaddr;
+               }
+
+               /* Paranoid check before deleting. */
+               result = S_ISSOCK(st.st_mode);
+               if(!result) {
+                       ERR("The socket we are about to delete is not a socket.");
+                       goto free_sockaddr;
+               }
+
+               result = unlink(sockaddr->sun_path);
+               if(result < 0) {
+                       PERROR("unlink");
+               }
+       }
+
+free_sockaddr:
+       free(sockaddr);
+
+del_sock:
+       ustcomm_del_sock(sock, keep_socket_file);
+}
+
+int ustcomm_recv_alloc(int sock,
+                      struct ustcomm_header *header,
+                      char **data) {
+       int result;
+       struct ustcomm_header peek_header;
+       struct iovec iov[2];
+       struct msghdr msg;
+
+       /* Just to make the caller fail hard */
+       *data = NULL;
+
+       result = recv(sock, &peek_header, sizeof(peek_header),
+                     MSG_PEEK | MSG_WAITALL);
+       if (result <= 0) {
+               if(errno == ECONNRESET) {
+                       return 0;
+               } else if (errno == EINTR) {
+                       return -1;
+               } else if (result < 0) {
+                       PERROR("recv");
+                       return -1;
+               }
+               return 0;
+       }
+
+       memset(&msg, 0, sizeof(msg));
+
+       iov[0].iov_base = (char *)header;
+       iov[0].iov_len = sizeof(struct ustcomm_header);
+
+       msg.msg_iov = iov;
+       msg.msg_iovlen = 1;
+
+       if (peek_header.size) {
+               *data = zmalloc(peek_header.size);
+               if (!*data) {
+                       return -ENOMEM;
+               }
+
+               iov[1].iov_base = *data;
+               iov[1].iov_len = peek_header.size;
+
+               msg.msg_iovlen++;
+       }
+
+       result = recvmsg(sock, &msg, MSG_WAITALL);
+       if (result < 0) {
+               free(*data);
+               PERROR("recvmsg failed");
+       }
+
+       return result;
+}
+
+/* returns 1 to indicate a message was received
+ * returns 0 to indicate no message was received (end of stream)
+ * returns -1 to indicate an error
+ */
+int ustcomm_recv_fd(int sock,
+                   struct ustcomm_header *header,
+                   char *data, int *fd)
+{
+       int result;
+       struct ustcomm_header peek_header;
+       struct iovec iov[2];
+       struct msghdr msg;
+       struct cmsghdr *cmsg;
+       char buf[CMSG_SPACE(sizeof(int))];
+
+       result = recv(sock, &peek_header, sizeof(peek_header),
+                     MSG_PEEK | MSG_WAITALL);
+       if (result <= 0) {
+               if(errno == ECONNRESET) {
+                       return 0;
+               } else if (errno == EINTR) {
+                       return -1;
+               } else if (result < 0) {
+                       PERROR("recv");
+                       return -1;
+               }
+               return 0;
+       }
+
+       memset(&msg, 0, sizeof(msg));
+
+       iov[0].iov_base = (char *)header;
+       iov[0].iov_len = sizeof(struct ustcomm_header);
+
+       msg.msg_iov = iov;
+       msg.msg_iovlen = 1;
+
+       if (peek_header.size && data) {
+               if (peek_header.size < 0 ||
+                   peek_header.size > USTCOMM_DATA_SIZE) {
+                       ERR("big peek header! %ld", peek_header.size);
+                       return 0;
+               }
+
+               iov[1].iov_base = data;
+               iov[1].iov_len = peek_header.size;
+
+               msg.msg_iovlen++;
+       }
+
+       if (fd && peek_header.fd_included) {
+               msg.msg_control = buf;
+               msg.msg_controllen = sizeof(buf);
+       }
+
+       result = recvmsg(sock, &msg, MSG_WAITALL);
+       if (result <= 0) {
+               if (result < 0) {
+                       PERROR("recvmsg failed");
+               }
+               return result;
+       }
+
+       if (fd && peek_header.fd_included) {
+               cmsg = CMSG_FIRSTHDR(&msg);
+               result = 0;
+               while (cmsg != NULL) {
+                       if (cmsg->cmsg_level == SOL_SOCKET
+                           && cmsg->cmsg_type  == SCM_RIGHTS) {
+                               *fd = *(int *) CMSG_DATA(cmsg);
+                               result = 1;
+                               break;
+                       }
+                       cmsg = CMSG_NXTHDR(&msg, cmsg);
+               }
+               if (!result) {
+                       ERR("Failed to receive file descriptor\n");
+               }
+       }
+
+       return 1;
+}
+
+int ustcomm_recv(int sock,
+                struct ustcomm_header *header,
+                char *data)
+{
+       return ustcomm_recv_fd(sock, header, data, NULL);
+}
+
+
+int ustcomm_send_fd(int sock,
+                   const struct ustcomm_header *header,
+                   const char *data,
+                   int *fd)
+{
+       struct iovec iov[2];
+       struct msghdr msg;
+       int result;
+       struct cmsghdr *cmsg;
+       char buf[CMSG_SPACE(sizeof(int))];
+
+       memset(&msg, 0, sizeof(msg));
+
+       iov[0].iov_base = (char *)header;
+       iov[0].iov_len = sizeof(struct ustcomm_header);
+
+       msg.msg_iov = iov;
+       msg.msg_iovlen = 1;
+
+       if (header->size && data) {
+               iov[1].iov_base = (char *)data;
+               iov[1].iov_len = header->size;
+
+               msg.msg_iovlen++;
+
+       }
+
+       if (fd && header->fd_included) {
+               msg.msg_control = buf;
+               msg.msg_controllen = sizeof(buf);
+               cmsg = CMSG_FIRSTHDR(&msg);
+               cmsg->cmsg_level = SOL_SOCKET;
+               cmsg->cmsg_type = SCM_RIGHTS;
+               cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+               *(int *) CMSG_DATA(cmsg) = *fd;
+               msg.msg_controllen = cmsg->cmsg_len;
+       }
+
+       result = sendmsg(sock, &msg, MSG_NOSIGNAL);
+       if (result < 0 && errno != EPIPE) {
+               PERROR("sendmsg failed");
+       }
+       return result;
+}
+
+int ustcomm_send(int sock,
+                const struct ustcomm_header *header,
+                const char *data)
+{
+       return ustcomm_send_fd(sock, header, data, NULL);
+}
+
+int ustcomm_req(int sock,
+               const struct ustcomm_header *req_header,
+               const char *req_data,
+               struct ustcomm_header *res_header,
+               char *res_data)
+{
+       int result;
+
+       result = ustcomm_send(sock, req_header, req_data);
+       if ( result <= 0) {
+               return result;
+       }
+
+       return ustcomm_recv(sock, res_header, res_data);
+}
+
+/* Return value:
+ *  0: success
+ * -1: error
+ */
+
+int ustcomm_connect_path(const char *name, int *connection_fd)
+{
+       int result, fd;
+       size_t sock_addr_size;
+       struct sockaddr_un *addr;
+
+       fd = socket(PF_UNIX, SOCK_STREAM, 0);
+       if(fd == -1) {
+               PERROR("socket");
+               return -1;
+       }
+
+       addr = create_sock_addr(name, &sock_addr_size);
+       if (addr == NULL) {
+               ERR("allocating addr failed");
+               goto close_sock;
+       }
+
+       result = connect(fd, (struct sockaddr *)addr, sock_addr_size);
+       if(result == -1) {
+               PERROR("connect (path=%s)", name);
+               goto free_sock_addr;
+       }
+
+       *connection_fd = fd;
+
+       free(addr);
+
+       return 0;
+
+free_sock_addr:
+       free(addr);
+close_sock:
+       close(fd);
+
+       return -1;
+}
+
+/* Returns the current users socket directory, must be freed */
+char *ustcomm_user_sock_dir(void)
+{
+       int result;
+       char *sock_dir = NULL;
+
+       result = asprintf(&sock_dir, "%s%s", USER_SOCK_DIR,
+                         cuserid(NULL));
+       if (result < 0) {
+               ERR("string overflow allocating directory name");
+               return NULL;
+       }
+
+       return sock_dir;
+}
+
+static int time_and_pid_from_socket_name(char *sock_name, unsigned long *time,
+                                        pid_t *pid)
+{
+       char *saveptr, *pid_m_time_str;
+       char *sock_basename = strdup(basename(sock_name));
+
+       if (!sock_basename) {
+               return -1;
+       }
+
+       /* This is the pid */
+       pid_m_time_str = strtok_r(sock_basename, ".", &saveptr);
+       if (!pid_m_time_str) {
+               goto out_err;
+       }
+
+       errno = 0;
+       *pid = (pid_t)strtoul(pid_m_time_str, NULL, 10);
+       if (errno) {
+               goto out_err;
+       }
+
+       /* This should be the time-stamp */
+       pid_m_time_str = strtok_r(NULL, ".", &saveptr);
+       if (!pid_m_time_str) {
+               goto out_err;
+       }
+
+       errno = 0;
+       *time = strtoul(pid_m_time_str, NULL, 10);
+       if (errno) {
+               goto out_err;
+       }
+
+       return 0;
+
+out_err:
+       free(sock_basename);
+       return -1;
+}
+
+time_t ustcomm_pid_st_mtime(pid_t pid)
+{
+       struct stat proc_stat;
+       char proc_name[PATH_MAX];
+
+       if (snprintf(proc_name, PATH_MAX - 1, "/proc/%ld", (long) pid) < 0) {
+               return 0;
+       }
+
+       if (stat(proc_name, &proc_stat)) {
+               return 0;
+       }
+
+       return proc_stat.st_mtime;
+}
+
+int ustcomm_is_socket_live(char *sock_name, pid_t *read_pid)
+{
+       time_t time_from_pid;
+       unsigned long time_from_sock;
+       pid_t pid;
+
+       if (time_and_pid_from_socket_name(sock_name, &time_from_sock, &pid)) {
+               return 0;
+       }
+
+       if (read_pid) {
+               *read_pid = pid;
+       }
+
+       time_from_pid = ustcomm_pid_st_mtime(pid);
+       if (!time_from_pid) {
+               return 0;
+       }
+
+       if ((unsigned long) time_from_pid == time_from_sock) {
+               return 1;
+       }
+
+       return 0;
+}
+
+#define MAX_SOCK_PATH_BASE_LEN 100
+
+static int ustcomm_get_sock_name(char *dir_name, pid_t pid, char *sock_name)
+{
+       struct dirent *dirent;
+       char sock_path_base[MAX_SOCK_PATH_BASE_LEN];
+       int len;
+       DIR *dir = opendir(dir_name);
+
+       snprintf(sock_path_base, MAX_SOCK_PATH_BASE_LEN - 1,
+                "%ld.", (long) pid);
+       len = strlen(sock_path_base);
+
+       while ((dirent = readdir(dir))) {
+               if (!strcmp(dirent->d_name, ".") ||
+                   !strcmp(dirent->d_name, "..") ||
+                   !strcmp(dirent->d_name, "ust-consumer") ||
+                   dirent->d_type == DT_DIR ||
+                   strncmp(dirent->d_name, sock_path_base, len)) {
+                       continue;
+               }
+
+               if (ustcomm_is_socket_live(dirent->d_name, NULL)) {
+                       if (snprintf(sock_name, PATH_MAX - 1, "%s/%s",
+                                    dir_name, dirent->d_name) < 0) {
+                               PERROR("path longer than PATH_MAX?");
+                               goto out_err;
+                       }
+                       closedir(dir);
+                       return 0;
+               }
+       }
+
+out_err:
+       closedir(dir);
+       return -1;
+}
+
+/* Open a connection to a traceable app.
+ *
+ * Return value:
+ *  0: success
+ * -1: error
+ */
+
+static int connect_app_non_root(pid_t pid, int *app_fd)
+{
+       int result;
+       int retval = 0;
+       char *dir_name;
+       char sock_name[PATH_MAX];
+
+       dir_name = ustcomm_user_sock_dir();
+       if (!dir_name)
+               return -ENOMEM;
+
+       if (ustcomm_get_sock_name(dir_name, pid, sock_name)) {
+               retval = -ENOENT;
+               goto free_dir_name;
+       }
+
+       result = ustcomm_connect_path(sock_name, app_fd);
+       if (result < 0) {
+               ERR("failed to connect to app");
+               retval = -1;
+               goto free_dir_name;
+       }
+
+free_dir_name:
+       free(dir_name);
+
+       return retval;
+}
+
+
+
+static int connect_app_root(pid_t pid, int *app_fd)
+{
+       DIR *tmp_dir;
+       struct dirent *dirent;
+       char dir_name[PATH_MAX], sock_name[PATH_MAX];
+       int result = -1;
+
+       tmp_dir = opendir(USER_TMP_DIR);
+       if (!tmp_dir) {
+               return -1;
+       }
+
+       while ((dirent = readdir(tmp_dir))) {
+               if (!strncmp(dirent->d_name, USER_SOCK_DIR_BASE,
+                            strlen(USER_SOCK_DIR_BASE))) {
+
+                       if (snprintf(dir_name, PATH_MAX - 1, "%s/%s", USER_TMP_DIR,
+                                    dirent->d_name) < 0) {
+                               continue;
+                       }
+
+                       if (ustcomm_get_sock_name(dir_name, pid, sock_name)) {
+                               continue;
+                       }
+
+                       result = ustcomm_connect_path(sock_name, app_fd);
+
+                       if (result == 0) {
+                               goto close_tmp_dir;
+                       }
+               }
+       }
+
+close_tmp_dir:
+       closedir(tmp_dir);
+
+       return result;
+}
+
+int ustcomm_connect_app(pid_t pid, int *app_fd)
+{
+       *app_fd = 0;
+
+       if (geteuid()) {
+               return connect_app_non_root(pid, app_fd);
+       } else {
+               return connect_app_root(pid, app_fd);
+       }
+
+}
+
+int ensure_dir_exists(const char *dir, mode_t mode)
+{
+       struct stat st;
+       int result;
+
+       if (!strcmp(dir, ""))
+               return -1;
+
+       result = stat(dir, &st);
+       if (result < 0 && errno != ENOENT) {
+               return -1;
+       } else if (result < 0) {
+               /* ENOENT */
+               int result;
+
+               result = mkdir_p(dir, mode);
+               if(result != 0) {
+                       ERR("executing in recursive creation of directory %s", dir);
+                       return -1;
+               }
+       } else {
+               if (st.st_mode != mode) {
+                       result = chmod(dir, mode);
+                       if (result < 0) {
+                               ERR("couldn't set directory mode on %s", dir);
+                               return -1;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+char * ustcomm_print_data(char *data_field, int field_size,
+                         int *offset, const char *format, ...)
+{
+       va_list args;
+       int count, limit;
+       char *ptr = USTCOMM_POISON_PTR;
+
+       limit = field_size - *offset;
+       va_start(args, format);
+       count = vsnprintf(&data_field[*offset], limit, format, args);
+       va_end(args);
+
+       if (count < limit && count > -1) {
+               ptr = NULL + *offset;
+               *offset = *offset + count + 1;
+       }
+
+       return ptr;
+}
+
+char * ustcomm_restore_ptr(char *ptr, char *data_field, int data_field_size)
+{
+       if ((unsigned long)ptr > data_field_size ||
+           ptr == USTCOMM_POISON_PTR) {
+               return NULL;
+       }
+
+       return data_field + (long)ptr;
+}
+
+int ustcomm_pack_single_field(struct ustcomm_header *header,
+                             struct ustcomm_single_field *single_field,
+                             const char *string)
+{
+       int offset = 0;
+
+       single_field->field = ustcomm_print_data(single_field->data,
+                                                sizeof(single_field->data),
+                                                &offset,
+                                                string);
+
+       if (single_field->field == USTCOMM_POISON_PTR) {
+               return -ENOMEM;
+       }
+
+       header->size = COMPUTE_MSG_SIZE(single_field, offset);
+
+       return 0;
+}
+
+int ustcomm_unpack_single_field(struct ustcomm_single_field *single_field)
+{
+       single_field->field = ustcomm_restore_ptr(single_field->field,
+                                                 single_field->data,
+                                                 sizeof(single_field->data));
+       if (!single_field->field) {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+int ustcomm_pack_channel_info(struct ustcomm_header *header,
+                             struct ustcomm_channel_info *ch_inf,
+                             const char *trace,
+                             const char *channel)
+{
+       int offset = 0;
+
+       ch_inf->trace = ustcomm_print_data(ch_inf->data,
+                                          sizeof(ch_inf->data),
+                                          &offset,
+                                          trace);
+
+       if (ch_inf->trace == USTCOMM_POISON_PTR) {
+               return -ENOMEM;
+       }
+
+       ch_inf->channel = ustcomm_print_data(ch_inf->data,
+                                            sizeof(ch_inf->data),
+                                            &offset,
+                                            channel);
+
+       if (ch_inf->channel == USTCOMM_POISON_PTR) {
+               return -ENOMEM;
+       }
+
+       header->size = COMPUTE_MSG_SIZE(ch_inf, offset);
+
+       return 0;
+}
+
+
+int ustcomm_unpack_channel_info(struct ustcomm_channel_info *ch_inf)
+{
+       ch_inf->trace = ustcomm_restore_ptr(ch_inf->trace,
+                                           ch_inf->data,
+                                           sizeof(ch_inf->data));
+       if (!ch_inf->trace) {
+               return -EINVAL;
+       }
+
+       ch_inf->channel = ustcomm_restore_ptr(ch_inf->channel,
+                                             ch_inf->data,
+                                             sizeof(ch_inf->data));
+       if (!ch_inf->channel) {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+int ustcomm_pack_buffer_info(struct ustcomm_header *header,
+                            struct ustcomm_buffer_info *buf_inf,
+                            const char *trace,
+                            const char *channel,
+                            int channel_cpu)
+{
+       int offset = 0;
+
+       buf_inf->trace = ustcomm_print_data(buf_inf->data,
+                                           sizeof(buf_inf->data),
+                                           &offset,
+                                           trace);
+
+       if (buf_inf->trace == USTCOMM_POISON_PTR) {
+               return -ENOMEM;
+       }
+
+       buf_inf->channel = ustcomm_print_data(buf_inf->data,
+                                             sizeof(buf_inf->data),
+                                             &offset,
+                                             channel);
+
+       if (buf_inf->channel == USTCOMM_POISON_PTR) {
+               return -ENOMEM;
+       }
+
+       buf_inf->ch_cpu = channel_cpu;
+
+       header->size = COMPUTE_MSG_SIZE(buf_inf, offset);
+
+       return 0;
+}
+
+
+int ustcomm_unpack_buffer_info(struct ustcomm_buffer_info *buf_inf)
+{
+       buf_inf->trace = ustcomm_restore_ptr(buf_inf->trace,
+                                            buf_inf->data,
+                                            sizeof(buf_inf->data));
+       if (!buf_inf->trace) {
+               return -EINVAL;
+       }
+
+       buf_inf->channel = ustcomm_restore_ptr(buf_inf->channel,
+                                              buf_inf->data,
+                                              sizeof(buf_inf->data));
+       if (!buf_inf->channel) {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+int ustcomm_pack_ust_marker_info(struct ustcomm_header *header,
+                            struct ustcomm_ust_marker_info *ust_marker_inf,
+                            const char *trace,
+                            const char *channel,
+                            const char *ust_marker)
+{
+       int offset = 0;
+
+       ust_marker_inf->trace = ustcomm_print_data(ust_marker_inf->data,
+                                              sizeof(ust_marker_inf->data),
+                                              &offset,
+                                              trace);
+
+       if (ust_marker_inf->trace == USTCOMM_POISON_PTR) {
+               return -ENOMEM;
+       }
+
+
+       ust_marker_inf->channel = ustcomm_print_data(ust_marker_inf->data,
+                                                sizeof(ust_marker_inf->data),
+                                                &offset,
+                                                channel);
+
+       if (ust_marker_inf->channel == USTCOMM_POISON_PTR) {
+               return -ENOMEM;
+       }
+
+
+       ust_marker_inf->ust_marker = ustcomm_print_data(ust_marker_inf->data,
+                                                sizeof(ust_marker_inf->data),
+                                                &offset,
+                                                ust_marker);
+
+       if (ust_marker_inf->ust_marker == USTCOMM_POISON_PTR) {
+               return -ENOMEM;
+       }
+
+       header->size = COMPUTE_MSG_SIZE(ust_marker_inf, offset);
+
+       return 0;
+}
+
+int ustcomm_unpack_ust_marker_info(struct ustcomm_ust_marker_info *ust_marker_inf)
+{
+       ust_marker_inf->trace = ustcomm_restore_ptr(ust_marker_inf->trace,
+                                               ust_marker_inf->data,
+                                               sizeof(ust_marker_inf->data));
+       if (!ust_marker_inf->trace) {
+               return -EINVAL;
+       }
+
+       ust_marker_inf->channel = ustcomm_restore_ptr(ust_marker_inf->channel,
+                                                 ust_marker_inf->data,
+                                                 sizeof(ust_marker_inf->data));
+       if (!ust_marker_inf->channel) {
+               return -EINVAL;
+       }
+
+       ust_marker_inf->ust_marker = ustcomm_restore_ptr(ust_marker_inf->ust_marker,
+                                                ust_marker_inf->data,
+                                                sizeof(ust_marker_inf->data));
+       if (!ust_marker_inf->ust_marker) {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
diff --git a/deprecated/libustcomm/ustcomm.h b/deprecated/libustcomm/ustcomm.h
new file mode 100644 (file)
index 0000000..4706b72
--- /dev/null
@@ -0,0 +1,220 @@
+/* Copyright (C) 2009  Pierre-Marc Fournier
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef USTCOMM_H
+#define USTCOMM_H
+
+#include <sys/types.h>
+#include <sys/un.h>
+#include <urcu/list.h>
+
+#include <ust/kcompat/kcompat.h>
+
+#define SOCK_DIR "/tmp/ust-app-socks"
+#define USER_TMP_DIR "/tmp"
+#define USER_SOCK_DIR_BASE "ust-socks-"
+#define USER_SOCK_DIR USER_TMP_DIR "/" USER_SOCK_DIR_BASE
+
+struct ustcomm_sock {
+       struct cds_list_head list;
+       int fd;
+       int epoll_fd;
+};
+
+struct ustcomm_header {
+       int command;
+       long size;
+       int result;
+       int fd_included;
+};
+
+#define USTCOMM_BUFFER_SIZE ((1 << 12) - sizeof(struct ustcomm_header))
+
+/* Specify a sata size that leaves margin at the end of a buffer
+ * in order to make sure that we never have more data than
+ * will fit in the buffer AND that the last chars (due to a
+ * pre-receive memset) will always be 0, terminating any string
+ */
+#define USTCOMM_DATA_SIZE (USTCOMM_BUFFER_SIZE - 20 * sizeof(void *))
+
+enum tracectl_commands {
+       ALLOC_TRACE,
+       CONSUME_BUFFER,
+       CREATE_TRACE,
+       DESTROY_TRACE,
+       DISABLE_MARKER,
+       ENABLE_MARKER,
+       EXIT,
+       FORCE_SUBBUF_SWITCH,
+       GET_BUF_SHMID_PIPE_FD,
+       GET_PIDUNIQUE,
+       GET_SOCK_PATH,
+       GET_SUBBUFFER,
+       GET_SUBBUF_NUM_SIZE,
+       LIST_MARKERS,
+       LIST_TRACE_EVENTS,
+       LOAD_PROBE_LIB,
+       NOTIFY_BUF_MAPPED,
+       PRINT_MARKERS,
+       PRINT_TRACE_EVENTS,
+       PUT_SUBBUFFER,
+       SETUP_TRACE,
+       SET_SOCK_PATH,
+       SET_SUBBUF_NUM,
+       SET_SUBBUF_SIZE,
+       START,
+       START_TRACE,
+       STOP_TRACE,
+};
+
+struct ustcomm_single_field {
+       char *field;
+       char data[USTCOMM_DATA_SIZE];
+};
+
+struct ustcomm_channel_info {
+       char *trace;
+       char *channel;
+       unsigned int subbuf_size;
+       unsigned int subbuf_num;
+       char data[USTCOMM_DATA_SIZE];
+};
+
+struct ustcomm_buffer_info {
+       char *trace;
+       char *channel;
+       int ch_cpu;
+       pid_t pid;
+       int buf_shmid;
+       int buf_struct_shmid;
+       long consumed_old;
+       char data[USTCOMM_DATA_SIZE];
+};
+
+struct ustcomm_ust_marker_info {
+       char *trace;
+       char *channel;
+       char *ust_marker;
+       char data[USTCOMM_DATA_SIZE];
+};
+
+struct ustcomm_pidunique {
+       s64 pidunique;
+};
+
+struct ustcomm_notify_buf_mapped {
+       char data[USTCOMM_DATA_SIZE];
+};
+
+/* Ensure directory existence, usefull for unix sockets */
+extern int ensure_dir_exists(const char *dir, mode_t mode);
+
+/* Create and delete sockets */
+extern struct ustcomm_sock * ustcomm_init_sock(int fd, int epoll_fd,
+                                              struct cds_list_head *list);
+extern void ustcomm_del_sock(struct ustcomm_sock *sock, int keep_in_epoll);
+
+/* Create and delete named sockets */
+extern struct ustcomm_sock * ustcomm_init_named_socket(const char *name,
+                                                      int epoll_fd);
+extern void ustcomm_del_named_sock(struct ustcomm_sock *sock,
+                                  int keep_socket_file);
+
+/* Send and receive functions for file descriptors */
+extern int ustcomm_send_fd(int sock, const struct ustcomm_header *header,
+                          const char *data, int *fd);
+extern int ustcomm_recv_fd(int sock, struct ustcomm_header *header,
+                          char *data, int *fd);
+
+/* Normal send and receive functions */
+extern int ustcomm_send(int sock, const struct ustcomm_header *header,
+                       const char *data);
+extern int ustcomm_recv(int sock, struct ustcomm_header *header,
+                       char *data);
+
+/* Receive and allocate data, not to be used inside libust */
+extern int ustcomm_recv_alloc(int sock,
+                             struct ustcomm_header *header,
+                             char **data);
+
+/* Request function, send and receive */
+extern int ustcomm_req(int sock,
+                      const struct ustcomm_header *req_header,
+                      const char *req_data,
+                      struct ustcomm_header *res_header,
+                      char *res_data);
+
+extern int ustcomm_request_consumer(pid_t pid, const char *channel);
+
+/* Returns the current users socket directory, must be freed */
+extern char *ustcomm_user_sock_dir(void);
+
+/* Get the st_m_time from proc*/
+extern time_t ustcomm_pid_st_mtime(pid_t pid);
+
+/* Check that a socket is live */
+extern int ustcomm_is_socket_live(char *sock_name, pid_t *read_pid);
+
+extern int ustcomm_connect_app(pid_t pid, int *app_fd);
+extern int ustcomm_connect_path(const char *path, int *connection_fd);
+
+extern int nth_token_is(const char *str, const char *token, int tok_no);
+
+extern char *nth_token(const char *str, int tok_no);
+
+/* String serialising functions, printf straight into a buffer */
+#define USTCOMM_POISON_PTR (void *)0x19831018
+
+extern char * ustcomm_print_data(char *data_field, int field_size,
+                                int *offset, const char *format, ...);
+extern char * ustcomm_restore_ptr(char *ptr, char *data_field,
+                                 int data_field_size);
+
+#define COMPUTE_MSG_SIZE(struct_ptr, offset)                           \
+       (size_t) (long)(struct_ptr)->data - (long)(struct_ptr) + (offset)
+
+/* Packing and unpacking functions, making life easier */
+extern int ustcomm_pack_single_field(struct ustcomm_header *header,
+                                  struct ustcomm_single_field *sf,
+                                  const char *trace);
+
+extern int ustcomm_unpack_single_field(struct ustcomm_single_field *sf);
+
+extern int ustcomm_pack_channel_info(struct ustcomm_header *header,
+                                    struct ustcomm_channel_info *ch_inf,
+                                    const char *trace,
+                                    const char *channel);
+
+extern int ustcomm_unpack_channel_info(struct ustcomm_channel_info *ch_inf);
+
+extern int ustcomm_pack_buffer_info(struct ustcomm_header *header,
+                                   struct ustcomm_buffer_info *buf_inf,
+                                   const char *trace,
+                                   const char *channel,
+                                   int channel_cpu);
+
+extern int ustcomm_unpack_buffer_info(struct ustcomm_buffer_info *buf_inf);
+
+extern int ustcomm_pack_ust_marker_info(struct ustcomm_header *header,
+                                   struct ustcomm_ust_marker_info *ust_marker_inf,
+                                   const char *trace,
+                                   const char *channel,
+                                   const char *ust_marker);
+
+extern int ustcomm_unpack_ust_marker_info(struct ustcomm_ust_marker_info *ust_marker_inf);
+
+#endif /* USTCOMM_H */
diff --git a/deprecated/libustconsumer/Makefile.am b/deprecated/libustconsumer/Makefile.am
new file mode 100644 (file)
index 0000000..1f87479
--- /dev/null
@@ -0,0 +1,16 @@
+AM_CPPFLAGS = -I$(top_srcdir)/libust -I$(top_srcdir)/libustcomm \
+       -I$(top_srcdir)/include
+AM_CFLAGS = -fno-strict-aliasing
+
+lib_LTLIBRARIES = libustconsumer.la
+
+libustconsumer_la_SOURCES = libustconsumer.c lowlevel.c lowlevel.h
+
+libustconsumer_la_LDFLAGS = -no-undefined -version-info 0:0:0
+
+libustconsumer_la_LIBADD = \
+       -lpthread \
+       $(top_builddir)/snprintf/libustsnprintf.la \
+       $(top_builddir)/libustcomm/libustcomm.la
+
+libustconsumer_la_CFLAGS = -fno-strict-aliasing
diff --git a/deprecated/libustconsumer/libustconsumer.c b/deprecated/libustconsumer/libustconsumer.c
new file mode 100644 (file)
index 0000000..c6dd20c
--- /dev/null
@@ -0,0 +1,923 @@
+/* Copyright (C) 2009  Pierre-Marc Fournier
+ *               2010  Alexis Halle
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#define _GNU_SOURCE
+
+#include <sys/epoll.h>
+#include <sys/shm.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <signal.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <ust/ustconsumer.h>
+#include "lowlevel.h"
+#include "usterr_signal_safe.h"
+#include "ustcomm.h"
+
+#define GET_SUBBUF_OK 1
+#define GET_SUBBUF_DONE 0
+#define GET_SUBBUF_DIED 2
+
+#define PUT_SUBBUF_OK 1
+#define PUT_SUBBUF_DIED 0
+#define PUT_SUBBUF_PUSHED 2
+#define PUT_SUBBUF_DONE 3
+
+#define UNIX_PATH_MAX 108
+
+static int get_subbuffer(struct buffer_info *buf)
+{
+       struct ustcomm_header _send_hdr, *send_hdr;
+       struct ustcomm_header _recv_hdr, *recv_hdr;
+       struct ustcomm_buffer_info _send_msg, _recv_msg;
+       struct ustcomm_buffer_info *send_msg, *recv_msg;
+       int result;
+
+       send_hdr = &_send_hdr;
+       recv_hdr = &_recv_hdr;
+       send_msg = &_send_msg;
+       recv_msg = &_recv_msg;
+
+       result = ustcomm_pack_buffer_info(send_hdr, send_msg, buf->trace,
+                                         buf->channel, buf->channel_cpu);
+       if (result < 0) {
+               return result;
+       }
+
+       send_hdr->command = GET_SUBBUFFER;
+
+       result = ustcomm_req(buf->app_sock, send_hdr, (char *)send_msg,
+                            recv_hdr, (char *)recv_msg);
+       if ((result < 0 && (errno == ECONNRESET || errno == EPIPE)) ||
+           result == 0) {
+               DBG("app died while being traced");
+               return GET_SUBBUF_DIED;
+       } else if (result < 0) {
+               ERR("get_subbuffer: ustcomm_req failed");
+               return result;
+       }
+
+       if (!recv_hdr->result) {
+               DBG("got subbuffer %s", buf->name);
+               buf->consumed_old = recv_msg->consumed_old;
+               return GET_SUBBUF_OK;
+       } else if (recv_hdr->result == -ENODATA) {
+               DBG("For buffer %s, the trace was not found. This likely means"
+                   " it was destroyed by the user.", buf->name);
+               return GET_SUBBUF_DIED;
+       }
+
+       DBG("error getting subbuffer %s", buf->name);
+       return recv_hdr->result;
+}
+
+static int put_subbuffer(struct buffer_info *buf)
+{
+       struct ustcomm_header _send_hdr, *send_hdr;
+       struct ustcomm_header _recv_hdr, *recv_hdr;
+       struct ustcomm_buffer_info _send_msg, *send_msg;
+       int result;
+
+       send_hdr = &_send_hdr;
+       recv_hdr = &_recv_hdr;
+       send_msg = &_send_msg;
+
+       result = ustcomm_pack_buffer_info(send_hdr, send_msg, buf->trace,
+                                         buf->channel, buf->channel_cpu);
+       if (result < 0) {
+               return result;
+       }
+
+       send_hdr->command = PUT_SUBBUFFER;
+       send_msg->consumed_old = buf->consumed_old;
+
+       result = ustcomm_req(buf->app_sock, send_hdr, (char *)send_msg,
+                            recv_hdr, NULL);
+       if ((result < 0 && (errno == ECONNRESET || errno == EPIPE)) ||
+           result == 0) {
+               DBG("app died while being traced");
+               return PUT_SUBBUF_DIED;
+       } else if (result < 0) {
+               ERR("put_subbuffer: ustcomm_req failed");
+               return result;
+       }
+
+       if (!recv_hdr->result) {
+               DBG("put subbuffer %s", buf->name);
+               return PUT_SUBBUF_OK;
+       } else if (recv_hdr->result == -ENODATA) {
+               DBG("For buffer %s, the trace was not found. This likely means"
+                   " it was destroyed by the user.", buf->name);
+               return PUT_SUBBUF_DIED;
+       }
+
+       DBG("error getting subbuffer %s", buf->name);
+       return recv_hdr->result;
+}
+
+void decrement_active_buffers(void *arg)
+{
+       struct ustconsumer_instance *instance = arg;
+       pthread_mutex_lock(&instance->mutex);
+       instance->active_buffers--;
+       pthread_mutex_unlock(&instance->mutex);
+}
+
+static int get_pidunique(int sock, int64_t *pidunique)
+{
+       struct ustcomm_header _send_hdr, *send_hdr;
+       struct ustcomm_header _recv_hdr, *recv_hdr;
+       struct ustcomm_pidunique _recv_msg, *recv_msg;
+       int result;
+
+       send_hdr = &_send_hdr;
+       recv_hdr = &_recv_hdr;
+       recv_msg = &_recv_msg;
+
+       memset(send_hdr, 0, sizeof(*send_hdr));
+
+       send_hdr->command = GET_PIDUNIQUE;
+       result = ustcomm_req(sock, send_hdr, NULL, recv_hdr, (char *)recv_msg);
+       if (result < 1) {
+               return -ENOTCONN;
+       }
+       if (recv_hdr->result < 0) {
+               ERR("App responded with error: %s", strerror(recv_hdr->result));
+               return recv_hdr->result;
+       }
+
+       *pidunique = recv_msg->pidunique;
+
+       return 0;
+}
+
+static int get_buf_shmid_pipe_fd(int sock, struct buffer_info *buf,
+                                int *buf_shmid, int *buf_struct_shmid,
+                                int *buf_pipe_fd)
+{
+       struct ustcomm_header _send_hdr, *send_hdr;
+       struct ustcomm_header _recv_hdr, *recv_hdr;
+       struct ustcomm_buffer_info _send_msg, *send_msg;
+       struct ustcomm_buffer_info _recv_msg, *recv_msg;
+       int result, recv_pipe_fd;
+
+       send_hdr = &_send_hdr;
+       recv_hdr = &_recv_hdr;
+       send_msg = &_send_msg;
+       recv_msg = &_recv_msg;
+
+       result = ustcomm_pack_buffer_info(send_hdr, send_msg, buf->trace,
+                                         buf->channel, buf->channel_cpu);
+       if (result < 0) {
+               ERR("Failed to pack buffer info");
+               return result;
+       }
+
+       send_hdr->command = GET_BUF_SHMID_PIPE_FD;
+
+       result = ustcomm_send(sock, send_hdr, (char *)send_msg);
+       if (result < 1) {
+               ERR("Failed to send request");
+               return -ENOTCONN;
+       }
+       result = ustcomm_recv_fd(sock, recv_hdr, (char *)recv_msg, &recv_pipe_fd);
+       if (result < 1) {
+               ERR("Failed to receive message and fd");
+               return -ENOTCONN;
+       }
+       if (recv_hdr->result < 0) {
+               ERR("App responded with error %s", strerror(recv_hdr->result));
+               return recv_hdr->result;
+       }
+
+       *buf_shmid = recv_msg->buf_shmid;
+       *buf_struct_shmid = recv_msg->buf_struct_shmid;
+       *buf_pipe_fd = recv_pipe_fd;
+
+       return 0;
+}
+
+static int get_subbuf_num_size(int sock, struct buffer_info *buf,
+                              int *subbuf_num, int *subbuf_size)
+{
+       struct ustcomm_header _send_hdr, *send_hdr;
+       struct ustcomm_header _recv_hdr, *recv_hdr;
+       struct ustcomm_channel_info _send_msg, *send_msg;
+       struct ustcomm_channel_info _recv_msg, *recv_msg;
+       int result;
+
+       send_hdr = &_send_hdr;
+       recv_hdr = &_recv_hdr;
+       send_msg = &_send_msg;
+       recv_msg = &_recv_msg;
+
+       result = ustcomm_pack_channel_info(send_hdr, send_msg, buf->trace,
+                                          buf->channel);
+       if (result < 0) {
+               return result;
+       }
+
+       send_hdr->command = GET_SUBBUF_NUM_SIZE;
+
+       result = ustcomm_req(sock, send_hdr, (char *)send_msg,
+                            recv_hdr, (char *)recv_msg);
+       if (result < 1) {
+               return -ENOTCONN;
+       }
+
+       *subbuf_num = recv_msg->subbuf_num;
+       *subbuf_size = recv_msg->subbuf_size;
+
+       return recv_hdr->result;
+}
+
+
+static int notify_buffer_mapped(int sock, struct buffer_info *buf)
+{
+       struct ustcomm_header _send_hdr, *send_hdr;
+       struct ustcomm_header _recv_hdr, *recv_hdr;
+       struct ustcomm_buffer_info _send_msg, *send_msg;
+       int result;
+
+       send_hdr = &_send_hdr;
+       recv_hdr = &_recv_hdr;
+       send_msg = &_send_msg;
+
+       result = ustcomm_pack_buffer_info(send_hdr, send_msg, buf->trace,
+                                         buf->channel, buf->channel_cpu);
+       if (result < 0) {
+               return result;
+       }
+
+       send_hdr->command = NOTIFY_BUF_MAPPED;
+
+       result = ustcomm_req(sock, send_hdr, (char *)send_msg,
+                            recv_hdr, NULL);
+       if (result < 1) {
+               return -ENOTCONN;
+       }
+
+       return recv_hdr->result;
+}
+
+
+struct buffer_info *connect_buffer(struct ustconsumer_instance *instance, pid_t pid,
+                                  const char *trace, const char *channel,
+                                  int channel_cpu)
+{
+       struct buffer_info *buf;
+       int result;
+       struct shmid_ds shmds;
+
+       buf = (struct buffer_info *) zmalloc(sizeof(struct buffer_info));
+       if(buf == NULL) {
+               ERR("add_buffer: insufficient memory");
+               return NULL;
+       }
+
+       buf->trace = strdup(trace);
+       if (!buf->trace) {
+               goto free_buf;
+       }
+
+       buf->channel = strdup(channel);
+       if (!buf->channel) {
+               goto free_buf_trace;
+       }
+
+       result = asprintf(&buf->name, "%s_%d", channel, channel_cpu);
+       if (result < 0 || buf->name == NULL) {
+               goto free_buf_channel;
+       }
+
+       buf->channel_cpu = channel_cpu;
+       buf->pid = pid;
+
+       result = ustcomm_connect_app(buf->pid, &buf->app_sock);
+       if(result) {
+               WARN("unable to connect to process, it probably died before we were able to connect");
+               goto free_buf_name;
+       }
+
+       /* get pidunique */
+       result = get_pidunique(buf->app_sock, &buf->pidunique);
+       if (result < 0) {
+               ERR("Failed to get pidunique");
+               goto close_app_sock;
+       }
+
+       /* get shmid and pipe fd */
+       result = get_buf_shmid_pipe_fd(buf->app_sock, buf, &buf->shmid,
+                                      &buf->bufstruct_shmid, &buf->pipe_fd);
+       if (result < 0) {
+               ERR("Failed to get buf_shmid and pipe_fd");
+               goto close_app_sock;
+       } else {
+               struct stat temp;
+               fstat(buf->pipe_fd, &temp);
+               if (!S_ISFIFO(temp.st_mode)) {
+                       ERR("Didn't receive a fifo from the app");
+                       goto close_app_sock;
+               }
+       }
+
+
+       /* get number of subbufs and subbuf size */
+       result = get_subbuf_num_size(buf->app_sock, buf, &buf->n_subbufs,
+                                    &buf->subbuf_size);
+       if (result < 0) {
+               ERR("Failed to get subbuf number and size");
+               goto close_fifo;
+       }
+
+       /* Set subbuffer's information */
+       buf->subbuf_size_order = get_count_order(buf->subbuf_size);
+       buf->alloc_size = buf->subbuf_size * buf->n_subbufs;
+
+       /* attach memory */
+       buf->mem = shmat(buf->shmid, NULL, 0);
+       if(buf->mem == (void *) 0) {
+               PERROR("shmat");
+               goto close_fifo;
+       }
+       DBG("successfully attached buffer memory");
+
+       buf->bufstruct_mem = shmat(buf->bufstruct_shmid, NULL, 0);
+       if(buf->bufstruct_mem == (void *) 0) {
+               PERROR("shmat");
+               goto shmdt_mem;
+       }
+       DBG("successfully attached buffer bufstruct memory");
+
+       /* obtain info on the memory segment */
+       result = shmctl(buf->shmid, IPC_STAT, &shmds);
+       if(result == -1) {
+               PERROR("shmctl");
+               goto shmdt_bufstruct_mem;
+       }
+       buf->memlen = shmds.shm_segsz;
+
+       /* Notify the application that we have mapped the buffer */
+       result = notify_buffer_mapped(buf->app_sock, buf);
+       if (result < 0) {
+               goto shmdt_bufstruct_mem;
+       }
+
+       if(instance->callbacks->on_open_buffer)
+               instance->callbacks->on_open_buffer(instance->callbacks, buf);
+
+       pthread_mutex_lock(&instance->mutex);
+       instance->active_buffers++;
+       pthread_mutex_unlock(&instance->mutex);
+
+       return buf;
+
+shmdt_bufstruct_mem:
+       shmdt(buf->bufstruct_mem);
+
+shmdt_mem:
+       shmdt(buf->mem);
+
+close_fifo:
+       close(buf->pipe_fd);
+
+close_app_sock:
+       close(buf->app_sock);
+
+free_buf_name:
+       free(buf->name);
+
+free_buf_channel:
+       free(buf->channel);
+
+free_buf_trace:
+       free(buf->trace);
+
+free_buf:
+       free(buf);
+       return NULL;
+}
+
+static void destroy_buffer(struct ustconsumer_callbacks *callbacks,
+                       struct buffer_info *buf)
+{
+       int result;
+
+       result = close(buf->pipe_fd);
+       if(result == -1) {
+               WARN("problem closing the pipe fd");
+       }
+
+       result = close(buf->app_sock);
+       if(result == -1) {
+               WARN("problem calling ustcomm_close_app");
+       }
+
+       result = shmdt(buf->mem);
+       if(result == -1) {
+               PERROR("shmdt");
+       }
+
+       result = shmdt(buf->bufstruct_mem);
+       if(result == -1) {
+               PERROR("shmdt");
+       }
+
+       if(callbacks->on_close_buffer)
+               callbacks->on_close_buffer(callbacks, buf);
+
+       free(buf);
+}
+
+int consumer_loop(struct ustconsumer_instance *instance, struct buffer_info *buf)
+{
+       int result = 0;
+       int read_result;
+       char read_buf;
+
+       pthread_cleanup_push(decrement_active_buffers, instance);
+
+       for(;;) {
+               read_result = read(buf->pipe_fd, &read_buf, 1);
+               /* get the subbuffer */
+               if (read_result == 1) {
+                       result = get_subbuffer(buf);
+                       if (result < 0) {
+                               ERR("error getting subbuffer");
+                               continue;
+                       } else if (result == GET_SUBBUF_DIED) {
+                               finish_consuming_dead_subbuffer(instance->callbacks, buf);
+                               break;
+                       }
+               } else if ((read_result == -1 && (errno == ECONNRESET || errno == EPIPE)) ||
+                          result == 0) {
+                       DBG("App died while being traced");
+                       finish_consuming_dead_subbuffer(instance->callbacks, buf);
+                       break;
+               } else if (read_result == -1 && errno == EINTR) {
+                       continue;
+               }
+
+               if(instance->callbacks->on_read_subbuffer)
+                       instance->callbacks->on_read_subbuffer(instance->callbacks, buf);
+
+               /* put the subbuffer */
+               result = put_subbuffer(buf);
+               if(result == -1) {
+                       ERR("unknown error putting subbuffer (channel=%s)", buf->name);
+                       break;
+               }
+               else if(result == PUT_SUBBUF_PUSHED) {
+                       ERR("Buffer overflow (channel=%s), reader pushed. This channel will not be usable passed this point.", buf->name);
+                       break;
+               }
+               else if(result == PUT_SUBBUF_DIED) {
+                       DBG("application died while putting subbuffer");
+                       /* Skip the first subbuffer. We are not sure it is trustable
+                        * because the put_subbuffer() did not complete.
+                        */
+                       /* TODO: check on_put_error return value */
+                       if(instance->callbacks->on_put_error)
+                               instance->callbacks->on_put_error(instance->callbacks, buf);
+
+                       finish_consuming_dead_subbuffer(instance->callbacks, buf);
+                       break;
+               }
+               else if(result == PUT_SUBBUF_DONE) {
+                       /* Done with this subbuffer */
+                       /* FIXME: add a case where this branch is used? Upon
+                        * normal trace termination, at put_subbuf time, a
+                        * special last-subbuffer code could be returned by
+                        * the listener.
+                        */
+                       break;
+               }
+               else if(result == PUT_SUBBUF_OK) {
+               }
+       }
+
+       DBG("thread for buffer %s is stopping", buf->name);
+
+       /* FIXME: destroy, unalloc... */
+
+       pthread_cleanup_pop(1);
+
+       return 0;
+}
+
+struct consumer_thread_args {
+       pid_t pid;
+       const char *trace;
+       const char *channel;
+       int channel_cpu;
+       struct ustconsumer_instance *instance;
+};
+
+void *consumer_thread(void *arg)
+{
+       struct buffer_info *buf;
+       struct consumer_thread_args *args = (struct consumer_thread_args *) arg;
+       int result;
+       sigset_t sigset;
+
+       pthread_mutex_lock(&args->instance->mutex);
+       args->instance->active_threads++;
+       pthread_mutex_unlock(&args->instance->mutex);
+
+       if(args->instance->callbacks->on_new_thread)
+               args->instance->callbacks->on_new_thread(args->instance->callbacks);
+
+       /* Block signals that should be handled by the main thread. */
+       result = sigemptyset(&sigset);
+       if(result == -1) {
+               PERROR("sigemptyset");
+               goto end;
+       }
+       result = sigaddset(&sigset, SIGTERM);
+       if(result == -1) {
+               PERROR("sigaddset");
+               goto end;
+       }
+       result = sigaddset(&sigset, SIGINT);
+       if(result == -1) {
+               PERROR("sigaddset");
+               goto end;
+       }
+       result = sigprocmask(SIG_BLOCK, &sigset, NULL);
+       if(result == -1) {
+               PERROR("sigprocmask");
+               goto end;
+       }
+
+       buf = connect_buffer(args->instance, args->pid, args->trace,
+                            args->channel, args->channel_cpu);
+       if(buf == NULL) {
+               ERR("failed to connect to buffer");
+               goto end;
+       }
+
+       consumer_loop(args->instance, buf);
+
+       destroy_buffer(args->instance->callbacks, buf);
+
+       end:
+
+       if(args->instance->callbacks->on_close_thread)
+               args->instance->callbacks->on_close_thread(args->instance->callbacks);
+
+       pthread_mutex_lock(&args->instance->mutex);
+       args->instance->active_threads--;
+       pthread_mutex_unlock(&args->instance->mutex);
+
+       free((void *)args->channel);
+       free(args);
+       return NULL;
+}
+
+int start_consuming_buffer(struct ustconsumer_instance *instance, pid_t pid,
+                          const char *trace, const char *channel,
+                          int channel_cpu)
+{
+       pthread_t thr;
+       struct consumer_thread_args *args;
+       int result;
+
+       DBG("beginning of start_consuming_buffer: args: pid %d bufname %s_%d", pid, channel,
+           channel_cpu);
+
+       args = (struct consumer_thread_args *) zmalloc(sizeof(struct consumer_thread_args));
+       if (!args) {
+               return -ENOMEM;
+       }
+
+       args->pid = pid;
+       args->trace = strdup(trace);
+       args->channel = strdup(channel);
+       args->channel_cpu = channel_cpu;
+       args->instance = instance;
+       DBG("beginning2 of start_consuming_buffer: args: pid %d trace %s"
+           " bufname %s_%d", args->pid, args->trace, args->channel, args->channel_cpu);
+
+       result = pthread_create(&thr, NULL, consumer_thread, args);
+       if(result == -1) {
+               ERR("pthread_create failed");
+               return -1;
+       }
+       result = pthread_detach(thr);
+       if(result == -1) {
+               ERR("pthread_detach failed");
+               return -1;
+       }
+       DBG("end of start_consuming_buffer: args: pid %d trace %s "
+           "bufname %s_%d", args->pid, args->channel, args->trace, args->channel_cpu);
+
+       return 0;
+}
+static void process_client_cmd(int sock, struct ustcomm_header *req_header,
+                              char *recvbuf, struct ustconsumer_instance *instance)
+{
+       int result;
+       struct ustcomm_header _res_header = {0};
+       struct ustcomm_header *res_header = &_res_header;
+       struct ustcomm_buffer_info *buf_inf;
+
+       DBG("Processing client command");
+
+       switch (req_header->command) {
+       case CONSUME_BUFFER:
+
+               buf_inf = (struct ustcomm_buffer_info *)recvbuf;
+               result = ustcomm_unpack_buffer_info(buf_inf);
+               if (result < 0) {
+                       ERR("Couldn't unpack buffer info");
+                       return;
+               }
+
+               DBG("Going to consume trace %s buffer %s_%d in process %d",
+                   buf_inf->trace, buf_inf->channel, buf_inf->ch_cpu,
+                   buf_inf->pid);
+               result = start_consuming_buffer(instance, buf_inf->pid,
+                                               buf_inf->trace,
+                                               buf_inf->channel,
+                                               buf_inf->ch_cpu);
+               if (result < 0) {
+                       ERR("error in add_buffer");
+                       return;
+               }
+
+               res_header->result = 0;
+               break;
+       case EXIT:
+               res_header->result = 0;
+               /* Only there to force poll to return */
+               break;
+       default:
+               res_header->result = -EINVAL;
+               WARN("unknown command: %d", req_header->command);
+       }
+
+       if (ustcomm_send(sock, res_header, NULL) <= 0) {
+               ERR("couldn't send command response");
+       }
+}
+
+#define MAX_EVENTS 10
+
+int ustconsumer_start_instance(struct ustconsumer_instance *instance)
+{
+       struct ustcomm_header recv_hdr;
+       char recv_buf[USTCOMM_BUFFER_SIZE];
+       struct ustcomm_sock *epoll_sock;
+       struct epoll_event events[MAX_EVENTS];
+       struct sockaddr addr;
+       int result, epoll_fd, accept_fd, nfds, i, addr_size, timeout;
+
+       if(!instance->is_init) {
+               ERR("libustconsumer instance not initialized");
+               return 1;
+       }
+       epoll_fd = instance->epoll_fd;
+
+       timeout = -1;
+
+       /* app loop */
+       for(;;) {
+               nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, timeout);
+               if (nfds == -1 && errno == EINTR) {
+                       /* Caught signal */
+               } else if (nfds == -1) {
+                       PERROR("ustconsumer_start_instance: epoll_wait failed");
+                       continue;
+               }
+
+               for (i = 0; i < nfds; ++i) {
+                       epoll_sock = (struct ustcomm_sock *)events[i].data.ptr;
+                       if (epoll_sock == instance->listen_sock) {
+                               addr_size = sizeof(struct sockaddr);
+                               accept_fd = accept(epoll_sock->fd,
+                                                  &addr,
+                                                  (socklen_t *)&addr_size);
+                               if (accept_fd == -1) {
+                                       PERROR("ustconsumer_start_instance: "
+                                              "accept failed");
+                                       continue;
+                               }
+                               ustcomm_init_sock(accept_fd, epoll_fd,
+                                                &instance->connections);
+                       } else {
+                               result = ustcomm_recv(epoll_sock->fd, &recv_hdr,
+                                                     recv_buf);
+                               if (result < 1) {
+                                       ustcomm_del_sock(epoll_sock, 0);
+                               } else {
+                                       process_client_cmd(epoll_sock->fd,
+                                                          &recv_hdr, recv_buf,
+                                                          instance);
+                               }
+
+                       }
+               }
+
+               if (instance->quit_program) {
+                       pthread_mutex_lock(&instance->mutex);
+                       if (instance->active_buffers == 0 && instance->active_threads == 0) {
+                               pthread_mutex_unlock(&instance->mutex);
+                               break;
+                       }
+                       pthread_mutex_unlock(&instance->mutex);
+                       timeout = 100;
+               }
+       }
+
+       if(instance->callbacks->on_trace_end)
+               instance->callbacks->on_trace_end(instance);
+
+       ustconsumer_delete_instance(instance);
+
+       return 0;
+}
+
+/* FIXME: threads and connections !? */
+void ustconsumer_delete_instance(struct ustconsumer_instance *instance)
+{
+       if (instance->is_init) {
+               ustcomm_del_named_sock(instance->listen_sock, 0);
+               close(instance->epoll_fd);
+       }
+
+       pthread_mutex_destroy(&instance->mutex);
+       free(instance->sock_path);
+       free(instance);
+}
+
+/* FIXME: Do something about the fixed path length, maybe get rid
+ * of the whole concept and use a pipe?
+ */
+int ustconsumer_stop_instance(struct ustconsumer_instance *instance, int send_msg)
+{
+       int result;
+       int fd;
+       int bytes = 0;
+
+       char msg[] = "exit";
+
+       instance->quit_program = 1;
+
+       if(!send_msg)
+               return 0;
+
+       /* Send a message through the socket to force poll to return */
+
+       struct sockaddr_un addr;
+
+socket_again:
+       result = fd = socket(PF_UNIX, SOCK_STREAM, 0);
+       if(result == -1) {
+               if (errno == EINTR)
+                       goto socket_again;
+               PERROR("socket");
+               return 1;
+       }
+
+       addr.sun_family = AF_UNIX;
+
+       strncpy(addr.sun_path, instance->sock_path, UNIX_PATH_MAX);
+       addr.sun_path[UNIX_PATH_MAX-1] = '\0';
+
+connect_again:
+       result = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
+       if(result == -1) {
+               if (errno == EINTR)
+                       goto connect_again;
+               PERROR("connect");
+       }
+
+       while(bytes != sizeof(msg)) {
+               int inc = send(fd, msg, sizeof(msg), 0);
+               if (inc < 0 && errno != EINTR)
+                       break;
+               else
+                       bytes += inc;
+       }
+
+       close(fd);
+
+       return 0;
+}
+
+struct ustconsumer_instance
+*ustconsumer_new_instance(struct ustconsumer_callbacks *callbacks,
+                     char *sock_path)
+{
+       struct ustconsumer_instance *instance =
+               zmalloc(sizeof(struct ustconsumer_instance));
+       if(!instance) {
+               return NULL;
+       }
+
+       instance->callbacks = callbacks;
+       instance->quit_program = 0;
+       instance->is_init = 0;
+       instance->active_buffers = 0;
+       pthread_mutex_init(&instance->mutex, NULL);
+
+       if (sock_path) {
+               instance->sock_path = strdup(sock_path);
+       } else {
+               instance->sock_path = NULL;
+       }
+
+       return instance;
+}
+
+static int init_ustconsumer_socket(struct ustconsumer_instance *instance)
+{
+       char *name;
+
+       if (instance->sock_path) {
+               if (asprintf(&name, "%s", instance->sock_path) < 0) {
+                       ERR("ustcomm_init_ustconsumer : asprintf failed (sock_path %s)",
+                           instance->sock_path);
+                       return -1;
+               }
+       } else {
+               int result;
+
+               /* Only check if socket dir exists if we are using the default directory */
+               result = ensure_dir_exists(SOCK_DIR, S_IRWXU | S_IRWXG | S_IRWXO);
+               if (result == -1) {
+                       ERR("Unable to create socket directory %s", SOCK_DIR);
+                       return -1;
+               }
+
+               if (asprintf(&name, "%s/%s", SOCK_DIR, "ustconsumer") < 0) {
+                       ERR("ustcomm_init_ustconsumer : asprintf failed (%s/ustconsumer)",
+                           SOCK_DIR);
+                       return -1;
+               }
+       }
+
+       /* Set up epoll */
+       instance->epoll_fd = epoll_create(MAX_EVENTS);
+       if (instance->epoll_fd == -1) {
+               ERR("epoll_create failed, start instance bailing");
+               goto free_name;
+       }
+
+       /* Create the named socket */
+       instance->listen_sock = ustcomm_init_named_socket(name,
+                                                         instance->epoll_fd);
+       if(!instance->listen_sock) {
+               ERR("error initializing named socket at %s", name);
+               goto close_epoll;
+       }
+
+       CDS_INIT_LIST_HEAD(&instance->connections);
+
+       free(name);
+
+       return 0;
+
+close_epoll:
+       close(instance->epoll_fd);
+free_name:
+       free(name);
+
+       return -1;
+}
+
+int ustconsumer_init_instance(struct ustconsumer_instance *instance)
+{
+       int result;
+       result = init_ustconsumer_socket(instance);
+       if(result == -1) {
+               ERR("failed to initialize socket");
+               return 1;
+       }
+       instance->is_init = 1;
+       return 0;
+}
+
diff --git a/deprecated/libustconsumer/lowlevel.c b/deprecated/libustconsumer/lowlevel.c
new file mode 100644 (file)
index 0000000..a54a8db
--- /dev/null
@@ -0,0 +1,207 @@
+/* Copyright (C) 2009  Pierre-Marc Fournier
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <byteswap.h>
+
+#include "ust/ustconsumer.h"
+#include "buffers.h"
+#include "tracer.h"
+#include "usterr_signal_safe.h"
+
+/* This truncates to an offset in the buffer. */
+#define USTD_BUFFER_TRUNC(offset, bufinfo) \
+       ((offset) & (~(((bufinfo)->subbuf_size*(bufinfo)->n_subbufs)-1)))
+
+#define LTT_MAGIC_NUMBER 0x00D6B7ED
+#define LTT_REV_MAGIC_NUMBER 0xEDB7D600
+
+
+static void ltt_relay_print_subbuffer_errors(
+               struct buffer_info *buf,
+               long cons_off, int cpu)
+{
+       struct ust_buffer *ust_buf = buf->bufstruct_mem;
+       long cons_idx, commit_count, commit_count_mask, write_offset;
+
+       cons_idx = SUBBUF_INDEX(cons_off, buf);
+       commit_count = uatomic_read(&ust_buf->commit_seq[cons_idx]);
+       commit_count_mask = (~0UL >> get_count_order(buf->n_subbufs));
+
+       /*
+        * No need to order commit_count and write_offset reads because we
+        * execute after trace is stopped when there are no readers left.
+        */
+       write_offset = uatomic_read(&ust_buf->offset);
+       WARN( "LTT : unread channel %s offset is %ld "
+                       "and cons_off : %ld (cpu %d)\n",
+                       buf->channel, write_offset, cons_off, cpu);
+       /* Check each sub-buffer for non filled commit count */
+       if (((commit_count - buf->subbuf_size) & commit_count_mask)
+                       - (BUFFER_TRUNC(cons_off, buf) >> get_count_order(buf->n_subbufs)) != 0) {
+               ERR("LTT : %s : subbuffer %lu has non filled "
+                               "commit count [seq] [%lu].\n",
+                               buf->channel, cons_idx, commit_count);
+       }
+       ERR("LTT : %s : commit count : %lu, subbuf size %d\n",
+                       buf->channel, commit_count,
+                       buf->subbuf_size);
+}
+
+static void ltt_relay_print_errors(struct buffer_info *buf, int cpu)
+{
+       struct ust_buffer *ust_buf = buf->bufstruct_mem;
+       long cons_off;
+
+       for (cons_off = uatomic_read(&ust_buf->consumed);
+                       (SUBBUF_TRUNC(uatomic_read(&ust_buf->offset), buf)
+                               - cons_off) > 0;
+                       cons_off = SUBBUF_ALIGN(cons_off, buf))
+               ltt_relay_print_subbuffer_errors(buf, cons_off, cpu);
+}
+
+static void ltt_relay_print_buffer_errors(struct buffer_info *buf, int cpu)
+{
+       struct ust_buffer *ust_buf = buf->bufstruct_mem;
+
+       if (uatomic_read(&ust_buf->events_lost))
+               ERR("channel %s: %ld events lost (cpu %d)",
+                               buf->channel,
+                               uatomic_read(&ust_buf->events_lost), cpu);
+       if (uatomic_read(&ust_buf->corrupted_subbuffers))
+               ERR("channel %s : %ld corrupted subbuffers (cpu %d)",
+                               buf->channel,
+                               uatomic_read(&ust_buf->corrupted_subbuffers), cpu);
+
+       ltt_relay_print_errors(buf, cpu);
+}
+
+/* Returns the size of a subbuffer size. This is the size that
+ * will need to be written to disk.
+ *
+ * @subbuffer: pointer to the beginning of the subbuffer (the
+ *             beginning of its header)
+ */
+
+size_t subbuffer_data_size(void *subbuf)
+{
+       struct ltt_subbuffer_header *header = subbuf;
+       int reverse;
+       u32 data_size;
+
+       if(header->magic_number == LTT_MAGIC_NUMBER) {
+               reverse = 0;
+       }
+       else if(header->magic_number == LTT_REV_MAGIC_NUMBER) {
+               reverse = 1;
+       }
+       else {
+               return -1;
+       }
+
+       data_size = header->sb_size;
+       if(reverse)
+               data_size = bswap_32(data_size);
+
+       return data_size;
+}
+
+
+void finish_consuming_dead_subbuffer(struct ustconsumer_callbacks *callbacks, struct buffer_info *buf)
+{
+       struct ust_buffer *ust_buf = buf->bufstruct_mem;
+       unsigned long n_subbufs_order = get_count_order(buf->n_subbufs);
+       unsigned long commit_seq_mask = (~0UL >> n_subbufs_order);
+       unsigned long cons_off;
+       int ret;
+
+       DBG("processing dead buffer (%s)", buf->name);
+       DBG("consumed offset is %ld (%s)", uatomic_read(&ust_buf->consumed),
+                                          buf->name);
+       DBG("write offset is %ld (%s)", uatomic_read(&ust_buf->offset),
+                                       buf->name);
+
+       /*
+        * Iterate on subbuffers to recover, including the one the writer
+        * just wrote data into. Using write position - 1 since the writer
+        * position points into the position that is going to be written.
+        */
+       for (cons_off = uatomic_read(&ust_buf->consumed);
+                       (long) (SUBBUF_TRUNC(uatomic_read(&ust_buf->offset) - 1, buf)
+                               - cons_off) >= 0;
+                       cons_off = SUBBUF_ALIGN(cons_off, buf)) {
+               /*
+                * commit_seq is the offset in the buffer of the end of the last sequential commit.
+                * Bytes beyond this limit cannot be recovered. This is a free-running counter.
+                */
+               unsigned long commit_seq =
+                       uatomic_read(&ust_buf->commit_seq[SUBBUF_INDEX(cons_off, buf)]);
+               struct ltt_subbuffer_header *header =
+                       (struct ltt_subbuffer_header *)((char *) buf->mem
+                               + SUBBUF_INDEX(cons_off, buf) * buf->subbuf_size);
+               unsigned long valid_length;
+
+               /* Check if subbuf was fully written. This is from Mathieu's algorithm/paper. */
+               if (((commit_seq - buf->subbuf_size) & commit_seq_mask)
+                   - (USTD_BUFFER_TRUNC(uatomic_read(&ust_buf->consumed), buf) >> n_subbufs_order) == 0
+                    && header->data_size != 0xffffffff) {
+                       assert(header->sb_size != 0xffffffff);
+                       /*
+                        * If it was fully written, we only check the data_size.
+                        * This is the amount of valid data at the beginning of
+                        * the subbuffer.
+                        */
+                       valid_length = header->data_size;
+                       DBG("writing full subbuffer (%ld) with valid_length = %ld",
+                           SUBBUF_INDEX(cons_off, buf), valid_length);
+               } else {
+                       /*
+                        * If the subbuffer was not fully written, then we don't
+                        * check data_size because it hasn't been written yet.
+                        * Instead we check commit_seq and use it to choose a
+                        * value for data_size. The viewer will need this value
+                        * when parsing. Generally, this will happen only for
+                        * the last subbuffer. However, if we have threads still
+                        * holding reserved slots in the previous subbuffers,
+                        * which could happen for other subbuffers prior to the
+                        * last one. Note that when data_size is set, the
+                        * commit_seq count is still at a value that shows the
+                        * amount of valid data to read. It's only _after_
+                        * writing data_size that commit_seq is updated to
+                        * include the end-of-buffer padding.
+                        */
+                       valid_length = commit_seq & (buf->subbuf_size - 1);
+                       DBG("writing unfull subbuffer (%ld) with valid_length = %ld",
+                           SUBBUF_INDEX(cons_off, buf), valid_length);
+                       header->data_size = valid_length;
+                       header->sb_size = PAGE_ALIGN(valid_length);
+               }
+
+               if (callbacks->on_read_partial_subbuffer) {
+                       ret = callbacks->on_read_partial_subbuffer(callbacks, buf,
+                                                                  SUBBUF_INDEX(cons_off, buf),
+                                                                  valid_length);
+                       if (ret < 0)
+                               break;  /* Error happened */
+               }
+       }
+       /* Increment the consumed offset */
+       uatomic_set(&ust_buf->consumed, cons_off);
+       ltt_relay_print_buffer_errors(buf, buf->channel_cpu);
+}
+
diff --git a/deprecated/libustconsumer/lowlevel.h b/deprecated/libustconsumer/lowlevel.h
new file mode 100644 (file)
index 0000000..6ae6476
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * lowlevel libustd header file
+ *
+ * Copyright 2005-2010 -
+ *              Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ * Copyright 2010-
+ *              Oumarou Dicko <oumarou.dicko@polymtl.ca>
+ *              Michael Sills-Lavoie <michael.sills-lavoie@polymtl.ca>
+ *              Alexis Halle <alexis.halle@polymtl.ca>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef LOWLEVEL_H
+#define LOWLEVEL_H
+
+#include "ust/ustconsumer.h"
+
+void finish_consuming_dead_subbuffer(struct ustconsumer_callbacks *callbacks, struct buffer_info *buf);
+size_t subbuffer_data_size(void *subbuf);
+
+#endif /* LOWLEVEL_H */
+
diff --git a/deprecated/libustctl/Makefile.am b/deprecated/libustctl/Makefile.am
new file mode 100644 (file)
index 0000000..bc7526b
--- /dev/null
@@ -0,0 +1,14 @@
+AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libustcomm
+AM_CFLAGS = -fno-strict-aliasing
+
+lib_LTLIBRARIES = libustctl.la
+
+libustctl_la_SOURCES = \
+       libustctl.c
+
+libustctl_la_LDFLAGS = -no-undefined -version-info 0:0:0
+
+libustctl_la_LIBADD = \
+       $(top_builddir)/libustcomm/libustcomm.la
+
+libustctl_la_CFLAGS = -DUST_COMPONENT="libustctl" -fno-strict-aliasing
diff --git a/deprecated/libustctl/README b/deprecated/libustctl/README
new file mode 100644 (file)
index 0000000..fd4cc97
--- /dev/null
@@ -0,0 +1,2 @@
+libustctl is a library that provides an API and its implementation to send
+commands to traceable processes.
diff --git a/deprecated/libustctl/libustctl.c b/deprecated/libustctl/libustctl.c
new file mode 100644 (file)
index 0000000..4e6c495
--- /dev/null
@@ -0,0 +1,770 @@
+/* Copyright (C) 2009  Pierre-Marc Fournier, Philippe Proulx-Barrette
+ * Copyright (C) 2011  Ericsson AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+#include <dirent.h>
+
+#include "ustcomm.h"
+#include "ust/ustctl.h"
+#include "usterr.h"
+
+static int do_cmd(int sock,
+                 const struct ustcomm_header *req_header,
+                 const char *req_data,
+                 struct ustcomm_header *res_header,
+                 char **res_data)
+{
+       int result, saved_errno = 0;
+       char *recv_buf;
+
+       recv_buf = zmalloc(USTCOMM_BUFFER_SIZE);
+       if (!recv_buf) {
+               saved_errno = ENOMEM;
+               goto out;
+       }
+
+       result = ustcomm_req(sock, req_header, req_data, res_header, recv_buf);
+       if (result > 0) {
+               saved_errno = -res_header->result;
+               if (res_header->size == 0 || saved_errno > 0) {
+                       free(recv_buf);
+               } else {
+                       if (res_data) {
+                               *res_data = recv_buf;
+                       } else {
+                               free(recv_buf);
+                       }
+               }
+       } else {
+               ERR("ustcomm req failed");
+               if (result == 0) {
+                       saved_errno = ENOTCONN;
+               } else {
+                       saved_errno = -result;
+               }
+               free(recv_buf);
+       }
+
+out:
+       errno = saved_errno;
+       if (errno) {
+               return -1;
+       }
+
+       return 0;
+}
+
+int ustctl_connect_pid(pid_t pid)
+{
+       int sock;
+
+       if (ustcomm_connect_app(pid, &sock)) {
+               ERR("could not connect to PID %u", (unsigned int) pid);
+               errno = ENOTCONN;
+               return -1;
+       }
+
+       return sock;
+}
+
+static int realloc_pid_list(pid_t **pid_list, unsigned int *pid_list_size)
+{
+       pid_t *new_pid_list;
+       unsigned int new_pid_list_size = 2 * *pid_list_size;
+
+       new_pid_list = realloc(*pid_list,
+                              new_pid_list_size * sizeof(pid_t));
+       if (!*new_pid_list) {
+               return -1;
+       }
+
+       *pid_list = new_pid_list;
+       *pid_list_size = new_pid_list_size;
+
+       return 0;
+}
+
+static int get_pids_in_dir(DIR *dir, pid_t **pid_list,
+                           unsigned int *pid_list_index,
+                           unsigned int *pid_list_size)
+{
+       struct dirent *dirent;
+       pid_t read_pid;
+
+       while ((dirent = readdir(dir))) {
+               if (!strcmp(dirent->d_name, ".") ||
+                   !strcmp(dirent->d_name, "..") ||
+                   !strcmp(dirent->d_name, "ust-consumer") ||
+                   dirent->d_type == DT_DIR) {
+
+                       continue;
+               }
+
+               if (ustcomm_is_socket_live(dirent->d_name, &read_pid)) {
+
+                       (*pid_list)[(*pid_list_index)++] = (long) read_pid;
+
+                       if (*pid_list_index == *pid_list_size) {
+                               if (realloc_pid_list(pid_list, pid_list_size)) {
+                                       return -1;
+                               }
+                       }
+               }
+       }
+
+       (*pid_list)[*pid_list_index] = 0; /* Array end */
+
+       return 0;
+}
+
+static pid_t *get_pids_non_root(void)
+{
+       char *dir_name;
+       DIR *dir;
+       unsigned int pid_list_index = 0, pid_list_size = 1;
+       pid_t *pid_list = NULL;
+
+       dir_name = ustcomm_user_sock_dir();
+       if (!dir_name) {
+               return NULL;
+       }
+
+       dir = opendir(dir_name);
+       if (!dir) {
+               goto free_dir_name;
+       }
+
+       pid_list = malloc(pid_list_size * sizeof(pid_t));
+       if (!pid_list) {
+               goto close_dir;
+       }
+
+       if (get_pids_in_dir(dir, &pid_list, &pid_list_index, &pid_list_size)) {
+               /* if any errors are encountered, force freeing of the list */
+               pid_list[0] = 0;
+       }
+
+close_dir:
+       closedir(dir);
+
+free_dir_name:
+       free(dir_name);
+
+       return pid_list;
+}
+
+static pid_t *get_pids_root(void)
+{
+       char *dir_name;
+       DIR *tmp_dir, *dir;
+       unsigned int pid_list_index = 0, pid_list_size = 1;
+       pid_t *pid_list = NULL;
+       struct dirent *dirent;
+       int result;
+
+       tmp_dir = opendir(USER_TMP_DIR);
+       if (!tmp_dir) {
+               return NULL;
+       }
+
+       pid_list = malloc(pid_list_size * sizeof(pid_t));
+       if (!pid_list) {
+               goto close_tmp_dir;
+       }
+
+       while ((dirent = readdir(tmp_dir))) {
+               /* Compare the dir to check for the USER_SOCK_DIR_BASE prefix */
+               if (!strncmp(dirent->d_name, USER_SOCK_DIR_BASE,
+                            strlen(USER_SOCK_DIR_BASE))) {
+
+                       if (asprintf(&dir_name, USER_TMP_DIR "/%s",
+                                    dirent->d_name) < 0) {
+                               goto close_tmp_dir;
+                       }
+
+                       dir = opendir(dir_name);
+
+                       free(dir_name);
+
+                       if (!dir) {
+                               continue;
+                       }
+
+                       result = get_pids_in_dir(dir, &pid_list, &pid_list_index,
+                                                &pid_list_size);
+
+                       closedir(dir);
+
+                       if (result) {
+                               /*
+                                * if any errors are encountered,
+                                * force freeing of the list
+                                */
+                               pid_list[0] = 0;
+                               break;
+                       }
+               }
+       }
+
+close_tmp_dir:
+       closedir(tmp_dir);
+
+       return pid_list;
+}
+
+pid_t *ustctl_get_online_pids(void)
+{
+       pid_t *pid_list;
+
+       if (geteuid()) {
+               pid_list = get_pids_non_root();
+       } else {
+               pid_list = get_pids_root();
+       }
+
+       if (pid_list && pid_list[0] == 0) {
+               /* No PID at all */
+               free(pid_list);
+               pid_list = NULL;
+       }
+
+       return pid_list;
+}
+
+/**
+ * Sets ust_marker state (USTCTL_MS_ON or USTCTL_MS_OFF).
+ *
+ * @param mn   Marker name
+ * @param state        Marker's new state
+ * @param pid  Traced process ID
+ * @return     0 if successful, or errors {USTCTL_ERR_GEN, USTCTL_ERR_ARG}
+ */
+int ustctl_set_ust_marker_state(int sock, const char *trace, const char *channel,
+                           const char *ust_marker, int state)
+{
+       struct ustcomm_header req_header, res_header;
+       struct ustcomm_ust_marker_info ust_marker_inf;
+       int result;
+
+       result = ustcomm_pack_ust_marker_info(&req_header,
+                                         &ust_marker_inf,
+                                         trace,
+                                         channel,
+                                         ust_marker);
+       if (result < 0) {
+               errno = -result;
+               return -1;
+       }
+
+       req_header.command = state ? ENABLE_MARKER : DISABLE_MARKER;
+
+       return do_cmd(sock, &req_header, (char *)&ust_marker_inf,
+                     &res_header, NULL);
+}
+
+/**
+ * Set subbuffer size.
+ *
+ * @param channel_size Channel name and size
+ * @param pid          Traced process ID
+ * @return             0 if successful, or error
+ */
+int ustctl_set_subbuf_size(int sock, const char *trace, const char *channel,
+                          unsigned int subbuf_size)
+{
+       struct ustcomm_header req_header, res_header;
+       struct ustcomm_channel_info ch_inf;
+       int result;
+
+       result = ustcomm_pack_channel_info(&req_header,
+                                          &ch_inf,
+                                          trace,
+                                          channel);
+       if (result < 0) {
+               errno = -result;
+               return -1;
+       }
+
+       req_header.command = SET_SUBBUF_SIZE;
+       ch_inf.subbuf_size = subbuf_size;
+
+       return do_cmd(sock, &req_header, (char *)&ch_inf,
+                     &res_header, NULL);
+}
+
+/**
+ * Set subbuffer num.
+ *
+ * @param channel_num  Channel name and num
+ * @param pid          Traced process ID
+ * @return             0 if successful, or error
+ */
+int ustctl_set_subbuf_num(int sock, const char *trace, const char *channel,
+                         unsigned int num)
+{
+       struct ustcomm_header req_header, res_header;
+       struct ustcomm_channel_info ch_inf;
+       int result;
+
+       result = ustcomm_pack_channel_info(&req_header,
+                                          &ch_inf,
+                                          trace,
+                                          channel);
+       if (result < 0) {
+               errno = -result;
+               return -1;
+       }
+
+       req_header.command = SET_SUBBUF_NUM;
+       ch_inf.subbuf_num = num;
+
+       return do_cmd(sock, &req_header, (char *)&ch_inf,
+                     &res_header, NULL);
+
+}
+
+
+static int ustctl_get_subbuf_num_size(int sock, const char *trace, const char *channel,
+                                     int *num, int *size)
+{
+       struct ustcomm_header req_header, res_header;
+       struct ustcomm_channel_info ch_inf, *ch_inf_res;
+       int result;
+
+
+       result = ustcomm_pack_channel_info(&req_header,
+                                          &ch_inf,
+                                          trace,
+                                          channel);
+       if (result < 0) {
+               errno = -result;
+               return -1;
+       }
+
+       req_header.command = GET_SUBBUF_NUM_SIZE;
+
+       result = do_cmd(sock, &req_header, (char *)&ch_inf,
+                       &res_header, (char **)&ch_inf_res);
+       if (result < 0) {
+               return -1;
+       }
+
+       *num = ch_inf_res->subbuf_num;
+       *size = ch_inf_res->subbuf_size;
+
+       free(ch_inf_res);
+
+       return 0;
+}
+
+/**
+ * Get subbuffer num.
+ *
+ * @param channel      Channel name
+ * @param pid          Traced process ID
+ * @return             subbuf cnf if successful, or error
+ */
+int ustctl_get_subbuf_num(int sock, const char *trace, const char *channel)
+{
+       int num, size, result;
+
+       result = ustctl_get_subbuf_num_size(sock, trace, channel,
+                                           &num, &size);
+       if (result < 0) {
+               errno = -result;
+               return -1;
+       }
+
+       return num;
+}
+
+/**
+ * Get subbuffer size.
+ *
+ * @param channel      Channel name
+ * @param pid          Traced process ID
+ * @return             subbuf size if successful, or error
+ */
+int ustctl_get_subbuf_size(int sock, const char *trace, const char *channel)
+{
+       int num, size, result;
+
+       result = ustctl_get_subbuf_num_size(sock, trace, channel,
+                                           &num, &size);
+       if (result < 0) {
+               errno = -result;
+               return -1;
+       }
+
+       return size;
+}
+
+static int do_trace_cmd(int sock, const char *trace, int command)
+{
+       struct ustcomm_header req_header, res_header;
+       struct ustcomm_single_field trace_inf;
+       int result;
+
+       result = ustcomm_pack_single_field(&req_header,
+                                          &trace_inf,
+                                          trace);
+       if (result < 0) {
+               errno = -result;
+               return -1;
+       }
+
+       req_header.command = command;
+
+       return do_cmd(sock, &req_header, (char *)&trace_inf, &res_header, NULL);
+}
+
+/**
+ * Destroys an UST trace according to a PID.
+ *
+ * @param pid  Traced process ID
+ * @return     0 if successful, or error USTCTL_ERR_GEN
+ */
+int ustctl_destroy_trace(int sock, const char *trace)
+{
+       return do_trace_cmd(sock, trace, DESTROY_TRACE);
+}
+
+/**
+ * Starts an UST trace (and setups it) according to a PID.
+ *
+ * @param pid  Traced process ID
+ * @return     0 if successful, or error USTCTL_ERR_GEN
+ */
+int ustctl_setup_and_start(int sock, const char *trace)
+{
+       return do_trace_cmd(sock, trace, START);
+}
+
+/**
+ * Creates an UST trace according to a PID.
+ *
+ * @param pid  Traced process ID
+ * @return     0 if successful, or error USTCTL_ERR_GEN
+ */
+int ustctl_create_trace(int sock, const char *trace)
+{
+       return do_trace_cmd(sock, trace, CREATE_TRACE);
+}
+
+/**
+ * Starts an UST trace according to a PID.
+ *
+ * @param pid  Traced process ID
+ * @return     0 if successful, or error USTCTL_ERR_GEN
+ */
+int ustctl_start_trace(int sock, const char *trace)
+{
+       return do_trace_cmd(sock, trace, START_TRACE);
+}
+
+/**
+ * Alloc an UST trace according to a PID.
+ *
+ * @param pid  Traced process ID
+ * @return     0 if successful, or error USTCTL_ERR_GEN
+ */
+int ustctl_alloc_trace(int sock, const char *trace)
+{
+       return do_trace_cmd(sock, trace, ALLOC_TRACE);
+}
+
+
+int ustctl_force_switch(int sock, const char *trace)
+{
+       return do_trace_cmd(sock, trace, FORCE_SUBBUF_SWITCH);
+}
+
+/**
+ * Stops an UST trace according to a PID.
+ *
+ * @param pid  Traced process ID
+ * @return     0 if successful, or error USTCTL_ERR_GEN
+ */
+int ustctl_stop_trace(int sock, const char *trace)
+{
+       return do_trace_cmd(sock, trace, STOP_TRACE);
+}
+
+/**
+ * Counts newlines ('\n') in a string.
+ *
+ * @param str  String to search in
+ * @return     Total newlines count
+ */
+unsigned int ustctl_count_nl(const char *str)
+{
+       unsigned int i = 0, tot = 0;
+
+       while (str[i] != '\0') {
+               if (str[i] == '\n') {
+                       ++tot;
+               }
+               ++i;
+       }
+
+       return tot;
+}
+
+/**
+ * Frees a CMSF array.
+ *
+ * @param cmsf CMSF array to free
+ * @return     0 if successful, or error USTCTL_ERR_ARG
+ */
+int ustctl_free_cmsf(struct ust_marker_status *cmsf)
+{
+       if (cmsf == NULL) {
+               return USTCTL_ERR_ARG;
+       }
+
+       unsigned int i = 0;
+       while (cmsf[i].channel != NULL) {
+               free(cmsf[i].channel);
+               free(cmsf[i].ust_marker);
+               free(cmsf[i].fs);
+               ++i;
+       }
+       free(cmsf);
+
+       return 0;
+}
+
+/**
+ * Gets channel/ust_marker/state/format string for a given PID.
+ *
+ * @param cmsf Pointer to CMSF array to be filled (callee allocates, caller
+ *             frees with `ustctl_free_cmsf')
+ * @param pid  Targeted PID
+ * @return     0 if successful, or -1 on error
+ */
+int ustctl_get_cmsf(int sock, struct ust_marker_status **cmsf)
+{
+       struct ustcomm_header req_header, res_header;
+       char *big_str = NULL;
+       int result;
+       struct ust_marker_status *tmp_cmsf = NULL;
+       unsigned int i = 0, cmsf_ind = 0;
+
+       if (cmsf == NULL) {
+               return -1;
+       }
+
+       req_header.command = LIST_MARKERS;
+       req_header.size = 0;
+
+       result = ustcomm_send(sock, &req_header, NULL);
+       if (result <= 0) {
+               PERROR("error while requesting ust_marker list");
+               return -1;
+       }
+
+       result = ustcomm_recv_alloc(sock, &res_header, &big_str);
+       if (result <= 0) {
+               ERR("error while receiving ust_marker list");
+               return -1;
+       }
+
+       tmp_cmsf = (struct ust_marker_status *) zmalloc(sizeof(struct ust_marker_status) *
+                                                   (ustctl_count_nl(big_str) + 1));
+       if (tmp_cmsf == NULL) {
+               ERR("Failed to allocate CMSF array");
+               return -1;
+       }
+
+       /* Parse received reply string (format: "[chan]/[mark] [st] [fs]"): */
+       while (big_str[i] != '\0') {
+               char state;
+
+               sscanf(big_str + i, "ust_marker: %a[^/]/%a[^ ] %c %a[^\n]",
+                      &tmp_cmsf[cmsf_ind].channel,
+                      &tmp_cmsf[cmsf_ind].ust_marker,
+                      &state,
+                      &tmp_cmsf[cmsf_ind].fs);
+               tmp_cmsf[cmsf_ind].state = (state == USTCTL_MS_CHR_ON ?
+                                           USTCTL_MS_ON : USTCTL_MS_OFF); /* Marker state */
+
+               while (big_str[i] != '\n') {
+                       ++i; /* Go to next '\n' */
+               }
+               ++i; /* Skip current pointed '\n' */
+               ++cmsf_ind;
+       }
+       tmp_cmsf[cmsf_ind].channel = NULL;
+       tmp_cmsf[cmsf_ind].ust_marker = NULL;
+       tmp_cmsf[cmsf_ind].fs = NULL;
+
+       *cmsf = tmp_cmsf;
+
+       free(big_str);
+       return 0;
+}
+
+/**
+ * Frees a TES array.
+ *
+ * @param tes  TES array to free
+ * @return     0 if successful, or error USTCTL_ERR_ARG
+ */
+int ustctl_free_tes(struct trace_event_status *tes)
+{
+       if (tes == NULL) {
+               return USTCTL_ERR_ARG;
+       }
+
+       unsigned int i = 0;
+       while (tes[i].name != NULL) {
+               free(tes[i].name);
+               ++i;
+       }
+       free(tes);
+
+       return 0;
+}
+
+/**
+ * Gets trace_events string for a given PID.
+ *
+ * @param tes  Pointer to TES array to be filled (callee allocates, caller
+ *             frees with `ustctl_free_tes')
+ * @param pid  Targeted PID
+ * @return     0 if successful, or -1 on error
+ */
+int ustctl_get_tes(int sock, struct trace_event_status **tes)
+{
+       struct ustcomm_header req_header, res_header;
+       char *big_str = NULL;
+       int result;
+       struct trace_event_status *tmp_tes = NULL;
+       unsigned int i = 0, tes_ind = 0;
+
+       if (tes == NULL) {
+               return -1;
+       }
+
+       req_header.command = LIST_TRACE_EVENTS;
+       req_header.size = 0;
+
+       result = ustcomm_send(sock, &req_header, NULL);
+       if (result != 1) {
+               ERR("error while requesting trace_event list");
+               return -1;
+       }
+
+       result = ustcomm_recv_alloc(sock, &res_header, &big_str);
+       if (result != 1) {
+               ERR("error while receiving ust_marker list");
+               return -1;
+       }
+
+       tmp_tes = (struct trace_event_status *)
+               zmalloc(sizeof(struct trace_event_status) *
+                       (ustctl_count_nl(big_str) + 1));
+       if (tmp_tes == NULL) {
+               ERR("Failed to allocate TES array");
+               return -1;
+       }
+
+       /* Parse received reply string (format: "[name]"): */
+       while (big_str[i] != '\0') {
+               sscanf(big_str + i, "trace_event: %a[^\n]",
+                      &tmp_tes[tes_ind].name);
+               while (big_str[i] != '\n') {
+                       ++i; /* Go to next '\n' */
+               }
+               ++i; /* Skip current pointed '\n' */
+               ++tes_ind;
+       }
+       tmp_tes[tes_ind].name = NULL;
+
+       *tes = tmp_tes;
+
+       free(big_str);
+       return 0;
+}
+
+/**
+ * Set sock path
+ *
+ * @param sock_path    Sock path
+ * @param pid          Traced process ID
+ * @return             0 if successful, or error
+ */
+int ustctl_set_sock_path(int sock, const char *sock_path)
+{
+       int result;
+       struct ustcomm_header req_header, res_header;
+       struct ustcomm_single_field sock_path_msg;
+
+       result = ustcomm_pack_single_field(&req_header,
+                                          &sock_path_msg,
+                                          sock_path);
+       if (result < 0) {
+               errno = -result;
+               return -1;
+       }
+
+       req_header.command = SET_SOCK_PATH;
+
+       return do_cmd(sock, &req_header, (char *)&sock_path_msg,
+                     &res_header, NULL);
+}
+
+/**
+ * Get sock path
+ *
+ * @param sock_path    Pointer to where the sock path will be returned
+ * @param pid          Traced process ID
+ * @return             0 if successful, or error
+ */
+int ustctl_get_sock_path(int sock, char **sock_path)
+{
+       int result;
+       struct ustcomm_header req_header, res_header;
+       struct ustcomm_single_field *sock_path_msg;
+
+       req_header.command = GET_SOCK_PATH;
+       req_header.size = 0;
+
+       result = do_cmd(sock, &req_header, NULL, &res_header,
+                       (char **)&sock_path_msg);
+       if (result < 0) {
+               return -1;
+       }
+
+       result = ustcomm_unpack_single_field(sock_path_msg);
+       if (result < 0) {
+               return result;
+       }
+
+       *sock_path = strdup(sock_path_msg->field);
+
+       free(sock_path_msg);
+
+       return 0;
+}
diff --git a/deprecated/ust-consumerd/Makefile.am b/deprecated/ust-consumerd/Makefile.am
new file mode 100644 (file)
index 0000000..01e3b82
--- /dev/null
@@ -0,0 +1,14 @@
+AM_CPPFLAGS = -I$(top_srcdir)/libust -I$(top_srcdir)/libustcomm \
+       -I$(top_srcdir)/include -I$(top_srcdir)/libustconsumer
+AM_CFLAGS = -fno-strict-aliasing
+
+bin_PROGRAMS = ust-consumerd
+
+ust_consumerd_SOURCES = ust-consumerd.c
+
+ust_consumerd_LDADD = \
+       $(top_builddir)/snprintf/libustsnprintf.la \
+       $(top_builddir)/libustcomm/libustcomm.la \
+       $(top_builddir)/libustconsumer/libustconsumer.la
+
+ust_consumerd_CFLAGS = -DUST_COMPONENT=ust-consumerd -fno-strict-aliasing
diff --git a/deprecated/ust-consumerd/README b/deprecated/ust-consumerd/README
new file mode 100644 (file)
index 0000000..6df4015
--- /dev/null
@@ -0,0 +1,3 @@
+This is ust-consumerd, the UST consumer daemon.
+
+This daemon is used to collect the traces for the traced programs and write them to disk.
diff --git a/deprecated/ust-consumerd/ust-consumerd.c b/deprecated/ust-consumerd/ust-consumerd.c
new file mode 100644 (file)
index 0000000..0761253
--- /dev/null
@@ -0,0 +1,516 @@
+/* Copyright (C) 2009  Pierre-Marc Fournier
+ *               2010  Alexis Halle
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/shm.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <inttypes.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <getopt.h>
+
+#include "ust/ustconsumer.h"
+#include "../libustconsumer/lowlevel.h"
+#include "usterr.h"
+
+char *sock_path=NULL;
+char *trace_path=NULL;
+int daemon_mode = 0;
+char *pidfile = NULL;
+
+struct ustconsumer_instance *instance;
+
+struct buffer_info_local {
+       /* output file */
+       int file_fd;
+       /* the offset we must truncate to, to unput the last subbuffer */
+       off_t previous_offset;
+};
+
+static int write_pidfile(const char *file_name, pid_t pid)
+{
+       FILE *pidfp;
+
+       pidfp = fopen(file_name, "w");
+       if(!pidfp) {
+               PERROR("fopen (%s)", file_name);
+               WARN("killing child process");
+               return -1;
+       }
+
+       fprintf(pidfp, "%d\n", pid);
+
+       fclose(pidfp);
+
+       return 0;
+}
+
+int create_dir_if_needed(char *dir)
+{
+       int result;
+       result = mkdir(dir, 0777);
+       if(result == -1) {
+               if(errno != EEXIST) {
+                       PERROR("mkdir");
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+int unwrite_last_subbuffer(struct buffer_info *buf)
+{
+       int result;
+       struct buffer_info_local *buf_local = buf->user_data;
+
+       result = ftruncate(buf_local->file_fd, buf_local->previous_offset);
+       if(result == -1) {
+               PERROR("ftruncate");
+               return -1;
+       }
+
+       result = lseek(buf_local->file_fd, buf_local->previous_offset, SEEK_SET);
+       if(result == (int)(off_t)-1) {
+               PERROR("lseek");
+               return -1;
+       }
+
+       return 0;
+}
+
+int write_current_subbuffer(struct buffer_info *buf)
+{
+       int result;
+       struct buffer_info_local *buf_local = buf->user_data;
+
+       void *subbuf_mem = buf->mem + (buf->consumed_old & (buf->n_subbufs * buf->subbuf_size-1));
+
+       size_t cur_sb_size = subbuffer_data_size(subbuf_mem);
+
+       off_t cur_offset = lseek(buf_local->file_fd, 0, SEEK_CUR);
+       if(cur_offset == (off_t)-1) {
+               PERROR("lseek");
+               return -1;
+       }
+
+       buf_local->previous_offset = cur_offset;
+       DBG("previous_offset: %ld", cur_offset);
+
+       result = patient_write(buf_local->file_fd, subbuf_mem, cur_sb_size);
+       if(result == -1) {
+               PERROR("write");
+               return -1;
+       }
+
+       return 0;
+}
+
+int on_read_subbuffer(struct ustconsumer_callbacks *data, struct buffer_info *buf)
+{
+       return write_current_subbuffer(buf);
+}
+
+int on_read_partial_subbuffer(struct ustconsumer_callbacks *data, struct buffer_info *buf,
+                               long subbuf_index, unsigned long valid_length)
+{
+       struct buffer_info_local *buf_local = buf->user_data;
+       char *tmp;
+       int result;
+       unsigned long pad_size;
+
+       result = patient_write(buf_local->file_fd, buf->mem + subbuf_index * buf->subbuf_size, valid_length);
+       if(result == -1) {
+               ERR("Error writing to buffer file");
+               return result;
+       }
+
+       /* pad with empty bytes */
+       pad_size = PAGE_ALIGN(valid_length)-valid_length;
+       if(pad_size) {
+               tmp = zmalloc(pad_size);
+               result = patient_write(buf_local->file_fd, tmp, pad_size);
+               if(result == -1) {
+                       ERR("Error writing to buffer file");
+                       return result;
+               }
+               free(tmp);
+       }
+       return result;
+}
+
+int on_open_buffer(struct ustconsumer_callbacks *data, struct buffer_info *buf)
+{
+       char *tmp;
+       int result;
+       int fd;
+       struct buffer_info_local *buf_local =
+               zmalloc(sizeof(struct buffer_info_local));
+
+       if(!buf_local) {
+               ERR("could not allocate buffer_info_local struct");
+               return 1;
+       }
+
+       buf->user_data = buf_local;
+
+       /* open file for output */
+       if(!trace_path) {
+               /* Only create the directory if using the default path, because
+                * of the risk of typo when using trace path override. We don't
+                * want to risk creating plenty of useless directories in that case.
+                */
+               result = create_dir_if_needed(USTCONSUMER_DEFAULT_TRACE_PATH);
+               if(result == -1) {
+                       ERR("could not create directory %s", USTCONSUMER_DEFAULT_TRACE_PATH);
+                       return 1;
+               }
+
+               trace_path = USTCONSUMER_DEFAULT_TRACE_PATH;
+       }
+
+       if (asprintf(&tmp, "%s/%u_%" PRId64 "", trace_path, buf->pid, buf->pidunique) < 0) {
+               ERR("on_open_buffer : asprintf failed (%s/%u_%" PRId64 ")",
+                   trace_path, buf->pid, buf->pidunique);
+               return 1;
+       }
+       result = create_dir_if_needed(tmp);
+       if(result == -1) {
+               ERR("could not create directory %s", tmp);
+               free(tmp);
+               return 1;
+       }
+       free(tmp);
+
+       if (asprintf(&tmp, "%s/%u_%" PRId64 "/%s", trace_path, buf->pid, buf->pidunique, buf->name) < 0) {
+               ERR("on_open_buffer : asprintf failed (%s/%u_%" PRId64 "/%s)",
+                   trace_path, buf->pid, buf->pidunique, buf->name);
+               return 1;
+       }
+again:
+       result = fd = open(tmp, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 00600);
+       if (result == -1 && errno == EINTR)
+               goto again;
+
+       if(result == -1) {
+               PERROR("open");
+               ERR("failed opening trace file %s", tmp);
+               return 1;
+       }
+       buf_local->file_fd = fd;
+       free(tmp);
+
+       return 0;
+}
+
+int on_close_buffer(struct ustconsumer_callbacks *data, struct buffer_info *buf)
+{
+       struct buffer_info_local *buf_local = buf->user_data;
+       int result;
+
+again:
+       result = close(buf_local->file_fd);
+       if (result == -1 && errno == EINTR)
+               goto again;
+       free(buf_local);
+       if(result == -1) {
+               PERROR("close");
+       }
+       return 0;
+}
+
+int on_put_error(struct ustconsumer_callbacks *data, struct buffer_info *buf)
+{
+       return unwrite_last_subbuffer(buf);
+}
+
+struct ustconsumer_callbacks *new_callbacks()
+{
+       struct ustconsumer_callbacks *callbacks =
+               zmalloc(sizeof(struct ustconsumer_callbacks));
+
+       if(!callbacks)
+               return NULL;
+
+       callbacks->on_open_buffer = on_open_buffer;
+       callbacks->on_close_buffer = on_close_buffer;
+       callbacks->on_read_subbuffer = on_read_subbuffer;
+       callbacks->on_read_partial_subbuffer = on_read_partial_subbuffer;
+       callbacks->on_put_error = on_put_error;
+       callbacks->on_new_thread = NULL;
+       callbacks->on_close_thread = NULL;
+       callbacks->on_trace_end = NULL;
+
+       return callbacks;
+
+}
+
+int is_directory(const char *dir)
+{
+       int result;
+       struct stat st;
+
+       result = stat(dir, &st);
+       if(result == -1) {
+               PERROR("stat");
+               return 0;
+       }
+
+       if(!S_ISDIR(st.st_mode)) {
+               return 0;
+       }
+
+       return 1;
+}
+
+void usage(void)
+{
+       fprintf(stderr, "Usage:\nust-consumerd OPTIONS\n\nOptions:\n"
+                       "\t-h\t\tDisplay this usage.\n"
+                       "\t-o DIR\t\tSpecify the directory where to output the traces.\n"
+                       "\t-s PATH\t\tSpecify the path to use for the daemon socket.\n"
+                       "\t-d\t\tStart as a daemon.\n"
+                       "\t--pidfile FILE\tWrite the PID in this file (when using -d).\n");
+}
+
+int parse_args(int argc, char **argv)
+{
+       int c;
+
+       while (1) {
+               int option_index = 0;
+               static struct option long_options[] = {
+                       {"pidfile", 1, 0, 'p'},
+                       {"help", 0, 0, 'h'},
+                       {"version", 0, 0, 'V'},
+                       {0, 0, 0, 0}
+               };
+
+               c = getopt_long(argc, argv, "hs:o:d", long_options, &option_index);
+               if (c == -1)
+                       break;
+
+               switch (c) {
+               case 0:
+                       printf("option %s", long_options[option_index].name);
+                       if (optarg)
+                               printf(" with arg %s", optarg);
+                       printf("\n");
+                       break;
+               case 's':
+                       sock_path = optarg;
+                       break;
+               case 'o':
+                       trace_path = optarg;
+                       if(!is_directory(trace_path)) {
+                               ERR("Not a valid directory. (%s)", trace_path);
+                               return -1;
+                       }
+                       break;
+               case 'd':
+                       daemon_mode = 1;
+                       break;
+               case 'p':
+                       pidfile = strdup(optarg);
+                       break;
+               case 'h':
+                       usage();
+                       exit(0);
+               case 'V':
+                       printf("Version 0.0\n");
+                       break;
+
+               default:
+                       /* unknown option or other error; error is
+                       printed by getopt, just return */
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+void sigterm_handler(int sig)
+{
+       ustconsumer_stop_instance(instance, 0);
+}
+
+int start_ustconsumer(int fd)
+{
+       int result;
+       sigset_t sigset;
+       struct sigaction sa;
+
+       struct ustconsumer_callbacks *callbacks = new_callbacks();
+       if(!callbacks) {
+               PERROR("new_callbacks");
+               return 1;
+       }
+
+       result = sigemptyset(&sigset);
+       if(result == -1) {
+               PERROR("sigemptyset");
+               return 1;
+       }
+       sa.sa_handler = sigterm_handler;
+       sa.sa_mask = sigset;
+       sa.sa_flags = 0;
+       result = sigaction(SIGTERM, &sa, NULL);
+       if(result == -1) {
+               PERROR("sigaction");
+               return 1;
+       }
+       result = sigaction(SIGINT, &sa, NULL);
+       if(result == -1) {
+               PERROR("sigaction");
+               return 1;
+       }
+
+       instance = ustconsumer_new_instance(callbacks, sock_path);
+       if(!instance) {
+               ERR("failed to create ustconsumer instance");
+               return 1;
+       }
+
+       result = ustconsumer_init_instance(instance);
+       if(result) {
+               ERR("failed to initialize ustconsumer instance");
+               return 1;
+       }
+
+       /* setup handler for SIGPIPE */
+       result = sigemptyset(&sigset);
+       if(result == -1) {
+               PERROR("sigemptyset");
+               return 1;
+       }
+       result = sigaddset(&sigset, SIGPIPE);
+       if(result == -1) {
+               PERROR("sigaddset");
+               return 1;
+       }
+       result = sigprocmask(SIG_BLOCK, &sigset, NULL);
+       if(result == -1) {
+               PERROR("sigprocmask");
+               return 1;
+       }
+
+       /* Write pidfile */
+       if(pidfile) {
+               result = write_pidfile(pidfile, getpid());
+               if(result == -1) {
+                       ERR("failed to write pidfile");
+                       return 1;
+               }
+       }
+
+       /* Notify parent that we are successfully started. */
+       if(fd != -1) {
+               /* write any one character */
+               result = write(fd, "!", 1);
+               if(result == -1) {
+                       PERROR("write");
+                       return -1;
+               }
+               if(result != 1) {
+                       ERR("Problem sending confirmation of daemon start to parent");
+                       return -1;
+               }
+               result = close(fd);
+               if(result == -1) {
+                       PERROR("close");
+               }
+       }
+
+       ustconsumer_start_instance(instance);
+
+       free(callbacks);
+
+       return 0;
+}
+
+int start_ustconsumer_daemon()
+{
+       int result;
+       int fd[2];
+       pid_t child_pid;
+
+       result = pipe(fd);
+
+       result = child_pid = fork();
+       if(result == -1) {
+               PERROR("fork");
+               return -1;
+       }
+       else if(result == 0) {
+               return start_ustconsumer(fd[1]);
+       }
+       else {
+               char buf;
+
+               result = read(fd[0], &buf, 1);
+               if(result == -1) {
+                       PERROR("read");
+                       return -1;
+               }
+               if(result != 1) {
+                       ERR("did not receive valid confirmation that the daemon is started");
+                       return -1;
+               }
+
+               result = close(fd[0]);
+               if(result == -1) {
+                       PERROR("close");
+               }
+
+               DBG("The daemon is now successfully started");
+       }
+
+       /* Wait for confirmation that the server is ready. */
+
+
+       return 0;
+}
+
+int main(int argc, char **argv)
+{
+       int result;
+
+       result = parse_args(argc, argv);
+       if(result == -1) {
+               exit(1);
+       }
+
+       if(daemon_mode) {
+               result = start_ustconsumer_daemon();
+       }
+       else {
+               result = start_ustconsumer(-1);
+       }
+
+       return result;
+}
diff --git a/deprecated/ustctl/Makefile.am b/deprecated/ustctl/Makefile.am
new file mode 100644 (file)
index 0000000..1e442a3
--- /dev/null
@@ -0,0 +1,15 @@
+AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libustcomm \
+       -I$(top_srcdir)/libustctl $(KCOMPAT_CFLAGS)
+AM_CFLAGS = -fno-strict-aliasing
+
+bin_PROGRAMS = ustctl
+
+ustctl_SOURCES = \
+       ustctl.c marker_cmds.c trace_cmds.c channel_cmds.c cli.c cli.h scanning_functions.c scanning_functions.h
+
+ustctl_CFLAGS = -DUST_COMPONENT=ustctl -fno-strict-aliasing
+
+ustctl_LDADD = \
+       $(top_builddir)/snprintf/libustsnprintf.la \
+       $(top_builddir)/libustcomm/libustcomm.la \
+       $(top_builddir)/libustctl/libustctl.la
diff --git a/deprecated/ustctl/README b/deprecated/ustctl/README
new file mode 100644 (file)
index 0000000..3fdfbbd
--- /dev/null
@@ -0,0 +1,3 @@
+ustctl is a helper application used to control tracing on programs that support tracing.
+
+It can list markers, enable/disable markers, start tracing and stop tracing.
diff --git a/deprecated/ustctl/channel_cmds.c b/deprecated/ustctl/channel_cmds.c
new file mode 100644 (file)
index 0000000..315fd56
--- /dev/null
@@ -0,0 +1,151 @@
+/* Copyright (C) 2011  Ericsson AB, Nils Carlson <nils.carlson@ericsson.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <ust/ustctl.h>
+#include "scanning_functions.h"
+#include "usterr.h"
+#include "cli.h"
+
+static int set_subbuf_size(int argc, char *argv[])
+{
+       int sock, result = 0;
+       char *channel = NULL;
+       unsigned int size;
+
+       sock = parse_and_connect_pid(argv[1]);
+
+       if (scan_ch_and_num(argv[3], &channel, &size)) {
+               fprintf(stderr, "Failed to scan channel and size from"
+                               " %s\n", argv[3]);
+               if (channel)
+                       free(channel);
+               return -1;
+       }
+       if (ustctl_set_subbuf_size(sock, argv[2], channel, size)) {
+               ERR("error while trying to set the size of subbuffers "
+                   "for PID %s\n",
+                   argv[1]);
+               result = -1;
+       }
+
+       free(channel);
+
+       return result;
+}
+
+static int set_subbuf_num(int argc, char *argv[])
+{
+       int sock, result = 0;
+       char *channel = NULL;
+       unsigned int num;
+
+       sock = parse_and_connect_pid(argv[1]);
+
+       if (scan_ch_and_num(argv[3], &channel, &num)) {
+               fprintf(stderr, "Failed to scan channel and number from"
+                               " %s\n", argv[3]);
+               if (channel)
+                       free(channel);
+               return -1;
+       }
+       if (ustctl_set_subbuf_num(sock, argv[2], channel, num)) {
+               ERR("error while trying to set the number of subbuffers for PID %s\n",
+                   argv[1]);
+               result = -1;
+       }
+
+       free(channel);
+
+       return result;
+}
+
+static int get_subbuf_size(int argc, char *argv[])
+{
+       int sock;
+       unsigned int size;
+
+       sock = parse_and_connect_pid(argv[1]);
+
+       if ((size = ustctl_get_subbuf_size(sock, argv[2], argv[3])) < 0) {
+               ERR("error while trying to get the subbuffer size from PID %s\n",
+                   argv[1]);
+               return -1;
+       }
+
+       printf("The subbufer size is %d bytes\n", size);
+
+       return 0;
+}
+
+static int get_subbuf_num(int argc, char *argv[])
+{
+       int sock;
+       unsigned int num;
+
+       sock = parse_and_connect_pid(argv[1]);
+
+       if ((num = ustctl_get_subbuf_num(sock, argv[2], argv[3])) < 0) {
+               ERR("error while trying to get the subbuffer size from PID %s\n",
+                   argv[1]);
+               return -1;
+       }
+
+       printf("There are %u subbufers in each buffer\n", num);
+
+       return 0;
+}
+
+struct cli_cmd __cli_cmds channel_cmds[] = {
+       {
+               .name = "set-subbuf-size",
+               .description = "Set the subbuffer size for a channel",
+               .help_text = "set-subbuf-size <pid> <trace> <channel>/<size> \n"
+               "Set the subbuffer size for a channel\n",
+               .function = set_subbuf_size,
+               .desired_args = 3,
+               .desired_args_op = CLI_EQ,
+       },
+       {
+               .name = "set-subbuf-num",
+               .description = "Set the number of subbuffers for a channel",
+               .help_text = "set-subbuf-num <pid> <trace> <channel>/<num> \n"
+               "Set the number of subbuffers for a channel\n",
+               .function = set_subbuf_num,
+               .desired_args = 3,
+               .desired_args_op = CLI_EQ,
+       },
+       {
+               .name = "get-subbuf-size",
+               .description = "Get the subbuffer size for a channel",
+               .help_text = "get-subbuf-size <pid> <trace> <channel>\n"
+               "Get the subbuffer size for a channel\n",
+               .function = get_subbuf_size,
+               .desired_args = 3,
+               .desired_args_op = CLI_EQ,
+       },
+       {
+               .name = "get-subbuf-num",
+               .description = "Get the number of subbuffers for a channel",
+               .help_text = "get-subbuf-num <pid> <trace> <channel>\n"
+               "Get the number of subbuffers for a channel\n",
+               .function = get_subbuf_num,
+               .desired_args = 3,
+               .desired_args_op = CLI_EQ,
+       },
+};
diff --git a/deprecated/ustctl/cli.c b/deprecated/ustctl/cli.c
new file mode 100644 (file)
index 0000000..0ca9db5
--- /dev/null
@@ -0,0 +1,207 @@
+/* Copyright (C) 2011  Ericsson AB, Nils Carlson <nils.carlson@ericsson.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "cli.h"
+
+/* This dummy command is needed to create the sections in cli.o before
+ *  other .o files have these sections, usefull for development.
+ */
+static int _dummy(int argc, char *argv[]) {
+       return 0;
+}
+
+/* Define a dummy cmd to guarantee existence of the builtin variables */
+struct cli_cmd __cli_cmds __dummy_cli_cmd[] = {
+       {
+               .name = "_dummy",
+               .description = NULL,
+               .help_text = NULL,
+               .function = _dummy,
+               .desired_args = 0,
+               .desired_args_op = 0,
+       },
+};
+
+extern struct cli_cmd __start___cli_cmds[] __attribute__((visibility("hidden")));
+extern struct cli_cmd __stop___cli_cmds[] __attribute__((visibility("hidden")));
+
+static struct cli_cmd **cli_cmd_list;
+static int cli_cmd_list_size;
+
+static char *process_name;
+
+static int compute_cli_cmds_size(void)
+{
+       long cli_cmds_start, cli_cmds_end;
+
+       cli_cmds_start = (long)__start___cli_cmds;
+       cli_cmds_end = (long)__stop___cli_cmds;
+
+       return (cli_cmds_end - cli_cmds_start) / sizeof(struct cli_cmd);
+}
+
+static void __attribute__((constructor)) generate_cli_cmd_list(int argc, char *argv[])
+{
+       struct cli_cmd *cli_cmd;
+       int section_size, i;
+
+       process_name = basename(argv[0]);
+
+       section_size = compute_cli_cmds_size();
+
+       cli_cmd_list = malloc(section_size * sizeof(void *));
+       if (!cli_cmd_list) {
+               fprintf(stderr, "Failed to allocate command list!");
+               exit(EXIT_FAILURE);
+       }
+
+       cli_cmd_list_size = 0;
+
+       cli_cmd = __start___cli_cmds;
+       for (i = 0; i < section_size; i++) {
+               if (&cli_cmd[i] == &__dummy_cli_cmd[0]) {
+                       continue;
+               }
+
+               if (cli_cmd[i].name) {
+                       cli_cmd_list[cli_cmd_list_size++] = &cli_cmd[i];
+               }
+       }
+}
+
+struct cli_cmd *find_cli_cmd(const char *command)
+{
+       int i;
+
+       for (i = 0; i < cli_cmd_list_size; i++) {
+               if (!strcmp(cli_cmd_list[i]->name, command)) {
+                       return cli_cmd_list[i];
+               }
+       }
+
+       return NULL;
+}
+
+static int cmpcli_cmds(const void *p1, const void *p2)
+{
+       return strcmp(* (char * const *) ((struct cli_cmd *)p1)->name,
+                     * (char * const *) ((struct cli_cmd *)p2)->name);
+}
+
+#define HELP_BUFFER_SIZE 4096
+
+static void print_cmd_help(const char *prefix, const char *infix,
+                          struct cli_cmd *cli_cmd)
+{
+       if (cli_cmd->help_text) {
+               fprintf(stderr, "%s%s%s",
+                       prefix,
+                       infix,
+                       cli_cmd->help_text);
+       } else if (cli_cmd->description) {
+               fprintf(stderr, "%s%s%s\n%s\n",
+                       prefix,
+                       infix,
+                       cli_cmd->name,
+                       cli_cmd->description);
+       } else {
+               fprintf(stderr, "No help available for %s\n",
+                       cli_cmd->name);
+       }
+}
+
+void list_cli_cmds(int option)
+{
+       int i;
+
+       qsort(cli_cmd_list, cli_cmd_list_size, sizeof(void *), cmpcli_cmds);
+
+       for (i = 0; i < cli_cmd_list_size; i++) {
+               switch (option) {
+               case CLI_SIMPLE_LIST:
+                       fprintf(stderr, "%s ", cli_cmd_list[i]->name);
+                       break;
+               case CLI_DESCRIPTIVE_LIST:
+                       fprintf(stderr, "   %-25s%s\n", cli_cmd_list[i]->name,
+                               cli_cmd_list[i]->description);
+                       break;
+               case CLI_EXTENDED_LIST:
+                       print_cmd_help("", "", cli_cmd_list[i]);
+                       fprintf(stderr, "\n");
+                       break;
+               }
+       }
+
+       if (option == CLI_SIMPLE_LIST) {
+               fprintf(stderr, "\n");
+       }
+}
+
+int cli_print_help(const char *command)
+{
+       struct cli_cmd *cli_cmd;
+
+       cli_cmd = find_cli_cmd(command);
+       if (!cli_cmd) {
+               return -1;
+       }
+
+       print_cmd_help(process_name, " ", cli_cmd);
+
+       return 0;
+}
+
+static void cli_check_argc(const char *command, int args,
+                          int operator, int desired_args)
+{
+       switch(operator) {
+       case CLI_EQ:
+               if (args != desired_args)
+                       goto print_error;
+               break;
+       case CLI_GE:
+               if (args < desired_args)
+                       goto print_error;
+               break;
+       }
+
+       return;
+
+print_error:
+       fprintf(stderr, "%s %s requires %s%d argument%s, see usage.\n",
+               process_name, command, operator == CLI_EQ ? "" : "at least ",
+               desired_args, desired_args > 1 ? "s" : "");
+       cli_print_help(command);
+       exit(EXIT_FAILURE);
+}
+
+
+void cli_dispatch_cmd(struct cli_cmd *cmd, int argc, char *argv[])
+{
+       cli_check_argc(cmd->name, argc - 1, cmd->desired_args_op,
+                      cmd->desired_args);
+
+       if (cmd->function(argc, argv)) {
+               exit(EXIT_FAILURE);
+       }
+
+       exit(EXIT_SUCCESS);
+}
diff --git a/deprecated/ustctl/cli.h b/deprecated/ustctl/cli.h
new file mode 100644 (file)
index 0000000..a1e4eed
--- /dev/null
@@ -0,0 +1,50 @@
+/* Copyright (C) 2011  Ericsson AB, Nils Carlson <nils.carlson@ericsson.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+#ifndef _CLI_H
+#define _CLI_H
+
+struct cli_cmd {
+       const char *name;
+       const char *description;
+       const char *help_text;
+       int (*function)(int, char **);
+       int desired_args;
+       int desired_args_op;
+} __attribute__((aligned(8)));
+
+#define __cli_cmds __attribute__((section("__cli_cmds"), aligned(8), used))
+
+struct cli_cmd *find_cli_cmd(const char *command);
+
+enum cli_list_opts {
+       CLI_SIMPLE_LIST,
+       CLI_DESCRIPTIVE_LIST,
+       CLI_EXTENDED_LIST,
+};
+
+void list_cli_cmds(int option);
+
+int cli_print_help(const char *command);
+
+enum cli_arg_ops {
+       CLI_EQ,
+       CLI_GE,
+};
+
+void cli_dispatch_cmd(struct cli_cmd *cmd, int argc, char *argv[]);
+
+#endif /* _CLI_H */
diff --git a/deprecated/ustctl/marker_cmds.c b/deprecated/ustctl/marker_cmds.c
new file mode 100644 (file)
index 0000000..8bcab83
--- /dev/null
@@ -0,0 +1,141 @@
+/* Copyright (C) 2011  Ericsson AB, Nils Carlson <nils.carlson@ericsson.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <ust/ustctl.h>
+#include "scanning_functions.h"
+#include "usterr.h"
+#include "cli.h"
+
+static int list_markers(int argc, char *argv[])
+{
+       struct ust_marker_status *cmsf = NULL;
+       int i, sock;
+
+       sock = parse_and_connect_pid(argv[1]);
+
+       if (ustctl_get_cmsf(sock, &cmsf)) {
+               ERR("error while trying to list markers for PID %s\n", argv[1]);
+               return -1;
+       }
+       for (i = 0; cmsf[i].channel; i++) {
+               printf("{PID: %s, channel/marker: %s/%s, "
+                      "state: %u, fmt: %s}\n",
+                      argv[1],
+                      cmsf[i].channel,
+                      cmsf[i].ust_marker,
+                      cmsf[i].state,
+                      cmsf[i].fs);
+       }
+       ustctl_free_cmsf(cmsf);
+       return 0;
+}
+
+static int enable_marker(int argc, char *argv[])
+{
+       int i, sock, result = 0;
+       char *channel, *marker;
+
+       sock = parse_and_connect_pid(argv[1]);
+
+       for (i = 3; i < argc; i++) {
+               channel = NULL;
+               marker = NULL;
+               if (scan_ch_marker(argv[i],
+                                  &channel, &marker)) {
+                       result = -1;
+                       fprintf(stderr, "Failed to scan channel and marker from"
+                               " %s\n", argv[i]);
+                       if (channel)
+                               free(channel);
+                       if (marker)
+                               free(marker);
+               }
+               if (ustctl_set_ust_marker_state(sock, argv[2], channel, marker, 1)) {
+                       PERROR("error while trying to enable marker %s with PID %s",
+                              argv[i], argv[1]);
+                       result = -1;
+               }
+               free(channel);
+               free(marker);
+       }
+
+       return result;
+}
+
+static int disable_marker(int argc, char *argv[])
+{
+       int i, sock, result = 0;
+       char *channel, *marker;
+
+       sock = parse_and_connect_pid(argv[1]);
+
+       for (i = 3; i < argc; i++) {
+               channel = NULL;
+               marker = NULL;
+               if (scan_ch_marker(argv[i],
+                                  &channel, &marker)) {
+                       fprintf(stderr, "Failed to scan channel and marker from"
+                               " %s\n", argv[i]);
+                       if (channel)
+                               free(channel);
+                       if (marker)
+                               free(marker);
+                       return -1;
+               }
+               if (ustctl_set_ust_marker_state(sock, argv[2], channel, marker, 0)) {
+                       PERROR("error while trying to disable marker %s with PID %s",
+                              argv[i], argv[1]);
+                       result = -1;
+               }
+               free(channel);
+               free(marker);
+       }
+
+       return result;
+}
+
+struct cli_cmd __cli_cmds ust_marker_cmds[] = {
+       {
+               .name = "list-markers",
+               .description = "List markers for a given pid",
+               .help_text = "list-markers <pid>\n"
+               "List the markers in a process\n",
+               .function = list_markers,
+               .desired_args = 1,
+               .desired_args_op = CLI_EQ,
+       },
+       {
+               .name = "enable-marker",
+               .description = "Enable markers for a given pid",
+               .help_text = "enable-marker <pid> <trace> <channel>/<marker>... \n"
+               "Enable the listed markers for the trace in process pid\n",
+               .function = enable_marker,
+               .desired_args = 3,
+               .desired_args_op = CLI_GE,
+       },
+       {
+              .name = "disable-marker",
+              .description = "Disable markers for a given pid",
+              .help_text = "disable-marker <pid> <trace> <channel>/<marker>... \n"
+              "Disable the listed markers for the trace in process pid\n",
+              .function = disable_marker,
+              .desired_args = 3,
+              .desired_args_op = CLI_GE,
+       }
+};
diff --git a/deprecated/ustctl/scanning_functions.c b/deprecated/ustctl/scanning_functions.c
new file mode 100644 (file)
index 0000000..4aa8c1c
--- /dev/null
@@ -0,0 +1,91 @@
+/* Copyright (C) 2011  Ericsson AB, Nils Carlson <nils.carlson@ericsson.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <ust/ustctl.h>
+#include "usterr.h"
+
+
+int parse_and_connect_pid(const char *pid_string)
+{
+       pid_t pid;
+       int sock;
+
+       errno = 0;
+       pid = strtoull(pid_string, NULL, 10);
+       if (errno) {
+               perror("Failed to parse pid");
+               exit(EXIT_FAILURE);
+       }
+
+       sock = ustctl_connect_pid(pid);
+       if (sock < 0) {
+               perror("Failed to connect to process");
+               exit(EXIT_FAILURE);
+       }
+
+       return sock;
+}
+
+int scan_ch_marker(const char *channel_marker, char **channel, char **marker)
+{
+       int result;
+
+       *channel = NULL;
+       *marker = NULL;
+
+       result = sscanf(channel_marker, "%a[^/]/%as", channel, marker);
+       if (result != 2) {
+               if (errno) {
+                       PERROR("Failed to read channel and marker names");
+               } else {
+                       ERR("Failed to parse marker and channel names");
+               }
+               if (*channel) {
+                       free(*channel);
+               }
+               if (*marker) {
+                       free(*marker);
+               }
+               return -1;
+       }
+
+       return 0;
+}
+
+int scan_ch_and_num(const char *ch_num, char **channel, unsigned int *num)
+{
+       int result;
+
+       *channel = NULL;
+
+       result = sscanf(ch_num, "%a[^/]/%u", channel, num);
+       if (result != 2) {
+               if (errno) {
+                       PERROR("Failed to parse channel and number");
+               } else {
+                       ERR("Failed to parse channel and number");
+               }
+               if (*channel) {
+                       free(*channel);
+               }
+               return -1;
+       }
+
+       return 0;
+}
diff --git a/deprecated/ustctl/scanning_functions.h b/deprecated/ustctl/scanning_functions.h
new file mode 100644 (file)
index 0000000..0f2d62e
--- /dev/null
@@ -0,0 +1,26 @@
+/* Copyright (C) 2011  Ericsson AB, Nils Carlson <nils.carlson@ericsson.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+#ifndef __SCANNING_FUNCTIONS_H
+#define __SCANNING_FUNCTIONS_H
+
+int parse_and_connect_pid(const char *pid_string);
+
+int scan_ch_marker(const char *channel_marker, char **channel, char **marker);
+
+int scan_ch_and_num(const char *ch_num, char **channel, unsigned int *num);
+
+#endif /* __SCANNING_FUNCTIONS_H */
diff --git a/deprecated/ustctl/trace_cmds.c b/deprecated/ustctl/trace_cmds.c
new file mode 100644 (file)
index 0000000..a8f3a9c
--- /dev/null
@@ -0,0 +1,162 @@
+/* Copyright (C) 2011  Ericsson AB, Nils Carlson <nils.carlson@ericsson.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <ust/ustctl.h>
+#include "scanning_functions.h"
+#include "usterr.h"
+#include "cli.h"
+
+
+static int create_trace(int argc, char *argv[])
+{
+       int sock;
+
+       sock = parse_and_connect_pid(argv[1]);
+
+       if (ustctl_create_trace(sock, argv[2])) {
+               ERR("Failed to create trace %s for PID %s\n", argv[2], argv[1]);
+               return -1;
+       }
+
+       return 0;
+}
+
+static int alloc_trace(int argc, char *argv[])
+{
+       int sock;
+
+       sock = parse_and_connect_pid(argv[1]);
+
+       if (ustctl_alloc_trace(sock, argv[2])) {
+               ERR("Failed to allocate trace %s for PID %s\n", argv[2], argv[1]);
+               return -1;
+       }
+       return 0;
+}
+
+static int start_trace(int argc, char *argv[])
+{
+       int sock;
+
+       sock = parse_and_connect_pid(argv[1]);
+
+       if (ustctl_start_trace(sock, argv[2])) {
+               ERR("Failed to start trace %s for PID %s\n", argv[2], argv[1]);
+               return -1;
+       }
+       return 0;
+}
+
+static int stop_trace(int argc, char *argv[])
+{
+       int sock;
+
+       sock = parse_and_connect_pid(argv[1]);
+
+       if (ustctl_stop_trace(sock, argv[2])) {
+               ERR("Failed to stop trace %s for PID %s\n", argv[2], argv[1]);
+               return -1;
+       }
+       return 0;
+}
+
+static int destroy_trace(int argc, char *argv[])
+{
+       int sock;
+
+       sock = parse_and_connect_pid(argv[1]);
+
+       if (ustctl_destroy_trace(sock, argv[2])) {
+               ERR("Failed to destroy trace %s for PID %s\n", argv[2], argv[1]);
+               return -1;
+       }
+       return 0;
+}
+
+static int force_subbuf_switch(int argc, char *argv[])
+{
+       int sock;
+
+       sock = parse_and_connect_pid(argv[1]);
+
+       if (ustctl_force_switch(sock, argv[2])) {
+               ERR("error while trying to force switch for PID %s\n", argv[1]);
+               return -1;
+       }
+
+       return 0;
+}
+
+struct cli_cmd __cli_cmds trace_cmds[] = {
+       {
+               .name = "create-trace",
+               .description = "Create a trace for a process",
+               .help_text = "create-trace <pid> <trace>\n"
+               "Create a trace for a process\n",
+               .function = create_trace,
+               .desired_args = 2,
+               .desired_args_op = CLI_EQ,
+       },
+       {
+               .name = "alloc-trace",
+               .description = "Allocate a trace for a process",
+               .help_text = "alloc-trace <pid> <trace>\n"
+               "Allocate a trace for a process\n",
+               .function = alloc_trace,
+               .desired_args = 2,
+               .desired_args_op = CLI_EQ,
+       },
+       {
+               .name = "start-trace",
+               .description = "Start a trace for a process",
+               .help_text = "start-trace <pid> <trace>\n"
+               "Start a trace for a process\n",
+               .function = start_trace,
+               .desired_args = 2,
+               .desired_args_op = CLI_EQ,
+       },
+       {
+               .name = "stop-trace",
+               .description = "Stop a trace for a process",
+               .help_text = "stop-trace <pid> <trace>\n"
+               "Stop a trace for a process\n",
+               .function = stop_trace,
+               .desired_args = 2,
+               .desired_args_op = CLI_EQ,
+       },
+       {
+               .name = "destroy-trace",
+               .description = "Destroy a trace for a process",
+               .help_text = "destroy-trace <pid> <trace>\n"
+               "Destroy a trace for a process\n",
+               .function = destroy_trace,
+               .desired_args = 2,
+               .desired_args_op = CLI_EQ,
+       },
+       {
+               .name = "force-subbuf-switch",
+               .description = "Force a subbuffer switch",
+               .help_text = "force-subbuf-switch <pid> <trace>\n"
+               "Force a subbuffer switch for a trace, currently this forces\n"
+               "a subbuffer switch for all traces in a process\n",
+               .function = force_subbuf_switch,
+               .desired_args = 2,
+               .desired_args_op = CLI_EQ,
+       },
+};
diff --git a/deprecated/ustctl/ustctl.c b/deprecated/ustctl/ustctl.c
new file mode 100644 (file)
index 0000000..18f7d30
--- /dev/null
@@ -0,0 +1,272 @@
+/* Copyright (C) 2009  Pierre-Marc Fournier
+ * Copyright (C) 2011  Ericsson AB, Nils Carlson <nils.carlson@ericsson.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#include "ust/ustctl.h"
+#include "usterr.h"
+#include "cli.h"
+#include "scanning_functions.h"
+
+void usage(const char *process_name)
+{
+       fprintf(stderr, "Usage: %s COMMAND [ARGS]...\n", process_name);
+       fprintf(stderr,
+               "Control tracing within a process that supports UST,\n"
+               " the Userspace Tracing libary\n"
+               "Options:\n"
+               "  -h[<cmd>], --help[=<cmd>]        "
+               "help, for a command if provided\n"
+               "  -l, --list                       "
+               "short list of commands\n"
+               "  -e, --extended-list              "
+              "extented list of commands with help\n"
+               "Commands:\n");
+       list_cli_cmds(CLI_DESCRIPTIVE_LIST);
+}
+
+/*
+ * Provide backward compatibility for scripts that make use of the
+ * --commands in ustctl version <= 0.11
+ */
+enum command {
+       CREATE_TRACE=1000,
+       ALLOC_TRACE,
+       START_TRACE,
+       STOP_TRACE,
+       DESTROY_TRACE,
+       LIST_MARKERS,
+       LIST_TRACE_EVENTS,
+       ENABLE_MARKER,
+       DISABLE_MARKER,
+};
+
+struct option options[] =
+{
+       { "create-trace", 0, 0, CREATE_TRACE },
+       { "alloc-trace", 0, 0, ALLOC_TRACE },
+       { "start-trace", 0, 0, START_TRACE },
+       { "stop-trace", 0, 0, STOP_TRACE },
+       { "destroy-trace", 0, 0, DESTROY_TRACE },
+       { "list-markers", 0, 0, LIST_MARKERS },
+       { "list-trace-events", 0, 0, LIST_TRACE_EVENTS},
+       { "enable-marker", 0, 0, ENABLE_MARKER },
+       { "disable-marker", 0, 0, DISABLE_MARKER },
+       {"help", 2, NULL, 'h'},
+       {"list", 0, NULL, 'l'},
+       {"extended-list", 0, NULL, 'e'},
+       {NULL, 0, NULL, 0},
+};
+
+int main(int argc, char *argv[])
+{
+       struct cli_cmd *cli_cmd;
+       char **args = argv;
+       int opt;
+       int i;
+
+       if(argc <= 1) {
+               fprintf(stderr, "No operation specified.\n");
+               usage(argv[0]);
+               exit(EXIT_FAILURE);
+       }
+
+       while ((opt = getopt_long(argc, argv, "+h::le",
+                                 options, NULL)) != -1) {
+               switch (opt) {
+               case 'h':
+                       if (!optarg) {
+                               usage(argv[0]);
+                       } else {
+                               if (cli_print_help(optarg)) {
+                                       fprintf(stderr, "No such command %s\n",
+                                               optarg);
+                               }
+                       }
+                       exit(EXIT_FAILURE);
+                       break;
+               case 'l':
+                       list_cli_cmds(CLI_SIMPLE_LIST);
+                       exit(EXIT_FAILURE);
+                       break;
+               case 'e':
+                       list_cli_cmds(CLI_EXTENDED_LIST);
+                       exit(EXIT_FAILURE);
+               case LIST_MARKERS:
+               case LIST_TRACE_EVENTS:
+               case CREATE_TRACE:
+               case ALLOC_TRACE:
+               case START_TRACE:
+               case STOP_TRACE:
+               case DESTROY_TRACE:
+               case ENABLE_MARKER:
+               case DISABLE_MARKER:
+                       args = (char **)malloc(sizeof(char *) * (argc + 3));
+                       optind--;
+                       args[optind] = strdup(&argv[optind][2]);
+                       for (i = optind + 1; i < argc; i++) {
+                               args[i] = argv[i];
+                       }
+                       if (opt >= CREATE_TRACE && opt <= DESTROY_TRACE) {
+                               args[argc] = strdup("auto");
+                               argc++;
+                       }
+                       if (opt >= ENABLE_MARKER && opt <= DISABLE_MARKER) {
+                               args[argc] = args[argc - 2];
+                               args[argc - 2] = args[argc - 1];
+                               args[argc - 1] = strdup("auto");
+                               argc++;
+                       }
+                       args[argc] = NULL;
+                       goto do_cli;
+               default:
+                       fprintf(stderr, "Unknown option\n");
+                       break;
+               }
+       }
+
+do_cli:
+       cli_cmd = find_cli_cmd(args[optind]);
+       if (!cli_cmd) {
+               fprintf(stderr, "No such command %s\n",
+                       args[optind]);
+               exit(EXIT_FAILURE);
+       }
+
+       cli_dispatch_cmd(cli_cmd, argc - optind, &args[optind]);
+
+       return 0;
+}
+
+static int list_trace_events(int argc, char *argv[])
+{
+       struct trace_event_status *tes = NULL;
+       int i, sock;
+
+       sock = parse_and_connect_pid(argv[1]);
+
+       if (ustctl_get_tes(sock, &tes)) {
+               ERR("error while trying to list "
+                   "trace_events for PID %s\n",
+                   argv[1]);
+               return -1;
+       }
+       i = 0;
+       for (i = 0; tes[i].name; i++) {
+               printf("{PID: %s, trace_event: %s}\n",
+                      argv[1],
+                      tes[i].name);
+       }
+       ustctl_free_tes(tes);
+
+       return 0;
+}
+
+static int set_sock_path(int argc, char *argv[])
+{
+       int sock;
+
+       sock = parse_and_connect_pid(argv[1]);
+
+       if (ustctl_set_sock_path(sock, argv[2])) {
+               ERR("error while trying to set sock path for PID %s\n", argv[1]);
+               return -1;
+       }
+
+       return 0;
+}
+
+static int get_sock_path(int argc, char *argv[])
+{
+       int sock;
+       char *sock_path;
+
+       sock = parse_and_connect_pid(argv[1]);
+
+       if (ustctl_get_sock_path(sock, &sock_path)) {
+               ERR("error while trying to get sock path for PID %s\n", argv[1]);
+               return -1;
+       }
+       printf("The socket path is %s\n", sock_path);
+       free(sock_path);
+
+       return 0;
+}
+
+static int list_pids(int argc, char *argv[])
+{
+       pid_t *pid_list;
+       int i;
+
+       pid_list = ustctl_get_online_pids();
+       if (!pid_list) {
+               return -1;
+       }
+
+       for (i = 0; pid_list[i]; i++) {
+               printf("%ld\n", (long)pid_list[i]);
+       }
+
+       free(pid_list);
+
+       return 0;
+}
+
+struct cli_cmd __cli_cmds general_cmds[] = {
+       {
+               .name = "list-trace-events",
+               .description = "List trace-events for a given pid",
+               .help_text = "list-trace-events <pid>\n"
+               "List the trace-events in a process\n",
+               .function = list_trace_events,
+               .desired_args = 1,
+               .desired_args_op = CLI_EQ,
+       },
+       {
+               .name = "set-sock-path",
+               .description = "Set the path to the consumer daemon socket",
+               .help_text = "set-sock-path <pid> <sock-path>\n"
+               "Set the path to the consumer daemon socket\n",
+               .function = set_sock_path,
+               .desired_args = 2,
+               .desired_args_op = CLI_EQ,
+       },
+       {
+               .name = "get-sock-path",
+               .description = "Get the path to the consumer daemon socket",
+               .help_text = "get-sock-path <pid>\n"
+               "Get the path to the consumer daemon socket\n",
+               .function = get_sock_path,
+               .desired_args = 1,
+               .desired_args_op = CLI_EQ,
+       },
+       {
+               .name = "list-pids",
+               .description = "List traceable pids",
+               .help_text = "list-pids\n"
+               "List the traceable pids for the current user\n",
+               .function = list_pids,
+               .desired_args = 0,
+               .desired_args_op = CLI_EQ,
+       },
+};
diff --git a/libustcomm/Makefile.am b/libustcomm/Makefile.am
deleted file mode 100644 (file)
index 3ae96d5..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-AM_CPPFLAGS = -I$(top_srcdir)/include
-AM_CFLAGS = -fno-strict-aliasing
-
-noinst_LTLIBRARIES = libustcomm.la
-libustcomm_la_SOURCES = \
-       ustcomm.h \
-       ustcomm.c
-
-libustcomm_la_LDFLAGS = -no-undefined -static
-libustcomm_la_CFLAGS = -DUST_COMPONENT="libustcomm" -fPIC -fno-strict-aliasing
diff --git a/libustcomm/ustcomm.c b/libustcomm/ustcomm.c
deleted file mode 100644 (file)
index 07f7f87..0000000
+++ /dev/null
@@ -1,1028 +0,0 @@
-/* Copyright (C) 2009  Pierre-Marc Fournier
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-/* API used by UST components to communicate with each other via sockets. */
-
-#define _GNU_SOURCE
-#include <dirent.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <errno.h>
-#include <limits.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-#include <poll.h>
-#include <sys/epoll.h>
-#include <sys/stat.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "ustcomm.h"
-#include "usterr.h"
-#include "share.h"
-
-static int mkdir_p(const char *path, mode_t mode)
-{
-       const char *path_p;
-       char *tmp;
-
-       int retval = 0;
-       int result;
-       mode_t old_umask;
-
-       tmp = zmalloc(strlen(path) + 1);
-       if (tmp == NULL)
-               return -1;
-
-       /* skip first / */
-       path_p = path+1;
-
-       old_umask = umask(0);
-       for(;;) {
-               while (*path_p != '/') {
-                       if(*path_p == 0)
-                               break;
-                       ++path_p;
-               }
-               if (*path_p == '/') {
-                       strncpy(tmp, path, path_p - path);
-                       tmp[path_p-path] = '\0';
-                       if (tmp[path_p - path - 1] != '/') {
-                               result = mkdir(tmp, mode);
-                               if(result == -1) {
-                                       if (!(errno == EEXIST || errno == EACCES || errno == EROFS)) {
-                                               /* Then this is a real error */
-                                               retval = -1;
-                                               break;
-                                       }
-                               }
-                       }
-                       /* pass / */
-                       path_p++;
-               } else {
-                       /* last component */
-                       result = mkdir(path, mode);
-                       if (result == -1)
-                               retval = -1;
-                       break;
-               }
-       }
-
-       free(tmp);
-       umask(old_umask);
-       return retval;
-}
-
-static struct sockaddr_un * create_sock_addr(const char *name,
-                                            size_t *sock_addr_size)
-{
-       struct sockaddr_un * addr;
-       size_t alloc_size;
-
-       alloc_size = (size_t) (((struct sockaddr_un *) 0)->sun_path) +
-               strlen(name) + 1;
-
-       addr = malloc(alloc_size);
-       if (addr < 0) {
-               ERR("allocating addr failed");
-               return NULL;
-       }
-
-       addr->sun_family = AF_UNIX;
-       strcpy(addr->sun_path, name);
-
-       *sock_addr_size = alloc_size;
-
-       return addr;
-}
-
-struct ustcomm_sock * ustcomm_init_sock(int fd, int epoll_fd,
-                                       struct cds_list_head *list)
-{
-       struct epoll_event ev;
-       struct ustcomm_sock *sock;
-
-       sock = malloc(sizeof(struct ustcomm_sock));
-       if (!sock) {
-               perror("malloc: couldn't allocate ustcomm_sock");
-               return NULL;
-       }
-
-       ev.events = EPOLLIN;
-       ev.data.ptr = sock;
-       sock->fd = fd;
-
-       if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sock->fd, &ev) == -1) {
-               perror("epoll_ctl: failed to add socket\n");
-               free(sock);
-               return NULL;
-       }
-
-       sock->epoll_fd = epoll_fd;
-       if (list) {
-               cds_list_add(&sock->list, list);
-       } else {
-               CDS_INIT_LIST_HEAD(&sock->list);
-       }
-
-       return sock;
-}
-
-void ustcomm_del_sock(struct ustcomm_sock *sock, int keep_in_epoll)
-{
-       cds_list_del(&sock->list);
-       if (!keep_in_epoll) {
-               if (epoll_ctl(sock->epoll_fd, EPOLL_CTL_DEL, sock->fd, NULL) == -1) {
-                       PERROR("epoll_ctl: failed to delete socket");
-               }
-       }
-       close(sock->fd);
-       free(sock);
-}
-
-struct ustcomm_sock * ustcomm_init_named_socket(const char *name,
-                                               int epoll_fd)
-{
-       int result;
-       int fd;
-       size_t sock_addr_size;
-       struct sockaddr_un * addr;
-       struct ustcomm_sock *sock;
-
-       fd = socket(PF_UNIX, SOCK_STREAM, 0);
-       if(fd == -1) {
-               PERROR("socket");
-               return NULL;
-       }
-
-       addr = create_sock_addr(name, &sock_addr_size);
-       if (addr == NULL) {
-               ERR("allocating addr, UST thread bailing");
-               goto close_sock;
-       }
-
-       result = access(name, F_OK);
-       if(result == 0) {
-               /* file exists */
-               result = unlink(name);
-               if(result == -1) {
-                       PERROR("unlink of socket file");
-                       goto free_addr;
-               }
-               DBG("socket already exists; overwriting");
-       }
-
-       result = bind(fd, (struct sockaddr *)addr, sock_addr_size);
-       if(result == -1) {
-               PERROR("bind");
-               goto free_addr;
-       }
-
-       result = listen(fd, 1);
-       if(result == -1) {
-               PERROR("listen");
-               goto free_addr;
-       }
-
-       sock = ustcomm_init_sock(fd, epoll_fd,
-                                NULL);
-       if (!sock) {
-               ERR("failed to create ustcomm_sock");
-               goto free_addr;
-       }
-
-       free(addr);
-
-       return sock;
-
-free_addr:
-       free(addr);
-close_sock:
-       close(fd);
-
-       return NULL;
-}
-
-void ustcomm_del_named_sock(struct ustcomm_sock *sock,
-                           int keep_socket_file)
-{
-       int result, fd;
-       struct stat st;
-       struct sockaddr dummy;
-       struct sockaddr_un *sockaddr = NULL;
-       int alloc_size;
-
-       fd = sock->fd;
-
-       if(!keep_socket_file) {
-
-               /* Get the socket name */
-               alloc_size = sizeof(dummy);
-               if (getsockname(fd, &dummy, (socklen_t *)&alloc_size) < 0) {
-                       PERROR("getsockname failed");
-                       goto del_sock;
-               }
-
-               sockaddr = zmalloc(alloc_size);
-               if (!sockaddr) {
-                       ERR("failed to allocate sockaddr");
-                       goto del_sock;
-               }
-
-               if (getsockname(fd, sockaddr, (socklen_t *)&alloc_size) < 0) {
-                       PERROR("getsockname failed");
-                       goto free_sockaddr;
-               }
-
-               /* Destroy socket */
-               result = stat(sockaddr->sun_path, &st);
-               if(result < 0) {
-                       PERROR("stat (%s)", sockaddr->sun_path);
-                       goto free_sockaddr;
-               }
-
-               /* Paranoid check before deleting. */
-               result = S_ISSOCK(st.st_mode);
-               if(!result) {
-                       ERR("The socket we are about to delete is not a socket.");
-                       goto free_sockaddr;
-               }
-
-               result = unlink(sockaddr->sun_path);
-               if(result < 0) {
-                       PERROR("unlink");
-               }
-       }
-
-free_sockaddr:
-       free(sockaddr);
-
-del_sock:
-       ustcomm_del_sock(sock, keep_socket_file);
-}
-
-int ustcomm_recv_alloc(int sock,
-                      struct ustcomm_header *header,
-                      char **data) {
-       int result;
-       struct ustcomm_header peek_header;
-       struct iovec iov[2];
-       struct msghdr msg;
-
-       /* Just to make the caller fail hard */
-       *data = NULL;
-
-       result = recv(sock, &peek_header, sizeof(peek_header),
-                     MSG_PEEK | MSG_WAITALL);
-       if (result <= 0) {
-               if(errno == ECONNRESET) {
-                       return 0;
-               } else if (errno == EINTR) {
-                       return -1;
-               } else if (result < 0) {
-                       PERROR("recv");
-                       return -1;
-               }
-               return 0;
-       }
-
-       memset(&msg, 0, sizeof(msg));
-
-       iov[0].iov_base = (char *)header;
-       iov[0].iov_len = sizeof(struct ustcomm_header);
-
-       msg.msg_iov = iov;
-       msg.msg_iovlen = 1;
-
-       if (peek_header.size) {
-               *data = zmalloc(peek_header.size);
-               if (!*data) {
-                       return -ENOMEM;
-               }
-
-               iov[1].iov_base = *data;
-               iov[1].iov_len = peek_header.size;
-
-               msg.msg_iovlen++;
-       }
-
-       result = recvmsg(sock, &msg, MSG_WAITALL);
-       if (result < 0) {
-               free(*data);
-               PERROR("recvmsg failed");
-       }
-
-       return result;
-}
-
-/* returns 1 to indicate a message was received
- * returns 0 to indicate no message was received (end of stream)
- * returns -1 to indicate an error
- */
-int ustcomm_recv_fd(int sock,
-                   struct ustcomm_header *header,
-                   char *data, int *fd)
-{
-       int result;
-       struct ustcomm_header peek_header;
-       struct iovec iov[2];
-       struct msghdr msg;
-       struct cmsghdr *cmsg;
-       char buf[CMSG_SPACE(sizeof(int))];
-
-       result = recv(sock, &peek_header, sizeof(peek_header),
-                     MSG_PEEK | MSG_WAITALL);
-       if (result <= 0) {
-               if(errno == ECONNRESET) {
-                       return 0;
-               } else if (errno == EINTR) {
-                       return -1;
-               } else if (result < 0) {
-                       PERROR("recv");
-                       return -1;
-               }
-               return 0;
-       }
-
-       memset(&msg, 0, sizeof(msg));
-
-       iov[0].iov_base = (char *)header;
-       iov[0].iov_len = sizeof(struct ustcomm_header);
-
-       msg.msg_iov = iov;
-       msg.msg_iovlen = 1;
-
-       if (peek_header.size && data) {
-               if (peek_header.size < 0 ||
-                   peek_header.size > USTCOMM_DATA_SIZE) {
-                       ERR("big peek header! %ld", peek_header.size);
-                       return 0;
-               }
-
-               iov[1].iov_base = data;
-               iov[1].iov_len = peek_header.size;
-
-               msg.msg_iovlen++;
-       }
-
-       if (fd && peek_header.fd_included) {
-               msg.msg_control = buf;
-               msg.msg_controllen = sizeof(buf);
-       }
-
-       result = recvmsg(sock, &msg, MSG_WAITALL);
-       if (result <= 0) {
-               if (result < 0) {
-                       PERROR("recvmsg failed");
-               }
-               return result;
-       }
-
-       if (fd && peek_header.fd_included) {
-               cmsg = CMSG_FIRSTHDR(&msg);
-               result = 0;
-               while (cmsg != NULL) {
-                       if (cmsg->cmsg_level == SOL_SOCKET
-                           && cmsg->cmsg_type  == SCM_RIGHTS) {
-                               *fd = *(int *) CMSG_DATA(cmsg);
-                               result = 1;
-                               break;
-                       }
-                       cmsg = CMSG_NXTHDR(&msg, cmsg);
-               }
-               if (!result) {
-                       ERR("Failed to receive file descriptor\n");
-               }
-       }
-
-       return 1;
-}
-
-int ustcomm_recv(int sock,
-                struct ustcomm_header *header,
-                char *data)
-{
-       return ustcomm_recv_fd(sock, header, data, NULL);
-}
-
-
-int ustcomm_send_fd(int sock,
-                   const struct ustcomm_header *header,
-                   const char *data,
-                   int *fd)
-{
-       struct iovec iov[2];
-       struct msghdr msg;
-       int result;
-       struct cmsghdr *cmsg;
-       char buf[CMSG_SPACE(sizeof(int))];
-
-       memset(&msg, 0, sizeof(msg));
-
-       iov[0].iov_base = (char *)header;
-       iov[0].iov_len = sizeof(struct ustcomm_header);
-
-       msg.msg_iov = iov;
-       msg.msg_iovlen = 1;
-
-       if (header->size && data) {
-               iov[1].iov_base = (char *)data;
-               iov[1].iov_len = header->size;
-
-               msg.msg_iovlen++;
-
-       }
-
-       if (fd && header->fd_included) {
-               msg.msg_control = buf;
-               msg.msg_controllen = sizeof(buf);
-               cmsg = CMSG_FIRSTHDR(&msg);
-               cmsg->cmsg_level = SOL_SOCKET;
-               cmsg->cmsg_type = SCM_RIGHTS;
-               cmsg->cmsg_len = CMSG_LEN(sizeof(int));
-               *(int *) CMSG_DATA(cmsg) = *fd;
-               msg.msg_controllen = cmsg->cmsg_len;
-       }
-
-       result = sendmsg(sock, &msg, MSG_NOSIGNAL);
-       if (result < 0 && errno != EPIPE) {
-               PERROR("sendmsg failed");
-       }
-       return result;
-}
-
-int ustcomm_send(int sock,
-                const struct ustcomm_header *header,
-                const char *data)
-{
-       return ustcomm_send_fd(sock, header, data, NULL);
-}
-
-int ustcomm_req(int sock,
-               const struct ustcomm_header *req_header,
-               const char *req_data,
-               struct ustcomm_header *res_header,
-               char *res_data)
-{
-       int result;
-
-       result = ustcomm_send(sock, req_header, req_data);
-       if ( result <= 0) {
-               return result;
-       }
-
-       return ustcomm_recv(sock, res_header, res_data);
-}
-
-/* Return value:
- *  0: success
- * -1: error
- */
-
-int ustcomm_connect_path(const char *name, int *connection_fd)
-{
-       int result, fd;
-       size_t sock_addr_size;
-       struct sockaddr_un *addr;
-
-       fd = socket(PF_UNIX, SOCK_STREAM, 0);
-       if(fd == -1) {
-               PERROR("socket");
-               return -1;
-       }
-
-       addr = create_sock_addr(name, &sock_addr_size);
-       if (addr == NULL) {
-               ERR("allocating addr failed");
-               goto close_sock;
-       }
-
-       result = connect(fd, (struct sockaddr *)addr, sock_addr_size);
-       if(result == -1) {
-               PERROR("connect (path=%s)", name);
-               goto free_sock_addr;
-       }
-
-       *connection_fd = fd;
-
-       free(addr);
-
-       return 0;
-
-free_sock_addr:
-       free(addr);
-close_sock:
-       close(fd);
-
-       return -1;
-}
-
-/* Returns the current users socket directory, must be freed */
-char *ustcomm_user_sock_dir(void)
-{
-       int result;
-       char *sock_dir = NULL;
-
-       result = asprintf(&sock_dir, "%s%s", USER_SOCK_DIR,
-                         cuserid(NULL));
-       if (result < 0) {
-               ERR("string overflow allocating directory name");
-               return NULL;
-       }
-
-       return sock_dir;
-}
-
-static int time_and_pid_from_socket_name(char *sock_name, unsigned long *time,
-                                        pid_t *pid)
-{
-       char *saveptr, *pid_m_time_str;
-       char *sock_basename = strdup(basename(sock_name));
-
-       if (!sock_basename) {
-               return -1;
-       }
-
-       /* This is the pid */
-       pid_m_time_str = strtok_r(sock_basename, ".", &saveptr);
-       if (!pid_m_time_str) {
-               goto out_err;
-       }
-
-       errno = 0;
-       *pid = (pid_t)strtoul(pid_m_time_str, NULL, 10);
-       if (errno) {
-               goto out_err;
-       }
-
-       /* This should be the time-stamp */
-       pid_m_time_str = strtok_r(NULL, ".", &saveptr);
-       if (!pid_m_time_str) {
-               goto out_err;
-       }
-
-       errno = 0;
-       *time = strtoul(pid_m_time_str, NULL, 10);
-       if (errno) {
-               goto out_err;
-       }
-
-       return 0;
-
-out_err:
-       free(sock_basename);
-       return -1;
-}
-
-time_t ustcomm_pid_st_mtime(pid_t pid)
-{
-       struct stat proc_stat;
-       char proc_name[PATH_MAX];
-
-       if (snprintf(proc_name, PATH_MAX - 1, "/proc/%ld", (long) pid) < 0) {
-               return 0;
-       }
-
-       if (stat(proc_name, &proc_stat)) {
-               return 0;
-       }
-
-       return proc_stat.st_mtime;
-}
-
-int ustcomm_is_socket_live(char *sock_name, pid_t *read_pid)
-{
-       time_t time_from_pid;
-       unsigned long time_from_sock;
-       pid_t pid;
-
-       if (time_and_pid_from_socket_name(sock_name, &time_from_sock, &pid)) {
-               return 0;
-       }
-
-       if (read_pid) {
-               *read_pid = pid;
-       }
-
-       time_from_pid = ustcomm_pid_st_mtime(pid);
-       if (!time_from_pid) {
-               return 0;
-       }
-
-       if ((unsigned long) time_from_pid == time_from_sock) {
-               return 1;
-       }
-
-       return 0;
-}
-
-#define MAX_SOCK_PATH_BASE_LEN 100
-
-static int ustcomm_get_sock_name(char *dir_name, pid_t pid, char *sock_name)
-{
-       struct dirent *dirent;
-       char sock_path_base[MAX_SOCK_PATH_BASE_LEN];
-       int len;
-       DIR *dir = opendir(dir_name);
-
-       snprintf(sock_path_base, MAX_SOCK_PATH_BASE_LEN - 1,
-                "%ld.", (long) pid);
-       len = strlen(sock_path_base);
-
-       while ((dirent = readdir(dir))) {
-               if (!strcmp(dirent->d_name, ".") ||
-                   !strcmp(dirent->d_name, "..") ||
-                   !strcmp(dirent->d_name, "ust-consumer") ||
-                   dirent->d_type == DT_DIR ||
-                   strncmp(dirent->d_name, sock_path_base, len)) {
-                       continue;
-               }
-
-               if (ustcomm_is_socket_live(dirent->d_name, NULL)) {
-                       if (snprintf(sock_name, PATH_MAX - 1, "%s/%s",
-                                    dir_name, dirent->d_name) < 0) {
-                               PERROR("path longer than PATH_MAX?");
-                               goto out_err;
-                       }
-                       closedir(dir);
-                       return 0;
-               }
-       }
-
-out_err:
-       closedir(dir);
-       return -1;
-}
-
-/* Open a connection to a traceable app.
- *
- * Return value:
- *  0: success
- * -1: error
- */
-
-static int connect_app_non_root(pid_t pid, int *app_fd)
-{
-       int result;
-       int retval = 0;
-       char *dir_name;
-       char sock_name[PATH_MAX];
-
-       dir_name = ustcomm_user_sock_dir();
-       if (!dir_name)
-               return -ENOMEM;
-
-       if (ustcomm_get_sock_name(dir_name, pid, sock_name)) {
-               retval = -ENOENT;
-               goto free_dir_name;
-       }
-
-       result = ustcomm_connect_path(sock_name, app_fd);
-       if (result < 0) {
-               ERR("failed to connect to app");
-               retval = -1;
-               goto free_dir_name;
-       }
-
-free_dir_name:
-       free(dir_name);
-
-       return retval;
-}
-
-
-
-static int connect_app_root(pid_t pid, int *app_fd)
-{
-       DIR *tmp_dir;
-       struct dirent *dirent;
-       char dir_name[PATH_MAX], sock_name[PATH_MAX];
-       int result = -1;
-
-       tmp_dir = opendir(USER_TMP_DIR);
-       if (!tmp_dir) {
-               return -1;
-       }
-
-       while ((dirent = readdir(tmp_dir))) {
-               if (!strncmp(dirent->d_name, USER_SOCK_DIR_BASE,
-                            strlen(USER_SOCK_DIR_BASE))) {
-
-                       if (snprintf(dir_name, PATH_MAX - 1, "%s/%s", USER_TMP_DIR,
-                                    dirent->d_name) < 0) {
-                               continue;
-                       }
-
-                       if (ustcomm_get_sock_name(dir_name, pid, sock_name)) {
-                               continue;
-                       }
-
-                       result = ustcomm_connect_path(sock_name, app_fd);
-
-                       if (result == 0) {
-                               goto close_tmp_dir;
-                       }
-               }
-       }
-
-close_tmp_dir:
-       closedir(tmp_dir);
-
-       return result;
-}
-
-int ustcomm_connect_app(pid_t pid, int *app_fd)
-{
-       *app_fd = 0;
-
-       if (geteuid()) {
-               return connect_app_non_root(pid, app_fd);
-       } else {
-               return connect_app_root(pid, app_fd);
-       }
-
-}
-
-int ensure_dir_exists(const char *dir, mode_t mode)
-{
-       struct stat st;
-       int result;
-
-       if (!strcmp(dir, ""))
-               return -1;
-
-       result = stat(dir, &st);
-       if (result < 0 && errno != ENOENT) {
-               return -1;
-       } else if (result < 0) {
-               /* ENOENT */
-               int result;
-
-               result = mkdir_p(dir, mode);
-               if(result != 0) {
-                       ERR("executing in recursive creation of directory %s", dir);
-                       return -1;
-               }
-       } else {
-               if (st.st_mode != mode) {
-                       result = chmod(dir, mode);
-                       if (result < 0) {
-                               ERR("couldn't set directory mode on %s", dir);
-                               return -1;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-char * ustcomm_print_data(char *data_field, int field_size,
-                         int *offset, const char *format, ...)
-{
-       va_list args;
-       int count, limit;
-       char *ptr = USTCOMM_POISON_PTR;
-
-       limit = field_size - *offset;
-       va_start(args, format);
-       count = vsnprintf(&data_field[*offset], limit, format, args);
-       va_end(args);
-
-       if (count < limit && count > -1) {
-               ptr = NULL + *offset;
-               *offset = *offset + count + 1;
-       }
-
-       return ptr;
-}
-
-char * ustcomm_restore_ptr(char *ptr, char *data_field, int data_field_size)
-{
-       if ((unsigned long)ptr > data_field_size ||
-           ptr == USTCOMM_POISON_PTR) {
-               return NULL;
-       }
-
-       return data_field + (long)ptr;
-}
-
-int ustcomm_pack_single_field(struct ustcomm_header *header,
-                             struct ustcomm_single_field *single_field,
-                             const char *string)
-{
-       int offset = 0;
-
-       single_field->field = ustcomm_print_data(single_field->data,
-                                                sizeof(single_field->data),
-                                                &offset,
-                                                string);
-
-       if (single_field->field == USTCOMM_POISON_PTR) {
-               return -ENOMEM;
-       }
-
-       header->size = COMPUTE_MSG_SIZE(single_field, offset);
-
-       return 0;
-}
-
-int ustcomm_unpack_single_field(struct ustcomm_single_field *single_field)
-{
-       single_field->field = ustcomm_restore_ptr(single_field->field,
-                                                 single_field->data,
-                                                 sizeof(single_field->data));
-       if (!single_field->field) {
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-int ustcomm_pack_channel_info(struct ustcomm_header *header,
-                             struct ustcomm_channel_info *ch_inf,
-                             const char *trace,
-                             const char *channel)
-{
-       int offset = 0;
-
-       ch_inf->trace = ustcomm_print_data(ch_inf->data,
-                                          sizeof(ch_inf->data),
-                                          &offset,
-                                          trace);
-
-       if (ch_inf->trace == USTCOMM_POISON_PTR) {
-               return -ENOMEM;
-       }
-
-       ch_inf->channel = ustcomm_print_data(ch_inf->data,
-                                            sizeof(ch_inf->data),
-                                            &offset,
-                                            channel);
-
-       if (ch_inf->channel == USTCOMM_POISON_PTR) {
-               return -ENOMEM;
-       }
-
-       header->size = COMPUTE_MSG_SIZE(ch_inf, offset);
-
-       return 0;
-}
-
-
-int ustcomm_unpack_channel_info(struct ustcomm_channel_info *ch_inf)
-{
-       ch_inf->trace = ustcomm_restore_ptr(ch_inf->trace,
-                                           ch_inf->data,
-                                           sizeof(ch_inf->data));
-       if (!ch_inf->trace) {
-               return -EINVAL;
-       }
-
-       ch_inf->channel = ustcomm_restore_ptr(ch_inf->channel,
-                                             ch_inf->data,
-                                             sizeof(ch_inf->data));
-       if (!ch_inf->channel) {
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-int ustcomm_pack_buffer_info(struct ustcomm_header *header,
-                            struct ustcomm_buffer_info *buf_inf,
-                            const char *trace,
-                            const char *channel,
-                            int channel_cpu)
-{
-       int offset = 0;
-
-       buf_inf->trace = ustcomm_print_data(buf_inf->data,
-                                           sizeof(buf_inf->data),
-                                           &offset,
-                                           trace);
-
-       if (buf_inf->trace == USTCOMM_POISON_PTR) {
-               return -ENOMEM;
-       }
-
-       buf_inf->channel = ustcomm_print_data(buf_inf->data,
-                                             sizeof(buf_inf->data),
-                                             &offset,
-                                             channel);
-
-       if (buf_inf->channel == USTCOMM_POISON_PTR) {
-               return -ENOMEM;
-       }
-
-       buf_inf->ch_cpu = channel_cpu;
-
-       header->size = COMPUTE_MSG_SIZE(buf_inf, offset);
-
-       return 0;
-}
-
-
-int ustcomm_unpack_buffer_info(struct ustcomm_buffer_info *buf_inf)
-{
-       buf_inf->trace = ustcomm_restore_ptr(buf_inf->trace,
-                                            buf_inf->data,
-                                            sizeof(buf_inf->data));
-       if (!buf_inf->trace) {
-               return -EINVAL;
-       }
-
-       buf_inf->channel = ustcomm_restore_ptr(buf_inf->channel,
-                                              buf_inf->data,
-                                              sizeof(buf_inf->data));
-       if (!buf_inf->channel) {
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-int ustcomm_pack_ust_marker_info(struct ustcomm_header *header,
-                            struct ustcomm_ust_marker_info *ust_marker_inf,
-                            const char *trace,
-                            const char *channel,
-                            const char *ust_marker)
-{
-       int offset = 0;
-
-       ust_marker_inf->trace = ustcomm_print_data(ust_marker_inf->data,
-                                              sizeof(ust_marker_inf->data),
-                                              &offset,
-                                              trace);
-
-       if (ust_marker_inf->trace == USTCOMM_POISON_PTR) {
-               return -ENOMEM;
-       }
-
-
-       ust_marker_inf->channel = ustcomm_print_data(ust_marker_inf->data,
-                                                sizeof(ust_marker_inf->data),
-                                                &offset,
-                                                channel);
-
-       if (ust_marker_inf->channel == USTCOMM_POISON_PTR) {
-               return -ENOMEM;
-       }
-
-
-       ust_marker_inf->ust_marker = ustcomm_print_data(ust_marker_inf->data,
-                                                sizeof(ust_marker_inf->data),
-                                                &offset,
-                                                ust_marker);
-
-       if (ust_marker_inf->ust_marker == USTCOMM_POISON_PTR) {
-               return -ENOMEM;
-       }
-
-       header->size = COMPUTE_MSG_SIZE(ust_marker_inf, offset);
-
-       return 0;
-}
-
-int ustcomm_unpack_ust_marker_info(struct ustcomm_ust_marker_info *ust_marker_inf)
-{
-       ust_marker_inf->trace = ustcomm_restore_ptr(ust_marker_inf->trace,
-                                               ust_marker_inf->data,
-                                               sizeof(ust_marker_inf->data));
-       if (!ust_marker_inf->trace) {
-               return -EINVAL;
-       }
-
-       ust_marker_inf->channel = ustcomm_restore_ptr(ust_marker_inf->channel,
-                                                 ust_marker_inf->data,
-                                                 sizeof(ust_marker_inf->data));
-       if (!ust_marker_inf->channel) {
-               return -EINVAL;
-       }
-
-       ust_marker_inf->ust_marker = ustcomm_restore_ptr(ust_marker_inf->ust_marker,
-                                                ust_marker_inf->data,
-                                                sizeof(ust_marker_inf->data));
-       if (!ust_marker_inf->ust_marker) {
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
diff --git a/libustcomm/ustcomm.h b/libustcomm/ustcomm.h
deleted file mode 100644 (file)
index 4706b72..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-/* Copyright (C) 2009  Pierre-Marc Fournier
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#ifndef USTCOMM_H
-#define USTCOMM_H
-
-#include <sys/types.h>
-#include <sys/un.h>
-#include <urcu/list.h>
-
-#include <ust/kcompat/kcompat.h>
-
-#define SOCK_DIR "/tmp/ust-app-socks"
-#define USER_TMP_DIR "/tmp"
-#define USER_SOCK_DIR_BASE "ust-socks-"
-#define USER_SOCK_DIR USER_TMP_DIR "/" USER_SOCK_DIR_BASE
-
-struct ustcomm_sock {
-       struct cds_list_head list;
-       int fd;
-       int epoll_fd;
-};
-
-struct ustcomm_header {
-       int command;
-       long size;
-       int result;
-       int fd_included;
-};
-
-#define USTCOMM_BUFFER_SIZE ((1 << 12) - sizeof(struct ustcomm_header))
-
-/* Specify a sata size that leaves margin at the end of a buffer
- * in order to make sure that we never have more data than
- * will fit in the buffer AND that the last chars (due to a
- * pre-receive memset) will always be 0, terminating any string
- */
-#define USTCOMM_DATA_SIZE (USTCOMM_BUFFER_SIZE - 20 * sizeof(void *))
-
-enum tracectl_commands {
-       ALLOC_TRACE,
-       CONSUME_BUFFER,
-       CREATE_TRACE,
-       DESTROY_TRACE,
-       DISABLE_MARKER,
-       ENABLE_MARKER,
-       EXIT,
-       FORCE_SUBBUF_SWITCH,
-       GET_BUF_SHMID_PIPE_FD,
-       GET_PIDUNIQUE,
-       GET_SOCK_PATH,
-       GET_SUBBUFFER,
-       GET_SUBBUF_NUM_SIZE,
-       LIST_MARKERS,
-       LIST_TRACE_EVENTS,
-       LOAD_PROBE_LIB,
-       NOTIFY_BUF_MAPPED,
-       PRINT_MARKERS,
-       PRINT_TRACE_EVENTS,
-       PUT_SUBBUFFER,
-       SETUP_TRACE,
-       SET_SOCK_PATH,
-       SET_SUBBUF_NUM,
-       SET_SUBBUF_SIZE,
-       START,
-       START_TRACE,
-       STOP_TRACE,
-};
-
-struct ustcomm_single_field {
-       char *field;
-       char data[USTCOMM_DATA_SIZE];
-};
-
-struct ustcomm_channel_info {
-       char *trace;
-       char *channel;
-       unsigned int subbuf_size;
-       unsigned int subbuf_num;
-       char data[USTCOMM_DATA_SIZE];
-};
-
-struct ustcomm_buffer_info {
-       char *trace;
-       char *channel;
-       int ch_cpu;
-       pid_t pid;
-       int buf_shmid;
-       int buf_struct_shmid;
-       long consumed_old;
-       char data[USTCOMM_DATA_SIZE];
-};
-
-struct ustcomm_ust_marker_info {
-       char *trace;
-       char *channel;
-       char *ust_marker;
-       char data[USTCOMM_DATA_SIZE];
-};
-
-struct ustcomm_pidunique {
-       s64 pidunique;
-};
-
-struct ustcomm_notify_buf_mapped {
-       char data[USTCOMM_DATA_SIZE];
-};
-
-/* Ensure directory existence, usefull for unix sockets */
-extern int ensure_dir_exists(const char *dir, mode_t mode);
-
-/* Create and delete sockets */
-extern struct ustcomm_sock * ustcomm_init_sock(int fd, int epoll_fd,
-                                              struct cds_list_head *list);
-extern void ustcomm_del_sock(struct ustcomm_sock *sock, int keep_in_epoll);
-
-/* Create and delete named sockets */
-extern struct ustcomm_sock * ustcomm_init_named_socket(const char *name,
-                                                      int epoll_fd);
-extern void ustcomm_del_named_sock(struct ustcomm_sock *sock,
-                                  int keep_socket_file);
-
-/* Send and receive functions for file descriptors */
-extern int ustcomm_send_fd(int sock, const struct ustcomm_header *header,
-                          const char *data, int *fd);
-extern int ustcomm_recv_fd(int sock, struct ustcomm_header *header,
-                          char *data, int *fd);
-
-/* Normal send and receive functions */
-extern int ustcomm_send(int sock, const struct ustcomm_header *header,
-                       const char *data);
-extern int ustcomm_recv(int sock, struct ustcomm_header *header,
-                       char *data);
-
-/* Receive and allocate data, not to be used inside libust */
-extern int ustcomm_recv_alloc(int sock,
-                             struct ustcomm_header *header,
-                             char **data);
-
-/* Request function, send and receive */
-extern int ustcomm_req(int sock,
-                      const struct ustcomm_header *req_header,
-                      const char *req_data,
-                      struct ustcomm_header *res_header,
-                      char *res_data);
-
-extern int ustcomm_request_consumer(pid_t pid, const char *channel);
-
-/* Returns the current users socket directory, must be freed */
-extern char *ustcomm_user_sock_dir(void);
-
-/* Get the st_m_time from proc*/
-extern time_t ustcomm_pid_st_mtime(pid_t pid);
-
-/* Check that a socket is live */
-extern int ustcomm_is_socket_live(char *sock_name, pid_t *read_pid);
-
-extern int ustcomm_connect_app(pid_t pid, int *app_fd);
-extern int ustcomm_connect_path(const char *path, int *connection_fd);
-
-extern int nth_token_is(const char *str, const char *token, int tok_no);
-
-extern char *nth_token(const char *str, int tok_no);
-
-/* String serialising functions, printf straight into a buffer */
-#define USTCOMM_POISON_PTR (void *)0x19831018
-
-extern char * ustcomm_print_data(char *data_field, int field_size,
-                                int *offset, const char *format, ...);
-extern char * ustcomm_restore_ptr(char *ptr, char *data_field,
-                                 int data_field_size);
-
-#define COMPUTE_MSG_SIZE(struct_ptr, offset)                           \
-       (size_t) (long)(struct_ptr)->data - (long)(struct_ptr) + (offset)
-
-/* Packing and unpacking functions, making life easier */
-extern int ustcomm_pack_single_field(struct ustcomm_header *header,
-                                  struct ustcomm_single_field *sf,
-                                  const char *trace);
-
-extern int ustcomm_unpack_single_field(struct ustcomm_single_field *sf);
-
-extern int ustcomm_pack_channel_info(struct ustcomm_header *header,
-                                    struct ustcomm_channel_info *ch_inf,
-                                    const char *trace,
-                                    const char *channel);
-
-extern int ustcomm_unpack_channel_info(struct ustcomm_channel_info *ch_inf);
-
-extern int ustcomm_pack_buffer_info(struct ustcomm_header *header,
-                                   struct ustcomm_buffer_info *buf_inf,
-                                   const char *trace,
-                                   const char *channel,
-                                   int channel_cpu);
-
-extern int ustcomm_unpack_buffer_info(struct ustcomm_buffer_info *buf_inf);
-
-extern int ustcomm_pack_ust_marker_info(struct ustcomm_header *header,
-                                   struct ustcomm_ust_marker_info *ust_marker_inf,
-                                   const char *trace,
-                                   const char *channel,
-                                   const char *ust_marker);
-
-extern int ustcomm_unpack_ust_marker_info(struct ustcomm_ust_marker_info *ust_marker_inf);
-
-#endif /* USTCOMM_H */
diff --git a/libustconsumer/Makefile.am b/libustconsumer/Makefile.am
deleted file mode 100644 (file)
index 1f87479..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-AM_CPPFLAGS = -I$(top_srcdir)/libust -I$(top_srcdir)/libustcomm \
-       -I$(top_srcdir)/include
-AM_CFLAGS = -fno-strict-aliasing
-
-lib_LTLIBRARIES = libustconsumer.la
-
-libustconsumer_la_SOURCES = libustconsumer.c lowlevel.c lowlevel.h
-
-libustconsumer_la_LDFLAGS = -no-undefined -version-info 0:0:0
-
-libustconsumer_la_LIBADD = \
-       -lpthread \
-       $(top_builddir)/snprintf/libustsnprintf.la \
-       $(top_builddir)/libustcomm/libustcomm.la
-
-libustconsumer_la_CFLAGS = -fno-strict-aliasing
diff --git a/libustconsumer/libustconsumer.c b/libustconsumer/libustconsumer.c
deleted file mode 100644 (file)
index c6dd20c..0000000
+++ /dev/null
@@ -1,923 +0,0 @@
-/* Copyright (C) 2009  Pierre-Marc Fournier
- *               2010  Alexis Halle
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#define _GNU_SOURCE
-
-#include <sys/epoll.h>
-#include <sys/shm.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <signal.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include <ust/ustconsumer.h>
-#include "lowlevel.h"
-#include "usterr_signal_safe.h"
-#include "ustcomm.h"
-
-#define GET_SUBBUF_OK 1
-#define GET_SUBBUF_DONE 0
-#define GET_SUBBUF_DIED 2
-
-#define PUT_SUBBUF_OK 1
-#define PUT_SUBBUF_DIED 0
-#define PUT_SUBBUF_PUSHED 2
-#define PUT_SUBBUF_DONE 3
-
-#define UNIX_PATH_MAX 108
-
-static int get_subbuffer(struct buffer_info *buf)
-{
-       struct ustcomm_header _send_hdr, *send_hdr;
-       struct ustcomm_header _recv_hdr, *recv_hdr;
-       struct ustcomm_buffer_info _send_msg, _recv_msg;
-       struct ustcomm_buffer_info *send_msg, *recv_msg;
-       int result;
-
-       send_hdr = &_send_hdr;
-       recv_hdr = &_recv_hdr;
-       send_msg = &_send_msg;
-       recv_msg = &_recv_msg;
-
-       result = ustcomm_pack_buffer_info(send_hdr, send_msg, buf->trace,
-                                         buf->channel, buf->channel_cpu);
-       if (result < 0) {
-               return result;
-       }
-
-       send_hdr->command = GET_SUBBUFFER;
-
-       result = ustcomm_req(buf->app_sock, send_hdr, (char *)send_msg,
-                            recv_hdr, (char *)recv_msg);
-       if ((result < 0 && (errno == ECONNRESET || errno == EPIPE)) ||
-           result == 0) {
-               DBG("app died while being traced");
-               return GET_SUBBUF_DIED;
-       } else if (result < 0) {
-               ERR("get_subbuffer: ustcomm_req failed");
-               return result;
-       }
-
-       if (!recv_hdr->result) {
-               DBG("got subbuffer %s", buf->name);
-               buf->consumed_old = recv_msg->consumed_old;
-               return GET_SUBBUF_OK;
-       } else if (recv_hdr->result == -ENODATA) {
-               DBG("For buffer %s, the trace was not found. This likely means"
-                   " it was destroyed by the user.", buf->name);
-               return GET_SUBBUF_DIED;
-       }
-
-       DBG("error getting subbuffer %s", buf->name);
-       return recv_hdr->result;
-}
-
-static int put_subbuffer(struct buffer_info *buf)
-{
-       struct ustcomm_header _send_hdr, *send_hdr;
-       struct ustcomm_header _recv_hdr, *recv_hdr;
-       struct ustcomm_buffer_info _send_msg, *send_msg;
-       int result;
-
-       send_hdr = &_send_hdr;
-       recv_hdr = &_recv_hdr;
-       send_msg = &_send_msg;
-
-       result = ustcomm_pack_buffer_info(send_hdr, send_msg, buf->trace,
-                                         buf->channel, buf->channel_cpu);
-       if (result < 0) {
-               return result;
-       }
-
-       send_hdr->command = PUT_SUBBUFFER;
-       send_msg->consumed_old = buf->consumed_old;
-
-       result = ustcomm_req(buf->app_sock, send_hdr, (char *)send_msg,
-                            recv_hdr, NULL);
-       if ((result < 0 && (errno == ECONNRESET || errno == EPIPE)) ||
-           result == 0) {
-               DBG("app died while being traced");
-               return PUT_SUBBUF_DIED;
-       } else if (result < 0) {
-               ERR("put_subbuffer: ustcomm_req failed");
-               return result;
-       }
-
-       if (!recv_hdr->result) {
-               DBG("put subbuffer %s", buf->name);
-               return PUT_SUBBUF_OK;
-       } else if (recv_hdr->result == -ENODATA) {
-               DBG("For buffer %s, the trace was not found. This likely means"
-                   " it was destroyed by the user.", buf->name);
-               return PUT_SUBBUF_DIED;
-       }
-
-       DBG("error getting subbuffer %s", buf->name);
-       return recv_hdr->result;
-}
-
-void decrement_active_buffers(void *arg)
-{
-       struct ustconsumer_instance *instance = arg;
-       pthread_mutex_lock(&instance->mutex);
-       instance->active_buffers--;
-       pthread_mutex_unlock(&instance->mutex);
-}
-
-static int get_pidunique(int sock, int64_t *pidunique)
-{
-       struct ustcomm_header _send_hdr, *send_hdr;
-       struct ustcomm_header _recv_hdr, *recv_hdr;
-       struct ustcomm_pidunique _recv_msg, *recv_msg;
-       int result;
-
-       send_hdr = &_send_hdr;
-       recv_hdr = &_recv_hdr;
-       recv_msg = &_recv_msg;
-
-       memset(send_hdr, 0, sizeof(*send_hdr));
-
-       send_hdr->command = GET_PIDUNIQUE;
-       result = ustcomm_req(sock, send_hdr, NULL, recv_hdr, (char *)recv_msg);
-       if (result < 1) {
-               return -ENOTCONN;
-       }
-       if (recv_hdr->result < 0) {
-               ERR("App responded with error: %s", strerror(recv_hdr->result));
-               return recv_hdr->result;
-       }
-
-       *pidunique = recv_msg->pidunique;
-
-       return 0;
-}
-
-static int get_buf_shmid_pipe_fd(int sock, struct buffer_info *buf,
-                                int *buf_shmid, int *buf_struct_shmid,
-                                int *buf_pipe_fd)
-{
-       struct ustcomm_header _send_hdr, *send_hdr;
-       struct ustcomm_header _recv_hdr, *recv_hdr;
-       struct ustcomm_buffer_info _send_msg, *send_msg;
-       struct ustcomm_buffer_info _recv_msg, *recv_msg;
-       int result, recv_pipe_fd;
-
-       send_hdr = &_send_hdr;
-       recv_hdr = &_recv_hdr;
-       send_msg = &_send_msg;
-       recv_msg = &_recv_msg;
-
-       result = ustcomm_pack_buffer_info(send_hdr, send_msg, buf->trace,
-                                         buf->channel, buf->channel_cpu);
-       if (result < 0) {
-               ERR("Failed to pack buffer info");
-               return result;
-       }
-
-       send_hdr->command = GET_BUF_SHMID_PIPE_FD;
-
-       result = ustcomm_send(sock, send_hdr, (char *)send_msg);
-       if (result < 1) {
-               ERR("Failed to send request");
-               return -ENOTCONN;
-       }
-       result = ustcomm_recv_fd(sock, recv_hdr, (char *)recv_msg, &recv_pipe_fd);
-       if (result < 1) {
-               ERR("Failed to receive message and fd");
-               return -ENOTCONN;
-       }
-       if (recv_hdr->result < 0) {
-               ERR("App responded with error %s", strerror(recv_hdr->result));
-               return recv_hdr->result;
-       }
-
-       *buf_shmid = recv_msg->buf_shmid;
-       *buf_struct_shmid = recv_msg->buf_struct_shmid;
-       *buf_pipe_fd = recv_pipe_fd;
-
-       return 0;
-}
-
-static int get_subbuf_num_size(int sock, struct buffer_info *buf,
-                              int *subbuf_num, int *subbuf_size)
-{
-       struct ustcomm_header _send_hdr, *send_hdr;
-       struct ustcomm_header _recv_hdr, *recv_hdr;
-       struct ustcomm_channel_info _send_msg, *send_msg;
-       struct ustcomm_channel_info _recv_msg, *recv_msg;
-       int result;
-
-       send_hdr = &_send_hdr;
-       recv_hdr = &_recv_hdr;
-       send_msg = &_send_msg;
-       recv_msg = &_recv_msg;
-
-       result = ustcomm_pack_channel_info(send_hdr, send_msg, buf->trace,
-                                          buf->channel);
-       if (result < 0) {
-               return result;
-       }
-
-       send_hdr->command = GET_SUBBUF_NUM_SIZE;
-
-       result = ustcomm_req(sock, send_hdr, (char *)send_msg,
-                            recv_hdr, (char *)recv_msg);
-       if (result < 1) {
-               return -ENOTCONN;
-       }
-
-       *subbuf_num = recv_msg->subbuf_num;
-       *subbuf_size = recv_msg->subbuf_size;
-
-       return recv_hdr->result;
-}
-
-
-static int notify_buffer_mapped(int sock, struct buffer_info *buf)
-{
-       struct ustcomm_header _send_hdr, *send_hdr;
-       struct ustcomm_header _recv_hdr, *recv_hdr;
-       struct ustcomm_buffer_info _send_msg, *send_msg;
-       int result;
-
-       send_hdr = &_send_hdr;
-       recv_hdr = &_recv_hdr;
-       send_msg = &_send_msg;
-
-       result = ustcomm_pack_buffer_info(send_hdr, send_msg, buf->trace,
-                                         buf->channel, buf->channel_cpu);
-       if (result < 0) {
-               return result;
-       }
-
-       send_hdr->command = NOTIFY_BUF_MAPPED;
-
-       result = ustcomm_req(sock, send_hdr, (char *)send_msg,
-                            recv_hdr, NULL);
-       if (result < 1) {
-               return -ENOTCONN;
-       }
-
-       return recv_hdr->result;
-}
-
-
-struct buffer_info *connect_buffer(struct ustconsumer_instance *instance, pid_t pid,
-                                  const char *trace, const char *channel,
-                                  int channel_cpu)
-{
-       struct buffer_info *buf;
-       int result;
-       struct shmid_ds shmds;
-
-       buf = (struct buffer_info *) zmalloc(sizeof(struct buffer_info));
-       if(buf == NULL) {
-               ERR("add_buffer: insufficient memory");
-               return NULL;
-       }
-
-       buf->trace = strdup(trace);
-       if (!buf->trace) {
-               goto free_buf;
-       }
-
-       buf->channel = strdup(channel);
-       if (!buf->channel) {
-               goto free_buf_trace;
-       }
-
-       result = asprintf(&buf->name, "%s_%d", channel, channel_cpu);
-       if (result < 0 || buf->name == NULL) {
-               goto free_buf_channel;
-       }
-
-       buf->channel_cpu = channel_cpu;
-       buf->pid = pid;
-
-       result = ustcomm_connect_app(buf->pid, &buf->app_sock);
-       if(result) {
-               WARN("unable to connect to process, it probably died before we were able to connect");
-               goto free_buf_name;
-       }
-
-       /* get pidunique */
-       result = get_pidunique(buf->app_sock, &buf->pidunique);
-       if (result < 0) {
-               ERR("Failed to get pidunique");
-               goto close_app_sock;
-       }
-
-       /* get shmid and pipe fd */
-       result = get_buf_shmid_pipe_fd(buf->app_sock, buf, &buf->shmid,
-                                      &buf->bufstruct_shmid, &buf->pipe_fd);
-       if (result < 0) {
-               ERR("Failed to get buf_shmid and pipe_fd");
-               goto close_app_sock;
-       } else {
-               struct stat temp;
-               fstat(buf->pipe_fd, &temp);
-               if (!S_ISFIFO(temp.st_mode)) {
-                       ERR("Didn't receive a fifo from the app");
-                       goto close_app_sock;
-               }
-       }
-
-
-       /* get number of subbufs and subbuf size */
-       result = get_subbuf_num_size(buf->app_sock, buf, &buf->n_subbufs,
-                                    &buf->subbuf_size);
-       if (result < 0) {
-               ERR("Failed to get subbuf number and size");
-               goto close_fifo;
-       }
-
-       /* Set subbuffer's information */
-       buf->subbuf_size_order = get_count_order(buf->subbuf_size);
-       buf->alloc_size = buf->subbuf_size * buf->n_subbufs;
-
-       /* attach memory */
-       buf->mem = shmat(buf->shmid, NULL, 0);
-       if(buf->mem == (void *) 0) {
-               PERROR("shmat");
-               goto close_fifo;
-       }
-       DBG("successfully attached buffer memory");
-
-       buf->bufstruct_mem = shmat(buf->bufstruct_shmid, NULL, 0);
-       if(buf->bufstruct_mem == (void *) 0) {
-               PERROR("shmat");
-               goto shmdt_mem;
-       }
-       DBG("successfully attached buffer bufstruct memory");
-
-       /* obtain info on the memory segment */
-       result = shmctl(buf->shmid, IPC_STAT, &shmds);
-       if(result == -1) {
-               PERROR("shmctl");
-               goto shmdt_bufstruct_mem;
-       }
-       buf->memlen = shmds.shm_segsz;
-
-       /* Notify the application that we have mapped the buffer */
-       result = notify_buffer_mapped(buf->app_sock, buf);
-       if (result < 0) {
-               goto shmdt_bufstruct_mem;
-       }
-
-       if(instance->callbacks->on_open_buffer)
-               instance->callbacks->on_open_buffer(instance->callbacks, buf);
-
-       pthread_mutex_lock(&instance->mutex);
-       instance->active_buffers++;
-       pthread_mutex_unlock(&instance->mutex);
-
-       return buf;
-
-shmdt_bufstruct_mem:
-       shmdt(buf->bufstruct_mem);
-
-shmdt_mem:
-       shmdt(buf->mem);
-
-close_fifo:
-       close(buf->pipe_fd);
-
-close_app_sock:
-       close(buf->app_sock);
-
-free_buf_name:
-       free(buf->name);
-
-free_buf_channel:
-       free(buf->channel);
-
-free_buf_trace:
-       free(buf->trace);
-
-free_buf:
-       free(buf);
-       return NULL;
-}
-
-static void destroy_buffer(struct ustconsumer_callbacks *callbacks,
-                       struct buffer_info *buf)
-{
-       int result;
-
-       result = close(buf->pipe_fd);
-       if(result == -1) {
-               WARN("problem closing the pipe fd");
-       }
-
-       result = close(buf->app_sock);
-       if(result == -1) {
-               WARN("problem calling ustcomm_close_app");
-       }
-
-       result = shmdt(buf->mem);
-       if(result == -1) {
-               PERROR("shmdt");
-       }
-
-       result = shmdt(buf->bufstruct_mem);
-       if(result == -1) {
-               PERROR("shmdt");
-       }
-
-       if(callbacks->on_close_buffer)
-               callbacks->on_close_buffer(callbacks, buf);
-
-       free(buf);
-}
-
-int consumer_loop(struct ustconsumer_instance *instance, struct buffer_info *buf)
-{
-       int result = 0;
-       int read_result;
-       char read_buf;
-
-       pthread_cleanup_push(decrement_active_buffers, instance);
-
-       for(;;) {
-               read_result = read(buf->pipe_fd, &read_buf, 1);
-               /* get the subbuffer */
-               if (read_result == 1) {
-                       result = get_subbuffer(buf);
-                       if (result < 0) {
-                               ERR("error getting subbuffer");
-                               continue;
-                       } else if (result == GET_SUBBUF_DIED) {
-                               finish_consuming_dead_subbuffer(instance->callbacks, buf);
-                               break;
-                       }
-               } else if ((read_result == -1 && (errno == ECONNRESET || errno == EPIPE)) ||
-                          result == 0) {
-                       DBG("App died while being traced");
-                       finish_consuming_dead_subbuffer(instance->callbacks, buf);
-                       break;
-               } else if (read_result == -1 && errno == EINTR) {
-                       continue;
-               }
-
-               if(instance->callbacks->on_read_subbuffer)
-                       instance->callbacks->on_read_subbuffer(instance->callbacks, buf);
-
-               /* put the subbuffer */
-               result = put_subbuffer(buf);
-               if(result == -1) {
-                       ERR("unknown error putting subbuffer (channel=%s)", buf->name);
-                       break;
-               }
-               else if(result == PUT_SUBBUF_PUSHED) {
-                       ERR("Buffer overflow (channel=%s), reader pushed. This channel will not be usable passed this point.", buf->name);
-                       break;
-               }
-               else if(result == PUT_SUBBUF_DIED) {
-                       DBG("application died while putting subbuffer");
-                       /* Skip the first subbuffer. We are not sure it is trustable
-                        * because the put_subbuffer() did not complete.
-                        */
-                       /* TODO: check on_put_error return value */
-                       if(instance->callbacks->on_put_error)
-                               instance->callbacks->on_put_error(instance->callbacks, buf);
-
-                       finish_consuming_dead_subbuffer(instance->callbacks, buf);
-                       break;
-               }
-               else if(result == PUT_SUBBUF_DONE) {
-                       /* Done with this subbuffer */
-                       /* FIXME: add a case where this branch is used? Upon
-                        * normal trace termination, at put_subbuf time, a
-                        * special last-subbuffer code could be returned by
-                        * the listener.
-                        */
-                       break;
-               }
-               else if(result == PUT_SUBBUF_OK) {
-               }
-       }
-
-       DBG("thread for buffer %s is stopping", buf->name);
-
-       /* FIXME: destroy, unalloc... */
-
-       pthread_cleanup_pop(1);
-
-       return 0;
-}
-
-struct consumer_thread_args {
-       pid_t pid;
-       const char *trace;
-       const char *channel;
-       int channel_cpu;
-       struct ustconsumer_instance *instance;
-};
-
-void *consumer_thread(void *arg)
-{
-       struct buffer_info *buf;
-       struct consumer_thread_args *args = (struct consumer_thread_args *) arg;
-       int result;
-       sigset_t sigset;
-
-       pthread_mutex_lock(&args->instance->mutex);
-       args->instance->active_threads++;
-       pthread_mutex_unlock(&args->instance->mutex);
-
-       if(args->instance->callbacks->on_new_thread)
-               args->instance->callbacks->on_new_thread(args->instance->callbacks);
-
-       /* Block signals that should be handled by the main thread. */
-       result = sigemptyset(&sigset);
-       if(result == -1) {
-               PERROR("sigemptyset");
-               goto end;
-       }
-       result = sigaddset(&sigset, SIGTERM);
-       if(result == -1) {
-               PERROR("sigaddset");
-               goto end;
-       }
-       result = sigaddset(&sigset, SIGINT);
-       if(result == -1) {
-               PERROR("sigaddset");
-               goto end;
-       }
-       result = sigprocmask(SIG_BLOCK, &sigset, NULL);
-       if(result == -1) {
-               PERROR("sigprocmask");
-               goto end;
-       }
-
-       buf = connect_buffer(args->instance, args->pid, args->trace,
-                            args->channel, args->channel_cpu);
-       if(buf == NULL) {
-               ERR("failed to connect to buffer");
-               goto end;
-       }
-
-       consumer_loop(args->instance, buf);
-
-       destroy_buffer(args->instance->callbacks, buf);
-
-       end:
-
-       if(args->instance->callbacks->on_close_thread)
-               args->instance->callbacks->on_close_thread(args->instance->callbacks);
-
-       pthread_mutex_lock(&args->instance->mutex);
-       args->instance->active_threads--;
-       pthread_mutex_unlock(&args->instance->mutex);
-
-       free((void *)args->channel);
-       free(args);
-       return NULL;
-}
-
-int start_consuming_buffer(struct ustconsumer_instance *instance, pid_t pid,
-                          const char *trace, const char *channel,
-                          int channel_cpu)
-{
-       pthread_t thr;
-       struct consumer_thread_args *args;
-       int result;
-
-       DBG("beginning of start_consuming_buffer: args: pid %d bufname %s_%d", pid, channel,
-           channel_cpu);
-
-       args = (struct consumer_thread_args *) zmalloc(sizeof(struct consumer_thread_args));
-       if (!args) {
-               return -ENOMEM;
-       }
-
-       args->pid = pid;
-       args->trace = strdup(trace);
-       args->channel = strdup(channel);
-       args->channel_cpu = channel_cpu;
-       args->instance = instance;
-       DBG("beginning2 of start_consuming_buffer: args: pid %d trace %s"
-           " bufname %s_%d", args->pid, args->trace, args->channel, args->channel_cpu);
-
-       result = pthread_create(&thr, NULL, consumer_thread, args);
-       if(result == -1) {
-               ERR("pthread_create failed");
-               return -1;
-       }
-       result = pthread_detach(thr);
-       if(result == -1) {
-               ERR("pthread_detach failed");
-               return -1;
-       }
-       DBG("end of start_consuming_buffer: args: pid %d trace %s "
-           "bufname %s_%d", args->pid, args->channel, args->trace, args->channel_cpu);
-
-       return 0;
-}
-static void process_client_cmd(int sock, struct ustcomm_header *req_header,
-                              char *recvbuf, struct ustconsumer_instance *instance)
-{
-       int result;
-       struct ustcomm_header _res_header = {0};
-       struct ustcomm_header *res_header = &_res_header;
-       struct ustcomm_buffer_info *buf_inf;
-
-       DBG("Processing client command");
-
-       switch (req_header->command) {
-       case CONSUME_BUFFER:
-
-               buf_inf = (struct ustcomm_buffer_info *)recvbuf;
-               result = ustcomm_unpack_buffer_info(buf_inf);
-               if (result < 0) {
-                       ERR("Couldn't unpack buffer info");
-                       return;
-               }
-
-               DBG("Going to consume trace %s buffer %s_%d in process %d",
-                   buf_inf->trace, buf_inf->channel, buf_inf->ch_cpu,
-                   buf_inf->pid);
-               result = start_consuming_buffer(instance, buf_inf->pid,
-                                               buf_inf->trace,
-                                               buf_inf->channel,
-                                               buf_inf->ch_cpu);
-               if (result < 0) {
-                       ERR("error in add_buffer");
-                       return;
-               }
-
-               res_header->result = 0;
-               break;
-       case EXIT:
-               res_header->result = 0;
-               /* Only there to force poll to return */
-               break;
-       default:
-               res_header->result = -EINVAL;
-               WARN("unknown command: %d", req_header->command);
-       }
-
-       if (ustcomm_send(sock, res_header, NULL) <= 0) {
-               ERR("couldn't send command response");
-       }
-}
-
-#define MAX_EVENTS 10
-
-int ustconsumer_start_instance(struct ustconsumer_instance *instance)
-{
-       struct ustcomm_header recv_hdr;
-       char recv_buf[USTCOMM_BUFFER_SIZE];
-       struct ustcomm_sock *epoll_sock;
-       struct epoll_event events[MAX_EVENTS];
-       struct sockaddr addr;
-       int result, epoll_fd, accept_fd, nfds, i, addr_size, timeout;
-
-       if(!instance->is_init) {
-               ERR("libustconsumer instance not initialized");
-               return 1;
-       }
-       epoll_fd = instance->epoll_fd;
-
-       timeout = -1;
-
-       /* app loop */
-       for(;;) {
-               nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, timeout);
-               if (nfds == -1 && errno == EINTR) {
-                       /* Caught signal */
-               } else if (nfds == -1) {
-                       PERROR("ustconsumer_start_instance: epoll_wait failed");
-                       continue;
-               }
-
-               for (i = 0; i < nfds; ++i) {
-                       epoll_sock = (struct ustcomm_sock *)events[i].data.ptr;
-                       if (epoll_sock == instance->listen_sock) {
-                               addr_size = sizeof(struct sockaddr);
-                               accept_fd = accept(epoll_sock->fd,
-                                                  &addr,
-                                                  (socklen_t *)&addr_size);
-                               if (accept_fd == -1) {
-                                       PERROR("ustconsumer_start_instance: "
-                                              "accept failed");
-                                       continue;
-                               }
-                               ustcomm_init_sock(accept_fd, epoll_fd,
-                                                &instance->connections);
-                       } else {
-                               result = ustcomm_recv(epoll_sock->fd, &recv_hdr,
-                                                     recv_buf);
-                               if (result < 1) {
-                                       ustcomm_del_sock(epoll_sock, 0);
-                               } else {
-                                       process_client_cmd(epoll_sock->fd,
-                                                          &recv_hdr, recv_buf,
-                                                          instance);
-                               }
-
-                       }
-               }
-
-               if (instance->quit_program) {
-                       pthread_mutex_lock(&instance->mutex);
-                       if (instance->active_buffers == 0 && instance->active_threads == 0) {
-                               pthread_mutex_unlock(&instance->mutex);
-                               break;
-                       }
-                       pthread_mutex_unlock(&instance->mutex);
-                       timeout = 100;
-               }
-       }
-
-       if(instance->callbacks->on_trace_end)
-               instance->callbacks->on_trace_end(instance);
-
-       ustconsumer_delete_instance(instance);
-
-       return 0;
-}
-
-/* FIXME: threads and connections !? */
-void ustconsumer_delete_instance(struct ustconsumer_instance *instance)
-{
-       if (instance->is_init) {
-               ustcomm_del_named_sock(instance->listen_sock, 0);
-               close(instance->epoll_fd);
-       }
-
-       pthread_mutex_destroy(&instance->mutex);
-       free(instance->sock_path);
-       free(instance);
-}
-
-/* FIXME: Do something about the fixed path length, maybe get rid
- * of the whole concept and use a pipe?
- */
-int ustconsumer_stop_instance(struct ustconsumer_instance *instance, int send_msg)
-{
-       int result;
-       int fd;
-       int bytes = 0;
-
-       char msg[] = "exit";
-
-       instance->quit_program = 1;
-
-       if(!send_msg)
-               return 0;
-
-       /* Send a message through the socket to force poll to return */
-
-       struct sockaddr_un addr;
-
-socket_again:
-       result = fd = socket(PF_UNIX, SOCK_STREAM, 0);
-       if(result == -1) {
-               if (errno == EINTR)
-                       goto socket_again;
-               PERROR("socket");
-               return 1;
-       }
-
-       addr.sun_family = AF_UNIX;
-
-       strncpy(addr.sun_path, instance->sock_path, UNIX_PATH_MAX);
-       addr.sun_path[UNIX_PATH_MAX-1] = '\0';
-
-connect_again:
-       result = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
-       if(result == -1) {
-               if (errno == EINTR)
-                       goto connect_again;
-               PERROR("connect");
-       }
-
-       while(bytes != sizeof(msg)) {
-               int inc = send(fd, msg, sizeof(msg), 0);
-               if (inc < 0 && errno != EINTR)
-                       break;
-               else
-                       bytes += inc;
-       }
-
-       close(fd);
-
-       return 0;
-}
-
-struct ustconsumer_instance
-*ustconsumer_new_instance(struct ustconsumer_callbacks *callbacks,
-                     char *sock_path)
-{
-       struct ustconsumer_instance *instance =
-               zmalloc(sizeof(struct ustconsumer_instance));
-       if(!instance) {
-               return NULL;
-       }
-
-       instance->callbacks = callbacks;
-       instance->quit_program = 0;
-       instance->is_init = 0;
-       instance->active_buffers = 0;
-       pthread_mutex_init(&instance->mutex, NULL);
-
-       if (sock_path) {
-               instance->sock_path = strdup(sock_path);
-       } else {
-               instance->sock_path = NULL;
-       }
-
-       return instance;
-}
-
-static int init_ustconsumer_socket(struct ustconsumer_instance *instance)
-{
-       char *name;
-
-       if (instance->sock_path) {
-               if (asprintf(&name, "%s", instance->sock_path) < 0) {
-                       ERR("ustcomm_init_ustconsumer : asprintf failed (sock_path %s)",
-                           instance->sock_path);
-                       return -1;
-               }
-       } else {
-               int result;
-
-               /* Only check if socket dir exists if we are using the default directory */
-               result = ensure_dir_exists(SOCK_DIR, S_IRWXU | S_IRWXG | S_IRWXO);
-               if (result == -1) {
-                       ERR("Unable to create socket directory %s", SOCK_DIR);
-                       return -1;
-               }
-
-               if (asprintf(&name, "%s/%s", SOCK_DIR, "ustconsumer") < 0) {
-                       ERR("ustcomm_init_ustconsumer : asprintf failed (%s/ustconsumer)",
-                           SOCK_DIR);
-                       return -1;
-               }
-       }
-
-       /* Set up epoll */
-       instance->epoll_fd = epoll_create(MAX_EVENTS);
-       if (instance->epoll_fd == -1) {
-               ERR("epoll_create failed, start instance bailing");
-               goto free_name;
-       }
-
-       /* Create the named socket */
-       instance->listen_sock = ustcomm_init_named_socket(name,
-                                                         instance->epoll_fd);
-       if(!instance->listen_sock) {
-               ERR("error initializing named socket at %s", name);
-               goto close_epoll;
-       }
-
-       CDS_INIT_LIST_HEAD(&instance->connections);
-
-       free(name);
-
-       return 0;
-
-close_epoll:
-       close(instance->epoll_fd);
-free_name:
-       free(name);
-
-       return -1;
-}
-
-int ustconsumer_init_instance(struct ustconsumer_instance *instance)
-{
-       int result;
-       result = init_ustconsumer_socket(instance);
-       if(result == -1) {
-               ERR("failed to initialize socket");
-               return 1;
-       }
-       instance->is_init = 1;
-       return 0;
-}
-
diff --git a/libustconsumer/lowlevel.c b/libustconsumer/lowlevel.c
deleted file mode 100644 (file)
index a54a8db..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/* Copyright (C) 2009  Pierre-Marc Fournier
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#include <stdlib.h>
-#include <assert.h>
-#include <byteswap.h>
-
-#include "ust/ustconsumer.h"
-#include "buffers.h"
-#include "tracer.h"
-#include "usterr_signal_safe.h"
-
-/* This truncates to an offset in the buffer. */
-#define USTD_BUFFER_TRUNC(offset, bufinfo) \
-       ((offset) & (~(((bufinfo)->subbuf_size*(bufinfo)->n_subbufs)-1)))
-
-#define LTT_MAGIC_NUMBER 0x00D6B7ED
-#define LTT_REV_MAGIC_NUMBER 0xEDB7D600
-
-
-static void ltt_relay_print_subbuffer_errors(
-               struct buffer_info *buf,
-               long cons_off, int cpu)
-{
-       struct ust_buffer *ust_buf = buf->bufstruct_mem;
-       long cons_idx, commit_count, commit_count_mask, write_offset;
-
-       cons_idx = SUBBUF_INDEX(cons_off, buf);
-       commit_count = uatomic_read(&ust_buf->commit_seq[cons_idx]);
-       commit_count_mask = (~0UL >> get_count_order(buf->n_subbufs));
-
-       /*
-        * No need to order commit_count and write_offset reads because we
-        * execute after trace is stopped when there are no readers left.
-        */
-       write_offset = uatomic_read(&ust_buf->offset);
-       WARN( "LTT : unread channel %s offset is %ld "
-                       "and cons_off : %ld (cpu %d)\n",
-                       buf->channel, write_offset, cons_off, cpu);
-       /* Check each sub-buffer for non filled commit count */
-       if (((commit_count - buf->subbuf_size) & commit_count_mask)
-                       - (BUFFER_TRUNC(cons_off, buf) >> get_count_order(buf->n_subbufs)) != 0) {
-               ERR("LTT : %s : subbuffer %lu has non filled "
-                               "commit count [seq] [%lu].\n",
-                               buf->channel, cons_idx, commit_count);
-       }
-       ERR("LTT : %s : commit count : %lu, subbuf size %d\n",
-                       buf->channel, commit_count,
-                       buf->subbuf_size);
-}
-
-static void ltt_relay_print_errors(struct buffer_info *buf, int cpu)
-{
-       struct ust_buffer *ust_buf = buf->bufstruct_mem;
-       long cons_off;
-
-       for (cons_off = uatomic_read(&ust_buf->consumed);
-                       (SUBBUF_TRUNC(uatomic_read(&ust_buf->offset), buf)
-                               - cons_off) > 0;
-                       cons_off = SUBBUF_ALIGN(cons_off, buf))
-               ltt_relay_print_subbuffer_errors(buf, cons_off, cpu);
-}
-
-static void ltt_relay_print_buffer_errors(struct buffer_info *buf, int cpu)
-{
-       struct ust_buffer *ust_buf = buf->bufstruct_mem;
-
-       if (uatomic_read(&ust_buf->events_lost))
-               ERR("channel %s: %ld events lost (cpu %d)",
-                               buf->channel,
-                               uatomic_read(&ust_buf->events_lost), cpu);
-       if (uatomic_read(&ust_buf->corrupted_subbuffers))
-               ERR("channel %s : %ld corrupted subbuffers (cpu %d)",
-                               buf->channel,
-                               uatomic_read(&ust_buf->corrupted_subbuffers), cpu);
-
-       ltt_relay_print_errors(buf, cpu);
-}
-
-/* Returns the size of a subbuffer size. This is the size that
- * will need to be written to disk.
- *
- * @subbuffer: pointer to the beginning of the subbuffer (the
- *             beginning of its header)
- */
-
-size_t subbuffer_data_size(void *subbuf)
-{
-       struct ltt_subbuffer_header *header = subbuf;
-       int reverse;
-       u32 data_size;
-
-       if(header->magic_number == LTT_MAGIC_NUMBER) {
-               reverse = 0;
-       }
-       else if(header->magic_number == LTT_REV_MAGIC_NUMBER) {
-               reverse = 1;
-       }
-       else {
-               return -1;
-       }
-
-       data_size = header->sb_size;
-       if(reverse)
-               data_size = bswap_32(data_size);
-
-       return data_size;
-}
-
-
-void finish_consuming_dead_subbuffer(struct ustconsumer_callbacks *callbacks, struct buffer_info *buf)
-{
-       struct ust_buffer *ust_buf = buf->bufstruct_mem;
-       unsigned long n_subbufs_order = get_count_order(buf->n_subbufs);
-       unsigned long commit_seq_mask = (~0UL >> n_subbufs_order);
-       unsigned long cons_off;
-       int ret;
-
-       DBG("processing dead buffer (%s)", buf->name);
-       DBG("consumed offset is %ld (%s)", uatomic_read(&ust_buf->consumed),
-                                          buf->name);
-       DBG("write offset is %ld (%s)", uatomic_read(&ust_buf->offset),
-                                       buf->name);
-
-       /*
-        * Iterate on subbuffers to recover, including the one the writer
-        * just wrote data into. Using write position - 1 since the writer
-        * position points into the position that is going to be written.
-        */
-       for (cons_off = uatomic_read(&ust_buf->consumed);
-                       (long) (SUBBUF_TRUNC(uatomic_read(&ust_buf->offset) - 1, buf)
-                               - cons_off) >= 0;
-                       cons_off = SUBBUF_ALIGN(cons_off, buf)) {
-               /*
-                * commit_seq is the offset in the buffer of the end of the last sequential commit.
-                * Bytes beyond this limit cannot be recovered. This is a free-running counter.
-                */
-               unsigned long commit_seq =
-                       uatomic_read(&ust_buf->commit_seq[SUBBUF_INDEX(cons_off, buf)]);
-               struct ltt_subbuffer_header *header =
-                       (struct ltt_subbuffer_header *)((char *) buf->mem
-                               + SUBBUF_INDEX(cons_off, buf) * buf->subbuf_size);
-               unsigned long valid_length;
-
-               /* Check if subbuf was fully written. This is from Mathieu's algorithm/paper. */
-               if (((commit_seq - buf->subbuf_size) & commit_seq_mask)
-                   - (USTD_BUFFER_TRUNC(uatomic_read(&ust_buf->consumed), buf) >> n_subbufs_order) == 0
-                    && header->data_size != 0xffffffff) {
-                       assert(header->sb_size != 0xffffffff);
-                       /*
-                        * If it was fully written, we only check the data_size.
-                        * This is the amount of valid data at the beginning of
-                        * the subbuffer.
-                        */
-                       valid_length = header->data_size;
-                       DBG("writing full subbuffer (%ld) with valid_length = %ld",
-                           SUBBUF_INDEX(cons_off, buf), valid_length);
-               } else {
-                       /*
-                        * If the subbuffer was not fully written, then we don't
-                        * check data_size because it hasn't been written yet.
-                        * Instead we check commit_seq and use it to choose a
-                        * value for data_size. The viewer will need this value
-                        * when parsing. Generally, this will happen only for
-                        * the last subbuffer. However, if we have threads still
-                        * holding reserved slots in the previous subbuffers,
-                        * which could happen for other subbuffers prior to the
-                        * last one. Note that when data_size is set, the
-                        * commit_seq count is still at a value that shows the
-                        * amount of valid data to read. It's only _after_
-                        * writing data_size that commit_seq is updated to
-                        * include the end-of-buffer padding.
-                        */
-                       valid_length = commit_seq & (buf->subbuf_size - 1);
-                       DBG("writing unfull subbuffer (%ld) with valid_length = %ld",
-                           SUBBUF_INDEX(cons_off, buf), valid_length);
-                       header->data_size = valid_length;
-                       header->sb_size = PAGE_ALIGN(valid_length);
-               }
-
-               if (callbacks->on_read_partial_subbuffer) {
-                       ret = callbacks->on_read_partial_subbuffer(callbacks, buf,
-                                                                  SUBBUF_INDEX(cons_off, buf),
-                                                                  valid_length);
-                       if (ret < 0)
-                               break;  /* Error happened */
-               }
-       }
-       /* Increment the consumed offset */
-       uatomic_set(&ust_buf->consumed, cons_off);
-       ltt_relay_print_buffer_errors(buf, buf->channel_cpu);
-}
-
diff --git a/libustconsumer/lowlevel.h b/libustconsumer/lowlevel.h
deleted file mode 100644 (file)
index 6ae6476..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * lowlevel libustd header file
- *
- * Copyright 2005-2010 -
- *              Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
- * Copyright 2010-
- *              Oumarou Dicko <oumarou.dicko@polymtl.ca>
- *              Michael Sills-Lavoie <michael.sills-lavoie@polymtl.ca>
- *              Alexis Halle <alexis.halle@polymtl.ca>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef LOWLEVEL_H
-#define LOWLEVEL_H
-
-#include "ust/ustconsumer.h"
-
-void finish_consuming_dead_subbuffer(struct ustconsumer_callbacks *callbacks, struct buffer_info *buf);
-size_t subbuffer_data_size(void *subbuf);
-
-#endif /* LOWLEVEL_H */
-
diff --git a/libustctl/Makefile.am b/libustctl/Makefile.am
deleted file mode 100644 (file)
index bc7526b..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libustcomm
-AM_CFLAGS = -fno-strict-aliasing
-
-lib_LTLIBRARIES = libustctl.la
-
-libustctl_la_SOURCES = \
-       libustctl.c
-
-libustctl_la_LDFLAGS = -no-undefined -version-info 0:0:0
-
-libustctl_la_LIBADD = \
-       $(top_builddir)/libustcomm/libustcomm.la
-
-libustctl_la_CFLAGS = -DUST_COMPONENT="libustctl" -fno-strict-aliasing
diff --git a/libustctl/README b/libustctl/README
deleted file mode 100644 (file)
index fd4cc97..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-libustctl is a library that provides an API and its implementation to send
-commands to traceable processes.
diff --git a/libustctl/libustctl.c b/libustctl/libustctl.c
deleted file mode 100644 (file)
index 4e6c495..0000000
+++ /dev/null
@@ -1,770 +0,0 @@
-/* Copyright (C) 2009  Pierre-Marc Fournier, Philippe Proulx-Barrette
- * Copyright (C) 2011  Ericsson AB
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <string.h>
-#include <dirent.h>
-
-#include "ustcomm.h"
-#include "ust/ustctl.h"
-#include "usterr.h"
-
-static int do_cmd(int sock,
-                 const struct ustcomm_header *req_header,
-                 const char *req_data,
-                 struct ustcomm_header *res_header,
-                 char **res_data)
-{
-       int result, saved_errno = 0;
-       char *recv_buf;
-
-       recv_buf = zmalloc(USTCOMM_BUFFER_SIZE);
-       if (!recv_buf) {
-               saved_errno = ENOMEM;
-               goto out;
-       }
-
-       result = ustcomm_req(sock, req_header, req_data, res_header, recv_buf);
-       if (result > 0) {
-               saved_errno = -res_header->result;
-               if (res_header->size == 0 || saved_errno > 0) {
-                       free(recv_buf);
-               } else {
-                       if (res_data) {
-                               *res_data = recv_buf;
-                       } else {
-                               free(recv_buf);
-                       }
-               }
-       } else {
-               ERR("ustcomm req failed");
-               if (result == 0) {
-                       saved_errno = ENOTCONN;
-               } else {
-                       saved_errno = -result;
-               }
-               free(recv_buf);
-       }
-
-out:
-       errno = saved_errno;
-       if (errno) {
-               return -1;
-       }
-
-       return 0;
-}
-
-int ustctl_connect_pid(pid_t pid)
-{
-       int sock;
-
-       if (ustcomm_connect_app(pid, &sock)) {
-               ERR("could not connect to PID %u", (unsigned int) pid);
-               errno = ENOTCONN;
-               return -1;
-       }
-
-       return sock;
-}
-
-static int realloc_pid_list(pid_t **pid_list, unsigned int *pid_list_size)
-{
-       pid_t *new_pid_list;
-       unsigned int new_pid_list_size = 2 * *pid_list_size;
-
-       new_pid_list = realloc(*pid_list,
-                              new_pid_list_size * sizeof(pid_t));
-       if (!*new_pid_list) {
-               return -1;
-       }
-
-       *pid_list = new_pid_list;
-       *pid_list_size = new_pid_list_size;
-
-       return 0;
-}
-
-static int get_pids_in_dir(DIR *dir, pid_t **pid_list,
-                           unsigned int *pid_list_index,
-                           unsigned int *pid_list_size)
-{
-       struct dirent *dirent;
-       pid_t read_pid;
-
-       while ((dirent = readdir(dir))) {
-               if (!strcmp(dirent->d_name, ".") ||
-                   !strcmp(dirent->d_name, "..") ||
-                   !strcmp(dirent->d_name, "ust-consumer") ||
-                   dirent->d_type == DT_DIR) {
-
-                       continue;
-               }
-
-               if (ustcomm_is_socket_live(dirent->d_name, &read_pid)) {
-
-                       (*pid_list)[(*pid_list_index)++] = (long) read_pid;
-
-                       if (*pid_list_index == *pid_list_size) {
-                               if (realloc_pid_list(pid_list, pid_list_size)) {
-                                       return -1;
-                               }
-                       }
-               }
-       }
-
-       (*pid_list)[*pid_list_index] = 0; /* Array end */
-
-       return 0;
-}
-
-static pid_t *get_pids_non_root(void)
-{
-       char *dir_name;
-       DIR *dir;
-       unsigned int pid_list_index = 0, pid_list_size = 1;
-       pid_t *pid_list = NULL;
-
-       dir_name = ustcomm_user_sock_dir();
-       if (!dir_name) {
-               return NULL;
-       }
-
-       dir = opendir(dir_name);
-       if (!dir) {
-               goto free_dir_name;
-       }
-
-       pid_list = malloc(pid_list_size * sizeof(pid_t));
-       if (!pid_list) {
-               goto close_dir;
-       }
-
-       if (get_pids_in_dir(dir, &pid_list, &pid_list_index, &pid_list_size)) {
-               /* if any errors are encountered, force freeing of the list */
-               pid_list[0] = 0;
-       }
-
-close_dir:
-       closedir(dir);
-
-free_dir_name:
-       free(dir_name);
-
-       return pid_list;
-}
-
-static pid_t *get_pids_root(void)
-{
-       char *dir_name;
-       DIR *tmp_dir, *dir;
-       unsigned int pid_list_index = 0, pid_list_size = 1;
-       pid_t *pid_list = NULL;
-       struct dirent *dirent;
-       int result;
-
-       tmp_dir = opendir(USER_TMP_DIR);
-       if (!tmp_dir) {
-               return NULL;
-       }
-
-       pid_list = malloc(pid_list_size * sizeof(pid_t));
-       if (!pid_list) {
-               goto close_tmp_dir;
-       }
-
-       while ((dirent = readdir(tmp_dir))) {
-               /* Compare the dir to check for the USER_SOCK_DIR_BASE prefix */
-               if (!strncmp(dirent->d_name, USER_SOCK_DIR_BASE,
-                            strlen(USER_SOCK_DIR_BASE))) {
-
-                       if (asprintf(&dir_name, USER_TMP_DIR "/%s",
-                                    dirent->d_name) < 0) {
-                               goto close_tmp_dir;
-                       }
-
-                       dir = opendir(dir_name);
-
-                       free(dir_name);
-
-                       if (!dir) {
-                               continue;
-                       }
-
-                       result = get_pids_in_dir(dir, &pid_list, &pid_list_index,
-                                                &pid_list_size);
-
-                       closedir(dir);
-
-                       if (result) {
-                               /*
-                                * if any errors are encountered,
-                                * force freeing of the list
-                                */
-                               pid_list[0] = 0;
-                               break;
-                       }
-               }
-       }
-
-close_tmp_dir:
-       closedir(tmp_dir);
-
-       return pid_list;
-}
-
-pid_t *ustctl_get_online_pids(void)
-{
-       pid_t *pid_list;
-
-       if (geteuid()) {
-               pid_list = get_pids_non_root();
-       } else {
-               pid_list = get_pids_root();
-       }
-
-       if (pid_list && pid_list[0] == 0) {
-               /* No PID at all */
-               free(pid_list);
-               pid_list = NULL;
-       }
-
-       return pid_list;
-}
-
-/**
- * Sets ust_marker state (USTCTL_MS_ON or USTCTL_MS_OFF).
- *
- * @param mn   Marker name
- * @param state        Marker's new state
- * @param pid  Traced process ID
- * @return     0 if successful, or errors {USTCTL_ERR_GEN, USTCTL_ERR_ARG}
- */
-int ustctl_set_ust_marker_state(int sock, const char *trace, const char *channel,
-                           const char *ust_marker, int state)
-{
-       struct ustcomm_header req_header, res_header;
-       struct ustcomm_ust_marker_info ust_marker_inf;
-       int result;
-
-       result = ustcomm_pack_ust_marker_info(&req_header,
-                                         &ust_marker_inf,
-                                         trace,
-                                         channel,
-                                         ust_marker);
-       if (result < 0) {
-               errno = -result;
-               return -1;
-       }
-
-       req_header.command = state ? ENABLE_MARKER : DISABLE_MARKER;
-
-       return do_cmd(sock, &req_header, (char *)&ust_marker_inf,
-                     &res_header, NULL);
-}
-
-/**
- * Set subbuffer size.
- *
- * @param channel_size Channel name and size
- * @param pid          Traced process ID
- * @return             0 if successful, or error
- */
-int ustctl_set_subbuf_size(int sock, const char *trace, const char *channel,
-                          unsigned int subbuf_size)
-{
-       struct ustcomm_header req_header, res_header;
-       struct ustcomm_channel_info ch_inf;
-       int result;
-
-       result = ustcomm_pack_channel_info(&req_header,
-                                          &ch_inf,
-                                          trace,
-                                          channel);
-       if (result < 0) {
-               errno = -result;
-               return -1;
-       }
-
-       req_header.command = SET_SUBBUF_SIZE;
-       ch_inf.subbuf_size = subbuf_size;
-
-       return do_cmd(sock, &req_header, (char *)&ch_inf,
-                     &res_header, NULL);
-}
-
-/**
- * Set subbuffer num.
- *
- * @param channel_num  Channel name and num
- * @param pid          Traced process ID
- * @return             0 if successful, or error
- */
-int ustctl_set_subbuf_num(int sock, const char *trace, const char *channel,
-                         unsigned int num)
-{
-       struct ustcomm_header req_header, res_header;
-       struct ustcomm_channel_info ch_inf;
-       int result;
-
-       result = ustcomm_pack_channel_info(&req_header,
-                                          &ch_inf,
-                                          trace,
-                                          channel);
-       if (result < 0) {
-               errno = -result;
-               return -1;
-       }
-
-       req_header.command = SET_SUBBUF_NUM;
-       ch_inf.subbuf_num = num;
-
-       return do_cmd(sock, &req_header, (char *)&ch_inf,
-                     &res_header, NULL);
-
-}
-
-
-static int ustctl_get_subbuf_num_size(int sock, const char *trace, const char *channel,
-                                     int *num, int *size)
-{
-       struct ustcomm_header req_header, res_header;
-       struct ustcomm_channel_info ch_inf, *ch_inf_res;
-       int result;
-
-
-       result = ustcomm_pack_channel_info(&req_header,
-                                          &ch_inf,
-                                          trace,
-                                          channel);
-       if (result < 0) {
-               errno = -result;
-               return -1;
-       }
-
-       req_header.command = GET_SUBBUF_NUM_SIZE;
-
-       result = do_cmd(sock, &req_header, (char *)&ch_inf,
-                       &res_header, (char **)&ch_inf_res);
-       if (result < 0) {
-               return -1;
-       }
-
-       *num = ch_inf_res->subbuf_num;
-       *size = ch_inf_res->subbuf_size;
-
-       free(ch_inf_res);
-
-       return 0;
-}
-
-/**
- * Get subbuffer num.
- *
- * @param channel      Channel name
- * @param pid          Traced process ID
- * @return             subbuf cnf if successful, or error
- */
-int ustctl_get_subbuf_num(int sock, const char *trace, const char *channel)
-{
-       int num, size, result;
-
-       result = ustctl_get_subbuf_num_size(sock, trace, channel,
-                                           &num, &size);
-       if (result < 0) {
-               errno = -result;
-               return -1;
-       }
-
-       return num;
-}
-
-/**
- * Get subbuffer size.
- *
- * @param channel      Channel name
- * @param pid          Traced process ID
- * @return             subbuf size if successful, or error
- */
-int ustctl_get_subbuf_size(int sock, const char *trace, const char *channel)
-{
-       int num, size, result;
-
-       result = ustctl_get_subbuf_num_size(sock, trace, channel,
-                                           &num, &size);
-       if (result < 0) {
-               errno = -result;
-               return -1;
-       }
-
-       return size;
-}
-
-static int do_trace_cmd(int sock, const char *trace, int command)
-{
-       struct ustcomm_header req_header, res_header;
-       struct ustcomm_single_field trace_inf;
-       int result;
-
-       result = ustcomm_pack_single_field(&req_header,
-                                          &trace_inf,
-                                          trace);
-       if (result < 0) {
-               errno = -result;
-               return -1;
-       }
-
-       req_header.command = command;
-
-       return do_cmd(sock, &req_header, (char *)&trace_inf, &res_header, NULL);
-}
-
-/**
- * Destroys an UST trace according to a PID.
- *
- * @param pid  Traced process ID
- * @return     0 if successful, or error USTCTL_ERR_GEN
- */
-int ustctl_destroy_trace(int sock, const char *trace)
-{
-       return do_trace_cmd(sock, trace, DESTROY_TRACE);
-}
-
-/**
- * Starts an UST trace (and setups it) according to a PID.
- *
- * @param pid  Traced process ID
- * @return     0 if successful, or error USTCTL_ERR_GEN
- */
-int ustctl_setup_and_start(int sock, const char *trace)
-{
-       return do_trace_cmd(sock, trace, START);
-}
-
-/**
- * Creates an UST trace according to a PID.
- *
- * @param pid  Traced process ID
- * @return     0 if successful, or error USTCTL_ERR_GEN
- */
-int ustctl_create_trace(int sock, const char *trace)
-{
-       return do_trace_cmd(sock, trace, CREATE_TRACE);
-}
-
-/**
- * Starts an UST trace according to a PID.
- *
- * @param pid  Traced process ID
- * @return     0 if successful, or error USTCTL_ERR_GEN
- */
-int ustctl_start_trace(int sock, const char *trace)
-{
-       return do_trace_cmd(sock, trace, START_TRACE);
-}
-
-/**
- * Alloc an UST trace according to a PID.
- *
- * @param pid  Traced process ID
- * @return     0 if successful, or error USTCTL_ERR_GEN
- */
-int ustctl_alloc_trace(int sock, const char *trace)
-{
-       return do_trace_cmd(sock, trace, ALLOC_TRACE);
-}
-
-
-int ustctl_force_switch(int sock, const char *trace)
-{
-       return do_trace_cmd(sock, trace, FORCE_SUBBUF_SWITCH);
-}
-
-/**
- * Stops an UST trace according to a PID.
- *
- * @param pid  Traced process ID
- * @return     0 if successful, or error USTCTL_ERR_GEN
- */
-int ustctl_stop_trace(int sock, const char *trace)
-{
-       return do_trace_cmd(sock, trace, STOP_TRACE);
-}
-
-/**
- * Counts newlines ('\n') in a string.
- *
- * @param str  String to search in
- * @return     Total newlines count
- */
-unsigned int ustctl_count_nl(const char *str)
-{
-       unsigned int i = 0, tot = 0;
-
-       while (str[i] != '\0') {
-               if (str[i] == '\n') {
-                       ++tot;
-               }
-               ++i;
-       }
-
-       return tot;
-}
-
-/**
- * Frees a CMSF array.
- *
- * @param cmsf CMSF array to free
- * @return     0 if successful, or error USTCTL_ERR_ARG
- */
-int ustctl_free_cmsf(struct ust_marker_status *cmsf)
-{
-       if (cmsf == NULL) {
-               return USTCTL_ERR_ARG;
-       }
-
-       unsigned int i = 0;
-       while (cmsf[i].channel != NULL) {
-               free(cmsf[i].channel);
-               free(cmsf[i].ust_marker);
-               free(cmsf[i].fs);
-               ++i;
-       }
-       free(cmsf);
-
-       return 0;
-}
-
-/**
- * Gets channel/ust_marker/state/format string for a given PID.
- *
- * @param cmsf Pointer to CMSF array to be filled (callee allocates, caller
- *             frees with `ustctl_free_cmsf')
- * @param pid  Targeted PID
- * @return     0 if successful, or -1 on error
- */
-int ustctl_get_cmsf(int sock, struct ust_marker_status **cmsf)
-{
-       struct ustcomm_header req_header, res_header;
-       char *big_str = NULL;
-       int result;
-       struct ust_marker_status *tmp_cmsf = NULL;
-       unsigned int i = 0, cmsf_ind = 0;
-
-       if (cmsf == NULL) {
-               return -1;
-       }
-
-       req_header.command = LIST_MARKERS;
-       req_header.size = 0;
-
-       result = ustcomm_send(sock, &req_header, NULL);
-       if (result <= 0) {
-               PERROR("error while requesting ust_marker list");
-               return -1;
-       }
-
-       result = ustcomm_recv_alloc(sock, &res_header, &big_str);
-       if (result <= 0) {
-               ERR("error while receiving ust_marker list");
-               return -1;
-       }
-
-       tmp_cmsf = (struct ust_marker_status *) zmalloc(sizeof(struct ust_marker_status) *
-                                                   (ustctl_count_nl(big_str) + 1));
-       if (tmp_cmsf == NULL) {
-               ERR("Failed to allocate CMSF array");
-               return -1;
-       }
-
-       /* Parse received reply string (format: "[chan]/[mark] [st] [fs]"): */
-       while (big_str[i] != '\0') {
-               char state;
-
-               sscanf(big_str + i, "ust_marker: %a[^/]/%a[^ ] %c %a[^\n]",
-                      &tmp_cmsf[cmsf_ind].channel,
-                      &tmp_cmsf[cmsf_ind].ust_marker,
-                      &state,
-                      &tmp_cmsf[cmsf_ind].fs);
-               tmp_cmsf[cmsf_ind].state = (state == USTCTL_MS_CHR_ON ?
-                                           USTCTL_MS_ON : USTCTL_MS_OFF); /* Marker state */
-
-               while (big_str[i] != '\n') {
-                       ++i; /* Go to next '\n' */
-               }
-               ++i; /* Skip current pointed '\n' */
-               ++cmsf_ind;
-       }
-       tmp_cmsf[cmsf_ind].channel = NULL;
-       tmp_cmsf[cmsf_ind].ust_marker = NULL;
-       tmp_cmsf[cmsf_ind].fs = NULL;
-
-       *cmsf = tmp_cmsf;
-
-       free(big_str);
-       return 0;
-}
-
-/**
- * Frees a TES array.
- *
- * @param tes  TES array to free
- * @return     0 if successful, or error USTCTL_ERR_ARG
- */
-int ustctl_free_tes(struct trace_event_status *tes)
-{
-       if (tes == NULL) {
-               return USTCTL_ERR_ARG;
-       }
-
-       unsigned int i = 0;
-       while (tes[i].name != NULL) {
-               free(tes[i].name);
-               ++i;
-       }
-       free(tes);
-
-       return 0;
-}
-
-/**
- * Gets trace_events string for a given PID.
- *
- * @param tes  Pointer to TES array to be filled (callee allocates, caller
- *             frees with `ustctl_free_tes')
- * @param pid  Targeted PID
- * @return     0 if successful, or -1 on error
- */
-int ustctl_get_tes(int sock, struct trace_event_status **tes)
-{
-       struct ustcomm_header req_header, res_header;
-       char *big_str = NULL;
-       int result;
-       struct trace_event_status *tmp_tes = NULL;
-       unsigned int i = 0, tes_ind = 0;
-
-       if (tes == NULL) {
-               return -1;
-       }
-
-       req_header.command = LIST_TRACE_EVENTS;
-       req_header.size = 0;
-
-       result = ustcomm_send(sock, &req_header, NULL);
-       if (result != 1) {
-               ERR("error while requesting trace_event list");
-               return -1;
-       }
-
-       result = ustcomm_recv_alloc(sock, &res_header, &big_str);
-       if (result != 1) {
-               ERR("error while receiving ust_marker list");
-               return -1;
-       }
-
-       tmp_tes = (struct trace_event_status *)
-               zmalloc(sizeof(struct trace_event_status) *
-                       (ustctl_count_nl(big_str) + 1));
-       if (tmp_tes == NULL) {
-               ERR("Failed to allocate TES array");
-               return -1;
-       }
-
-       /* Parse received reply string (format: "[name]"): */
-       while (big_str[i] != '\0') {
-               sscanf(big_str + i, "trace_event: %a[^\n]",
-                      &tmp_tes[tes_ind].name);
-               while (big_str[i] != '\n') {
-                       ++i; /* Go to next '\n' */
-               }
-               ++i; /* Skip current pointed '\n' */
-               ++tes_ind;
-       }
-       tmp_tes[tes_ind].name = NULL;
-
-       *tes = tmp_tes;
-
-       free(big_str);
-       return 0;
-}
-
-/**
- * Set sock path
- *
- * @param sock_path    Sock path
- * @param pid          Traced process ID
- * @return             0 if successful, or error
- */
-int ustctl_set_sock_path(int sock, const char *sock_path)
-{
-       int result;
-       struct ustcomm_header req_header, res_header;
-       struct ustcomm_single_field sock_path_msg;
-
-       result = ustcomm_pack_single_field(&req_header,
-                                          &sock_path_msg,
-                                          sock_path);
-       if (result < 0) {
-               errno = -result;
-               return -1;
-       }
-
-       req_header.command = SET_SOCK_PATH;
-
-       return do_cmd(sock, &req_header, (char *)&sock_path_msg,
-                     &res_header, NULL);
-}
-
-/**
- * Get sock path
- *
- * @param sock_path    Pointer to where the sock path will be returned
- * @param pid          Traced process ID
- * @return             0 if successful, or error
- */
-int ustctl_get_sock_path(int sock, char **sock_path)
-{
-       int result;
-       struct ustcomm_header req_header, res_header;
-       struct ustcomm_single_field *sock_path_msg;
-
-       req_header.command = GET_SOCK_PATH;
-       req_header.size = 0;
-
-       result = do_cmd(sock, &req_header, NULL, &res_header,
-                       (char **)&sock_path_msg);
-       if (result < 0) {
-               return -1;
-       }
-
-       result = ustcomm_unpack_single_field(sock_path_msg);
-       if (result < 0) {
-               return result;
-       }
-
-       *sock_path = strdup(sock_path_msg->field);
-
-       free(sock_path_msg);
-
-       return 0;
-}
diff --git a/ust-consumerd/Makefile.am b/ust-consumerd/Makefile.am
deleted file mode 100644 (file)
index 01e3b82..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-AM_CPPFLAGS = -I$(top_srcdir)/libust -I$(top_srcdir)/libustcomm \
-       -I$(top_srcdir)/include -I$(top_srcdir)/libustconsumer
-AM_CFLAGS = -fno-strict-aliasing
-
-bin_PROGRAMS = ust-consumerd
-
-ust_consumerd_SOURCES = ust-consumerd.c
-
-ust_consumerd_LDADD = \
-       $(top_builddir)/snprintf/libustsnprintf.la \
-       $(top_builddir)/libustcomm/libustcomm.la \
-       $(top_builddir)/libustconsumer/libustconsumer.la
-
-ust_consumerd_CFLAGS = -DUST_COMPONENT=ust-consumerd -fno-strict-aliasing
diff --git a/ust-consumerd/README b/ust-consumerd/README
deleted file mode 100644 (file)
index 6df4015..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-This is ust-consumerd, the UST consumer daemon.
-
-This daemon is used to collect the traces for the traced programs and write them to disk.
diff --git a/ust-consumerd/ust-consumerd.c b/ust-consumerd/ust-consumerd.c
deleted file mode 100644 (file)
index 0761253..0000000
+++ /dev/null
@@ -1,516 +0,0 @@
-/* Copyright (C) 2009  Pierre-Marc Fournier
- *               2010  Alexis Halle
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#define _GNU_SOURCE
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/shm.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <signal.h>
-#include <inttypes.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <getopt.h>
-
-#include "ust/ustconsumer.h"
-#include "../libustconsumer/lowlevel.h"
-#include "usterr.h"
-
-char *sock_path=NULL;
-char *trace_path=NULL;
-int daemon_mode = 0;
-char *pidfile = NULL;
-
-struct ustconsumer_instance *instance;
-
-struct buffer_info_local {
-       /* output file */
-       int file_fd;
-       /* the offset we must truncate to, to unput the last subbuffer */
-       off_t previous_offset;
-};
-
-static int write_pidfile(const char *file_name, pid_t pid)
-{
-       FILE *pidfp;
-
-       pidfp = fopen(file_name, "w");
-       if(!pidfp) {
-               PERROR("fopen (%s)", file_name);
-               WARN("killing child process");
-               return -1;
-       }
-
-       fprintf(pidfp, "%d\n", pid);
-
-       fclose(pidfp);
-
-       return 0;
-}
-
-int create_dir_if_needed(char *dir)
-{
-       int result;
-       result = mkdir(dir, 0777);
-       if(result == -1) {
-               if(errno != EEXIST) {
-                       PERROR("mkdir");
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-int unwrite_last_subbuffer(struct buffer_info *buf)
-{
-       int result;
-       struct buffer_info_local *buf_local = buf->user_data;
-
-       result = ftruncate(buf_local->file_fd, buf_local->previous_offset);
-       if(result == -1) {
-               PERROR("ftruncate");
-               return -1;
-       }
-
-       result = lseek(buf_local->file_fd, buf_local->previous_offset, SEEK_SET);
-       if(result == (int)(off_t)-1) {
-               PERROR("lseek");
-               return -1;
-       }
-
-       return 0;
-}
-
-int write_current_subbuffer(struct buffer_info *buf)
-{
-       int result;
-       struct buffer_info_local *buf_local = buf->user_data;
-
-       void *subbuf_mem = buf->mem + (buf->consumed_old & (buf->n_subbufs * buf->subbuf_size-1));
-
-       size_t cur_sb_size = subbuffer_data_size(subbuf_mem);
-
-       off_t cur_offset = lseek(buf_local->file_fd, 0, SEEK_CUR);
-       if(cur_offset == (off_t)-1) {
-               PERROR("lseek");
-               return -1;
-       }
-
-       buf_local->previous_offset = cur_offset;
-       DBG("previous_offset: %ld", cur_offset);
-
-       result = patient_write(buf_local->file_fd, subbuf_mem, cur_sb_size);
-       if(result == -1) {
-               PERROR("write");
-               return -1;
-       }
-
-       return 0;
-}
-
-int on_read_subbuffer(struct ustconsumer_callbacks *data, struct buffer_info *buf)
-{
-       return write_current_subbuffer(buf);
-}
-
-int on_read_partial_subbuffer(struct ustconsumer_callbacks *data, struct buffer_info *buf,
-                               long subbuf_index, unsigned long valid_length)
-{
-       struct buffer_info_local *buf_local = buf->user_data;
-       char *tmp;
-       int result;
-       unsigned long pad_size;
-
-       result = patient_write(buf_local->file_fd, buf->mem + subbuf_index * buf->subbuf_size, valid_length);
-       if(result == -1) {
-               ERR("Error writing to buffer file");
-               return result;
-       }
-
-       /* pad with empty bytes */
-       pad_size = PAGE_ALIGN(valid_length)-valid_length;
-       if(pad_size) {
-               tmp = zmalloc(pad_size);
-               result = patient_write(buf_local->file_fd, tmp, pad_size);
-               if(result == -1) {
-                       ERR("Error writing to buffer file");
-                       return result;
-               }
-               free(tmp);
-       }
-       return result;
-}
-
-int on_open_buffer(struct ustconsumer_callbacks *data, struct buffer_info *buf)
-{
-       char *tmp;
-       int result;
-       int fd;
-       struct buffer_info_local *buf_local =
-               zmalloc(sizeof(struct buffer_info_local));
-
-       if(!buf_local) {
-               ERR("could not allocate buffer_info_local struct");
-               return 1;
-       }
-
-       buf->user_data = buf_local;
-
-       /* open file for output */
-       if(!trace_path) {
-               /* Only create the directory if using the default path, because
-                * of the risk of typo when using trace path override. We don't
-                * want to risk creating plenty of useless directories in that case.
-                */
-               result = create_dir_if_needed(USTCONSUMER_DEFAULT_TRACE_PATH);
-               if(result == -1) {
-                       ERR("could not create directory %s", USTCONSUMER_DEFAULT_TRACE_PATH);
-                       return 1;
-               }
-
-               trace_path = USTCONSUMER_DEFAULT_TRACE_PATH;
-       }
-
-       if (asprintf(&tmp, "%s/%u_%" PRId64 "", trace_path, buf->pid, buf->pidunique) < 0) {
-               ERR("on_open_buffer : asprintf failed (%s/%u_%" PRId64 ")",
-                   trace_path, buf->pid, buf->pidunique);
-               return 1;
-       }
-       result = create_dir_if_needed(tmp);
-       if(result == -1) {
-               ERR("could not create directory %s", tmp);
-               free(tmp);
-               return 1;
-       }
-       free(tmp);
-
-       if (asprintf(&tmp, "%s/%u_%" PRId64 "/%s", trace_path, buf->pid, buf->pidunique, buf->name) < 0) {
-               ERR("on_open_buffer : asprintf failed (%s/%u_%" PRId64 "/%s)",
-                   trace_path, buf->pid, buf->pidunique, buf->name);
-               return 1;
-       }
-again:
-       result = fd = open(tmp, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 00600);
-       if (result == -1 && errno == EINTR)
-               goto again;
-
-       if(result == -1) {
-               PERROR("open");
-               ERR("failed opening trace file %s", tmp);
-               return 1;
-       }
-       buf_local->file_fd = fd;
-       free(tmp);
-
-       return 0;
-}
-
-int on_close_buffer(struct ustconsumer_callbacks *data, struct buffer_info *buf)
-{
-       struct buffer_info_local *buf_local = buf->user_data;
-       int result;
-
-again:
-       result = close(buf_local->file_fd);
-       if (result == -1 && errno == EINTR)
-               goto again;
-       free(buf_local);
-       if(result == -1) {
-               PERROR("close");
-       }
-       return 0;
-}
-
-int on_put_error(struct ustconsumer_callbacks *data, struct buffer_info *buf)
-{
-       return unwrite_last_subbuffer(buf);
-}
-
-struct ustconsumer_callbacks *new_callbacks()
-{
-       struct ustconsumer_callbacks *callbacks =
-               zmalloc(sizeof(struct ustconsumer_callbacks));
-
-       if(!callbacks)
-               return NULL;
-
-       callbacks->on_open_buffer = on_open_buffer;
-       callbacks->on_close_buffer = on_close_buffer;
-       callbacks->on_read_subbuffer = on_read_subbuffer;
-       callbacks->on_read_partial_subbuffer = on_read_partial_subbuffer;
-       callbacks->on_put_error = on_put_error;
-       callbacks->on_new_thread = NULL;
-       callbacks->on_close_thread = NULL;
-       callbacks->on_trace_end = NULL;
-
-       return callbacks;
-
-}
-
-int is_directory(const char *dir)
-{
-       int result;
-       struct stat st;
-
-       result = stat(dir, &st);
-       if(result == -1) {
-               PERROR("stat");
-               return 0;
-       }
-
-       if(!S_ISDIR(st.st_mode)) {
-               return 0;
-       }
-
-       return 1;
-}
-
-void usage(void)
-{
-       fprintf(stderr, "Usage:\nust-consumerd OPTIONS\n\nOptions:\n"
-                       "\t-h\t\tDisplay this usage.\n"
-                       "\t-o DIR\t\tSpecify the directory where to output the traces.\n"
-                       "\t-s PATH\t\tSpecify the path to use for the daemon socket.\n"
-                       "\t-d\t\tStart as a daemon.\n"
-                       "\t--pidfile FILE\tWrite the PID in this file (when using -d).\n");
-}
-
-int parse_args(int argc, char **argv)
-{
-       int c;
-
-       while (1) {
-               int option_index = 0;
-               static struct option long_options[] = {
-                       {"pidfile", 1, 0, 'p'},
-                       {"help", 0, 0, 'h'},
-                       {"version", 0, 0, 'V'},
-                       {0, 0, 0, 0}
-               };
-
-               c = getopt_long(argc, argv, "hs:o:d", long_options, &option_index);
-               if (c == -1)
-                       break;
-
-               switch (c) {
-               case 0:
-                       printf("option %s", long_options[option_index].name);
-                       if (optarg)
-                               printf(" with arg %s", optarg);
-                       printf("\n");
-                       break;
-               case 's':
-                       sock_path = optarg;
-                       break;
-               case 'o':
-                       trace_path = optarg;
-                       if(!is_directory(trace_path)) {
-                               ERR("Not a valid directory. (%s)", trace_path);
-                               return -1;
-                       }
-                       break;
-               case 'd':
-                       daemon_mode = 1;
-                       break;
-               case 'p':
-                       pidfile = strdup(optarg);
-                       break;
-               case 'h':
-                       usage();
-                       exit(0);
-               case 'V':
-                       printf("Version 0.0\n");
-                       break;
-
-               default:
-                       /* unknown option or other error; error is
-                       printed by getopt, just return */
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-void sigterm_handler(int sig)
-{
-       ustconsumer_stop_instance(instance, 0);
-}
-
-int start_ustconsumer(int fd)
-{
-       int result;
-       sigset_t sigset;
-       struct sigaction sa;
-
-       struct ustconsumer_callbacks *callbacks = new_callbacks();
-       if(!callbacks) {
-               PERROR("new_callbacks");
-               return 1;
-       }
-
-       result = sigemptyset(&sigset);
-       if(result == -1) {
-               PERROR("sigemptyset");
-               return 1;
-       }
-       sa.sa_handler = sigterm_handler;
-       sa.sa_mask = sigset;
-       sa.sa_flags = 0;
-       result = sigaction(SIGTERM, &sa, NULL);
-       if(result == -1) {
-               PERROR("sigaction");
-               return 1;
-       }
-       result = sigaction(SIGINT, &sa, NULL);
-       if(result == -1) {
-               PERROR("sigaction");
-               return 1;
-       }
-
-       instance = ustconsumer_new_instance(callbacks, sock_path);
-       if(!instance) {
-               ERR("failed to create ustconsumer instance");
-               return 1;
-       }
-
-       result = ustconsumer_init_instance(instance);
-       if(result) {
-               ERR("failed to initialize ustconsumer instance");
-               return 1;
-       }
-
-       /* setup handler for SIGPIPE */
-       result = sigemptyset(&sigset);
-       if(result == -1) {
-               PERROR("sigemptyset");
-               return 1;
-       }
-       result = sigaddset(&sigset, SIGPIPE);
-       if(result == -1) {
-               PERROR("sigaddset");
-               return 1;
-       }
-       result = sigprocmask(SIG_BLOCK, &sigset, NULL);
-       if(result == -1) {
-               PERROR("sigprocmask");
-               return 1;
-       }
-
-       /* Write pidfile */
-       if(pidfile) {
-               result = write_pidfile(pidfile, getpid());
-               if(result == -1) {
-                       ERR("failed to write pidfile");
-                       return 1;
-               }
-       }
-
-       /* Notify parent that we are successfully started. */
-       if(fd != -1) {
-               /* write any one character */
-               result = write(fd, "!", 1);
-               if(result == -1) {
-                       PERROR("write");
-                       return -1;
-               }
-               if(result != 1) {
-                       ERR("Problem sending confirmation of daemon start to parent");
-                       return -1;
-               }
-               result = close(fd);
-               if(result == -1) {
-                       PERROR("close");
-               }
-       }
-
-       ustconsumer_start_instance(instance);
-
-       free(callbacks);
-
-       return 0;
-}
-
-int start_ustconsumer_daemon()
-{
-       int result;
-       int fd[2];
-       pid_t child_pid;
-
-       result = pipe(fd);
-
-       result = child_pid = fork();
-       if(result == -1) {
-               PERROR("fork");
-               return -1;
-       }
-       else if(result == 0) {
-               return start_ustconsumer(fd[1]);
-       }
-       else {
-               char buf;
-
-               result = read(fd[0], &buf, 1);
-               if(result == -1) {
-                       PERROR("read");
-                       return -1;
-               }
-               if(result != 1) {
-                       ERR("did not receive valid confirmation that the daemon is started");
-                       return -1;
-               }
-
-               result = close(fd[0]);
-               if(result == -1) {
-                       PERROR("close");
-               }
-
-               DBG("The daemon is now successfully started");
-       }
-
-       /* Wait for confirmation that the server is ready. */
-
-
-       return 0;
-}
-
-int main(int argc, char **argv)
-{
-       int result;
-
-       result = parse_args(argc, argv);
-       if(result == -1) {
-               exit(1);
-       }
-
-       if(daemon_mode) {
-               result = start_ustconsumer_daemon();
-       }
-       else {
-               result = start_ustconsumer(-1);
-       }
-
-       return result;
-}
diff --git a/ustctl/Makefile.am b/ustctl/Makefile.am
deleted file mode 100644 (file)
index 1e442a3..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libustcomm \
-       -I$(top_srcdir)/libustctl $(KCOMPAT_CFLAGS)
-AM_CFLAGS = -fno-strict-aliasing
-
-bin_PROGRAMS = ustctl
-
-ustctl_SOURCES = \
-       ustctl.c marker_cmds.c trace_cmds.c channel_cmds.c cli.c cli.h scanning_functions.c scanning_functions.h
-
-ustctl_CFLAGS = -DUST_COMPONENT=ustctl -fno-strict-aliasing
-
-ustctl_LDADD = \
-       $(top_builddir)/snprintf/libustsnprintf.la \
-       $(top_builddir)/libustcomm/libustcomm.la \
-       $(top_builddir)/libustctl/libustctl.la
diff --git a/ustctl/README b/ustctl/README
deleted file mode 100644 (file)
index 3fdfbbd..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-ustctl is a helper application used to control tracing on programs that support tracing.
-
-It can list markers, enable/disable markers, start tracing and stop tracing.
diff --git a/ustctl/channel_cmds.c b/ustctl/channel_cmds.c
deleted file mode 100644 (file)
index 315fd56..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/* Copyright (C) 2011  Ericsson AB, Nils Carlson <nils.carlson@ericsson.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <ust/ustctl.h>
-#include "scanning_functions.h"
-#include "usterr.h"
-#include "cli.h"
-
-static int set_subbuf_size(int argc, char *argv[])
-{
-       int sock, result = 0;
-       char *channel = NULL;
-       unsigned int size;
-
-       sock = parse_and_connect_pid(argv[1]);
-
-       if (scan_ch_and_num(argv[3], &channel, &size)) {
-               fprintf(stderr, "Failed to scan channel and size from"
-                               " %s\n", argv[3]);
-               if (channel)
-                       free(channel);
-               return -1;
-       }
-       if (ustctl_set_subbuf_size(sock, argv[2], channel, size)) {
-               ERR("error while trying to set the size of subbuffers "
-                   "for PID %s\n",
-                   argv[1]);
-               result = -1;
-       }
-
-       free(channel);
-
-       return result;
-}
-
-static int set_subbuf_num(int argc, char *argv[])
-{
-       int sock, result = 0;
-       char *channel = NULL;
-       unsigned int num;
-
-       sock = parse_and_connect_pid(argv[1]);
-
-       if (scan_ch_and_num(argv[3], &channel, &num)) {
-               fprintf(stderr, "Failed to scan channel and number from"
-                               " %s\n", argv[3]);
-               if (channel)
-                       free(channel);
-               return -1;
-       }
-       if (ustctl_set_subbuf_num(sock, argv[2], channel, num)) {
-               ERR("error while trying to set the number of subbuffers for PID %s\n",
-                   argv[1]);
-               result = -1;
-       }
-
-       free(channel);
-
-       return result;
-}
-
-static int get_subbuf_size(int argc, char *argv[])
-{
-       int sock;
-       unsigned int size;
-
-       sock = parse_and_connect_pid(argv[1]);
-
-       if ((size = ustctl_get_subbuf_size(sock, argv[2], argv[3])) < 0) {
-               ERR("error while trying to get the subbuffer size from PID %s\n",
-                   argv[1]);
-               return -1;
-       }
-
-       printf("The subbufer size is %d bytes\n", size);
-
-       return 0;
-}
-
-static int get_subbuf_num(int argc, char *argv[])
-{
-       int sock;
-       unsigned int num;
-
-       sock = parse_and_connect_pid(argv[1]);
-
-       if ((num = ustctl_get_subbuf_num(sock, argv[2], argv[3])) < 0) {
-               ERR("error while trying to get the subbuffer size from PID %s\n",
-                   argv[1]);
-               return -1;
-       }
-
-       printf("There are %u subbufers in each buffer\n", num);
-
-       return 0;
-}
-
-struct cli_cmd __cli_cmds channel_cmds[] = {
-       {
-               .name = "set-subbuf-size",
-               .description = "Set the subbuffer size for a channel",
-               .help_text = "set-subbuf-size <pid> <trace> <channel>/<size> \n"
-               "Set the subbuffer size for a channel\n",
-               .function = set_subbuf_size,
-               .desired_args = 3,
-               .desired_args_op = CLI_EQ,
-       },
-       {
-               .name = "set-subbuf-num",
-               .description = "Set the number of subbuffers for a channel",
-               .help_text = "set-subbuf-num <pid> <trace> <channel>/<num> \n"
-               "Set the number of subbuffers for a channel\n",
-               .function = set_subbuf_num,
-               .desired_args = 3,
-               .desired_args_op = CLI_EQ,
-       },
-       {
-               .name = "get-subbuf-size",
-               .description = "Get the subbuffer size for a channel",
-               .help_text = "get-subbuf-size <pid> <trace> <channel>\n"
-               "Get the subbuffer size for a channel\n",
-               .function = get_subbuf_size,
-               .desired_args = 3,
-               .desired_args_op = CLI_EQ,
-       },
-       {
-               .name = "get-subbuf-num",
-               .description = "Get the number of subbuffers for a channel",
-               .help_text = "get-subbuf-num <pid> <trace> <channel>\n"
-               "Get the number of subbuffers for a channel\n",
-               .function = get_subbuf_num,
-               .desired_args = 3,
-               .desired_args_op = CLI_EQ,
-       },
-};
diff --git a/ustctl/cli.c b/ustctl/cli.c
deleted file mode 100644 (file)
index 0ca9db5..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/* Copyright (C) 2011  Ericsson AB, Nils Carlson <nils.carlson@ericsson.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "cli.h"
-
-/* This dummy command is needed to create the sections in cli.o before
- *  other .o files have these sections, usefull for development.
- */
-static int _dummy(int argc, char *argv[]) {
-       return 0;
-}
-
-/* Define a dummy cmd to guarantee existence of the builtin variables */
-struct cli_cmd __cli_cmds __dummy_cli_cmd[] = {
-       {
-               .name = "_dummy",
-               .description = NULL,
-               .help_text = NULL,
-               .function = _dummy,
-               .desired_args = 0,
-               .desired_args_op = 0,
-       },
-};
-
-extern struct cli_cmd __start___cli_cmds[] __attribute__((visibility("hidden")));
-extern struct cli_cmd __stop___cli_cmds[] __attribute__((visibility("hidden")));
-
-static struct cli_cmd **cli_cmd_list;
-static int cli_cmd_list_size;
-
-static char *process_name;
-
-static int compute_cli_cmds_size(void)
-{
-       long cli_cmds_start, cli_cmds_end;
-
-       cli_cmds_start = (long)__start___cli_cmds;
-       cli_cmds_end = (long)__stop___cli_cmds;
-
-       return (cli_cmds_end - cli_cmds_start) / sizeof(struct cli_cmd);
-}
-
-static void __attribute__((constructor)) generate_cli_cmd_list(int argc, char *argv[])
-{
-       struct cli_cmd *cli_cmd;
-       int section_size, i;
-
-       process_name = basename(argv[0]);
-
-       section_size = compute_cli_cmds_size();
-
-       cli_cmd_list = malloc(section_size * sizeof(void *));
-       if (!cli_cmd_list) {
-               fprintf(stderr, "Failed to allocate command list!");
-               exit(EXIT_FAILURE);
-       }
-
-       cli_cmd_list_size = 0;
-
-       cli_cmd = __start___cli_cmds;
-       for (i = 0; i < section_size; i++) {
-               if (&cli_cmd[i] == &__dummy_cli_cmd[0]) {
-                       continue;
-               }
-
-               if (cli_cmd[i].name) {
-                       cli_cmd_list[cli_cmd_list_size++] = &cli_cmd[i];
-               }
-       }
-}
-
-struct cli_cmd *find_cli_cmd(const char *command)
-{
-       int i;
-
-       for (i = 0; i < cli_cmd_list_size; i++) {
-               if (!strcmp(cli_cmd_list[i]->name, command)) {
-                       return cli_cmd_list[i];
-               }
-       }
-
-       return NULL;
-}
-
-static int cmpcli_cmds(const void *p1, const void *p2)
-{
-       return strcmp(* (char * const *) ((struct cli_cmd *)p1)->name,
-                     * (char * const *) ((struct cli_cmd *)p2)->name);
-}
-
-#define HELP_BUFFER_SIZE 4096
-
-static void print_cmd_help(const char *prefix, const char *infix,
-                          struct cli_cmd *cli_cmd)
-{
-       if (cli_cmd->help_text) {
-               fprintf(stderr, "%s%s%s",
-                       prefix,
-                       infix,
-                       cli_cmd->help_text);
-       } else if (cli_cmd->description) {
-               fprintf(stderr, "%s%s%s\n%s\n",
-                       prefix,
-                       infix,
-                       cli_cmd->name,
-                       cli_cmd->description);
-       } else {
-               fprintf(stderr, "No help available for %s\n",
-                       cli_cmd->name);
-       }
-}
-
-void list_cli_cmds(int option)
-{
-       int i;
-
-       qsort(cli_cmd_list, cli_cmd_list_size, sizeof(void *), cmpcli_cmds);
-
-       for (i = 0; i < cli_cmd_list_size; i++) {
-               switch (option) {
-               case CLI_SIMPLE_LIST:
-                       fprintf(stderr, "%s ", cli_cmd_list[i]->name);
-                       break;
-               case CLI_DESCRIPTIVE_LIST:
-                       fprintf(stderr, "   %-25s%s\n", cli_cmd_list[i]->name,
-                               cli_cmd_list[i]->description);
-                       break;
-               case CLI_EXTENDED_LIST:
-                       print_cmd_help("", "", cli_cmd_list[i]);
-                       fprintf(stderr, "\n");
-                       break;
-               }
-       }
-
-       if (option == CLI_SIMPLE_LIST) {
-               fprintf(stderr, "\n");
-       }
-}
-
-int cli_print_help(const char *command)
-{
-       struct cli_cmd *cli_cmd;
-
-       cli_cmd = find_cli_cmd(command);
-       if (!cli_cmd) {
-               return -1;
-       }
-
-       print_cmd_help(process_name, " ", cli_cmd);
-
-       return 0;
-}
-
-static void cli_check_argc(const char *command, int args,
-                          int operator, int desired_args)
-{
-       switch(operator) {
-       case CLI_EQ:
-               if (args != desired_args)
-                       goto print_error;
-               break;
-       case CLI_GE:
-               if (args < desired_args)
-                       goto print_error;
-               break;
-       }
-
-       return;
-
-print_error:
-       fprintf(stderr, "%s %s requires %s%d argument%s, see usage.\n",
-               process_name, command, operator == CLI_EQ ? "" : "at least ",
-               desired_args, desired_args > 1 ? "s" : "");
-       cli_print_help(command);
-       exit(EXIT_FAILURE);
-}
-
-
-void cli_dispatch_cmd(struct cli_cmd *cmd, int argc, char *argv[])
-{
-       cli_check_argc(cmd->name, argc - 1, cmd->desired_args_op,
-                      cmd->desired_args);
-
-       if (cmd->function(argc, argv)) {
-               exit(EXIT_FAILURE);
-       }
-
-       exit(EXIT_SUCCESS);
-}
diff --git a/ustctl/cli.h b/ustctl/cli.h
deleted file mode 100644 (file)
index a1e4eed..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright (C) 2011  Ericsson AB, Nils Carlson <nils.carlson@ericsson.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-#ifndef _CLI_H
-#define _CLI_H
-
-struct cli_cmd {
-       const char *name;
-       const char *description;
-       const char *help_text;
-       int (*function)(int, char **);
-       int desired_args;
-       int desired_args_op;
-} __attribute__((aligned(8)));
-
-#define __cli_cmds __attribute__((section("__cli_cmds"), aligned(8), used))
-
-struct cli_cmd *find_cli_cmd(const char *command);
-
-enum cli_list_opts {
-       CLI_SIMPLE_LIST,
-       CLI_DESCRIPTIVE_LIST,
-       CLI_EXTENDED_LIST,
-};
-
-void list_cli_cmds(int option);
-
-int cli_print_help(const char *command);
-
-enum cli_arg_ops {
-       CLI_EQ,
-       CLI_GE,
-};
-
-void cli_dispatch_cmd(struct cli_cmd *cmd, int argc, char *argv[]);
-
-#endif /* _CLI_H */
diff --git a/ustctl/marker_cmds.c b/ustctl/marker_cmds.c
deleted file mode 100644 (file)
index 8bcab83..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/* Copyright (C) 2011  Ericsson AB, Nils Carlson <nils.carlson@ericsson.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <ust/ustctl.h>
-#include "scanning_functions.h"
-#include "usterr.h"
-#include "cli.h"
-
-static int list_markers(int argc, char *argv[])
-{
-       struct ust_marker_status *cmsf = NULL;
-       int i, sock;
-
-       sock = parse_and_connect_pid(argv[1]);
-
-       if (ustctl_get_cmsf(sock, &cmsf)) {
-               ERR("error while trying to list markers for PID %s\n", argv[1]);
-               return -1;
-       }
-       for (i = 0; cmsf[i].channel; i++) {
-               printf("{PID: %s, channel/marker: %s/%s, "
-                      "state: %u, fmt: %s}\n",
-                      argv[1],
-                      cmsf[i].channel,
-                      cmsf[i].ust_marker,
-                      cmsf[i].state,
-                      cmsf[i].fs);
-       }
-       ustctl_free_cmsf(cmsf);
-       return 0;
-}
-
-static int enable_marker(int argc, char *argv[])
-{
-       int i, sock, result = 0;
-       char *channel, *marker;
-
-       sock = parse_and_connect_pid(argv[1]);
-
-       for (i = 3; i < argc; i++) {
-               channel = NULL;
-               marker = NULL;
-               if (scan_ch_marker(argv[i],
-                                  &channel, &marker)) {
-                       result = -1;
-                       fprintf(stderr, "Failed to scan channel and marker from"
-                               " %s\n", argv[i]);
-                       if (channel)
-                               free(channel);
-                       if (marker)
-                               free(marker);
-               }
-               if (ustctl_set_ust_marker_state(sock, argv[2], channel, marker, 1)) {
-                       PERROR("error while trying to enable marker %s with PID %s",
-                              argv[i], argv[1]);
-                       result = -1;
-               }
-               free(channel);
-               free(marker);
-       }
-
-       return result;
-}
-
-static int disable_marker(int argc, char *argv[])
-{
-       int i, sock, result = 0;
-       char *channel, *marker;
-
-       sock = parse_and_connect_pid(argv[1]);
-
-       for (i = 3; i < argc; i++) {
-               channel = NULL;
-               marker = NULL;
-               if (scan_ch_marker(argv[i],
-                                  &channel, &marker)) {
-                       fprintf(stderr, "Failed to scan channel and marker from"
-                               " %s\n", argv[i]);
-                       if (channel)
-                               free(channel);
-                       if (marker)
-                               free(marker);
-                       return -1;
-               }
-               if (ustctl_set_ust_marker_state(sock, argv[2], channel, marker, 0)) {
-                       PERROR("error while trying to disable marker %s with PID %s",
-                              argv[i], argv[1]);
-                       result = -1;
-               }
-               free(channel);
-               free(marker);
-       }
-
-       return result;
-}
-
-struct cli_cmd __cli_cmds ust_marker_cmds[] = {
-       {
-               .name = "list-markers",
-               .description = "List markers for a given pid",
-               .help_text = "list-markers <pid>\n"
-               "List the markers in a process\n",
-               .function = list_markers,
-               .desired_args = 1,
-               .desired_args_op = CLI_EQ,
-       },
-       {
-               .name = "enable-marker",
-               .description = "Enable markers for a given pid",
-               .help_text = "enable-marker <pid> <trace> <channel>/<marker>... \n"
-               "Enable the listed markers for the trace in process pid\n",
-               .function = enable_marker,
-               .desired_args = 3,
-               .desired_args_op = CLI_GE,
-       },
-       {
-              .name = "disable-marker",
-              .description = "Disable markers for a given pid",
-              .help_text = "disable-marker <pid> <trace> <channel>/<marker>... \n"
-              "Disable the listed markers for the trace in process pid\n",
-              .function = disable_marker,
-              .desired_args = 3,
-              .desired_args_op = CLI_GE,
-       }
-};
diff --git a/ustctl/scanning_functions.c b/ustctl/scanning_functions.c
deleted file mode 100644 (file)
index 4aa8c1c..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Copyright (C) 2011  Ericsson AB, Nils Carlson <nils.carlson@ericsson.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <ust/ustctl.h>
-#include "usterr.h"
-
-
-int parse_and_connect_pid(const char *pid_string)
-{
-       pid_t pid;
-       int sock;
-
-       errno = 0;
-       pid = strtoull(pid_string, NULL, 10);
-       if (errno) {
-               perror("Failed to parse pid");
-               exit(EXIT_FAILURE);
-       }
-
-       sock = ustctl_connect_pid(pid);
-       if (sock < 0) {
-               perror("Failed to connect to process");
-               exit(EXIT_FAILURE);
-       }
-
-       return sock;
-}
-
-int scan_ch_marker(const char *channel_marker, char **channel, char **marker)
-{
-       int result;
-
-       *channel = NULL;
-       *marker = NULL;
-
-       result = sscanf(channel_marker, "%a[^/]/%as", channel, marker);
-       if (result != 2) {
-               if (errno) {
-                       PERROR("Failed to read channel and marker names");
-               } else {
-                       ERR("Failed to parse marker and channel names");
-               }
-               if (*channel) {
-                       free(*channel);
-               }
-               if (*marker) {
-                       free(*marker);
-               }
-               return -1;
-       }
-
-       return 0;
-}
-
-int scan_ch_and_num(const char *ch_num, char **channel, unsigned int *num)
-{
-       int result;
-
-       *channel = NULL;
-
-       result = sscanf(ch_num, "%a[^/]/%u", channel, num);
-       if (result != 2) {
-               if (errno) {
-                       PERROR("Failed to parse channel and number");
-               } else {
-                       ERR("Failed to parse channel and number");
-               }
-               if (*channel) {
-                       free(*channel);
-               }
-               return -1;
-       }
-
-       return 0;
-}
diff --git a/ustctl/scanning_functions.h b/ustctl/scanning_functions.h
deleted file mode 100644 (file)
index 0f2d62e..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright (C) 2011  Ericsson AB, Nils Carlson <nils.carlson@ericsson.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-#ifndef __SCANNING_FUNCTIONS_H
-#define __SCANNING_FUNCTIONS_H
-
-int parse_and_connect_pid(const char *pid_string);
-
-int scan_ch_marker(const char *channel_marker, char **channel, char **marker);
-
-int scan_ch_and_num(const char *ch_num, char **channel, unsigned int *num);
-
-#endif /* __SCANNING_FUNCTIONS_H */
diff --git a/ustctl/trace_cmds.c b/ustctl/trace_cmds.c
deleted file mode 100644 (file)
index a8f3a9c..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/* Copyright (C) 2011  Ericsson AB, Nils Carlson <nils.carlson@ericsson.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <ust/ustctl.h>
-#include "scanning_functions.h"
-#include "usterr.h"
-#include "cli.h"
-
-
-static int create_trace(int argc, char *argv[])
-{
-       int sock;
-
-       sock = parse_and_connect_pid(argv[1]);
-
-       if (ustctl_create_trace(sock, argv[2])) {
-               ERR("Failed to create trace %s for PID %s\n", argv[2], argv[1]);
-               return -1;
-       }
-
-       return 0;
-}
-
-static int alloc_trace(int argc, char *argv[])
-{
-       int sock;
-
-       sock = parse_and_connect_pid(argv[1]);
-
-       if (ustctl_alloc_trace(sock, argv[2])) {
-               ERR("Failed to allocate trace %s for PID %s\n", argv[2], argv[1]);
-               return -1;
-       }
-       return 0;
-}
-
-static int start_trace(int argc, char *argv[])
-{
-       int sock;
-
-       sock = parse_and_connect_pid(argv[1]);
-
-       if (ustctl_start_trace(sock, argv[2])) {
-               ERR("Failed to start trace %s for PID %s\n", argv[2], argv[1]);
-               return -1;
-       }
-       return 0;
-}
-
-static int stop_trace(int argc, char *argv[])
-{
-       int sock;
-
-       sock = parse_and_connect_pid(argv[1]);
-
-       if (ustctl_stop_trace(sock, argv[2])) {
-               ERR("Failed to stop trace %s for PID %s\n", argv[2], argv[1]);
-               return -1;
-       }
-       return 0;
-}
-
-static int destroy_trace(int argc, char *argv[])
-{
-       int sock;
-
-       sock = parse_and_connect_pid(argv[1]);
-
-       if (ustctl_destroy_trace(sock, argv[2])) {
-               ERR("Failed to destroy trace %s for PID %s\n", argv[2], argv[1]);
-               return -1;
-       }
-       return 0;
-}
-
-static int force_subbuf_switch(int argc, char *argv[])
-{
-       int sock;
-
-       sock = parse_and_connect_pid(argv[1]);
-
-       if (ustctl_force_switch(sock, argv[2])) {
-               ERR("error while trying to force switch for PID %s\n", argv[1]);
-               return -1;
-       }
-
-       return 0;
-}
-
-struct cli_cmd __cli_cmds trace_cmds[] = {
-       {
-               .name = "create-trace",
-               .description = "Create a trace for a process",
-               .help_text = "create-trace <pid> <trace>\n"
-               "Create a trace for a process\n",
-               .function = create_trace,
-               .desired_args = 2,
-               .desired_args_op = CLI_EQ,
-       },
-       {
-               .name = "alloc-trace",
-               .description = "Allocate a trace for a process",
-               .help_text = "alloc-trace <pid> <trace>\n"
-               "Allocate a trace for a process\n",
-               .function = alloc_trace,
-               .desired_args = 2,
-               .desired_args_op = CLI_EQ,
-       },
-       {
-               .name = "start-trace",
-               .description = "Start a trace for a process",
-               .help_text = "start-trace <pid> <trace>\n"
-               "Start a trace for a process\n",
-               .function = start_trace,
-               .desired_args = 2,
-               .desired_args_op = CLI_EQ,
-       },
-       {
-               .name = "stop-trace",
-               .description = "Stop a trace for a process",
-               .help_text = "stop-trace <pid> <trace>\n"
-               "Stop a trace for a process\n",
-               .function = stop_trace,
-               .desired_args = 2,
-               .desired_args_op = CLI_EQ,
-       },
-       {
-               .name = "destroy-trace",
-               .description = "Destroy a trace for a process",
-               .help_text = "destroy-trace <pid> <trace>\n"
-               "Destroy a trace for a process\n",
-               .function = destroy_trace,
-               .desired_args = 2,
-               .desired_args_op = CLI_EQ,
-       },
-       {
-               .name = "force-subbuf-switch",
-               .description = "Force a subbuffer switch",
-               .help_text = "force-subbuf-switch <pid> <trace>\n"
-               "Force a subbuffer switch for a trace, currently this forces\n"
-               "a subbuffer switch for all traces in a process\n",
-               .function = force_subbuf_switch,
-               .desired_args = 2,
-               .desired_args_op = CLI_EQ,
-       },
-};
diff --git a/ustctl/ustctl.c b/ustctl/ustctl.c
deleted file mode 100644 (file)
index 18f7d30..0000000
+++ /dev/null
@@ -1,272 +0,0 @@
-/* Copyright (C) 2009  Pierre-Marc Fournier
- * Copyright (C) 2011  Ericsson AB, Nils Carlson <nils.carlson@ericsson.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <stdlib.h>
-#include <fcntl.h>
-
-#include "ust/ustctl.h"
-#include "usterr.h"
-#include "cli.h"
-#include "scanning_functions.h"
-
-void usage(const char *process_name)
-{
-       fprintf(stderr, "Usage: %s COMMAND [ARGS]...\n", process_name);
-       fprintf(stderr,
-               "Control tracing within a process that supports UST,\n"
-               " the Userspace Tracing libary\n"
-               "Options:\n"
-               "  -h[<cmd>], --help[=<cmd>]        "
-               "help, for a command if provided\n"
-               "  -l, --list                       "
-               "short list of commands\n"
-               "  -e, --extended-list              "
-              "extented list of commands with help\n"
-               "Commands:\n");
-       list_cli_cmds(CLI_DESCRIPTIVE_LIST);
-}
-
-/*
- * Provide backward compatibility for scripts that make use of the
- * --commands in ustctl version <= 0.11
- */
-enum command {
-       CREATE_TRACE=1000,
-       ALLOC_TRACE,
-       START_TRACE,
-       STOP_TRACE,
-       DESTROY_TRACE,
-       LIST_MARKERS,
-       LIST_TRACE_EVENTS,
-       ENABLE_MARKER,
-       DISABLE_MARKER,
-};
-
-struct option options[] =
-{
-       { "create-trace", 0, 0, CREATE_TRACE },
-       { "alloc-trace", 0, 0, ALLOC_TRACE },
-       { "start-trace", 0, 0, START_TRACE },
-       { "stop-trace", 0, 0, STOP_TRACE },
-       { "destroy-trace", 0, 0, DESTROY_TRACE },
-       { "list-markers", 0, 0, LIST_MARKERS },
-       { "list-trace-events", 0, 0, LIST_TRACE_EVENTS},
-       { "enable-marker", 0, 0, ENABLE_MARKER },
-       { "disable-marker", 0, 0, DISABLE_MARKER },
-       {"help", 2, NULL, 'h'},
-       {"list", 0, NULL, 'l'},
-       {"extended-list", 0, NULL, 'e'},
-       {NULL, 0, NULL, 0},
-};
-
-int main(int argc, char *argv[])
-{
-       struct cli_cmd *cli_cmd;
-       char **args = argv;
-       int opt;
-       int i;
-
-       if(argc <= 1) {
-               fprintf(stderr, "No operation specified.\n");
-               usage(argv[0]);
-               exit(EXIT_FAILURE);
-       }
-
-       while ((opt = getopt_long(argc, argv, "+h::le",
-                                 options, NULL)) != -1) {
-               switch (opt) {
-               case 'h':
-                       if (!optarg) {
-                               usage(argv[0]);
-                       } else {
-                               if (cli_print_help(optarg)) {
-                                       fprintf(stderr, "No such command %s\n",
-                                               optarg);
-                               }
-                       }
-                       exit(EXIT_FAILURE);
-                       break;
-               case 'l':
-                       list_cli_cmds(CLI_SIMPLE_LIST);
-                       exit(EXIT_FAILURE);
-                       break;
-               case 'e':
-                       list_cli_cmds(CLI_EXTENDED_LIST);
-                       exit(EXIT_FAILURE);
-               case LIST_MARKERS:
-               case LIST_TRACE_EVENTS:
-               case CREATE_TRACE:
-               case ALLOC_TRACE:
-               case START_TRACE:
-               case STOP_TRACE:
-               case DESTROY_TRACE:
-               case ENABLE_MARKER:
-               case DISABLE_MARKER:
-                       args = (char **)malloc(sizeof(char *) * (argc + 3));
-                       optind--;
-                       args[optind] = strdup(&argv[optind][2]);
-                       for (i = optind + 1; i < argc; i++) {
-                               args[i] = argv[i];
-                       }
-                       if (opt >= CREATE_TRACE && opt <= DESTROY_TRACE) {
-                               args[argc] = strdup("auto");
-                               argc++;
-                       }
-                       if (opt >= ENABLE_MARKER && opt <= DISABLE_MARKER) {
-                               args[argc] = args[argc - 2];
-                               args[argc - 2] = args[argc - 1];
-                               args[argc - 1] = strdup("auto");
-                               argc++;
-                       }
-                       args[argc] = NULL;
-                       goto do_cli;
-               default:
-                       fprintf(stderr, "Unknown option\n");
-                       break;
-               }
-       }
-
-do_cli:
-       cli_cmd = find_cli_cmd(args[optind]);
-       if (!cli_cmd) {
-               fprintf(stderr, "No such command %s\n",
-                       args[optind]);
-               exit(EXIT_FAILURE);
-       }
-
-       cli_dispatch_cmd(cli_cmd, argc - optind, &args[optind]);
-
-       return 0;
-}
-
-static int list_trace_events(int argc, char *argv[])
-{
-       struct trace_event_status *tes = NULL;
-       int i, sock;
-
-       sock = parse_and_connect_pid(argv[1]);
-
-       if (ustctl_get_tes(sock, &tes)) {
-               ERR("error while trying to list "
-                   "trace_events for PID %s\n",
-                   argv[1]);
-               return -1;
-       }
-       i = 0;
-       for (i = 0; tes[i].name; i++) {
-               printf("{PID: %s, trace_event: %s}\n",
-                      argv[1],
-                      tes[i].name);
-       }
-       ustctl_free_tes(tes);
-
-       return 0;
-}
-
-static int set_sock_path(int argc, char *argv[])
-{
-       int sock;
-
-       sock = parse_and_connect_pid(argv[1]);
-
-       if (ustctl_set_sock_path(sock, argv[2])) {
-               ERR("error while trying to set sock path for PID %s\n", argv[1]);
-               return -1;
-       }
-
-       return 0;
-}
-
-static int get_sock_path(int argc, char *argv[])
-{
-       int sock;
-       char *sock_path;
-
-       sock = parse_and_connect_pid(argv[1]);
-
-       if (ustctl_get_sock_path(sock, &sock_path)) {
-               ERR("error while trying to get sock path for PID %s\n", argv[1]);
-               return -1;
-       }
-       printf("The socket path is %s\n", sock_path);
-       free(sock_path);
-
-       return 0;
-}
-
-static int list_pids(int argc, char *argv[])
-{
-       pid_t *pid_list;
-       int i;
-
-       pid_list = ustctl_get_online_pids();
-       if (!pid_list) {
-               return -1;
-       }
-
-       for (i = 0; pid_list[i]; i++) {
-               printf("%ld\n", (long)pid_list[i]);
-       }
-
-       free(pid_list);
-
-       return 0;
-}
-
-struct cli_cmd __cli_cmds general_cmds[] = {
-       {
-               .name = "list-trace-events",
-               .description = "List trace-events for a given pid",
-               .help_text = "list-trace-events <pid>\n"
-               "List the trace-events in a process\n",
-               .function = list_trace_events,
-               .desired_args = 1,
-               .desired_args_op = CLI_EQ,
-       },
-       {
-               .name = "set-sock-path",
-               .description = "Set the path to the consumer daemon socket",
-               .help_text = "set-sock-path <pid> <sock-path>\n"
-               "Set the path to the consumer daemon socket\n",
-               .function = set_sock_path,
-               .desired_args = 2,
-               .desired_args_op = CLI_EQ,
-       },
-       {
-               .name = "get-sock-path",
-               .description = "Get the path to the consumer daemon socket",
-               .help_text = "get-sock-path <pid>\n"
-               "Get the path to the consumer daemon socket\n",
-               .function = get_sock_path,
-               .desired_args = 1,
-               .desired_args_op = CLI_EQ,
-       },
-       {
-               .name = "list-pids",
-               .description = "List traceable pids",
-               .help_text = "list-pids\n"
-               "List the traceable pids for the current user\n",
-               .function = list_pids,
-               .desired_args = 0,
-               .desired_args_op = CLI_EQ,
-       },
-};
This page took 0.124067 seconds and 4 git commands to generate.