diff -r 4f1e39ec05d6 tools/xenlogd/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xenlogd/Makefile	Fri Jun 09 15:40:36 2006 +0900
@@ -0,0 +1,7 @@
+CC=gcc
+CFLAGS=-lxenctrl
+
+xenlogd:
+
+clean:
+	rm -f xenlogd
diff -r 4f1e39ec05d6 tools/xenlogd/TODO
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xenlogd/TODO	Fri Jun 09 15:40:36 2006 +0900
@@ -0,0 +1,9 @@
+
+Following is the usage, but usually no option is necessary.
+It will automatically be daemon.
+
+usage: xenlogd [-h] [-n] [-k] [-r]
+       -h: print help
+       -n: no daemonize
+       -k: kill alive logging daemon
+       -r: restart logging daemon after kill alive one
diff -r 4f1e39ec05d6 tools/xenlogd/xenlogd.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xenlogd/xenlogd.c	Fri Jun 09 15:40:36 2006 +0900
@@ -0,0 +1,283 @@
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <syslog.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <string.h>
+
+
+#define XCDSIZE (4096)
+#define XENHEAD "(XEN) "
+#define PIDFILE "/var/run/xenlogd.pid"
+#define STARTMSG "logging has been started."
+
+static char *cmdname;
+
+quit(int xc, char *fmt, ...)
+{
+  va_list ap;
+  
+  va_start(ap, fmt);
+  vsyslog(LOG_KERN|LOG_ALERT, fmt, ap);
+  va_end(ap);
+  exit(xc);
+}
+
+putsyslog(char *bp, int size)
+{
+  static char *prsvp = NULL;
+  static int prsvc = 0;
+  char *endp;
+  int offset;
+
+  if ((prsvp == NULL) && ((prsvp = malloc(XCDSIZE)) == NULL)) {
+    quit(1, "allocate buffer failed");
+  }
+
+  bp[size] = '\0';
+
+  for (endp = bp + size; bp < endp; bp++) {
+    if (*bp == '\n') {
+      prsvp[prsvc]  = '\0';
+      if ((strncmp(prsvp, XENHEAD, strlen(XENHEAD)) == 0)) {
+	offset = strlen(XENHEAD);
+      } else {
+	offset = 0;
+      }
+      syslog(LOG_KERN|LOG_ALERT, "%s", prsvp + offset);
+      prsvc = 0;
+    } else {
+      prsvp[prsvc] = *bp;
+      prsvc++;
+    }
+  }
+}
+
+static void child_exit(int sig)
+{
+  while (waitpid(-1, NULL, WNOHANG) > 0);
+}
+
+static void term_daemon(int sig)
+{
+  unlink(PIDFILE);
+  quit(0, "logging ended normally.");
+}
+
+void daemonize()
+{
+  pid_t pid;
+  int fd;
+  int len;
+  int i;
+  int pfd[2];
+  char buf[1024];
+  
+  if (getppid() == 1) {
+    return;
+  }
+
+  signal(SIGPIPE, SIG_IGN);
+
+  if (pipe(pfd) < 0) {
+    quit(1, "open pipe failed");
+  }
+
+  if ((pid = fork()) > 0) {
+    exit(0);
+  } 
+  if (pid < 0) {
+    quit(1, "fork failed: errno = %d", errno);
+  }
+  
+  setsid();
+  
+  if ((pid = fork()) > 0) {
+    exit(0);
+  } 
+  if (pid < 0) {
+    quit(1, "fork failed: errno = %d", errno);
+  }
+  
+  if ((fd = open("/dev/null",O_RDWR)) == -1) {
+    quit(1, "open /dev/null failed: errno = %d", errno);
+  }
+  
+  for (i = 0; i <= 2; i++) {
+    close(i);
+    dup2(fd, i);
+  }
+  
+  close(fd);
+  umask(027);
+
+  if (chdir("/") < 0) {
+    quit(1, "change to root dir failed: errno = %d", errno);
+  }
+
+  pid = getpid();
+  snprintf(buf, sizeof(buf), "%s.%d", PIDFILE, pid);
+  
+  fd = open(buf, O_RDWR | O_CREAT | O_EXCL);
+  if (fd < 0) {
+    quit(1, "open %s failed: errno = %d", buf, errno);
+  }
+
+  if (link(buf, PIDFILE) < 0) {
+    unlink(buf);
+    quit(1, "other logging daemon may keep alive");
+  }
+  unlink(buf);
+  
+  len = sprintf(buf, "%d\n", pid);
+  if (write(fd, buf, len) < 0) {
+    quit(1, "write %s failed: errno = %d", PIDFILE, errno);
+  }
+
+  signal(SIGCHLD, child_exit);
+  signal(SIGTSTP, SIG_IGN);
+  signal(SIGTTOU, SIG_IGN);
+  signal(SIGTTIN, SIG_IGN);
+  sigset(SIGTERM, term_daemon);
+
+  close(pfd[1]);
+  read(pfd[0], buf, sizeof(buf));
+  close(pfd[0]);
+}
+
+int kill_daemon()
+{
+  int fd, pid, len;
+  char buf[1024];
+  char *comm;
+
+  fd = open(PIDFILE, O_RDWR);
+  if (fd < 0) {
+    if (errno == ENOENT) {
+      fprintf(stderr,"%s: no other daemon exist\n", cmdname);
+    } else {
+      perror("open error: ");
+    }
+    return(1);
+  }
+  len = read(fd, buf, sizeof(buf));
+  if (len < 0) {
+    perror("read error: ");
+    return(1);
+  }
+  close(fd);
+  buf[len] = '\0';
+  pid = atoi(buf);
+  
+  if (pid) {
+    snprintf(buf, sizeof(buf), "/proc/%d/stat", pid);
+    if ((fd = open(buf, O_RDONLY)) >= 0) {
+      len = read(fd, buf, sizeof(buf));
+      strtok(buf, " ");
+      if (((comm = strtok(NULL, " ")) != NULL) 
+	  && (strcmp(comm, "(xenlogd)") == 0)) {
+	if (kill(pid, SIGTERM) < 0) {
+	  perror("kill error: ");
+	  return(1);
+	}
+	while (kill(pid, SIGTERM) == 0);
+	if (errno != ESRCH) {
+	  perror("kill error: ");
+	}
+      }
+    }
+  }
+  if ((fd = open(PIDFILE, O_RDWR)) >= 0) {
+    close(fd);
+    unlink(PIDFILE);
+    fprintf(stderr, "%s: lockfile existed but no daemon alive. it was deleted.\n", cmdname);
+  }
+}
+
+void usage()
+{
+  fprintf(stderr, "usage: %s [-h] [-n] [-k] [-r]\n", cmdname);
+  fprintf(stderr, "       -h: print help\n");
+  fprintf(stderr, "       -n: no daemonize\n");
+  fprintf(stderr, "       -k: kill alive logging daemon\n");
+  fprintf(stderr, "       -r: restart logging daemon after kill alive one\n");
+  exit(0);
+}
+
+
+main(int argc, char *argv[])
+{
+  int fd;
+  int rc;
+  int bufsize;
+  int opt;
+  char *bufaddr;
+  char *tmpp;
+  int no_daemonize = 0;
+  int kill_d = 0;
+  int restart_d = 0;
+
+  cmdname = argv[0];
+
+  while ((opt = getopt(argc, argv, "hnkr")) != -1) {
+    switch (opt) {
+    case 'h':
+    case '?':
+    default:
+      usage();
+      break;
+    case 'n':
+      no_daemonize = 1;
+      break;
+    case 'r':
+      restart_d = 1;
+      /* fall through */
+    case 'k':
+      kill_d = 1;
+      break;
+    }
+  }
+
+  openlog(XENHEAD, LOG_NDELAY|LOG_CONS, LOG_KERN);
+
+  fd = xc_interface_open();
+  if (fd < 0) {
+    quit(1, "failed to open xen interface");
+  }
+
+  if ((bufaddr = malloc(XCDSIZE)) ==NULL) {
+    quit(1, "allocate buffer failed");
+  }
+
+  if (kill_d) {
+    kill_daemon();
+    if (!restart_d) {
+      exit(0);
+    }
+  }
+
+  if (!no_daemonize) {
+    daemonize();
+  }
+  
+  syslog(LOG_KERN|LOG_ALERT, "logging has been started.");
+
+  for (;;) {
+    bufsize = XCDSIZE;
+
+    rc = xc_readconsolering(fd, &bufaddr, &bufsize, 1);
+    if (rc < 0) {
+      quit(1, "error: read console ring: %d: errno %d", rc, errno);
+    }
+
+    if (bufsize) {
+      putsyslog(bufaddr, bufsize);
+    }
+    sleep(1);
+  }
+}
