From mboxrd@z Thu Jan 1 00:00:00 1970 From: guijianfeng@cn.fujitsu.com (Gui Jianfeng) Date: Wed, 04 Feb 2009 14:44:39 +0800 Subject: [ltt-dev] [PATCH] LTTng: Make mark-control work in debugfs In-Reply-To: <20090204062051.GB10772@Krystal> References: <4988F393.8080605@cn.fujitsu.com> <20090204062051.GB10772@Krystal> Message-ID: <49893957.20303@cn.fujitsu.com> Mathieu Desnoyers wrote: > * Gui Jianfeng (guijianfeng at cn.fujitsu.com) wrote: >> Hi Mathieu, >> >> This patch makes mark-control work in debugfs >> Control files are organized as following. >> ltt/ >> |-- markers >> | |-- fs >> | | |-- buffer_wait_end >> | | | |-- enabled >> | | | `-- info >> | | |-- buffer_wait_start >> | | | |-- enabled >> | | | `-- info >> | | |-- close >> | | | |-- enabled >> | | | `-- info >> | | |-- exec >> | | | |-- enabled >> | | | `-- info >> ... >> >> One can enable or disable a marker by using the following command >> # echo 1 > ltt/markers/fs/close/enabled >> # echo 0 > ltt/markers/fs/close/enabled >> >> Show the marker information as following >> # cat ltt/markers/fs/close/info >> format: "fd %u" >> state: 1 >> event_id: 2 >> call: 0xc0459118 >> probe single : 0xc04f7b08 >> > > Thanks a lot Gui, this is a very good patch. I'll make the cosmetic > changes requested by scripts/checkpatch.pl myself and merge it. (please I see, thanks for pointing this out. :) BTW, I'll post a patch to modify user tools accordingly as soon as this patch has been merged into the new version of LTTng. > get used to run it before submission, it's very good at spotting > whitespaces at the end of lines and other coding style errors) > > Best regards, > > Mathieu > >> Signed-off-by: Gui Jianfeng >> --- >> ltt/ltt-trace-control.c | 302 ++++++++++++++++++++++++++++++++++++++++++++++- >> 1 files changed, 297 insertions(+), 5 deletions(-) >> >> diff --git a/ltt/ltt-trace-control.c b/ltt/ltt-trace-control.c >> index 16502a2..e4676bf 100644 >> --- a/ltt/ltt-trace-control.c >> +++ b/ltt/ltt-trace-control.c >> @@ -1,8 +1,10 @@ >> /* >> * LTT trace control module over debugfs. >> * >> - * Copyright 2008 - >> - * Zhaolei >> + * Copyright 2008 - Zhaolei >> + * >> + * Copyright 2009 - Gui Jianfeng >> + * Make mark-control work in debugfs >> */ >> >> /* >> @@ -16,14 +18,17 @@ >> #include >> #include >> #include >> +#include >> >> #define LTT_CONTROL_DIR "control" >> +#define MARKERS_CONTROL_DIR "markers" >> #define LTT_SETUP_TRACE_FILE "setup_trace" >> #define LTT_DESTROY_TRACE_FILE "destroy_trace" >> >> #define LTT_WRITE_MAXLEN (128) >> >> -struct dentry *ltt_control_dir, *ltt_setup_trace_file, *ltt_destroy_trace_file; >> +struct dentry *ltt_control_dir, *ltt_setup_trace_file, *ltt_destroy_trace_file, >> + *markers_control_dir; >> >> /* >> * the traces_lock nests inside control_lock. >> @@ -692,6 +697,272 @@ static struct file_operations ltt_destroy_trace_operations = { >> .write = destroy_trace_write, >> }; >> >> +static int marker_enabled_open(struct inode *inode, struct file *filp) >> +{ >> + filp->private_data = inode->i_private; >> + return 0; >> +} >> + >> +static ssize_t marker_enabled_read(struct file *filp, char __user *ubuf, >> + size_t cnt, loff_t *ppos) >> +{ >> + struct marker *marker; >> + char *buf; >> + int len; >> + >> + marker = (struct marker *)filp->private_data; >> + buf = kmalloc(1024, GFP_KERNEL); >> + >> + len = sprintf(buf, "%d\n", _imv_read(marker->state)); >> + >> + len = simple_read_from_buffer(ubuf, cnt, ppos, buf, len); >> + kfree(buf); >> + >> + return len; >> +} >> + >> +static ssize_t marker_enabled_write(struct file *filp, const char __user *ubuf, >> + size_t cnt, loff_t *ppos) >> +{ >> + char buf[NAME_MAX]; >> + int buf_size; >> + int err = 0; >> + struct marker *marker; >> + >> + marker = (struct marker *)filp->private_data; >> + buf_size = min(cnt, sizeof(buf) - 1); >> + err = copy_from_user(buf, ubuf, buf_size); >> + if (err) >> + return err; >> + >> + buf[buf_size] = 0; >> + >> + switch (buf[0]) { >> + case 'Y': >> + case 'y': >> + case '1': >> + err = ltt_marker_connect(marker->channel, marker->name, "default"); >> + if (err) >> + return err; >> + break; >> + case 'N': >> + case 'n': >> + case '0': >> + err = ltt_marker_disconnect(marker->channel, marker->name, >> + "default"); >> + if (err) >> + return err; >> + break; >> + default: >> + return -EPERM; >> + } >> + >> + return cnt; >> +} >> + >> +static struct file_operations enabled_fops = { >> + .open = marker_enabled_open, >> + .read = marker_enabled_read, >> + .write = marker_enabled_write, >> +}; >> + >> +static int marker_info_open(struct inode *inode, struct file *filp) >> +{ >> + filp->private_data = inode->i_private; >> + return 0; >> +} >> + >> +static ssize_t marker_info_read(struct file *filp, char __user *ubuf, >> + size_t cnt, loff_t *ppos) >> +{ >> + struct marker *marker; >> + char *buf; >> + int len; >> + >> + marker = (struct marker *)filp->private_data; >> + buf = kmalloc(1024, GFP_KERNEL); >> + >> + len = sprintf(buf, "format: \"%s\"\nstate: %d\n" >> + "event_id: %hu\n" >> + "call: 0x%p\n" >> + "probe %s : 0x%p\n", >> + marker->format, _imv_read(marker->state), >> + marker->event_id, marker->call, marker->ptype ? >> + "multi" : "single", marker->ptype ? >> + (void*)marker->multi : (void*)marker->single.func); >> + >> + len = simple_read_from_buffer(ubuf, cnt, ppos, buf, len); >> + kfree(buf); >> + >> + return len; >> +} >> + >> +static struct file_operations info_fops = { >> + .open = marker_info_open, >> + .read = marker_info_read, >> +}; >> + >> +static int build_marker_file(struct marker *marker) >> +{ >> + struct dentry *channel_d, *marker_d, *enabled_d, *info_d; >> + int err; >> + >> + channel_d = dir_lookup(markers_control_dir, marker->channel); >> + if (!channel_d) { >> + channel_d = debugfs_create_dir(marker->channel, >> + markers_control_dir); >> + if (IS_ERR(channel_d) || !channel_d) { >> + printk(KERN_ERR >> + "%s: build channel dir of %s failed\n", >> + __func__, marker->channel); >> + err = -ENOMEM; >> + goto err_build_fail; >> + } >> + } >> + >> + marker_d = dir_lookup(channel_d, marker->name); >> + if (!marker_d) { >> + marker_d = debugfs_create_dir(marker->name, channel_d); >> + if (IS_ERR(marker_d) || !marker_d) { >> + printk(KERN_ERR >> + "%s: marker dir of %s failed\n", >> + __func__, marker->name); >> + err = -ENOMEM; >> + goto err_build_fail; >> + } >> + } >> + >> + enabled_d = dir_lookup(marker_d, "enabled"); >> + if (!enabled_d) { >> + enabled_d = debugfs_create_file("enabled", 0644, marker_d, >> + marker, &enabled_fops); >> + if (IS_ERR(enabled_d) || !enabled_d) { >> + printk(KERN_ERR >> + "%s: create file of %s failed\n", >> + __func__, "enabled"); >> + err = -ENOMEM; >> + goto err_build_fail; >> + } >> + } >> + >> + info_d = dir_lookup(marker_d, "info"); >> + if (!info_d) { >> + info_d = debugfs_create_file("info", 0444, marker_d, >> + marker, &info_fops); >> + if (IS_ERR(info_d) || !info_d) { >> + printk(KERN_ERR >> + "%s: create file of %s failed\n", >> + __func__, "enabled"); >> + err = -ENOMEM; >> + goto err_build_fail; >> + } >> + } >> + >> + return 0; >> + >> +err_build_fail: >> + return err; >> +} >> + >> +static int build_marker_control_files(void) >> +{ >> + struct marker_iter iter; >> + int err; >> + >> + err = 0; >> + if (!markers_control_dir) >> + return -EEXIST; >> + >> + marker_iter_reset(&iter); >> + marker_iter_start(&iter); >> + for (; iter.marker != NULL; marker_iter_next(&iter)) { >> + err = build_marker_file(iter.marker); >> + if (err) >> + goto err_build_fail; >> + } >> + marker_iter_stop(&iter); >> + return 0; >> + >> +err_build_fail: >> + return err; >> +} >> + >> +static int remove_marker_control_dir(struct marker *marker) >> +{ >> + struct dentry *channel_d, *marker_d; >> + >> + channel_d = dir_lookup(markers_control_dir, marker->channel); >> + if (!channel_d) >> + return -ENOENT; >> + >> + marker_d = dir_lookup(channel_d, marker->name); >> + if (!marker_d) >> + return -ENOENT; >> + >> + debugfs_remove_recursive(marker_d); >> + if (list_empty(&channel_d->d_subdirs)) { >> + debugfs_remove(channel_d); >> + } >> + >> + return 0; >> +} >> + >> +static void cleanup_control_dir(struct marker *begin, struct marker *end) >> +{ >> + struct marker *iter; >> + >> + if (!markers_control_dir) >> + return; >> + >> + for (iter = begin; iter < end; iter++) { >> + remove_marker_control_dir(iter); >> + } >> + >> + return; >> +} >> + >> +static void build_control_dir(struct marker *begin, struct marker *end) >> +{ >> + struct marker *iter; >> + int err; >> + >> + err = 0; >> + if (!markers_control_dir) >> + return; >> + >> + for (iter = begin; iter < end; iter++) { >> + err = build_marker_file(iter); >> + if (err) >> + goto err_build_fail; >> + } >> + >> + return; >> +err_build_fail: >> + cleanup_control_dir(begin, end); >> + return; >> +} >> + >> +static int module_notify(struct notifier_block *self, >> + unsigned long val, void *data) >> +{ >> + struct module *mod = data; >> + >> + switch (val) { >> + case MODULE_STATE_COMING: >> + build_control_dir(mod->markers, >> + mod->markers + mod->num_markers); >> + break; >> + case MODULE_STATE_GOING: >> + cleanup_control_dir(mod->markers, >> + mod->markers + mod->num_markers); >> + break; >> + } >> + return NOTIFY_DONE; >> +} >> + >> +static struct notifier_block module_nb = { >> + .notifier_call = module_notify, >> +}; >> >> static int __init ltt_trace_control_init(void) >> { >> @@ -733,8 +1004,27 @@ static int __init ltt_trace_control_init(void) >> goto err_create_destroy_trace_file; >> } >> >> - return 0; >> - >> + markers_control_dir = debugfs_create_dir(MARKERS_CONTROL_DIR, >> + ltt_root_dentry); >> + if (IS_ERR(markers_control_dir) || !markers_control_dir) { >> + printk(KERN_ERR >> + "ltt_channel_control_init: create dir of %s failed\n", >> + MARKERS_CONTROL_DIR); >> + err = -ENOMEM; >> + goto err_create_marker_control_dir; >> + } >> + >> + if(build_marker_control_files()) >> + goto err_build_fail; >> + >> + if (!register_module_notifier(&module_nb)) >> + return 0; >> + >> +err_build_fail: >> + debugfs_remove_recursive(markers_control_dir); >> + markers_control_dir = NULL; >> +err_create_marker_control_dir: >> + debugfs_remove(ltt_destroy_trace_file); >> err_create_destroy_trace_file: >> debugfs_remove(ltt_setup_trace_file); >> err_create_setup_trace_file: >> @@ -759,6 +1049,8 @@ static void __exit ltt_trace_control_exit(void) >> debugfs_remove(ltt_setup_trace_file); >> debugfs_remove(ltt_destroy_trace_file); >> debugfs_remove_recursive(ltt_control_dir); >> + debugfs_remove_recursive(markers_control_dir); >> + unregister_module_notifier(&module_nb); >> } >> >> module_init(ltt_trace_control_init); >> -- >> 1.5.4.rc3 >> >> >> _______________________________________________ >> ltt-dev mailing list >> ltt-dev at lists.casi.polymtl.ca >> http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev >> > -- Regards Gui Jianfeng