The demise of utracer.
K.Prasad
prasad at linux.vnet.ibm.com
Tue Jul 1 09:34:35 UTC 2008
On Tue, Jul 01, 2008 at 01:44:17AM -0700, Roland McGrath wrote:
> Sorry to be blunt, Chris. But I think you're headed down a useless rat hole.
>
> I agree that the usage of /proc you've described is a bad interface.
> I am slightly mystified as to how that came to be what you settled on.
> I don't think it's worthwhile to hash over that. Let's move on.
>
> Please forget ptrace. Please forget about adding syscalls. At this
> point I think I just need you to give me the benefit of the doubt when
> I tell you I am sure this is not the way, and even dabbling sidetracks
> us from really useful progress. Let's move on.
>
> To reiterate: transport is boring. This is not where the there is.
> We need to focus on what we're providing that anyone could care to
> have a means to communicate with!
>
> I'm pretty sure what most people had in mind when saying "fd-based" is
> approximately this: you do one open call, that fd is your handle on
> one session with the interface. You can write/ioctl to send it
> commands, and you can read (and perhaps ioctl) on it to receive either
> information replies or event notifications. You can use poll/select
> et al for efficient wakeup when there is something the interface wants
> to tell you. As with all fds, sudden death of the holder of the fd
> implicitly closes it and that triggers cleanup of the session on the
> kernel side. There are more possibilities with multiple fds used
> together as one "session with the interface", but this is the basic
> one. Let's start with that focus and move on.
>
> Below is a trivial example I whipped up. This uses debugfs. There
> are myriad ways to do the same thing; this one is simple and handy.
> I hope it illustrates how a magic file can set up per-open data
> structures for its operations to use, and tear them down gracefully
> and automatically on close. It should be clear how to add .write,
> .poll, .unlocked_ioctl, etc. functions to build a full transport
> this way without much hair. This method is the easy path to start
> with, and we can worry more about transport later. Let's move on.
>
> The way to find the easy route is to ask for directions. When it
> seems like there ought to be a more natural way to do something, there
> might well be some ways. When you post here about what you're up
> against, people here can give you pointers to what might help. It's
> not like posting on LKML and braving the flames. Noone here is going
> to give you a hard time (not worse than this, anyway). We need your
> participation to be able to share what we know. Let's move on together.
>
> I'm sorry I've been remiss in writing up everything I've promised
> about what I think we do need to focus on. It hasn't helped to get
> sidetracked on what I say is the boring stuff. But I recognize that
> my disorganization makes it difficult on your end.
>
>
> Thanks,
> Roland
>
>
> -----
> /*
> * Compile the module and insmod it.
> * Be sure to have done "mount -t debugfs debugfs /sys/kernel/debug"
> * (systemtap or something else might already have done it for you).
> * Look at /sys/kernel/debug/foo for example behavior.
> */
>
> #include <linux/sched.h>
> #include <linux/module.h>
> #include <linux/debugfs.h>
> #include <asm/atomic.h>
>
> MODULE_DESCRIPTION("example using debugfs");
> MODULE_LICENSE("GPL");
>
> static atomic_t next = ATOMIC_INIT(0);
>
> static int example_open(struct inode *inode, struct file *file)
> {
> /*
> * The 'struct file' describes what the user's file descriptor
> * from this one open points to. It's shared by dup and fd
> * inheritance, but not by an independent open call. We can
> * stash here some data specific to just this one open file
> * description.
> */
> file->private_data = (void *) (unsigned long) atomic_inc_return(&next);
> return 0;
> }
>
> static ssize_t example_read(struct file *file, char __user *buf,
> size_t count, loff_t *ppos)
> {
> unsigned long n = (unsigned long) file->private_data;
> char string[128];
> int size = snprintf(string, sizeof string, "you are number %lu\n", n);
>
> return simple_read_from_buffer(buf, count, ppos, string, size);
> }
>
> static int example_release(struct inode *inode, struct file *file)
> {
> unsigned long n = (unsigned long) file->private_data;
> printk(KERN_NOTICE "bye bye number %lu\n", n);
> return 0;
> }
>
> static const struct file_operations example_fops = {
> .owner = THIS_MODULE,
> .open = example_open,
> .release = example_release,
> .read = example_read
> };
>
> static struct dentry *top_dentry;
>
> static int __init init_example(void)
> {
> struct dentry *d = debugfs_create_file("foo", 0666, NULL,
> NULL, &example_fops);
> if (!d)
> return -EROFS;
> if (IS_ERR(d))
> return PTR_ERR(d);
> top_dentry = d;
> return 0;
> }
>
> static void __exit exit_example(void)
> {
> debugfs_remove(top_dentry);
> }
>
> module_init(init_example);
> module_exit(exit_example);
>
Hi All,
Sorry if I have missed out something I need to know before I
respond to this email. But the "trace" infrastructure (lib/trace.c)
already provides such a facility which more features such as per-cpu
buffer for faster transmission (it is a wrapper over "relay" which
sits on top of "debugfs").
The interfaces provided by "trace" are much simpler/functional than
setting up a "debugfs" interface manually (see
samples/trace/fork_trace.c) and the directory structure and control
files setup by "trace" are already familiar to the systemtap code.
Thanks,
K.Prasad
P.S.: "trace" is currently in -mm tree.
More information about the utrace-devel
mailing list