tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
In-kernel process exit hooks?
Please see references [1], [2], and [3] for details on this issue ...
Based on internal implementation of filemon(4), there is an ordering
requirement imposed on the sequence of events that occur when a process
using /dev/filemon exits. In particular, the file descriptor on which
the device is open needs to be closed prior to closing the descriptor to
which avent/activity records are being logged. (Otherwise, because of
an extra reference on the log file, fd_close() will hang indefinitely.)
It has been suggested to implement a filemon(4)-specific "exit hook" to
ensure that the /dev/filemon device gets closed first. Instead of a
hook that is specific to filemon(4), I would propose that a generic hook
mechanism be added. This way, if any future ordering requirements are
found, we won't need another feature-specific mechanism.
We already have an exit_hook implementation, but unfortunately the hooks
are calls too late in the exit processing. Particularly, the hooks are
called after all files are closed (via fd_free()) and after the working
directory of the process has been free()d (via cwdfree()).
As far as I can tell, there are only two current users of the exithook
mechanism (in kern/sys_aio.c and kern/sysv_sem.c). It is not clear to
me if either of these users would be affected if the execution of the
exithooks were to happen _before_ the call to fd_free().
I'd rather not have two sets of exithooks if it can be avoided. We
could perhaps add a "phase" argument to the current exithook routines,
using it to select between phase-specific LIST_HEADs. Similar to
(in kern/kern_hook.c starting at line 222)
static hook_list_t exithook_pre_close_list =
LIST_HEAD_INITIALIZER(exithook_pre_close_list);
static hook_list_t exithook_post_close_list =
LIST_HEAD_INITIALIZER(exithook_post_close_list);
static hook_list_t *exithook_table[] = {
&exithook_pre_close_list,
&exithook_post_close_list
};
extern krwlock_t exec_lock;
void *
exithook_establish(void (*fn)(struct proc *, void *), void *arg, int ph)
{
void *rv;
KASSERT(ph >= 0 && ph < __arraycount(exithook_table));
rw_enter(&exec_lock, RW_WRITER);
rv = hook_establish(exithook_table[ph], (void (*)(void *))fn, arg);
rw_exit(&exec_lock);
return rv;
}
and with similar changes for exithook_disestablish() and doexithooks().
Then, in kern/kern_exit.c we simply have (at line 278+)
...
/*
* Close open files, release open-file table and free signal
* actions. This may block!
*/
doexithooks(p, EXITHOOK_PRE_CLOSE);
fd_free();
cwdfree(p->p_cwdi);
p->p_cwdi = NULL;
doexithooks(p, EXITHOOK_POST_CLOSE);
sigactsfree(p->p_sigacts);
...
Comments? Alternative approaches?
[1] http://mail-index.netbsd.org/source-changes-d/2016/01/06/msg008307.html
[2] http://mail-index.netbsd.org/tech-kern/2016/01/05/msg019896.html
[3] http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=50627
+------------------+--------------------------+------------------------+
| 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 |
+------------------+--------------------------+------------------------+
Home |
Main Index |
Thread Index |
Old Index