Author: pjd
Date: Sun Aug 29 21:39:49 2010
New Revision: 211976
URL: http://svn.freebsd.org/changeset/base/211976

Log:
  - 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

Modified:
  head/sbin/hastd/hooks.c
  head/sbin/hastd/hooks.h

Modified: head/sbin/hastd/hooks.c
==============================================================================
--- head/sbin/hastd/hooks.c     Sun Aug 29 21:37:21 2010        (r211975)
+++ head/sbin/hastd/hooks.c     Sun Aug 29 21:39:49 2010        (r211976)
@@ -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);
        }
 
        /*

Modified: head/sbin/hastd/hooks.h
==============================================================================
--- head/sbin/hastd/hooks.h     Sun Aug 29 21:37:21 2010        (r211975)
+++ head/sbin/hastd/hooks.h     Sun Aug 29 21:39:49 2010        (r211976)
@@ -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);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to