Changeset: 9540ecbf9d0e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=9540ecbf9d0e
Modified Files:
        tools/merovingian/daemon/controlrunner.c
        tools/merovingian/daemon/forkmserver.c
        tools/merovingian/daemon/forkmserver.h
Branch: default
Log Message:

Implement profiler shutdown procedure


diffs (151 lines):

diff --git a/tools/merovingian/daemon/controlrunner.c 
b/tools/merovingian/daemon/controlrunner.c
--- a/tools/merovingian/daemon/controlrunner.c
+++ b/tools/merovingian/daemon/controlrunner.c
@@ -639,7 +639,21 @@ static void ctl_handle_client(
                                }
                                msab_freeStatus(&stats);
                        }  else if (strncmp(p, "profilerstop", 
strlen("profilerstop")) == 0) {
-
+                               char *e = shutdown_profiler(q, &stats);
+                               if (e != NULL) {
+                                       Mfprintf(_mero_ctlerr, "%s: failed to 
shutdown the profiler "
+                                                        "database '%s': %s\n", 
origin, q, getErrMsg(e));
+                                       len = snprintf(buf2, sizeof(buf2),
+                                                                  "%s\n", 
getErrMsg(e));
+                                       send_client("!");
+                                       freeErr(e);
+                               } else {
+                                       len = snprintf(buf2, sizeof(buf2), 
"OK\n");
+                                       send_client("=");
+                                       Mfprintf(_mero_ctlout, "%s: profiler 
shut down for '%s'\n",
+                                                        origin, q);
+                               }
+                               msab_freeStatus(&stats);
                        } else if (strncmp(p, "name=", strlen("name=")) == 0) {
                                char *e;
 
diff --git a/tools/merovingian/daemon/forkmserver.c 
b/tools/merovingian/daemon/forkmserver.c
--- a/tools/merovingian/daemon/forkmserver.c
+++ b/tools/merovingian/daemon/forkmserver.c
@@ -12,6 +12,7 @@
 #include <sys/types.h>
 #include <sys/un.h>
 #include <sys/stat.h>
+#include <signal.h>
 #include <unistd.h>
 #include <string.h> /* char ** */
 #include <time.h> /* localtime */
@@ -942,8 +943,102 @@ fork_profiler(char *dbname, sabdb **stat
        freeConfFile(ckv);
        free(ckv);
        free(profiler_executable);
+       free(pidfilename);
        pthread_mutex_unlock(&fork_lock);
        return error;
 }
 
+err
+shutdown_profiler(char *dbname, sabdb **stats)
+{
+       err error=NO_ERR;
+       confkeyval *ckv, *kv;
+       size_t pidfnlen = 0;
+       char *pidfilename = NULL;
+       FILE *pidfile;
+       char buf[BUFSIZ];
+       size_t nbytes;
+       pid_t pid;
+
+       error = msab_getStatus(stats, dbname);
+       if (error != NULL) {
+               return error;
+       }
+
+       if (*stats == NULL) {
+               /* TODO: What now? */
+               error = newErr("Null stats for db %s", dbname);
+               return error;
+       }
+
+       /* Verify that the requested db is running */
+       if ((*stats)->state != SABdbRunning) {
+               /* server is not running, shoo */
+               error = newErr("Database %s is not running.", dbname);
+               goto cleanup;
+       }
+
+       /* Find the pid file and make sure the profiler is running */
+       ckv = getDefaultProps();
+       readAllProps(ckv, (*stats)->path);
+       kv = findConfKey(ckv, PROFILERLOGPROPERTY);
+
+       if (kv == NULL) {
+               error = newErr("Property 'profilerlogpath' not set for db %s\n",
+                                          dbname);
+               goto cleanup;
+       }
+
+       /* construct the filename of the pid file */
+       pidfnlen = strlen(kv->val) + strlen("/profiler.pid") + 1;
+       pidfilename = malloc(pidfnlen);
+       if (pidfilename == NULL) {
+               error = newErr("Cannot allocate buffer while shutting down of 
profiler");
+               goto cleanup;
+       }
+       snprintf(pidfilename, pidfnlen, "%s/profiler.pid", kv->val);
+
+       if ((pidfile = fopen(pidfilename, "r")) == NULL) {
+               error = newErr("Unable to open %s for reading", pidfilename);
+               goto cleanup;
+       }
+
+       clearerr(pidfile);
+       nbytes = fread(buf, 1, BUFSIZ, pidfile);
+
+       if (ferror(pidfile)) {
+               error = newErr("Cannot read pid (%s) from file %s", buf, 
pidfilename);
+               fclose(pidfile);
+               goto cleanup;
+       }
+       fclose(pidfile);
+
+       if (buf[nbytes - 1] == '\n') {
+               buf[nbytes - 1] = '\0';
+       }
+
+       pid = (pid_t)strtol(buf, NULL, 10);
+       if (pid == 0 && errno == EINVAL) {
+               error = newErr("File contents %s not a valid pid", buf);
+               goto cleanup;
+       }
+
+       if (kill(pid, SIGTERM) == -1) {
+               char error_message[BUFSIZ];
+               strerror_r(errno, error_message, BUFSIZ);
+               error = newErr("%s", error_message);
+               goto cleanup;
+       }
+
+       /* All went well. Remove the pidfile */
+       if (unlink(pidfilename) != 0) {
+               error = newErr("Profiler seems to have stopped, but cannot 
remove pid file.");
+       }
+
+  cleanup:
+       freeConfFile(ckv);
+       free(pidfilename);
+       return error;
+}
+
 /* vim:set ts=4 sw=4 noexpandtab: */
diff --git a/tools/merovingian/daemon/forkmserver.h 
b/tools/merovingian/daemon/forkmserver.h
--- a/tools/merovingian/daemon/forkmserver.h
+++ b/tools/merovingian/daemon/forkmserver.h
@@ -14,6 +14,7 @@
 
 err forkMserver(char* database, sabdb** stats, int force);
 err fork_profiler(char *database, sabdb **stats, char **log_path);
+err shutdown_profiler(char *dbname, sabdb **stats);
 
 #endif
 
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to