From mboxrd@z Thu Jan 1 00:00:00 1970 From: compudj@krystal.dyndns.org (Mathieu Desnoyers) Date: Wed, 4 Feb 2009 01:30:33 -0500 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: <20090204063033.GA12010@Krystal> * Mathieu Desnoyers (compudj at krystal.dyndns.org) 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 I'll also change enabled -> enable to follow the same semantic as debugfs/ltt/ per-channel control files. Mathieu > > | | | `-- 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 > 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 > > > > -- > Mathieu Desnoyers > OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68 > > _______________________________________________ > ltt-dev mailing list > ltt-dev at lists.casi.polymtl.ca > http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev > -- Mathieu Desnoyers OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68