Added TS_SAVELIST.
authorviric@llimona
Tue, 10 Apr 2007 23:31:21 +0200
changeset 120 790bc4cecd3b
parent 119 361b08d33762
child 121 7a42c36de0d0
Added TS_SAVELIST.
Changelog
Makefile
jobs.c
list.c
main.h
server.c
ts.1
--- a/Changelog	Tue Apr 10 17:16:25 2007 +0200
+++ b/Changelog	Tue Apr 10 23:31:21 2007 +0200
@@ -13,7 +13,7 @@
 v0.4:
  -* Allow killing 'ts' in a nice way.
    - It's good, because a spawner of 'ts' may want to kill it.
- - If the server is horribly killed (it may happen as this is software), store
+ -* If the server is horribly killed (it may happen as this is software), store
    the task queue in a file, so it can be recovered.
  - Allow inspecting the environment for a command queued: env, pwd., together
    with other job queuing options (gzip, ...)
--- a/Makefile	Tue Apr 10 17:16:25 2007 +0200
+++ b/Makefile	Tue Apr 10 23:31:21 2007 +0200
@@ -1,6 +1,6 @@
 PREFIX?=/usr/local
-GCCFLAGS=-D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED -D__STRICT_ANSI__
-CFLAGS=-pedantic -ansi -Wall -g -O0 ${GCCFLAGS}
+GLIBCFLAGS=-D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED -D__STRICT_ANSI__
+CFLAGS=-pedantic -ansi -Wall -g -O0 ${GLIBCFLAGS}
 OBJECTS=main.o \
 	server.o \
 	server_start.o \
--- a/jobs.c	Tue Apr 10 17:16:25 2007 +0200
+++ b/jobs.c	Tue Apr 10 23:31:21 2007 +0200
@@ -64,7 +64,7 @@
     send_msg(s, &m);
 }
 
-static struct Job * find_previous_job(struct Job *final)
+static struct Job * find_previous_job(const struct Job *final)
 {
     struct Job *p;
 
@@ -119,7 +119,7 @@
 
 const char * jstate2string(enum Jobstate s)
 {
-    char * jobstate;
+    const char * jobstate;
     switch(s)
     {
         case QUEUED:
@@ -140,8 +140,6 @@
     struct Job *p;
     char *buffer;
 
-    /* We limit to 100 bytes for output and 200 for the command.
-     * We also put spaces between the data, for assuring parseability. */
     /* Times:   0.00/0.00/0.00 - 4+4+4+2 = 14*/ 
     buffer = joblist_headers();
     send_list_line(s,buffer);
@@ -159,16 +157,13 @@
 
     p = first_finished_job;
 
-    if (p != 0)
+    /* Show Finished jobs */
+    while(p != 0)
     {
-        /* Show Finished jobs */
-        while(p != 0)
-        {
-            buffer = joblist_line(p);
-            send_list_line(s,buffer);
-            free(buffer);
-            p = p->next;
-        }
+        buffer = joblist_line(p);
+        send_list_line(s,buffer);
+        free(buffer);
+        p = p->next;
     }
 }
 
@@ -812,3 +807,41 @@
         p = p->next;
     }
 }
+
+void joblist_dump(int fd)
+{
+    struct Job *p;
+    char *buffer;
+
+    buffer = joblistdump_headers();
+    write(fd,buffer, strlen(buffer));
+    free(buffer);
+
+    /* We reuse the headers from the list */
+    buffer = joblist_headers();
+    write(fd, "# ", 2);
+    write(fd, buffer, strlen(buffer));
+
+    /* Show Finished jobs */
+    p = first_finished_job;
+    while(p != 0)
+    {
+        buffer = joblist_line(p);
+        write(fd, "# ", 2);
+        write(fd,buffer, strlen(buffer));
+        free(buffer);
+        p = p->next;
+    }
+
+    write(fd, "\n", 1);
+
+    /* Show Queued or Running jobs */
+    p = firstjob;
+    while(p != 0)
+    {
+        buffer = joblistdump_torun(p);
+        write(fd,buffer,strlen(buffer));
+        free(buffer);
+        p = p->next;
+    }
+}
--- a/list.c	Tue Apr 10 17:16:25 2007 +0200
+++ b/list.c	Tue Apr 10 23:31:21 2007 +0200
@@ -3,15 +3,28 @@
 #include <string.h>
 #include "main.h"
 
+char * joblistdump_headers()
+{
+    char * line;
+
+    line = malloc(600);
+    sprintf(line, "#!/bin/sh\n# - task spooler (ts) job dump\n"
+            "# This file has been created because a SIGTERM killed\n"
+            "# your queue server.\n"
+            "# The finished commands are listed first.\n"
+            "# The commands running or to be run are stored as you would\n"
+            "# probably run them. Take care - some quotes may have got"
+            " broken\n\n");
+
+    return line;
+}
+
 char * joblist_headers()
 {
     char * line;
 
     line = malloc(100);
-    /* We limit to 100 bytes for output and 200 for the command.
-     * We also put spaces between the data, for assuring parseability. */
-    /* Times:   0.00/0.00/0.00 - 4+4+4+2 = 14*/ 
-    sprintf(line, "%-4s %-10s %-20.100s %-8s %-14s %.200s\n",
+    sprintf(line, "%-4s %-10s %-20s %-8s %-14s %s\n",
             "ID",
             "State",
             "Output",
@@ -122,3 +135,19 @@
 
     return line;
 }
+
+char * joblistdump_torun(const struct Job *p)
+{
+    int maxlen;
+    char * line;
+
+    maxlen = 10 + strlen(p->command) + 20; /* 20 is the margin for errors */
+
+    line = (char *) malloc(maxlen);
+    if (line == NULL)
+        error("Malloc for %i failed.\n", maxlen);
+
+    sprintf(line, "ts %s", p->command);
+
+    return line;
+}
--- a/main.h	Tue Apr 10 17:16:25 2007 +0200
+++ b/main.h	Tue Apr 10 23:31:21 2007 +0200
@@ -167,6 +167,8 @@
 void s_send_state(int s, int jobid);
 void s_swap_jobs(int s, int jobid1, int jobid2);
 void dump_jobs_struct(FILE *out);
+void joblist_dump(int fd);
+const char * jstate2string(enum Jobstate s);
 
 /* server.c */
 void server_main(int notify_fd, char *_path);
@@ -205,9 +207,6 @@
 void send_msg(const int fd, const struct msg *m);
 int recv_msg(const int fd, struct msg *m);
 
-/* jobs.c */
-const char * jstate2string(enum Jobstate s);
-
 /* msgdump.c */
 void msgdump(FILE *, const struct msg *m);
 
@@ -218,3 +217,5 @@
 /* list.c */
 char * joblist_headers();
 char * joblist_line(const struct Job *p);
+char * joblistdump_torun(const struct Job *p);
+char * joblistdump_headers();
--- a/server.c	Tue Apr 10 17:16:25 2007 +0200
+++ b/server.c	Tue Apr 10 23:31:21 2007 +0200
@@ -16,6 +16,7 @@
 #include <unistd.h>
 #include <limits.h>
 #include <signal.h>
+#include <fcntl.h>
 
 #include <stdio.h>
 
@@ -53,9 +54,25 @@
 static char *path;
 static int max_descriptors;
 
-
 static void sigterm_handler(int n)
 {
+    const char *dumpfilename;
+    int fd;
+
+    /* Dump the job list if we should to */
+    dumpfilename = getenv("TS_SAVELIST");
+    if (dumpfilename != NULL)
+    {
+        fd = open(dumpfilename, O_WRONLY | O_APPEND | O_CREAT, 0600);
+        if (fd != -1)
+        {
+            joblist_dump(fd);
+            close(fd);
+        } else
+            warning("The TS_SAVELIST file \"%s\" cannot be opened",
+                    dumpfilename);
+    }
+
     /* path will be initialized for sure, before installing the handler */
     unlink(path);
     exit(1);
--- a/ts.1	Tue Apr 10 17:16:25 2007 +0200
+++ b/ts.1	Tue Apr 10 23:31:21 2007 +0200
@@ -182,6 +182,12 @@
 As seen above, it's used for the mail destination if
 .B TS_MAILTO
 is not specified.
+.TP
+.B "TS_SAVELIST"
+If it's defined when starting the queue server (probably the first
+.B ts
+command run), on SIGTERM the queue status will be saved to the file pointed
+by this environment variable - for example, at system shutdown.
 .SH BUGS
 If you want to run complex commands, you may want to run them through
 .B sh -c 'commands...'