Crossfs is a trivial file system based on my Null file system (Appendix sec-appendix-typical-stateless-nullfs). When a lookup operation crosses into this file system, it performs a simple action such as logging a message on the system console. For all other vnode and vfs operations, it forwards them to the interposed file system. Crossfs keeps no state.
The example of Figure fig-fist-definition-crossfs shows the FiST input for this file system. Specifically, in this implementation I wish to log the user ID and the host from where access to the files originated.
6.5in
%{
#ifdef HAVE_AC_CONFIG_H
/* include Autoconf-generated header */
# include "config.h"
#endif
%}
%fstype stateless
%filter syslog(%cur_uid, %from_host) $$ vn_lookup {%cur_uid > 999 && %cur_uid != 2301}
%%
/* Empty FiST rules section */
%%
/* No additional code needed */
|
The code automatically generated for Crossfs will be identical to Nullfs, with the exception of the lookup function. One possible code for the lookup function is shown in Figure fig-fist-definition-crossfs-code.
5.5in
static int
fist_crossfs_lookup( vnode_t *dvp, char *name, vnode_t **vpp,
pathname_t *pnp, int flags, vnode_t *rdir, cred_t *cr)
{
/* check if event should be logged */
if (u.u_uid > 999 && u.u_uid != 2301)
kernel_syslog("File %s was accessed at %d by %s@%s.\n",
name, curtime, u.u_uid, fist_get_from_host(u));
/* pass operation to file system, and return status */
return VOP_LOOKUP(dvp, name, vpp, pnp, flags, rdir, cr);
}
|
This example shows how FiST ``%'' directives get translated into local variables (name), global variables (curtime), or even special functions (fist_get_from_host()).
Figure fig-fist-definition-crossfs-code-4nfs shows the code that would be generated for the NFS version of the same lookup operation.
4.3in
diropres *
nfsproc2_crossfs_lookup( diropargs *argp,
struct svc_req *rqstp;
{
diropres res;
uid_t uid;
gid_t gid;
char host[MAXHOSTNAMELEN];
time_t tm;
/* get credentials */
if (fist_getcreds(rqstp, &uid, &gid, &host) < 0)
return(NULL);
/* get time */
time(&tm);
/* check if event should be logged */
if (uid > 999 && uid != 2301)
syslog("File %s was accessed at %d by %s@%s.\n",
argp->name, ctime(&tm), uid, host);
/* perform generic lookup operation, and return status */
res = fist_nfs_lookup(argp, rqstp);
return &res;
}
|