- adds utility which parses and exports LB dump files to JP
authorJiří Škrábal <nykolas@ics.muni.cz>
Mon, 8 Aug 2005 11:13:01 +0000 (11:13 +0000)
committerJiří Škrábal <nykolas@ics.muni.cz>
Mon, 8 Aug 2005 11:13:01 +0000 (11:13 +0000)
org.glite.lb.client/Makefile
org.glite.lb.client/src/lb_dump_exporter.c [new file with mode: 0644]

index 04bbb5c..2deaf94 100644 (file)
@@ -139,7 +139,7 @@ FAKETHRLIB:=libglite_lb_client_fake_${thrflavour}.la
 PLUSLIB:=libglite_lb_clientpp_${nothrflavour}.la
 THRPLUSLIB:=libglite_lb_clientpp_${thrflavour}.la
 
-TOOLS:=dump load purge
+TOOLS:=dump load purge lb_dump_exporter
 EXAMPLES:=log_usertag_proxy job_log job_reg feed_shark notify query_ext query_seq_code stats abort_job change_acl
 
 EXAMPLES_CL=user_jobs job_status
diff --git a/org.glite.lb.client/src/lb_dump_exporter.c b/org.glite.lb.client/src/lb_dump_exporter.c
new file mode 100644 (file)
index 0000000..55d148d
--- /dev/null
@@ -0,0 +1,306 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <time.h>
+#include <malloc.h>
+#include <limits.h>
+
+#include "glite/lb/context.h"
+#include "glite/lb/events.h"
+#include "glite/lb/events_parse.h"
+#include "glite/lb/lb_maildir.h"
+
+
+#define DUMP_FILE_STORE_PREFIX "/tmp"
+#define LB_MAILDIR_PATH                        "/tmp/dumpinfo_lbmd"
+
+typedef struct _buffer_t {
+       char   *str;
+       char   *eol;
+       int             sz;
+       int             use;
+} buffer_t;
+
+typedef struct _dump_storage_t {
+       char   *job;
+       char   *fname;
+       int             fhnd;
+} dump_storage_t;
+
+static const char *optstr = "d:s:m:h";
+
+static struct option opts[] = {
+       { "help",               0,      NULL,   'h'},
+       { "dump",               0,      NULL,   'd'},
+       { "store",              0,      NULL,   's'},
+       { "lbmaildir",  0,      NULL,   'm'},
+       { NULL,                 0,      NULL,   0}
+};
+
+void usage(char *me)
+{
+       fprintf(stderr, "usage: %s [option]\n"
+                       "\t-h, --help              Shows this screen.\n"
+                       "\t-d, --dump <file>       Dump file location.\n"
+                       "\t-s, --store <prefix>    New dump files storage.\n"
+                       "\t-m, --lbmaildir <path>  LB maildir path.\n"
+                       , me);
+}
+
+
+static int read_line(int, buffer_t *, char **);
+static dump_storage_t *dump_storage_find(dump_storage_t *, char *);
+static dump_storage_t *dump_storage_add(dump_storage_t **, char *, char *, int);
+static void dump_storage_free(dump_storage_t *);
+
+
+int main(int argc, char **argv)
+{
+       edg_wll_Context         ctx;
+       edg_wll_Event      *ev = NULL;
+       dump_storage_t     *dstorage = NULL,
+                                          *st;
+       buffer_t                        buf;
+       char                       *store_pref = DUMP_FILE_STORE_PREFIX,
+                                          *lb_maildir = LB_MAILDIR_PATH,
+                                          *name,
+                                          *fname,
+                                          *ln;
+       int                                     fhnd,
+                                               opt, ret;
+
+
+       name = strrchr(argv[0], '/');
+       if ( name ) name++; else name = argv[0];
+
+       fname = NULL;
+       while ( (opt = getopt_long(argc, argv, optstr, opts, NULL)) != EOF )
+               switch ( opt ) {
+               case 'd': fname = optarg; break;
+               case 's': store_pref = optarg; break;
+               case 'm': lb_maildir = optarg; break;
+               case 'h': usage(name); return 0;
+               case '?': usage(name); return 1;
+               }
+
+       if ( fname ) {
+               if ( (fhnd = open(fname, O_RDONLY)) < 0 ) {
+                       perror("Opening input file");
+                       exit(1);
+               }
+       } else fhnd = 0;
+
+       if ( edg_wll_MaildirInit(lb_maildir) ) {
+               perror(lbm_errdesc);
+               exit(1);
+       }
+
+
+#ifndef cleanup
+#      define cleanup(r)       { ret = (r); goto cleanup_lbl; }
+#endif
+
+       ret = 0;
+       memset(&buf, 0, sizeof(buf));
+       edg_wll_InitContext(&ctx);
+       while ( 1 ) {
+               int             rl_ret,
+                               written,
+                               lnsz, ct;
+               char   *jobid,
+                          *unique;
+
+               if ( (rl_ret = read_line(fhnd, &buf, &ln)) < 0 ) {
+                       perror("reading input file");
+                       cleanup(1);
+               }
+               if ( !ln ) break;
+
+               if ( edg_wll_ParseEvent(ctx, ln, &ev) != 0 ) {
+                       cleanup(1);
+               }
+               if ( !(jobid = edg_wlc_JobIdUnparse(ev->any.jobId)) ) {
+                       perror("Can't unparse jobid from event");
+                       cleanup(1);
+               }
+               if ( !(unique = edg_wlc_JobIdGetUnique(ev->any.jobId)) ) {
+                       perror("Can't unparse jobid from event");
+                       cleanup(1);
+               }
+
+               if ( !(st = dump_storage_find(dstorage, jobid)) ) {
+                       int             fd, i;
+                       char    fname[PATH_MAX];
+
+                       i = 0;
+                       while ( 1 ) {
+                               if ( ++i > 10 ) {
+                                       errno = ECANCELED;
+                                       perror("Can't create dump file - max tries limit reached ");
+                                       cleanup(1);
+                               }
+                               snprintf(fname, PATH_MAX, "%s/%s.%ld", store_pref, unique, time(NULL));
+                               if ( (fd = open(fname, O_CREAT|O_EXCL|O_RDWR, 00600)) < 0 ) {
+                                       if ( errno == EEXIST ) { sleep(2); continue; }
+                                       perror(fname);
+                                       cleanup(1);
+                               }
+                               break;
+                       }
+
+                       if ( !(st = dump_storage_add(&dstorage, jobid, fname, fd)) ) {
+                               perror("Can't record dump informations");
+                               cleanup(1);
+                       }
+               }
+               free(jobid);
+               free(unique);
+
+               lnsz = strlen(ln);
+               ln[lnsz++] = '\n';
+               written = 0;
+               while ( written < lnsz ) {
+                       if ( (ct = write(st->fhnd, ln+written, lnsz-written)) < 0 ) {
+                               if ( errno == EINTR ) { errno = 0; continue; }
+                               perror(fname);
+                               cleanup(1);
+                       }
+                       written += lnsz;
+               }
+
+
+               if ( !rl_ret ) break;
+               edg_wll_FreeEvent(ev); ev = NULL;
+       }
+
+       /* store info in lb_maildir */
+       for ( st = dstorage; st && st->job; st++ ) {
+               char *msg;
+               if ( !(msg = malloc(strlen(st->fname) + strlen(st->job) + 2)) ) {
+                       perror("allocating message");
+                       cleanup(1);
+               }
+               sprintf(msg, "%s\n%s", st->job, st->fname);
+               if ( edg_wll_MaildirStoreMsg(lb_maildir, "localhost", msg) < 0 ) {
+                       perror(lbm_errdesc);
+                       exit(1);
+               }
+               free(msg);
+       }
+
+cleanup_lbl:
+       edg_wll_FreeContext(ctx);
+       if ( ev ) edg_wll_FreeEvent(ev);
+       for ( st = dstorage; st && st->job; st++ ) if ( st->fhnd > 0 ) close(st->fhnd);
+       dump_storage_free(dstorage);
+       close(fhnd);
+       free(buf.str);
+
+       return (ret);
+}
+
+
+static dump_storage_t *dump_storage_find(dump_storage_t *st, char *job)
+{
+       while ( st && st->job ) {
+               if ( !strcmp(job, st->job) ) break;
+               st++;
+       }
+       if ( st && st->job ) return st;
+       return NULL;
+}
+
+static dump_storage_t *dump_storage_add(dump_storage_t **st, char *job, char *fname, int fhnd)
+{
+       dump_storage_t *tmp;
+       int                             ct;
+
+       for ( ct = 0, tmp = *st; tmp && tmp->job; ct++, tmp++ ) ;
+       if ( ct ) tmp = realloc(*st, (ct+2)*sizeof(*tmp));
+       else tmp = calloc(2, sizeof(*tmp));
+       if ( !tmp ) return NULL;
+
+       *st = tmp;
+       while ( tmp && tmp->job ) tmp++;
+       
+       if ( !(tmp->job = strdup(job)) ) return NULL;
+       if ( !(tmp->fname = strdup(fname)) ) { free(tmp->job); return NULL; }
+       tmp->fhnd = fhnd;
+
+       return tmp;
+}
+
+static void dump_storage_free(dump_storage_t *st)
+{
+       dump_storage_t *tmp;
+       for ( tmp = st; tmp && tmp->job; tmp++ ) {
+               free(tmp->job);
+               free(tmp->fname);
+       }
+       free(st);
+}
+
+/* Reads line from file and returns pointer to that.
+ * Returned string is not mem allocated. It only points to the buffer!
+ *
+ * Buffer must be given - it is handled (allocated etc.) fully in the
+ * function. It has to be freed outside.
+ *
+ * returns: -1 on error
+ *                     0       eof ('ln' could points to the last line in file)
+ *                     1       line successfuly read
+ */
+static int read_line(int fhnd, buffer_t *buf, char **ln)
+{
+       int             ct, toread;
+
+
+       if ( buf->eol ) {
+               int tmp = buf->eol - buf->str + 1;
+               
+               if ( tmp < buf->use ) {
+                       char *aux;
+                       if ( (aux = memchr(buf->eol+1, '\n', buf->use-tmp)) ) {
+                               *ln = buf->eol+1;
+                               *aux = 0;
+                               buf->eol = aux;
+                               return 1;
+                       }
+               }
+               memmove(buf->str, buf->eol+1, buf->use - tmp);
+               buf->eol = NULL;
+               buf->use -= tmp;
+       }
+
+       do {
+               if ( buf->use == buf->sz ) {
+                       char *tmp = realloc(buf->str, buf->sz+BUFSIZ);
+                       if ( !tmp ) return -1;
+                       buf->str = tmp;
+                       buf->sz += BUFSIZ;
+               }
+
+               toread = buf->sz - buf->use;
+               if ( (ct = read(fhnd, buf->str+buf->use, toread)) < 0 ) {
+                       if ( errno == EINTR ) continue;
+                       return -1;
+               }
+               if ( ct == 0 ) break;
+               buf->eol = memchr(buf->str+buf->use, '\n', ct);
+               buf->use += ct;
+       } while ( ct == toread && !buf->eol );
+
+       *ln = buf->use? buf->str: NULL;
+       if ( buf->eol ) {
+               *buf->eol = 0;
+               return 1;
+       }
+
+       return 0;
+}