Update of /cvsroot/monetdb/MonetDB5/src/tools
In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv3935

Modified Files:
        merovingian.mx monetdb.mx 
Log Message:
Implemented start/stop functionality by signalling the Merovingian
through a named pipe in the filesystem.  It's still a bit buggy as in
how to deal with the pipe, but it works to a certain extent.


Index: merovingian.mx
===================================================================
RCS file: /cvsroot/monetdb/MonetDB5/src/tools/merovingian.mx,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- merovingian.mx      1 Sep 2007 11:59:24 -0000       1.36
+++ merovingian.mx      2 Sep 2007 15:13:51 -0000       1.37
@@ -50,7 +50,7 @@
 FIXME: actually implement that
 
 @h
-#define MEROV_VERSION   "0.4"
+#define MEROV_VERSION   "0.5"
 #define MEROV_PORT      50000
 
 @c
@@ -111,13 +111,14 @@
        pthread_t tid;    /* thread id used when terminating this server */
        struct _dpair* next;
 }* dpair;
+static dpair topdp = NULL;
 
 static int _keepLogging = 1;
 static int _timeInterval = 0;
 static void
 logListener(void *p)
 {
-       dpair d = (dpair)p;
+       dpair d = topdp;
        dpair w;
        FILE *fout, *ferr;
        char buf[8096];
@@ -127,6 +128,8 @@
        struct tm *tmp;
        int equalouterr;
 
+       (void)p;
+
        /* the first entry in the list of d is where our output should go to */
        fout = d->fout;
        ferr = d->ferr;
@@ -199,8 +202,8 @@
 int timeout = 0;
 /**
  * The terminateProcess function tries to let the given mserver process
- * shut down gracefully within a given time-out.  If that fails, it send
- * the deadly SIGKILL signal to the mserver process and returns.
+ * shut down gracefully within a given time-out.  If that fails, it
+ * sends the deadly SIGKILL signal to the mserver process and returns.
  */
 static void
 terminateProcess(void *p)
@@ -346,10 +349,10 @@
  * this process any more after this function.  Hence, no client pid is
  * maintained or returned.  Before forking off, Sabaoth is consulted to
  * see if forking makes sense, or whether it is necessary at all, or
- * forbidden by restart policy. (TODO)
+ * forbidden by restart policy, e.g. when in maintenance.
  */
 static err
-forkMserver(str database, sabdb** stats, dpair dp, int sock)
+forkMserver(str database, sabdb** stats, int force)
 {
        pid_t pid;
        str er;
@@ -358,6 +361,7 @@
        char tstr[20];
        int pfdo[2];
        int pfde[2];
+       dpair dp = topdp;
 
        er = SABAOTHgetStatus(stats, database);
        if (er != MAL_SUCCEED) {
@@ -388,7 +392,8 @@
 
        if ((*stats)->locked == 1) {
                merlog("database '%s' is under maintenance", database);
-               return(NO_ERR);
+               if (force == 0)
+                       return(NO_ERR);
        }
 
        switch ((*stats)->state) {
@@ -431,6 +436,9 @@
                        return(newErr("unknown state: %d", 
(int)(*stats)->state));
        }
 
+       if ((*stats)->locked == 1 && force == 1)
+               merlog("startup of database under maintenance '%s' forced", 
database);
+
        /* create the pipes (filedescriptors) now, such that we and the
         * child have the same descriptor set */
        if (pipe(pfdo) == -1) {
@@ -458,9 +466,6 @@
                dup2(pfde[1], 2);
                close(pfde[1]);
 
-               /* we don't want the listening socket of the parent */
-               close(sock);
-
                /* we don't use stdin, neither should mserver ... */
                close(0);
 
@@ -550,7 +555,7 @@
 }
 
 static err
-handleClient(int sock, dpair dp)
+handleClient(int sock)
 {
        stream *fdin, *fout;
        bstream *fin;
@@ -692,7 +697,7 @@
                        return(newErr("no database running, and no database 
specified"));
                }
        } else {
-               err e = forkMserver(database, &top, dp, sock);
+               err e = forkMserver(database, &top, 0);
                if (e != NO_ERR) {
                        if (top == NULL) {
                                stream_printf(fout, "!no such database '%s', 
please create it first\n", database);
@@ -799,7 +804,7 @@
 
 static int _keepListening = 1;
 static str
-acceptConnections(int sock, dpair dp)
+acceptConnections(int sock)
 {
        str msg;
        int retval;
@@ -809,6 +814,7 @@
        err e;
 
        do {
+               /* handle socket connections */
                FD_ZERO(&fds);
                if (sock >= 0)
                        FD_SET(sock, &fds);
@@ -843,8 +849,7 @@
                        }
                } else
                        continue;
-               /* TODO: maybe do this in a thread */
-               e = handleClient(msgsock, dp);
+               e = handleClient(msgsock);
                if (e != NO_ERR) {
                        fprintf(stderr, "client error: %s\n", getErrMsg(e));
                        freeErr(e);
@@ -855,11 +860,76 @@
        return(NO_ERR);
 
 error:
+       _keepListening = 0;
        shutdown(sock, SHUT_RDWR);
        close(sock);
        return(newErr("accept connection: %s", msg));
 }
 
+static void
+controlRunner(void *d)
+{
+       FILE *f;
+       char buf[256];
+       char *p;
+       sabdb *stats;
+
+       while (_keepListening == 1) {
+               if ((f = fopen((char *)d, "r")) == NULL) {
+                       fprintf(stderr, "unable to open up control command 
channel for reading\n");
+                       return;
+               }
+
+               /* Try to handle control signals.  We can get race conditions 
due to
+                * clients coming in at the same time.  We might need to fix 
this
+                * situation sometime. */
+               while (_keepListening == 1 && fgets(buf, 256, f) != NULL) {
+                       /* format is simple: database<space>command */
+                       if ((p = strchr(buf, ' ')) == NULL) {
+                               fprintf(stderr, "malformed control signal: 
%s\n", buf);
+                       } else {
+                               *p++ = '\0';
+                               if (strcmp(p, "start\n") == 0) {
+                                       merlog("starting database %s due to 
control signal",
+                                                       buf);
+                                       forkMserver(buf, &stats, 1);
+                                       if (stats != NULL)
+                                               SABAOTHfreeStatus(&stats);
+                               } else if (strcmp(p, "stop\n") == 0 ||
+                                               strcmp(p, "kill\n") == 0)
+                               {
+                                       /* we need to f ind the right dpair, 
that is we
+                                        * sort of assume the control signal is 
right */
+                                       dpair dp = topdp;
+                                       while (dp != NULL) {
+                                               if (strcmp(dp->dbname, buf) == 
0) {
+                                                       if (strcmp(p, "stop\n") 
== 0) {
+                                                               
merlog("stopping database %s due to control "
+                                                                               
"signal", buf);
+                                                               kill(dp->pid, 
SIGTERM);
+                                                       } else {
+                                                               merlog("killing 
database %s due to control "
+                                                                               
"signal", buf);
+                                                               kill(dp->pid, 
SIGKILL);
+                                                       }
+                                                       break;
+                                               }
+                                               dp = dp->next;
+                                       }
+                                       if (dp == NULL) {
+                                               fprintf(stderr, "control stop 
signal for "
+                                                               "non-existing 
database: %s\n", buf);
+                                       }
+                               } else {
+                                       fprintf(stderr, "unknown control 
command: %s", p);
+                               }
+                       }
+               }
+               fclose(f);
+       }
+       fprintf(stderr, "control channel closed\n");
+}
+
 static str
 replacePrefix(str s)
 {
@@ -945,7 +1015,7 @@
        FILE *cnf = NULL;
        char buf[1024];
        sabdb* stats = NULL;
-       dpair d, q = alloca(sizeof(struct _dpair));
+       dpair d;
        int pfd[2];
        pthread_t tid;
        struct sigaction sa;
@@ -961,6 +1031,7 @@
        cnf = fopen(buf, "r");
        if (cnf == NULL) {
                fprintf(stderr, "cannot open config file %s\n", buf);
+               fflush(stderr);
                exit(1);
        }
 
@@ -993,51 +1064,72 @@
 
        if (dbfarm == NULL) {
                fprintf(stderr, "cannot find dbfarm via config file\n");
+               fflush(stderr);
                exit(1);
        }
 
-       q->pid = 0;
-       q->dbname = NULL;
+       snprintf(buf, 1024, "%s/.merovingian_lock", dbfarm);
+       /* we leak ret, but that doesn't matter as the file needs to remain
+        * available, otherwise we lose the lock */
+       if ((ret = MT_lockf(buf, F_TLOCK, 4, 1)) < 0) {
+               /* locking failed */
+               fprintf(stderr, "another merovingian is already running\n");
+               fflush(stderr);
+               exit(1);
+       }
+
+       snprintf(buf, 1024, "%s/.merovingian_control", dbfarm);
+       unlink(buf);
+       if ((ret = mkfifo(buf, 0660)) != 0) {
+               fprintf(stderr, "failed to create a control channel %s: %s\n",
+                               buf, strerror(errno));
+               fflush(stderr);
+               exit(1);
+       }
+
+       topdp = alloca(sizeof(struct _dpair));
+       topdp->pid = 0;
+       topdp->dbname = NULL;
 
        /* where should our msg output go to? */
        if (msglog == NULL) {
                /* stdout, save it */
                argp = dup(1);
-               q->fout = fdopen(argp, "w");
+               topdp->fout = fdopen(argp, "w");
        } else {
                /* write to the given file */
-               q->fout = fopen(msglog, "a");
-               if (q->fout == NULL) {
+               topdp->fout = fopen(msglog, "a");
+               if (topdp->fout == NULL) {
                        fprintf(stderr, "unable to open '%s': %s\n",
                                        msglog, strerror(errno));
                        exit(1);
                }
-               q->dbname = "file";
+               topdp->dbname = "file";
        }
 
        /* where should our err output go to? */
        if (errlog == NULL) {
                /* stderr, save it */
                argp = dup(2);
-               q->ferr = fdopen(argp, "w");
+               topdp->ferr = fdopen(argp, "w");
        } else {
                /* write to the given file */
                if (strcmp(msglog, errlog) == 0) {
-                       q->ferr = q->fout;
+                       topdp->ferr = topdp->fout;
                } else {
-                       q->ferr = fopen(errlog, "a");
-                       if (q->ferr == NULL) {
+                       topdp->ferr = fopen(errlog, "a");
+                       if (topdp->ferr == NULL) {
                                fprintf(stderr, "unable to open '%s': %s\n",
                                                errlog, strerror(errno));
                                exit(1);
                        }
                }
-               q->dbname = "file";
+               topdp->dbname = "file";
        }
        GDKfree(msglog);
        GDKfree(errlog);
 
-       d = q->next = alloca(sizeof(struct _dpair));
+       d = topdp->next = alloca(sizeof(struct _dpair));
 
        /* redirect stdout */
        if (pipe(pfd) == -1) {
@@ -1067,8 +1159,8 @@
 
        servers = d;
 
-       if (pthread_create(&tid, NULL, (void *(*)(void *))logListener, (void 
*)q) < 0) {
-               fprintf(q->ferr, "%s: unable to create logthread, exiting\n", 
argv[0]);
+       if (pthread_create(&tid, NULL, (void *(*)(void *))logListener, (void 
*)NULL) < 0) {
+               fprintf(topdp->ferr, "%s: unable to create logthread, 
exiting\n", argv[0]);
                return(1);
        }
 
@@ -1080,7 +1172,7 @@
                        sigaction(SIGQUIT, &sa, NULL) == -1 ||
                        sigaction(SIGTERM, &sa, NULL) == -1)
        {
-               fprintf(q->ferr, "%s: unable to create signal handlers\n", 
argv[0]);
+               fprintf(topdp->ferr, "%s: unable to create signal handlers\n", 
argv[0]);
                return(1);
        }
 
@@ -1088,7 +1180,7 @@
        sigemptyset(&sa.sa_mask);
        sa.sa_sigaction = childhandler;
        if (sigaction(SIGCHLD, &sa, NULL) == -1) {
-               fprintf(q->ferr, "%s: unable to create signal handlers\n", 
argv[0]);
+               fprintf(topdp->ferr, "%s: unable to create signal handlers\n", 
argv[0]);
                return(1);
        }
 
@@ -1101,8 +1193,9 @@
        /* open up a connection */
        e = openConnection(&sock, MEROV_PORT);
        if (e == NO_ERR) {
+               pthread_t ctid;
                for (argp = 1; argp < argc; argp++) {
-                       e = forkMserver(argv[argp], &stats, d, sock);
+                       e = forkMserver(argv[argp], &stats, 0);
                        if (e != NO_ERR) {
                                fprintf(stderr, "failed to fork mserver: %s\n", 
getErrMsg(e));
                                freeErr(e);
@@ -1111,10 +1204,20 @@
                                SABAOTHfreeStatus(&stats);
                }
 
+               /* handle control commands */
+               if (pthread_create(&ctid, NULL, (void *(*)(void 
*))controlRunner, (void *)buf) < 0) {
+                       fprintf(stderr, "unable to create control command 
thread\n");
+                       ctid = 0;
+               }
+
                /* handle external connections main loop */
-               e = acceptConnections(sock, d);
+               e = acceptConnections(sock);
+
+               /* shut down the control runner too */
+               pthread_join(ctid, NULL);
        }
 
+       unlink(buf);
        ret = 0;
 
        if (e != NO_ERR) {
@@ -1123,8 +1226,7 @@
                ret = 1;
        }
 
-       if (_keepListening != 0)
-               merlog("Merovingian %s stopping ...", MEROV_VERSION);
+       merlog("Merovingian %s stopping ...", MEROV_VERSION);
 
        /* we don't need merovingian itself */
        d = d->next;
@@ -1145,7 +1247,7 @@
                        if (pthread_create(&(t->tid), NULL,
                                                (void *(*)(void 
*))terminateProcess, (void *)t) < 0)
                        {
-                               fprintf(q->ferr, "%s: unable to create thread 
to terminate "
+                               fprintf(topdp->ferr, "%s: unable to create 
thread to terminate "
                                                "database '%s'\n", argv[0], 
d->dbname);
                                t->tid = 0;
                                ret = 1;
@@ -1156,7 +1258,7 @@
                t = d;
                while (t != NULL) {
                        if (t->tid != 0 && (argp = pthread_join(t->tid, NULL)) 
!= 0) {
-                               fprintf(q->ferr, "failed to wait for 
termination thread: "
+                               fprintf(topdp->ferr, "failed to wait for 
termination thread: "
                                                "%s\n", strerror(argp));
                                ret = 1;
                        }
@@ -1166,21 +1268,21 @@
 
        _keepLogging = 0;
        if ((argp = pthread_join(tid, NULL)) != 0) {
-               fprintf(q->ferr, "failed to wait for logging thread: %s\n", 
strerror(argp));
+               fprintf(topdp->ferr, "failed to wait for logging thread: %s\n", 
strerror(argp));
                ret = 1;
        }
 
-       fclose(q->fout);
-       if (q->fout != q->ferr)
-               fclose(q->ferr);
+       fclose(topdp->fout);
+       if (topdp->fout != topdp->ferr)
+               fclose(topdp->ferr);
 
        /* clean up dbpair structs */
        while (d != NULL) {
-               q = d->next;
+               topdp = d->next;
                if (d->dbname != NULL)
                        GDKfree(d->dbname);
                GDKfree(d);
-               d = q;
+               d = topdp;
        }
 
        return(ret);

Index: monetdb.mx
===================================================================
RCS file: /cvsroot/monetdb/MonetDB5/src/tools/monetdb.mx,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- monetdb.mx  1 Sep 2007 12:14:45 -0000       1.21
+++ monetdb.mx  2 Sep 2007 15:13:51 -0000       1.22
@@ -25,7 +25,7 @@
 information about them are the primary goals of this tool.
 
 @h
-#define TOOLKIT_VERSION   "0.1"
+#define TOOLKIT_VERSION   "0.2"
 
 @c
 #include "mal_config.h" /* MONETDBCONFIG, MONETDBPREFIX */
@@ -50,6 +50,7 @@
 #define NO_ERR (err)0
 
 static str dbfarm = NULL;
+static int mero_running = 0;
 
 static str
 replacePrefix(str s)
@@ -77,16 +78,10 @@
        if (argc != 2) {
                printf("Usage: monetdb command 
[command-options-and-arguments]\n");
                printf("  where command is one of:\n");
-               printf("    status, create, destroy, lock, release, help, 
version\n");
+               printf("    create, destroy, lock, release\n");
+               printf("    status, start, stop\n");
+               printf("    help, version\n");
                printf("  use the help command to get help for a particular 
command\n");
-       } else if (strcmp(argv[1], "status") == 0) {
-               printf("Usage: monetdb status [-als] [database ...]\n");
-               printf("  Shows the state of a given database.  Various 
options\n");
-               printf("  control what information is displayed.\n");
-               printf("Options:\n");
-               printf("  -a  list status of all databases\n");
-               printf("  -l  use long listing\n");
-               printf("  -s  use short one-line listing\n");
        } else if (strcmp(argv[1], "create") == 0) {
                printf("Usage: monetdb create [-l] database\n");
                printf("  Initialises a new database in the MonetDB Server.  
A\n");
@@ -113,6 +108,22 @@
                printf("  Brings back a database from maintenance mode.  A 
released\n");
                printf("  database is available again for normal use.  Use 
the\n");
                printf("  \"lock\" command to take a database under 
maintenance.\n");
+       } else if (strcmp(argv[1], "status") == 0) {
+               printf("Usage: monetdb status [-als] [database ...]\n");
+               printf("  Shows the state of a given database.  Various 
options\n");
+               printf("  control what information is displayed.\n");
+               printf("Options:\n");
+               printf("  -a  list status of all databases\n");
+               printf("  -l  use long listing\n");
+               printf("  -s  use short one-line listing\n");
+       } else if (strcmp(argv[1], "start") == 0) {
+               printf("Usage: monetdb start [-a] [database ...]\n");
+               printf("  Starts the given database, if the MonetDB Database 
Server\n");
+               printf("  is running.\n");
+       } else if (strcmp(argv[1], "stop") == 0) {
+               printf("Usage: monetdb stop [-a] [database ...]\n");
+               printf("  Stops the given database, if the MonetDB Database 
Server\n");
+               printf("  is running.\n");
        } else if (strcmp(argv[1], "help") == 0) {
                printf("Yeah , help on help, how desparate can you be? ;)");
        } else if (strcmp(argv[1], "version") == 0) {
@@ -126,7 +137,7 @@
 static void
 command_version()
 {
-       printf("MonetDB Toolkit v%s\n", TOOLKIT_VERSION);
+       printf("MonetDB Database Server Toolkit v%s\n", TOOLKIT_VERSION);
 }
 
 static void
@@ -432,6 +443,216 @@
 }
 
 static void
+command_start(int argc, char *argv[], char *dbfarm)
+{
+       int doall = 0;
+       char path[8096];
+       FILE *f;
+       char buf[256];
+       int i;
+       err e;
+       sabdb *stats;
+
+       snprintf(path, 8095, "%s/.merovingian_control", dbfarm);
+       path[8095] = '\0';
+
+       if (argc == 1) {
+               /* print help message for this command */
+               command_help(2, &argv[-1]);
+               exit(1);
+       } else if (argc == 0) {
+               exit(2);
+       }
+
+       /* time to collect some option flags */
+       for (i = 1; i < argc; i++) {
+               if (argv[i][0] == '-') {
+                       if (strcmp(&argv[i][1], "a") == 0) {
+                               doall = 1;
+                       } else if (strcmp(&argv[i][1], "-") == 0) {
+                               i = argc;
+                       } else {
+                               fprintf(stderr, "start: unknown option: -%c\n", 
argv[i][1]);
+                               command_help(2, &argv[-1]);
+                               exit(1);
+                       }
+                       /* make this option no longer available, for easy use
+                        * lateron */
+                       argv[i] = NULL;
+               }
+       }
+
+       /* if Merovingian isn't running, there's not much we can do */
+       if (mero_running == 0) {
+               fprintf(stderr, "start: cannot start: MonetDB Database Server "
+                               "(merovingian) is not running\n");
+               exit(1);
+       }
+
+       if ((f = fopen(path, "a")) == NULL) {
+               fprintf(stderr, "start: cannot write command: %s\n",
+                               strerror(errno));
+               exit(2);
+       }
+
+       if (doall == 1) {
+               sabdb *orig;
+               /* don't even look at the arguments, because we are instructed
+                * to start all known databases */
+               if ((e = SABAOTHgetStatus(&stats, NULL)) != MAL_SUCCEED) {
+                       fprintf(stderr, "start: internal error: %s\n", e);
+                       GDKfree(e);
+                       exit(2);
+               }
+       
+               orig = stats;
+               while (stats != NULL && stats->state != SABdbRunning) {
+                       snprintf(buf, 256, "%s start\n", stats->dbname);
+                       fputs(buf, f);
+                       stats = stats->next;
+               }
+
+               fflush(f);
+               fclose(f);
+
+               if (orig != NULL)
+                       SABAOTHfreeStatus(&orig);
+               return;
+       }
+
+       for (i = 1; i < argc; i++) {
+               if (argv[i] != NULL) {
+                       if ((e = SABAOTHgetStatus(&stats, argv[i])) != 
MAL_SUCCEED) {
+                               fprintf(stderr, "start: internal error: %s\n", 
e);
+                               GDKfree(e);
+                               exit(2);
+                       }
+
+                       if (stats == NULL) {
+                               fprintf(stderr, "start: no such database: 
%s\n", argv[i]);
+                       } else {
+                               if (stats->state == SABdbRunning) {
+                                       printf("start: database is already 
running: %s\n", argv[i]);
+                               } else {
+                                       snprintf(buf, 256, "%s start\n", 
stats->dbname);
+                                       fputs(buf, f);
+                               }
+
+                               SABAOTHfreeStatus(&stats);
+                       }
+               }
+       }
+
+       fflush(f);
+       fclose(f);
+}
+
+static void
+command_stop(int argc, char *argv[], char *dbfarm)
+{
+       int doall = 0;
+       char path[8096];
+       FILE *f;
+       char buf[256];
+       int i;
+       err e;
+       sabdb *stats;
+
+       snprintf(path, 8095, "%s/.merovingian_control", dbfarm);
+       path[8095] = '\0';
+
+       if (argc == 1) {
+               /* print help message for this command */
+               command_help(2, &argv[-1]);
+               exit(1);
+       } else if (argc == 0) {
+               exit(2);
+       }
+
+       /* time to collect some option flags */
+       for (i = 1; i < argc; i++) {
+               if (argv[i][0] == '-') {
+                       if (strcmp(&argv[i][1], "a") == 0) {
+                               doall = 1;
+                       } else if (strcmp(&argv[i][1], "-") == 0) {
+                               i = argc;
+                       } else {
+                               fprintf(stderr, "stop: unknown option: -%c\n", 
argv[i][1]);
+                               command_help(2, &argv[-1]);
+                               exit(1);
+                       }
+                       /* make this option no longer available, for easy use
+                        * lateron */
+                       argv[i] = NULL;
+               }
+       }
+
+       /* if Merovingian isn't running, there's not much we can do */
+       if (mero_running == 0) {
+               fprintf(stderr, "stop: cannot stop: MonetDB Database Server "
+                               "(merovingian) is not running\n");
+               exit(1);
+       }
+
+       if ((f = fopen(path, "a")) == NULL) {
+               fprintf(stderr, "stop: cannot write command: %s\n",
+                               strerror(errno));
+               exit(2);
+       }
+
+       if (doall == 1) {
+               sabdb *orig;
+               /* don't even look at the arguments, because we are instructed
+                * to stop all known databases */
+               if ((e = SABAOTHgetStatus(&stats, NULL)) != MAL_SUCCEED) {
+                       fprintf(stderr, "stop: internal error: %s\n", e);
+                       GDKfree(e);
+                       exit(2);
+               }
+       
+               orig = stats;
+               while (stats != NULL && stats->state == SABdbRunning) {
+                       snprintf(buf, 256, "%s stop\n", stats->dbname);
+                       fputs(buf, f);
+                       stats = stats->next;
+               }
+
+               fflush(f);
+               fclose(f);
+
+               if (orig != NULL)
+                       SABAOTHfreeStatus(&orig);
+               return;
+       }
+
+       for (i = 1; i < argc; i++) {
+               if (argv[i] != NULL) {
+                       if ((e = SABAOTHgetStatus(&stats, argv[i])) != 
MAL_SUCCEED) {
+                               fprintf(stderr, "stop: internal error: %s\n", 
e);
+                               GDKfree(e);
+                               exit(2);
+                       }
+
+                       if (stats == NULL) {
+                               fprintf(stderr, "stop: no such database: %s\n", 
argv[i]);
+                       } else {
+                               if (stats->state != SABdbRunning) {
+                                       printf("stop: database is not running: 
%s\n", argv[i]);
+                               } else {
+                                       snprintf(buf, 256, "%s stop\n", 
stats->dbname);
+                                       fputs(buf, f);
+                               }
+
+                               SABAOTHfreeStatus(&stats);
+                       }
+               }
+       }
+
+       fflush(f);
+       fclose(f);
+}
+
+static void
 command_create(int argc, char *argv[], char *dbfarm)
 {
        if (argc == 1 || argc >= 4) {
@@ -756,6 +977,7 @@
        str p;
        FILE *cnf = NULL;
        char buf[1024];
+       int fd;
 
        /* hunt for the config file, and read it */
        snprintf(buf, 1023, "%s%s", MONETDBPREFIX, conf + 9);
@@ -781,6 +1003,17 @@
                exit(2);
        }
 
+       mero_running = 1;
+       snprintf(buf, 1024, "%s/.merovingian_lock", dbfarm);
+       fd = MT_lockf(buf, F_TLOCK, 4, 1);
+       if (fd >= 0 || fd == -2) {
+               if (fd >= 0)
+                       close(fd);
+               /* locking succeed or locking was impossible */
+               fprintf(stderr, "warning: MonetDB Database Server is not 
running\n");
+               mero_running = 0;
+       }
+
        /* initialise Sabaoth so it knows where to look */
        SABAOTHinit(dbfarm, NULL);
 
@@ -789,8 +1022,6 @@
         */
        if (argc <= 1) {
                command_help(0, NULL);
-       } else if (strcmp(argv[1], "status") == 0) {
-               command_status(argc - 1, &argv[1]);
        } else if (strcmp(argv[1], "create") == 0) {
                command_create(argc - 1, &argv[1], dbfarm);
        } else if (strcmp(argv[1], "destroy") == 0) {
@@ -799,6 +1030,12 @@
                command_lock(argc - 1, &argv[1]);
        } else if (strcmp(argv[1], "release") == 0) {
                command_release(argc - 1, &argv[1]);
+       } else if (strcmp(argv[1], "status") == 0) {
+               command_status(argc - 1, &argv[1]);
+       } else if (strcmp(argv[1], "start") == 0) {
+               command_start(argc - 1, &argv[1], dbfarm);
+       } else if (strcmp(argv[1], "stop") == 0) {
+               command_stop(argc - 1, &argv[1], dbfarm);
        } else if (strcmp(argv[1], "help") == 0 || strcmp(argv[1], "-h") == 0) {
                command_help(argc - 1, &argv[1]);
        } else if (strcmp(argv[1], "version") == 0 || strcmp(argv[1], "-v") == 
0) {


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Monetdb-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-checkins

Reply via email to