RE: DazukoFS for FreeBSD 4
"Patrick Bihan-Faou" <[email protected]>
| Newsgroups | gmane.linux.dazuko.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi John,
Here is the patch set against a fresh checkout of the REL_21 branch of
dazuko.
This set of patch adds the following features:
- DAZUKO_ON_WRITE events: they monitor the following syscalls on freebsd 4:
- write
- writev
- pwrite
- aio_write (optionally)
- ftruncate
- mmap (to indicate that the file may be written)
in each case the offset + the size of the write is indicated except for
the following cases:
- truncate: only the offset is sent, no size
- mmap: no size and no offset
The write events are sent back to the userland daemon.
- Support for the dup and dup2 syscalls.
These are needed to properly track the number of references to a single
opened file. This also means that the hash structure used to keep track of
the monitored files contains a refcount.
- Finally, I have extended the logic of the filename resolution code to be
more consistent with what the system does as far as FOLLOW/NOFOLLOW goes and
also with respect to the CREATE logic.
- I have added the necessary options in configure to enable the write events
support and optionally the async I/O write (the issue with async is that
since the actual write may fail after the syscall occurs, the event may be
bogus, plus it makes it difficult to calculate the proper offset in case of
an append...).
All these changes have been tested on FreeBSD 4.9 and seem to be working
properly.
Next, I'll be working on the rename() syscall and various meta data stuff
(chmod, etc.)
In order to implement the writes/dups, I had to add a dazuko_hash_lookup()
call that returns a hash entry without removing it from the linked list.
Also in order to optimize a couple of things, I use this call from the
dazuko_freebsd.c file. This is not very clean architecture-wise, but it
simplifies a lot some cases. I think that this may call for the separation
of the hash linked list from the dazuko_xp.c code, or at least to make it
visible in a clean way from the platform specific code.
Anyway, there is room for improvement....
Have fun,
Patrick.
> -----Original Message-----
> From: John Ogness [mailto:[email protected]]
> Sent: Wednesday, September 08, 2004 10:51 AM
> To: [email protected]
> Subject: Re: [Dazuko-devel] DazukoFS for FreeBSD 4
>
>
> Patrick Bihan-Faou wrote:
> > As I said, let me clean them up first ;)
> >
> > I'll send that today.
>
> Hi,
>
> No need to rush. My favorite part of open source development is that
> everyone can go at his own pace and do things when they have time
> for it. I
> probably won't be able to check out the patches until the weekend anyway.
>
> John Ogness
>
> --
> Dazuko Maintainer
_______________________________________________
Dazuko-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/dazuko-devel
dz-2.1.0-pre1.write.patch
(application/octet-stream, 41.4 KB)
Index: configure
===================================================================
RCS file: /cvsroot/dazuko/dazuko/configure,v
retrieving revision 1.24.2.2
diff -u -r1.24.2.2 configure
--- configure 7 Sep 2004 20:38:52 -0000 1.24.2.2
+++ configure 8 Sep 2004 17:34:41 -0000
@@ -58,10 +58,12 @@
echo " --enable-event-unlink capture ON_UNLINK events"
echo " --enable-event-rmdir capture ON_RMDIR events"
echo " --enable-event-close-modified capture ON_CLOSE_MODIFIED events"
+ echo " --enable-event-write capture ON_WRITE events"
echo " --enable-devfs support devfs (Linux only)"
echo " --enable-default-capabilities support Default Capabilities (Linux 2.6 only)"
echo " --disable-compat1 disable 1.x compatibility (IO/Linux only)"
echo " --enable-fist enable FiST support (experimental)"
+ echo " --enable-async-io support async IO writes (FreeBSD only)"
echo " --enable-debug print extra debug information"
echo ""
echo "Optional Packages:"
@@ -527,6 +529,16 @@
echo "KFLAGS += -DDAZUKO_FIST" >> Makefile
fi
+ if [ ${ON_WRITE} -eq 1 ]
+ then
+ echo "KFLAGS += -DON_WRITE_SUPPORT" >> Makefile
+ fi
+
+ if [ ${ASYNC_IO} -eq 1 ]
+ then
+ echo "KFLAGS += -DASYNC_IO_SUPPORT" >> Makefile
+ fi
+
echo "" >> Makefile
echo "all: dazuko.o" >> Makefile
@@ -616,6 +628,16 @@
echo "CFLAGS += -DDAZUKO_FIST" >> Makefile
fi
+ if [ ${ON_WRITE} -eq 1 ]
+ then
+ echo "CFLAGS += -DON_WRITE_SUPPORT" >> Makefile
+ fi
+
+ if [ ${ASYNC_IO} -eq 1 ]
+ then
+ echo "CFLAGS += -DASYNC_IO_SUPPORT" >> Makefile
+ fi
+
echo "SRCS = dazuko_xp.c ${DAZUKO_EXT_C} vnode_if.h" >> Makefile
echo "KMOD = dazuko" >> Makefile
@@ -693,6 +715,11 @@
echo -n " ON_CLOSE_MODIFIED"
fi
+ if [ ${ON_WRITE} -eq 1 ]
+ then
+ echo -n " ON_WRITE"
+ fi
+
echo ""
if [ "${OS}" = "Linux" ]
@@ -734,6 +761,14 @@
fi
fi
+ echo -n "async io = "
+ if [ ${ASYNC_IO} -eq 1 ]
+ then
+ echo "yes"
+ else
+ echo "no"
+ fi
+
echo -n "library 1.x compatibility = "
if [ ${COMPAT12} -eq 1 ]
then
@@ -765,6 +800,8 @@
ON_UNLINK=0
ON_RMDIR=0
ON_CLOSE_MODIFIED=0
+ON_WRITE=0
+ASYNC_IO=0
COMPAT12=1
# DEVFS=2 => uninitialized
DEVFS=2
@@ -809,6 +846,9 @@
--disable-event-close-modified)
ON_CLOSE_MODIFIED=0
;;
+ --disable-event-write)
+ ON_WRITE=0
+ ;;
--enable-event-unlink)
ON_UNLINK=1
;;
@@ -818,6 +858,9 @@
--enable-event-close-modified)
ON_CLOSE_MODIFIED=1
;;
+ --enable-event-write)
+ ON_WRITE=1
+ ;;
--disable-devfs)
DEVFS=0
;;
@@ -830,6 +873,12 @@
--enable-default-capabilities)
DEFAULT_CAPABILITIES=1
;;
+ --disable-asyn-io)
+ ASYNC_IO=0
+ ;;
+ --enable-asyn-io)
+ ASYNC_IO=1
+ ;;
--disable-debug)
DEBUG=0
;;
Index: dazuko_events.h
===================================================================
RCS file: /cvsroot/dazuko/dazuko/dazuko_events.h,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 dazuko_events.h
--- dazuko_events.h 5 Sep 2004 15:21:52 -0000 1.1.2.1
+++ dazuko_events.h 8 Sep 2004 17:34:41 -0000
@@ -42,6 +42,7 @@
#define DAZUKO_ON_CLOSE_MODIFIED 8
#define DAZUKO_ON_UNLINK 16
#define DAZUKO_ON_RMDIR 32
+#define DAZUKO_ON_WRITE 64
#endif
Index: dazuko_freebsd.c
===================================================================
RCS file: /cvsroot/dazuko/dazuko/dazuko_freebsd.c,v
retrieving revision 1.30.2.2
diff -u -r1.30.2.2 dazuko_freebsd.c
--- dazuko_freebsd.c 7 Sep 2004 20:38:52 -0000 1.30.2.2
+++ dazuko_freebsd.c 8 Sep 2004 17:34:44 -0000
@@ -32,6 +32,50 @@
POSSIBILITY OF SUCH DAMAGE.
*/
+/* list of syscalls to intercept:
+ *
+ * ** write ssize_t write(int fd, const void *buf, size_t nbyte);
+ * ** open int open(char *path, int flags, int mode);
+ * ** close int close(int fd);
+ * creat int creat(char *path, int mode);
+ * link int link(char *path, char *link);
+ * unlink int unlink(char *path);
+ * ??? mknod int mknod(char *path, int mode, int dev);
+ * chmod int chmod(char *path, int mode);
+ * chown int chown(char *path, int uid, int gid);
+ * chflags int chflags(char *path, int flags);
+ * fchflags int fchflags(int fd, int flags);
+ * ??? ioctl
+ * symlink int symlink(char *path, char *link);
+ * ??? msync
+ * ** mmap int mmap(void *addr, int len, int prot, int flags, int fd, long pos);
+ * munmap int munmap(void *addr, size_t len);
+ * ??? fcntl
+ * ??? fsync
+ * ** writev int writev(int fd, struct iovec *iovp, u_int iovcnt);
+ * fchown int fchown(int fd, int uid, int gid);
+ * fchmod int fchmod(int fd, int mode);
+ * rename int rename(char *from, char *to);
+ * truncate int truncate(char *path, long length);
+ * ** ftruncate int ftruncate(int fd, long length);
+ * ??? mkfifo int mkfifo(char *path, int mode);
+ * mkdir int mkdir(char *path, int mode);
+ * rmdir int rmdir(char *path);
+ * utimes int utimes(char *path, struct timeval *tptr);
+ * ??? getfh
+ * ** pwrite ssize_t pwrite(int fd, const void *buf, size_t nbyte, int pad, off_t offset);
+ * ??? undelete int undelete(char *path);
+ * futimes int futimes(int fd, struct timeval *tptr);
+ * lchown int lchown(char *path, int uid, int gid);
+ * lchmod int lchmod(char *path, mode_t mode);
+ * lutimes int lutimes(char *path, struct timeval *tptr);
+ * ??? fhopen int fhopen(const struct fhandle *u_fhp, int flags);
+ * ** aio_write int aio_write(struct aiocb *aiocbp);
+ * ** dup int dup(ind fd);
+ * ** dup2 int dup2(int from, int to);
+ */
+
+
#include <sys/types.h>
#include <sys/module.h>
@@ -53,6 +97,15 @@
#include <sys/namei.h>
#include <sys/param.h>
#include <sys/vnode.h>
+#include <sys/fcntl.h>
+
+#ifdef ASYNC_IO_SUPPORT
+#include <sys/event.h> /* for aio_write */
+#include <sys/aio.h>
+#endif
+
+#include <sys/mman.h> /* for mmap */
+#include <vm/vm.h>
#include "dazuko_freebsd.h"
#include "dazuko_xp.h"
@@ -72,22 +125,52 @@
static int syscall_in_use = 0;
-#if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+#if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT) || defined(ON_WRITE_SUPPORT)
static int freebsd_dazuko_sys_open(struct proc *p, struct open_args *uap);
static struct sysent freebsd_dazuko_sys_open_sysent = { 3, (sy_call_t*)freebsd_dazuko_sys_open };
static sy_call_t *original_sys_open = NULL;
+
+static int freebsd_dazuko_sys_dup(struct proc *p, struct dup_args *uap);
+static struct sysent freebsd_dazuko_sys_dup_sysent = { (sizeof(struct dup_args) / sizeof(register_t)), (sy_call_t*)freebsd_dazuko_sys_dup };
+static sy_call_t *original_sys_dup = NULL;
+
+static int freebsd_dazuko_sys_dup2(struct proc *p, struct dup2_args *uap);
+static struct sysent freebsd_dazuko_sys_dup2_sysent = { (sizeof(struct dup2_args) / sizeof(register_t)), (sy_call_t*)freebsd_dazuko_sys_dup2 };
+static sy_call_t *original_sys_dup2 = NULL;
#endif
-#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT) || defined(ON_WRITE_SUPPORT)
static int freebsd_dazuko_sys_close(struct proc *p, struct close_args *uap);
static struct sysent freebsd_dazuko_sys_close_sysent = { 1, (sy_call_t*)freebsd_dazuko_sys_close };
static sy_call_t *original_sys_close = NULL;
#endif
-#ifdef ON_CLOSE_MODIFIED_SUPPORT
+#if defined(ON_CLOSE_MODIFIED_SUPPORT) || defined(ON_WRITE_SUPPORT)
static int freebsd_dazuko_sys_write(struct proc *p, struct write_args *uap);
static struct sysent freebsd_dazuko_sys_write_sysent = { 3, (sy_call_t*)freebsd_dazuko_sys_write };
static sy_call_t *original_sys_write = NULL;
+
+static int freebsd_dazuko_sys_writev(struct proc *p, struct writev_args *uap);
+static struct sysent freebsd_dazuko_sys_writev_sysent = { sizeof(struct writev_args) / sizeof(register_t), (sy_call_t*)freebsd_dazuko_sys_writev };
+static sy_call_t *original_sys_writev = NULL;
+
+static int freebsd_dazuko_sys_pwrite(struct proc *p, struct pwrite_args *uap);
+static struct sysent freebsd_dazuko_sys_pwrite_sysent = { sizeof(struct pwrite_args) / sizeof(register_t), (sy_call_t*)freebsd_dazuko_sys_pwrite };
+static sy_call_t *original_sys_pwrite = NULL;
+
+#ifdef ASYNC_IO_SUPPORT
+static int freebsd_dazuko_sys_aio_write(struct proc *p, struct aio_write_args *uap);
+static struct sysent freebsd_dazuko_sys_aio_write_sysent = { sizeof(struct aio_write_args) / sizeof(register_t), (sy_call_t*)freebsd_dazuko_sys_aio_write };
+static sy_call_t *original_sys_aio_write = NULL;
+#endif
+
+static int freebsd_dazuko_sys_ftruncate(struct proc *p, struct ftruncate_args *uap);
+static struct sysent freebsd_dazuko_sys_ftruncate_sysent = { sizeof(struct ftruncate_args) / sizeof(register_t), (sy_call_t*)freebsd_dazuko_sys_ftruncate };
+static sy_call_t *original_sys_ftruncate = NULL;
+
+static int freebsd_dazuko_sys_mmap(struct proc *p, struct mmap_args *uap);
+static struct sysent freebsd_dazuko_sys_mmap_sysent = { sizeof(struct mmap_args) / sizeof(register_t), (sy_call_t*)freebsd_dazuko_sys_mmap };
+static sy_call_t *original_sys_mmap = NULL;
#endif
#ifdef ON_EXEC_SUPPORT
@@ -347,9 +430,9 @@
/* file structure */
#ifdef DAZUKO_FIST
-static void freebsd_get_full_fileinfo(struct proc *p, struct vnode *v, char **fullpath, char **freefullpath, struct file_properties *file_p)
+static void freebsd_get_full_fileinfo(struct proc *p, struct vnode *v, char **fullpath, char **freefullpath, struct file_properties *file_p, int create, int nofollow)
#else
-static void freebsd_get_full_fileinfo(struct proc *p, const char *path, char **fullpath, char **freefullpath, struct file_properties *file_p)
+static void freebsd_get_full_fileinfo(struct proc *p, const char *path, char **fullpath, char **freefullpath, struct file_properties *file_p, int create, int nofollow)
#endif
{
struct proc localp;
@@ -367,13 +450,13 @@
dazuko_bzero(&localfd, sizeof(localfd));
dazuko_bzero(file_p, sizeof(struct file_properties));
- NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, path, p);
+ NDINIT(&nd, LOOKUP, nofollow ? NOFOLLOW : FOLLOW, UIO_USERSPACE, path, p);
error = namei(&nd);
if (error != 0)
{
- if (error == ENOENT)
+ if (error == ENOENT && create)
{
/* let's try to resolve the parent dir (if possible) */
char * kpath = xp_malloc(MAXPATHLEN+1);
@@ -420,7 +503,7 @@
dazuko_bzero(&ndparent, sizeof(ndparent));
- NDINIT(&ndparent, LOOKUP, NOFOLLOW, UIO_SYSSPACE, lookuppath, p);
+ NDINIT(&ndparent, LOOKUP, nofollow ? NOFOLLOW : FOLLOW, UIO_SYSSPACE, lookuppath, p);
error = namei(&ndparent);
@@ -430,7 +513,8 @@
return;
}
- if (ndparent.ni_vp != NULL)
+ if ((ndparent.ni_vp != NULL) /* if we found the parent */
+ && (ndparent.ni_vp->v_type == VDIR)) /* and it is a directory */
{
localp.p_textvp = ndparent.ni_vp;
localp.p_fd = &localfd;
@@ -517,9 +601,9 @@
int length;
#ifdef DAZUKO_FIST
- freebsd_get_full_fileinfo(dfs->extra_data->p, dfs->extra_data->vnode, &fullpath, &freefullpath, &(dfs->file_p));
+ freebsd_get_full_fileinfo(dfs->extra_data->p, dfs->extra_data->vnode, &fullpath, &freefullpath, &(dfs->file_p), dfs->extra_data->create, dfs->extra_data->nofollow);
#else
- freebsd_get_full_fileinfo(dfs->extra_data->p, dfs->extra_data->user_filename, &fullpath, &freefullpath, &(dfs->file_p));
+ freebsd_get_full_fileinfo(dfs->extra_data->p, dfs->extra_data->user_filename, &fullpath, &freefullpath, &(dfs->file_p), dfs->extra_data->create, dfs->extra_data->nofollow);
#endif
if (freefullpath)
@@ -643,7 +727,7 @@
return ret; \
}
-#if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+#if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT) || defined(ON_WRITE_SUPPORT)
static inline int freebsd_dazuko_sys_open_inner(struct proc *p, struct open_args *uap)
{
struct dazuko_file_struct *dfs = NULL;
@@ -651,7 +735,7 @@
struct xp_daemon_id xp_id;
int error = 0;
int check_error = 0;
-#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT) || defined(ON_WRITE_SUPPORT)
struct xp_file file;
#endif
@@ -704,6 +788,9 @@
dfs->extra_data->user_filename = uap->path;
dfs->extra_data->p = p;
+ dfs->extra_data->create = (event_p.flags & O_CREAT);
+ dfs->extra_data->nofollow = (event_p.flags & O_NOFOLLOW);
+
error = dazuko_sys_pre(DAZUKO_ON_OPEN, dfs, &event_p);
}
else
@@ -726,7 +813,7 @@
/* call the standard open function */
error = original_sys_open(p, uap);
- #if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+ #if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT) || defined(ON_WRITE_SUPPORT)
{
if (!check_error)
{
@@ -765,7 +852,7 @@
if (!check_error)
{
- #if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+ #if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT) || defined(ON_WRITE_SUPPORT)
{
if (!error && dfs)
dazuko_sys_post(DAZUKO_ON_OPEN, dfs, &file, &event_p);
@@ -779,9 +866,242 @@
}
DAZUKO_SYSCALL_WRAPPER(open)
+
+static inline int freebsd_dazuko_sys_dup_inner(struct proc *p, struct dup_args *uap)
+{
+ struct dazuko_file_struct dfs;
+ struct event_properties event_open;
+ struct xp_daemon_id xp_id;
+ int error = 0;
+ int check_error = 0;
+ struct xp_file file_from;
+ struct xp_file file_new;
+ int new_fd;
+ struct hash * h;
+
+ if (p == NULL)
+ {
+ xp_print("dazuko: warning: freebsd_dazuko_sys_dup(NULL, ...)\n");
+ check_error = -1;
+ }
+ else
+ {
+ xp_id.pid = p->p_pid;
+ check_error = dazuko_sys_check(DAZUKO_ON_OPEN, 1, &xp_id);
+ }
+
+ if (!check_error)
+ {
+ if ( (uap == NULL)
+ || (p->p_fd == NULL)
+ || (p->p_fd->fd_ofiles == NULL) )
+ {
+ /* something is seriously wrong */
+ check_error = -1;
+ }
+ else if ( (uap->fd < 0)
+ || ((u_int)(uap->fd) >= p->p_fd->fd_nfiles)
+ || (p->p_fd->fd_ofiles[uap->fd] == NULL) )
+ {
+ /* the oldfd is invalid */
+ check_error = -1;
+ }
+ else
+ {
+ /* grab the file* for possible later use */
+ file_from.file = p->p_fd->fd_ofiles[uap->fd];
+ }
+ }
+
+ error = original_sys_dup(p, uap);
+
+ if (error || check_error)
+ {
+ return error;
+ }
+
+ new_fd = p->p_retval[0];
+
+ if (new_fd < 0
+ || new_fd >= p->p_fd->fd_nfiles
+ || p->p_fd->fd_ofiles == NULL
+ || p->p_fd->fd_ofiles[new_fd] == NULL)
+ {
+ return error;
+ }
+
+ if (p->p_cred == NULL)
+ {
+ xp_print("dazuko: error: freebsd_dazuko_sys_close.p->p_cred=NULL\n");
+ return error;
+ }
+
+ /* now indicate the open event for the duplicated fd */
+
+ /* we have to grab the filename */
+
+ h = dazuko_lookup_hash(&file_from);
+
+ if (!h)
+ return error;
+
+ dazuko_bzero(&dfs, sizeof(struct dazuko_file_struct));
+ dfs.filename = h->name;
+ dfs.filename_length = h->namelen;
+ dfs.should_scan = 1;
+
+ dazuko_bzero(&event_open, sizeof(event_open));
+ event_open.pid = p->p_pid;
+ event_open.set_pid = 1;
+ event_open.uid = p->p_cred->p_ruid;
+ event_open.set_uid = 1;
+
+ file_new.file = p->p_fd->fd_ofiles[new_fd];
+
+ dazuko_sys_post(DAZUKO_ON_OPEN, &dfs, &file_new, &event_open);
+
+ return error;
+}
+
+DAZUKO_SYSCALL_WRAPPER(dup)
+
+static inline int freebsd_dazuko_sys_dup2_inner(struct proc *p, struct dup2_args *uap)
+{
+ struct dazuko_file_struct dfs;
+ struct event_properties event_open;
+ struct xp_daemon_id xp_id;
+ int error = 0;
+ int check_error = 0;
+ struct xp_file file_from;
+ struct xp_file file_to;
+ struct xp_file file_new;
+ int new_fd;
+ int will_close_newfd = 0;
+ struct hash * h;
+
+ if (p == NULL)
+ {
+ xp_print("dazuko: warning: freebsd_dazuko_sys_open(NULL, ...)\n");
+ check_error = -1;
+ }
+ else
+ {
+ xp_id.pid = p->p_pid;
+ check_error = dazuko_sys_check(DAZUKO_ON_OPEN, 1, &xp_id);
+ }
+
+ if (!check_error)
+ {
+ if ( (uap == NULL)
+ || (p->p_fd == NULL)
+ || (p->p_fd->fd_ofiles == NULL) )
+ {
+ /* something is seriously wrong */
+ check_error = -1;
+ }
+ else if ( (uap->from < 0)
+ || ((u_int)(uap->from) >= p->p_fd->fd_nfiles)
+ || (p->p_fd->fd_ofiles[uap->from] == NULL) )
+ {
+ /* the oldfd is invalid */
+ check_error = -1;
+ }
+ else if (uap->from == uap->to)
+ {
+ /* oldfd and newfd are equal, there is nothing to do */
+ check_error = -1;
+ }
+ else
+ {
+ /* grab the file* for possible later use */
+ file_from.file = p->p_fd->fd_ofiles[uap->from];
+
+ if ( (uap->to < 0)
+ || ((u_int)(uap->to) >= p->p_fd->fd_nfiles)
+ || (p->p_fd->fd_ofiles[uap->to] == NULL) )
+ {
+ will_close_newfd = 0;
+ }
+ else
+ {
+ will_close_newfd = 1;
+ file_to.file = p->p_fd->fd_ofiles[uap->to];
+ }
+ }
+ }
+
+ error = original_sys_dup2(p, uap);
+
+ new_fd = p->p_retval[0];
+
+ if ( error
+ || check_error
+ || (new_fd < 0)
+ || (new_fd >= p->p_fd->fd_nfiles)
+ || (p->p_fd->fd_ofiles == NULL)
+ || (p->p_fd->fd_ofiles[new_fd] == NULL) )
+ {
+ return error;
+ }
+
+ if (p->p_cred == NULL)
+ {
+ xp_print("dazuko: error: freebsd_dazuko_sys_dup2.p->p_cred=NULL\n");
+ return error;
+ }
+
+ h = dazuko_lookup_hash(&file_to);
+
+ if (will_close_newfd && h)
+ {
+ /* first indicate the close of the old fd */
+
+ struct event_properties event_close;
+
+ dazuko_bzero(&event_close, sizeof(event_close));
+ event_close.pid = p->p_pid;
+ event_close.set_pid = 1;
+ event_close.uid = p->p_cred->p_ruid;
+ event_close.set_uid = 1;
+
+ dazuko_sys_post(DAZUKO_ON_CLOSE, NULL, &file_to, &event_close);
+ }
+
+
+ /* now indicate the open event for the duplicated fd */
+
+ /* we have to grab the filename */
+
+ h = dazuko_lookup_hash(&file_from);
+
+ /* if we can't find the hash entry, that means the file is not monitored
+ * in this case, no need to indicate the dup event */
+ if (!h)
+ return error;
+
+ dazuko_bzero(&dfs, sizeof(struct dazuko_file_struct));
+
+ dfs.should_scan = 1;
+ dfs.filename = h->name;
+ dfs.filename_length = h->namelen;
+
+ dazuko_bzero(&event_open, sizeof(event_open));
+ event_open.pid = p->p_pid;
+ event_open.set_pid = 1;
+ event_open.uid = p->p_cred->p_ruid;
+ event_open.set_uid = 1;
+
+ file_new.file = p->p_fd->fd_ofiles[new_fd];
+
+ dazuko_sys_post(DAZUKO_ON_OPEN, &dfs, &file_new, &event_open);
+
+ return error;
+}
+
+DAZUKO_SYSCALL_WRAPPER(dup2)
#endif
-#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT) || defined(ON_WRITE_SUPPORT)
static inline int freebsd_dazuko_sys_close_inner(struct proc *p, struct close_args *uap)
{
/* The kernel wants to close the given file
@@ -863,7 +1183,7 @@
DAZUKO_SYSCALL_WRAPPER(close)
#endif
-#ifdef ON_CLOSE_MODIFIED_SUPPORT
+#if defined(ON_CLOSE_MODIFIED_SUPPORT) || defined(ON_WRITE_SUPPORT)
static inline int freebsd_dazuko_sys_write_inner(struct proc *p, struct write_args *uap)
{
/* The kernel wants to write to the given file
@@ -874,9 +1194,12 @@
struct xp_file file;
struct event_properties event_p;
struct xp_daemon_id xp_id;
+ size_t size = 0;
+ off_t offset = 0;
+ struct hash * h = NULL;
xp_id.pid = p->p_pid;
- check_error = dazuko_sys_check(DAZUKO_ON_CLOSE_MODIFIED, 1, &xp_id);
+ check_error = dazuko_sys_check(DAZUKO_ON_WRITE, 1, &xp_id);
if (!check_error)
{
@@ -900,14 +1223,37 @@
{
check_error = -1;
}
- else if (p->p_fd->fd_ofiles[uap->fd] == NULL)
+ else if ((file.file = p->p_fd->fd_ofiles[uap->fd]) == NULL)
+ {
+ check_error = -1;
+ }
+ else if ((h = dazuko_lookup_hash(&file)) == NULL)
{
+ /* the file is not monitored, stop now */
check_error = -1;
}
else
{
- /* grab the file* for possible later use */
- file.file = p->p_fd->fd_ofiles[uap->fd];
+ /* get the offset and size of the write event */
+
+ if ((file.file)->f_flag & O_APPEND)
+ {
+ struct vnode * vn;
+ struct vattr attr;
+ int is_locked;
+
+ vn = (struct vnode *)(file.file)->f_data;
+ is_locked = VOP_ISLOCKED(vn, p);
+ if (!is_locked) vn_lock(vn, LK_SHARED | LK_RETRY, p);
+ VOP_GETATTR(vn, &attr, p->p_ucred, p);
+ if (!is_locked) VOP_UNLOCK(vn, 0, p);
+ offset = attr.va_size;
+ }
+ else
+ {
+ offset = (file.file)->f_offset;
+ }
+ size = uap->nbyte;
}
}
@@ -918,14 +1264,433 @@
if (!error && !check_error)
{
dazuko_bzero(&event_p, sizeof(event_p));
+ event_p.pid = p->p_pid;
+ event_p.set_pid = 1;
+ event_p.uid = p->p_cred->p_ruid;
+ event_p.set_uid = 1;
+ event_p.set_size = 1;
+ event_p.size = size;
+ event_p.set_offset = 1;
+ event_p.offset = offset;
- dazuko_sys_post(DAZUKO_ON_CLOSE_MODIFIED, NULL, &file, &event_p);
+ dazuko_sys_post(DAZUKO_ON_WRITE, NULL, &file, &event_p);
}
return error;
}
DAZUKO_SYSCALL_WRAPPER(write)
+
+static inline int freebsd_dazuko_sys_writev_inner(struct proc *p, struct writev_args *uap)
+{
+ /* The kernel wants to write to the given file
+ * descriptor. */
+
+ int error = 0;
+ int check_error = 0;
+ struct xp_file file;
+ struct event_properties event_p;
+ struct xp_daemon_id xp_id;
+ off_t offset = 0;
+ struct hash * h;
+
+ xp_id.pid = p->p_pid;
+ check_error = dazuko_sys_check(DAZUKO_ON_WRITE, 1, &xp_id);
+
+ if (!check_error)
+ {
+ if (uap == NULL)
+ {
+ check_error = -1;
+ }
+ else if (p->p_fd == NULL)
+ {
+ check_error = -1;
+ }
+ else if (uap->fd < 0)
+ {
+ check_error = -1;
+ }
+ else if ((u_int)(uap->fd) >= p->p_fd->fd_nfiles)
+ {
+ check_error = -1;
+ }
+ else if (p->p_fd->fd_ofiles == NULL)
+ {
+ check_error = -1;
+ }
+ else if ((file.file = p->p_fd->fd_ofiles[uap->fd]) == NULL)
+ {
+ check_error = -1;
+ }
+ else if ((h = dazuko_lookup_hash(&file)) == NULL)
+ {
+ /* the file is not monitored, stop now */
+ check_error = -1;
+ }
+ else
+ {
+ /* get the offset of the write event */
+
+ if ((file.file)->f_flag & O_APPEND)
+ {
+ struct vnode * vn;
+ struct vattr attr;
+ int is_locked;
+
+ vn = (struct vnode *)(file.file)->f_data;
+ is_locked = VOP_ISLOCKED(vn, p);
+ if (!is_locked) vn_lock(vn, LK_SHARED | LK_RETRY, p);
+ VOP_GETATTR(vn, &attr, p->p_ucred, p);
+ if (!is_locked) VOP_UNLOCK(vn, 0, p);
+ offset = attr.va_size;
+ }
+ else
+ {
+ offset = (file.file)->f_offset;
+ }
+ }
+ }
+
+ error = original_sys_writev(p, uap);
+
+ /* did we actually write anything? */
+
+ if (!error && !check_error)
+ {
+ dazuko_bzero(&event_p, sizeof(event_p));
+ event_p.pid = p->p_pid;
+ event_p.set_pid = 1;
+ event_p.uid = p->p_cred->p_ruid;
+ event_p.set_uid = 1;
+ event_p.set_size = 1;
+ event_p.size = p->p_retval[0];
+ event_p.set_offset = 1;
+ event_p.offset = offset;
+
+ dazuko_sys_post(DAZUKO_ON_WRITE, NULL, &file, &event_p);
+ }
+
+ return error;
+}
+
+DAZUKO_SYSCALL_WRAPPER(writev)
+
+static inline int freebsd_dazuko_sys_pwrite_inner(struct proc *p, struct pwrite_args *uap)
+{
+ /* The kernel wants to write to the given file
+ * descriptor. */
+
+ int error = 0;
+ int check_error = 0;
+ struct xp_file file;
+ struct event_properties event_p;
+ struct xp_daemon_id xp_id;
+ size_t size = 0;
+ off_t offset = 0;
+ struct hash * h;
+
+ xp_id.pid = p->p_pid;
+ check_error = dazuko_sys_check(DAZUKO_ON_WRITE, 1, &xp_id);
+
+ if (!check_error)
+ {
+ if (uap == NULL)
+ {
+ check_error = -1;
+ }
+ else if (p->p_fd == NULL)
+ {
+ check_error = -1;
+ }
+ else if (uap->fd < 0)
+ {
+ check_error = -1;
+ }
+ else if ((u_int)(uap->fd) >= p->p_fd->fd_nfiles)
+ {
+ check_error = -1;
+ }
+ else if (p->p_fd->fd_ofiles == NULL)
+ {
+ check_error = -1;
+ }
+ else if ((file.file = p->p_fd->fd_ofiles[uap->fd]) == NULL)
+ {
+ check_error = -1;
+ }
+ else if ((h = dazuko_lookup_hash(&file)) == NULL)
+ {
+ /* the file is not monitored, stop now */
+ check_error = -1;
+ }
+ else
+ {
+ offset = uap->offset;
+ size = uap->nbyte;
+ }
+ }
+
+ error = original_sys_pwrite(p, uap);
+
+ /* did we actually write anything? */
+
+ if (!error && !check_error)
+ {
+ dazuko_bzero(&event_p, sizeof(event_p));
+ event_p.pid = p->p_pid;
+ event_p.set_pid = 1;
+ event_p.uid = p->p_cred->p_ruid;
+ event_p.set_uid = 1;
+ event_p.set_size = 1;
+ event_p.size = size;
+ event_p.set_offset = 1;
+ event_p.offset = offset;
+
+ dazuko_sys_post(DAZUKO_ON_WRITE, NULL, &file, &event_p);
+ }
+
+ return error;
+}
+
+DAZUKO_SYSCALL_WRAPPER(pwrite)
+
+#ifdef ASYNC_IO_SUPPORT
+static inline int freebsd_dazuko_sys_aio_write_inner(struct proc *p, struct aio_write_args *uap)
+{
+ /* The kernel wants to write to the given file
+ * descriptor. */
+
+ int error = 0;
+ int check_error = 0;
+ struct xp_file file;
+ struct event_properties event_p;
+ struct xp_daemon_id xp_id;
+ int fd = ((uap)->aiocbp)->aio_fildes;
+ off_t offset = 0;
+ size_t size = 0;
+ struct hash * h;
+
+ xp_id.pid = p->p_pid;
+ check_error = dazuko_sys_check(DAZUKO_ON_WRITE, 1, &xp_id);
+
+ if (!check_error)
+ {
+ if (uap == NULL)
+ {
+ check_error = -1;
+ }
+ else if (p->p_fd == NULL)
+ {
+ check_error = -1;
+ }
+ else if (fd < 0)
+ {
+ check_error = -1;
+ }
+ else if ((u_int)(fd) >= p->p_fd->fd_nfiles)
+ {
+ check_error = -1;
+ }
+ else if (p->p_fd->fd_ofiles == NULL)
+ {
+ check_error = -1;
+ }
+ else if ((file.file = p->p_fd->fd_ofiles[uap->aiocbp->aio_fildes]) == NULL)
+ {
+ check_error = -1;
+ }
+ else if ((h = dazuko_lookup_hash(&file)) == NULL)
+ {
+ /* the file is not monitored, stop now */
+ check_error = -1;
+ }
+ else
+ {
+ /* note that this is not quite right:
+ * if the file is in append mode, the write will happen at the
+ * end of the file at the time the write is performed...
+ * however there is no way we can catch that unfortunately.
+ *
+ * also the write may fail while being processed
+ * (for example if offset > file_size and the file is not in append
+ * mode...)
+ * This could be caught be actually defering the notification of the
+ * event to the time 'aio_return' is called instead.
+ */
+ offset = uap->aiocbp->aio_offset;
+ size = uap->aiocbp->aio_nbytes;
+ }
+ }
+
+ error = original_sys_aio_write(p, uap);
+
+ /* did we actually write anything? */
+
+ if (!error && !check_error)
+ {
+ dazuko_bzero(&event_p, sizeof(event_p));
+ event_p.pid = p->p_pid;
+ event_p.set_pid = 1;
+ event_p.uid = p->p_cred->p_ruid;
+ event_p.set_uid = 1;
+ event_p.set_size = 1;
+ event_p.size = size;
+ event_p.set_offset = 1;
+ event_p.offset = offset;
+
+ dazuko_sys_post(DAZUKO_ON_WRITE, NULL, &file, &event_p);
+ }
+
+ return error;
+}
+
+DAZUKO_SYSCALL_WRAPPER(aio_write)
+#endif
+
+static inline int freebsd_dazuko_sys_ftruncate_inner(struct proc *p, struct ftruncate_args *uap)
+{
+ /* The kernel wants to write to the given file
+ * descriptor. */
+
+ int error = 0;
+ int check_error = 0;
+ struct xp_file file;
+ struct event_properties event_p;
+ struct xp_daemon_id xp_id;
+ int fd = uap->fd;
+ off_t offset = 0;
+ struct hash * h;
+
+ xp_id.pid = p->p_pid;
+ check_error = dazuko_sys_check(DAZUKO_ON_WRITE, 1, &xp_id);
+
+ if (!check_error)
+ {
+ if (uap == NULL)
+ {
+ check_error = -1;
+ }
+ else if (p->p_fd == NULL)
+ {
+ check_error = -1;
+ }
+ else if (fd < 0)
+ {
+ check_error = -1;
+ }
+ else if ((u_int)(fd) >= p->p_fd->fd_nfiles)
+ {
+ check_error = -1;
+ }
+ else if (p->p_fd->fd_ofiles == NULL)
+ {
+ check_error = -1;
+ }
+ else if ((file.file = p->p_fd->fd_ofiles[uap->fd]) == NULL)
+ {
+ check_error = -1;
+ }
+ else if ((h = dazuko_lookup_hash(&file)) == NULL)
+ {
+ /* the file is not monitored, stop now */
+ check_error = -1;
+ }
+ else
+ {
+ offset = uap->length;
+ }
+ }
+
+ error = original_sys_ftruncate(p, uap);
+
+ /* did we actually write anything? */
+
+ if (!error && !check_error)
+ {
+ dazuko_bzero(&event_p, sizeof(event_p));
+ event_p.pid = p->p_pid;
+ event_p.set_pid = 1;
+ event_p.uid = p->p_cred->p_ruid;
+ event_p.set_uid = 1;
+ event_p.offset = offset;
+ event_p.set_offset = 1;
+
+ dazuko_sys_post(DAZUKO_ON_WRITE, NULL, &file, &event_p);
+ }
+
+ return error;
+}
+
+DAZUKO_SYSCALL_WRAPPER(ftruncate)
+
+static inline int freebsd_dazuko_sys_mmap_inner(struct proc *p, struct mmap_args *uap)
+{
+ /* The kernel wants to write to the given file
+ * descriptor. */
+
+ int error = 0;
+ int check_error = 0;
+ struct xp_file file;
+ struct event_properties event_p;
+ struct xp_daemon_id xp_id;
+ int access = uap->prot;
+ struct hash * h;
+
+ xp_id.pid = p->p_pid;
+ check_error = dazuko_sys_check(DAZUKO_ON_WRITE, 1, &xp_id);
+
+ if (!check_error)
+ {
+ if (uap == NULL)
+ {
+ check_error = -1;
+ }
+ else if (p->p_fd == NULL)
+ {
+ check_error = -1;
+ }
+ else if (uap->fd < 0)
+ {
+ check_error = -1;
+ }
+ else if ((u_int)(uap->fd) >= p->p_fd->fd_nfiles)
+ {
+ check_error = -1;
+ }
+ else if (p->p_fd->fd_ofiles == NULL)
+ {
+ check_error = -1;
+ }
+ else if ((file.file = p->p_fd->fd_ofiles[uap->fd]) == NULL)
+ {
+ check_error = -1;
+ }
+ else if ((h = dazuko_lookup_hash(&file)) == NULL)
+ {
+ /* the file is not monitored, stop now */
+ check_error = -1;
+ }
+ }
+
+ error = original_sys_mmap(p, uap);
+
+ /* did we actually write anything? */
+
+ if (!error && !check_error && (access & PROT_WRITE))
+ {
+ dazuko_bzero(&event_p, sizeof(event_p));
+ event_p.pid = p->p_pid;
+ event_p.set_pid = 1;
+ event_p.uid = p->p_cred->p_ruid;
+ event_p.set_uid = 1;
+ dazuko_sys_post(DAZUKO_ON_WRITE, NULL, &file, &event_p);
+ }
+
+ return error;
+}
+
+DAZUKO_SYSCALL_WRAPPER(mmap)
#endif
#endif
@@ -1081,16 +1846,25 @@
#ifndef DAZUKO_FIST
-#if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+#if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT) || defined(ON_WRITE_SUPPORT)
DAZUKO_HOOK(open);
+ DAZUKO_HOOK(dup);
+ DAZUKO_HOOK(dup2);
#endif
-#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT) || defined(ON_WRITE_SUPPORT)
DAZUKO_HOOK(close);
#endif
-#ifdef ON_CLOSE_MODIFIED_SUPPORT
+#if defined(ON_CLOSE_MODIFIED_SUPPORT) || defined(ON_WRITE_SUPPORT)
DAZUKO_HOOK(write);
+ DAZUKO_HOOK(writev);
+ DAZUKO_HOOK(pwrite);
+#ifdef ASYNC_IO_SUPPORT
+ DAZUKO_HOOK(aio_write);
+#endif
+ DAZUKO_HOOK(ftruncate);
+ DAZUKO_HOOK(mmap);
#endif
#ifdef ON_EXEC_SUPPORT
@@ -1126,16 +1900,25 @@
{
#ifndef DAZUKO_FIST
-#if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+#if defined(ON_OPEN_SUPPORT) || defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT) || defined(ON_WRITE_SUPPORT)
DAZUKO_UNHOOK(open);
+ DAZUKO_UNHOOK(dup);
+ DAZUKO_UNHOOK(dup2);
#endif
-#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT)
+#if defined(ON_CLOSE_SUPPORT) || defined(ON_CLOSE_MODIFIED_SUPPORT) || defined(ON_WRITE_SUPPORT)
DAZUKO_UNHOOK(close);
#endif
-#ifdef ON_CLOSE_MODIFIED_SUPPORT
+#if defined(ON_CLOSE_MODIFIED_SUPPORT) || defined(ON_WRITE_SUPPORT)
DAZUKO_UNHOOK(write);
+ DAZUKO_UNHOOK(writev);
+ DAZUKO_UNHOOK(pwrite);
+#ifdef ASYNC_IO_SUPPORT
+ DAZUKO_UNHOOK(aio_write);
+#endif
+ DAZUKO_UNHOOK(ftruncate);
+ DAZUKO_UNHOOK(mmap);
#endif
#ifdef ON_EXEC_SUPPORT
@@ -1334,6 +2117,8 @@
/* init/exit */
+
+
static int dazuko_loader(struct module *m, int what, void *arg)
{
int err = 0;
Index: dazuko_freebsd.h
===================================================================
RCS file: /cvsroot/dazuko/dazuko/dazuko_freebsd.h,v
retrieving revision 1.12.4.1
diff -u -r1.12.4.1 dazuko_freebsd.h
--- dazuko_freebsd.h 7 Sep 2004 20:38:52 -0000 1.12.4.1
+++ dazuko_freebsd.h 8 Sep 2004 17:34:44 -0000
@@ -38,6 +38,7 @@
#include <sys/param.h>
#include <sys/libkern.h>
#include <sys/lock.h>
+#include <sys/file.h>
#include <machine/stdarg.h>
@@ -79,6 +80,8 @@
const char *user_filename;
#endif
struct proc *p;
+ int create; /* shall we assume that the file will be created */
+ int nofollow; /* shall we assume that symlinks should not be followed */
};
struct xp_queue
Index: dazuko_xp.c
===================================================================
RCS file: /cvsroot/dazuko/dazuko/dazuko_xp.c,v
retrieving revision 1.32.2.2
diff -u -r1.32.2.2 dazuko_xp.c
--- dazuko_xp.c 5 Sep 2004 15:33:49 -0000 1.32.2.2
+++ dazuko_xp.c 8 Sep 2004 17:34:48 -0000
@@ -45,6 +45,7 @@
#define SCAN_ON_CLOSE (access_mask & DAZUKO_ON_CLOSE)
#define SCAN_ON_EXEC (access_mask & DAZUKO_ON_EXEC)
#define SCAN_ON_CLOSE_MODIFIED (access_mask & DAZUKO_ON_CLOSE_MODIFIED)
+#define SCAN_ON_WRITE (access_mask & DAZUKO_ON_WRITE)
struct path
{
@@ -56,6 +57,7 @@
char path[1]; /* this MUST be at the end of the struct */
};
+#if 0
struct hash
{
/* A node in a linked list of filenames.
@@ -68,6 +70,7 @@
int namelen;
char name[1]; /* this MUST be at the end of the struct */
};
+#endif
struct daemon_id
{
@@ -1573,6 +1576,12 @@
if (s->event_p.set_mode)
dazuko_add_keyvalue_to_replybuffer(request, "\nMD=", &(s->event_p.mode), 'd');
+ if (s->event_p.set_size)
+ dazuko_add_keyvalue_to_replybuffer(request, "\nWS=", &(s->event_p.size), 'l');
+
+ if (s->event_p.set_offset)
+ dazuko_add_keyvalue_to_replybuffer(request, "\nWO=", &(s->event_p.offset), 'l');
+
if (s->file_p.set_size)
dazuko_add_keyvalue_to_replybuffer(request, "\nFS=", &(s->file_p.size), 'l');
@@ -2300,15 +2309,27 @@
struct hash *h;
+ /* first try to see if we already have this hash entry */
+ h = _dazuko_lookup_hash(file,1);
+ if (h)
+ {
+ h->refcount++;
+ call_xp_write_unlock(&lock_hash);
+ return 0;
+ }
+
/* create a new struct hash structure making room for name also */
h = (struct hash *)call_xp_malloc(sizeof(struct hash) + len);
if (h == NULL)
return XP_ERROR_FAULT;
+ dazuko_bzero(h, sizeof(struct hash) + len);
+
/* fill in structure items */
call_xp_copy_file(&(h->file), file);
h->dirty = 0;
+ h->refcount = 1;
h->namelen = len;
memcpy(h->name, filename, len);
h->name[len] = 0;
@@ -2316,8 +2337,6 @@
/* add the new struct hash item to the head of the
* struct hash linked list */
-/* LOCK */
- call_xp_write_lock(&lock_hash);
h->next = hash;
hash = h;
call_xp_write_unlock(&lock_hash);
@@ -2433,11 +2452,16 @@
{
/* we found the entry */
- /* remove the item from the list */
- if (!prev)
- hash = cur->next;
- else
- prev->next = cur->next;
+ cur->refcount--;
+
+ if (cur->refcount == 0)
+ {
+ /* remove the item from the list */
+ if (!prev)
+ hash = cur->next;
+ else
+ prev->next = cur->next;
+ }
break;
}
@@ -2451,6 +2475,34 @@
return cur;
}
+struct hash *_dazuko_lookup_hash(struct xp_file *file, int lock)
+{
+ /* Find the given file within our list
+ * and return it. */
+
+ struct hash *cur;
+
+/* LOCK */
+ call_xp_write_lock(&lock_hash);
+
+ cur = hash;
+
+ while (cur)
+ {
+ if (call_xp_compare_file(&(cur->file), file) == 0)
+ {
+ /* we found the entry */
+ break;
+ }
+ cur = cur->next;
+ }
+
+ if (!lock) call_xp_write_unlock(&lock_hash);
+/* UNLOCK */
+
+ return cur;
+}
+
inline int dazuko_get_filename_length(char *filename)
{
int len;
@@ -2526,7 +2578,7 @@
/* this is a special case because the on_close information needs
* to be saved during the on_open event */
- if ((SCAN_ON_OPEN || SCAN_ON_CLOSE || SCAN_ON_CLOSE_MODIFIED) == 0)
+ if ((SCAN_ON_OPEN || SCAN_ON_CLOSE || SCAN_ON_CLOSE_MODIFIED || SCAN_ON_WRITE) == 0)
return -1;
break;
@@ -2537,6 +2589,11 @@
return -1;
break;
+ case DAZUKO_ON_WRITE:
+ if ((SCAN_ON_WRITE || SCAN_ON_CLOSE_MODIFIED) == 0)
+ return -1;
+ break;
+
default:
if ((access_mask & event) == 0)
return -1;
@@ -2588,6 +2645,7 @@
return 0;
case DAZUKO_ON_CLOSE_MODIFIED:
+ case DAZUKO_ON_WRITE:
/* (this is really sys_write) always permitted */
return 0;
@@ -2644,7 +2702,7 @@
if ((call_xp_atomic_read(&active) > 0) && file != NULL && kfs != NULL)
{
- if (SCAN_ON_OPEN || SCAN_ON_CLOSE || SCAN_ON_CLOSE_MODIFIED)
+ if (SCAN_ON_OPEN || SCAN_ON_CLOSE || SCAN_ON_CLOSE_MODIFIED || SCAN_ON_WRITE)
{
/* make sure we should scan this file */
if (dazuko_should_scan(kfs))
@@ -2680,7 +2738,7 @@
dazuko_run_daemon(DAZUKO_ON_CLOSE, h->name, h->namelen, event_p, NULL);
/* clean up the struct hash structure */
- call_xp_free(h);
+ if (h->refcount == 0) call_xp_free(h);
}
}
else
@@ -2696,6 +2754,7 @@
break;
case DAZUKO_ON_CLOSE_MODIFIED: /* file required */
+ case DAZUKO_ON_WRITE: /* file required */
if (file != NULL)
{
/* if we actually wrote something and we found the
@@ -2703,6 +2762,12 @@
/* Swade 4/24/02: Move to end of clean list */
dazuko_mark_hash_dirty(file);
+
+ if ( SCAN_ON_WRITE
+ && (h = dazuko_lookup_hash(file)) != NULL )
+ {
+ dazuko_run_daemon(DAZUKO_ON_WRITE, h->name, h->namelen, event_p, NULL);
+ }
}
break;
Index: dazuko_xp.h
===================================================================
RCS file: /cvsroot/dazuko/dazuko/dazuko_xp.h,v
retrieving revision 1.26.2.1
diff -u -r1.26.2.1 dazuko_xp.h
--- dazuko_xp.h 5 Sep 2004 15:20:25 -0000 1.26.2.1
+++ dazuko_xp.h 8 Sep 2004 17:34:49 -0000
@@ -80,6 +80,11 @@
char set_uid;
int pid;
char set_pid;
+
+ size_t size;
+ char set_size;
+ off_t offset;
+ char set_offset;
};
struct file_properties
@@ -199,4 +204,20 @@
int dazuko_init(void);
int dazuko_exit(void);
+struct hash
+{
+ /* A node in a linked list of filenames.
+ * Used for the list of files to be
+ * scanned on close. */
+ struct hash *next;
+ struct xp_file file;
+ int dirty;
+ int refcount;
+ int namelen;
+ char name[1]; /* this MUST be at the end of the struct */
+};
+
+struct hash *_dazuko_lookup_hash(struct xp_file *file, int lock);
+#define dazuko_lookup_hash(f) _dazuko_lookup_hash((f),0)
+
#endif
Index: dazukoio.c
===================================================================
RCS file: /cvsroot/dazuko/dazuko/dazukoio.c,v
retrieving revision 1.28.2.1
diff -u -r1.28.2.1 dazukoio.c
--- dazukoio.c 5 Sep 2004 15:20:25 -0000 1.28.2.1
+++ dazukoio.c 8 Sep 2004 17:34:50 -0000
@@ -718,6 +718,18 @@
temp_acc->file_device = atoi(buffer);
temp_acc->set_file_device = 1;
}
+
+ if (get_value("\nWS=", request->reply_buffer, buffer, sizeof(buffer)) == 0)
+ {
+ temp_acc->write_size = atol(buffer);
+ temp_acc->set_write_size = 1;
+ }
+
+ if (get_value("\nWO=", request->reply_buffer, buffer, sizeof(buffer)) == 0)
+ {
+ temp_acc->write_offset = atol(buffer);
+ temp_acc->set_write_offset = 1;
+ }
}
free(request->reply_buffer);
Index: dazukoio.h
===================================================================
RCS file: /cvsroot/dazuko/dazuko/dazukoio.h,v
retrieving revision 1.19.4.1
diff -u -r1.19.4.1 dazukoio.h
--- dazukoio.h 5 Sep 2004 15:20:25 -0000 1.19.4.1
+++ dazukoio.h 8 Sep 2004 17:34:50 -0000
@@ -35,8 +35,10 @@
#ifndef DAZUKOIO_H
#define DAZUKOIO_H
+#include <sys/types.h>
#include "dazuko_events.h"
+
struct dazuko_access
{
int deny;
@@ -62,6 +64,10 @@
char set_file_mode;
int file_device;
char set_file_device;
+ size_t write_size;
+ char set_write_size;
+ off_t write_offset;
+ char set_write_offset;
};
struct dazuko_id;
Index: example_c/example.c
===================================================================
RCS file: /cvsroot/dazuko/dazuko/example_c/example.c,v
retrieving revision 1.2
diff -u -r1.2 example.c
--- example_c/example.c 8 Feb 2004 11:48:11 -0000 1.2
+++ example_c/example.c 8 Sep 2004 17:34:50 -0000
@@ -50,6 +50,7 @@
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
+#include <fcntl.h>
#include <sys/types.h>
#include "dazukoio.h"
@@ -97,6 +98,9 @@
case DAZUKO_ON_RMDIR:
printf("RMDIR ");
break;
+ case DAZUKO_ON_WRITE:
+ printf("WRITE ");
+ break;
default:
printf("???? event:%d ", acc->event);
break;
@@ -109,10 +113,30 @@
printf(" pid:%d", acc->pid);
if (acc->set_mode)
- printf(" mode:%d", acc->mode);
+ printf(" mode:0x%x", acc->mode);
if (acc->set_flags)
- printf(" flags:%d", acc->flags);
+ {
+ printf(" flags:0x%x", acc->flags);
+ if (acc->event == DAZUKO_ON_OPEN)
+ {
+ printf(" (");
+ if (acc->flags & O_RDONLY) printf("O_RDONLY ");
+ if (acc->flags & O_WRONLY) printf("O_WRONLY ");
+ if (acc->flags & O_RDWR) printf("O_RDWR ");
+ if (acc->flags & O_NONBLOCK) printf("O_NONBLOCK ");
+ if (acc->flags & O_APPEND) printf("O_APPEND ");
+ if (acc->flags & O_CREAT) printf("O_CREAT ");
+ if (acc->flags & O_TRUNC) printf("O_TRUNC ");
+ if (acc->flags & O_EXCL) printf("O_EXCL ");
+ if (acc->flags & O_SHLOCK) printf("O_SHLOCK ");
+ if (acc->flags & O_EXLOCK) printf("O_EXLOCK ");
+ if (acc->flags & O_DIRECT) printf("O_DIRECT ");
+ if (acc->flags & O_FSYNC) printf("O_FSYNC ");
+ if (acc->flags & O_NOFOLLOW) printf("O_NOFOLLOW ");
+ printf(")");
+ }
+ }
if (acc->set_file_uid)
printf(" file_uid:%d", acc->file_uid);
@@ -121,7 +145,7 @@
printf(" file_gid:%d", acc->file_gid);
if (acc->set_file_mode)
- printf(" file_mode:%d", acc->file_mode);
+ printf(" file_mode:0x%x", acc->file_mode);
if (acc->set_file_device)
printf(" file_device:%d", acc->file_device);
@@ -132,6 +156,12 @@
if (acc->set_filename)
printf(" file:%s", acc->filename);
+ if (acc->set_write_size)
+ printf(" write_size:%lu", acc->write_size);
+
+ if (acc->set_write_offset)
+ printf(" write_offset:%lu", acc->write_offset);
+
printf("\n");
fflush(stdout);
@@ -166,7 +196,7 @@
signal(SIGINT, sigterm);
/* set access mask */
- if (dazukoSetAccessMask(DAZUKO_ON_OPEN | DAZUKO_ON_CLOSE | DAZUKO_ON_CLOSE_MODIFIED | DAZUKO_ON_EXEC | DAZUKO_ON_UNLINK | DAZUKO_ON_RMDIR) != 0)
+ if (dazukoSetAccessMask(DAZUKO_ON_OPEN | DAZUKO_ON_CLOSE | DAZUKO_ON_CLOSE_MODIFIED | DAZUKO_ON_EXEC | DAZUKO_ON_UNLINK | DAZUKO_ON_RMDIR | DAZUKO_ON_WRITE) != 0)
{
printf("error: failed to set access mask\n");
dazukoUnregister();