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; } |