From dae944be128833cba5d48bb088c7d2d230d9bb69 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ji=C5=99=C3=AD=20=C5=A0kr=C3=A1bal?= Date: Mon, 8 Aug 2005 11:13:01 +0000 Subject: [PATCH] - adds utility which parses and exports LB dump files to JP --- org.glite.lb.client/Makefile | 2 +- org.glite.lb.client/src/lb_dump_exporter.c | 306 +++++++++++++++++++++++++++++ 2 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 org.glite.lb.client/src/lb_dump_exporter.c diff --git a/org.glite.lb.client/Makefile b/org.glite.lb.client/Makefile index 04bbb5c..2deaf94 100644 --- a/org.glite.lb.client/Makefile +++ b/org.glite.lb.client/Makefile @@ -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 index 0000000..55d148d --- /dev/null +++ b/org.glite.lb.client/src/lb_dump_exporter.c @@ -0,0 +1,306 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 Dump file location.\n" + "\t-s, --store New dump files storage.\n" + "\t-m, --lbmaildir 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; +} -- 1.8.2.3