Changeset: 1e8997d04879 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=1e8997d04879
Modified Files:
        tools/merovingian/ChangeLog.Aug2011
        tools/merovingian/daemon/argvcmds.c
        tools/merovingian/daemon/merovingian.c
        tools/merovingian/daemon/merovingian.h
        tools/merovingian/daemon/monetdbd.1.in
Branch: Aug2011
Log Message:

monetdbd: make forking into the background a runtime option

Instead of being a compile-time option whether or not to fork into the
background, make it a run-time option, since this aids debugging, but
also allows many start/stop services to more easily work with monetdbd
as deamon, since not forking means they can reliably stop the started
process again.


diffs (truncated from 308 to 300 lines):

diff --git a/tools/merovingian/ChangeLog.Aug2011 
b/tools/merovingian/ChangeLog.Aug2011
--- a/tools/merovingian/ChangeLog.Aug2011
+++ b/tools/merovingian/ChangeLog.Aug2011
@@ -1,6 +1,10 @@
 # ChangeLog file for sql/src/backends/monet5/merovingian
 # This file is updated with mchangelog
 
+* Wed Aug 17 2011 Fabian Groffen <[email protected]>
+- Added -n option to monetdbd start command, which prevents monetdbd
+  from forking into the background.
+
 * Sat Aug  6 2011 Fabian Groffen <[email protected]>
 - Fix incorrect (misleading) path for pidfile in pidfile error message,
   bug #2851
diff --git a/tools/merovingian/daemon/argvcmds.c 
b/tools/merovingian/daemon/argvcmds.c
--- a/tools/merovingian/daemon/argvcmds.c
+++ b/tools/merovingian/daemon/argvcmds.c
@@ -52,9 +52,10 @@ command_help(int argc, char *argv[])
                printf("  must be a path in the filesystem where a directory 
can be\n");
                printf("  created, or a directory that is writable that already 
exists.\n");
        } else if (strcmp(argv[1], "start") == 0) {
-               printf("usage: monetdbd start [dbfarm]\n");
+               printf("usage: monetdbd start [-n] [dbfarm]\n");
                printf("  Starts the monetdbd deamon.  When no dbfarm given, it 
starts\n");
                printf("  in the default dbfarm (%s).\n", LOCALSTATEDIR 
"/monetdb5/dbfarm");
+               printf("  When -n is given, monetdbd will not fork into the 
background.");
        } else if (strcmp(argv[1], "stop") == 0) {
                printf("usage: monetdbd stop [dbfarm]\n");
                printf("  Stops a running monetdbd deamon for the given dbfarm, 
or\n");
diff --git a/tools/merovingian/daemon/merovingian.c 
b/tools/merovingian/daemon/merovingian.c
--- a/tools/merovingian/daemon/merovingian.c
+++ b/tools/merovingian/daemon/merovingian.c
@@ -452,6 +452,7 @@ main(int argc, char *argv[])
        FILE *oerr = NULL;
        pthread_mutexattr_t mta;
        int thret;
+       char merodontfork = 0;
        confkeyval ckv[] = {
                {"logfile",       strdup("merovingian.log"), 0,                
STR},
                {"pidfile",       strdup("merovingian.pid"), 0,                
STR},
@@ -469,78 +470,8 @@ main(int argc, char *argv[])
                { NULL,           NULL,                    0,                  
INVALID}
        };
        confkeyval *kv;
-#ifndef MERO_DONTFORK
-       char buf[4];
        int retfd = -1;
 
-       /* Fork into the background immediately.  By doing this our child
-        * can simply do everything it needs to do itself.  Via a pipe it
-        * will tell us if it is happy or not. */
-       if (pipe(pfd) == -1) {
-               Mfprintf(stderr, "unable to create pipe: %s\n", 
strerror(errno));
-               return(1);
-       }
-       switch (fork()) {
-               case -1:
-                       /* oops, forking went wrong! */
-                       Mfprintf(stderr, "unable to fork into background: %s\n",
-                                       strerror(errno));
-                       return(1);
-               case 0:
-                       /* detach client from controlling tty, we only write to 
the
-                        * pipe to daddy */
-                       if (setsid() < 0)
-                               Mfprintf(stderr, "hmmm, can't detach from 
controlling tty, "
-                                               "continuing anyway\n");
-                       retfd = open("/dev/null", O_RDONLY);
-                       dup2(retfd, 0);
-                       close(retfd);
-                       close(pfd[0]); /* close unused read end */
-                       retfd = pfd[1]; /* store the write end */
-               break;
-               default:
-                       /* the parent, we want it to die, after we know the 
child
-                        * has a good time */
-                       close(pfd[1]); /* close unused write end */
-                       if (read(pfd[0], &buf, 1) != 1) {
-                               Mfprintf(stderr, "unable to retrieve startup 
status\n");
-                               return(1);
-                       }
-                       close(pfd[0]);
-                       return(buf[0]); /* whatever the child returned, we 
return */
-       }
-
-/* use after the logger thread has started */
-#define MERO_EXIT(status) { \
-               char s = status; \
-               if (write(retfd, &s, 1) != 1 || close(retfd) != 0) { \
-                       Mfprintf(stderr, "could not write to parent\n"); \
-               } \
-               if (status != 0) { \
-                       Mfprintf(stderr, "fatal startup condition encountered, 
" \
-                                       "aborting startup\n"); \
-                       goto shutdown; \
-               } \
-       }
-/* use before logger thread has started */
-#define MERO_EXIT_CLEAN(status) { \
-               char s = status; \
-               if (write(retfd, &s, 1) != 1 || close(retfd) != 0) { \
-                       Mfprintf(stderr, "could not write to parent\n"); \
-               } \
-               exit(s); \
-       }
-#else
-#define MERO_EXIT(status) \
-       if (status != 0) { \
-               Mfprintf(stderr, "fatal startup condition encountered, " \
-                               "aborting startup\n"); \
-               goto shutdown; \
-       }
-#define MERO_EXIT_CLEAN(status) \
-               exit(status);
-#endif
-
        /* seed the randomiser for when we create a database, send responses
         * to HELO, etc */
        srand(time(NULL));
@@ -580,50 +511,122 @@ main(int argc, char *argv[])
                Mfprintf(stderr, "fatal: compiled in dbfarm location exceeds " \
                                "allocated path length, please file a bug at " \
                                "http://bugs.monetdb.org/\n";);
-               MERO_EXIT_CLEAN(1);
+               exit(1);
        }
        snprintf(dbfarm, sizeof(dbfarm), "%s", LOCALSTATEDIR 
"/monetdb5/dbfarm");
        if (argc > 1) {
-               /* future: support -v or something like monetdb(1), for now we
-                * just don't */
                if (strcmp(argv[1], "--help") == 0 ||
                                strcmp(argv[1], "-h") == 0 ||
                                strcmp(argv[1], "help") == 0)
                {
-                       MERO_EXIT_CLEAN(command_help(argc - 1, &argv[1]));
+                       exit(command_help(argc - 1, &argv[1]));
                } else if (strcmp(argv[1], "--version") == 0 ||
                                strcmp(argv[1], "-v") == 0 ||
                                strcmp(argv[1], "version") == 0)
                {
-                       MERO_EXIT_CLEAN(command_version());
+                       exit(command_version());
                } else if (strcmp(argv[1], "create") == 0) {
-                       MERO_EXIT_CLEAN(command_create(argc - 1, &argv[1]));
+                       exit(command_create(argc - 1, &argv[1]));
                } else if (strcmp(argv[1], "get") == 0) {
-                       MERO_EXIT_CLEAN(command_get(ckv, argc - 1, &argv[1]));
+                       exit(command_get(ckv, argc - 1, &argv[1]));
                } else if (strcmp(argv[1], "set") == 0) {
-                       MERO_EXIT_CLEAN(command_set(ckv, argc - 1, &argv[1]));
+                       exit(command_set(ckv, argc - 1, &argv[1]));
                } else if (strcmp(argv[1], "start") == 0) {
-                       /* start without argument just means start hardwired 
dbfarm */
-                       if (argc > 2) {
+                       /* start without path argument just means start 
hardwired dbfarm */
+                       if (argc > 2 && strcmp(argv[2], "-n") == 0)
+                                       merodontfork = 1;
+                       if (argc > 2 + merodontfork) {
                                int len;
-                               len = snprintf(dbfarm, sizeof(dbfarm), "%s", 
argv[2]);
+                               len = snprintf(dbfarm, sizeof(dbfarm), "%s",
+                                               argv[2 + merodontfork]);
                        
                                if (len > 0 && (size_t)len >= sizeof(dbfarm)) {
                                        Mfprintf(stderr, "fatal: dbfarm exceeds 
allocated " \
                                                        "path length, please 
file a bug at " \
                                                        
"http://bugs.monetdb.org/\n";);
-                                       MERO_EXIT_CLEAN(1);
+                                       exit(1);
                                }
                        }
                } else if (strcmp(argv[1], "stop") == 0) {
-                       MERO_EXIT_CLEAN(command_stop(ckv, argc - 1, &argv[1]));
+                       exit(command_stop(ckv, argc - 1, &argv[1]));
                } else {
                        fprintf(stderr, "monetdbd: unknown command: %s\n", 
argv[1]);
                        command_help(0, NULL);
-                       MERO_EXIT_CLEAN(1);
+                       exit(1);
                }
        }
 
+       /* fork into background before doing anything more */
+       if (!merodontfork) {
+               char buf[4];
+
+               /* Fork into the background immediately.  By doing this our 
child
+                * can simply do everything it needs to do itself.  Via a pipe 
it
+                * will tell us if it is happy or not. */
+               if (pipe(pfd) == -1) {
+                       Mfprintf(stderr, "unable to create pipe: %s\n", 
strerror(errno));
+                       return(1);
+               }
+               switch (fork()) {
+                       case -1:
+                               /* oops, forking went wrong! */
+                               Mfprintf(stderr, "unable to fork into 
background: %s\n",
+                                               strerror(errno));
+                               return(1);
+                       case 0:
+                               /* detach client from controlling tty, we only 
write to the
+                                * pipe to daddy */
+                               if (setsid() < 0)
+                                       Mfprintf(stderr, "hmmm, can't detach 
from controlling tty, "
+                                                       "continuing anyway\n");
+                               retfd = open("/dev/null", O_RDONLY);
+                               dup2(retfd, 0);
+                               close(retfd);
+                               close(pfd[0]); /* close unused read end */
+                               retfd = pfd[1]; /* store the write end */
+                       break;
+                       default:
+                               /* the parent, we want it to die, after we know 
the child
+                                * has a good time */
+                               close(pfd[1]); /* close unused write end */
+                               if (read(pfd[0], &buf, 1) != 1) {
+                                       Mfprintf(stderr, "unable to retrieve 
startup status\n");
+                                       return(1);
+                               }
+                               close(pfd[0]);
+                               return(buf[0]); /* whatever the child returned, 
we return */
+               }
+       }
+
+/* use after the logger thread has started */
+#define MERO_EXIT(status) if (!merodontfork) { \
+               char s = status; \
+               if (write(retfd, &s, 1) != 1 || close(retfd) != 0) { \
+                       Mfprintf(stderr, "could not write to parent\n"); \
+               } \
+               if (status != 0) { \
+                       Mfprintf(stderr, "fatal startup condition encountered, 
" \
+                                       "aborting startup\n"); \
+                       goto shutdown; \
+               } \
+       } else { \
+               if (status != 0) { \
+                       Mfprintf(stderr, "fatal startup condition encountered, 
" \
+                                       "aborting startup\n"); \
+                       goto shutdown; \
+               } \
+       }
+/* use before logger thread has started */
+#define MERO_EXIT_CLEAN(status) if (!merodontfork) { \
+               char s = status; \
+               if (write(retfd, &s, 1) != 1 || close(retfd) != 0) { \
+                       Mfprintf(stderr, "could not write to parent\n"); \
+               } \
+               exit(s); \
+       } else { \
+               exit(status); \
+       }
+
        /* check if dbfarm actually exists */
        if (stat(dbfarm, &sb) == -1) {
                Mfprintf(stderr, "dbfarm directory '%s' does not exist, "
diff --git a/tools/merovingian/daemon/merovingian.h 
b/tools/merovingian/daemon/merovingian.h
--- a/tools/merovingian/daemon/merovingian.h
+++ b/tools/merovingian/daemon/merovingian.h
@@ -26,7 +26,7 @@
 
 #include "utils/utils.h" /* confkeyval */
 
-#define MERO_VERSION   "1.4"
+#define MERO_VERSION   "1.5"
 #define MERO_PORT      "50000"
 #define CONTROL_PORT   "50001"
 #define MERO_SOCK      ".s.monetdb."
diff --git a/tools/merovingian/daemon/monetdbd.1.in 
b/tools/merovingian/daemon/monetdbd.1.in
--- a/tools/merovingian/daemon/monetdbd.1.in
+++ b/tools/merovingian/daemon/monetdbd.1.in
@@ -1,7 +1,7 @@
 .\" Process this file with
 .\" groff -man -Tascii foo.1
 .\"
-.TH MONETDBD 1 "APRIL 2011" MonetDB "MonetDB Applications"
+.TH MONETDBD 1 "AUGUST 2011" MonetDB "MonetDB Applications"
 .SH NAME
 monetdbd \- the MonetDB Database Server daemon
 .SH SYNOPSIS
@@ -57,7 +57,7 @@ database process, started on the fly whe
 .P
 When started,
 .B monetdbd
-runs in the background, sending log messages to
+runs by default in the background, sending log messages to
 .IR merovingian.log ,
 until being sent a stop, terminate or interrupt signal, possibly using
 the stop command of
@@ -91,11 +91,16 @@ be created, and an initial properties fi
 itself.
 .I dbfarm
 must be a location addressable in the local filesystem hierarchy.
-.IP "start [dbfarm]"
+.IP "start [-n] [dbfarm]"
 Starts
 .BR monetdbd ,
 the MonetDB Database Server, on the given dbfarm, or its default, the
-system-wide location @Elocalstatedir@/monetdb5/dbfarm.
+system-wide location @Elocalstatedir@/monetdb5/dbfarm.  When the
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to