From: Nils Carlson Date: Fri, 28 Jan 2011 08:52:08 +0000 (+0100) Subject: Rename libustcmd to libustctl X-Git-Tag: v0.12~72^2 X-Git-Url: http://git.lttng.org/?p=ust.git;a=commitdiff_plain;h=2298f3297443ba26f761e272c45456ed857071bc Rename libustcmd to libustctl This patch renames libustcmd to libustctl mostly because libustctl sounds much better but also to clarify the connection between ustctl and libustctl. Signed-off-by: Nils Carlson Acked-by: Mathieu Desnoyers Acked-by: David Goulet --- diff --git a/Makefile.am b/Makefile.am index 249bf02..6957f07 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,7 +5,7 @@ ACLOCAL_AMFLAGS = -I config # libust and '.' (that contains the linker script). However, '.' # must be installed after libust so it can overwrite libust.so with # the linker script. -SUBDIRS = snprintf libustcomm libustcmd libust . tests libustinstr-malloc libustconsumer ust-consumerd ustctl libustfork include doc +SUBDIRS = snprintf libustcomm libustctl libust . tests libustinstr-malloc libustconsumer ust-consumerd ustctl libustfork include doc EXTRA_DIST = libust.ldscript.in libust-initializer.c libust-initializer.h dist_bin_SCRIPTS = usttrace diff --git a/README b/README index a381c95..b09a1ab 100644 --- a/README +++ b/README @@ -79,11 +79,11 @@ PACKAGE CONTENTS: calls in order to trace across these calls. It _has_ to be LD_PRELOAD'ed in order to hijack calls. In contrast, libust may be linked at build time. - - libustcmd + - libustctl A library to control tracing in other processes. Used by ustctl. - libustcomm - A static library shared between libust, ust-consumerd and libustcmd, that + A static library shared between libust, ust-consumerd and libustctl, that provides functions that allow these components to communicate together. - libustconsumer diff --git a/configure.ac b/configure.ac index c7d966b..2b2962a 100644 --- a/configure.ac +++ b/configure.ac @@ -130,14 +130,14 @@ AC_CONFIG_FILES([ tests/tracepoint/Makefile tests/tracepoint/benchmark/Makefile tests/register_test/Makefile - tests/ustcmd_function_tests/Makefile + tests/libustctl_function_tests/Makefile libustinstr-malloc/Makefile libustfork/Makefile libustconsumer/Makefile ust-consumerd/Makefile ustctl/Makefile libustcomm/Makefile - libustcmd/Makefile + libustctl/Makefile snprintf/Makefile ]) AC_OUTPUT diff --git a/doc/info/ust.texi b/doc/info/ust.texi index 73a8bcd..83c91e0 100644 --- a/doc/info/ust.texi +++ b/doc/info/ust.texi @@ -91,7 +91,7 @@ Components licensed as LGPL v2.1: Components licensed as GPL v2: @itemize @bullet @item ustctl -@item libustcmd +@item libustctl @item ust-consumerd @end itemize diff --git a/include/Makefile.am b/include/Makefile.am index 400e8b1..e703ffd 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -17,7 +17,7 @@ nobase_include_HEADERS = \ ust/kcompat/simple.h \ ust/kcompat/types.h \ ust/kcompat/stringify.h \ - ust/ustcmd.h \ + ust/ustctl.h \ ust/ustconsumer.h noinst_HEADERS = share.h usterr.h ust_snprintf.h diff --git a/include/ust/ustcmd.h b/include/ust/ustcmd.h deleted file mode 100644 index 6273575..0000000 --- a/include/ust/ustcmd.h +++ /dev/null @@ -1,76 +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 _USTCMD_H -#define _USTCMD_H - -#include -#include -#include -#include -#include - -#define USTCMD_ERR_CONN 1 /* Process connection error */ -#define USTCMD_ERR_ARG 2 /* Invalid function argument */ -#define USTCMD_ERR_GEN 3 /* General ustcmd error */ - -#define USTCMD_MS_CHR_OFF '0' /* Marker state 'on' character */ -#define USTCMD_MS_CHR_ON '1' /* Marker state 'on' character */ -#define USTCMD_MS_OFF 0 /* Marker state 'on' value */ -#define USTCMD_MS_ON 1 /* Marker state 'on' value */ - -#define USTCMD_SOCK_PATH "/tmp/socks/" - -/* Channel/marker/state/format string (cmsf) info. structure */ -struct marker_status { - char *channel; /* Channel name (end of marker_status array if NULL) */ - char *marker; /* Marker name (end of marker_status array if NULL) */ - int state; /* State (0 := marker disabled, 1 := marker enabled) */ - char *fs; /* Format string (end of marker_status array if NULL) */ -}; - -struct trace_event_status { - char *name; -}; - -extern pid_t *ustcmd_get_online_pids(void); -extern int ustcmd_set_marker_state(const char *trace, const char *channel, - const char *marker, int state, pid_t pid); -extern int ustcmd_set_subbuf_size(const char *trace, const char *channel, - unsigned int subbuf_size, pid_t pid); -extern int ustcmd_set_subbuf_num(const char *trace, const char *channel, - unsigned int num, pid_t pid); -extern int ustcmd_get_subbuf_size(const char *trace, const char *channel, - pid_t pid); -extern int ustcmd_get_subbuf_num(const char *trace, const char *channel, - pid_t pid); -extern int ustcmd_destroy_trace(const char *trace, pid_t pid); -extern int ustcmd_setup_and_start(const char *trace, pid_t pid); -extern int ustcmd_stop_trace(const char *trace, pid_t pid); -extern int ustcmd_create_trace(const char *trace, pid_t pid); -extern int ustcmd_start_trace(const char *trace, pid_t pid); -extern int ustcmd_alloc_trace(const char *trace, pid_t pid); -extern int ustcmd_free_cmsf(struct marker_status *); -extern unsigned int ustcmd_count_nl(const char *); -extern int ustcmd_get_cmsf(struct marker_status **, pid_t); -extern int ustcmd_free_tes(struct trace_event_status *); -extern int ustcmd_get_tes(struct trace_event_status **, pid_t); -extern int ustcmd_set_sock_path(const char *sock_path, pid_t pid); -extern int ustcmd_get_sock_path(char **sock_path, pid_t pid); -extern int ustcmd_force_switch(pid_t pid); - -#endif /* _USTCMD_H */ diff --git a/include/ust/ustctl.h b/include/ust/ustctl.h new file mode 100644 index 0000000..195ee26 --- /dev/null +++ b/include/ust/ustctl.h @@ -0,0 +1,76 @@ +/* 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 _USTCTL_H +#define _USTCTL_H + +#include +#include +#include +#include +#include + +#define USTCTL_ERR_CONN 1 /* Process connection error */ +#define USTCTL_ERR_ARG 2 /* Invalid function argument */ +#define USTCTL_ERR_GEN 3 /* General ustctl error */ + +#define USTCTL_MS_CHR_OFF '0' /* Marker state 'on' character */ +#define USTCTL_MS_CHR_ON '1' /* Marker state 'on' character */ +#define USTCTL_MS_OFF 0 /* Marker state 'on' value */ +#define USTCTL_MS_ON 1 /* Marker state 'on' value */ + +#define USTCTL_SOCK_PATH "/tmp/socks/" + +/* Channel/marker/state/format string (cmsf) info. structure */ +struct marker_status { + char *channel; /* Channel name (end of marker_status array if NULL) */ + char *marker; /* Marker name (end of marker_status array if NULL) */ + int state; /* State (0 := marker disabled, 1 := marker enabled) */ + char *fs; /* Format string (end of marker_status array if NULL) */ +}; + +struct trace_event_status { + char *name; +}; + +extern pid_t *ustctl_get_online_pids(void); +extern int ustctl_set_marker_state(const char *trace, const char *channel, + const char *marker, int state, pid_t pid); +extern int ustctl_set_subbuf_size(const char *trace, const char *channel, + unsigned int subbuf_size, pid_t pid); +extern int ustctl_set_subbuf_num(const char *trace, const char *channel, + unsigned int num, pid_t pid); +extern int ustctl_get_subbuf_size(const char *trace, const char *channel, + pid_t pid); +extern int ustctl_get_subbuf_num(const char *trace, const char *channel, + pid_t pid); +extern int ustctl_destroy_trace(const char *trace, pid_t pid); +extern int ustctl_setup_and_start(const char *trace, pid_t pid); +extern int ustctl_stop_trace(const char *trace, pid_t pid); +extern int ustctl_create_trace(const char *trace, pid_t pid); +extern int ustctl_start_trace(const char *trace, pid_t pid); +extern int ustctl_alloc_trace(const char *trace, pid_t pid); +extern int ustctl_free_cmsf(struct marker_status *); +extern unsigned int ustctl_count_nl(const char *); +extern int ustctl_get_cmsf(struct marker_status **, pid_t); +extern int ustctl_free_tes(struct trace_event_status *); +extern int ustctl_get_tes(struct trace_event_status **, pid_t); +extern int ustctl_set_sock_path(const char *sock_path, pid_t pid); +extern int ustctl_get_sock_path(char **sock_path, pid_t pid); +extern int ustctl_force_switch(pid_t pid); + +#endif /* _USTCTL_H */ diff --git a/libustcmd/Makefile.am b/libustcmd/Makefile.am deleted file mode 100644 index f467244..0000000 --- a/libustcmd/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libustcomm -AM_CFLAGS = -fno-strict-aliasing - -lib_LTLIBRARIES = libustcmd.la - -libustcmd_la_SOURCES = \ - ustcmd.c - -libustcmd_la_LDFLAGS = -no-undefined -version-info 0:0:0 - -libustcmd_la_LIBADD = \ - $(top_builddir)/libustcomm/libustcomm.la - -libustcmd_la_CFLAGS = -DUST_COMPONENT="libustcmd" -fno-strict-aliasing diff --git a/libustcmd/README b/libustcmd/README deleted file mode 100644 index 8c2819a..0000000 --- a/libustcmd/README +++ /dev/null @@ -1,2 +0,0 @@ -libustcmd is a library that provides an API and its implementation to send -commands to traceable processes. diff --git a/libustcmd/ustcmd.c b/libustcmd/ustcmd.c deleted file mode 100644 index 62c117f..0000000 --- a/libustcmd/ustcmd.c +++ /dev/null @@ -1,671 +0,0 @@ -/* Copyright (C) 2009 Pierre-Marc Fournier, Philippe Proulx-Barrette - * - * 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 -#include -#include -#include -#include -#include -#include - -#include "ustcomm.h" -#include "ust/ustcmd.h" -#include "usterr.h" - -static int do_cmd(const pid_t pid, - const struct ustcomm_header *req_header, - const char *req_data, - struct ustcomm_header *res_header, - char **res_data) -{ - int app_fd, result, saved_errno = 0; - char *recv_buf; - - if (ustcomm_connect_app(pid, &app_fd)) { - ERR("could not connect to PID %u", (unsigned int) pid); - errno = ENOTCONN; - return -1; - } - - recv_buf = zmalloc(USTCOMM_BUFFER_SIZE); - if (!recv_buf) { - saved_errno = ENOMEM; - goto close_app_fd; - } - - result = ustcomm_req(app_fd, 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); - } - -close_app_fd: - close(app_fd); - - errno = saved_errno; - - if (errno) { - return -1; - } - - return 0; -} - -pid_t *ustcmd_get_online_pids(void) -{ - struct dirent *dirent; - DIR *dir; - unsigned int ret_size = 1 * sizeof(pid_t), i = 0; - - dir = opendir(SOCK_DIR); - if (!dir) { - return NULL; - } - - pid_t *ret = (pid_t *) malloc(ret_size); - - while ((dirent = readdir(dir))) { - if (!strcmp(dirent->d_name, ".") || - !strcmp(dirent->d_name, "..")) { - - continue; - } - - if (dirent->d_type != DT_DIR && - !!strcmp(dirent->d_name, "ust-consumer")) { - - sscanf(dirent->d_name, "%u", (unsigned int *) &ret[i]); - /* FIXME: Here we previously called pid_is_online, which - * always returned 1, now I replaced it with just 1. - * We need to figure out an intelligent way of solving - * this, maybe connect-disconnect. - */ - if (1) { - ret_size += sizeof(pid_t); - ret = (pid_t *) realloc(ret, ret_size); - ++i; - } - } - } - - ret[i] = 0; /* Array end */ - - if (ret[0] == 0) { - /* No PID at all */ - free(ret); - return NULL; - } - - closedir(dir); - return ret; -} - -/** - * Sets marker state (USTCMD_MS_ON or USTCMD_MS_OFF). - * - * @param mn Marker name - * @param state Marker's new state - * @param pid Traced process ID - * @return 0 if successful, or errors {USTCMD_ERR_GEN, USTCMD_ERR_ARG} - */ -int ustcmd_set_marker_state(const char *trace, const char *channel, - const char *marker, int state, pid_t pid) -{ - struct ustcomm_header req_header, res_header; - struct ustcomm_marker_info marker_inf; - int result; - - result = ustcomm_pack_marker_info(&req_header, - &marker_inf, - trace, - channel, - marker); - if (result < 0) { - errno = -result; - return -1; - } - - req_header.command = state ? ENABLE_MARKER : DISABLE_MARKER; - - return do_cmd(pid, &req_header, (char *)&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 ustcmd_set_subbuf_size(const char *trace, const char *channel, - unsigned int subbuf_size, pid_t pid) -{ - 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(pid, &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 ustcmd_set_subbuf_num(const char *trace, const char *channel, - unsigned int num, pid_t pid) -{ - 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(pid, &req_header, (char *)&ch_inf, - &res_header, NULL); - -} - -static int ustcmd_get_subbuf_num_size(const char *trace, const char *channel, - pid_t pid, 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(pid, &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 ustcmd_get_subbuf_num(const char *trace, const char *channel, pid_t pid) -{ - int num, size, result; - - result = ustcmd_get_subbuf_num_size(trace, channel, pid, - &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 ustcmd_get_subbuf_size(const char *trace, const char *channel, pid_t pid) -{ - int num, size, result; - - result = ustcmd_get_subbuf_num_size(trace, channel, pid, - &num, &size); - if (result < 0) { - errno = -result; - return -1; - } - - return size; -} - - -static int do_trace_cmd(const char *trace, pid_t pid, 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(pid, &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 USTCMD_ERR_GEN - */ -int ustcmd_destroy_trace(const char *trace, pid_t pid) -{ - return do_trace_cmd(trace, pid, DESTROY_TRACE); -} - -/** - * Starts an UST trace (and setups it) according to a PID. - * - * @param pid Traced process ID - * @return 0 if successful, or error USTCMD_ERR_GEN - */ -int ustcmd_setup_and_start(const char *trace, pid_t pid) -{ - return do_trace_cmd(trace, pid, START); -} - -/** - * Creates an UST trace according to a PID. - * - * @param pid Traced process ID - * @return 0 if successful, or error USTCMD_ERR_GEN - */ -int ustcmd_create_trace(const char *trace, pid_t pid) -{ - return do_trace_cmd(trace, pid, CREATE_TRACE); -} - -/** - * Starts an UST trace according to a PID. - * - * @param pid Traced process ID - * @return 0 if successful, or error USTCMD_ERR_GEN - */ -int ustcmd_start_trace(const char *trace, pid_t pid) -{ - return do_trace_cmd(trace, pid, START_TRACE); -} - -/** - * Alloc an UST trace according to a PID. - * - * @param pid Traced process ID - * @return 0 if successful, or error USTCMD_ERR_GEN - */ -int ustcmd_alloc_trace(const char *trace, pid_t pid) -{ - return do_trace_cmd(trace, pid, ALLOC_TRACE); -} - -/** - * Stops an UST trace according to a PID. - * - * @param pid Traced process ID - * @return 0 if successful, or error USTCMD_ERR_GEN - */ -int ustcmd_stop_trace(const char *trace, pid_t pid) -{ - return do_trace_cmd(trace, pid, STOP_TRACE); -} - -/** - * Counts newlines ('\n') in a string. - * - * @param str String to search in - * @return Total newlines count - */ -unsigned int ustcmd_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 USTCMD_ERR_ARG - */ -int ustcmd_free_cmsf(struct marker_status *cmsf) -{ - if (cmsf == NULL) { - return USTCMD_ERR_ARG; - } - - unsigned int i = 0; - while (cmsf[i].channel != NULL) { - free(cmsf[i].channel); - free(cmsf[i].marker); - free(cmsf[i].fs); - ++i; - } - free(cmsf); - - return 0; -} - -/** - * Gets channel/marker/state/format string for a given PID. - * - * @param cmsf Pointer to CMSF array to be filled (callee allocates, caller - * frees with `ustcmd_free_cmsf') - * @param pid Targeted PID - * @return 0 if successful, or -1 on error - */ -int ustcmd_get_cmsf(struct marker_status **cmsf, const pid_t pid) -{ - struct ustcomm_header req_header, res_header; - char *big_str = NULL; - int result, app_fd; - struct marker_status *tmp_cmsf = NULL; - unsigned int i = 0, cmsf_ind = 0; - - if (cmsf == NULL) { - return -1; - } - - if (ustcomm_connect_app(pid, &app_fd)) { - ERR("could not connect to PID %u", (unsigned int) pid); - return -1; - } - - req_header.command = LIST_MARKERS; - req_header.size = 0; - - result = ustcomm_send(app_fd, &req_header, NULL); - if (result <= 0) { - PERROR("error while requesting markers list for process %d", pid); - return -1; - } - - result = ustcomm_recv_alloc(app_fd, &res_header, &big_str); - if (result <= 0) { - ERR("error while receiving markers list"); - return -1; - } - - close(app_fd); - - tmp_cmsf = (struct marker_status *) zmalloc(sizeof(struct marker_status) * - (ustcmd_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, "marker: %a[^/]/%a[^ ] %c %a[^\n]", - &tmp_cmsf[cmsf_ind].channel, - &tmp_cmsf[cmsf_ind].marker, - &state, - &tmp_cmsf[cmsf_ind].fs); - tmp_cmsf[cmsf_ind].state = (state == USTCMD_MS_CHR_ON ? - USTCMD_MS_ON : USTCMD_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].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 USTCMD_ERR_ARG - */ -int ustcmd_free_tes(struct trace_event_status *tes) -{ - if (tes == NULL) { - return USTCMD_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 `ustcmd_free_tes') - * @param pid Targeted PID - * @return 0 if successful, or -1 on error - */ -int ustcmd_get_tes(struct trace_event_status **tes, - const pid_t pid) -{ - struct ustcomm_header req_header, res_header; - char *big_str = NULL; - int result, app_fd; - struct trace_event_status *tmp_tes = NULL; - unsigned int i = 0, tes_ind = 0; - - if (tes == NULL) { - return -1; - } - - if (ustcomm_connect_app(pid, &app_fd)) { - ERR("could not connect to PID %u", (unsigned int) pid); - return -1; - } - - req_header.command = LIST_TRACE_EVENTS; - req_header.size = 0; - - result = ustcomm_send(app_fd, &req_header, NULL); - if (result != 1) { - ERR("error while requesting trace_event list"); - return -1; - } - - result = ustcomm_recv_alloc(app_fd, &res_header, &big_str); - if (result != 1) { - ERR("error while receiving markers list"); - return -1; - } - - close(app_fd); - - tmp_tes = (struct trace_event_status *) - zmalloc(sizeof(struct trace_event_status) * - (ustcmd_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 socket path - * - * @param sock_path Socket path - * @param pid Traced process ID - * @return 0 if successful, or error - */ -int ustcmd_set_sock_path(const char *sock_path, pid_t pid) -{ - 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(pid, &req_header, (char *)&sock_path_msg, - &res_header, NULL); -} - -/** - * Get socket path - * - * @param sock_path Pointer to where the socket path will be returned - * @param pid Traced process ID - * @return 0 if successful, or error - */ -int ustcmd_get_sock_path(char **sock_path, pid_t pid) -{ - 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(pid, &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; -} - -int ustcmd_force_switch(pid_t pid) -{ - struct ustcomm_header req_header, res_header; - - req_header.command = FORCE_SUBBUF_SWITCH; - req_header.size = 0; - - return do_cmd(pid, &req_header, NULL, &res_header, NULL); -} - diff --git a/libustctl/Makefile.am b/libustctl/Makefile.am new file mode 100644 index 0000000..bc7526b --- /dev/null +++ b/libustctl/Makefile.am @@ -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/libustctl/README b/libustctl/README new file mode 100644 index 0000000..fd4cc97 --- /dev/null +++ b/libustctl/README @@ -0,0 +1,2 @@ +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 new file mode 100644 index 0000000..9c4ced2 --- /dev/null +++ b/libustctl/libustctl.c @@ -0,0 +1,671 @@ +/* Copyright (C) 2009 Pierre-Marc Fournier, Philippe Proulx-Barrette + * + * 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 +#include +#include +#include +#include +#include +#include + +#include "ustcomm.h" +#include "ust/ustctl.h" +#include "usterr.h" + +static int do_cmd(const pid_t pid, + const struct ustcomm_header *req_header, + const char *req_data, + struct ustcomm_header *res_header, + char **res_data) +{ + int app_fd, result, saved_errno = 0; + char *recv_buf; + + if (ustcomm_connect_app(pid, &app_fd)) { + ERR("could not connect to PID %u", (unsigned int) pid); + errno = ENOTCONN; + return -1; + } + + recv_buf = zmalloc(USTCOMM_BUFFER_SIZE); + if (!recv_buf) { + saved_errno = ENOMEM; + goto close_app_fd; + } + + result = ustcomm_req(app_fd, 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); + } + +close_app_fd: + close(app_fd); + + errno = saved_errno; + + if (errno) { + return -1; + } + + return 0; +} + +pid_t *ustctl_get_online_pids(void) +{ + struct dirent *dirent; + DIR *dir; + unsigned int ret_size = 1 * sizeof(pid_t), i = 0; + + dir = opendir(SOCK_DIR); + if (!dir) { + return NULL; + } + + pid_t *ret = (pid_t *) malloc(ret_size); + + while ((dirent = readdir(dir))) { + if (!strcmp(dirent->d_name, ".") || + !strcmp(dirent->d_name, "..")) { + + continue; + } + + if (dirent->d_type != DT_DIR && + !!strcmp(dirent->d_name, "ust-consumer")) { + + sscanf(dirent->d_name, "%u", (unsigned int *) &ret[i]); + /* FIXME: Here we previously called pid_is_online, which + * always returned 1, now I replaced it with just 1. + * We need to figure out an intelligent way of solving + * this, maybe connect-disconnect. + */ + if (1) { + ret_size += sizeof(pid_t); + ret = (pid_t *) realloc(ret, ret_size); + ++i; + } + } + } + + ret[i] = 0; /* Array end */ + + if (ret[0] == 0) { + /* No PID at all */ + free(ret); + return NULL; + } + + closedir(dir); + return ret; +} + +/** + * Sets 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_marker_state(const char *trace, const char *channel, + const char *marker, int state, pid_t pid) +{ + struct ustcomm_header req_header, res_header; + struct ustcomm_marker_info marker_inf; + int result; + + result = ustcomm_pack_marker_info(&req_header, + &marker_inf, + trace, + channel, + marker); + if (result < 0) { + errno = -result; + return -1; + } + + req_header.command = state ? ENABLE_MARKER : DISABLE_MARKER; + + return do_cmd(pid, &req_header, (char *)&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(const char *trace, const char *channel, + unsigned int subbuf_size, pid_t pid) +{ + 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(pid, &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(const char *trace, const char *channel, + unsigned int num, pid_t pid) +{ + 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(pid, &req_header, (char *)&ch_inf, + &res_header, NULL); + +} + +static int ustctl_get_subbuf_num_size(const char *trace, const char *channel, + pid_t pid, 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(pid, &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(const char *trace, const char *channel, pid_t pid) +{ + int num, size, result; + + result = ustctl_get_subbuf_num_size(trace, channel, pid, + &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(const char *trace, const char *channel, pid_t pid) +{ + int num, size, result; + + result = ustctl_get_subbuf_num_size(trace, channel, pid, + &num, &size); + if (result < 0) { + errno = -result; + return -1; + } + + return size; +} + + +static int do_trace_cmd(const char *trace, pid_t pid, 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(pid, &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(const char *trace, pid_t pid) +{ + return do_trace_cmd(trace, pid, 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(const char *trace, pid_t pid) +{ + return do_trace_cmd(trace, pid, 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(const char *trace, pid_t pid) +{ + return do_trace_cmd(trace, pid, 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(const char *trace, pid_t pid) +{ + return do_trace_cmd(trace, pid, 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(const char *trace, pid_t pid) +{ + return do_trace_cmd(trace, pid, ALLOC_TRACE); +} + +/** + * 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(const char *trace, pid_t pid) +{ + return do_trace_cmd(trace, pid, 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 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].marker); + free(cmsf[i].fs); + ++i; + } + free(cmsf); + + return 0; +} + +/** + * Gets channel/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(struct marker_status **cmsf, const pid_t pid) +{ + struct ustcomm_header req_header, res_header; + char *big_str = NULL; + int result, app_fd; + struct marker_status *tmp_cmsf = NULL; + unsigned int i = 0, cmsf_ind = 0; + + if (cmsf == NULL) { + return -1; + } + + if (ustcomm_connect_app(pid, &app_fd)) { + ERR("could not connect to PID %u", (unsigned int) pid); + return -1; + } + + req_header.command = LIST_MARKERS; + req_header.size = 0; + + result = ustcomm_send(app_fd, &req_header, NULL); + if (result <= 0) { + PERROR("error while requesting markers list for process %d", pid); + return -1; + } + + result = ustcomm_recv_alloc(app_fd, &res_header, &big_str); + if (result <= 0) { + ERR("error while receiving markers list"); + return -1; + } + + close(app_fd); + + tmp_cmsf = (struct marker_status *) zmalloc(sizeof(struct 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, "marker: %a[^/]/%a[^ ] %c %a[^\n]", + &tmp_cmsf[cmsf_ind].channel, + &tmp_cmsf[cmsf_ind].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].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(struct trace_event_status **tes, + const pid_t pid) +{ + struct ustcomm_header req_header, res_header; + char *big_str = NULL; + int result, app_fd; + struct trace_event_status *tmp_tes = NULL; + unsigned int i = 0, tes_ind = 0; + + if (tes == NULL) { + return -1; + } + + if (ustcomm_connect_app(pid, &app_fd)) { + ERR("could not connect to PID %u", (unsigned int) pid); + return -1; + } + + req_header.command = LIST_TRACE_EVENTS; + req_header.size = 0; + + result = ustcomm_send(app_fd, &req_header, NULL); + if (result != 1) { + ERR("error while requesting trace_event list"); + return -1; + } + + result = ustcomm_recv_alloc(app_fd, &res_header, &big_str); + if (result != 1) { + ERR("error while receiving markers list"); + return -1; + } + + close(app_fd); + + 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 socket path + * + * @param sock_path Socket path + * @param pid Traced process ID + * @return 0 if successful, or error + */ +int ustctl_set_sock_path(const char *sock_path, pid_t pid) +{ + 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(pid, &req_header, (char *)&sock_path_msg, + &res_header, NULL); +} + +/** + * Get socket path + * + * @param sock_path Pointer to where the socket path will be returned + * @param pid Traced process ID + * @return 0 if successful, or error + */ +int ustctl_get_sock_path(char **sock_path, pid_t pid) +{ + 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(pid, &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; +} + +int ustctl_force_switch(pid_t pid) +{ + struct ustcomm_header req_header, res_header; + + req_header.command = FORCE_SUBBUF_SWITCH; + req_header.size = 0; + + return do_cmd(pid, &req_header, NULL, &res_header, NULL); +} + diff --git a/tests/Makefile.am b/tests/Makefile.am index 526f81c..e4e06ce 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = . hello hello2 basic basic_long fork simple_include snprintf test-nevents test-libustinstr-malloc dlopen same_line_marker trace_event register_test tracepoint ustcmd_function_tests +SUBDIRS = . hello hello2 basic basic_long fork simple_include snprintf test-nevents test-libustinstr-malloc dlopen same_line_marker trace_event register_test tracepoint libustctl_function_tests dist_noinst_SCRIPTS = test_loop runtests trace_matches diff --git a/tests/libustctl_function_tests/Makefile.am b/tests/libustctl_function_tests/Makefile.am new file mode 100644 index 0000000..723b456 --- /dev/null +++ b/tests/libustctl_function_tests/Makefile.am @@ -0,0 +1,10 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/tests/ + +noinst_PROGRAMS = libustctl_function_tests +libustctl_function_tests_SOURCES = libustctl_function_tests.c +libustctl_function_tests_LDADD = $(top_builddir)/libust/libust.la \ + $(top_builddir)/libustctl/libustctl.la \ + $(top_builddir)/libust-initializer.o \ + $(top_builddir)/tests/libtap.la \ + -lpthread + diff --git a/tests/libustctl_function_tests/libustctl_function_tests.c b/tests/libustctl_function_tests/libustctl_function_tests.c new file mode 100644 index 0000000..784ff5d --- /dev/null +++ b/tests/libustctl_function_tests/libustctl_function_tests.c @@ -0,0 +1,184 @@ +/* Copyright (C) 2010 Nils Carlson + * + * 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 + */ + +/* Simple function tests for ustctl */ + +#include +#include +#include + +#include +#include + +#include "tap.h" + +static void ustctl_function_tests(pid_t pid) +{ + int result; + unsigned int subbuf_size, subbuf_num; + unsigned int new_subbuf_size, new_subbuf_num; + struct marker_status *marker_status, *ms_ptr; + char *old_socket_path, *new_socket_path; + char *tmp_ustd_socket = "/tmp/tmp_ustd_socket"; + char *trace = "auto"; + + printf("Connecting to pid %d\n", pid); + + /* marker status array functions */ + result = ustctl_get_cmsf(&marker_status, pid); + tap_ok(!result, "ustctl_get_cmsf"); + + result = 0; + for (ms_ptr = marker_status; ms_ptr->channel; ms_ptr++) { + if (!strcmp(ms_ptr->channel, "ust") && + !strcmp(ms_ptr->marker, "bar")) { + result = 1; + } + } + tap_ok(result, "Found channel \"ust\", marker \"bar\""); + + tap_ok(!ustctl_free_cmsf(marker_status), "ustctl_free_cmsf"); + + /* Get and set the socket path */ + tap_ok(!ustctl_get_sock_path(&old_socket_path, pid), + "ustctl_get_sock_path"); + + printf("Socket path: %s\n", old_socket_path); + + tap_ok(!ustctl_set_sock_path(tmp_ustd_socket, pid), + "ustctl_set_sock_path - set a new path"); + + tap_ok(!ustctl_get_sock_path(&new_socket_path, pid), + "ustctl_get_sock_path - get the new path"); + + tap_ok(!strcmp(new_socket_path, tmp_ustd_socket), + "Compare the set path and the retrieved path"); + + free(new_socket_path); + + tap_ok(!ustctl_set_sock_path(old_socket_path, pid), + "Reset the socket path"); + + free(old_socket_path); + + /* Enable, disable markers */ + tap_ok(!ustctl_set_marker_state(trace, "ust", "bar", 1, pid), + "ustctl_set_marker_state - existing marker ust bar"); + + /* Create and allocate a trace */ + tap_ok(!ustctl_create_trace(trace, pid), "ustctl_create_trace"); + + tap_ok(!ustctl_alloc_trace(trace, pid), "ustctl_alloc_trace"); + + /* Get subbuf size and number */ + subbuf_num = ustctl_get_subbuf_num(trace, "ust", pid); + tap_ok(subbuf_num > 0, "ustctl_get_subbuf_num - %d sub-buffers", + subbuf_num); + + subbuf_size = ustctl_get_subbuf_size(trace, "ust", pid); + tap_ok(subbuf_size, "ustctl_get_subbuf_size - sub-buffer size is %d", + subbuf_size); + + /* Start the trace */ + tap_ok(!ustctl_start_trace(trace, pid), "ustctl_start_trace"); + + + /* Stop the trace and destroy it*/ + tap_ok(!ustctl_stop_trace(trace, pid), "ustctl_stop_trace"); + + tap_ok(!ustctl_destroy_trace(trace, pid), "ustctl_destroy_trace"); + + /* Create a new trace */ + tap_ok(!ustctl_create_trace(trace, pid), "ustctl_create_trace - create a new trace"); + + printf("Setting new subbufer number and sizes (doubling)\n"); + new_subbuf_num = 2 * subbuf_num; + new_subbuf_size = 2 * subbuf_size; + + tap_ok(!ustctl_set_subbuf_num(trace, "ust", new_subbuf_num, pid), + "ustctl_set_subbuf_num"); + + tap_ok(!ustctl_set_subbuf_size(trace, "ust", new_subbuf_size, pid), + "ustctl_set_subbuf_size"); + + + /* Allocate the new trace */ + tap_ok(!ustctl_alloc_trace(trace, pid), "ustctl_alloc_trace - allocate the new trace"); + + + /* Get subbuf size and number and compare with what was set */ + subbuf_num = ustctl_get_subbuf_num(trace, "ust", pid); + + subbuf_size = ustctl_get_subbuf_size(trace, "ust", pid); + + tap_ok(subbuf_num == new_subbuf_num, "Set a new subbuf number, %d == %d", + subbuf_num, new_subbuf_num); + + + result = ustctl_get_subbuf_size(trace, "ust", pid); + tap_ok(subbuf_size == new_subbuf_size, "Set a new subbuf size, %d == %d", + subbuf_size, new_subbuf_size); + + tap_ok(!ustctl_destroy_trace(trace, pid), "ustctl_destroy_trace - without ever starting"); + + + printf("##### Tests that definetly should work are completed #####\n"); + printf("############## Start expected failure cases ##############\n"); + + tap_ok(ustctl_set_marker_state(trace, "ust","bar", 1, pid), + "Enable already enabled marker ust/bar"); + + tap_ok(ustctl_set_marker_state(trace, "ustl", "blar", 1, pid), + "Enable non-existent marker ustl blar"); + + tap_ok(ustctl_start_trace(trace, pid), + "Start a non-existent trace"); + + tap_ok(ustctl_destroy_trace(trace, pid), + "Destroy non-existent trace"); + + exit(tap_status() ? EXIT_FAILURE : EXIT_SUCCESS); + +} + + +int main() +{ + int i, status, pipefd[2]; + pid_t parent_pid, child_pid; + FILE *pipe_file; + + tap_plan(27); + + printf("Function tests for ustctl\n"); + + parent_pid = getpid(); + child_pid = fork(); + if (child_pid) { + for(i=0; i<10; i++) { + trace_mark(ust, bar, "str %s", "FOOBAZ"); + trace_mark(ust, bar2, "number1 %d number2 %d", 53, 9800); + usleep(100000); + } + + wait(&status); + } else { + ustctl_function_tests(parent_pid); + } + + exit(status ? EXIT_FAILURE : EXIT_SUCCESS); +} diff --git a/tests/runtests b/tests/runtests index afc1e21..68427f2 100755 --- a/tests/runtests +++ b/tests/runtests @@ -45,7 +45,7 @@ simple_harness_run same_line_marker/same_line_marker.sh simple_harness_run tracepoint/run -simple_harness_run ustcmd_function_tests/ustcmd_function_tests +simple_harness_run libustctl_function_tests/libustctl_function_tests echo "************************************" if [[ $tests_failed -eq 0 ]]; then diff --git a/tests/ustcmd_function_tests/Makefile.am b/tests/ustcmd_function_tests/Makefile.am deleted file mode 100644 index b70e784..0000000 --- a/tests/ustcmd_function_tests/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/tests/ - -noinst_PROGRAMS = ustcmd_function_tests -ustcmd_function_tests_SOURCES = ustcmd_function_tests.c -ustcmd_function_tests_LDADD = $(top_builddir)/libust/libust.la \ - $(top_builddir)/libustcmd/libustcmd.la \ - $(top_builddir)/libust-initializer.o \ - $(top_builddir)/tests/libtap.la \ - -lpthread - diff --git a/tests/ustcmd_function_tests/ustcmd_function_tests.c b/tests/ustcmd_function_tests/ustcmd_function_tests.c deleted file mode 100644 index d44dafc..0000000 --- a/tests/ustcmd_function_tests/ustcmd_function_tests.c +++ /dev/null @@ -1,184 +0,0 @@ -/* Copyright (C) 2010 Nils Carlson - * - * 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 - */ - -/* Simple function tests for ustcmd */ - -#include -#include -#include - -#include -#include - -#include "tap.h" - -static void ustcmd_function_tests(pid_t pid) -{ - int result; - unsigned int subbuf_size, subbuf_num; - unsigned int new_subbuf_size, new_subbuf_num; - struct marker_status *marker_status, *ms_ptr; - char *old_socket_path, *new_socket_path; - char *tmp_ustd_socket = "/tmp/tmp_ustd_socket"; - char *trace = "auto"; - - printf("Connecting to pid %d\n", pid); - - /* marker status array functions */ - result = ustcmd_get_cmsf(&marker_status, pid); - tap_ok(!result, "ustcmd_get_cmsf"); - - result = 0; - for (ms_ptr = marker_status; ms_ptr->channel; ms_ptr++) { - if (!strcmp(ms_ptr->channel, "ust") && - !strcmp(ms_ptr->marker, "bar")) { - result = 1; - } - } - tap_ok(result, "Found channel \"ust\", marker \"bar\""); - - tap_ok(!ustcmd_free_cmsf(marker_status), "ustcmd_free_cmsf"); - - /* Get and set the socket path */ - tap_ok(!ustcmd_get_sock_path(&old_socket_path, pid), - "ustcmd_get_sock_path"); - - printf("Socket path: %s\n", old_socket_path); - - tap_ok(!ustcmd_set_sock_path(tmp_ustd_socket, pid), - "ustcmd_set_sock_path - set a new path"); - - tap_ok(!ustcmd_get_sock_path(&new_socket_path, pid), - "ustcmd_get_sock_path - get the new path"); - - tap_ok(!strcmp(new_socket_path, tmp_ustd_socket), - "Compare the set path and the retrieved path"); - - free(new_socket_path); - - tap_ok(!ustcmd_set_sock_path(old_socket_path, pid), - "Reset the socket path"); - - free(old_socket_path); - - /* Enable, disable markers */ - tap_ok(!ustcmd_set_marker_state(trace, "ust", "bar", 1, pid), - "ustcmd_set_marker_state - existing marker ust bar"); - - /* Create and allocate a trace */ - tap_ok(!ustcmd_create_trace(trace, pid), "ustcmd_create_trace"); - - tap_ok(!ustcmd_alloc_trace(trace, pid), "ustcmd_alloc_trace"); - - /* Get subbuf size and number */ - subbuf_num = ustcmd_get_subbuf_num(trace, "ust", pid); - tap_ok(subbuf_num > 0, "ustcmd_get_subbuf_num - %d sub-buffers", - subbuf_num); - - subbuf_size = ustcmd_get_subbuf_size(trace, "ust", pid); - tap_ok(subbuf_size, "ustcmd_get_subbuf_size - sub-buffer size is %d", - subbuf_size); - - /* Start the trace */ - tap_ok(!ustcmd_start_trace(trace, pid), "ustcmd_start_trace"); - - - /* Stop the trace and destroy it*/ - tap_ok(!ustcmd_stop_trace(trace, pid), "ustcmd_stop_trace"); - - tap_ok(!ustcmd_destroy_trace(trace, pid), "ustcmd_destroy_trace"); - - /* Create a new trace */ - tap_ok(!ustcmd_create_trace(trace, pid), "ustcmd_create_trace - create a new trace"); - - printf("Setting new subbufer number and sizes (doubling)\n"); - new_subbuf_num = 2 * subbuf_num; - new_subbuf_size = 2 * subbuf_size; - - tap_ok(!ustcmd_set_subbuf_num(trace, "ust", new_subbuf_num, pid), - "ustcmd_set_subbuf_num"); - - tap_ok(!ustcmd_set_subbuf_size(trace, "ust", new_subbuf_size, pid), - "ustcmd_set_subbuf_size"); - - - /* Allocate the new trace */ - tap_ok(!ustcmd_alloc_trace(trace, pid), "ustcmd_alloc_trace - allocate the new trace"); - - - /* Get subbuf size and number and compare with what was set */ - subbuf_num = ustcmd_get_subbuf_num(trace, "ust", pid); - - subbuf_size = ustcmd_get_subbuf_size(trace, "ust", pid); - - tap_ok(subbuf_num == new_subbuf_num, "Set a new subbuf number, %d == %d", - subbuf_num, new_subbuf_num); - - - result = ustcmd_get_subbuf_size(trace, "ust", pid); - tap_ok(subbuf_size == new_subbuf_size, "Set a new subbuf size, %d == %d", - subbuf_size, new_subbuf_size); - - tap_ok(!ustcmd_destroy_trace(trace, pid), "ustcmd_destroy_trace - without ever starting"); - - - printf("##### Tests that definetly should work are completed #####\n"); - printf("############## Start expected failure cases ##############\n"); - - tap_ok(ustcmd_set_marker_state(trace, "ust","bar", 1, pid), - "Enable already enabled marker ust/bar"); - - tap_ok(ustcmd_set_marker_state(trace, "ustl", "blar", 1, pid), - "Enable non-existent marker ustl blar"); - - tap_ok(ustcmd_start_trace(trace, pid), - "Start a non-existent trace"); - - tap_ok(ustcmd_destroy_trace(trace, pid), - "Destroy non-existent trace"); - - exit(tap_status() ? EXIT_FAILURE : EXIT_SUCCESS); - -} - - -int main() -{ - int i, status, pipefd[2]; - pid_t parent_pid, child_pid; - FILE *pipe_file; - - tap_plan(27); - - printf("Function tests for ustcmd\n"); - - parent_pid = getpid(); - child_pid = fork(); - if (child_pid) { - for(i=0; i<10; i++) { - trace_mark(ust, bar, "str %s", "FOOBAZ"); - trace_mark(ust, bar2, "number1 %d number2 %d", 53, 9800); - usleep(100000); - } - - wait(&status); - } else { - ustcmd_function_tests(parent_pid); - } - - exit(status ? EXIT_FAILURE : EXIT_SUCCESS); -} diff --git a/ustctl/Makefile.am b/ustctl/Makefile.am index 3b09745..1e442a3 100644 --- a/ustctl/Makefile.am +++ b/ustctl/Makefile.am @@ -1,5 +1,5 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libustcomm \ - -I$(top_srcdir)/libustcmd $(KCOMPAT_CFLAGS) + -I$(top_srcdir)/libustctl $(KCOMPAT_CFLAGS) AM_CFLAGS = -fno-strict-aliasing bin_PROGRAMS = ustctl @@ -12,4 +12,4 @@ ustctl_CFLAGS = -DUST_COMPONENT=ustctl -fno-strict-aliasing ustctl_LDADD = \ $(top_builddir)/snprintf/libustsnprintf.la \ $(top_builddir)/libustcomm/libustcomm.la \ - $(top_builddir)/libustcmd/libustcmd.la + $(top_builddir)/libustctl/libustctl.la diff --git a/ustctl/channel_cmds.c b/ustctl/channel_cmds.c index 51f7d50..2ccf460 100644 --- a/ustctl/channel_cmds.c +++ b/ustctl/channel_cmds.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include "scanning_functions.h" #include "usterr.h" #include "cli.h" @@ -38,7 +38,7 @@ static int set_subbuf_size(int argc, char *argv[]) free(channel); return -1; } - if (ustcmd_set_subbuf_size(argv[2], channel, size, pid)) { + if (ustctl_set_subbuf_size(argv[2], channel, size, pid)) { ERR("error while trying to set the size of subbuffers " "for PID %u\n", pid); @@ -66,7 +66,7 @@ static int set_subbuf_num(int argc, char *argv[]) free(channel); return -1; } - if (ustcmd_set_subbuf_num(argv[2], channel, num, pid)) { + if (ustctl_set_subbuf_num(argv[2], channel, num, pid)) { ERR("error while trying to set the number of subbuffers for PID %u\n", pid); result = -1; @@ -84,7 +84,7 @@ static int get_subbuf_size(int argc, char *argv[]) pid = parse_pid(argv[1]); - if ((size = ustcmd_get_subbuf_size(argv[2], argv[3], pid)) < 0) { + if ((size = ustctl_get_subbuf_size(argv[2], argv[3], pid)) < 0) { ERR("error while trying to get the subbuffer size from PID %u\n", pid); return -1; @@ -102,7 +102,7 @@ static int get_subbuf_num(int argc, char *argv[]) pid = parse_pid(argv[1]); - if ((num = ustcmd_get_subbuf_num(argv[2], argv[3], pid)) < 0) { + if ((num = ustctl_get_subbuf_num(argv[2], argv[3], pid)) < 0) { ERR("error while trying to get the subbuffer size from PID %u\n", pid); return -1; diff --git a/ustctl/marker_cmds.c b/ustctl/marker_cmds.c index 20222dd..6544669 100644 --- a/ustctl/marker_cmds.c +++ b/ustctl/marker_cmds.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include "scanning_functions.h" #include "usterr.h" #include "cli.h" @@ -30,7 +30,7 @@ static int list_markers(int argc, char *argv[]) pid = parse_pid(argv[1]); - if (ustcmd_get_cmsf(&cmsf, pid)) { + if (ustctl_get_cmsf(&cmsf, pid)) { ERR("error while trying to list markers for PID %u\n", pid); return -1; } @@ -43,7 +43,7 @@ static int list_markers(int argc, char *argv[]) cmsf[i].state, cmsf[i].fs); } - ustcmd_free_cmsf(cmsf); + ustctl_free_cmsf(cmsf); return 0; } @@ -68,7 +68,7 @@ static int enable_marker(int argc, char *argv[]) if (marker) free(marker); } - if (ustcmd_set_marker_state(argv[2], channel, marker, 1, pid)) { + if (ustctl_set_marker_state(argv[2], channel, marker, 1, pid)) { PERROR("error while trying to enable marker %s with PID %u", argv[i], pid); result = -1; @@ -101,7 +101,7 @@ static int disable_marker(int argc, char *argv[]) free(marker); return -1; } - if (ustcmd_set_marker_state(argv[2], channel, marker, 0, pid)) { + if (ustctl_set_marker_state(argv[2], channel, marker, 0, pid)) { PERROR("error while trying to disable marker %s with PID %u", argv[i], pid); result = -1; diff --git a/ustctl/scanning_functions.c b/ustctl/scanning_functions.c index 0cf809e..a3eceb5 100644 --- a/ustctl/scanning_functions.c +++ b/ustctl/scanning_functions.c @@ -17,7 +17,7 @@ #define _GNU_SOURCE #include -#include +#include #include "usterr.h" diff --git a/ustctl/trace_cmds.c b/ustctl/trace_cmds.c index f6e11a7..020e5b2 100644 --- a/ustctl/trace_cmds.c +++ b/ustctl/trace_cmds.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include "scanning_functions.h" #include "usterr.h" #include "cli.h" @@ -29,7 +29,7 @@ static int create_trace(int argc, char *argv[]) pid = parse_pid(argv[1]); - if (ustcmd_create_trace(argv[2], pid)) { + if (ustctl_create_trace(argv[2], pid)) { ERR("Failed to create trace %s for PID %u\n", argv[2], pid); return -1; } @@ -43,7 +43,7 @@ static int alloc_trace(int argc, char *argv[]) pid = parse_pid(argv[1]); - if (ustcmd_alloc_trace(argv[2], pid)) { + if (ustctl_alloc_trace(argv[2], pid)) { ERR("Failed to allocate trace %s for PID %u\n", argv[2], pid); return -1; } @@ -56,7 +56,7 @@ static int start_trace(int argc, char *argv[]) pid = parse_pid(argv[1]); - if (ustcmd_start_trace(argv[2], pid)) { + if (ustctl_start_trace(argv[2], pid)) { ERR("Failed to start trace %s for PID %u\n", argv[2], pid); return -1; } @@ -69,7 +69,7 @@ static int stop_trace(int argc, char *argv[]) pid = parse_pid(argv[1]); - if (ustcmd_stop_trace(argv[2], pid)) { + if (ustctl_stop_trace(argv[2], pid)) { ERR("Failed to stop trace %s for PID %u\n", argv[2], pid); return -1; } @@ -82,7 +82,7 @@ static int destroy_trace(int argc, char *argv[]) pid = parse_pid(argv[1]); - if (ustcmd_destroy_trace(argv[2], pid)) { + if (ustctl_destroy_trace(argv[2], pid)) { ERR("Failed to destroy trace %s for PID %u\n", argv[2], pid); return -1; } @@ -95,7 +95,7 @@ static int force_subbuf_switch(int argc, char *argv[]) pid = parse_pid(argv[1]); - if (ustcmd_force_switch(pid)) { + if (ustctl_force_switch(pid)) { ERR("error while trying to force switch for PID %u\n", pid); return -1; } diff --git a/ustctl/ustctl.c b/ustctl/ustctl.c index 2b75a58..c1bbe8c 100644 --- a/ustctl/ustctl.c +++ b/ustctl/ustctl.c @@ -23,7 +23,7 @@ #include #include -#include "ust/ustcmd.h" +#include "ust/ustctl.h" #include "usterr.h" #include "cli.h" #include "scanning_functions.h" @@ -111,7 +111,7 @@ static int list_trace_events(int argc, char *argv[]) pid = parse_pid(argv[1]); - if (ustcmd_get_tes(&tes, pid)) { + if (ustctl_get_tes(&tes, pid)) { ERR("error while trying to list " "trace_events for PID %u\n", pid); @@ -123,7 +123,7 @@ static int list_trace_events(int argc, char *argv[]) pid, tes[i].name); } - ustcmd_free_tes(tes); + ustctl_free_tes(tes); return 0; } @@ -134,7 +134,7 @@ static int set_sock_path(int argc, char *argv[]) pid = parse_pid(argv[1]); - if (ustcmd_set_sock_path(argv[2], pid)) { + if (ustctl_set_sock_path(argv[2], pid)) { ERR("error while trying to set sock path for PID %u\n", pid); return -1; } @@ -149,7 +149,7 @@ static int get_sock_path(int argc, char *argv[]) pid = parse_pid(argv[1]); - if (ustcmd_get_sock_path(&sock_path, pid)) { + if (ustctl_get_sock_path(&sock_path, pid)) { ERR("error while trying to get sock path for PID %u\n", pid); return -1; }