#include "kernelcompat.h"
#include "channels.h"
#include "usterr.h"
+#include "marker.h"
/*
* ltt_channel_mutex may be nested inside the LTT trace mutex.
//ust// #include <linux/mutex.h>
//ust// #include <linux/seq_file.h>
//ust// #include <linux/slab.h>
+#include <ctype.h>
+
#include "kernelcompat.h"
//#include "list.h"
#include "tracer.h"
return NULL;
}
+/* (unused)
static char *skip_spaces(char *buf)
{
while (*buf != '\0' && isspace(*buf))
*end = skip_nonspaces(*start);
**end = '\0';
}
+*/
int ltt_probe_register(struct ltt_available_probe *pdata)
{
mutex_unlock(&probes_mutex);
return ret;
}
-EXPORT_SYMBOL_GPL(ltt_probe_register);
/*
* Called when a probe does not want to be called anymore.
mutex_unlock(&probes_mutex);
return ret;
}
-EXPORT_SYMBOL_GPL(ltt_probe_unregister);
/*
* Connect marker "mname" to probe "pname".
ltt_unlock_traces();
return ret;
}
-EXPORT_SYMBOL_GPL(ltt_marker_connect);
/*
* Disconnect marker "mname", probe "pname".
mutex_unlock(&probes_mutex);
return ret;
}
-EXPORT_SYMBOL_GPL(ltt_marker_disconnect);
/*
* function handling proc entry write.
}
//ust// module_init(marker_control_init);
-static void __exit marker_control_exit(void)
+static void __attribute__((destructor)) marker_control_exit(void)
{
int ret;
*/
static DEFINE_MUTEX(markers_mutex);
+static LIST_HEAD(libs);
+
+
void lock_markers(void)
{
mutex_lock(&markers_mutex);
*/
static void disable_marker(struct marker *elem)
{
- int ret;
-
- /* leave "call" as is. It is known statically. */
+//ust// int ret;
+//ust//
+//ust// /* leave "call" as is. It is known statically. */
//ust// if (elem->tp_name && _imv_read(elem->state)) {
//ust// WARN_ON(!elem->tp_cb);
//ust// /*
mutex_unlock(&markers_mutex);
}
+static void lib_update_markers(void)
+{
+ struct lib *lib;
+
+ /* FIXME: we should probably take a mutex here on libs */
+//ust// mutex_lock(&module_mutex);
+ list_for_each_entry(lib, &libs, list)
+ marker_update_probe_range(lib->markers_start,
+ lib->markers_start + lib->markers_count);
+//ust// mutex_unlock(&module_mutex);
+}
+
/*
* Update probes, removing the faulty probes.
*
//ust//#ifdef CONFIG_MODULES
+/*
+ * Returns 0 if current not found.
+ * Returns 1 if current found.
+ */
+int lib_get_iter_markers(struct marker_iter *iter)
+{
+ struct lib *iter_lib;
+ int found = 0;
+
+//ust// mutex_lock(&module_mutex);
+ list_for_each_entry(iter_lib, &libs, list) {
+ if (iter_lib < iter->lib)
+ continue;
+ else if (iter_lib > iter->lib)
+ iter->marker = NULL;
+ found = marker_get_iter_range(&iter->marker,
+ iter_lib->markers_start,
+ iter_lib->markers_start + iter_lib->markers_count);
+ if (found) {
+ iter->lib = iter_lib;
+ break;
+ }
+ }
+//ust// mutex_unlock(&module_mutex);
+ return found;
+}
+
/**
* marker_get_iter_range - Get a next marker iterator given a range.
* @marker: current markers (in), next marker (out)
}
//ust// EXPORT_SYMBOL_GPL(ltt_dump_marker_state);
-
-static LIST_HEAD(libs);
-
-/*
- * Returns 0 if current not found.
- * Returns 1 if current found.
- */
-int lib_get_iter_markers(struct marker_iter *iter)
-{
- struct lib *iter_lib;
- int found = 0;
-
-//ust// mutex_lock(&module_mutex);
- list_for_each_entry(iter_lib, &libs, list) {
- if (iter_lib < iter->lib)
- continue;
- else if (iter_lib > iter->lib)
- iter->marker = NULL;
- found = marker_get_iter_range(&iter->marker,
- iter_lib->markers_start,
- iter_lib->markers_start + iter_lib->markers_count);
- if (found) {
- iter->lib = iter_lib;
- break;
- }
- }
-//ust// mutex_unlock(&module_mutex);
- return found;
-}
-
-void lib_update_markers(void)
-{
- struct lib *lib;
-
-//ust// mutex_lock(&module_mutex);
- list_for_each_entry(lib, &libs, list)
- marker_update_probe_range(lib->markers_start,
- lib->markers_start + lib->markers_count);
-//ust// mutex_unlock(&module_mutex);
-}
-
static void (*new_marker_cb)(struct marker *) = NULL;
void marker_set_new_marker_cb(void (*cb)(struct marker *))
static void relay_destroy_buf(struct rchan_buf *buf)
{
struct rchan *chan = buf->chan;
- struct buf_page *buf_page, *n;
+//ust// struct buf_page *buf_page;
int result;
result = munmap(buf->buf_data, buf->buf_size);
/*
* create_buf_file_create() default callback. Does nothing.
*/
-static struct dentry *create_buf_file_default_callback(const char *filename,
- struct dentry *parent,
- int mode,
- struct rchan_buf *buf)
-{
- return NULL;
-}
+//ust// static struct dentry *create_buf_file_default_callback(const char *filename,
+//ust// struct dentry *parent,
+//ust// int mode,
+//ust// struct rchan_buf *buf)
+//ust// {
+//ust// return NULL;
+//ust// }
-/*
- * remove_buf_file() default callback. Does nothing.
- */
-static int remove_buf_file_default_callback(struct dentry *dentry)
-{
- return -EINVAL;
-}
+//ust// /*
+//ust// * remove_buf_file() default callback. Does nothing.
+//ust// */
+//ust// static int remove_buf_file_default_callback(struct dentry *dentry)
+//ust// {
+//ust// return -EINVAL;
+//ust// }
/**
* wakeup_readers - wake up readers waiting on a channel
static struct rchan_buf *relay_open_buf(struct rchan *chan)
{
struct rchan_buf *buf = NULL;
- struct dentry *dentry;
+//ust// struct dentry *dentry;
//ust// char *tmpname;
//ust// tmpname = kzalloc(NAME_MAX + 1, GFP_KERNEL);
goto free_name;
-free_buf:
+//ust//free_buf:
relay_destroy_buf(buf);
buf = NULL;
free_name:
//ust// kfree(tmpname);
-end:
+//ust//end:
return buf;
}
size_t n_subbufs,
void *private_data)
{
- unsigned int i;
+//ust// unsigned int i;
struct rchan *chan;
//ust// if (!base_filename)
//ust// return NULL;
*/
void ltt_relay_close(struct rchan *chan)
{
- unsigned int i;
+//ust// unsigned int i;
if (!chan)
return;
return NULL;
}
-static int ltt_remove_buf_file_callback(struct rchan_buf *buf)
-{
-//ust// struct rchan_buf *buf = dentry->d_inode->i_private;
- struct ltt_channel_struct *ltt_chan = buf->chan->private_data;
-
-//ust// debugfs_remove(dentry);
- ltt_relay_destroy_buffer(ltt_chan);
-
- return 0;
-}
+//ust// static int ltt_remove_buf_file_callback(struct rchan_buf *buf)
+//ust// {
+//ust// //ust// struct rchan_buf *buf = dentry->d_inode->i_private;
+//ust// struct ltt_channel_struct *ltt_chan = buf->chan->private_data;
+//ust//
+//ust// //ust// debugfs_remove(dentry);
+//ust// ltt_relay_destroy_buffer(ltt_chan);
+//ust//
+//ust// return 0;
+//ust// }
/*
* Wake writers :
static void ltt_relay_finish_buffer(struct ltt_channel_struct *ltt_channel)
{
struct rchan *rchan = ltt_channel->trans_channel_data;
- int result;
+// int result;
if (rchan->buf) {
struct ltt_channel_buf_struct *ltt_buf = ltt_channel->buf;
static void ltt_relay_finish_channel(struct ltt_channel_struct *ltt_channel)
{
- unsigned int i;
+//ust// unsigned int i;
//ust// for_each_possible_cpu(i)
ltt_relay_finish_buffer(ltt_channel);
}
}
-static void __exit ltt_relay_exit(void)
+static void __attribute__((destructor)) ltt_relay_exit(void)
{
//ust// printk(KERN_INFO "LTT : ltt-relay exit\n");
void init_ustrelay_transport(void);
+/*static*/ /* inline */ notrace void ltt_commit_slot(
+ struct ltt_channel_struct *ltt_channel,
+ void **transport_data, long buf_offset,
+ size_t data_size, size_t slot_size);
+
#endif /* _LINUX_LTT_RELAY_H */
}
return buf_offset;
}
-EXPORT_SYMBOL_GPL(ltt_serialize_data);
/*
* Calculate data size
ltt_nesting--;
rcu_read_unlock(); //ust// rcu_read_unlock_sched_notrace();
}
-EXPORT_SYMBOL_GPL(ltt_vtrace);
notrace void ltt_trace(const struct marker *mdata, void *probe_data,
void *call_data, const char *fmt, ...)
ltt_vtrace(mdata, probe_data, call_data, fmt, &args);
va_end(args);
}
-EXPORT_SYMBOL_GPL(ltt_trace);
//ust// MODULE_LICENSE("GPL");
//ust// MODULE_AUTHOR("Mathieu Desnoyers");
mutex_unlock(&tracepoints_mutex);
}
+static void lib_update_tracepoints(void)
+{
+ struct tracepoint_lib *lib;
+
+//ust// mutex_lock(&module_mutex);
+ list_for_each_entry(lib, &libs, list)
+ tracepoint_update_probe_range(lib->tracepoints_start,
+ lib->tracepoints_start + lib->tracepoints_count);
+//ust// mutex_unlock(&module_mutex);
+}
+
/*
* Update probes, removing the faulty probes.
*/
}
//ust// EXPORT_SYMBOL_GPL(tracepoint_probe_update_all);
+/*
+ * Returns 0 if current not found.
+ * Returns 1 if current found.
+ */
+int lib_get_iter_tracepoints(struct tracepoint_iter *iter)
+{
+ struct tracepoint_lib *iter_lib;
+ int found = 0;
+
+//ust// mutex_lock(&module_mutex);
+ list_for_each_entry(iter_lib, &libs, list) {
+ if (iter_lib < iter->lib)
+ continue;
+ else if (iter_lib > iter->lib)
+ iter->tracepoint = NULL;
+ found = tracepoint_get_iter_range(&iter->tracepoint,
+ iter_lib->tracepoints_start,
+ iter_lib->tracepoints_start + iter_lib->tracepoints_count);
+ if (found) {
+ iter->lib = iter_lib;
+ break;
+ }
+ }
+//ust// mutex_unlock(&module_mutex);
+ return found;
+}
+
/**
* tracepoint_get_iter_range - Get a next tracepoint iterator given a range.
* @tracepoint: current tracepoints (in), next tracepoint (out)
//ust// }
/* tracepoints in libs. */
found = lib_get_iter_tracepoints(iter);
-end:
+//ust// end:
if (!found)
tracepoint_iter_reset(iter);
}
//ust// #endif /* CONFIG_MODULES */
-/*
- * Returns 0 if current not found.
- * Returns 1 if current found.
- */
-int lib_get_iter_tracepoints(struct tracepoint_iter *iter)
-{
- struct tracepoint_lib *iter_lib;
- int found = 0;
-
-//ust// mutex_lock(&module_mutex);
- list_for_each_entry(iter_lib, &libs, list) {
- if (iter_lib < iter->lib)
- continue;
- else if (iter_lib > iter->lib)
- iter->tracepoint = NULL;
- found = marker_get_iter_range(&iter->tracepoint,
- iter_lib->tracepoints_start,
- iter_lib->tracepoints_start + iter_lib->tracepoints_count);
- if (found) {
- iter->lib = iter_lib;
- break;
- }
- }
-//ust// mutex_unlock(&module_mutex);
- return found;
-}
-
-void lib_update_tracepoints(void)
-{
- struct tracepoint_lib *lib;
-
-//ust// mutex_lock(&module_mutex);
- list_for_each_entry(lib, &libs, list)
- tracepoint_update_probe_range(lib->tracepoints_start,
- lib->tracepoints_start + lib->tracepoints_count);
-//ust// mutex_unlock(&module_mutex);
-}
-
static void (*new_tracepoint_cb)(struct tracepoint *) = NULL;
void tracepoint_set_new_tracepoint_cb(void (*cb)(struct tracepoint *))
*/
void ltt_release_transport(struct kref *kref)
{
- struct ltt_trace_struct *trace = container_of(kref,
- struct ltt_trace_struct, ltt_transport_kref);
-//ust// trace->ops->remove_dirs(trace);
+//ust// struct ltt_trace_struct *trace = container_of(kref,
+//ust// struct ltt_trace_struct, ltt_transport_kref);
+//ust// trace->ops->remove_dirs(trace);
}
//ust// EXPORT_SYMBOL_GPL(ltt_release_transport);
int err = 0;
struct ltt_trace_struct *trace;
unsigned int subbuf_size, subbuf_cnt;
- unsigned long flags;
+//ust// unsigned long flags;
int chan;
const char *channel_name;
if (trace->channels[chan].active)
trace->ops->remove_channel(&trace->channels[chan]);
-dirs_error:
+//ust// dirs_error:
//ust// module_put(trace->transport->owner);
transport_error:
//ust// put_trace_clock();
* We will make a new ltt_control based on debugfs, and control each channel's
* buffer.
*/
-static int ltt_trace_create(const char *trace_name, const char *trace_type,
- enum trace_mode mode,
- unsigned int subbuf_size_low, unsigned int n_subbufs_low,
- unsigned int subbuf_size_med, unsigned int n_subbufs_med,
- unsigned int subbuf_size_high, unsigned int n_subbufs_high)
-{
- int err = 0;
-
- err = ltt_trace_setup(trace_name);
- if (IS_ERR_VALUE(err))
- return err;
-
- err = ltt_trace_set_type(trace_name, trace_type);
- if (IS_ERR_VALUE(err))
- return err;
-
- err = ltt_trace_alloc(trace_name);
- if (IS_ERR_VALUE(err))
- return err;
-
- return err;
-}
+//ust// static int ltt_trace_create(const char *trace_name, const char *trace_type,
+//ust// enum trace_mode mode,
+//ust// unsigned int subbuf_size_low, unsigned int n_subbufs_low,
+//ust// unsigned int subbuf_size_med, unsigned int n_subbufs_med,
+//ust// unsigned int subbuf_size_high, unsigned int n_subbufs_high)
+//ust// {
+//ust// int err = 0;
+//ust//
+//ust// err = ltt_trace_setup(trace_name);
+//ust// if (IS_ERR_VALUE(err))
+//ust// return err;
+//ust//
+//ust// err = ltt_trace_set_type(trace_name, trace_type);
+//ust// if (IS_ERR_VALUE(err))
+//ust// return err;
+//ust//
+//ust// err = ltt_trace_alloc(trace_name);
+//ust// if (IS_ERR_VALUE(err))
+//ust// return err;
+//ust//
+//ust// return err;
+//ust// }
/* Must be called while sure that trace is in the list. */
static int _ltt_trace_destroy(struct ltt_trace_struct *trace)
return err;
/* error handling */
-get_ltt_run_filter_error:
+//ust// get_ltt_run_filter_error:
traces_error:
return err;
}
}
//ust// module_put(ltt_filter_control_owner);
-get_module_error:
+//ust// get_module_error:
trace_error:
ltt_unlock_traces();
return err;
#include <fcntl.h>
#include <string.h>
#include <dirent.h>
-#
#include "ustcomm.h"
#include "ustcmd.h"
#define _GNU_SOURCE
-pid_t* ustcmd_get_online_pids(void) {
+pid_t* ustcmd_get_online_pids(void)
+{
struct dirent* dirent;
DIR* dir;
unsigned int ret_size = 1 * sizeof(pid_t), i = 0;
pid_t* ret = (pid_t*) malloc(ret_size);
- while (dirent = readdir(dir)) {
+ while ((dirent = readdir(dir))) {
if (!strcmp(dirent->d_name, ".") ||
!strcmp(dirent->d_name, "..")) {
* @param pid Traced process ID
* @return 0 if successful, or error USTCMD_ERR_GEN
*/
-int ustcmd_destroy_trace(pid_t pid) {
- int tres;
+int ustcmd_destroy_trace(pid_t pid)
+{
+ int result;
- if (tres = ustcmd_shoot("destroy", pid, NULL)) {
+ result = ustcmd_shoot("destroy", pid, NULL);
+ if (result) {
return USTCMD_ERR_GEN;
}
* @param pid Traced process ID
* @return 0 if successful, or error USTCMD_ERR_GEN
*/
-int ustcmd_setup_and_start(pid_t pid) {
- int tres;
+int ustcmd_setup_and_start(pid_t pid)
+{
+ int result;
- if (tres = ustcmd_shoot("start", pid, NULL)) {
+ result = ustcmd_shoot("start", pid, NULL);
+ if (result) {
return USTCMD_ERR_GEN;
}
* @param pid Traced process ID
* @return 0 if successful, or error USTCMD_ERR_GEN
*/
-int ustcmd_start_trace(pid_t pid) {
- int tres;
+int ustcmd_start_trace(pid_t pid)
+{
+ int result;
- if (tres = ustcmd_shoot("trace_start", pid, NULL)) {
+ result = ustcmd_shoot("trace_start", pid, NULL);
+ if (result) {
return USTCMD_ERR_GEN;
}
* @param pid Traced process ID
* @return 0 if successful, or error USTCMD_ERR_GEN
*/
-int ustcmd_stop_trace(pid_t pid) {
- int tres;
+int ustcmd_stop_trace(pid_t pid)
+{
+ int result;
- if (tres = ustcmd_shoot("trace_stop", pid, NULL)) {
+ result = ustcmd_shoot("trace_stop", pid, NULL);
+ if (result) {
return USTCMD_ERR_GEN;
}
* @param str String to search in
* @return Total newlines count
*/
-unsigned int ustcmd_count_nl(const char* str) {
+unsigned int ustcmd_count_nl(const char* str)
+{
unsigned int i = 0, tot = 0;
while (str[i] != '\0') {
* @param cmsf CMSF array to free
* @return 0 if successful, or error USTCMD_ERR_ARG
*/
-int ustcmd_free_cmsf(struct USTcmd_cmsf* cmsf) {
+int ustcmd_free_cmsf(struct USTcmd_cmsf* cmsf)
+{
if (cmsf == NULL) {
return USTCMD_ERR_ARG;
}
* @param pid Targeted PID
* @return 0 if successful, or errors {USTCMD_ERR_ARG, USTCMD_ERR_GEN}
*/
-int ustcmd_get_cmsf(struct USTcmd_cmsf** cmsf, const pid_t pid) {
+int ustcmd_get_cmsf(struct USTcmd_cmsf** cmsf, const pid_t pid)
+{
char* big_str = NULL;
int result;
struct USTcmd_cmsf* tmp_cmsf = NULL;
* be NULL if no reply is needed for the given command).
* @return 0 if successful, or errors {USTCMD_ERR_ARG, USTCMD_ERR_CONN}
*/
-int ustcmd_shoot(const char* cmd, const pid_t pid, char** reply) {
+
+int ustcmd_shoot(const char* cmd, const pid_t pid, char** reply)
+{
+ struct ustcomm_connection conn;
+
if (cmd == NULL) {
return USTCMD_ERR_ARG;
}
return -1;
}
-int ustcomm_send_request(struct ustcomm_connection *conn, char *req, char **reply)
+int ustcomm_send_request(struct ustcomm_connection *conn, const char *req, char **reply)
{
int result;
int ustcomm_init_ustd(struct ustcomm_ustd *handle);
int ustcomm_connect_app(pid_t pid, struct ustcomm_connection *conn);
-int ustcomm_send_request(struct ustcomm_connection *conn, char *req, char **reply);
+int ustcomm_send_request(struct ustcomm_connection *conn, const char *req, char **reply);
int ustcomm_send_reply(struct ustcomm_server *server, char *msg, struct ustcomm_source *src);
int nth_token_is(char *str, char *token, int tok_no);
/* ATTRIBUTES */
#define ____cacheline_aligned
-#define __init
-#define __exit
/* MATH */
}
}
- if(argc - optind > 0 && opts->cmd != GET_ONLINE_PIDS) {
+ if (argc - optind > 0 && opts->cmd != GET_ONLINE_PIDS) {
int i;
int pididx=0;
opts->pids = malloc((argc-optind+1) * sizeof(pid_t));
opts->pids[pididx] = -1;
}
+ if (opts->cmd == ENABLE_MARKER || opts->cmd == DISABLE_MARKER) {
+ if (opts->regex_state = regcomp(&opts->preg, opts->regex, 0)) {
+ fprintf(stderr, "Invalid regular expression.\n");
+ }
+ }
+
return 0;
}
+static void regex_change_m_state(struct ust_opts* opts, pid_t pid) {
+ struct USTcmd_cmsf* cmsf = NULL;
+ unsigned int i = 0;
+ int e = (opts->cmd == ENABLE_MARKER);
+
+ if (opts->regex_state != 0) {
+ return;
+ }
+
+ if (ustcmd_get_cmsf(&cmsf, pid)) {
+ fprintf(stderr, "error while trying to get markers for PID "
+ "%u\n", (unsigned int) pid);
+ return;
+ }
+ while (cmsf[i].channel != NULL) {
+ char* mc;
+ asprintf(&mc, "%s/%s", cmsf[i].channel, cmsf[i].marker);
+ if (regexec(&opts->preg, mc, 0, NULL, 0) == 0) {
+ /* We got a match! */
+ if (ustcmd_set_marker_state(mc,
+ e ? USTCMD_MS_ON : USTCMD_MS_OFF, pid)) {
+ fprintf(stderr,
+ "error while trying to %sable marker"
+ "\"%s\" for PID %u\n",
+ e ? "en" : "dis", mc,
+ (unsigned int) pid);
+ } else {
+ printf("sucessfully %sabled marker "
+ "\"%s\" for PID %u\n",
+ e ? "en" : "dis", mc,
+ (unsigned int) pid);
+ }
+ }
+ free(mc);
+ ++i;
+ }
+ ustcmd_free_cmsf(cmsf);
+}
+
int main(int argc, char *argv[])
{
pid_t *pidit;
- //char *msg = argv[2];
struct ustcomm_connection conn;
int result;
struct ust_opts opts;