Friday May 13, 2005 FEM: Let's get technical Back again. They say a picture is worth a thousand words, but I don't know how to make pictures so I'll just use words and code snippets. Remembering from my previous entry that FEM was designed for use by the NFS server and that there is no user side API, let me try to tell you how to use FEM. Hmm, I just realized that it would help to know about the Vnode Interfaces project, which introduced the concept of vnode/vfs operation registration, however, I'll leave that to someone else. So let's say you're inside the kernel and you want to be notified of certain vnode operations, how do you do it? Step 1: Define the template for the ops you're interested in monitoring static const fs_operation_def_t my_ops_tmpl[] = { VOPNAME_OPEN, my_open, VOPNAME_WRITE, my_write, VOPNAME_SETATTR, my_setattr, VOPNAME_RWLOCK, my_rwlock, VOPNAME_SPACE, my_space, VOPNAME_SETSECATTR, my_setsecattr, VOPNAME_VNEVENT, my_vnevent, /* I haven't explained this one yet, tune in later */ NULL, NULL }; Step 2: Create your fem_t (your monitor array of operations) fem_t *my_ops; e = fem_create("my operations", my_ops_tmpl, &my_ops); if (e != 0) operation FAILED; Now you're ready to roll, pick the vnodes you want to monitor and throw your ops on them. Step 3: Install the monitored ops onto a vnode fem_install(vp, my_ops, (void *)myarg, OPUNIQ, NULL, NULL); That's it, you're done with the easy part. Now is where the work begins. Why did you throw a monitor on this vnode? What do you want to do when one of the monitored operations occurs? Its time to write your monitors. Like I said earlier, FEM is just a mechanism to intercept vnode/vfs operations, all the work is up to you when you write the monitor. However, before I continue, let me explain a few of the arguments to the fem_install() function. The first 2 should be obvious, but the others may need a little explanation. "myarg" is whatever you need to pass to you're monitor, in the case of NFSv4, I pass a one of the server state structures known as an rfs4_file_t. By the way, this arg cannot be NULL. The next arg is a flag which specifies how to install the monitor: FORCE - means install this monitor, no matter what other monitors may be on this vnode. OPUNIQ - means install this monitor if the operation set is unique (don't install the same set of monitors twice) OPARGUNIQ - means install this monitor if the ops/arg combination is unique The last two args are function pointers to hold and release functions for the arg that you pass in. These are optional. Step 4: Define your monitors This could have been step 1, and may well be step one during your design phase. So let me pick an op that is in my_ops array, like OPEN, and define a monitor for it. int my_open( femarg_t *arg, int mode, cred_t *cr) /* note, looks a lot like vop_open only uses femarg_t instead of vnode */ { int rc; myarg_t *myarg; myarg = (myarg_t *)arg->fa_fnode->fn_available; /* this is the arg you passed on fem_install() */ /* * you have now intercepted a call to open on this vnode, do whatever you want here before passing control * on to the next level, which could be another monitor or the underlying file system. * for nfsv4, I check for conflict and recall the delegation. */ rc = vnext_open(arg, mode, cr); /* here is where you could do some post processing, if desired */ return (rc); } That's it. Be creative, have fun, but be careful. You can install and uninstall (fem_uninstall()) monitors as you wish, but be careful what you do inside the monitors. It is up to you to prevent deadlocks. Calling other VOPs from inside a monitor is dangerous unless you know what you're doing. Also note, you can deny service just by having your monitor return without calling the vnext_ routine. This is getting too long already. I will need to write again to explain the vnode lifecycle events (how do you monitor a vnode before it is created and how do you know when it is destroyed) and VOP_VNEVENT. I also need to talk about the lack of user level APIs, though I think you should see why now. Here's a hint: 1) the only consumer so far is in the kernel. 2) FEM is just a framework, to have a user API, default monitors would have to exist in the kernel already. More later. ( May 13 2005, 10:51:19 AM PDT ) Permalink Comments [13]
Posted by Carson Gaspar on August 03, 2005 at 12:45 AM PDT #
Posted by kl on January 22, 2006 at 07:36 AM PST #
Posted by 手机图片 on May 19, 2006 at 01:47 AM PDT #
Posted by sd on June 30, 2006 at 01:51 AM PDT #
Posted by rewrew on July 08, 2006 at 06:53 PM PDT #
Posted by wer on August 01, 2006 at 06:53 PM PDT #
Posted by werwe on August 10, 2006 at 01:13 AM PDT #
Posted by 24634eerter on August 21, 2006 at 01:44 AM PDT #
Posted by werwe on September 29, 2006 at 12:57 AM PDT #
Posted by xfsdfsd on October 12, 2006 at 10:40 AM PDT #
Posted by fdasfdsa on October 12, 2006 at 07:39 PM PDT #