tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: In-kernel process exit hooks?



> Another possibility would be to change filemon(4) to do fd_getfile
> each it needs to use the file descriptor.  This makes it a little
> more brittle (fails if you close the descriptor), but would sidestep
> the problem.

Hmmm, perhaps.  Failure would not be a problem, since we would just
revert to the initial "output file unspecified" conditions.

I think I like this approach.  :)  I'll give it a try.

This actually works quite well. Please see the attached diffs for your review.

One possible problem is what happens if the monitoring program closes the file descriptor, and then re-uses that fd? I've included a check to compare the original 'struct file *' pointer with the current one, which will catch "some" instances, but not guaranteed to catch them all. It could be a bit of a surprise if filemon output shows up in unexpected places. :)

Because of this potential for surprising the user, I think I'm still leaning to my earlier proposal of extending exithook processing. But given the limited number of use-cases for filemon, I could live with making the fd_getfile()-only-when-you-need-it change instead.


+------------------+--------------------------+------------------------+
| Paul Goyette     | PGP Key fingerprint:     | E-mail addresses:      |
| (Retired)        | FA29 0E3B 35AF E8AE 6651 | paul at whooppee.com   |
| Kernel Developer | 0786 F758 55DE 53BA 7731 | pgoyette at netbsd.org |
+------------------+--------------------------+------------------------+
Index: filemon.c
===================================================================
RCS file: /cvsroot/src/sys/dev/filemon/filemon.c,v
retrieving revision 1.24
diff -u -p -r1.24 filemon.c
--- filemon.c	5 Jan 2016 22:08:54 -0000	1.24
+++ filemon.c	7 Jan 2016 00:45:46 -0000
@@ -94,9 +94,21 @@ filemon_output(struct filemon * filemon,
 {
 	struct uio auio;
 	struct iovec aiov;
+	struct file *fp;     /* Output file pointer. */
 
-	if (filemon->fm_fp == NULL)
+
+	if (filemon->fm_fp == NULL)	/* No output file specified */
+		return;
+	if ((fp = fd_getfile(filemon->fm_fd)) != filemon->fm_fp) {
+		/*
+		 * The file descriptor refers to a different file
+		 * than when it was passed to SET_FD.  So assume we
+		 * never had an output file.
+		 */
+		filemon->fm_fp = NULL;
+		filemon->fm_fd = -1;
 		return;
+	}
 
 	aiov.iov_base = msg;
 	aiov.iov_len = len;
@@ -122,6 +134,7 @@ filemon_output(struct filemon * filemon,
 	(*filemon->fm_fp->f_ops->fo_write) (filemon->fm_fp,
 	    &(filemon->fm_fp->f_offset),
 	    &auio, curlwp->l_cred, FOF_UPDATE_OFFSET);
+	fd_putfile(filemon->fm_fd);	/* release our reference */
 }
 
 void
@@ -264,10 +277,7 @@ filemon_close(struct file * fp)
 	 * once we have exclusive access, it should never be used again
 	 */
 	rw_enter(&filemon->fm_mtx, RW_WRITER);
-	if (filemon->fm_fp) {
-		fd_putfile(filemon->fm_fd);	/* release our reference */
-		filemon->fm_fp = NULL;
-	}
+	filemon->fm_fp = NULL;
 	rw_exit(&filemon->fm_mtx);
 	rw_destroy(&filemon->fm_mtx);
 	kmem_free(filemon, sizeof(struct filemon));
@@ -309,6 +319,7 @@ filemon_ioctl(struct file * fp, u_long c
 			error = EBADF;
 			break;
 		}
+		fd_putfile(filemon->fm_fd);
 		/* Write the file header. */
 		filemon_comment(filemon);
 		break;


Home | Main Index | Thread Index | Old Index