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