You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Jim Jagielski <ji...@jaguNET.com> on 1995/12/21 23:35:44 UTC

Replacement for mktemp and httpd_monitor

Because Apache currently uses mktemp(), which has a format that varies from
OS to OS, it's beneficial for it to use a version in which _it_ defines
the format. This allows for the use of a "universal" httpd_monitor
app, for example.

The diffs basically do a few things:
   o define a new format for mkatemp() files ("filename.xxxxxxxx") This
     is because we assume 4 bytes for a long (which getpid() is cast
     to when the PidFile is printed) but we also don't worry too much
     about the size since we only allow up to 8 fields.
   o the name of the scoreboard file now uses the PID in hex, rather
     than decimal. Again, it's limited to 8 hex chars.
   o httpd_monitor now reads the PID directly from the PidFile and
     emulates mkatemp internally, so that it'll always grab the right
     scoreboard file (since it uses the valid PID and forces the scoreboard
     name just like mkatemp()).

Sorry if this shouldn't be posted to the group... I'll also upload to
incoming on apache.org/hyperreal.com, but I don't have an account there
yet so I'll be placing them in the anon-ftp dropbox.

I'll simply call it 'apache-score-mon.diffs'

Anyway, here it is:
*** src/Oconf.h	Thu Dec 21 16:28:50 1995
--- src/conf.h	Thu Dec 21 17:04:34 1995
***************
*** 420,426 ****
  int getpeername (int s, struct sockaddr *name, int *namelen);
  int gethostname (char *name, int namelen);     
  void syslog (int, char *, ...);
- char *mktemp (char *);
       
  #include <stdarg.h>
  long vfprintf (FILE *, char *, va_list);
--- 420,425 ----
*** src/Ohttp_main.c	Wed Dec 20 17:38:31 1995
--- src/http_main.c	Thu Dec 21 17:11:19 1995
***************
*** 105,110 ****
--- 105,111 ----
  int daemons_min_free;
  int daemons_max_free;
  int daemons_limit;
+ char *mkatemp(char *);
  
  char server_root[MAX_STRING_LEN];
  char server_confname[MAX_STRING_LEN];
***************
*** 147,153 ****
  
!     strcpy(lock_fname, "/usr/tmp/htlock.XXXXXX");
      
!     if (mktemp(lock_fname) == NULL || lock_fname[0] == '\0')
      {
  	fprintf (stderr, "Cannot assign name to lock file!\n");
  	exit (1);
--- 148,154 ----
  
!     strcpy(lock_fname, "/usr/tmp/htlock.xxxxxxxx");
      
!     if (mkatemp(lock_fname) == NULL || lock_fname[0] == '\0')
      {
  	fprintf (stderr, "Cannot assign name to lock file!\n");
  	exit (1);
***************
*** 324,330 ****
   */
  
  static short_score scoreboard_image[HARD_SERVER_MAX];
! static char scoreboard_fname[] = "/tmp/htstatus.XXXXXX";
  static int have_scoreboard_fname = 0;
  static int scoreboard_fd;
  
--- 325,331 ----
   */
  
  static short_score scoreboard_image[HARD_SERVER_MAX];
! static char scoreboard_fname[] = SCOREBOARD_NAME;
  static int have_scoreboard_fname = 0;
  static int scoreboard_fd;
  
***************
*** 360,366 ****
  
  void reinit_scoreboard (pool *p)
  {
!     if (!have_scoreboard_fname && (mktemp(scoreboard_fname) == NULL ||
  				   scoreboard_fname[0] == '\0')) {
  	fprintf (stderr, "Cannot assign name to scoreboard file!\n");
  	exit (1);
--- 361,367 ----
  
  void reinit_scoreboard (pool *p)
  {
!     if (!have_scoreboard_fname && (mkatemp(scoreboard_fname) == NULL ||
  				   scoreboard_fname[0] == '\0')) {
  	fprintf (stderr, "Cannot assign name to scoreboard file!\n");
  	exit (1);
***************
*** 1043,1045 ****
--- 1044,1064 ----
  }
  
  
+ char *mkatemp(char *string) {
+     char *ptmp;
+     char buf[9];
+ 
+     sprintf(buf, "%08lx", (long)getpid());	/* that's what log does */
+     /*
+      * Now check for the right format. Barf if no good
+      */
+     if ((ptmp = strrchr(string, '.')) == NULL)
+ 	return(NULL);
+     if (strcmp(++ptmp, "xxxxxxxx") != 0)
+ 	return(NULL);
+     /*
+      * At this point we should be golden
+      */
+     *ptmp = '\0';
+     return(strcat(string, buf));
+ }
*** src/Oscoreboard.h	Wed Dec 20 17:38:21 1995
--- src/scoreboard.h	Thu Dec 21 16:53:38 1995
***************
*** 61,67 ****
   *
   * Status values:
   */
!    
  #define SERVER_DEAD 0		/* Unused scoreboard entry */
  #define SERVER_READY 1		/* Waiting for connection (or accept() lock) */
  #define SERVER_BUSY 2		/* Processing a client request */
--- 61,68 ----
   *
   * Status values:
   */
! 
! #define SCOREBOARD_NAME	"/usr/local/httpd/tmp/htstatus.xxxxxxxx"
  #define SERVER_DEAD 0		/* Unused scoreboard entry */
  #define SERVER_READY 1		/* Waiting for connection (or accept() lock) */
  #define SERVER_BUSY 2		/* Processing a client request */
*** support/OMakefile	Wed Dec 20 17:28:53 1995
--- support/Makefile	Wed Dec 20 20:16:56 1995
***************
*** 10,23 ****
  # For SCO ODT
  #EXTRA_LIBS= -lcrypt_i
  
  RM= /bin/rm -f
  #--- You shouldn't have to edit anything else. ---
  
  .c.o: 
! 	$(CC) -c $(CFLAGS) $<
  
! all: htpasswd unescape inc2shtml
  
  ibm: $(OBJS)
  	make all CC=gcc
  
--- 10,28 ----
  # For SCO ODT
  #EXTRA_LIBS= -lcrypt_i
  
+ INCLUDES= -I../src
+ 
  RM= /bin/rm -f
  #--- You shouldn't have to edit anything else. ---
  
  .c.o: 
! 	$(CC) -c $(CFLAGS) $(INCLUDES) $<
  
! all: htpasswd unescape inc2shtml httpd_monitor
  
+ aux: $(OBJS)
+ 	make all CC=gcc CFLAGS=-O2
+ 
  ibm: $(OBJS)
  	make all CC=gcc
  
***************
*** 48,53 ****
  inc2shtml: inc2shtml.c
  	$(CC) $(CFLAGS) inc2shtml.c -o inc2shtml
  	
  clean:
! 	rm -f htpasswd unescape inc2shtml
  
--- 53,61 ----
  inc2shtml: inc2shtml.c
  	$(CC) $(CFLAGS) inc2shtml.c -o inc2shtml
  	
+ httpd_monitor: httpd_monitor.c
+ 	$(CC) $(INCLUDES) $(CFLAGS) httpd_monitor.c -o httpd_monitor
+ 	
  clean:
! 	rm -f htpasswd unescape inc2shtml httpd_monitor
  
*** /dev/null	Thu Dec 21 17:05:35 1995
--- support/httpd_monitor.c	Thu Dec 21 17:16:26 1995
***************
*** 0 ****
--- 1,210 ----
+ /*
+  * ====================================================================
+  * Copyright (c) 1995 The Apache Group.  All rights reserved.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  *
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer. 
+  *
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in
+  *    the documentation and/or other materials provided with the
+  *    distribution.
+  *
+  * 3. All advertising materials mentioning features or use of this
+  *    software must display the following acknowledgment:
+  *    "This product includes software developed by the Apache Group
+  *    for use in the Apache HTTP server project (http://www.apache.org/)."
+  *
+  * 4. The names "Apache Server" and "Apache Group" must not be used to
+  *    endorse or promote products derived from this software without
+  *    prior written permission.
+  *
+  * 5. Redistributions of any form whatsoever must retain the following
+  *    acknowledgment:
+  *    "This product includes software developed by the Apache Group
+  *    for use in the Apache HTTP server project (http://www.apache.org/)."
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
+  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
+  * IT'S CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+  * OF THE POSSIBILITY OF SUCH DAMAGE.
+  * ====================================================================
+  *
+  * This software consists of voluntary contributions made by many
+  * individuals on behalf of the Apache Group and was originally based
+  * on public domain software written at the National Center for
+  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
+  * For more information on the Apache Group and the Apache HTTP server
+  * project, please see <http://www.apache.org/>.
+ 
+ 
+  * simple script to monitor the child Apache processes
+  *   Usage:
+  *      httpd_monitor -p pid_file -s sleep_time
+  *                Will give you an update ever sleep_time seconds
+  *                 using pid_file as the location of the PID file.
+  *                If you choose 0, it might chew up lots of CPU time.
+  *
+  * Output explanation..
+  *
+  *  s = sleeping but "ready to go" child
+  *  R = active child
+  *  _ = dead child (no longer needed)
+  *  t = just starting
+  *
+  */
+ 
+ #include <stdio.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include "scoreboard.h"
+ 
+ #define DEFAULT_PID_FILE	"/usr/local/httpd/logs/httpd.pid"
+ #define DEFAULT_SLEEPTIME	2
+ #define ASIZE			256
+ #define MAX_PROC		40
+ 
+ int
+ main(argc, argv)
+ int argc;
+ char **argv;
+ {
+     short_score scoreboard_image;
+     FILE *pid_file;
+     char pid_name[ASIZE];
+     char score_name[ASIZE];
+     char tbuf[ASIZE];
+     char ext[10];
+     char *ptmp;
+     static char kid_stat[] = { '_', 's', 'R', 't' };
+     char achar;
+     long thepid;
+     int score_fd;
+     int sleep_time = DEFAULT_SLEEPTIME;
+     int last_len = 0;
+     int kiddies;
+     int running, dead, total, loop;
+     struct stat statbuf;
+     time_t last_time = 0;
+     extern char *optarg;
+     extern int optind, opterr;
+ 
+     int usage();
+ 
+     /*
+      * Handle the options. Using getopt() is most probably overkill,
+      * but let's think about the future!
+      */
+     strcpy(pid_name, DEFAULT_PID_FILE);
+     strcpy(score_name, SCOREBOARD_NAME);
+     while((achar = getopt(argc,argv,"s:p:")) != -1) {
+ 	switch(achar) {
+ 	  case 'p':
+ 	    strncpy(pid_name, optarg, ASIZE-1);
+ 	    break;
+ 	  case 's':
+ 	    sleep_time = atoi(optarg);
+ 	    break;
+ 	  case '?':
+ 	    usage(argv[0]);
+ 	}
+     }
+ 
+     /*
+      * Make sure we have the right PID file... Barf if not
+      * Once we get it, use it for the scoreboard.
+      */
+     pid_file = fopen(pid_name, "r");
+     if (!pid_file) {
+ 	perror("httpd_monitor");
+ 	fprintf(stderr, "Can't open PID file: %s\n", pid_name);
+ 	exit(1);
+     }
+     fscanf(pid_file, "%ld", &thepid);
+     sprintf(ext, ".%08lx", thepid);	/* slurp */
+     fclose(pid_file);
+     ptmp = strrchr(score_name, '.');
+     if (!ptmp) {
+ 	fprintf(stderr, "Hmmm... scoreboard name doesn't seem right\n");
+ 	fprintf(stderr, " -> \"%s\" ?\n", score_name);
+ 	exit(1);
+     }
+     if (strcmp(ptmp, ".xxxxxxxx") != 0) {
+ 	fprintf(stderr, "Hmmm... scoreboard name doesn't seem right\n");
+ 	fprintf(stderr, " -> \"%s\" ?\n", score_name);
+ 	exit(1);
+     }
+     *ptmp = '\0';
+     strncat(score_name, ext, ASIZE-strlen(score_name)-1); /* null-terminated */
+ 
+     for(;;sleep(sleep_time)) {
+ 	if (stat(score_name, &statbuf)) {
+ 	    perror("httpd_monitor");
+ 	    fprintf(stderr, "Can't stat scoreboard file: %s\n", score_name);
+ 	    exit(1);
+ 	}
+ 	if (last_time == statbuf.st_mtime)
+ 	    continue;	/* tricky ;) */
+ 	last_time = statbuf.st_mtime;	/* for next time */
+ 	score_fd = open(score_name, 0);
+ 	if (score_fd == -1) {
+ 	    perror("httpd_monitor");
+ 	    fprintf(stderr, "Can't open scoreboard file: %s\n", score_name);
+ 	    exit(1);
+ 	}
+ 	/*
+ 	 * all that for _this_
+ 	 */
+ 	running = dead = total = 0;
+ 	ptmp = tbuf;
+ 	*ptmp = '\0';
+ 	for(kiddies=0;kiddies<MAX_PROC; kiddies++) {
+ 	    read(score_fd, (char *)&scoreboard_image, sizeof(short_score));
+ 	    achar = kid_stat[(int)scoreboard_image.status];
+ 	    if (scoreboard_image.pid != 0 && scoreboard_image.pid != thepid) {
+ 		total++;
+ 		if (achar == 'R')
+ 		    running++;
+ 		*ptmp = achar;
+ 		*++ptmp = '\0';
+ 	    }
+ 	}
+ 	close(score_fd);
+ 	sprintf(ptmp, " (%d/%d)", running, total);
+ 	for(loop=1;loop<=last_len;loop++)
+ 	    putchar('\010');
+ 	if (last_len > strlen(tbuf)) {
+ 	    for(loop=1;loop<=last_len;loop++)
+ 		putchar(' ');
+ 	    for(loop=1;loop<=last_len;loop++)
+ 		putchar('\010');
+ 	}
+ 	printf("%s", tbuf);
+ 	fflush(stdout);
+ 	last_len = strlen(tbuf);
+     }	/* for */
+ }
+ 
+ int
+ usage(arg)
+ char *arg;
+ {
+     printf("httpd_monitor: Usage\n");
+     printf("  httpd_monitor [ -p pid-file] [ -s sleep-time ]\n");
+     printf("    Defaults: pid-file = %s\n", DEFAULT_PID_FILE);
+     printf("              sleep-time = %d seconds\n", DEFAULT_SLEEPTIME);
+     exit(0);
+ }
-- 
Jim Jagielski  << jim@jaguNET.com >>   |           "Wind the frog!"
  **  jaguNET Access Services  **      |       - Woody (from Toy Story)
++       Email: info@jaguNET.com      +++        Voice:  410-931-3157       ++
++       http://www.jaguNET.com/      +++         Data: 410-931-7060        ++