]> granicus.if.org Git - apache/commitdiff
Add "-k start|startssl|restart|graceful|stop" support to httpd
authorJeff Trawick <trawick@apache.org>
Thu, 23 May 2002 12:58:37 +0000 (12:58 +0000)
committerJeff Trawick <trawick@apache.org>
Thu, 23 May 2002 12:58:37 +0000 (12:58 +0000)
for the Unix MPMs.  These have semantics very similar to the
old apachectl commands of the same name.

The use of stderr/stdout and exit status for error conditions
needs to be revisited.  For now it matches apachectl behavior.

Justin Erenkrantz got the ball rolling with this feature.  Some
of his support code was used unchanged.  Other code was shuffled
around and modified or rewritten.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@95237 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
include/http_main.h
include/mpm_common.h
server/main.c
server/mpm/prefork/mpm.h
server/mpm/prefork/prefork.c
server/mpm/worker/mpm.h
server/mpm/worker/worker.c
server/mpm_common.c

diff --git a/CHANGES b/CHANGES
index 48399aa3a6555729c1cb90af36d68680fbb5c703..62e1aedae425be9ffdfca9ca37bc901f635c2fac 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,10 @@
 Changes with Apache 2.0.37
 
+  *) Add "-k start|startssl|restart|graceful|stop" support to httpd
+     for the Unix MPMs.  These have semantics very similar to the
+     old apachectl commands of the same name.
+     [Justin Erenkrantz, Jeff Trawick]
+
   *) Make sure that the runtime dir is created by make install.
      PR 9233.  [Jeff Trawick]
 
index 724f5575b410639d45c057f91e78f92cb521ab58..46c322acc793ecb2c02925cb31f018ff2b77bd4e 100644 (file)
@@ -59,6 +59,8 @@
 #ifndef APACHE_HTTP_MAIN_H
 #define APACHE_HTTP_MAIN_H
 
+#include "apr_optional.h"
+
 /* AP_SERVER_BASEARGS is the command argument list parsed by http_main.c
  * in apr_getopt() format.  Use this for default'ing args that the MPM
  * can safely ignore and pass on from its rewrite_args() handler.
@@ -89,6 +91,8 @@ AP_DECLARE_DATA extern apr_array_header_t *ap_server_post_read_config;
  *  effect the server based on command line options */
 AP_DECLARE_DATA extern apr_array_header_t *ap_server_config_defines;
 
+APR_DECLARE_OPTIONAL_FN(int, ap_signal_server, (int *, apr_pool_t *));
+
 #ifdef __cplusplus
 }
 #endif
index 472f9b5928369ca6a0c5f05cb78c200b81cc2d16..be58aec4a49f184d70044e6636798741015cb607 100644 (file)
@@ -280,6 +280,11 @@ const char *ap_mpm_set_coredumpdir(cmd_parms *cmd, void *dummy,
                                    const char *arg);
 #endif
 
+#ifdef AP_MPM_WANT_SIGNAL_SERVER
+int ap_signal_server(int *, apr_pool_t *);
+void ap_mpm_rewrite_args(process_rec *);
+#endif
+
 #ifdef __cplusplus
 }
 #endif
index 49a85f94d37e09deaadf7b3c1d76daff95d8a33f..9a1cdb456cfcf0661fd7ebee7c4085784964092a 100644 (file)
@@ -76,6 +76,7 @@
 #include "apr_uri.h"
 #include "util_ebcdic.h"
 #include "ap_mpm.h"
+#include "mpm_common.h"
 
 /* WARNING: Win32 binds http_main.c dynamically to the server. Please place
  *          extern functions and global data in another appropriate module.
@@ -309,7 +310,11 @@ static void usage(process_rec *process)
                  "       %s [-k install|config|uninstall] [-n service_name]",
                  pad);
 #endif
-
+#ifdef AP_MPM_WANT_SIGNAL_SERVER
+    ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
+                 "       %s [-k start|startssl|restart|graceful|stop]",
+                 pad);
+#endif
     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
                  "       %s [-v] [-V] [-h] [-l] [-L] [-t] [-T]", pad);
     ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL,
@@ -404,6 +409,7 @@ int main(int argc, const char * const argv[])
     apr_status_t rv;
     module **mod;
     const char *optarg;
+    APR_OPTIONAL_FN_TYPE(ap_signal_server) *signal_server;
 
     AP_MONCONTROL(0); /* turn off profiling of startup */
 
@@ -565,6 +571,15 @@ int main(int argc, const char * const argv[])
         destroy_and_exit_process(process, 0);
     }
 
+    signal_server = APR_RETRIEVE_OPTIONAL_FN(ap_signal_server);
+    if (signal_server) {
+        int exit_status;
+
+        if (signal_server(&exit_status, pconf) != 0) {
+            destroy_and_exit_process(process, exit_status);
+        }
+    }
+
     apr_pool_clear(plog);
 
     /* It is assumed that if you are going to fail the open_logs phase, then
index 514c2b02f40396010d21f270793abd6cd9dd9c8b..fc2ff771c5125a4796ba9eddde02ad58151a1ff0 100644 (file)
@@ -77,6 +77,7 @@
 #define AP_MPM_WANT_SET_MAX_REQUESTS
 #define AP_MPM_WANT_SET_COREDUMPDIR
 #define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH
+#define AP_MPM_WANT_SIGNAL_SERVER
 #define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK
 
 #define AP_MPM_USES_POD 1
index adb3aae1294eb380858209a749f54f850e4c77d7..1f5f7a0d24ad96dcdbbb3da0b2e69347c04be3bd 100644 (file)
@@ -1388,7 +1388,7 @@ AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF,
 
 module AP_MODULE_DECLARE_DATA mpm_prefork_module = {
     MPM20_MODULE_STUFF,
-    NULL,                       /* hook to run before apache parses args */
+    ap_mpm_rewrite_args,        /* hook to run before apache parses args */
     NULL,                      /* create per-directory config structure */
     NULL,                      /* merge per-directory config structures */
     NULL,                      /* create per-server config structure */
index 896fb82b962247b172794d5739ae2d1d89a43ce3..a22c8f0686eed50bc9d792f999318dd55abcbad1 100644 (file)
@@ -74,6 +74,7 @@
 #define AP_MPM_WANT_SET_MAX_REQUESTS
 #define AP_MPM_WANT_SET_COREDUMPDIR
 #define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH
+#define AP_MPM_WANT_SIGNAL_SERVER
 #define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK
 
 #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid)
index 913273e56c9fa874cb9996a9c019c15772fa8b73..f9c23ca270913badff80fce98fd804e7d5f73120 100644 (file)
@@ -2158,7 +2158,7 @@ AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF,
 
 module AP_MODULE_DECLARE_DATA mpm_worker_module = {
     MPM20_MODULE_STUFF,
-    NULL,                       /* hook to run before apache parses args */
+    ap_mpm_rewrite_args,        /* hook to run before apache parses args */
     NULL,                       /* create per-directory config structure */
     NULL,                       /* merge per-directory config structures */
     NULL,                       /* create per-server config structure */
index fd1f3dd39463971fb72e19e3eeb38fba9dfcddc2..c6d4e9524c2803a186e62623f983d5a5550bc22f 100644 (file)
@@ -73,6 +73,8 @@
 #include "apr_strings.h"
 #define APR_WANT_STRFUNC
 #include "apr_want.h"
+#include "apr_getopt.h"
+#include "apr_optional.h"
 
 #include "httpd.h"
 #include "http_config.h"
@@ -730,3 +732,157 @@ AP_DECLARE(const char *) ap_mpm_set_accept_lock_mech(cmd_parms *cmd,
 }
 
 #endif
+
+#ifdef AP_MPM_WANT_SIGNAL_SERVER
+
+static const char *dash_k_arg;
+
+static int send_signal(pid_t pid, int sig)
+{
+    if (kill(pid, sig) < 0) {
+        ap_log_error(APLOG_MARK, APLOG_STARTUP, errno, NULL,
+                     "sending signal to server");
+        return 1;
+    }
+    return 0;
+}
+
+int ap_signal_server(int *exit_status, apr_pool_t *pconf)
+{
+    apr_status_t rv;
+    pid_t otherpid;
+    int running = 0;
+    int have_pid_file = 0;
+    const char *status;
+    
+    *exit_status = 0;
+
+    rv = ap_read_pid(pconf, ap_pid_fname, &otherpid);
+    if (rv != APR_SUCCESS) {
+        if (rv != APR_ENOENT) {
+            ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, NULL,
+                         "Error retrieving pid file %s", ap_pid_fname);
+            *exit_status = 1;
+            return 1;
+        }
+        status = "httpd (no pid file) not running";
+    }
+    else {
+        have_pid_file = 1;
+        if (kill(otherpid, 0) == 0) {
+            running = 1;
+            status = apr_psprintf(pconf, 
+                                  "httpd (pid %" APR_PID_T_FMT ") already "
+                                  "running", otherpid);
+        }
+        else {
+            status = apr_psprintf(pconf,
+                                  "httpd (pid %" APR_PID_T_FMT "?) not running",
+                                  otherpid);
+        }
+    }
+
+    if (!strcmp(dash_k_arg, "start")) {
+        if (running) {
+            printf("%s\n", status);
+            return 1;
+        }
+    }
+
+    if (!strcmp(dash_k_arg, "stop")) {
+        if (!running) {
+            printf("%s\n", status);
+        }
+        else {
+            send_signal(otherpid, SIGTERM);
+        }
+        return 1;
+    }
+
+    if (!strcmp(dash_k_arg, "restart")) {
+        if (!running) {
+            printf("httpd not running, trying to start\n");
+        }
+        else {
+            *exit_status = send_signal(otherpid, SIGHUP);
+            return 1;
+        }
+    }
+
+    if (!strcmp(dash_k_arg, "graceful")) {
+        if (!running) {
+            printf("httpd not running, trying to start\n");
+        }
+        else {
+            *exit_status = send_signal(otherpid, SIGUSR1);
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+void ap_mpm_rewrite_args(process_rec *process)
+{
+    apr_array_header_t *mpm_new_argv;
+    apr_status_t rv;
+    apr_getopt_t *opt;
+    char optbuf[3];
+    const char *optarg;
+    int fixed_args;
+
+    mpm_new_argv = apr_array_make(process->pool, process->argc,
+                                  sizeof(const char **));
+    *(const char **)apr_array_push(mpm_new_argv) = process->argv[0];
+    fixed_args = mpm_new_argv->nelts;
+    apr_getopt_init(&opt, process->pool, process->argc, process->argv);
+    opt->errfn = NULL;
+    optbuf[0] = '-';
+    while ((rv = apr_getopt(opt, "k:" AP_SERVER_BASEARGS,
+                            optbuf + 1, &optarg)) == APR_SUCCESS) {
+        switch(optbuf[1]) {
+        case 'k':
+            if (!dash_k_arg) {
+                if (!strcmp(optarg, "start") || !strcmp(optarg, "stop") ||
+                    !strcmp(optarg, "restart") || !strcmp(optarg, "graceful")) {
+                    dash_k_arg = optarg;
+                    break;
+                }
+                if (!strcmp(optarg, "startssl")) {
+                    char **new_define;
+
+                    dash_k_arg = "start";
+                    new_define = (char **)apr_array_push(ap_server_config_defines);
+                    *new_define = "SSL";
+                    break;
+                }
+            }
+        default:
+            *(const char **)apr_array_push(mpm_new_argv) =
+                apr_pstrdup(process->pool, optbuf);
+            if (optarg) {
+                *(const char **)apr_array_push(mpm_new_argv) = optarg;
+            }
+        }
+    }
+
+    /* back up to capture the bad argument */
+    if (rv == APR_BADCH || rv == APR_BADARG) {
+        opt->ind--;
+    }
+
+    while (opt->ind < opt->argc) {
+        *(const char **)apr_array_push(mpm_new_argv) =
+            apr_pstrdup(process->pool, opt->argv[opt->ind++]);
+    }
+
+    process->argc = mpm_new_argv->nelts;
+    process->argv = (const char * const *)mpm_new_argv->elts;
+
+    if (dash_k_arg) {
+        APR_REGISTER_OPTIONAL_FN(ap_signal_server);
+    }
+}
+
+#endif /* AP_MPM_WANT_SIGNAL_SERVER */
+