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
