summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2010-08-29 21:39:49 +0000
committerpjd <pjd@FreeBSD.org>2010-08-29 21:39:49 +0000
commit9a66bc9a3072bb3aaa48a140ee6c2ef69809de24 (patch)
treeeb91eac7d88da2a0a59338be53956393ff580ed5 /sbin
parent4a3477caff76069b800be71fe6f98105ad52d6e7 (diff)
downloadFreeBSD-src-9a66bc9a3072bb3aaa48a140ee6c2ef69809de24.zip
FreeBSD-src-9a66bc9a3072bb3aaa48a140ee6c2ef69809de24.tar.gz
- Add hook_fini() which should be called after fork() from the main hastd
process, once it start to use hooks. - Add hook_check_one() in case the caller expects different child processes and once it can recognize it, it will pass pid and status to hook_check_one(). MFC after: 2 weeks Obtained from: Wheel Systems Sp. z o.o. http://www.wheelsystems.com
Diffstat (limited to 'sbin')
-rw-r--r--sbin/hastd/hooks.c80
-rw-r--r--sbin/hastd/hooks.h4
2 files changed, 62 insertions, 22 deletions
diff --git a/sbin/hastd/hooks.c b/sbin/hastd/hooks.c
index 11ede20..eff2f6f 100644
--- a/sbin/hastd/hooks.c
+++ b/sbin/hastd/hooks.c
@@ -82,6 +82,9 @@ struct hookproc {
static TAILQ_HEAD(, hookproc) hookprocs;
static pthread_mutex_t hookprocs_lock;
+static void hook_remove(struct hookproc *hp);
+static void hook_free(struct hookproc *hp);
+
static void
descriptors(void)
{
@@ -147,11 +150,35 @@ void
hook_init(void)
{
+ assert(!hooks_initialized);
+
mtx_init(&hookprocs_lock);
TAILQ_INIT(&hookprocs);
hooks_initialized = true;
}
+void
+hook_fini(void)
+{
+ struct hookproc *hp;
+
+ assert(hooks_initialized);
+
+ mtx_lock(&hookprocs_lock);
+ while ((hp = TAILQ_FIRST(&hookprocs)) != NULL) {
+ assert(hp->hp_magic == HOOKPROC_MAGIC_ONLIST);
+ assert(hp->hp_pid > 0);
+
+ hook_remove(hp);
+ hook_free(hp);
+ }
+ mtx_unlock(&hookprocs_lock);
+
+ mtx_destroy(&hookprocs_lock);
+ TAILQ_INIT(&hookprocs);
+ hooks_initialized = false;
+}
+
static struct hookproc *
hook_alloc(const char *path, char **args)
{
@@ -238,6 +265,34 @@ hook_find(pid_t pid)
}
void
+hook_check_one(pid_t pid, int status)
+{
+ struct hookproc *hp;
+
+ mtx_lock(&hookprocs_lock);
+ hp = hook_find(pid);
+ if (hp == NULL) {
+ mtx_unlock(&hookprocs_lock);
+ pjdlog_debug(1, "Unknown process pid=%u", pid);
+ return;
+ }
+ hook_remove(hp);
+ mtx_unlock(&hookprocs_lock);
+ if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+ pjdlog_debug(1, "Hook exited gracefully (pid=%u, cmd=[%s]).",
+ pid, hp->hp_comm);
+ } else if (WIFSIGNALED(status)) {
+ pjdlog_error("Hook was killed (pid=%u, signal=%d, cmd=[%s]).",
+ pid, WTERMSIG(status), hp->hp_comm);
+ } else {
+ pjdlog_error("Hook exited ungracefully (pid=%u, exitcode=%d, cmd=[%s]).",
+ pid, WIFEXITED(status) ? WEXITSTATUS(status) : -1,
+ hp->hp_comm);
+ }
+ hook_free(hp);
+}
+
+void
hook_check(bool sigchld)
{
struct hookproc *hp, *hp2;
@@ -250,28 +305,9 @@ hook_check(bool sigchld)
/*
* If SIGCHLD was received, garbage collect finished processes.
*/
- while (sigchld && (pid = wait3(&status, WNOHANG, NULL)) > 0) {
- mtx_lock(&hookprocs_lock);
- hp = hook_find(pid);
- if (hp == NULL) {
- mtx_unlock(&hookprocs_lock);
- pjdlog_warning("Unknown process pid=%u", pid);
- continue;
- }
- hook_remove(hp);
- mtx_unlock(&hookprocs_lock);
- if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
- pjdlog_debug(1, "Hook exited gracefully (pid=%u, cmd=[%s]).",
- pid, hp->hp_comm);
- } else if (WIFSIGNALED(status)) {
- pjdlog_error("Hook was killed (pid=%u, signal=%d, cmd=[%s]).",
- pid, WTERMSIG(status), hp->hp_comm);
- } else {
- pjdlog_error("Hook exited ungracefully (pid=%u, exitcode=%d, cmd=[%s]).",
- pid, WIFEXITED(status) ? WEXITSTATUS(status) : -1,
- hp->hp_comm);
- }
- hook_free(hp);
+ if (sigchld) {
+ while ((pid = wait3(&status, WNOHANG, NULL)) > 0)
+ hook_check_one(pid, status);
}
/*
diff --git a/sbin/hastd/hooks.h b/sbin/hastd/hooks.h
index d18ddc4..5cc57df 100644
--- a/sbin/hastd/hooks.h
+++ b/sbin/hastd/hooks.h
@@ -33,10 +33,14 @@
#ifndef _HOOKS_H_
#define _HOOKS_H_
+#include <sys/types.h>
+
#include <stdarg.h>
#include <stdbool.h>
void hook_init(void);
+void hook_fini(void);
+void hook_check_one(pid_t pid, int status);
void hook_check(bool sigchld);
void hook_exec(const char *path, ...);
void hook_execv(const char *path, va_list ap);
OpenPOWER on IntegriCloud