rc-scripts/branches/vserver/src: Makefile.am initlog.c minilogd.c

baggins cvs at pld-linux.org
Mon Oct 17 17:05:39 CEST 2005


Author: baggins
Date: Mon Oct 17 17:05:38 2005
New Revision: 6454

Added:
   rc-scripts/branches/vserver/src/minilogd.c
Modified:
   rc-scripts/branches/vserver/src/Makefile.am
   rc-scripts/branches/vserver/src/initlog.c
Log:
- reverted minilogd removal, there is a clean way to cope with it


Modified: rc-scripts/branches/vserver/src/Makefile.am
==============================================================================
--- rc-scripts/branches/vserver/src/Makefile.am	(original)
+++ rc-scripts/branches/vserver/src/Makefile.am	Mon Oct 17 17:05:38 2005
@@ -21,6 +21,7 @@
 	getkey \
 	initlog \
 	loglevel \
+	minilogd \
 	netreport \
 	start-stop-daemon
 	

Modified: rc-scripts/branches/vserver/src/initlog.c
==============================================================================
--- rc-scripts/branches/vserver/src/initlog.c	(original)
+++ rc-scripts/branches/vserver/src/initlog.c	Mon Oct 17 17:05:38 2005
@@ -168,6 +168,38 @@
     return lines;
 }
 
+int startDaemon() {
+    int pid;
+    int rc;
+    
+    if ( (pid = fork()) == -1 ) {
+	perror("fork");
+	return -1;
+    }
+    if ( pid ) {
+	/* parent */
+	waitpid(pid,&rc,0);
+	if (WIFEXITED(rc)) {
+	  DDEBUG("minilogd returned %d!\n",WEXITSTATUS(rc));
+	  return WEXITSTATUS(rc);
+	}
+	else
+	  return -1;
+    } else {
+	int fd;
+	
+	fd=open("/dev/null",O_RDWR);
+	dup2(fd,0);
+	dup2(fd,1);
+	dup2(fd,2);
+        close(fd);
+	/* kid */
+	execlp("minilogd","minilogd",NULL);
+	perror("exec");
+	exit(-1);
+    }
+}
+
 int trySocket() {
 	int s;
 	struct sockaddr_un addr;
@@ -212,6 +244,7 @@
     
 	
     if  ( ((stat(_PATH_LOG,&statbuf)==-1) || trySocket())
+	  && startDaemon()
 	) {
 	DDEBUG("starting daemon failed, pooling entry %d\n",logEntries);
 	logData=realloc(logData,(logEntries+1)*sizeof(struct logInfo));

Added: rc-scripts/branches/vserver/src/minilogd.c
==============================================================================
--- (empty file)
+++ rc-scripts/branches/vserver/src/minilogd.c	Mon Oct 17 17:05:38 2005
@@ -0,0 +1,183 @@
+/* minilogd.c
+ * 
+ * A pale imitation of syslogd. Most notably, doesn't write anything
+ * anywhere except possibly back to syslogd.
+ *
+ * Copyright (c) 1999-2001 Red Hat, Inc. All rights reserved.
+ *
+ * This software may be freely redistributed under the terms of the GNU
+ * public license.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+
+static int we_own_log=0;
+static char **buffer=NULL;
+static int buflines=0;
+
+int debug;
+
+int recvsock;
+
+void alarm_handler(int x) {
+	alarm(0);
+	close(recvsock);
+	recvsock = -1;
+}
+
+void freeBuffer() {
+   struct sockaddr_un addr;
+   int sock;
+   int x=0,conn;
+   
+   bzero(&addr,sizeof(addr));
+   addr.sun_family = AF_LOCAL;
+   strncpy(addr.sun_path,_PATH_LOG,sizeof(addr.sun_path)-1);
+   /* wait for klogd to hit syslog */
+   sleep(2);
+   sock = socket(AF_LOCAL, SOCK_DGRAM,0);
+   conn=connect(sock,(struct sockaddr *) &addr,sizeof(addr));
+   while (x<buflines) {
+      if (!conn) write(sock,buffer[x],strlen(buffer[x])+1);
+      free(buffer[x]);
+      x++;
+   }
+}
+
+void cleanup(int exitcode) {
+   /* If we own the log, unlink it before trying to free our buffer.
+    * Otherwise, sending the buffer to /dev/log doesn't make much sense.... */
+   if (we_own_log) {
+      perror("wol");
+      unlink(_PATH_LOG);
+   }
+   /* Don't try to free buffer if we were called from a signal handler */
+   if (exitcode<=0) {
+       if (buffer) freeBuffer();
+       exit(exitcode);
+   } else
+      exit(exitcode+128);
+}
+
+void runDaemon(int sock) {
+   struct sockaddr_un addr;
+   int x,len,addrlen,done=0;
+   char *message;
+   struct stat s1,s2;
+   struct pollfd pfds;
+    
+    daemon(0,-1);
+    /* try not to leave stale sockets lying around */
+    /* Hopefully, we won't actually get any of these */
+    signal(SIGHUP,cleanup);
+    signal(SIGINT,cleanup);
+    signal(SIGQUIT,cleanup);
+    signal(SIGILL,cleanup);
+    signal(SIGABRT,cleanup);
+    signal(SIGFPE,cleanup);
+    signal(SIGSEGV,cleanup);
+    signal(SIGPIPE,cleanup);
+    signal(SIGBUS,cleanup);
+    signal(SIGTERM,cleanup);
+   done = 0;
+   /* Get stat info on /dev/log so we can later check to make sure we
+    * still own it... */
+   if (stat(_PATH_LOG,&s1) != 0)
+	  memset(&s1, '\0', sizeof(struct stat));
+   while (!done) {
+      pfds.fd = sock;
+      pfds.events = POLLIN|POLLPRI;
+      if ( ( (x=poll(&pfds,1,500))==-1) && errno !=EINTR) {
+	 perror("poll");
+	 cleanup(-1);
+      }
+      if ( (x>0) && pfds.revents & (POLLIN | POLLPRI)) {
+	 message = calloc(8192,sizeof(char));
+	 recvsock = accept(sock,(struct sockaddr *) &addr, &addrlen);
+	 alarm(2);
+	 signal(SIGALRM, alarm_handler);
+	 len = read(recvsock,message,8192);
+	 alarm(0);
+	 close(recvsock);
+	 if (len>0) {
+		 if (buflines < 200000) {
+			 if (buffer)
+			   buffer = realloc(buffer,(buflines+1)*sizeof(char *));
+			 else
+			   buffer = malloc(sizeof(char *));
+			 message[strlen(message)]='\n';
+			 buffer[buflines]=message;
+			 buflines++;
+		 }
+	 }
+	 else {
+	    recvsock=-1;
+	 }
+      }
+      if ( (x>0) && ( pfds.revents & (POLLHUP | POLLNVAL)) )
+	done = 1;
+      /* Check to see if syslogd's yanked our socket out from under us */
+      if ( (stat(_PATH_LOG,&s2)!=0) ||
+	    (s1.st_ino != s2.st_ino ) || (s1.st_ctime != s2.st_ctime) ||
+	    (s1.st_mtime != s2.st_mtime) || (s1.st_atime != s2.st_atime) ) {
+	 done = 1;
+	 we_own_log = 0;
+      }
+   }
+   cleanup(0);
+}
+
+int main(int argc, char **argv) {
+   struct sockaddr_un addr;
+   int sock;
+   int pid;
+    
+   /* option processing made simple... */
+   if (argc>1) debug=1;
+   /* just in case */
+   sock = open("/dev/null",O_RDWR);
+   dup2(sock,0);
+   dup2(sock,1);
+   dup2(sock,2);
+   close(sock);
+	
+   bzero(&addr, sizeof(addr));
+   addr.sun_family = AF_LOCAL;
+   strncpy(addr.sun_path,_PATH_LOG,sizeof(addr.sun_path)-1);
+   sock = socket(AF_LOCAL, SOCK_STREAM,0);
+   unlink(_PATH_LOG);
+   /* Bind socket before forking, so we know if the server started */
+   if (!bind(sock,(struct sockaddr *) &addr, sizeof(addr))) {
+      we_own_log = 1;
+      listen(sock,5);
+      if ((pid=fork())==-1) {
+	 perror("fork");
+	 exit(3);
+      }
+      if (pid) {
+	 exit(0);
+      } else {
+	  runDaemon(sock);
+	  /* shouldn't get back here... */
+	  exit(4);
+      }
+   } else {
+      exit(5);
+   }
+}



More information about the pld-cvs-commit mailing list